algokit-utils 5.0.0a3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- algokit_abi/__init__.py +9 -0
- algokit_abi/_arc32_to_arc56.py +242 -0
- algokit_abi/_arc56_serde.py +161 -0
- algokit_abi/abi.py +667 -0
- algokit_abi/arc32.py +210 -0
- algokit_abi/arc56.py +821 -0
- algokit_abi/py.typed +0 -0
- algokit_algo25/__init__.py +38 -0
- algokit_algo25/_encoding.py +46 -0
- algokit_algo25/_wordlist.py +2065 -0
- algokit_algo25/exceptions.py +29 -0
- algokit_algo25/mnemonic.py +128 -0
- algokit_algo25/py.typed +0 -0
- algokit_algod_client/__init__.py +10 -0
- algokit_algod_client/client.py +1585 -0
- algokit_algod_client/config.py +36 -0
- algokit_algod_client/exceptions.py +59 -0
- algokit_algod_client/models/__init__.py +229 -0
- algokit_algod_client/models/_account.py +150 -0
- algokit_algod_client/models/_account_application_response.py +25 -0
- algokit_algod_client/models/_account_asset_response.py +25 -0
- algokit_algod_client/models/_account_participation.py +53 -0
- algokit_algod_client/models/_account_state_delta.py +30 -0
- algokit_algod_client/models/_allocations_for_genesis_file.py +23 -0
- algokit_algod_client/models/_allocations_for_genesis_file_state_model.py +42 -0
- algokit_algod_client/models/_application.py +23 -0
- algokit_algod_client/models/_application_initial_states.py +37 -0
- algokit_algod_client/models/_application_kvstorage.py +29 -0
- algokit_algod_client/models/_application_local_state.py +33 -0
- algokit_algod_client/models/_application_params.py +63 -0
- algokit_algod_client/models/_application_state_operation.py +41 -0
- algokit_algod_client/models/_application_state_schema.py +22 -0
- algokit_algod_client/models/_asset.py +23 -0
- algokit_algod_client/models/_asset_holding.py +29 -0
- algokit_algod_client/models/_asset_params.py +102 -0
- algokit_algod_client/models/_avm_key_value.py +28 -0
- algokit_algod_client/models/_avm_value.py +32 -0
- algokit_algod_client/models/_block.py +363 -0
- algokit_algod_client/models/_block_hash_response.py +14 -0
- algokit_algod_client/models/_block_txids_response.py +14 -0
- algokit_algod_client/models/_box.py +36 -0
- algokit_algod_client/models/_box_descriptor.py +24 -0
- algokit_algod_client/models/_boxes_response.py +21 -0
- algokit_algod_client/models/_build_version_contains_the_current_algod_build_version_information.py +34 -0
- algokit_algod_client/models/_compile_response.py +24 -0
- algokit_algod_client/models/_disassemble_response.py +14 -0
- algokit_algod_client/models/_error_response.py +22 -0
- algokit_algod_client/models/_eval_delta.py +32 -0
- algokit_algod_client/models/_eval_delta_key_value.py +28 -0
- algokit_algod_client/models/_genesis_file_in_json.py +53 -0
- algokit_algod_client/models/_get_block_time_stamp_offset_response.py +14 -0
- algokit_algod_client/models/_get_sync_round_response.py +14 -0
- algokit_algod_client/models/_ledger_state_delta.py +389 -0
- algokit_algod_client/models/_light_block_header_proof.py +32 -0
- algokit_algod_client/models/_node_status_response.py +118 -0
- algokit_algod_client/models/_pending_transaction_response.py +91 -0
- algokit_algod_client/models/_pending_transactions_response.py +29 -0
- algokit_algod_client/models/_post_transactions_response.py +14 -0
- algokit_algod_client/models/_scratch_change.py +23 -0
- algokit_algod_client/models/_serde_helpers.py +241 -0
- algokit_algod_client/models/_simulate_initial_states.py +25 -0
- algokit_algod_client/models/_simulate_request.py +54 -0
- algokit_algod_client/models/_simulate_request_transaction_group.py +25 -0
- algokit_algod_client/models/_simulate_response.py +44 -0
- algokit_algod_client/models/_simulate_trace_config.py +30 -0
- algokit_algod_client/models/_simulate_transaction_group_result.py +46 -0
- algokit_algod_client/models/_simulate_transaction_result.py +41 -0
- algokit_algod_client/models/_simulate_unnamed_resources_accessed.py +64 -0
- algokit_algod_client/models/_simulation_eval_overrides.py +40 -0
- algokit_algod_client/models/_simulation_opcode_trace_unit.py +55 -0
- algokit_algod_client/models/_simulation_transaction_exec_trace.py +82 -0
- algokit_algod_client/models/_source_map.py +30 -0
- algokit_algod_client/models/_state_delta.py +6 -0
- algokit_algod_client/models/_state_proof.py +28 -0
- algokit_algod_client/models/_state_proof_message.py +44 -0
- algokit_algod_client/models/_supply_response.py +26 -0
- algokit_algod_client/models/_teal_key_value.py +28 -0
- algokit_algod_client/models/_teal_key_value_store.py +6 -0
- algokit_algod_client/models/_teal_value.py +32 -0
- algokit_algod_client/models/_transaction_group_ledger_state_deltas_for_round_response.py +21 -0
- algokit_algod_client/models/_transaction_parameters_response.py +45 -0
- algokit_algod_client/models/_transaction_proof.py +44 -0
- algokit_algod_client/models/_version_contains_the_current_algod_version.py +38 -0
- algokit_algod_client/models/suggested_params.py +42 -0
- algokit_algod_client/py.typed +1 -0
- algokit_algod_client/types.py +7 -0
- algokit_algosdk/__init__.py +38 -0
- algokit_algosdk/account.py +32 -0
- algokit_algosdk/app_access.py +228 -0
- algokit_algosdk/box_reference.py +100 -0
- algokit_algosdk/constants.py +147 -0
- algokit_algosdk/encoding.py +89 -0
- algokit_algosdk/error.py +180 -0
- algokit_algosdk/logic.py +61 -0
- algokit_algosdk/logicsig.py +218 -0
- algokit_algosdk/mnemonic.py +216 -0
- algokit_algosdk/multisig.py +161 -0
- algokit_algosdk/py.typed +0 -0
- algokit_algosdk/transaction.py +596 -0
- algokit_algosdk/wordlist.py +2054 -0
- algokit_common/__init__.py +50 -0
- algokit_common/address.py +34 -0
- algokit_common/constants.py +47 -0
- algokit_common/hashing.py +25 -0
- algokit_common/py.typed +0 -0
- algokit_common/serde/__init__.py +40 -0
- algokit_common/serde/_core.py +610 -0
- algokit_common/serde/_primitives.py +135 -0
- algokit_common/source_map.py +158 -0
- algokit_indexer_client/__init__.py +10 -0
- algokit_indexer_client/client.py +1456 -0
- algokit_indexer_client/config.py +36 -0
- algokit_indexer_client/exceptions.py +59 -0
- algokit_indexer_client/models/__init__.py +148 -0
- algokit_indexer_client/models/_account.py +161 -0
- algokit_indexer_client/models/_account_participation.py +53 -0
- algokit_indexer_client/models/_account_response.py +19 -0
- algokit_indexer_client/models/_account_state_delta.py +29 -0
- algokit_indexer_client/models/_accounts_response.py +29 -0
- algokit_indexer_client/models/_application.py +35 -0
- algokit_indexer_client/models/_application_local_state.py +45 -0
- algokit_indexer_client/models/_application_local_states_response.py +29 -0
- algokit_indexer_client/models/_application_log_data.py +28 -0
- algokit_indexer_client/models/_application_logs_response.py +33 -0
- algokit_indexer_client/models/_application_params.py +62 -0
- algokit_indexer_client/models/_application_response.py +20 -0
- algokit_indexer_client/models/_application_state_schema.py +22 -0
- algokit_indexer_client/models/_applications_response.py +29 -0
- algokit_indexer_client/models/_asset.py +35 -0
- algokit_indexer_client/models/_asset_balances_response.py +29 -0
- algokit_indexer_client/models/_asset_holding.py +41 -0
- algokit_indexer_client/models/_asset_holdings_response.py +29 -0
- algokit_indexer_client/models/_asset_params.py +102 -0
- algokit_indexer_client/models/_asset_response.py +19 -0
- algokit_indexer_client/models/_assets_response.py +29 -0
- algokit_indexer_client/models/_block.py +150 -0
- algokit_indexer_client/models/_block_headers_response.py +29 -0
- algokit_indexer_client/models/_block_rewards.py +38 -0
- algokit_indexer_client/models/_block_upgrade_state.py +34 -0
- algokit_indexer_client/models/_block_upgrade_vote.py +26 -0
- algokit_indexer_client/models/_box.py +36 -0
- algokit_indexer_client/models/_box_descriptor.py +24 -0
- algokit_indexer_client/models/_box_reference.py +28 -0
- algokit_indexer_client/models/_boxes_response.py +29 -0
- algokit_indexer_client/models/_error_response.py +18 -0
- algokit_indexer_client/models/_eval_delta.py +32 -0
- algokit_indexer_client/models/_eval_delta_key_value.py +28 -0
- algokit_indexer_client/models/_hash_factory.py +14 -0
- algokit_indexer_client/models/_hb_proof_fields.py +57 -0
- algokit_indexer_client/models/_health_check.py +42 -0
- algokit_indexer_client/models/_holding_ref.py +23 -0
- algokit_indexer_client/models/_indexer_state_proof_message.py +40 -0
- algokit_indexer_client/models/_locals_ref.py +23 -0
- algokit_indexer_client/models/_merkle_array_proof.py +29 -0
- algokit_indexer_client/models/_mini_asset_holding.py +38 -0
- algokit_indexer_client/models/_on_completion.py +25 -0
- algokit_indexer_client/models/_participation_updates.py +22 -0
- algokit_indexer_client/models/_resource_ref.py +42 -0
- algokit_indexer_client/models/_serde_helpers.py +241 -0
- algokit_indexer_client/models/_state_delta.py +6 -0
- algokit_indexer_client/models/_state_proof_fields.py +57 -0
- algokit_indexer_client/models/_state_proof_participant.py +20 -0
- algokit_indexer_client/models/_state_proof_reveal.py +25 -0
- algokit_indexer_client/models/_state_proof_sig_slot.py +20 -0
- algokit_indexer_client/models/_state_proof_signature.py +37 -0
- algokit_indexer_client/models/_state_proof_tracking.py +32 -0
- algokit_indexer_client/models/_state_proof_verifier.py +24 -0
- algokit_indexer_client/models/_state_schema.py +25 -0
- algokit_indexer_client/models/_teal_key_value.py +28 -0
- algokit_indexer_client/models/_teal_key_value_store.py +6 -0
- algokit_indexer_client/models/_teal_value.py +32 -0
- algokit_indexer_client/models/_transaction.py +213 -0
- algokit_indexer_client/models/_transaction_application.py +105 -0
- algokit_indexer_client/models/_transaction_asset_config.py +31 -0
- algokit_indexer_client/models/_transaction_asset_freeze.py +29 -0
- algokit_indexer_client/models/_transaction_asset_transfer.py +41 -0
- algokit_indexer_client/models/_transaction_heartbeat.py +52 -0
- algokit_indexer_client/models/_transaction_keyreg.py +59 -0
- algokit_indexer_client/models/_transaction_payment.py +33 -0
- algokit_indexer_client/models/_transaction_response.py +19 -0
- algokit_indexer_client/models/_transaction_signature.py +35 -0
- algokit_indexer_client/models/_transaction_signature_logicsig.py +59 -0
- algokit_indexer_client/models/_transaction_signature_multisig.py +36 -0
- algokit_indexer_client/models/_transaction_signature_multisig_subsignature.py +28 -0
- algokit_indexer_client/models/_transaction_state_proof.py +32 -0
- algokit_indexer_client/models/_transactions_response.py +29 -0
- algokit_indexer_client/py.typed +1 -0
- algokit_indexer_client/types.py +7 -0
- algokit_kmd_client/__init__.py +10 -0
- algokit_kmd_client/client.py +1240 -0
- algokit_kmd_client/config.py +36 -0
- algokit_kmd_client/exceptions.py +59 -0
- algokit_kmd_client/models/__init__.py +112 -0
- algokit_kmd_client/models/_classical_signatures.py +4 -0
- algokit_kmd_client/models/_create_wallet_request.py +30 -0
- algokit_kmd_client/models/_create_wallet_response.py +19 -0
- algokit_kmd_client/models/_delete_key_request.py +27 -0
- algokit_kmd_client/models/_delete_multisig_request.py +27 -0
- algokit_kmd_client/models/_digest_represents_a32_byte_value_holding_the256_bit_hash_digest.py +4 -0
- algokit_kmd_client/models/_ed25519_public_key.py +4 -0
- algokit_kmd_client/models/_export_key_request.py +27 -0
- algokit_kmd_client/models/_export_key_response.py +24 -0
- algokit_kmd_client/models/_export_master_key_request.py +22 -0
- algokit_kmd_client/models/_export_master_key_response.py +18 -0
- algokit_kmd_client/models/_export_multisig_request.py +23 -0
- algokit_kmd_client/models/_export_multisig_response.py +26 -0
- algokit_kmd_client/models/_generate_key_request.py +18 -0
- algokit_kmd_client/models/_generate_key_response.py +19 -0
- algokit_kmd_client/models/_import_key_request.py +28 -0
- algokit_kmd_client/models/_import_key_response.py +19 -0
- algokit_kmd_client/models/_import_multisig_request.py +30 -0
- algokit_kmd_client/models/_import_multisig_response.py +19 -0
- algokit_kmd_client/models/_init_wallet_handle_token_request.py +22 -0
- algokit_kmd_client/models/_init_wallet_handle_token_response.py +18 -0
- algokit_kmd_client/models/_list_keys_request.py +18 -0
- algokit_kmd_client/models/_list_keys_response.py +18 -0
- algokit_kmd_client/models/_list_multisig_request.py +18 -0
- algokit_kmd_client/models/_list_multisig_response.py +18 -0
- algokit_kmd_client/models/_list_wallets_request.py +11 -0
- algokit_kmd_client/models/_list_wallets_response.py +25 -0
- algokit_kmd_client/models/_master_derivation_key.py +4 -0
- algokit_kmd_client/models/_multisig_sig.py +33 -0
- algokit_kmd_client/models/_multisig_subsig.py +23 -0
- algokit_kmd_client/models/_public_key.py +4 -0
- algokit_kmd_client/models/_release_wallet_handle_token_request.py +18 -0
- algokit_kmd_client/models/_rename_wallet_request.py +26 -0
- algokit_kmd_client/models/_rename_wallet_response.py +19 -0
- algokit_kmd_client/models/_renew_wallet_handle_token_request.py +18 -0
- algokit_kmd_client/models/_renew_wallet_handle_token_response.py +19 -0
- algokit_kmd_client/models/_serde_helpers.py +241 -0
- algokit_kmd_client/models/_sign_multisig_response.py +24 -0
- algokit_kmd_client/models/_sign_multisig_txn_request.py +45 -0
- algokit_kmd_client/models/_sign_program_multisig_request.py +50 -0
- algokit_kmd_client/models/_sign_program_multisig_response.py +24 -0
- algokit_kmd_client/models/_sign_program_request.py +37 -0
- algokit_kmd_client/models/_sign_program_response.py +24 -0
- algokit_kmd_client/models/_sign_transaction_response.py +24 -0
- algokit_kmd_client/models/_sign_txn_request.py +36 -0
- algokit_kmd_client/models/_signature.py +4 -0
- algokit_kmd_client/models/_tx_type.py +4 -0
- algokit_kmd_client/models/_versions_request.py +11 -0
- algokit_kmd_client/models/_versions_response.py +19 -0
- algokit_kmd_client/models/_wallet.py +38 -0
- algokit_kmd_client/models/_wallet_handle.py +24 -0
- algokit_kmd_client/models/_wallet_info_request.py +18 -0
- algokit_kmd_client/models/_wallet_info_response.py +19 -0
- algokit_kmd_client/py.typed +1 -0
- algokit_kmd_client/types.py +7 -0
- algokit_transact/__init__.py +190 -0
- algokit_transact/codec/__init__.py +0 -0
- algokit_transact/codec/msgpack.py +11 -0
- algokit_transact/codec/serde.py +7 -0
- algokit_transact/codec/signed.py +57 -0
- algokit_transact/codec/transaction.py +65 -0
- algokit_transact/exceptions.py +17 -0
- algokit_transact/logicsig.py +220 -0
- algokit_transact/models/__init__.py +0 -0
- algokit_transact/models/app_call.py +447 -0
- algokit_transact/models/asset_config.py +19 -0
- algokit_transact/models/asset_freeze.py +11 -0
- algokit_transact/models/asset_transfer.py +13 -0
- algokit_transact/models/common.py +17 -0
- algokit_transact/models/heartbeat.py +21 -0
- algokit_transact/models/key_registration.py +14 -0
- algokit_transact/models/payment.py +14 -0
- algokit_transact/models/signed_transaction.py +21 -0
- algokit_transact/models/state_proof.py +150 -0
- algokit_transact/models/transaction.py +88 -0
- algokit_transact/multisig.py +93 -0
- algokit_transact/ops/__init__.py +0 -0
- algokit_transact/ops/fees.py +47 -0
- algokit_transact/ops/group.py +28 -0
- algokit_transact/ops/ids.py +14 -0
- algokit_transact/ops/validate.py +503 -0
- algokit_transact/py.typed +0 -0
- algokit_transact/signer.py +195 -0
- algokit_transact/signing/__init__.py +0 -0
- algokit_transact/signing/logic_signature.py +19 -0
- algokit_transact/signing/multisig.py +84 -0
- algokit_transact/signing/types.py +39 -0
- algokit_transact/signing/validation.py +63 -0
- algokit_utils/__init__.py +23 -0
- algokit_utils/_debugging.py +304 -0
- algokit_utils/accounts/__init__.py +2 -0
- algokit_utils/accounts/account_manager.py +1051 -0
- algokit_utils/accounts/kmd_account_manager.py +206 -0
- algokit_utils/algo25.py +46 -0
- algokit_utils/algorand.py +383 -0
- algokit_utils/applications/__init__.py +7 -0
- algokit_utils/applications/abi.py +280 -0
- algokit_utils/applications/app_client.py +2193 -0
- algokit_utils/applications/app_deployer.py +788 -0
- algokit_utils/applications/app_factory.py +1140 -0
- algokit_utils/applications/app_manager.py +575 -0
- algokit_utils/applications/app_spec/__init__.py +6 -0
- algokit_utils/applications/enums.py +40 -0
- algokit_utils/assets/__init__.py +1 -0
- algokit_utils/assets/asset_manager.py +344 -0
- algokit_utils/clients/__init__.py +41 -0
- algokit_utils/clients/client_manager.py +756 -0
- algokit_utils/clients/dispenser_api_client.py +212 -0
- algokit_utils/common.py +40 -0
- algokit_utils/config.py +159 -0
- algokit_utils/errors/__init__.py +1 -0
- algokit_utils/errors/logic_error.py +160 -0
- algokit_utils/models/__init__.py +7 -0
- algokit_utils/models/account.py +12 -0
- algokit_utils/models/amount.py +198 -0
- algokit_utils/models/application.py +90 -0
- algokit_utils/models/network.py +29 -0
- algokit_utils/models/simulate.py +7 -0
- algokit_utils/models/state.py +53 -0
- algokit_utils/models/transaction.py +49 -0
- algokit_utils/protocols/__init__.py +3 -0
- algokit_utils/protocols/account.py +11 -0
- algokit_utils/protocols/signer.py +17 -0
- algokit_utils/protocols/typed_clients.py +110 -0
- algokit_utils/py.typed +0 -0
- algokit_utils/transact.py +195 -0
- algokit_utils/transactions/__init__.py +3 -0
- algokit_utils/transactions/builders/__init__.py +67 -0
- algokit_utils/transactions/builders/app.py +248 -0
- algokit_utils/transactions/builders/asset.py +256 -0
- algokit_utils/transactions/builders/common.py +263 -0
- algokit_utils/transactions/builders/keyreg.py +103 -0
- algokit_utils/transactions/builders/method_call.py +380 -0
- algokit_utils/transactions/builders/payment.py +43 -0
- algokit_utils/transactions/composer_resources.py +409 -0
- algokit_utils/transactions/fee_coverage.py +79 -0
- algokit_utils/transactions/helpers.py +9 -0
- algokit_utils/transactions/transaction_composer.py +1574 -0
- algokit_utils/transactions/transaction_creator.py +699 -0
- algokit_utils/transactions/transaction_sender.py +1240 -0
- algokit_utils/transactions/types.py +262 -0
- algokit_utils-5.0.0a3.dist-info/METADATA +105 -0
- algokit_utils-5.0.0a3.dist-info/RECORD +337 -0
- algokit_utils-5.0.0a3.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,1140 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import dataclasses
|
|
3
|
+
from collections.abc import Callable, Sequence
|
|
4
|
+
from dataclasses import asdict, dataclass
|
|
5
|
+
from typing import Any, Generic, TypeVar
|
|
6
|
+
|
|
7
|
+
from typing_extensions import Self
|
|
8
|
+
|
|
9
|
+
from algokit_abi import arc56
|
|
10
|
+
from algokit_common import ProgramSourceMap
|
|
11
|
+
from algokit_transact import OnApplicationComplete
|
|
12
|
+
from algokit_transact.models.transaction import Transaction
|
|
13
|
+
from algokit_utils.algorand import AlgorandClient
|
|
14
|
+
from algokit_utils.applications.abi import (
|
|
15
|
+
ABIReturn,
|
|
16
|
+
Arc56ReturnValueType,
|
|
17
|
+
get_abi_decoded_value,
|
|
18
|
+
)
|
|
19
|
+
from algokit_utils.applications.app_client import (
|
|
20
|
+
AppClient,
|
|
21
|
+
AppClientBareCallCreateParams,
|
|
22
|
+
AppClientBareCallParams,
|
|
23
|
+
AppClientCompilationParams,
|
|
24
|
+
AppClientCompilationResult,
|
|
25
|
+
AppClientMethodCallCreateParams,
|
|
26
|
+
AppClientMethodCallParams,
|
|
27
|
+
AppClientParams,
|
|
28
|
+
CreateOnComplete,
|
|
29
|
+
)
|
|
30
|
+
from algokit_utils.applications.app_deployer import (
|
|
31
|
+
AppDeploymentMetaData,
|
|
32
|
+
AppDeployParams,
|
|
33
|
+
AppDeployResult,
|
|
34
|
+
ApplicationLookup,
|
|
35
|
+
ApplicationMetaData,
|
|
36
|
+
OnSchemaBreak,
|
|
37
|
+
OnUpdate,
|
|
38
|
+
OperationPerformed,
|
|
39
|
+
)
|
|
40
|
+
from algokit_utils.applications.app_manager import DELETABLE_TEMPLATE_NAME, UPDATABLE_TEMPLATE_NAME
|
|
41
|
+
from algokit_utils.models.application import AppSourceMaps
|
|
42
|
+
from algokit_utils.models.transaction import SendParams
|
|
43
|
+
from algokit_utils.protocols.signer import TransactionSigner
|
|
44
|
+
from algokit_utils.transactions.transaction_composer import (
|
|
45
|
+
AppCreateMethodCallParams,
|
|
46
|
+
AppCreateParams,
|
|
47
|
+
AppDeleteMethodCallParams,
|
|
48
|
+
AppDeleteParams,
|
|
49
|
+
AppUpdateMethodCallParams,
|
|
50
|
+
AppUpdateParams,
|
|
51
|
+
BuiltTransactions,
|
|
52
|
+
)
|
|
53
|
+
from algokit_utils.transactions.transaction_sender import (
|
|
54
|
+
SendAppCreateTransactionResult,
|
|
55
|
+
SendAppTransactionResult,
|
|
56
|
+
SendAppUpdateTransactionResult,
|
|
57
|
+
SendSingleTransactionResult,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
T = TypeVar("T")
|
|
61
|
+
|
|
62
|
+
__all__ = [
|
|
63
|
+
"AppFactory",
|
|
64
|
+
"AppFactoryCreateMethodCallParams",
|
|
65
|
+
"AppFactoryCreateMethodCallResult",
|
|
66
|
+
"AppFactoryCreateParams",
|
|
67
|
+
"AppFactoryDeployResult",
|
|
68
|
+
"AppFactoryParams",
|
|
69
|
+
"SendAppCreateFactoryTransactionResult",
|
|
70
|
+
"SendAppFactoryTransactionResult",
|
|
71
|
+
"SendAppUpdateFactoryTransactionResult",
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@dataclass(kw_only=True, frozen=True)
|
|
76
|
+
class AppFactoryParams:
|
|
77
|
+
algorand: AlgorandClient
|
|
78
|
+
app_spec: arc56.Arc56Contract | str
|
|
79
|
+
app_name: str | None = None
|
|
80
|
+
default_sender: str | None = None
|
|
81
|
+
default_signer: TransactionSigner | None = None
|
|
82
|
+
version: str | None = None
|
|
83
|
+
compilation_params: AppClientCompilationParams | None = None
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@dataclass(kw_only=True, frozen=True)
|
|
87
|
+
class AppFactoryCreateParams(AppClientBareCallCreateParams):
|
|
88
|
+
on_complete: CreateOnComplete | None = None
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@dataclass(kw_only=True, frozen=True)
|
|
92
|
+
class AppFactoryCreateMethodCallParams(AppClientMethodCallCreateParams):
|
|
93
|
+
pass
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
ABIReturnT = TypeVar(
|
|
97
|
+
"ABIReturnT",
|
|
98
|
+
bound=Arc56ReturnValueType,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@dataclass(frozen=True, kw_only=True)
|
|
103
|
+
class AppFactoryCreateMethodCallResult(SendSingleTransactionResult, Generic[ABIReturnT]):
|
|
104
|
+
app_id: int
|
|
105
|
+
app_address: str
|
|
106
|
+
compiled_approval: Any | None = None
|
|
107
|
+
compiled_clear: Any | None = None
|
|
108
|
+
abi_return: ABIReturnT | None = None
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@dataclass(frozen=True)
|
|
112
|
+
class SendAppFactoryTransactionResult(SendAppTransactionResult[Arc56ReturnValueType]):
|
|
113
|
+
pass
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@dataclass(frozen=True)
|
|
117
|
+
class SendAppUpdateFactoryTransactionResult(SendAppUpdateTransactionResult[Arc56ReturnValueType]):
|
|
118
|
+
pass
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@dataclass(frozen=True, kw_only=True)
|
|
122
|
+
class SendAppCreateFactoryTransactionResult(SendAppCreateTransactionResult[Arc56ReturnValueType]):
|
|
123
|
+
pass
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@dataclass(frozen=True)
|
|
127
|
+
class AppFactoryDeployResult:
|
|
128
|
+
"""Result from deploying an application via AppFactory"""
|
|
129
|
+
|
|
130
|
+
app: ApplicationMetaData
|
|
131
|
+
"""The application metadata"""
|
|
132
|
+
operation_performed: OperationPerformed
|
|
133
|
+
"""The operation performed"""
|
|
134
|
+
create_result: SendAppCreateFactoryTransactionResult | None = None
|
|
135
|
+
"""The create result"""
|
|
136
|
+
update_result: SendAppUpdateFactoryTransactionResult | None = None
|
|
137
|
+
"""The update result"""
|
|
138
|
+
delete_result: SendAppFactoryTransactionResult | None = None
|
|
139
|
+
"""The delete result"""
|
|
140
|
+
|
|
141
|
+
@classmethod
|
|
142
|
+
def from_deploy_result(
|
|
143
|
+
cls,
|
|
144
|
+
response: AppDeployResult,
|
|
145
|
+
deploy_params: AppDeployParams,
|
|
146
|
+
app_spec: arc56.Arc56Contract, # noqa: ARG003
|
|
147
|
+
app_compilation_data: AppClientCompilationResult | None = None,
|
|
148
|
+
) -> Self:
|
|
149
|
+
"""
|
|
150
|
+
Construct an AppFactoryDeployResult from a deployment result.
|
|
151
|
+
|
|
152
|
+
:param response: The deployment response.
|
|
153
|
+
:param deploy_params: The deployment parameters.
|
|
154
|
+
:param app_spec: The application specification.
|
|
155
|
+
:param app_compilation_data: Optional app compilation data.
|
|
156
|
+
:return: An instance of AppFactoryDeployResult.
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
def to_factory_result(
|
|
160
|
+
response_data: SendAppTransactionResult[ABIReturn]
|
|
161
|
+
| SendAppCreateTransactionResult
|
|
162
|
+
| SendAppUpdateTransactionResult
|
|
163
|
+
| None,
|
|
164
|
+
params: Any, # noqa: ANN401
|
|
165
|
+
) -> Any | None: # noqa: ANN401
|
|
166
|
+
_ = params # kept for compatibility
|
|
167
|
+
if not response_data:
|
|
168
|
+
return None
|
|
169
|
+
|
|
170
|
+
response_data_dict = {
|
|
171
|
+
field.name: getattr(response_data, field.name) for field in dataclasses.fields(type(response_data))
|
|
172
|
+
}
|
|
173
|
+
abi_return = response_data.abi_return
|
|
174
|
+
if abi_return and abi_return.method:
|
|
175
|
+
if abi_return.decode_error:
|
|
176
|
+
raise ValueError(abi_return.decode_error)
|
|
177
|
+
response_data_dict["abi_return"] = abi_return.value
|
|
178
|
+
|
|
179
|
+
match response_data:
|
|
180
|
+
case SendAppCreateTransactionResult():
|
|
181
|
+
return SendAppCreateFactoryTransactionResult(**response_data_dict)
|
|
182
|
+
case SendAppUpdateTransactionResult():
|
|
183
|
+
response_data_dict["compiled_approval"] = (
|
|
184
|
+
app_compilation_data.compiled_approval if app_compilation_data else None
|
|
185
|
+
)
|
|
186
|
+
response_data_dict["compiled_clear"] = (
|
|
187
|
+
app_compilation_data.compiled_clear if app_compilation_data else None
|
|
188
|
+
)
|
|
189
|
+
return SendAppUpdateFactoryTransactionResult(**response_data_dict)
|
|
190
|
+
case SendAppTransactionResult():
|
|
191
|
+
return SendAppFactoryTransactionResult(**response_data_dict)
|
|
192
|
+
|
|
193
|
+
return cls(
|
|
194
|
+
app=response.app,
|
|
195
|
+
operation_performed=response.operation_performed,
|
|
196
|
+
create_result=to_factory_result(
|
|
197
|
+
response.create_result,
|
|
198
|
+
deploy_params.create_params,
|
|
199
|
+
),
|
|
200
|
+
update_result=to_factory_result(
|
|
201
|
+
response.update_result,
|
|
202
|
+
deploy_params.update_params,
|
|
203
|
+
),
|
|
204
|
+
delete_result=to_factory_result(
|
|
205
|
+
response.delete_result,
|
|
206
|
+
deploy_params.delete_params,
|
|
207
|
+
),
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
class _BareParamsBuilder:
|
|
212
|
+
"""The bare params builder.
|
|
213
|
+
|
|
214
|
+
:param factory: The AppFactory instance.
|
|
215
|
+
"""
|
|
216
|
+
|
|
217
|
+
def __init__(self, factory: "AppFactory") -> None:
|
|
218
|
+
self._factory = factory
|
|
219
|
+
self._algorand = factory._algorand
|
|
220
|
+
|
|
221
|
+
def create(
|
|
222
|
+
self, params: AppFactoryCreateParams | None = None, compilation_params: AppClientCompilationParams | None = None
|
|
223
|
+
) -> AppCreateParams:
|
|
224
|
+
"""
|
|
225
|
+
Create AppCreateParams using the provided parameters and compilation settings.
|
|
226
|
+
|
|
227
|
+
:param params: Optional AppFactoryCreateParams instance.
|
|
228
|
+
:param compilation_params: Optional AppClientCompilationParams instance.
|
|
229
|
+
:return: An instance of AppCreateParams.
|
|
230
|
+
"""
|
|
231
|
+
base_params = params or AppFactoryCreateParams()
|
|
232
|
+
compiled = self._factory.compile(compilation_params)
|
|
233
|
+
|
|
234
|
+
return AppCreateParams(
|
|
235
|
+
**{
|
|
236
|
+
**{
|
|
237
|
+
param: value
|
|
238
|
+
for param, value in asdict(base_params).items()
|
|
239
|
+
if param in {f.name for f in dataclasses.fields(AppCreateParams)}
|
|
240
|
+
},
|
|
241
|
+
"approval_program": compiled.approval_program,
|
|
242
|
+
"clear_state_program": compiled.clear_state_program,
|
|
243
|
+
"schema": base_params.schema
|
|
244
|
+
or {
|
|
245
|
+
"global_byte_slices": self._factory._app_spec.state.schema.global_state.bytes,
|
|
246
|
+
"global_ints": self._factory._app_spec.state.schema.global_state.ints,
|
|
247
|
+
"local_byte_slices": self._factory._app_spec.state.schema.local_state.bytes,
|
|
248
|
+
"local_ints": self._factory._app_spec.state.schema.local_state.ints,
|
|
249
|
+
},
|
|
250
|
+
"sender": self._factory._get_sender(base_params.sender),
|
|
251
|
+
"signer": self._factory._get_signer(base_params.sender, base_params.signer),
|
|
252
|
+
"on_complete": base_params.on_complete or OnApplicationComplete.NoOp,
|
|
253
|
+
}
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
def deploy_update(self, params: AppClientBareCallParams | None = None) -> AppUpdateParams:
|
|
257
|
+
"""
|
|
258
|
+
Create AppUpdateParams for an update operation.
|
|
259
|
+
|
|
260
|
+
:param params: Optional AppClientBareCallParams instance.
|
|
261
|
+
:return: An instance of AppUpdateParams.
|
|
262
|
+
"""
|
|
263
|
+
return AppUpdateParams(
|
|
264
|
+
**{
|
|
265
|
+
**{
|
|
266
|
+
param: value
|
|
267
|
+
for param, value in asdict(params or AppClientBareCallParams()).items()
|
|
268
|
+
if param in {f.name for f in dataclasses.fields(AppUpdateParams)}
|
|
269
|
+
},
|
|
270
|
+
"app_id": 0,
|
|
271
|
+
"approval_program": "",
|
|
272
|
+
"clear_state_program": "",
|
|
273
|
+
"sender": self._factory._get_sender(params.sender if params else None),
|
|
274
|
+
"on_complete": OnApplicationComplete.UpdateApplication,
|
|
275
|
+
"signer": self._factory._get_signer(
|
|
276
|
+
params.sender if params else None, params.signer if params else None
|
|
277
|
+
),
|
|
278
|
+
}
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
def deploy_delete(self, params: AppClientBareCallParams | None = None) -> AppDeleteParams:
|
|
282
|
+
"""
|
|
283
|
+
Create AppDeleteParams for a delete operation.
|
|
284
|
+
|
|
285
|
+
:param params: Optional AppClientBareCallParams instance.
|
|
286
|
+
:return: An instance of AppDeleteParams.
|
|
287
|
+
"""
|
|
288
|
+
return AppDeleteParams(
|
|
289
|
+
**{
|
|
290
|
+
**{
|
|
291
|
+
param: value
|
|
292
|
+
for param, value in asdict(params or AppClientBareCallParams()).items()
|
|
293
|
+
if param in {f.name for f in dataclasses.fields(AppDeleteParams)}
|
|
294
|
+
},
|
|
295
|
+
"app_id": 0,
|
|
296
|
+
"sender": self._factory._get_sender(params.sender if params else None),
|
|
297
|
+
"signer": self._factory._get_signer(
|
|
298
|
+
params.sender if params else None, params.signer if params else None
|
|
299
|
+
),
|
|
300
|
+
"on_complete": OnApplicationComplete.DeleteApplication,
|
|
301
|
+
}
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
class _MethodParamsBuilder:
|
|
306
|
+
"""The method params builder.
|
|
307
|
+
|
|
308
|
+
:param factory: The AppFactory instance.
|
|
309
|
+
"""
|
|
310
|
+
|
|
311
|
+
def __init__(self, factory: "AppFactory") -> None:
|
|
312
|
+
self._factory = factory
|
|
313
|
+
self._bare = _BareParamsBuilder(factory)
|
|
314
|
+
|
|
315
|
+
@property
|
|
316
|
+
def bare(self) -> _BareParamsBuilder:
|
|
317
|
+
"""
|
|
318
|
+
Get the bare parameters builder.
|
|
319
|
+
|
|
320
|
+
:return: The _BareParamsBuilder instance.
|
|
321
|
+
"""
|
|
322
|
+
return self._bare
|
|
323
|
+
|
|
324
|
+
def create(
|
|
325
|
+
self, params: AppFactoryCreateMethodCallParams, compilation_params: AppClientCompilationParams | None = None
|
|
326
|
+
) -> AppCreateMethodCallParams:
|
|
327
|
+
"""
|
|
328
|
+
Create AppCreateMethodCallParams using the provided parameters and compilation settings.
|
|
329
|
+
|
|
330
|
+
:param params: AppFactoryCreateMethodCallParams instance.
|
|
331
|
+
:param compilation_params: Optional AppClientCompilationParams instance.
|
|
332
|
+
:return: An instance of AppCreateMethodCallParams.
|
|
333
|
+
"""
|
|
334
|
+
compiled = self._factory.compile(compilation_params)
|
|
335
|
+
|
|
336
|
+
return AppCreateMethodCallParams(
|
|
337
|
+
**{
|
|
338
|
+
**{
|
|
339
|
+
param: value
|
|
340
|
+
for param, value in asdict(params).items()
|
|
341
|
+
if param in {f.name for f in dataclasses.fields(AppCreateMethodCallParams)}
|
|
342
|
+
},
|
|
343
|
+
"app_id": 0,
|
|
344
|
+
"approval_program": compiled.approval_program,
|
|
345
|
+
"clear_state_program": compiled.clear_state_program,
|
|
346
|
+
"schema": params.schema
|
|
347
|
+
or {
|
|
348
|
+
"global_byte_slices": self._factory._app_spec.state.schema.global_state.bytes,
|
|
349
|
+
"global_ints": self._factory._app_spec.state.schema.global_state.ints,
|
|
350
|
+
"local_byte_slices": self._factory._app_spec.state.schema.local_state.bytes,
|
|
351
|
+
"local_ints": self._factory._app_spec.state.schema.local_state.ints,
|
|
352
|
+
},
|
|
353
|
+
"sender": self._factory._get_sender(params.sender),
|
|
354
|
+
"signer": self._factory._get_signer(
|
|
355
|
+
params.sender if params else None, params.signer if params else None
|
|
356
|
+
),
|
|
357
|
+
"method": self._factory._app_spec.get_abi_method(params.method),
|
|
358
|
+
"args": self._factory._get_create_abi_args_with_default_values(params.method, params.args),
|
|
359
|
+
"on_complete": params.on_complete or OnApplicationComplete.NoOp,
|
|
360
|
+
}
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
def deploy_update(self, params: AppClientMethodCallParams) -> AppUpdateMethodCallParams:
|
|
364
|
+
"""
|
|
365
|
+
Create AppUpdateMethodCallParams for an update operation.
|
|
366
|
+
|
|
367
|
+
:param params: AppClientMethodCallParams instance.
|
|
368
|
+
:return: An instance of AppUpdateMethodCallParams.
|
|
369
|
+
"""
|
|
370
|
+
return AppUpdateMethodCallParams(
|
|
371
|
+
**{
|
|
372
|
+
**{
|
|
373
|
+
param: value
|
|
374
|
+
for param, value in asdict(params).items()
|
|
375
|
+
if param in {f.name for f in dataclasses.fields(AppUpdateMethodCallParams)}
|
|
376
|
+
},
|
|
377
|
+
"app_id": 0,
|
|
378
|
+
"approval_program": "",
|
|
379
|
+
"clear_state_program": "",
|
|
380
|
+
"sender": self._factory._get_sender(params.sender),
|
|
381
|
+
"signer": self._factory._get_signer(
|
|
382
|
+
params.sender if params else None, params.signer if params else None
|
|
383
|
+
),
|
|
384
|
+
"method": self._factory._app_spec.get_abi_method(params.method),
|
|
385
|
+
"args": self._factory._get_create_abi_args_with_default_values(params.method, params.args),
|
|
386
|
+
"on_complete": OnApplicationComplete.UpdateApplication,
|
|
387
|
+
}
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
def deploy_delete(self, params: AppClientMethodCallParams) -> AppDeleteMethodCallParams:
|
|
391
|
+
"""
|
|
392
|
+
Create AppDeleteMethodCallParams for a delete operation.
|
|
393
|
+
|
|
394
|
+
:param params: AppClientMethodCallParams instance.
|
|
395
|
+
:return: An instance of AppDeleteMethodCallParams.
|
|
396
|
+
"""
|
|
397
|
+
return AppDeleteMethodCallParams(
|
|
398
|
+
**{
|
|
399
|
+
**{
|
|
400
|
+
param: value
|
|
401
|
+
for param, value in asdict(params).items()
|
|
402
|
+
if param in {f.name for f in dataclasses.fields(AppDeleteMethodCallParams)}
|
|
403
|
+
},
|
|
404
|
+
"app_id": 0,
|
|
405
|
+
"sender": self._factory._get_sender(params.sender),
|
|
406
|
+
"signer": self._factory._get_signer(
|
|
407
|
+
params.sender if params else None, params.signer if params else None
|
|
408
|
+
),
|
|
409
|
+
"method": self._factory.app_spec.get_abi_method(params.method),
|
|
410
|
+
"args": self._factory._get_create_abi_args_with_default_values(params.method, params.args),
|
|
411
|
+
"on_complete": OnApplicationComplete.DeleteApplication,
|
|
412
|
+
}
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
class _AppFactoryBareCreateTransactionAccessor:
|
|
417
|
+
"""Initialize the bare create transaction accessor.
|
|
418
|
+
|
|
419
|
+
:param factory: The AppFactory instance.
|
|
420
|
+
"""
|
|
421
|
+
|
|
422
|
+
def __init__(self, factory: "AppFactory") -> None:
|
|
423
|
+
self._factory = factory
|
|
424
|
+
|
|
425
|
+
def create(self, params: AppFactoryCreateParams | None = None) -> Transaction:
|
|
426
|
+
"""
|
|
427
|
+
Create a transaction for app creation.
|
|
428
|
+
|
|
429
|
+
:param params: Optional AppFactoryCreateParams instance.
|
|
430
|
+
:return: A Transaction instance.
|
|
431
|
+
"""
|
|
432
|
+
return self._factory._algorand.create_transaction.app_create(self._factory.params.bare.create(params))
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
class _TransactionCreator:
|
|
436
|
+
"""
|
|
437
|
+
The transaction creator.
|
|
438
|
+
|
|
439
|
+
:param factory: The AppFactory instance.
|
|
440
|
+
"""
|
|
441
|
+
|
|
442
|
+
def __init__(self, factory: "AppFactory") -> None:
|
|
443
|
+
self._factory = factory
|
|
444
|
+
self._bare = _AppFactoryBareCreateTransactionAccessor(factory)
|
|
445
|
+
|
|
446
|
+
@property
|
|
447
|
+
def bare(self) -> _AppFactoryBareCreateTransactionAccessor:
|
|
448
|
+
"""
|
|
449
|
+
Get the bare create transaction accessor.
|
|
450
|
+
|
|
451
|
+
:return: The _AppFactoryBareCreateTransactionAccessor instance.
|
|
452
|
+
"""
|
|
453
|
+
return self._bare
|
|
454
|
+
|
|
455
|
+
def create(self, params: AppFactoryCreateMethodCallParams) -> BuiltTransactions:
|
|
456
|
+
"""
|
|
457
|
+
Create built transactions for an app method call.
|
|
458
|
+
|
|
459
|
+
:param params: AppFactoryCreateMethodCallParams instance.
|
|
460
|
+
:return: A BuiltTransactions instance.
|
|
461
|
+
"""
|
|
462
|
+
return self._factory._algorand.create_transaction.app_create_method_call(self._factory.params.create(params))
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
class _AppFactoryBareSendAccessor:
|
|
466
|
+
"""
|
|
467
|
+
The bare send accessor.
|
|
468
|
+
|
|
469
|
+
:param factory: The AppFactory instance.
|
|
470
|
+
"""
|
|
471
|
+
|
|
472
|
+
def __init__(self, factory: "AppFactory") -> None:
|
|
473
|
+
self._factory = factory
|
|
474
|
+
self._algorand = factory._algorand
|
|
475
|
+
|
|
476
|
+
def create(
|
|
477
|
+
self,
|
|
478
|
+
params: AppFactoryCreateParams | None = None,
|
|
479
|
+
send_params: SendParams | None = None,
|
|
480
|
+
compilation_params: AppClientCompilationParams | None = None,
|
|
481
|
+
) -> tuple[AppClient, SendAppCreateTransactionResult]:
|
|
482
|
+
"""
|
|
483
|
+
Send an app creation transaction and return the app client along with the transaction result.
|
|
484
|
+
|
|
485
|
+
:param params: Optional AppFactoryCreateParams instance.
|
|
486
|
+
:param send_params: Optional SendParams instance.
|
|
487
|
+
:param compilation_params: Optional AppClientCompilationParams instance.
|
|
488
|
+
:return: A tuple containing the AppClient and SendAppCreateTransactionResult.
|
|
489
|
+
"""
|
|
490
|
+
compilation_params = compilation_params or AppClientCompilationParams()
|
|
491
|
+
compilation_params["updatable"] = (
|
|
492
|
+
compilation_params.get("updatable")
|
|
493
|
+
if compilation_params.get("updatable") is not None
|
|
494
|
+
else self._factory._updatable
|
|
495
|
+
)
|
|
496
|
+
compilation_params["deletable"] = (
|
|
497
|
+
compilation_params.get("deletable")
|
|
498
|
+
if compilation_params.get("deletable") is not None
|
|
499
|
+
else self._factory._deletable
|
|
500
|
+
)
|
|
501
|
+
compilation_params["deploy_time_params"] = (
|
|
502
|
+
compilation_params.get("deploy_time_params")
|
|
503
|
+
if compilation_params.get("deploy_time_params") is not None
|
|
504
|
+
else self._factory._deploy_time_params
|
|
505
|
+
)
|
|
506
|
+
|
|
507
|
+
compiled = self._factory.compile(compilation_params)
|
|
508
|
+
|
|
509
|
+
result = self._factory._handle_call_errors(
|
|
510
|
+
lambda: self._algorand.send.app_create(
|
|
511
|
+
self._factory.params.bare.create(params, compilation_params), send_params
|
|
512
|
+
)
|
|
513
|
+
)
|
|
514
|
+
|
|
515
|
+
return (
|
|
516
|
+
self._factory.get_app_client_by_id(
|
|
517
|
+
app_id=result.app_id,
|
|
518
|
+
),
|
|
519
|
+
SendAppCreateTransactionResult[ABIReturn](
|
|
520
|
+
transaction=result.transaction,
|
|
521
|
+
confirmation=result.confirmation,
|
|
522
|
+
app_id=result.app_id,
|
|
523
|
+
app_address=result.app_address,
|
|
524
|
+
compiled_approval=compiled.compiled_approval if compiled else None,
|
|
525
|
+
compiled_clear=compiled.compiled_clear if compiled else None,
|
|
526
|
+
group_id=result.group_id,
|
|
527
|
+
tx_ids=result.tx_ids,
|
|
528
|
+
transactions=result.transactions,
|
|
529
|
+
confirmations=result.confirmations,
|
|
530
|
+
),
|
|
531
|
+
)
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
class _TransactionSender:
|
|
535
|
+
"""
|
|
536
|
+
The transaction sender.
|
|
537
|
+
|
|
538
|
+
:param factory: The AppFactory instance.
|
|
539
|
+
"""
|
|
540
|
+
|
|
541
|
+
def __init__(self, factory: "AppFactory") -> None:
|
|
542
|
+
self._factory = factory
|
|
543
|
+
self._algorand = factory._algorand
|
|
544
|
+
self._bare = _AppFactoryBareSendAccessor(factory)
|
|
545
|
+
|
|
546
|
+
@property
|
|
547
|
+
def bare(self) -> _AppFactoryBareSendAccessor:
|
|
548
|
+
"""
|
|
549
|
+
Get the bare send accessor.
|
|
550
|
+
|
|
551
|
+
:return: The _AppFactoryBareSendAccessor instance.
|
|
552
|
+
"""
|
|
553
|
+
return self._bare
|
|
554
|
+
|
|
555
|
+
def create(
|
|
556
|
+
self,
|
|
557
|
+
params: AppFactoryCreateMethodCallParams,
|
|
558
|
+
send_params: SendParams | None = None,
|
|
559
|
+
compilation_params: AppClientCompilationParams | None = None,
|
|
560
|
+
) -> tuple[AppClient, AppFactoryCreateMethodCallResult[Arc56ReturnValueType]]:
|
|
561
|
+
"""
|
|
562
|
+
Send an app creation method call and return the app client along with the method call result.
|
|
563
|
+
|
|
564
|
+
:param params: AppFactoryCreateMethodCallParams instance.
|
|
565
|
+
:param send_params: Optional SendParams instance.
|
|
566
|
+
:param compilation_params: Optional AppClientCompilationParams instance.
|
|
567
|
+
:return: A tuple containing the AppClient and AppFactoryCreateMethodCallResult.
|
|
568
|
+
"""
|
|
569
|
+
compilation_params = compilation_params or AppClientCompilationParams()
|
|
570
|
+
compilation_params["updatable"] = (
|
|
571
|
+
compilation_params.get("updatable")
|
|
572
|
+
if compilation_params.get("updatable") is not None
|
|
573
|
+
else self._factory._updatable
|
|
574
|
+
)
|
|
575
|
+
compilation_params["deletable"] = (
|
|
576
|
+
compilation_params.get("deletable")
|
|
577
|
+
if compilation_params.get("deletable") is not None
|
|
578
|
+
else self._factory._deletable
|
|
579
|
+
)
|
|
580
|
+
compilation_params["deploy_time_params"] = (
|
|
581
|
+
compilation_params.get("deploy_time_params")
|
|
582
|
+
if compilation_params.get("deploy_time_params") is not None
|
|
583
|
+
else self._factory._deploy_time_params
|
|
584
|
+
)
|
|
585
|
+
|
|
586
|
+
compiled = self._factory.compile(compilation_params)
|
|
587
|
+
result = self._factory._handle_call_errors(
|
|
588
|
+
lambda: self._factory._parse_method_call_return(
|
|
589
|
+
lambda: self._algorand.send.app_create_method_call(
|
|
590
|
+
self._factory.params.create(params, compilation_params), send_params
|
|
591
|
+
),
|
|
592
|
+
self._factory._app_spec.get_abi_method(params.method),
|
|
593
|
+
)
|
|
594
|
+
)
|
|
595
|
+
|
|
596
|
+
return (
|
|
597
|
+
self._factory.get_app_client_by_id(
|
|
598
|
+
app_id=result.app_id,
|
|
599
|
+
),
|
|
600
|
+
AppFactoryCreateMethodCallResult[Arc56ReturnValueType](
|
|
601
|
+
transaction=result.transaction,
|
|
602
|
+
confirmation=result.confirmation,
|
|
603
|
+
tx_id=result.tx_id,
|
|
604
|
+
app_id=result.app_id,
|
|
605
|
+
app_address=result.app_address,
|
|
606
|
+
abi_return=result.abi_return,
|
|
607
|
+
compiled_approval=compiled.compiled_approval if compiled else None,
|
|
608
|
+
compiled_clear=compiled.compiled_clear if compiled else None,
|
|
609
|
+
group_id=result.group_id,
|
|
610
|
+
tx_ids=result.tx_ids,
|
|
611
|
+
transactions=result.transactions,
|
|
612
|
+
confirmations=result.confirmations,
|
|
613
|
+
returns=result.returns,
|
|
614
|
+
),
|
|
615
|
+
)
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
class AppFactory:
|
|
619
|
+
"""ARC-56/ARC-32 app factory that, for a given app spec, allows you to create
|
|
620
|
+
and deploy one or more app instances and to create one or more app clients
|
|
621
|
+
to interact with those (or other) app instances.
|
|
622
|
+
|
|
623
|
+
:param params: The parameters for the factory
|
|
624
|
+
|
|
625
|
+
:example:
|
|
626
|
+
>>> factory = AppFactory(AppFactoryParams(
|
|
627
|
+
>>> algorand=AlgorandClient.mainnet(),
|
|
628
|
+
>>> app_spec=app_spec,
|
|
629
|
+
>>> )
|
|
630
|
+
>>> )
|
|
631
|
+
"""
|
|
632
|
+
|
|
633
|
+
def __init__(self, params: AppFactoryParams) -> None:
|
|
634
|
+
self._app_spec = AppClient.normalise_app_spec(params.app_spec)
|
|
635
|
+
self._app_name = params.app_name or self._app_spec.name
|
|
636
|
+
self._algorand = params.algorand
|
|
637
|
+
self._version = params.version or "1.0"
|
|
638
|
+
self._default_sender = params.default_sender
|
|
639
|
+
self._default_signer = params.default_signer
|
|
640
|
+
self._approval_source_map: ProgramSourceMap | None = None
|
|
641
|
+
self._clear_source_map: ProgramSourceMap | None = None
|
|
642
|
+
self._params_accessor = _MethodParamsBuilder(self)
|
|
643
|
+
self._send_accessor = _TransactionSender(self)
|
|
644
|
+
self._create_transaction_accessor = _TransactionCreator(self)
|
|
645
|
+
|
|
646
|
+
compilation_params = params.compilation_params or AppClientCompilationParams()
|
|
647
|
+
self._deploy_time_params = compilation_params.get("deploy_time_params")
|
|
648
|
+
self._updatable = compilation_params.get("updatable")
|
|
649
|
+
self._deletable = compilation_params.get("deletable")
|
|
650
|
+
|
|
651
|
+
@property
|
|
652
|
+
def app_name(self) -> str:
|
|
653
|
+
"""The name of the app"""
|
|
654
|
+
return self._app_name
|
|
655
|
+
|
|
656
|
+
@property
|
|
657
|
+
def app_spec(self) -> arc56.Arc56Contract:
|
|
658
|
+
"""The app spec"""
|
|
659
|
+
return self._app_spec
|
|
660
|
+
|
|
661
|
+
@property
|
|
662
|
+
def algorand(self) -> AlgorandClient:
|
|
663
|
+
"""The algorand client"""
|
|
664
|
+
return self._algorand
|
|
665
|
+
|
|
666
|
+
@property
|
|
667
|
+
def params(self) -> _MethodParamsBuilder:
|
|
668
|
+
"""Get parameters to create transactions (create and deploy related calls) for the current app.
|
|
669
|
+
|
|
670
|
+
A good mental model for this is that these parameters represent a deferred transaction creation.
|
|
671
|
+
|
|
672
|
+
:example: Create a transaction in the future using Algorand Client
|
|
673
|
+
>>> create_app_params = app_factory.params.create(
|
|
674
|
+
... AppFactoryCreateMethodCallParams(
|
|
675
|
+
... method='create_method',
|
|
676
|
+
... args=[123, 'hello']
|
|
677
|
+
... )
|
|
678
|
+
... )
|
|
679
|
+
>>> # ...
|
|
680
|
+
>>> algorand.send.app_create_method_call(create_app_params)
|
|
681
|
+
|
|
682
|
+
:example: Define a nested transaction as an ABI argument
|
|
683
|
+
>>> create_app_params = appFactory.params.create(
|
|
684
|
+
... AppFactoryCreateMethodCallParams(
|
|
685
|
+
... method='create_method',
|
|
686
|
+
... args=[123, 'hello']
|
|
687
|
+
... )
|
|
688
|
+
... )
|
|
689
|
+
>>> app_client.send.call(
|
|
690
|
+
... AppClientMethodCallParams(
|
|
691
|
+
... method='my_method',
|
|
692
|
+
... args=[create_app_params]
|
|
693
|
+
... )
|
|
694
|
+
... )
|
|
695
|
+
"""
|
|
696
|
+
return self._params_accessor
|
|
697
|
+
|
|
698
|
+
@property
|
|
699
|
+
def send(self) -> _TransactionSender:
|
|
700
|
+
"""
|
|
701
|
+
Get the transaction sender.
|
|
702
|
+
|
|
703
|
+
:return: The _TransactionSender instance.
|
|
704
|
+
"""
|
|
705
|
+
return self._send_accessor
|
|
706
|
+
|
|
707
|
+
@property
|
|
708
|
+
def create_transaction(self) -> _TransactionCreator:
|
|
709
|
+
"""
|
|
710
|
+
Get the transaction creator.
|
|
711
|
+
|
|
712
|
+
:return: The _TransactionCreator instance.
|
|
713
|
+
"""
|
|
714
|
+
return self._create_transaction_accessor
|
|
715
|
+
|
|
716
|
+
def deploy(
|
|
717
|
+
self,
|
|
718
|
+
*,
|
|
719
|
+
on_update: OnUpdate | None = None,
|
|
720
|
+
on_schema_break: OnSchemaBreak | None = None,
|
|
721
|
+
create_params: AppClientMethodCallCreateParams | AppClientBareCallCreateParams | None = None,
|
|
722
|
+
update_params: AppClientMethodCallParams | AppClientBareCallParams | None = None,
|
|
723
|
+
delete_params: AppClientMethodCallParams | AppClientBareCallParams | None = None,
|
|
724
|
+
existing_deployments: ApplicationLookup | None = None,
|
|
725
|
+
ignore_cache: bool = False,
|
|
726
|
+
app_name: str | None = None,
|
|
727
|
+
send_params: SendParams | None = None,
|
|
728
|
+
compilation_params: AppClientCompilationParams | None = None,
|
|
729
|
+
) -> tuple[AppClient, AppFactoryDeployResult]:
|
|
730
|
+
"""Idempotently deploy (create if not exists, update if changed) an app against the given name for the given
|
|
731
|
+
creator account, including deploy-time TEAL template placeholder substitutions (if specified).
|
|
732
|
+
|
|
733
|
+
**Note:** When using the return from this function be sure to check `operationPerformed` to get access to
|
|
734
|
+
various return properties like `transaction`, `confirmation` and `deleteResult`.
|
|
735
|
+
|
|
736
|
+
**Note:** if there is a breaking state schema change to an existing app (and `onSchemaBreak` is set to
|
|
737
|
+
`'replace'`) the existing app will be deleted and re-created.
|
|
738
|
+
|
|
739
|
+
**Note:** if there is an update (different TEAL code) to an existing app (and `onUpdate` is set to
|
|
740
|
+
`'replace'`) the existing app will be deleted and re-created.
|
|
741
|
+
|
|
742
|
+
:param on_update: The action to take if there is an update to the app
|
|
743
|
+
:param on_schema_break: The action to take if there is a breaking state schema change to the app
|
|
744
|
+
:param create_params: The arguments to create the app
|
|
745
|
+
:param update_params: The arguments to update the app
|
|
746
|
+
:param delete_params: The arguments to delete the app
|
|
747
|
+
:param existing_deployments: The existing deployments to use
|
|
748
|
+
:param ignore_cache: Whether to ignore the cache
|
|
749
|
+
:param app_name: The name of the app
|
|
750
|
+
:param send_params: The parameters for the send call
|
|
751
|
+
:param compilation_params: The parameters for the compilation
|
|
752
|
+
:returns: The app client and the result of the deployment
|
|
753
|
+
|
|
754
|
+
:example:
|
|
755
|
+
>>> app_client, result = factory.deploy({
|
|
756
|
+
>>> create_params=AppClientMethodCallCreateParams(
|
|
757
|
+
>>> sender='SENDER_ADDRESS',
|
|
758
|
+
>>> approval_program='APPROVAL PROGRAM',
|
|
759
|
+
>>> clear_state_program='CLEAR PROGRAM',
|
|
760
|
+
>>> schema={
|
|
761
|
+
>>> "global_byte_slices": 0,
|
|
762
|
+
>>> "global_ints": 0,
|
|
763
|
+
>>> "local_byte_slices": 0,
|
|
764
|
+
>>> "local_ints": 0
|
|
765
|
+
>>> }
|
|
766
|
+
>>> ),
|
|
767
|
+
>>> update_params=AppClientMethodCallParams(
|
|
768
|
+
>>> sender='SENDER_ADDRESS'
|
|
769
|
+
>>> ),
|
|
770
|
+
>>> delete_params=AppClientMethodCallParams(
|
|
771
|
+
>>> sender='SENDER_ADDRESS'
|
|
772
|
+
>>> ),
|
|
773
|
+
>>> compilation_params=AppClientCompilationParams(
|
|
774
|
+
>>> updatable=False,
|
|
775
|
+
>>> deletable=False
|
|
776
|
+
>>> ),
|
|
777
|
+
>>> app_name='my_app',
|
|
778
|
+
>>> on_schema_break=OnSchemaBreak.AppendApp,
|
|
779
|
+
>>> on_update=OnUpdate.AppendApp
|
|
780
|
+
>>> })
|
|
781
|
+
"""
|
|
782
|
+
# Resolve control parameters with factory defaults
|
|
783
|
+
send_params = send_params or SendParams()
|
|
784
|
+
compilation_params = compilation_params or AppClientCompilationParams()
|
|
785
|
+
resolved_updatable = (
|
|
786
|
+
upd
|
|
787
|
+
if (upd := compilation_params.get("updatable")) is not None
|
|
788
|
+
else self._updatable or self._get_deploy_time_control("updatable")
|
|
789
|
+
)
|
|
790
|
+
resolved_deletable = (
|
|
791
|
+
dlb
|
|
792
|
+
if (dlb := compilation_params.get("deletable")) is not None
|
|
793
|
+
else self._deletable or self._get_deploy_time_control("deletable")
|
|
794
|
+
)
|
|
795
|
+
resolved_deploy_time_params = compilation_params.get("deploy_time_params") or self._deploy_time_params
|
|
796
|
+
|
|
797
|
+
def prepare_create_args() -> AppCreateMethodCallParams | AppCreateParams:
|
|
798
|
+
"""Prepare create arguments based on parameter type."""
|
|
799
|
+
if create_params and isinstance(create_params, AppClientMethodCallCreateParams):
|
|
800
|
+
return self.params.create(
|
|
801
|
+
AppFactoryCreateMethodCallParams(
|
|
802
|
+
**asdict(create_params),
|
|
803
|
+
),
|
|
804
|
+
compilation_params={
|
|
805
|
+
"updatable": resolved_updatable,
|
|
806
|
+
"deletable": resolved_deletable,
|
|
807
|
+
"deploy_time_params": resolved_deploy_time_params,
|
|
808
|
+
},
|
|
809
|
+
)
|
|
810
|
+
|
|
811
|
+
base_params = create_params or AppClientBareCallCreateParams()
|
|
812
|
+
return self.params.bare.create(
|
|
813
|
+
AppFactoryCreateParams(
|
|
814
|
+
**asdict(base_params) if base_params else {},
|
|
815
|
+
),
|
|
816
|
+
compilation_params={
|
|
817
|
+
"updatable": resolved_updatable,
|
|
818
|
+
"deletable": resolved_deletable,
|
|
819
|
+
"deploy_time_params": resolved_deploy_time_params,
|
|
820
|
+
},
|
|
821
|
+
)
|
|
822
|
+
|
|
823
|
+
def prepare_update_args() -> AppUpdateMethodCallParams | AppUpdateParams:
|
|
824
|
+
"""Prepare update arguments based on parameter type."""
|
|
825
|
+
return (
|
|
826
|
+
self.params.deploy_update(update_params)
|
|
827
|
+
if isinstance(update_params, AppClientMethodCallParams)
|
|
828
|
+
else self.params.bare.deploy_update(update_params)
|
|
829
|
+
)
|
|
830
|
+
|
|
831
|
+
def prepare_delete_args() -> AppDeleteMethodCallParams | AppDeleteParams:
|
|
832
|
+
"""Prepare delete arguments based on parameter type."""
|
|
833
|
+
return (
|
|
834
|
+
self.params.deploy_delete(delete_params)
|
|
835
|
+
if isinstance(delete_params, AppClientMethodCallParams)
|
|
836
|
+
else self.params.bare.deploy_delete(delete_params)
|
|
837
|
+
)
|
|
838
|
+
|
|
839
|
+
# Execute deployment
|
|
840
|
+
deploy_params = AppDeployParams(
|
|
841
|
+
deploy_time_params=resolved_deploy_time_params,
|
|
842
|
+
on_schema_break=on_schema_break,
|
|
843
|
+
on_update=on_update,
|
|
844
|
+
existing_deployments=existing_deployments,
|
|
845
|
+
ignore_cache=ignore_cache,
|
|
846
|
+
create_params=prepare_create_args(),
|
|
847
|
+
update_params=prepare_update_args(),
|
|
848
|
+
delete_params=prepare_delete_args(),
|
|
849
|
+
metadata=AppDeploymentMetaData(
|
|
850
|
+
name=app_name or self._app_name,
|
|
851
|
+
version=self._version,
|
|
852
|
+
updatable=resolved_updatable,
|
|
853
|
+
deletable=resolved_deletable,
|
|
854
|
+
),
|
|
855
|
+
send_params=send_params,
|
|
856
|
+
)
|
|
857
|
+
deploy_result = self._algorand.app_deployer.deploy(deploy_params)
|
|
858
|
+
|
|
859
|
+
# Prepare app client and factory deploy response
|
|
860
|
+
app_client = self.get_app_client_by_id(
|
|
861
|
+
app_id=deploy_result.app.app_id,
|
|
862
|
+
app_name=app_name,
|
|
863
|
+
default_sender=self._default_sender,
|
|
864
|
+
default_signer=self._default_signer,
|
|
865
|
+
)
|
|
866
|
+
factory_deploy_result = AppFactoryDeployResult.from_deploy_result(
|
|
867
|
+
response=deploy_result,
|
|
868
|
+
deploy_params=deploy_params,
|
|
869
|
+
app_spec=app_client.app_spec,
|
|
870
|
+
app_compilation_data=self.compile(
|
|
871
|
+
AppClientCompilationParams(
|
|
872
|
+
deploy_time_params=resolved_deploy_time_params,
|
|
873
|
+
updatable=resolved_updatable,
|
|
874
|
+
deletable=resolved_deletable,
|
|
875
|
+
)
|
|
876
|
+
),
|
|
877
|
+
)
|
|
878
|
+
|
|
879
|
+
return app_client, factory_deploy_result
|
|
880
|
+
|
|
881
|
+
def get_app_client_by_id(
|
|
882
|
+
self,
|
|
883
|
+
app_id: int,
|
|
884
|
+
app_name: str | None = None,
|
|
885
|
+
default_sender: str | None = None, # Address can be string or bytes
|
|
886
|
+
default_signer: TransactionSigner | None = None,
|
|
887
|
+
approval_source_map: ProgramSourceMap | None = None,
|
|
888
|
+
clear_source_map: ProgramSourceMap | None = None,
|
|
889
|
+
) -> AppClient:
|
|
890
|
+
"""Returns a new `AppClient` client for an app instance of the given ID.
|
|
891
|
+
|
|
892
|
+
:param app_id: The id of the app
|
|
893
|
+
:param app_name: The name of the app
|
|
894
|
+
:param default_sender: The default sender address
|
|
895
|
+
:param default_signer: The default signer
|
|
896
|
+
:param approval_source_map: The approval source map
|
|
897
|
+
:param clear_source_map: The clear source map
|
|
898
|
+
:return AppClient: The app client
|
|
899
|
+
|
|
900
|
+
:example:
|
|
901
|
+
>>> app_client = factory.get_app_client_by_id(app_id=123)
|
|
902
|
+
"""
|
|
903
|
+
return AppClient(
|
|
904
|
+
AppClientParams(
|
|
905
|
+
app_id=app_id,
|
|
906
|
+
algorand=self._algorand,
|
|
907
|
+
app_spec=self._app_spec,
|
|
908
|
+
app_name=app_name or self._app_name,
|
|
909
|
+
default_sender=default_sender or self._default_sender,
|
|
910
|
+
default_signer=default_signer or self._default_signer,
|
|
911
|
+
approval_source_map=approval_source_map or self._approval_source_map,
|
|
912
|
+
clear_source_map=clear_source_map or self._clear_source_map,
|
|
913
|
+
)
|
|
914
|
+
)
|
|
915
|
+
|
|
916
|
+
def get_app_client_by_creator_and_name(
|
|
917
|
+
self,
|
|
918
|
+
creator_address: str,
|
|
919
|
+
app_name: str,
|
|
920
|
+
default_sender: str | None = None,
|
|
921
|
+
default_signer: TransactionSigner | None = None,
|
|
922
|
+
ignore_cache: bool | None = None,
|
|
923
|
+
app_lookup_cache: ApplicationLookup | None = None,
|
|
924
|
+
approval_source_map: ProgramSourceMap | None = None,
|
|
925
|
+
clear_source_map: ProgramSourceMap | None = None,
|
|
926
|
+
) -> AppClient:
|
|
927
|
+
"""Returns a new `AppClient` client, resolving the app by creator address and name
|
|
928
|
+
using AlgoKit app deployment semantics (i.e. looking for the app creation transaction note).
|
|
929
|
+
|
|
930
|
+
:param creator_address: The creator address
|
|
931
|
+
:param app_name: The name of the app
|
|
932
|
+
:param default_sender: The default sender address
|
|
933
|
+
:param default_signer: The default signer
|
|
934
|
+
:param ignore_cache: Whether to ignore the cache and force a lookup
|
|
935
|
+
:param app_lookup_cache: Optional cache of existing app deployments to use instead of querying the indexer
|
|
936
|
+
:param approval_source_map: Optional source map for the approval program
|
|
937
|
+
:param clear_source_map: Optional source map for the clear state program
|
|
938
|
+
:return: An AppClient instance configured for the resolved application
|
|
939
|
+
|
|
940
|
+
:example:
|
|
941
|
+
>>> app_client = factory.get_app_client_by_creator_and_name(
|
|
942
|
+
... creator_address='SENDER_ADDRESS',
|
|
943
|
+
... app_name='my_app'
|
|
944
|
+
... )
|
|
945
|
+
"""
|
|
946
|
+
return AppClient.from_creator_and_name(
|
|
947
|
+
creator_address=creator_address,
|
|
948
|
+
app_name=app_name or self._app_name,
|
|
949
|
+
default_sender=default_sender or self._default_sender,
|
|
950
|
+
default_signer=default_signer or self._default_signer,
|
|
951
|
+
approval_source_map=approval_source_map or self._approval_source_map,
|
|
952
|
+
clear_source_map=clear_source_map or self._clear_source_map,
|
|
953
|
+
ignore_cache=ignore_cache,
|
|
954
|
+
app_lookup_cache=app_lookup_cache,
|
|
955
|
+
app_spec=self._app_spec,
|
|
956
|
+
algorand=self._algorand,
|
|
957
|
+
)
|
|
958
|
+
|
|
959
|
+
def export_source_maps(self) -> AppSourceMaps:
|
|
960
|
+
if not self._approval_source_map or not self._clear_source_map:
|
|
961
|
+
raise ValueError(
|
|
962
|
+
"Unable to export source maps; they haven't been loaded into this client - "
|
|
963
|
+
"you need to call create, update, or deploy first"
|
|
964
|
+
)
|
|
965
|
+
return AppSourceMaps(
|
|
966
|
+
approval_source_map=self._approval_source_map,
|
|
967
|
+
clear_source_map=self._clear_source_map,
|
|
968
|
+
)
|
|
969
|
+
|
|
970
|
+
def import_source_maps(self, source_maps: AppSourceMaps) -> None:
|
|
971
|
+
"""
|
|
972
|
+
Import the provided source maps into the factory.
|
|
973
|
+
|
|
974
|
+
:param source_maps: An AppSourceMaps instance containing the approval and clear source maps.
|
|
975
|
+
"""
|
|
976
|
+
self._approval_source_map = source_maps.approval_source_map
|
|
977
|
+
self._clear_source_map = source_maps.clear_source_map
|
|
978
|
+
|
|
979
|
+
def compile(self, compilation_params: AppClientCompilationParams | None = None) -> AppClientCompilationResult:
|
|
980
|
+
"""Compile the app's TEAL code.
|
|
981
|
+
|
|
982
|
+
:param compilation_params: The compilation parameters
|
|
983
|
+
:return AppClientCompilationResult: The compilation result
|
|
984
|
+
|
|
985
|
+
:example:
|
|
986
|
+
>>> compilation_result = factory.compile()
|
|
987
|
+
"""
|
|
988
|
+
compilation = compilation_params or AppClientCompilationParams()
|
|
989
|
+
result = AppClient.compile(
|
|
990
|
+
app_spec=self._app_spec,
|
|
991
|
+
app_manager=self._algorand.app,
|
|
992
|
+
compilation_params=compilation,
|
|
993
|
+
)
|
|
994
|
+
|
|
995
|
+
if result.compiled_approval:
|
|
996
|
+
self._approval_source_map = result.compiled_approval.source_map
|
|
997
|
+
if result.compiled_clear:
|
|
998
|
+
self._clear_source_map = result.compiled_clear.source_map
|
|
999
|
+
|
|
1000
|
+
return result
|
|
1001
|
+
|
|
1002
|
+
def _expose_logic_error(self, e: Exception, is_clear_state_program: bool = False) -> Exception: # noqa: FBT002 FBT001
|
|
1003
|
+
"""
|
|
1004
|
+
Convert a low-level exception into a descriptive logic error.
|
|
1005
|
+
|
|
1006
|
+
:param e: The original exception.
|
|
1007
|
+
:param is_clear_state_program: Flag indicating if the error is related to the clear state program.
|
|
1008
|
+
:return: The transformed exception.
|
|
1009
|
+
"""
|
|
1010
|
+
return AppClient._expose_logic_error_static(
|
|
1011
|
+
e=e,
|
|
1012
|
+
app_spec=self._app_spec,
|
|
1013
|
+
is_clear_state_program=is_clear_state_program,
|
|
1014
|
+
approval_source_map=self._approval_source_map,
|
|
1015
|
+
clear_source_map=self._clear_source_map,
|
|
1016
|
+
program=None,
|
|
1017
|
+
approval_source_info=(self._app_spec.source_info.approval if self._app_spec.source_info else None),
|
|
1018
|
+
clear_source_info=(self._app_spec.source_info.clear if self._app_spec.source_info else None),
|
|
1019
|
+
)
|
|
1020
|
+
|
|
1021
|
+
def _get_deploy_time_control(self, control: str) -> bool | None:
|
|
1022
|
+
"""
|
|
1023
|
+
Determine the deploy time control flag for the specified control type.
|
|
1024
|
+
|
|
1025
|
+
:param control: The control type ('updatable' or 'deletable').
|
|
1026
|
+
:return: A boolean flag or None if not determinable.
|
|
1027
|
+
"""
|
|
1028
|
+
approval = self._app_spec.source.get_decoded_approval() if self._app_spec.source else None
|
|
1029
|
+
|
|
1030
|
+
template_name = UPDATABLE_TEMPLATE_NAME if control == "updatable" else DELETABLE_TEMPLATE_NAME
|
|
1031
|
+
if not approval or template_name not in approval:
|
|
1032
|
+
return None
|
|
1033
|
+
|
|
1034
|
+
on_complete = "UpdateApplication" if control == "updatable" else "DeleteApplication"
|
|
1035
|
+
return on_complete in self._app_spec.bare_actions.call or any(
|
|
1036
|
+
on_complete in m.actions.call for m in self._app_spec.methods if m.actions and m.actions.call
|
|
1037
|
+
)
|
|
1038
|
+
|
|
1039
|
+
def _get_sender(self, sender: str | None) -> str:
|
|
1040
|
+
"""
|
|
1041
|
+
Retrieve the sender address.
|
|
1042
|
+
|
|
1043
|
+
:param sender: The specified sender address.
|
|
1044
|
+
:return: The sender address.
|
|
1045
|
+
:raises Exception: If no sender is provided and no default sender is set.
|
|
1046
|
+
"""
|
|
1047
|
+
if not sender and not self._default_sender:
|
|
1048
|
+
raise Exception(
|
|
1049
|
+
f"No sender provided and no default sender present in app client for call to app {self._app_name}"
|
|
1050
|
+
)
|
|
1051
|
+
return str(sender or self._default_sender)
|
|
1052
|
+
|
|
1053
|
+
def _get_signer(self, sender: str | None, signer: TransactionSigner | None) -> TransactionSigner | None:
|
|
1054
|
+
"""
|
|
1055
|
+
Retrieve the transaction signer.
|
|
1056
|
+
|
|
1057
|
+
:param sender: The sender address.
|
|
1058
|
+
:param signer: The provided signer.
|
|
1059
|
+
:return: The transaction signer if available.
|
|
1060
|
+
"""
|
|
1061
|
+
return signer or (self._default_signer if not sender or sender == self._default_sender else None)
|
|
1062
|
+
|
|
1063
|
+
def _handle_call_errors(self, call: Callable[[], T]) -> T:
|
|
1064
|
+
try:
|
|
1065
|
+
return call()
|
|
1066
|
+
except Exception as e:
|
|
1067
|
+
raise self._expose_logic_error(e) from None
|
|
1068
|
+
|
|
1069
|
+
def _parse_method_call_return(
|
|
1070
|
+
self,
|
|
1071
|
+
result: Callable[
|
|
1072
|
+
[], SendAppTransactionResult | SendAppCreateTransactionResult | SendAppUpdateTransactionResult
|
|
1073
|
+
],
|
|
1074
|
+
method: arc56.Method,
|
|
1075
|
+
) -> AppFactoryCreateMethodCallResult[Arc56ReturnValueType]:
|
|
1076
|
+
_ = method # kept for compatibility
|
|
1077
|
+
"""
|
|
1078
|
+
Parse the method call return value and convert the ABI return.
|
|
1079
|
+
|
|
1080
|
+
:param result: A callable that returns the transaction result.
|
|
1081
|
+
:param method: The ABI method associated with the call.
|
|
1082
|
+
:return: An AppFactoryCreateMethodCallResult with the parsed ABI return.
|
|
1083
|
+
:raises ValueError: If ABI return decoding failed.
|
|
1084
|
+
"""
|
|
1085
|
+
result_value = result()
|
|
1086
|
+
abi_return_value: Arc56ReturnValueType
|
|
1087
|
+
if isinstance(result_value.abi_return, ABIReturn):
|
|
1088
|
+
if result_value.abi_return.decode_error:
|
|
1089
|
+
raise ValueError(result_value.abi_return.decode_error)
|
|
1090
|
+
abi_return_value = result_value.abi_return.value
|
|
1091
|
+
else:
|
|
1092
|
+
abi_return_value = None
|
|
1093
|
+
return AppFactoryCreateMethodCallResult[Arc56ReturnValueType](
|
|
1094
|
+
**{
|
|
1095
|
+
**result_value.__dict__,
|
|
1096
|
+
"abi_return": abi_return_value,
|
|
1097
|
+
}
|
|
1098
|
+
)
|
|
1099
|
+
|
|
1100
|
+
def _get_create_abi_args_with_default_values(
|
|
1101
|
+
self,
|
|
1102
|
+
method_name_or_signature: str,
|
|
1103
|
+
user_args: Sequence[Any] | None,
|
|
1104
|
+
) -> list[Any]:
|
|
1105
|
+
"""
|
|
1106
|
+
Builds a list of ABI argument values for creation calls, applying default
|
|
1107
|
+
argument values when not provided.
|
|
1108
|
+
"""
|
|
1109
|
+
method = self._app_spec.get_abi_method(method_name_or_signature)
|
|
1110
|
+
|
|
1111
|
+
results: list[Any] = []
|
|
1112
|
+
|
|
1113
|
+
for i, param in enumerate(method.args):
|
|
1114
|
+
if user_args and i < len(user_args):
|
|
1115
|
+
arg_value = user_args[i]
|
|
1116
|
+
|
|
1117
|
+
results.append(arg_value)
|
|
1118
|
+
continue
|
|
1119
|
+
|
|
1120
|
+
default_value = getattr(param, "default_value", None)
|
|
1121
|
+
if default_value:
|
|
1122
|
+
if default_value.source == "literal":
|
|
1123
|
+
raw_value = base64.b64decode(default_value.data)
|
|
1124
|
+
value_type = default_value.type or param.type
|
|
1125
|
+
assert not isinstance(value_type, arc56.TransactionType), (
|
|
1126
|
+
"transaction type cannot be a default value"
|
|
1127
|
+
)
|
|
1128
|
+
decoded_value = get_abi_decoded_value(raw_value, value_type)
|
|
1129
|
+
results.append(decoded_value)
|
|
1130
|
+
else:
|
|
1131
|
+
raise ValueError(
|
|
1132
|
+
f"Cannot provide default value from source={default_value.source} for a contract creation call."
|
|
1133
|
+
)
|
|
1134
|
+
else:
|
|
1135
|
+
param_name = param.name or f"arg{i + 1}"
|
|
1136
|
+
raise ValueError(
|
|
1137
|
+
f"No value provided for required argument {param_name} in call to method {method.name}"
|
|
1138
|
+
)
|
|
1139
|
+
|
|
1140
|
+
return results
|