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,756 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from typing import TYPE_CHECKING, Literal, Optional, TypeVar
|
|
4
|
+
from urllib import parse
|
|
5
|
+
|
|
6
|
+
from algokit_abi import arc56
|
|
7
|
+
from algokit_algod_client import AlgodClient
|
|
8
|
+
from algokit_algod_client import ClientConfig as AlgodClientConfig
|
|
9
|
+
from algokit_algod_client import models as algod_models
|
|
10
|
+
from algokit_common import ProgramSourceMap
|
|
11
|
+
from algokit_indexer_client import ClientConfig as IndexerClientConfig
|
|
12
|
+
from algokit_indexer_client import IndexerClient
|
|
13
|
+
from algokit_kmd_client import ClientConfig as KmdClientConfig
|
|
14
|
+
from algokit_kmd_client import KmdClient
|
|
15
|
+
from algokit_utils.clients.dispenser_api_client import TestNetDispenserApiClient
|
|
16
|
+
from algokit_utils.models.network import AlgoClientConfigs, AlgoClientNetworkConfig
|
|
17
|
+
from algokit_utils.protocols.signer import TransactionSigner
|
|
18
|
+
from algokit_utils.protocols.typed_clients import TypedAppClientProtocol, TypedAppFactoryProtocol
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from algokit_utils.algorand import AlgorandClient
|
|
22
|
+
from algokit_utils.applications.app_client import AppClient, AppClientCompilationParams
|
|
23
|
+
from algokit_utils.applications.app_deployer import ApplicationLookup
|
|
24
|
+
from algokit_utils.applications.app_factory import AppFactory
|
|
25
|
+
|
|
26
|
+
__all__ = [
|
|
27
|
+
"AlgoSdkClients",
|
|
28
|
+
"ClientManager",
|
|
29
|
+
"NetworkDetail",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
TypedFactoryT = TypeVar("TypedFactoryT", bound=TypedAppFactoryProtocol)
|
|
33
|
+
TypedAppClientT = TypeVar("TypedAppClientT", bound=TypedAppClientProtocol)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class AlgoSdkClients:
|
|
37
|
+
"""Container for Algorand SDK client instances.
|
|
38
|
+
|
|
39
|
+
Holds references to Algod, Indexer and KMD clients.
|
|
40
|
+
|
|
41
|
+
:param algod: Algod client instance (protocol-compatible typed client)
|
|
42
|
+
:param indexer: Optional Indexer client instance
|
|
43
|
+
:param kmd: Optional KMD client instance
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(
|
|
47
|
+
self,
|
|
48
|
+
algod: AlgodClient,
|
|
49
|
+
indexer: IndexerClient | None = None,
|
|
50
|
+
kmd: KmdClient | None = None,
|
|
51
|
+
):
|
|
52
|
+
self.algod = algod
|
|
53
|
+
self.indexer = indexer
|
|
54
|
+
self.kmd = kmd
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass(kw_only=True, frozen=True)
|
|
58
|
+
class NetworkDetail:
|
|
59
|
+
"""Details about an Algorand network.
|
|
60
|
+
|
|
61
|
+
Contains network type flags and genesis information.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
is_testnet: bool
|
|
65
|
+
"""Whether the network is a testnet"""
|
|
66
|
+
is_mainnet: bool
|
|
67
|
+
"""Whether the network is a mainnet"""
|
|
68
|
+
is_localnet: bool
|
|
69
|
+
"""Whether the network is a localnet"""
|
|
70
|
+
genesis_id: str
|
|
71
|
+
"""The genesis ID of the network"""
|
|
72
|
+
genesis_hash: str
|
|
73
|
+
"""The genesis hash of the network"""
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _get_config_from_environment(environment_prefix: str) -> AlgoClientNetworkConfig:
|
|
77
|
+
server = os.getenv(f"{environment_prefix}_SERVER")
|
|
78
|
+
if server is None:
|
|
79
|
+
raise Exception(f"Server environment variable not set: {environment_prefix}_SERVER")
|
|
80
|
+
port = os.getenv(f"{environment_prefix}_PORT")
|
|
81
|
+
if port:
|
|
82
|
+
parsed = parse.urlparse(server)
|
|
83
|
+
server = parsed._replace(netloc=f"{parsed.hostname}").geturl()
|
|
84
|
+
return AlgoClientNetworkConfig(server, os.getenv(f"{environment_prefix}_TOKEN", ""), port=port)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class ClientManager:
|
|
88
|
+
"""Manager for Algorand SDK clients.
|
|
89
|
+
|
|
90
|
+
Provides access to Algod, Indexer and KMD clients and helper methods for working with them.
|
|
91
|
+
|
|
92
|
+
:param clients_or_configs: Either client instances or client configurations
|
|
93
|
+
:param algorand_client: "AlgorandClient" instance
|
|
94
|
+
|
|
95
|
+
:example:
|
|
96
|
+
>>> # Algod only
|
|
97
|
+
>>> client_manager = ClientManager(algod_client)
|
|
98
|
+
>>> # Algod and Indexer
|
|
99
|
+
>>> client_manager = ClientManager(algod_client, indexer_client)
|
|
100
|
+
>>> # Algod config only
|
|
101
|
+
>>> client_manager = ClientManager(ClientManager.get_algod_config_from_environment())
|
|
102
|
+
>>> # Algod and Indexer config
|
|
103
|
+
>>> client_manager = ClientManager(ClientManager.get_algod_config_from_environment(),
|
|
104
|
+
... ClientManager.get_indexer_config_from_environment())
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
def __init__(self, clients_or_configs: AlgoClientConfigs | AlgoSdkClients, algorand_client: "AlgorandClient"):
|
|
108
|
+
if isinstance(clients_or_configs, AlgoSdkClients):
|
|
109
|
+
_clients = clients_or_configs
|
|
110
|
+
elif isinstance(clients_or_configs, AlgoClientConfigs):
|
|
111
|
+
_clients = AlgoSdkClients(
|
|
112
|
+
algod=ClientManager.get_algod_client(clients_or_configs.algod_config),
|
|
113
|
+
indexer=ClientManager.get_indexer_client(clients_or_configs.indexer_config)
|
|
114
|
+
if clients_or_configs.indexer_config
|
|
115
|
+
else None,
|
|
116
|
+
kmd=ClientManager.get_kmd_client(clients_or_configs.kmd_config)
|
|
117
|
+
if clients_or_configs.kmd_config
|
|
118
|
+
else None,
|
|
119
|
+
)
|
|
120
|
+
self._algod = _clients.algod
|
|
121
|
+
self._indexer = _clients.indexer
|
|
122
|
+
self._kmd = _clients.kmd
|
|
123
|
+
self._algorand = algorand_client
|
|
124
|
+
self._suggested_params: algod_models.SuggestedParams | None = None
|
|
125
|
+
|
|
126
|
+
@property
|
|
127
|
+
def algod(self) -> AlgodClient:
|
|
128
|
+
"""Returns the typed Algod API client instance.
|
|
129
|
+
|
|
130
|
+
:return: Algod client instance
|
|
131
|
+
"""
|
|
132
|
+
return self._algod
|
|
133
|
+
|
|
134
|
+
@property
|
|
135
|
+
def indexer(self) -> IndexerClient:
|
|
136
|
+
"""Returns an Indexer API client.
|
|
137
|
+
|
|
138
|
+
:raises ValueError: If no Indexer client is configured
|
|
139
|
+
:return: Indexer client instance
|
|
140
|
+
"""
|
|
141
|
+
if not self._indexer:
|
|
142
|
+
raise ValueError("Attempt to use Indexer client in AlgoKit instance with no Indexer configured")
|
|
143
|
+
return self._indexer
|
|
144
|
+
|
|
145
|
+
@property
|
|
146
|
+
def indexer_if_present(self) -> IndexerClient | None:
|
|
147
|
+
"""Returns the Indexer client if configured, otherwise None.
|
|
148
|
+
|
|
149
|
+
:return: Indexer client instance or None
|
|
150
|
+
"""
|
|
151
|
+
return self._indexer
|
|
152
|
+
|
|
153
|
+
@property
|
|
154
|
+
def kmd(self) -> KmdClient:
|
|
155
|
+
"""Returns a KMD-compatible API client.
|
|
156
|
+
|
|
157
|
+
:raises ValueError: If no KMD client is configured
|
|
158
|
+
:return: KMD client instance
|
|
159
|
+
"""
|
|
160
|
+
if not self._kmd:
|
|
161
|
+
raise ValueError("Attempt to use Kmd client in AlgoKit instance with no Kmd configured")
|
|
162
|
+
return self._kmd
|
|
163
|
+
|
|
164
|
+
def network(self) -> NetworkDetail:
|
|
165
|
+
"""Get details about the connected Algorand network.
|
|
166
|
+
|
|
167
|
+
:return: Network details including type and genesis information
|
|
168
|
+
|
|
169
|
+
:example:
|
|
170
|
+
>>> client_manager = ClientManager(algod_client)
|
|
171
|
+
>>> network_detail = client_manager.network()
|
|
172
|
+
"""
|
|
173
|
+
import base64
|
|
174
|
+
|
|
175
|
+
if self._suggested_params is None:
|
|
176
|
+
self._suggested_params = self._algod.suggested_params()
|
|
177
|
+
sp = self._suggested_params
|
|
178
|
+
return NetworkDetail(
|
|
179
|
+
is_testnet=sp.genesis_id in ["testnet-v1.0", "testnet-v1", "testnet"],
|
|
180
|
+
is_mainnet=sp.genesis_id in ["mainnet-v1.0", "mainnet-v1", "mainnet"],
|
|
181
|
+
is_localnet=ClientManager.genesis_id_is_localnet(str(sp.genesis_id)),
|
|
182
|
+
genesis_id=str(sp.genesis_id),
|
|
183
|
+
genesis_hash=base64.b64encode(sp.genesis_hash).decode("utf-8")
|
|
184
|
+
if isinstance(sp.genesis_hash, bytes)
|
|
185
|
+
else sp.genesis_hash,
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
def is_localnet(self) -> bool:
|
|
189
|
+
"""Check if connected to a local network.
|
|
190
|
+
|
|
191
|
+
:return: True if connected to a local network
|
|
192
|
+
"""
|
|
193
|
+
return self.network().is_localnet
|
|
194
|
+
|
|
195
|
+
def is_testnet(self) -> bool:
|
|
196
|
+
"""Check if connected to TestNet.
|
|
197
|
+
|
|
198
|
+
:return: True if connected to TestNet
|
|
199
|
+
"""
|
|
200
|
+
return self.network().is_testnet
|
|
201
|
+
|
|
202
|
+
def is_mainnet(self) -> bool:
|
|
203
|
+
"""Check if connected to MainNet.
|
|
204
|
+
|
|
205
|
+
:return: True if connected to MainNet
|
|
206
|
+
"""
|
|
207
|
+
return self.network().is_mainnet
|
|
208
|
+
|
|
209
|
+
def close(self) -> None:
|
|
210
|
+
"""Close the underlying HTTP client connections.
|
|
211
|
+
|
|
212
|
+
This method should be called when the ClientManager is no longer needed
|
|
213
|
+
to properly clean up resources.
|
|
214
|
+
|
|
215
|
+
:example:
|
|
216
|
+
>>> client_manager = ClientManager(algod_client)
|
|
217
|
+
>>> # ... use client_manager ...
|
|
218
|
+
>>> client_manager.close()
|
|
219
|
+
"""
|
|
220
|
+
if isinstance(self._algod, AlgodClient):
|
|
221
|
+
self._algod.close()
|
|
222
|
+
|
|
223
|
+
def get_testnet_dispenser(
|
|
224
|
+
self, auth_token: str | None = None, request_timeout: int | None = None
|
|
225
|
+
) -> TestNetDispenserApiClient:
|
|
226
|
+
"""Get a TestNet dispenser API client.
|
|
227
|
+
|
|
228
|
+
:param auth_token: Optional authentication token
|
|
229
|
+
:param request_timeout: Optional request timeout in seconds
|
|
230
|
+
:return: TestNet dispenser client instance
|
|
231
|
+
"""
|
|
232
|
+
if request_timeout:
|
|
233
|
+
return TestNetDispenserApiClient(auth_token=auth_token, request_timeout=request_timeout)
|
|
234
|
+
|
|
235
|
+
return TestNetDispenserApiClient(auth_token=auth_token)
|
|
236
|
+
|
|
237
|
+
def get_app_factory(
|
|
238
|
+
self,
|
|
239
|
+
app_spec: arc56.Arc56Contract | str,
|
|
240
|
+
app_name: str | None = None,
|
|
241
|
+
default_sender: str | None = None,
|
|
242
|
+
default_signer: TransactionSigner | None = None,
|
|
243
|
+
version: str | None = None,
|
|
244
|
+
compilation_params: Optional["AppClientCompilationParams"] = None,
|
|
245
|
+
) -> "AppFactory":
|
|
246
|
+
"""Get an application factory for deploying smart contracts.
|
|
247
|
+
|
|
248
|
+
:param app_spec: Application specification
|
|
249
|
+
:param app_name: Optional application name
|
|
250
|
+
:param default_sender: Optional default sender address
|
|
251
|
+
:param default_signer: Optional default transaction signer
|
|
252
|
+
:param version: Optional version string
|
|
253
|
+
:param compilation_params: Optional compilation parameters
|
|
254
|
+
:raises ValueError: If no Algorand client is configured
|
|
255
|
+
:return: Application factory instance
|
|
256
|
+
"""
|
|
257
|
+
from algokit_utils.applications.app_factory import AppFactory, AppFactoryParams
|
|
258
|
+
|
|
259
|
+
if not self._algorand:
|
|
260
|
+
raise ValueError("Attempt to get app factory from a ClientManager without an Algorand client")
|
|
261
|
+
|
|
262
|
+
return AppFactory(
|
|
263
|
+
AppFactoryParams(
|
|
264
|
+
algorand=self._algorand,
|
|
265
|
+
app_spec=app_spec,
|
|
266
|
+
app_name=app_name,
|
|
267
|
+
default_sender=default_sender,
|
|
268
|
+
default_signer=default_signer,
|
|
269
|
+
version=version,
|
|
270
|
+
compilation_params=compilation_params,
|
|
271
|
+
)
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
def get_app_client_by_id(
|
|
275
|
+
self,
|
|
276
|
+
app_spec: arc56.Arc56Contract | str,
|
|
277
|
+
app_id: int,
|
|
278
|
+
app_name: str | None = None,
|
|
279
|
+
default_sender: str | None = None,
|
|
280
|
+
default_signer: TransactionSigner | None = None,
|
|
281
|
+
approval_source_map: ProgramSourceMap | None = None,
|
|
282
|
+
clear_source_map: ProgramSourceMap | None = None,
|
|
283
|
+
) -> "AppClient":
|
|
284
|
+
"""Get an application client for an existing application by ID.
|
|
285
|
+
|
|
286
|
+
:param app_spec: Application specification
|
|
287
|
+
:param app_id: Application ID
|
|
288
|
+
:param app_name: Optional application name
|
|
289
|
+
:param default_sender: Optional default sender address
|
|
290
|
+
:param default_signer: Optional default transaction signer
|
|
291
|
+
:param approval_source_map: Optional approval program source map
|
|
292
|
+
:param clear_source_map: Optional clear program source map
|
|
293
|
+
:raises ValueError: If no Algorand client is configured
|
|
294
|
+
:return: Application client instance
|
|
295
|
+
"""
|
|
296
|
+
from algokit_utils.applications.app_client import AppClient, AppClientParams
|
|
297
|
+
|
|
298
|
+
if not self._algorand:
|
|
299
|
+
raise ValueError("Attempt to get app client from a ClientManager without an Algorand client")
|
|
300
|
+
|
|
301
|
+
return AppClient(
|
|
302
|
+
AppClientParams(
|
|
303
|
+
app_spec=app_spec,
|
|
304
|
+
algorand=self._algorand,
|
|
305
|
+
app_id=app_id,
|
|
306
|
+
app_name=app_name,
|
|
307
|
+
default_sender=default_sender,
|
|
308
|
+
default_signer=default_signer,
|
|
309
|
+
approval_source_map=approval_source_map,
|
|
310
|
+
clear_source_map=clear_source_map,
|
|
311
|
+
)
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
def get_app_client_by_network(
|
|
315
|
+
self,
|
|
316
|
+
app_spec: (arc56.Arc56Contract | str),
|
|
317
|
+
app_name: str | None = None,
|
|
318
|
+
default_sender: str | None = None,
|
|
319
|
+
default_signer: TransactionSigner | None = None,
|
|
320
|
+
approval_source_map: ProgramSourceMap | None = None,
|
|
321
|
+
clear_source_map: ProgramSourceMap | None = None,
|
|
322
|
+
) -> "AppClient":
|
|
323
|
+
"""Get an application client for an existing application by network.
|
|
324
|
+
|
|
325
|
+
:param app_spec: Application specification
|
|
326
|
+
:param app_name: Optional application name
|
|
327
|
+
:param default_sender: Optional default sender address
|
|
328
|
+
:param default_signer: Optional default transaction signer
|
|
329
|
+
:param approval_source_map: Optional approval program source map
|
|
330
|
+
:param clear_source_map: Optional clear program source map
|
|
331
|
+
:raises ValueError: If no Algorand client is configured
|
|
332
|
+
:return: Application client instance
|
|
333
|
+
"""
|
|
334
|
+
from algokit_utils.applications.app_client import AppClient
|
|
335
|
+
|
|
336
|
+
if not self._algorand:
|
|
337
|
+
raise ValueError("Attempt to get app client from a ClientManager without an Algorand client")
|
|
338
|
+
|
|
339
|
+
return AppClient.from_network(
|
|
340
|
+
app_spec=app_spec,
|
|
341
|
+
app_name=app_name,
|
|
342
|
+
default_sender=default_sender,
|
|
343
|
+
default_signer=default_signer,
|
|
344
|
+
approval_source_map=approval_source_map,
|
|
345
|
+
clear_source_map=clear_source_map,
|
|
346
|
+
algorand=self._algorand,
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
def get_app_client_by_creator_and_name(
|
|
350
|
+
self,
|
|
351
|
+
creator_address: str,
|
|
352
|
+
app_name: str,
|
|
353
|
+
app_spec: arc56.Arc56Contract | str,
|
|
354
|
+
default_sender: str | None = None,
|
|
355
|
+
default_signer: TransactionSigner | None = None,
|
|
356
|
+
ignore_cache: bool | None = None,
|
|
357
|
+
app_lookup_cache: Optional["ApplicationLookup"] = None,
|
|
358
|
+
approval_source_map: ProgramSourceMap | None = None,
|
|
359
|
+
clear_source_map: ProgramSourceMap | None = None,
|
|
360
|
+
) -> "AppClient":
|
|
361
|
+
"""Get an application client by creator address and name.
|
|
362
|
+
|
|
363
|
+
:param creator_address: Creator address
|
|
364
|
+
:param app_name: Application name
|
|
365
|
+
:param app_spec: Application specification
|
|
366
|
+
:param default_sender: Optional default sender address
|
|
367
|
+
:param default_signer: Optional default transaction signer
|
|
368
|
+
:param ignore_cache: Optional flag to ignore cache
|
|
369
|
+
:param app_lookup_cache: Optional app lookup cache
|
|
370
|
+
:param approval_source_map: Optional approval program source map
|
|
371
|
+
:param clear_source_map: Optional clear program source map
|
|
372
|
+
:return: Application client instance
|
|
373
|
+
"""
|
|
374
|
+
from algokit_utils.applications.app_client import AppClient
|
|
375
|
+
|
|
376
|
+
return AppClient.from_creator_and_name(
|
|
377
|
+
creator_address=creator_address,
|
|
378
|
+
app_name=app_name,
|
|
379
|
+
default_sender=default_sender,
|
|
380
|
+
default_signer=default_signer,
|
|
381
|
+
ignore_cache=ignore_cache,
|
|
382
|
+
app_lookup_cache=app_lookup_cache,
|
|
383
|
+
app_spec=app_spec,
|
|
384
|
+
approval_source_map=approval_source_map,
|
|
385
|
+
clear_source_map=clear_source_map,
|
|
386
|
+
algorand=self._algorand,
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
@staticmethod
|
|
390
|
+
def get_algod_client(config: AlgoClientNetworkConfig) -> AlgodClient:
|
|
391
|
+
"""Get a typed Algod client from config.
|
|
392
|
+
|
|
393
|
+
:param config: Client configuration
|
|
394
|
+
:return: Typed Algod client instance
|
|
395
|
+
"""
|
|
396
|
+
client_config = AlgodClientConfig(
|
|
397
|
+
base_url=config.full_url(),
|
|
398
|
+
token=config.token or None,
|
|
399
|
+
)
|
|
400
|
+
return AlgodClient(client_config)
|
|
401
|
+
|
|
402
|
+
@staticmethod
|
|
403
|
+
def get_algod_client_from_environment() -> AlgodClient:
|
|
404
|
+
"""Get an Algod client from environment variables.
|
|
405
|
+
|
|
406
|
+
:return: Algod client instance
|
|
407
|
+
"""
|
|
408
|
+
return ClientManager.get_algod_client(ClientManager.get_algod_config_from_environment())
|
|
409
|
+
|
|
410
|
+
@staticmethod
|
|
411
|
+
def get_kmd_client(config: AlgoClientNetworkConfig) -> KmdClient:
|
|
412
|
+
"""Get a KMD client from config or environment.
|
|
413
|
+
|
|
414
|
+
:param config: Optional client configuration
|
|
415
|
+
:return: KMD client instance
|
|
416
|
+
"""
|
|
417
|
+
client_config = KmdClientConfig(
|
|
418
|
+
base_url=config.full_url(),
|
|
419
|
+
token=config.token or None,
|
|
420
|
+
)
|
|
421
|
+
return KmdClient(client_config)
|
|
422
|
+
|
|
423
|
+
@staticmethod
|
|
424
|
+
def get_kmd_client_from_environment() -> KmdClient:
|
|
425
|
+
"""Get a KMD client from environment variables.
|
|
426
|
+
|
|
427
|
+
:return: KMD client instance
|
|
428
|
+
"""
|
|
429
|
+
return ClientManager.get_kmd_client(ClientManager.get_kmd_config_from_environment())
|
|
430
|
+
|
|
431
|
+
@staticmethod
|
|
432
|
+
def get_indexer_client(config: AlgoClientNetworkConfig) -> IndexerClient:
|
|
433
|
+
"""Get an Indexer client from config or environment.
|
|
434
|
+
|
|
435
|
+
:param config: Optional client configuration
|
|
436
|
+
:return: Indexer client instance
|
|
437
|
+
"""
|
|
438
|
+
client_config = IndexerClientConfig(
|
|
439
|
+
base_url=config.full_url(),
|
|
440
|
+
token=config.token or None,
|
|
441
|
+
)
|
|
442
|
+
return IndexerClient(client_config)
|
|
443
|
+
|
|
444
|
+
@staticmethod
|
|
445
|
+
def get_indexer_client_from_environment() -> IndexerClient:
|
|
446
|
+
"""Get an Indexer client from environment variables.
|
|
447
|
+
|
|
448
|
+
:return: Indexer client instance
|
|
449
|
+
"""
|
|
450
|
+
return ClientManager.get_indexer_client(ClientManager.get_indexer_config_from_environment())
|
|
451
|
+
|
|
452
|
+
@staticmethod
|
|
453
|
+
def genesis_id_is_localnet(genesis_id: str | None) -> bool:
|
|
454
|
+
"""Check if a genesis ID indicates a local network.
|
|
455
|
+
|
|
456
|
+
:param genesis_id: Genesis ID to check
|
|
457
|
+
:return: True if genesis ID indicates a local network
|
|
458
|
+
|
|
459
|
+
:example:
|
|
460
|
+
>>> ClientManager.genesis_id_is_localnet("devnet-v1")
|
|
461
|
+
"""
|
|
462
|
+
return genesis_id in ["devnet-v1", "sandnet-v1", "dockernet-v1"]
|
|
463
|
+
|
|
464
|
+
def get_typed_app_client_by_creator_and_name(
|
|
465
|
+
self,
|
|
466
|
+
typed_client: type[TypedAppClientT],
|
|
467
|
+
*,
|
|
468
|
+
creator_address: str,
|
|
469
|
+
app_name: str,
|
|
470
|
+
default_sender: str | None = None,
|
|
471
|
+
default_signer: TransactionSigner | None = None,
|
|
472
|
+
ignore_cache: bool | None = None,
|
|
473
|
+
app_lookup_cache: Optional["ApplicationLookup"] = None,
|
|
474
|
+
) -> TypedAppClientT:
|
|
475
|
+
"""Get a typed application client by creator address and name.
|
|
476
|
+
|
|
477
|
+
:param typed_client: Typed client class
|
|
478
|
+
:param creator_address: Creator address
|
|
479
|
+
:param app_name: Application name
|
|
480
|
+
:param default_sender: Optional default sender address
|
|
481
|
+
:param default_signer: Optional default transaction signer
|
|
482
|
+
:param ignore_cache: Optional flag to ignore cache
|
|
483
|
+
:param app_lookup_cache: Optional app lookup cache
|
|
484
|
+
:raises ValueError: If no Algorand client is configured
|
|
485
|
+
:return: Typed application client instance
|
|
486
|
+
|
|
487
|
+
:example:
|
|
488
|
+
>>> client_manager = ClientManager(algod_client)
|
|
489
|
+
>>> typed_app_client = client_manager.get_typed_app_client_by_creator_and_name(
|
|
490
|
+
... typed_client=MyAppClient,
|
|
491
|
+
... creator_address="creator_address",
|
|
492
|
+
... app_name="app_name",
|
|
493
|
+
... )
|
|
494
|
+
"""
|
|
495
|
+
if not self._algorand:
|
|
496
|
+
raise ValueError("Attempt to get app client from a ClientManager without an Algorand client")
|
|
497
|
+
|
|
498
|
+
return typed_client.from_creator_and_name(
|
|
499
|
+
creator_address=creator_address,
|
|
500
|
+
app_name=app_name,
|
|
501
|
+
default_sender=default_sender,
|
|
502
|
+
default_signer=default_signer,
|
|
503
|
+
ignore_cache=ignore_cache,
|
|
504
|
+
app_lookup_cache=app_lookup_cache,
|
|
505
|
+
algorand=self._algorand,
|
|
506
|
+
)
|
|
507
|
+
|
|
508
|
+
def get_typed_app_client_by_id(
|
|
509
|
+
self,
|
|
510
|
+
typed_client: type[TypedAppClientT],
|
|
511
|
+
*,
|
|
512
|
+
app_id: int,
|
|
513
|
+
app_name: str | None = None,
|
|
514
|
+
default_sender: str | None = None,
|
|
515
|
+
default_signer: TransactionSigner | None = None,
|
|
516
|
+
approval_source_map: ProgramSourceMap | None = None,
|
|
517
|
+
clear_source_map: ProgramSourceMap | None = None,
|
|
518
|
+
) -> TypedAppClientT:
|
|
519
|
+
"""Get a typed application client by ID.
|
|
520
|
+
|
|
521
|
+
:param typed_client: Typed client class
|
|
522
|
+
:param app_id: Application ID
|
|
523
|
+
:param app_name: Optional application name
|
|
524
|
+
:param default_sender: Optional default sender address
|
|
525
|
+
:param default_signer: Optional default transaction signer
|
|
526
|
+
:param approval_source_map: Optional approval program source map
|
|
527
|
+
:param clear_source_map: Optional clear program source map
|
|
528
|
+
:raises ValueError: If no Algorand client is configured
|
|
529
|
+
:return: Typed application client instance
|
|
530
|
+
|
|
531
|
+
:example:
|
|
532
|
+
>>> client_manager = ClientManager(algod_client)
|
|
533
|
+
>>> typed_app_client = client_manager.get_typed_app_client_by_id(
|
|
534
|
+
... typed_client=MyAppClient,
|
|
535
|
+
... app_id=1234567890,
|
|
536
|
+
... )
|
|
537
|
+
"""
|
|
538
|
+
if not self._algorand:
|
|
539
|
+
raise ValueError("Attempt to get app client from a ClientManager without an Algorand client")
|
|
540
|
+
|
|
541
|
+
return typed_client(
|
|
542
|
+
app_id=app_id,
|
|
543
|
+
app_name=app_name,
|
|
544
|
+
default_sender=default_sender,
|
|
545
|
+
default_signer=default_signer,
|
|
546
|
+
approval_source_map=approval_source_map,
|
|
547
|
+
clear_source_map=clear_source_map,
|
|
548
|
+
algorand=self._algorand,
|
|
549
|
+
)
|
|
550
|
+
|
|
551
|
+
def get_typed_app_client_by_network(
|
|
552
|
+
self,
|
|
553
|
+
typed_client: type[TypedAppClientT],
|
|
554
|
+
*,
|
|
555
|
+
app_name: str | None = None,
|
|
556
|
+
default_sender: str | None = None,
|
|
557
|
+
default_signer: TransactionSigner | None = None,
|
|
558
|
+
approval_source_map: ProgramSourceMap | None = None,
|
|
559
|
+
clear_source_map: ProgramSourceMap | None = None,
|
|
560
|
+
) -> TypedAppClientT:
|
|
561
|
+
"""Returns a new typed client, resolves the app ID for the current network.
|
|
562
|
+
|
|
563
|
+
Uses pre-determined network-specific app IDs specified in the ARC-56 app spec.
|
|
564
|
+
If no IDs are in the app spec or the network isn't recognised, an error is thrown.
|
|
565
|
+
|
|
566
|
+
:param typed_client: The typed client class to instantiate
|
|
567
|
+
:param app_name: Optional application name
|
|
568
|
+
:param default_sender: Optional default sender address
|
|
569
|
+
:param default_signer: Optional default transaction signer
|
|
570
|
+
:param approval_source_map: Optional approval program source map
|
|
571
|
+
:param clear_source_map: Optional clear program source map
|
|
572
|
+
:raises ValueError: If no Algorand client is configured
|
|
573
|
+
:return: The typed client instance
|
|
574
|
+
|
|
575
|
+
:example:
|
|
576
|
+
>>> client_manager = ClientManager(algod_client)
|
|
577
|
+
>>> typed_app_client = client_manager.get_typed_app_client_by_network(
|
|
578
|
+
... typed_client=MyAppClient,
|
|
579
|
+
... app_name="app_name",
|
|
580
|
+
... )
|
|
581
|
+
"""
|
|
582
|
+
if not self._algorand:
|
|
583
|
+
raise ValueError("Attempt to get app client from a ClientManager without an Algorand client")
|
|
584
|
+
|
|
585
|
+
return typed_client.from_network(
|
|
586
|
+
app_name=app_name,
|
|
587
|
+
default_sender=default_sender,
|
|
588
|
+
default_signer=default_signer,
|
|
589
|
+
approval_source_map=approval_source_map,
|
|
590
|
+
clear_source_map=clear_source_map,
|
|
591
|
+
algorand=self._algorand,
|
|
592
|
+
)
|
|
593
|
+
|
|
594
|
+
def get_typed_app_factory(
|
|
595
|
+
self,
|
|
596
|
+
typed_factory: type[TypedFactoryT],
|
|
597
|
+
*,
|
|
598
|
+
app_name: str | None = None,
|
|
599
|
+
default_sender: str | None = None,
|
|
600
|
+
default_signer: TransactionSigner | None = None,
|
|
601
|
+
version: str | None = None,
|
|
602
|
+
compilation_params: Optional["AppClientCompilationParams"] = None,
|
|
603
|
+
) -> TypedFactoryT:
|
|
604
|
+
"""Get a typed application factory.
|
|
605
|
+
|
|
606
|
+
:param typed_factory: Typed factory class
|
|
607
|
+
:param app_name: Optional application name
|
|
608
|
+
:param default_sender: Optional default sender address
|
|
609
|
+
:param default_signer: Optional default transaction signer
|
|
610
|
+
:param version: Optional version string
|
|
611
|
+
:param compilation_params: Optional compilation parameters
|
|
612
|
+
:raises ValueError: If no Algorand client is configured
|
|
613
|
+
:return: Typed application factory instance
|
|
614
|
+
|
|
615
|
+
:example:
|
|
616
|
+
>>> client_manager = ClientManager(algod_client)
|
|
617
|
+
>>> typed_app_factory = client_manager.get_typed_app_factory(
|
|
618
|
+
... typed_factory=MyAppFactory,
|
|
619
|
+
... app_name="app_name",
|
|
620
|
+
... )
|
|
621
|
+
"""
|
|
622
|
+
if not self._algorand:
|
|
623
|
+
raise ValueError("Attempt to get app factory from a ClientManager without an Algorand client")
|
|
624
|
+
|
|
625
|
+
return typed_factory(
|
|
626
|
+
algorand=self._algorand,
|
|
627
|
+
app_name=app_name,
|
|
628
|
+
default_sender=default_sender,
|
|
629
|
+
default_signer=default_signer,
|
|
630
|
+
version=version,
|
|
631
|
+
compilation_params=compilation_params,
|
|
632
|
+
)
|
|
633
|
+
|
|
634
|
+
@staticmethod
|
|
635
|
+
def get_config_from_environment_or_localnet() -> AlgoClientConfigs:
|
|
636
|
+
"""Retrieve client configuration from environment variables or fallback to localnet defaults.
|
|
637
|
+
|
|
638
|
+
If ALGOD_SERVER is set in environment variables, it will use environment configuration,
|
|
639
|
+
otherwise it will use default localnet configuration.
|
|
640
|
+
|
|
641
|
+
:return: Configuration for algod, indexer, and optionally kmd
|
|
642
|
+
|
|
643
|
+
:example:
|
|
644
|
+
>>> client_manager = ClientManager(algod_client)
|
|
645
|
+
>>> config = client_manager.get_config_from_environment_or_localnet()
|
|
646
|
+
"""
|
|
647
|
+
algod_server = os.getenv("ALGOD_SERVER")
|
|
648
|
+
|
|
649
|
+
if algod_server:
|
|
650
|
+
# Use environment configuration
|
|
651
|
+
algod_config = ClientManager.get_algod_config_from_environment()
|
|
652
|
+
|
|
653
|
+
# Only include indexer if INDEXER_SERVER is set
|
|
654
|
+
indexer_config = (
|
|
655
|
+
ClientManager.get_indexer_config_from_environment() if os.getenv("INDEXER_SERVER") else None
|
|
656
|
+
)
|
|
657
|
+
|
|
658
|
+
# Include KMD config only for local networks (not mainnet/testnet)
|
|
659
|
+
kmd_config = (
|
|
660
|
+
AlgoClientNetworkConfig(
|
|
661
|
+
server=algod_config.server, token=algod_config.token, port=os.getenv("KMD_PORT", "4002")
|
|
662
|
+
)
|
|
663
|
+
if not any(net in algod_server.lower() for net in ["mainnet", "testnet"])
|
|
664
|
+
else None
|
|
665
|
+
)
|
|
666
|
+
else:
|
|
667
|
+
# Use localnet defaults
|
|
668
|
+
algod_config = ClientManager.get_default_localnet_config("algod")
|
|
669
|
+
indexer_config = ClientManager.get_default_localnet_config("indexer")
|
|
670
|
+
kmd_config = ClientManager.get_default_localnet_config("kmd")
|
|
671
|
+
|
|
672
|
+
return AlgoClientConfigs(
|
|
673
|
+
algod_config=algod_config,
|
|
674
|
+
indexer_config=indexer_config,
|
|
675
|
+
kmd_config=kmd_config,
|
|
676
|
+
)
|
|
677
|
+
|
|
678
|
+
@staticmethod
|
|
679
|
+
def get_default_localnet_config(
|
|
680
|
+
config_or_port: Literal["algod", "indexer", "kmd"] | int,
|
|
681
|
+
) -> AlgoClientNetworkConfig:
|
|
682
|
+
"""Get default configuration for local network services.
|
|
683
|
+
|
|
684
|
+
:param config_or_port: Service name or port number
|
|
685
|
+
:return: Client configuration for local network
|
|
686
|
+
|
|
687
|
+
:example:
|
|
688
|
+
>>> client_manager = ClientManager(algod_client)
|
|
689
|
+
>>> config = client_manager.get_default_localnet_config("algod")
|
|
690
|
+
"""
|
|
691
|
+
port = (
|
|
692
|
+
config_or_port
|
|
693
|
+
if isinstance(config_or_port, int)
|
|
694
|
+
else {"algod": 4001, "indexer": 8980, "kmd": 4002}[config_or_port]
|
|
695
|
+
)
|
|
696
|
+
|
|
697
|
+
return AlgoClientNetworkConfig(server="http://localhost", token="a" * 64, port=port)
|
|
698
|
+
|
|
699
|
+
@staticmethod
|
|
700
|
+
def get_algod_config_from_environment() -> AlgoClientNetworkConfig:
|
|
701
|
+
"""Retrieve the algod configuration from environment variables.
|
|
702
|
+
Will raise an error if ALGOD_SERVER environment variable is not set
|
|
703
|
+
|
|
704
|
+
:return: Algod client configuration
|
|
705
|
+
|
|
706
|
+
:example:
|
|
707
|
+
>>> client_manager = ClientManager(algod_client)
|
|
708
|
+
>>> config = client_manager.get_algod_config_from_environment()
|
|
709
|
+
"""
|
|
710
|
+
return _get_config_from_environment("ALGOD")
|
|
711
|
+
|
|
712
|
+
@staticmethod
|
|
713
|
+
def get_indexer_config_from_environment() -> AlgoClientNetworkConfig:
|
|
714
|
+
"""Retrieve the indexer configuration from environment variables.
|
|
715
|
+
Will raise an error if INDEXER_SERVER environment variable is not set
|
|
716
|
+
|
|
717
|
+
:return: Indexer client configuration
|
|
718
|
+
|
|
719
|
+
:example:
|
|
720
|
+
>>> client_manager = ClientManager(algod_client)
|
|
721
|
+
>>> config = client_manager.get_indexer_config_from_environment()
|
|
722
|
+
"""
|
|
723
|
+
return _get_config_from_environment("INDEXER")
|
|
724
|
+
|
|
725
|
+
@staticmethod
|
|
726
|
+
def get_kmd_config_from_environment() -> AlgoClientNetworkConfig:
|
|
727
|
+
"""Retrieve the kmd configuration from environment variables.
|
|
728
|
+
|
|
729
|
+
:return: KMD client configuration
|
|
730
|
+
|
|
731
|
+
:example:
|
|
732
|
+
>>> client_manager = ClientManager(algod_client)
|
|
733
|
+
>>> config = client_manager.get_kmd_config_from_environment()
|
|
734
|
+
"""
|
|
735
|
+
return _get_config_from_environment("KMD")
|
|
736
|
+
|
|
737
|
+
@staticmethod
|
|
738
|
+
def get_algonode_config(
|
|
739
|
+
network: Literal["testnet", "mainnet"], config: Literal["algod", "indexer"]
|
|
740
|
+
) -> AlgoClientNetworkConfig:
|
|
741
|
+
"""Returns the Algorand configuration to point to the free tier of the AlgoNode service.
|
|
742
|
+
|
|
743
|
+
:param network: Which network to connect to - TestNet or MainNet
|
|
744
|
+
:param config: Which algod config to return - Algod or Indexer
|
|
745
|
+
:return: Configuration for the specified network and service
|
|
746
|
+
|
|
747
|
+
:example:
|
|
748
|
+
>>> client_manager = ClientManager(algod_client)
|
|
749
|
+
>>> config = client_manager.get_algonode_config("testnet", "algod")
|
|
750
|
+
"""
|
|
751
|
+
service_type = "api" if config == "algod" else "idx"
|
|
752
|
+
return AlgoClientNetworkConfig(
|
|
753
|
+
server=f"https://{network}-{service_type}.algonode.cloud",
|
|
754
|
+
port=443,
|
|
755
|
+
token="",
|
|
756
|
+
)
|