Skip to content

Commit 422ff48

Browse files
Merge branch 'main' of https://github.com/tech0priyanshu/hiero-sdk-python into feat/add-token-airdrop
2 parents 9b4cafe + b3d33a1 commit 422ff48

27 files changed

+5159
-396
lines changed

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,31 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
1313
- add revenue generating topic tests/example
1414
- add fee_schedule_key, fee_exempt_keys, custom_fees fields in TopicCreateTransaction, TopicUpdateTransaction, TopicInfo classes
1515
- add CustomFeeLimit class
16+
- TokenNftAllowance class
17+
- TokenAllowance class
18+
- HbarAllowance class
19+
- HbarTransfer class
20+
- AccountAllowanceApproveTransaction class
21+
- AccountAllowanceDeleteTransaction class
22+
- Approved transfer support to TransferTransaction
23+
- set_transaction_id() API to Transaction class
24+
- Allowance examples (hbar_allowance.py, token_allowance.py, nft_allowance.py)
25+
26+
### Changed
27+
- TransferTransaction refactored to use TokenTransfer and HbarTransfer classes instead of dictionaries
1628
- Added checksum validation for TokenId
29+
- Refactor examples/token_cancel_airdrop
30+
31+
### Changed
32+
33+
- Refactor token_associate.py for better structure, add association verification query (#367)
34+
- Refactored `examples/account_create.py` to improve modularity and readability (#363)
35+
- Replace Hendrik Ebbers with Sophie Bulloch in the MAINTAINERS.md file
1736

1837
### Fixed
1938

2039
- Incompatible Types assignment in token_transfer_list.py
40+
- Corrected references to __require_not_frozen() to _require_not_frozen() and removed the surplus _is_frozen
2141

2242
## [0.1.5] - 2025-09-25
2343

MAINTAINERS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Maintainers are assigned the following scopes in this repository:
1919
| Name | GitHub ID | Scope | LFID | Discord ID | Email | Company Affiliation |
2020
| -------------- | ------------- | ----- | ---- | -------------- | ----- | ------------------- |
2121
| Nadine Loepfe | nadineloepfe | | | nadine_90669 | | Hashgraph |
22-
| Hendrik Ebbers | hendrikebbers | | | hendrik.ebbers | | Hashgraph |
22+
| Sophie Bulloch | exploreriii | | | explorer3 | | |
2323
| Richard Bair | rbair23 | | | rbair | | Hashgraph |
2424

2525

examples/account_create.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,17 @@
1818

1919
load_dotenv()
2020

21-
def create_new_account():
21+
def setup_client():
2222
network = Network(network='testnet')
2323
client = Client(network)
2424

2525
operator_id = AccountId.from_string(os.getenv('OPERATOR_ID'))
2626
operator_key = PrivateKey.from_string(os.getenv('OPERATOR_KEY'))
2727
client.set_operator(operator_id, operator_key)
2828

29+
return client, operator_key
30+
31+
def create_new_account(client, operator_key):
2932
new_account_private_key = PrivateKey.generate("ed25519")
3033
new_account_public_key = new_account_private_key.public_key()
3134

@@ -60,4 +63,5 @@ def create_new_account():
6063
sys.exit(1)
6164

6265
if __name__ == "__main__":
63-
create_new_account()
66+
client, operator_key = setup_client()
67+
create_new_account(client, operator_key)

examples/hbar_allowance.py

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
"""
2+
Example demonstrating hbar allowance approval and usage.
3+
"""
4+
5+
import os
6+
import sys
7+
8+
from dotenv import load_dotenv
9+
10+
from hiero_sdk_python import AccountId, Client, Hbar, Network, PrivateKey, TransactionId
11+
from hiero_sdk_python.account.account_allowance_approve_transaction import (
12+
AccountAllowanceApproveTransaction,
13+
)
14+
from hiero_sdk_python.account.account_create_transaction import AccountCreateTransaction
15+
from hiero_sdk_python.response_code import ResponseCode
16+
from hiero_sdk_python.transaction.transfer_transaction import TransferTransaction
17+
18+
load_dotenv()
19+
20+
21+
def setup_client():
22+
"""Initialize and set up the client with operator account"""
23+
network = Network(network="testnet")
24+
client = Client(network)
25+
26+
operator_id = AccountId.from_string(os.getenv("OPERATOR_ID"))
27+
operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY"))
28+
client.set_operator(operator_id, operator_key)
29+
30+
return client
31+
32+
33+
def create_account(client):
34+
"""Create an account"""
35+
account_private_key = PrivateKey.generate_ed25519()
36+
account_public_key = account_private_key.public_key()
37+
38+
account_receipt = (
39+
AccountCreateTransaction()
40+
.set_key(account_public_key)
41+
.set_initial_balance(Hbar(1))
42+
.set_account_memo("Account for hbar allowance")
43+
.execute(client)
44+
)
45+
46+
if account_receipt.status != ResponseCode.SUCCESS:
47+
print(f"Account creation failed with status: {ResponseCode(account_receipt.status).name}")
48+
sys.exit(1)
49+
50+
account_account_id = account_receipt.account_id
51+
52+
return account_account_id, account_private_key
53+
54+
55+
def approve_hbar_allowance(client, owner_account_id, spender_account_id, amount):
56+
"""Approve Hbar allowance for spender"""
57+
receipt = (
58+
AccountAllowanceApproveTransaction()
59+
.approve_hbar_allowance(owner_account_id, spender_account_id, amount)
60+
.execute(client)
61+
)
62+
63+
if receipt.status != ResponseCode.SUCCESS:
64+
print(f"Hbar allowance approval failed with status: {ResponseCode(receipt.status).name}")
65+
sys.exit(1)
66+
67+
print(f"Hbar allowance of {amount} approved for spender {spender_account_id}")
68+
return receipt
69+
70+
71+
def delete_hbar_allowance(client, owner_account_id, spender_account_id):
72+
"""Delete hbar allowance by setting amount to 0"""
73+
receipt = (
74+
AccountAllowanceApproveTransaction()
75+
.approve_hbar_allowance(owner_account_id, spender_account_id, Hbar(0))
76+
.execute(client)
77+
)
78+
79+
if receipt.status != ResponseCode.SUCCESS:
80+
print(f"Hbar allowance deletion failed with status: {ResponseCode(receipt.status).name}")
81+
sys.exit(1)
82+
83+
print(f"Hbar allowance deleted for spender {spender_account_id}")
84+
return receipt
85+
86+
87+
def transfer_hbar_without_allowance(client, spender_account_id, spender_private_key, amount):
88+
"""Transfer hbars without allowance"""
89+
print("Trying to transfer hbars without allowance...")
90+
owner_account_id = client.operator_account_id
91+
client.set_operator(spender_account_id, spender_private_key) # Set operator to spender
92+
93+
receipt = (
94+
TransferTransaction()
95+
.add_approved_hbar_transfer(owner_account_id, -amount.to_tinybars())
96+
.add_approved_hbar_transfer(spender_account_id, amount.to_tinybars())
97+
.execute(client)
98+
)
99+
100+
if receipt.status != ResponseCode.SPENDER_DOES_NOT_HAVE_ALLOWANCE:
101+
print(
102+
f"Hbar transfer should have failed with SPENDER_DOES_NOT_HAVE_ALLOWANCE "
103+
f"status but got: {ResponseCode(receipt.status).name}"
104+
)
105+
106+
print(f"Hbar transfer successfully failed with {ResponseCode(receipt.status).name} status")
107+
108+
109+
def hbar_allowance():
110+
"""
111+
Demonstrates hbar allowance functionality by:
112+
1. Setting up client with operator account
113+
2. Creating spender and receiver accounts
114+
3. Approving hbar allowance for spender
115+
4. Transferring hbars using the allowance
116+
5. Deleting the allowance
117+
6. Attempting to transfer hbars without allowance (should fail)
118+
"""
119+
client = setup_client()
120+
121+
# Create spender and receiver accounts
122+
spender_id, spender_private_key = create_account(client)
123+
print(f"Spender account created with ID: {spender_id}")
124+
125+
receiver_id, _ = create_account(client)
126+
print(f"Receiver account created with ID: {receiver_id}")
127+
128+
# Approve hbar allowance for spender
129+
allowance_amount = Hbar(2)
130+
131+
approve_hbar_allowance(client, client.operator_account_id, spender_id, allowance_amount)
132+
133+
# Transfer hbars using the allowance
134+
receipt = (
135+
TransferTransaction()
136+
.set_transaction_id(TransactionId.generate(spender_id))
137+
.add_approved_hbar_transfer(client.operator_account_id, -allowance_amount.to_tinybars())
138+
.add_approved_hbar_transfer(receiver_id, allowance_amount.to_tinybars())
139+
.freeze_with(client)
140+
.sign(spender_private_key)
141+
.execute(client)
142+
)
143+
144+
if receipt.status != ResponseCode.SUCCESS:
145+
print(f"Hbar transfer failed with status: {ResponseCode(receipt.status).name}")
146+
sys.exit(1)
147+
148+
print(f"Successfully transferred {allowance_amount} from", end=" ")
149+
print(f"{client.operator_account_id} to {receiver_id} using allowance")
150+
151+
# Delete allowance
152+
delete_hbar_allowance(client, client.operator_account_id, spender_id)
153+
154+
# Try to transfer hbars without allowance
155+
transfer_hbar_without_allowance(client, spender_id, spender_private_key, allowance_amount)
156+
157+
158+
if __name__ == "__main__":
159+
hbar_allowance()

0 commit comments

Comments
 (0)