Skip to content
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
- `alias`, `staked_account_id`, `staked_node_id` and `decline_staking_reward` fields to AccountCreateTransaction
- `staked_account_id`, `staked_node_id` and `decline_staking_reward` fields to AccountInfo
- Added `examples/token_create_transaction_supply_key.py` to demonstrate token creation with and without a supply key.
- Added `examples/token_create_transaction_kyc_key.py` to demonstrate KYC key functionality, including creating tokens with/without KYC keys, granting/revoking KYC status, and understanding KYC requirements for token transfers.
- Added BatchTransaction class
- Add support for token metadata (bytes, max 100 bytes) in `TokenCreateTransaction`, including a new `set_metadata` setter, example, and tests. [#799]

- Added `examples/token_create_transaction_token_fee_schedule.py` to demonstrate creating tokens with custom fee schedules and the consequences of not having it.
- Added `examples/token_create_transaction_wipe_key.py` to demonstrate token wiping and the role of the wipe key.
- Refactored examples/transfer_token.py into modular functions (setup_client(), create_account(), create_token(), associate_token(), transfer_tokens()) and introduced a clear main() execution flow for improved readability, reuse, and maintainability while preserving identical runtime behavior (#773).

### Changed
- Upgraded step-security/harden-runner v2.13.2
Expand Down
60 changes: 29 additions & 31 deletions examples/transfer_token.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""
uv run examples/transfer_token.py
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Raja-89 , this file is now renamed to examples/transaction/transfer_transaction_fungible.py.

cc- @exploreriii

python examples/transfer_token.py

"""
import os
import sys
Expand All @@ -23,18 +22,18 @@
load_dotenv()
network_name = os.getenv('NETWORK', 'testnet').lower()


def setup_client():
"""Initialize and set up the client with operator account"""
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: Creating client, Please check your .env file")
Expand All @@ -55,12 +54,13 @@ def create_account(client, operator_key):
recipient_id = receipt.account_id
print(f"✅ Success! Created a new recipient account with ID: {recipient_id}")
return recipient_id, recipient_key

except Exception as e:
print(f"Error creating new account: {e}")
sys.exit(1)


def create_token(client, operator_id, operator_key):
"""Create a new token"""
print("\nSTEP 2: Creating a new token...")
try:
token_tx = (
Expand All @@ -81,7 +81,9 @@ def create_token(client, operator_id, operator_key):
print(f"❌ Error creating token: {e}")
sys.exit(1)


def associate_token(client, recipient_id, recipient_key, token_id):
"""Associate token with the recipient"""
print("\nSTEP 3: Associating Token...")
try:
association_tx = (
Expand All @@ -96,57 +98,53 @@ def associate_token(client, recipient_id, recipient_key, token_id):
print(f"❌ Error associating token: {e}")
sys.exit(1)

def transfer_tokens():
"""
A full example to create a new recipent account, a fungible token, and
transfer the token to that account
"""
# Config Client
client, operator_id, operator_key = setup_client()

# Create a new recipient account.
recipient_id, recipient_key = create_account(client, operator_key)

# Create new tokens.
token_id = create_token(client, operator_id, operator_key)

# Associate Token
associate_token(client, recipient_id, recipient_key, token_id)

# Transfer Token
print("\nSTEP 4: Transfering Token...")
def transfer_tokens(client, operator_id, operator_key, recipient_id, token_id):
"""Perform the token transfer"""
print("\nSTEP 4: Transferring Token...")
try:
# Check balance before transfer
# Check balance before
balance_before = (
CryptoGetAccountBalanceQuery(account_id=recipient_id)
.execute(client)
.token_balances
)
print("Token balance before token transfer:")
print("Token balance before transfer:")
print(f"{token_id}: {balance_before.get(token_id)}")

transfer_tx = (
tx = (
TransferTransaction()
.add_token_transfer(token_id, operator_id, -1)
.add_token_transfer(token_id, recipient_id, 1)
.freeze_with(client)
.sign(operator_key)
)
transfer_tx.execute(client)
tx.execute(client)

print("\n✅ Success! Token transfer complete.\n")

# Check balance after transfer
# Check balance after
balance_after = (
CryptoGetAccountBalanceQuery(account_id=recipient_id)
.execute(client)
.token_balances
)
print("Token balance after token transfer:")
print("Token balance after transfer:")
print(f"{token_id}: {balance_after.get(token_id)}")

except Exception as e:
print(f"❌ Error transferring token: {str(e)}")
sys.exit(1)


def main():
"""Main script runner"""
client, operator_id, operator_key = setup_client()
recipient_id, recipient_key = create_account(client, operator_key)
token_id = create_token(client, operator_id, operator_key)
associate_token(client, recipient_id, recipient_key, token_id)
transfer_tokens(client, operator_id, operator_key, recipient_id, token_id)


if __name__ == "__main__":
transfer_tokens()
main()