diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a3c78672..b8f5f57d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1. - Rename test files across the repository to ensure they consistently end with _test.py (#1055) - Cleaned up `token_airdrop_claim_signature_required` example for pylint compliance (no functional changes). (#1080) - Rename the file 'test_token_fee_schedule_update_transaction_e2e.py' to make it ends with _test.py as all other test files.(#1117) +- Format token examples with Black for consistent code style and improved readability (#1119) ### Fixed diff --git a/examples/tokens/account_allowance_approve_transaction.py b/examples/tokens/account_allowance_approve_transaction.py index c3e0b74d2..fb83f5f9e 100644 --- a/examples/tokens/account_allowance_approve_transaction.py +++ b/examples/tokens/account_allowance_approve_transaction.py @@ -17,14 +17,17 @@ from hiero_sdk_python.account.account_create_transaction import AccountCreateTransaction from hiero_sdk_python.response_code import ResponseCode from hiero_sdk_python.tokens.supply_type import SupplyType -from hiero_sdk_python.tokens.token_associate_transaction import TokenAssociateTransaction +from hiero_sdk_python.tokens.token_associate_transaction import ( + TokenAssociateTransaction, +) from hiero_sdk_python.tokens.token_create_transaction import TokenCreateTransaction from hiero_sdk_python.tokens.token_type import TokenType from hiero_sdk_python.transaction.transfer_transaction import TransferTransaction load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -54,7 +57,9 @@ def create_account(client): ) if account_receipt.status != ResponseCode.SUCCESS: - print(f"Account creation failed with status: {ResponseCode(account_receipt.status).name}") + print( + f"Account creation failed with status: {ResponseCode(account_receipt.status).name}" + ) sys.exit(1) account_account_id = account_receipt.account_id @@ -99,13 +104,17 @@ def associate_token_with_account(client, account_id, account_private_key, token_ ) if receipt.status != ResponseCode.SUCCESS: - print(f"Token association failed with status: {ResponseCode(receipt.status).name}") + print( + f"Token association failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) print(f"Token {token_id} associated with account {account_id}") -def approve_token_allowance(client, token_id, owner_account_id, spender_account_id, amount): +def approve_token_allowance( + client, token_id, owner_account_id, spender_account_id, amount +): """Approve token allowance for spender""" receipt = ( AccountAllowanceApproveTransaction() @@ -114,7 +123,9 @@ def approve_token_allowance(client, token_id, owner_account_id, spender_account_ ) if receipt.status != ResponseCode.SUCCESS: - print(f"Token allowance approval failed with status: {ResponseCode(receipt.status).name}") + print( + f"Token allowance approval failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) print(f"Token allowance of {amount} approved for spender {spender_account_id}") @@ -130,7 +141,9 @@ def delete_token_allowance(client, token_id, owner_account_id, spender_account_i ) if receipt.status != ResponseCode.SUCCESS: - print(f"Token allowance deletion failed with status: {ResponseCode(receipt.status).name}") + print( + f"Token allowance deletion failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) print(f"Token allowance deleted for spender {spender_account_id}") @@ -138,12 +151,19 @@ def delete_token_allowance(client, token_id, owner_account_id, spender_account_i def transfer_token_without_allowance( - client, spender_account_id, spender_private_key, amount, receiver_account_id, token_id + client, + spender_account_id, + spender_private_key, + amount, + receiver_account_id, + token_id, ): """Transfer tokens without allowance""" print("Trying to transfer tokens without allowance...") owner_account_id = client.operator_account_id - client.set_operator(spender_account_id, spender_private_key) # Set operator to spender + client.set_operator( + spender_account_id, spender_private_key + ) # Set operator to spender receipt = ( TransferTransaction() @@ -158,7 +178,9 @@ def transfer_token_without_allowance( f"status but got: {ResponseCode(receipt.status).name}" ) - print(f"Token transfer successfully failed with {ResponseCode(receipt.status).name} status") + print( + f"Token transfer successfully failed with {ResponseCode(receipt.status).name} status" + ) def token_allowance(): @@ -198,7 +220,9 @@ def token_allowance(): receipt = ( TransferTransaction() .set_transaction_id(TransactionId.generate(spender_id)) - .add_approved_token_transfer(token_id, client.operator_account_id, -allowance_amount) + .add_approved_token_transfer( + token_id, client.operator_account_id, -allowance_amount + ) .add_approved_token_transfer(token_id, receiver_id, allowance_amount) .freeze_with(client) .sign(spender_private_key) diff --git a/examples/tokens/custom_fee_fixed.py b/examples/tokens/custom_fee_fixed.py index c55830cbf..0576c6d1b 100644 --- a/examples/tokens/custom_fee_fixed.py +++ b/examples/tokens/custom_fee_fixed.py @@ -1,12 +1,14 @@ """ -Run with: +Run with: uv run examples/tokens/custom_fixed_fee.py python examples/tokens/custom_fixed_fee.py """ + from hiero_sdk_python.tokens.custom_fixed_fee import CustomFixedFee from hiero_sdk_python.account.account_id import AccountId from hiero_sdk_python.tokens.token_id import TokenId + def custom_fixed_fee(): fixed_fee = CustomFixedFee( amount=100, @@ -19,9 +21,9 @@ def custom_fixed_fee(): # Convert to protobuf fixed_fee_proto = fixed_fee._to_proto() - + print("Fixed Fee Protobuf:", fixed_fee_proto) - - + + if __name__ == "__main__": - custom_fixed_fee() \ No newline at end of file + custom_fixed_fee() diff --git a/examples/tokens/custom_fee_fractional.py b/examples/tokens/custom_fee_fractional.py index 7154773e9..3ceb64d6c 100644 --- a/examples/tokens/custom_fee_fractional.py +++ b/examples/tokens/custom_fee_fractional.py @@ -1,5 +1,5 @@ """ -Run with: +Run with: uv run examples/tokens/custom_fractional_fee.py python examples/tokens/custom_fractional_fee.py """ @@ -8,7 +8,10 @@ import sys from dotenv import load_dotenv -from hiero_sdk_python.tokens.token_create_transaction import TokenCreateTransaction, TokenParams +from hiero_sdk_python.tokens.token_create_transaction import ( + TokenCreateTransaction, + TokenParams, +) from hiero_sdk_python.tokens.custom_fractional_fee import CustomFractionalFee from hiero_sdk_python.tokens.fee_assessment_method import FeeAssessmentMethod from hiero_sdk_python.query.token_info_query import TokenInfoQuery @@ -23,6 +26,7 @@ load_dotenv() + def setup_client(): network_name = os.getenv("NETWORK", "testnet") @@ -36,17 +40,18 @@ def setup_client(): print(f"Connecting to Hedera {network_name} network!") client = Client(network) - operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", '')) - operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") except Exception as e: - raise ConnectionError(f'Error initializing client: {e}') from e + raise ConnectionError(f"Error initializing client: {e}") from e print(f"✅ Connected to Hedera {network_name} network as operator: {operator_id}") return client, operator_id, operator_key + def build_fractional_fee(operator_account: AccountId) -> CustomFractionalFee: """Creates a CustomFractionalFee instance.""" return CustomFractionalFee( @@ -58,7 +63,8 @@ def build_fractional_fee(operator_account: AccountId) -> CustomFractionalFee: fee_collector_account_id=operator_account, all_collectors_are_exempt=True, ) - + + def create_token_with_fee_key(client, operator_id, fractional_fee: CustomFractionalFee): """Create a fungible token with a fee_schedule_key.""" print("Creating fungible token with fee_schedule_key...") @@ -74,19 +80,20 @@ def create_token_with_fee_key(client, operator_id, fractional_fee: CustomFractio supply_type=SupplyType.INFINITE, custom_fees=fractional_fee, ) - + tx = TokenCreateTransaction(token_params=token_params) tx.freeze_with(client) receipt = tx.execute(client) - + if receipt.status != ResponseCode.SUCCESS: print(f"Token creation failed: {ResponseCode(receipt.status).name}") sys.exit(1) - + token_id = receipt.token_id print(f"Token created with ID: {token_id}") return token_id + def print_fractional_fees(token_info, fractional_fee): """Print all CustomFractionalFee objects from a TokenInfo.""" if not token_info.custom_fees: @@ -96,22 +103,25 @@ def print_fractional_fees(token_info, fractional_fee): print("\n--- Custom Fractional Fee ---") print(fractional_fee) + def query_and_validate_fractional_fee(client: Client, token_id): """Fetch token info from Hedera and print the custom fractional fees.""" print("\nQuerying token info to validate fractional fee...") token_info = TokenInfoQuery(token_id=token_id).execute(client) return token_info + def main(): client, operator_id, _ = setup_client() # Build fractional fee fractional_fee = build_fractional_fee(operator_id) token_id = create_token_with_fee_key(client, operator_id, fractional_fee) - + # Query and validate fractional fee token_info = query_and_validate_fractional_fee(client, token_id) print_fractional_fees(token_info, fractional_fee) print("✅ Example completed successfully.") - + + if __name__ == "__main__": main() diff --git a/examples/tokens/custom_fee_royalty.py b/examples/tokens/custom_fee_royalty.py index 7f1ec3173..0c0c8c2b0 100644 --- a/examples/tokens/custom_fee_royalty.py +++ b/examples/tokens/custom_fee_royalty.py @@ -1,13 +1,15 @@ """ -Run with: +Run with: uv run examples/tokens/custom_royalty_fee.py python examples/tokens/custom_royalty_fee.py """ + from hiero_sdk_python.tokens.custom_fixed_fee import CustomFixedFee from hiero_sdk_python.tokens.custom_royalty_fee import CustomRoyaltyFee from hiero_sdk_python.account.account_id import AccountId from hiero_sdk_python.tokens.token_id import TokenId + def custom_royalty_fee(): fallback_fee = CustomFixedFee( amount=50, @@ -27,5 +29,6 @@ def custom_royalty_fee(): print("Royalty Fee Protobuf:", royalty_fee_proto) + if __name__ == "__main__": - custom_royalty_fee() \ No newline at end of file + custom_royalty_fee() diff --git a/examples/tokens/token_airdrop_claim_auto.py b/examples/tokens/token_airdrop_claim_auto.py index 2246ba3fb..562d93c2d 100644 --- a/examples/tokens/token_airdrop_claim_auto.py +++ b/examples/tokens/token_airdrop_claim_auto.py @@ -20,6 +20,7 @@ uv run examples/tokens/token_airdrop_claim_auto.py python examples/tokens/token_airdrop_claim_auto.py """ + # pylint: disable=import-error, # pylint: disable=too-many-arguments, # pylint: disable=too-many-positional-arguments, @@ -30,7 +31,8 @@ import sys from typing import Iterable from dotenv import load_dotenv -from hiero_sdk_python import (Client, +from hiero_sdk_python import ( + Client, Network, AccountId, PrivateKey, @@ -45,11 +47,12 @@ ResponseCode, Hbar, TokenId, - TokenNftInfoQuery + TokenNftInfoQuery, ) load_dotenv() + def setup_client(): """Set up and return a Hedera client using environment configuration.""" network_name = os.getenv("NETWORK", "testnet") @@ -64,25 +67,21 @@ def setup_client(): print(f"Connecting to Hedera {network_name} network!") client = Client(network) - operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", '')) - operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") except Exception as e: - raise ConnectionError( - f"Error initializing client: {e}" - ) from e + raise ConnectionError(f"Error initializing client: {e}") from e print(f"✅ Connected to Hedera {network_name} network as operator: {operator_id}") return client, operator_id, operator_key -def create_receiver( - client: Client, - signature_required: bool =False, - max_auto_assoc: int =10 - ): +def create_receiver( + client: Client, signature_required: bool = False, max_auto_assoc: int = 10 +): """Create and return a configured Hedera client.""" receiver_key = PrivateKey.generate() receiver_public_key = receiver_key.public_key() @@ -113,14 +112,14 @@ def create_receiver( def create_fungible_token( - client: Client, - operator_id: AccountId, - operator_key: PrivateKey, - name: str ="My Fungible Token", - symbol: str ="MFT", - initial_supply: int =50, - max_supply: int = 1000, - ): + client: Client, + operator_id: AccountId, + operator_key: PrivateKey, + name: str = "My Fungible Token", + symbol: str = "MFT", + initial_supply: int = 50, + max_supply: int = 1000, +): """Create and return a fungible token on the Hedera network.""" try: receipt = ( @@ -148,13 +147,13 @@ def create_fungible_token( def create_nft_token( - client: Client, - operator_id: AccountId, - operator_key: PrivateKey, - name: str ="My NFT Token", - symbol: str ="MNT", - max_supply: int = 100 - ): + client: Client, + operator_id: AccountId, + operator_key: PrivateKey, + name: str = "My NFT Token", + symbol: str = "MNT", + max_supply: int = 100, +): """Create and return a non-fungible (NFT) token on the Hedera network.""" try: receipt = ( @@ -183,10 +182,10 @@ def create_nft_token( def mint_nft_token( - client: Client, - operator_key: PrivateKey, - nft_token_id: TokenId, - ): + client: Client, + operator_key: PrivateKey, + nft_token_id: TokenId, +): """Mint a new NFT for the given NFT token and return its serial number.""" try: receipt = ( @@ -208,33 +207,33 @@ def mint_nft_token( return nft_id except Exception as e: raise RuntimeError(f"❌ Error minting NFT token: {e}") from e + + def log_balances( client: Client, operator_id: AccountId, receiver_id: AccountId, fungible_ids: Iterable[TokenId], nft_ids: Iterable[NftId], - prefix: str = "" + prefix: str = "", ): """Fetch and log token balances for operator and receiver accounts.""" print(f"\n===== {prefix} Balances =====") try: operator_balance = ( - CryptoGetAccountBalanceQuery() - .set_account_id(operator_id) - .execute(client) + CryptoGetAccountBalanceQuery().set_account_id(operator_id).execute(client) ) receiver_balance = ( - CryptoGetAccountBalanceQuery() - .set_account_id(receiver_id) - .execute(client) + CryptoGetAccountBalanceQuery().set_account_id(receiver_id).execute(client) ) - except Exception as e: # pylint: disable=broad-exception-caught + except Exception as e: # pylint: disable=broad-exception-caught print(f"❌ Failed to fetch balances: {e}") return - def log_fungible(_account_id: AccountId, balances: dict, token_ids: Iterable[TokenId]): + def log_fungible( + _account_id: AccountId, balances: dict, token_ids: Iterable[TokenId] + ): print(" Fungible tokens:") for token_id in token_ids: print(f" {token_id}: {balances.get(token_id, 0)}") @@ -265,15 +264,16 @@ def log_nfts(account_id: AccountId, nft_ids: Iterable[NftId]): print("=============================================\n") + def perform_airdrop( - client: Client, - operator_id: AccountId, - operator_key: PrivateKey, - receiver_id: AccountId, - fungible_ids: Iterable[TokenId], - nft_ids: Iterable[NftId], - ft_amount: int = 100, - ): + client: Client, + operator_id: AccountId, + operator_key: PrivateKey, + receiver_id: AccountId, + fungible_ids: Iterable[TokenId], + nft_ids: Iterable[NftId], + ft_amount: int = 100, +): """Perform a token airdrop from operator to receiver.""" try: tx = TokenAirdropTransaction() @@ -288,8 +288,6 @@ def perform_airdrop( ) print(message) - - for nft_id in nft_ids: tx.add_nft_transfer(nft_id, operator_id, receiver_id) print(f"🎨 Transferring NFT {nft_id} from {operator_id} → {receiver_id}") @@ -299,14 +297,19 @@ def perform_airdrop( if receipt.status != ResponseCode.SUCCESS: status_message = ResponseCode(receipt.status).name - raise RuntimeError(f"Airdrop transaction failed with status: {status_message}") + raise RuntimeError( + f"Airdrop transaction failed with status: {status_message}" + ) - print(f"✅ Airdrop executed successfully! Transaction ID: {receipt.transaction_id}") + print( + f"✅ Airdrop executed successfully! Transaction ID: {receipt.transaction_id}" + ) except Exception as e: print(f"❌ Airdrop failed: {e}") raise RuntimeError("Airdrop execution failed") from e + def main(): """Run the token airdrop auto-claim example workflow.""" # Set up client and return client, operator_id, operator_key @@ -314,63 +317,74 @@ def main(): # Create and return a fungible token to airdrop print("Create 50 fungible tokens and 1 NFT to airdrop") - fungible_id = create_fungible_token(client, operator_id, - operator_key, - name="My Fungible Token", - symbol="123", initial_supply=50, - max_supply = 2000 - ) + fungible_id = create_fungible_token( + client, + operator_id, + operator_key, + name="My Fungible Token", + symbol="123", + initial_supply=50, + max_supply=2000, + ) # Create and return an nft token to airdrop - nft_token_id = create_nft_token(client, operator_id, - operator_key, name="My NFT Token", - symbol = "MNFT", max_supply=1000 - ) + nft_token_id = create_nft_token( + client, + operator_id, + operator_key, + name="My NFT Token", + symbol="MNFT", + max_supply=1000, + ) # Mint and return an nft to airdrop nft_serial = mint_nft_token(client, operator_key, nft_token_id) # Create a receiver that will test no signature is required to claim the auto-airdrop - # Ensure false for signature required - # Assume 10 max association slots + # Ensure false for signature required + # Assume 10 max association slots # Return the receiver id and receiver private key print("Creating the account that will automatically receive the airdropped tokens") receiver_id, receiver_key = create_receiver(client, False, 10) # Check pre-airdrop balances print("\n🔍 Verifying sender has tokens to airdrop and receiver neither:") - log_balances(client, operator_id, receiver_id, [fungible_id], [nft_serial], - prefix="Before airdrop") + log_balances( + client, + operator_id, + receiver_id, + [fungible_id], + [nft_serial], + prefix="Before airdrop", + ) # Initiate airdrop of 20 fungible tokens and 1 nft token id - perform_airdrop(client, - operator_id, - operator_key, - receiver_id, - [fungible_id], - [nft_serial], - 20 - ) - - print("\n🔍 Verifying receiver has received airdrop contents automatically" + perform_airdrop( + client, operator_id, operator_key, receiver_id, [fungible_id], [nft_serial], 20 + ) + + print( + "\n🔍 Verifying receiver has received airdrop contents automatically" "and sender has sent:" ) log_balances( - client, - operator_id, - receiver_id, - [fungible_id], - [nft_serial], - prefix="After airdrop", + client, + operator_id, + receiver_id, + [fungible_id], + [nft_serial], + prefix="After airdrop", ) - - print("✅ Auto-association successful: Receiver accepted airdropped tokens " + print( + "✅ Auto-association successful: Receiver accepted airdropped tokens " "without pre-association." ) - print("✅ Airdrop successful: Receiver accepted new fungible tokens " + print( + "✅ Airdrop successful: Receiver accepted new fungible tokens " "without pre-association." ) + if __name__ == "__main__": main() diff --git a/examples/tokens/token_airdrop_claim_signature_required.py b/examples/tokens/token_airdrop_claim_signature_required.py index 24785dc89..2abcb7ca6 100644 --- a/examples/tokens/token_airdrop_claim_signature_required.py +++ b/examples/tokens/token_airdrop_claim_signature_required.py @@ -52,11 +52,12 @@ PendingAirdropId, TransactionRecordQuery, TransactionRecord, - TransactionId + TransactionId, ) load_dotenv() + def setup_client(): """ Sets up the Hedera client using environment variables. @@ -73,22 +74,21 @@ def setup_client(): print(f"Connecting to Hedera {network_name} network!") client = Client(network) - operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", '')) - operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") except Exception as exc: - raise ConnectionError(f'Error initializing client: {exc}') from exc + raise ConnectionError(f"Error initializing client: {exc}") from exc print(f"✅ Connected to Hedera {network_name} network as operator: {operator_id}") return client, operator_id, operator_key + def create_receiver( - client: Client, - signature_required: bool =True, - max_auto_assoc: int = 0 - ): + client: Client, signature_required: bool = True, max_auto_assoc: int = 0 +): """ Creates a receiver account with specific configurations. """ @@ -119,15 +119,16 @@ def create_receiver( except Exception as exc: raise RuntimeError(f"❌ Error creating receiver account: {exc}") from exc + def create_fungible_token( - client: Client, - operator_id: AccountId, - operator_key: PrivateKey, - name: str ="My Fungible Token", - symbol: str ="MFT", - initial_supply: int =50, - max_supply: int = 1000, - ): + client: Client, + operator_id: AccountId, + operator_key: PrivateKey, + name: str = "My Fungible Token", + symbol: str = "MFT", + initial_supply: int = 50, + max_supply: int = 1000, +): """ Creates a fungible token. """ @@ -155,14 +156,15 @@ def create_fungible_token( except Exception as exc: raise RuntimeError(f"❌ Error creating fungible token: {exc}") from exc + def create_nft_token( - client: Client, - operator_id: AccountId, - operator_key: PrivateKey, - name: str ="My NFT Token", - symbol: str ="MNT", - max_supply: int = 100 - ): + client: Client, + operator_id: AccountId, + operator_key: PrivateKey, + name: str = "My NFT Token", + symbol: str = "MNT", + max_supply: int = 100, +): """ Creates an NFT token. """ @@ -191,11 +193,12 @@ def create_nft_token( except Exception as exc: raise RuntimeError(f"❌ Error creating NFT token: {exc}") from exc + def mint_nft_token( - client: Client, - operator_key: PrivateKey, - nft_token_id: TokenId, - ): + client: Client, + operator_key: PrivateKey, + nft_token_id: TokenId, +): """ Mints an NFT token. """ @@ -221,22 +224,23 @@ def mint_nft_token( except Exception as exc: raise RuntimeError(f"❌ Error minting NFT token: {exc}") from exc + def get_token_association_status( - client: Client, - receiver_id: AccountId, - token_ids: List[TokenId] - ) -> Dict[TokenId, bool]: + client: Client, receiver_id: AccountId, token_ids: List[TokenId] +) -> Dict[TokenId, bool]: """ Checks if the receiver account is associated with the given tokens. """ try: # Query the receiver's balance, which includes token associations - balance = CryptoGetAccountBalanceQuery()\ - .set_account_id(receiver_id)\ - .execute(client) + balance = ( + CryptoGetAccountBalanceQuery().set_account_id(receiver_id).execute(client) + ) associated_tokens = set(balance.token_balances.keys()) - association_status = {token_id: token_id in associated_tokens for token_id in token_ids} + association_status = { + token_id: token_id in associated_tokens for token_id in token_ids + } print(f"✅ Association status for account {receiver_id}:") for tid, associated in association_status.items(): @@ -247,6 +251,8 @@ def get_token_association_status( except Exception as exc: print(f"❌ Failed to fetch token associations for account {receiver_id}: {exc}") return {token_id: False for token_id in token_ids} + + def log_fungible_balances(balances: dict, token_ids: Iterable[TokenId]): """ Logs the balances of fungible tokens. @@ -257,7 +263,6 @@ def log_fungible_balances(balances: dict, token_ids: Iterable[TokenId]): print(f" {token_id}: {amount}") - def log_nft_balances(client: Client, account_id: AccountId, nft_ids: Iterable[NftId]): """ Logs the ownership of NFTs. @@ -285,7 +290,7 @@ def log_balances( receiver_id: AccountId, fungible_ids: Iterable[TokenId], nft_ids: Iterable[NftId], - prefix: str = "" + prefix: str = "", ): """ Logs the balances of both the operator and receiver accounts. @@ -293,10 +298,12 @@ def log_balances( print(f"\n===== {prefix} Balances =====") try: - operator_balance = CryptoGetAccountBalanceQuery().set_account_id( - operator_id).execute(client) - receiver_balance = CryptoGetAccountBalanceQuery().set_account_id( - receiver_id).execute(client) + operator_balance = ( + CryptoGetAccountBalanceQuery().set_account_id(operator_id).execute(client) + ) + receiver_balance = ( + CryptoGetAccountBalanceQuery().set_account_id(receiver_id).execute(client) + ) except Exception as exc: print(f"❌ Failed to fetch balances: {exc}") return @@ -320,15 +327,16 @@ def log_balances( print("=============================================\n") + def perform_airdrop( - client: Client, - operator_id: AccountId, - operator_key: PrivateKey, - receiver_id: AccountId, - fungible_ids: Iterable[TokenId], - nft_ids: Iterable[NftId], - ft_amount: int = 100 - ): + client: Client, + operator_id: AccountId, + operator_key: PrivateKey, + receiver_id: AccountId, + fungible_ids: Iterable[TokenId], + nft_ids: Iterable[NftId], + ft_amount: int = 100, +): """ Performs an airdrop of fungible and NFT tokens. """ @@ -351,7 +359,9 @@ def perform_airdrop( if receipt.status != ResponseCode.SUCCESS: status_message = ResponseCode(receipt.status).name - raise RuntimeError(f"Airdrop transaction failed with status: {status_message}") + raise RuntimeError( + f"Airdrop transaction failed with status: {status_message}" + ) transaction_id = receipt.transaction_id print(f"✅ Airdrop executed successfully! Transaction ID: {transaction_id}") @@ -361,10 +371,10 @@ def perform_airdrop( print(f"❌ Airdrop failed: {exc}") raise RuntimeError("Airdrop execution failed") from exc + def fetch_pending_airdrops( - client: Client, - transaction_id: TransactionId - ) -> List[PendingAirdropId]: + client: Client, transaction_id: TransactionId +) -> List[PendingAirdropId]: """ Retrieve all pending airdrop IDs generated by a specific transaction. @@ -373,7 +383,9 @@ def fetch_pending_airdrops( `new_pending_airdrops` field. """ try: - record: TransactionRecord = TransactionRecordQuery(transaction_id).execute(client) + record: TransactionRecord = TransactionRecordQuery(transaction_id).execute( + client + ) pending_airdrops = record.new_pending_airdrops # List of PendingAirdropRecord pending_airdrop_ids = [p.pending_airdrop_id for p in pending_airdrops] @@ -385,14 +397,15 @@ def fetch_pending_airdrops( return pending_airdrop_ids except Exception as exc: - print(f"❌ Failed to fetch pending airdrops for transaction {transaction_id}: {exc}") + print( + f"❌ Failed to fetch pending airdrops for transaction {transaction_id}: {exc}" + ) return [] + def claim_airdrop( - client: Client, - receiver_key: PrivateKey, - pending_airdrops: List[PendingAirdropId] - ): + client: Client, receiver_key: PrivateKey, pending_airdrops: List[PendingAirdropId] +): """ Claims one or more pending airdrops on behalf of the receiver. @@ -405,7 +418,7 @@ def claim_airdrop( TokenClaimAirdropTransaction() .add_pending_airdrop_ids(pending_airdrops) .freeze_with(client) - .sign(receiver_key) # Signing with receiver is required + .sign(receiver_key) # Signing with receiver is required ) print(f"{transaction}") @@ -420,6 +433,7 @@ def claim_airdrop( except Exception as exc: raise RuntimeError(f"❌ Error claiming airdrop: {exc}") from exc + def main(): """ Main function to execute the airdrop claim example. @@ -436,7 +450,7 @@ def main(): name="My Fungible Token", symbol="123", initial_supply=50, - max_supply = 2000 + max_supply=2000, ) # Create and return an nft token to airdrop @@ -445,35 +459,25 @@ def main(): operator_id, operator_key, name="My NFT Token", - symbol = "MNFT", - max_supply=1000 + symbol="MNFT", + max_supply=1000, ) # Mint and return an nft to airdrop - nft_serial = mint_nft_token( - client, - operator_key, - nft_token_id - ) + nft_serial = mint_nft_token(client, operator_key, nft_token_id) # Create a receiver that will require signature to claim the airdrop - # Ensure true for signature required (for the receiver) - # 0 max association slots + # Ensure true for signature required (for the receiver) + # 0 max association slots # Return the receiver id and receiver private key print("Creating the account that will receive the airdropped tokens on signing") - receiver_id, receiver_key = create_receiver( - client, - True, - 0 - ) + receiver_id, receiver_key = create_receiver(client, True, 0) # Verify this receiver does NOT have any of the fungible or NFT tokens associated # Claim airdrop will work regardless token_ids_to_check = [fungible_id, nft_token_id] association_status = get_token_association_status( - client, - receiver_id, - token_ids_to_check + client, receiver_id, token_ids_to_check ) print(association_status) @@ -485,23 +489,24 @@ def main(): receiver_id, [fungible_id], [nft_serial], - prefix="Before airdrop" + prefix="Before airdrop", ) # Initiate airdrop of 20 fungible tokens and 1 nft token id transaction_id = perform_airdrop( + client, operator_id, operator_key, receiver_id, [fungible_id], [nft_serial], 20 + ) + + print("\n🔍 Verifying no balance change as airdrop is not yet claimed:") + log_balances( client, operator_id, - operator_key, receiver_id, [fungible_id], [nft_serial], - 20 + prefix="After airdrop", ) - print("\n🔍 Verifying no balance change as airdrop is not yet claimed:") - log_balances(client,operator_id,receiver_id,[fungible_id],[nft_serial],prefix="After airdrop") - # Get a list of pending airdrops pending_airdrop_ids = fetch_pending_airdrops(client, transaction_id) print(pending_airdrop_ids) @@ -517,12 +522,22 @@ def main(): # Check airdrop has resulted in transfers print("\n🔍 Verifying balances have now changed after claim:") - log_balances(client,operator_id,receiver_id,[fungible_id],[nft_serial],prefix="After claim") + log_balances( + client, + operator_id, + receiver_id, + [fungible_id], + [nft_serial], + prefix="After claim", + ) # Check Hedera network has associated these tokens behind the scenes token_ids_to_check = [fungible_id, nft_token_id] - association_status = get_token_association_status(client,receiver_id,token_ids_to_check) + association_status = get_token_association_status( + client, receiver_id, token_ids_to_check + ) print(association_status) + if __name__ == "__main__": main() diff --git a/examples/tokens/token_airdrop_transaction.py b/examples/tokens/token_airdrop_transaction.py index 4eaee7ae6..e411f111f 100644 --- a/examples/tokens/token_airdrop_transaction.py +++ b/examples/tokens/token_airdrop_transaction.py @@ -7,26 +7,27 @@ import sys from dotenv import load_dotenv from hiero_sdk_python import ( - Client, - Network, - AccountId, - PrivateKey, - Hbar, - AccountCreateTransaction, - TokenCreateTransaction, - TokenAirdropTransaction, - TokenAssociateTransaction, - TokenMintTransaction, - TokenType, - ResponseCode, - NftId, - TransactionRecordQuery, - TokenNftInfoQuery + Client, + Network, + AccountId, + PrivateKey, + Hbar, + AccountCreateTransaction, + TokenCreateTransaction, + TokenAirdropTransaction, + TokenAssociateTransaction, + TokenMintTransaction, + TokenType, + ResponseCode, + NftId, + TransactionRecordQuery, + TokenNftInfoQuery, ) from hiero_sdk_python.query.account_info_query import AccountInfoQuery load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -35,18 +36,18 @@ def setup_client(): client = Client(network) - try: - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) - client.set_operator(operator_id, operator_key) - print(f"Client set up with operator id {client.operator_account_id}") + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) + client.set_operator(operator_id, operator_key) + print(f"Client set up with operator id {client.operator_account_id}") - return client, operator_id, operator_key + return client, operator_id, operator_key except (TypeError, ValueError): print("❌ Error: Creating client, Please check your .env file") sys.exit(1) + def create_account(client, operator_key): """Create a new recipient account""" print("\nCreating a new account...") @@ -58,7 +59,9 @@ def create_account(client, operator_key): .set_key(recipient_key.public_key()) .set_initial_balance(Hbar.from_tinybars(100_000_000)) ) - account_receipt = account_tx.freeze_with(client).sign(operator_key).execute(client) + account_receipt = ( + account_tx.freeze_with(client).sign(operator_key).execute(client) + ) recipient_id = account_receipt.account_id print(f"✅ Success! Created a new recipient account with ID: {recipient_id}") @@ -67,6 +70,7 @@ def create_account(client, operator_key): print(f"❌ Error creating new recipient account: {e}") sys.exit(1) + def create_token(client, operator_id, operator_key): """Create a fungible token""" print("\nCreating a token...") @@ -89,6 +93,7 @@ def create_token(client, operator_id, operator_key): print(f"❌ Error creating token: {e}") sys.exit(1) + def create_nft(client, operator_key, operator_id): """Create a NFT""" print("\nCreating a nft...") @@ -111,6 +116,7 @@ def create_nft(client, operator_key, operator_id): print(f"❌ Error creating nft: {e}") sys.exit(1) + def mint_nft(client, operator_key, nft_id): """Mint the NFT with metadata""" print("\nMinting a nft...") @@ -127,13 +133,13 @@ def mint_nft(client, operator_key, nft_id): print(f"❌ Error minting nft: {e}") sys.exit(1) + def associate_tokens(client, recipient_id, recipient_key, tokens): """Associate the token and nft with the recipient""" print("\nAssociating tokens to recipient...") try: assocciate_tx = TokenAssociateTransaction( - account_id=recipient_id, - token_ids=tokens + account_id=recipient_id, token_ids=tokens ) assocciate_tx.freeze_with(client) assocciate_tx.sign(recipient_key) @@ -141,7 +147,7 @@ def associate_tokens(client, recipient_id, recipient_key, tokens): # Use AccountInfoQuery to check token associations info = AccountInfoQuery(account_id=recipient_id).execute(client) - + # Get the list of associated token IDs from token_relationships associated_token_ids = [rel.token_id for rel in info.token_relationships] @@ -157,14 +163,18 @@ def associate_tokens(client, recipient_id, recipient_key, tokens): sys.exit(1) -def airdrop_tokens(client, operator_id, operator_key, recipient_id, token_id, nft_id, serial_number): +def airdrop_tokens( + client, operator_id, operator_key, recipient_id, token_id, nft_id, serial_number +): """ Build and execute a TokenAirdropTransaction that transfers one fungible token and the specified NFT serial. Returns the airdrop receipt. """ print(f"\nStep 6: Airdropping tokens to recipient {recipient_id}:") print(f" - 1 fungible token TKA ({token_id})") - print(f" - NFT from NFTA collection ({nft_id}) with serial number #{serial_number}") + print( + f" - NFT from NFTA collection ({nft_id}) with serial number #{serial_number}" + ) try: airdrop_tx = ( TokenAirdropTransaction() @@ -196,9 +206,15 @@ def _check_token_transfer_for_pair(record, token_id, operator_id, recipient_id): try: token_transfers = getattr(record, "token_transfers", {}) or {} # Try direct mapping lookup, otherwise fall back to equality-match in a generator - transfers = token_transfers.get(token_id) or next((v for k, v in token_transfers.items() if k == token_id), None) + transfers = token_transfers.get(token_id) or next( + (v for k, v in token_transfers.items() if k == token_id), None + ) # Validate shape and compare expected amounts in a single expression - return isinstance(transfers, dict) and transfers.get(operator_id) == -1 and transfers.get(recipient_id) == 1 + return ( + isinstance(transfers, dict) + and transfers.get(operator_id) == -1 + and transfers.get(recipient_id) == 1 + ) except Exception: return False @@ -215,7 +231,9 @@ def _extract_nft_transfers(record): if nft_transfers is None: continue # Skip non-iterable or string-like values - if not hasattr(nft_transfers, "__iter__") or isinstance(nft_transfers, (str, bytes)): + if not hasattr(nft_transfers, "__iter__") or isinstance( + nft_transfers, (str, bytes) + ): continue for nft_transfer in nft_transfers: @@ -247,7 +265,9 @@ def verify_transaction_record( } try: - record = TransactionRecordQuery(transaction_id=airdrop_receipt.transaction_id).execute(client) + record = TransactionRecordQuery( + transaction_id=airdrop_receipt.transaction_id + ).execute(client) except Exception as e: print(f"❌ Error fetching transaction record: {e}") return result @@ -265,7 +285,10 @@ def verify_transaction_record( # Single-pass confirmation using any() to keep branching minimal result["nft_transfer_confirmed"] = any( - token_key == nft_id and sender == operator_id and receiver == recipient_id and serial == serial_number + token_key == nft_id + and sender == operator_id + and receiver == recipient_id + and serial == serial_number for token_key, serial, sender, receiver in nft_serials ) @@ -304,7 +327,9 @@ def verify_post_airdrop_balances( # Get current account info and balances using AccountInfoQuery (more robust) try: sender_info = AccountInfoQuery(account_id=operator_id).execute(client) - sender_current = {rel.token_id: rel.balance for rel in sender_info.token_relationships} + sender_current = { + rel.token_id: rel.balance for rel in sender_info.token_relationships + } except Exception as e: details["error"] = f"Error fetching sender account info: {e}" details["fully_verified"] = False @@ -312,7 +337,9 @@ def verify_post_airdrop_balances( try: recipient_info = AccountInfoQuery(account_id=recipient_id).execute(client) - recipient_current = {rel.token_id: rel.balance for rel in recipient_info.token_relationships} + recipient_current = { + rel.token_id: rel.balance for rel in recipient_info.token_relationships + } except Exception as e: details["error"] = f"Error fetching recipient account info: {e}" details["fully_verified"] = False @@ -326,7 +353,9 @@ def verify_post_airdrop_balances( recipient_nft_before = recipient_balances_before.get(nft_id, 0) recipient_nft_after = recipient_current.get(nft_id, 0) - print(f"\n - NFT balance changes: sender {sender_nft_before} -> {sender_nft_after}, recipient {recipient_nft_before} -> {recipient_nft_after}") + print( + f"\n - NFT balance changes: sender {sender_nft_before} -> {sender_nft_after}, recipient {recipient_nft_before} -> {recipient_nft_after}" + ) # Query NFT info for the serial to confirm ownership (optional) nft_serial_id = NftId(token_id=nft_id, serial_number=serial_number) @@ -356,50 +385,85 @@ def verify_post_airdrop_balances( def _log_balances_before(client, operator_id, recipient_id, token_id, nft_id): """Fetch and print sender/recipient token balances and associations before airdrop.""" print("\nStep 5: Checking balances and associations before airdrop...") - + # Get account info to verify associations sender_info = AccountInfoQuery(account_id=operator_id).execute(client) recipient_info = AccountInfoQuery(account_id=recipient_id).execute(client) - + # Build dictionaries for balances from token_relationships (more robust than balance query) - sender_balances_before = {rel.token_id: rel.balance for rel in sender_info.token_relationships} - recipient_balances_before = {rel.token_id: rel.balance for rel in recipient_info.token_relationships} - + sender_balances_before = { + rel.token_id: rel.balance for rel in sender_info.token_relationships + } + recipient_balances_before = { + rel.token_id: rel.balance for rel in recipient_info.token_relationships + } + print(f"Sender ({operator_id}) balances before airdrop:") print(f" {token_id}: {sender_balances_before.get(token_id, 0)}") print(f" {nft_id}: {sender_balances_before.get(nft_id, 0)}") print(f"Recipient ({recipient_id}) balances before airdrop:") print(f" {token_id}: {recipient_balances_before.get(token_id, 0)}") print(f" {nft_id}: {recipient_balances_before.get(nft_id, 0)}") - + return sender_balances_before, recipient_balances_before -def _print_verification_summary(record_result, verification_details, operator_id, recipient_id, nft_id, serial_number): +def _print_verification_summary( + record_result, + verification_details, + operator_id, + recipient_id, + nft_id, + serial_number, +): """Print a concise verification summary based on results.""" - print(f" - Token transfer verification (fungible): {'OK' if record_result.get('expected_token_transfer') else 'MISSING'}") - print(f" - NFT transfer seen in record: {'OK' if record_result.get('nft_transfer_confirmed') else 'MISSING'}") - print(f" - NFT owner according to TokenNftInfoQuery: {verification_details.get('nft_owner')}") - print(f" - NFT owner matches recipient: {'YES' if verification_details.get('owner_matches') else 'NO'}") + print( + f" - Token transfer verification (fungible): {'OK' if record_result.get('expected_token_transfer') else 'MISSING'}" + ) + print( + f" - NFT transfer seen in record: {'OK' if record_result.get('nft_transfer_confirmed') else 'MISSING'}" + ) + print( + f" - NFT owner according to TokenNftInfoQuery: {verification_details.get('nft_owner')}" + ) + print( + f" - NFT owner matches recipient: {'YES' if verification_details.get('owner_matches') else 'NO'}" + ) - if verification_details.get('fully_verified'): - print(f"\n ✅ Success! NFT {nft_id} serial #{serial_number} was transferred from {operator_id} to {recipient_id} and verified by record + balances + TokenNftInfoQuery") + if verification_details.get("fully_verified"): + print( + f"\n ✅ Success! NFT {nft_id} serial #{serial_number} was transferred from {operator_id} to {recipient_id} and verified by record + balances + TokenNftInfoQuery" + ) else: - print(f"\n ⚠️ Warning: Could not fully verify NFT {nft_id} serial #{serial_number}. Combined checks result: {verification_details.get('fully_verified')}") + print( + f"\n ⚠️ Warning: Could not fully verify NFT {nft_id} serial #{serial_number}. Combined checks result: {verification_details.get('fully_verified')}" + ) -def _print_final_summary(client, operator_id, recipient_id, token_id, nft_id, serial_number, verification_details): +def _print_final_summary( + client, + operator_id, + recipient_id, + token_id, + nft_id, + serial_number, + verification_details, +): """Print final balances after airdrop and a small summary table.""" # Use AccountInfoQuery for accurate balance retrieval if not already cached if verification_details.get("sender_balances_after") is None: sender_info = AccountInfoQuery(account_id=operator_id).execute(client) - sender_balances_after = {rel.token_id: rel.balance for rel in sender_info.token_relationships} + sender_balances_after = { + rel.token_id: rel.balance for rel in sender_info.token_relationships + } else: sender_balances_after = verification_details.get("sender_balances_after") - + if verification_details.get("recipient_balances_after") is None: recipient_info = AccountInfoQuery(account_id=recipient_id).execute(client) - recipient_balances_after = {rel.token_id: rel.balance for rel in recipient_info.token_relationships} + recipient_balances_after = { + rel.token_id: rel.balance for rel in recipient_info.token_relationships + } else: recipient_balances_after = verification_details.get("recipient_balances_after") @@ -412,18 +476,30 @@ def _print_final_summary(client, operator_id, recipient_id, token_id, nft_id, se print(f" {nft_id}: {recipient_balances_after.get(nft_id, 0)}") print("\nSummary Table:") - print("+----------------+----------------------+----------------------+----------------------+----------------------+") - print("| Token Type | Token ID | NFT Serial | Sender Balance | Recipient Balance |") - print("+----------------+----------------------+----------------------+----------------------+----------------------+") - print(f"| Fungible (TKA) | {str(token_id):20} | {'N/A':20} | {str(sender_balances_after.get(token_id, 0)):20} | {str(recipient_balances_after.get(token_id, 0)):20} |") - print(f"| NFT (NFTA) | {str(nft_id):20} | #{str(serial_number):19} | {str(sender_balances_after.get(nft_id, 0)):20} | {str(recipient_balances_after.get(nft_id, 0)):20} |") - print("+----------------+----------------------+----------------------+----------------------+----------------------+") + print( + "+----------------+----------------------+----------------------+----------------------+----------------------+" + ) + print( + "| Token Type | Token ID | NFT Serial | Sender Balance | Recipient Balance |" + ) + print( + "+----------------+----------------------+----------------------+----------------------+----------------------+" + ) + print( + f"| Fungible (TKA) | {str(token_id):20} | {'N/A':20} | {str(sender_balances_after.get(token_id, 0)):20} | {str(recipient_balances_after.get(token_id, 0)):20} |" + ) + print( + f"| NFT (NFTA) | {str(nft_id):20} | #{str(serial_number):19} | {str(sender_balances_after.get(nft_id, 0)):20} | {str(recipient_balances_after.get(nft_id, 0)):20} |" + ) + print( + "+----------------+----------------------+----------------------+----------------------+----------------------+" + ) print("\n✅ Finished token airdrop example (see summary above).") def token_airdrop(): """ - A full example that creates an account, a token, associate token, and + A full example that creates an account, a token, associate token, and finally perform token airdrop. """ # Setup Client @@ -438,7 +514,7 @@ def token_airdrop(): # Create a nft nft_id = create_nft(client, operator_key, operator_id) - #Mint nft + # Mint nft serial_number = mint_nft(client, operator_key, nft_id) # Associate tokens @@ -456,11 +532,20 @@ def token_airdrop(): # 1) Verify record contents (token transfers and nft transfers) record_result = verify_transaction_record( - client, airdrop_receipt, operator_id, recipient_id, token_id, nft_id, serial_number + client, + airdrop_receipt, + operator_id, + recipient_id, + token_id, + nft_id, + serial_number, ) # 2) Verify post-airdrop balances and nft ownership - balances_before = {"sender": sender_balances_before, "recipient": recipient_balances_before} + balances_before = { + "sender": sender_balances_before, + "recipient": recipient_balances_before, + } fully_verified, verification_details = verify_post_airdrop_balances( client, operator_id, @@ -473,8 +558,23 @@ def token_airdrop(): ) # Print condensed verification summary and final table - _print_verification_summary(record_result, verification_details, operator_id, recipient_id, nft_id, serial_number) - _print_final_summary(client, operator_id, recipient_id, token_id, nft_id, serial_number, verification_details) + _print_verification_summary( + record_result, + verification_details, + operator_id, + recipient_id, + nft_id, + serial_number, + ) + _print_final_summary( + client, + operator_id, + recipient_id, + token_id, + nft_id, + serial_number, + verification_details, + ) if __name__ == "__main__": diff --git a/examples/tokens/token_airdrop_transaction_cancel.py b/examples/tokens/token_airdrop_transaction_cancel.py index 4d9dd049d..b7cd2cd2f 100644 --- a/examples/tokens/token_airdrop_transaction_cancel.py +++ b/examples/tokens/token_airdrop_transaction_cancel.py @@ -19,13 +19,14 @@ TransactionRecordQuery, TokenCancelAirdropTransaction, CryptoGetAccountBalanceQuery, - ResponseCode + ResponseCode, ) # Load environment variables from .env file load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize the Hedera client using environment variables.""" @@ -34,8 +35,8 @@ def setup_client(): client = Client(network) try: - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") @@ -45,7 +46,9 @@ def setup_client(): sys.exit(1) -def create_account(client, operator_key, initial_balance=Hbar.from_tinybars(100_000_000)): +def create_account( + client, operator_key, initial_balance=Hbar.from_tinybars(100_000_000) +): """Create a new account with the given initial balance.""" print("\nCreating a new account...") recipient_key = PrivateKey.generate("ed25519") @@ -64,7 +67,9 @@ def create_account(client, operator_key, initial_balance=Hbar.from_tinybars(100_ sys.exit(1) -def create_token(client, operator_id, operator_key, token_name, token_symbol, initial_supply=1): +def create_token( + client, operator_id, operator_key, token_name, token_symbol, initial_supply=1 +): """Create a new token and return its token ID.""" print(f"\nCreating token: {token_name} ({token_symbol})...") try: @@ -83,19 +88,32 @@ def create_token(client, operator_id, operator_key, token_name, token_symbol, in print(f"Error creating token {token_name}: {e}") sys.exit(1) + def airdrop_tokens(client, operator_id, operator_key, recipient_id, token_ids): """Airdrop the provided tokens to a recipient account.""" - print(f"\nAirdropping tokens {', '.join([str(t) for t in token_ids])} to recipient {recipient_id}...") + print( + f"\nAirdropping tokens {', '.join([str(t) for t in token_ids])} to recipient {recipient_id}..." + ) try: # Balances before airdrop - sender_balances_before = CryptoGetAccountBalanceQuery(account_id=operator_id).execute(client).token_balances - recipient_balances_before = CryptoGetAccountBalanceQuery(account_id=recipient_id).execute(client).token_balances + sender_balances_before = ( + CryptoGetAccountBalanceQuery(account_id=operator_id) + .execute(client) + .token_balances + ) + recipient_balances_before = ( + CryptoGetAccountBalanceQuery(account_id=recipient_id) + .execute(client) + .token_balances + ) print("\nBalances before airdrop:") for t in token_ids: # token_ids elements are TokenId objects (not strings), so use them as dict keys - print(f" {str(t)}: sender={sender_balances_before.get(t, 0)} recipient={recipient_balances_before.get(t, 0)}") + print( + f" {str(t)}: sender={sender_balances_before.get(t, 0)} recipient={recipient_balances_before.get(t, 0)}" + ) tx = TokenAirdropTransaction() for token_id in token_ids: @@ -103,20 +121,32 @@ def airdrop_tokens(client, operator_id, operator_key, recipient_id, token_ids): tx.add_token_transfer(token_id=token_id, account_id=recipient_id, amount=1) receipt = tx.freeze_with(client).sign(operator_key).execute(client) - print(f"Token airdrop executed: status={receipt.status} transaction_id={receipt.transaction_id}") + print( + f"Token airdrop executed: status={receipt.status} transaction_id={receipt.transaction_id}" + ) # Get record to inspect pending airdrops airdrop_record = TransactionRecordQuery(receipt.transaction_id).execute(client) pending = getattr(airdrop_record, "new_pending_airdrops", []) or [] # Balances after airdrop - sender_balances_after = CryptoGetAccountBalanceQuery(account_id=operator_id).execute(client).token_balances - recipient_balances_after = CryptoGetAccountBalanceQuery(account_id=recipient_id).execute(client).token_balances + sender_balances_after = ( + CryptoGetAccountBalanceQuery(account_id=operator_id) + .execute(client) + .token_balances + ) + recipient_balances_after = ( + CryptoGetAccountBalanceQuery(account_id=recipient_id) + .execute(client) + .token_balances + ) print("\nBalances after airdrop:") for t in token_ids: # token_ids elements are TokenId objects (not strings), so use them as dict keys - print(f" {str(t)}: sender={sender_balances_after.get(t, 0)} recipient={recipient_balances_after.get(t, 0)}") + print( + f" {str(t)}: sender={sender_balances_after.get(t, 0)} recipient={recipient_balances_after.get(t, 0)}" + ) return pending except Exception as e: @@ -161,11 +191,13 @@ def token_airdrop_cancel(): token_id_2 = create_token(client, operator_id, operator_key, "Second Token", "TKB") # Airdrop tokens - pending_airdrops = airdrop_tokens(client, operator_id, operator_key, recipient_id, [token_id_1, token_id_2]) + pending_airdrops = airdrop_tokens( + client, operator_id, operator_key, recipient_id, [token_id_1, token_id_2] + ) # Cancel airdrops cancel_airdrops(client, operator_key, pending_airdrops) if __name__ == "__main__": - token_airdrop_cancel() \ No newline at end of file + token_airdrop_cancel() diff --git a/examples/tokens/token_associate_transaction.py b/examples/tokens/token_associate_transaction.py index c19b3f9f7..3904baad4 100644 --- a/examples/tokens/token_associate_transaction.py +++ b/examples/tokens/token_associate_transaction.py @@ -26,7 +26,7 @@ # Load environment variables from .env file load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() def setup_client(): @@ -54,6 +54,7 @@ def setup_client(): print("❌ Error: Please check OPERATOR_ID and OPERATOR_KEY in your .env file.") sys.exit(1) + def create_test_account(client, operator_key): """ Create a new test account for demonstration. @@ -94,6 +95,7 @@ def create_test_account(client, operator_key): print(f"❌ Error creating new account: {e}") sys.exit(1) + def create_fungible_token(client, operator_id, operator_key): """ Create a fungible token for association with test account. @@ -135,6 +137,7 @@ def create_fungible_token(client, operator_id, operator_key): print(f"❌ Error creating token: {e}") sys.exit(1) + def associate_token_with_account(client, token_id, account_id, account_key): """ Associate the token with the test account. @@ -170,7 +173,9 @@ def associate_token_with_account(client, token_id, account_id, account_key): sys.exit(1) -def associate_two_tokens_mixed_types_with_set_token_ids(client, token_id_1, token_id_2, account_id, account_key): +def associate_two_tokens_mixed_types_with_set_token_ids( + client, token_id_1, token_id_2, account_id, account_key +): """ Associate two tokens using set_token_ids() with mixed types: - first as TokenId diff --git a/examples/tokens/token_burn_transaction_fungible.py b/examples/tokens/token_burn_transaction_fungible.py index 1591961ce..7df03bd01 100644 --- a/examples/tokens/token_burn_transaction_fungible.py +++ b/examples/tokens/token_burn_transaction_fungible.py @@ -1,8 +1,9 @@ """ -uv run examples/tokens/token_burn_transaction_fungible.py +uv run examples/tokens/token_burn_transaction_fungible.py python examples/tokens/token_burn_transaction_fungible.py """ + import os import sys from dotenv import load_dotenv @@ -22,7 +23,8 @@ load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -30,14 +32,15 @@ def setup_client(): print(f"Connecting to Hedera {network_name} network!") client = Client(network) - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) print(f"Client set up with operator id {client.operator_account_id}") client.set_operator(operator_id, operator_key) - + return client, operator_id, operator_key + def create_fungible_token(client, operator_id, operator_key): """Create a fungible token""" receipt = ( @@ -54,26 +57,26 @@ def create_fungible_token(client, operator_id, operator_key): .set_supply_key(operator_key) .execute(client) ) - + if receipt.status != ResponseCode.SUCCESS: - print(f"Fungible token creation failed with status: {ResponseCode(receipt.status).name}") + print( + f"Fungible token creation failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) - + token_id = receipt.token_id print(f"Fungible token created with ID: {token_id}") - + return token_id + def get_token_info(client, token_id): """Get token info for the token""" - token_info = ( - TokenInfoQuery() - .set_token_id(token_id) - .execute(client) - ) - + token_info = TokenInfoQuery().set_token_id(token_id).execute(client) + print(f"Token supply: {token_info.total_supply}") + def token_burn_fungible(): """ Demonstrates the fungible token burn functionality by: @@ -87,13 +90,13 @@ def token_burn_fungible(): # Create a fungible token with the treasury account as owner and signer token_id = create_fungible_token(client, operator_id, operator_key) - + # Get and print token supply before burn to show the initial state print("\nToken supply before burn:") get_token_info(client, token_id) - + burn_amount = 40 - + # Burn 40 tokens out of 100 receipt = ( TokenBurnTransaction() @@ -101,16 +104,17 @@ def token_burn_fungible(): .set_amount(burn_amount) .execute(client) ) - + if receipt.status != ResponseCode.SUCCESS: print(f"Token burn failed with status: {ResponseCode(receipt.status).name}") sys.exit(1) - + print(f"Successfully burned {burn_amount} tokens from {token_id}") - + # Get and print token supply after burn to show the final state print("\nToken supply after burn:") get_token_info(client, token_id) - + + if __name__ == "__main__": token_burn_fungible() diff --git a/examples/tokens/token_burn_transaction_nft.py b/examples/tokens/token_burn_transaction_nft.py index b6841cd6e..2fe60e6e6 100644 --- a/examples/tokens/token_burn_transaction_nft.py +++ b/examples/tokens/token_burn_transaction_nft.py @@ -1,8 +1,9 @@ """ -uv run examples/tokens/token_burn_transaction_nft.py +uv run examples/tokens/token_burn_transaction_nft.py python examples/tokens/token_burn_transaction_nft.py """ + import os import sys from dotenv import load_dotenv @@ -23,7 +24,8 @@ load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -31,13 +33,14 @@ def setup_client(): print(f"Connecting to Hedera {network_name} network!") client = Client(network) - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client, operator_id, operator_key + def create_nft(client, operator_id, operator_key): """Create a non-fungible token""" receipt = ( @@ -54,18 +57,19 @@ def create_nft(client, operator_id, operator_key): .set_supply_key(operator_key) .execute(client) ) - + # Check if nft creation was successful if receipt.status != ResponseCode.SUCCESS: print(f"NFT creation failed with status: {ResponseCode(receipt.status).name}") sys.exit(1) - + # Get token ID from receipt nft_token_id = receipt.token_id print(f"NFT created with ID: {nft_token_id}") - + return nft_token_id + def mint_nfts(client, nft_token_id, metadata_list): """Mint a non-fungible token""" receipt = ( @@ -74,25 +78,23 @@ def mint_nfts(client, nft_token_id, metadata_list): .set_metadata(metadata_list) .execute(client) ) - + if receipt.status != ResponseCode.SUCCESS: print(f"NFT minting failed with status: {ResponseCode(receipt.status).name}") sys.exit(1) - + print(f"NFT minted with serial numbers: {receipt.serial_numbers}") - + return receipt.serial_numbers + def get_token_info(client, token_id): """Get token info for the token""" - token_info = ( - TokenInfoQuery() - .set_token_id(token_id) - .execute(client) - ) - + token_info = TokenInfoQuery().set_token_id(token_id).execute(client) + print(f"Token supply: {token_info.total_supply}") + def token_burn_nft(): """ Demonstrates the NFT burn functionality by: @@ -107,15 +109,15 @@ def token_burn_nft(): # Create a fungible token with the treasury account as owner and signer token_id = create_nft(client, operator_id, operator_key) - + # Mint 4 NFTs - metadata_list = [b'metadata1', b'metadata2', b'metadata3', b'metadata4'] + metadata_list = [b"metadata1", b"metadata2", b"metadata3", b"metadata4"] serial_numbers = mint_nfts(client, token_id, metadata_list) - + # Get and print token balances before burn to show the initial state print("\nToken balances before burn:") get_token_info(client, token_id) - + # Burn first 2 NFTs from the minted collection (serials 1 and 2) receipt = ( TokenBurnTransaction() @@ -123,16 +125,19 @@ def token_burn_nft(): .set_serials(serial_numbers[0:2]) .execute(client) ) - + if receipt.status != ResponseCode.SUCCESS: print(f"NFT burn failed with status: {ResponseCode(receipt.status).name}") sys.exit(1) - - print(f"Successfully burned NFTs with serial numbers {serial_numbers[0:2]} from {token_id}") + + print( + f"Successfully burned NFTs with serial numbers {serial_numbers[0:2]} from {token_id}" + ) # Get and print token balances after burn to show the final state print("\nToken balances after burn:") get_token_info(client, token_id) - + + if __name__ == "__main__": token_burn_nft() diff --git a/examples/tokens/token_create_transaction_admin_key.py b/examples/tokens/token_create_transaction_admin_key.py index 34af32093..5214be089 100644 --- a/examples/tokens/token_create_transaction_admin_key.py +++ b/examples/tokens/token_create_transaction_admin_key.py @@ -36,7 +36,7 @@ from hiero_sdk_python.tokens.supply_type import SupplyType load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() def setup_client(): @@ -46,8 +46,8 @@ def setup_client(): client = Client(network) try: - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client, operator_id, operator_key @@ -140,8 +140,12 @@ def demonstrate_failed_supply_key_addition(client, token_id, admin_key): try: receipt = transaction.execute(client) if receipt.status != ResponseCode.SUCCESS: - print(f"❌ As expected, adding supply key failed: {ResponseCode(receipt.status).name}") - print(" Admin key cannot authorize adding keys that were not present during token creation.") + print( + f"❌ As expected, adding supply key failed: {ResponseCode(receipt.status).name}" + ) + print( + " Admin key cannot authorize adding keys that were not present during token creation." + ) return True # Expected failure else: print("⚠️ Unexpectedly succeeded - this shouldn't happen") @@ -169,7 +173,9 @@ def demonstrate_admin_key_update(client, token_id, admin_key, operator_key): receipt = transaction.execute(client) if receipt.status != ResponseCode.SUCCESS: - print(f"Admin key update failed with status: {ResponseCode(receipt.status).name}") + print( + f"Admin key update failed with status: {ResponseCode(receipt.status).name}" + ) return False print("✅ Admin key updated successfully") @@ -202,11 +208,7 @@ def demonstrate_token_deletion(client, token_id, operator_key): def get_token_info(client, token_id): """Query and display token information.""" try: - info = ( - TokenInfoQuery() - .set_token_id(token_id) - .execute(client) - ) + info = TokenInfoQuery().set_token_id(token_id).execute(client) print(f"\nToken Info for {token_id}:") print(f" Name: {info.name}") print(f" Symbol: {info.symbol}") diff --git a/examples/tokens/token_create_transaction_freeze_key.py b/examples/tokens/token_create_transaction_freeze_key.py index 33d679ab6..712a434d8 100644 --- a/examples/tokens/token_create_transaction_freeze_key.py +++ b/examples/tokens/token_create_transaction_freeze_key.py @@ -196,11 +196,11 @@ def create_demo_account(client: Client, operator_key: PrivateKey) -> DemoAccount return DemoAccount(account_id, new_key) -def associate_token( - client: Client, token_id, account: DemoAccount, signer: PrivateKey -): +def associate_token(client: Client, token_id, account: DemoAccount, signer: PrivateKey): """Associate a token with a given account.""" - print(f"\nSTEP 5️⃣ Associating token {token_id} with account {account.account_id}...") + print( + f"\nSTEP 5️⃣ Associating token {token_id} with account {account.account_id}..." + ) receipt = ( TokenAssociateTransaction() .set_account_id(account.account_id) @@ -310,7 +310,9 @@ def demonstrate_freeze_default_flow( symbol="FDF", ) default_frozen_account = create_demo_account(client, operator_key) - associate_token(client, token_id, default_frozen_account, default_frozen_account.private_key) + associate_token( + client, token_id, default_frozen_account, default_frozen_account.private_key + ) success_before_unfreeze = attempt_transfer( client, @@ -321,9 +323,13 @@ def demonstrate_freeze_default_flow( note="freezeDefault=True (should FAIL)", ) if success_before_unfreeze: - print("⚠️ Unexpected success: account should start frozen when freezeDefault=True.") + print( + "⚠️ Unexpected success: account should start frozen when freezeDefault=True." + ) else: - print("✅ Transfer blocked as expected because the account was frozen by default.") + print( + "✅ Transfer blocked as expected because the account was frozen by default." + ) unfreeze_account(client, token_id, default_frozen_account.account_id, freeze_key) attempt_transfer( @@ -343,7 +349,9 @@ def main(): client, operator_id, operator_key = setup_client() # Token without a freeze key - token_without_key = create_token_without_freeze_key(client, operator_id, operator_key) + token_without_key = create_token_without_freeze_key( + client, operator_id, operator_key + ) demonstrate_missing_freeze_key(client, token_without_key, operator_id, operator_key) # Token with a freeze key @@ -391,9 +399,10 @@ def main(): # Bonus behavior demonstrate_freeze_default_flow(client, operator_id, operator_key, freeze_key) - print("\n🎉 Freeze key demonstration completed! Review the log above for each step.") + print( + "\n🎉 Freeze key demonstration completed! Review the log above for each step." + ) if __name__ == "__main__": main() - diff --git a/examples/tokens/token_create_transaction_fungible_finite.py b/examples/tokens/token_create_transaction_fungible_finite.py index e776c4105..8ca93e9aa 100644 --- a/examples/tokens/token_create_transaction_fungible_finite.py +++ b/examples/tokens/token_create_transaction_fungible_finite.py @@ -35,15 +35,17 @@ def parse_optional_key(key_str): """Parse an optional private key from environment variables.""" - if not key_str or key_str.startswith('<') or key_str.endswith('>'): + if not key_str or key_str.startswith("<") or key_str.endswith(">"): return None try: return PrivateKey.from_string_ed25519(key_str) except Exception: return None + load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -51,8 +53,8 @@ def setup_client(): print(f"Connecting to Hedera {network_name} network!") client = Client(network) - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") @@ -61,10 +63,10 @@ def setup_client(): def load_optional_keys(): """Load optional keys (admin, supply, freeze, pause).""" - admin_key = parse_optional_key(os.getenv('ADMIN_KEY')) - supply_key = parse_optional_key(os.getenv('SUPPLY_KEY')) - freeze_key = parse_optional_key(os.getenv('FREEZE_KEY')) - pause_key = parse_optional_key(os.getenv('PAUSE_KEY')) + admin_key = parse_optional_key(os.getenv("ADMIN_KEY")) + supply_key = parse_optional_key(os.getenv("SUPPLY_KEY")) + freeze_key = parse_optional_key(os.getenv("FREEZE_KEY")) + pause_key = parse_optional_key(os.getenv("PAUSE_KEY")) return admin_key, supply_key, freeze_key, pause_key @@ -108,7 +110,9 @@ def execute_transaction(transaction, client, operator_key, admin_key): if receipt and receipt.token_id: print(f"Finite fungible token created with ID: {receipt.token_id}") else: - print("Finite fungible token creation failed: Token ID not returned in receipt.") + print( + "Finite fungible token creation failed: Token ID not returned in receipt." + ) sys.exit(1) except Exception as e: print(f"Token creation failed: {str(e)}") diff --git a/examples/tokens/token_create_transaction_fungible_infinite.py b/examples/tokens/token_create_transaction_fungible_infinite.py index e8be92476..7d50f2081 100644 --- a/examples/tokens/token_create_transaction_fungible_infinite.py +++ b/examples/tokens/token_create_transaction_fungible_infinite.py @@ -29,7 +29,8 @@ ) load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -38,8 +39,8 @@ def setup_client(): client = Client(network) try: - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client, operator_id, operator_key @@ -88,7 +89,9 @@ def execute_transaction(transaction, client, operator_key, admin_key, supply_key try: receipt = transaction.execute(client) if receipt and receipt.token_id: - print(f"Success! Infinite fungible token created with ID: {receipt.token_id}") + print( + f"Success! Infinite fungible token created with ID: {receipt.token_id}" + ) else: print("Token creation failed: Token ID not returned in receipt.") sys.exit(1) diff --git a/examples/tokens/token_create_transaction_kyc_key.py b/examples/tokens/token_create_transaction_kyc_key.py index defd4e8ea..ce20ee22b 100644 --- a/examples/tokens/token_create_transaction_kyc_key.py +++ b/examples/tokens/token_create_transaction_kyc_key.py @@ -19,6 +19,7 @@ python examples/tokens/token_create_transaction_kyc_key.py """ + import os import sys import time @@ -35,16 +36,20 @@ from hiero_sdk_python.account.account_create_transaction import AccountCreateTransaction from hiero_sdk_python.hapi.services.basic_types_pb2 import TokenType from hiero_sdk_python.tokens.supply_type import SupplyType -from hiero_sdk_python.tokens.token_associate_transaction import TokenAssociateTransaction +from hiero_sdk_python.tokens.token_associate_transaction import ( + TokenAssociateTransaction, +) from hiero_sdk_python.tokens.token_create_transaction import TokenCreateTransaction from hiero_sdk_python.tokens.token_grant_kyc_transaction import TokenGrantKycTransaction -from hiero_sdk_python.tokens.token_revoke_kyc_transaction import TokenRevokeKycTransaction +from hiero_sdk_python.tokens.token_revoke_kyc_transaction import ( + TokenRevokeKycTransaction, +) from hiero_sdk_python.transaction.transfer_transaction import TransferTransaction from hiero_sdk_python.query.account_balance_query import CryptoGetAccountBalanceQuery load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() def setup_client(): @@ -58,8 +63,8 @@ def setup_client(): client = Client(Network(network=network_name)) try: - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY")) client.set_operator(operator_id, operator_key) print(f" Client configured with operator: {operator_id}\n") return client, operator_id, operator_key @@ -95,7 +100,8 @@ def create_account(client, operator_key, initial_balance=Hbar(2)): if receipt.status != ResponseCode.SUCCESS: print( - f" Account creation failed with status: {ResponseCode(receipt.status).name}") + f" Account creation failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) account_id = receipt.account_id @@ -139,7 +145,8 @@ def create_token_without_kyc_key(client, operator_id, operator_key): if receipt.status != ResponseCode.SUCCESS: print( - f" Token creation failed with status: {ResponseCode(receipt.status).name}") + f" Token creation failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) token_id = receipt.token_id @@ -221,7 +228,8 @@ def create_token_with_kyc_key(client, operator_id, operator_key, kyc_private_key if receipt.status != ResponseCode.SUCCESS: print( - f" Token creation failed with status: {ResponseCode(receipt.status).name}") + f" Token creation failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) token_id = receipt.token_id @@ -250,7 +258,8 @@ def associate_token_to_account(client, token_id, account_id, account_private_key if receipt.status != ResponseCode.SUCCESS: print( - f" Token association failed with status: {ResponseCode(receipt.status).name}") + f" Token association failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) print(f" Token {token_id} associated with account {account_id}") @@ -259,7 +268,9 @@ def associate_token_to_account(client, token_id, account_id, account_private_key sys.exit(1) -def attempt_transfer_without_kyc(client, token_id, operator_id, recipient_id, operator_key): +def attempt_transfer_without_kyc( + client, token_id, operator_id, recipient_id, operator_key +): """ Attempt to transfer tokens to an account that has not been granted KYC. Depending on token configuration, this may fail. @@ -279,8 +290,7 @@ def attempt_transfer_without_kyc(client, token_id, operator_id, recipient_id, op .token_balances ) recipient_balance_before = balance_before.get(token_id, 0) - print( - f"Recipient's token balance before transfer: {recipient_balance_before}") + print(f"Recipient's token balance before transfer: {recipient_balance_before}") # Attempt transfer transfer_tx = ( @@ -308,7 +318,8 @@ def attempt_transfer_without_kyc(client, token_id, operator_id, recipient_id, op ) recipient_balance_after = balance_after.get(token_id, 0) print( - f"Recipient's token balance after transfer: {recipient_balance_after}\n") + f"Recipient's token balance after transfer: {recipient_balance_after}\n" + ) return True except Exception as e: print(f" Error during transfer attempt: {e}\n") @@ -335,8 +346,7 @@ def grant_kyc_to_account(client, token_id, account_id, kyc_private_key): ) if receipt.status != ResponseCode.SUCCESS: - print( - f" KYC grant failed with status: {ResponseCode(receipt.status).name}") + print(f" KYC grant failed with status: {ResponseCode(receipt.status).name}") sys.exit(1) print(f" KYC granted for account {account_id} on token {token_id}\n") @@ -362,8 +372,7 @@ def transfer_token_after_kyc(client, token_id, operator_id, recipient_id, operat .token_balances ) recipient_balance_before = balance_before.get(token_id, 0) - print( - f"Recipient's token balance before transfer: {recipient_balance_before}") + print(f"Recipient's token balance before transfer: {recipient_balance_before}") # Perform transfer transfer_tx = ( @@ -390,8 +399,7 @@ def transfer_token_after_kyc(client, token_id, operator_id, recipient_id, operat .token_balances ) recipient_balance_after = balance_after.get(token_id, 0) - print( - f"Recipient's token balance after transfer: {recipient_balance_after}\n") + print(f"Recipient's token balance after transfer: {recipient_balance_after}\n") except Exception as e: print(f" Error transferring token: {e}") sys.exit(1) @@ -418,7 +426,8 @@ def revoke_kyc_from_account(client, token_id, account_id, kyc_private_key): if receipt.status != ResponseCode.SUCCESS: print( - f" KYC revoke failed with status: {ResponseCode(receipt.status).name}") + f" KYC revoke failed with status: {ResponseCode(receipt.status).name}" + ) return False print(f" KYC revoked for account {account_id} on token {token_id}") @@ -450,30 +459,31 @@ def main(): # ===== PART 1: Token WITHOUT KYC Key ===== token_without_kyc = create_token_without_kyc_key( - client, operator_id, operator_key) + client, operator_id, operator_key + ) # Create test account for failed KYC attempt - test_account_1, test_account_key_1 = create_account( - client, operator_key) + test_account_1, test_account_key_1 = create_account(client, operator_key) associate_token_to_account( - client, token_without_kyc, test_account_1, test_account_key_1) + client, token_without_kyc, test_account_1, test_account_key_1 + ) # Try to grant KYC (should fail) - attempt_kyc_without_key(client, token_without_kyc, - test_account_1, operator_key) + attempt_kyc_without_key(client, token_without_kyc, test_account_1, operator_key) # ===== PART 2: Token WITH KYC Key ===== token_with_kyc = create_token_with_kyc_key( - client, operator_id, operator_key, kyc_private_key) + client, operator_id, operator_key, kyc_private_key + ) # Create and associate an account for KYC testing print("\n" + "=" * 70) print("STEP 4: Creating a new account for KYC testing") print("=" * 70) - test_account_2, test_account_key_2 = create_account( - client, operator_key) + test_account_2, test_account_key_2 = create_account(client, operator_key) associate_token_to_account( - client, token_with_kyc, test_account_2, test_account_key_2) + client, token_with_kyc, test_account_2, test_account_key_2 + ) # Try to transfer without KYC (may fail) transfer_without_kyc_result = attempt_transfer_without_kyc( @@ -481,19 +491,18 @@ def main(): ) # Grant KYC - grant_kyc_to_account(client, token_with_kyc, - test_account_2, kyc_private_key) + grant_kyc_to_account(client, token_with_kyc, test_account_2, kyc_private_key) # Wait a moment for state to be consistent time.sleep(1) # Transfer after KYC (should succeed) transfer_token_after_kyc( - client, token_with_kyc, operator_id, test_account_2, operator_key) + client, token_with_kyc, operator_id, test_account_2, operator_key + ) # ===== BONUS: Revoke KYC ===== - revoke_kyc_from_account(client, token_with_kyc, - test_account_2, kyc_private_key) + revoke_kyc_from_account(client, token_with_kyc, test_account_2, kyc_private_key) # Print summary print("\n" + "=" * 70) diff --git a/examples/tokens/token_create_transaction_max_automatic_token_associations_0.py b/examples/tokens/token_create_transaction_max_automatic_token_associations_0.py index b22852b96..5660fd411 100644 --- a/examples/tokens/token_create_transaction_max_automatic_token_associations_0.py +++ b/examples/tokens/token_create_transaction_max_automatic_token_associations_0.py @@ -81,9 +81,13 @@ def create_demo_token( return receipt.token_id -def create_max_account(client: Client, operator_key: PrivateKey) -> Tuple[AccountId, PrivateKey]: +def create_max_account( + client: Client, operator_key: PrivateKey +) -> Tuple[AccountId, PrivateKey]: """Create an account whose max automatic associations equals zero.""" - print("\nSTEP 2: Creating account 'max' with max automatic associations set to 0...") + print( + "\nSTEP 2: Creating account 'max' with max automatic associations set to 0..." + ) max_key = PrivateKey.generate() # Configure the new account to require explicit associations before accepting tokens. tx = ( @@ -238,5 +242,6 @@ def main() -> None: "Verify balances, association status, and token configuration." ) + if __name__ == "__main__": main() diff --git a/examples/tokens/token_create_transaction_nft_finite.py b/examples/tokens/token_create_transaction_nft_finite.py index 2d550182a..6727209b7 100644 --- a/examples/tokens/token_create_transaction_nft_finite.py +++ b/examples/tokens/token_create_transaction_nft_finite.py @@ -29,7 +29,8 @@ ) load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -38,8 +39,8 @@ def setup_client(): client = Client(network) try: - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client, operator_id, operator_key @@ -87,7 +88,9 @@ def execute_transaction(transaction, client, operator_key, admin_key, supply_key try: receipt = transaction.execute(client) if receipt and receipt.token_id: - print(f"Success! Finite non-fungible token created with ID: {receipt.token_id}") + print( + f"Success! Finite non-fungible token created with ID: {receipt.token_id}" + ) else: print("Token creation failed: Token ID not returned in receipt.") sys.exit(1) diff --git a/examples/tokens/token_create_transaction_nft_infinite.py b/examples/tokens/token_create_transaction_nft_infinite.py index 4fe89bf9b..36f974747 100644 --- a/examples/tokens/token_create_transaction_nft_infinite.py +++ b/examples/tokens/token_create_transaction_nft_infinite.py @@ -19,7 +19,8 @@ # Load environment variables from .env file load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -36,9 +37,12 @@ def setup_client(): print("Error: Please check OPERATOR_ID and OPERATOR_KEY in your .env file.") sys.exit(1) + """ 2. Generate Keys On-the-Fly """ + + def keys_on_fly(): print("\nGenerating new admin and supply keys for the NFT...") admin_key = PrivateKey.generate_ed25519() @@ -46,9 +50,12 @@ def keys_on_fly(): print("Keys generated successfully.") return admin_key, supply_key + """ 3. Build and Execute Transaction """ + + def transaction(client, operator_id, operator_key, admin_key, supply_key): try: print("\nBuilding transaction to create an infinite NFT...") @@ -60,7 +67,7 @@ def transaction(client, operator_id, operator_key, admin_key, supply_key): .set_treasury_account_id(operator_id) .set_initial_supply(0) # NFTs must have an initial supply of 0 .set_supply_type(SupplyType.INFINITE) # Infinite supply - .set_admin_key(admin_key) # Generated admin key + .set_admin_key(admin_key) # Generated admin key .set_supply_key(supply_key) # Generated supply key .freeze_with(client) ) @@ -68,15 +75,17 @@ def transaction(client, operator_id, operator_key, admin_key, supply_key): # Sign the transaction with required keys print("Signing transaction...") transaction.sign(operator_key) # Treasury account must sign - transaction.sign(admin_key) # Admin key must sign - transaction.sign(supply_key) # Supply key must sign + transaction.sign(admin_key) # Admin key must sign + transaction.sign(supply_key) # Supply key must sign # Execute the transaction print("Executing transaction...") receipt = transaction.execute(client) if receipt and receipt.token_id: - print(f"Success! Infinite non-fungible token created with ID: {receipt.token_id}") + print( + f"Success! Infinite non-fungible token created with ID: {receipt.token_id}" + ) return receipt.token_id else: print("Token creation failed: Token ID not returned in receipt.") @@ -86,14 +95,18 @@ def transaction(client, operator_id, operator_key, admin_key, supply_key): print(f"Token creation failed: {e}") sys.exit(1) + """ Creates an infinite NFT by generating admin and supply keys on the fly. """ + + def create_token_nft_infinite(): client, operator_id, operator_key = setup_client() admin_key, supply_key = keys_on_fly() token_id = transaction(client, operator_id, operator_key, admin_key, supply_key) print(f"\nCreated token: {token_id}") + if __name__ == "__main__": create_token_nft_infinite() diff --git a/examples/tokens/token_create_transaction_pause_key.py b/examples/tokens/token_create_transaction_pause_key.py index 026040c42..31197a31d 100644 --- a/examples/tokens/token_create_transaction_pause_key.py +++ b/examples/tokens/token_create_transaction_pause_key.py @@ -106,7 +106,9 @@ def attempt_pause_should_fail(client, token_id, operator_key): receipt = tx.execute(client) if receipt.status == ResponseCode.TOKEN_HAS_NO_PAUSE_KEY: - print("✅ Expected failure: token cannot be paused because no pause key exists.\n") + print( + "✅ Expected failure: token cannot be paused because no pause key exists.\n" + ) else: print(f"❌ Unexpected status: {ResponseCode(receipt.status).name}\n") @@ -210,8 +212,9 @@ def create_temp_account(client, operator_key): return account_id, new_key - -def test_transfer_while_paused(client, operator_id, operator_key, recipient_id, token_id): +def test_transfer_while_paused( + client, operator_id, operator_key, recipient_id, token_id +): print("🔹 Attempting transfer WHILE token is paused (expected failure)...") tx = ( @@ -229,6 +232,7 @@ def test_transfer_while_paused(client, operator_id, operator_key, recipient_id, else: print(f"⚠️ Unexpected status: {ResponseCode(receipt.status).name}\n") + # ------------------------------------------------------- # MAIN # ------------------------------------------------------- diff --git a/examples/tokens/token_create_transaction_supply_key.py b/examples/tokens/token_create_transaction_supply_key.py index 0c4aec985..e0f1481fa 100644 --- a/examples/tokens/token_create_transaction_supply_key.py +++ b/examples/tokens/token_create_transaction_supply_key.py @@ -34,7 +34,7 @@ from hiero_sdk_python.tokens.supply_type import SupplyType load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() def setup_client(): @@ -44,8 +44,8 @@ def setup_client(): client = Client(network) try: - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client, operator_id, operator_key @@ -68,8 +68,8 @@ def create_token_no_supply_key(client, operator_id, operator_key): TokenCreateTransaction() .set_token_name("Fixed Supply Token") .set_token_symbol("FST") - .set_token_type(TokenType.FUNGIBLE_COMMON) - .set_initial_supply(1000) + .set_token_type(TokenType.FUNGIBLE_COMMON) + .set_initial_supply(1000) .set_decimals(0) .set_treasury_account_id(operator_id) .freeze_with(client) @@ -77,16 +77,18 @@ def create_token_no_supply_key(client, operator_id, operator_key): transaction.sign(operator_key) - try: + try: reciept = transaction.execute(client) if reciept.status != ResponseCode.SUCCESS: - print(f"Token creation failed with status: {ResponseCode(reciept.status).name}") + print( + f"Token creation failed with status: {ResponseCode(reciept.status).name}" + ) sys.exit(1) - + token_id = reciept.token_id print(f" ✅ Token created successfully with ID: {token_id}") return token_id - + except Exception as e: print(f"Error during token creation as: {e}.") sys.exit(1) @@ -102,17 +104,19 @@ def demonstrate_mint_fail(client, token_id): transaction = ( TokenMintTransaction() .set_token_id(token_id) - .set_amount(100) # Trying to mint 100 more fungible tokens + .set_amount(100) # Trying to mint 100 more fungible tokens .freeze_with(client) ) - + try: receipt = transaction.execute(client) if receipt.status == ResponseCode.TOKEN_HAS_NO_SUPPLY_KEY: - print(f" --> Mint failed as expected! Status: {ResponseCode(receipt.status).name}") + print( + f" --> Mint failed as expected! Status: {ResponseCode(receipt.status).name}" + ) else: - print(f"Mint failed with status: {ResponseCode(receipt.status).name}") - + print(f"Mint failed with status: {ResponseCode(receipt.status).name}") + except Exception as e: print(f"✅ Mint failed as expected! Error: {e}") @@ -122,7 +126,7 @@ def create_token_with_supply_key(client, operator_id, operator_key): Create a Non-Fungible token (NFT) WITH a supply key. """ print("\n--- Scenario 2: Token WITH Supply Key ---") - + # Generate a specific supply key supply_key = PrivateKey.generate_ed25519() print(" ---> Generated new Supply Key.") @@ -141,21 +145,23 @@ def create_token_with_supply_key(client, operator_id, operator_key): .freeze_with(client) ) - # Sign with operator and supply key + # Sign with operator and supply key transaction.sign(operator_key) transaction.sign(supply_key) - + try: receipt = transaction.execute(client) if receipt.status != ResponseCode.SUCCESS: - print(f"Token creation failed with status: {ResponseCode(receipt.status).name}") + print( + f"Token creation failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) token_id = receipt.token_id print(f" ✅ Token created successfully with ID: {token_id}") return token_id, supply_key - - except Exception as e: + + except Exception as e: print(f"Error during token Creation as :{e}.") sys.exit(1) @@ -178,7 +184,7 @@ def demonstrate_mint_success(client, token_id, supply_key): transaction.sign(supply_key) receipt = transaction.execute(client) - + if receipt.status != ResponseCode.SUCCESS: print(f" ❌ Mint failed with status: {ResponseCode(receipt.status).name}") return @@ -190,7 +196,7 @@ def verify_token_info(client, token_id): """Query token info to see total supply.""" print(f"Querying Token Info for {token_id}...") info = TokenInfoQuery().set_token_id(token_id).execute(client) - + print(f" - Total Supply: {info.total_supply}") print(f" - Supply Key Set: {info.supply_key is not None}") @@ -207,7 +213,9 @@ def main(): demonstrate_mint_fail(client, token_id_no_key) # 2. Demonstrate Success (With Supply Key) - token_id_with_key, supply_key = create_token_with_supply_key(client, operator_id, operator_key) + token_id_with_key, supply_key = create_token_with_supply_key( + client, operator_id, operator_key + ) demonstrate_mint_success(client, token_id_with_key, supply_key) verify_token_info(client, token_id_with_key) @@ -215,4 +223,4 @@ def main(): if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/examples/tokens/token_create_transaction_token_fee_schedule_key.py b/examples/tokens/token_create_transaction_token_fee_schedule_key.py index 429f01304..b4a1ff977 100644 --- a/examples/tokens/token_create_transaction_token_fee_schedule_key.py +++ b/examples/tokens/token_create_transaction_token_fee_schedule_key.py @@ -19,10 +19,16 @@ from dotenv import load_dotenv from hiero_sdk_python import Client, AccountId, PrivateKey, Network -from hiero_sdk_python.tokens.token_create_transaction import TokenCreateTransaction, TokenParams, TokenKeys +from hiero_sdk_python.tokens.token_create_transaction import ( + TokenCreateTransaction, + TokenParams, + TokenKeys, +) from hiero_sdk_python.tokens.token_type import TokenType from hiero_sdk_python.tokens.supply_type import SupplyType -from hiero_sdk_python.tokens.token_fee_schedule_update_transaction import TokenFeeScheduleUpdateTransaction +from hiero_sdk_python.tokens.token_fee_schedule_update_transaction import ( + TokenFeeScheduleUpdateTransaction, +) from hiero_sdk_python.tokens.custom_fixed_fee import CustomFixedFee from hiero_sdk_python.response_code import ResponseCode from hiero_sdk_python.query.token_info_query import TokenInfoQuery @@ -30,21 +36,23 @@ # Load environment variables load_dotenv() + def setup_client(): """Initialize client and operator credentials from .env.""" - network = Network(os.getenv('NETWORK', 'testnet')) + network = Network(os.getenv("NETWORK", "testnet")) client = Client(network) operator_id = AccountId.from_string(os.getenv("OPERATOR_ID")) operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY")) client.set_operator(operator_id, operator_key) return client, operator_id, operator_key + def create_token_with_fee_key(client, operator_id): """Create a fungible token with a fee_schedule_key.""" print("Creating fungible token with fee_schedule_key...") fee_schedule_key = PrivateKey.generate_ed25519() initial_fees = [CustomFixedFee(amount=100, fee_collector_account_id=operator_id)] - + token_params = TokenParams( token_name="Fee Key Token", token_symbol="FKT", @@ -55,26 +63,27 @@ def create_token_with_fee_key(client, operator_id): supply_type=SupplyType.INFINITE, custom_fees=initial_fees, ) - + keys = TokenKeys(fee_schedule_key=fee_schedule_key) - + tx = TokenCreateTransaction(token_params=token_params, keys=keys) tx.freeze_with(client) receipt = tx.execute(client) - + if receipt.status != ResponseCode.SUCCESS: print(f"Token creation failed: {ResponseCode(receipt.status).name}") sys.exit(1) - + token_id = receipt.token_id print(f"Token created with ID: {token_id} (has fee_schedule_key)") return token_id, fee_schedule_key + def create_token_without_fee_key(client, operator_id): """Create a fungible token without a fee_schedule_key.""" print("Creating fungible token without fee_schedule_key...") initial_fees = [CustomFixedFee(amount=100, fee_collector_account_id=operator_id)] - + token_params = TokenParams( token_name="No Fee Key Token", token_symbol="NFKT", @@ -85,20 +94,21 @@ def create_token_without_fee_key(client, operator_id): supply_type=SupplyType.INFINITE, custom_fees=initial_fees, ) - + # No keys set, so no fee_schedule_key tx = TokenCreateTransaction(token_params=token_params) tx.freeze_with(client) receipt = tx.execute(client) - + if receipt.status != ResponseCode.SUCCESS: print(f"Token creation failed: {ResponseCode(receipt.status).name}") sys.exit(1) - + token_id = receipt.token_id print(f"Token created with ID: {token_id} (no fee_schedule_key)") return token_id + def query_token_fees(client, token_id, description): """Query and display the custom fees for a token.""" token_info = TokenInfoQuery(token_id=token_id).execute(client) @@ -107,16 +117,23 @@ def query_token_fees(client, token_id, description): for fee in fees: print(f" - Fixed fee: {fee.amount} to {fee.fee_collector_account_id}") + def attempt_fee_update(client, token_id, fee_schedule_key, description): """Attempt to update custom fees for a token.""" print(f"\nAttempting to update fees for {description}...") - new_fees = [CustomFixedFee(amount=200, fee_collector_account_id=client.operator_account_id)] - - tx = TokenFeeScheduleUpdateTransaction().set_token_id(token_id).set_custom_fees(new_fees) - + new_fees = [ + CustomFixedFee(amount=200, fee_collector_account_id=client.operator_account_id) + ] + + tx = ( + TokenFeeScheduleUpdateTransaction() + .set_token_id(token_id) + .set_custom_fees(new_fees) + ) + if fee_schedule_key: tx.freeze_with(client).sign(fee_schedule_key) - + try: receipt = tx.execute(client) if receipt.status == ResponseCode.SUCCESS: @@ -126,31 +143,45 @@ def attempt_fee_update(client, token_id, fee_schedule_key, description): except Exception as e: print(f"Fee update failed with exception: {e}") + def main(): client, operator_id, operator_key = setup_client() - + try: # Create token with fee_schedule_key token_with_key, fee_key = create_token_with_fee_key(client, operator_id) - query_token_fees(client, token_with_key, "Token with fee_schedule_key (initial)") - + query_token_fees( + client, token_with_key, "Token with fee_schedule_key (initial)" + ) + # Create token without fee_schedule_key token_without_key = create_token_without_fee_key(client, operator_id) - query_token_fees(client, token_without_key, "Token without fee_schedule_key (initial)") - + query_token_fees( + client, token_without_key, "Token without fee_schedule_key (initial)" + ) + # Attempt updates - attempt_fee_update(client, token_with_key, fee_key, "token with fee_schedule_key") - attempt_fee_update(client, token_without_key, None, "token without fee_schedule_key") - + attempt_fee_update( + client, token_with_key, fee_key, "token with fee_schedule_key" + ) + attempt_fee_update( + client, token_without_key, None, "token without fee_schedule_key" + ) + # Query final fees - query_token_fees(client, token_with_key, "Token with fee_schedule_key (after update)") - query_token_fees(client, token_without_key, "Token without fee_schedule_key (after update)") - + query_token_fees( + client, token_with_key, "Token with fee_schedule_key (after update)" + ) + query_token_fees( + client, token_without_key, "Token without fee_schedule_key (after update)" + ) + except Exception as e: print(f"Error during operations: {e}") finally: client.close() print("\nClient closed. Example complete.") + if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/examples/tokens/token_create_transaction_token_metadata.py b/examples/tokens/token_create_transaction_token_metadata.py index 741a7b47e..b03227c85 100644 --- a/examples/tokens/token_create_transaction_token_metadata.py +++ b/examples/tokens/token_create_transaction_token_metadata.py @@ -115,7 +115,7 @@ def try_update_metadata_without_key(client, operator_key, token_id): ) sys.exit(1) else: - print(f"✅ Expected failure: metadata update rejected -> status={status}") + print(f"✅ Expected failure: metadata update rejected -> status={status}") except Exception as e: print(f"Failed: {e}") @@ -216,7 +216,7 @@ def demonstrate_metadata_length_validation(client, operator_key, operator_id): print( "Error: Expected ValueError for metadata > 100 bytes, but none was raised." ) - + sys.exit(1) except ValueError as exc: print("Expected error raised for metadata > 100 bytes") diff --git a/examples/tokens/token_create_transaction_wipe_key.py b/examples/tokens/token_create_transaction_wipe_key.py index 364fdb0a8..914958e18 100644 --- a/examples/tokens/token_create_transaction_wipe_key.py +++ b/examples/tokens/token_create_transaction_wipe_key.py @@ -35,7 +35,7 @@ TokenInfoQuery, TokenMintTransaction, Hbar, - NftId # <--- FIX 1: Added NftId import + NftId, # <--- FIX 1: Added NftId import ) from hiero_sdk_python.response_code import ResponseCode @@ -43,7 +43,8 @@ from hiero_sdk_python.tokens.supply_type import SupplyType load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """ @@ -52,18 +53,21 @@ def setup_client(): network = Network(network_name) print(f"Connecting to Hedera {network_name} network") client = Client(network) - + try: - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set-up with operator id {client.operator_account_id}.") return client, operator_id, operator_key - + except (TypeError, ValueError): - print("Error: please check OPERATOR_ID and OPERATOR_KEY in you environment file.") + print( + "Error: please check OPERATOR_ID and OPERATOR_KEY in you environment file." + ) sys.exit(1) - + + def create_recipient_account(client): """ Helper: Create a new account to hold tokens(wiped ones) @@ -76,15 +80,18 @@ def create_recipient_account(client): ) receipt = tx.execute(client) if receipt.status != ResponseCode.SUCCESS: - print(f"❌ Account creation failed with status: {ResponseCode(receipt.status).name}") + print( + f"❌ Account creation failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) print(f"✅ Account created: {receipt.account_id}") return receipt.account_id, private_key + def associate_and_transfer(client, token_id, recipient_id, recipient_key, amount): """Helper: Associate token to recipient and transfer tokens to them""" - + associate_tx = ( TokenAssociateTransaction() .set_account_id(recipient_id) @@ -95,10 +102,12 @@ def associate_and_transfer(client, token_id, recipient_id, recipient_key, amount receipt_associate = associate_tx.execute(client) if receipt_associate.status != ResponseCode.SUCCESS: - print(f"❌ Token association failed with status: {ResponseCode(receipt_associate.status).name}") + print( + f"❌ Token association failed with status: {ResponseCode(receipt_associate.status).name}" + ) sys.exit(1) print(f" --> Associated token {token_id} to account {recipient_id}.") - + transfer_tx = ( TransferTransaction() .add_token_transfer(token_id, client.operator_account_id, -amount) @@ -108,7 +117,9 @@ def associate_and_transfer(client, token_id, recipient_id, recipient_key, amount receipt_transfer = transfer_tx.execute(client) if receipt_transfer.status != ResponseCode.SUCCESS: - print(f"❌ Token transfer failed with status: {ResponseCode(receipt_transfer.status).name}") + print( + f"❌ Token transfer failed with status: {ResponseCode(receipt_transfer.status).name}" + ) sys.exit(1) print(f" --> Transferred {amount} tokens to account {recipient_id}.") @@ -117,7 +128,7 @@ def create_token_no_wipe_key(client, operator_id, operator_key): """Create a token WITHOUT a wipe key.""" print("\n--- Scenario 1: Token WITHOUT Wipe Key ---") print("Creating token WITHOUT a wipe key...") - + transaction = ( TokenCreateTransaction() .set_token_name("No Wipe Token") @@ -133,9 +144,11 @@ def create_token_no_wipe_key(client, operator_id, operator_key): try: receipt = transaction.execute(client) if receipt.status != ResponseCode.SUCCESS: - print(f"❌ Token creation failed with status: {ResponseCode(receipt.status).name}") + print( + f"❌ Token creation failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) - + print(f"✅ Token created: {receipt.token_id}") return receipt.token_id @@ -155,15 +168,19 @@ def demonstrate_wipe_fail(client, token_id, target_account_id): .set_amount(10) .freeze_with(client) ) - + try: # Since no wipe key exists on the token, Hiero will reject this. receipt = transaction.execute(client) if receipt.status == ResponseCode.TOKEN_HAS_NO_WIPE_KEY: - print(f"✅ Wipe failed as expected! Token has no wipe key with status: {ResponseCode(receipt.status).name}.") + print( + f"✅ Wipe failed as expected! Token has no wipe key with status: {ResponseCode(receipt.status).name}." + ) else: - print(f"❌ Wipe unexpectedly succeeded or failed with status: {ResponseCode(receipt.status).name}") - + print( + f"❌ Wipe unexpectedly succeeded or failed with status: {ResponseCode(receipt.status).name}" + ) + except Exception as e: print(f"✅ Wipe failed as expected with error: {e}") @@ -173,7 +190,7 @@ def create_token_with_wipe_key(client, operator_id, operator_key): print("\n--- Scenario 2: Token WITH Wipe Key ---") print("Creating token WITH a wipe key...") wipe_key = PrivateKey.generate_ed25519() - + transaction = ( TokenCreateTransaction() .set_token_name("With Wipe Token") @@ -185,13 +202,15 @@ def create_token_with_wipe_key(client, operator_id, operator_key): .freeze_with(client) ) transaction.sign(operator_key) - + try: receipt = transaction.execute(client) if receipt.status != ResponseCode.SUCCESS: - print(f"❌ Token creation failed with status: {ResponseCode(receipt.status).name}") + print( + f"❌ Token creation failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) - + print(f"✅ Token created: {receipt.token_id}") return receipt.token_id, wipe_key @@ -199,6 +218,7 @@ def create_token_with_wipe_key(client, operator_id, operator_key): print(f"❌ Token creation failed with error: {e}") sys.exit(1) + def demonstrate_wipe_success(client, token_id, target_account_id, wipe_key): """Wipe tokens using the valid wipe key.""" print(f"Wiping 10 tokens from {target_account_id} using Wipe Key...") @@ -210,7 +230,7 @@ def demonstrate_wipe_success(client, token_id, target_account_id, wipe_key): .set_amount(10) .freeze_with(client) ) - + # Critical: Sign with the wipe key transaction.sign(wipe_key) @@ -238,7 +258,7 @@ def demonstrate_nft_wipe_scenario(client, operator_id, operator_key, user_id, us print("Creating an NFT Collection with a Wipe Key...") wipe_key = PrivateKey.generate_ed25519() - supply_key = PrivateKey.generate_ed25519() # Needed to mint the NFT first + supply_key = PrivateKey.generate_ed25519() # Needed to mint the NFT first # 1. Create the NFT Token transaction = ( @@ -249,12 +269,12 @@ def demonstrate_nft_wipe_scenario(client, operator_id, operator_key, user_id, us .set_initial_supply(0) .set_treasury_account_id(operator_id) .set_admin_key(operator_key) - .set_supply_key(supply_key) # Required to mint - .set_wipe_key(wipe_key) # Required to wipe + .set_supply_key(supply_key) # Required to mint + .set_wipe_key(wipe_key) # Required to wipe .freeze_with(client) ) transaction.sign(operator_key) - + receipt = transaction.execute(client) nft_token_id = receipt.token_id print(f"✅ NFT Token created: {nft_token_id}") @@ -274,7 +294,7 @@ def demonstrate_nft_wipe_scenario(client, operator_id, operator_key, user_id, us # 3. Associate User and Transfer NFT to them print(f"Transferring NFT #{serial_number} to user {user_id}...") - + # Associate associate_tx = ( TokenAssociateTransaction() @@ -295,20 +315,22 @@ def demonstrate_nft_wipe_scenario(client, operator_id, operator_key, user_id, us # 4. Wipe the NFT from the User print(f"Attempting to WIPE NFT #{serial_number} from user {user_id}...") - + wipe_tx = ( TokenWipeTransaction() .set_token_id(nft_token_id) .set_account_id(user_id) - .set_serial([serial_number]) + .set_serial([serial_number]) .freeze_with(client) ) - wipe_tx.sign(wipe_key) # Sign with Wipe Key + wipe_tx.sign(wipe_key) # Sign with Wipe Key wipe_receipt = wipe_tx.execute(client) - + if wipe_receipt.status == ResponseCode.SUCCESS: - print("✅ NFT Wipe Successful! The NFT has been effectively burned from the user's account.") + print( + "✅ NFT Wipe Successful! The NFT has been effectively burned from the user's account." + ) else: print(f"❌ NFT Wipe Failed: {ResponseCode(wipe_receipt.status).name}") @@ -335,9 +357,11 @@ def main(): demonstrate_wipe_fail(client, token_id_no_key, user_id) # --- Scenario 2: With Wipe Key (Fungible) --- - token_id_with_key, wipe_key = create_token_with_wipe_key(client, operator_id, operator_key) + token_id_with_key, wipe_key = create_token_with_wipe_key( + client, operator_id, operator_key + ) associate_and_transfer(client, token_id_with_key, user_id, user_key, 50) - + if demonstrate_wipe_success(client, token_id_with_key, user_id, wipe_key): verify_supply(client, token_id_with_key) @@ -346,5 +370,6 @@ def main(): print("\n🎉 Wipe key demonstration completed!") + if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/examples/tokens/token_delete_transaction.py b/examples/tokens/token_delete_transaction.py index ae43a7825..f202fd6bc 100644 --- a/examples/tokens/token_delete_transaction.py +++ b/examples/tokens/token_delete_transaction.py @@ -17,18 +17,19 @@ # Load environment variables from .env file load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): - """Setup Client """ + """Setup Client""" network = Network(network_name) print(f"Connecting to Hedera {network_name} network!") client = Client(network) # Get the operator account from the .env file try: - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) # Set the operator (payer) account for the client client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") @@ -36,7 +37,7 @@ def setup_client(): except (TypeError, ValueError): print("Error: Please check OPERATOR_ID and OPERATOR_KEY in your .env file.") sys.exit(1) - + def generate_admin_key(): """Generate a new admin key within the script: @@ -44,12 +45,13 @@ def generate_admin_key(): """ print("\nGenerating a new admin key for the token...") - admin_key = PrivateKey.generate(os.getenv('KEY_TYPE', 'ed25519')) + admin_key = PrivateKey.generate(os.getenv("KEY_TYPE", "ed25519")) print("Admin key generated successfully.") return admin_key + def create_new_token(client, operator_id, operator_key, admin_key): - """ Create the Token""" + """Create the Token""" token_id_to_delete = None try: @@ -62,7 +64,7 @@ def create_new_token(client, operator_id, operator_key, admin_key): .set_treasury_account_id(operator_id) .set_admin_key(admin_key) # Use the newly generated admin key .freeze_with(client) - .sign(operator_key) # Operator (treasury) must sign + .sign(operator_key) # Operator (treasury) must sign .sign(admin_key) # The new admin key must also sign ) @@ -92,10 +94,10 @@ def delete_token(admin_key, token_id_to_delete, client, operator_key): print(f"\nSTEP 2: Deleting token {token_id_to_delete}...") delete_tx = ( TokenDeleteTransaction() - .set_token_id(token_id_to_delete) # Use the ID from the token we just made + .set_token_id(token_id_to_delete) # Use the ID from the token we just made .freeze_with(client) # Use the ID from the token we just made - .sign(operator_key) # Operator must sign - .sign(admin_key) # Sign with the same admin key used to create it + .sign(operator_key) # Operator must sign + .sign(admin_key) # Sign with the same admin key used to create it ) delete_receipt = delete_tx.execute(client) @@ -112,6 +114,7 @@ def delete_token(admin_key, token_id_to_delete, client, operator_key): print(f"❌ Error deleting token: {repr(e)}") sys.exit(1) + def main(): """ 1. Call create_new_token() to create a new token and get its admin key, token ID, client, and operator key. @@ -126,5 +129,6 @@ def main(): token_id_to_delete = create_new_token(client, operator_id, operator_key, admin_key) delete_token(admin_key, token_id_to_delete, client, operator_key) + if __name__ == "__main__": main() diff --git a/examples/tokens/token_dissociate_transaction.py b/examples/tokens/token_dissociate_transaction.py index 6def716ce..933329317 100644 --- a/examples/tokens/token_dissociate_transaction.py +++ b/examples/tokens/token_dissociate_transaction.py @@ -24,7 +24,8 @@ # Load environment variables from .env file load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Setup Client""" @@ -33,8 +34,8 @@ def setup_client(): client = Client(network) try: - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client, operator_id, operator_key @@ -47,14 +48,14 @@ def setup_client(): def create_new_account(client, operator_id, operator_key): """Create a new account to associate/dissociate with tokens""" print("\nSTEP 1: Creating a new account...") - recipient_key = PrivateKey.generate(os.getenv('KEY_TYPE', 'ed25519')) + recipient_key = PrivateKey.generate(os.getenv("KEY_TYPE", "ed25519")) try: # Build the transaction tx = ( AccountCreateTransaction() - .set_key(recipient_key.public_key()) # <-- THE FIX: Call as a method - .set_initial_balance(Hbar.from_tinybars(100_000_000)) # 1 Hbar + .set_key(recipient_key.public_key()) # <-- THE FIX: Call as a method + .set_initial_balance(Hbar.from_tinybars(100_000_000)) # 1 Hbar ) # Freeze the transaction, sign with the operator, then execute @@ -66,8 +67,10 @@ def create_new_account(client, operator_id, operator_key): except (ValueError, RuntimeError) as e: print(f"❌ Error creating new account: {e}") sys.exit(1) + + def create_token(client, operator_key, recipient_id, recipient_key, operator_id): - """Create two new tokens (one NFT and one fungible) for demonstration purposes. """ + """Create two new tokens (one NFT and one fungible) for demonstration purposes.""" print("\nSTEP 2: Creating two new tokens...") try: # Generate supply key for NFT @@ -93,17 +96,24 @@ def create_token(client, operator_key, recipient_id, recipient_key, operator_id) .set_initial_supply(1) .set_treasury_account_id(operator_id) ) - fungible_receipt = fungible_tx.freeze_with(client).sign(operator_key).execute(client) + fungible_receipt = ( + fungible_tx.freeze_with(client).sign(operator_key).execute(client) + ) fungible_token_id = fungible_receipt.token_id - print(f"✅ Success! Created NFT token: {nft_token_id} and fungible token: {fungible_token_id}") + print( + f"✅ Success! Created NFT token: {nft_token_id} and fungible token: {fungible_token_id}" + ) return client, nft_token_id, fungible_token_id, recipient_id, recipient_key except (ValueError, RuntimeError) as e: print(f"❌ Error creating tokens: {e}") sys.exit(1) -def token_associate(client, nft_token_id, fungible_token_id, recipient_id, recipient_key): + +def token_associate( + client, nft_token_id, fungible_token_id, recipient_id, recipient_key +): """ Associate the tokens with the new account. @@ -111,8 +121,12 @@ def token_associate(client, nft_token_id, fungible_token_id, recipient_id, recip Association is a prerequisite for holding, transferring, or later dissociating tokens. """ - print(f"\nSTEP 3: Associating NFT and fungible tokens with account {recipient_id}...") - print("Note: Tokens must be associated with an account before they can be used or dissociated.") + print( + f"\nSTEP 3: Associating NFT and fungible tokens with account {recipient_id}..." + ) + print( + "Note: Tokens must be associated with an account before they can be used or dissociated." + ) try: receipt = ( TokenAssociateTransaction() @@ -129,17 +143,26 @@ def token_associate(client, nft_token_id, fungible_token_id, recipient_id, recip print(f"❌ Error associating tokens: {e}") sys.exit(1) + def verify_dissociation(client, nft_token_id, fungible_token_id, recipient_id): """Verify that the specified tokens are dissociated from the account.""" print("\nVerifying token dissociation...") info = AccountInfoQuery().set_account_id(recipient_id).execute(client) - associated_tokens = [rel.token_id for rel in getattr(info, 'token_relationships', [])] - if nft_token_id not in associated_tokens and fungible_token_id not in associated_tokens: + associated_tokens = [ + rel.token_id for rel in getattr(info, "token_relationships", []) + ] + if ( + nft_token_id not in associated_tokens + and fungible_token_id not in associated_tokens + ): print("✅ Verified: Both tokens are dissociated from the account.") else: print("❌ Verification failed: Some tokens are still associated.") -def token_dissociate(client, nft_token_id, fungible_token_id, recipient_id, recipient_key): + +def token_dissociate( + client, nft_token_id, fungible_token_id, recipient_id, recipient_key +): """ Dissociate the tokens from the new account. @@ -150,22 +173,27 @@ def token_dissociate(client, nft_token_id, fungible_token_id, recipient_id, reci - To comply with business or regulatory requirements """ - print(f"\nSTEP 4: Dissociating NFT and fungible tokens from account {recipient_id}...") + print( + f"\nSTEP 4: Dissociating NFT and fungible tokens from account {recipient_id}..." + ) try: receipt = ( TokenDissociateTransaction() .set_account_id(recipient_id) .set_token_ids([nft_token_id, fungible_token_id]) .freeze_with(client) - .sign(recipient_key) # Recipient must sign to approve + .sign(recipient_key) # Recipient must sign to approve .execute(client) ) - print(f"✅ Success! Token dissociation complete for both NFT and fungible tokens, Status: {ResponseCode(receipt.status).name}") + print( + f"✅ Success! Token dissociation complete for both NFT and fungible tokens, Status: {ResponseCode(receipt.status).name}" + ) except (ValueError, RuntimeError) as e: print(f"❌ Error dissociating tokens: {e}") sys.exit(1) + def main(): """ 1-create new account @@ -175,10 +203,18 @@ def main(): 5-verify dissociation """ client, operator_id, operator_key = setup_client() - client, operator_key, recipient_id, recipient_key, operator_id =create_new_account(client, operator_id, operator_key) - client, nft_token_id, fungible_token_id, recipient_id, recipient_key = create_token(client, operator_key, recipient_id, recipient_key, operator_id) - token_associate(client, nft_token_id, fungible_token_id, recipient_id, recipient_key) - token_dissociate(client, nft_token_id, fungible_token_id, recipient_id, recipient_key) + client, operator_key, recipient_id, recipient_key, operator_id = create_new_account( + client, operator_id, operator_key + ) + client, nft_token_id, fungible_token_id, recipient_id, recipient_key = create_token( + client, operator_key, recipient_id, recipient_key, operator_id + ) + token_associate( + client, nft_token_id, fungible_token_id, recipient_id, recipient_key + ) + token_dissociate( + client, nft_token_id, fungible_token_id, recipient_id, recipient_key + ) # Optional: Verify dissociation verify_dissociation(client, nft_token_id, fungible_token_id, recipient_id) diff --git a/examples/tokens/token_fee_schedule_update_transaction_fungible.py b/examples/tokens/token_fee_schedule_update_transaction_fungible.py index ffa1a9f23..d919c3b39 100644 --- a/examples/tokens/token_fee_schedule_update_transaction_fungible.py +++ b/examples/tokens/token_fee_schedule_update_transaction_fungible.py @@ -2,15 +2,22 @@ uv run examples/tokens/token_fee_schedule_update_transaction_fungible.py python examples/tokens/token_fee_schedule_update_transaction_fungible.py """ + import os import sys from dotenv import load_dotenv from hiero_sdk_python import Client, AccountId, PrivateKey, Network -from hiero_sdk_python.tokens.token_create_transaction import TokenCreateTransaction, TokenParams, TokenKeys +from hiero_sdk_python.tokens.token_create_transaction import ( + TokenCreateTransaction, + TokenParams, + TokenKeys, +) from hiero_sdk_python.tokens.token_type import TokenType from hiero_sdk_python.tokens.supply_type import SupplyType -from hiero_sdk_python.tokens.token_fee_schedule_update_transaction import TokenFeeScheduleUpdateTransaction +from hiero_sdk_python.tokens.token_fee_schedule_update_transaction import ( + TokenFeeScheduleUpdateTransaction, +) from hiero_sdk_python.tokens.custom_fixed_fee import CustomFixedFee from hiero_sdk_python.response_code import ResponseCode from hiero_sdk_python.query.token_info_query import TokenInfoQuery @@ -19,7 +26,7 @@ def setup_client(): """Initialize client and operator credentials from .env.""" load_dotenv() - network_name = os.getenv('NETWORK', 'testnet').lower() + network_name = os.getenv("NETWORK", "testnet").lower() try: network = Network(network_name) @@ -47,15 +54,13 @@ def create_fungible_token(client, operator_id, fee_schedule_key): token_type=TokenType.FUNGIBLE_COMMON, supply_type=SupplyType.FINITE, max_supply=2000, - custom_fees=[], # No custom fees at creation - ) - - keys = TokenKeys( - fee_schedule_key=fee_schedule_key + custom_fees=[], # No custom fees at creation ) + keys = TokenKeys(fee_schedule_key=fee_schedule_key) + tx = TokenCreateTransaction(token_params=token_params, keys=keys) - + tx.freeze_with(client) receipt = tx.execute(client) @@ -82,9 +87,9 @@ def update_custom_fixed_fee(client, token_id, fee_schedule_key, treasury_account .set_token_id(token_id) .set_custom_fees(new_fees) ) - + # The transaction MUST be signed by the fee_schedule_key - tx.freeze_with(client).sign(fee_schedule_key) + tx.freeze_with(client).sign(fee_schedule_key) try: receipt = tx.execute(client) @@ -104,7 +109,7 @@ def query_token_info(client, token_id): try: token_info = TokenInfoQuery(token_id=token_id).execute(client) print("Token Info Retrieved Successfully!\n") - + print(f"Name: {getattr(token_info, 'name', 'N/A')}") print(f"Symbol: {getattr(token_info, 'symbol', 'N/A')}") print(f"Total Supply: {getattr(token_info, 'total_supply', 'N/A')}") @@ -118,7 +123,9 @@ def query_token_info(client, token_id): print(f"Found {len(custom_fees)} custom fee(s):") for i, fee in enumerate(custom_fees, 1): print(f" Fee #{i}: {type(fee).__name__}") - print(f" Collector: {getattr(fee, 'fee_collector_account_id', 'N/A')}") + print( + f" Collector: {getattr(fee, 'fee_collector_account_id', 'N/A')}" + ) if isinstance(fee, CustomFixedFee): print(f" Amount: {getattr(fee, 'amount', 'N/A')}") else: @@ -134,15 +141,15 @@ def main(): token_id = None try: fee_key = operator_key - + token_id = create_fungible_token(client, operator_id, fee_key) - + if token_id: - query_token_info(client, token_id) + query_token_info(client, token_id) # Pass the operator_id as the fee collector (which is also the treasury) update_custom_fixed_fee(client, token_id, fee_key, operator_id) query_token_info(client, token_id) - + except Exception as e: print(f" Error during token operations: {e}") finally: @@ -152,4 +159,3 @@ def main(): if __name__ == "__main__": main() - diff --git a/examples/tokens/token_fee_schedule_update_transaction_nft.py b/examples/tokens/token_fee_schedule_update_transaction_nft.py index 82f93afb6..b1155ca9d 100644 --- a/examples/tokens/token_fee_schedule_update_transaction_nft.py +++ b/examples/tokens/token_fee_schedule_update_transaction_nft.py @@ -1,15 +1,22 @@ """Example: Update Custom Fees for an NFT uv run examples/tokens/token_fee_schedule_update_transaction_nft.py python examples/tokens/token_fee_schedule_update_transaction_nft.py""" + import os import sys from dotenv import load_dotenv from hiero_sdk_python import Client, AccountId, PrivateKey, Network -from hiero_sdk_python.tokens.token_create_transaction import TokenCreateTransaction, TokenParams, TokenKeys +from hiero_sdk_python.tokens.token_create_transaction import ( + TokenCreateTransaction, + TokenParams, + TokenKeys, +) from hiero_sdk_python.tokens.token_type import TokenType from hiero_sdk_python.tokens.supply_type import SupplyType -from hiero_sdk_python.tokens.token_fee_schedule_update_transaction import TokenFeeScheduleUpdateTransaction +from hiero_sdk_python.tokens.token_fee_schedule_update_transaction import ( + TokenFeeScheduleUpdateTransaction, +) from hiero_sdk_python.tokens.custom_royalty_fee import CustomRoyaltyFee from hiero_sdk_python.response_code import ResponseCode from hiero_sdk_python.query.token_info_query import TokenInfoQuery @@ -18,7 +25,7 @@ def setup_client(): """Initialize client and operator credentials from .env.""" load_dotenv() - network_name = os.getenv('NETWORK', 'testnet').lower() + network_name = os.getenv("NETWORK", "testnet").lower() try: network = Network(network_name) @@ -46,19 +53,16 @@ def create_nft(client, operator_id, supply_key, fee_schedule_key): token_type=TokenType.NON_FUNGIBLE_UNIQUE, supply_type=SupplyType.FINITE, max_supply=1000, - custom_fees=[], + custom_fees=[], ) - + # A supply_key is REQUIRED for NFTs (to mint) # A fee_schedule_key is required to update fees - keys = TokenKeys( - supply_key=supply_key, - fee_schedule_key=fee_schedule_key - ) + keys = TokenKeys(supply_key=supply_key, fee_schedule_key=fee_schedule_key) tx = TokenCreateTransaction(token_params=token_params, keys=keys) # tx.set_fee_schedule_key(fee_schedule_key) - + # Sign with the supply key as well tx.freeze_with(client).sign(supply_key) receipt = tx.execute(client) @@ -78,9 +82,9 @@ def update_custom_royalty_fee(client, token_id, fee_schedule_key, collector_acco print(f" Updating custom royalty fee for token {token_id}...") new_fees = [ CustomRoyaltyFee( - numerator=5, - denominator=100, # 5% royalty - fee_collector_account_id=collector_account_id + numerator=5, + denominator=100, # 5% royalty + fee_collector_account_id=collector_account_id, ) ] print(f" Defined {len(new_fees)} new custom fees.\n") @@ -89,19 +93,19 @@ def update_custom_royalty_fee(client, token_id, fee_schedule_key, collector_acco .set_token_id(token_id) .set_custom_fees(new_fees) ) - - tx.freeze_with(client).sign(fee_schedule_key) + + tx.freeze_with(client).sign(fee_schedule_key) try: receipt = tx.execute(client) if receipt.status != ResponseCode.SUCCESS: print(f" Fee schedule update failed: {ResponseCode(receipt.status).name}\n") - sys.exit(1) + sys.exit(1) else: print(" Fee schedule updated successfully.\n") except Exception as e: print(f" Error during fee schedule update execution: {e}\n") - sys.exit(1) + sys.exit(1) def query_token_info(client, token_id): @@ -110,7 +114,7 @@ def query_token_info(client, token_id): try: token_info = TokenInfoQuery(token_id=token_id).execute(client) print("Token Info Retrieved Successfully!\n") - + print(f"Name: {getattr(token_info, 'name', 'N/A')}") print(f"Symbol: {getattr(token_info, 'symbol', 'N/A')}") print(f"Total Supply: {getattr(token_info, 'total_supply', 'N/A')}") @@ -124,7 +128,9 @@ def query_token_info(client, token_id): print(f"Found {len(custom_fees)} custom fee(s):") for i, fee in enumerate(custom_fees, 1): print(f" Fee #{i}: {type(fee).__name__}") - print(f" Collector: {getattr(fee, 'fee_collector_account_id', 'N/A')}") + print( + f" Collector: {getattr(fee, 'fee_collector_account_id', 'N/A')}" + ) if isinstance(fee, CustomRoyaltyFee): print(f" Royalty: {fee.numerator}/{fee.denominator}") else: @@ -134,7 +140,8 @@ def query_token_info(client, token_id): except Exception as e: print(f"Error querying token info: {e}") - sys.exit(1) + sys.exit(1) + def main(): client, operator_id, operator_key = setup_client() @@ -143,14 +150,14 @@ def main(): # Use operator key as both supply and fee key supply_key = operator_key fee_key = operator_key - + token_id = create_nft(client, operator_id, supply_key, fee_key) - + if token_id: - query_token_info(client, token_id) + query_token_info(client, token_id) update_custom_royalty_fee(client, token_id, fee_key, operator_id) query_token_info(client, token_id) - + except Exception as e: print(f" Error during token operations: {e}") finally: @@ -160,4 +167,3 @@ def main(): if __name__ == "__main__": main() - diff --git a/examples/tokens/token_freeze_transaction.py b/examples/tokens/token_freeze_transaction.py index e7e28517c..afa063ed1 100644 --- a/examples/tokens/token_freeze_transaction.py +++ b/examples/tokens/token_freeze_transaction.py @@ -23,7 +23,8 @@ # Load environment variables from .env file load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Setup Client""" @@ -32,8 +33,8 @@ def setup_client(): client = Client(network) try: - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client, operator_id, operator_key @@ -45,10 +46,11 @@ def setup_client(): def generate_freeze_key(): """Generate a Freeze Key""" print("\nSTEP 1: Generating a new freeze key...") - freeze_key = PrivateKey.generate(os.getenv('KEY_TYPE', 'ed25519')) + freeze_key = PrivateKey.generate(os.getenv("KEY_TYPE", "ed25519")) print("✅ Freeze key generated.") return freeze_key + def create_freezeable_token(client, operator_id, operator_key): """Create a token with the freeze key""" freeze_key = generate_freeze_key() @@ -60,14 +62,14 @@ def create_freezeable_token(client, operator_id, operator_key): .set_token_symbol("FRZ") .set_initial_supply(1000) .set_treasury_account_id(operator_id) - .set_freeze_key(freeze_key) # <-- THE FIX: Pass the private key directly + .set_freeze_key(freeze_key) # <-- THE FIX: Pass the private key directly ) # Freeze, sign with BOTH operator and the new freeze key, then execute receipt = ( tx.freeze_with(client) .sign(operator_key) - .sign(freeze_key) # The new freeze key must sign to give consent + .sign(freeze_key) # The new freeze key must sign to give consent .execute(client) ) token_id = receipt.token_id @@ -87,17 +89,20 @@ def freeze_token(token_id, client, operator_id, freeze_key): receipt = ( TokenFreezeTransaction() .set_token_id(token_id) - .set_account_id(operator_id) # Target the operator account + .set_account_id(operator_id) # Target the operator account .freeze_with(client) - .sign(freeze_key) # Must be signed by the freeze key + .sign(freeze_key) # Must be signed by the freeze key .execute(client) ) - print(f"✅ Success! Token freeze complete. Status: {ResponseCode(receipt.status).name}") - + print( + f"✅ Success! Token freeze complete. Status: {ResponseCode(receipt.status).name}" + ) + except RuntimeError as e: print(f"❌ Error freezing token: {e}") sys.exit(1) + def verify_freeze(token_id, client, operator_id, operator_key): """Attempt a token transfer to confirm the account cannot perform the operation while frozen.""" @@ -116,14 +121,19 @@ def verify_freeze(token_id, client, operator_id, operator_key): status_code = transfer_receipt.status status_name = ResponseCode(status_code).name if status_name in ["ACCOUNT_FROZEN_FOR_TOKEN", "ACCOUNT_FROZEN"]: - print(f"✅ Verified: Transfer blocked as expected due to freeze. Status: {status_name}") + print( + f"✅ Verified: Transfer blocked as expected due to freeze. Status: {status_name}" + ) elif status_name == "SUCCESS": - print("❌ Error: Transfer succeeded, but should have failed because the account is frozen.") + print( + "❌ Error: Transfer succeeded, but should have failed because the account is frozen." + ) else: print(f"❌ Unexpected: Transfer result. Status: {status_name}") except RuntimeError as e: print(f"✅ Verified: Transfer failed as expected due to freeze. Error: {e}") + def main(): """ 1. Create a freezeable token with a freeze key. @@ -131,9 +141,12 @@ def main(): 3. Attempt a token transfer to verify the freeze (should fail). 4. Return token details for further operations.""" client, operator_id, operator_key = setup_client() - freeze_key, token_id, client, operator_id, operator_key = create_freezeable_token(client, operator_id, operator_key) + freeze_key, token_id, client, operator_id, operator_key = create_freezeable_token( + client, operator_id, operator_key + ) freeze_token(token_id, client, operator_id, freeze_key) verify_freeze(token_id, client, operator_id, operator_key) + if __name__ == "__main__": main() diff --git a/examples/tokens/token_grant_kyc_transaction.py b/examples/tokens/token_grant_kyc_transaction.py index bcff2d0c8..35f841a94 100644 --- a/examples/tokens/token_grant_kyc_transaction.py +++ b/examples/tokens/token_grant_kyc_transaction.py @@ -3,6 +3,7 @@ python examples/tokens/token_grant_kyc_transaction.py """ + import os import sys from dotenv import load_dotenv @@ -18,12 +19,15 @@ from hiero_sdk_python.hbar import Hbar from hiero_sdk_python.response_code import ResponseCode from hiero_sdk_python.tokens.supply_type import SupplyType -from hiero_sdk_python.tokens.token_associate_transaction import TokenAssociateTransaction +from hiero_sdk_python.tokens.token_associate_transaction import ( + TokenAssociateTransaction, +) from hiero_sdk_python.tokens.token_grant_kyc_transaction import TokenGrantKycTransaction from hiero_sdk_python.tokens.token_create_transaction import TokenCreateTransaction load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -31,13 +35,14 @@ def setup_client(): print(f"Connecting to Hedera {network_name} network!") client = Client(network) - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client, operator_id, operator_key + def create_fungible_token(client, operator_id, operator_key, kyc_private_key): """Create a fungible token""" receipt = ( @@ -52,19 +57,24 @@ def create_fungible_token(client, operator_id, operator_key, kyc_private_key): .set_max_supply(1000) .set_admin_key(operator_key) .set_supply_key(operator_key) - .set_kyc_key(kyc_private_key) # Required key for granting KYC approval to accounts + .set_kyc_key( + kyc_private_key + ) # Required key for granting KYC approval to accounts .execute(client) ) - + if receipt.status != ResponseCode.SUCCESS: - print(f"Fungible token creation failed with status: {ResponseCode(receipt.status).name}") + print( + f"Fungible token creation failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) - + token_id = receipt.token_id print(f"Fungible token created with ID: {token_id}") - + return token_id + def associate_token(client, token_id, account_id, account_private_key): """Associate a token with an account""" associate_transaction = ( @@ -72,23 +82,26 @@ def associate_token(client, token_id, account_id, account_private_key): .set_account_id(account_id) .add_token_id(token_id) .freeze_with(client) - .sign(account_private_key) # Has to be signed by new account's key + .sign(account_private_key) # Has to be signed by new account's key ) - + receipt = associate_transaction.execute(client) - + if receipt.status != ResponseCode.SUCCESS: - print(f"Token association failed with status: {ResponseCode(receipt.status).name}") + print( + f"Token association failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) - + print("Token successfully associated with account") + def create_test_account(client): """Create a new account for testing""" # Generate private key for new account new_account_private_key = PrivateKey.generate() new_account_public_key = new_account_private_key.public_key() - + # Create new account with initial balance of 1 HBAR transaction = ( AccountCreateTransaction() @@ -96,20 +109,23 @@ def create_test_account(client): .set_initial_balance(Hbar(1)) .freeze_with(client) ) - + receipt = transaction.execute(client) - + # Check if account creation was successful if receipt.status != ResponseCode.SUCCESS: - print(f"Account creation failed with status: {ResponseCode(receipt.status).name}") + print( + f"Account creation failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) - + # Get account ID from receipt account_id = receipt.account_id print(f"New account created with ID: {account_id}") - + return account_id, new_account_private_key + def token_grant_kyc(): """ Demonstrates the token grant KYC functionality by: @@ -120,19 +136,19 @@ def token_grant_kyc(): 5. Granting KYC to the new account """ client, operator_id, operator_key = setup_client() - + # Create KYC key kyc_private_key = PrivateKey.generate_ed25519() - + # Create a fungible token with KYC key token_id = create_fungible_token(client, operator_id, operator_key, kyc_private_key) - + # Create a new account account_id, account_private_key = create_test_account(client) - + # Associate the token with the new account associate_token(client, token_id, account_id, account_private_key) - + # Grant KYC to the new account receipt = ( TokenGrantKycTransaction() @@ -142,13 +158,16 @@ def token_grant_kyc(): .sign(kyc_private_key) # Has to be signed by the KYC key .execute(client) ) - + # Check if the transaction was successful if receipt.status != ResponseCode.SUCCESS: - print(f"Token grant KYC failed with status: {ResponseCode(receipt.status).name}") + print( + f"Token grant KYC failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) - + print(f"Granted KYC for account {account_id} on token {token_id}") + if __name__ == "__main__": token_grant_kyc() diff --git a/examples/tokens/token_mint_transaction_fungible.py b/examples/tokens/token_mint_transaction_fungible.py index f81c11bfc..bb24bb143 100644 --- a/examples/tokens/token_mint_transaction_fungible.py +++ b/examples/tokens/token_mint_transaction_fungible.py @@ -19,13 +19,13 @@ TokenCreateTransaction, TokenMintTransaction, TokenInfoQuery, - ResponseCode - + ResponseCode, ) # Load environment variables from .env file load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Setup Client""" @@ -34,8 +34,8 @@ def setup_client(): client = Client(network) try: - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client, operator_id, operator_key @@ -44,14 +44,14 @@ def setup_client(): sys.exit(1) - def generate_supply_key(): """Generate a new supply key for the token.""" print("\nSTEP 1: Generating a new supply key...") - supply_key = PrivateKey.generate(os.getenv('KEY_TYPE', 'ed25519')) + supply_key = PrivateKey.generate(os.getenv("KEY_TYPE", "ed25519")) print("✅ Supply key generated.") return supply_key + def create_new_token(): """ Create a fungible token that can have its supply changed (minted or burned). @@ -83,7 +83,7 @@ def create_new_token(): # Confirm the token has a supply key set info = TokenInfoQuery().set_token_id(token_id).execute(client) - if getattr(info, 'supply_key', None): + if getattr(info, "supply_key", None): print("✅ Verified: Token has a supply key set.") else: print("❌ Warning: Token does not have a supply key set.") @@ -102,7 +102,7 @@ def token_mint_fungible(client, token_id, supply_key): Only the holder of the supply key can perform these actions. """ - mint_amount = 5000 # This is 50.00 tokens because decimals is 2 + mint_amount = 5000 # This is 50.00 tokens because decimals is 2 print(f"\nSTEP 3: Minting {mint_amount} more tokens for {token_id}...") # Confirm total supply before minting @@ -120,7 +120,9 @@ def token_mint_fungible(client, token_id, supply_key): .sign(supply_key) # Must be signed by the supply key .execute(client) ) - print(f"✅ Success! Token minting complete, Status: {ResponseCode(receipt.status).name}") + print( + f"✅ Success! Token minting complete, Status: {ResponseCode(receipt.status).name}" + ) # Confirm total supply after minting info_after = TokenInfoQuery().set_token_id(token_id).execute(client) @@ -129,6 +131,7 @@ def token_mint_fungible(client, token_id, supply_key): print(f"❌ Error minting tokens: {e}") sys.exit(1) + def main(): """ 1. Create a new token with a supply key so its supply can be changed later @@ -139,5 +142,6 @@ def main(): client, token_id, supply_key = create_new_token() token_mint_fungible(client, token_id, supply_key) + if __name__ == "__main__": main() diff --git a/examples/tokens/token_mint_transaction_non_fungible.py b/examples/tokens/token_mint_transaction_non_fungible.py index cc8592471..3ab00218a 100644 --- a/examples/tokens/token_mint_transaction_non_fungible.py +++ b/examples/tokens/token_mint_transaction_non_fungible.py @@ -25,7 +25,8 @@ # Load environment variables from .env file load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Setup and return a Hedera client.""" @@ -34,8 +35,8 @@ def setup_client(): client = Client(network) try: - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client, operator_id, operator_key @@ -47,12 +48,13 @@ def setup_client(): def generate_supply_key(): """Generate a new supply key for the token.""" print("\nSTEP 1: Generating a new supply key...") - supply_key = PrivateKey.generate(os.getenv('HSDK_KEY_TYPE', 'ed25519')) + supply_key = PrivateKey.generate(os.getenv("HSDK_KEY_TYPE", "ed25519")) print("✅ Supply key generated") return supply_key + def create_nft_collection(): - """ Create the NFT Collection (Token) """ + """Create the NFT Collection (Token)""" client, operator_id, operator_key = setup_client() supply_key = generate_supply_key() print("\nSTEP 2: Creating a new NFT collection...") @@ -79,6 +81,8 @@ def create_nft_collection(): except Exception as e: print(f"❌ Error creating token: {e}") sys.exit(1) + + def token_mint_non_fungible(client, token_id, supply_key): """ Mint new NFTs with metadata @@ -104,14 +108,16 @@ def token_mint_non_fungible(client, token_id, supply_key): receipt = ( TokenMintTransaction() .set_token_id(token_id) - .set_metadata(metadata_list) # Set the list of metadata + .set_metadata(metadata_list) # Set the list of metadata .freeze_with(client) .sign(supply_key) # Must be signed by the supply key .execute(client) ) # THE FIX: The receipt confirms status, it does not contain serial numbers. - print(f"✅ Success! NFT minting complete, Status: {ResponseCode(receipt.status).name}") + print( + f"✅ Success! NFT minting complete, Status: {ResponseCode(receipt.status).name}" + ) # Confirm total supply after minting info_after = TokenInfoQuery().set_token_id(token_id).execute(client) print(f"Total supply after minting: {info_after.total_supply}") @@ -119,6 +125,7 @@ def token_mint_non_fungible(client, token_id, supply_key): print(f"❌ Error minting NFTs: {e}") sys.exit(1) + def main(): """ 1. Create a new NFT collection (token) with a supply key @@ -130,5 +137,6 @@ def main(): client, token_id, supply_key = create_nft_collection() token_mint_non_fungible(client, token_id, supply_key) + if __name__ == "__main__": main() diff --git a/examples/tokens/token_pause_transaction.py b/examples/tokens/token_pause_transaction.py index d17b85398..dba4aed8e 100644 --- a/examples/tokens/token_pause_transaction.py +++ b/examples/tokens/token_pause_transaction.py @@ -3,16 +3,12 @@ python examples/tokens/token_pause_transaction.py """ + import os import sys from dotenv import load_dotenv -from hiero_sdk_python import ( - Client, - AccountId, - PrivateKey, - Network -) +from hiero_sdk_python import Client, AccountId, PrivateKey, Network from hiero_sdk_python.response_code import ResponseCode from hiero_sdk_python.tokens.supply_type import SupplyType from hiero_sdk_python.tokens.token_type import TokenType @@ -22,7 +18,8 @@ from hiero_sdk_python.query.token_info_query import TokenInfoQuery load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -32,13 +29,14 @@ def setup_client(): client = Client(network) # Set up operator account - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client, operator_id, operator_key + def assert_success(receipt, action: str): """ Verify that a transaction or query succeeded, else raise. @@ -55,6 +53,7 @@ def assert_success(receipt, action: str): name = ResponseCode(receipt.status).name raise RuntimeError(f"{action!r} failed with status {name}") + def create_token(client, operator_id, admin_key, pause_key): """Create a fungible token""" # Create fungible token @@ -68,20 +67,21 @@ def create_token(client, operator_id, admin_key, pause_key): .set_token_type(TokenType.FUNGIBLE_COMMON) .set_supply_type(SupplyType.FINITE) .set_max_supply(100) - .set_admin_key(admin_key) # Required for token delete - .set_pause_key(pause_key) # Required for pausing tokens + .set_admin_key(admin_key) # Required for token delete + .set_pause_key(pause_key) # Required for pausing tokens .freeze_with(client) ) - + receipt = create_token_transaction.execute(client) assert_success(receipt, "Token creation") - + # Get token ID from receipt token_id = receipt.token_id print(f"Token created with ID: {token_id}") - + return token_id + def pause_token(client, token_id, pause_key): """Pause token""" # Note: This requires the pause key that was specified during token creation @@ -91,19 +91,21 @@ def pause_token(client, token_id, pause_key): .freeze_with(client) .sign(pause_key) ) - + receipt = pause_transaction.execute(client) - assert_success(receipt, "Token pause") + assert_success(receipt, "Token pause") print(f"Successfully paused token {token_id}") + def check_pause_status(client, token_id): """ Query and print the current paused/unpaused status of a token. """ info = TokenInfoQuery().set_token_id(token_id).execute(client) print(f"Token status is now: {info.pause_status.name}") - + + def delete_token(client, token_id, admin_key): """Delete token""" # Note: This requires the admin key that was specified during token creation @@ -115,10 +117,11 @@ def delete_token(client, token_id, admin_key): ) receipt = delete_transaction.execute(client) - assert_success(receipt, "Token delete") + assert_success(receipt, "Token delete") print(f"Successfully deleted token {token_id}") + def token_pause(): """ Demonstrates the token pause functionality by: @@ -129,12 +132,12 @@ def token_pause(): """ client, operator_id, operator_key = setup_client() - pause_key = operator_key # for token pause - admin_key = operator_key # for token delete + pause_key = operator_key # for token pause + admin_key = operator_key # for token delete # Create token with required keys for pause and delete. token_id = create_token(client, operator_id, admin_key, pause_key) - + # Pause token using pause key – should succeed pause_token(client, token_id, pause_key) @@ -144,9 +147,12 @@ def token_pause(): # Try deleting token with admin key – should fail with TOKEN_IS_PAUSED try: delete_token(client, token_id, admin_key) - print("❌ Whoops, delete succeeded—but it should have failed on a paused token!") + print( + "❌ Whoops, delete succeeded—but it should have failed on a paused token!" + ) except RuntimeError as e: print(f"✅ Unable to delete token as expected as it is paused: {e}") + if __name__ == "__main__": token_pause() diff --git a/examples/tokens/token_reject_transaction_fungible_token.py b/examples/tokens/token_reject_transaction_fungible_token.py index 86887525e..2a9171b4d 100644 --- a/examples/tokens/token_reject_transaction_fungible_token.py +++ b/examples/tokens/token_reject_transaction_fungible_token.py @@ -3,6 +3,7 @@ python examples/tokens/token_reject_transaction_fungible_token.py """ + import os import sys from dotenv import load_dotenv @@ -20,12 +21,15 @@ from hiero_sdk_python.query.account_balance_query import CryptoGetAccountBalanceQuery from hiero_sdk_python.response_code import ResponseCode from hiero_sdk_python.tokens.supply_type import SupplyType -from hiero_sdk_python.tokens.token_associate_transaction import TokenAssociateTransaction +from hiero_sdk_python.tokens.token_associate_transaction import ( + TokenAssociateTransaction, +) from hiero_sdk_python.tokens.token_create_transaction import TokenCreateTransaction from hiero_sdk_python.tokens.token_reject_transaction import TokenRejectTransaction load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -33,19 +37,20 @@ def setup_client(): print(f"Connecting to Hedera {network_name} network!") client = Client(network) - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID','')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY','')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client + def create_test_account(client): """Create a new account for testing""" # Generate private key for new account new_account_private_key = PrivateKey.generate_ed25519() new_account_public_key = new_account_private_key.public_key() - + # Create new account with initial balance of 1 HBAR receipt = ( AccountCreateTransaction() @@ -53,19 +58,22 @@ def create_test_account(client): .set_initial_balance(Hbar(1)) .execute(client) ) - + # Check if account creation was successful if receipt.status != ResponseCode.SUCCESS: - print(f"Account creation failed with status: {ResponseCode(receipt.status).name}") + print( + f"Account creation failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) - + # Get account ID from receipt account_id = receipt.account_id print(f"New account created with ID: {account_id}") - + return account_id, new_account_private_key -def create_fungible_token(client: 'Client', treasury_id, treasury_private_key): + +def create_fungible_token(client: "Client", treasury_id, treasury_private_key): """Create a fungible token""" receipt = ( TokenCreateTransaction() @@ -81,19 +89,24 @@ def create_fungible_token(client: 'Client', treasury_id, treasury_private_key): .set_supply_key(treasury_private_key) .set_freeze_key(treasury_private_key) .freeze_with(client) - .sign(treasury_private_key) # Has to be signed by treasury account's key as we set the treasury_account_id to be the treasury_id + .sign( + treasury_private_key + ) # Has to be signed by treasury account's key as we set the treasury_account_id to be the treasury_id .execute(client) ) - + if receipt.status != ResponseCode.SUCCESS: - print(f"Fungible token creation failed with status: {ResponseCode(receipt.status).name}") + print( + f"Fungible token creation failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) - + token_id = receipt.token_id print(f"Fungible token created with ID: {token_id}") - + return token_id + def associate_token(client, receiver_id, token_id, receiver_private_key): """Associate token with an account""" # Associate the token_id with the new account @@ -102,17 +115,22 @@ def associate_token(client, receiver_id, token_id, receiver_private_key): .set_account_id(receiver_id) .add_token_id(token_id) .freeze_with(client) - .sign(receiver_private_key) # Has to be signed here by receiver's key + .sign(receiver_private_key) # Has to be signed here by receiver's key .execute(client) ) - + if receipt.status != ResponseCode.SUCCESS: - print(f"Token association failed with status: {ResponseCode(receipt.status).name}") + print( + f"Token association failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) - + print(f"Token successfully associated with account: {receiver_id}") -def transfer_tokens(client, treasury_id, treasury_private_key, receiver_id, token_id, amount=10): + +def transfer_tokens( + client, treasury_id, treasury_private_key, receiver_id, token_id, amount=10 +): """Transfer tokens to the receiver account so we can later reject them""" # Transfer tokens to the receiver account receipt = ( @@ -123,29 +141,31 @@ def transfer_tokens(client, treasury_id, treasury_private_key, receiver_id, toke .sign(treasury_private_key) .execute(client) ) - + # Check if transfer was successful if receipt.status != ResponseCode.SUCCESS: print(f"Transfer failed with status: {ResponseCode(receipt.status).name}") sys.exit(1) - + print(f"Successfully transferred {amount} tokens to receiver account {receiver_id}") - + + def get_token_balances(client, treasury_id, receiver_id, token_id): """Get token balances for both accounts""" token_balance = ( - CryptoGetAccountBalanceQuery() - .set_account_id(treasury_id) - .execute(client) + CryptoGetAccountBalanceQuery().set_account_id(treasury_id).execute(client) ) - print(f"Token balance of treasury {treasury_id}: {token_balance.token_balances[token_id]}") - + print( + f"Token balance of treasury {treasury_id}: {token_balance.token_balances[token_id]}" + ) + receiver_token_balance = ( - CryptoGetAccountBalanceQuery() - .set_account_id(receiver_id) - .execute(client) + CryptoGetAccountBalanceQuery().set_account_id(receiver_id).execute(client) ) - print(f"Token balance of receiver {receiver_id}: {receiver_token_balance.token_balances[token_id]}") + print( + f"Token balance of receiver {receiver_id}: {receiver_token_balance.token_balances[token_id]}" + ) + def token_reject_fungible(): """ @@ -162,20 +182,20 @@ def token_reject_fungible(): treasury_id, treasury_private_key = create_test_account(client) # Create receiver account that will receive and later reject tokens receiver_id, receiver_private_key = create_test_account(client) - + # Create a fungible token with the treasury account as owner and signer token_id = create_fungible_token(client, treasury_id, treasury_private_key) - + # Associate token with the receiver account so they can receive the tokens from the treasury associate_token(client, receiver_id, token_id, receiver_private_key) - + # Transfer tokens to the receiver account transfer_tokens(client, treasury_id, treasury_private_key, receiver_id, token_id) # Get and print token balances before rejection to show the initial state print("\nToken balances before rejection:") get_token_balances(client, treasury_id, receiver_id, token_id) - + # Receiver rejects the fungible tokens that were previously transferred to them receipt = ( TokenRejectTransaction() @@ -185,16 +205,19 @@ def token_reject_fungible(): .sign(receiver_private_key) .execute(client) ) - + if receipt.status != ResponseCode.SUCCESS: - print(f"Token rejection failed with status: {ResponseCode(receipt.status).name}") + print( + f"Token rejection failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) - + print(f"Successfully rejected token {token_id} from account {receiver_id}") - + # Get and print token balances after rejection to show the final state print("\nToken balances after rejection:") get_token_balances(client, treasury_id, receiver_id, token_id) - + + if __name__ == "__main__": token_reject_fungible() diff --git a/examples/tokens/token_reject_transaction_nft.py b/examples/tokens/token_reject_transaction_nft.py index 4da01a512..7be75b082 100644 --- a/examples/tokens/token_reject_transaction_nft.py +++ b/examples/tokens/token_reject_transaction_nft.py @@ -3,6 +3,7 @@ python examples/tokens/token_reject_transaction_nft.py """ + import os import sys from dotenv import load_dotenv @@ -21,13 +22,16 @@ from hiero_sdk_python.response_code import ResponseCode from hiero_sdk_python.tokens.nft_id import NftId from hiero_sdk_python.tokens.supply_type import SupplyType -from hiero_sdk_python.tokens.token_associate_transaction import TokenAssociateTransaction +from hiero_sdk_python.tokens.token_associate_transaction import ( + TokenAssociateTransaction, +) from hiero_sdk_python.tokens.token_create_transaction import TokenCreateTransaction from hiero_sdk_python.tokens.token_mint_transaction import TokenMintTransaction from hiero_sdk_python.tokens.token_reject_transaction import TokenRejectTransaction load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -35,19 +39,20 @@ def setup_client(): print(f"Connecting to Hedera {network_name} network!") client = Client(network) - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client + def create_test_account(client): """Create a new account for testing""" # Generate private key for new account new_account_private_key = PrivateKey.generate_ed25519() new_account_public_key = new_account_private_key.public_key() - + # Create new account with initial balance of 1 HBAR receipt = ( AccountCreateTransaction() @@ -55,18 +60,21 @@ def create_test_account(client): .set_initial_balance(Hbar(1)) .execute(client) ) - + # Check if account creation was successful if receipt.status != ResponseCode.SUCCESS: - print(f"Account creation failed with status: {ResponseCode(receipt.status).name}") + print( + f"Account creation failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) - + # Get account ID from receipt account_id = receipt.account_id print(f"New account created with ID: {account_id}") - + return account_id, new_account_private_key + def create_nft(client, treasury_id, treasury_private_key): """Create a non-fungible token""" receipt = ( @@ -83,21 +91,24 @@ def create_nft(client, treasury_id, treasury_private_key): .set_supply_key(treasury_private_key) .set_freeze_key(treasury_private_key) .freeze_with(client) - .sign(treasury_private_key) # Has to be signed here by treasury's key as we set the treasury_account_id to be the treasury_id + .sign( + treasury_private_key + ) # Has to be signed here by treasury's key as we set the treasury_account_id to be the treasury_id .execute(client) ) - + # Check if nft creation was successful if receipt.status != ResponseCode.SUCCESS: print(f"NFT creation failed with status: {ResponseCode(receipt.status).name}") sys.exit(1) - + # Get token ID from receipt nft_token_id = receipt.token_id print(f"NFT created with ID: {nft_token_id}") - + return nft_token_id + def mint_nfts(client, nft_token_id, metadata_list, treasury_private_key): """Mint a non-fungible token""" receipt = ( @@ -105,17 +116,22 @@ def mint_nfts(client, nft_token_id, metadata_list, treasury_private_key): .set_token_id(nft_token_id) .set_metadata(metadata_list) .freeze_with(client) - .sign(treasury_private_key) # Has to be signed here by treasury's key because they own the supply key + .sign( + treasury_private_key + ) # Has to be signed here by treasury's key because they own the supply key .execute(client) ) - + if receipt.status != ResponseCode.SUCCESS: print(f"NFT minting failed with status: {ResponseCode(receipt.status).name}") sys.exit(1) - + print(f"NFT minted with serial numbers: {receipt.serial_numbers}") - - return [NftId(nft_token_id, serial_number) for serial_number in receipt.serial_numbers] + + return [ + NftId(nft_token_id, serial_number) for serial_number in receipt.serial_numbers + ] + def associate_token(client, receiver_id, nft_token_id, receiver_private_key): """Associate token with an account""" @@ -125,16 +141,19 @@ def associate_token(client, receiver_id, nft_token_id, receiver_private_key): .set_account_id(receiver_id) .add_token_id(nft_token_id) .freeze_with(client) - .sign(receiver_private_key) # Has to be signed here by receiver's key + .sign(receiver_private_key) # Has to be signed here by receiver's key .execute(client) ) - + if receipt.status != ResponseCode.SUCCESS: - print(f"Token association failed with status: {ResponseCode(receipt.status).name}") + print( + f"Token association failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) - + print(f"Token successfully associated with account: {receiver_id}") + def transfer_nfts(client, treasury_id, treasury_private_key, receiver_id, nft_ids): """Transfer NFTs to the receiver account so we can later reject them""" # Transfer NFTs to the receiver account @@ -146,29 +165,31 @@ def transfer_nfts(client, treasury_id, treasury_private_key, receiver_id, nft_id .sign(treasury_private_key) .execute(client) ) - + # Check if transfer was successful if receipt.status != ResponseCode.SUCCESS: print(f"Transfer failed with status: {ResponseCode(receipt.status).name}") sys.exit(1) - + print(f"Successfully transferred NFTs to receiver account {receiver_id}") - + + def get_nft_balances(client, treasury_id, receiver_id, nft_token_id): """Get NFT balances for both accounts""" token_balance = ( - CryptoGetAccountBalanceQuery() - .set_account_id(treasury_id) - .execute(client) + CryptoGetAccountBalanceQuery().set_account_id(treasury_id).execute(client) + ) + print( + f"NFT balance of treasury {treasury_id}: {token_balance.token_balances[nft_token_id]}" ) - print(f"NFT balance of treasury {treasury_id}: {token_balance.token_balances[nft_token_id]}") - + receiver_token_balance = ( - CryptoGetAccountBalanceQuery() - .set_account_id(receiver_id) - .execute(client) + CryptoGetAccountBalanceQuery().set_account_id(receiver_id).execute(client) + ) + print( + f"NFT balance of receiver {receiver_id}: {receiver_token_balance.token_balances[nft_token_id]}" ) - print(f"NFT balance of receiver {receiver_id}: {receiver_token_balance.token_balances[nft_token_id]}") + def token_reject_nft(): """ @@ -186,22 +207,27 @@ def token_reject_nft(): treasury_id, treasury_private_key = create_test_account(client) # Create receiver account that will receive and later reject tokens receiver_id, receiver_private_key = create_test_account(client) - + # Create a new NFT collection with the treasury account as owner nft_token_id = create_nft(client, treasury_id, treasury_private_key) # Mint 2 NFTs in the collection with example metadata and get their unique IDs that we will send and reject - nft_ids = mint_nfts(client, nft_token_id, [b"ExampleMetadata 1", b"ExampleMetadata 2"], treasury_private_key) - + nft_ids = mint_nfts( + client, + nft_token_id, + [b"ExampleMetadata 1", b"ExampleMetadata 2"], + treasury_private_key, + ) + # Associate the NFT token with the receiver account so they can receive the NFTs associate_token(client, receiver_id, nft_token_id, receiver_private_key) - + # Transfer NFTs to the receiver account transfer_nfts(client, treasury_id, treasury_private_key, receiver_id, nft_ids) # Get and print NFT balances before rejection to show the initial state print("\nNFT balances before rejection:") get_nft_balances(client, treasury_id, receiver_id, nft_token_id) - + # Receiver rejects the NFTs that were previously transferred to them receipt = ( TokenRejectTransaction() @@ -211,16 +237,19 @@ def token_reject_nft(): .sign(receiver_private_key) .execute(client) ) - + if receipt.status != ResponseCode.SUCCESS: print(f"NFT rejection failed with status: {ResponseCode(receipt.status).name}") sys.exit(1) - - print(f"Successfully rejected NFTs {nft_ids[0]} and {nft_ids[1]} from account {receiver_id}") - + + print( + f"Successfully rejected NFTs {nft_ids[0]} and {nft_ids[1]} from account {receiver_id}" + ) + # Get and print NFT balances after rejection to show the final state print("\nNFT balances after rejection:") get_nft_balances(client, treasury_id, receiver_id, nft_token_id) - + + if __name__ == "__main__": token_reject_nft() diff --git a/examples/tokens/token_revoke_kyc_transaction.py b/examples/tokens/token_revoke_kyc_transaction.py index 96eac0729..14216c58a 100644 --- a/examples/tokens/token_revoke_kyc_transaction.py +++ b/examples/tokens/token_revoke_kyc_transaction.py @@ -3,6 +3,7 @@ python examples/tokens/token_revoke_kyc_transaction.py.py """ + import os import sys from dotenv import load_dotenv @@ -18,13 +19,18 @@ from hiero_sdk_python.hbar import Hbar from hiero_sdk_python.response_code import ResponseCode from hiero_sdk_python.tokens.supply_type import SupplyType -from hiero_sdk_python.tokens.token_associate_transaction import TokenAssociateTransaction +from hiero_sdk_python.tokens.token_associate_transaction import ( + TokenAssociateTransaction, +) from hiero_sdk_python.tokens.token_grant_kyc_transaction import TokenGrantKycTransaction -from hiero_sdk_python.tokens.token_revoke_kyc_transaction import TokenRevokeKycTransaction +from hiero_sdk_python.tokens.token_revoke_kyc_transaction import ( + TokenRevokeKycTransaction, +) from hiero_sdk_python.tokens.token_create_transaction import TokenCreateTransaction load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -32,13 +38,14 @@ def setup_client(): print(f"Connecting to Hedera {network_name} network!") client = Client(network) - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client, operator_id, operator_key + def create_fungible_token(client, operator_id, operator_key, kyc_private_key): """Create a fungible token""" receipt = ( @@ -53,19 +60,24 @@ def create_fungible_token(client, operator_id, operator_key, kyc_private_key): .set_max_supply(1000) .set_admin_key(operator_key) .set_supply_key(operator_key) - .set_kyc_key(kyc_private_key) # Required key for granting/revoking KYC approval to accounts + .set_kyc_key( + kyc_private_key + ) # Required key for granting/revoking KYC approval to accounts .execute(client) ) - + if receipt.status != ResponseCode.SUCCESS: - print(f"Fungible token creation failed with status: {ResponseCode(receipt.status).name}") + print( + f"Fungible token creation failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) - + token_id = receipt.token_id print(f"Fungible token created with ID: {token_id}") - + return token_id + def associate_token(client, token_id, account_id, account_private_key): """Associate a token with an account""" associate_transaction = ( @@ -73,23 +85,26 @@ def associate_token(client, token_id, account_id, account_private_key): .set_account_id(account_id) .add_token_id(token_id) .freeze_with(client) - .sign(account_private_key) # Has to be signed by new account's key + .sign(account_private_key) # Has to be signed by new account's key ) - + receipt = associate_transaction.execute(client) - + if receipt.status != ResponseCode.SUCCESS: - print(f"Token association failed with status: {ResponseCode.get_name(receipt.status)}") + print( + f"Token association failed with status: {ResponseCode.get_name(receipt.status)}" + ) sys.exit(1) - + print("Token successfully associated with account") + def create_test_account(client): """Create a new account for testing""" # Generate private key for new account new_account_private_key = PrivateKey.generate() new_account_public_key = new_account_private_key.public_key() - + # Create new account with initial balance of 1 HBAR transaction = ( AccountCreateTransaction() @@ -97,20 +112,23 @@ def create_test_account(client): .set_initial_balance(Hbar(1)) .freeze_with(client) ) - + receipt = transaction.execute(client) - + # Check if account creation was successful if receipt.status != ResponseCode.SUCCESS: - print(f"Account creation failed with status: {ResponseCode.get_name(receipt.status)}") + print( + f"Account creation failed with status: {ResponseCode.get_name(receipt.status)}" + ) sys.exit(1) - + # Get account ID from receipt account_id = receipt.account_id print(f"New account created with ID: {account_id}") - + return account_id, new_account_private_key + def grant_kyc(client, token_id, account_id, kyc_private_key): """Grant KYC to an account""" receipt = ( @@ -121,13 +139,16 @@ def grant_kyc(client, token_id, account_id, kyc_private_key): .sign(kyc_private_key) # Has to be signed by the KYC key .execute(client) ) - + if receipt.status != ResponseCode.SUCCESS: - print(f"Token grant KYC failed with status: {ResponseCode.get_name(receipt.status)}") + print( + f"Token grant KYC failed with status: {ResponseCode.get_name(receipt.status)}" + ) sys.exit(1) - + print(f"Granted KYC for account {account_id} on token {token_id}") + def token_revoke_kyc(): """ Demonstrates the token revoke KYC functionality by: @@ -139,22 +160,22 @@ def token_revoke_kyc(): 6. Revoking KYC from the new account """ client, operator_id, operator_key = setup_client() - + # Create KYC key kyc_private_key = PrivateKey.generate_ed25519() - + # Create a fungible token with KYC key token_id = create_fungible_token(client, operator_id, operator_key, kyc_private_key) - + # Create a new account account_id, account_private_key = create_test_account(client) - + # Associate the token with the new account associate_token(client, token_id, account_id, account_private_key) - + # Grant KYC to the new account first grant_kyc(client, token_id, account_id, kyc_private_key) - + # Revoke KYC from the new account receipt = ( TokenRevokeKycTransaction() @@ -164,13 +185,16 @@ def token_revoke_kyc(): .sign(kyc_private_key) # Has to be signed by the KYC key .execute(client) ) - + # Check if the transaction was successful if receipt.status != ResponseCode.SUCCESS: - print(f"Token revoke KYC failed with status: {ResponseCode.get_name(receipt.status)}") + print( + f"Token revoke KYC failed with status: {ResponseCode.get_name(receipt.status)}" + ) sys.exit(1) - + print(f"Revoked KYC for account {account_id} on token {token_id}") + if __name__ == "__main__": - token_revoke_kyc() \ No newline at end of file + token_revoke_kyc() diff --git a/examples/tokens/token_unfreeze_transaction.py b/examples/tokens/token_unfreeze_transaction.py index aa4a6c7ac..fa8858c3a 100644 --- a/examples/tokens/token_unfreeze_transaction.py +++ b/examples/tokens/token_unfreeze_transaction.py @@ -5,6 +5,7 @@ python examples/tokens/token_unfreeze_transaction.py """ + import os import sys from dotenv import load_dotenv @@ -23,7 +24,8 @@ # Load environment variables from .env file load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Setup Client""" @@ -32,8 +34,8 @@ def setup_client(): client = Client(network) try: - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID','')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY','')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client, operator_id, operator_key @@ -46,10 +48,11 @@ def setup_client(): def generate_freeze_key(): """Generate a Freeze Key on the fly""" print("\nSTEP 1: Generating a new freeze key...") - freeze_key = PrivateKey.generate(os.getenv('KEY_TYPE', 'ed25519')) + freeze_key = PrivateKey.generate(os.getenv("KEY_TYPE", "ed25519")) print("✅ Freeze key generated.") return freeze_key + def create_freezable_token(): """Create a token with the freeze key""" client, operator_id, operator_key = setup_client() @@ -67,10 +70,7 @@ def create_freezable_token(): # FIX: The .execute() method returns the receipt directly. receipt = ( - tx.freeze_with(client) - .sign(operator_key) - .sign(freeze_key) - .execute(client) + tx.freeze_with(client).sign(operator_key).sign(freeze_key).execute(client) ) token_id = receipt.token_id print(f"✅ Success! Created token with ID: {token_id}") @@ -79,6 +79,7 @@ def create_freezable_token(): print(f"❌ Error creating token: {e}") sys.exit(1) + def freeze_token(token_id, client, operator_id, freeze_key): """Freeze the token for the operator account""" print(f"\nSTEP 3: Freezing token {token_id} for operator account {operator_id}...") @@ -91,15 +92,20 @@ def freeze_token(token_id, client, operator_id, freeze_key): .sign(freeze_key) .execute(client) ) - print(f"✅ Success! Token freeze complete, Status: {ResponseCode(receipt.status).name}") + print( + f"✅ Success! Token freeze complete, Status: {ResponseCode(receipt.status).name}" + ) except (RuntimeError, ValueError) as e: print(f"❌ Error freezing token: {e}") sys.exit(1) + def unfreeze_token(token_id, client, operator_id, freeze_key, operator_key): """Unfreeze the token for the operator account""" # Step 1: Unfreeze the token for the operator account - print(f"\nSTEP 4: Unfreezing token {token_id} for operator account {operator_id}...") + print( + f"\nSTEP 4: Unfreezing token {token_id} for operator account {operator_id}..." + ) try: receipt = ( TokenUnfreezeTransaction() @@ -109,7 +115,9 @@ def unfreeze_token(token_id, client, operator_id, freeze_key, operator_key): .sign(freeze_key) .execute(client) ) - print(f"✅ Success! Token unfreeze complete, Status: {ResponseCode(receipt.status).name}") + print( + f"✅ Success! Token unfreeze complete, Status: {ResponseCode(receipt.status).name}" + ) # Step 2: Attempt a test transfer of 1 unit of token to self print(f"Attempting a test transfer of 1 unit of token {token_id} to self...") @@ -122,15 +130,18 @@ def unfreeze_token(token_id, client, operator_id, freeze_key, operator_key): .sign(operator_key) .execute(client) ) - print(f"✅ Test transfer succeeded. Token is unfrozen and usable, Status: {ResponseCode(transfer_receipt.status).name}") + print( + f"✅ Test transfer succeeded. Token is unfrozen and usable, Status: {ResponseCode(transfer_receipt.status).name}" + ) except (RuntimeError, ValueError) as transfer_error: print(f"❌ Test transfer failed: {transfer_error}") except (RuntimeError, ValueError) as e: print(f"❌ Error unfreezing token: {e}") sys.exit(1) + def main(): - """ Unfreeze the token for the operator account. + """Unfreeze the token for the operator account. 1. Freeze the token for the operator account (calls freeze_token()). 2. Unfreeze the token for the operator account using TokenUnfreezeTransaction. 3. Attempt a test transfer of 1 unit of the token to self to verify unfreeze. @@ -139,5 +150,6 @@ def main(): freeze_token(token_id, client, operator_id, freeze_key) unfreeze_token(token_id, client, operator_id, freeze_key, operator_key) + if __name__ == "__main__": main() diff --git a/examples/tokens/token_unpause_transaction.py b/examples/tokens/token_unpause_transaction.py index c925ad3a2..857cf0b13 100644 --- a/examples/tokens/token_unpause_transaction.py +++ b/examples/tokens/token_unpause_transaction.py @@ -3,6 +3,7 @@ python examples/tokens/token_unpause_transaction.py """ + import os import sys from dotenv import load_dotenv @@ -18,11 +19,12 @@ TokenCreateTransaction, TokenUnpauseTransaction, TokenPauseTransaction, - TokenInfoQuery + TokenInfoQuery, ) load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -31,9 +33,9 @@ def setup_client(): network = Network(network_name) print(f"Connecting to Hedera {network_name} network!") client = Client(network) - - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") @@ -42,7 +44,12 @@ def setup_client(): print("❌ Error: Creating client, Please check your .env file") sys.exit(1) -def create_token(client: Client, operator_id: AccountId, pause_key: PrivateKey,): + +def create_token( + client: Client, + operator_id: AccountId, + pause_key: PrivateKey, +): """Create a fungible token""" print("\nCreating a token...") @@ -54,21 +61,22 @@ def create_token(client: Client, operator_id: AccountId, pause_key: PrivateKey,) .set_initial_supply(1) .set_treasury_account_id(operator_id) .set_token_type(TokenType.FUNGIBLE_COMMON) - .set_pause_key(pause_key) # Required for pausing tokens + .set_pause_key(pause_key) # Required for pausing tokens .freeze_with(client) ) - + receipt = token_tx.sign(pause_key).execute(client) - + token_id = receipt.token_id print(f"✅ Success! Created token: {token_id}") check_pause_status(client, token_id) - + return token_id except Exception as e: print(f"❌ Error creating token: {e}") sys.exit(1) + def pause_token(client: Client, token_id: TokenId, pause_key: PrivateKey): """Pause token""" print("\nAttempting to pause the token...") @@ -80,7 +88,7 @@ def pause_token(client: Client, token_id: TokenId, pause_key: PrivateKey): .freeze_with(client) .sign(pause_key) ) - + receipt = pause_tx.execute(client) if receipt.status == ResponseCode.SUCCESS: @@ -93,11 +101,12 @@ def pause_token(client: Client, token_id: TokenId, pause_key: PrivateKey): print(f"❌ Error pausing token: {e}") sys.exit(1) + def check_pause_status(client, token_id: TokenId): """Query and print the current paused/unpaused status of a token.""" info = TokenInfoQuery().set_token_id(token_id).execute(client) print(f"Token status is now: {info.pause_status.name}") - + def unpause_token(): pause_key = PrivateKey.generate() @@ -128,5 +137,6 @@ def unpause_token(): print(f"❌ Error pausing token: {e}") sys.exit(1) + if __name__ == "__main__": unpause_token() diff --git a/examples/tokens/token_update_nfts_transaction_nfts.py b/examples/tokens/token_update_nfts_transaction_nfts.py index cef1d1eec..1bc8caa2b 100644 --- a/examples/tokens/token_update_nfts_transaction_nfts.py +++ b/examples/tokens/token_update_nfts_transaction_nfts.py @@ -3,6 +3,7 @@ python examples/tokens/token_update_transaction_nfts.py """ + import os import sys from dotenv import load_dotenv @@ -19,11 +20,14 @@ from hiero_sdk_python.tokens.supply_type import SupplyType from hiero_sdk_python.tokens.token_create_transaction import TokenCreateTransaction from hiero_sdk_python.tokens.token_mint_transaction import TokenMintTransaction -from hiero_sdk_python.tokens.token_update_nfts_transaction import TokenUpdateNftsTransaction +from hiero_sdk_python.tokens.token_update_nfts_transaction import ( + TokenUpdateNftsTransaction, +) from hiero_sdk_python.query.token_nft_info_query import TokenNftInfoQuery load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -31,13 +35,14 @@ def setup_client(): print(f"Connecting to Hedera {network_name} network!") client = Client(network) - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client, operator_id, operator_key + def create_nft(client, operator_id, operator_key, metadata_key): """Create a non-fungible token""" receipt = ( @@ -56,18 +61,19 @@ def create_nft(client, operator_id, operator_key, metadata_key): .set_metadata_key(metadata_key) # Needed to update NFTs .execute(client) ) - + # Check if nft creation was successful if receipt.status != ResponseCode.SUCCESS: print(f"NFT creation failed with status: {ResponseCode(receipt.status).name}") sys.exit(1) - + # Get token ID from receipt nft_token_id = receipt.token_id print(f"NFT created with ID: {nft_token_id}") - + return nft_token_id + def mint_nfts(client, nft_token_id, metadata_list): """Mint a non-fungible token""" receipt = ( @@ -76,31 +82,33 @@ def mint_nfts(client, nft_token_id, metadata_list): .set_metadata(metadata_list) .execute(client) ) - + if receipt.status != ResponseCode.SUCCESS: print(f"NFT minting failed with status: {ResponseCode(receipt.status).name}") sys.exit(1) - + print(f"NFT minted with serial numbers: {receipt.serial_numbers}") - - return [NftId(nft_token_id, serial_number) for serial_number in receipt.serial_numbers], receipt.serial_numbers + + return [ + NftId(nft_token_id, serial_number) for serial_number in receipt.serial_numbers + ], receipt.serial_numbers + def get_nft_info(client, nft_id): """Get information about an NFT""" - info = ( - TokenNftInfoQuery() - .set_nft_id(nft_id) - .execute(client) - ) - + info = TokenNftInfoQuery().set_nft_id(nft_id).execute(client) + return info -def update_nft_metadata(client, nft_token_id, serial_numbers, new_metadata, metadata_private_key): + +def update_nft_metadata( + client, nft_token_id, serial_numbers, new_metadata, metadata_private_key +): """Update metadata for NFTs in a collection""" receipt = ( TokenUpdateNftsTransaction() .set_token_id(nft_token_id) - .set_serial_numbers(serial_numbers) + .set_serial_numbers(serial_numbers) .set_metadata(new_metadata) .freeze_with(client) .sign(metadata_private_key) # Has to be signed here by metadata_key @@ -108,10 +116,15 @@ def update_nft_metadata(client, nft_token_id, serial_numbers, new_metadata, meta ) if receipt.status != ResponseCode.SUCCESS: - print(f"NFT metadata update failed with status: {ResponseCode(receipt.status).name}") + print( + f"NFT metadata update failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) - print(f"Successfully updated metadata for NFTs with serial numbers: {serial_numbers}") + print( + f"Successfully updated metadata for NFTs with serial numbers: {serial_numbers}" + ) + def token_update_nfts(): """ @@ -124,38 +137,45 @@ def token_update_nfts(): 6. Verifying the updated NFT metadata """ client, operator_id, operator_key = setup_client() - + # Create metadata key metadata_private_key = PrivateKey.generate_ed25519() - + # Create a new NFT collection with the treasury account as owner nft_token_id = create_nft(client, operator_id, operator_key, metadata_private_key) - + # Initial metadata for our NFTs initial_metadata = [b"Initial metadata 1", b"Initial metadata 2"] - + # New metadata to update the first NFT new_metadata = b"Updated metadata1" - + # Mint 2 NFTs in the collection with initial metadata nft_ids, serial_numbers = mint_nfts(client, nft_token_id, initial_metadata) - + # Get and print information about the NFTs print("\nCheck that the NFTs have the initial metadata") for nft_id in nft_ids: nft_info = get_nft_info(client, nft_id) print(f"NFT ID: {nft_info.nft_id}, Metadata: {nft_info.metadata}") - + # Update metadata for specific NFTs by providing their id and serial numbers # Only the NFTs with the provided serial numbers will have their metadata updated serial_numbers_to_update = [serial_numbers[0]] - update_nft_metadata(client, nft_token_id, serial_numbers_to_update, new_metadata, metadata_private_key) - + update_nft_metadata( + client, + nft_token_id, + serial_numbers_to_update, + new_metadata, + metadata_private_key, + ) + # Get and print information about the NFTs print("\nCheck that only the first NFT has the updated metadata") for nft_id in nft_ids: nft_info = get_nft_info(client, nft_id) print(f"NFT ID: {nft_info.nft_id}, Metadata: {nft_info.metadata}") - + + if __name__ == "__main__": token_update_nfts() diff --git a/examples/tokens/token_update_transaction_fungible.py b/examples/tokens/token_update_transaction_fungible.py index 5d13575ac..aea1c9b68 100644 --- a/examples/tokens/token_update_transaction_fungible.py +++ b/examples/tokens/token_update_transaction_fungible.py @@ -3,6 +3,7 @@ python examples/tokens/token_update_transaction_fungible.py """ + import os import sys from dotenv import load_dotenv @@ -21,7 +22,8 @@ from hiero_sdk_python.tokens.token_update_transaction import TokenUpdateTransaction load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -29,22 +31,23 @@ def setup_client(): print(f"Connecting to Hedera {network_name} network!") client = Client(network) - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client, operator_id, operator_key + def create_fungible_token(client, operator_id, operator_key, metadata_key): """ Create a fungible token - + If we want to update metadata later using TokenUpdateTransaction: 1. Set a metadata_key and sign the update transaction with it, or 2. Sign the update transaction with the admin_key - - Note: If no Admin Key was assigned during token creation (immutable token), + + Note: If no Admin Key was assigned during token creation (immutable token), token updates will fail with TOKEN_IS_IMMUTABLE. """ receipt = ( @@ -63,29 +66,36 @@ def create_fungible_token(client, operator_id, operator_key, metadata_key): .set_metadata_key(metadata_key) .execute(client) ) - + # Check if token creation was successful if receipt.status != ResponseCode.SUCCESS: - print(f"Fungible token creation failed with status: {ResponseCode.get_name(receipt.status)}") + print( + f"Fungible token creation failed with status: {ResponseCode.get_name(receipt.status)}" + ) sys.exit(1) - + # Get token ID from receipt token_id = receipt.token_id print(f"Fungible token created with ID: {token_id}") - + return token_id + def get_token_info(client, token_id): """Get information about a fungible token""" - info = ( - TokenInfoQuery() - .set_token_id(token_id) - .execute(client) - ) - + info = TokenInfoQuery().set_token_id(token_id).execute(client) + return info -def update_token_data(client, token_id, update_metadata, update_token_name, update_token_symbol, update_token_memo): + +def update_token_data( + client, + token_id, + update_metadata, + update_token_name, + update_token_symbol, + update_token_memo, +): """Update metadata for a fungible token""" receipt = ( TokenUpdateTransaction() @@ -96,13 +106,16 @@ def update_token_data(client, token_id, update_metadata, update_token_name, upda .set_token_memo(update_token_memo) .execute(client) ) - + if receipt.status != ResponseCode.SUCCESS: - print(f"Token metadata update failed with status: {ResponseCode.get_name(receipt.status)}") + print( + f"Token metadata update failed with status: {ResponseCode.get_name(receipt.status)}" + ) sys.exit(1) - + print(f"Successfully updated token data") + def token_update_fungible(): """ Demonstrates the fungible token update functionality by: @@ -113,27 +126,37 @@ def token_update_fungible(): 5. Verifying the updated token info """ client, operator_id, operator_key = setup_client() - + # Create metadata key metadata_private_key = PrivateKey.generate_ed25519() - - token_id = create_fungible_token(client, operator_id, operator_key, metadata_private_key) - + + token_id = create_fungible_token( + client, operator_id, operator_key, metadata_private_key + ) + print("\nToken info before update:") token_info = get_token_info(client, token_id) print(token_info) - + # New data to update the fungible token update_metadata = b"Updated metadata" update_token_name = "Updated Token" update_token_symbol = "UPD" update_token_memo = "Updated memo" - - update_token_data(client, token_id, update_metadata, update_token_name, update_token_symbol, update_token_memo) - + + update_token_data( + client, + token_id, + update_metadata, + update_token_name, + update_token_symbol, + update_token_memo, + ) + print("\nToken info after update:") token_info = get_token_info(client, token_id) print(token_info) - + + if __name__ == "__main__": token_update_fungible() diff --git a/examples/tokens/token_update_transaction_key.py b/examples/tokens/token_update_transaction_key.py index f32852445..360e7cefc 100644 --- a/examples/tokens/token_update_transaction_key.py +++ b/examples/tokens/token_update_transaction_key.py @@ -1,9 +1,9 @@ - """ uv run examples/tokens/token_update_transaction_key.py python examples/tokens/token_update_transaction_key.py """ + import os import sys from dotenv import load_dotenv @@ -23,7 +23,8 @@ from hiero_sdk_python.tokens.token_update_transaction import TokenUpdateTransaction load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -31,13 +32,14 @@ def setup_client(): print(f"Connecting to Hedera {network_name} network!") client = Client(network) - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client, operator_id + def create_fungible_token(client, operator_id, admin_key, wipe_key): """Create a fungible token""" receipt = ( @@ -56,32 +58,32 @@ def create_fungible_token(client, operator_id, admin_key, wipe_key): .sign(admin_key) .execute(client) ) - + # Check if token creation was successful if receipt.status != ResponseCode.SUCCESS: - print(f"Fungible token creation failed with status: {ResponseCode.get_name(receipt.status)}") + print( + f"Fungible token creation failed with status: {ResponseCode.get_name(receipt.status)}" + ) sys.exit(1) - + # Get token ID from receipt token_id = receipt.token_id print(f"Fungible token created with ID: {token_id}") - + return token_id + def get_token_info(client, token_id): """Get information about a fungible token""" - info = ( - TokenInfoQuery() - .set_token_id(token_id) - .execute(client) - ) - + info = TokenInfoQuery().set_token_id(token_id).execute(client) + return info + def update_wipe_key_full_validation(client, token_id, old_wipe_key): """ Update token wipe key with full validation mode. - + This demonstrates using FULL_VALIDATION mode (default) which requires both old and new key signatures. This ensures that there cannot be an accidental update to a public key for which the user does not possess the private key. @@ -90,7 +92,7 @@ def update_wipe_key_full_validation(client, token_id, old_wipe_key): """ # Generate new wipe key new_wipe_key = PrivateKey.generate_ed25519() - + receipt = ( TokenUpdateTransaction() .set_token_id(token_id) @@ -101,17 +103,20 @@ def update_wipe_key_full_validation(client, token_id, old_wipe_key): .sign(old_wipe_key) .execute(client) ) - + if receipt.status != ResponseCode.SUCCESS: - print(f"Token update failed with status: {ResponseCode.get_name(receipt.status)}") + print( + f"Token update failed with status: {ResponseCode.get_name(receipt.status)}" + ) sys.exit(1) - + print(f"Successfully updated wipe key") # Query token info to verify wipe key update info = get_token_info(client, token_id) print(f"Token's wipe key after update: {info.wipe_key}") + def token_update_key(): """ Demonstrates updating keys on a fungible token by: @@ -121,19 +126,20 @@ def token_update_key(): 4. Updating the wipe key with full validation """ client, operator_id = setup_client() - + admin_key = PrivateKey.generate_ed25519() wipe_key = PrivateKey.generate_ed25519() - + token_id = create_fungible_token(client, operator_id, admin_key, wipe_key) - + print("\nToken info before update:") token_info = get_token_info(client, token_id) - + print(f"Token's wipe key after creation: {token_info.wipe_key}") print(f"Token's admin key after creation: {token_info.admin_key}") - + update_wipe_key_full_validation(client, token_id, wipe_key) - + + if __name__ == "__main__": token_update_key() diff --git a/examples/tokens/token_update_transaction_nft.py b/examples/tokens/token_update_transaction_nft.py index 19e4464a5..89b270944 100644 --- a/examples/tokens/token_update_transaction_nft.py +++ b/examples/tokens/token_update_transaction_nft.py @@ -3,6 +3,7 @@ python examples/tokens/token_update_transaction_nft.py """ + import os import sys from dotenv import load_dotenv @@ -21,7 +22,8 @@ from hiero_sdk_python.tokens.token_update_transaction import TokenUpdateTransaction load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -29,22 +31,23 @@ def setup_client(): print(f"Connecting to Hedera {network_name} network!") client = Client(network) - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client, operator_id, operator_key + def create_nft(client, operator_id, operator_key, metadata_key): """ Create a non-fungible token - + If we want to update metadata later using TokenUpdateTransaction: 1. Set a metadata_key and sign the update transaction with it, or 2. Sign the update transaction with the admin_key - - Note: If no Admin Key was assigned during token creation (immutable token), + + Note: If no Admin Key was assigned during token creation (immutable token), token updates will fail with TOKEN_IS_IMMUTABLE. """ receipt = ( @@ -63,29 +66,36 @@ def create_nft(client, operator_id, operator_key, metadata_key): .set_metadata_key(metadata_key) .execute(client) ) - + # Check if nft creation was successful if receipt.status != ResponseCode.SUCCESS: - print(f"NFT creation failed with status: {ResponseCode.get_name(receipt.status)}") + print( + f"NFT creation failed with status: {ResponseCode.get_name(receipt.status)}" + ) sys.exit(1) - + # Get token ID from receipt nft_token_id = receipt.token_id print(f"NFT created with ID: {nft_token_id}") - + return nft_token_id + def get_nft_info(client, nft_token_id): """Get information about an NFT""" - info = ( - TokenInfoQuery() - .set_token_id(nft_token_id) - .execute(client) - ) - + info = TokenInfoQuery().set_token_id(nft_token_id).execute(client) + return info -def update_nft_data(client, nft_token_id, update_metadata, update_token_name, update_token_symbol, update_token_memo): + +def update_nft_data( + client, + nft_token_id, + update_metadata, + update_token_name, + update_token_symbol, + update_token_memo, +): """Update data for an NFT""" receipt = ( TokenUpdateTransaction() @@ -96,13 +106,16 @@ def update_nft_data(client, nft_token_id, update_metadata, update_token_name, up .set_token_memo(update_token_memo) .execute(client) ) - + if receipt.status != ResponseCode.SUCCESS: - print(f"NFT data update failed with status: {ResponseCode.get_name(receipt.status)}") + print( + f"NFT data update failed with status: {ResponseCode.get_name(receipt.status)}" + ) sys.exit(1) - + print(f"Successfully updated NFT data") + def token_update_nft(): """ Demonstrates the NFT token update functionality by: @@ -113,27 +126,35 @@ def token_update_nft(): 5. Verifying the updated NFT info """ client, operator_id, operator_key = setup_client() - + # Create metadata key metadata_private_key = PrivateKey.generate_ed25519() - + nft_token_id = create_nft(client, operator_id, operator_key, metadata_private_key) - + print("\nNFT info before update:") nft_info = get_nft_info(client, nft_token_id) print(nft_info) - + # New data to update the NFT update_metadata = b"Updated metadata" update_token_name = "Updated NFT" update_token_symbol = "UPD" update_token_memo = "Updated memo" - - update_nft_data(client, nft_token_id, update_metadata, update_token_name, update_token_symbol, update_token_memo) - + + update_nft_data( + client, + nft_token_id, + update_metadata, + update_token_name, + update_token_symbol, + update_token_memo, + ) + print("\nNFT info after update:") nft_info = get_nft_info(client, nft_token_id) print(nft_info) - + + if __name__ == "__main__": token_update_nft() diff --git a/examples/tokens/token_wipe_transaction.py b/examples/tokens/token_wipe_transaction.py index 12ae5614f..f0a2c3816 100644 --- a/examples/tokens/token_wipe_transaction.py +++ b/examples/tokens/token_wipe_transaction.py @@ -2,6 +2,7 @@ uv run examples/tokens/token_wipe_transaction.py python examples/tokens/token_wipe_transaction.py """ + import os import sys from dotenv import load_dotenv @@ -23,7 +24,8 @@ from hiero_sdk_python.tokens.token_wipe_transaction import TokenWipeTransaction load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() + def setup_client(): """Initialize and set up the client with operator account""" @@ -33,19 +35,20 @@ def setup_client(): client = Client(network) # Set up operator account - operator_id = AccountId.from_string(os.getenv('OPERATOR_ID', '')) - operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY', '')) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client, operator_id, operator_key + def create_test_account(client): """Create a new account for testing""" # Generate private key for new account new_account_private_key = PrivateKey.generate() new_account_public_key = new_account_private_key.public_key() - + # Create new account with initial balance of 1 HBAR transaction = ( AccountCreateTransaction() @@ -53,20 +56,23 @@ def create_test_account(client): .set_initial_balance(Hbar(1)) .freeze_with(client) ) - + receipt = transaction.execute(client) - + # Check if account creation was successful if receipt.status != ResponseCode.SUCCESS: - print(f"Account creation failed with status: {ResponseCode(receipt.status).name}") + print( + f"Account creation failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) - + # Get account ID from receipt account_id = receipt.account_id print(f"New account created with ID: {account_id}") - + return account_id, new_account_private_key + def create_token(client, operator_id, operator_key): """Create a fungible token""" # Create fungible token @@ -81,26 +87,27 @@ def create_token(client, operator_id, operator_key): .set_token_type(TokenType.FUNGIBLE_COMMON) .set_supply_type(SupplyType.FINITE) .set_max_supply(100) - .set_admin_key(operator_key) # For token management - .set_supply_key(operator_key) # For minting/burning - .set_freeze_key(operator_key) # For freezing accounts - .set_wipe_key(operator_key) # Required for wiping tokens + .set_admin_key(operator_key) # For token management + .set_supply_key(operator_key) # For minting/burning + .set_freeze_key(operator_key) # For freezing accounts + .set_wipe_key(operator_key) # Required for wiping tokens .freeze_with(client) ) - + receipt = transaction.execute(client) - + # Check if token creation was successful if receipt.status != ResponseCode.SUCCESS: print(f"Token creation failed with status: {ResponseCode(receipt.status).name}") sys.exit(1) - + # Get token ID from receipt token_id = receipt.token_id print(f"Token created with ID: {token_id}") - + return token_id + def associate_token(client, account_id, token_id, account_private_key): """Associate a token with an account""" # Associate the token with the new account @@ -110,17 +117,20 @@ def associate_token(client, account_id, token_id, account_private_key): .set_account_id(account_id) .add_token_id(token_id) .freeze_with(client) - .sign(account_private_key) # Has to be signed by new account's key + .sign(account_private_key) # Has to be signed by new account's key ) - + receipt = associate_transaction.execute(client) - + if receipt.status != ResponseCode.SUCCESS: - print(f"Token association failed with status: {ResponseCode(receipt.status).name}") + print( + f"Token association failed with status: {ResponseCode(receipt.status).name}" + ) sys.exit(1) - + print("Token successfully associated with account") + def transfer_tokens(client, token_id, operator_id, account_id, amount): """Transfer tokens from operator to the specified account""" # Transfer tokens to the new account @@ -128,19 +138,20 @@ def transfer_tokens(client, token_id, operator_id, account_id, amount): transfer_transaction = ( TransferTransaction() .add_token_transfer(token_id, operator_id, -amount) # From operator - .add_token_transfer(token_id, account_id, amount) # To new account + .add_token_transfer(token_id, account_id, amount) # To new account .freeze_with(client) ) - + receipt = transfer_transaction.execute(client) - + # Check if token transfer was successful if receipt.status != ResponseCode.SUCCESS: print(f"Token transfer failed with status: {ResponseCode(receipt.status).name}") sys.exit(1) - + print(f"Successfully transferred {amount} tokens to account {account_id}") + def wipe_tokens(client, token_id, account_id, amount): """Wipe tokens from the specified account""" # Wipe the tokens from the account @@ -152,15 +163,16 @@ def wipe_tokens(client, token_id, account_id, amount): .set_amount(amount) .freeze_with(client) ) - + receipt = transaction.execute(client) - + if receipt.status != ResponseCode.SUCCESS: print(f"Token wipe failed with status: {ResponseCode(receipt.status).name}") sys.exit(1) - + print(f"Successfully wiped {amount} tokens from account {account_id}") + def token_wipe(): """ Demonstrates the token wipe functionality by: @@ -174,10 +186,11 @@ def token_wipe(): account_id, new_account_private_key = create_test_account(client) token_id = create_token(client, operator_id, operator_key) associate_token(client, account_id, token_id, new_account_private_key) - + amount = 10 transfer_tokens(client, token_id, operator_id, account_id, amount) wipe_tokens(client, token_id, account_id, amount) + if __name__ == "__main__": token_wipe()