Skip to content

Commit fe2b9f1

Browse files
committed
chore: Adapt custom_fee_royalty.py to be end-to-end #679
Signed-off-by: Prakhar Sharma <prakharsharma_mc24b06_001@dtu.ac.in>
1 parent 348c875 commit fe2b9f1

File tree

2 files changed

+108
-28
lines changed

2 files changed

+108
-28
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
2727
- fix: Replaced `collections.namedtuple` with `typing.NamedTuple` in `client.py` for improved type checking.
2828
- chore: Refactored examples/custom_fee.py into three separate example files.
2929
- Expanded `docs/sdk_developers/checklist.md` with a self-review guide for all pull request submission requirements (#645).
30+
- chore: Adapt examples/custom_fee_royalty.py to be a full end-to-end example (#679)
3031

3132

3233

@@ -37,7 +38,6 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
3738
- fix: Resolve `__eq__` type conflict in `CustomFee` class (#627)
3839

3940
### Breaking Changes
40-
4141
## [0.1.7] - 2025-10-28
4242

4343
### Added

examples/custom_fee_royalty.py

Lines changed: 107 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,117 @@
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
88
from 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"\nQuerying 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("\nCustomRoyaltyFee:")
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"\nAn error occurred: {e}")
35115

36116
if __name__ == "__main__":
37-
custom_royalty_fee()
117+
main()

0 commit comments

Comments
 (0)