diff --git a/CHANGELOG.md b/CHANGELOG.md index 6de11633a..b97d9b895 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1. - Refactored `account_create_transaction_with_fallback_alias.py` by splitting the monolithic `create_account_with_fallback_alias` function into modular functions: `generate_fallback_key`, `fetch_account_info`, and `print_account_summary`. The existing `setup_client()` function was reused for improved readability and structure (#1018) - Allow `PublicKey` for `TokenUpdateKeys` in `TokenUpdateTransaction`, enabling non-custodial workflows where operators can build transactions using only public keys (#934). - Bump protobuf toml to protobuf==6.33.2 +- chore: Move account allowance example to correct folder - Added more tests to the CustomFee class for different functionalities (#991) - Changed messaged for test failure summaries so it is clearer by extracting test failure names into summary - Renamed example files to match src naming (#1053) diff --git a/examples/account/account_allowance_approve_transaction_hbar.py b/examples/account/account_allowance_approve_transaction_hbar.py index ef63c1d46..f3ccbaca7 100644 --- a/examples/account/account_allowance_approve_transaction_hbar.py +++ b/examples/account/account_allowance_approve_transaction_hbar.py @@ -1,7 +1,5 @@ """ Example demonstrating hbar allowance approval and usage. -Run: -uv run examples/account/account_allowance_approve_transaction_hbar.py """ import os @@ -18,24 +16,25 @@ from hiero_sdk_python.transaction.transfer_transaction import TransferTransaction load_dotenv() -network_name = os.getenv('NETWORK', 'testnet').lower() +network_name = os.getenv("NETWORK", "testnet").lower() -def setup_client(): - """Initialize and set up the client with operator account""" + +def setup_client() -> Client: + """Initialize and set up the client with operator account using env vars.""" network = Network(network_name) print(f"Connecting to Hedera {network_name} network!") client = Client(network) - operator_id = AccountId.from_string(os.getenv("OPERATOR_ID","")) - operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY","")) + operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) + operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) client.set_operator(operator_id, operator_key) print(f"Client set up with operator id {client.operator_account_id}") return client -def create_account(client): - """Create an account""" +def create_account(client: Client): + """Create a new Hedera account with initial balance.""" account_private_key = PrivateKey.generate_ed25519() account_public_key = account_private_key.public_key() @@ -48,7 +47,10 @@ def create_account(client): ) if account_receipt.status != ResponseCode.SUCCESS: - print(f"Account creation failed with status: {ResponseCode(account_receipt.status).name}") + print( + "Account creation failed with status: " + f"{ResponseCode(account_receipt.status).name}" + ) sys.exit(1) account_account_id = account_receipt.account_id @@ -56,8 +58,13 @@ def create_account(client): return account_account_id, account_private_key -def approve_hbar_allowance(client, owner_account_id, spender_account_id, amount): - """Approve Hbar allowance for spender""" +def approve_hbar_allowance( + client: Client, + owner_account_id: AccountId, + spender_account_id: AccountId, + amount: Hbar, +): + """Approve Hbar allowance for spender.""" receipt = ( AccountAllowanceApproveTransaction() .approve_hbar_allowance(owner_account_id, spender_account_id, amount) @@ -65,60 +72,55 @@ def approve_hbar_allowance(client, owner_account_id, spender_account_id, amount) ) if receipt.status != ResponseCode.SUCCESS: - print(f"Hbar allowance approval failed with status: {ResponseCode(receipt.status).name}") + print( + "Hbar allowance approval failed with status: " + f"{ResponseCode(receipt.status).name}" + ) sys.exit(1) print(f"Hbar allowance of {amount} approved for spender {spender_account_id}") return receipt -def delete_hbar_allowance(client, owner_account_id, spender_account_id): - """Delete hbar allowance by setting amount to 0""" +def transfer_hbar_with_allowance( + client: Client, + owner_account_id: AccountId, + spender_account_id: AccountId, + spender_private_key: PrivateKey, + receiver_account_id: AccountId, + amount: Hbar, +): + """Transfer hbars using a previously approved allowance.""" receipt = ( - AccountAllowanceApproveTransaction() - .approve_hbar_allowance(owner_account_id, spender_account_id, Hbar(0)) + TransferTransaction() + # Transaction is paid for / initiated by spender + .set_transaction_id(TransactionId.generate(spender_account_id)) + .add_approved_hbar_transfer(owner_account_id, -amount.to_tinybars()) + .add_approved_hbar_transfer(receiver_account_id, amount.to_tinybars()) + .freeze_with(client) + .sign(spender_private_key) .execute(client) ) if receipt.status != ResponseCode.SUCCESS: - print(f"Hbar allowance deletion failed with status: {ResponseCode(receipt.status).name}") + print(f"Hbar transfer failed with status: {ResponseCode(receipt.status).name}") sys.exit(1) - print(f"Hbar allowance deleted for spender {spender_account_id}") - return receipt - - -def transfer_hbar_without_allowance(client, spender_account_id, spender_private_key, amount): - """Transfer hbars without allowance""" - print("Trying to transfer hbars without allowance...") - owner_account_id = client.operator_account_id - client.set_operator(spender_account_id, spender_private_key) # Set operator to spender - - receipt = ( - TransferTransaction() - .add_approved_hbar_transfer(owner_account_id, -amount.to_tinybars()) - .add_approved_hbar_transfer(spender_account_id, amount.to_tinybars()) - .execute(client) + print( + f"Successfully transferred {amount} from {owner_account_id} " + f"to {receiver_account_id} using allowance" ) - if receipt.status != ResponseCode.SPENDER_DOES_NOT_HAVE_ALLOWANCE: - print( - f"Hbar transfer should have failed with SPENDER_DOES_NOT_HAVE_ALLOWANCE " - f"status but got: {ResponseCode(receipt.status).name}" - ) - - print(f"Hbar transfer successfully failed with {ResponseCode(receipt.status).name} status") + return receipt -def hbar_allowance(): +def main(): """ Demonstrates hbar allowance functionality by: 1. Setting up client with operator account 2. Creating spender and receiver accounts 3. Approving hbar allowance for spender 4. Transferring hbars using the allowance - 5. Deleting the allowance - 6. Attempting to transfer hbars without allowance (should fail) """ client = setup_client() @@ -131,33 +133,20 @@ def hbar_allowance(): # Approve hbar allowance for spender allowance_amount = Hbar(2) + owner_account_id = client.operator_account_id - approve_hbar_allowance(client, client.operator_account_id, spender_id, allowance_amount) + approve_hbar_allowance(client, owner_account_id, spender_id, allowance_amount) # Transfer hbars using the allowance - receipt = ( - TransferTransaction() - .set_transaction_id(TransactionId.generate(spender_id)) - .add_approved_hbar_transfer(client.operator_account_id, -allowance_amount.to_tinybars()) - .add_approved_hbar_transfer(receiver_id, allowance_amount.to_tinybars()) - .freeze_with(client) - .sign(spender_private_key) - .execute(client) + transfer_hbar_with_allowance( + client=client, + owner_account_id=owner_account_id, + spender_account_id=spender_id, + spender_private_key=spender_private_key, + receiver_account_id=receiver_id, + amount=allowance_amount, ) - if receipt.status != ResponseCode.SUCCESS: - print(f"Hbar transfer failed with status: {ResponseCode(receipt.status).name}") - sys.exit(1) - - print(f"Successfully transferred {allowance_amount} from", end=" ") - print(f"{client.operator_account_id} to {receiver_id} using allowance") - - # Delete allowance - delete_hbar_allowance(client, client.operator_account_id, spender_id) - - # Try to transfer hbars without allowance - transfer_hbar_without_allowance(client, spender_id, spender_private_key, allowance_amount) - if __name__ == "__main__": - hbar_allowance() + main() diff --git a/examples/account_allowance_approve_transaction_hbar.py b/examples/account_allowance_approve_transaction_hbar.py deleted file mode 100644 index f3ccbaca7..000000000 --- a/examples/account_allowance_approve_transaction_hbar.py +++ /dev/null @@ -1,152 +0,0 @@ -""" -Example demonstrating hbar allowance approval and usage. -""" - -import os -import sys - -from dotenv import load_dotenv - -from hiero_sdk_python import AccountId, Client, Hbar, Network, PrivateKey, TransactionId -from hiero_sdk_python.account.account_allowance_approve_transaction import ( - AccountAllowanceApproveTransaction, -) -from hiero_sdk_python.account.account_create_transaction import AccountCreateTransaction -from hiero_sdk_python.response_code import ResponseCode -from hiero_sdk_python.transaction.transfer_transaction import TransferTransaction - -load_dotenv() -network_name = os.getenv("NETWORK", "testnet").lower() - - -def setup_client() -> Client: - """Initialize and set up the client with operator account using env vars.""" - network = Network(network_name) - print(f"Connecting to Hedera {network_name} network!") - client = Client(network) - - operator_id = AccountId.from_string(os.getenv("OPERATOR_ID", "")) - operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY", "")) - client.set_operator(operator_id, operator_key) - print(f"Client set up with operator id {client.operator_account_id}") - - return client - - -def create_account(client: Client): - """Create a new Hedera account with initial balance.""" - account_private_key = PrivateKey.generate_ed25519() - account_public_key = account_private_key.public_key() - - account_receipt = ( - AccountCreateTransaction() - .set_key(account_public_key) - .set_initial_balance(Hbar(1)) - .set_account_memo("Account for hbar allowance") - .execute(client) - ) - - if account_receipt.status != ResponseCode.SUCCESS: - print( - "Account creation failed with status: " - f"{ResponseCode(account_receipt.status).name}" - ) - sys.exit(1) - - account_account_id = account_receipt.account_id - - return account_account_id, account_private_key - - -def approve_hbar_allowance( - client: Client, - owner_account_id: AccountId, - spender_account_id: AccountId, - amount: Hbar, -): - """Approve Hbar allowance for spender.""" - receipt = ( - AccountAllowanceApproveTransaction() - .approve_hbar_allowance(owner_account_id, spender_account_id, amount) - .execute(client) - ) - - if receipt.status != ResponseCode.SUCCESS: - print( - "Hbar allowance approval failed with status: " - f"{ResponseCode(receipt.status).name}" - ) - sys.exit(1) - - print(f"Hbar allowance of {amount} approved for spender {spender_account_id}") - return receipt - - -def transfer_hbar_with_allowance( - client: Client, - owner_account_id: AccountId, - spender_account_id: AccountId, - spender_private_key: PrivateKey, - receiver_account_id: AccountId, - amount: Hbar, -): - """Transfer hbars using a previously approved allowance.""" - receipt = ( - TransferTransaction() - # Transaction is paid for / initiated by spender - .set_transaction_id(TransactionId.generate(spender_account_id)) - .add_approved_hbar_transfer(owner_account_id, -amount.to_tinybars()) - .add_approved_hbar_transfer(receiver_account_id, amount.to_tinybars()) - .freeze_with(client) - .sign(spender_private_key) - .execute(client) - ) - - if receipt.status != ResponseCode.SUCCESS: - print(f"Hbar transfer failed with status: {ResponseCode(receipt.status).name}") - sys.exit(1) - - print( - f"Successfully transferred {amount} from {owner_account_id} " - f"to {receiver_account_id} using allowance" - ) - - return receipt - - -def main(): - """ - Demonstrates hbar allowance functionality by: - 1. Setting up client with operator account - 2. Creating spender and receiver accounts - 3. Approving hbar allowance for spender - 4. Transferring hbars using the allowance - """ - client = setup_client() - - # Create spender and receiver accounts - spender_id, spender_private_key = create_account(client) - print(f"Spender account created with ID: {spender_id}") - - receiver_id, _ = create_account(client) - print(f"Receiver account created with ID: {receiver_id}") - - # Approve hbar allowance for spender - allowance_amount = Hbar(2) - owner_account_id = client.operator_account_id - - approve_hbar_allowance(client, owner_account_id, spender_id, allowance_amount) - - # Transfer hbars using the allowance - transfer_hbar_with_allowance( - client=client, - owner_account_id=owner_account_id, - spender_account_id=spender_id, - spender_private_key=spender_private_key, - receiver_account_id=receiver_id, - amount=allowance_amount, - ) - - -if __name__ == "__main__": - main()