11"""
22Example demonstrating hbar allowance approval and usage.
3- Run:
4- uv run examples/account/account_allowance_approve_transaction_hbar.py
53"""
64
75import os
1816from hiero_sdk_python .transaction .transfer_transaction import TransferTransaction
1917
2018load_dotenv ()
21- network_name = os .getenv (' NETWORK' , ' testnet' ).lower ()
19+ network_name = os .getenv (" NETWORK" , " testnet" ).lower ()
2220
23- def setup_client ():
24- """Initialize and set up the client with operator account"""
21+
22+ def setup_client () -> Client :
23+ """Initialize and set up the client with operator account using env vars."""
2524 network = Network (network_name )
2625 print (f"Connecting to Hedera { network_name } network!" )
2726 client = Client (network )
2827
29- operator_id = AccountId .from_string (os .getenv ("OPERATOR_ID" ,"" ))
30- operator_key = PrivateKey .from_string (os .getenv ("OPERATOR_KEY" ,"" ))
28+ operator_id = AccountId .from_string (os .getenv ("OPERATOR_ID" , "" ))
29+ operator_key = PrivateKey .from_string (os .getenv ("OPERATOR_KEY" , "" ))
3130 client .set_operator (operator_id , operator_key )
3231 print (f"Client set up with operator id { client .operator_account_id } " )
3332
3433 return client
3534
3635
37- def create_account (client ):
38- """Create an account"""
36+ def create_account (client : Client ):
37+ """Create a new Hedera account with initial balance. """
3938 account_private_key = PrivateKey .generate_ed25519 ()
4039 account_public_key = account_private_key .public_key ()
4140
@@ -48,77 +47,80 @@ def create_account(client):
4847 )
4948
5049 if account_receipt .status != ResponseCode .SUCCESS :
51- print (f"Account creation failed with status: { ResponseCode (account_receipt .status ).name } " )
50+ print (
51+ "Account creation failed with status: "
52+ f"{ ResponseCode (account_receipt .status ).name } "
53+ )
5254 sys .exit (1 )
5355
5456 account_account_id = account_receipt .account_id
5557
5658 return account_account_id , account_private_key
5759
5860
59- def approve_hbar_allowance (client , owner_account_id , spender_account_id , amount ):
60- """Approve Hbar allowance for spender"""
61+ def approve_hbar_allowance (
62+ client : Client ,
63+ owner_account_id : AccountId ,
64+ spender_account_id : AccountId ,
65+ amount : Hbar ,
66+ ):
67+ """Approve Hbar allowance for spender."""
6168 receipt = (
6269 AccountAllowanceApproveTransaction ()
6370 .approve_hbar_allowance (owner_account_id , spender_account_id , amount )
6471 .execute (client )
6572 )
6673
6774 if receipt .status != ResponseCode .SUCCESS :
68- print (f"Hbar allowance approval failed with status: { ResponseCode (receipt .status ).name } " )
75+ print (
76+ "Hbar allowance approval failed with status: "
77+ f"{ ResponseCode (receipt .status ).name } "
78+ )
6979 sys .exit (1 )
7080
7181 print (f"Hbar allowance of { amount } approved for spender { spender_account_id } " )
7282 return receipt
7383
7484
75- def delete_hbar_allowance (client , owner_account_id , spender_account_id ):
76- """Delete hbar allowance by setting amount to 0"""
85+ def transfer_hbar_with_allowance (
86+ client : Client ,
87+ owner_account_id : AccountId ,
88+ spender_account_id : AccountId ,
89+ spender_private_key : PrivateKey ,
90+ receiver_account_id : AccountId ,
91+ amount : Hbar ,
92+ ):
93+ """Transfer hbars using a previously approved allowance."""
7794 receipt = (
78- AccountAllowanceApproveTransaction ()
79- .approve_hbar_allowance (owner_account_id , spender_account_id , Hbar (0 ))
95+ TransferTransaction ()
96+ # Transaction is paid for / initiated by spender
97+ .set_transaction_id (TransactionId .generate (spender_account_id ))
98+ .add_approved_hbar_transfer (owner_account_id , - amount .to_tinybars ())
99+ .add_approved_hbar_transfer (receiver_account_id , amount .to_tinybars ())
100+ .freeze_with (client )
101+ .sign (spender_private_key )
80102 .execute (client )
81103 )
82104
83105 if receipt .status != ResponseCode .SUCCESS :
84- print (f"Hbar allowance deletion failed with status: { ResponseCode (receipt .status ).name } " )
106+ print (f"Hbar transfer failed with status: { ResponseCode (receipt .status ).name } " )
85107 sys .exit (1 )
86108
87- print (f"Hbar allowance deleted for spender { spender_account_id } " )
88- return receipt
89-
90-
91- def transfer_hbar_without_allowance (client , spender_account_id , spender_private_key , amount ):
92- """Transfer hbars without allowance"""
93- print ("Trying to transfer hbars without allowance..." )
94- owner_account_id = client .operator_account_id
95- client .set_operator (spender_account_id , spender_private_key ) # Set operator to spender
96-
97- receipt = (
98- TransferTransaction ()
99- .add_approved_hbar_transfer (owner_account_id , - amount .to_tinybars ())
100- .add_approved_hbar_transfer (spender_account_id , amount .to_tinybars ())
101- .execute (client )
109+ print (
110+ f"Successfully transferred { amount } from { owner_account_id } "
111+ f"to { receiver_account_id } using allowance"
102112 )
103113
104- if receipt .status != ResponseCode .SPENDER_DOES_NOT_HAVE_ALLOWANCE :
105- print (
106- f"Hbar transfer should have failed with SPENDER_DOES_NOT_HAVE_ALLOWANCE "
107- f"status but got: { ResponseCode (receipt .status ).name } "
108- )
109-
110- print (f"Hbar transfer successfully failed with { ResponseCode (receipt .status ).name } status" )
114+ return receipt
111115
112116
113- def hbar_allowance ():
117+ def main ():
114118 """
115119 Demonstrates hbar allowance functionality by:
116120 1. Setting up client with operator account
117121 2. Creating spender and receiver accounts
118122 3. Approving hbar allowance for spender
119123 4. Transferring hbars using the allowance
120- 5. Deleting the allowance
121- 6. Attempting to transfer hbars without allowance (should fail)
122124 """
123125 client = setup_client ()
124126
@@ -131,33 +133,20 @@ def hbar_allowance():
131133
132134 # Approve hbar allowance for spender
133135 allowance_amount = Hbar (2 )
136+ owner_account_id = client .operator_account_id
134137
135- approve_hbar_allowance (client , client . operator_account_id , spender_id , allowance_amount )
138+ approve_hbar_allowance (client , owner_account_id , spender_id , allowance_amount )
136139
137140 # Transfer hbars using the allowance
138- receipt = (
139- TransferTransaction ()
140- .set_transaction_id (TransactionId .generate (spender_id ))
141- .add_approved_hbar_transfer (client .operator_account_id , - allowance_amount .to_tinybars ())
142- .add_approved_hbar_transfer (receiver_id , allowance_amount .to_tinybars ())
143- .freeze_with (client )
144- .sign (spender_private_key )
145- .execute (client )
141+ transfer_hbar_with_allowance (
142+ client = client ,
143+ owner_account_id = owner_account_id ,
144+ spender_account_id = spender_id ,
145+ spender_private_key = spender_private_key ,
146+ receiver_account_id = receiver_id ,
147+ amount = allowance_amount ,
146148 )
147149
148- if receipt .status != ResponseCode .SUCCESS :
149- print (f"Hbar transfer failed with status: { ResponseCode (receipt .status ).name } " )
150- sys .exit (1 )
151-
152- print (f"Successfully transferred { allowance_amount } from" , end = " " )
153- print (f"{ client .operator_account_id } to { receiver_id } using allowance" )
154-
155- # Delete allowance
156- delete_hbar_allowance (client , client .operator_account_id , spender_id )
157-
158- # Try to transfer hbars without allowance
159- transfer_hbar_without_allowance (client , spender_id , spender_private_key , allowance_amount )
160-
161150
162151if __name__ == "__main__" :
163- hbar_allowance ()
152+ main ()
0 commit comments