diff --git a/docs/markdown/autoapi/account_manager/index.md b/docs/markdown/autoapi/account_manager/index.md deleted file mode 100644 index afa7273e..00000000 --- a/docs/markdown/autoapi/account_manager/index.md +++ /dev/null @@ -1 +0,0 @@ -# account_manager diff --git a/docs/markdown/autoapi/algokit_utils/accounts/account_manager/index.md b/docs/markdown/autoapi/algokit_utils/accounts/account_manager/index.md index 688f6131..16008e08 100644 --- a/docs/markdown/autoapi/algokit_utils/accounts/account_manager/index.md +++ b/docs/markdown/autoapi/algokit_utils/accounts/account_manager/index.md @@ -28,98 +28,126 @@ Information about an Algorand account’s current status, balance and other prop See https://developer.algorand.org/docs/rest-apis/algod/#account for detailed field descriptions. -* **Variables:** - * **address** (*str*) – The account’s address - * **amount** ([*AlgoAmount*](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount)) – The account’s current balance - * **amount_without_pending_rewards** ([*AlgoAmount*](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount)) – The account’s balance without the pending rewards - * **min_balance** ([*AlgoAmount*](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount)) – The account’s minimum required balance - * **pending_rewards** ([*AlgoAmount*](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount)) – The amount of pending rewards - * **rewards** ([*AlgoAmount*](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount)) – The amount of rewards earned - * **round** (*int*) – The round for which this information is relevant - * **status** (*str*) – The account’s status (e.g., ‘Offline’, ‘Online’) - * **total_apps_opted_in** (*int* *|**None*) – Number of applications this account has opted into - * **total_assets_opted_in** (*int* *|**None*) – Number of assets this account has opted into - * **total_box_bytes** (*int* *|**None*) – Total number of box bytes used by this account - * **total_boxes** (*int* *|**None*) – Total number of boxes used by this account - * **total_created_apps** (*int* *|**None*) – Number of applications created by this account - * **total_created_assets** (*int* *|**None*) – Number of assets created by this account - * **apps_local_state** (*list* *[**dict* *]* *|**None*) – Local state of applications this account has opted into - * **apps_total_extra_pages** (*int* *|**None*) – Number of extra pages allocated to applications - * **apps_total_schema** (*dict* *|**None*) – Total schema for all applications - * **assets** (*list* *[**dict* *]* *|**None*) – Assets held by this account - * **auth_addr** (*str* *|**None*) – If rekeyed, the authorized address - * **closed_at_round** (*int* *|**None*) – Round when this account was closed - * **created_apps** (*list* *[**dict* *]* *|**None*) – Applications created by this account - * **created_assets** (*list* *[**dict* *]* *|**None*) – Assets created by this account - * **created_at_round** (*int* *|**None*) – Round when this account was created - * **deleted** (*bool* *|**None*) – Whether this account is deleted - * **incentive_eligible** (*bool* *|**None*) – Whether this account is eligible for incentives - * **last_heartbeat** (*int* *|**None*) – Last heartbeat round for this account - * **last_proposed** (*int* *|**None*) – Last round this account proposed a block - * **participation** (*dict* *|**None*) – Participation information for this account - * **reward_base** (*int* *|**None*) – Base reward for this account - * **sig_type** (*str* *|**None*) – Signature type for this account - #### address *: str* +The account’s address + #### amount *: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount)* +The account’s current balance + #### amount_without_pending_rewards *: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount)* +The account’s balance without the pending rewards + #### min_balance *: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount)* +The account’s minimum required balance + #### pending_rewards *: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount)* +The amount of pending rewards + #### rewards *: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount)* +The amount of rewards earned + #### round *: int* +The round for which this information is relevant + #### status *: str* +The account’s status (e.g., ‘Offline’, ‘Online’) + #### total_apps_opted_in *: int | None* *= None* +Number of applications this account has opted into + #### total_assets_opted_in *: int | None* *= None* +Number of assets this account has opted into + #### total_box_bytes *: int | None* *= None* +Total number of box bytes used by this account + #### total_boxes *: int | None* *= None* +Total number of boxes used by this account + #### total_created_apps *: int | None* *= None* +Number of applications created by this account + #### total_created_assets *: int | None* *= None* +Number of assets created by this account + #### apps_local_state *: list[dict] | None* *= None* +Local state of applications this account has opted into + #### apps_total_extra_pages *: int | None* *= None* +Number of extra pages allocated to applications + #### apps_total_schema *: dict | None* *= None* +Total schema for all applications + #### assets *: list[dict] | None* *= None* +Assets held by this account + #### auth_addr *: str | None* *= None* +If rekeyed, the authorized address + #### closed_at_round *: int | None* *= None* +Round when this account was closed + #### created_apps *: list[dict] | None* *= None* +Applications created by this account + #### created_assets *: list[dict] | None* *= None* +Assets created by this account + #### created_at_round *: int | None* *= None* +Round when this account was created + #### deleted *: bool | None* *= None* +Whether this account is deleted + #### incentive_eligible *: bool | None* *= None* +Whether this account is eligible for incentives + #### last_heartbeat *: int | None* *= None* +Last heartbeat round for this account + #### last_proposed *: int | None* *= None* +Last round this account proposed a block + #### participation *: dict | None* *= None* +Participation information for this account + #### reward_base *: int | None* *= None* +Base reward for this account + #### sig_type *: str | None* *= None* +Signature type for this account + ### *class* algokit_utils.accounts.account_manager.AccountManager(client_manager: [algokit_utils.clients.client_manager.ClientManager](../../clients/client_manager/index.md#algokit_utils.clients.client_manager.ClientManager)) Creates and keeps track of signing accounts that can sign transactions for a sending address. @@ -136,6 +164,15 @@ mnemonic-based, rekeyed, multisig, and logic signature accounts. #### *property* kmd *: [algokit_utils.accounts.kmd_account_manager.KmdAccountManager](../kmd_account_manager/index.md#algokit_utils.accounts.kmd_account_manager.KmdAccountManager)* +KMD account manager that allows you to easily get and create accounts using KMD. + +* **Return KmdAccountManager:** + The ‘KmdAccountManager’ instance +* **Example:** + ```pycon + >>> kmd_manager = account_manager.kmd + ``` + #### set_default_signer(signer: algosdk.atomic_transaction_composer.TransactionSigner | [algokit_utils.protocols.account.TransactionSignerAccountProtocol](../../protocols/account/index.md#algokit_utils.protocols.account.TransactionSignerAccountProtocol)) → typing_extensions.Self Sets the default signer to use if no other signer is specified. @@ -150,10 +187,7 @@ then an error will be thrown from get_signer / get_account. * **Example:** ```pycon >>> signer_account = account_manager.random() - >>> account_manager.set_default_signer(signer_account.signer) - >>> # When signing a transaction, if there is no signer registered for the sender - >>> # then the default signer will be used - >>> signer = account_manager.get_signer("{SENDERADDRESS}") + >>> account_manager.set_default_signer(signer_account) ``` #### set_signer(sender: str, signer: algosdk.atomic_transaction_composer.TransactionSigner) → typing_extensions.Self @@ -179,6 +213,10 @@ Merges the given AccountManager into this one. * **overwrite_existing** – Whether to overwrite existing signers in this manager * **Returns:** The AccountManager instance for method chaining +* **Example:** + ```pycon + >>> accountManager2.set_signers(accountManager1) + ``` #### set_signer_from_account(account: [algokit_utils.protocols.account.TransactionSignerAccountProtocol](../../protocols/account/index.md#algokit_utils.protocols.account.TransactionSignerAccountProtocol)) → typing_extensions.Self @@ -333,7 +371,7 @@ Tracks and returns an account that represents a logic signature. A logic signature account wrapper * **Example:** ```pycon - >>> account = account.logic_sig(program, [new Uint8Array(3, ...)]) + >>> account = account.logicsig(program, [new Uint8Array(3, ...)]) ``` #### multisig(metadata: [algokit_utils.models.account.MultisigMetadata](../../models/account/index.md#algokit_utils.models.account.MultisigMetadata), signing_accounts: list[[algokit_utils.models.account.SigningAccount](../../models/account/index.md#algokit_utils.models.account.SigningAccount)]) → [algokit_utils.models.account.MultiSigAccount](../../models/account/index.md#algokit_utils.models.account.MultiSigAccount) @@ -434,22 +472,22 @@ Please be careful with this function and be sure to read the * **Example:** ```pycon >>> # Basic example (with string addresses): - >>> algorand.account.rekey_account({account: "ACCOUNTADDRESS", rekey_to: "NEWADDRESS"}) + >>> algorand.account.rekey_account("ACCOUNTADDRESS", "NEWADDRESS") >>> # Basic example (with signer accounts): - >>> algorand.account.rekey_account({account: account1, rekey_to: newSignerAccount}) + >>> algorand.account.rekey_account(account1, newSignerAccount) >>> # Advanced example: - >>> algorand.account.rekey_account({ - ... account: "ACCOUNTADDRESS", - ... rekey_to: "NEWADDRESS", - ... lease: 'lease', - ... note: 'note', - ... first_valid_round: 1000, - ... validity_window: 10, - ... extra_fee: AlgoAmount.from_micro_algo(1000), - ... static_fee: AlgoAmount.from_micro_algo(1000), - ... max_fee: AlgoAmount.from_micro_algo(3000), - ... suppress_log: True, - ... }) + >>> algorand.account.rekey_account( + ... account="ACCOUNTADDRESS", + ... rekey_to="NEWADDRESS", + ... lease='lease', + ... note='note', + ... first_valid_round=1000, + ... validity_window=10, + ... extra_fee=AlgoAmount.from_micro_algo(1000), + ... static_fee=AlgoAmount.from_micro_algo(1000), + ... max_fee=AlgoAmount.from_micro_algo(3000), + ... suppress_log=True, + ... ) ``` #### ensure_funded(account_to_fund: str | [algokit_utils.models.account.SigningAccount](../../models/account/index.md#algokit_utils.models.account.SigningAccount), dispenser_account: str | [algokit_utils.models.account.SigningAccount](../../models/account/index.md#algokit_utils.models.account.SigningAccount), min_spending_balance: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount), min_funding_increment: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount) | None = None, send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None, signer: algosdk.atomic_transaction_composer.TransactionSigner | None = None, rekey_to: str | None = None, note: bytes | None = None, lease: bytes | None = None, static_fee: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount) | None = None, extra_fee: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount) | None = None, max_fee: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount) | None = None, validity_window: int | None = None, first_valid_round: int | None = None, last_valid_round: int | None = None) → [EnsureFundedResult](#algokit_utils.accounts.account_manager.EnsureFundedResult) | None @@ -484,13 +522,13 @@ See [https://developer.algorand.org/docs/get-details/accounts/#minimum-balance]( * **Example:** ```pycon >>> # Basic example: - >>> algorand.account.ensure_funded("ACCOUNTADDRESS", "DISPENSERADDRESS", algokit.algo(1)) + >>> algorand.account.ensure_funded("ACCOUNTADDRESS", "DISPENSERADDRESS", AlgoAmount.from_algo(1)) >>> # With configuration: >>> algorand.account.ensure_funded( ... "ACCOUNTADDRESS", ... "DISPENSERADDRESS", - ... algokit.algo(1), - ... min_funding_increment=algokit.algo(2), + ... AlgoAmount.from_algo(1), + ... min_funding_increment=AlgoAmount.from_algo(2), ... fee=AlgoAmount.from_micro_algo(1000), ... suppress_log=True ... ) @@ -534,12 +572,12 @@ if it’s a rekeyed account, or against default LocalNet if no environment varia * **Example:** ```pycon >>> # Basic example: - >>> algorand.account.ensure_funded_from_environment("ACCOUNTADDRESS", algokit.algo(1)) + >>> algorand.account.ensure_funded_from_environment("ACCOUNTADDRESS", AlgoAmount.from_algo(1)) >>> # With configuration: >>> algorand.account.ensure_funded_from_environment( ... "ACCOUNTADDRESS", - ... algokit.algo(1), - ... min_funding_increment=algokit.algo(2), + ... AlgoAmount.from_algo(1), + ... min_funding_increment=AlgoAmount.from_algo(2), ... fee=AlgoAmount.from_micro_algo(1000), ... suppress_log=True ... ) @@ -568,16 +606,16 @@ See [https://developer.algorand.org/docs/get-details/accounts/#minimum-balance]( * **Example:** ```pycon >>> # Basic example: - >>> algorand.account.ensure_funded_from_testnet_dispenser_api( + >>> account_manager.ensure_funded_from_testnet_dispenser_api( ... "ACCOUNTADDRESS", ... algorand.client.get_testnet_dispenser_from_environment(), - ... algokit.algo(1) + ... AlgoAmount.from_algo(1) ... ) >>> # With configuration: - >>> algorand.account.ensure_funded_from_testnet_dispenser_api( + >>> account_manager.ensure_funded_from_testnet_dispenser_api( ... "ACCOUNTADDRESS", ... algorand.client.get_testnet_dispenser_from_environment(), - ... algokit.algo(1), - ... min_funding_increment=algokit.algo(2) + ... AlgoAmount.from_algo(1), + ... min_funding_increment=AlgoAmount.from_algo(2) ... ) ``` diff --git a/docs/markdown/autoapi/algokit_utils/algorand/index.md b/docs/markdown/autoapi/algokit_utils/algorand/index.md index 3e0f3115..3b32aa00 100644 --- a/docs/markdown/autoapi/algokit_utils/algorand/index.md +++ b/docs/markdown/autoapi/algokit_utils/algorand/index.md @@ -19,6 +19,10 @@ Sets the default validity window for transactions. **validity_window** – The number of rounds between the first and last valid rounds * **Returns:** The AlgorandClient so method calls can be chained +* **Example:** + ```pycon + >>> algorand = AlgorandClient.mainnet().set_default_validity_window(1000); + ``` #### set_default_signer(signer: algosdk.atomic_transaction_composer.TransactionSigner | [algokit_utils.protocols.account.TransactionSignerAccountProtocol](../protocols/account/index.md#algokit_utils.protocols.account.TransactionSignerAccountProtocol)) → typing_extensions.Self @@ -28,6 +32,11 @@ Sets the default signer to use if no other signer is specified. **signer** – The signer to use, either a TransactionSigner or a TransactionSignerAccountProtocol * **Returns:** The AlgorandClient so method calls can be chained +* **Example:** + ```pycon + >>> signer = SigningAccount(private_key=..., address=...) + >>> algorand = AlgorandClient.mainnet().set_default_signer(signer) + ``` #### set_signer(sender: str, signer: algosdk.atomic_transaction_composer.TransactionSigner) → typing_extensions.Self @@ -38,8 +47,13 @@ Tracks the given account for later signing. * **signer** – The signer to sign transactions with for the given sender * **Returns:** The AlgorandClient so method calls can be chained +* **Example:** + ```pycon + >>> signer = SigningAccount(private_key=..., address=...) + >>> algorand = AlgorandClient.mainnet().set_signer(signer.addr, signer.signer) + ``` -#### set_signer_account(signer: [algokit_utils.protocols.account.TransactionSignerAccountProtocol](../protocols/account/index.md#algokit_utils.protocols.account.TransactionSignerAccountProtocol)) → typing_extensions.Self +#### set_signer_from_account(signer: [algokit_utils.protocols.account.TransactionSignerAccountProtocol](../protocols/account/index.md#algokit_utils.protocols.account.TransactionSignerAccountProtocol)) → typing_extensions.Self Sets the default signer to use if no other signer is specified. @@ -47,8 +61,17 @@ Sets the default signer to use if no other signer is specified. **signer** – The signer to use, either a TransactionSigner or a TransactionSignerAccountProtocol * **Returns:** The AlgorandClient so method calls can be chained - -#### set_suggested_params(suggested_params: algosdk.transaction.SuggestedParams, until: float | None = None) → typing_extensions.Self +* **Example:** + ```pycon + >>> accountManager = AlgorandClient.mainnet() + >>> accountManager.set_signer_from_account(TransactionSignerAccount(address=..., signer=...)) + >>> accountManager.set_signer_from_account(algosdk.LogicSigAccount(program, args)) + >>> accountManager.set_signer_from_account(SigningAccount(private_key=..., address=...)) + >>> accountManager.set_signer_from_account(MultisigAccount(metadata, signing_accounts)) + >>> accountManager.set_signer_from_account(account) + ``` + +#### set_suggested_params_cache(suggested_params: algosdk.transaction.SuggestedParams, until: float | None = None) → typing_extensions.Self Sets a cache value to use for suggested params. @@ -57,8 +80,12 @@ Sets a cache value to use for suggested params. * **until** – A timestamp until which to cache, or if not specified then the timeout is used * **Returns:** The AlgorandClient so method calls can be chained +* **Example:** + ```pycon + >>> algorand = AlgorandClient.mainnet().set_suggested_params_cache(suggested_params, time.time() + 3.6e6) + ``` -#### set_suggested_params_timeout(timeout: int) → typing_extensions.Self +#### set_suggested_params_cache_timeout(timeout: int) → typing_extensions.Self Sets the timeout for caching suggested params. @@ -66,47 +93,113 @@ Sets the timeout for caching suggested params. **timeout** – The timeout in milliseconds * **Returns:** The AlgorandClient so method calls can be chained +* **Example:** + ```pycon + >>> algorand = AlgorandClient.mainnet().set_suggested_params_cache_timeout(10_000) + ``` #### get_suggested_params() → algosdk.transaction.SuggestedParams Get suggested params for a transaction (either cached or from algod if the cache is stale or empty) +* **Example:** + ```pycon + >>> algorand = AlgorandClient.mainnet().get_suggested_params() + ``` + #### new_group() → [algokit_utils.transactions.transaction_composer.TransactionComposer](../transactions/transaction_composer/index.md#algokit_utils.transactions.transaction_composer.TransactionComposer) Start a new TransactionComposer transaction group +* **Example:** + ```pycon + >>> composer = AlgorandClient.mainnet().new_group() + >>> result = await composer.add_transaction(payment).send() + ``` + #### *property* client *: [algokit_utils.clients.client_manager.ClientManager](../clients/client_manager/index.md#algokit_utils.clients.client_manager.ClientManager)* Get clients, including algosdk clients and app clients. +* **Example:** + ```pycon + >>> clientManager = AlgorandClient.mainnet().client + ``` + #### *property* account *: [algokit_utils.accounts.account_manager.AccountManager](../accounts/account_manager/index.md#algokit_utils.accounts.account_manager.AccountManager)* Get or create accounts that can sign transactions. +* **Example:** + ```pycon + >>> accountManager = AlgorandClient.mainnet().account + ``` + #### *property* asset *: [algokit_utils.assets.asset_manager.AssetManager](../assets/asset_manager/index.md#algokit_utils.assets.asset_manager.AssetManager)* Get or create assets. +* **Example:** + ```pycon + >>> assetManager = AlgorandClient.mainnet().asset + ``` + #### *property* app *: [algokit_utils.applications.app_manager.AppManager](../applications/app_manager/index.md#algokit_utils.applications.app_manager.AppManager)* +Get or create applications. + +* **Example:** + ```pycon + >>> appManager = AlgorandClient.mainnet().app + ``` + #### *property* app_deployer *: [algokit_utils.applications.app_deployer.AppDeployer](../applications/app_deployer/index.md#algokit_utils.applications.app_deployer.AppDeployer)* Get or create applications. +* **Example:** + ```pycon + >>> appDeployer = AlgorandClient.mainnet().app_deployer + ``` + #### *property* send *: [algokit_utils.transactions.transaction_sender.AlgorandClientTransactionSender](../transactions/transaction_sender/index.md#algokit_utils.transactions.transaction_sender.AlgorandClientTransactionSender)* Methods for sending a transaction and waiting for confirmation +* **Example:** + ```pycon + >>> result = await AlgorandClient.mainnet().send.payment( + >>> PaymentParams( + >>> sender="SENDERADDRESS", + >>> receiver="RECEIVERADDRESS", + >>> amount=AlgoAmount(algo-1) + >>> )) + ``` + #### *property* create_transaction *: [algokit_utils.transactions.transaction_creator.AlgorandClientTransactionCreator](../transactions/transaction_creator/index.md#algokit_utils.transactions.transaction_creator.AlgorandClientTransactionCreator)* Methods for building transactions +* **Example:** + ```pycon + >>> transaction = AlgorandClient.mainnet().create_transaction.payment( + >>> PaymentParams( + >>> sender="SENDERADDRESS", + >>> receiver="RECEIVERADDRESS", + >>> amount=AlgoAmount(algo=1) + >>> )) + ``` + #### *static* default_localnet() → [AlgorandClient](#algokit_utils.algorand.AlgorandClient) Returns an AlgorandClient pointing at default LocalNet ports and API token. * **Returns:** The AlgorandClient +* **Example:** + ```pycon + >>> algorand = AlgorandClient.default_localnet() + ``` #### *static* testnet() → [AlgorandClient](#algokit_utils.algorand.AlgorandClient) @@ -114,6 +207,10 @@ Returns an AlgorandClient pointing at TestNet using AlgoNode. * **Returns:** The AlgorandClient +* **Example:** + ```pycon + >>> algorand = AlgorandClient.testnet() + ``` #### *static* mainnet() → [AlgorandClient](#algokit_utils.algorand.AlgorandClient) @@ -121,6 +218,10 @@ Returns an AlgorandClient pointing at MainNet using AlgoNode. * **Returns:** The AlgorandClient +* **Example:** + ```pycon + >>> algorand = AlgorandClient.mainnet() + ``` #### *static* from_clients(algod: algosdk.v2client.algod.AlgodClient, indexer: algosdk.v2client.indexer.IndexerClient | None = None, kmd: algosdk.kmd.KMDClient | None = None) → [AlgorandClient](#algokit_utils.algorand.AlgorandClient) @@ -132,6 +233,10 @@ Returns an AlgorandClient pointing to the given client(s). * **kmd** – The kmd client to use * **Returns:** The AlgorandClient +* **Example:** + ```pycon + >>> algorand = AlgorandClient.from_clients(algod, indexer, kmd) + ``` #### *static* from_environment() → [AlgorandClient](#algokit_utils.algorand.AlgorandClient) @@ -143,6 +248,10 @@ Expects to be called from a Python environment. * **Returns:** The AlgorandClient +* **Example:** + ```pycon + >>> algorand = AlgorandClient.from_environment() + ``` #### *static* from_config(algod_config: [algokit_utils.models.network.AlgoClientNetworkConfig](../models/network/index.md#algokit_utils.models.network.AlgoClientNetworkConfig), indexer_config: [algokit_utils.models.network.AlgoClientNetworkConfig](../models/network/index.md#algokit_utils.models.network.AlgoClientNetworkConfig) | None = None, kmd_config: [algokit_utils.models.network.AlgoClientNetworkConfig](../models/network/index.md#algokit_utils.models.network.AlgoClientNetworkConfig) | None = None) → [AlgorandClient](#algokit_utils.algorand.AlgorandClient) @@ -154,3 +263,7 @@ Returns an AlgorandClient from the given config. * **kmd_config** – The config to use for the kmd client * **Returns:** The AlgorandClient +* **Example:** + ```pycon + >>> algorand = AlgorandClient.from_config(algod_config, indexer_config, kmd_config) + ``` diff --git a/docs/markdown/autoapi/algokit_utils/applications/abi/index.md b/docs/markdown/autoapi/algokit_utils/applications/abi/index.md index a1d105a8..a2e10d96 100644 --- a/docs/markdown/autoapi/algokit_utils/applications/abi/index.md +++ b/docs/markdown/autoapi/algokit_utils/applications/abi/index.md @@ -43,24 +43,26 @@ Represents the return value from an ABI method call. Wraps the raw return value and decoded value along with any decode errors. -* **Variables:** - * **result** – The ABIResult object containing the method call results - * **raw_value** – The raw return value from the method call - * **value** – The decoded return value from the method call - * **method** – The ABI method definition - * **decode_error** – The exception that occurred during decoding, if any - * **tx_info** – The transaction info for the method call from raw algosdk ABIResult - #### raw_value *: bytes | None* *= None* +The raw return value from the method call + #### value *: ABIValue | None* *= None* +The decoded return value from the method call + #### method *: algosdk.abi.method.Method | None* *= None* +The ABI method definition + #### decode_error *: Exception | None* *= None* +The exception that occurred during decoding, if any + #### tx_info *: dict[str, Any] | None* *= None* +The transaction info for the method call from raw algosdk ABIResult + #### *property* is_success *: bool* Returns True if the ABI call was successful (no decode error) @@ -155,10 +157,10 @@ Converts a decoded tuple to an ABI struct. Represents an ABI value stored in a box. -* **Variables:** - * **name** – The name of the box - * **value** – The ABI value stored in the box - #### name *: [algokit_utils.models.state.BoxName](../../models/state/index.md#algokit_utils.models.state.BoxName)* +The name of the box + #### value *: ABIValue* + +The ABI value stored in the box diff --git a/docs/markdown/autoapi/algokit_utils/applications/app_client/index.md b/docs/markdown/autoapi/algokit_utils/applications/app_client/index.md index d5a6ea28..485aa6bf 100644 --- a/docs/markdown/autoapi/algokit_utils/applications/app_client/index.md +++ b/docs/markdown/autoapi/algokit_utils/applications/app_client/index.md @@ -48,20 +48,22 @@ Result of compiling an application’s TEAL code. Contains the compiled approval and clear state programs along with optional compilation artifacts. -* **Variables:** - * **approval_program** – The compiled approval program bytes - * **clear_state_program** – The compiled clear state program bytes - * **compiled_approval** – Optional compilation artifacts for approval program - * **compiled_clear** – Optional compilation artifacts for clear state program - #### approval_program *: bytes* +The compiled approval program bytes + #### clear_state_program *: bytes* +The compiled clear state program bytes + #### compiled_approval *: [algokit_utils.models.application.CompiledTeal](../../models/application/index.md#algokit_utils.models.application.CompiledTeal) | None* *= None* +Optional compilation artifacts for approval program + #### compiled_clear *: [algokit_utils.models.application.CompiledTeal](../../models/application/index.md#algokit_utils.models.application.CompiledTeal) | None* *= None* +Optional compilation artifacts for clear state program + ### *class* algokit_utils.applications.app_client.AppClientCompilationParams Bases: `TypedDict` @@ -83,67 +85,82 @@ Parameters for compiling an application’s TEAL code. Common configuration for app call transaction parameters -* **Variables:** - * **account_references** – List of account addresses to reference - * **app_references** – List of app IDs to reference - * **asset_references** – List of asset IDs to reference - * **box_references** – List of box references to include - * **extra_fee** – Additional fee to add to transaction - * **lease** – Transaction lease value - * **max_fee** – Maximum fee allowed for transaction - * **note** – Arbitrary note for the transaction - * **rekey_to** – Address to rekey account to - * **sender** – Sender address override - * **signer** – Custom transaction signer - * **static_fee** – Fixed fee for transaction - * **validity_window** – Number of rounds valid - * **first_valid_round** – First valid round number - * **last_valid_round** – Last valid round number - #### account_references *: list[str] | None* *= None* +List of account addresses to reference + #### app_references *: list[int] | None* *= None* +List of app IDs to reference + #### asset_references *: list[int] | None* *= None* +List of asset IDs to reference + #### box_references *: list[[algokit_utils.models.state.BoxReference](../../models/state/index.md#algokit_utils.models.state.BoxReference) | algokit_utils.models.state.BoxIdentifier] | None* *= None* +List of box references to include + #### extra_fee *: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount) | None* *= None* +Additional fee to add to transaction + #### lease *: bytes | None* *= None* +Transaction lease value + #### max_fee *: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount) | None* *= None* +Maximum fee allowed for transaction + #### note *: bytes | None* *= None* +Custom note for the transaction + #### rekey_to *: str | None* *= None* +Address to rekey account to + #### sender *: str | None* *= None* +Sender address override + #### signer *: algosdk.atomic_transaction_composer.TransactionSigner | None* *= None* +Custom transaction signer + #### static_fee *: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount) | None* *= None* +Fixed fee for transaction + #### validity_window *: int | None* *= None* +Number of rounds valid + #### first_valid_round *: int | None* *= None* +First valid round number + #### last_valid_round *: int | None* *= None* +Last valid round number + #### on_complete *: algosdk.transaction.OnComplete | None* *= None* +Optional on complete action + ### *class* algokit_utils.applications.app_client.AppClientCreateSchema Schema for application creation. -* **Variables:** - * **extra_program_pages** – Optional number of extra program pages - * **schema** – Optional application creation schema - #### extra_program_pages *: int | None* *= None* +Optional number of extra program pages + #### schema *: [algokit_utils.transactions.transaction_composer.AppCreateSchema](../../transactions/transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppCreateSchema) | None* *= None* +Optional application creation schema + ### *class* algokit_utils.applications.app_client.CommonAppCallCreateParams Bases: [`AppClientCreateSchema`](#algokit_utils.applications.app_client.AppClientCreateSchema), [`CommonAppCallParams`](#algokit_utils.applications.app_client.CommonAppCallParams) @@ -152,31 +169,32 @@ Common configuration for app create call transaction parameters. #### on_complete *: CreateOnComplete | None* *= None* +Optional on complete action + ### *class* algokit_utils.applications.app_client.FundAppAccountParams Bases: [`CommonAppCallParams`](#algokit_utils.applications.app_client.CommonAppCallParams) Parameters for funding an application’s account. -* **Variables:** - * **amount** – Amount to fund - * **close_remainder_to** – Optional address to close remainder to - #### amount *: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount)* +Amount to fund + #### close_remainder_to *: str | None* *= None* +Optional address to close remainder to + ### *class* algokit_utils.applications.app_client.AppClientBareCallParams Bases: [`CommonAppCallParams`](#algokit_utils.applications.app_client.CommonAppCallParams) Parameters for bare application calls. -* **Variables:** - **args** – Optional arguments - #### args *: list[bytes] | None* *= None* +Optional arguments + ### *class* algokit_utils.applications.app_client.AppClientBareCallCreateParams Bases: [`CommonAppCallCreateParams`](#algokit_utils.applications.app_client.CommonAppCallCreateParams) @@ -185,21 +203,22 @@ Parameters for creating application with bare call. #### on_complete *: CreateOnComplete | None* *= None* +Optional on complete action + ### *class* algokit_utils.applications.app_client.BaseAppClientMethodCallParams Bases: `Generic`[`ArgsT`, `MethodT`], [`CommonAppCallParams`](#algokit_utils.applications.app_client.CommonAppCallParams) Base parameters for application method calls. -* **Variables:** - * **method** – Method to call - * **args** – Optional arguments to pass to method - * **on_complete** – Optional on complete action - #### method *: MethodT* +Method to call + #### args *: ArgsT | None* *= None* +Arguments to pass to the application method call + ### *class* algokit_utils.applications.app_client.AppClientMethodCallParams Bases: [`BaseAppClientMethodCallParams`](#algokit_utils.applications.app_client.BaseAppClientMethodCallParams)[`collections.abc.Sequence`[`algokit_utils.applications.abi.ABIValue | algokit_utils.applications.abi.ABIStruct | algokit_utils.transactions.transaction_composer.AppMethodCallTransactionArgument | None`], `str`] @@ -214,26 +233,44 @@ Parameters for creating application with method call #### on_complete *: CreateOnComplete | None* *= None* +Optional on complete action + ### *class* algokit_utils.applications.app_client.AppClientParams Full parameters for creating an app client #### app_spec *: [algokit_utils.applications.app_spec.arc56.Arc56Contract](../app_spec/arc56/index.md#algokit_utils.applications.app_spec.arc56.Arc56Contract) | [algokit_utils.applications.app_spec.arc32.Arc32Contract](../app_spec/arc32/index.md#algokit_utils.applications.app_spec.arc32.Arc32Contract) | str* +The application specification + #### algorand *: [algokit_utils.algorand.AlgorandClient](../../algorand/index.md#algokit_utils.algorand.AlgorandClient)* +The Algorand client + #### app_id *: int* +The application ID + #### app_name *: str | None* *= None* +The application name + #### default_sender *: str | None* *= None* +The default sender address + #### default_signer *: algosdk.atomic_transaction_composer.TransactionSigner | None* *= None* +The default transaction signer + #### approval_source_map *: algosdk.source_map.SourceMap | None* *= None* +The approval source map + #### clear_source_map *: algosdk.source_map.SourceMap | None* *= None* +The clear source map + ### *class* algokit_utils.applications.app_client.AppClient(params: [AppClientParams](#algokit_utils.applications.app_client.AppClientParams)) A client for interacting with an Algorand smart contract application. @@ -243,6 +280,27 @@ methods for calling application methods, managing state, and handling transactio * **Parameters:** **params** – Parameters for creating the app client +* **Example:** + ```pycon + >>> params = AppClientParams( + ... app_spec=Arc56Contract.from_json(app_spec_json), + ... algorand=algorand, + ... app_id=1234567890, + ... app_name="My App", + ... default_sender="SENDERADDRESS", + ... default_signer=TransactionSigner( + ... account="SIGNERACCOUNT", + ... private_key="SIGNERPRIVATEKEY", + ... ), + ... approval_source_map=SourceMap( + ... source="APPROVALSOURCE", + ... ), + ... clear_source_map=SourceMap( + ... source="CLEARSOURCE", + ... ), + ... ) + >>> client = AppClient(params) + ``` #### *property* algorand *: [algokit_utils.algorand.AlgorandClient](../../algorand/index.md#algokit_utils.algorand.AlgorandClient)* @@ -292,6 +350,20 @@ Get the method parameters builder. * **Returns:** The method parameters builder for this application +* **Example:** + ```pycon + >>> # Create a transaction in the future using Algorand Client + >>> my_method_call = app_client.params.call(AppClientMethodCallParams( + method='my_method', + args=[123, 'hello'])) + >>> # ... + >>> await algorand.send.AppMethodCall(my_method_call) + >>> # Define a nested transaction as an ABI argument + >>> my_method_call = app_client.params.call(AppClientMethodCallParams( + method='my_method', + args=[123, 'hello'])) + >>> app_client.send.call(AppClientMethodCallParams(method='my_method2', args=[my_method_call])) + ``` #### *property* send *: \_TransactionSender* @@ -312,11 +384,16 @@ Get the transaction creator. Normalize an application specification to ARC-56 format. * **Parameters:** - **app_spec** – The application specification to normalize + **app_spec** – The application specification to normalize. Can be raw arc32 or arc56 json, + or an Arc32Contract or Arc56Contract instance * **Returns:** The normalized ARC-56 contract specification * **Raises:** **ValueError** – If the app spec format is invalid +* **Example:** + ```pycon + >>> spec = AppClient.normalise_app_spec(app_spec_json) + ``` #### *static* from_network(app_spec: [algokit_utils.applications.app_spec.arc56.Arc56Contract](../app_spec/arc56/index.md#algokit_utils.applications.app_spec.arc56.Arc56Contract) | [algokit_utils.applications.app_spec.arc32.Arc32Contract](../app_spec/arc32/index.md#algokit_utils.applications.app_spec.arc32.Arc32Contract) | str, algorand: [algokit_utils.algorand.AlgorandClient](../../algorand/index.md#algokit_utils.algorand.AlgorandClient), app_name: str | None = None, default_sender: str | None = None, default_signer: algosdk.atomic_transaction_composer.TransactionSigner | None = None, approval_source_map: algosdk.source_map.SourceMap | None = None, clear_source_map: algosdk.source_map.SourceMap | None = None) → [AppClient](#algokit_utils.applications.app_client.AppClient) @@ -334,6 +411,25 @@ Create an AppClient instance from network information. A new AppClient instance * **Raises:** **Exception** – If no app ID is found for the network +* **Example:** + ```pycon + >>> client = AppClient.from_network( + ... app_spec=Arc56Contract.from_json(app_spec_json), + ... algorand=algorand, + ... app_name="My App", + ... default_sender="SENDERADDRESS", + ... default_signer=TransactionSigner( + ... account="SIGNERACCOUNT", + ... private_key="SIGNERPRIVATEKEY", + ... ), + ... approval_source_map=SourceMap( + ... source="APPROVALSOURCE", + ... ), + ... clear_source_map=SourceMap( + ... source="CLEARSOURCE", + ... ), + ... ) + ``` #### *static* from_creator_and_name(creator_address: str, app_name: str, app_spec: [algokit_utils.applications.app_spec.arc56.Arc56Contract](../app_spec/arc56/index.md#algokit_utils.applications.app_spec.arc56.Arc56Contract) | [algokit_utils.applications.app_spec.arc32.Arc32Contract](../app_spec/arc32/index.md#algokit_utils.applications.app_spec.arc32.Arc32Contract) | str, algorand: [algokit_utils.algorand.AlgorandClient](../../algorand/index.md#algokit_utils.algorand.AlgorandClient), default_sender: str | None = None, default_signer: algosdk.atomic_transaction_composer.TransactionSigner | None = None, approval_source_map: algosdk.source_map.SourceMap | None = None, clear_source_map: algosdk.source_map.SourceMap | None = None, ignore_cache: bool | None = None, app_lookup_cache: [algokit_utils.applications.app_deployer.ApplicationLookup](../app_deployer/index.md#algokit_utils.applications.app_deployer.ApplicationLookup) | None = None) → [AppClient](#algokit_utils.applications.app_client.AppClient) @@ -354,6 +450,15 @@ Create an AppClient instance from creator address and application name. A new AppClient instance * **Raises:** **ValueError** – If the app is not found for the creator and name +* **Example:** + ```pycon + >>> client = AppClient.from_creator_and_name( + ... creator_address="CREATORADDRESS", + ... app_name="APPNAME", + ... app_spec=Arc56Contract.from_json(app_spec_json), + ... algorand=algorand, + ... ) + ``` #### *static* compile(app_spec: [algokit_utils.applications.app_spec.arc56.Arc56Contract](../app_spec/arc56/index.md#algokit_utils.applications.app_spec.arc56.Arc56Contract), app_manager: [algokit_utils.applications.app_manager.AppManager](../app_manager/index.md#algokit_utils.applications.app_manager.AppManager), compilation_params: [AppClientCompilationParams](#algokit_utils.applications.app_client.AppClientCompilationParams) | None = None) → [AppClientCompilationResult](#algokit_utils.applications.app_client.AppClientCompilationResult) @@ -388,7 +493,12 @@ Create a cloned AppClient instance with optionally overridden parameters. * **approval_source_map** – Optional new approval source map * **clear_source_map** – Optional new clear source map * **Returns:** - A new AppClient instance with the specified parameters + A new AppClient instance +* **Example:** + ```pycon + >>> client = AppClient(params) + >>> cloned_client = client.clone(app_name="Cloned App", default_sender="NEW_SENDER") + ``` #### export_source_maps() → [algokit_utils.models.application.AppSourceMaps](../../models/application/index.md#algokit_utils.models.application.AppSourceMaps) @@ -423,6 +533,10 @@ Get the application’s global state. * **Returns:** The application’s global state +* **Example:** + ```pycon + >>> global_state = client.get_global_state() + ``` #### get_box_names() → list[[algokit_utils.models.state.BoxName](../../models/state/index.md#algokit_utils.models.state.BoxName)] @@ -430,6 +544,10 @@ Get all box names for the application. * **Returns:** List of box names +* **Example:** + ```pycon + >>> box_names = client.get_box_names() + ``` #### get_box_value(name: algokit_utils.models.state.BoxIdentifier) → bytes @@ -439,6 +557,10 @@ Get the value of a box. **name** – The box identifier * **Returns:** The box value as bytes +* **Example:** + ```pycon + >>> box_value = client.get_box_value(box_name) + ``` #### get_box_value_from_abi_type(name: algokit_utils.models.state.BoxIdentifier, abi_type: algokit_utils.applications.abi.ABIType) → algokit_utils.applications.abi.ABIValue @@ -449,6 +571,10 @@ Get a box value decoded according to an ABI type. * **abi_type** – The ABI type to decode as * **Returns:** The decoded box value +* **Example:** + ```pycon + >>> box_value = client.get_box_value_from_abi_type(box_name, abi_type) + ``` #### get_box_values(filter_func: collections.abc.Callable[[[algokit_utils.models.state.BoxName](../../models/state/index.md#algokit_utils.models.state.BoxName)], bool] | None = None) → list[[algokit_utils.models.state.BoxValue](../../models/state/index.md#algokit_utils.models.state.BoxValue)] @@ -458,6 +584,10 @@ Get values for multiple boxes. **filter_func** – Optional function to filter box names * **Returns:** List of box values +* **Example:** + ```pycon + >>> box_values = client.get_box_values() + ``` #### get_box_values_from_abi_type(abi_type: algokit_utils.applications.abi.ABIType, filter_func: collections.abc.Callable[[[algokit_utils.models.state.BoxName](../../models/state/index.md#algokit_utils.models.state.BoxName)], bool] | None = None) → list[[algokit_utils.applications.abi.BoxABIValue](../abi/index.md#algokit_utils.applications.abi.BoxABIValue)] @@ -468,6 +598,10 @@ Get multiple box values decoded according to an ABI type. * **filter_func** – Optional function to filter box names * **Returns:** List of decoded box values +* **Example:** + ```pycon + >>> box_values = client.get_box_values_from_abi_type(abi_type) + ``` #### fund_app_account(params: [FundAppAccountParams](#algokit_utils.applications.app_client.FundAppAccountParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → [algokit_utils.transactions.transaction_sender.SendSingleTransactionResult](../../transactions/transaction_sender/index.md#algokit_utils.transactions.transaction_sender.SendSingleTransactionResult) @@ -478,3 +612,7 @@ Fund the application’s account. * **send_params** – Send parameters, defaults to None * **Returns:** The transaction result +* **Example:** + ```pycon + >>> result = client.fund_app_account(params) + ``` diff --git a/docs/markdown/autoapi/algokit_utils/applications/app_deployer/index.md b/docs/markdown/autoapi/algokit_utils/applications/app_deployer/index.md index 0719b1a3..624fed0b 100644 --- a/docs/markdown/autoapi/algokit_utils/applications/app_deployer/index.md +++ b/docs/markdown/autoapi/algokit_utils/applications/app_deployer/index.md @@ -13,7 +13,7 @@ | [`ApplicationMetaData`](#algokit_utils.applications.app_deployer.ApplicationMetaData) | Complete metadata about a deployed app | | [`ApplicationLookup`](#algokit_utils.applications.app_deployer.ApplicationLookup) | Cache of {py:class}\`ApplicationMetaData\` for a specific creator | | [`AppDeployParams`](#algokit_utils.applications.app_deployer.AppDeployParams) | Parameters for deploying an app | -| [`AppDeployResult`](#algokit_utils.applications.app_deployer.AppDeployResult) | | +| [`AppDeployResult`](#algokit_utils.applications.app_deployer.AppDeployResult) | The result of a deployment | | [`AppDeployer`](#algokit_utils.applications.app_deployer.AppDeployer) | Manages deployment and deployment metadata of applications | ## Module Contents @@ -85,44 +85,159 @@ Parameters for deploying an app #### metadata *: [AppDeploymentMetaData](#algokit_utils.applications.app_deployer.AppDeploymentMetaData)* +The deployment metadata + #### deploy_time_params *: algokit_utils.models.state.TealTemplateParams | None* *= None* +Optional template parameters to use during compilation + #### on_schema_break *: Literal['replace', 'fail', 'append'] | [algokit_utils.applications.enums.OnSchemaBreak](../enums/index.md#algokit_utils.applications.enums.OnSchemaBreak) | None* *= None* +Optional on schema break action + #### on_update *: Literal['update', 'replace', 'fail', 'append'] | [algokit_utils.applications.enums.OnUpdate](../enums/index.md#algokit_utils.applications.enums.OnUpdate) | None* *= None* +Optional on update action + #### create_params *: [algokit_utils.transactions.transaction_composer.AppCreateParams](../../transactions/transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppCreateParams) | [algokit_utils.transactions.transaction_composer.AppCreateMethodCallParams](../../transactions/transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppCreateMethodCallParams)* +The creation parameters + #### update_params *: [algokit_utils.transactions.transaction_composer.AppUpdateParams](../../transactions/transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppUpdateParams) | [algokit_utils.transactions.transaction_composer.AppUpdateMethodCallParams](../../transactions/transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppUpdateMethodCallParams)* +The update parameters + #### delete_params *: [algokit_utils.transactions.transaction_composer.AppDeleteParams](../../transactions/transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppDeleteParams) | [algokit_utils.transactions.transaction_composer.AppDeleteMethodCallParams](../../transactions/transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppDeleteMethodCallParams)* +The deletion parameters + #### existing_deployments *: [ApplicationLookup](#algokit_utils.applications.app_deployer.ApplicationLookup) | None* *= None* +Optional existing deployments + #### ignore_cache *: bool* *= False* +Whether to ignore the cache + #### max_fee *: int | None* *= None* +Optional maximum fee + #### send_params *: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None* *= None* +Optional send parameters + ### *class* algokit_utils.applications.app_deployer.AppDeployResult +The result of a deployment + #### app *: [ApplicationMetaData](#algokit_utils.applications.app_deployer.ApplicationMetaData)* +The application metadata + #### operation_performed *: [algokit_utils.applications.enums.OperationPerformed](../enums/index.md#algokit_utils.applications.enums.OperationPerformed)* +The operation performed + #### create_result *: [algokit_utils.transactions.transaction_sender.SendAppCreateTransactionResult](../../transactions/transaction_sender/index.md#algokit_utils.transactions.transaction_sender.SendAppCreateTransactionResult)[[algokit_utils.applications.abi.ABIReturn](../abi/index.md#algokit_utils.applications.abi.ABIReturn)] | None* *= None* +The create result + #### update_result *: [algokit_utils.transactions.transaction_sender.SendAppUpdateTransactionResult](../../transactions/transaction_sender/index.md#algokit_utils.transactions.transaction_sender.SendAppUpdateTransactionResult)[[algokit_utils.applications.abi.ABIReturn](../abi/index.md#algokit_utils.applications.abi.ABIReturn)] | None* *= None* +The update result + #### delete_result *: [algokit_utils.transactions.transaction_sender.SendAppTransactionResult](../../transactions/transaction_sender/index.md#algokit_utils.transactions.transaction_sender.SendAppTransactionResult)[[algokit_utils.applications.abi.ABIReturn](../abi/index.md#algokit_utils.applications.abi.ABIReturn)] | None* *= None* +The delete result + ### *class* algokit_utils.applications.app_deployer.AppDeployer(app_manager: [algokit_utils.applications.app_manager.AppManager](../app_manager/index.md#algokit_utils.applications.app_manager.AppManager), transaction_sender: [algokit_utils.transactions.transaction_sender.AlgorandClientTransactionSender](../../transactions/transaction_sender/index.md#algokit_utils.transactions.transaction_sender.AlgorandClientTransactionSender), indexer: algosdk.v2client.indexer.IndexerClient | None = None) Manages deployment and deployment metadata of applications +* **Parameters:** + * **app_manager** – The app manager to use + * **transaction_sender** – The transaction sender to use + * **indexer** – The indexer to use +* **Example:** + ```pycon + >>> deployer = AppDeployer(app_manager, transaction_sender, indexer) + ``` + #### deploy(deployment: [AppDeployParams](#algokit_utils.applications.app_deployer.AppDeployParams)) → [AppDeployResult](#algokit_utils.applications.app_deployer.AppDeployResult) +Idempotently deploy (create if not exists, update if changed) an app against the given name for the given +creator account, including deploy-time TEAL template placeholder substitutions (if specified). + +To understand the architecture decisions behind this functionality please see +[https://github.com/algorandfoundation/algokit-cli/blob/main/docs/architecture-decisions/2023-01-12_smart-contract-deployment.md](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/architecture-decisions/2023-01-12_smart-contract-deployment.md) + +**Note:** When using the return from this function be sure to check operation_performed to get access to +return properties like transaction, confirmation and delete_result. + +**Note:** if there is a breaking state schema change to an existing app (and on_schema_break is set to +‘replace’) the existing app will be deleted and re-created. + +**Note:** if there is an update (different TEAL code) to an existing app (and on_update is set to ‘replace’) +the existing app will be deleted and re-created. + +* **Parameters:** + **deployment** – The arguments to control the app deployment +* **Returns:** + The result of the deployment +* **Raises:** + **ValueError** – If the app spec format is invalid +* **Example:** + ```pycon + >>> deployer.deploy(AppDeployParams( + ... create_params=AppCreateParams( + ... sender='SENDER_ADDRESS', + ... approval_program='APPROVAL PROGRAM', + ... clear_state_program='CLEAR PROGRAM', + ... schema={ + ... 'global_byte_slices': 0, + ... 'global_ints': 0, + ... 'local_byte_slices': 0, + ... 'local_ints': 0 + ... } + ... ), + ... update_params=AppUpdateParams( + ... sender='SENDER_ADDRESS' + ... ), + ... delete_params=AppDeleteParams( + ... sender='SENDER_ADDRESS' + ... ), + ... metadata=AppDeploymentMetaData( + ... name='my_app', + ... version='2.0', + ... updatable=False, + ... deletable=False + ... ), + ... on_schema_break=OnSchemaBreak.AppendApp, + ... on_update=OnUpdate.AppendApp + ... ) + ... ) + ``` + #### get_creator_apps_by_name(\*, creator_address: str, ignore_cache: bool = False) → [ApplicationLookup](#algokit_utils.applications.app_deployer.ApplicationLookup) -Get apps created by an account +Returns a lookup of name => app metadata (id, address, …metadata) for all apps created by the given account +that have an [ARC-2]([https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0002.md](https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0002.md)) AppDeployNote as +the transaction note of the app creation transaction. + +This function caches the result for the given creator account so that subsequent calls won’t require an indexer +lookup. + +If the AppManager instance wasn’t created with an indexer client, this function will throw an error. + +* **Parameters:** + * **creator_address** – The address of the account that is the creator of the apps you want to search for + * **ignore_cache** – Whether or not to ignore the cache and force a lookup, default: use the cache +* **Returns:** + A name-based lookup of the app metadata +* **Raises:** + **ValueError** – If the app spec format is invalid +* **Example:** + ```pycon + >>> result = await deployer.get_creator_apps_by_name(creator) + ``` diff --git a/docs/markdown/autoapi/algokit_utils/applications/app_factory/index.md b/docs/markdown/autoapi/algokit_utils/applications/app_factory/index.md index c5bf88a2..1e2829e4 100644 --- a/docs/markdown/autoapi/algokit_utils/applications/app_factory/index.md +++ b/docs/markdown/autoapi/algokit_utils/applications/app_factory/index.md @@ -2,16 +2,16 @@ ## Classes -| [`AppFactoryParams`](#algokit_utils.applications.app_factory.AppFactoryParams) | | -|--------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------| -| [`AppFactoryCreateParams`](#algokit_utils.applications.app_factory.AppFactoryCreateParams) | Parameters for creating application with bare call. | -| [`AppFactoryCreateMethodCallParams`](#algokit_utils.applications.app_factory.AppFactoryCreateMethodCallParams) | Parameters for creating application with method call | -| [`AppFactoryCreateMethodCallResult`](#algokit_utils.applications.app_factory.AppFactoryCreateMethodCallResult) | Base class for transaction results. | -| [`SendAppFactoryTransactionResult`](#algokit_utils.applications.app_factory.SendAppFactoryTransactionResult) | Result of an application transaction. | -| [`SendAppUpdateFactoryTransactionResult`](#algokit_utils.applications.app_factory.SendAppUpdateFactoryTransactionResult) | Result of updating an application. | -| [`SendAppCreateFactoryTransactionResult`](#algokit_utils.applications.app_factory.SendAppCreateFactoryTransactionResult) | Result of creating a new application. | -| [`AppFactoryDeployResult`](#algokit_utils.applications.app_factory.AppFactoryDeployResult) | Result from deploying an application via AppFactory | -| [`AppFactory`](#algokit_utils.applications.app_factory.AppFactory) | | +| [`AppFactoryParams`](#algokit_utils.applications.app_factory.AppFactoryParams) | | +|--------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------| +| [`AppFactoryCreateParams`](#algokit_utils.applications.app_factory.AppFactoryCreateParams) | Parameters for creating application with bare call. | +| [`AppFactoryCreateMethodCallParams`](#algokit_utils.applications.app_factory.AppFactoryCreateMethodCallParams) | Parameters for creating application with method call | +| [`AppFactoryCreateMethodCallResult`](#algokit_utils.applications.app_factory.AppFactoryCreateMethodCallResult) | Base class for transaction results. | +| [`SendAppFactoryTransactionResult`](#algokit_utils.applications.app_factory.SendAppFactoryTransactionResult) | Result of an application transaction. | +| [`SendAppUpdateFactoryTransactionResult`](#algokit_utils.applications.app_factory.SendAppUpdateFactoryTransactionResult) | Result of updating an application. | +| [`SendAppCreateFactoryTransactionResult`](#algokit_utils.applications.app_factory.SendAppCreateFactoryTransactionResult) | Result of creating a new application. | +| [`AppFactoryDeployResult`](#algokit_utils.applications.app_factory.AppFactoryDeployResult) | Result from deploying an application via AppFactory | +| [`AppFactory`](#algokit_utils.applications.app_factory.AppFactory) | ARC-56/ARC-32 app factory that, for a given app spec, allows you to create | ## Module Contents @@ -39,6 +39,8 @@ Parameters for creating application with bare call. #### on_complete *: algokit_utils.applications.app_client.CreateOnComplete | None* *= None* +Optional on complete action + ### *class* algokit_utils.applications.app_factory.AppFactoryCreateMethodCallParams Bases: [`algokit_utils.applications.app_client.AppClientMethodCallCreateParams`](../app_client/index.md#algokit_utils.applications.app_client.AppClientMethodCallCreateParams) @@ -93,40 +95,227 @@ Result from deploying an application via AppFactory #### app *: [algokit_utils.applications.app_deployer.ApplicationMetaData](../app_deployer/index.md#algokit_utils.applications.app_deployer.ApplicationMetaData)* +The application metadata + #### operation_performed *: algokit_utils.applications.app_deployer.OperationPerformed* +The operation performed + #### create_result *: [SendAppCreateFactoryTransactionResult](#algokit_utils.applications.app_factory.SendAppCreateFactoryTransactionResult) | None* *= None* +The create result + #### update_result *: [SendAppUpdateFactoryTransactionResult](#algokit_utils.applications.app_factory.SendAppUpdateFactoryTransactionResult) | None* *= None* +The update result + #### delete_result *: [SendAppFactoryTransactionResult](#algokit_utils.applications.app_factory.SendAppFactoryTransactionResult) | None* *= None* +The delete result + #### *classmethod* from_deploy_result(response: [algokit_utils.applications.app_deployer.AppDeployResult](../app_deployer/index.md#algokit_utils.applications.app_deployer.AppDeployResult), deploy_params: [algokit_utils.applications.app_deployer.AppDeployParams](../app_deployer/index.md#algokit_utils.applications.app_deployer.AppDeployParams), app_spec: [algokit_utils.applications.app_spec.arc56.Arc56Contract](../app_spec/arc56/index.md#algokit_utils.applications.app_spec.arc56.Arc56Contract), app_compilation_data: [algokit_utils.applications.app_client.AppClientCompilationResult](../app_client/index.md#algokit_utils.applications.app_client.AppClientCompilationResult) | None = None) → typing_extensions.Self +Construct an AppFactoryDeployResult from a deployment result. + +* **Parameters:** + * **response** – The deployment response. + * **deploy_params** – The deployment parameters. + * **app_spec** – The application specification. + * **app_compilation_data** – Optional app compilation data. +* **Returns:** + An instance of AppFactoryDeployResult. + ### *class* algokit_utils.applications.app_factory.AppFactory(params: [AppFactoryParams](#algokit_utils.applications.app_factory.AppFactoryParams)) +ARC-56/ARC-32 app factory that, for a given app spec, allows you to create +and deploy one or more app instances and to create one or more app clients +to interact with those (or other) app instances. + +* **Parameters:** + **params** – The parameters for the factory +* **Example:** + ```pycon + >>> factory = AppFactory(AppFactoryParams( + >>> algorand=AlgorandClient.mainnet(), + >>> app_spec=app_spec, + >>> ) + >>> ) + ``` + #### *property* app_name *: str* +The name of the app + #### *property* app_spec *: [algokit_utils.applications.app_spec.arc56.Arc56Contract](../app_spec/arc56/index.md#algokit_utils.applications.app_spec.arc56.Arc56Contract)* +The app spec + #### *property* algorand *: [algokit_utils.algorand.AlgorandClient](../../algorand/index.md#algokit_utils.algorand.AlgorandClient)* +The algorand client + #### *property* params *: \_MethodParamsBuilder* +Get parameters to create transactions (create and deploy related calls) for the current app. + +A good mental model for this is that these parameters represent a deferred transaction creation. + +* **Example:** + Create a transaction in the future using Algorand Client + >>> create_app_params = app_factory.params.create( + … AppFactoryCreateMethodCallParams( + … method=’create_method’, + … args=[123, ‘hello’] + … ) + … ) + >>> # … + >>> algorand.send.app_create_method_call(create_app_params) +* **Example:** + Define a nested transaction as an ABI argument + >>> create_app_params = appFactory.params.create( + … AppFactoryCreateMethodCallParams( + … method=’create_method’, + … args=[123, ‘hello’] + … ) + … ) + >>> app_client.send.call( + … AppClientMethodCallParams( + … method=’my_method’, + … args=[create_app_params] + … ) + … ) + #### *property* send *: \_TransactionSender* +Get the transaction sender. + +* **Returns:** + The \_TransactionSender instance. + #### *property* create_transaction *: \_TransactionCreator* +Get the transaction creator. + +* **Returns:** + The \_TransactionCreator instance. + #### deploy(\*, on_update: algokit_utils.applications.app_deployer.OnUpdate | None = None, on_schema_break: algokit_utils.applications.app_deployer.OnSchemaBreak | None = None, create_params: [algokit_utils.applications.app_client.AppClientMethodCallCreateParams](../app_client/index.md#algokit_utils.applications.app_client.AppClientMethodCallCreateParams) | [algokit_utils.applications.app_client.AppClientBareCallCreateParams](../app_client/index.md#algokit_utils.applications.app_client.AppClientBareCallCreateParams) | None = None, update_params: [algokit_utils.applications.app_client.AppClientMethodCallParams](../app_client/index.md#algokit_utils.applications.app_client.AppClientMethodCallParams) | [algokit_utils.applications.app_client.AppClientBareCallParams](../app_client/index.md#algokit_utils.applications.app_client.AppClientBareCallParams) | None = None, delete_params: [algokit_utils.applications.app_client.AppClientMethodCallParams](../app_client/index.md#algokit_utils.applications.app_client.AppClientMethodCallParams) | [algokit_utils.applications.app_client.AppClientBareCallParams](../app_client/index.md#algokit_utils.applications.app_client.AppClientBareCallParams) | None = None, existing_deployments: [algokit_utils.applications.app_deployer.ApplicationLookup](../app_deployer/index.md#algokit_utils.applications.app_deployer.ApplicationLookup) | None = None, ignore_cache: bool = False, app_name: str | None = None, send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None, compilation_params: [algokit_utils.applications.app_client.AppClientCompilationParams](../app_client/index.md#algokit_utils.applications.app_client.AppClientCompilationParams) | None = None) → tuple[[algokit_utils.applications.app_client.AppClient](../app_client/index.md#algokit_utils.applications.app_client.AppClient), [AppFactoryDeployResult](#algokit_utils.applications.app_factory.AppFactoryDeployResult)] -Deploy the application with the specified parameters. +Idempotently deploy (create if not exists, update if changed) an app against the given name for the given +creator account, including deploy-time TEAL template placeholder substitutions (if specified). + +**Note:** When using the return from this function be sure to check operationPerformed to get access to +various return properties like transaction, confirmation and deleteResult. + +**Note:** if there is a breaking state schema change to an existing app (and onSchemaBreak is set to +‘replace’) the existing app will be deleted and re-created. + +**Note:** if there is an update (different TEAL code) to an existing app (and onUpdate is set to +‘replace’) the existing app will be deleted and re-created. + +* **Parameters:** + * **on_update** – The action to take if there is an update to the app + * **on_schema_break** – The action to take if there is a breaking state schema change to the app + * **create_params** – The arguments to create the app + * **update_params** – The arguments to update the app + * **delete_params** – The arguments to delete the app + * **existing_deployments** – The existing deployments to use + * **ignore_cache** – Whether to ignore the cache + * **app_name** – The name of the app + * **send_params** – The parameters for the send call + * **compilation_params** – The parameters for the compilation +* **Returns:** + The app client and the result of the deployment +* **Example:** + ```pycon + >>> app_client, result = factory.deploy({ + >>> create_params=AppClientMethodCallCreateParams( + >>> sender='SENDER_ADDRESS', + >>> approval_program='APPROVAL PROGRAM', + >>> clear_state_program='CLEAR PROGRAM', + >>> schema={ + >>> "global_byte_slices": 0, + >>> "global_ints": 0, + >>> "local_byte_slices": 0, + >>> "local_ints": 0 + >>> } + >>> ), + >>> update_params=AppClientMethodCallParams( + >>> sender='SENDER_ADDRESS' + >>> ), + >>> delete_params=AppClientMethodCallParams( + >>> sender='SENDER_ADDRESS' + >>> ), + >>> compilation_params=AppClientCompilationParams( + >>> updatable=False, + >>> deletable=False + >>> ), + >>> app_name='my_app', + >>> on_schema_break=OnSchemaBreak.AppendApp, + >>> on_update=OnUpdate.AppendApp + >>> }) + ``` #### get_app_client_by_id(app_id: int, app_name: str | None = None, default_sender: str | None = None, default_signer: algosdk.atomic_transaction_composer.TransactionSigner | None = None, approval_source_map: algosdk.source_map.SourceMap | None = None, clear_source_map: algosdk.source_map.SourceMap | None = None) → [algokit_utils.applications.app_client.AppClient](../app_client/index.md#algokit_utils.applications.app_client.AppClient) +Returns a new AppClient client for an app instance of the given ID. + +* **Parameters:** + * **app_id** – The id of the app + * **app_name** – The name of the app + * **default_sender** – The default sender address + * **default_signer** – The default signer + * **approval_source_map** – The approval source map + * **clear_source_map** – The clear source map +* **Return AppClient:** + The app client +* **Example:** + ```pycon + >>> app_client = factory.get_app_client_by_id(app_id=123) + ``` + #### get_app_client_by_creator_and_name(creator_address: str, app_name: str, default_sender: str | None = None, default_signer: algosdk.atomic_transaction_composer.TransactionSigner | None = None, ignore_cache: bool | None = None, app_lookup_cache: [algokit_utils.applications.app_deployer.ApplicationLookup](../app_deployer/index.md#algokit_utils.applications.app_deployer.ApplicationLookup) | None = None, approval_source_map: algosdk.source_map.SourceMap | None = None, clear_source_map: algosdk.source_map.SourceMap | None = None) → [algokit_utils.applications.app_client.AppClient](../app_client/index.md#algokit_utils.applications.app_client.AppClient) +Returns a new AppClient client, resolving the app by creator address and name +using AlgoKit app deployment semantics (i.e. looking for the app creation transaction note). + +* **Parameters:** + * **creator_address** – The creator address + * **app_name** – The name of the app + * **default_sender** – The default sender address + * **default_signer** – The default signer + * **ignore_cache** – Whether to ignore the cache and force a lookup + * **app_lookup_cache** – Optional cache of existing app deployments to use instead of querying the indexer + * **approval_source_map** – Optional source map for the approval program + * **clear_source_map** – Optional source map for the clear state program +* **Returns:** + An AppClient instance configured for the resolved application +* **Example:** + ```pycon + >>> app_client = factory.get_app_client_by_creator_and_name( + ... creator_address='SENDER_ADDRESS', + ... app_name='my_app' + ... ) + ``` + #### export_source_maps() → [algokit_utils.models.application.AppSourceMaps](../../models/application/index.md#algokit_utils.models.application.AppSourceMaps) #### import_source_maps(source_maps: [algokit_utils.models.application.AppSourceMaps](../../models/application/index.md#algokit_utils.models.application.AppSourceMaps)) → None +Import the provided source maps into the factory. + +* **Parameters:** + **source_maps** – An AppSourceMaps instance containing the approval and clear source maps. + #### compile(compilation_params: [algokit_utils.applications.app_client.AppClientCompilationParams](../app_client/index.md#algokit_utils.applications.app_client.AppClientCompilationParams) | None = None) → [algokit_utils.applications.app_client.AppClientCompilationResult](../app_client/index.md#algokit_utils.applications.app_client.AppClientCompilationResult) + +Compile the app’s TEAL code. + +* **Parameters:** + **compilation_params** – The compilation parameters +* **Return AppClientCompilationResult:** + The compilation result +* **Example:** + ```pycon + >>> compilation_result = factory.compile() + ``` diff --git a/docs/markdown/autoapi/algokit_utils/applications/app_manager/index.md b/docs/markdown/autoapi/algokit_utils/applications/app_manager/index.md index a29a20ec..d27cb919 100644 --- a/docs/markdown/autoapi/algokit_utils/applications/app_manager/index.md +++ b/docs/markdown/autoapi/algokit_utils/applications/app_manager/index.md @@ -30,6 +30,10 @@ and interacting with application boxes. * **Parameters:** **algod_client** – The Algorand client instance to use for interacting with the network +* **Example:** + ```pycon + >>> app_manager = AppManager(algod_client) + ``` #### compile_teal(teal_code: str) → [algokit_utils.models.application.CompiledTeal](../../models/application/index.md#algokit_utils.models.application.CompiledTeal) @@ -50,6 +54,15 @@ Compile a TEAL template with parameters. * **deployment_metadata** – Deployment control parameters * **Returns:** The compiled TEAL code and associated metadata +* **Example:** + ```pycon + >>> app_manager = AppManager(algod_client) + >>> teal_template_code = + ... # This is a TEAL template + ... # It can contain template variables like {TMPL_UPDATABLE} and {TMPL_DELETABLE} + ... + >>> compiled_teal = app_manager.compile_teal_template(teal_template_code) + ``` #### get_compilation_result(teal_code: str) → [algokit_utils.models.application.CompiledTeal](../../models/application/index.md#algokit_utils.models.application.CompiledTeal) | None @@ -59,6 +72,13 @@ Get cached compilation result for TEAL code if available. **teal_code** – The TEAL source code * **Returns:** The cached compilation result if available, None otherwise +* **Example:** + ```pycon + >>> app_manager = AppManager(algod_client) + >>> teal_code = "RETURN 1" + >>> compiled_teal = app_manager.compile_teal(teal_code) + >>> compilation_result = app_manager.get_compilation_result(teal_code) + ``` #### get_by_id(app_id: int) → [algokit_utils.models.application.AppInformation](../../models/application/index.md#algokit_utils.models.application.AppInformation) @@ -68,6 +88,12 @@ Get information about an application by ID. **app_id** – The application ID * **Returns:** Information about the application +* **Example:** + ```pycon + >>> app_manager = AppManager(algod_client) + >>> app_id = 1234567890 + >>> app_info = app_manager.get_by_id(app_id) + ``` #### get_global_state(app_id: int) → dict[str, [algokit_utils.models.application.AppState](../../models/application/index.md#algokit_utils.models.application.AppState)] @@ -77,6 +103,12 @@ Get the global state of an application. **app_id** – The application ID * **Returns:** The application’s global state +* **Example:** + ```pycon + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> global_state = app_manager.get_global_state(app_id) + ``` #### get_local_state(app_id: int, address: str) → dict[str, [algokit_utils.models.application.AppState](../../models/application/index.md#algokit_utils.models.application.AppState)] @@ -89,6 +121,13 @@ Get the local state for an account in an application. The account’s local state for the application * **Raises:** **ValueError** – If local state is not found +* **Example:** + ```pycon + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> address = "SENDER_ADDRESS" + >>> local_state = app_manager.get_local_state(app_id, address) + ``` #### get_box_names(app_id: int) → list[[algokit_utils.models.state.BoxName](../../models/state/index.md#algokit_utils.models.state.BoxName)] @@ -98,6 +137,12 @@ Get names of all boxes for an application. **app_id** – The application ID * **Returns:** List of box names +* **Example:** + ```pycon + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> box_names = app_manager.get_box_names(app_id) + ``` #### get_box_value(app_id: int, box_name: algokit_utils.models.state.BoxIdentifier) → bytes @@ -108,6 +153,13 @@ Get the value stored in a box. * **box_name** – The box identifier * **Returns:** The box value as bytes +* **Example:** + ```pycon + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> box_name = "BOX_NAME" + >>> box_value = app_manager.get_box_value(app_id, box_name) + ``` #### get_box_values(app_id: int, box_names: list[algokit_utils.models.state.BoxIdentifier]) → list[bytes] @@ -118,6 +170,13 @@ Get values for multiple boxes. * **box_names** – List of box identifiers * **Returns:** List of box values as bytes +* **Example:** + ```pycon + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> box_names = ["BOX_NAME_1", "BOX_NAME_2"] + >>> box_values = app_manager.get_box_values(app_id, box_names) + ``` #### get_box_value_from_abi_type(app_id: int, box_name: algokit_utils.models.state.BoxIdentifier, abi_type: algokit_utils.applications.abi.ABIType) → algokit_utils.applications.abi.ABIValue @@ -131,6 +190,14 @@ Get and decode a box value using an ABI type. The decoded box value * **Raises:** **ValueError** – If decoding fails +* **Example:** + ```pycon + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> box_name = "BOX_NAME" + >>> abi_type = ABIType.UINT + >>> box_value = app_manager.get_box_value_from_abi_type(app_id, box_name, abi_type) + ``` #### get_box_values_from_abi_type(app_id: int, box_names: list[algokit_utils.models.state.BoxIdentifier], abi_type: algokit_utils.applications.abi.ABIType) → list[algokit_utils.applications.abi.ABIValue] @@ -142,6 +209,14 @@ Get and decode multiple box values using an ABI type. * **abi_type** – The ABI type to decode with * **Returns:** List of decoded box values +* **Example:** + ```pycon + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> box_names = ["BOX_NAME_1", "BOX_NAME_2"] + >>> abi_type = ABIType.UINT + >>> box_values = app_manager.get_box_values_from_abi_type(app_id, box_names, abi_type) + ``` #### *static* get_box_reference(box_id: algokit_utils.models.state.BoxIdentifier | [algokit_utils.models.state.BoxReference](../../models/state/index.md#algokit_utils.models.state.BoxReference)) → tuple[int, bytes] @@ -153,6 +228,13 @@ Get standardized box reference from various identifier types. Tuple of (app_id, box_name_bytes) * **Raises:** **ValueError** – If box identifier type is invalid +* **Example:** + ```pycon + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> box_name = "BOX_NAME" + >>> box_reference = app_manager.get_box_reference(box_name) + ``` #### *static* get_abi_return(confirmation: algosdk.v2client.algod.AlgodResponseType, method: algosdk.abi.Method | None = None) → [algokit_utils.applications.abi.ABIReturn](../abi/index.md#algokit_utils.applications.abi.ABIReturn) | None @@ -163,6 +245,14 @@ Get the ABI return value from a transaction confirmation. * **method** – The ABI method * **Returns:** The parsed ABI return value, or None if not available +* **Example:** + ```pycon + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> method = "METHOD_NAME" + >>> confirmation = algod_client.pending_transaction_info(tx_id) + >>> abi_return = app_manager.get_abi_return(confirmation, method) + ``` #### *static* decode_app_state(state: list[dict[str, Any]]) → dict[str, [algokit_utils.models.application.AppState](../../models/application/index.md#algokit_utils.models.application.AppState)] @@ -174,6 +264,13 @@ Decode application state from raw format. Decoded application state * **Raises:** **ValueError** – If unknown state data type is encountered +* **Example:** + ```pycon + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> state = app_manager.get_global_state(app_id) + >>> decoded_state = app_manager.decode_app_state(state) + ``` #### *static* replace_template_variables(program: str, template_values: algokit_utils.models.state.TealTemplateParams) → str @@ -186,6 +283,14 @@ Replace template variables in TEAL code. TEAL code with substituted values * **Raises:** **ValueError** – If template value type is unexpected +* **Example:** + ```pycon + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> program = "RETURN 1" + >>> template_values = {"TMPL_UPDATABLE": True, "TMPL_DELETABLE": True} + >>> updated_program = app_manager.replace_template_variables(program, template_values) + ``` #### *static* replace_teal_template_deploy_time_control_params(teal_template_code: str, params: collections.abc.Mapping[str, bool | None]) → str @@ -198,5 +303,28 @@ Replace deploy-time control parameters in TEAL template. TEAL code with substituted control parameters * **Raises:** **ValueError** – If template variables not found in code +* **Example:** + ```pycon + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> teal_template_code = "RETURN 1" + >>> params = {"TMPL_UPDATABLE": True, "TMPL_DELETABLE": True} + >>> updated_teal_code = app_manager.replace_teal_template_deploy_time_control_params( + teal_template_code, params + ) + ``` #### *static* strip_teal_comments(teal_code: str) → str + +Strip comments from TEAL code. + +* **Parameters:** + **teal_code** – The TEAL code to strip comments from +* **Returns:** + The TEAL code with comments stripped +* **Example:** + ```pycon + >>> app_manager = AppManager(algod_client) + >>> teal_code = "RETURN 1" + >>> stripped_teal_code = app_manager.strip_teal_comments(teal_code) + ``` diff --git a/docs/markdown/autoapi/algokit_utils/applications/app_spec/arc56/index.md b/docs/markdown/autoapi/algokit_utils/applications/app_spec/arc56/index.md index f6262e7a..14168ec5 100644 --- a/docs/markdown/autoapi/algokit_utils/applications/app_spec/arc56/index.md +++ b/docs/markdown/autoapi/algokit_utils/applications/app_spec/arc56/index.md @@ -44,14 +44,14 @@ Represents a field in a struct type. -* **Variables:** - * **name** – Name of the struct field - * **type** – Type of the struct field, either a string or list of StructFields - #### name *: str* +The name of the struct field + #### type *: list[[StructField](#algokit_utils.applications.app_spec.arc56.StructField)] | str* +The type of the struct field, either a string or list of StructFields + #### *static* from_dict(data: dict[str, Any]) → [StructField](#algokit_utils.applications.app_spec.arc56.StructField) ### *class* algokit_utils.applications.app_spec.arc56.CallEnum @@ -88,28 +88,28 @@ Enum representing different create types for application transactions. Represents bare call and create actions for an application. -* **Variables:** - * **call** – List of allowed call actions - * **create** – List of allowed create actions - #### call *: list[[CallEnum](#algokit_utils.applications.app_spec.arc56.CallEnum)]* +The list of allowed call actions + #### create *: list[[CreateEnum](#algokit_utils.applications.app_spec.arc56.CreateEnum)]* +The list of allowed create actions + #### *static* from_dict(data: dict[str, Any]) → [BareActions](#algokit_utils.applications.app_spec.arc56.BareActions) ### *class* algokit_utils.applications.app_spec.arc56.ByteCode Represents the approval and clear program bytecode. -* **Variables:** - * **approval** – Base64 encoded approval program bytecode - * **clear** – Base64 encoded clear program bytecode - #### approval *: str* +The base64 encoded approval program bytecode + #### clear *: str* +The base64 encoded clear program bytecode + #### *static* from_dict(data: dict[str, Any]) → [ByteCode](#algokit_utils.applications.app_spec.arc56.ByteCode) ### *class* algokit_utils.applications.app_spec.arc56.Compiler @@ -126,73 +126,74 @@ Enum representing different compiler types. Represents compiler version information. -* **Variables:** - * **commit_hash** – Git commit hash of the compiler - * **major** – Major version number - * **minor** – Minor version number - * **patch** – Patch version number - #### commit_hash *: str | None* *= None* +The git commit hash of the compiler + #### major *: int | None* *= None* +The major version number + #### minor *: int | None* *= None* +The minor version number + #### patch *: int | None* *= None* +The patch version number + #### *static* from_dict(data: dict[str, Any]) → [CompilerVersion](#algokit_utils.applications.app_spec.arc56.CompilerVersion) ### *class* algokit_utils.applications.app_spec.arc56.CompilerInfo Information about the compiler used. -* **Variables:** - * **compiler** – Type of compiler used - * **compiler_version** – Version information for the compiler - #### compiler *: [Compiler](#algokit_utils.applications.app_spec.arc56.Compiler)* +The type of compiler used + #### compiler_version *: [CompilerVersion](#algokit_utils.applications.app_spec.arc56.CompilerVersion)* +Version information for the compiler + #### *static* from_dict(data: dict[str, Any]) → [CompilerInfo](#algokit_utils.applications.app_spec.arc56.CompilerInfo) ### *class* algokit_utils.applications.app_spec.arc56.Network Network-specific application information. -* **Variables:** - **app_id** – Application ID on the network - #### app_id *: int* +The application ID on the network + #### *static* from_dict(data: dict[str, Any]) → [Network](#algokit_utils.applications.app_spec.arc56.Network) ### *class* algokit_utils.applications.app_spec.arc56.ScratchVariables Information about scratch space variables. -* **Variables:** - * **slot** – Scratch slot number - * **type** – Type of the scratch variable - #### slot *: int* +The scratch slot number + #### type *: str* +The type of the scratch variable + #### *static* from_dict(data: dict[str, Any]) → [ScratchVariables](#algokit_utils.applications.app_spec.arc56.ScratchVariables) ### *class* algokit_utils.applications.app_spec.arc56.Source Source code for approval and clear programs. -* **Variables:** - * **approval** – Base64 encoded approval program source - * **clear** – Base64 encoded clear program source - #### approval *: str* +The base64 encoded approval program source + #### clear *: str* +The base64 encoded clear program source + #### *static* from_dict(data: dict[str, Any]) → [Source](#algokit_utils.applications.app_spec.arc56.Source) #### get_decoded_approval() → str @@ -213,239 +214,258 @@ Get decoded clear program source. Global state schema. -* **Variables:** - * **bytes** – Number of byte slices in global state - * **ints** – Number of integers in global state - #### bytes *: int* +The number of byte slices in global state + #### ints *: int* +The number of integers in global state + #### *static* from_dict(data: dict[str, Any]) → [Global](#algokit_utils.applications.app_spec.arc56.Global) ### *class* algokit_utils.applications.app_spec.arc56.Local Local state schema. -* **Variables:** - * **bytes** – Number of byte slices in local state - * **ints** – Number of integers in local state - #### bytes *: int* +The number of byte slices in local state + #### ints *: int* +The number of integers in local state + #### *static* from_dict(data: dict[str, Any]) → [Local](#algokit_utils.applications.app_spec.arc56.Local) ### *class* algokit_utils.applications.app_spec.arc56.Schema Application state schema. -* **Variables:** - * **global_state** – Global state schema - * **local_state** – Local state schema - #### global_state *: [Global](#algokit_utils.applications.app_spec.arc56.Global)* +The global state schema + #### local_state *: [Local](#algokit_utils.applications.app_spec.arc56.Local)* +The local state schema + #### *static* from_dict(data: dict[str, Any]) → [Schema](#algokit_utils.applications.app_spec.arc56.Schema) ### *class* algokit_utils.applications.app_spec.arc56.TemplateVariables Template variable information. -* **Variables:** - * **type** – Type of the template variable - * **value** – Optional value of the template variable - #### type *: str* +The type of the template variable + #### value *: str | None* *= None* +The optional value of the template variable + #### *static* from_dict(data: dict[str, Any]) → [TemplateVariables](#algokit_utils.applications.app_spec.arc56.TemplateVariables) ### *class* algokit_utils.applications.app_spec.arc56.EventArg Event argument information. -* **Variables:** - * **type** – Type of the event argument - * **desc** – Optional description of the argument - * **name** – Optional name of the argument - * **struct** – Optional struct type name - #### type *: str* +The type of the event argument + #### desc *: str | None* *= None* +The optional description of the argument + #### name *: str | None* *= None* +The optional name of the argument + #### struct *: str | None* *= None* +The optional struct type name + #### *static* from_dict(data: dict[str, Any]) → [EventArg](#algokit_utils.applications.app_spec.arc56.EventArg) ### *class* algokit_utils.applications.app_spec.arc56.Event Event information. -* **Variables:** - * **args** – List of event arguments - * **name** – Name of the event - * **desc** – Optional description of the event - #### args *: list[[EventArg](#algokit_utils.applications.app_spec.arc56.EventArg)]* +The list of event arguments + #### name *: str* +The name of the event + #### desc *: str | None* *= None* +The optional description of the event + #### *static* from_dict(data: dict[str, Any]) → [Event](#algokit_utils.applications.app_spec.arc56.Event) ### *class* algokit_utils.applications.app_spec.arc56.Actions Method actions information. -* **Variables:** - * **call** – Optional list of allowed call actions - * **create** – Optional list of allowed create actions - #### call *: list[[CallEnum](#algokit_utils.applications.app_spec.arc56.CallEnum)] | None* *= None* +The optional list of allowed call actions + #### create *: list[[CreateEnum](#algokit_utils.applications.app_spec.arc56.CreateEnum)] | None* *= None* +The optional list of allowed create actions + #### *static* from_dict(data: dict[str, Any]) → [Actions](#algokit_utils.applications.app_spec.arc56.Actions) ### *class* algokit_utils.applications.app_spec.arc56.DefaultValue Default value information for method arguments. -* **Variables:** - * **data** – Default value data - * **source** – Source of the default value - * **type** – Optional type of the default value - #### data *: str* +The default value data + #### source *: Literal['box', 'global', 'local', 'literal', 'method']* +The source of the default value + #### type *: str | None* *= None* +The optional type of the default value + #### *static* from_dict(data: dict[str, Any]) → [DefaultValue](#algokit_utils.applications.app_spec.arc56.DefaultValue) ### *class* algokit_utils.applications.app_spec.arc56.MethodArg Method argument information. -* **Variables:** - * **type** – Type of the argument - * **default_value** – Optional default value - * **desc** – Optional description - * **name** – Optional name - * **struct** – Optional struct type name - #### type *: str* +The type of the argument + #### default_value *: [DefaultValue](#algokit_utils.applications.app_spec.arc56.DefaultValue) | None* *= None* +The optional default value + #### desc *: str | None* *= None* +The optional description + #### name *: str | None* *= None* +The optional name + #### struct *: str | None* *= None* +The optional struct type name + #### *static* from_dict(data: dict[str, Any]) → [MethodArg](#algokit_utils.applications.app_spec.arc56.MethodArg) ### *class* algokit_utils.applications.app_spec.arc56.Boxes Box storage requirements. -* **Variables:** - * **key** – Box key - * **read_bytes** – Number of bytes to read - * **write_bytes** – Number of bytes to write - * **app** – Optional application ID - #### key *: str* +The box key + #### read_bytes *: int* +The number of bytes to read + #### write_bytes *: int* +The number of bytes to write + #### app *: int | None* *= None* +The optional application ID + #### *static* from_dict(data: dict[str, Any]) → [Boxes](#algokit_utils.applications.app_spec.arc56.Boxes) ### *class* algokit_utils.applications.app_spec.arc56.Recommendations Method execution recommendations. -* **Variables:** - * **accounts** – Optional list of accounts - * **apps** – Optional list of applications - * **assets** – Optional list of assets - * **boxes** – Optional box storage requirements - * **inner_transaction_count** – Optional inner transaction count - #### accounts *: list[str] | None* *= None* +The optional list of accounts + #### apps *: list[int] | None* *= None* +The optional list of applications + #### assets *: list[int] | None* *= None* +The optional list of assets + #### boxes *: [Boxes](#algokit_utils.applications.app_spec.arc56.Boxes) | None* *= None* +The optional box storage requirements + #### inner_transaction_count *: int | None* *= None* +The optional inner transaction count + #### *static* from_dict(data: dict[str, Any]) → [Recommendations](#algokit_utils.applications.app_spec.arc56.Recommendations) ### *class* algokit_utils.applications.app_spec.arc56.Returns Method return information. -* **Variables:** - * **type** – Return type - * **desc** – Optional description - * **struct** – Optional struct type name - #### type *: str* +The type of the return value + #### desc *: str | None* *= None* +The optional description + #### struct *: str | None* *= None* +The optional struct type name + #### *static* from_dict(data: dict[str, Any]) → [Returns](#algokit_utils.applications.app_spec.arc56.Returns) ### *class* algokit_utils.applications.app_spec.arc56.Method Method information. -* **Variables:** - * **actions** – Allowed actions - * **args** – Method arguments - * **name** – Method name - * **returns** – Return information - * **desc** – Optional description - * **events** – Optional list of events - * **readonly** – Optional readonly flag - * **recommendations** – Optional execution recommendations - #### actions *: [Actions](#algokit_utils.applications.app_spec.arc56.Actions)* +The allowed actions + #### args *: list[[MethodArg](#algokit_utils.applications.app_spec.arc56.MethodArg)]* +The method arguments + #### name *: str* +The method name + #### returns *: [Returns](#algokit_utils.applications.app_spec.arc56.Returns)* +The return information + #### desc *: str | None* *= None* +The optional description + #### events *: list[[Event](#algokit_utils.applications.app_spec.arc56.Event)] | None* *= None* +The optional list of events + #### readonly *: bool | None* *= None* +The optional readonly flag + #### recommendations *: [Recommendations](#algokit_utils.applications.app_spec.arc56.Recommendations) | None* *= None* +The optional execution recommendations + #### to_abi_method() → algosdk.abi.Method Convert to ABI method. @@ -471,139 +491,148 @@ PC offset method types. Source code location information. -* **Variables:** - * **pc** – List of program counter values - * **error_message** – Optional error message - * **source** – Optional source code - * **teal** – Optional TEAL version - #### pc *: list[int]* +The list of program counter values + #### error_message *: str | None* *= None* +The optional error message + #### source *: str | None* *= None* +The optional source code + #### teal *: int | None* *= None* +The optional TEAL version + #### *static* from_dict(data: dict[str, Any]) → [SourceInfo](#algokit_utils.applications.app_spec.arc56.SourceInfo) ### *class* algokit_utils.applications.app_spec.arc56.StorageKey Storage key information. -* **Variables:** - * **key** – Storage key - * **key_type** – Type of the key - * **value_type** – Type of the value - * **desc** – Optional description - #### key *: str* +The storage key + #### key_type *: str* +The type of the key + #### value_type *: str* +The type of the value + #### desc *: str | None* *= None* +The optional description + #### *static* from_dict(data: dict[str, Any]) → [StorageKey](#algokit_utils.applications.app_spec.arc56.StorageKey) ### *class* algokit_utils.applications.app_spec.arc56.StorageMap Storage map information. -* **Variables:** - * **key_type** – Type of map keys - * **value_type** – Type of map values - * **desc** – Optional description - * **prefix** – Optional key prefix - #### key_type *: str* +The type of the map keys + #### value_type *: str* +The type of the map values + #### desc *: str | None* *= None* +The optional description + #### prefix *: str | None* *= None* +The optional key prefix + #### *static* from_dict(data: dict[str, Any]) → [StorageMap](#algokit_utils.applications.app_spec.arc56.StorageMap) ### *class* algokit_utils.applications.app_spec.arc56.Keys Storage keys for different storage types. -* **Variables:** - * **box** – Box storage keys - * **global_state** – Global state storage keys - * **local_state** – Local state storage keys - #### box *: dict[str, [StorageKey](#algokit_utils.applications.app_spec.arc56.StorageKey)]* +The box storage keys + #### global_state *: dict[str, [StorageKey](#algokit_utils.applications.app_spec.arc56.StorageKey)]* +The global state storage keys + #### local_state *: dict[str, [StorageKey](#algokit_utils.applications.app_spec.arc56.StorageKey)]* +The local state storage keys + #### *static* from_dict(data: dict[str, Any]) → [Keys](#algokit_utils.applications.app_spec.arc56.Keys) ### *class* algokit_utils.applications.app_spec.arc56.Maps Storage maps for different storage types. -* **Variables:** - * **box** – Box storage maps - * **global_state** – Global state storage maps - * **local_state** – Local state storage maps - #### box *: dict[str, [StorageMap](#algokit_utils.applications.app_spec.arc56.StorageMap)]* +The box storage maps + #### global_state *: dict[str, [StorageMap](#algokit_utils.applications.app_spec.arc56.StorageMap)]* +The global state storage maps + #### local_state *: dict[str, [StorageMap](#algokit_utils.applications.app_spec.arc56.StorageMap)]* +The local state storage maps + #### *static* from_dict(data: dict[str, Any]) → [Maps](#algokit_utils.applications.app_spec.arc56.Maps) ### *class* algokit_utils.applications.app_spec.arc56.State Application state information. -* **Variables:** - * **keys** – Storage keys - * **maps** – Storage maps - * **schema** – State schema - #### keys *: [Keys](#algokit_utils.applications.app_spec.arc56.Keys)* +The storage keys + #### maps *: [Maps](#algokit_utils.applications.app_spec.arc56.Maps)* +The storage maps + #### schema *: [Schema](#algokit_utils.applications.app_spec.arc56.Schema)* +The state schema + #### *static* from_dict(data: dict[str, Any]) → [State](#algokit_utils.applications.app_spec.arc56.State) ### *class* algokit_utils.applications.app_spec.arc56.ProgramSourceInfo Program source information. -* **Variables:** - * **pc_offset_method** – PC offset method - * **source_info** – List of source info entries - #### pc_offset_method *: [PcOffsetMethod](#algokit_utils.applications.app_spec.arc56.PcOffsetMethod)* +The PC offset method + #### source_info *: list[[SourceInfo](#algokit_utils.applications.app_spec.arc56.SourceInfo)]* +The list of source info entries + #### *static* from_dict(data: dict[str, Any]) → [ProgramSourceInfo](#algokit_utils.applications.app_spec.arc56.ProgramSourceInfo) ### *class* algokit_utils.applications.app_spec.arc56.SourceInfoModel Source information for approval and clear programs. -* **Variables:** - * **approval** – Approval program source info - * **clear** – Clear program source info - #### approval *: [ProgramSourceInfo](#algokit_utils.applications.app_spec.arc56.ProgramSourceInfo)* +The approval program source info + #### clear *: [ProgramSourceInfo](#algokit_utils.applications.app_spec.arc56.ProgramSourceInfo)* +The clear program source info + #### *static* from_dict(data: dict[str, Any]) → [SourceInfoModel](#algokit_utils.applications.app_spec.arc56.SourceInfoModel) ### *class* algokit_utils.applications.app_spec.arc56.Arc56Contract @@ -612,53 +641,66 @@ ARC-0056 application specification. See [https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0056.md](https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0056.md) -* **Variables:** - * **arcs** – List of supported ARC version numbers - * **bare_actions** – Bare call and create actions - * **methods** – List of contract methods - * **name** – Contract name - * **state** – Contract state information - * **structs** – Contract struct definitions - * **byte_code** – Optional bytecode for approval and clear programs - * **compiler_info** – Optional compiler information - * **desc** – Optional contract description - * **events** – Optional list of contract events - * **networks** – Optional network deployment information - * **scratch_variables** – Optional scratch variable information - * **source** – Optional source code - * **source_info** – Optional source code information - * **template_variables** – Optional template variable information - #### arcs *: list[int]* +The list of supported ARC version numbers + #### bare_actions *: [BareActions](#algokit_utils.applications.app_spec.arc56.BareActions)* +The bare call and create actions + #### methods *: list[[Method](#algokit_utils.applications.app_spec.arc56.Method)]* +The list of contract methods + #### name *: str* +The contract name + #### state *: [State](#algokit_utils.applications.app_spec.arc56.State)* +The contract state information + #### structs *: dict[str, list[[StructField](#algokit_utils.applications.app_spec.arc56.StructField)]]* +The contract struct definitions + #### byte_code *: [ByteCode](#algokit_utils.applications.app_spec.arc56.ByteCode) | None* *= None* +The optional bytecode for approval and clear programs + #### compiler_info *: [CompilerInfo](#algokit_utils.applications.app_spec.arc56.CompilerInfo) | None* *= None* +The optional compiler information + #### desc *: str | None* *= None* +The optional contract description + #### events *: list[[Event](#algokit_utils.applications.app_spec.arc56.Event)] | None* *= None* +The optional list of contract events + #### networks *: dict[str, [Network](#algokit_utils.applications.app_spec.arc56.Network)] | None* *= None* +The optional network deployment information + #### scratch_variables *: dict[str, [ScratchVariables](#algokit_utils.applications.app_spec.arc56.ScratchVariables)] | None* *= None* +The optional scratch variable information + #### source *: [Source](#algokit_utils.applications.app_spec.arc56.Source) | None* *= None* +The optional source code + #### source_info *: [SourceInfoModel](#algokit_utils.applications.app_spec.arc56.SourceInfoModel) | None* *= None* +The optional source code information + #### template_variables *: dict[str, [TemplateVariables](#algokit_utils.applications.app_spec.arc56.TemplateVariables)] | None* *= None* +The optional template variable information + #### *static* from_dict(application_spec: dict) → [Arc56Contract](#algokit_utils.applications.app_spec.arc56.Arc56Contract) Create Arc56Contract from dictionary. diff --git a/docs/markdown/autoapi/algokit_utils/assets/asset_manager/index.md b/docs/markdown/autoapi/algokit_utils/assets/asset_manager/index.md index 9c30327a..529f8893 100644 --- a/docs/markdown/autoapi/algokit_utils/assets/asset_manager/index.md +++ b/docs/markdown/autoapi/algokit_utils/assets/asset_manager/index.md @@ -14,79 +14,94 @@ Information about an account’s holding of a particular asset. -* **Variables:** - * **asset_id** – The ID of the asset - * **balance** – The amount of the asset held by the account - * **frozen** – Whether the asset is frozen for this account - * **round** – The round this information was retrieved at - #### asset_id *: int* +The ID of the asset + #### balance *: int* +The amount of the asset held by the account + #### frozen *: bool* +Whether the asset is frozen for this account + #### round *: int* +The round this information was retrieved at + ### *class* algokit_utils.assets.asset_manager.AssetInformation Information about an Algorand Standard Asset (ASA). -* **Variables:** - * **asset_id** – The ID of the asset - * **creator** – The address of the account that created the asset - * **total** – The total amount of the smallest divisible units that were created of the asset - * **decimals** – The amount of decimal places the asset was created with - * **default_frozen** – Whether the asset was frozen by default for all accounts, defaults to None - * **manager** – The address of the optional account that can manage the configuration of the asset and destroy it, - defaults to None - * **reserve** – The address of the optional account that holds the reserve (uncirculated supply) units of the asset, - defaults to None - * **freeze** – The address of the optional account that can be used to freeze or unfreeze holdings of this asset, - defaults to None - * **clawback** – The address of the optional account that can clawback holdings of this asset from any account, - defaults to None - * **unit_name** – The optional name of the unit of this asset (e.g. ticker name), defaults to None - * **unit_name_b64** – The optional name of the unit of this asset as bytes, defaults to None - * **asset_name** – The optional name of the asset, defaults to None - * **asset_name_b64** – The optional name of the asset as bytes, defaults to None - * **url** – Optional URL where more information about the asset can be retrieved, defaults to None - * **url_b64** – Optional URL where more information about the asset can be retrieved as bytes, defaults to None - * **metadata_hash** – 32-byte hash of some metadata that is relevant to the asset and/or asset holders, - defaults to None - #### asset_id *: int* +The ID of the asset + #### creator *: str* +The address of the account that created the asset + #### total *: int* +The total amount of the smallest divisible units that were created of the asset + #### decimals *: int* +The amount of decimal places the asset was created with + #### default_frozen *: bool | None* *= None* +Whether the asset was frozen by default for all accounts, defaults to None + #### manager *: str | None* *= None* +The address of the optional account that can manage the configuration of the asset and destroy it, +defaults to None + #### reserve *: str | None* *= None* +The address of the optional account that holds the reserve (uncirculated supply) units of the asset, +defaults to None + #### freeze *: str | None* *= None* +The address of the optional account that can be used to freeze or unfreeze holdings of this asset, +defaults to None + #### clawback *: str | None* *= None* +The address of the optional account that can clawback holdings of this asset from any account, +defaults to None + #### unit_name *: str | None* *= None* +The optional name of the unit of this asset (e.g. ticker name), defaults to None + #### unit_name_b64 *: bytes | None* *= None* +The optional name of the unit of this asset as bytes, defaults to None + #### asset_name *: str | None* *= None* +The optional name of the asset, defaults to None + #### asset_name_b64 *: bytes | None* *= None* +The optional name of the asset as bytes, defaults to None + #### url *: str | None* *= None* +The optional URL where more information about the asset can be retrieved, defaults to None + #### url_b64 *: bytes | None* *= None* +The optional URL where more information about the asset can be retrieved as bytes, defaults to None + #### metadata_hash *: bytes | None* *= None* +The 32-byte hash of some metadata that is relevant to the asset and/or asset holders, defaults to None + ### *class* algokit_utils.assets.asset_manager.BulkAssetOptInOutResult Result from performing a bulk opt-in or bulk opt-out for an account against a series of assets. @@ -97,8 +112,12 @@ Result from performing a bulk opt-in or bulk opt-out for an account against a se #### asset_id *: int* +The ID of the asset opted into / out of + #### transaction_id *: str* +The transaction ID of the resulting opt in / out + ### *class* algokit_utils.assets.asset_manager.AssetManager(algod_client: algosdk.v2client.algod.AlgodClient, new_group: collections.abc.Callable[[], [algokit_utils.transactions.transaction_composer.TransactionComposer](../../transactions/transaction_composer/index.md#algokit_utils.transactions.transaction_composer.TransactionComposer)]) A manager for Algorand Standard Assets (ASAs). @@ -106,6 +125,10 @@ A manager for Algorand Standard Assets (ASAs). * **Parameters:** * **algod_client** – An algod client * **new_group** – A function that creates a new TransactionComposer transaction group +* **Example:** + ```pycon + >>> asset_manager = AssetManager(algod_client) + ``` #### get_by_id(asset_id: int) → [AssetInformation](#algokit_utils.assets.asset_manager.AssetInformation) @@ -115,6 +138,11 @@ Returns the current asset information for the asset with the given ID. **asset_id** – The ID of the asset * **Returns:** The asset information +* **Example:** + ```pycon + >>> asset_manager = AssetManager(algod_client) + >>> asset_info = asset_manager.get_by_id(1234567890) + ``` #### get_account_information(sender: str | [algokit_utils.models.account.SigningAccount](../../models/account/index.md#algokit_utils.models.account.SigningAccount) | algosdk.atomic_transaction_composer.TransactionSigner, asset_id: int) → [AccountAssetInformation](#algokit_utils.assets.asset_manager.AccountAssetInformation) @@ -125,6 +153,11 @@ Returns the given sender account’s asset holding for a given asset. * **asset_id** – The ID of the asset to return a holding for * **Returns:** The account asset holding information +* **Example:** + ```pycon + >>> asset_manager = AssetManager(algod_client) + >>> account_asset_info = asset_manager.get_account_information(sender, asset_id) + ``` #### bulk_opt_in(account: str, asset_ids: list[int], signer: algosdk.atomic_transaction_composer.TransactionSigner | None = None, rekey_to: str | None = None, note: bytes | None = None, lease: bytes | None = None, static_fee: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount) | None = None, extra_fee: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount) | None = None, max_fee: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount) | None = None, validity_window: int | None = None, first_valid_round: int | None = None, last_valid_round: int | None = None, send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → list[[BulkAssetOptInOutResult](#algokit_utils.assets.asset_manager.BulkAssetOptInOutResult)] @@ -146,6 +179,11 @@ Opt an account in to a list of Algorand Standard Assets. * **send_params** – The send parameters to use for the transaction, defaults to None * **Returns:** An array of records matching asset ID to transaction ID of the opt in +* **Example:** + ```pycon + >>> asset_manager = AssetManager(algod_client) + >>> results = asset_manager.bulk_opt_in(account, asset_ids) + ``` #### bulk_opt_out(\*, account: str, asset_ids: list[int], ensure_zero_balance: bool = True, signer: algosdk.atomic_transaction_composer.TransactionSigner | None = None, rekey_to: str | None = None, note: bytes | None = None, lease: bytes | None = None, static_fee: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount) | None = None, extra_fee: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount) | None = None, max_fee: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount) | None = None, validity_window: int | None = None, first_valid_round: int | None = None, last_valid_round: int | None = None, send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → list[[BulkAssetOptInOutResult](#algokit_utils.assets.asset_manager.BulkAssetOptInOutResult)] @@ -170,3 +208,8 @@ Opt an account out of a list of Algorand Standard Assets. **ValueError** – If ensure_zero_balance is True and account has non-zero balance or is not opted in * **Returns:** An array of records matching asset ID to transaction ID of the opt out +* **Example:** + ```pycon + >>> asset_manager = AssetManager(algod_client) + >>> results = asset_manager.bulk_opt_out(account, asset_ids) + ``` diff --git a/docs/markdown/autoapi/algokit_utils/clients/client_manager/index.md b/docs/markdown/autoapi/algokit_utils/clients/client_manager/index.md index 2f1ea030..48afb839 100644 --- a/docs/markdown/autoapi/algokit_utils/clients/client_manager/index.md +++ b/docs/markdown/autoapi/algokit_utils/clients/client_manager/index.md @@ -34,14 +34,24 @@ Contains network type flags and genesis information. #### is_testnet *: bool* +Whether the network is a testnet + #### is_mainnet *: bool* +Whether the network is a mainnet + #### is_localnet *: bool* +Whether the network is a localnet + #### genesis_id *: str* +The genesis ID of the network + #### genesis_hash *: str* +The genesis hash of the network + ### *class* algokit_utils.clients.client_manager.ClientManager(clients_or_configs: [algokit_utils.models.network.AlgoClientConfigs](../../models/network/index.md#algokit_utils.models.network.AlgoClientConfigs) | [AlgoSdkClients](#algokit_utils.clients.client_manager.AlgoSdkClients), algorand_client: [algokit_utils.algorand.AlgorandClient](../../algorand/index.md#algokit_utils.algorand.AlgorandClient)) Manager for Algorand SDK clients. @@ -51,6 +61,18 @@ Provides access to Algod, Indexer and KMD clients and helper methods for working * **Parameters:** * **clients_or_configs** – Either client instances or client configurations * **algorand_client** – AlgorandClient instance +* **Example:** + ```pycon + >>> # Algod only + >>> client_manager = ClientManager(algod_client) + >>> # Algod and Indexer + >>> client_manager = ClientManager(algod_client, indexer_client) + >>> # Algod config only + >>> client_manager = ClientManager(ClientManager.get_algod_config_from_environment()) + >>> # Algod and Indexer config + >>> client_manager = ClientManager(ClientManager.get_algod_config_from_environment(), + ... ClientManager.get_indexer_config_from_environment()) + ``` #### *property* algod *: algosdk.v2client.algod.AlgodClient* @@ -90,6 +112,11 @@ Get details about the connected Algorand network. * **Returns:** Network details including type and genesis information +* **Example:** + ```pycon + >>> client_manager = ClientManager(algod_client) + >>> network_detail = client_manager.network() + ``` #### is_localnet() → bool @@ -244,6 +271,10 @@ Check if a genesis ID indicates a local network. **genesis_id** – Genesis ID to check * **Returns:** True if genesis ID indicates a local network +* **Example:** + ```pycon + >>> ClientManager.genesis_id_is_localnet("devnet-v1") + ``` #### get_typed_app_client_by_creator_and_name(typed_client: type[TypedAppClientT], \*, creator_address: str, app_name: str, default_sender: str | None = None, default_signer: algosdk.atomic_transaction_composer.TransactionSigner | None = None, ignore_cache: bool | None = None, app_lookup_cache: [algokit_utils.applications.app_deployer.ApplicationLookup](../../applications/app_deployer/index.md#algokit_utils.applications.app_deployer.ApplicationLookup) | None = None) → TypedAppClientT @@ -261,6 +292,15 @@ Get a typed application client by creator address and name. **ValueError** – If no Algorand client is configured * **Returns:** Typed application client instance +* **Example:** + ```pycon + >>> client_manager = ClientManager(algod_client) + >>> typed_app_client = client_manager.get_typed_app_client_by_creator_and_name( + ... typed_client=MyAppClient, + ... creator_address="creator_address", + ... app_name="app_name", + ... ) + ``` #### get_typed_app_client_by_id(typed_client: type[TypedAppClientT], \*, app_id: int, app_name: str | None = None, default_sender: str | None = None, default_signer: algosdk.atomic_transaction_composer.TransactionSigner | None = None, approval_source_map: algosdk.source_map.SourceMap | None = None, clear_source_map: algosdk.source_map.SourceMap | None = None) → TypedAppClientT @@ -278,6 +318,14 @@ Get a typed application client by ID. **ValueError** – If no Algorand client is configured * **Returns:** Typed application client instance +* **Example:** + ```pycon + >>> client_manager = ClientManager(algod_client) + >>> typed_app_client = client_manager.get_typed_app_client_by_id( + ... typed_client=MyAppClient, + ... app_id=1234567890, + ... ) + ``` #### get_typed_app_client_by_network(typed_client: type[TypedAppClientT], \*, app_name: str | None = None, default_sender: str | None = None, default_signer: algosdk.atomic_transaction_composer.TransactionSigner | None = None, approval_source_map: algosdk.source_map.SourceMap | None = None, clear_source_map: algosdk.source_map.SourceMap | None = None) → TypedAppClientT @@ -297,6 +345,14 @@ If no IDs are in the app spec or the network isn’t recognised, an error is thr **ValueError** – If no Algorand client is configured * **Returns:** The typed client instance +* **Example:** + ```pycon + >>> client_manager = ClientManager(algod_client) + >>> typed_app_client = client_manager.get_typed_app_client_by_network( + ... typed_client=MyAppClient, + ... app_name="app_name", + ... ) + ``` #### get_typed_app_factory(typed_factory: type[TypedFactoryT], \*, app_name: str | None = None, default_sender: str | None = None, default_signer: algosdk.atomic_transaction_composer.TransactionSigner | None = None, version: str | None = None, compilation_params: [algokit_utils.applications.app_client.AppClientCompilationParams](../../applications/app_client/index.md#algokit_utils.applications.app_client.AppClientCompilationParams) | None = None) → TypedFactoryT @@ -313,6 +369,14 @@ Get a typed application factory. **ValueError** – If no Algorand client is configured * **Returns:** Typed application factory instance +* **Example:** + ```pycon + >>> client_manager = ClientManager(algod_client) + >>> typed_app_factory = client_manager.get_typed_app_factory( + ... typed_factory=MyAppFactory, + ... app_name="app_name", + ... ) + ``` #### *static* get_config_from_environment_or_localnet() → [algokit_utils.models.network.AlgoClientConfigs](../../models/network/index.md#algokit_utils.models.network.AlgoClientConfigs) @@ -323,6 +387,11 @@ otherwise it will use default localnet configuration. * **Returns:** Configuration for algod, indexer, and optionally kmd +* **Example:** + ```pycon + >>> client_manager = ClientManager(algod_client) + >>> config = client_manager.get_config_from_environment_or_localnet() + ``` #### *static* get_default_localnet_config(config_or_port: Literal['algod', 'indexer', 'kmd'] | int) → [algokit_utils.models.network.AlgoClientNetworkConfig](../../models/network/index.md#algokit_utils.models.network.AlgoClientNetworkConfig) @@ -332,6 +401,11 @@ Get default configuration for local network services. **config_or_port** – Service name or port number * **Returns:** Client configuration for local network +* **Example:** + ```pycon + >>> client_manager = ClientManager(algod_client) + >>> config = client_manager.get_default_localnet_config("algod") + ``` #### *static* get_algod_config_from_environment() → [algokit_utils.models.network.AlgoClientNetworkConfig](../../models/network/index.md#algokit_utils.models.network.AlgoClientNetworkConfig) @@ -340,6 +414,11 @@ Will raise an error if ALGOD_SERVER environment variable is not set * **Returns:** Algod client configuration +* **Example:** + ```pycon + >>> client_manager = ClientManager(algod_client) + >>> config = client_manager.get_algod_config_from_environment() + ``` #### *static* get_indexer_config_from_environment() → [algokit_utils.models.network.AlgoClientNetworkConfig](../../models/network/index.md#algokit_utils.models.network.AlgoClientNetworkConfig) @@ -348,6 +427,11 @@ Will raise an error if INDEXER_SERVER environment variable is not set * **Returns:** Indexer client configuration +* **Example:** + ```pycon + >>> client_manager = ClientManager(algod_client) + >>> config = client_manager.get_indexer_config_from_environment() + ``` #### *static* get_kmd_config_from_environment() → [algokit_utils.models.network.AlgoClientNetworkConfig](../../models/network/index.md#algokit_utils.models.network.AlgoClientNetworkConfig) @@ -355,6 +439,11 @@ Retrieve the kmd configuration from environment variables. * **Returns:** KMD client configuration +* **Example:** + ```pycon + >>> client_manager = ClientManager(algod_client) + >>> config = client_manager.get_kmd_config_from_environment() + ``` #### *static* get_algonode_config(network: Literal['testnet', 'mainnet'], config: Literal['algod', 'indexer']) → [algokit_utils.models.network.AlgoClientNetworkConfig](../../models/network/index.md#algokit_utils.models.network.AlgoClientNetworkConfig) @@ -365,3 +454,8 @@ Returns the Algorand configuration to point to the free tier of the AlgoNode ser * **config** – Which algod config to return - Algod or Indexer * **Returns:** Configuration for the specified network and service +* **Example:** + ```pycon + >>> client_manager = ClientManager(algod_client) + >>> config = client_manager.get_algonode_config("testnet", "algod") + ``` diff --git a/docs/markdown/autoapi/algokit_utils/clients/dispenser_api_client/index.md b/docs/markdown/autoapi/algokit_utils/clients/dispenser_api_client/index.md index c1f83d93..053b81d3 100644 --- a/docs/markdown/autoapi/algokit_utils/clients/dispenser_api_client/index.md +++ b/docs/markdown/autoapi/algokit_utils/clients/dispenser_api_client/index.md @@ -35,20 +35,32 @@ Enum where members are also (and must be) ints #### asset_id *: int* +The ID of the asset + #### decimals *: int* +The amount of decimal places the asset was created with + #### description *: str* +The description of the asset + ### *class* algokit_utils.clients.dispenser_api_client.DispenserFundResponse #### tx_id *: str* +The transaction ID of the funded transaction + #### amount *: int* +The amount of Algos funded + ### *class* algokit_utils.clients.dispenser_api_client.DispenserLimitResponse #### amount *: int* +The amount of Algos that can be funded + ### algokit_utils.clients.dispenser_api_client.DISPENSER_ASSETS ### algokit_utils.clients.dispenser_api_client.DISPENSER_REQUEST_TIMEOUT *= 15* @@ -69,10 +81,23 @@ Default request timeout is 15 seconds. Modify by passing request_timeout to the #### request_timeout *= 15* -#### fund(address: str, amount: int, asset_id: int) → [DispenserFundResponse](#algokit_utils.clients.dispenser_api_client.DispenserFundResponse) +#### fund(address: str, amount: int) → [DispenserFundResponse](#algokit_utils.clients.dispenser_api_client.DispenserFundResponse) Fund an account with Algos from the dispenser API +* **Parameters:** + * **address** – The address to fund + * **amount** – The amount of Algos to fund +* **Returns:** + The transaction ID of the funded transaction +* **Raises:** + **Exception** – If the dispenser API request fails +* **Example:** + ```pycon + >>> dispenser_client = TestNetDispenserApiClient() + >>> dispenser_client.fund(address="SENDER_ADDRESS", amount=1000000) + ``` + #### refund(refund_txn_id: str) → None Register a refund for a transaction with the dispenser API diff --git a/docs/markdown/autoapi/algokit_utils/models/application/index.md b/docs/markdown/autoapi/algokit_utils/models/application/index.md index 1211df33..3ac8e148 100644 --- a/docs/markdown/autoapi/algokit_utils/models/application/index.md +++ b/docs/markdown/autoapi/algokit_utils/models/application/index.md @@ -2,12 +2,12 @@ ## Classes -| [`AppState`](#algokit_utils.models.application.AppState) | | -|----------------------------------------------------------------------------------|----| -| [`AppInformation`](#algokit_utils.models.application.AppInformation) | | -| [`CompiledTeal`](#algokit_utils.models.application.CompiledTeal) | | -| [`AppCompilationResult`](#algokit_utils.models.application.AppCompilationResult) | | -| [`AppSourceMaps`](#algokit_utils.models.application.AppSourceMaps) | | +| [`AppState`](#algokit_utils.models.application.AppState) | | +|----------------------------------------------------------------------------------|-------------------------------------| +| [`AppInformation`](#algokit_utils.models.application.AppInformation) | | +| [`CompiledTeal`](#algokit_utils.models.application.CompiledTeal) | The compiled teal code | +| [`AppCompilationResult`](#algokit_utils.models.application.AppCompilationResult) | The compiled teal code | +| [`AppSourceMaps`](#algokit_utils.models.application.AppSourceMaps) | The source maps for the application | ## Module Contents @@ -15,58 +15,112 @@ #### key_raw *: bytes* +The key of the state as raw bytes + #### key_base64 *: str* +The key of the state + #### value_raw *: bytes | None* +The value of the state as raw bytes + #### value_base64 *: str | None* +The value of the state as base64 encoded string + #### value *: str | int* +The value of the state as a string or integer + ### *class* algokit_utils.models.application.AppInformation #### app_id *: int* +The ID of the application + #### app_address *: str* +The address of the application + #### approval_program *: bytes* +The approval program + #### clear_state_program *: bytes* +The clear state program + #### creator *: str* +The creator of the application + #### global_state *: dict[str, [AppState](#algokit_utils.models.application.AppState)]* +The global state of the application + #### local_ints *: int* +The number of local ints + #### local_byte_slices *: int* +The number of local byte slices + #### global_ints *: int* +The number of global ints + #### global_byte_slices *: int* +The number of global byte slices + #### extra_program_pages *: int | None* +The number of extra program pages + ### *class* algokit_utils.models.application.CompiledTeal +The compiled teal code + #### teal *: str* +The teal code + #### compiled *: str* +The compiled teal code + #### compiled_hash *: str* +The compiled hash + #### compiled_base64_to_bytes *: bytes* +The compiled base64 to bytes + #### source_map *: algosdk.source_map.SourceMap | None* ### *class* algokit_utils.models.application.AppCompilationResult +The compiled teal code + #### compiled_approval *: [CompiledTeal](#algokit_utils.models.application.CompiledTeal)* +The compiled approval program + #### compiled_clear *: [CompiledTeal](#algokit_utils.models.application.CompiledTeal)* +The compiled clear state program + ### *class* algokit_utils.models.application.AppSourceMaps +The source maps for the application + #### approval_source_map *: algosdk.source_map.SourceMap | None* *= None* +The source map for the approval program + #### clear_source_map *: algosdk.source_map.SourceMap | None* *= None* + +The source map for the clear state program diff --git a/docs/markdown/autoapi/algokit_utils/models/state/index.md b/docs/markdown/autoapi/algokit_utils/models/state/index.md index 61e3c040..612cbc46 100644 --- a/docs/markdown/autoapi/algokit_utils/models/state/index.md +++ b/docs/markdown/autoapi/algokit_utils/models/state/index.md @@ -8,9 +8,9 @@ ## Classes -| [`BoxName`](#algokit_utils.models.state.BoxName) | | +| [`BoxName`](#algokit_utils.models.state.BoxName) | The name of the box | |------------------------------------------------------------|-----------------------------------------------------------------------| -| [`BoxValue`](#algokit_utils.models.state.BoxValue) | | +| [`BoxValue`](#algokit_utils.models.state.BoxValue) | The value of the box | | [`DataTypeFlag`](#algokit_utils.models.state.DataTypeFlag) | Enum where members are also (and must be) ints | | [`BoxReference`](#algokit_utils.models.state.BoxReference) | Represents a box reference with a foreign app index and the box name. | @@ -18,18 +18,32 @@ ### *class* algokit_utils.models.state.BoxName +The name of the box + #### name *: str* +The name of the box as a string + #### name_raw *: bytes* +The name of the box as raw bytes + #### name_base64 *: str* +The name of the box as a base64 encoded string + ### *class* algokit_utils.models.state.BoxValue +The value of the box + #### name *: [BoxName](#algokit_utils.models.state.BoxName)* +The name of the box + #### value *: bytes* +The value of the box as raw bytes + ### *class* algokit_utils.models.state.DataTypeFlag Bases: `enum.IntEnum` diff --git a/docs/markdown/autoapi/algokit_utils/transactions/transaction_composer/index.md b/docs/markdown/autoapi/algokit_utils/transactions/transaction_composer/index.md index 223010bf..bc11143a 100644 --- a/docs/markdown/autoapi/algokit_utils/transactions/transaction_composer/index.md +++ b/docs/markdown/autoapi/algokit_utils/transactions/transaction_composer/index.md @@ -50,236 +50,262 @@ Bases: `_CommonTxnParams` Parameters for a payment transaction. -* **Variables:** - * **receiver** – The account that will receive the ALGO - * **amount** – Amount to send - * **close_remainder_to** – If given, close the sender account and send the remaining balance to this address, - defaults to None - #### receiver *: str* +The account that will receive the ALGO + #### amount *: [algokit_utils.models.amount.AlgoAmount](../../models/amount/index.md#algokit_utils.models.amount.AlgoAmount)* +Amount to send + #### close_remainder_to *: str | None* *= None* +If given, close the sender account and send the remaining balance to this address, defaults to None + ### *class* algokit_utils.transactions.transaction_composer.AssetCreateParams Bases: `_CommonTxnParams` Parameters for creating a new asset. -* **Variables:** - * **total** – The total amount of the smallest divisible unit to create - * **decimals** – The amount of decimal places the asset should have, defaults to None - * **default_frozen** – Whether the asset is frozen by default in the creator address, defaults to None - * **manager** – The address that can change the manager, reserve, clawback, and freeze addresses, defaults to None - * **reserve** – The address that holds the uncirculated supply, defaults to None - * **freeze** – The address that can freeze the asset in any account, defaults to None - * **clawback** – The address that can clawback the asset from any account, defaults to None - * **unit_name** – The short ticker name for the asset, defaults to None - * **asset_name** – The full name of the asset, defaults to None - * **url** – The metadata URL for the asset, defaults to None - * **metadata_hash** – Hash of the metadata contained in the metadata URL, defaults to None - #### total *: int* +The total amount of the smallest divisible unit to create + #### asset_name *: str | None* *= None* +The full name of the asset + #### unit_name *: str | None* *= None* +The short ticker name for the asset + #### url *: str | None* *= None* +The metadata URL for the asset + #### decimals *: int | None* *= None* +The amount of decimal places the asset should have + #### default_frozen *: bool | None* *= None* +Whether the asset is frozen by default in the creator address + #### manager *: str | None* *= None* +The address that can change the manager, reserve, clawback, and freeze addresses + #### reserve *: str | None* *= None* +The address that holds the uncirculated supply + #### freeze *: str | None* *= None* +The address that can freeze the asset in any account + #### clawback *: str | None* *= None* +The address that can clawback the asset from any account + #### metadata_hash *: bytes | None* *= None* +Hash of the metadata contained in the metadata URL + ### *class* algokit_utils.transactions.transaction_composer.AssetConfigParams Bases: `_CommonTxnParams` Parameters for configuring an existing asset. -* **Variables:** - * **asset_id** – ID of the asset - * **manager** – The address that can change the manager, reserve, clawback, and freeze addresses, defaults to None - * **reserve** – The address that holds the uncirculated supply, defaults to None - * **freeze** – The address that can freeze the asset in any account, defaults to None - * **clawback** – The address that can clawback the asset from any account, defaults to None - #### asset_id *: int* +The ID of the asset + #### manager *: str | None* *= None* +The address that can change the manager, reserve, clawback, and freeze addresses, defaults to None + #### reserve *: str | None* *= None* +The address that holds the uncirculated supply, defaults to None + #### freeze *: str | None* *= None* +The address that can freeze the asset in any account, defaults to None + #### clawback *: str | None* *= None* +The address that can clawback the asset from any account, defaults to None + ### *class* algokit_utils.transactions.transaction_composer.AssetFreezeParams Bases: `_CommonTxnParams` Parameters for freezing an asset. -* **Variables:** - * **asset_id** – The ID of the asset - * **account** – The account to freeze or unfreeze - * **frozen** – Whether the assets in the account should be frozen - #### asset_id *: int* +The ID of the asset + #### account *: str* +The account to freeze or unfreeze + #### frozen *: bool* +Whether the assets in the account should be frozen + ### *class* algokit_utils.transactions.transaction_composer.AssetDestroyParams Bases: `_CommonTxnParams` Parameters for destroying an asset. -* **Variables:** - **asset_id** – ID of the asset - #### asset_id *: int* +The ID of the asset + ### *class* algokit_utils.transactions.transaction_composer.OnlineKeyRegistrationParams Bases: `_CommonTxnParams` Parameters for online key registration. -* **Variables:** - * **vote_key** – The root participation public key - * **selection_key** – The VRF public key - * **vote_first** – The first round that the participation key is valid - * **vote_last** – The last round that the participation key is valid - * **vote_key_dilution** – The dilution for the 2-level participation key - * **state_proof_key** – The 64 byte state proof public key commitment, defaults to None - #### vote_key *: str* +The root participation public key + #### selection_key *: str* +The VRF public key + #### vote_first *: int* +The first round that the participation key is valid + #### vote_last *: int* +The last round that the participation key is valid + #### vote_key_dilution *: int* +The dilution for the 2-level participation key + #### state_proof_key *: bytes | None* *= None* +The 64 byte state proof public key commitment, defaults to None + ### *class* algokit_utils.transactions.transaction_composer.OfflineKeyRegistrationParams Bases: `_CommonTxnParams` Parameters for offline key registration. -* **Variables:** - **prevent_account_from_ever_participating_again** – Whether to prevent the account from ever participating again - #### prevent_account_from_ever_participating_again *: bool* +Whether to prevent the account from ever participating again + ### *class* algokit_utils.transactions.transaction_composer.AssetTransferParams Bases: `_CommonTxnParams` Parameters for transferring an asset. -* **Variables:** - * **asset_id** – ID of the asset - * **amount** – Amount of the asset to transfer (smallest divisible unit) - * **receiver** – The account to send the asset to - * **clawback_target** – The account to take the asset from, defaults to None - * **close_asset_to** – The account to close the asset to, defaults to None - #### asset_id *: int* +The ID of the asset + #### amount *: int* +The amount of the asset to transfer (smallest divisible unit) + #### receiver *: str* +The account to send the asset to + #### clawback_target *: str | None* *= None* +The account to take the asset from, defaults to None + #### close_asset_to *: str | None* *= None* +The account to close the asset to, defaults to None + ### *class* algokit_utils.transactions.transaction_composer.AssetOptInParams Bases: `_CommonTxnParams` Parameters for opting into an asset. -* **Variables:** - **asset_id** – ID of the asset - #### asset_id *: int* +The ID of the asset + ### *class* algokit_utils.transactions.transaction_composer.AssetOptOutParams Bases: `_CommonTxnParams` Parameters for opting out of an asset. -* **Variables:** - * **asset_id** – ID of the asset - * **creator** – The creator address of the asset - #### asset_id *: int* +The ID of the asset + #### creator *: str* +The creator address of the asset + ### *class* algokit_utils.transactions.transaction_composer.AppCallParams Bases: `_CommonTxnParams` Parameters for calling an application. -* **Variables:** - * **on_complete** – The OnComplete action - * **app_id** – ID of the application, defaults to None - * **approval_program** – The program to execute for all OnCompletes other than ClearState, defaults to None - * **clear_state_program** – The program to execute for ClearState OnComplete, defaults to None - * **schema** – The state schema for the app. This is immutable, defaults to None - * **args** – Application arguments, defaults to None - * **account_references** – Account references, defaults to None - * **app_references** – App references, defaults to None - * **asset_references** – Asset references, defaults to None - * **extra_pages** – Number of extra pages required for the programs, defaults to None - * **box_references** – Box references, defaults to None - #### on_complete *: algosdk.transaction.OnComplete* +The OnComplete action, defaults to None + #### app_id *: int | None* *= None* +The ID of the application, defaults to None + #### approval_program *: str | bytes | None* *= None* +The program to execute for all OnCompletes other than ClearState, defaults to None + #### clear_state_program *: str | bytes | None* *= None* +The program to execute for ClearState OnComplete, defaults to None + #### schema *: dict[str, int] | None* *= None* +The state schema for the app, defaults to None + #### args *: list[bytes] | None* *= None* +Application arguments, defaults to None + #### account_references *: list[str] | None* *= None* +Account references, defaults to None + #### app_references *: list[int] | None* *= None* +App references, defaults to None + #### asset_references *: list[int] | None* *= None* +Asset references, defaults to None + #### extra_pages *: int | None* *= None* +Number of extra pages required for the programs, defaults to None + #### box_references *: list[[algokit_utils.models.state.BoxReference](../../models/state/index.md#algokit_utils.models.state.BoxReference) | algokit_utils.models.state.BoxIdentifier] | None* *= None* +Box references, defaults to None + ### *class* algokit_utils.transactions.transaction_composer.AppCreateSchema Bases: `TypedDict` @@ -306,192 +332,218 @@ kwargs) -> new dictionary initialized with the name=value pairs #### global_ints *: int* +The number of global ints in the schema + #### global_byte_slices *: int* +The number of global byte slices in the schema + #### local_ints *: int* +The number of local ints in the schema + #### local_byte_slices *: int* +The number of local byte slices in the schema + ### *class* algokit_utils.transactions.transaction_composer.AppCreateParams Bases: `_CommonTxnParams` Parameters for creating an application. -* **Variables:** - * **approval_program** – The program to execute for all OnCompletes other than ClearState as raw teal (string) - or compiled teal (bytes) - * **clear_state_program** – The program to execute for ClearState OnComplete as raw teal (string) - or compiled teal (bytes) - * **schema** – The state schema for the app. This is immutable, defaults to None - * **on_complete** – The OnComplete action (cannot be ClearState), defaults to None - * **args** – Application arguments, defaults to None - * **account_references** – Account references, defaults to None - * **app_references** – App references, defaults to None - * **asset_references** – Asset references, defaults to None - * **box_references** – Box references, defaults to None - * **extra_program_pages** – Number of extra pages required for the programs, defaults to None - #### approval_program *: str | bytes* +The program to execute for all OnCompletes other than ClearState + #### clear_state_program *: str | bytes* +The program to execute for ClearState OnComplete + #### schema *: [AppCreateSchema](#algokit_utils.transactions.transaction_composer.AppCreateSchema) | None* *= None* +The state schema for the app, defaults to None + #### on_complete *: algosdk.transaction.OnComplete | None* *= None* +The OnComplete action, defaults to None + #### args *: list[bytes] | None* *= None* +Application arguments, defaults to None + #### account_references *: list[str] | None* *= None* +Account references, defaults to None + #### app_references *: list[int] | None* *= None* +App references, defaults to None + #### asset_references *: list[int] | None* *= None* +Asset references, defaults to None + #### box_references *: list[[algokit_utils.models.state.BoxReference](../../models/state/index.md#algokit_utils.models.state.BoxReference) | algokit_utils.models.state.BoxIdentifier] | None* *= None* +Box references, defaults to None + #### extra_program_pages *: int | None* *= None* +Number of extra pages required for the programs, defaults to None + ### *class* algokit_utils.transactions.transaction_composer.AppUpdateParams Bases: `_CommonTxnParams` Parameters for updating an application. -* **Variables:** - * **app_id** – ID of the application - * **approval_program** – The program to execute for all OnCompletes other than ClearState as raw teal (string) - or compiled teal (bytes) - * **clear_state_program** – The program to execute for ClearState OnComplete as raw teal (string) - or compiled teal (bytes) - * **args** – Application arguments, defaults to None - * **account_references** – Account references, defaults to None - * **app_references** – App references, defaults to None - * **asset_references** – Asset references, defaults to None - * **box_references** – Box references, defaults to None - * **on_complete** – The OnComplete action, defaults to None - #### app_id *: int* +The ID of the application + #### approval_program *: str | bytes* +The program to execute for all OnCompletes other than ClearState + #### clear_state_program *: str | bytes* +The program to execute for ClearState OnComplete + #### args *: list[bytes] | None* *= None* +Application arguments, defaults to None + #### account_references *: list[str] | None* *= None* +Account references, defaults to None + #### app_references *: list[int] | None* *= None* +App references, defaults to None + #### asset_references *: list[int] | None* *= None* +Asset references, defaults to None + #### box_references *: list[[algokit_utils.models.state.BoxReference](../../models/state/index.md#algokit_utils.models.state.BoxReference) | algokit_utils.models.state.BoxIdentifier] | None* *= None* +Box references, defaults to None + #### on_complete *: algosdk.transaction.OnComplete | None* *= None* +The OnComplete action, defaults to None + ### *class* algokit_utils.transactions.transaction_composer.AppDeleteParams Bases: `_CommonTxnParams` Parameters for deleting an application. -* **Variables:** - * **app_id** – ID of the application - * **args** – Application arguments, defaults to None - * **account_references** – Account references, defaults to None - * **app_references** – App references, defaults to None - * **asset_references** – Asset references, defaults to None - * **box_references** – Box references, defaults to None - * **on_complete** – The OnComplete action, defaults to DeleteApplicationOC - #### app_id *: int* +The ID of the application + #### args *: list[bytes] | None* *= None* +Application arguments, defaults to None + #### account_references *: list[str] | None* *= None* +Account references, defaults to None + #### app_references *: list[int] | None* *= None* +App references, defaults to None + #### asset_references *: list[int] | None* *= None* +Asset references, defaults to None + #### box_references *: list[[algokit_utils.models.state.BoxReference](../../models/state/index.md#algokit_utils.models.state.BoxReference) | algokit_utils.models.state.BoxIdentifier] | None* *= None* +Box references, defaults to None + #### on_complete *: algosdk.transaction.OnComplete* +The OnComplete action, defaults to DeleteApplicationOC + ### *class* algokit_utils.transactions.transaction_composer.AppCallMethodCallParams Bases: `_BaseAppMethodCall` Parameters for a regular ABI method call. -* **Variables:** - * **app_id** – ID of the application - * **method** – The ABI method to call - * **args** – Arguments to the ABI method, either an ABI value, transaction with explicit signer, - transaction, another method call, or None - * **on_complete** – The OnComplete action (cannot be UpdateApplication or ClearState), defaults to None - #### app_id *: int* +The ID of the application + #### on_complete *: algosdk.transaction.OnComplete | None* *= None* +The OnComplete action, defaults to None + ### *class* algokit_utils.transactions.transaction_composer.AppCreateMethodCallParams Bases: `_BaseAppMethodCall` Parameters for an ABI method call that creates an application. -* **Variables:** - * **approval_program** – The program to execute for all OnCompletes other than ClearState - * **clear_state_program** – The program to execute for ClearState OnComplete - * **schema** – The state schema for the app, defaults to None - * **on_complete** – The OnComplete action (cannot be ClearState), defaults to None - * **extra_program_pages** – Number of extra pages required for the programs, defaults to None - #### approval_program *: str | bytes* +The program to execute for all OnCompletes other than ClearState + #### clear_state_program *: str | bytes* +The program to execute for ClearState OnComplete + #### schema *: [AppCreateSchema](#algokit_utils.transactions.transaction_composer.AppCreateSchema) | None* *= None* +The state schema for the app, defaults to None + #### on_complete *: algosdk.transaction.OnComplete | None* *= None* +The OnComplete action (cannot be ClearState), defaults to None + #### extra_program_pages *: int | None* *= None* +Number of extra pages required for the programs, defaults to None + ### *class* algokit_utils.transactions.transaction_composer.AppUpdateMethodCallParams Bases: `_BaseAppMethodCall` Parameters for an ABI method call that updates an application. -* **Variables:** - * **app_id** – ID of the application - * **approval_program** – The program to execute for all OnCompletes other than ClearState - * **clear_state_program** – The program to execute for ClearState OnComplete - * **on_complete** – The OnComplete action, defaults to UpdateApplicationOC - #### app_id *: int* +The ID of the application + #### approval_program *: str | bytes* +The program to execute for all OnCompletes other than ClearState + #### clear_state_program *: str | bytes* +The program to execute for ClearState OnComplete + #### on_complete *: algosdk.transaction.OnComplete* +The OnComplete action + ### *class* algokit_utils.transactions.transaction_composer.AppDeleteMethodCallParams Bases: `_BaseAppMethodCall` Parameters for an ABI method call that deletes an application. -* **Variables:** - * **app_id** – ID of the application - * **on_complete** – The OnComplete action, defaults to DeleteApplicationOC - #### app_id *: int* +The ID of the application + #### on_complete *: algosdk.transaction.OnComplete* +The OnComplete action + ### algokit_utils.transactions.transaction_composer.MethodCallParams ### algokit_utils.transactions.transaction_composer.AppMethodCallTransactionArgument @@ -502,56 +554,62 @@ Parameters for an ABI method call that deletes an application. Set of transactions built by TransactionComposer. -* **Variables:** - * **transactions** – The built transactions - * **method_calls** – Any ABIMethod objects associated with any of the transactions in a map keyed by txn id - * **signers** – Any TransactionSigner objects associated with any of the transactions in a map keyed by txn id - #### transactions *: list[algosdk.transaction.Transaction]* +The built transactions + #### method_calls *: dict[int, algosdk.abi.Method]* +Map of transaction index to ABI method + #### signers *: dict[int, algosdk.atomic_transaction_composer.TransactionSigner]* +Map of transaction index to TransactionSigner + ### *class* algokit_utils.transactions.transaction_composer.TransactionComposerBuildResult Result of building transactions with TransactionComposer. -* **Variables:** - * **atc** – The AtomicTransactionComposer instance - * **transactions** – The list of transactions with signers - * **method_calls** – Map of transaction index to ABI method - #### atc *: algosdk.atomic_transaction_composer.AtomicTransactionComposer* +The AtomicTransactionComposer instance + #### transactions *: list[algosdk.atomic_transaction_composer.TransactionWithSigner]* +The list of transactions with signers + #### method_calls *: dict[int, algosdk.abi.Method]* +Map of transaction index to ABI method + ### *class* algokit_utils.transactions.transaction_composer.SendAtomicTransactionComposerResults Results from sending an AtomicTransactionComposer transaction group. -* **Variables:** - * **group_id** – The group ID if this was a transaction group - * **confirmations** – The confirmation info for each transaction - * **tx_ids** – The transaction IDs that were sent - * **transactions** – The transactions that were sent - * **returns** – The ABI return values from any ABI method calls - * **simulate_response** – The simulation response if simulation was performed, defaults to None - #### group_id *: str* +The group ID if this was a transaction group + #### confirmations *: list[algosdk.v2client.algod.AlgodResponseType]* +The confirmation info for each transaction + #### tx_ids *: list[str]* +The transaction IDs that were sent + #### transactions *: list[[algokit_utils.models.transaction.TransactionWrapper](../../models/transaction/index.md#algokit_utils.models.transaction.TransactionWrapper)]* +The transactions that were sent + #### returns *: list[[algokit_utils.applications.abi.ABIReturn](../../applications/abi/index.md#algokit_utils.applications.abi.ABIReturn)]* +The ABI return values from any ABI method calls + #### simulate_response *: dict[str, Any] | None* *= None* +The simulation response if simulation was performed, defaults to None + ### algokit_utils.transactions.transaction_composer.calculate_extra_program_pages(approval: bytes | None, clear: bytes | None) → int Calculate minimum number of extra_pages required for provided approval and clear programs @@ -624,11 +682,26 @@ Add a raw transaction to the composer. * **signer** – Optional transaction signer, defaults to getting signer from transaction sender * **Returns:** The transaction composer instance for chaining +* **Example:** + ```pycon + >>> composer.add_transaction(transaction) + ``` #### add_payment(params: [PaymentParams](#algokit_utils.transactions.transaction_composer.PaymentParams)) → [TransactionComposer](#algokit_utils.transactions.transaction_composer.TransactionComposer) Add a payment transaction. +* **Example:** + ```pycon + >>> params = PaymentParams( + ... sender="SENDER_ADDRESS", + ... receiver="RECEIVER_ADDRESS", + ... amount=AlgoAmount.from_algo(1), + ... close_remainder_to="CLOSE_ADDRESS" + ... ... (see PaymentParams for more options) + ... ) + >>> composer.add_payment(params) + ``` * **Parameters:** **params** – The payment transaction parameters * **Returns:** @@ -638,6 +711,23 @@ Add a payment transaction. Add an asset creation transaction. +* **Example:** + ```pycon + >>> params = AssetCreateParams( + ... sender="SENDER_ADDRESS", + ... total=1000, + ... asset_name="MyAsset", + ... unit_name="MA", + ... url="https://example.com", + ... decimals=0, + ... default_frozen=False, + ... manager="MANAGER_ADDRESS", + ... reserve="RESERVE_ADDRESS", + ... freeze="FREEZE_ADDRESS", + ... clawback="CLAWBACK_ADDRESS" + ... ... (see AssetCreateParams for more options) + >>> composer.add_asset_create(params) + ``` * **Parameters:** **params** – The asset creation parameters * **Returns:** @@ -647,6 +737,19 @@ Add an asset creation transaction. Add an asset configuration transaction. +* **Example:** + ```pycon + >>> params = AssetConfigParams( + ... sender="SENDER_ADDRESS", + ... asset_id=123456, + ... manager="NEW_MANAGER_ADDRESS", + ... reserve="NEW_RESERVE_ADDRESS", + ... freeze="NEW_FREEZE_ADDRESS", + ... clawback="NEW_CLAWBACK_ADDRESS" + ... ... (see AssetConfigParams for more options) + ... ) + >>> composer.add_asset_config(params) + ``` * **Parameters:** **params** – The asset configuration parameters * **Returns:** @@ -656,6 +759,17 @@ Add an asset configuration transaction. Add an asset freeze transaction. +* **Example:** + ```pycon + >>> params = AssetFreezeParams( + ... sender="SENDER_ADDRESS", + ... asset_id=123456, + ... account="ACCOUNT_TO_FREEZE", + ... frozen=True + ... ... (see AssetFreezeParams for more options) + ... ) + >>> composer.add_asset_freeze(params) + ``` * **Parameters:** **params** – The asset freeze parameters * **Returns:** @@ -665,6 +779,14 @@ Add an asset freeze transaction. Add an asset destruction transaction. +* **Example:** + ```pycon + >>> params = AssetDestroyParams( + ... sender="SENDER_ADDRESS", + ... asset_id=123456 + ... ... (see AssetDestroyParams for more options) + >>> composer.add_asset_destroy(params) + ``` * **Parameters:** **params** – The asset destruction parameters * **Returns:** @@ -674,6 +796,18 @@ Add an asset destruction transaction. Add an asset transfer transaction. +* **Example:** + ```pycon + >>> params = AssetTransferParams( + ... sender="SENDER_ADDRESS", + ... asset_id=123456, + ... amount=10, + ... receiver="RECEIVER_ADDRESS", + ... clawback_target="CLAWBACK_TARGET_ADDRESS", + ... close_asset_to="CLOSE_ADDRESS" + ... ... (see AssetTransferParams for more options) + >>> composer.add_asset_transfer(params) + ``` * **Parameters:** **params** – The asset transfer parameters * **Returns:** @@ -683,6 +817,15 @@ Add an asset transfer transaction. Add an asset opt-in transaction. +* **Example:** + ```pycon + >>> params = AssetOptInParams( + ... sender="SENDER_ADDRESS", + ... asset_id=123456 + ... ... (see AssetOptInParams for more options) + ... ) + >>> composer.add_asset_opt_in(params) + ``` * **Parameters:** **params** – The asset opt-in parameters * **Returns:** @@ -692,6 +835,15 @@ Add an asset opt-in transaction. Add an asset opt-out transaction. +* **Example:** + ```pycon + >>> params = AssetOptOutParams( + ... sender="SENDER_ADDRESS", + ... asset_id=123456, + ... creator="CREATOR_ADDRESS" + ... ... (see AssetOptOutParams for more options) + >>> composer.add_asset_opt_out(params) + ``` * **Parameters:** **params** – The asset opt-out parameters * **Returns:** @@ -701,6 +853,24 @@ Add an asset opt-out transaction. Add an application creation transaction. +* **Example:** + ```pycon + >>> params = AppCreateParams( + ... sender="SENDER_ADDRESS", + ... approval_program="TEAL_APPROVAL_CODE", + ... clear_state_program="TEAL_CLEAR_CODE", + ... schema={'global_ints': 1, 'global_byte_slices': 1, 'local_ints': 1, 'local_byte_slices': 1}, + ... on_complete=OnComplete.NoOpOC, + ... args=[b'arg1'], + ... account_references=["ACCOUNT1"], + ... app_references=[789], + ... asset_references=[123], + ... box_references=[], + ... extra_program_pages=0 + ... ... (see AppCreateParams for more options) + ... ) + >>> composer.add_app_create(params) + ``` * **Parameters:** **params** – The application creation parameters * **Returns:** @@ -710,6 +880,22 @@ Add an application creation transaction. Add an application update transaction. +* **Example:** + ```pycon + >>> params = AppUpdateParams( + ... sender="SENDER_ADDRESS", + ... app_id=789, + ... approval_program="TEAL_NEW_APPROVAL_CODE", + ... clear_state_program="TEAL_NEW_CLEAR_CODE", + ... args=[b'new_arg1'], + ... account_references=["ACCOUNT1"], + ... app_references=[789], + ... asset_references=[123], + ... box_references=[], + ... on_complete=OnComplete.UpdateApplicationOC + ... ... (see AppUpdateParams for more options) + >>> composer.add_app_update(params) + ``` * **Parameters:** **params** – The application update parameters * **Returns:** @@ -719,6 +905,20 @@ Add an application update transaction. Add an application deletion transaction. +* **Example:** + ```pycon + >>> params = AppDeleteParams( + ... sender="SENDER_ADDRESS", + ... app_id=789, + ... args=[b'delete_arg'], + ... account_references=["ACCOUNT1"], + ... app_references=[789], + ... asset_references=[123], + ... box_references=[], + ... on_complete=OnComplete.DeleteApplicationOC + ... ... (see AppDeleteParams for more options) + >>> composer.add_app_delete(params) + ``` * **Parameters:** **params** – The application deletion parameters * **Returns:** @@ -728,6 +928,19 @@ Add an application deletion transaction. Add an application call transaction. +* **Example:** + ```pycon + >>> params = AppCallParams( + ... sender="SENDER_ADDRESS", + ... on_complete=OnComplete.NoOpOC, + ... app_id=789, + ... approval_program="TEAL_APPROVAL_CODE", + ... clear_state_program="TEAL_CLEAR_CODE", + ... schema={'global_ints': 1, 'global_byte_slices': 1, 'local_ints': 1, 'local_byte_slices': 1}, + ... ... (see AppCallParams for more options) + ... ) + >>> composer.add_app_call(params) + ``` * **Parameters:** **params** – The application call parameters * **Returns:** @@ -741,6 +954,60 @@ Add an application creation method call transaction. **params** – The application creation method call parameters * **Returns:** The transaction composer instance for chaining +* **Example:** + ```pycon + >>> # Basic example + >>> method = algosdk.abi.Method( + ... name="method", + ... args=[...], + ... returns="string" + ... ) + >>> composer.add_app_create_method_call( + ... AppCreateMethodCallParams( + ... sender="CREATORADDRESS", + ... approval_program="TEALCODE", + ... clear_state_program="TEALCODE", + ... method=method, + ... args=["arg1_value"] + ... ) + ... ) + >>> + >>> # Advanced example + >>> method = ABIMethod( + ... name="method", + ... args=[{"name": "arg1", "type": "string"}], + ... returns={"type": "string"} + ... ) + >>> composer.add_app_create_method_call( + ... AppCreateMethodCallParams( + ... sender="CREATORADDRESS", + ... method=method, + ... args=["arg1_value"], + ... approval_program="TEALCODE", + ... clear_state_program="TEALCODE", + ... schema={ + ... "global_ints": 1, + ... "global_byte_slices": 2, + ... "local_ints": 3, + ... "local_byte_slices": 4 + ... }, + ... extra_pages=1, + ... on_complete=OnComplete.OptInOC, + ... args=[bytes([1, 2, 3, 4])], + ... account_references=["ACCOUNT_1"], + ... app_references=[123, 1234], + ... asset_references=[12345], + ... box_references=["box1", {"app_id": 1234, "name": "box2"}], + ... lease="lease", + ... note="note", + ... first_valid_round=1000, + ... validity_window=10, + ... extra_fee=AlgoAmount.from_micro_algos(1000), + ... static_fee=AlgoAmount.from_micro_algos(1000), + ... max_fee=AlgoAmount.from_micro_algos(3000) + ... ) + ... ) + ``` #### add_app_update_method_call(params: [AppUpdateMethodCallParams](#algokit_utils.transactions.transaction_composer.AppUpdateMethodCallParams)) → [TransactionComposer](#algokit_utils.transactions.transaction_composer.TransactionComposer) @@ -795,6 +1062,12 @@ Add an existing AtomicTransactionComposer’s transactions. **atc** – The AtomicTransactionComposer to add * **Returns:** The transaction composer instance for chaining +* **Example:** + ```pycon + >>> atc = AtomicTransactionComposer() + >>> atc.add_transaction(TransactionWithSigner(transaction, signer)) + >>> composer.add_atc(atc) + ``` #### count() → int @@ -851,6 +1124,10 @@ Simulate transaction group execution with configurable validation rules. * **skip_signatures** – Whether to skip signature validation * **Returns:** The simulation results +* **Example:** + ```pycon + >>> result = composer.simulate(extra_opcode_budget=1000, skip_signatures=True, ...) + ``` #### *static* arc2_note(note: algokit_utils.models.transaction.Arc2TransactionNote) → bytes diff --git a/docs/markdown/autoapi/algokit_utils/transactions/transaction_creator/index.md b/docs/markdown/autoapi/algokit_utils/transactions/transaction_creator/index.md index 34ebfb70..1d0db666 100644 --- a/docs/markdown/autoapi/algokit_utils/transactions/transaction_creator/index.md +++ b/docs/markdown/autoapi/algokit_utils/transactions/transaction_creator/index.md @@ -16,75 +16,648 @@ asset operations, application calls and key registrations. * **Parameters:** **new_group** – A lambda that starts a new TransactionComposer transaction group +* **Example:** + ```pycon + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> creator.payment(PaymentParams(sender="sender", receiver="receiver", amount=AlgoAmount.from_algo(1))) + ``` #### *property* payment *: collections.abc.Callable[[[algokit_utils.transactions.transaction_composer.PaymentParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.PaymentParams)], algosdk.transaction.Transaction]* Create a payment transaction to transfer Algo between accounts. +* **Example:** + ```pycon + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> creator.payment(PaymentParams(sender="sender", receiver="receiver", amount=AlgoAmount.from_algo(4))) + ``` +* **Example:** + ```pycon + >>> #Advanced example + >>> creator.payment(PaymentParams( + sender="SENDERADDRESS", + receiver="RECEIVERADDRESS", + amount=AlgoAmount.from_algo(4), + close_remainder_to="CLOSEREMAINDERTOADDRESS", + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + ``` + #### *property* asset_create *: collections.abc.Callable[[[algokit_utils.transactions.transaction_composer.AssetCreateParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AssetCreateParams)], algosdk.transaction.Transaction]* Create a create Algorand Standard Asset transaction. +* **Example:** + ```pycon + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AssetCreateParams(sender="SENDER_ADDRESS", total=1000) + >>> txn = creator.asset_create(params) + ``` +* **Example:** + ```pycon + >>> #Advanced example + >>> creator.asset_create(AssetCreateParams( + sender="SENDER_ADDRESS", + total=1000, + asset_name="MyAsset", + unit_name="MA", + url="https://example.com/asset", + decimals=0, + default_frozen=False, + manager="MANAGER_ADDRESS", + reserve="RESERVE_ADDRESS", + freeze="FREEZE_ADDRESS", + clawback="CLAWBACK_ADDRESS", + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + ``` + #### *property* asset_config *: collections.abc.Callable[[[algokit_utils.transactions.transaction_composer.AssetConfigParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AssetConfigParams)], algosdk.transaction.Transaction]* Create an asset config transaction to reconfigure an existing Algorand Standard Asset. +* **Example:** + ```pycon + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AssetConfigParams(sender="SENDER_ADDRESS", asset_id=123456, manager="NEW_MANAGER_ADDRESS") + >>> txn = creator.asset_config(params) + ``` +* **Example:** + ```pycon + >>> #Advanced example + >>> creator.asset_config(AssetConfigParams( + sender="SENDER_ADDRESS", + asset_id=123456, + manager="NEW_MANAGER_ADDRESS", + reserve="NEW_RESERVE_ADDRESS", + freeze="NEW_FREEZE_ADDRESS", + clawback="NEW_CLAWBACK_ADDRESS", + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + ``` + #### *property* asset_freeze *: collections.abc.Callable[[[algokit_utils.transactions.transaction_composer.AssetFreezeParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AssetFreezeParams)], algosdk.transaction.Transaction]* Create an Algorand Standard Asset freeze transaction. +* **Example:** + ```pycon + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AssetFreezeParams(sender="SENDER_ADDRESS", + asset_id=123456, + account="ACCOUNT_TO_FREEZE", + frozen=True) + >>> txn = creator.asset_freeze(params) + ``` +* **Example:** + ```pycon + >>> #Advanced example + >>> creator.asset_freeze(AssetFreezeParams( + sender="SENDER_ADDRESS", + asset_id=123456, + account="ACCOUNT_TO_FREEZE", + frozen=True, + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + ``` + #### *property* asset_destroy *: collections.abc.Callable[[[algokit_utils.transactions.transaction_composer.AssetDestroyParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AssetDestroyParams)], algosdk.transaction.Transaction]* Create an Algorand Standard Asset destroy transaction. +* **Example:** + ```pycon + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AssetDestroyParams(sender="SENDER_ADDRESS", asset_id=123456) + >>> txn = creator.asset_destroy(params) + ``` +* **Example:** + ```pycon + >>> #Advanced example + >>> creator.asset_destroy(AssetDestroyParams( + sender="SENDER_ADDRESS", + asset_id=123456, + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + ``` + #### *property* asset_transfer *: collections.abc.Callable[[[algokit_utils.transactions.transaction_composer.AssetTransferParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AssetTransferParams)], algosdk.transaction.Transaction]* Create an Algorand Standard Asset transfer transaction. +* **Example:** + ```pycon + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AssetTransferParams(sender="SENDER_ADDRESS", + asset_id=123456, + amount=10, + receiver="RECEIVER_ADDRESS") + >>> txn = creator.asset_transfer(params) + ``` +* **Example:** + ```pycon + >>> #Advanced example + >>> creator.asset_transfer(AssetTransferParams( + sender="SENDER_ADDRESS", + asset_id=123456, + amount=10, + receiver="RECEIVER_ADDRESS", + clawback_target="CLAWBACK_TARGET_ADDRESS", + close_asset_to="CLOSE_ASSET_TO_ADDRESS", + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + ``` + #### *property* asset_opt_in *: collections.abc.Callable[[[algokit_utils.transactions.transaction_composer.AssetOptInParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AssetOptInParams)], algosdk.transaction.Transaction]* Create an Algorand Standard Asset opt-in transaction. +* **Example:** + ```pycon + >>> # Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AssetOptInParams(sender="SENDER_ADDRESS", asset_id=123456) + >>> txn = creator.asset_opt_in(params) + ``` +* **Example:** + ```pycon + >>> # Advanced example + >>> creator.asset_opt_in(AssetOptInParams( + sender="SENDER_ADDRESS", + asset_id=123456, + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + ``` + #### *property* asset_opt_out *: collections.abc.Callable[[[algokit_utils.transactions.transaction_composer.AssetOptOutParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AssetOptOutParams)], algosdk.transaction.Transaction]* Create an asset opt-out transaction. +* **Example:** + ```pycon + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AssetOptOutParams(sender="SENDER_ADDRESS", asset_id=123456, creator="CREATOR_ADDRESS") + >>> txn = creator.asset_opt_out(params) + ``` +* **Example:** + ```pycon + >>> #Advanced example + >>> creator.asset_opt_out(AssetOptOutParams( + sender="SENDER_ADDRESS", + asset_id=123456, + creator="CREATOR_ADDRESS", + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + ``` + #### *property* app_create *: collections.abc.Callable[[[algokit_utils.transactions.transaction_composer.AppCreateParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppCreateParams)], algosdk.transaction.Transaction]* Create an application create transaction. +* **Example:** + ```pycon + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AppCreateParams( + ... sender="SENDER_ADDRESS", + ... approval_program="TEAL_APPROVAL_CODE", + ... clear_state_program="TEAL_CLEAR_CODE", + ... schema={ + ... 'global_ints': 1, + ... 'global_byte_slices': 1, + ... 'local_ints': 1, + ... 'local_byte_slices': 1 + ... } + ... ) + >>> txn = creator.app_create(params) + ``` +* **Example:** + ```pycon + >>> #Advanced example + >>> creator.app_create(AppCreateParams( + sender="SENDER_ADDRESS", + approval_program="TEAL_APPROVAL_CODE", + clear_state_program="TEAL_CLEAR_CODE", + schema={'global_ints': 1, 'global_byte_slices': 1, 'local_ints': 1, 'local_byte_slices': 1}, + on_complete=OnComplete.NoOpOC, + args=[b'arg1', b'arg2'], + account_references=["ACCOUNT1"], + app_references=[789], + asset_references=[123], + box_references=[], + extra_program_pages=0, + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + ``` + #### *property* app_update *: collections.abc.Callable[[[algokit_utils.transactions.transaction_composer.AppUpdateParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppUpdateParams)], algosdk.transaction.Transaction]* Create an application update transaction. +* **Example:** + ```pycon + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> txn = creator.app_update(AppUpdateParams(sender="SENDER_ADDRESS", + app_id=789, + approval_program="TEAL_NEW_APPROVAL_CODE", + clear_state_program="TEAL_NEW_CLEAR_CODE", + args=[b'new_arg1', b'new_arg2'])) + ``` +* **Example:** + ```pycon + >>> #Advanced example + >>> creator.app_update(AppUpdateParams( + sender="SENDER_ADDRESS", + app_id=789, + approval_program="TEAL_NEW_APPROVAL_CODE", + clear_state_program="TEAL_NEW_CLEAR_CODE", + args=[b'new_arg1', b'new_arg2'], + account_references=["ACCOUNT1"], + app_references=[789], + asset_references=[123], + box_references=[], + on_complete=OnComplete.UpdateApplicationOC, + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + ``` + #### *property* app_delete *: collections.abc.Callable[[[algokit_utils.transactions.transaction_composer.AppDeleteParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppDeleteParams)], algosdk.transaction.Transaction]* Create an application delete transaction. +* **Example:** + ```pycon + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AppDeleteParams(sender="SENDER_ADDRESS", app_id=789, args=[b'delete_arg']) + >>> txn = creator.app_delete(params) + ``` +* **Example:** + ```pycon + >>> #Advanced example + >>> creator.app_delete(AppDeleteParams( + sender="SENDER_ADDRESS", + app_id=789, + args=[b'delete_arg'], + account_references=["ACCOUNT1"], + app_references=[789], + asset_references=[123], + box_references=[], + on_complete=OnComplete.DeleteApplicationOC, + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + ``` + #### *property* app_call *: collections.abc.Callable[[[algokit_utils.transactions.transaction_composer.AppCallParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppCallParams)], algosdk.transaction.Transaction]* Create an application call transaction. +* **Example:** + ```pycon + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AppCallParams( + ... sender="SENDER_ADDRESS", + ... on_complete=OnComplete.NoOpOC, + ... app_id=789, + ... approval_program="TEAL_APPROVAL_CODE", + ... clear_state_program="TEAL_CLEAR_CODE", + ... schema={ + ... 'global_ints': 1, + ... 'global_byte_slices': 1, + ... 'local_ints': 1, + ... 'local_byte_slices': 1 + ... }, + ... args=[b'arg1', b'arg2'], + ... account_references=["ACCOUNT1"], + ... app_references=[789], + ... asset_references=[123], + ... extra_pages=0, + ... box_references=[] + ... ) + >>> txn = creator.app_call(params) + ``` +* **Example:** + ```pycon + >>> #Advanced example + >>> creator.app_call(AppCallParams( + sender="SENDER_ADDRESS", + on_complete=OnComplete.NoOpOC, + app_id=789, + approval_program="TEAL_APPROVAL_CODE", + clear_state_program="TEAL_CLEAR_CODE", + schema={'global_ints': 1, 'global_byte_slices': 1, 'local_ints': 1, 'local_byte_slices': 1}, + args=[b'arg1', b'arg2'], + account_references=["ACCOUNT1"], + app_references=[789], + asset_references=[123], + extra_pages=0, + box_references=[], + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + ``` + #### *property* app_create_method_call *: collections.abc.Callable[[[algokit_utils.transactions.transaction_composer.AppCreateMethodCallParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppCreateMethodCallParams)], [algokit_utils.transactions.transaction_composer.BuiltTransactions](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.BuiltTransactions)]* Create an application create call with ABI method call transaction. +* **Example:** + ```pycon + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AppCreateMethodCallParams(sender="SENDER_ADDRESS", app_id=0, method=some_abi_method_object) + >>> built_txns = creator.app_create_method_call(params) + ``` +* **Example:** + ```pycon + >>> #Advanced example + >>> creator.app_create_method_call(AppCreateMethodCallParams( + sender="SENDER_ADDRESS", + app_id=0, + method=some_abi_method_object, + args=[b'method_arg'], + account_references=["ACCOUNT1"], + app_references=[789], + asset_references=[123], + box_references=[], + schema={'global_ints': 1, 'global_byte_slices': 1, 'local_ints': 1, 'local_byte_slices': 1}, + approval_program="TEAL_APPROVAL_CODE", + clear_state_program="TEAL_CLEAR_CODE", + on_complete=OnComplete.NoOpOC, + extra_program_pages=0, + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + ``` + #### *property* app_update_method_call *: collections.abc.Callable[[[algokit_utils.transactions.transaction_composer.AppUpdateMethodCallParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppUpdateMethodCallParams)], [algokit_utils.transactions.transaction_composer.BuiltTransactions](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.BuiltTransactions)]* Create an application update call with ABI method call transaction. +* **Example:** + ```pycon + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AppUpdateMethodCallParams(sender="SENDER_ADDRESS", app_id=789, method=some_abi_method_object) + >>> built_txns = creator.app_update_method_call(params) + ``` +* **Example:** + ```pycon + >>> #Advanced example + >>> creator.app_update_method_call(AppUpdateMethodCallParams( + sender="SENDER_ADDRESS", + app_id=789, + method=some_abi_method_object, + args=[b'method_arg'], + account_references=["ACCOUNT1"], + app_references=[789], + asset_references=[123], + box_references=[], + schema={'global_ints': 1, 'global_byte_slices': 1, 'local_ints': 1, 'local_byte_slices': 1}, + approval_program="TEAL_NEW_APPROVAL_CODE", + clear_state_program="TEAL_NEW_CLEAR_CODE", + on_complete=OnComplete.UpdateApplicationOC, + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + ``` + #### *property* app_delete_method_call *: collections.abc.Callable[[[algokit_utils.transactions.transaction_composer.AppDeleteMethodCallParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppDeleteMethodCallParams)], [algokit_utils.transactions.transaction_composer.BuiltTransactions](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.BuiltTransactions)]* Create an application delete call with ABI method call transaction. +* **Example:** + ```pycon + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AppDeleteMethodCallParams(sender="SENDER_ADDRESS", app_id=789, method=some_abi_method_object) + >>> built_txns = creator.app_delete_method_call(params) + ``` +* **Example:** + ```pycon + >>> #Advanced example + >>> creator.app_delete_method_call(AppDeleteMethodCallParams( + sender="SENDER_ADDRESS", + app_id=789, + method=some_abi_method_object, + args=[b'method_arg'], + account_references=["ACCOUNT1"], + app_references=[789], + asset_references=[123], + box_references=[], + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + ``` + #### *property* app_call_method_call *: collections.abc.Callable[[[algokit_utils.transactions.transaction_composer.AppCallMethodCallParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppCallMethodCallParams)], [algokit_utils.transactions.transaction_composer.BuiltTransactions](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.BuiltTransactions)]* Create an application call with ABI method call transaction. +* **Example:** + ```pycon + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AppCallMethodCallParams(sender="SENDER_ADDRESS", app_id=789, method=some_abi_method_object) + >>> built_txns = creator.app_call_method_call(params) + ``` +* **Example:** + Advanced example + >>> creator.app_call_method_call(AppCallMethodCallParams( + > sender=”SENDER_ADDRESS”, + > app_id=789, + > method=some_abi_method_object, + > args=[b’method_arg’], + > account_references=[“ACCOUNT1”], + > app_references=[789], + > asset_references=[123], + > box_references=[], + > lease=”lease”, + > note=b”note”, + > rekey_to=”REKEYTOADDRESS”, + > first_valid_round=1000, + > validity_window=10, + > extra_fee=AlgoAmount.from_micro_algo(1000), + > static_fee=AlgoAmount.from_micro_algo(1000), + > max_fee=AlgoAmount.from_micro_algo(3000) + + )) + #### *property* online_key_registration *: collections.abc.Callable[[[algokit_utils.transactions.transaction_composer.OnlineKeyRegistrationParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.OnlineKeyRegistrationParams)], algosdk.transaction.Transaction]* Create an online key registration transaction. +* **Example:** + ```pycon + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = OnlineKeyRegistrationParams( + sender="SENDER_ADDRESS", + vote_key="VOTE_KEY", + selection_key="SELECTION_KEY", + vote_first=1000, + vote_last=2000, + vote_key_dilution=10, + state_proof_key=b"state_proof_key_bytes" + ) + >>> txn = creator.online_key_registration(params) + ``` +* **Example:** + ```pycon + >>> #Advanced example + >>> creator.online_key_registration(OnlineKeyRegistrationParams( + sender="SENDER_ADDRESS", + vote_key="VOTE_KEY", + selection_key="SELECTION_KEY", + vote_first=1000, + vote_last=2000, + vote_key_dilution=10, + state_proof_key=b"state_proof_key_bytes", + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + ``` + #### *property* offline_key_registration *: collections.abc.Callable[[[algokit_utils.transactions.transaction_composer.OfflineKeyRegistrationParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.OfflineKeyRegistrationParams)], algosdk.transaction.Transaction]* Create an offline key registration transaction. + +* **Example:** + ```pycon + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> txn = creator.offline_key_registration(OfflineKeyRegistrationParams(sender="SENDER_ADDRESS", + prevent_account_from_ever_participating_again=True)) + ``` +* **Example:** + ```pycon + >>> #Advanced example + >>> creator.offline_key_registration(OfflineKeyRegistrationParams( + sender="SENDER_ADDRESS", + prevent_account_from_ever_participating_again=True, + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + ``` diff --git a/docs/markdown/autoapi/algokit_utils/transactions/transaction_sender/index.md b/docs/markdown/autoapi/algokit_utils/transactions/transaction_sender/index.md index c8b886d6..10032c0f 100644 --- a/docs/markdown/autoapi/algokit_utils/transactions/transaction_sender/index.md +++ b/docs/markdown/autoapi/algokit_utils/transactions/transaction_sender/index.md @@ -20,20 +20,36 @@ Represents the result of sending a single transaction. #### transaction *: [algokit_utils.models.transaction.TransactionWrapper](../../models/transaction/index.md#algokit_utils.models.transaction.TransactionWrapper)* +The last transaction + #### confirmation *: algosdk.v2client.algod.AlgodResponseType* +The last confirmation + #### group_id *: str* +The group ID + #### tx_id *: str | None* *= None* +The transaction ID + #### tx_ids *: list[str]* +The full array of transaction IDs + #### transactions *: list[[algokit_utils.models.transaction.TransactionWrapper](../../models/transaction/index.md#algokit_utils.models.transaction.TransactionWrapper)]* +The full array of transactions + #### confirmations *: list[algosdk.v2client.algod.AlgodResponseType]* +The full array of confirmations + #### returns *: list[[algokit_utils.applications.abi.ABIReturn](../../applications/abi/index.md#algokit_utils.applications.abi.ABIReturn)] | None* *= None* +The ABI return value if applicable + #### *classmethod* from_composer_result(result: [algokit_utils.transactions.transaction_composer.SendAtomicTransactionComposerResults](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.SendAtomicTransactionComposerResults), index: int = -1) → typing_extensions.Self ### *class* algokit_utils.transactions.transaction_sender.SendSingleAssetCreateTransactionResult @@ -46,6 +62,8 @@ Contains the asset ID of the newly created asset. #### asset_id *: int* +The ID of the newly created asset + ### *class* algokit_utils.transactions.transaction_sender.SendAppTransactionResult Bases: [`SendSingleTransactionResult`](#algokit_utils.transactions.transaction_sender.SendSingleTransactionResult), `Generic`[`ABIReturnT`] @@ -56,6 +74,8 @@ Contains the ABI return value if applicable. #### abi_return *: ABIReturnT | None* *= None* +The ABI return value if applicable + ### *class* algokit_utils.transactions.transaction_sender.SendAppUpdateTransactionResult Bases: [`SendAppTransactionResult`](#algokit_utils.transactions.transaction_sender.SendAppTransactionResult)[`ABIReturnT`] @@ -66,8 +86,12 @@ Contains the compiled approval and clear programs. #### compiled_approval *: Any | None* *= None* +The compiled approval program + #### compiled_clear *: Any | None* *= None* +The compiled clear state program + ### *class* algokit_utils.transactions.transaction_sender.SendAppCreateTransactionResult Bases: [`SendAppUpdateTransactionResult`](#algokit_utils.transactions.transaction_sender.SendAppUpdateTransactionResult)[`ABIReturnT`] @@ -78,8 +102,12 @@ Contains the app ID and address of the newly created application. #### app_id *: int* +The ID of the newly created application + #### app_address *: str* +The address of the newly created application + ### *class* algokit_utils.transactions.transaction_sender.AlgorandClientTransactionSender(new_group: collections.abc.Callable[[], [algokit_utils.transactions.transaction_composer.TransactionComposer](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.TransactionComposer)], asset_manager: [algokit_utils.assets.asset_manager.AssetManager](../../assets/asset_manager/index.md#algokit_utils.assets.asset_manager.AssetManager), app_manager: [algokit_utils.applications.app_manager.AppManager](../../applications/app_manager/index.md#algokit_utils.applications.app_manager.AppManager), algod_client: algosdk.v2client.algod.AlgodClient) Orchestrates sending transactions for AlgorandClient. @@ -93,6 +121,13 @@ Create a new transaction group. * **Returns:** A new TransactionComposer instance +* **Example:** + ```pycon + >>> sender = AlgorandClientTransactionSender(new_group, asset_manager, app_manager, algod_client) + >>> composer = sender.new_group() + >>> composer(PaymentParams(sender="sender", receiver="receiver", amount=AlgoAmount(algo=1))) + >>> composer.send() + ``` #### payment(params: [algokit_utils.transactions.transaction_composer.PaymentParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.PaymentParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → [SendSingleTransactionResult](#algokit_utils.transactions.transaction_sender.SendSingleTransactionResult) @@ -103,6 +138,36 @@ Send a payment transaction to transfer Algo between accounts. * **send_params** – Send parameters * **Returns:** Result of the payment transaction +* **Example:** + ```pycon + >>> result = algorand.send.payment(PaymentParams( + >>> sender="SENDERADDRESS", + >>> receiver="RECEIVERADDRESS", + >>> amount=AlgoAmount(algo=4), + >>> )) + ``` + + ```pycon + >>> # Advanced example + >>> result = algorand.send.payment(PaymentParams( + >>> amount=AlgoAmount(algo=4), + >>> receiver="RECEIVERADDRESS", + >>> sender="SENDERADDRESS", + >>> close_remainder_to="CLOSEREMAINDERTOADDRESS", + >>> lease="lease", + >>> note="note", + >>> rekey_to="REKEYTOADDRESS", + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> signer=transactionSigner + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) + ``` #### asset_create(params: [algokit_utils.transactions.transaction_composer.AssetCreateParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AssetCreateParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → [SendSingleAssetCreateTransactionResult](#algokit_utils.transactions.transaction_sender.SendSingleAssetCreateTransactionResult) @@ -113,6 +178,50 @@ Create a new Algorand Standard Asset. * **send_params** – Send parameters * **Returns:** Result containing the new asset ID +* **Example:** + ```pycon + >>> result = algorand.send.asset_create(AssetCreateParams( + >>> sender="SENDERADDRESS", + >>> asset_name="ASSETNAME", + >>> unit_name="UNITNAME", + >>> total=1000, + >>> )) + ``` + + ```pycon + >>> # Advanced example + >>> result = algorand.send.asset_create(AssetCreateParams( + >>> sender="CREATORADDRESS", + >>> total=100, + >>> decimals=2, + >>> asset_name="asset", + >>> unit_name="unit", + >>> url="url", + >>> metadata_hash="metadataHash", + >>> default_frozen=False, + >>> manager="MANAGERADDRESS", + >>> reserve="RESERVEADDRESS", + >>> freeze="FREEZEADDRESS", + >>> clawback="CLAWBACKADDRESS", + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) + ``` #### asset_config(params: [algokit_utils.transactions.transaction_composer.AssetConfigParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AssetConfigParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → [SendSingleTransactionResult](#algokit_utils.transactions.transaction_sender.SendSingleTransactionResult) @@ -123,6 +232,34 @@ Configure an existing Algorand Standard Asset. * **send_params** – Send parameters * **Returns:** Result of the configuration transaction +* **Example:** + ```pycon + >>> result = algorand.send.asset_config(AssetConfigParams( + >>> sender="MANAGERADDRESS", + >>> asset_id=123456, + >>> manager="MANAGERADDRESS", + >>> reserve="RESERVEADDRESS", + >>> freeze="FREEZEADDRESS", + >>> clawback="CLAWBACKADDRESS", + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) + ``` #### asset_freeze(params: [algokit_utils.transactions.transaction_composer.AssetFreezeParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AssetFreezeParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → [SendSingleTransactionResult](#algokit_utils.transactions.transaction_sender.SendSingleTransactionResult) @@ -133,6 +270,42 @@ Freeze or unfreeze an Algorand Standard Asset for an account. * **send_params** – Send parameters * **Returns:** Result of the freeze transaction +* **Example:** + ```pycon + >>> result = algorand.send.asset_freeze(AssetFreezeParams( + >>> sender="MANAGERADDRESS", + >>> asset_id=123456, + >>> account="ACCOUNTADDRESS", + >>> frozen=True, + >>> )) + ``` + + ```pycon + >>> # Advanced example + >>> result = algorand.send.asset_freeze(AssetFreezeParams( + >>> sender="MANAGERADDRESS", + >>> asset_id=123456, + >>> account="ACCOUNTADDRESS", + >>> frozen=True, + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) + ``` #### asset_destroy(params: [algokit_utils.transactions.transaction_composer.AssetDestroyParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AssetDestroyParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → [SendSingleTransactionResult](#algokit_utils.transactions.transaction_sender.SendSingleTransactionResult) @@ -143,6 +316,38 @@ Destroys an Algorand Standard Asset. * **send_params** – Send parameters * **Returns:** Result of the destroy transaction +* **Example:** + ```pycon + >>> result = algorand.send.asset_destroy(AssetDestroyParams( + >>> sender="MANAGERADDRESS", + >>> asset_id=123456, + >>> )) + ``` + + ```pycon + >>> # Advanced example + >>> result = algorand.send.asset_destroy(AssetDestroyParams( + >>> sender="MANAGERADDRESS", + >>> asset_id=123456, + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) + ``` #### asset_transfer(params: [algokit_utils.transactions.transaction_composer.AssetTransferParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AssetTransferParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → [SendSingleTransactionResult](#algokit_utils.transactions.transaction_sender.SendSingleTransactionResult) @@ -153,6 +358,45 @@ Transfer an Algorand Standard Asset. * **send_params** – Send parameters * **Returns:** Result of the transfer transaction +* **Example:** + ```pycon + >>> result = algorand.send.asset_transfer(AssetTransferParams( + >>> sender="HOLDERADDRESS", + >>> asset_id=123456, + >>> amount=1, + >>> receiver="RECEIVERADDRESS", + >>> )) + ``` + + ```pycon + >>> # Advanced example (with clawback) + >>> result = algorand.send.asset_transfer(AssetTransferParams( + >>> sender="CLAWBACKADDRESS", + >>> asset_id=123456, + >>> amount=1, + >>> receiver="RECEIVERADDRESS", + >>> clawback_target="HOLDERADDRESS", + >>> # This field needs to be used with caution + >>> close_asset_to="ADDRESSTOCLOSETO", + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) + ``` #### asset_opt_in(params: [algokit_utils.transactions.transaction_composer.AssetOptInParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AssetOptInParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → [SendSingleTransactionResult](#algokit_utils.transactions.transaction_sender.SendSingleTransactionResult) @@ -163,6 +407,38 @@ Opt an account into an Algorand Standard Asset. * **send_params** – Send parameters * **Returns:** Result of the opt-in transaction +* **Example:** + ```pycon + >>> result = algorand.send.asset_opt_in(AssetOptInParams( + >>> sender="SENDERADDRESS", + >>> asset_id=123456, + >>> )) + ``` + + ```pycon + >>> # Advanced example + >>> result = algorand.send.asset_opt_in(AssetOptInParams( + >>> sender="SENDERADDRESS", + >>> asset_id=123456, + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) + ``` #### asset_opt_out(\*, params: [algokit_utils.transactions.transaction_composer.AssetOptOutParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AssetOptOutParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None, ensure_zero_balance: bool = True) → [SendSingleTransactionResult](#algokit_utils.transactions.transaction_sender.SendSingleTransactionResult) @@ -176,6 +452,42 @@ Opt an account out of an Algorand Standard Asset. **ValueError** – If account has non-zero balance or is not opted in * **Returns:** Result of the opt-out transaction +* **Example:** + ```pycon + >>> result = algorand.send.asset_opt_out(AssetOptOutParams( + >>> sender="SENDERADDRESS", + >>> creator="CREATORADDRESS", + >>> asset_id=123456, + >>> ensure_zero_balance=True, + >>> )) + ``` + + ```pycon + >>> # Advanced example + >>> result = algorand.send.asset_opt_out(AssetOptOutParams( + >>> sender="SENDERADDRESS", + >>> asset_id=123456, + >>> creator="CREATORADDRESS", + >>> ensure_zero_balance=True, + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) + ``` #### app_create(params: [algokit_utils.transactions.transaction_composer.AppCreateParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppCreateParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → [SendAppCreateTransactionResult](#algokit_utils.transactions.transaction_sender.SendAppCreateTransactionResult)[[algokit_utils.applications.abi.ABIReturn](../../applications/abi/index.md#algokit_utils.applications.abi.ABIReturn)] @@ -186,6 +498,58 @@ Create a new application. * **send_params** – Send parameters * **Returns:** Result containing the new application ID and address +* **Example:** + ```pycon + >>> result = algorand.send.app_create(AppCreateParams( + >>> sender="CREATORADDRESS", + >>> approval_program="TEALCODE", + >>> clear_state_program="TEALCODE", + >>> )) + ``` + + ```pycon + >>> # Advanced example + >>> result = algorand.send.app_create(AppCreateParams( + >>> sender="CREATORADDRESS", + >>> approval_program="TEALCODE", + >>> clear_state_program="TEALCODE", + >>> )) + >>> # algorand.send.appCreate(AppCreateParams( + >>> # sender='CREATORADDRESS', + >>> # approval_program="TEALCODE", + >>> # clear_state_program="TEALCODE", + >>> # schema={ + >>> # "global_ints": 1, + >>> # "global_byte_slices": 2, + >>> # "local_ints": 3, + >>> # "local_byte_slices": 4 + >>> # }, + >>> # extra_program_pages: 1, + >>> # on_complete: algosdk.transaction.OnComplete.OptInOC, + >>> # args: [b'some_bytes'] + >>> # account_references: ["ACCOUNT_1"] + >>> # app_references: [123, 1234] + >>> # asset_references: [12345] + >>> # box_references: ["box1", {app_id: 1234, name: "box2"}] + >>> # lease: 'lease', + >>> # note: 'note', + >>> # # You wouldn't normally set this field + >>> # first_valid_round: 1000, + >>> # validity_window: 10, + >>> # extra_fee: AlgoAmount(micro_algo=1000), + >>> # static_fee: AlgoAmount(micro_algo=1000), + >>> # # Max fee doesn't make sense with extraFee AND staticFee + >>> # # already specified, but here for completeness + >>> # max_fee: AlgoAmount(micro_algo=3000), + >>> # # Signer only needed if you want to provide one, + >>> # # generally you'd register it with AlgorandClient + >>> # # against the sender and not need to pass it in + >>> # signer: transactionSigner + >>> #}, send_params=SendParams( + >>> # max_rounds_to_wait_for_confirmation=5, + >>> # suppress_log=True, + >>> #)) + ``` #### app_update(params: [algokit_utils.transactions.transaction_composer.AppUpdateParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppUpdateParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → [SendAppUpdateTransactionResult](#algokit_utils.transactions.transaction_sender.SendAppUpdateTransactionResult)[[algokit_utils.applications.abi.ABIReturn](../../applications/abi/index.md#algokit_utils.applications.abi.ABIReturn)] @@ -196,6 +560,44 @@ Update an application. * **send_params** – Send parameters * **Returns:** Result containing the compiled programs +* **Example:** + ```pycon + >>> # Basic example + >>> algorand.send.app_update(AppUpdateParams( + >>> sender="CREATORADDRESS", + >>> approval_program="TEALCODE", + >>> clear_state_program="TEALCODE", + >>> )) + >>> # Advanced example + >>> algorand.send.app_update(AppUpdateParams( + >>> sender="CREATORADDRESS", + >>> approval_program="TEALCODE", + >>> clear_state_program="TEALCODE", + >>> on_complete=OnComplete.UpdateApplicationOC, + >>> args=[b'some_bytes'], + >>> account_references=["ACCOUNT_1"], + >>> app_references=[123, 1234], + >>> asset_references=[12345], + >>> box_references=[...], + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) + ``` #### app_delete(params: [algokit_utils.transactions.transaction_composer.AppDeleteParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppDeleteParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → [SendAppTransactionResult](#algokit_utils.transactions.transaction_sender.SendAppTransactionResult)[[algokit_utils.applications.abi.ABIReturn](../../applications/abi/index.md#algokit_utils.applications.abi.ABIReturn)] @@ -206,6 +608,41 @@ Delete an application. * **send_params** – Send parameters * **Returns:** Result of the deletion transaction +* **Example:** + ```pycon + >>> # Basic example + >>> algorand.send.app_delete(AppDeleteParams( + >>> sender="CREATORADDRESS", + >>> app_id=123456, + >>> )) + >>> # Advanced example + >>> algorand.send.app_delete(AppDeleteParams( + >>> sender="CREATORADDRESS", + >>> on_complete=OnComplete.DeleteApplicationOC, + >>> args=[b'some_bytes'], + >>> account_references=["ACCOUNT_1"], + >>> app_references=[123, 1234], + >>> asset_references=[12345], + >>> box_references=[...], + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner, + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) + ``` #### app_call(params: [algokit_utils.transactions.transaction_composer.AppCallParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppCallParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → [SendAppTransactionResult](#algokit_utils.transactions.transaction_sender.SendAppTransactionResult)[[algokit_utils.applications.abi.ABIReturn](../../applications/abi/index.md#algokit_utils.applications.abi.ABIReturn)] @@ -216,6 +653,41 @@ Call an application. * **send_params** – Send parameters * **Returns:** Result containing any ABI return value +* **Example:** + ```pycon + >>> # Basic example + >>> algorand.send.app_call(AppCallParams( + >>> sender="CREATORADDRESS", + >>> app_id=123456, + >>> )) + >>> # Advanced example + >>> algorand.send.app_call(AppCallParams( + >>> sender="CREATORADDRESS", + >>> on_complete=OnComplete.OptInOC, + >>> args=[b'some_bytes'], + >>> account_references=["ACCOUNT_1"], + >>> app_references=[123, 1234], + >>> asset_references=[12345], + >>> box_references=[...], + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner, + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) + ``` #### app_create_method_call(params: [algokit_utils.transactions.transaction_composer.AppCreateMethodCallParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppCreateMethodCallParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → [SendAppCreateTransactionResult](#algokit_utils.transactions.transaction_sender.SendAppCreateTransactionResult)[[algokit_utils.applications.abi.ABIReturn](../../applications/abi/index.md#algokit_utils.applications.abi.ABIReturn)] @@ -226,6 +698,68 @@ Call an application’s create method. * **send_params** – Send parameters * **Returns:** Result containing the new application ID and address +* **Example:** + ```pycon + >>> # Note: you may prefer to use `algorand.client` to get an app client for more advanced functionality. + >>> # + >>> # @param params The parameters for the app creation transaction + >>> # Basic example + >>> method = algorand.abi.Method( + >>> name='method', + >>> args=[b'arg1'], + >>> returns='string' + >>> ) + >>> result = algorand.send.app_create_method_call({ sender: 'CREATORADDRESS', + >>> approval_program: 'TEALCODE', + >>> clear_state_program: 'TEALCODE', + >>> method: method, + >>> args: ["arg1_value"] }) + >>> created_app_id = result.app_id + >>> ... + >>> # Advanced example + >>> method = algorand.abi.Method( + >>> name='method', + >>> args=[b'arg1'], + >>> returns='string' + >>> ) + >>> result = algorand.send.app_create_method_call({ + >>> sender: 'CREATORADDRESS', + >>> method: method, + >>> args: ["arg1_value"], + >>> approval_program: "TEALCODE", + >>> clear_state_program: "TEALCODE", + >>> schema: { + >>> "global_ints": 1, + >>> "global_byte_slices": 2, + >>> "local_ints": 3, + >>> "local_byte_slices": 4 + >>> }, + >>> extra_program_pages: 1, + >>> on_complete: algosdk.transaction.OnComplete.OptInOC, + >>> args: [new Uint8Array(1, 2, 3, 4)], + >>> account_references: ["ACCOUNT_1"], + >>> app_references: [123, 1234], + >>> asset_references: [12345], + >>> box_references: [...], + >>> lease: 'lease', + >>> note: 'note', + >>> # You wouldn't normally set this field + >>> first_valid_round: 1000, + >>> validity_window: 10, + >>> extra_fee: AlgoAmount(micro_algo=1000), + >>> static_fee: AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee: AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer: transactionSigner, + >>> }, send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) + ``` #### app_update_method_call(params: [algokit_utils.transactions.transaction_composer.AppUpdateMethodCallParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppUpdateMethodCallParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → [SendAppUpdateTransactionResult](#algokit_utils.transactions.transaction_sender.SendAppUpdateTransactionResult)[[algokit_utils.applications.abi.ABIReturn](../../applications/abi/index.md#algokit_utils.applications.abi.ABIReturn)] @@ -236,6 +770,43 @@ Call an application’s update method. * **send_params** – Send parameters * **Returns:** Result containing the compiled programs +* **Example:** + # Basic example: + >>> method = algorand.abi.Method( + … name=”updateMethod”, + … args=[{“type”: “string”, “name”: “arg1”}], + … returns=”string” + … ) + >>> params = AppUpdateMethodCallParams( + … sender=”CREATORADDRESS”, + … app_id=123, + … method=method, + … args=[“new_value”], + … approval_program=”TEALCODE”, + … clear_state_program=”TEALCODE” + … ) + >>> result = algorand.send.app_update_method_call(params) + >>> print(result.compiled_approval, result.compiled_clear) + + # Advanced example: + >>> method = algorand.abi.Method( + … name=”updateMethod”, + … args=[{“type”: “string”, “name”: “arg1”}, {“type”: “uint64”, “name”: “arg2”}], + … returns=”string” + … ) + >>> params = AppUpdateMethodCallParams( + … sender=”CREATORADDRESS”, + … app_id=456, + … method=method, + … args=[“new_value”, 42], + … approval_program=”TEALCODE_ADVANCED”, + … clear_state_program=”TEALCLEAR_ADVANCED”, + … account_references=[“ACCOUNT1”, “ACCOUNT2”], + … app_references=[789], + … asset_references=[101112] + … ) + >>> result = algorand.send.app_update_method_call(params) + >>> print(result.compiled_approval, result.compiled_clear) #### app_delete_method_call(params: [algokit_utils.transactions.transaction_composer.AppDeleteMethodCallParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppDeleteMethodCallParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → [SendAppTransactionResult](#algokit_utils.transactions.transaction_sender.SendAppTransactionResult)[[algokit_utils.applications.abi.ABIReturn](../../applications/abi/index.md#algokit_utils.applications.abi.ABIReturn)] @@ -246,6 +817,37 @@ Call an application’s delete method. * **send_params** – Send parameters * **Returns:** Result of the deletion transaction +* **Example:** + # Basic example: + >>> method = algorand.abi.Method( + … name=”deleteMethod”, + … args=[], + … returns=”void” + … ) + >>> params = AppDeleteMethodCallParams( + … sender=”CREATORADDRESS”, + … app_id=123, + … method=method + … ) + >>> result = algorand.send.app_delete_method_call(params) + >>> print(result.tx_id) + + # Advanced example: + >>> method = algorand.abi.Method( + … name=”deleteMethod”, + … args=[{“type”: “uint64”, “name”: “confirmation”}], + … returns=”void” + … ) + >>> params = AppDeleteMethodCallParams( + … sender=”CREATORADDRESS”, + … app_id=123, + … method=method, + … args=[1], + … account_references=[“ACCOUNT1”], + … app_references=[456] + … ) + >>> result = algorand.send.app_delete_method_call(params) + >>> print(result.tx_id) #### app_call_method_call(params: [algokit_utils.transactions.transaction_composer.AppCallMethodCallParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.AppCallMethodCallParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → [SendAppTransactionResult](#algokit_utils.transactions.transaction_sender.SendAppTransactionResult)[[algokit_utils.applications.abi.ABIReturn](../../applications/abi/index.md#algokit_utils.applications.abi.ABIReturn)] @@ -256,6 +858,39 @@ Call an application’s call method. * **send_params** – Send parameters * **Returns:** Result containing any ABI return value +* **Example:** + # Basic example: + >>> method = algorand.abi.Method( + … name=”callMethod”, + … args=[{“type”: “uint64”, “name”: “arg1”}], + … returns=”uint64” + … ) + >>> params = AppCallMethodCallParams( + … sender=”CALLERADDRESS”, + … app_id=123, + … method=method, + … args=[12345] + … ) + >>> result = algorand.send.app_call_method_call(params) + >>> print(result.abi_return) + + # Advanced example: + >>> method = algorand.abi.Method( + … name=”callMethod”, + … args=[{“type”: “uint64”, “name”: “arg1”}, {“type”: “string”, “name”: “arg2”}], + … returns=”uint64” + … ) + >>> params = AppCallMethodCallParams( + … sender=”CALLERADDRESS”, + … app_id=123, + … method=method, + … args=[12345, “extra”], + … account_references=[“ACCOUNT1”], + … asset_references=[101112], + … app_references=[789] + … ) + >>> result = algorand.send.app_call_method_call(params) + >>> print(result.abi_return) #### online_key_registration(params: [algokit_utils.transactions.transaction_composer.OnlineKeyRegistrationParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.OnlineKeyRegistrationParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → [SendSingleTransactionResult](#algokit_utils.transactions.transaction_sender.SendSingleTransactionResult) @@ -266,6 +901,31 @@ Register an online key. * **send_params** – Send parameters * **Returns:** Result of the registration transaction +* **Example:** + # Basic example: + >>> params = OnlineKeyRegistrationParams( + … sender=”ACCOUNTADDRESS”, + … vote_key=”VOTEKEY”, + … selection_key=”SELECTIONKEY”, + … vote_first=1000, + … vote_last=2000, + … vote_key_dilution=10 + … ) + >>> result = algorand.send.online_key_registration(params) + >>> print(result.tx_id) + + # Advanced example: + >>> params = OnlineKeyRegistrationParams( + … sender=”ACCOUNTADDRESS”, + … vote_key=”VOTEKEY”, + … selection_key=”SELECTIONKEY”, + … vote_first=1000, + … vote_last=2100, + … vote_key_dilution=10, + … state_proof_key=b’’ \* 64 + … ) + >>> result = algorand.send.online_key_registration(params) + >>> print(result.tx_id) #### offline_key_registration(params: [algokit_utils.transactions.transaction_composer.OfflineKeyRegistrationParams](../transaction_composer/index.md#algokit_utils.transactions.transaction_composer.OfflineKeyRegistrationParams), send_params: [algokit_utils.models.transaction.SendParams](../../models/transaction/index.md#algokit_utils.models.transaction.SendParams) | None = None) → [SendSingleTransactionResult](#algokit_utils.transactions.transaction_sender.SendSingleTransactionResult) @@ -276,3 +936,20 @@ Register an offline key. * **send_params** – Send parameters * **Returns:** Result of the registration transaction +* **Example:** + # Basic example: + >>> params = OfflineKeyRegistrationParams( + … sender=”ACCOUNTADDRESS”, + … prevent_account_from_ever_participating_again=True + … ) + >>> result = algorand.send.offline_key_registration(params) + >>> print(result.tx_id) + + # Advanced example: + >>> params = OfflineKeyRegistrationParams( + … sender=”ACCOUNTADDRESS”, + … prevent_account_from_ever_participating_again=True, + … note=b’Offline registration’ + … ) + >>> result = algorand.send.offline_key_registration(params) + >>> print(result.tx_id) diff --git a/docs/markdown/autoapi/algorand_client/index.md b/docs/markdown/autoapi/algorand_client/index.md deleted file mode 100644 index e2034ce0..00000000 --- a/docs/markdown/autoapi/algorand_client/index.md +++ /dev/null @@ -1 +0,0 @@ -# algorand_client diff --git a/docs/markdown/autoapi/client_manager/index.md b/docs/markdown/autoapi/client_manager/index.md deleted file mode 100644 index e73efa8f..00000000 --- a/docs/markdown/autoapi/client_manager/index.md +++ /dev/null @@ -1 +0,0 @@ -# client_manager diff --git a/docs/markdown/autoapi/composer/index.md b/docs/markdown/autoapi/composer/index.md deleted file mode 100644 index 4cb259e0..00000000 --- a/docs/markdown/autoapi/composer/index.md +++ /dev/null @@ -1 +0,0 @@ -# composer diff --git a/docs/markdown/autoapi/index.md b/docs/markdown/autoapi/index.md index 32153723..69409179 100644 --- a/docs/markdown/autoapi/index.md +++ b/docs/markdown/autoapi/index.md @@ -2,7 +2,6 @@ This page contains auto-generated API reference documentation [1](#f1). -* [composer](composer/index.md) * [algokit_utils](algokit_utils/index.md) * [algokit_utils.accounts](algokit_utils/accounts/index.md) * [algokit_utils.accounts.account_manager](algokit_utils/accounts/account_manager/index.md) @@ -41,8 +40,5 @@ This page contains auto-generated API reference documentation [1](#f1)**[1]** Created with [sphinx-autoapi](https://github.com/readthedocs/sphinx-autoapi) diff --git a/docs/markdown/capabilities/account.md b/docs/markdown/capabilities/account.md index 914822d6..b9df44fa 100644 --- a/docs/markdown/capabilities/account.md +++ b/docs/markdown/capabilities/account.md @@ -53,7 +53,7 @@ algorand.account ## Default signer -If you want to have a default signer that is used to sign transactions without a registered signer (rather than throwing an exception) then you can [register a default signer](): +If you want to have a default signer that is used to sign transactions without a registered signer (rather than throwing an exception) then you can [`set_default_signer`](../autoapi/algokit_utils/accounts/account_manager/index.md#algokit_utils.accounts.account_manager.AccountManager.set_default_signer): ```python algorand.account.set_default_signer(my_default_signer) @@ -104,7 +104,7 @@ One of the unique features of Algorand is the ability to change the private key > [!WARNING] > Rekeying should be done with caution as a rekey transaction can result in permanent loss of control of an account. -You can issue a transaction to rekey an account by using the [`algorand.account.rekeyAccount(account, rekeyTo, options)`]() function: +You can issue a transaction to rekey an account by using the [`rekey_account`](../autoapi/algokit_utils/accounts/account_manager/index.md#algokit_utils.accounts.account_manager.AccountManager.rekey_account) function: - `account: string | TransactionSignerAccount` - The account address or signing account of the account that will be rekeyed - `rekeyTo: string | TransactionSignerAccount` - The account address or signing account of the account that will be used to authorise transactions for the rekeyed account going forward. If a signing account is provided that will now be tracked as the signer for `account` in the `AccountManager` instance. @@ -208,6 +208,8 @@ Some of this functionality is directly exposed from [`AccountManager`](), which localnet_dispenser = algorand.account.localnet_dispenser() # Get and register a dispenser by environment variable, or if not set then LocalNet dispenser via KMD dispenser = algorand.account.dispenser_from_environment() +# Get an account from KMD idempotently by name. In this case we'll get the default dispenser account +dispenser_via_kmd = algorand.account.from_kmd('unencrypted-default-wallet', lambda a: a.status != 'Offline' and a.amount > 1_000_000_000) # Get / create and register account from KMD idempotently by name -account1 = algorand.account.from_kmd("account1", AlgoAmount.from_algos(2)) +fresh_account_via_kmd = algorand.account.kmd.get_or_create_wallet_account('account1', AlgoAmount.from_algos(2)) ``` diff --git a/docs/markdown/capabilities/algorand-client.md b/docs/markdown/capabilities/algorand-client.md index 9404653e..0ac2a42c 100644 --- a/docs/markdown/capabilities/algorand-client.md +++ b/docs/markdown/capabilities/algorand-client.md @@ -2,7 +2,7 @@ `AlgorandClient` is a client class that brokers easy access to Algorand functionality. It’s the [default entrypoint](../index.md#id3) into AlgoKit Utils functionality. -The main entrypoint to the bulk of the functionality in AlgoKit Utils is the `AlgorandClient` class, most of the time you can get started by typing `AlgorandClient.` and choosing one of the static initialisation methods to create an [Algorand client](), e.g.: +The main entrypoint to the bulk of the functionality in AlgoKit Utils is the `AlgorandClient` class, most of the time you can get started by typing `AlgorandClient.` and choosing one of the static initialisation methods to create an [`algokit_utils.algorand.AlgorandClient`](../autoapi/algokit_utils/algorand/index.md#algokit_utils.algorand.AlgorandClient), e.g.: ```python # Point to the network configured through environment variables or @@ -29,6 +29,14 @@ algorand = AlgorandClient.from_config( ) ``` +> NOTE: AlgorandClient introducted in v3.0.0 implements a new functionality that caches suggested parameters for you automatically. This is to reduce the number of requests made to the network for suggested parameters, to control this behaviour you can use the following methods: +> +> - `algorand.set_suggested_params_cache_timeout(timeout)` - Set the timeout that is used to cache the suggested network parameters (by default 3 seconds) +> - `algorand.set_suggested_params_cache(suggested_params, until)` - Set the suggested network parameters to use (optionally until the given time) +> - `algorand.get_suggested_params()` - Get the current suggested network parameters object, either the cached value, or if the cache has expired a fresh value +> +> See [Transaction configuration](transaction.md#transaction-configuration) for more information. + ## Accessing SDK clients Once you have an `AlgorandClient` instance, you can access the SDK clients for the various Algorand APIs via the `algorand.client` property. @@ -58,7 +66,7 @@ The `AlgorandClient` has a number of manager class instances that help you quick ### Creating transactions -You can compose a transaction via `algorand.create_transaction.`, which gives you an instance of the [`AlgorandClientTransactionCreator`]() class. Intellisense will guide you on the different options. +You can compose a transaction via `algorand.create_transaction.`, which gives you an instance of the `algokit_utils.transactions.AlgorandClientTransactionCreator` class. Intellisense will guide you on the different options. The signature for the calls to send a single transaction usually look like: @@ -114,7 +122,7 @@ This signifies the fact that an ABI method call can actually result in multiple ### Sending a single transaction -You can compose a single transaction via `algorand.send...`, which gives you an instance of the [`AlgorandClientTransactionSender`]() class. Intellisense will guide you on the different options. +You can compose a single transaction via `algorand.send...`, which gives you an instance of the `algokit_utils.transactions.AlgorandClientTransactionSender` class. Intellisense will guide you on the different options. Further documentation is present in the related capabilities: @@ -128,8 +136,8 @@ The signature for the calls to send a single transaction usually look like: - To get intellisense on the params, use your IDE’s intellisense keyboard shortcut (e.g. ctrl+space). - `TxnParams` is a union type that can be any of the Algorand transaction types, exact dataclasses can be imported from `algokit_utils`. -- [`SendParams`]() a typed dictionary exposing setting to apply during send operation. -- [`SendSingleTransactionResult`]() is all of the information that is relevant when [sending a single transaction to the network](transaction.md#sending-a-transaction) +- `algokit_utils.transactions.SendParams` a typed dictionary exposing setting to apply during send operation. +- `algokit_utils.transactions.SendSingleTransactionResult` is all of the information that is relevant when [sending a single transaction to the network](transaction.md#transaction-results) Generally, the functions to immediately send a single transaction will emit log messages before and/or after sending the transaction. You can opt-out of this by sending `suppressLog: true`. @@ -137,7 +145,7 @@ Generally, the functions to immediately send a single transaction will emit log You can compose a group of transactions for execution by using the `new_group()` method on `AlgorandClient` and then use the various `.add_{Type}()` methods on [`TransactionComposer`](transaction-composer.md) to add a series of transactions. -```typescript +```python result = (algorand .new_group() .add_payment( @@ -164,20 +172,19 @@ To create a transaction you instantiate a relevant Transaction parameters datacl All transaction parameters share the following common base parameters: -- [`CommonTransactionParams`]() - - `sender: str` - The address of the account sending the transaction. - - `signer: algosdk.TransactionSigner | TransactionSignerAccount | None` - The function used to sign transaction(s); if not specified then an attempt will be made to find a registered signer for the given `sender` or use a default signer (if configured). - - `rekey_to: string | None` - Change the signing key of the sender to the given address. **Warning:** Please be careful with this parameter and be sure to read the [official rekey guidance](https://developer.algorand.org/docs/get-details/accounts/rekey/). - - `note: bytes | str | None` - Note to attach to the transaction. Max of 1000 bytes. - - `lease: bytes | str | None` - Prevent multiple transactions with the same lease being included within the validity window. A [lease](https://developer.algorand.org/articles/leased-transactions-securing-advanced-smart-contract-design/) enforces a mutually exclusive transaction (useful to prevent double-posting and other scenarios). - - Fee management - - `static_fee: AlgoAmount | None` - The static transaction fee. In most cases you want to use `extra_fee` unless setting the fee to 0 to be covered by another transaction. - - `extra_fee: AlgoAmount | None` - The fee to pay IN ADDITION to the suggested fee. Useful for covering inner transaction fees. - - `max_fee: AlgoAmount | None` - Throw an error if the fee for the transaction is more than this amount; prevents overspending on fees during high congestion periods. - - Round validity management - - `validity_window: int | None` - How many rounds the transaction should be valid for, if not specified then the registered default validity window will be used. - - `first_valid_round: int | None` - Set the first round this transaction is valid. If left undefined, the value from algod will be used. We recommend you only set this when you intentionally want this to be some time in the future. - - `last_valid_round: int | None` - The last round this transaction is valid. It is recommended to use `validity_window` instead. +- `sender: str` - The address of the account sending the transaction. +- `signer: algosdk.TransactionSigner | TransactionSignerAccount | None` - The function used to sign transaction(s); if not specified then an attempt will be made to find a registered signer for the given `sender` or use a default signer (if configured). +- `rekey_to: string | None` - Change the signing key of the sender to the given address. **Warning:** Please be careful with this parameter and be sure to read the [official rekey guidance](https://developer.algorand.org/docs/get-details/accounts/rekey/). +- `note: bytes | str | None` - Note to attach to the transaction. Max of 1000 bytes. +- `lease: bytes | str | None` - Prevent multiple transactions with the same lease being included within the validity window. A [lease](https://developer.algorand.org/articles/leased-transactions-securing-advanced-smart-contract-design/) enforces a mutually exclusive transaction (useful to prevent double-posting and other scenarios). +- Fee management + - `static_fee: AlgoAmount | None` - The static transaction fee. In most cases you want to use `extra_fee` unless setting the fee to 0 to be covered by another transaction. + - `extra_fee: AlgoAmount | None` - The fee to pay IN ADDITION to the suggested fee. Useful for covering inner transaction fees. + - `max_fee: AlgoAmount | None` - Throw an error if the fee for the transaction is more than this amount; prevents overspending on fees during high congestion periods. +- Round validity management + - `validity_window: int | None` - How many rounds the transaction should be valid for, if not specified then the registered default validity window will be used. + - `first_valid_round: int | None` - Set the first round this transaction is valid. If left undefined, the value from algod will be used. We recommend you only set this when you intentionally want this to be some time in the future. + - `last_valid_round: int | None` - The last round this transaction is valid. It is recommended to use `validity_window` instead. Then on top of that the base type gets extended for the specific type of transaction you are issuing. These are all defined as part of [`TransactionComposer`](transaction-composer.md) and we recommend reading these docs, especially when leveraging either `populate_app_call_resources` or `cover_app_call_inner_transaction_fees`. @@ -186,6 +193,6 @@ Then on top of that the base type gets extended for the specific type of transac AlgorandClient caches network provided transaction values for you automatically to reduce network traffic. It has a set of default configurations that control this behaviour, but you have the ability to override and change the configuration of this behaviour: - `algorand.set_default_validity_window(validity_window)` - Set the default validity window (number of rounds from the current known round that the transaction will be valid to be accepted for), having a smallish value for this is usually ideal to avoid transactions that are valid for a long future period and may be submitted even after you think it failed to submit if waiting for a particular number of rounds for the transaction to be successfully submitted. The validity window defaults to `10`, except localnet environments where it’s set to `1000`. -- `algorand.set_suggested_params(suggested_params, until?)` - Set the suggested network parameters to use (optionally until the given time) +- `algorand.set_suggested_params(suggested_params, until)` - Set the suggested network parameters to use (optionally until the given time) - `algorand.set_suggested_params_timeout(timeout)` - Set the timeout that is used to cache the suggested network parameters (by default 3 seconds) - `algorand.get_suggested_params()` - Get the current suggested network parameters object, either the cached value, or if the cache has expired a fresh value diff --git a/docs/markdown/capabilities/amount.md b/docs/markdown/capabilities/amount.md index bdf607ff..cf169c75 100644 --- a/docs/markdown/capabilities/amount.md +++ b/docs/markdown/capabilities/amount.md @@ -2,7 +2,7 @@ Algo amount handling is one of the core capabilities provided by AlgoKit Utils. It allows you to reliably and tersely specify amounts of microAlgo and Algo and safely convert between them. -Any AlgoKit Utils function that needs an Algo amount will take an `AlgoAmount` object, which ensures that there is never any confusion about what value is being passed around. Whenever an AlgoKit Utils function calls into an underlying algosdk function, or if you need to take an `AlgoAmount` and pass it into an underlying algosdk function (per the modularity principle) you can safely and explicitly convert to microAlgo or Algo. +Any AlgoKit Utils function that needs an Algo amount will take an `AlgoAmount` object, which ensures that there is never any confusion about what value is being passed around. Whenever an AlgoKit Utils function calls into an underlying algosdk function, or if you need to take an `AlgoAmount` and pass it into an underlying algosdk function (per the [modularity principle](../index.md#core-principles)) you can safely and explicitly convert to microAlgo or Algo. To see some usage examples check out the automated tests. Alternatively, you can see the reference documentation for `AlgoAmount`. diff --git a/docs/markdown/capabilities/app-deploy.md b/docs/markdown/capabilities/app-deploy.md index 3f8f60a8..f8d1f423 100644 --- a/docs/markdown/capabilities/app-deploy.md +++ b/docs/markdown/capabilities/app-deploy.md @@ -154,9 +154,9 @@ It will automatically [add metadata to the transaction note of the create or upd The first parameter `deployment` is an `AppDeployParams`, which is an object with: - `metadata: AppDeployMetadata` - determines the [deployment metadata]() of the deployment -- `create_params: AppCreateParams | CreateCallABI` - the parameters for an [app creation call](app.md#creation) (raw parameters or ABI method call) -- `update_params: AppUpdateParams | UpdateCallABI` - the parameters for an [app update call](app.md#updating) (raw parameters or ABI method call) without the `app_id`, `approval_program`, or `clear_state_program` as these are handled by the deploy logic -- `delete_params: AppDeleteParams | DeleteCallABI` - the parameters for an [app delete call](app.md#deleting) (raw parameters or ABI method call) without the `app_id` parameter +- `create_params: AppCreateParams | CreateCallABI` - the parameters for an [app creation call](app.md) (raw parameters or ABI method call) +- `update_params: AppUpdateParams | UpdateCallABI` - the parameters for an [app update call](app.md) (raw parameters or ABI method call) without the `app_id`, `approval_program`, or `clear_state_program` as these are handled by the deploy logic +- `delete_params: AppDeleteParams | DeleteCallABI` - the parameters for an [app delete call](app.md) (raw parameters or ABI method call) without the `app_id` parameter - `deploy_time_params: TealTemplateParams | None` - optional parameters for [TEAL template substitution]() - `TealTemplateParams` is a dict that replaces `TMPL_{key}` with `value` (strings/Uint8Arrays are properly encoded) - `on_schema_break: OnSchemaBreak | str | None` - determines `OnSchemaBreak` if schema requirements increase (values: ‘replace’, ‘fail’, ‘append’) @@ -204,11 +204,11 @@ The `deploy` call itself may do one of the following (which you can determine by - `OperationPerformed.REPLACE` - The smart contract app was deleted and created again (in an atomic transaction) - `OperationPerformed.NOTHING` - Nothing was done since it was detected the existing smart contract app deployment was up to date -As well as the `operation_performed` parameter and the [optional compilation result](), the return value will have the [`ApplicationMetaData`]() [fields]() present. +As well as the `operation_performed` parameter and the [optional compilation result](), the return value will have the [`ApplicationMetaData`](../autoapi/algokit_utils/applications/app_deployer/index.md#algokit_utils.applications.app_deployer.ApplicationMetaData) [fields]() present. Based on the value of `operation_performed`, there will be other data available in the return value: -- If `CREATE`, `UPDATE` or `REPLACE` then it will have the relevant [`SendAppTransactionResult`](app.md#calling-an-app) values: +- If `CREATE`, `UPDATE` or `REPLACE` then it will have the relevant [`SendAppTransactionResult`](../autoapi/algokit_utils/transactions/transaction_sender/index.md#algokit_utils.transactions.transaction_sender.SendAppTransactionResult) values: - `create_result` for create operations - `update_result` for update operations - If `REPLACE` then it will also have `delete_result` to capture the result of deleting the existing app diff --git a/docs/markdown/index.md b/docs/markdown/index.md index 6d745850..179ab0c4 100644 --- a/docs/markdown/index.md +++ b/docs/markdown/index.md @@ -99,11 +99,7 @@ If you prefer TypeScript there’s an equivalent [TypeScript utility library](ht * [Best Practices](v3-migration-guide.md#best-practices) * [Troubleshooting](v3-migration-guide.md#troubleshooting) * [API Reference](autoapi/index.md) - * [composer](autoapi/composer/index.md) * [algokit_utils](autoapi/algokit_utils/index.md) - * [client_manager](autoapi/client_manager/index.md) - * [algorand_client](autoapi/algorand_client/index.md) - * [account_manager](autoapi/account_manager/index.md) diff --git a/docs/source/capabilities/account.md b/docs/source/capabilities/account.md index aa6298ec..8a3b405a 100644 --- a/docs/source/capabilities/account.md +++ b/docs/source/capabilities/account.md @@ -53,7 +53,7 @@ algorand.account ## Default signer -If you want to have a default signer that is used to sign transactions without a registered signer (rather than throwing an exception) then you can [register a default signer](../code/classes/types_account_manager.AccountManager.md#setdefaultsigner): +If you want to have a default signer that is used to sign transactions without a registered signer (rather than throwing an exception) then you can {py:meth}`set_default_signer `: ```python algorand.account.set_default_signer(my_default_signer) @@ -104,7 +104,7 @@ One of the unique features of Algorand is the ability to change the private key > [!WARNING] > Rekeying should be done with caution as a rekey transaction can result in permanent loss of control of an account. -You can issue a transaction to rekey an account by using the [`algorand.account.rekeyAccount(account, rekeyTo, options)`](../code/classes/types_account_manager.AccountManager.md#rekeyaccount) function: +You can issue a transaction to rekey an account by using the {py:meth}`rekey_account ` function: - `account: string | TransactionSignerAccount` - The account address or signing account of the account that will be rekeyed - `rekeyTo: string | TransactionSignerAccount` - The account address or signing account of the account that will be used to authorise transactions for the rekeyed account going forward. If a signing account is provided that will now be tracked as the signer for `account` in the `AccountManager` instance. @@ -208,6 +208,8 @@ Some of this functionality is directly exposed from [`AccountManager`](#accountm localnet_dispenser = algorand.account.localnet_dispenser() # Get and register a dispenser by environment variable, or if not set then LocalNet dispenser via KMD dispenser = algorand.account.dispenser_from_environment() +# Get an account from KMD idempotently by name. In this case we'll get the default dispenser account +dispenser_via_kmd = algorand.account.from_kmd('unencrypted-default-wallet', lambda a: a.status != 'Offline' and a.amount > 1_000_000_000) # Get / create and register account from KMD idempotently by name -account1 = algorand.account.from_kmd("account1", AlgoAmount.from_algos(2)) +fresh_account_via_kmd = algorand.account.kmd.get_or_create_wallet_account('account1', AlgoAmount.from_algos(2)) ``` diff --git a/docs/source/capabilities/algorand-client.md b/docs/source/capabilities/algorand-client.md index 9ed7638c..adde5f4b 100644 --- a/docs/source/capabilities/algorand-client.md +++ b/docs/source/capabilities/algorand-client.md @@ -2,7 +2,7 @@ `AlgorandClient` is a client class that brokers easy access to Algorand functionality. It's the [default entrypoint](../index.md#usage) into AlgoKit Utils functionality. -The main entrypoint to the bulk of the functionality in AlgoKit Utils is the `AlgorandClient` class, most of the time you can get started by typing `AlgorandClient.` and choosing one of the static initialisation methods to create an [Algorand client](./capabilities/algorand-client.md), e.g.: +The main entrypoint to the bulk of the functionality in AlgoKit Utils is the `AlgorandClient` class, most of the time you can get started by typing `AlgorandClient.` and choosing one of the static initialisation methods to create an {py:class}`algokit_utils.algorand.AlgorandClient`, e.g.: ```python # Point to the network configured through environment variables or @@ -58,7 +58,7 @@ The `AlgorandClient` has a number of manager class instances that help you quick ### Creating transactions -You can compose a transaction via `algorand.create_transaction.`, which gives you an instance of the [`AlgorandClientTransactionCreator`](../autoapi/algokit_utils/applications/app_client.md#algokit_utils.applications.app_client.AlgorandClientTransactionCreator) class. Intellisense will guide you on the different options. +You can compose a transaction via `algorand.create_transaction.`, which gives you an instance of the {py:class}`algokit_utils.transactions.AlgorandClientTransactionCreator` class. Intellisense will guide you on the different options. The signature for the calls to send a single transaction usually look like: @@ -114,7 +114,7 @@ This signifies the fact that an ABI method call can actually result in multiple ### Sending a single transaction -You can compose a single transaction via `algorand.send...`, which gives you an instance of the [`AlgorandClientTransactionSender`](../autoapi/algokit_utils/applications/app_client.md#algokit_utils.applications.app_client.AlgorandClientTransactionSender) class. Intellisense will guide you on the different options. +You can compose a single transaction via `algorand.send...`, which gives you an instance of the {py:class}`algokit_utils.transactions.AlgorandClientTransactionSender` class. Intellisense will guide you on the different options. Further documentation is present in the related capabilities: @@ -128,8 +128,8 @@ The signature for the calls to send a single transaction usually look like: - To get intellisense on the params, use your IDE's intellisense keyboard shortcut (e.g. ctrl+space). - `TxnParams` is a union type that can be any of the Algorand transaction types, exact dataclasses can be imported from `algokit_utils`. -- [`SendParams`](../autoapi/algokit_utils/models/transaction/SendParams.md) a typed dictionary exposing setting to apply during send operation. -- [`SendSingleTransactionResult`](../autoapi/algokit_utils/models/transaction/SendSingleTransactionResult.md) is all of the information that is relevant when [sending a single transaction to the network](./transaction.md#sending-a-transaction) +- {py:class}`algokit_utils.transactions.SendParams` a typed dictionary exposing setting to apply during send operation. +- {py:class}`algokit_utils.transactions.SendSingleTransactionResult` is all of the information that is relevant when [sending a single transaction to the network](./transaction.md#transaction-results) Generally, the functions to immediately send a single transaction will emit log messages before and/or after sending the transaction. You can opt-out of this by sending `suppressLog: true`. @@ -137,7 +137,7 @@ Generally, the functions to immediately send a single transaction will emit log You can compose a group of transactions for execution by using the `new_group()` method on `AlgorandClient` and then use the various `.add_{Type}()` methods on [`TransactionComposer`](./transaction-composer.md) to add a series of transactions. -```typescript +```python result = (algorand .new_group() .add_payment( @@ -164,20 +164,19 @@ To create a transaction you instantiate a relevant Transaction parameters datacl All transaction parameters share the following common base parameters: -- [`CommonTransactionParams`](../autoapi/algokit_utils/models/transaction/CommonTransactionParams.md) - - `sender: str` - The address of the account sending the transaction. - - `signer: algosdk.TransactionSigner | TransactionSignerAccount | None` - The function used to sign transaction(s); if not specified then an attempt will be made to find a registered signer for the given `sender` or use a default signer (if configured). - - `rekey_to: string | None` - Change the signing key of the sender to the given address. **Warning:** Please be careful with this parameter and be sure to read the [official rekey guidance](https://developer.algorand.org/docs/get-details/accounts/rekey/). - - `note: bytes | str | None` - Note to attach to the transaction. Max of 1000 bytes. - - `lease: bytes | str | None` - Prevent multiple transactions with the same lease being included within the validity window. A [lease](https://developer.algorand.org/articles/leased-transactions-securing-advanced-smart-contract-design/) enforces a mutually exclusive transaction (useful to prevent double-posting and other scenarios). - - Fee management - - `static_fee: AlgoAmount | None` - The static transaction fee. In most cases you want to use `extra_fee` unless setting the fee to 0 to be covered by another transaction. - - `extra_fee: AlgoAmount | None` - The fee to pay IN ADDITION to the suggested fee. Useful for covering inner transaction fees. - - `max_fee: AlgoAmount | None` - Throw an error if the fee for the transaction is more than this amount; prevents overspending on fees during high congestion periods. - - Round validity management - - `validity_window: int | None` - How many rounds the transaction should be valid for, if not specified then the registered default validity window will be used. - - `first_valid_round: int | None` - Set the first round this transaction is valid. If left undefined, the value from algod will be used. We recommend you only set this when you intentionally want this to be some time in the future. - - `last_valid_round: int | None` - The last round this transaction is valid. It is recommended to use `validity_window` instead. +- `sender: str` - The address of the account sending the transaction. +- `signer: algosdk.TransactionSigner | TransactionSignerAccount | None` - The function used to sign transaction(s); if not specified then an attempt will be made to find a registered signer for the given `sender` or use a default signer (if configured). +- `rekey_to: string | None` - Change the signing key of the sender to the given address. **Warning:** Please be careful with this parameter and be sure to read the [official rekey guidance](https://developer.algorand.org/docs/get-details/accounts/rekey/). +- `note: bytes | str | None` - Note to attach to the transaction. Max of 1000 bytes. +- `lease: bytes | str | None` - Prevent multiple transactions with the same lease being included within the validity window. A [lease](https://developer.algorand.org/articles/leased-transactions-securing-advanced-smart-contract-design/) enforces a mutually exclusive transaction (useful to prevent double-posting and other scenarios). +- Fee management + - `static_fee: AlgoAmount | None` - The static transaction fee. In most cases you want to use `extra_fee` unless setting the fee to 0 to be covered by another transaction. + - `extra_fee: AlgoAmount | None` - The fee to pay IN ADDITION to the suggested fee. Useful for covering inner transaction fees. + - `max_fee: AlgoAmount | None` - Throw an error if the fee for the transaction is more than this amount; prevents overspending on fees during high congestion periods. +- Round validity management + - `validity_window: int | None` - How many rounds the transaction should be valid for, if not specified then the registered default validity window will be used. + - `first_valid_round: int | None` - Set the first round this transaction is valid. If left undefined, the value from algod will be used. We recommend you only set this when you intentionally want this to be some time in the future. + - `last_valid_round: int | None` - The last round this transaction is valid. It is recommended to use `validity_window` instead. Then on top of that the base type gets extended for the specific type of transaction you are issuing. These are all defined as part of [`TransactionComposer`](./transaction-composer.md) and we recommend reading these docs, especially when leveraging either `populate_app_call_resources` or `cover_app_call_inner_transaction_fees`. diff --git a/docs/source/capabilities/amount.md b/docs/source/capabilities/amount.md index 9c79ba58..9030f612 100644 --- a/docs/source/capabilities/amount.md +++ b/docs/source/capabilities/amount.md @@ -2,7 +2,7 @@ Algo amount handling is one of the core capabilities provided by AlgoKit Utils. It allows you to reliably and tersely specify amounts of microAlgo and Algo and safely convert between them. -Any AlgoKit Utils function that needs an Algo amount will take an `AlgoAmount` object, which ensures that there is never any confusion about what value is being passed around. Whenever an AlgoKit Utils function calls into an underlying algosdk function, or if you need to take an `AlgoAmount` and pass it into an underlying algosdk function (per the {ref}`modularity principle `) you can safely and explicitly convert to microAlgo or Algo. +Any AlgoKit Utils function that needs an Algo amount will take an `AlgoAmount` object, which ensures that there is never any confusion about what value is being passed around. Whenever an AlgoKit Utils function calls into an underlying algosdk function, or if you need to take an `AlgoAmount` and pass it into an underlying algosdk function (per the {ref}`modularity principle `) you can safely and explicitly convert to microAlgo or Algo. To see some usage examples check out the automated tests. Alternatively, you can see the reference documentation for `AlgoAmount`. diff --git a/docs/source/capabilities/app-deploy.md b/docs/source/capabilities/app-deploy.md index f29bda6d..3f85dd52 100644 --- a/docs/source/capabilities/app-deploy.md +++ b/docs/source/capabilities/app-deploy.md @@ -154,9 +154,9 @@ It will automatically [add metadata to the transaction note of the create or upd The first parameter `deployment` is an {py:obj}`AppDeployParams `, which is an object with: - `metadata: AppDeployMetadata` - determines the [deployment metadata](#deployment-metadata) of the deployment -- `create_params: AppCreateParams | CreateCallABI` - the parameters for an [app creation call](./app.md#creation) (raw parameters or ABI method call) -- `update_params: AppUpdateParams | UpdateCallABI` - the parameters for an [app update call](./app.md#updating) (raw parameters or ABI method call) without the `app_id`, `approval_program`, or `clear_state_program` as these are handled by the deploy logic -- `delete_params: AppDeleteParams | DeleteCallABI` - the parameters for an [app delete call](./app.md#deleting) (raw parameters or ABI method call) without the `app_id` parameter +- `create_params: AppCreateParams | CreateCallABI` - the parameters for an [app creation call](./app.md) (raw parameters or ABI method call) +- `update_params: AppUpdateParams | UpdateCallABI` - the parameters for an [app update call](./app.md) (raw parameters or ABI method call) without the `app_id`, `approval_program`, or `clear_state_program` as these are handled by the deploy logic +- `delete_params: AppDeleteParams | DeleteCallABI` - the parameters for an [app delete call](./app.md) (raw parameters or ABI method call) without the `app_id` parameter - `deploy_time_params: TealTemplateParams | None` - optional parameters for [TEAL template substitution](#compilation-and-template-substitution) - {py:obj}`TealTemplateParams ` is a dict that replaces `TMPL_{key}` with `value` (strings/Uint8Arrays are properly encoded) - `on_schema_break: OnSchemaBreak | str | None` - determines {py:obj}`OnSchemaBreak ` if schema requirements increase (values: 'replace', 'fail', 'append') @@ -171,7 +171,7 @@ The first parameter `deployment` is an {py:obj}`AppDeployParams ` [fields](#deployment-metadata) present. Based on the value of `operation_performed`, there will be other data available in the return value: -- If `CREATE`, `UPDATE` or `REPLACE` then it will have the relevant [`SendAppTransactionResult`](./app.md#calling-an-app) values: +- If `CREATE`, `UPDATE` or `REPLACE` then it will have the relevant {py:obj}`SendAppTransactionResult ` values: - `create_result` for create operations - `update_result` for update operations - If `REPLACE` then it will also have `delete_result` to capture the result of deleting the existing app diff --git a/docs/source/conf.py b/docs/source/conf.py index 72fa0770..f42d2546 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -30,8 +30,14 @@ autoapi_options = ['members', 'undoc-members', 'show-inheritance', - 'show-module-summary'] + 'show-module-summary', + ] + autoapi_ignore = ['*algokit_utils/beta/__init__.py', + '*algokit_utils/beta/account_manager.py', + '*algokit_utils/beta/algorand_client.py', + '*algokit_utils/beta/client_manager.py', + '*algokit_utils/beta/composer.py', '*algokit_utils/asset.py', '*algokit_utils/deploy.py', "*algokit_utils/network_clients.py", diff --git a/src/algokit_utils/_legacy_v2/_ensure_funded.py b/src/algokit_utils/_legacy_v2/_ensure_funded.py index 1add7522..e3417c84 100644 --- a/src/algokit_utils/_legacy_v2/_ensure_funded.py +++ b/src/algokit_utils/_legacy_v2/_ensure_funded.py @@ -10,12 +10,10 @@ from algokit_utils._legacy_v2.account import get_dispenser_account from algokit_utils._legacy_v2.models import Account from algokit_utils._legacy_v2.network_clients import is_testnet -from algokit_utils.clients.dispenser_api_client import ( - DispenserAssetName, - TestNetDispenserApiClient, -) +from algokit_utils.clients.dispenser_api_client import TestNetDispenserApiClient +@deprecated("Use `algorand.account.ensure_funded()` instead") @dataclass(kw_only=True) class EnsureBalanceParameters: """Parameters for ensuring an account has a minimum number of µALGOs""" @@ -86,9 +84,7 @@ def _calculate_fund_amount( def _fund_using_dispenser_api( dispenser_client: TestNetDispenserApiClient, address_to_fund: str, fund_amount_micro_algos: int ) -> EnsureFundedResponse | None: - response = dispenser_client.fund( - address=address_to_fund, amount=fund_amount_micro_algos, asset_id=DispenserAssetName.ALGO - ) + response = dispenser_client.fund(address=address_to_fund, amount=fund_amount_micro_algos) return EnsureFundedResponse(transaction_id=response.tx_id, amount=response.amount) diff --git a/src/algokit_utils/_legacy_v2/_transfer.py b/src/algokit_utils/_legacy_v2/_transfer.py index b5136051..ae8945ec 100644 --- a/src/algokit_utils/_legacy_v2/_transfer.py +++ b/src/algokit_utils/_legacy_v2/_transfer.py @@ -17,6 +17,7 @@ logger = logging.getLogger(__name__) +@deprecated("Send transactions via `algorand.{send|create_transaction}.{txn_type}()` instead") @dataclasses.dataclass(kw_only=True) class TransferParametersBase: """Parameters for transferring µALGOs between accounts. @@ -39,6 +40,7 @@ class TransferParametersBase: max_fee_micro_algos: int | None = None +@deprecated("Use `algorand.send.payment(...)` / `algorand.create_transaction.payment(...)` instead") @dataclasses.dataclass(kw_only=True) class TransferParameters(TransferParametersBase): """Parameters for transferring µALGOs between accounts""" @@ -46,6 +48,7 @@ class TransferParameters(TransferParametersBase): micro_algos: int +@deprecated("Use `algorand.send.asset_transfer(...)` / `algorand.create_transaction.asset_transfer(...)` instead") @dataclasses.dataclass(kw_only=True) class TransferAssetParameters(TransferParametersBase): """Parameters for transferring assets between accounts. @@ -79,7 +82,7 @@ def _check_fee(transaction: PaymentTxn | AssetTransferTxn, max_fee: int | None) ) -@deprecated("Use the `TransactionComposer` abstraction instead to construct appropriate transfer transactions") +@deprecated("Use `algorand.send.payment(...)` / `algorand.create_transaction.payment(...)` instead") def transfer(client: "AlgodClient", parameters: TransferParameters) -> PaymentTxn: """Transfer µALGOs between accounts""" @@ -100,7 +103,7 @@ def transfer(client: "AlgodClient", parameters: TransferParameters) -> PaymentTx return result -@deprecated("Use the `TransactionComposer` abstraction instead to construct appropriate transfer transactions") +@deprecated("Use `algorand.send.asset_transfer(...)` / `algorand.create_transaction.asset_transfer(...)` instead") def transfer_asset(client: "AlgodClient", parameters: TransferAssetParameters) -> AssetTransferTxn: """Transfer assets between accounts""" diff --git a/src/algokit_utils/_legacy_v2/account.py b/src/algokit_utils/_legacy_v2/account.py index 6ce3cab6..c6ef95b4 100644 --- a/src/algokit_utils/_legacy_v2/account.py +++ b/src/algokit_utils/_legacy_v2/account.py @@ -41,7 +41,9 @@ def get_account_from_mnemonic(mnemonic: str) -> Account: return Account(private_key=private_key, address=address) -@deprecated("Use `algorand.account.from_kmd()` instead. Example: " "`account = algorand.account.from_kmd(name)`") +@deprecated( + "Use `algorand.account.kmd.get_or_create_wallet_account(name, fund_with)` or `KMDAccountManager(clientManager).get_or_create_wallet_account(name, fund_with)` instead" +) def create_kmd_wallet_account(kmd_client: "KMDClient", name: str) -> Account: """Creates a wallet with specified name""" wallet_id = kmd_client.create_wallet(name, "")["id"] @@ -56,8 +58,7 @@ def create_kmd_wallet_account(kmd_client: "KMDClient", name: str) -> Account: @deprecated( - "Use `algorand.account.from_kmd()` instead. Example: " - "`account = algorand.account.from_kmd(name, fund_with=AlgoAmount.from_algo(1000))`" + "Use `algorand.account.kmd.get_or_create_wallet_account(name, fund_with)` or `KMDAccountManager(clientManager).get_or_create_wallet_account(name, fund_with)` instead" ) def get_or_create_kmd_wallet_account( client: "AlgodClient", name: str, fund_with_algos: float = 1000, kmd_client: "KMDClient | None" = None @@ -100,8 +101,7 @@ def _is_default_account(account: dict[str, Any]) -> bool: @deprecated( - "Use `algorand.account.from_kmd()` instead. Example: " - "`account = algorand.account.from_kmd('unencrypted-default-wallet', lambda a: a['status'] != 'Offline' and a['amount'] > 1_000_000_000)`" + "Use `algorand.account.localnet_dispenser()` or `algorand.account.from_kmd('unencrypted-default-wallet', lambda a: a['status'] != 'Offline' and a['amount'] > 1_000_000_000)`" ) def get_localnet_default_account(client: "AlgodClient") -> Account: """Returns the default Account in a LocalNet instance""" diff --git a/src/algokit_utils/_legacy_v2/deploy.py b/src/algokit_utils/_legacy_v2/deploy.py index 91d6eb14..b5a67cfb 100644 --- a/src/algokit_utils/_legacy_v2/deploy.py +++ b/src/algokit_utils/_legacy_v2/deploy.py @@ -175,7 +175,7 @@ def _parse_note(metadata_b64: str | None) -> AppDeployMetaData | None: return None -@deprecated("Use algorand.appDeployer.get_creator_apps_by_name() instead. ") +@deprecated("Use algorand.app_deployer.get_creator_apps_by_name() instead. ") def get_creator_apps(indexer: "IndexerClient", creator_account: Account | str) -> AppLookup: """Returns a mapping of Application names to {py:class}`AppMetaData` for all Applications created by specified creator that have a transaction note containing {py:class}`AppDeployMetaData` diff --git a/src/algokit_utils/_legacy_v2/network_clients.py b/src/algokit_utils/_legacy_v2/network_clients.py index 9a5bc9aa..47668dbe 100644 --- a/src/algokit_utils/_legacy_v2/network_clients.py +++ b/src/algokit_utils/_legacy_v2/network_clients.py @@ -41,14 +41,14 @@ class AlgoClientConfigs: kmd_config: AlgoClientConfig | None -@deprecated("Use AlgorandClient.client.algod") +@deprecated("Use `ClientManager.get_default_localnet_config(config)` instead") def get_default_localnet_config(config: Literal["algod", "indexer", "kmd"]) -> AlgoClientConfig: """Returns the client configuration to point to the default LocalNet""" port = {"algod": 4001, "indexer": 8980, "kmd": 4002}[config] return AlgoClientConfig(server=f"http://localhost:{port}", token="a" * 64) -@deprecated("Use AlgorandClient.testnet() or AlgorandClient.mainnet() instead") +@deprecated("Use `ClientManager.get_algonode_config(network, config)` instead") def get_algonode_config( network: Literal["testnet", "mainnet"], config: Literal["algod", "indexer"], token: str ) -> AlgoClientConfig: @@ -59,7 +59,9 @@ def get_algonode_config( ) -@deprecated("Use AlgorandClient.from_environment() instead.") +@deprecated( + "Use `ClientManager.get_algod_client(config)` or `ClientManager.get_algod_client_from_environment()` instead." +) def get_algod_client(config: AlgoClientConfig | None = None) -> AlgodClient: """Returns an {py:class}`algosdk.v2client.algod.AlgodClient` from `config` or environment @@ -69,7 +71,7 @@ def get_algod_client(config: AlgoClientConfig | None = None) -> AlgodClient: return AlgodClient(config.token, config.server, headers) -@deprecated("Use AlgorandClient.default_localnet().kmd instead") +@deprecated("Use `ClientManager.get_kmd_client(config)` or `ClientManager.get_kmd_client_from_environment()` instead.") def get_kmd_client(config: AlgoClientConfig | None = None) -> KMDClient: """Returns an {py:class}`algosdk.kmd.KMDClient` from `config` or environment @@ -78,7 +80,9 @@ def get_kmd_client(config: AlgoClientConfig | None = None) -> KMDClient: return KMDClient(config.token, config.server) -@deprecated("Use AlgorandClient.client.from_environment().indexer instead") +@deprecated( + "Use `ClientManager.get_indexer_client(config)` or `ClientManager.get_indexer_client_from_environment()` instead." +) def get_indexer_client(config: AlgoClientConfig | None = None) -> IndexerClient: """Returns an {py:class}`algosdk.v2client.indexer.IndexerClient` from `config` or environment. @@ -109,7 +113,7 @@ def is_testnet(client: AlgodClient) -> bool: return params.gen in ["testnet-v1.0", "testnet-v1", "testnet"] -@deprecated("Use AlgorandClient.default_localnet().kmd instead") +@deprecated("Use `ClientManager.get_kmd_client(config)` or `ClientManager.get_kmd_client_from_environment()` instead.") def get_kmd_client_from_algod_client(client: AlgodClient) -> KMDClient: """Returns an {py:class}`algosdk.kmd.KMDClient` from supplied `client` diff --git a/src/algokit_utils/accounts/account_manager.py b/src/algokit_utils/accounts/account_manager.py index bda98c42..9300fc18 100644 --- a/src/algokit_utils/accounts/account_manager.py +++ b/src/algokit_utils/accounts/account_manager.py @@ -12,7 +12,7 @@ from algokit_utils.accounts.kmd_account_manager import KmdAccountManager from algokit_utils.clients.client_manager import ClientManager -from algokit_utils.clients.dispenser_api_client import DispenserAssetName, TestNetDispenserApiClient +from algokit_utils.clients.dispenser_api_client import TestNetDispenserApiClient from algokit_utils.config import config from algokit_utils.models.account import ( DISPENSER_ACCOUNT_NAME, @@ -49,7 +49,9 @@ class _CommonEnsureFundedParams: """ transaction_id: str + """The transaction ID of the funded transaction""" amount_funded: AlgoAmount + """The amount of Algos funded""" @dataclass(frozen=True, kw_only=True) @@ -72,69 +74,68 @@ class AccountInformation: Information about an Algorand account's current status, balance and other properties. See `https://developer.algorand.org/docs/rest-apis/algod/#account` for detailed field descriptions. - - :ivar str address: The account's address - :ivar AlgoAmount amount: The account's current balance - :ivar AlgoAmount amount_without_pending_rewards: The account's balance without the pending rewards - :ivar AlgoAmount min_balance: The account's minimum required balance - :ivar AlgoAmount pending_rewards: The amount of pending rewards - :ivar AlgoAmount rewards: The amount of rewards earned - :ivar int round: The round for which this information is relevant - :ivar str status: The account's status (e.g., 'Offline', 'Online') - :ivar int|None total_apps_opted_in: Number of applications this account has opted into - :ivar int|None total_assets_opted_in: Number of assets this account has opted into - :ivar int|None total_box_bytes: Total number of box bytes used by this account - :ivar int|None total_boxes: Total number of boxes used by this account - :ivar int|None total_created_apps: Number of applications created by this account - :ivar int|None total_created_assets: Number of assets created by this account - :ivar list[dict]|None apps_local_state: Local state of applications this account has opted into - :ivar int|None apps_total_extra_pages: Number of extra pages allocated to applications - :ivar dict|None apps_total_schema: Total schema for all applications - :ivar list[dict]|None assets: Assets held by this account - :ivar str|None auth_addr: If rekeyed, the authorized address - :ivar int|None closed_at_round: Round when this account was closed - :ivar list[dict]|None created_apps: Applications created by this account - :ivar list[dict]|None created_assets: Assets created by this account - :ivar int|None created_at_round: Round when this account was created - :ivar bool|None deleted: Whether this account is deleted - :ivar bool|None incentive_eligible: Whether this account is eligible for incentives - :ivar int|None last_heartbeat: Last heartbeat round for this account - :ivar int|None last_proposed: Last round this account proposed a block - :ivar dict|None participation: Participation information for this account - :ivar int|None reward_base: Base reward for this account - :ivar str|None sig_type: Signature type for this account """ address: str + """The account's address""" amount: AlgoAmount + """The account's current balance""" amount_without_pending_rewards: AlgoAmount + """The account's balance without the pending rewards""" min_balance: AlgoAmount + """The account's minimum required balance""" pending_rewards: AlgoAmount + """The amount of pending rewards""" rewards: AlgoAmount + """The amount of rewards earned""" round: int + """The round for which this information is relevant""" status: str + """The account's status (e.g., 'Offline', 'Online')""" total_apps_opted_in: int | None = None + """Number of applications this account has opted into""" total_assets_opted_in: int | None = None + """Number of assets this account has opted into""" total_box_bytes: int | None = None + """Total number of box bytes used by this account""" total_boxes: int | None = None + """Total number of boxes used by this account""" total_created_apps: int | None = None + """Number of applications created by this account""" total_created_assets: int | None = None + """Number of assets created by this account""" apps_local_state: list[dict] | None = None + """Local state of applications this account has opted into""" apps_total_extra_pages: int | None = None + """Number of extra pages allocated to applications""" apps_total_schema: dict | None = None + """Total schema for all applications""" assets: list[dict] | None = None + """Assets held by this account""" auth_addr: str | None = None + """If rekeyed, the authorized address""" closed_at_round: int | None = None + """Round when this account was closed""" created_apps: list[dict] | None = None + """Applications created by this account""" created_assets: list[dict] | None = None + """Assets created by this account""" created_at_round: int | None = None + """Round when this account was created""" deleted: bool | None = None + """Whether this account is deleted""" incentive_eligible: bool | None = None + """Whether this account is eligible for incentives""" last_heartbeat: int | None = None + """Last heartbeat round for this account""" last_proposed: int | None = None + """Last round this account proposed a block""" participation: dict | None = None + """Participation information for this account""" reward_base: int | None = None + """Base reward for this account""" sig_type: str | None = None + """Signature type for this account""" class AccountManager: @@ -158,6 +159,13 @@ def __init__(self, client_manager: ClientManager): @property def kmd(self) -> KmdAccountManager: + """ + KMD account manager that allows you to easily get and create accounts using KMD. + + :return KmdAccountManager: The 'KmdAccountManager' instance + :example: + >>> kmd_manager = account_manager.kmd + """ return self._kmd_account_manager def set_default_signer(self, signer: TransactionSigner | TransactionSignerAccountProtocol) -> Self: @@ -172,10 +180,7 @@ def set_default_signer(self, signer: TransactionSigner | TransactionSignerAccoun :example: >>> signer_account = account_manager.random() - >>> account_manager.set_default_signer(signer_account.signer) - >>> # When signing a transaction, if there is no signer registered for the sender - >>> # then the default signer will be used - >>> signer = account_manager.get_signer("{SENDERADDRESS}") + >>> account_manager.set_default_signer(signer_account) """ self._default_signer = signer if isinstance(signer, TransactionSigner) else signer.signer return self @@ -201,6 +206,9 @@ def set_signers(self, *, another_account_manager: "AccountManager", overwrite_ex :param another_account_manager: The `AccountManager` to merge into this one :param overwrite_existing: Whether to overwrite existing signers in this manager :returns: The `AccountManager` instance for method chaining + + :example: + >>> accountManager2.set_signers(accountManager1) """ self._accounts = ( {**self._accounts, **another_account_manager._accounts} # noqa: SLF001 @@ -417,7 +425,7 @@ def logicsig(self, program: bytes, args: list[bytes] | None = None) -> LogicSigA :returns: A logic signature account wrapper :example: - >>> account = account.logic_sig(program, [new Uint8Array(3, ...)]) + >>> account = account.logicsig(program, [new Uint8Array(3, ...)]) """ return self._register_logicsig(program, args) @@ -540,22 +548,22 @@ def rekey_account( # noqa: PLR0913 :example: >>> # Basic example (with string addresses): - >>> algorand.account.rekey_account({account: "ACCOUNTADDRESS", rekey_to: "NEWADDRESS"}) + >>> algorand.account.rekey_account("ACCOUNTADDRESS", "NEWADDRESS") >>> # Basic example (with signer accounts): - >>> algorand.account.rekey_account({account: account1, rekey_to: newSignerAccount}) + >>> algorand.account.rekey_account(account1, newSignerAccount) >>> # Advanced example: - >>> algorand.account.rekey_account({ - ... account: "ACCOUNTADDRESS", - ... rekey_to: "NEWADDRESS", - ... lease: 'lease', - ... note: 'note', - ... first_valid_round: 1000, - ... validity_window: 10, - ... extra_fee: AlgoAmount.from_micro_algo(1000), - ... static_fee: AlgoAmount.from_micro_algo(1000), - ... max_fee: AlgoAmount.from_micro_algo(3000), - ... suppress_log: True, - ... }) + >>> algorand.account.rekey_account( + ... account="ACCOUNTADDRESS", + ... rekey_to="NEWADDRESS", + ... lease='lease', + ... note='note', + ... first_valid_round=1000, + ... validity_window=10, + ... extra_fee=AlgoAmount.from_micro_algo(1000), + ... static_fee=AlgoAmount.from_micro_algo(1000), + ... max_fee=AlgoAmount.from_micro_algo(3000), + ... suppress_log=True, + ... ) """ sender_address = self._get_address(account) rekey_address = self._get_address(rekey_to) @@ -640,13 +648,13 @@ def ensure_funded( # noqa: PLR0913 :example: >>> # Basic example: - >>> algorand.account.ensure_funded("ACCOUNTADDRESS", "DISPENSERADDRESS", algokit.algo(1)) + >>> algorand.account.ensure_funded("ACCOUNTADDRESS", "DISPENSERADDRESS", AlgoAmount.from_algo(1)) >>> # With configuration: >>> algorand.account.ensure_funded( ... "ACCOUNTADDRESS", ... "DISPENSERADDRESS", - ... algokit.algo(1), - ... min_funding_increment=algokit.algo(2), + ... AlgoAmount.from_algo(1), + ... min_funding_increment=AlgoAmount.from_algo(2), ... fee=AlgoAmount.from_micro_algo(1000), ... suppress_log=True ... ) @@ -746,12 +754,12 @@ def ensure_funded_from_environment( # noqa: PLR0913 :example: >>> # Basic example: - >>> algorand.account.ensure_funded_from_environment("ACCOUNTADDRESS", algokit.algo(1)) + >>> algorand.account.ensure_funded_from_environment("ACCOUNTADDRESS", AlgoAmount.from_algo(1)) >>> # With configuration: >>> algorand.account.ensure_funded_from_environment( ... "ACCOUNTADDRESS", - ... algokit.algo(1), - ... min_funding_increment=algokit.algo(2), + ... AlgoAmount.from_algo(1), + ... min_funding_increment=AlgoAmount.from_algo(2), ... fee=AlgoAmount.from_micro_algo(1000), ... suppress_log=True ... ) @@ -825,17 +833,17 @@ def ensure_funded_from_testnet_dispenser_api( :example: >>> # Basic example: - >>> algorand.account.ensure_funded_from_testnet_dispenser_api( + >>> account_manager.ensure_funded_from_testnet_dispenser_api( ... "ACCOUNTADDRESS", ... algorand.client.get_testnet_dispenser_from_environment(), - ... algokit.algo(1) + ... AlgoAmount.from_algo(1) ... ) >>> # With configuration: - >>> algorand.account.ensure_funded_from_testnet_dispenser_api( + >>> account_manager.ensure_funded_from_testnet_dispenser_api( ... "ACCOUNTADDRESS", ... algorand.client.get_testnet_dispenser_from_environment(), - ... algokit.algo(1), - ... min_funding_increment=algokit.algo(2) + ... AlgoAmount.from_algo(1), + ... min_funding_increment=AlgoAmount.from_algo(2) ... ) """ account_to_fund = self._get_address(account_to_fund) @@ -848,11 +856,7 @@ def ensure_funded_from_testnet_dispenser_api( if not amount_funded: return None - result = dispenser_client.fund( - address=account_to_fund, - amount=amount_funded.micro_algo, - asset_id=DispenserAssetName.ALGO, - ) + result = dispenser_client.fund(address=account_to_fund, amount=amount_funded.micro_algo) return EnsureFundedFromTestnetDispenserApiResult( transaction_id=result.tx_id, diff --git a/src/algokit_utils/algorand.py b/src/algokit_utils/algorand.py index 83a8c56d..ba6b1652 100644 --- a/src/algokit_utils/algorand.py +++ b/src/algokit_utils/algorand.py @@ -58,6 +58,8 @@ def set_default_validity_window(self, validity_window: int) -> typing_extensions :param validity_window: The number of rounds between the first and last valid rounds :return: The `AlgorandClient` so method calls can be chained + :example: + >>> algorand = AlgorandClient.mainnet().set_default_validity_window(1000); """ self._default_validity_window = validity_window return self @@ -70,6 +72,9 @@ def set_default_signer( :param signer: The signer to use, either a `TransactionSigner` or a `TransactionSignerAccountProtocol` :return: The `AlgorandClient` so method calls can be chained + :example: + >>> signer = SigningAccount(private_key=..., address=...) + >>> algorand = AlgorandClient.mainnet().set_default_signer(signer) """ self._account_manager.set_default_signer(signer) return self @@ -81,21 +86,31 @@ def set_signer(self, sender: str, signer: TransactionSigner) -> typing_extension :param sender: The sender address to use this signer for :param signer: The signer to sign transactions with for the given sender :return: The `AlgorandClient` so method calls can be chained + :example: + >>> signer = SigningAccount(private_key=..., address=...) + >>> algorand = AlgorandClient.mainnet().set_signer(signer.addr, signer.signer) """ self._account_manager.set_signer(sender, signer) return self - def set_signer_account(self, signer: TransactionSignerAccountProtocol) -> typing_extensions.Self: + def set_signer_from_account(self, signer: TransactionSignerAccountProtocol) -> typing_extensions.Self: """ Sets the default signer to use if no other signer is specified. :param signer: The signer to use, either a `TransactionSigner` or a `TransactionSignerAccountProtocol` :return: The `AlgorandClient` so method calls can be chained + :example: + >>> accountManager = AlgorandClient.mainnet() + >>> accountManager.set_signer_from_account(TransactionSignerAccount(address=..., signer=...)) + >>> accountManager.set_signer_from_account(algosdk.LogicSigAccount(program, args)) + >>> accountManager.set_signer_from_account(SigningAccount(private_key=..., address=...)) + >>> accountManager.set_signer_from_account(MultisigAccount(metadata, signing_accounts)) + >>> accountManager.set_signer_from_account(account) """ self._account_manager.set_default_signer(signer) return self - def set_suggested_params( + def set_suggested_params_cache( self, suggested_params: SuggestedParams, until: float | None = None ) -> typing_extensions.Self: """ @@ -104,23 +119,32 @@ def set_suggested_params( :param suggested_params: The suggested params to use :param until: A timestamp until which to cache, or if not specified then the timeout is used :return: The `AlgorandClient` so method calls can be chained + :example: + >>> algorand = AlgorandClient.mainnet().set_suggested_params_cache(suggested_params, time.time() + 3.6e6) """ self._cached_suggested_params = suggested_params self._cached_suggested_params_expiry = until or time.time() + self._cached_suggested_params_timeout return self - def set_suggested_params_timeout(self, timeout: int) -> typing_extensions.Self: + def set_suggested_params_cache_timeout(self, timeout: int) -> typing_extensions.Self: """ Sets the timeout for caching suggested params. :param timeout: The timeout in milliseconds :return: The `AlgorandClient` so method calls can be chained + :example: + >>> algorand = AlgorandClient.mainnet().set_suggested_params_cache_timeout(10_000) """ self._cached_suggested_params_timeout = timeout return self def get_suggested_params(self) -> SuggestedParams: - """Get suggested params for a transaction (either cached or from algod if the cache is stale or empty)""" + """ + Get suggested params for a transaction (either cached or from algod if the cache is stale or empty) + + :example: + >>> algorand = AlgorandClient.mainnet().get_suggested_params() + """ if self._cached_suggested_params and ( self._cached_suggested_params_expiry is None or self._cached_suggested_params_expiry > time.time() ): @@ -132,7 +156,14 @@ def get_suggested_params(self) -> SuggestedParams: return copy.deepcopy(self._cached_suggested_params) def new_group(self) -> TransactionComposer: - """Start a new `TransactionComposer` transaction group""" + """ + Start a new `TransactionComposer` transaction group + + :example: + >>> composer = AlgorandClient.mainnet().new_group() + >>> result = await composer.add_transaction(payment).send() + """ + return TransactionComposer( algod=self.client.algod, get_signer=lambda addr: self.account.get_signer(addr), @@ -142,36 +173,81 @@ def new_group(self) -> TransactionComposer: @property def client(self) -> ClientManager: - """Get clients, including algosdk clients and app clients.""" + """ + Get clients, including algosdk clients and app clients. + + :example: + >>> clientManager = AlgorandClient.mainnet().client + """ return self._client_manager @property def account(self) -> AccountManager: - """Get or create accounts that can sign transactions.""" + """Get or create accounts that can sign transactions. + + :example: + >>> accountManager = AlgorandClient.mainnet().account + """ return self._account_manager @property def asset(self) -> AssetManager: - """Get or create assets.""" + """ + Get or create assets. + + :example: + >>> assetManager = AlgorandClient.mainnet().asset + """ return self._asset_manager @property def app(self) -> AppManager: + """ + Get or create applications. + + :example: + >>> appManager = AlgorandClient.mainnet().app + """ return self._app_manager @property def app_deployer(self) -> AppDeployer: - """Get or create applications.""" + """ + Get or create applications. + + :example: + >>> appDeployer = AlgorandClient.mainnet().app_deployer + """ return self._app_deployer @property def send(self) -> AlgorandClientTransactionSender: - """Methods for sending a transaction and waiting for confirmation""" + """ + Methods for sending a transaction and waiting for confirmation + + :example: + >>> result = await AlgorandClient.mainnet().send.payment( + >>> PaymentParams( + >>> sender="SENDERADDRESS", + >>> receiver="RECEIVERADDRESS", + >>> amount=AlgoAmount(algo-1) + >>> )) + """ return self._transaction_sender @property def create_transaction(self) -> AlgorandClientTransactionCreator: - """Methods for building transactions""" + """ + Methods for building transactions + + :example: + >>> transaction = AlgorandClient.mainnet().create_transaction.payment( + >>> PaymentParams( + >>> sender="SENDERADDRESS", + >>> receiver="RECEIVERADDRESS", + >>> amount=AlgoAmount(algo=1) + >>> )) + """ return self._transaction_creator @staticmethod @@ -180,6 +256,9 @@ def default_localnet() -> "AlgorandClient": Returns an `AlgorandClient` pointing at default LocalNet ports and API token. :return: The `AlgorandClient` + + :example: + >>> algorand = AlgorandClient.default_localnet() """ return AlgorandClient( AlgoClientConfigs( @@ -195,6 +274,9 @@ def testnet() -> "AlgorandClient": Returns an `AlgorandClient` pointing at TestNet using AlgoNode. :return: The `AlgorandClient` + + :example: + >>> algorand = AlgorandClient.testnet() """ return AlgorandClient( AlgoClientConfigs( @@ -210,6 +292,9 @@ def mainnet() -> "AlgorandClient": Returns an `AlgorandClient` pointing at MainNet using AlgoNode. :return: The `AlgorandClient` + + :example: + >>> algorand = AlgorandClient.mainnet() """ return AlgorandClient( AlgoClientConfigs( @@ -230,6 +315,9 @@ def from_clients( :param indexer: The indexer client to use :param kmd: The kmd client to use :return: The `AlgorandClient` + + :example: + >>> algorand = AlgorandClient.from_clients(algod, indexer, kmd) """ return AlgorandClient(AlgoSdkClients(algod=algod, indexer=indexer, kmd=kmd)) @@ -243,6 +331,9 @@ def from_environment() -> "AlgorandClient": Expects to be called from a Python environment. :return: The `AlgorandClient` + + :example: + >>> algorand = AlgorandClient.from_environment() """ return AlgorandClient(ClientManager.get_config_from_environment_or_localnet()) @@ -259,6 +350,9 @@ def from_config( :param indexer_config: The config to use for the indexer client :param kmd_config: The config to use for the kmd client :return: The `AlgorandClient` + + :example: + >>> algorand = AlgorandClient.from_config(algod_config, indexer_config, kmd_config) """ return AlgorandClient( AlgoClientConfigs(algod_config=algod_config, indexer_config=indexer_config, kmd_config=kmd_config) diff --git a/src/algokit_utils/application_specification.py b/src/algokit_utils/application_specification.py index d85952d9..f6d51c48 100644 --- a/src/algokit_utils/application_specification.py +++ b/src/algokit_utils/application_specification.py @@ -7,7 +7,7 @@ Use `from algokit_utils.applications.app_spec.arc32 import ...` to access Arc32 app spec instead. By default, the ARC52Contract is a recommended app spec to use, serving as a replacement for legacy 'ApplicationSpecification' class. - To convert legacy app specs to ARC52, use `arc32_to_arc52` function from algokit_utils.applications.utils. + To convert legacy app specs to ARC52, use `Arc56Contract.from_arc32`. """, DeprecationWarning, stacklevel=2, diff --git a/src/algokit_utils/applications/abi.py b/src/algokit_utils/applications/abi.py index f617ef57..2be639ba 100644 --- a/src/algokit_utils/applications/abi.py +++ b/src/algokit_utils/applications/abi.py @@ -45,20 +45,18 @@ class ABIReturn: """Represents the return value from an ABI method call. Wraps the raw return value and decoded value along with any decode errors. - - :ivar result: The ABIResult object containing the method call results - :ivar raw_value: The raw return value from the method call - :ivar value: The decoded return value from the method call - :ivar method: The ABI method definition - :ivar decode_error: The exception that occurred during decoding, if any - :ivar tx_info: The transaction info for the method call from raw algosdk `ABIResult` """ raw_value: bytes | None = None + """The raw return value from the method call""" value: ABIValue | None = None + """The decoded return value from the method call""" method: AlgorandABIMethod | None = None + """The ABI method definition""" decode_error: Exception | None = None + """The exception that occurred during decoding, if any""" tx_info: dict[str, Any] | None = None + """The transaction info for the method call from raw algosdk `ABIResult`""" def __init__(self, result: ABIResult) -> None: self.decode_error = result.decode_error @@ -269,11 +267,9 @@ def get_abi_struct_from_abi_tuple( @dataclass(kw_only=True, frozen=True) class BoxABIValue: - """Represents an ABI value stored in a box. - - :ivar name: The name of the box - :ivar value: The ABI value stored in the box - """ + """Represents an ABI value stored in a box.""" name: BoxName + """The name of the box""" value: ABIValue + """The ABI value stored in the box""" diff --git a/src/algokit_utils/applications/app_client.py b/src/algokit_utils/applications/app_client.py index 3213ab76..782e42e9 100644 --- a/src/algokit_utils/applications/app_client.py +++ b/src/algokit_utils/applications/app_client.py @@ -177,17 +177,16 @@ class AppClientCompilationResult: """Result of compiling an application's TEAL code. Contains the compiled approval and clear state programs along with optional compilation artifacts. - - :ivar approval_program: The compiled approval program bytes - :ivar clear_state_program: The compiled clear state program bytes - :ivar compiled_approval: Optional compilation artifacts for approval program - :ivar compiled_clear: Optional compilation artifacts for clear state program """ approval_program: bytes + """The compiled approval program bytes""" clear_state_program: bytes + """The compiled clear state program bytes""" compiled_approval: CompiledTeal | None = None + """Optional compilation artifacts for approval program""" compiled_clear: CompiledTeal | None = None + """Optional compilation artifacts for clear state program""" class AppClientCompilationParams(TypedDict, total=False): @@ -209,52 +208,50 @@ class AppClientCompilationParams(TypedDict, total=False): @dataclass(kw_only=True, frozen=True) class CommonAppCallParams: - """Common configuration for app call transaction parameters - - :ivar account_references: List of account addresses to reference - :ivar app_references: List of app IDs to reference - :ivar asset_references: List of asset IDs to reference - :ivar box_references: List of box references to include - :ivar extra_fee: Additional fee to add to transaction - :ivar lease: Transaction lease value - :ivar max_fee: Maximum fee allowed for transaction - :ivar note: Arbitrary note for the transaction - :ivar rekey_to: Address to rekey account to - :ivar sender: Sender address override - :ivar signer: Custom transaction signer - :ivar static_fee: Fixed fee for transaction - :ivar validity_window: Number of rounds valid - :ivar first_valid_round: First valid round number - :ivar last_valid_round: Last valid round number""" + """Common configuration for app call transaction parameters""" account_references: list[str] | None = None + """List of account addresses to reference""" app_references: list[int] | None = None + """List of app IDs to reference""" asset_references: list[int] | None = None + """List of asset IDs to reference""" box_references: list[BoxReference | BoxIdentifier] | None = None + """List of box references to include""" extra_fee: AlgoAmount | None = None + """Additional fee to add to transaction""" lease: bytes | None = None + """Transaction lease value""" max_fee: AlgoAmount | None = None + """Maximum fee allowed for transaction""" note: bytes | None = None + """Custom note for the transaction""" rekey_to: str | None = None + """Address to rekey account to""" sender: str | None = None + """Sender address override""" signer: TransactionSigner | None = None + """Custom transaction signer""" static_fee: AlgoAmount | None = None + """Fixed fee for transaction""" validity_window: int | None = None + """Number of rounds valid""" first_valid_round: int | None = None + """First valid round number""" last_valid_round: int | None = None + """Last valid round number""" on_complete: OnComplete | None = None + """Optional on complete action""" @dataclass(frozen=True) class AppClientCreateSchema: - """Schema for application creation. - - :ivar extra_program_pages: Optional number of extra program pages - :ivar schema: Optional application creation schema - """ + """Schema for application creation.""" extra_program_pages: int | None = None + """Optional number of extra program pages""" schema: AppCreateSchema | None = None + """Optional application creation schema""" @dataclass(kw_only=True, frozen=True) @@ -262,28 +259,25 @@ class CommonAppCallCreateParams(AppClientCreateSchema, CommonAppCallParams): """Common configuration for app create call transaction parameters.""" on_complete: CreateOnComplete | None = None + """Optional on complete action""" @dataclass(kw_only=True, frozen=True) class FundAppAccountParams(CommonAppCallParams): - """Parameters for funding an application's account. - - :ivar amount: Amount to fund - :ivar close_remainder_to: Optional address to close remainder to - """ + """Parameters for funding an application's account.""" amount: AlgoAmount + """Amount to fund""" close_remainder_to: str | None = None + """Optional address to close remainder to""" @dataclass(kw_only=True, frozen=True) class AppClientBareCallParams(CommonAppCallParams): - """Parameters for bare application calls. - - :ivar args: Optional arguments - """ + """Parameters for bare application calls.""" args: list[bytes] | None = None + """Optional arguments""" @dataclass(frozen=True) @@ -291,19 +285,17 @@ class AppClientBareCallCreateParams(CommonAppCallCreateParams): """Parameters for creating application with bare call.""" on_complete: CreateOnComplete | None = None + """Optional on complete action""" @dataclass(kw_only=True, frozen=True) class BaseAppClientMethodCallParams(Generic[ArgsT, MethodT], CommonAppCallParams): - """Base parameters for application method calls. - - :ivar method: Method to call - :ivar args: Optional arguments to pass to method - :ivar on_complete: Optional on complete action - """ + """Base parameters for application method calls.""" method: MethodT + """Method to call""" args: ArgsT | None = None + """Arguments to pass to the application method call""" @dataclass(kw_only=True, frozen=True) @@ -321,6 +313,7 @@ class AppClientMethodCallCreateParams(AppClientCreateSchema, AppClientMethodCall """Parameters for creating application with method call""" on_complete: CreateOnComplete | None = None + """Optional on complete action""" class _AppClientStateMethods: @@ -1261,13 +1254,21 @@ class AppClientParams: """Full parameters for creating an app client""" app_spec: Arc56Contract | Arc32Contract | str + """The application specification""" algorand: AlgorandClient + """The Algorand client""" app_id: int + """The application ID""" app_name: str | None = None + """The application name""" default_sender: str | None = None + """The default sender address""" default_signer: TransactionSigner | None = None + """The default transaction signer""" approval_source_map: SourceMap | None = None + """The approval source map""" clear_source_map: SourceMap | None = None + """The clear source map""" class AppClient: @@ -1277,6 +1278,26 @@ class AppClient: methods for calling application methods, managing state, and handling transactions. :param params: Parameters for creating the app client + + :example: + >>> params = AppClientParams( + ... app_spec=Arc56Contract.from_json(app_spec_json), + ... algorand=algorand, + ... app_id=1234567890, + ... app_name="My App", + ... default_sender="SENDERADDRESS", + ... default_signer=TransactionSigner( + ... account="SIGNERACCOUNT", + ... private_key="SIGNERPRIVATEKEY", + ... ), + ... approval_source_map=SourceMap( + ... source="APPROVALSOURCE", + ... ), + ... clear_source_map=SourceMap( + ... source="CLEARSOURCE", + ... ), + ... ) + >>> client = AppClient(params) """ def __init__(self, params: AppClientParams) -> None: @@ -1347,6 +1368,19 @@ def params(self) -> _MethodParamsBuilder: """Get the method parameters builder. :return: The method parameters builder for this application + + :example: + >>> # Create a transaction in the future using Algorand Client + >>> my_method_call = app_client.params.call(AppClientMethodCallParams( + method='my_method', + args=[123, 'hello'])) + >>> # ... + >>> await algorand.send.AppMethodCall(my_method_call) + >>> # Define a nested transaction as an ABI argument + >>> my_method_call = app_client.params.call(AppClientMethodCallParams( + method='my_method', + args=[123, 'hello'])) + >>> app_client.send.call(AppClientMethodCallParams(method='my_method2', args=[my_method_call])) """ return self._params_accessor @@ -1370,9 +1404,13 @@ def create_transaction(self) -> _TransactionCreator: def normalise_app_spec(app_spec: Arc56Contract | Arc32Contract | str) -> Arc56Contract: """Normalize an application specification to ARC-56 format. - :param app_spec: The application specification to normalize + :param app_spec: The application specification to normalize. Can be raw arc32 or arc56 json, + or an Arc32Contract or Arc56Contract instance :return: The normalized ARC-56 contract specification :raises ValueError: If the app spec format is invalid + + :example: + >>> spec = AppClient.normalise_app_spec(app_spec_json) """ if isinstance(app_spec, str): spec_dict = json.loads(app_spec) @@ -1411,6 +1449,24 @@ def from_network( :param clear_source_map: Optional clear program source map :return: A new AppClient instance :raises Exception: If no app ID is found for the network + + :example: + >>> client = AppClient.from_network( + ... app_spec=Arc56Contract.from_json(app_spec_json), + ... algorand=algorand, + ... app_name="My App", + ... default_sender="SENDERADDRESS", + ... default_signer=TransactionSigner( + ... account="SIGNERACCOUNT", + ... private_key="SIGNERPRIVATEKEY", + ... ), + ... approval_source_map=SourceMap( + ... source="APPROVALSOURCE", + ... ), + ... clear_source_map=SourceMap( + ... source="CLEARSOURCE", + ... ), + ... ) """ network = algorand.client.network() app_spec = AppClient.normalise_app_spec(app_spec) @@ -1471,6 +1527,14 @@ def from_creator_and_name( :param app_lookup_cache: Optional app lookup cache :return: A new AppClient instance :raises ValueError: If the app is not found for the creator and name + + :example: + >>> client = AppClient.from_creator_and_name( + ... creator_address="CREATORADDRESS", + ... app_name="APPNAME", + ... app_spec=Arc56Contract.from_json(app_spec_json), + ... algorand=algorand, + ... ) """ app_spec_ = AppClient.normalise_app_spec(app_spec) app_lookup = app_lookup_cache or algorand.app_deployer.get_creator_apps_by_name( @@ -1693,7 +1757,11 @@ def clone( :param default_signer: Optional new default signer :param approval_source_map: Optional new approval source map :param clear_source_map: Optional new clear source map - :return: A new AppClient instance with the specified parameters + :return: A new AppClient instance + + :example: + >>> client = AppClient(params) + >>> cloned_client = client.clone(app_name="Cloned App", default_sender="NEW_SENDER") """ return AppClient( AppClientParams( @@ -1770,6 +1838,8 @@ def get_global_state(self) -> dict[str, AppState]: """Get the application's global state. :return: The application's global state + :example: + >>> global_state = client.get_global_state() """ return self._state_accessor.get_global_state() @@ -1777,6 +1847,9 @@ def get_box_names(self) -> list[BoxName]: """Get all box names for the application. :return: List of box names + + :example: + >>> box_names = client.get_box_names() """ return self._algorand.app.get_box_names(self._app_id) @@ -1785,6 +1858,9 @@ def get_box_value(self, name: BoxIdentifier) -> bytes: :param name: The box identifier :return: The box value as bytes + + :example: + >>> box_value = client.get_box_value(box_name) """ return self._algorand.app.get_box_value(self._app_id, name) @@ -1794,6 +1870,9 @@ def get_box_value_from_abi_type(self, name: BoxIdentifier, abi_type: ABIType) -> :param name: The box identifier :param abi_type: The ABI type to decode as :return: The decoded box value + + :example: + >>> box_value = client.get_box_value_from_abi_type(box_name, abi_type) """ return self._algorand.app.get_box_value_from_abi_type(self._app_id, name, abi_type) @@ -1802,6 +1881,9 @@ def get_box_values(self, filter_func: Callable[[BoxName], bool] | None = None) - :param filter_func: Optional function to filter box names :return: List of box values + + :example: + >>> box_values = client.get_box_values() """ names = [n for n in self.get_box_names() if not filter_func or filter_func(n)] values = self._algorand.app.get_box_values(self.app_id, [n.name_raw for n in names]) @@ -1815,6 +1897,9 @@ def get_box_values_from_abi_type( :param abi_type: The ABI type to decode as :param filter_func: Optional function to filter box names :return: List of decoded box values + + :example: + >>> box_values = client.get_box_values_from_abi_type(abi_type) """ names = self.get_box_names() if filter_func: @@ -1834,6 +1919,9 @@ def fund_app_account( :param params: The funding parameters :param send_params: Send parameters, defaults to None :return: The transaction result + + :example: + >>> result = client.fund_app_account(params) """ return self.send.fund_app_account(params, send_params) diff --git a/src/algokit_utils/applications/app_deployer.py b/src/algokit_utils/applications/app_deployer.py index d7ed4470..95fda719 100644 --- a/src/algokit_utils/applications/app_deployer.py +++ b/src/algokit_utils/applications/app_deployer.py @@ -123,30 +123,56 @@ class AppDeployParams: """Parameters for deploying an app""" metadata: AppDeploymentMetaData + """The deployment metadata""" deploy_time_params: TealTemplateParams | None = None + """Optional template parameters to use during compilation""" on_schema_break: (Literal["replace", "fail", "append"] | OnSchemaBreak) | None = None + """Optional on schema break action""" on_update: (Literal["update", "replace", "fail", "append"] | OnUpdate) | None = None + """Optional on update action""" create_params: AppCreateParams | AppCreateMethodCallParams + """The creation parameters""" update_params: AppUpdateParams | AppUpdateMethodCallParams + """The update parameters""" delete_params: AppDeleteParams | AppDeleteMethodCallParams + """The deletion parameters""" existing_deployments: ApplicationLookup | None = None + """Optional existing deployments""" ignore_cache: bool = False + """Whether to ignore the cache""" max_fee: int | None = None + """Optional maximum fee""" send_params: SendParams | None = None + """Optional send parameters""" # Union type for all possible deploy results @dataclass(frozen=True) class AppDeployResult: + """The result of a deployment""" + app: ApplicationMetaData + """The application metadata""" operation_performed: OperationPerformed + """The operation performed""" create_result: SendAppCreateTransactionResult[ABIReturn] | None = None + """The create result""" update_result: SendAppUpdateTransactionResult[ABIReturn] | None = None + """The update result""" delete_result: SendAppTransactionResult[ABIReturn] | None = None + """The delete result""" class AppDeployer: - """Manages deployment and deployment metadata of applications""" + """Manages deployment and deployment metadata of applications + + :param app_manager: The app manager to use + :param transaction_sender: The transaction sender to use + :param indexer: The indexer to use + + :example: + >>> deployer = AppDeployer(app_manager, transaction_sender, indexer) + """ def __init__( self, @@ -160,6 +186,56 @@ def __init__( self._app_lookups: dict[str, ApplicationLookup] = {} def deploy(self, deployment: AppDeployParams) -> AppDeployResult: + """Idempotently deploy (create if not exists, update if changed) an app against the given name for the given + creator account, including deploy-time TEAL template placeholder substitutions (if specified). + + To understand the architecture decisions behind this functionality please see + https://github.com/algorandfoundation/algokit-cli/blob/main/docs/architecture-decisions/2023-01-12_smart-contract-deployment.md + + **Note:** When using the return from this function be sure to check `operation_performed` to get access to + return properties like `transaction`, `confirmation` and `delete_result`. + + **Note:** if there is a breaking state schema change to an existing app (and `on_schema_break` is set to + `'replace'`) the existing app will be deleted and re-created. + + **Note:** if there is an update (different TEAL code) to an existing app (and `on_update` is set to `'replace'`) + the existing app will be deleted and re-created. + + :param deployment: The arguments to control the app deployment + :returns: The result of the deployment + :raises ValueError: If the app spec format is invalid + + :example: + >>> deployer.deploy(AppDeployParams( + ... create_params=AppCreateParams( + ... sender='SENDER_ADDRESS', + ... approval_program='APPROVAL PROGRAM', + ... clear_state_program='CLEAR PROGRAM', + ... schema={ + ... 'global_byte_slices': 0, + ... 'global_ints': 0, + ... 'local_byte_slices': 0, + ... 'local_ints': 0 + ... } + ... ), + ... update_params=AppUpdateParams( + ... sender='SENDER_ADDRESS' + ... ), + ... delete_params=AppDeleteParams( + ... sender='SENDER_ADDRESS' + ... ), + ... metadata=AppDeploymentMetaData( + ... name='my_app', + ... version='2.0', + ... updatable=False, + ... deletable=False + ... ), + ... on_schema_break=OnSchemaBreak.AppendApp, + ... on_update=OnUpdate.AppendApp + ... ) + ... ) + """ + # Create new instances with updated notes send_params = deployment.send_params or SendParams() suppress_log = send_params.get("suppress_log") or False @@ -569,7 +645,22 @@ def _update_app_lookup(self, sender: str, app_metadata: ApplicationMetaData) -> lookup.apps[app_metadata.name] = app_metadata def get_creator_apps_by_name(self, *, creator_address: str, ignore_cache: bool = False) -> ApplicationLookup: - """Get apps created by an account""" + """Returns a lookup of name => app metadata (id, address, ...metadata) for all apps created by the given account + that have an [ARC-2](https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0002.md) `AppDeployNote` as + the transaction note of the app creation transaction. + + This function caches the result for the given creator account so that subsequent calls won't require an indexer + lookup. + + If the `AppManager` instance wasn't created with an indexer client, this function will throw an error. + + :param creator_address: The address of the account that is the creator of the apps you want to search for + :param ignore_cache: Whether or not to ignore the cache and force a lookup, default: use the cache + :returns: A name-based lookup of the app metadata + :raises ValueError: If the app spec format is invalid + :example: + >>> result = await deployer.get_creator_apps_by_name(creator) + """ if not ignore_cache and creator_address in self._app_lookups: return self._app_lookups[creator_address] diff --git a/src/algokit_utils/applications/app_factory.py b/src/algokit_utils/applications/app_factory.py index 78857ab8..577ba312 100644 --- a/src/algokit_utils/applications/app_factory.py +++ b/src/algokit_utils/applications/app_factory.py @@ -131,10 +131,15 @@ class AppFactoryDeployResult: """Result from deploying an application via AppFactory""" app: ApplicationMetaData + """The application metadata""" operation_performed: OperationPerformed + """The operation performed""" create_result: SendAppCreateFactoryTransactionResult | None = None + """The create result""" update_result: SendAppUpdateFactoryTransactionResult | None = None + """The update result""" delete_result: SendAppFactoryTransactionResult | None = None + """The delete result""" @classmethod def from_deploy_result( @@ -144,6 +149,16 @@ def from_deploy_result( app_spec: Arc56Contract, app_compilation_data: AppClientCompilationResult | None = None, ) -> Self: + """ + Construct an AppFactoryDeployResult from a deployment result. + + :param response: The deployment response. + :param deploy_params: The deployment parameters. + :param app_spec: The application specification. + :param app_compilation_data: Optional app compilation data. + :return: An instance of AppFactoryDeployResult. + """ + def to_factory_result( response_data: SendAppTransactionResult[ABIReturn] | SendAppCreateTransactionResult @@ -192,6 +207,11 @@ def to_factory_result( class _BareParamsBuilder: + """The bare params builder. + + :param factory: The AppFactory instance. + """ + def __init__(self, factory: "AppFactory") -> None: self._factory = factory self._algorand = factory._algorand @@ -199,6 +219,13 @@ def __init__(self, factory: "AppFactory") -> None: def create( self, params: AppFactoryCreateParams | None = None, compilation_params: AppClientCompilationParams | None = None ) -> AppCreateParams: + """ + Create AppCreateParams using the provided parameters and compilation settings. + + :param params: Optional AppFactoryCreateParams instance. + :param compilation_params: Optional AppClientCompilationParams instance. + :return: An instance of AppCreateParams. + """ base_params = params or AppFactoryCreateParams() compiled = self._factory.compile(compilation_params) @@ -225,6 +252,12 @@ def create( ) def deploy_update(self, params: AppClientBareCallParams | None = None) -> AppUpdateParams: + """ + Create AppUpdateParams for an update operation. + + :param params: Optional AppClientBareCallParams instance. + :return: An instance of AppUpdateParams. + """ return AppUpdateParams( **{ **{ @@ -244,6 +277,12 @@ def deploy_update(self, params: AppClientBareCallParams | None = None) -> AppUpd ) def deploy_delete(self, params: AppClientBareCallParams | None = None) -> AppDeleteParams: + """ + Create AppDeleteParams for a delete operation. + + :param params: Optional AppClientBareCallParams instance. + :return: An instance of AppDeleteParams. + """ return AppDeleteParams( **{ **{ @@ -262,17 +301,34 @@ def deploy_delete(self, params: AppClientBareCallParams | None = None) -> AppDel class _MethodParamsBuilder: + """The method params builder. + + :param factory: The AppFactory instance. + """ + def __init__(self, factory: "AppFactory") -> None: self._factory = factory self._bare = _BareParamsBuilder(factory) @property def bare(self) -> _BareParamsBuilder: + """ + Get the bare parameters builder. + + :return: The _BareParamsBuilder instance. + """ return self._bare def create( self, params: AppFactoryCreateMethodCallParams, compilation_params: AppClientCompilationParams | None = None ) -> AppCreateMethodCallParams: + """ + Create AppCreateMethodCallParams using the provided parameters and compilation settings. + + :param params: AppFactoryCreateMethodCallParams instance. + :param compilation_params: Optional AppClientCompilationParams instance. + :return: An instance of AppCreateMethodCallParams. + """ compiled = self._factory.compile(compilation_params) return AppCreateMethodCallParams( @@ -303,6 +359,12 @@ def create( ) def deploy_update(self, params: AppClientMethodCallParams) -> AppUpdateMethodCallParams: + """ + Create AppUpdateMethodCallParams for an update operation. + + :param params: AppClientMethodCallParams instance. + :return: An instance of AppUpdateMethodCallParams. + """ return AppUpdateMethodCallParams( **{ **{ @@ -324,6 +386,12 @@ def deploy_update(self, params: AppClientMethodCallParams) -> AppUpdateMethodCal ) def deploy_delete(self, params: AppClientMethodCallParams) -> AppDeleteMethodCallParams: + """ + Create AppDeleteMethodCallParams for a delete operation. + + :param params: AppClientMethodCallParams instance. + :return: An instance of AppDeleteMethodCallParams. + """ return AppDeleteMethodCallParams( **{ **{ @@ -344,27 +412,61 @@ def deploy_delete(self, params: AppClientMethodCallParams) -> AppDeleteMethodCal class _AppFactoryBareCreateTransactionAccessor: + """Initialize the bare create transaction accessor. + + :param factory: The AppFactory instance. + """ + def __init__(self, factory: "AppFactory") -> None: self._factory = factory def create(self, params: AppFactoryCreateParams | None = None) -> Transaction: + """ + Create a transaction for app creation. + + :param params: Optional AppFactoryCreateParams instance. + :return: A Transaction instance. + """ return self._factory._algorand.create_transaction.app_create(self._factory.params.bare.create(params)) class _TransactionCreator: + """ + The transaction creator. + + :param factory: The AppFactory instance. + """ + def __init__(self, factory: "AppFactory") -> None: self._factory = factory self._bare = _AppFactoryBareCreateTransactionAccessor(factory) @property def bare(self) -> _AppFactoryBareCreateTransactionAccessor: + """ + Get the bare create transaction accessor. + + :return: The _AppFactoryBareCreateTransactionAccessor instance. + """ return self._bare def create(self, params: AppFactoryCreateMethodCallParams) -> BuiltTransactions: + """ + Create built transactions for an app method call. + + :param params: AppFactoryCreateMethodCallParams instance. + :return: A BuiltTransactions instance. + """ return self._factory._algorand.create_transaction.app_create_method_call(self._factory.params.create(params)) class _AppFactoryBareSendAccessor: + """ + The bare send accessor. + + :param factory: The AppFactory instance. + """ + def __init__(self, factory: "AppFactory") -> None: self._factory = factory self._algorand = factory._algorand @@ -375,6 +477,14 @@ def create( send_params: SendParams | None = None, compilation_params: AppClientCompilationParams | None = None, ) -> tuple[AppClient, SendAppCreateTransactionResult]: + """ + Send an app creation transaction and return the app client along with the transaction result. + + :param params: Optional AppFactoryCreateParams instance. + :param send_params: Optional SendParams instance. + :param compilation_params: Optional AppClientCompilationParams instance. + :return: A tuple containing the AppClient and SendAppCreateTransactionResult. + """ compilation_params = compilation_params or AppClientCompilationParams() compilation_params["updatable"] = ( compilation_params.get("updatable") @@ -420,6 +530,12 @@ def create( class _TransactionSender: + """ + The transaction sender. + + :param factory: The AppFactory instance. + """ + def __init__(self, factory: "AppFactory") -> None: self._factory = factory self._algorand = factory._algorand @@ -427,6 +543,11 @@ def __init__(self, factory: "AppFactory") -> None: @property def bare(self) -> _AppFactoryBareSendAccessor: + """ + Get the bare send accessor. + + :return: The _AppFactoryBareSendAccessor instance. + """ return self._bare def create( @@ -435,6 +556,14 @@ def create( send_params: SendParams | None = None, compilation_params: AppClientCompilationParams | None = None, ) -> tuple[AppClient, AppFactoryCreateMethodCallResult[Arc56ReturnValueType]]: + """ + Send an app creation method call and return the app client along with the method call result. + + :param params: AppFactoryCreateMethodCallParams instance. + :param send_params: Optional SendParams instance. + :param compilation_params: Optional AppClientCompilationParams instance. + :return: A tuple containing the AppClient and AppFactoryCreateMethodCallResult. + """ compilation_params = compilation_params or AppClientCompilationParams() compilation_params["updatable"] = ( compilation_params.get("updatable") @@ -485,6 +614,20 @@ def create( class AppFactory: + """ARC-56/ARC-32 app factory that, for a given app spec, allows you to create + and deploy one or more app instances and to create one or more app clients + to interact with those (or other) app instances. + + :param params: The parameters for the factory + + :example: + >>> factory = AppFactory(AppFactoryParams( + >>> algorand=AlgorandClient.mainnet(), + >>> app_spec=app_spec, + >>> ) + >>> ) + """ + def __init__(self, params: AppFactoryParams) -> None: self._app_spec = AppClient.normalise_app_spec(params.app_spec) self._app_name = params.app_name or self._app_spec.name @@ -505,26 +648,67 @@ def __init__(self, params: AppFactoryParams) -> None: @property def app_name(self) -> str: + """The name of the app""" return self._app_name @property def app_spec(self) -> Arc56Contract: + """The app spec""" return self._app_spec @property def algorand(self) -> AlgorandClient: + """The algorand client""" return self._algorand @property def params(self) -> _MethodParamsBuilder: + """Get parameters to create transactions (create and deploy related calls) for the current app. + + A good mental model for this is that these parameters represent a deferred transaction creation. + + :example: Create a transaction in the future using Algorand Client + >>> create_app_params = app_factory.params.create( + ... AppFactoryCreateMethodCallParams( + ... method='create_method', + ... args=[123, 'hello'] + ... ) + ... ) + >>> # ... + >>> algorand.send.app_create_method_call(create_app_params) + + :example: Define a nested transaction as an ABI argument + >>> create_app_params = appFactory.params.create( + ... AppFactoryCreateMethodCallParams( + ... method='create_method', + ... args=[123, 'hello'] + ... ) + ... ) + >>> app_client.send.call( + ... AppClientMethodCallParams( + ... method='my_method', + ... args=[create_app_params] + ... ) + ... ) + """ return self._params_accessor @property def send(self) -> _TransactionSender: + """ + Get the transaction sender. + + :return: The _TransactionSender instance. + """ return self._send_accessor @property def create_transaction(self) -> _TransactionCreator: + """ + Get the transaction creator. + + :return: The _TransactionCreator instance. + """ return self._create_transaction_accessor def deploy( @@ -541,7 +725,58 @@ def deploy( send_params: SendParams | None = None, compilation_params: AppClientCompilationParams | None = None, ) -> tuple[AppClient, AppFactoryDeployResult]: - """Deploy the application with the specified parameters.""" + """Idempotently deploy (create if not exists, update if changed) an app against the given name for the given + creator account, including deploy-time TEAL template placeholder substitutions (if specified). + + **Note:** When using the return from this function be sure to check `operationPerformed` to get access to + various return properties like `transaction`, `confirmation` and `deleteResult`. + + **Note:** if there is a breaking state schema change to an existing app (and `onSchemaBreak` is set to + `'replace'`) the existing app will be deleted and re-created. + + **Note:** if there is an update (different TEAL code) to an existing app (and `onUpdate` is set to + `'replace'`) the existing app will be deleted and re-created. + + :param on_update: The action to take if there is an update to the app + :param on_schema_break: The action to take if there is a breaking state schema change to the app + :param create_params: The arguments to create the app + :param update_params: The arguments to update the app + :param delete_params: The arguments to delete the app + :param existing_deployments: The existing deployments to use + :param ignore_cache: Whether to ignore the cache + :param app_name: The name of the app + :param send_params: The parameters for the send call + :param compilation_params: The parameters for the compilation + :returns: The app client and the result of the deployment + + :example: + >>> app_client, result = factory.deploy({ + >>> create_params=AppClientMethodCallCreateParams( + >>> sender='SENDER_ADDRESS', + >>> approval_program='APPROVAL PROGRAM', + >>> clear_state_program='CLEAR PROGRAM', + >>> schema={ + >>> "global_byte_slices": 0, + >>> "global_ints": 0, + >>> "local_byte_slices": 0, + >>> "local_ints": 0 + >>> } + >>> ), + >>> update_params=AppClientMethodCallParams( + >>> sender='SENDER_ADDRESS' + >>> ), + >>> delete_params=AppClientMethodCallParams( + >>> sender='SENDER_ADDRESS' + >>> ), + >>> compilation_params=AppClientCompilationParams( + >>> updatable=False, + >>> deletable=False + >>> ), + >>> app_name='my_app', + >>> on_schema_break=OnSchemaBreak.AppendApp, + >>> on_update=OnUpdate.AppendApp + >>> }) + """ # Resolve control parameters with factory defaults send_params = send_params or SendParams() compilation_params = compilation_params or AppClientCompilationParams() @@ -650,6 +885,19 @@ def get_app_client_by_id( approval_source_map: SourceMap | None = None, clear_source_map: SourceMap | None = None, ) -> AppClient: + """Returns a new `AppClient` client for an app instance of the given ID. + + :param app_id: The id of the app + :param app_name: The name of the app + :param default_sender: The default sender address + :param default_signer: The default signer + :param approval_source_map: The approval source map + :param clear_source_map: The clear source map + :return AppClient: The app client + + :example: + >>> app_client = factory.get_app_client_by_id(app_id=123) + """ return AppClient( AppClientParams( app_id=app_id, @@ -674,6 +922,25 @@ def get_app_client_by_creator_and_name( approval_source_map: SourceMap | None = None, clear_source_map: SourceMap | None = None, ) -> AppClient: + """Returns a new `AppClient` client, resolving the app by creator address and name + using AlgoKit app deployment semantics (i.e. looking for the app creation transaction note). + + :param creator_address: The creator address + :param app_name: The name of the app + :param default_sender: The default sender address + :param default_signer: The default signer + :param ignore_cache: Whether to ignore the cache and force a lookup + :param app_lookup_cache: Optional cache of existing app deployments to use instead of querying the indexer + :param approval_source_map: Optional source map for the approval program + :param clear_source_map: Optional source map for the clear state program + :return: An AppClient instance configured for the resolved application + + :example: + >>> app_client = factory.get_app_client_by_creator_and_name( + ... creator_address='SENDER_ADDRESS', + ... app_name='my_app' + ... ) + """ return AppClient.from_creator_and_name( creator_address=creator_address, app_name=app_name or self._app_name, @@ -699,10 +966,23 @@ def export_source_maps(self) -> AppSourceMaps: ) def import_source_maps(self, source_maps: AppSourceMaps) -> None: + """ + Import the provided source maps into the factory. + + :param source_maps: An AppSourceMaps instance containing the approval and clear source maps. + """ self._approval_source_map = source_maps.approval_source_map self._clear_source_map = source_maps.clear_source_map def compile(self, compilation_params: AppClientCompilationParams | None = None) -> AppClientCompilationResult: + """Compile the app's TEAL code. + + :param compilation_params: The compilation parameters + :return AppClientCompilationResult: The compilation result + + :example: + >>> compilation_result = factory.compile() + """ compilation = compilation_params or AppClientCompilationParams() result = AppClient.compile( app_spec=self._app_spec, @@ -718,6 +998,13 @@ def compile(self, compilation_params: AppClientCompilationParams | None = None) return result def _expose_logic_error(self, e: Exception, is_clear_state_program: bool = False) -> Exception: # noqa: FBT002 FBT001 + """ + Convert a low-level exception into a descriptive logic error. + + :param e: The original exception. + :param is_clear_state_program: Flag indicating if the error is related to the clear state program. + :return: The transformed exception. + """ return AppClient._expose_logic_error_static( e=e, app_spec=self._app_spec, @@ -730,6 +1017,12 @@ def _expose_logic_error(self, e: Exception, is_clear_state_program: bool = False ) def _get_deploy_time_control(self, control: str) -> bool | None: + """ + Determine the deploy time control flag for the specified control type. + + :param control: The control type ('updatable' or 'deletable'). + :return: A boolean flag or None if not determinable. + """ approval = self._app_spec.source.get_decoded_approval() if self._app_spec.source else None template_name = UPDATABLE_TEMPLATE_NAME if control == "updatable" else DELETABLE_TEMPLATE_NAME @@ -742,6 +1035,13 @@ def _get_deploy_time_control(self, control: str) -> bool | None: ) def _get_sender(self, sender: str | None) -> str: + """ + Retrieve the sender address. + + :param sender: The specified sender address. + :return: The sender address. + :raises Exception: If no sender is provided and no default sender is set. + """ if not sender and not self._default_sender: raise Exception( f"No sender provided and no default sender present in app client for call to app {self._app_name}" @@ -749,6 +1049,13 @@ def _get_sender(self, sender: str | None) -> str: return str(sender or self._default_sender) def _get_signer(self, sender: str | None, signer: TransactionSigner | None) -> TransactionSigner | None: + """ + Retrieve the transaction signer. + + :param sender: The sender address. + :param signer: The provided signer. + :return: The transaction signer if available. + """ return signer or (self._default_signer if not sender or sender == self._default_sender else None) def _handle_call_errors(self, call: Callable[[], T]) -> T: @@ -764,6 +1071,13 @@ def _parse_method_call_return( ], method: Method, ) -> AppFactoryCreateMethodCallResult[Arc56ReturnValueType]: + """ + Parse the method call return value and convert the ABI return. + + :param result: A callable that returns the transaction result. + :param method: The ABI method associated with the call. + :return: An AppFactoryCreateMethodCallResult with the parsed ABI return. + """ result_value = result() return AppFactoryCreateMethodCallResult[Arc56ReturnValueType]( **{ diff --git a/src/algokit_utils/applications/app_manager.py b/src/algokit_utils/applications/app_manager.py index 54269963..f06bd46f 100644 --- a/src/algokit_utils/applications/app_manager.py +++ b/src/algokit_utils/applications/app_manager.py @@ -119,6 +119,9 @@ class AppManager: and interacting with application boxes. :param algod_client: The Algorand client instance to use for interacting with the network + + :example: + >>> app_manager = AppManager(algod_client) """ def __init__(self, algod_client: algod.AlgodClient): @@ -158,6 +161,14 @@ def compile_teal_template( :param template_params: Parameters to substitute in the template :param deployment_metadata: Deployment control parameters :return: The compiled TEAL code and associated metadata + + :example: + >>> app_manager = AppManager(algod_client) + >>> teal_template_code = + ... # This is a TEAL template + ... # It can contain template variables like {TMPL_UPDATABLE} and {TMPL_DELETABLE} + ... + >>> compiled_teal = app_manager.compile_teal_template(teal_template_code) """ teal_code = AppManager.strip_teal_comments(teal_template_code) @@ -173,8 +184,13 @@ def get_compilation_result(self, teal_code: str) -> CompiledTeal | None: :param teal_code: The TEAL source code :return: The cached compilation result if available, None otherwise - """ + :example: + >>> app_manager = AppManager(algod_client) + >>> teal_code = "RETURN 1" + >>> compiled_teal = app_manager.compile_teal(teal_code) + >>> compilation_result = app_manager.get_compilation_result(teal_code) + """ return self._compilation_results.get(teal_code) def get_by_id(self, app_id: int) -> AppInformation: @@ -182,6 +198,11 @@ def get_by_id(self, app_id: int) -> AppInformation: :param app_id: The application ID :return: Information about the application + + :example: + >>> app_manager = AppManager(algod_client) + >>> app_id = 1234567890 + >>> app_info = app_manager.get_by_id(app_id) """ app = self._algod.application_info(app_id) @@ -207,6 +228,11 @@ def get_global_state(self, app_id: int) -> dict[str, AppState]: :param app_id: The application ID :return: The application's global state + + :example: + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> global_state = app_manager.get_global_state(app_id) """ return self.get_by_id(app_id).global_state @@ -218,6 +244,12 @@ def get_local_state(self, app_id: int, address: str) -> dict[str, AppState]: :param address: The account address :return: The account's local state for the application :raises ValueError: If local state is not found + + :example: + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> address = "SENDER_ADDRESS" + >>> local_state = app_manager.get_local_state(app_id, address) """ app_info = self._algod.account_application_info(address, app_id) @@ -231,6 +263,11 @@ def get_box_names(self, app_id: int) -> list[BoxName]: :param app_id: The application ID :return: List of box names + + :example: + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> box_names = app_manager.get_box_names(app_id) """ box_result = self._algod.application_boxes(app_id) @@ -250,6 +287,12 @@ def get_box_value(self, app_id: int, box_name: BoxIdentifier) -> bytes: :param app_id: The application ID :param box_name: The box identifier :return: The box value as bytes + + :example: + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> box_name = "BOX_NAME" + >>> box_value = app_manager.get_box_value(app_id, box_name) """ name = AppManager.get_box_reference(box_name)[1] @@ -263,6 +306,12 @@ def get_box_values(self, app_id: int, box_names: list[BoxIdentifier]) -> list[by :param app_id: The application ID :param box_names: List of box identifiers :return: List of box values as bytes + + :example: + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> box_names = ["BOX_NAME_1", "BOX_NAME_2"] + >>> box_values = app_manager.get_box_values(app_id, box_names) """ return [self.get_box_value(app_id, box_name) for box_name in box_names] @@ -275,6 +324,13 @@ def get_box_value_from_abi_type(self, app_id: int, box_name: BoxIdentifier, abi_ :param abi_type: The ABI type to decode with :return: The decoded box value :raises ValueError: If decoding fails + + :example: + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> box_name = "BOX_NAME" + >>> abi_type = ABIType.UINT + >>> box_value = app_manager.get_box_value_from_abi_type(app_id, box_name, abi_type) """ value = self.get_box_value(app_id, box_name) @@ -294,6 +350,13 @@ def get_box_values_from_abi_type( :param box_names: List of box identifiers :param abi_type: The ABI type to decode with :return: List of decoded box values + + :example: + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> box_names = ["BOX_NAME_1", "BOX_NAME_2"] + >>> abi_type = ABIType.UINT + >>> box_values = app_manager.get_box_values_from_abi_type(app_id, box_names, abi_type) """ return [self.get_box_value_from_abi_type(app_id, box_name, abi_type) for box_name in box_names] @@ -305,6 +368,12 @@ def get_box_reference(box_id: BoxIdentifier | BoxReference) -> tuple[int, bytes] :param box_id: The box identifier :return: Tuple of (app_id, box_name_bytes) :raises ValueError: If box identifier type is invalid + + :example: + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> box_name = "BOX_NAME" + >>> box_reference = app_manager.get_box_reference(box_name) """ if isinstance(box_id, (BoxReference | AlgosdkBoxReference)): @@ -333,8 +402,14 @@ def get_abi_return( :param confirmation: The transaction confirmation :param method: The ABI method :return: The parsed ABI return value, or None if not available - """ + :example: + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> method = "METHOD_NAME" + >>> confirmation = algod_client.pending_transaction_info(tx_id) + >>> abi_return = app_manager.get_abi_return(confirmation, method) + """ if not method: return None @@ -357,6 +432,12 @@ def decode_app_state(state: list[dict[str, Any]]) -> dict[str, AppState]: :param state: The raw application state :return: Decoded application state :raises ValueError: If unknown state data type is encountered + + :example: + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> state = app_manager.get_global_state(app_id) + >>> decoded_state = app_manager.decode_app_state(state) """ state_values: dict[str, AppState] = {} @@ -407,6 +488,13 @@ def replace_template_variables(program: str, template_values: TealTemplateParams :param template_values: Template variable values to substitute :return: TEAL code with substituted values :raises ValueError: If template value type is unexpected + + :example: + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> program = "RETURN 1" + >>> template_values = {"TMPL_UPDATABLE": True, "TMPL_DELETABLE": True} + >>> updated_program = app_manager.replace_template_variables(program, template_values) """ program_lines = program.splitlines() @@ -437,6 +525,15 @@ def replace_teal_template_deploy_time_control_params( :param params: The deploy-time control parameters :return: TEAL code with substituted control parameters :raises ValueError: If template variables not found in code + + :example: + >>> app_manager = AppManager(algod_client) + >>> app_id = 123 + >>> teal_template_code = "RETURN 1" + >>> params = {"TMPL_UPDATABLE": True, "TMPL_DELETABLE": True} + >>> updated_teal_code = app_manager.replace_teal_template_deploy_time_control_params( + teal_template_code, params + ) """ updatable = params.get("updatable") @@ -461,6 +558,17 @@ def replace_teal_template_deploy_time_control_params( @staticmethod def strip_teal_comments(teal_code: str) -> str: + """Strip comments from TEAL code. + + :param teal_code: The TEAL code to strip comments from + :return: The TEAL code with comments stripped + + :example: + >>> app_manager = AppManager(algod_client) + >>> teal_code = "RETURN 1" + >>> stripped_teal_code = app_manager.strip_teal_comments(teal_code) + """ + def _strip_comment(line: str) -> str: comment_idx = _find_unquoted_string(line, "//") if comment_idx is None: diff --git a/src/algokit_utils/applications/app_spec/arc56.py b/src/algokit_utils/applications/app_spec/arc56.py index 9e7e2021..590a14fc 100644 --- a/src/algokit_utils/applications/app_spec/arc56.py +++ b/src/algokit_utils/applications/app_spec/arc56.py @@ -58,14 +58,12 @@ class _ActionType(str, Enum): @dataclass class StructField: - """Represents a field in a struct type. - - :ivar name: Name of the struct field - :ivar type: Type of the struct field, either a string or list of StructFields - """ + """Represents a field in a struct type.""" name: str + """The name of the struct field""" type: list[StructField] | str + """The type of the struct field, either a string or list of StructFields""" @staticmethod def from_dict(data: dict[str, Any]) -> StructField: @@ -95,14 +93,12 @@ class CreateEnum(str, Enum): @dataclass class BareActions: - """Represents bare call and create actions for an application. - - :ivar call: List of allowed call actions - :ivar create: List of allowed create actions - """ + """Represents bare call and create actions for an application.""" call: list[CallEnum] + """The list of allowed call actions""" create: list[CreateEnum] + """The list of allowed create actions""" @staticmethod def from_dict(data: dict[str, Any]) -> BareActions: @@ -111,14 +107,12 @@ def from_dict(data: dict[str, Any]) -> BareActions: @dataclass class ByteCode: - """Represents the approval and clear program bytecode. - - :ivar approval: Base64 encoded approval program bytecode - :ivar clear: Base64 encoded clear program bytecode - """ + """Represents the approval and clear program bytecode.""" approval: str + """The base64 encoded approval program bytecode""" clear: str + """The base64 encoded clear program bytecode""" @staticmethod def from_dict(data: dict[str, Any]) -> ByteCode: @@ -134,18 +128,16 @@ class Compiler(str, Enum): @dataclass class CompilerVersion: - """Represents compiler version information. - - :ivar commit_hash: Git commit hash of the compiler - :ivar major: Major version number - :ivar minor: Minor version number - :ivar patch: Patch version number - """ + """Represents compiler version information.""" commit_hash: str | None = None + """The git commit hash of the compiler""" major: int | None = None + """The major version number""" minor: int | None = None + """The minor version number""" patch: int | None = None + """The patch version number""" @staticmethod def from_dict(data: dict[str, Any]) -> CompilerVersion: @@ -154,14 +146,12 @@ def from_dict(data: dict[str, Any]) -> CompilerVersion: @dataclass class CompilerInfo: - """Information about the compiler used. - - :ivar compiler: Type of compiler used - :ivar compiler_version: Version information for the compiler - """ + """Information about the compiler used.""" compiler: Compiler + """The type of compiler used""" compiler_version: CompilerVersion + """Version information for the compiler""" @staticmethod def from_dict(data: dict[str, Any]) -> CompilerInfo: @@ -171,12 +161,10 @@ def from_dict(data: dict[str, Any]) -> CompilerInfo: @dataclass class Network: - """Network-specific application information. - - :ivar app_id: Application ID on the network - """ + """Network-specific application information.""" app_id: int + """The application ID on the network""" @staticmethod def from_dict(data: dict[str, Any]) -> Network: @@ -185,14 +173,12 @@ def from_dict(data: dict[str, Any]) -> Network: @dataclass class ScratchVariables: - """Information about scratch space variables. - - :ivar slot: Scratch slot number - :ivar type: Type of the scratch variable - """ + """Information about scratch space variables.""" slot: int + """The scratch slot number""" type: str + """The type of the scratch variable""" @staticmethod def from_dict(data: dict[str, Any]) -> ScratchVariables: @@ -201,14 +187,12 @@ def from_dict(data: dict[str, Any]) -> ScratchVariables: @dataclass class Source: - """Source code for approval and clear programs. - - :ivar approval: Base64 encoded approval program source - :ivar clear: Base64 encoded clear program source - """ + """Source code for approval and clear programs.""" approval: str + """The base64 encoded approval program source""" clear: str + """The base64 encoded clear program source""" @staticmethod def from_dict(data: dict[str, Any]) -> Source: @@ -234,14 +218,12 @@ def _decode_source(self, b64_text: str) -> str: @dataclass class Global: - """Global state schema. - - :ivar bytes: Number of byte slices in global state - :ivar ints: Number of integers in global state - """ + """Global state schema.""" bytes: int + """The number of byte slices in global state""" ints: int + """The number of integers in global state""" @staticmethod def from_dict(data: dict[str, Any]) -> Global: @@ -250,14 +232,12 @@ def from_dict(data: dict[str, Any]) -> Global: @dataclass class Local: - """Local state schema. - - :ivar bytes: Number of byte slices in local state - :ivar ints: Number of integers in local state - """ + """Local state schema.""" bytes: int + """The number of byte slices in local state""" ints: int + """The number of integers in local state""" @staticmethod def from_dict(data: dict[str, Any]) -> Local: @@ -266,14 +246,12 @@ def from_dict(data: dict[str, Any]) -> Local: @dataclass class Schema: - """Application state schema. - - :ivar global_state: Global state schema - :ivar local_state: Local state schema - """ + """Application state schema.""" global_state: Global # actual schema field is "global" since it's a reserved word + """The global state schema""" local_state: Local # actual schema field is "local" for consistency with renamed "global" + """The local state schema""" @staticmethod def from_dict(data: dict[str, Any]) -> Schema: @@ -284,14 +262,12 @@ def from_dict(data: dict[str, Any]) -> Schema: @dataclass class TemplateVariables: - """Template variable information. - - :ivar type: Type of the template variable - :ivar value: Optional value of the template variable - """ + """Template variable information.""" type: str + """The type of the template variable""" value: str | None = None + """The optional value of the template variable""" @staticmethod def from_dict(data: dict[str, Any]) -> TemplateVariables: @@ -300,18 +276,16 @@ def from_dict(data: dict[str, Any]) -> TemplateVariables: @dataclass class EventArg: - """Event argument information. - - :ivar type: Type of the event argument - :ivar desc: Optional description of the argument - :ivar name: Optional name of the argument - :ivar struct: Optional struct type name - """ + """Event argument information.""" type: str + """The type of the event argument""" desc: str | None = None + """The optional description of the argument""" name: str | None = None + """The optional name of the argument""" struct: str | None = None + """The optional struct type name""" @staticmethod def from_dict(data: dict[str, Any]) -> EventArg: @@ -320,16 +294,14 @@ def from_dict(data: dict[str, Any]) -> EventArg: @dataclass class Event: - """Event information. - - :ivar args: List of event arguments - :ivar name: Name of the event - :ivar desc: Optional description of the event - """ + """Event information.""" args: list[EventArg] + """The list of event arguments""" name: str + """The name of the event""" desc: str | None = None + """The optional description of the event""" @staticmethod def from_dict(data: dict[str, Any]) -> Event: @@ -339,14 +311,12 @@ def from_dict(data: dict[str, Any]) -> Event: @dataclass class Actions: - """Method actions information. - - :ivar call: Optional list of allowed call actions - :ivar create: Optional list of allowed create actions - """ + """Method actions information.""" call: list[CallEnum] | None = None + """The optional list of allowed call actions""" create: list[CreateEnum] | None = None + """The optional list of allowed create actions""" @staticmethod def from_dict(data: dict[str, Any]) -> Actions: @@ -355,16 +325,14 @@ def from_dict(data: dict[str, Any]) -> Actions: @dataclass class DefaultValue: - """Default value information for method arguments. - - :ivar data: Default value data - :ivar source: Source of the default value - :ivar type: Optional type of the default value - """ + """Default value information for method arguments.""" data: str + """The default value data""" source: Literal["box", "global", "local", "literal", "method"] + """The source of the default value""" type: str | None = None + """The optional type of the default value""" @staticmethod def from_dict(data: dict[str, Any]) -> DefaultValue: @@ -373,20 +341,18 @@ def from_dict(data: dict[str, Any]) -> DefaultValue: @dataclass class MethodArg: - """Method argument information. - - :ivar type: Type of the argument - :ivar default_value: Optional default value - :ivar desc: Optional description - :ivar name: Optional name - :ivar struct: Optional struct type name - """ + """Method argument information.""" type: str + """The type of the argument""" default_value: DefaultValue | None = None + """The optional default value""" desc: str | None = None + """The optional description""" name: str | None = None + """The optional name""" struct: str | None = None + """The optional struct type name""" @staticmethod def from_dict(data: dict[str, Any]) -> MethodArg: @@ -397,18 +363,16 @@ def from_dict(data: dict[str, Any]) -> MethodArg: @dataclass class Boxes: - """Box storage requirements. - - :ivar key: Box key - :ivar read_bytes: Number of bytes to read - :ivar write_bytes: Number of bytes to write - :ivar app: Optional application ID - """ + """Box storage requirements.""" key: str + """The box key""" read_bytes: int + """The number of bytes to read""" write_bytes: int + """The number of bytes to write""" app: int | None = None + """The optional application ID""" @staticmethod def from_dict(data: dict[str, Any]) -> Boxes: @@ -417,20 +381,18 @@ def from_dict(data: dict[str, Any]) -> Boxes: @dataclass class Recommendations: - """Method execution recommendations. - - :ivar accounts: Optional list of accounts - :ivar apps: Optional list of applications - :ivar assets: Optional list of assets - :ivar boxes: Optional box storage requirements - :ivar inner_transaction_count: Optional inner transaction count - """ + """Method execution recommendations.""" accounts: list[str] | None = None + """The optional list of accounts""" apps: list[int] | None = None + """The optional list of applications""" assets: list[int] | None = None + """The optional list of assets""" boxes: Boxes | None = None + """The optional box storage requirements""" inner_transaction_count: int | None = None + """The optional inner transaction count""" @staticmethod def from_dict(data: dict[str, Any]) -> Recommendations: @@ -441,16 +403,14 @@ def from_dict(data: dict[str, Any]) -> Recommendations: @dataclass class Returns: - """Method return information. - - :ivar type: Return type - :ivar desc: Optional description - :ivar struct: Optional struct type name - """ + """Method return information.""" type: str + """The type of the return value""" desc: str | None = None + """The optional description""" struct: str | None = None + """The optional struct type name""" @staticmethod def from_dict(data: dict[str, Any]) -> Returns: @@ -459,26 +419,24 @@ def from_dict(data: dict[str, Any]) -> Returns: @dataclass class Method: - """Method information. - - :ivar actions: Allowed actions - :ivar args: Method arguments - :ivar name: Method name - :ivar returns: Return information - :ivar desc: Optional description - :ivar events: Optional list of events - :ivar readonly: Optional readonly flag - :ivar recommendations: Optional execution recommendations - """ + """Method information.""" actions: Actions + """The allowed actions""" args: list[MethodArg] + """The method arguments""" name: str + """The method name""" returns: Returns + """The return information""" desc: str | None = None + """The optional description""" events: list[Event] | None = None + """The optional list of events""" readonly: bool | None = None + """The optional readonly flag""" recommendations: Recommendations | None = None + """The optional execution recommendations""" _abi_method: AlgosdkMethod | None = None @@ -516,18 +474,16 @@ class PcOffsetMethod(str, Enum): @dataclass class SourceInfo: - """Source code location information. - - :ivar pc: List of program counter values - :ivar error_message: Optional error message - :ivar source: Optional source code - :ivar teal: Optional TEAL version - """ + """Source code location information.""" pc: list[int] + """The list of program counter values""" error_message: str | None = None + """The optional error message""" source: str | None = None + """The optional source code""" teal: int | None = None + """The optional TEAL version""" @staticmethod def from_dict(data: dict[str, Any]) -> SourceInfo: @@ -536,18 +492,16 @@ def from_dict(data: dict[str, Any]) -> SourceInfo: @dataclass class StorageKey: - """Storage key information. - - :ivar key: Storage key - :ivar key_type: Type of the key - :ivar value_type: Type of the value - :ivar desc: Optional description - """ + """Storage key information.""" key: str + """The storage key""" key_type: str + """The type of the key""" value_type: str + """The type of the value""" desc: str | None = None + """The optional description""" @staticmethod def from_dict(data: dict[str, Any]) -> StorageKey: @@ -556,18 +510,16 @@ def from_dict(data: dict[str, Any]) -> StorageKey: @dataclass class StorageMap: - """Storage map information. - - :ivar key_type: Type of map keys - :ivar value_type: Type of map values - :ivar desc: Optional description - :ivar prefix: Optional key prefix - """ + """Storage map information.""" key_type: str + """The type of the map keys""" value_type: str + """The type of the map values""" desc: str | None = None + """The optional description""" prefix: str | None = None + """The optional key prefix""" @staticmethod def from_dict(data: dict[str, Any]) -> StorageMap: @@ -576,16 +528,14 @@ def from_dict(data: dict[str, Any]) -> StorageMap: @dataclass class Keys: - """Storage keys for different storage types. - - :ivar box: Box storage keys - :ivar global_state: Global state storage keys - :ivar local_state: Local state storage keys - """ + """Storage keys for different storage types.""" box: dict[str, StorageKey] + """The box storage keys""" global_state: dict[str, StorageKey] # actual schema field is "global" since it's a reserved word + """The global state storage keys""" local_state: dict[str, StorageKey] # actual schema field is "local" for consistency with renamed "global" + """The local state storage keys""" @staticmethod def from_dict(data: dict[str, Any]) -> Keys: @@ -597,16 +547,14 @@ def from_dict(data: dict[str, Any]) -> Keys: @dataclass class Maps: - """Storage maps for different storage types. - - :ivar box: Box storage maps - :ivar global_state: Global state storage maps - :ivar local_state: Local state storage maps - """ + """Storage maps for different storage types.""" box: dict[str, StorageMap] + """The box storage maps""" global_state: dict[str, StorageMap] # actual schema field is "global" since it's a reserved word + """The global state storage maps""" local_state: dict[str, StorageMap] # actual schema field is "local" for consistency with renamed "global" + """The local state storage maps""" @staticmethod def from_dict(data: dict[str, Any]) -> Maps: @@ -618,16 +566,14 @@ def from_dict(data: dict[str, Any]) -> Maps: @dataclass class State: - """Application state information. - - :ivar keys: Storage keys - :ivar maps: Storage maps - :ivar schema: State schema - """ + """Application state information.""" keys: Keys + """The storage keys""" maps: Maps + """The storage maps""" schema: Schema + """The state schema""" @staticmethod def from_dict(data: dict[str, Any]) -> State: @@ -639,14 +585,12 @@ def from_dict(data: dict[str, Any]) -> State: @dataclass class ProgramSourceInfo: - """Program source information. - - :ivar pc_offset_method: PC offset method - :ivar source_info: List of source info entries - """ + """Program source information.""" pc_offset_method: PcOffsetMethod + """The PC offset method""" source_info: list[SourceInfo] + """The list of source info entries""" @staticmethod def from_dict(data: dict[str, Any]) -> ProgramSourceInfo: @@ -656,14 +600,12 @@ def from_dict(data: dict[str, Any]) -> ProgramSourceInfo: @dataclass class SourceInfoModel: - """Source information for approval and clear programs. - - :ivar approval: Approval program source info - :ivar clear: Clear program source info - """ + """Source information for approval and clear programs.""" approval: ProgramSourceInfo + """The approval program source info""" clear: ProgramSourceInfo + """The clear program source info""" @staticmethod def from_dict(data: dict[str, Any]) -> SourceInfoModel: @@ -912,39 +854,38 @@ class Arc56Contract: """ARC-0056 application specification. See https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0056.md - - :ivar arcs: List of supported ARC version numbers - :ivar bare_actions: Bare call and create actions - :ivar methods: List of contract methods - :ivar name: Contract name - :ivar state: Contract state information - :ivar structs: Contract struct definitions - :ivar byte_code: Optional bytecode for approval and clear programs - :ivar compiler_info: Optional compiler information - :ivar desc: Optional contract description - :ivar events: Optional list of contract events - :ivar networks: Optional network deployment information - :ivar scratch_variables: Optional scratch variable information - :ivar source: Optional source code - :ivar source_info: Optional source code information - :ivar template_variables: Optional template variable information """ arcs: list[int] + """The list of supported ARC version numbers""" bare_actions: BareActions + """The bare call and create actions""" methods: list[Method] + """The list of contract methods""" name: str + """The contract name""" state: State + """The contract state information""" structs: dict[str, list[StructField]] + """The contract struct definitions""" byte_code: ByteCode | None = None + """The optional bytecode for approval and clear programs""" compiler_info: CompilerInfo | None = None + """The optional compiler information""" desc: str | None = None + """The optional contract description""" events: list[Event] | None = None + """The optional list of contract events""" networks: dict[str, Network] | None = None + """The optional network deployment information""" scratch_variables: dict[str, ScratchVariables] | None = None + """The optional scratch variable information""" source: Source | None = None + """The optional source code""" source_info: SourceInfoModel | None = None + """The optional source code information""" template_variables: dict[str, TemplateVariables] | None = None + """The optional template variable information""" @staticmethod def from_dict(application_spec: dict) -> Arc56Contract: diff --git a/src/algokit_utils/assets/asset_manager.py b/src/algokit_utils/assets/asset_manager.py index 0f48aebe..dbe39fb8 100644 --- a/src/algokit_utils/assets/asset_manager.py +++ b/src/algokit_utils/assets/asset_manager.py @@ -19,63 +19,58 @@ @dataclass(kw_only=True, frozen=True) class AccountAssetInformation: - """Information about an account's holding of a particular asset. - - :ivar asset_id: The ID of the asset - :ivar balance: The amount of the asset held by the account - :ivar frozen: Whether the asset is frozen for this account - :ivar round: The round this information was retrieved at - """ + """Information about an account's holding of a particular asset.""" asset_id: int + """The ID of the asset""" balance: int + """The amount of the asset held by the account""" frozen: bool + """Whether the asset is frozen for this account""" round: int + """The round this information was retrieved at""" @dataclass(kw_only=True, frozen=True) class AssetInformation: - """Information about an Algorand Standard Asset (ASA). - - :ivar asset_id: The ID of the asset - :ivar creator: The address of the account that created the asset - :ivar total: The total amount of the smallest divisible units that were created of the asset - :ivar decimals: The amount of decimal places the asset was created with - :ivar default_frozen: Whether the asset was frozen by default for all accounts, defaults to None - :ivar manager: The address of the optional account that can manage the configuration of the asset and destroy it, - defaults to None - :ivar reserve: The address of the optional account that holds the reserve (uncirculated supply) units of the asset, - defaults to None - :ivar freeze: The address of the optional account that can be used to freeze or unfreeze holdings of this asset, - defaults to None - :ivar clawback: The address of the optional account that can clawback holdings of this asset from any account, - defaults to None - :ivar unit_name: The optional name of the unit of this asset (e.g. ticker name), defaults to None - :ivar unit_name_b64: The optional name of the unit of this asset as bytes, defaults to None - :ivar asset_name: The optional name of the asset, defaults to None - :ivar asset_name_b64: The optional name of the asset as bytes, defaults to None - :ivar url: Optional URL where more information about the asset can be retrieved, defaults to None - :ivar url_b64: Optional URL where more information about the asset can be retrieved as bytes, defaults to None - :ivar metadata_hash: 32-byte hash of some metadata that is relevant to the asset and/or asset holders, - defaults to None - """ + """Information about an Algorand Standard Asset (ASA).""" asset_id: int + """The ID of the asset""" creator: str + """The address of the account that created the asset""" total: int + """The total amount of the smallest divisible units that were created of the asset""" decimals: int + """The amount of decimal places the asset was created with""" default_frozen: bool | None = None + """Whether the asset was frozen by default for all accounts, defaults to None""" manager: str | None = None + """The address of the optional account that can manage the configuration of the asset and destroy it, + defaults to None""" reserve: str | None = None + """The address of the optional account that holds the reserve (uncirculated supply) units of the asset, + defaults to None""" freeze: str | None = None + """The address of the optional account that can be used to freeze or unfreeze holdings of this asset, + defaults to None""" clawback: str | None = None + """The address of the optional account that can clawback holdings of this asset from any account, + defaults to None""" unit_name: str | None = None + """The optional name of the unit of this asset (e.g. ticker name), defaults to None""" unit_name_b64: bytes | None = None + """The optional name of the unit of this asset as bytes, defaults to None""" asset_name: str | None = None + """The optional name of the asset, defaults to None""" asset_name_b64: bytes | None = None + """The optional name of the asset as bytes, defaults to None""" url: str | None = None + """The optional URL where more information about the asset can be retrieved, defaults to None""" url_b64: bytes | None = None + """The optional URL where more information about the asset can be retrieved as bytes, defaults to None""" metadata_hash: bytes | None = None + """The 32-byte hash of some metadata that is relevant to the asset and/or asset holders, defaults to None""" @dataclass(kw_only=True, frozen=True) @@ -87,7 +82,9 @@ class BulkAssetOptInOutResult: """ asset_id: int + """The ID of the asset opted into / out of""" transaction_id: str + """The transaction ID of the resulting opt in / out""" class AssetManager: @@ -95,6 +92,9 @@ class AssetManager: :param algod_client: An algod client :param new_group: A function that creates a new TransactionComposer transaction group + + :example: + >>> asset_manager = AssetManager(algod_client) """ def __init__(self, algod_client: algod.AlgodClient, new_group: Callable[[], TransactionComposer]): @@ -106,6 +106,10 @@ def get_by_id(self, asset_id: int) -> AssetInformation: :param asset_id: The ID of the asset :return: The asset information + + :example: + >>> asset_manager = AssetManager(algod_client) + >>> asset_info = asset_manager.get_by_id(1234567890) """ asset = self._algod.asset_info(asset_id) assert isinstance(asset, dict) @@ -138,6 +142,10 @@ def get_account_information( :param sender: The address of the sender/account to look up :param asset_id: The ID of the asset to return a holding for :return: The account asset holding information + + :example: + >>> asset_manager = AssetManager(algod_client) + >>> account_asset_info = asset_manager.get_account_information(sender, asset_id) """ address = self._get_address_from_sender(sender) info = self._algod.account_asset_info(address, asset_id) @@ -182,6 +190,10 @@ def bulk_opt_in( # noqa: PLR0913 :param last_valid_round: The last valid round to include in the transaction, defaults to None :param send_params: The send parameters to use for the transaction, defaults to None :return: An array of records matching asset ID to transaction ID of the opt in + + :example: + >>> asset_manager = AssetManager(algod_client) + >>> results = asset_manager.bulk_opt_in(account, asset_ids) """ results: list[BulkAssetOptInOutResult] = [] sender = self._get_address_from_sender(account) @@ -249,6 +261,10 @@ def bulk_opt_out( # noqa: C901, PLR0913 :param send_params: The send parameters to use for the transaction, defaults to None :raises ValueError: If ensure_zero_balance is True and account has non-zero balance or is not opted in :return: An array of records matching asset ID to transaction ID of the opt out + + :example: + >>> asset_manager = AssetManager(algod_client) + >>> results = asset_manager.bulk_opt_out(account, asset_ids) """ results: list[BulkAssetOptInOutResult] = [] sender = self._get_address_from_sender(account) diff --git a/src/algokit_utils/clients/client_manager.py b/src/algokit_utils/clients/client_manager.py index 97ef7c7c..e3bf497b 100644 --- a/src/algokit_utils/clients/client_manager.py +++ b/src/algokit_utils/clients/client_manager.py @@ -64,10 +64,15 @@ class NetworkDetail: """ is_testnet: bool + """Whether the network is a testnet""" is_mainnet: bool + """Whether the network is a mainnet""" is_localnet: bool + """Whether the network is a localnet""" genesis_id: str + """The genesis ID of the network""" genesis_hash: str + """The genesis hash of the network""" def _get_config_from_environment(environment_prefix: str) -> AlgoClientNetworkConfig: @@ -88,6 +93,17 @@ class ClientManager: :param clients_or_configs: Either client instances or client configurations :param algorand_client: AlgorandClient instance + + :example: + >>> # Algod only + >>> client_manager = ClientManager(algod_client) + >>> # Algod and Indexer + >>> client_manager = ClientManager(algod_client, indexer_client) + >>> # Algod config only + >>> client_manager = ClientManager(ClientManager.get_algod_config_from_environment()) + >>> # Algod and Indexer config + >>> client_manager = ClientManager(ClientManager.get_algod_config_from_environment(), + ... ClientManager.get_indexer_config_from_environment()) """ def __init__(self, clients_or_configs: AlgoClientConfigs | AlgoSdkClients, algorand_client: AlgorandClient): @@ -151,6 +167,10 @@ def network(self) -> NetworkDetail: """Get details about the connected Algorand network. :return: Network details including type and genesis information + + :example: + >>> client_manager = ClientManager(algod_client) + >>> network_detail = client_manager.network() """ if self._suggested_params is None: self._suggested_params = self._algod.suggested_params() @@ -417,6 +437,9 @@ def genesis_id_is_localnet(genesis_id: str | None) -> bool: :param genesis_id: Genesis ID to check :return: True if genesis ID indicates a local network + + :example: + >>> ClientManager.genesis_id_is_localnet("devnet-v1") """ return genesis_id in ["devnet-v1", "sandnet-v1", "dockernet-v1"] @@ -442,6 +465,14 @@ def get_typed_app_client_by_creator_and_name( :param app_lookup_cache: Optional app lookup cache :raises ValueError: If no Algorand client is configured :return: Typed application client instance + + :example: + >>> client_manager = ClientManager(algod_client) + >>> typed_app_client = client_manager.get_typed_app_client_by_creator_and_name( + ... typed_client=MyAppClient, + ... creator_address="creator_address", + ... app_name="app_name", + ... ) """ if not self._algorand: raise ValueError("Attempt to get app client from a ClientManager without an Algorand client") @@ -478,6 +509,13 @@ def get_typed_app_client_by_id( :param clear_source_map: Optional clear program source map :raises ValueError: If no Algorand client is configured :return: Typed application client instance + + :example: + >>> client_manager = ClientManager(algod_client) + >>> typed_app_client = client_manager.get_typed_app_client_by_id( + ... typed_client=MyAppClient, + ... app_id=1234567890, + ... ) """ if not self._algorand: raise ValueError("Attempt to get app client from a ClientManager without an Algorand client") @@ -515,6 +553,13 @@ def get_typed_app_client_by_network( :param clear_source_map: Optional clear program source map :raises ValueError: If no Algorand client is configured :return: The typed client instance + + :example: + >>> client_manager = ClientManager(algod_client) + >>> typed_app_client = client_manager.get_typed_app_client_by_network( + ... typed_client=MyAppClient, + ... app_name="app_name", + ... ) """ if not self._algorand: raise ValueError("Attempt to get app client from a ClientManager without an Algorand client") @@ -548,6 +593,13 @@ def get_typed_app_factory( :param compilation_params: Optional compilation parameters :raises ValueError: If no Algorand client is configured :return: Typed application factory instance + + :example: + >>> client_manager = ClientManager(algod_client) + >>> typed_app_factory = client_manager.get_typed_app_factory( + ... typed_factory=MyAppFactory, + ... app_name="app_name", + ... ) """ if not self._algorand: raise ValueError("Attempt to get app factory from a ClientManager without an Algorand client") @@ -569,6 +621,10 @@ def get_config_from_environment_or_localnet() -> AlgoClientConfigs: otherwise it will use default localnet configuration. :return: Configuration for algod, indexer, and optionally kmd + + :example: + >>> client_manager = ClientManager(algod_client) + >>> config = client_manager.get_config_from_environment_or_localnet() """ algod_server = os.getenv("ALGOD_SERVER") @@ -609,6 +665,10 @@ def get_default_localnet_config( :param config_or_port: Service name or port number :return: Client configuration for local network + + :example: + >>> client_manager = ClientManager(algod_client) + >>> config = client_manager.get_default_localnet_config("algod") """ port = ( config_or_port @@ -624,6 +684,10 @@ def get_algod_config_from_environment() -> AlgoClientNetworkConfig: Will raise an error if ALGOD_SERVER environment variable is not set :return: Algod client configuration + + :example: + >>> client_manager = ClientManager(algod_client) + >>> config = client_manager.get_algod_config_from_environment() """ return _get_config_from_environment("ALGOD") @@ -633,6 +697,10 @@ def get_indexer_config_from_environment() -> AlgoClientNetworkConfig: Will raise an error if INDEXER_SERVER environment variable is not set :return: Indexer client configuration + + :example: + >>> client_manager = ClientManager(algod_client) + >>> config = client_manager.get_indexer_config_from_environment() """ return _get_config_from_environment("INDEXER") @@ -641,6 +709,10 @@ def get_kmd_config_from_environment() -> AlgoClientNetworkConfig: """Retrieve the kmd configuration from environment variables. :return: KMD client configuration + + :example: + >>> client_manager = ClientManager(algod_client) + >>> config = client_manager.get_kmd_config_from_environment() """ return _get_config_from_environment("KMD") @@ -653,6 +725,10 @@ def get_algonode_config( :param network: Which network to connect to - TestNet or MainNet :param config: Which algod config to return - Algod or Indexer :return: Configuration for the specified network and service + + :example: + >>> client_manager = ClientManager(algod_client) + >>> config = client_manager.get_algonode_config("testnet", "algod") """ service_type = "api" if config == "algod" else "idx" return AlgoClientNetworkConfig( diff --git a/src/algokit_utils/clients/dispenser_api_client.py b/src/algokit_utils/clients/dispenser_api_client.py index 4f262d63..9ba47f66 100644 --- a/src/algokit_utils/clients/dispenser_api_client.py +++ b/src/algokit_utils/clients/dispenser_api_client.py @@ -2,8 +2,10 @@ import enum import os from dataclasses import dataclass +from typing import overload import httpx +from typing_extensions import deprecated from algokit_utils.config import config @@ -34,19 +36,25 @@ class DispenserAssetName(enum.IntEnum): @dataclass class DispenserAsset: asset_id: int + """The ID of the asset""" decimals: int + """The amount of decimal places the asset was created with""" description: str + """The description of the asset""" @dataclass class DispenserFundResponse: tx_id: str + """The transaction ID of the funded transaction""" amount: int + """The amount of Algos funded""" @dataclass class DispenserLimitResponse: amount: int + """The amount of Algos that can be funded""" DISPENSER_ASSETS = { @@ -136,16 +144,37 @@ def _process_dispenser_request( logger.debug(f"{error_message}: {err}", exc_info=True) raise err - def fund(self, address: str, amount: int, asset_id: int) -> DispenserFundResponse: + @overload + def fund(self, address: str, amount: int) -> DispenserFundResponse: ... + + @deprecated("Asset ID parameter is deprecated. Can now use `fund(address, amount)` instead.") + @overload + def fund(self, address: str, amount: int, asset_id: int | None = None) -> DispenserFundResponse: ... + + def fund(self, address: str, amount: int, asset_id: int | None = None) -> DispenserFundResponse: # noqa: ARG002 """ Fund an account with Algos from the dispenser API + + :param address: The address to fund + :param amount: The amount of Algos to fund + :param asset_id: The asset ID to fund (deprecated) + :return: The transaction ID of the funded transaction + :raises Exception: If the dispenser API request fails + + :example: + >>> dispenser_client = TestNetDispenserApiClient() + >>> dispenser_client.fund(address="SENDER_ADDRESS", amount=1000000) """ try: response = self._process_dispenser_request( auth_token=self.auth_token, - url_suffix=f"fund/{asset_id}", - data={"receiver": address, "amount": amount, "assetID": asset_id}, + url_suffix=f"fund/{DISPENSER_ASSETS[DispenserAssetName.ALGO].asset_id}", + data={ + "receiver": address, + "amount": amount, + "assetID": DISPENSER_ASSETS[DispenserAssetName.ALGO].asset_id, + }, method="POST", ) diff --git a/src/algokit_utils/models/application.py b/src/algokit_utils/models/application.py index 46d2ddba..a9187c8f 100644 --- a/src/algokit_utils/models/application.py +++ b/src/algokit_utils/models/application.py @@ -19,43 +19,73 @@ @dataclass(kw_only=True, frozen=True) class AppState: key_raw: bytes + """The key of the state as raw bytes""" key_base64: str + """The key of the state""" value_raw: bytes | None + """The value of the state as raw bytes""" value_base64: str | None + """The value of the state as base64 encoded string""" value: str | int + """The value of the state as a string or integer""" @dataclass(kw_only=True, frozen=True) class AppInformation: app_id: int + """The ID of the application""" app_address: str + """The address of the application""" approval_program: bytes + """The approval program""" clear_state_program: bytes + """The clear state program""" creator: str + """The creator of the application""" global_state: dict[str, AppState] + """The global state of the application""" local_ints: int + """The number of local ints""" local_byte_slices: int + """The number of local byte slices""" global_ints: int + """The number of global ints""" global_byte_slices: int + """The number of global byte slices""" extra_program_pages: int | None + """The number of extra program pages""" @dataclass(kw_only=True, frozen=True) class CompiledTeal: + """The compiled teal code""" + teal: str + """The teal code""" compiled: str + """The compiled teal code""" compiled_hash: str + """The compiled hash""" compiled_base64_to_bytes: bytes + """The compiled base64 to bytes""" source_map: algosdk.source_map.SourceMap | None @dataclass(kw_only=True, frozen=True) class AppCompilationResult: + """The compiled teal code""" + compiled_approval: CompiledTeal + """The compiled approval program""" compiled_clear: CompiledTeal + """The compiled clear state program""" @dataclass(kw_only=True, frozen=True) class AppSourceMaps: + """The source maps for the application""" + approval_source_map: SourceMap | None = None + """The source map for the approval program""" clear_source_map: SourceMap | None = None + """The source map for the clear state program""" diff --git a/src/algokit_utils/models/state.py b/src/algokit_utils/models/state.py index f5d7804e..a4088c4d 100644 --- a/src/algokit_utils/models/state.py +++ b/src/algokit_utils/models/state.py @@ -19,15 +19,24 @@ @dataclass(kw_only=True, frozen=True) class BoxName: + """The name of the box""" + name: str + """The name of the box as a string""" name_raw: bytes + """The name of the box as raw bytes""" name_base64: str + """The name of the box as a base64 encoded string""" @dataclass(kw_only=True, frozen=True) class BoxValue: + """The value of the box""" + name: BoxName + """The name of the box""" value: bytes + """The value of the box as raw bytes""" class DataTypeFlag(IntEnum): diff --git a/src/algokit_utils/transactions/transaction_composer.py b/src/algokit_utils/transactions/transaction_composer.py index 98837be1..0aa2995c 100644 --- a/src/algokit_utils/transactions/transaction_composer.py +++ b/src/algokit_utils/transactions/transaction_composer.py @@ -85,393 +85,374 @@ @dataclass(kw_only=True, frozen=True) class _CommonTxnParams: sender: str + """The account that will send the transaction""" signer: TransactionSigner | TransactionSignerAccountProtocol | None = None + """The signer for the transaction, defaults to None""" rekey_to: str | None = None + """The account to rekey to, defaults to None""" note: bytes | None = None + """The note for the transaction, defaults to None""" lease: bytes | None = None + """The lease for the transaction, defaults to None""" static_fee: AlgoAmount | None = None + """The static fee for the transaction, defaults to None""" extra_fee: AlgoAmount | None = None + """The extra fee for the transaction, defaults to None""" max_fee: AlgoAmount | None = None + """The maximum fee for the transaction, defaults to None""" validity_window: int | None = None + """The validity window for the transaction, defaults to None""" first_valid_round: int | None = None + """The first valid round for the transaction, defaults to None""" last_valid_round: int | None = None + """The last valid round for the transaction, defaults to None""" @dataclass(kw_only=True, frozen=True) class AdditionalAtcContext: max_fees: dict[int, AlgoAmount] | None = None + """The maximum fees for each transaction, defaults to None""" suggested_params: SuggestedParams | None = None + """The suggested parameters for the transaction, defaults to None""" @dataclass(kw_only=True, frozen=True) class PaymentParams(_CommonTxnParams): - """Parameters for a payment transaction. - - :ivar receiver: The account that will receive the ALGO - :ivar amount: Amount to send - :ivar close_remainder_to: If given, close the sender account and send the remaining balance to this address, - defaults to None - """ + """Parameters for a payment transaction.""" receiver: str + """The account that will receive the ALGO""" amount: AlgoAmount + """Amount to send""" close_remainder_to: str | None = None + """If given, close the sender account and send the remaining balance to this address, defaults to None""" @dataclass(kw_only=True, frozen=True) class AssetCreateParams(_CommonTxnParams): - """Parameters for creating a new asset. - - :ivar total: The total amount of the smallest divisible unit to create - :ivar decimals: The amount of decimal places the asset should have, defaults to None - :ivar default_frozen: Whether the asset is frozen by default in the creator address, defaults to None - :ivar manager: The address that can change the manager, reserve, clawback, and freeze addresses, defaults to None - :ivar reserve: The address that holds the uncirculated supply, defaults to None - :ivar freeze: The address that can freeze the asset in any account, defaults to None - :ivar clawback: The address that can clawback the asset from any account, defaults to None - :ivar unit_name: The short ticker name for the asset, defaults to None - :ivar asset_name: The full name of the asset, defaults to None - :ivar url: The metadata URL for the asset, defaults to None - :ivar metadata_hash: Hash of the metadata contained in the metadata URL, defaults to None - """ + """Parameters for creating a new asset.""" total: int + """The total amount of the smallest divisible unit to create""" asset_name: str | None = None + """The full name of the asset""" unit_name: str | None = None + """The short ticker name for the asset""" url: str | None = None + """The metadata URL for the asset""" decimals: int | None = None + """The amount of decimal places the asset should have""" default_frozen: bool | None = None + """Whether the asset is frozen by default in the creator address""" manager: str | None = None + """The address that can change the manager, reserve, clawback, and freeze addresses""" reserve: str | None = None + """The address that holds the uncirculated supply""" freeze: str | None = None + """The address that can freeze the asset in any account""" clawback: str | None = None + """The address that can clawback the asset from any account""" metadata_hash: bytes | None = None + """Hash of the metadata contained in the metadata URL""" @dataclass(kw_only=True, frozen=True) class AssetConfigParams(_CommonTxnParams): - """Parameters for configuring an existing asset. - - :ivar asset_id: ID of the asset - :ivar manager: The address that can change the manager, reserve, clawback, and freeze addresses, defaults to None - :ivar reserve: The address that holds the uncirculated supply, defaults to None - :ivar freeze: The address that can freeze the asset in any account, defaults to None - :ivar clawback: The address that can clawback the asset from any account, defaults to None - """ + """Parameters for configuring an existing asset.""" asset_id: int + """The ID of the asset""" manager: str | None = None + """The address that can change the manager, reserve, clawback, and freeze addresses, defaults to None""" reserve: str | None = None + """The address that holds the uncirculated supply, defaults to None""" freeze: str | None = None + """The address that can freeze the asset in any account, defaults to None""" clawback: str | None = None + """The address that can clawback the asset from any account, defaults to None""" @dataclass(kw_only=True, frozen=True) class AssetFreezeParams(_CommonTxnParams): - """Parameters for freezing an asset. - - :ivar asset_id: The ID of the asset - :ivar account: The account to freeze or unfreeze - :ivar frozen: Whether the assets in the account should be frozen - """ + """Parameters for freezing an asset.""" asset_id: int + """The ID of the asset""" account: str + """The account to freeze or unfreeze""" frozen: bool + """Whether the assets in the account should be frozen""" @dataclass(kw_only=True, frozen=True) class AssetDestroyParams(_CommonTxnParams): - """Parameters for destroying an asset. - - :ivar asset_id: ID of the asset - """ + """Parameters for destroying an asset.""" asset_id: int + """The ID of the asset""" @dataclass(kw_only=True, frozen=True) class OnlineKeyRegistrationParams(_CommonTxnParams): - """Parameters for online key registration. - - :ivar vote_key: The root participation public key - :ivar selection_key: The VRF public key - :ivar vote_first: The first round that the participation key is valid - :ivar vote_last: The last round that the participation key is valid - :ivar vote_key_dilution: The dilution for the 2-level participation key - :ivar state_proof_key: The 64 byte state proof public key commitment, defaults to None - """ + """Parameters for online key registration.""" vote_key: str + """The root participation public key""" selection_key: str + """The VRF public key""" vote_first: int + """The first round that the participation key is valid""" vote_last: int + """The last round that the participation key is valid""" vote_key_dilution: int + """The dilution for the 2-level participation key""" state_proof_key: bytes | None = None + """The 64 byte state proof public key commitment, defaults to None""" @dataclass(kw_only=True, frozen=True) class OfflineKeyRegistrationParams(_CommonTxnParams): - """Parameters for offline key registration. - - :ivar prevent_account_from_ever_participating_again: Whether to prevent the account from ever participating again - """ + """Parameters for offline key registration.""" prevent_account_from_ever_participating_again: bool + """Whether to prevent the account from ever participating again""" @dataclass(kw_only=True, frozen=True) class AssetTransferParams(_CommonTxnParams): - """Parameters for transferring an asset. - - :ivar asset_id: ID of the asset - :ivar amount: Amount of the asset to transfer (smallest divisible unit) - :ivar receiver: The account to send the asset to - :ivar clawback_target: The account to take the asset from, defaults to None - :ivar close_asset_to: The account to close the asset to, defaults to None - """ + """Parameters for transferring an asset.""" asset_id: int + """The ID of the asset""" amount: int + """The amount of the asset to transfer (smallest divisible unit)""" receiver: str + """The account to send the asset to""" clawback_target: str | None = None + """The account to take the asset from, defaults to None""" close_asset_to: str | None = None + """The account to close the asset to, defaults to None""" @dataclass(kw_only=True, frozen=True) class AssetOptInParams(_CommonTxnParams): - """Parameters for opting into an asset. - - :ivar asset_id: ID of the asset - """ + """Parameters for opting into an asset.""" asset_id: int + """The ID of the asset""" @dataclass(kw_only=True, frozen=True) class AssetOptOutParams(_CommonTxnParams): - """Parameters for opting out of an asset. - - :ivar asset_id: ID of the asset - :ivar creator: The creator address of the asset - """ + """Parameters for opting out of an asset.""" asset_id: int + """The ID of the asset""" creator: str + """The creator address of the asset""" @dataclass(kw_only=True, frozen=True) class AppCallParams(_CommonTxnParams): - """Parameters for calling an application. - - :ivar on_complete: The OnComplete action - :ivar app_id: ID of the application, defaults to None - :ivar approval_program: The program to execute for all OnCompletes other than ClearState, defaults to None - :ivar clear_state_program: The program to execute for ClearState OnComplete, defaults to None - :ivar schema: The state schema for the app. This is immutable, defaults to None - :ivar args: Application arguments, defaults to None - :ivar account_references: Account references, defaults to None - :ivar app_references: App references, defaults to None - :ivar asset_references: Asset references, defaults to None - :ivar extra_pages: Number of extra pages required for the programs, defaults to None - :ivar box_references: Box references, defaults to None - """ + """Parameters for calling an application.""" on_complete: OnComplete + """The OnComplete action, defaults to None""" app_id: int | None = None + """The ID of the application, defaults to None""" approval_program: str | bytes | None = None + """The program to execute for all OnCompletes other than ClearState, defaults to None""" clear_state_program: str | bytes | None = None + """The program to execute for ClearState OnComplete, defaults to None""" schema: dict[str, int] | None = None + """The state schema for the app, defaults to None""" args: list[bytes] | None = None + """Application arguments, defaults to None""" account_references: list[str] | None = None + """Account references, defaults to None""" app_references: list[int] | None = None + """App references, defaults to None""" asset_references: list[int] | None = None + """Asset references, defaults to None""" extra_pages: int | None = None + """Number of extra pages required for the programs, defaults to None""" box_references: list[BoxReference | BoxIdentifier] | None = None + """Box references, defaults to None""" class AppCreateSchema(TypedDict): global_ints: int + """The number of global ints in the schema""" global_byte_slices: int + """The number of global byte slices in the schema""" local_ints: int + """The number of local ints in the schema""" local_byte_slices: int + """The number of local byte slices in the schema""" @dataclass(kw_only=True, frozen=True) class AppCreateParams(_CommonTxnParams): - """Parameters for creating an application. - - :ivar approval_program: The program to execute for all OnCompletes other than ClearState as raw teal (string) - or compiled teal (bytes) - :ivar clear_state_program: The program to execute for ClearState OnComplete as raw teal (string) - or compiled teal (bytes) - :ivar schema: The state schema for the app. This is immutable, defaults to None - :ivar on_complete: The OnComplete action (cannot be ClearState), defaults to None - :ivar args: Application arguments, defaults to None - :ivar account_references: Account references, defaults to None - :ivar app_references: App references, defaults to None - :ivar asset_references: Asset references, defaults to None - :ivar box_references: Box references, defaults to None - :ivar extra_program_pages: Number of extra pages required for the programs, defaults to None - """ + """Parameters for creating an application.""" approval_program: str | bytes + """The program to execute for all OnCompletes other than ClearState""" clear_state_program: str | bytes + """The program to execute for ClearState OnComplete""" schema: AppCreateSchema | None = None + """The state schema for the app, defaults to None""" on_complete: OnComplete | None = None + """The OnComplete action, defaults to None""" args: list[bytes] | None = None + """Application arguments, defaults to None""" account_references: list[str] | None = None + """Account references, defaults to None""" app_references: list[int] | None = None + """App references, defaults to None""" asset_references: list[int] | None = None + """Asset references, defaults to None""" box_references: list[BoxReference | BoxIdentifier] | None = None + """Box references, defaults to None""" extra_program_pages: int | None = None + """Number of extra pages required for the programs, defaults to None""" @dataclass(kw_only=True, frozen=True) class AppUpdateParams(_CommonTxnParams): - """Parameters for updating an application. - - :ivar app_id: ID of the application - :ivar approval_program: The program to execute for all OnCompletes other than ClearState as raw teal (string) - or compiled teal (bytes) - :ivar clear_state_program: The program to execute for ClearState OnComplete as raw teal (string) - or compiled teal (bytes) - :ivar args: Application arguments, defaults to None - :ivar account_references: Account references, defaults to None - :ivar app_references: App references, defaults to None - :ivar asset_references: Asset references, defaults to None - :ivar box_references: Box references, defaults to None - :ivar on_complete: The OnComplete action, defaults to None - """ + """Parameters for updating an application.""" app_id: int + """The ID of the application""" approval_program: str | bytes + """The program to execute for all OnCompletes other than ClearState""" clear_state_program: str | bytes + """The program to execute for ClearState OnComplete""" args: list[bytes] | None = None + """Application arguments, defaults to None""" account_references: list[str] | None = None + """Account references, defaults to None""" app_references: list[int] | None = None + """App references, defaults to None""" asset_references: list[int] | None = None + """Asset references, defaults to None""" box_references: list[BoxReference | BoxIdentifier] | None = None + """Box references, defaults to None""" on_complete: OnComplete | None = None + """The OnComplete action, defaults to None""" @dataclass(kw_only=True, frozen=True) class AppDeleteParams(_CommonTxnParams): - """Parameters for deleting an application. - - :ivar app_id: ID of the application - :ivar args: Application arguments, defaults to None - :ivar account_references: Account references, defaults to None - :ivar app_references: App references, defaults to None - :ivar asset_references: Asset references, defaults to None - :ivar box_references: Box references, defaults to None - :ivar on_complete: The OnComplete action, defaults to DeleteApplicationOC - """ + """Parameters for deleting an application.""" app_id: int + """The ID of the application""" args: list[bytes] | None = None + """Application arguments, defaults to None""" account_references: list[str] | None = None + """Account references, defaults to None""" app_references: list[int] | None = None + """App references, defaults to None""" asset_references: list[int] | None = None + """Asset references, defaults to None""" box_references: list[BoxReference | BoxIdentifier] | None = None + """Box references, defaults to None""" on_complete: OnComplete = OnComplete.DeleteApplicationOC + """The OnComplete action, defaults to DeleteApplicationOC""" @dataclass(kw_only=True, frozen=True) class _BaseAppMethodCall(_CommonTxnParams): app_id: int + """The ID of the application""" method: Method + """The ABI method to call""" args: list | None = None + """Arguments to the ABI method, defaults to None""" account_references: list[str] | None = None + """Account references, defaults to None""" app_references: list[int] | None = None + """App references, defaults to None""" asset_references: list[int] | None = None + """Asset references, defaults to None""" box_references: list[BoxReference | BoxIdentifier] | None = None + """Box references, defaults to None""" schema: AppCreateSchema | None = None + """The state schema for the app, defaults to None""" + on_complete: OnComplete | None = None + """The OnComplete action, defaults to None""" @dataclass(kw_only=True, frozen=True) class AppMethodCallParams(_CommonTxnParams): - """Parameters for calling an application method. - - :ivar app_id: ID of the application - :ivar method: The ABI method to call - :ivar args: Arguments to the ABI method, defaults to None - :ivar on_complete: The OnComplete action (cannot be UpdateApplication or ClearState), defaults to None - :ivar account_references: Account references, defaults to None - :ivar app_references: App references, defaults to None - :ivar asset_references: Asset references, defaults to None - :ivar box_references: Box references, defaults to None - """ + """Parameters for calling an application method.""" app_id: int + """The ID of the application""" method: Method + """The ABI method to call""" args: list[bytes] | None = None + """Arguments to the ABI method, defaults to None""" on_complete: OnComplete | None = None + """The OnComplete action, defaults to None""" account_references: list[str] | None = None + """Account references, defaults to None""" app_references: list[int] | None = None + """App references, defaults to None""" asset_references: list[int] | None = None + """Asset references, defaults to None""" box_references: list[BoxReference | BoxIdentifier] | None = None + """Box references, defaults to None""" @dataclass(kw_only=True, frozen=True) class AppCallMethodCallParams(_BaseAppMethodCall): - """Parameters for a regular ABI method call. - - :ivar app_id: ID of the application - :ivar method: The ABI method to call - :ivar args: Arguments to the ABI method, either an ABI value, transaction with explicit signer, - transaction, another method call, or None - :ivar on_complete: The OnComplete action (cannot be UpdateApplication or ClearState), defaults to None - """ + """Parameters for a regular ABI method call.""" app_id: int + """The ID of the application""" on_complete: OnComplete | None = None + """The OnComplete action, defaults to None""" @dataclass(kw_only=True, frozen=True) class AppCreateMethodCallParams(_BaseAppMethodCall): - """Parameters for an ABI method call that creates an application. - - :ivar approval_program: The program to execute for all OnCompletes other than ClearState - :ivar clear_state_program: The program to execute for ClearState OnComplete - :ivar schema: The state schema for the app, defaults to None - :ivar on_complete: The OnComplete action (cannot be ClearState), defaults to None - :ivar extra_program_pages: Number of extra pages required for the programs, defaults to None - """ + """Parameters for an ABI method call that creates an application.""" approval_program: str | bytes + """The program to execute for all OnCompletes other than ClearState""" clear_state_program: str | bytes + """The program to execute for ClearState OnComplete""" schema: AppCreateSchema | None = None + """The state schema for the app, defaults to None""" on_complete: OnComplete | None = None + """The OnComplete action (cannot be ClearState), defaults to None""" extra_program_pages: int | None = None + """Number of extra pages required for the programs, defaults to None""" @dataclass(kw_only=True, frozen=True) class AppUpdateMethodCallParams(_BaseAppMethodCall): - """Parameters for an ABI method call that updates an application. - - :ivar app_id: ID of the application - :ivar approval_program: The program to execute for all OnCompletes other than ClearState - :ivar clear_state_program: The program to execute for ClearState OnComplete - :ivar on_complete: The OnComplete action, defaults to UpdateApplicationOC - """ + """Parameters for an ABI method call that updates an application.""" app_id: int + """The ID of the application""" approval_program: str | bytes + """The program to execute for all OnCompletes other than ClearState""" clear_state_program: str | bytes + """The program to execute for ClearState OnComplete""" on_complete: OnComplete = OnComplete.UpdateApplicationOC + """The OnComplete action""" @dataclass(kw_only=True, frozen=True) class AppDeleteMethodCallParams(_BaseAppMethodCall): - """Parameters for an ABI method call that deletes an application. - - :ivar app_id: ID of the application - :ivar on_complete: The OnComplete action, defaults to DeleteApplicationOC - """ + """Parameters for an ABI method call that deletes an application.""" app_id: int + """The ID of the application""" on_complete: OnComplete = OnComplete.DeleteApplicationOC + """The OnComplete action""" MethodCallParams = ( @@ -545,50 +526,44 @@ def from_txn_with_context( @dataclass(frozen=True) class BuiltTransactions: - """Set of transactions built by TransactionComposer. - - :ivar transactions: The built transactions - :ivar method_calls: Any ABIMethod objects associated with any of the transactions in a map keyed by txn id - :ivar signers: Any TransactionSigner objects associated with any of the transactions in a map keyed by txn id - """ + """Set of transactions built by TransactionComposer.""" transactions: list[algosdk.transaction.Transaction] + """The built transactions""" method_calls: dict[int, Method] + """Map of transaction index to ABI method""" signers: dict[int, TransactionSigner] + """Map of transaction index to TransactionSigner""" @dataclass class TransactionComposerBuildResult: - """Result of building transactions with TransactionComposer. - - :ivar atc: The AtomicTransactionComposer instance - :ivar transactions: The list of transactions with signers - :ivar method_calls: Map of transaction index to ABI method - """ + """Result of building transactions with TransactionComposer.""" atc: AtomicTransactionComposer + """The AtomicTransactionComposer instance""" transactions: list[TransactionWithSigner] + """The list of transactions with signers""" method_calls: dict[int, Method] + """Map of transaction index to ABI method""" @dataclass class SendAtomicTransactionComposerResults: - """Results from sending an AtomicTransactionComposer transaction group. - - :ivar group_id: The group ID if this was a transaction group - :ivar confirmations: The confirmation info for each transaction - :ivar tx_ids: The transaction IDs that were sent - :ivar transactions: The transactions that were sent - :ivar returns: The ABI return values from any ABI method calls - :ivar simulate_response: The simulation response if simulation was performed, defaults to None - """ + """Results from sending an AtomicTransactionComposer transaction group.""" group_id: str + """The group ID if this was a transaction group""" confirmations: list[algosdk.v2client.algod.AlgodResponseType] + """The confirmation info for each transaction""" tx_ids: list[str] + """The transaction IDs that were sent""" transactions: list[TransactionWrapper] + """The transactions that were sent""" returns: list[ABIReturn] + """The ABI return values from any ABI method calls""" simulate_response: dict[str, Any] | None = None + """The simulation response if simulation was performed, defaults to None""" class UnnamedResourcesAccessed: @@ -611,8 +586,12 @@ def __init__(self, resources_accessed: dict[str, Any] | None = None): @dataclass class ExecutionInfoTxn: + """Execution info for a transaction.""" + unnamed_resources_accessed: UnnamedResourcesAccessed | None = None + """The unnamed resources accessed in the transaction""" required_fee_delta: int = 0 + """The required fee delta for the transaction""" @dataclass @@ -620,7 +599,9 @@ class ExecutionInfo: """Information about transaction execution from simulation.""" group_unnamed_resources_accessed: UnnamedResourcesAccessed | None = None + """The unnamed resources accessed in the group""" txns: list[ExecutionInfoTxn] | None = None + """The execution info for each transaction""" @dataclass @@ -1377,6 +1358,9 @@ def add_transaction( :param transaction: The transaction to add :param signer: Optional transaction signer, defaults to getting signer from transaction sender :return: The transaction composer instance for chaining + + :example: + >>> composer.add_transaction(transaction) """ self._txns.append(TransactionWithSigner(txn=transaction, signer=signer or self._get_signer(transaction.sender))) return self @@ -1384,6 +1368,16 @@ def add_transaction( def add_payment(self, params: PaymentParams) -> TransactionComposer: """Add a payment transaction. + :example: + >>> params = PaymentParams( + ... sender="SENDER_ADDRESS", + ... receiver="RECEIVER_ADDRESS", + ... amount=AlgoAmount.from_algo(1), + ... close_remainder_to="CLOSE_ADDRESS" + ... ... (see PaymentParams for more options) + ... ) + >>> composer.add_payment(params) + :param params: The payment transaction parameters :return: The transaction composer instance for chaining """ @@ -1393,6 +1387,22 @@ def add_payment(self, params: PaymentParams) -> TransactionComposer: def add_asset_create(self, params: AssetCreateParams) -> TransactionComposer: """Add an asset creation transaction. + :example: + >>> params = AssetCreateParams( + ... sender="SENDER_ADDRESS", + ... total=1000, + ... asset_name="MyAsset", + ... unit_name="MA", + ... url="https://example.com", + ... decimals=0, + ... default_frozen=False, + ... manager="MANAGER_ADDRESS", + ... reserve="RESERVE_ADDRESS", + ... freeze="FREEZE_ADDRESS", + ... clawback="CLAWBACK_ADDRESS" + ... ... (see AssetCreateParams for more options) + >>> composer.add_asset_create(params) + :param params: The asset creation parameters :return: The transaction composer instance for chaining """ @@ -1402,6 +1412,18 @@ def add_asset_create(self, params: AssetCreateParams) -> TransactionComposer: def add_asset_config(self, params: AssetConfigParams) -> TransactionComposer: """Add an asset configuration transaction. + :example: + >>> params = AssetConfigParams( + ... sender="SENDER_ADDRESS", + ... asset_id=123456, + ... manager="NEW_MANAGER_ADDRESS", + ... reserve="NEW_RESERVE_ADDRESS", + ... freeze="NEW_FREEZE_ADDRESS", + ... clawback="NEW_CLAWBACK_ADDRESS" + ... ... (see AssetConfigParams for more options) + ... ) + >>> composer.add_asset_config(params) + :param params: The asset configuration parameters :return: The transaction composer instance for chaining """ @@ -1411,6 +1433,16 @@ def add_asset_config(self, params: AssetConfigParams) -> TransactionComposer: def add_asset_freeze(self, params: AssetFreezeParams) -> TransactionComposer: """Add an asset freeze transaction. + :example: + >>> params = AssetFreezeParams( + ... sender="SENDER_ADDRESS", + ... asset_id=123456, + ... account="ACCOUNT_TO_FREEZE", + ... frozen=True + ... ... (see AssetFreezeParams for more options) + ... ) + >>> composer.add_asset_freeze(params) + :param params: The asset freeze parameters :return: The transaction composer instance for chaining """ @@ -1420,6 +1452,13 @@ def add_asset_freeze(self, params: AssetFreezeParams) -> TransactionComposer: def add_asset_destroy(self, params: AssetDestroyParams) -> TransactionComposer: """Add an asset destruction transaction. + :example: + >>> params = AssetDestroyParams( + ... sender="SENDER_ADDRESS", + ... asset_id=123456 + ... ... (see AssetDestroyParams for more options) + >>> composer.add_asset_destroy(params) + :param params: The asset destruction parameters :return: The transaction composer instance for chaining """ @@ -1429,6 +1468,17 @@ def add_asset_destroy(self, params: AssetDestroyParams) -> TransactionComposer: def add_asset_transfer(self, params: AssetTransferParams) -> TransactionComposer: """Add an asset transfer transaction. + :example: + >>> params = AssetTransferParams( + ... sender="SENDER_ADDRESS", + ... asset_id=123456, + ... amount=10, + ... receiver="RECEIVER_ADDRESS", + ... clawback_target="CLAWBACK_TARGET_ADDRESS", + ... close_asset_to="CLOSE_ADDRESS" + ... ... (see AssetTransferParams for more options) + >>> composer.add_asset_transfer(params) + :param params: The asset transfer parameters :return: The transaction composer instance for chaining """ @@ -1438,6 +1488,14 @@ def add_asset_transfer(self, params: AssetTransferParams) -> TransactionComposer def add_asset_opt_in(self, params: AssetOptInParams) -> TransactionComposer: """Add an asset opt-in transaction. + :example: + >>> params = AssetOptInParams( + ... sender="SENDER_ADDRESS", + ... asset_id=123456 + ... ... (see AssetOptInParams for more options) + ... ) + >>> composer.add_asset_opt_in(params) + :param params: The asset opt-in parameters :return: The transaction composer instance for chaining """ @@ -1447,6 +1505,14 @@ def add_asset_opt_in(self, params: AssetOptInParams) -> TransactionComposer: def add_asset_opt_out(self, params: AssetOptOutParams) -> TransactionComposer: """Add an asset opt-out transaction. + :example: + >>> params = AssetOptOutParams( + ... sender="SENDER_ADDRESS", + ... asset_id=123456, + ... creator="CREATOR_ADDRESS" + ... ... (see AssetOptOutParams for more options) + >>> composer.add_asset_opt_out(params) + :param params: The asset opt-out parameters :return: The transaction composer instance for chaining """ @@ -1456,6 +1522,23 @@ def add_asset_opt_out(self, params: AssetOptOutParams) -> TransactionComposer: def add_app_create(self, params: AppCreateParams) -> TransactionComposer: """Add an application creation transaction. + :example: + >>> params = AppCreateParams( + ... sender="SENDER_ADDRESS", + ... approval_program="TEAL_APPROVAL_CODE", + ... clear_state_program="TEAL_CLEAR_CODE", + ... schema={'global_ints': 1, 'global_byte_slices': 1, 'local_ints': 1, 'local_byte_slices': 1}, + ... on_complete=OnComplete.NoOpOC, + ... args=[b'arg1'], + ... account_references=["ACCOUNT1"], + ... app_references=[789], + ... asset_references=[123], + ... box_references=[], + ... extra_program_pages=0 + ... ... (see AppCreateParams for more options) + ... ) + >>> composer.add_app_create(params) + :param params: The application creation parameters :return: The transaction composer instance for chaining """ @@ -1465,6 +1548,21 @@ def add_app_create(self, params: AppCreateParams) -> TransactionComposer: def add_app_update(self, params: AppUpdateParams) -> TransactionComposer: """Add an application update transaction. + :example: + >>> params = AppUpdateParams( + ... sender="SENDER_ADDRESS", + ... app_id=789, + ... approval_program="TEAL_NEW_APPROVAL_CODE", + ... clear_state_program="TEAL_NEW_CLEAR_CODE", + ... args=[b'new_arg1'], + ... account_references=["ACCOUNT1"], + ... app_references=[789], + ... asset_references=[123], + ... box_references=[], + ... on_complete=OnComplete.UpdateApplicationOC + ... ... (see AppUpdateParams for more options) + >>> composer.add_app_update(params) + :param params: The application update parameters :return: The transaction composer instance for chaining """ @@ -1474,6 +1572,19 @@ def add_app_update(self, params: AppUpdateParams) -> TransactionComposer: def add_app_delete(self, params: AppDeleteParams) -> TransactionComposer: """Add an application deletion transaction. + :example: + >>> params = AppDeleteParams( + ... sender="SENDER_ADDRESS", + ... app_id=789, + ... args=[b'delete_arg'], + ... account_references=["ACCOUNT1"], + ... app_references=[789], + ... asset_references=[123], + ... box_references=[], + ... on_complete=OnComplete.DeleteApplicationOC + ... ... (see AppDeleteParams for more options) + >>> composer.add_app_delete(params) + :param params: The application deletion parameters :return: The transaction composer instance for chaining """ @@ -1483,6 +1594,18 @@ def add_app_delete(self, params: AppDeleteParams) -> TransactionComposer: def add_app_call(self, params: AppCallParams) -> TransactionComposer: """Add an application call transaction. + :example: + >>> params = AppCallParams( + ... sender="SENDER_ADDRESS", + ... on_complete=OnComplete.NoOpOC, + ... app_id=789, + ... approval_program="TEAL_APPROVAL_CODE", + ... clear_state_program="TEAL_CLEAR_CODE", + ... schema={'global_ints': 1, 'global_byte_slices': 1, 'local_ints': 1, 'local_byte_slices': 1}, + ... ... (see AppCallParams for more options) + ... ) + >>> composer.add_app_call(params) + :param params: The application call parameters :return: The transaction composer instance for chaining """ @@ -1494,6 +1617,59 @@ def add_app_create_method_call(self, params: AppCreateMethodCallParams) -> Trans :param params: The application creation method call parameters :return: The transaction composer instance for chaining + + :example: + >>> # Basic example + >>> method = algosdk.abi.Method( + ... name="method", + ... args=[...], + ... returns="string" + ... ) + >>> composer.add_app_create_method_call( + ... AppCreateMethodCallParams( + ... sender="CREATORADDRESS", + ... approval_program="TEALCODE", + ... clear_state_program="TEALCODE", + ... method=method, + ... args=["arg1_value"] + ... ) + ... ) + >>> + >>> # Advanced example + >>> method = ABIMethod( + ... name="method", + ... args=[{"name": "arg1", "type": "string"}], + ... returns={"type": "string"} + ... ) + >>> composer.add_app_create_method_call( + ... AppCreateMethodCallParams( + ... sender="CREATORADDRESS", + ... method=method, + ... args=["arg1_value"], + ... approval_program="TEALCODE", + ... clear_state_program="TEALCODE", + ... schema={ + ... "global_ints": 1, + ... "global_byte_slices": 2, + ... "local_ints": 3, + ... "local_byte_slices": 4 + ... }, + ... extra_pages=1, + ... on_complete=OnComplete.OptInOC, + ... args=[bytes([1, 2, 3, 4])], + ... account_references=["ACCOUNT_1"], + ... app_references=[123, 1234], + ... asset_references=[12345], + ... box_references=["box1", {"app_id": 1234, "name": "box2"}], + ... lease="lease", + ... note="note", + ... first_valid_round=1000, + ... validity_window=10, + ... extra_fee=AlgoAmount.from_micro_algos(1000), + ... static_fee=AlgoAmount.from_micro_algos(1000), + ... max_fee=AlgoAmount.from_micro_algos(3000) + ... ) + ... ) """ self._txns.append(params) return self @@ -1548,6 +1724,11 @@ def add_atc(self, atc: AtomicTransactionComposer) -> TransactionComposer: :param atc: The AtomicTransactionComposer to add :return: The transaction composer instance for chaining + + :example: + >>> atc = AtomicTransactionComposer() + >>> atc.add_transaction(TransactionWithSigner(transaction, signer)) + >>> composer.add_atc(atc) """ self._txns.append(atc) return self @@ -1708,6 +1889,9 @@ def simulate( :param simulation_round: Round number to simulate at :param skip_signatures: Whether to skip signature validation :return: The simulation results + + :example: + >>> result = composer.simulate(extra_opcode_budget=1000, skip_signatures=True, ...) """ from algokit_utils._debugging import simulate_and_persist_response, simulate_response diff --git a/src/algokit_utils/transactions/transaction_creator.py b/src/algokit_utils/transactions/transaction_creator.py index cff47510..e4081d06 100644 --- a/src/algokit_utils/transactions/transaction_creator.py +++ b/src/algokit_utils/transactions/transaction_creator.py @@ -41,6 +41,10 @@ class AlgorandClientTransactionCreator: asset operations, application calls and key registrations. :param new_group: A lambda that starts a new TransactionComposer transaction group + + :example: + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> creator.payment(PaymentParams(sender="sender", receiver="receiver", amount=AlgoAmount.from_algo(1))) """ def __init__(self, new_group: Callable[[], TransactionComposer]) -> None: @@ -67,90 +71,618 @@ def create_transactions(params: TxnParam) -> BuiltTransactions: @property def payment(self) -> Callable[[PaymentParams], Transaction]: - """Create a payment transaction to transfer Algo between accounts.""" + """Create a payment transaction to transfer Algo between accounts. + + :example: + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> creator.payment(PaymentParams(sender="sender", receiver="receiver", amount=AlgoAmount.from_algo(4))) + :example: + >>> #Advanced example + >>> creator.payment(PaymentParams( + sender="SENDERADDRESS", + receiver="RECEIVERADDRESS", + amount=AlgoAmount.from_algo(4), + close_remainder_to="CLOSEREMAINDERTOADDRESS", + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + """ return self._transaction(lambda c: c.add_payment) @property def asset_create(self) -> Callable[[AssetCreateParams], Transaction]: - """Create a create Algorand Standard Asset transaction.""" + """Create a create Algorand Standard Asset transaction. + + :example: + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AssetCreateParams(sender="SENDER_ADDRESS", total=1000) + >>> txn = creator.asset_create(params) + :example: + >>> #Advanced example + >>> creator.asset_create(AssetCreateParams( + sender="SENDER_ADDRESS", + total=1000, + asset_name="MyAsset", + unit_name="MA", + url="https://example.com/asset", + decimals=0, + default_frozen=False, + manager="MANAGER_ADDRESS", + reserve="RESERVE_ADDRESS", + freeze="FREEZE_ADDRESS", + clawback="CLAWBACK_ADDRESS", + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + """ return self._transaction(lambda c: c.add_asset_create) @property def asset_config(self) -> Callable[[AssetConfigParams], Transaction]: - """Create an asset config transaction to reconfigure an existing Algorand Standard Asset.""" + """Create an asset config transaction to reconfigure an existing Algorand Standard Asset. + + :example: + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AssetConfigParams(sender="SENDER_ADDRESS", asset_id=123456, manager="NEW_MANAGER_ADDRESS") + >>> txn = creator.asset_config(params) + :example: + >>> #Advanced example + >>> creator.asset_config(AssetConfigParams( + sender="SENDER_ADDRESS", + asset_id=123456, + manager="NEW_MANAGER_ADDRESS", + reserve="NEW_RESERVE_ADDRESS", + freeze="NEW_FREEZE_ADDRESS", + clawback="NEW_CLAWBACK_ADDRESS", + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + """ return self._transaction(lambda c: c.add_asset_config) @property def asset_freeze(self) -> Callable[[AssetFreezeParams], Transaction]: - """Create an Algorand Standard Asset freeze transaction.""" + """Create an Algorand Standard Asset freeze transaction. + + :example: + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AssetFreezeParams(sender="SENDER_ADDRESS", + asset_id=123456, + account="ACCOUNT_TO_FREEZE", + frozen=True) + >>> txn = creator.asset_freeze(params) + + :example: + >>> #Advanced example + >>> creator.asset_freeze(AssetFreezeParams( + sender="SENDER_ADDRESS", + asset_id=123456, + account="ACCOUNT_TO_FREEZE", + frozen=True, + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + """ return self._transaction(lambda c: c.add_asset_freeze) @property def asset_destroy(self) -> Callable[[AssetDestroyParams], Transaction]: - """Create an Algorand Standard Asset destroy transaction.""" + """Create an Algorand Standard Asset destroy transaction. + + :example: + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AssetDestroyParams(sender="SENDER_ADDRESS", asset_id=123456) + >>> txn = creator.asset_destroy(params) + + :example: + >>> #Advanced example + >>> creator.asset_destroy(AssetDestroyParams( + sender="SENDER_ADDRESS", + asset_id=123456, + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + """ return self._transaction(lambda c: c.add_asset_destroy) @property def asset_transfer(self) -> Callable[[AssetTransferParams], Transaction]: - """Create an Algorand Standard Asset transfer transaction.""" + """Create an Algorand Standard Asset transfer transaction. + + :example: + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AssetTransferParams(sender="SENDER_ADDRESS", + asset_id=123456, + amount=10, + receiver="RECEIVER_ADDRESS") + >>> txn = creator.asset_transfer(params) + + :example: + >>> #Advanced example + >>> creator.asset_transfer(AssetTransferParams( + sender="SENDER_ADDRESS", + asset_id=123456, + amount=10, + receiver="RECEIVER_ADDRESS", + clawback_target="CLAWBACK_TARGET_ADDRESS", + close_asset_to="CLOSE_ASSET_TO_ADDRESS", + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + """ return self._transaction(lambda c: c.add_asset_transfer) @property def asset_opt_in(self) -> Callable[[AssetOptInParams], Transaction]: - """Create an Algorand Standard Asset opt-in transaction.""" + """Create an Algorand Standard Asset opt-in transaction. + + :example: + >>> # Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AssetOptInParams(sender="SENDER_ADDRESS", asset_id=123456) + >>> txn = creator.asset_opt_in(params) + + :example: + >>> # Advanced example + >>> creator.asset_opt_in(AssetOptInParams( + sender="SENDER_ADDRESS", + asset_id=123456, + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + """ return self._transaction(lambda c: c.add_asset_opt_in) @property def asset_opt_out(self) -> Callable[[AssetOptOutParams], Transaction]: - """Create an asset opt-out transaction.""" + """Create an asset opt-out transaction. + + :example: + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AssetOptOutParams(sender="SENDER_ADDRESS", asset_id=123456, creator="CREATOR_ADDRESS") + >>> txn = creator.asset_opt_out(params) + + :example: + >>> #Advanced example + >>> creator.asset_opt_out(AssetOptOutParams( + sender="SENDER_ADDRESS", + asset_id=123456, + creator="CREATOR_ADDRESS", + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + """ return self._transaction(lambda c: c.add_asset_opt_out) @property def app_create(self) -> Callable[[AppCreateParams], Transaction]: - """Create an application create transaction.""" + """Create an application create transaction. + + :example: + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AppCreateParams( + ... sender="SENDER_ADDRESS", + ... approval_program="TEAL_APPROVAL_CODE", + ... clear_state_program="TEAL_CLEAR_CODE", + ... schema={ + ... 'global_ints': 1, + ... 'global_byte_slices': 1, + ... 'local_ints': 1, + ... 'local_byte_slices': 1 + ... } + ... ) + >>> txn = creator.app_create(params) + + :example: + >>> #Advanced example + >>> creator.app_create(AppCreateParams( + sender="SENDER_ADDRESS", + approval_program="TEAL_APPROVAL_CODE", + clear_state_program="TEAL_CLEAR_CODE", + schema={'global_ints': 1, 'global_byte_slices': 1, 'local_ints': 1, 'local_byte_slices': 1}, + on_complete=OnComplete.NoOpOC, + args=[b'arg1', b'arg2'], + account_references=["ACCOUNT1"], + app_references=[789], + asset_references=[123], + box_references=[], + extra_program_pages=0, + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + """ return self._transaction(lambda c: c.add_app_create) @property def app_update(self) -> Callable[[AppUpdateParams], Transaction]: - """Create an application update transaction.""" + """Create an application update transaction. + + :example: + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> txn = creator.app_update(AppUpdateParams(sender="SENDER_ADDRESS", + app_id=789, + approval_program="TEAL_NEW_APPROVAL_CODE", + clear_state_program="TEAL_NEW_CLEAR_CODE", + args=[b'new_arg1', b'new_arg2'])) + + :example: + >>> #Advanced example + >>> creator.app_update(AppUpdateParams( + sender="SENDER_ADDRESS", + app_id=789, + approval_program="TEAL_NEW_APPROVAL_CODE", + clear_state_program="TEAL_NEW_CLEAR_CODE", + args=[b'new_arg1', b'new_arg2'], + account_references=["ACCOUNT1"], + app_references=[789], + asset_references=[123], + box_references=[], + on_complete=OnComplete.UpdateApplicationOC, + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + """ return self._transaction(lambda c: c.add_app_update) @property def app_delete(self) -> Callable[[AppDeleteParams], Transaction]: - """Create an application delete transaction.""" + """Create an application delete transaction. + + :example: + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AppDeleteParams(sender="SENDER_ADDRESS", app_id=789, args=[b'delete_arg']) + >>> txn = creator.app_delete(params) + + :example: + >>> #Advanced example + >>> creator.app_delete(AppDeleteParams( + sender="SENDER_ADDRESS", + app_id=789, + args=[b'delete_arg'], + account_references=["ACCOUNT1"], + app_references=[789], + asset_references=[123], + box_references=[], + on_complete=OnComplete.DeleteApplicationOC, + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + """ return self._transaction(lambda c: c.add_app_delete) @property def app_call(self) -> Callable[[AppCallParams], Transaction]: - """Create an application call transaction.""" + """Create an application call transaction. + + :example: + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AppCallParams( + ... sender="SENDER_ADDRESS", + ... on_complete=OnComplete.NoOpOC, + ... app_id=789, + ... approval_program="TEAL_APPROVAL_CODE", + ... clear_state_program="TEAL_CLEAR_CODE", + ... schema={ + ... 'global_ints': 1, + ... 'global_byte_slices': 1, + ... 'local_ints': 1, + ... 'local_byte_slices': 1 + ... }, + ... args=[b'arg1', b'arg2'], + ... account_references=["ACCOUNT1"], + ... app_references=[789], + ... asset_references=[123], + ... extra_pages=0, + ... box_references=[] + ... ) + >>> txn = creator.app_call(params) + + :example: + >>> #Advanced example + >>> creator.app_call(AppCallParams( + sender="SENDER_ADDRESS", + on_complete=OnComplete.NoOpOC, + app_id=789, + approval_program="TEAL_APPROVAL_CODE", + clear_state_program="TEAL_CLEAR_CODE", + schema={'global_ints': 1, 'global_byte_slices': 1, 'local_ints': 1, 'local_byte_slices': 1}, + args=[b'arg1', b'arg2'], + account_references=["ACCOUNT1"], + app_references=[789], + asset_references=[123], + extra_pages=0, + box_references=[], + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + """ return self._transaction(lambda c: c.add_app_call) @property def app_create_method_call(self) -> Callable[[AppCreateMethodCallParams], BuiltTransactions]: - """Create an application create call with ABI method call transaction.""" + """Create an application create call with ABI method call transaction. + + :example: + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AppCreateMethodCallParams(sender="SENDER_ADDRESS", app_id=0, method=some_abi_method_object) + >>> built_txns = creator.app_create_method_call(params) + + :example: + >>> #Advanced example + >>> creator.app_create_method_call(AppCreateMethodCallParams( + sender="SENDER_ADDRESS", + app_id=0, + method=some_abi_method_object, + args=[b'method_arg'], + account_references=["ACCOUNT1"], + app_references=[789], + asset_references=[123], + box_references=[], + schema={'global_ints': 1, 'global_byte_slices': 1, 'local_ints': 1, 'local_byte_slices': 1}, + approval_program="TEAL_APPROVAL_CODE", + clear_state_program="TEAL_CLEAR_CODE", + on_complete=OnComplete.NoOpOC, + extra_program_pages=0, + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + """ return self._transactions(lambda c: c.add_app_create_method_call) @property def app_update_method_call(self) -> Callable[[AppUpdateMethodCallParams], BuiltTransactions]: - """Create an application update call with ABI method call transaction.""" + """Create an application update call with ABI method call transaction. + + :example: + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AppUpdateMethodCallParams(sender="SENDER_ADDRESS", app_id=789, method=some_abi_method_object) + >>> built_txns = creator.app_update_method_call(params) + + :example: + >>> #Advanced example + >>> creator.app_update_method_call(AppUpdateMethodCallParams( + sender="SENDER_ADDRESS", + app_id=789, + method=some_abi_method_object, + args=[b'method_arg'], + account_references=["ACCOUNT1"], + app_references=[789], + asset_references=[123], + box_references=[], + schema={'global_ints': 1, 'global_byte_slices': 1, 'local_ints': 1, 'local_byte_slices': 1}, + approval_program="TEAL_NEW_APPROVAL_CODE", + clear_state_program="TEAL_NEW_CLEAR_CODE", + on_complete=OnComplete.UpdateApplicationOC, + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + """ return self._transactions(lambda c: c.add_app_update_method_call) @property def app_delete_method_call(self) -> Callable[[AppDeleteMethodCallParams], BuiltTransactions]: - """Create an application delete call with ABI method call transaction.""" + """Create an application delete call with ABI method call transaction. + + :example: + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AppDeleteMethodCallParams(sender="SENDER_ADDRESS", app_id=789, method=some_abi_method_object) + >>> built_txns = creator.app_delete_method_call(params) + + :example: + >>> #Advanced example + >>> creator.app_delete_method_call(AppDeleteMethodCallParams( + sender="SENDER_ADDRESS", + app_id=789, + method=some_abi_method_object, + args=[b'method_arg'], + account_references=["ACCOUNT1"], + app_references=[789], + asset_references=[123], + box_references=[], + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + """ return self._transactions(lambda c: c.add_app_delete_method_call) @property def app_call_method_call(self) -> Callable[[AppCallMethodCallParams], BuiltTransactions]: - """Create an application call with ABI method call transaction.""" + """Create an application call with ABI method call transaction. + + :example: + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = AppCallMethodCallParams(sender="SENDER_ADDRESS", app_id=789, method=some_abi_method_object) + >>> built_txns = creator.app_call_method_call(params) + :example: Advanced example + >>> creator.app_call_method_call(AppCallMethodCallParams( + sender="SENDER_ADDRESS", + app_id=789, + method=some_abi_method_object, + args=[b'method_arg'], + account_references=["ACCOUNT1"], + app_references=[789], + asset_references=[123], + box_references=[], + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + """ return self._transactions(lambda c: c.add_app_call_method_call) @property def online_key_registration(self) -> Callable[[OnlineKeyRegistrationParams], Transaction]: - """Create an online key registration transaction.""" + """Create an online key registration transaction. + + :example: + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> params = OnlineKeyRegistrationParams( + sender="SENDER_ADDRESS", + vote_key="VOTE_KEY", + selection_key="SELECTION_KEY", + vote_first=1000, + vote_last=2000, + vote_key_dilution=10, + state_proof_key=b"state_proof_key_bytes" + ) + >>> txn = creator.online_key_registration(params) + + :example: + >>> #Advanced example + >>> creator.online_key_registration(OnlineKeyRegistrationParams( + sender="SENDER_ADDRESS", + vote_key="VOTE_KEY", + selection_key="SELECTION_KEY", + vote_first=1000, + vote_last=2000, + vote_key_dilution=10, + state_proof_key=b"state_proof_key_bytes", + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + """ return self._transaction(lambda c: c.add_online_key_registration) @property def offline_key_registration(self) -> Callable[[OfflineKeyRegistrationParams], Transaction]: - """Create an offline key registration transaction.""" + """Create an offline key registration transaction. + + :example: + >>> #Basic example + >>> creator = AlgorandClientTransactionCreator(lambda: TransactionComposer()) + >>> txn = creator.offline_key_registration(OfflineKeyRegistrationParams(sender="SENDER_ADDRESS", + prevent_account_from_ever_participating_again=True)) + + :example: + >>> #Advanced example + >>> creator.offline_key_registration(OfflineKeyRegistrationParams( + sender="SENDER_ADDRESS", + prevent_account_from_ever_participating_again=True, + lease="lease", + note=b"note", + rekey_to="REKEYTOADDRESS", + first_valid_round=1000, + validity_window=10, + extra_fee=AlgoAmount.from_micro_algo(1000), + static_fee=AlgoAmount.from_micro_algo(1000), + max_fee=AlgoAmount.from_micro_algo(3000) + )) + """ return self._transaction(lambda c: c.add_offline_key_registration) diff --git a/src/algokit_utils/transactions/transaction_sender.py b/src/algokit_utils/transactions/transaction_sender.py index e11b83dd..97831a2f 100644 --- a/src/algokit_utils/transactions/transaction_sender.py +++ b/src/algokit_utils/transactions/transaction_sender.py @@ -59,15 +59,28 @@ class SendSingleTransactionResult: """ transaction: TransactionWrapper # Last transaction + """The last transaction""" + confirmation: algosdk.v2client.algod.AlgodResponseType # Last confirmation + """The last confirmation""" # Fields from SendAtomicTransactionComposerResults group_id: str + """The group ID""" + tx_id: str | None = None + """The transaction ID""" + tx_ids: list[str] # Full array of transaction IDs + """The full array of transaction IDs""" transactions: list[TransactionWrapper] + """The full array of transactions""" + confirmations: list[algosdk.v2client.algod.AlgodResponseType] + """The full array of confirmations""" + returns: list[ABIReturn] | None = None + """The ABI return value if applicable""" @classmethod def from_composer_result(cls, result: SendAtomicTransactionComposerResults, index: int = -1) -> Self: @@ -111,6 +124,7 @@ class SendSingleAssetCreateTransactionResult(SendSingleTransactionResult): """ asset_id: int + """The ID of the newly created asset""" ABIReturnT = TypeVar("ABIReturnT") @@ -124,6 +138,7 @@ class SendAppTransactionResult(SendSingleTransactionResult, Generic[ABIReturnT]) """ abi_return: ABIReturnT | None = None + """The ABI return value if applicable""" @dataclass(frozen=True) @@ -134,7 +149,10 @@ class SendAppUpdateTransactionResult(SendAppTransactionResult[ABIReturnT]): """ compiled_approval: Any | None = None + """The compiled approval program""" + compiled_clear: Any | None = None + """The compiled clear state program""" @dataclass(frozen=True, kw_only=True) @@ -145,7 +163,10 @@ class SendAppCreateTransactionResult(SendAppUpdateTransactionResult[ABIReturnT]) """ app_id: int + """The ID of the newly created application""" + app_address: str + """The address of the newly created application""" class AlgorandClientTransactionSender: @@ -171,6 +192,12 @@ def new_group(self) -> TransactionComposer: """Create a new transaction group. :return: A new TransactionComposer instance + + :example: + >>> sender = AlgorandClientTransactionSender(new_group, asset_manager, app_manager, algod_client) + >>> composer = sender.new_group() + >>> composer(PaymentParams(sender="sender", receiver="receiver", amount=AlgoAmount(algo=1))) + >>> composer.send() """ return self._new_group() @@ -292,6 +319,33 @@ def payment(self, params: PaymentParams, send_params: SendParams | None = None) :param params: Payment transaction parameters :param send_params: Send parameters :return: Result of the payment transaction + + :example: + >>> result = algorand.send.payment(PaymentParams( + >>> sender="SENDERADDRESS", + >>> receiver="RECEIVERADDRESS", + >>> amount=AlgoAmount(algo=4), + >>> )) + + >>> # Advanced example + >>> result = algorand.send.payment(PaymentParams( + >>> amount=AlgoAmount(algo=4), + >>> receiver="RECEIVERADDRESS", + >>> sender="SENDERADDRESS", + >>> close_remainder_to="CLOSEREMAINDERTOADDRESS", + >>> lease="lease", + >>> note="note", + >>> rekey_to="REKEYTOADDRESS", + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> signer=transactionSigner + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) """ return self._send( lambda c: c.add_payment, @@ -309,6 +363,47 @@ def asset_create( :param params: Asset creation parameters :param send_params: Send parameters :return: Result containing the new asset ID + + :example: + >>> result = algorand.send.asset_create(AssetCreateParams( + >>> sender="SENDERADDRESS", + >>> asset_name="ASSETNAME", + >>> unit_name="UNITNAME", + >>> total=1000, + >>> )) + + >>> # Advanced example + >>> result = algorand.send.asset_create(AssetCreateParams( + >>> sender="CREATORADDRESS", + >>> total=100, + >>> decimals=2, + >>> asset_name="asset", + >>> unit_name="unit", + >>> url="url", + >>> metadata_hash="metadataHash", + >>> default_frozen=False, + >>> manager="MANAGERADDRESS", + >>> reserve="RESERVEADDRESS", + >>> freeze="FREEZEADDRESS", + >>> clawback="CLAWBACKADDRESS", + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) """ result = self._send( lambda c: c.add_asset_create, @@ -334,6 +429,33 @@ def asset_config( :param params: Asset configuration parameters :param send_params: Send parameters :return: Result of the configuration transaction + + :example: + >>> result = algorand.send.asset_config(AssetConfigParams( + >>> sender="MANAGERADDRESS", + >>> asset_id=123456, + >>> manager="MANAGERADDRESS", + >>> reserve="RESERVEADDRESS", + >>> freeze="FREEZEADDRESS", + >>> clawback="CLAWBACKADDRESS", + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) """ return self._send( lambda c: c.add_asset_config, @@ -350,6 +472,39 @@ def asset_freeze( :param params: Asset freeze parameters :param send_params: Send parameters :return: Result of the freeze transaction + + :example: + >>> result = algorand.send.asset_freeze(AssetFreezeParams( + >>> sender="MANAGERADDRESS", + >>> asset_id=123456, + >>> account="ACCOUNTADDRESS", + >>> frozen=True, + >>> )) + + >>> # Advanced example + >>> result = algorand.send.asset_freeze(AssetFreezeParams( + >>> sender="MANAGERADDRESS", + >>> asset_id=123456, + >>> account="ACCOUNTADDRESS", + >>> frozen=True, + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) """ return self._send( lambda c: c.add_asset_freeze, @@ -366,6 +521,35 @@ def asset_destroy( :param params: Asset destruction parameters :param send_params: Send parameters :return: Result of the destroy transaction + + :example: + >>> result = algorand.send.asset_destroy(AssetDestroyParams( + >>> sender="MANAGERADDRESS", + >>> asset_id=123456, + >>> )) + + >>> # Advanced example + >>> result = algorand.send.asset_destroy(AssetDestroyParams( + >>> sender="MANAGERADDRESS", + >>> asset_id=123456, + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) """ return self._send( lambda c: c.add_asset_destroy, @@ -382,6 +566,42 @@ def asset_transfer( :param params: Asset transfer parameters :param send_params: Send parameters :return: Result of the transfer transaction + + :example: + >>> result = algorand.send.asset_transfer(AssetTransferParams( + >>> sender="HOLDERADDRESS", + >>> asset_id=123456, + >>> amount=1, + >>> receiver="RECEIVERADDRESS", + >>> )) + + >>> # Advanced example (with clawback) + >>> result = algorand.send.asset_transfer(AssetTransferParams( + >>> sender="CLAWBACKADDRESS", + >>> asset_id=123456, + >>> amount=1, + >>> receiver="RECEIVERADDRESS", + >>> clawback_target="HOLDERADDRESS", + >>> # This field needs to be used with caution + >>> close_asset_to="ADDRESSTOCLOSETO", + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) """ return self._send( lambda c: c.add_asset_transfer, @@ -399,6 +619,35 @@ def asset_opt_in( :param params: Asset opt-in parameters :param send_params: Send parameters :return: Result of the opt-in transaction + + :example: + >>> result = algorand.send.asset_opt_in(AssetOptInParams( + >>> sender="SENDERADDRESS", + >>> asset_id=123456, + >>> )) + + >>> # Advanced example + >>> result = algorand.send.asset_opt_in(AssetOptInParams( + >>> sender="SENDERADDRESS", + >>> asset_id=123456, + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) """ return self._send( lambda c: c.add_asset_opt_in, @@ -422,6 +671,39 @@ def asset_opt_out( :param ensure_zero_balance: Check if account has zero balance before opt-out, defaults to True :raises ValueError: If account has non-zero balance or is not opted in :return: Result of the opt-out transaction + + :example: + >>> result = algorand.send.asset_opt_out(AssetOptOutParams( + >>> sender="SENDERADDRESS", + >>> creator="CREATORADDRESS", + >>> asset_id=123456, + >>> ensure_zero_balance=True, + >>> )) + + >>> # Advanced example + >>> result = algorand.send.asset_opt_out(AssetOptOutParams( + >>> sender="SENDERADDRESS", + >>> asset_id=123456, + >>> creator="CREATORADDRESS", + >>> ensure_zero_balance=True, + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) """ if ensure_zero_balance: try: @@ -461,6 +743,55 @@ def app_create( :param params: Application creation parameters :param send_params: Send parameters :return: Result containing the new application ID and address + + :example: + >>> result = algorand.send.app_create(AppCreateParams( + >>> sender="CREATORADDRESS", + >>> approval_program="TEALCODE", + >>> clear_state_program="TEALCODE", + >>> )) + + >>> # Advanced example + >>> result = algorand.send.app_create(AppCreateParams( + >>> sender="CREATORADDRESS", + >>> approval_program="TEALCODE", + >>> clear_state_program="TEALCODE", + >>> )) + >>> # algorand.send.appCreate(AppCreateParams( + >>> # sender='CREATORADDRESS', + >>> # approval_program="TEALCODE", + >>> # clear_state_program="TEALCODE", + >>> # schema={ + >>> # "global_ints": 1, + >>> # "global_byte_slices": 2, + >>> # "local_ints": 3, + >>> # "local_byte_slices": 4 + >>> # }, + >>> # extra_program_pages: 1, + >>> # on_complete: algosdk.transaction.OnComplete.OptInOC, + >>> # args: [b'some_bytes'] + >>> # account_references: ["ACCOUNT_1"] + >>> # app_references: [123, 1234] + >>> # asset_references: [12345] + >>> # box_references: ["box1", {app_id: 1234, name: "box2"}] + >>> # lease: 'lease', + >>> # note: 'note', + >>> # # You wouldn't normally set this field + >>> # first_valid_round: 1000, + >>> # validity_window: 10, + >>> # extra_fee: AlgoAmount(micro_algo=1000), + >>> # static_fee: AlgoAmount(micro_algo=1000), + >>> # # Max fee doesn't make sense with extraFee AND staticFee + >>> # # already specified, but here for completeness + >>> # max_fee: AlgoAmount(micro_algo=3000), + >>> # # Signer only needed if you want to provide one, + >>> # # generally you'd register it with AlgorandClient + >>> # # against the sender and not need to pass it in + >>> # signer: transactionSigner + >>> #}, send_params=SendParams( + >>> # max_rounds_to_wait_for_confirmation=5, + >>> # suppress_log=True, + >>> #)) """ return self._send_app_create_call(lambda c: c.add_app_create)(params, send_params) @@ -472,6 +803,43 @@ def app_update( :param params: Application update parameters :param send_params: Send parameters :return: Result containing the compiled programs + + :example: + >>> # Basic example + >>> algorand.send.app_update(AppUpdateParams( + >>> sender="CREATORADDRESS", + >>> approval_program="TEALCODE", + >>> clear_state_program="TEALCODE", + >>> )) + >>> # Advanced example + >>> algorand.send.app_update(AppUpdateParams( + >>> sender="CREATORADDRESS", + >>> approval_program="TEALCODE", + >>> clear_state_program="TEALCODE", + >>> on_complete=OnComplete.UpdateApplicationOC, + >>> args=[b'some_bytes'], + >>> account_references=["ACCOUNT_1"], + >>> app_references=[123, 1234], + >>> asset_references=[12345], + >>> box_references=[...], + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) """ return self._send_app_update_call(lambda c: c.add_app_update)(params, send_params) @@ -483,6 +851,40 @@ def app_delete( :param params: Application deletion parameters :param send_params: Send parameters :return: Result of the deletion transaction + + :example: + >>> # Basic example + >>> algorand.send.app_delete(AppDeleteParams( + >>> sender="CREATORADDRESS", + >>> app_id=123456, + >>> )) + >>> # Advanced example + >>> algorand.send.app_delete(AppDeleteParams( + >>> sender="CREATORADDRESS", + >>> on_complete=OnComplete.DeleteApplicationOC, + >>> args=[b'some_bytes'], + >>> account_references=["ACCOUNT_1"], + >>> app_references=[123, 1234], + >>> asset_references=[12345], + >>> box_references=[...], + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner, + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) """ return self._send_app_call(lambda c: c.add_app_delete)(params, send_params) @@ -494,6 +896,40 @@ def app_call( :param params: Application call parameters :param send_params: Send parameters :return: Result containing any ABI return value + + :example: + >>> # Basic example + >>> algorand.send.app_call(AppCallParams( + >>> sender="CREATORADDRESS", + >>> app_id=123456, + >>> )) + >>> # Advanced example + >>> algorand.send.app_call(AppCallParams( + >>> sender="CREATORADDRESS", + >>> on_complete=OnComplete.OptInOC, + >>> args=[b'some_bytes'], + >>> account_references=["ACCOUNT_1"], + >>> app_references=[123, 1234], + >>> asset_references=[12345], + >>> box_references=[...], + >>> lease="lease", + >>> note="note", + >>> # You wouldn't normally set this field + >>> first_valid_round=1000, + >>> validity_window=10, + >>> extra_fee=AlgoAmount(micro_algo=1000), + >>> static_fee=AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee=AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer=transactionSigner, + >>> ), send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) """ return self._send_app_call(lambda c: c.add_app_call)(params, send_params) @@ -505,6 +941,67 @@ def app_create_method_call( :param params: Method call parameters for application creation :param send_params: Send parameters :return: Result containing the new application ID and address + + :example: + >>> # Note: you may prefer to use `algorand.client` to get an app client for more advanced functionality. + >>> # + >>> # @param params The parameters for the app creation transaction + >>> # Basic example + >>> method = algorand.abi.Method( + >>> name='method', + >>> args=[b'arg1'], + >>> returns='string' + >>> ) + >>> result = algorand.send.app_create_method_call({ sender: 'CREATORADDRESS', + >>> approval_program: 'TEALCODE', + >>> clear_state_program: 'TEALCODE', + >>> method: method, + >>> args: ["arg1_value"] }) + >>> created_app_id = result.app_id + >>> ... + >>> # Advanced example + >>> method = algorand.abi.Method( + >>> name='method', + >>> args=[b'arg1'], + >>> returns='string' + >>> ) + >>> result = algorand.send.app_create_method_call({ + >>> sender: 'CREATORADDRESS', + >>> method: method, + >>> args: ["arg1_value"], + >>> approval_program: "TEALCODE", + >>> clear_state_program: "TEALCODE", + >>> schema: { + >>> "global_ints": 1, + >>> "global_byte_slices": 2, + >>> "local_ints": 3, + >>> "local_byte_slices": 4 + >>> }, + >>> extra_program_pages: 1, + >>> on_complete: algosdk.transaction.OnComplete.OptInOC, + >>> args: [new Uint8Array(1, 2, 3, 4)], + >>> account_references: ["ACCOUNT_1"], + >>> app_references: [123, 1234], + >>> asset_references: [12345], + >>> box_references: [...], + >>> lease: 'lease', + >>> note: 'note', + >>> # You wouldn't normally set this field + >>> first_valid_round: 1000, + >>> validity_window: 10, + >>> extra_fee: AlgoAmount(micro_algo=1000), + >>> static_fee: AlgoAmount(micro_algo=1000), + >>> # Max fee doesn't make sense with extraFee AND staticFee + >>> # already specified, but here for completeness + >>> max_fee: AlgoAmount(micro_algo=3000), + >>> # Signer only needed if you want to provide one, + >>> # generally you'd register it with AlgorandClient + >>> # against the sender and not need to pass it in + >>> signer: transactionSigner, + >>> }, send_params=SendParams( + >>> max_rounds_to_wait_for_confirmation=5, + >>> suppress_log=True, + >>> )) """ return self._send_app_create_call(lambda c: c.add_app_create_method_call)(params, send_params) @@ -516,6 +1013,44 @@ def app_update_method_call( :param params: Method call parameters for application update :param send_params: Send parameters :return: Result containing the compiled programs + + :example: + # Basic example: + >>> method = algorand.abi.Method( + ... name="updateMethod", + ... args=[{"type": "string", "name": "arg1"}], + ... returns="string" + ... ) + >>> params = AppUpdateMethodCallParams( + ... sender="CREATORADDRESS", + ... app_id=123, + ... method=method, + ... args=["new_value"], + ... approval_program="TEALCODE", + ... clear_state_program="TEALCODE" + ... ) + >>> result = algorand.send.app_update_method_call(params) + >>> print(result.compiled_approval, result.compiled_clear) + + # Advanced example: + >>> method = algorand.abi.Method( + ... name="updateMethod", + ... args=[{"type": "string", "name": "arg1"}, {"type": "uint64", "name": "arg2"}], + ... returns="string" + ... ) + >>> params = AppUpdateMethodCallParams( + ... sender="CREATORADDRESS", + ... app_id=456, + ... method=method, + ... args=["new_value", 42], + ... approval_program="TEALCODE_ADVANCED", + ... clear_state_program="TEALCLEAR_ADVANCED", + ... account_references=["ACCOUNT1", "ACCOUNT2"], + ... app_references=[789], + ... asset_references=[101112] + ... ) + >>> result = algorand.send.app_update_method_call(params) + >>> print(result.compiled_approval, result.compiled_clear) """ return self._send_app_update_call(lambda c: c.add_app_update_method_call)(params, send_params) @@ -527,6 +1062,38 @@ def app_delete_method_call( :param params: Method call parameters for application deletion :param send_params: Send parameters :return: Result of the deletion transaction + + :example: + # Basic example: + >>> method = algorand.abi.Method( + ... name="deleteMethod", + ... args=[], + ... returns="void" + ... ) + >>> params = AppDeleteMethodCallParams( + ... sender="CREATORADDRESS", + ... app_id=123, + ... method=method + ... ) + >>> result = algorand.send.app_delete_method_call(params) + >>> print(result.tx_id) + + # Advanced example: + >>> method = algorand.abi.Method( + ... name="deleteMethod", + ... args=[{"type": "uint64", "name": "confirmation"}], + ... returns="void" + ... ) + >>> params = AppDeleteMethodCallParams( + ... sender="CREATORADDRESS", + ... app_id=123, + ... method=method, + ... args=[1], + ... account_references=["ACCOUNT1"], + ... app_references=[456] + ... ) + >>> result = algorand.send.app_delete_method_call(params) + >>> print(result.tx_id) """ return self._send_app_call(lambda c: c.add_app_delete_method_call)(params, send_params) @@ -538,6 +1105,40 @@ def app_call_method_call( :param params: Method call parameters :param send_params: Send parameters :return: Result containing any ABI return value + + :example: + # Basic example: + >>> method = algorand.abi.Method( + ... name="callMethod", + ... args=[{"type": "uint64", "name": "arg1"}], + ... returns="uint64" + ... ) + >>> params = AppCallMethodCallParams( + ... sender="CALLERADDRESS", + ... app_id=123, + ... method=method, + ... args=[12345] + ... ) + >>> result = algorand.send.app_call_method_call(params) + >>> print(result.abi_return) + + # Advanced example: + >>> method = algorand.abi.Method( + ... name="callMethod", + ... args=[{"type": "uint64", "name": "arg1"}, {"type": "string", "name": "arg2"}], + ... returns="uint64" + ... ) + >>> params = AppCallMethodCallParams( + ... sender="CALLERADDRESS", + ... app_id=123, + ... method=method, + ... args=[12345, "extra"], + ... account_references=["ACCOUNT1"], + ... asset_references=[101112], + ... app_references=[789] + ... ) + >>> result = algorand.send.app_call_method_call(params) + >>> print(result.abi_return) """ return self._send_app_call(lambda c: c.add_app_call_method_call)(params, send_params) @@ -549,6 +1150,32 @@ def online_key_registration( :param params: Key registration parameters :param send_params: Send parameters :return: Result of the registration transaction + + :example: + # Basic example: + >>> params = OnlineKeyRegistrationParams( + ... sender="ACCOUNTADDRESS", + ... vote_key="VOTEKEY", + ... selection_key="SELECTIONKEY", + ... vote_first=1000, + ... vote_last=2000, + ... vote_key_dilution=10 + ... ) + >>> result = algorand.send.online_key_registration(params) + >>> print(result.tx_id) + + # Advanced example: + >>> params = OnlineKeyRegistrationParams( + ... sender="ACCOUNTADDRESS", + ... vote_key="VOTEKEY", + ... selection_key="SELECTIONKEY", + ... vote_first=1000, + ... vote_last=2100, + ... vote_key_dilution=10, + ... state_proof_key=b'\x01' * 64 + ... ) + >>> result = algorand.send.online_key_registration(params) + >>> print(result.tx_id) """ return self._send( lambda c: c.add_online_key_registration, @@ -565,6 +1192,24 @@ def offline_key_registration( :param params: Key registration parameters :param send_params: Send parameters :return: Result of the registration transaction + + :example: + # Basic example: + >>> params = OfflineKeyRegistrationParams( + ... sender="ACCOUNTADDRESS", + ... prevent_account_from_ever_participating_again=True + ... ) + >>> result = algorand.send.offline_key_registration(params) + >>> print(result.tx_id) + + # Advanced example: + >>> params = OfflineKeyRegistrationParams( + ... sender="ACCOUNTADDRESS", + ... prevent_account_from_ever_participating_again=True, + ... note=b'Offline registration' + ... ) + >>> result = algorand.send.offline_key_registration(params) + >>> print(result.tx_id) """ return self._send( lambda c: c.add_offline_key_registration,