Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
- Transformed `examples/tokens/custom_fee_fixed.py` to be an end-to-end example, that interacts with the Hedera network, rather than a static object demo.
- Format token examples with Black for consistent code style and improved readability (#1119)
- Replaced `ResponseCode.get_name(receipt.status)` with the `ResponseCode(receipt.status).name` across examples and integration tests for consistency. (#1136)
- Transformed `examples/tokens/custom_fee_royalty.py` to be an end-to-end example, that interacts with the Hedera network, rather than a static object demo.



Expand Down
117 changes: 104 additions & 13 deletions examples/tokens/custom_fee_royalty.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,122 @@
python examples/tokens/custom_royalty_fee.py
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

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

The filename in the comment is incorrect. It should be 'custom_fee_royalty.py' to match the actual filename, not 'custom_royalty_fee.py'.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

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

your file name should be custom_royalty_fee.py to match the exact src name
src/hiero_sdk_python/tokens/custom_royalty_fee.py

"""

import os
import sys
from dotenv import load_dotenv

from hiero_sdk_python.client.network import Network
from hiero_sdk_python.crypto.private_key import PrivateKey
from hiero_sdk_python.client.client import Client
from hiero_sdk_python.query.token_info_query import TokenInfoQuery
from hiero_sdk_python.account.account_id import AccountId
from hiero_sdk_python.response_code import ResponseCode
from hiero_sdk_python.tokens.supply_type import SupplyType
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
from hiero_sdk_python.hbar import Hbar
from hiero_sdk_python.tokens.token_create_transaction import TokenCreateTransaction
from hiero_sdk_python.tokens.token_type import TokenType
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 the Hedera {network_name} network")
client = Client(network)

try:
operator_id_str = os.getenv('OPERATOR_ID')
operator_key_str = os.getenv('OPERATOR_KEY')

if not operator_id_str or not operator_key_str:
raise ValueError("Environment variables OPERATOR_ID or OPERATOR_KEY are missing.")

def custom_royalty_fee():
operator_id = AccountId.from_string(operator_id_str)
operator_key = PrivateKey.from_string(operator_key_str)

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) as e:
print(f"Error: {e}")
print("Please check OPERATOR_ID and OPERATOR_KEY in your .env file.")
sys.exit(1)

def custom_royalty_fee_example():
"""Demonstrates how to create a token with a custom royalty fee."""

client, operator_id, operator_key = setup_client()



print("\n--- Creating Custom Royalty Fee ---")

fallback_fee = CustomFixedFee(
amount=50,
denominating_token_id=TokenId(0, 0, 789),
amount=Hbar(1).to_tinybars(),
fee_collector_account_id=operator_id,
all_collectors_are_exempt=False
)

royalty_fee = CustomRoyaltyFee(
numerator=5,
numerator=5,
denominator=100,
fallback_fee=fallback_fee,
fee_collector_account_id=AccountId(0, 0, 456),
all_collectors_are_exempt=True,
fee_collector_account_id=operator_id,
all_collectors_are_exempt=False
)
print(royalty_fee)

print(f"Royalty Fee Configured: 5/100 (5%)")
print(f"Fallback Fee: 1 HBAR")

print(f"\n--- Creating Token with Royalty Fee ---")
transaction = (
TokenCreateTransaction()
.set_token_name("Royalty NFT Collection")
.set_token_symbol("RNFT")
.set_treasury_account_id(operator_id)
.set_admin_key(operator_key)
.set_supply_key(operator_key)
.set_token_type(TokenType.NON_FUNGIBLE_UNIQUE)
.set_decimals(0)
.set_initial_supply(0)
.set_supply_type(SupplyType.FINITE)
.set_max_supply(100)
.set_custom_fees([royalty_fee])
.freeze_with(client)
.sign(operator_key)
)

try:
# Execute the transaction
receipt = transaction.execute(client)

if receipt.status != ResponseCode.SUCCESS:
print(f"Transaction failed with status: {ResponseCode(receipt.status).name}")
return
Comment on lines +100 to +102
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

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

Missing early return after error status check. When the transaction fails (line 103-105), the function should return early to prevent executing the remaining code. Without this return, the code will continue to line 107 and attempt to access receipt.token_id, which may not be set when the transaction fails, potentially causing an error.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

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

yes


token_id = receipt.token_id
print(f"Token created successfully with ID: {token_id}")

# Convert to protobuf
royalty_fee_proto = royalty_fee._to_proto()
print("\n--- Verifying Fee on Network ---")
token_info = TokenInfoQuery().set_token_id(token_id).execute(client)

print("Royalty Fee Protobuf:", royalty_fee_proto)
retrieved_fees = token_info.custom_fees
if retrieved_fees:
print(f"Success! Found {len(retrieved_fees)} custom fee(s) on token.")
for fee in retrieved_fees:
print(fee)
else:
print("Error: No custom fees found on the token.")

except Exception as e:
print(f"Transaction failed: {e}")
sys.exit(1)
finally:
client.close()
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

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

Instance of context-manager class Client is closed in a finally block. Consider using 'with' statement.

Copilot uses AI. Check for mistakes.

if __name__ == "__main__":
custom_royalty_fee()
custom_royalty_fee_example()
Loading