11"""
2- Run with:
3- uv run examples/custom_royalty_fee.py
4- python examples/custom_royalty_fee.py
2+ End-to-end example for creating a Non-Fungible Token (NFT)
3+ with a custom royalty fee on the Hedera testnet.
54"""
6- from hiero_sdk_python .tokens .custom_fixed_fee import CustomFixedFee
7- from hiero_sdk_python .tokens .custom_royalty_fee import CustomRoyaltyFee
5+
6+ import os
7+ from dotenv import load_dotenv
88from hiero_sdk_python .account .account_id import AccountId
9- from hiero_sdk_python .tokens .token_id import TokenId
9+ from hiero_sdk_python .client .client import Client
10+ from hiero_sdk_python .custom_fees .custom_royalty_fee import CustomRoyaltyFee
11+ from hiero_sdk_python .token .token_create_transaction import TokenCreateTransaction
12+ from hiero_sdk_python .token .token_info_query import TokenInfoQuery
13+ from hiero_sdk_python .token .token_type import TokenType
14+ from hiero_sdk_python .token .token_supply_type import TokenSupplyType
15+ from hiero_sdk_python .key .key import Key
16+ from hiero_sdk_python .hbar .hbar import Hbar
17+
18+ def set_up_client () -> Client :
19+ """
20+ Sets up and returns the Hedera client.
21+ (Copied from other examples for consistency)
22+ """
23+ load_dotenv ()
24+ try :
25+ operator_id_str = os .environ ["OPERATOR_ID" ]
26+ operator_key_str = os .environ ["OPERATOR_KEY" ]
27+ except KeyError :
28+ raise Exception ("OPERATOR_ID and OPERATOR_KEY env variables must be set" )
29+
30+ client = Client .for_testnet ()
31+ client .set_operator (AccountId .from_string (operator_id_str ), Key .from_string (operator_key_str ))
32+ return client
1033
11- def custom_royalty_fee ():
12- fallback_fee = CustomFixedFee (
13- amount = 50 ,
14- denominating_token_id = TokenId (0 , 0 , 789 ),
34+ def create_token_with_fee (client : Client , fee : CustomRoyaltyFee ) -> AccountId :
35+ """
36+ Creates a new Non-Fungible Token (NFT) with a custom royalty fee.
37+ Royalty fees can only be applied to NON_FUNGIBLE_UNIQUE token types.
38+ """
39+ print ("Creating a new NFT with a custom royalty fee..." )
40+
41+ operator_id = client .operator_account_id
42+ operator_key = client .operator_private_key
43+
44+ # Create the TokenCreateTransaction
45+ tx = TokenCreateTransaction (
46+ token_name = "My Royalty NFT" ,
47+ token_symbol = "MRNFT" ,
48+ token_type = TokenType .NON_FUNGIBLE_UNIQUE ,
49+ supply_type = TokenSupplyType .FINITE ,
50+ treasury_account_id = operator_id ,
51+ # Add the custom fee we defined
52+ custom_fees = [fee ],
53+ admin_key = operator_key ,
54+ supply_key = operator_key ,
55+ max_supply = 100 ,
56+ # Set transaction fee
57+ max_transaction_fee = Hbar (30 )
1558 )
59+
60+ # Sign and execute
61+ submitted_tx = tx .execute (client )
62+ receipt = submitted_tx .get_receipt (client )
63+ token_id = receipt .token_id
64+
65+ print (f"Successfully created token with ID: { token_id } " )
66+ return token_id
67+
68+ def query_token (client : Client , token_id : AccountId ):
69+ """
70+ Queries the token info to verify the custom fee.
71+ """
72+ print (f"\n Querying token { token_id } for custom fee verification..." )
73+
74+ token_info = TokenInfoQuery ().set_token_id (token_id ).execute (client )
75+
76+ print (f"Found { len (token_info .custom_fees )} custom fees." )
77+
78+ if token_info .custom_fees :
79+ # Access the first fee (we only added one)
80+ fee = token_info .custom_fees [0 ]
81+ if isinstance (fee , CustomRoyaltyFee ):
82+ print ("Verified: CustomRoyaltyFee found." )
83+ print (f" Numerator: { fee .numerator } " )
84+ print (f" Denominator: { fee .denominator } " )
85+ print (f" Fee Collector: { fee .fee_collector_account_id } " )
86+ else :
87+ print (f"Verified: Found a fee, but it's not a Royalty Fee. Type: { type (fee )} " )
88+ else :
89+ print ("Error: No custom fees found on the token." )
90+
91+ def main ():
92+ """
93+ Main function to orchestrate the end-to-end example.
94+ """
95+ client = set_up_client ()
96+ operator_id = client .operator_account_id
97+
98+
99+ # This will be a 10/100 (10%) royalty fee, paid to the operator's account
16100 royalty_fee = CustomRoyaltyFee (
17- numerator = 5 ,
101+ numerator = 10 ,
18102 denominator = 100 ,
19- fallback_fee = fallback_fee ,
20- fee_collector_account_id = AccountId (0 , 0 , 456 ),
21- all_collectors_are_exempt = True ,
103+ fallback_fee = None , # No fallback fee for this example
104+ fee_collector_account_id = operator_id
22105 )
23- print ("\n CustomRoyaltyFee:" )
24- print (f"Numerator: { royalty_fee .numerator } " )
25- print (f"Denominator: { royalty_fee .denominator } " )
26- print (f"Fallback Fee Amount: { royalty_fee .fallback_fee .amount if royalty_fee .fallback_fee is not None else 'None' } " )
27- print (f"Fallback Fee Denominating Token ID: { royalty_fee .fallback_fee .denominating_token_id if royalty_fee .fallback_fee is not None else 'None' } " )
28- print (f"Fee Collector Account ID: { royalty_fee .fee_collector_account_id } " )
29- print (f"All Collectors Exempt: { royalty_fee .all_collectors_are_exempt } " )
30-
31- # Convert to protobuf
32- royalty_fee_proto = royalty_fee ._to_proto ()
33-
34- print ("Royalty Fee Protobuf:" , royalty_fee_proto )
106+
107+ try :
108+
109+ token_id = create_token_with_fee (client , royalty_fee )
110+
111+
112+ query_token (client , token_id )
113+ except Exception as e :
114+ print (f"\n An error occurred: { e } " )
35115
36116if __name__ == "__main__" :
37- custom_royalty_fee ()
117+ main ()
0 commit comments