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,135 @@
|
|
|
1
|
+
from algokit_common import address_from_public_key, public_key_from_address
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def encode_address(addr: str | None) -> bytes | None:
|
|
5
|
+
if addr is None:
|
|
6
|
+
return None
|
|
7
|
+
return public_key_from_address(addr)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def decode_address(pk: bytes | None) -> str | None:
|
|
11
|
+
if pk is None:
|
|
12
|
+
return None
|
|
13
|
+
return address_from_public_key(pk)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def encode_bytes(b: bytes | None) -> bytes | None:
|
|
17
|
+
return b if b not in (None, b"") else None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def encode_int(n: int | None, *, keep_zero: bool = False) -> int | None:
|
|
21
|
+
match n:
|
|
22
|
+
case None:
|
|
23
|
+
return None
|
|
24
|
+
case 0 if not keep_zero:
|
|
25
|
+
return None
|
|
26
|
+
case _:
|
|
27
|
+
return n
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def encode_bool(v: bool | None) -> bool | None:
|
|
31
|
+
return None if v in (None, False) else v
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def encode_bytes_sequence(seq: tuple[bytes, ...] | None) -> list[bytes] | None:
|
|
35
|
+
if not seq:
|
|
36
|
+
return None
|
|
37
|
+
return [bytes(item) for item in seq]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def encode_int_sequence(seq: tuple[int, ...] | None) -> list[int] | None:
|
|
41
|
+
if not seq:
|
|
42
|
+
return None
|
|
43
|
+
return [int(item) for item in seq]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def decode_bytes_like(value: object | None) -> bytes | None:
|
|
47
|
+
if isinstance(value, bytes | bytearray):
|
|
48
|
+
return bytes(value)
|
|
49
|
+
return None
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def decode_int_like(value: object | None) -> int | None:
|
|
53
|
+
match value:
|
|
54
|
+
case None:
|
|
55
|
+
return None
|
|
56
|
+
case bool():
|
|
57
|
+
return value
|
|
58
|
+
case int():
|
|
59
|
+
return int(value)
|
|
60
|
+
case _:
|
|
61
|
+
return None
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
_TYPE_PRIORITY = {int: 0, str: 1, bytes: 2}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def sort_msgpack_value(value: object) -> object:
|
|
68
|
+
"""
|
|
69
|
+
Recursively sort msgpack values with canonical key ordering.
|
|
70
|
+
|
|
71
|
+
Implements canonical msgpack encoding where map keys are ordered by type:
|
|
72
|
+
- Integer keys first (sorted numerically)
|
|
73
|
+
- String keys second (sorted lexicographically)
|
|
74
|
+
- Binary keys third (sorted by byte value)
|
|
75
|
+
|
|
76
|
+
This ensures deterministic, canonical msgpack encoding that matches
|
|
77
|
+
the behavior of Algorand's protocol layer (Go's msgp library and Rust's rmpv).
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
value: A Python object (dict, list, or scalar) to sort recursively.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
The value with all dictionaries sorted according to msgpack canonical rules.
|
|
84
|
+
"""
|
|
85
|
+
if isinstance(value, dict):
|
|
86
|
+
return {
|
|
87
|
+
k: sort_msgpack_value(v)
|
|
88
|
+
for k, v in sorted(
|
|
89
|
+
value.items(),
|
|
90
|
+
key=lambda kv: (_TYPE_PRIORITY.get(type(kv[0]), 3), kv[0]),
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
elif isinstance(value, list | tuple):
|
|
94
|
+
return [sort_msgpack_value(v) for v in value]
|
|
95
|
+
return value
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def omit_defaults_and_sort(value: object) -> object:
|
|
99
|
+
"""
|
|
100
|
+
Recursively omit default-like values and sort with canonical msgpack ordering.
|
|
101
|
+
|
|
102
|
+
Combines two operations:
|
|
103
|
+
1. Filters out default-like values (None, 0, "", empty bytes, empty collections)
|
|
104
|
+
2. Sorts dictionaries by key using canonical msgpack ordering (int → str → bytes)
|
|
105
|
+
|
|
106
|
+
This is used by to_wire_canonical() for protocol wire format encoding.
|
|
107
|
+
"""
|
|
108
|
+
if isinstance(value, dict):
|
|
109
|
+
filtered = {
|
|
110
|
+
k: omit_defaults_and_sort(v) for k, v in value.items() if not is_default_like(omit_defaults_and_sort(v))
|
|
111
|
+
}
|
|
112
|
+
# Use sort_msgpack_value for canonical ordering instead of simple lexicographic sort
|
|
113
|
+
return sort_msgpack_value(filtered)
|
|
114
|
+
if isinstance(value, list | tuple):
|
|
115
|
+
return [omit_defaults_and_sort(v) for v in value]
|
|
116
|
+
return value
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def is_default_like(value: object) -> bool: # noqa: PLR0911
|
|
120
|
+
match value:
|
|
121
|
+
case None:
|
|
122
|
+
return True
|
|
123
|
+
case int() as i if i == 0:
|
|
124
|
+
return True
|
|
125
|
+
case str() as s if s == "":
|
|
126
|
+
return True
|
|
127
|
+
case (bytes() | bytearray()) as b if len(b) == 0:
|
|
128
|
+
return True
|
|
129
|
+
case list() as l if len(l) == 0:
|
|
130
|
+
return True
|
|
131
|
+
case dict() as d:
|
|
132
|
+
# omit-empty-object
|
|
133
|
+
return all(is_default_like(v) for v in d.values())
|
|
134
|
+
case _:
|
|
135
|
+
return False
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Source map utilities for mapping PC values to TEAL source code lines.
|
|
3
|
+
|
|
4
|
+
Provides VLQ-encoded source map decoding per the Source Map Revision 3 spec.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from typing import Any, Final, cast
|
|
9
|
+
|
|
10
|
+
# Source Map Revision 3 - the only supported version
|
|
11
|
+
# https://sourcemaps.info/spec.html
|
|
12
|
+
SOURCE_MAP_VERSION: Final[int] = 3
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SourceMapVersionError(Exception):
|
|
16
|
+
"""Raised when an unsupported source map version is encountered."""
|
|
17
|
+
|
|
18
|
+
def __init__(self, version: int) -> None:
|
|
19
|
+
super().__init__(f"unsupported source map version: {version}")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class SourceLocation:
|
|
24
|
+
"""Represents a location in source code.
|
|
25
|
+
|
|
26
|
+
Attributes:
|
|
27
|
+
line: The 0-based line number in the source file.
|
|
28
|
+
column: The 0-based column number in the source file (optional).
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
line: int
|
|
32
|
+
column: int | None = None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass
|
|
36
|
+
class PcLineLocation:
|
|
37
|
+
"""Represents a mapping from PC (program counter) to source location.
|
|
38
|
+
|
|
39
|
+
Attributes:
|
|
40
|
+
pc: The program counter value.
|
|
41
|
+
line: The 0-based line number in the source file.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
pc: int
|
|
45
|
+
line: int
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class ProgramSourceMap:
|
|
49
|
+
"""
|
|
50
|
+
Decodes a VLQ-encoded source mapping between PC values and TEAL source code lines.
|
|
51
|
+
Spec available here: https://sourcemaps.info/spec.html
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
source_map: source map JSON from algod compile endpoint
|
|
55
|
+
|
|
56
|
+
Attributes:
|
|
57
|
+
version: The source map version (must be 3).
|
|
58
|
+
sources: List of source file names.
|
|
59
|
+
mappings: The raw VLQ-encoded mappings string.
|
|
60
|
+
pc_to_line: Mapping from program counter to source line number.
|
|
61
|
+
line_to_pc: Mapping from source line number to list of program counters.
|
|
62
|
+
|
|
63
|
+
Raises:
|
|
64
|
+
SourceMapVersionError: If the source map version is not 3.
|
|
65
|
+
|
|
66
|
+
Example:
|
|
67
|
+
>>> from algokit_common import ProgramSourceMap
|
|
68
|
+
>>> source_map_data = {"version": 3, "sources": ["main.teal"], "mappings": "..."}
|
|
69
|
+
>>> source_map = ProgramSourceMap(source_map_data)
|
|
70
|
+
>>> line = source_map.get_line_for_pc(10)
|
|
71
|
+
>>> pcs = source_map.get_pcs_for_line(5)
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
def __init__(self, source_map: dict[str, Any]) -> None:
|
|
75
|
+
self.version: int = source_map["version"]
|
|
76
|
+
|
|
77
|
+
if self.version != SOURCE_MAP_VERSION:
|
|
78
|
+
raise SourceMapVersionError(self.version)
|
|
79
|
+
|
|
80
|
+
self.sources: list[str] = source_map["sources"]
|
|
81
|
+
|
|
82
|
+
self.mappings: str = source_map["mappings"]
|
|
83
|
+
|
|
84
|
+
pc_list = [_decode_int_value(raw_val) for raw_val in self.mappings.split(";")]
|
|
85
|
+
|
|
86
|
+
self.pc_to_line: dict[int, int] = {}
|
|
87
|
+
self.line_to_pc: dict[int, list[int]] = {}
|
|
88
|
+
|
|
89
|
+
last_line = 0
|
|
90
|
+
for index, line_delta in enumerate(pc_list):
|
|
91
|
+
# line_delta is None if the line number has not changed
|
|
92
|
+
# or if the line is empty
|
|
93
|
+
if line_delta is not None:
|
|
94
|
+
last_line = last_line + line_delta
|
|
95
|
+
|
|
96
|
+
if last_line not in self.line_to_pc:
|
|
97
|
+
self.line_to_pc[last_line] = []
|
|
98
|
+
|
|
99
|
+
self.line_to_pc[last_line].append(index)
|
|
100
|
+
self.pc_to_line[index] = last_line
|
|
101
|
+
|
|
102
|
+
def get_line_for_pc(self, pc: int) -> int | None:
|
|
103
|
+
"""Get the source line number for a given program counter.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
pc: The program counter value.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
The source line number, or None if not found.
|
|
110
|
+
"""
|
|
111
|
+
return self.pc_to_line.get(pc, None)
|
|
112
|
+
|
|
113
|
+
def get_pcs_for_line(self, line: int) -> list[int] | None:
|
|
114
|
+
"""Get the program counter values for a given source line.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
line: The source line number.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
A list of program counter values, or None if not found.
|
|
121
|
+
"""
|
|
122
|
+
return self.line_to_pc.get(line, None)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _decode_int_value(value: str) -> int | None:
|
|
126
|
+
"""Decode a VLQ segment to extract the line delta.
|
|
127
|
+
|
|
128
|
+
Mappings may have up to 5 segments:
|
|
129
|
+
Third segment represents the zero-based starting line in the original source represented.
|
|
130
|
+
"""
|
|
131
|
+
decoded_value = _base64vlq_decode(value)
|
|
132
|
+
return decoded_value[2] if decoded_value else None
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
# Source taken from: https://gist.github.com/mjpieters/86b0d152bb51d5f5979346d11005588b
|
|
136
|
+
_b64chars = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
|
137
|
+
_b64table: Final[list[int | None]] = [None] * (max(_b64chars) + 1)
|
|
138
|
+
for _i, _b in enumerate(_b64chars):
|
|
139
|
+
_b64table[_b] = _i
|
|
140
|
+
|
|
141
|
+
_shiftsize, _flag, _mask = 5, 1 << 5, (1 << 5) - 1
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def _base64vlq_decode(vlqval: str) -> tuple[int, ...]:
|
|
145
|
+
"""Decode Base64 VLQ value."""
|
|
146
|
+
results = []
|
|
147
|
+
shift = value = 0
|
|
148
|
+
# use byte values and a table to go from base64 characters to integers
|
|
149
|
+
for v in map(_b64table.__getitem__, vlqval.encode("ascii")):
|
|
150
|
+
v = cast(int, v) # force int type given context
|
|
151
|
+
value += (v & _mask) << shift
|
|
152
|
+
if v & _flag:
|
|
153
|
+
shift += _shiftsize
|
|
154
|
+
continue
|
|
155
|
+
# determine sign and add to results
|
|
156
|
+
results.append((value >> 1) * (-1 if value & 1 else 1))
|
|
157
|
+
shift = value = 0
|
|
158
|
+
return tuple(results)
|