Working with NFTs
This section provides a complete guide to working with NFT collections using the tonutils
library. It covers Standard, Soulbound, Editable, and Editable Onchain collections, including deployment, minting, batch operations, editing, and administrative tasks.
Standard Collection
Deploy Collection
from pytoniq_core import Address
from tonutils.client import ToncenterV3Client
from tonutils.nft import CollectionStandard
from tonutils.nft.content import CollectionOffchainContent
from tonutils.nft.royalty_params import RoyaltyParams
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the owner of the NFT collection
OWNER_ADDRESS = "UQ..."
# URI of the collection's metadata
# https://github.com/ton-blockchain/TEPs/blob/master/text/0064-token-data-standard.md#nft-collection-metadata-example-offchain
URI = "https://example.com/nft/collection.json"
PREFIX_URI = "https://example.com/nft/"
# Royalty parameters: base and factor for calculating the royalty
ROYALTY_BASE = 1000
ROYALTY_FACTOR = 55 # 5.5% royalty
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
collection = CollectionStandard(
owner_address=Address(OWNER_ADDRESS),
next_item_index=0,
content=CollectionOffchainContent(uri=URI, prefix_uri=PREFIX_URI),
royalty_params=RoyaltyParams(
base=ROYALTY_BASE,
factor=ROYALTY_FACTOR,
address=Address(OWNER_ADDRESS),
),
)
""" If you want the option to withdraw extra balance in the future and store collection and NFT data on-chain,
you can use `CollectionStandardModified`. It removes the need for `prefix_uri` because NFTs minted in this
format include a direct link to the metadata for each item, rather than using a shared prefix for all items.
Example:
collection = CollectionStandardModified(
owner_address=Address(OWNER_ADDRESS),
next_item_index=0,
content=CollectionModifiedOffchainContent(uri=URI), # URI example: `https://example.com/nft/collection.json`.
royalty_params=RoyaltyParams(
base=ROYALTY_BASE,
factor=ROYALTY_FACTOR,
address=Address(OWNER_ADDRESS),
),
)
"""
tx_hash = await wallet.transfer(
destination=collection.address,
amount=0.05,
state_init=collection.state_init,
)
print(f"Successfully deployed NFT Collection at address: {collection.address.to_str()}")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Mint NFT
from pytoniq_core import Address
from tonutils.client import ToncenterV3Client
from tonutils.nft.content import NFTOffchainContent
from tonutils.nft.contract.standard.collection import CollectionStandard
from tonutils.nft.contract.standard.nft import NFTStandard
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the owner of the NFT and the NFT collection contract
OWNER_ADDRESS = "UQ..."
COLLECTION_ADDRESS = "EQ..."
# Index of the NFT to be minted
NFT_INDEX = 0
# Suffix URI of the NFT metadata
SUFFIX_URI = f"{NFT_INDEX}.json"
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
nft = NFTStandard(
index=NFT_INDEX,
collection_address=Address(COLLECTION_ADDRESS),
)
body = CollectionStandard.build_mint_body(
index=NFT_INDEX,
owner_address=Address(OWNER_ADDRESS),
content=NFTOffchainContent(suffix_uri=SUFFIX_URI),
)
""" If you deployed the collection using the Modified variant, replace the above code with:
Replace `CollectionStandard` and `NFTStandard` with their modified versions,
and use `NFTModifiedOffchainContent` to specify the full `URI` for the NFT metadata.
Example:
nft = NFTStandardModified(
index=NFT_INDEX,
collection_address=Address(COLLECTION_ADDRESS),
)
body = CollectionStandardModified.build_mint_body(
index=NFT_INDEX,
owner_address=Address(OWNER_ADDRESS),
content=NFTModifiedOffchainContent(uri=URI), # URI example: `https://example.com/nft/0.json`.
)
"""
tx_hash = await wallet.transfer(
destination=COLLECTION_ADDRESS,
amount=0.02,
body=body,
)
print(f"Successfully minted NFT with index {NFT_INDEX}: {nft.address.to_str()}")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Batch Mint NFT
from pytoniq_core import Address
from tonutils.client import ToncenterV3Client
from tonutils.nft import CollectionStandard
from tonutils.nft.content import NFTOffchainContent
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the owner of the NFT and the NFT collection contract
OWNER_ADDRESS = "UQ..."
COLLECTION_ADDRESS = "EQ..."
# Starting index for minting items
FROM_INDEX = 0
# Number of items to mint
ITEMS_COUNT = 100
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
body = CollectionStandard.build_batch_mint_body(
data=[
(
NFTOffchainContent(suffix_uri=f"{index}.json"),
Address(OWNER_ADDRESS),
)
for index in range(FROM_INDEX, FROM_INDEX + ITEMS_COUNT)
],
from_index=FROM_INDEX,
)
""" If you deployed the collection using the Modified variant, replace the above code with:
Replace `CollectionStandard` with `CollectionStandardModified`,
and use `NFTModifiedOffchainContent` to specify the full `URI` for each NFT metadata.
Example:
body = CollectionStandardModified.build_batch_mint_body(
data=[
(
NFTModifiedOffchainContent(uri=URI), # URI example: `https://example.com/nft/{index}.json`.
Address(OWNER_ADDRESS),
)
for index in range(FROM_INDEX, FROM_INDEX + ITEMS_COUNT)
],
from_index=FROM_INDEX,
)
"""
tx_hash = await wallet.transfer(
destination=COLLECTION_ADDRESS,
amount=ITEMS_COUNT * 0.05,
body=body,
)
print(f"Successfully minted {ITEMS_COUNT} items in the collection at address: {COLLECTION_ADDRESS}.")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Soulbound Collection
Deploy Collection
from pytoniq_core import Address
from tonutils.client import ToncenterV3Client
from tonutils.nft import CollectionSoulbound
from tonutils.nft.content import CollectionOffchainContent
from tonutils.nft.royalty_params import RoyaltyParams
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the owner of the NFT and the NFT collection contract
OWNER_ADDRESS = "UQ..."
# URI of the collection's metadata
# https://github.com/ton-blockchain/TEPs/blob/master/text/0064-token-data-standard.md#nft-collection-metadata-example-offchain
URI = "https://example.com/nft/collection.json"
PREFIX_URI = "https://example.com/nft/"
# Royalty parameters: base and factor for calculating the royalty
ROYALTY_BASE = 1000
ROYALTY_FACTOR = 55 # 5.5% royalty
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
collection = CollectionSoulbound(
owner_address=Address(OWNER_ADDRESS),
next_item_index=0,
content=CollectionOffchainContent(uri=URI, prefix_uri=PREFIX_URI),
royalty_params=RoyaltyParams(
base=ROYALTY_BASE,
factor=ROYALTY_FACTOR,
address=Address(OWNER_ADDRESS),
),
)
""" If you want the option to withdraw extra balance in the future and store collection and NFT data on-chain,
you can use `CollectionSoulboundModified`. It removes the need for `prefix_uri` because NFTs minted in this
format include a direct link to the metadata for each item, rather than using a shared prefix for all items.
Example:
collection = CollectionSoulboundModified(
owner_address=Address(OWNER_ADDRESS),
next_item_index=0,
content=CollectionModifiedOffchainContent(uri=URI), # URI example: `https://example.com/nft/collection.json`.
royalty_params=RoyaltyParams(
base=ROYALTY_BASE,
factor=ROYALTY_FACTOR,
address=Address(OWNER_ADDRESS),
),
)
"""
tx_hash = await wallet.transfer(
destination=collection.address,
amount=0.05,
state_init=collection.state_init,
)
print(f"Successfully deployed NFT Collection at address: {collection.address.to_str()}")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Mint NFT
from pytoniq_core import Address
from tonutils.client import ToncenterV3Client
from tonutils.nft import CollectionSoulbound, NFTSoulbound
from tonutils.nft.content import NFTOffchainContent
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the owner of the NFT and the NFT collection contract
OWNER_ADDRESS = "UQ..."
COLLECTION_ADDRESS = "EQ..."
# Index of the NFT to be minted
NFT_INDEX = 0
# Suffix URI of the NFT metadata
SUFFIX_URI = f"{NFT_INDEX}.json"
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
nft = NFTSoulbound(
index=NFT_INDEX,
collection_address=Address(COLLECTION_ADDRESS),
)
body = CollectionSoulbound.build_mint_body(
index=NFT_INDEX,
owner_address=Address(OWNER_ADDRESS),
content=NFTOffchainContent(suffix_uri=SUFFIX_URI),
)
""" If you deployed the collection using the Modified variant, replace the above code with:
Replace `CollectionSoulbound` and `NFTSoulbound` with their modified versions,
and use `NFTModifiedOffchainContent` to specify the full `URI` for the NFT metadata.
Example:
nft = NFTSoulboundModified(
index=NFT_INDEX,
collection_address=Address(COLLECTION_ADDRESS),
)
body = CollectionSoulboundModified.build_mint_body(
index=NFT_INDEX,
owner_address=Address(OWNER_ADDRESS),
content=NFTModifiedOffchainContent(uri=URI), # URI example: `https://example.com/nft/0.json`.
)
"""
tx_hash = await wallet.transfer(
destination=COLLECTION_ADDRESS,
amount=0.02,
body=body,
)
print(f"Successfully minted NFT with index {NFT_INDEX}: {nft.address.to_str()}")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Batch Mint NFT
from pytoniq_core import Address
from tonutils.client import ToncenterV3Client
from tonutils.nft import CollectionSoulbound
from tonutils.nft.content import NFTOffchainContent
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the owner and editor of the NFT and the NFT collection contract
OWNER_ADDRESS = "UQ..."
EDITOR_ADDRESS = "UQ..."
COLLECTION_ADDRESS = "EQ..."
# Starting index for minting items
FROM_INDEX = 0
# Number of items to mint
ITEMS_COUNT = 100
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
body = CollectionSoulbound.build_batch_mint_body(
data=[
(
NFTOffchainContent(suffix_uri=f"{index}.json"),
Address(OWNER_ADDRESS),
Address(EDITOR_ADDRESS),
None, # revoked at
)
for index in range(FROM_INDEX, FROM_INDEX + ITEMS_COUNT)
],
from_index=FROM_INDEX,
)
""" If you deployed the collection using the Modified variant, replace the above code with:
Replace `CollectionSoulbound` with `CollectionSoulboundModified`,
and use `NFTModifiedOffchainContent` to specify the full `URI` for each NFT metadata.
Example:
body = CollectionSoulboundModified.build_batch_mint_body(
data=[
(
NFTModifiedOffchainContent(uri=URI), # URI example: `https://example.com/nft/{index}.json`.
Address(OWNER_ADDRESS),
Address(EDITOR_ADDRESS),
None, # revoked at
)
for index in range(FROM_INDEX, FROM_INDEX + ITEMS_COUNT)
],
from_index=FROM_INDEX,
)
"""
tx_hash = await wallet.transfer(
destination=COLLECTION_ADDRESS,
amount=ITEMS_COUNT * 0.05,
body=body,
)
print(f"Minted {ITEMS_COUNT} items in collection {COLLECTION_ADDRESS}")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Revoke NFT
from tonutils.client import ToncenterV3Client
from tonutils.nft import NFTSoulbound
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the NFT to be revoked
NFT_ADDRESS = "EQ..."
async def main() -> None:
# Initialize TonapiClient and Wallet
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
body = NFTSoulbound.build_revoke_body()
tx_hash = await wallet.transfer(
destination=NFT_ADDRESS,
amount=0.02,
body=body,
)
print(f"Successfully revoked NFT at address: {NFT_ADDRESS}.")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Destroy NFT
from tonutils.client import ToncenterV3Client
from tonutils.nft import NFTSoulbound
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the NFT to be destroyed
NFT_ADDRESS = "EQ..."
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
body = NFTSoulbound.build_destroy_body()
tx_hash = await wallet.transfer(
destination=NFT_ADDRESS,
amount=0.02,
body=body,
)
print(f"Successfully destroyed NFT at address: {NFT_ADDRESS}.")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Editable Collection
Deploy Collection
from pytoniq_core import Address
from tonutils.client import ToncenterV3Client
from tonutils.nft import CollectionEditable
from tonutils.nft.content import CollectionOffchainContent
from tonutils.nft.royalty_params import RoyaltyParams
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the owner of the NFT collection
OWNER_ADDRESS = "UQ..."
# URI of the collection's metadata
# https://github.com/ton-blockchain/TEPs/blob/master/text/0064-token-data-standard.md#nft-collection-metadata-example-offchain
URI = "https://example.com/nft/collection.json"
PREFIX_URI = "https://example.com/nft/"
# Royalty parameters: base and factor for calculating the royalty
ROYALTY_BASE = 1000
ROYALTY_FACTOR = 55 # 5.5% royalty
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
collection = CollectionEditable(
owner_address=Address(OWNER_ADDRESS),
next_item_index=0,
content=CollectionOffchainContent(uri=URI, prefix_uri=PREFIX_URI),
royalty_params=RoyaltyParams(
base=ROYALTY_BASE,
factor=ROYALTY_FACTOR,
address=Address(OWNER_ADDRESS),
),
)
""" If you want the option to withdraw extra balance in the future and store collection and NFT data on-chain,
you can use `CollectionEditableModified`. It removes the need for `prefix_uri` because NFTs minted in this
format include a direct link to the metadata for each item, rather than using a shared prefix for all items.
Example:
collection = CollectionEditableModified(
owner_address=Address(OWNER_ADDRESS),
next_item_index=0,
content=CollectionModifiedOffchainContent(uri=URI), # URI example: `https://example.com/nft/collection.json`.
royalty_params=RoyaltyParams(
base=ROYALTY_BASE,
factor=ROYALTY_FACTOR,
address=Address(OWNER_ADDRESS),
),
)
"""
tx_hash = await wallet.transfer(
destination=collection.address,
amount=0.05,
state_init=collection.state_init,
)
print(f"Successfully deployed NFT Collection at address: {collection.address.to_str()}")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Mint NFT
from pytoniq_core import Address
from tonutils.client import ToncenterV3Client
from tonutils.nft import CollectionEditable, NFTEditable
from tonutils.nft.content import NFTOffchainContent
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the owner of the NFT and the NFT collection contract
OWNER_ADDRESS = "UQ..."
COLLECTION_ADDRESS = "EQ..."
# Index of the NFT to be minted
NFT_INDEX = 0
# Suffix URI of the NFT metadata
SUFFIX_URI = f"{NFT_INDEX}.json"
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
nft = NFTEditable(
index=NFT_INDEX,
collection_address=Address(COLLECTION_ADDRESS),
)
body = CollectionEditable.build_mint_body(
index=NFT_INDEX,
owner_address=Address(OWNER_ADDRESS),
content=NFTOffchainContent(suffix_uri=SUFFIX_URI),
)
""" If you deployed the collection using the Modified variant, replace the above code with:
Replace `CollectionEditable` and `NFTEditable` with their modified versions,
and use `NFTModifiedOffchainContent` to specify the full `URI` for the NFT metadata.
Example:
nft = NFTEditableModified(
index=NFT_INDEX,
collection_address=Address(COLLECTION_ADDRESS),
)
body = CollectionEditableModified.build_mint_body(
index=NFT_INDEX,
owner_address=Address(OWNER_ADDRESS),
content=NFTModifiedOffchainContent(uri=URI), # URI example: `https://example.com/nft/0.json`.
)
"""
tx_hash = await wallet.transfer(
destination=COLLECTION_ADDRESS,
amount=0.02,
body=body,
)
print(f"Successfully minted NFT with index {NFT_INDEX}: {nft.address.to_str()}")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Batch Mint NFT
from pytoniq_core import Address
from tonutils.client import ToncenterV3Client
from tonutils.nft import CollectionEditable
from tonutils.nft.content import NFTOffchainContent
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the owner and editor of the NFT and the NFT collection contract
OWNER_ADDRESS = "UQ..."
EDITOR_ADDRESS = "UQ..."
COLLECTION_ADDRESS = "EQ..."
# Starting index for minting items
FROM_INDEX = 0
# Number of items to mint
ITEMS_COUNT = 100
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
body = CollectionEditable.build_batch_mint_body(
data=[
(
NFTOffchainContent(suffix_uri=f"{index}.json"),
Address(OWNER_ADDRESS),
Address(EDITOR_ADDRESS),
)
for index in range(FROM_INDEX, FROM_INDEX + ITEMS_COUNT)
],
from_index=FROM_INDEX,
)
""" If you deployed the collection using the Modified variant, replace the above code with:
Replace `CollectionEditable` with `CollectionEditableModified`,
and use `NFTModifiedOffchainContent` to specify the full `URI` for each NFT metadata.
Example:
body = CollectionEditableModified.build_batch_mint_body(
data=[
(
NFTModifiedOffchainContent(uri=URI), # URI example: `https://example.com/nft/{index}.json`.
Address(OWNER_ADDRESS),
Address(EDITOR_ADDRESS),
)
for index in range(FROM_INDEX, FROM_INDEX + ITEMS_COUNT)
],
from_index=FROM_INDEX,
)
"""
tx_hash = await wallet.transfer(
destination=COLLECTION_ADDRESS,
amount=ITEMS_COUNT * 0.05,
body=body,
)
print(f"Minted {ITEMS_COUNT} items in collection {COLLECTION_ADDRESS}")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Edit NFT Content
from tonutils.client import ToncenterV3Client
from tonutils.nft import NFTEditable
from tonutils.nft.content import NFTOffchainContent
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the NFT to be edited
NFT_ADDRESS = "EQ..."
# Suffix URI of the NFT metadata
SUFFIX_URI = f"new-content.json"
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
body = NFTEditable.build_edit_content_body(
content=NFTOffchainContent(suffix_uri=SUFFIX_URI),
)
tx_hash = await wallet.transfer(
destination=NFT_ADDRESS,
amount=0.02,
body=body,
)
print(f"Successfully edited the content of NFT at address: {NFT_ADDRESS}.")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Change NFT Editorship
from pytoniq_core import Address
from tonutils.client import ToncenterV3Client
from tonutils.nft import NFTEditable
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the NFT whose editorship will be changed
NFT_ADDRESS = "EQ..."
# Address of the new editor to whom the editorship will be transferred
NEW_EDITOR_ADDRESS = "UQ..."
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
body = NFTEditable.build_change_editorship_body(
editor_address=Address(NEW_EDITOR_ADDRESS),
)
tx_hash = await wallet.transfer(
destination=NFT_ADDRESS,
amount=0.02,
body=body,
)
print(f"Successfully changed the editorship of NFT {NFT_ADDRESS} to {NEW_EDITOR_ADDRESS}.")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Edit Collection Content
from pytoniq_core import Address
from tonutils.client import ToncenterV3Client
from tonutils.nft import CollectionEditable
from tonutils.nft.content import CollectionOffchainContent
from tonutils.nft.royalty_params import RoyaltyParams
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the royalty receiver and the NFT collection contract
ROYALTY_ADDRESS = "UQ..."
COLLECTION_ADDRESS = "EQ..."
# URI of the collection's metadata
# https://github.com/ton-blockchain/TEPs/blob/master/text/0064-token-data-standard.md#nft-collection-metadata-example-offchain
URI = "https://example.com/nft/collection.json"
PREFIX_URI = "https://example.com/nft/"
# Royalty parameters: base and factor for calculating the royalty
ROYALTY_BASE = 1000
ROYALTY_FACTOR = 60 # 6% royalty
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
body = CollectionEditable.build_edit_content_body(
content=CollectionOffchainContent(uri=URI, prefix_uri=PREFIX_URI),
royalty_params=RoyaltyParams(
base=ROYALTY_BASE,
factor=ROYALTY_FACTOR,
address=Address(ROYALTY_ADDRESS),
),
)
tx_hash = await wallet.transfer(
destination=COLLECTION_ADDRESS,
amount=0.02,
body=body,
)
print(f"Successfully edited the collection at address: {COLLECTION_ADDRESS}.")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Change Collection Owner
from pytoniq_core import Address
from tonutils.client import ToncenterV3Client
from tonutils.nft import CollectionEditable
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the new owner to whom the collection ownership will be transferred
NEW_OWNER_ADDRESS = "UQ..."
# Address of the NFT collection whose ownership will be changed
COLLECTION_ADDRESS = "EQ..."
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
body = CollectionEditable.build_change_owner_body(
owner_address=Address(NEW_OWNER_ADDRESS),
)
tx_hash = await wallet.transfer(
destination=COLLECTION_ADDRESS,
amount=0.02,
body=body,
)
print(f"Successfully changed the owner of collection {COLLECTION_ADDRESS} to {NEW_OWNER_ADDRESS}.")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Editable Onchain Collection
Deploy Collection
from pytoniq_core import Address
from tonutils.client import ToncenterV3Client
from tonutils.nft import CollectionEditableModified
from tonutils.nft.content import CollectionModifiedOnchainContent
from tonutils.nft.royalty_params import RoyaltyParams
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the owner of the NFT collection
OWNER_ADDRESS = "UQ..."
# Royalty parameters: base and factor for calculating the royalty
ROYALTY_BASE = 1000
ROYALTY_FACTOR = 55 # 5.5% royalty
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
collection = CollectionEditableModified(
owner_address=Address(OWNER_ADDRESS),
next_item_index=0,
content=CollectionModifiedOnchainContent(
name="Welcome to TON",
description="Each digital artwork represents a memorable token",
image_data=b'image data',
),
royalty_params=RoyaltyParams(
base=ROYALTY_BASE,
factor=ROYALTY_FACTOR,
address=Address(OWNER_ADDRESS),
),
)
tx_hash = await wallet.transfer(
destination=collection.address,
amount=0.05,
state_init=collection.state_init,
)
print(f"Successfully deployed NFT Collection at address: {collection.address.to_str()}")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Mint NFT
from pytoniq_core import Address
from tonutils.client import ToncenterV3Client
from tonutils.nft import CollectionEditableModified, NFTEditableModified
from tonutils.nft.content import NFTModifiedOnchainContent
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the owner of the NFT and the NFT collection contract
OWNER_ADDRESS = "UQ..."
COLLECTION_ADDRESS = "EQ..."
# Index of the NFT to be minted
NFT_INDEX = 0
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
nft = NFTEditableModified(
index=NFT_INDEX,
collection_address=Address(COLLECTION_ADDRESS),
)
body = CollectionEditableModified.build_mint_body(
index=NFT_INDEX,
owner_address=Address(OWNER_ADDRESS),
content=NFTModifiedOnchainContent(
name="TON Collectible #0",
description="Memorable token for completing an onboarding quest about the TON ecosystem",
image_data=b'image data',
),
)
tx_hash = await wallet.transfer(
destination=COLLECTION_ADDRESS,
amount=0.02,
body=body,
)
print(f"Successfully minted NFT with index {NFT_INDEX}: {nft.address.to_str()}")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Return Collection Balance
from tonutils.client import ToncenterV3Client
from tonutils.nft import CollectionEditableModified
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the NFT collection contract
COLLECTION_ADDRESS = "EQ..."
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
body = CollectionEditableModified.build_return_balance()
tx_hash = await wallet.transfer(
destination=COLLECTION_ADDRESS,
amount=0.02,
body=body,
)
print(f"Successfully returned the balance of collection {COLLECTION_ADDRESS}.")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Listing on Getgems.io
List NFT for Sale
from pytoniq_core import Address
from tonutils.client import ToncenterV3Client
from tonutils.nft import Collection, NFT
from tonutils.nft.marketplace.getgems.addresses import *
from tonutils.nft.marketplace.getgems.contract.salev3r3 import SaleV3R3
from tonutils.utils import to_nano
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the NFT to be listed for sale
NFT_ADDRESS = "EQ.."
# Sale price for the NFT in TON
PRICE = 1
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
nft_data = await NFT.get_nft_data(client, NFT_ADDRESS)
royalty_params = await Collection.get_royalty_params(client, nft_data.collection_address)
price = to_nano(PRICE)
royalty_fee = int(price * (royalty_params.base / royalty_params.factor))
marketplace_fee = int(price * 0.05)
sale = SaleV3R3(
nft_address=NFT_ADDRESS,
owner_address=wallet.address,
marketplace_address=TESTNET_GETGEMS_ADDRESS if IS_TESTNET else GETGEMS_ADDRESS,
marketplace_fee_address=TESTNET_GETGEMS_FEE_ADDRESS if IS_TESTNET else GETGEMS_FEE_ADDRESS,
royalty_address=royalty_params.address,
marketplace_fee=marketplace_fee,
royalty_fee=royalty_fee,
price=price,
)
body = sale.build_transfer_nft_body(
destination=Address(TESTNET_GETGEMS_DEPLOYER_ADDRESS if IS_TESTNET else GETGEMS_DEPLOYER_ADDRESS),
owner_address=wallet.address,
state_init=sale.state_init,
)
tx_hash = await wallet.transfer(
destination=NFT_ADDRESS,
amount=0.25,
body=body,
)
# Print the result of the operation
print(f"NFT {NFT_ADDRESS} successfully put on sale at price {PRICE} TON.")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Change NFT Price
from tonutils.client import ToncenterV3Client
from tonutils.nft import Collection, NFT
from tonutils.nft.marketplace.getgems.contract.salev3r3 import SaleV3R3
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the NFT and sale contract
NFT_ADDRESS = "EQ..."
SALE_ADDRESS = "EQ..."
# New sale price for the NFT in TON
PRICE = 1
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
nft_data = await NFT.get_nft_data(client, NFT_ADDRESS)
royalty_params = await Collection.get_royalty_params(client, nft_data.collection_address)
price = int(PRICE * 1e9)
royalty_fee = int(price * (royalty_params.base / royalty_params.factor))
marketplace_fee = int(price * 0.05)
body = SaleV3R3.build_change_price_body(
marketplace_fee=marketplace_fee,
royalty_fee=royalty_fee,
price=price,
)
tx_hash = await wallet.transfer(
destination=SALE_ADDRESS,
amount=0.005,
body=body,
)
print(f"Successfully updated the price for NFT sale.")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Cancel NFT Sale
from tonutils.client import ToncenterV3Client
from tonutils.nft.marketplace.getgems.contract.salev3r3 import SaleV3R3
from tonutils.wallet import WalletV4R2
# Set to True for test network, False for main network
IS_TESTNET = True
# Mnemonic phrase
MNEMONIC = "word1 word2 word3 ..."
# Address of the sale contract
SALE_ADDRESS = "EQ..."
async def main() -> None:
client = ToncenterV3Client(is_testnet=IS_TESTNET, rps=1, max_retries=1)
wallet, _, _, _ = WalletV4R2.from_mnemonic(client, MNEMONIC)
body = SaleV3R3.build_cancel_sale_body()
tx_hash = await wallet.transfer(
destination=SALE_ADDRESS,
amount=0.2,
body=body,
)
print("Sale has been successfully canceled.")
print(f"Transaction hash: {tx_hash}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())