#
tokens: 46857/50000 8/942 files (page 34/93)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 34 of 93. Use http://codebase.md/goplausible/algorand-mcp?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── llms-install.md
├── llms.txt
├── package.json
├── packages
│   ├── client
│   │   ├── .env.example
│   │   ├── package.json
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── env.ts
│   │   │   ├── index.ts
│   │   │   └── LocalWallet.ts
│   │   └── tsconfig.json
│   └── server
│       ├── .env.example
│       ├── API specs
│       │   ├── algod_api.json
│       │   ├── indexer_api.json
│       │   ├── mcp.json
│       │   ├── nfd_api.json
│       │   ├── ultrade_api.json
│       │   ├── vestige_api.json
│       │   └── vestige_free_api.json
│       ├── Dockerfile
│       ├── jest.config.js
│       ├── package.json
│       ├── README.md
│       ├── smithery.yaml
│       ├── src
│       │   ├── algorand-client.ts
│       │   ├── env.ts
│       │   ├── index.ts
│       │   ├── resources
│       │   │   ├── index.ts
│       │   │   ├── knowledge
│       │   │   │   ├── ARCs.txt
│       │   │   │   ├── developers-algokit-architecture-decisions.txt
│       │   │   │   ├── developers-algokit-cli.txt
│       │   │   │   ├── developers-algokit-utils-python.txt
│       │   │   │   ├── developers-algokit-utils-typescript.txt
│       │   │   │   ├── developers-clis.txt
│       │   │   │   ├── developers-details.txt
│       │   │   │   ├── developers-liquid-auth.txt
│       │   │   │   ├── developers-nodes.txt
│       │   │   │   ├── developers-puya.txt
│       │   │   │   ├── developers-python.txt
│       │   │   │   ├── developers-sdks-js.txt
│       │   │   │   ├── developers-sdks-python.txt
│       │   │   │   ├── developers-tealscript.txt
│       │   │   │   ├── developers.txt
│       │   │   │   ├── index.ts
│       │   │   │   ├── taxonomy
│       │   │   │   │   ├── algokit-cli:README.md
│       │   │   │   │   ├── algokit:cli:algokit.md
│       │   │   │   │   ├── algokit:cli:architecture-decisions:2022-11-14_sandbox-approach.md
│       │   │   │   │   ├── algokit:cli:architecture-decisions:2022-11-22_beaker-testing-strategy.md
│       │   │   │   │   ├── algokit:cli:architecture-decisions:2023-01-11_beaker_productionisation_review.md
│       │   │   │   │   ├── algokit:cli:architecture-decisions:2023-01-11_brew_install.md
│       │   │   │   │   ├── algokit:cli:architecture-decisions:2023-01-12_smart-contract-deployment.md
│       │   │   │   │   ├── algokit:cli:architecture-decisions:2023-06-06_frontend-templates.md
│       │   │   │   │   ├── algokit:cli:architecture-decisions:2023-07-19_advanced_generate_command.md
│       │   │   │   │   ├── algokit:cli:architecture-decisions:2024-01-13_native_binaries.md
│       │   │   │   │   ├── algokit:cli:architecture-decisions:2024-01-23_init-wizard-v2.md
│       │   │   │   │   ├── algokit:cli:architecture-decisions:2024-01-31_binary_distribution.md
│       │   │   │   │   ├── algokit:cli:architecture-decisions:2024-03-06_local_dev_ui_packaging.md
│       │   │   │   │   ├── algokit:cli:articles:output_stability.md
│       │   │   │   │   ├── algokit:cli:cli:index.md
│       │   │   │   │   ├── algokit:cli:features:compile.md
│       │   │   │   │   ├── algokit:cli:features:completions.md
│       │   │   │   │   ├── algokit:cli:features:config.md
│       │   │   │   │   ├── algokit:cli:features:dispenser.md
│       │   │   │   │   ├── algokit:cli:features:doctor.md
│       │   │   │   │   ├── algokit:cli:features:explore.md
│       │   │   │   │   ├── algokit:cli:features:generate.md
│       │   │   │   │   ├── algokit:cli:features:goal.md
│       │   │   │   │   ├── algokit:cli:features:init.md
│       │   │   │   │   ├── algokit:cli:features:localnet.md
│       │   │   │   │   ├── algokit:cli:features:project:bootstrap.md
│       │   │   │   │   ├── algokit:cli:features:project:deploy.md
│       │   │   │   │   ├── algokit:cli:features:project:link.md
│       │   │   │   │   ├── algokit:cli:features:project:list.md
│       │   │   │   │   ├── algokit:cli:features:project:run.md
│       │   │   │   │   ├── algokit:cli:features:project.md
│       │   │   │   │   ├── algokit:cli:features:tasks:analyze.md
│       │   │   │   │   ├── algokit:cli:features:tasks:ipfs.md
│       │   │   │   │   ├── algokit:cli:features:tasks:mint.md
│       │   │   │   │   ├── algokit:cli:features:tasks:nfd.md
│       │   │   │   │   ├── algokit:cli:features:tasks:opt.md
│       │   │   │   │   ├── algokit:cli:features:tasks:send.md
│       │   │   │   │   ├── algokit:cli:features:tasks:sign.md
│       │   │   │   │   ├── algokit:cli:features:tasks:transfer.md
│       │   │   │   │   ├── algokit:cli:features:tasks:vanity_address.md
│       │   │   │   │   ├── algokit:cli:features:tasks:wallet.md
│       │   │   │   │   ├── algokit:cli:features:tasks.md
│       │   │   │   │   ├── algokit:cli:tutorials:algokit-template.md
│       │   │   │   │   ├── algokit:cli:tutorials:intro.md
│       │   │   │   │   ├── algokit:cli:tutorials:smart-contracts.md
│       │   │   │   │   ├── algokit:docs:testnet_api.md
│       │   │   │   │   ├── algokit:lora:README.md
│       │   │   │   │   ├── algokit:README.md
│       │   │   │   │   ├── algokit:utils:python:markdown:apidocs:algokit_utils:algokit_utils.md
│       │   │   │   │   ├── algokit:utils:python:markdown:capabilities:account.md
│       │   │   │   │   ├── algokit:utils:python:markdown:capabilities:app-client.md
│       │   │   │   │   ├── algokit:utils:python:markdown:capabilities:app-deploy.md
│       │   │   │   │   ├── algokit:utils:python:markdown:capabilities:client.md
│       │   │   │   │   ├── algokit:utils:python:markdown:capabilities:debugger.md
│       │   │   │   │   ├── algokit:utils:python:markdown:capabilities:dispenser-client.md
│       │   │   │   │   ├── algokit:utils:python:markdown:capabilities:transfer.md
│       │   │   │   │   ├── algokit:utils:python:markdown:index.md
│       │   │   │   │   ├── algokit:utils:python:README.md
│       │   │   │   │   ├── algokit:utils:python:source:capabilities:account.md
│       │   │   │   │   ├── algokit:utils:python:source:capabilities:app-client.md
│       │   │   │   │   ├── algokit:utils:python:source:capabilities:app-deploy.md
│       │   │   │   │   ├── algokit:utils:python:source:capabilities:client.md
│       │   │   │   │   ├── algokit:utils:python:source:capabilities:debugger.md
│       │   │   │   │   ├── algokit:utils:python:source:capabilities:dispenser-client.md
│       │   │   │   │   ├── algokit:utils:python:source:capabilities:transfer.md
│       │   │   │   │   ├── algokit:utils:python:source:index.md
│       │   │   │   │   ├── algokit:utils:typescript:capabilities:account.md
│       │   │   │   │   ├── algokit:utils:typescript:capabilities:algorand-client.md
│       │   │   │   │   ├── algokit:utils:typescript:capabilities:amount.md
│       │   │   │   │   ├── algokit:utils:typescript:capabilities:app-client.md
│       │   │   │   │   ├── algokit:utils:typescript:capabilities:app-deploy.md
│       │   │   │   │   ├── algokit:utils:typescript:capabilities:app.md
│       │   │   │   │   ├── algokit:utils:typescript:capabilities:asset.md
│       │   │   │   │   ├── algokit:utils:typescript:capabilities:client.md
│       │   │   │   │   ├── algokit:utils:typescript:capabilities:debugging.md
│       │   │   │   │   ├── algokit:utils:typescript:capabilities:dispenser-client.md
│       │   │   │   │   ├── algokit:utils:typescript:capabilities:event-emitter.md
│       │   │   │   │   ├── algokit:utils:typescript:capabilities:indexer.md
│       │   │   │   │   ├── algokit:utils:typescript:capabilities:testing.md
│       │   │   │   │   ├── algokit:utils:typescript:capabilities:transaction-composer.md
│       │   │   │   │   ├── algokit:utils:typescript:capabilities:transaction.md
│       │   │   │   │   ├── algokit:utils:typescript:capabilities:transfer.md
│       │   │   │   │   ├── algokit:utils:typescript:capabilities:typed-app-clients.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:testing.TestLogger.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:testing.TransactionLogger.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_account_manager.AccountManager.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_account.MultisigAccount.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_account.SigningAccount.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_algo_http_client_with_retry.AlgoHttpClientWithRetry.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_algorand_client_transaction_creator.AlgorandClientTransactionCreator.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_algorand_client_transaction_sender.AlgorandClientTransactionSender.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_algorand_client.AlgorandClient.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_amount.AlgoAmount.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_app_arc56.Arc56Method.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_app_client.AppClient.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_app_client.ApplicationClient.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_app_deployer.AppDeployer.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_app_factory.AppFactory.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_app_manager.AppManager.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_asset_manager.AssetManager.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_async_event_emitter.AsyncEventEmitter.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_client_manager.ClientManager.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_composer.TransactionComposer.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_config.UpdatableConfig.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_dispenser_client.TestNetDispenserApiClient.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_kmd_account_manager.KmdAccountManager.md
│       │   │   │   │   ├── algokit:utils:typescript:code:classes:types_logic_error.LogicError.md
│       │   │   │   │   ├── algokit:utils:typescript:code:enums:types_app.OnSchemaBreak.md
│       │   │   │   │   ├── algokit:utils:typescript:code:enums:types_app.OnUpdate.md
│       │   │   │   │   ├── algokit:utils:typescript:code:enums:types_indexer.AccountStatus.md
│       │   │   │   │   ├── algokit:utils:typescript:code:enums:types_indexer.ApplicationOnComplete.md
│       │   │   │   │   ├── algokit:utils:typescript:code:enums:types_indexer.SignatureType.md
│       │   │   │   │   ├── algokit:utils:typescript:code:enums:types_lifecycle_events.EventType.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_account_manager.EnsureFundedResult.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_account.AccountConfig.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_account.TransactionSignerAccount.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_algorand_client_interface.AlgorandClientInterface.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_arc56.Arc56Contract.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_arc56.Event.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_arc56.Method.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_arc56.ProgramSourceInfo.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_arc56.StorageKey.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_arc56.StorageMap.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_arc56.StructField.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientCallABIArgs.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientCallCoreParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientCompilationParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientCompilationResult.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientDeployCallInterfaceParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientDeployCoreParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientDeployParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_client.AppSourceMaps.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_client.FundAppAccountParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_client.ResolveAppById.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_client.ResolveAppByIdBase.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_client.SourceMapExport.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_deployer.AppLookup.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_deployer.AppMetadata.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_factory.AppFactoryParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_manager.AppInformation.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_manager.BoxReference.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_manager.BoxValueRequestParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_manager.BoxValuesRequestParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_spec.AppSources.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_spec.AppSpec.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_spec.CallConfig.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_spec.DeclaredSchemaValueSpec.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_spec.Hint.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_spec.ReservedSchemaValueSpec.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_spec.Schema.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_spec.SchemaSpec.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_spec.StateSchemaSpec.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app_spec.Struct.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.AppCallParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.AppCallTransactionResultOfType.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.AppCompilationResult.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.AppDeploymentParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.AppDeployMetadata.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.AppLookup.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.AppMetadata.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.AppReference.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.AppState.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.AppStorageSchema.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.BoxName.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.BoxReference.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.BoxValueRequestParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.BoxValuesRequestParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.CompiledTeal.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.CoreAppCallArgs.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.CreateAppParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.RawAppCallArgs.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.TealTemplateParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_app.UpdateAppParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_asset_manager.AssetInformation.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_asset_manager.BulkAssetOptInOutResult.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_asset.AssetBulkOptInOutParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_asset.AssetOptInParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_asset.AssetOptOutParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_asset.CreateAssetParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_client_manager.AlgoSdkClients.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_client_manager.TypedAppClient.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_client_manager.TypedAppFactory.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_composer.BuiltTransactions.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_config.Config.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_debugging.AVMTracesEventData.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_debugging.TealSourceDebugEventData.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_debugging.TealSourcesDebugEventData.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_dispenser_client.DispenserFundResponse.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_dispenser_client.DispenserLimitResponse.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_dispenser_client.TestNetDispenserApiClientParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_indexer.LookupAssetHoldingsOptions.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_logic_error.LogicErrorDetails.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_network_client.AlgoClientConfig.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_network_client.AlgoConfig.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_network_client.NetworkDetails.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_testing.AlgoKitLogCaptureFixture.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_testing.AlgorandFixture.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_testing.AlgorandFixtureConfig.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_testing.AlgorandTestAutomationContext.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_testing.GetTestAccountParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_testing.LogSnapshotConfig.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_transaction.AtomicTransactionComposerToSend.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_transaction.ConfirmedTransactionResult.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_transaction.ConfirmedTransactionResults.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_transaction.SendAtomicTransactionComposerResults.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_transaction.SendParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_transaction.SendTransactionParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_transaction.SendTransactionResult.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_transaction.SendTransactionResults.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_transaction.TransactionGroupToSend.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_transaction.TransactionToSign.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_transfer.AlgoRekeyParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_transfer.AlgoTransferParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_transfer.EnsureFundedParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_transfer.EnsureFundedReturnType.md
│       │   │   │   │   ├── algokit:utils:typescript:code:interfaces:types_transfer.TransferAssetParams.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:index.indexer.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:index.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:testing.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_account_manager_spec.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_account_manager.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_account.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_algo_http_client_with_retry.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_algorand_client_asset_spec.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_algorand_client_interface.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_algorand_client_spec.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_algorand_client_transaction_creator.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_algorand_client_transaction_sender.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_algorand_client_transfer_spec.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_algorand_client.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_amount_spec.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_amount.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_app_arc56.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_app_client_spec.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_app_client.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_app_deployer.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_app_factory_and_client_spec.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_app_factory.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_app_manager.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_app_spec.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_app.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_asset_manager.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_asset.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_async_event_emitter_spec.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_async_event_emitter.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_client_manager_spec.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_client_manager.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_composer.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_config.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_debugging.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_dispenser_client_spec.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_dispenser_client.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_expand.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_indexer.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_kmd_account_manager.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_lifecycle_events.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_logging.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_logic_error.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_network_client.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_testing.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_transaction.md
│       │   │   │   │   ├── algokit:utils:typescript:code:modules:types_transfer.md
│       │   │   │   │   ├── algokit:utils:typescript:code:README.md
│       │   │   │   │   ├── algokit:utils:typescript:README.md
│       │   │   │   │   ├── algokit:utils:typescript:v7-migration.md
│       │   │   │   │   ├── algokit:utils:typescript:v8-migration.md
│       │   │   │   │   ├── ARCs:ARC-template.md
│       │   │   │   │   ├── ARCs:assets:arc-0012:README.md
│       │   │   │   │   ├── ARCs:assets:arc-0034:TemplateForm.md
│       │   │   │   │   ├── ARCs:assets:arc-0062:README.md
│       │   │   │   │   ├── ARCs:pages:nfts.md
│       │   │   │   │   ├── ARCs:pages:wallets.md
│       │   │   │   │   ├── ARCs:README.md
│       │   │   │   │   ├── ARCs:specs:arc-0000.md
│       │   │   │   │   ├── ARCs:specs:arc-0001.md
│       │   │   │   │   ├── ARCs:specs:arc-0002.md
│       │   │   │   │   ├── ARCs:specs:arc-0003.md
│       │   │   │   │   ├── ARCs:specs:arc-0004.md
│       │   │   │   │   ├── ARCs:specs:arc-0005.md
│       │   │   │   │   ├── ARCs:specs:arc-0006.md
│       │   │   │   │   ├── ARCs:specs:arc-0007.md
│       │   │   │   │   ├── ARCs:specs:arc-0008.md
│       │   │   │   │   ├── ARCs:specs:arc-0009.md
│       │   │   │   │   ├── ARCs:specs:arc-0010.md
│       │   │   │   │   ├── ARCs:specs:arc-0011.md
│       │   │   │   │   ├── ARCs:specs:arc-0012.md
│       │   │   │   │   ├── ARCs:specs:arc-0015.md
│       │   │   │   │   ├── ARCs:specs:arc-0016.md
│       │   │   │   │   ├── ARCs:specs:arc-0018.md
│       │   │   │   │   ├── ARCs:specs:arc-0019.md
│       │   │   │   │   ├── ARCs:specs:arc-0020.md
│       │   │   │   │   ├── ARCs:specs:arc-0021.md
│       │   │   │   │   ├── ARCs:specs:arc-0022.md
│       │   │   │   │   ├── ARCs:specs:arc-0023.md
│       │   │   │   │   ├── ARCs:specs:arc-0025.md
│       │   │   │   │   ├── ARCs:specs:arc-0026.md
│       │   │   │   │   ├── ARCs:specs:arc-0028.md
│       │   │   │   │   ├── ARCs:specs:arc-0032.md
│       │   │   │   │   ├── ARCs:specs:arc-0033.md
│       │   │   │   │   ├── ARCs:specs:arc-0034.md
│       │   │   │   │   ├── ARCs:specs:arc-0035.md
│       │   │   │   │   ├── ARCs:specs:arc-0036.md
│       │   │   │   │   ├── ARCs:specs:arc-0042.md
│       │   │   │   │   ├── ARCs:specs:arc-0047.md
│       │   │   │   │   ├── ARCs:specs:arc-0048.md
│       │   │   │   │   ├── ARCs:specs:arc-0049.md
│       │   │   │   │   ├── ARCs:specs:arc-0054.md
│       │   │   │   │   ├── ARCs:specs:arc-0055.md
│       │   │   │   │   ├── ARCs:specs:arc-0056.md
│       │   │   │   │   ├── ARCs:specs:arc-0059.md
│       │   │   │   │   ├── ARCs:specs:arc-0062.md
│       │   │   │   │   ├── ARCs:specs:arc-0065.md
│       │   │   │   │   ├── ARCs:specs:arc-0069.md
│       │   │   │   │   ├── ARCs:specs:arc-0072.md
│       │   │   │   │   ├── ARCs:specs:arc-0073.md
│       │   │   │   │   ├── ARCs:specs:arc-0074.md
│       │   │   │   │   ├── ARCs:specs:arc-0076.md
│       │   │   │   │   ├── ARCs:specs:arc-0078.md
│       │   │   │   │   ├── ARCs:specs:arc-0079.md
│       │   │   │   │   ├── ARCs:specs:arc-0200.md
│       │   │   │   │   ├── clis_index.md
│       │   │   │   │   ├── developer:docs:about.md
│       │   │   │   │   ├── developer:docs:clis:algokey:algokey.md
│       │   │   │   │   ├── developer:docs:clis:algokey:generate.md
│       │   │   │   │   ├── developer:docs:clis:algokey:import.md
│       │   │   │   │   ├── developer:docs:clis:algokey:multisig:append-auth-addr.md
│       │   │   │   │   ├── developer:docs:clis:algokey:multisig:multisig.md
│       │   │   │   │   ├── developer:docs:clis:algokey:part:info.md
│       │   │   │   │   ├── developer:docs:clis:algokey:part:part.md
│       │   │   │   │   ├── developer:docs:clis:algokey:part:reparent.md
│       │   │   │   │   ├── developer:docs:clis:algokey:sign.md
│       │   │   │   │   ├── developer:docs:clis:conduit:conduit.md
│       │   │   │   │   ├── developer:docs:clis:conduit:init.md
│       │   │   │   │   ├── developer:docs:clis:conduit:list:exporters.md
│       │   │   │   │   ├── developer:docs:clis:conduit:list:importers.md
│       │   │   │   │   ├── developer:docs:clis:conduit:list:list.md
│       │   │   │   │   ├── developer:docs:clis:conduit:list:processors.md
│       │   │   │   │   ├── developer:docs:clis:diagcfg:diagcfg.md
│       │   │   │   │   ├── developer:docs:clis:diagcfg:metric:disable.md
│       │   │   │   │   ├── developer:docs:clis:diagcfg:metric:enable.md
│       │   │   │   │   ├── developer:docs:clis:diagcfg:metric:metric.md
│       │   │   │   │   ├── developer:docs:clis:diagcfg:metric:status.md
│       │   │   │   │   ├── developer:docs:clis:diagcfg:telemetry:disable.md
│       │   │   │   │   ├── developer:docs:clis:diagcfg:telemetry:enable.md
│       │   │   │   │   ├── developer:docs:clis:diagcfg:telemetry:endpoint.md
│       │   │   │   │   ├── developer:docs:clis:diagcfg:telemetry:name.md
│       │   │   │   │   ├── developer:docs:clis:diagcfg:telemetry:status.md
│       │   │   │   │   ├── developer:docs:clis:diagcfg:telemetry:telemetry.md
│       │   │   │   │   ├── developer:docs:clis:goal:node:restart.md
│       │   │   │   │   ├── developer:docs:clis:goal:node:start.md
│       │   │   │   │   ├── developer:docs:clis:goal:node:status.md
│       │   │   │   │   ├── developer:docs:clis:goal:node:stop.md
│       │   │   │   │   ├── developer:docs:clis:goal:node:wait.md
│       │   │   │   │   ├── developer:docs:clis:goal:protocols.md
│       │   │   │   │   ├── developer:docs:clis:goal:report.md
│       │   │   │   │   ├── developer:docs:clis:goal:version.md
│       │   │   │   │   ├── developer:docs:clis:goal:wallet:list.md
│       │   │   │   │   ├── developer:docs:clis:goal:wallet:new.md
│       │   │   │   │   ├── developer:docs:clis:goal:wallet:wallet.md
│       │   │   │   │   ├── developer:docs:clis:indexer:api-config.md
│       │   │   │   │   ├── developer:docs:clis:indexer:daemon.md
│       │   │   │   │   ├── developer:docs:clis:indexer:indexer.md
│       │   │   │   │   ├── developer:docs:clis:indexer:util:util.md
│       │   │   │   │   ├── developer:docs:clis:indexer:util:validator.md
│       │   │   │   │   ├── developer:docs:clis:kmd.md
│       │   │   │   │   ├── developer:docs:clis:tealdbg:debug.md
│       │   │   │   │   ├── developer:docs:clis:tealdbg:remote.md
│       │   │   │   │   ├── developer:docs:clis:tealdbg:tealdbg.md
│       │   │   │   │   ├── developer:docs:details:accounts:create.md
│       │   │   │   │   ├── developer:docs:details:accounts:index.md
│       │   │   │   │   ├── developer:docs:details:accounts:rekey.md
│       │   │   │   │   ├── developer:docs:details:algorand_consensus.md
│       │   │   │   │   ├── developer:docs:details:algorand-networks:betanet.md
│       │   │   │   │   ├── developer:docs:details:algorand-networks:index.md
│       │   │   │   │   ├── developer:docs:details:algorand-networks:mainnet.md
│       │   │   │   │   ├── developer:docs:details:algorand-networks:testnet.md
│       │   │   │   │   ├── developer:docs:details:asa.md
│       │   │   │   │   ├── developer:docs:details:atc.md
│       │   │   │   │   ├── developer:docs:details:atomic_transfers.md
│       │   │   │   │   ├── developer:docs:details:conduit.md
│       │   │   │   │   ├── developer:docs:details:crust.md
│       │   │   │   │   ├── developer:docs:details:dapps:avm:index.md
│       │   │   │   │   ├── developer:docs:details:dapps:avm:teal:guidelines.md
│       │   │   │   │   ├── developer:docs:details:dapps:avm:teal:index.md
│       │   │   │   │   ├── developer:docs:details:dapps:avm:teal:jsonspec.md
│       │   │   │   │   ├── developer:docs:details:dapps:avm:teal:opcodes:index.md
│       │   │   │   │   ├── developer:docs:details:dapps:avm:teal:opcodes:v1.md
│       │   │   │   │   ├── developer:docs:details:dapps:avm:teal:opcodes:v10.md
│       │   │   │   │   ├── developer:docs:details:dapps:avm:teal:opcodes:v2.md
│       │   │   │   │   ├── developer:docs:details:dapps:avm:teal:opcodes:v3.md
│       │   │   │   │   ├── developer:docs:details:dapps:avm:teal:opcodes:v4.md
│       │   │   │   │   ├── developer:docs:details:dapps:avm:teal:opcodes:v5.md
│       │   │   │   │   ├── developer:docs:details:dapps:avm:teal:opcodes:v6.md
│       │   │   │   │   ├── developer:docs:details:dapps:avm:teal:opcodes:v7.md
│       │   │   │   │   ├── developer:docs:details:dapps:avm:teal:opcodes:v8.md
│       │   │   │   │   ├── developer:docs:details:dapps:avm:teal:opcodes:v9.md
│       │   │   │   │   ├── developer:docs:details:dapps:avm:teal:specification.md
│       │   │   │   │   ├── developer:docs:details:dapps:smart-contracts:ABI:index.md
│       │   │   │   │   ├── developer:docs:details:dapps:smart-contracts:apps:create.md
│       │   │   │   │   ├── developer:docs:details:dapps:smart-contracts:apps:index.md
│       │   │   │   │   ├── developer:docs:details:dapps:smart-contracts:apps:innertx.md
│       │   │   │   │   ├── developer:docs:details:dapps:smart-contracts:apps:state.md
│       │   │   │   │   ├── developer:docs:details:dapps:smart-contracts:apps:txs.md
│       │   │   │   │   ├── developer:docs:details:dapps:smart-contracts:debugging.md
│       │   │   │   │   ├── developer:docs:details:dapps:smart-contracts:frontend:apps.md
│       │   │   │   │   ├── developer:docs:details:dapps:smart-contracts:frontend:smartsigs.md
│       │   │   │   │   ├── developer:docs:details:dapps:smart-contracts:guidelines.md
│       │   │   │   │   ├── developer:docs:details:dapps:smart-contracts:index.md
│       │   │   │   │   ├── developer:docs:details:dapps:smart-contracts:smartsigs:index.md
│       │   │   │   │   ├── developer:docs:details:dapps:smart-contracts:smartsigs:modes.md
│       │   │   │   │   ├── developer:docs:details:dapps:smart-contracts:smartsigs:walkthrough.md
│       │   │   │   │   ├── developer:docs:details:dapps:writing-contracts:beaker.md
│       │   │   │   │   ├── developer:docs:details:dapps:writing-contracts:pyteal.md
│       │   │   │   │   ├── developer:docs:details:dapps:writing-contracts:python.md
│       │   │   │   │   ├── developer:docs:details:encoding.md
│       │   │   │   │   ├── developer:docs:details:ethereum_to_algorand.md
│       │   │   │   │   ├── developer:docs:details:index.md
│       │   │   │   │   ├── developer:docs:details:indexer.md
│       │   │   │   │   ├── developer:docs:details:parameter_tables.md
│       │   │   │   │   ├── developer:docs:details:stateproofs:index.md
│       │   │   │   │   ├── developer:docs:details:stateproofs:light_client.md
│       │   │   │   │   ├── developer:docs:details:technical_faq.md
│       │   │   │   │   ├── developer:docs:details:transactions:index.md
│       │   │   │   │   ├── developer:docs:details:transactions:offline_transactions.md
│       │   │   │   │   ├── developer:docs:details:transactions:payment_prompts.md
│       │   │   │   │   ├── developer:docs:details:transactions:signatures.md
│       │   │   │   │   ├── developer:docs:details:transactions:transactions.md
│       │   │   │   │   ├── developer:docs:details:useful_resources.md
│       │   │   │   │   ├── developer:docs:get-started:algokit.md
│       │   │   │   │   ├── developer:docs:get-started:basics:what_is_blockchain.md
│       │   │   │   │   ├── developer:docs:get-started:basics:whats_a_dapp.md
│       │   │   │   │   ├── developer:docs:get-started:basics:where_to_start.md
│       │   │   │   │   ├── developer:docs:get-started:basics:why_algorand.md
│       │   │   │   │   ├── developer:docs:get-started:tokenization:ft.md
│       │   │   │   │   ├── developer:docs:get-started:tokenization:nft.md
│       │   │   │   │   ├── developer:docs:index.md
│       │   │   │   │   ├── developer:docs:rest-apis:algod.md
│       │   │   │   │   ├── developer:docs:rest-apis:indexer.md
│       │   │   │   │   ├── developer:docs:rest-apis:kmd.md
│       │   │   │   │   ├── developer:docs:rest-apis:restendpoints.md
│       │   │   │   │   ├── developer:docs:run-a-node:operations:catchup.md
│       │   │   │   │   ├── developer:docs:run-a-node:operations:switch_networks.md
│       │   │   │   │   ├── developer:docs:run-a-node:participate:generate_keys.md
│       │   │   │   │   ├── developer:docs:run-a-node:participate:index.md
│       │   │   │   │   ├── developer:docs:run-a-node:participate:offline.md
│       │   │   │   │   ├── developer:docs:run-a-node:participate:online.md
│       │   │   │   │   ├── developer:docs:run-a-node:participate:renew.md
│       │   │   │   │   ├── developer:docs:run-a-node:reference:artifacts.md
│       │   │   │   │   ├── developer:docs:run-a-node:reference:config.md
│       │   │   │   │   ├── developer:docs:run-a-node:reference:relay.md
│       │   │   │   │   ├── developer:docs:run-a-node:reference:telemetry-config.md
│       │   │   │   │   ├── developer:docs:run-a-node:setup:indexer.md
│       │   │   │   │   ├── developer:docs:run-a-node:setup:install.md
│       │   │   │   │   ├── developer:docs:run-a-node:setup:node-troubleshooting.md
│       │   │   │   │   ├── developer:docs:run-a-node:setup:types.md
│       │   │   │   │   ├── developer:docs:sdks:go:index.md
│       │   │   │   │   ├── developer:docs:sdks:index.md
│       │   │   │   │   ├── developer:docs:sdks:java:index.md
│       │   │   │   │   ├── developer:docs:sdks:javascript:index.md
│       │   │   │   │   ├── developer:docs:sdks:python:index.md
│       │   │   │   │   ├── developer:python:code:example:accounts.md
│       │   │   │   │   ├── developer:python:code:example:arc4_types.md
│       │   │   │   │   ├── developer:python:code:example:assets.md
│       │   │   │   │   ├── developer:python:code:example:box_storage.md
│       │   │   │   │   ├── developer:python:code:example:control_flow.md
│       │   │   │   │   ├── developer:python:code:example:crypto:merkle_tree.md
│       │   │   │   │   ├── developer:python:code:example:defi:amm.md
│       │   │   │   │   ├── developer:python:code:example:defi:auction.md
│       │   │   │   │   ├── developer:python:code:example:defi:htlc_logicsig.md
│       │   │   │   │   ├── developer:python:code:example:defi:marketplace.md
│       │   │   │   │   ├── developer:python:code:example:events:arc28_events.md
│       │   │   │   │   ├── developer:python:code:example:global_storage.md
│       │   │   │   │   ├── developer:python:code:example:governance:simple_voting.md
│       │   │   │   │   ├── developer:python:code:example:hello_world.md
│       │   │   │   │   ├── developer:python:code:example:inner_transactions.md
│       │   │   │   │   ├── developer:python:code:example:local_storage.md
│       │   │   │   │   ├── developer:python:code:example:nft:proof_of_attendance.md
│       │   │   │   │   ├── developer:python:code:example:privacy:zk_whitelist.md
│       │   │   │   │   ├── developer:python:code:example:scratch_storage.md
│       │   │   │   │   ├── developer:python:code:example:self_payment.md
│       │   │   │   │   ├── developer:python:code:example:struct_in_box.md
│       │   │   │   │   ├── developer:python:code:example:subsidize_app_call.md
│       │   │   │   │   ├── developer:python:code:example:transactions.md
│       │   │   │   │   ├── developer:python:code:example:utility:calculator.md
│       │   │   │   │   ├── devportal-code-examples:projects:python-contract-examples:README.md
│       │   │   │   │   ├── devportal-code-examples:README.md
│       │   │   │   │   ├── docs:.walletconnect:index.md
│       │   │   │   │   ├── docs:.walletconnect:walletconnect-schema.md
│       │   │   │   │   ├── docs:README.md
│       │   │   │   │   ├── docs:scripts:example_tracker:example_list.md
│       │   │   │   │   ├── docs:scripts:README.md
│       │   │   │   │   ├── index.md
│       │   │   │   │   ├── liquid_auth_index.md
│       │   │   │   │   ├── liquid-auth:ARCHITECTURE.md
│       │   │   │   │   ├── liquid-auth:decisions:1-Service-Authentication.md
│       │   │   │   │   ├── liquid-auth:decisions:2-Bidirectional-Communication.md
│       │   │   │   │   ├── liquid-auth:decisions:3-Peer-to-Peer-Signaling.md
│       │   │   │   │   ├── liquid-auth:decisions:4-Fido-Extension.md
│       │   │   │   │   ├── liquid-auth:decisions:README.md
│       │   │   │   │   ├── liquid-auth:docs:architecture.md
│       │   │   │   │   ├── liquid-auth:docs:clients:android:provider-service:authenticate.md
│       │   │   │   │   ├── liquid-auth:docs:clients:android:provider-service:register.md
│       │   │   │   │   ├── liquid-auth:docs:clients:browser:authentication.md
│       │   │   │   │   ├── liquid-auth:docs:clients:browser:example.md
│       │   │   │   │   ├── liquid-auth:docs:introduction.md
│       │   │   │   │   ├── liquid-auth:docs:README.md
│       │   │   │   │   ├── liquid-auth:docs:server:environment-variables.md
│       │   │   │   │   ├── liquid-auth:docs:server:integrations.md
│       │   │   │   │   ├── liquid-auth:docs:server:introduction.md
│       │   │   │   │   ├── liquid-auth:docs:server:running-locally.md
│       │   │   │   │   ├── liquid-auth:README.md
│       │   │   │   │   ├── liquid-auth:SEQUENCE.md
│       │   │   │   │   ├── liquid-auth:services:liquid-auth-api-js:src:assertion:assertion.controller.post.request.md
│       │   │   │   │   ├── liquid-auth:services:liquid-auth-api-js:src:assertion:assertion.controller.post.response.md
│       │   │   │   │   ├── liquid-auth:services:liquid-auth-api-js:src:attestation:attestation.controller.post.request.md
│       │   │   │   │   ├── liquid-auth:services:liquid-auth-api-js:src:auth:auth.controller.get.user.md
│       │   │   │   │   ├── liquid-auth:sites:express-dapp:README.md
│       │   │   │   │   ├── liquid-auth:VISION.md
│       │   │   │   │   ├── puya_index.md
│       │   │   │   │   ├── puya:docs:algopy_testing:index.md
│       │   │   │   │   ├── puya:docs:api-algopy.arc4.md
│       │   │   │   │   ├── puya:docs:api-algopy.gtxn.md
│       │   │   │   │   ├── puya:docs:api-algopy.itxn.md
│       │   │   │   │   ├── puya:docs:api-algopy.md
│       │   │   │   │   ├── puya:docs:api-algopy.op.md
│       │   │   │   │   ├── puya:docs:api.md
│       │   │   │   │   ├── puya:docs:compiler.md
│       │   │   │   │   ├── puya:docs:index.md
│       │   │   │   │   ├── puya:docs:language-guide.md
│       │   │   │   │   ├── puya:docs:lg-arc28.md
│       │   │   │   │   ├── puya:docs:lg-arc4.md
│       │   │   │   │   ├── puya:docs:lg-builtins.md
│       │   │   │   │   ├── puya:docs:lg-calling-apps.md
│       │   │   │   │   ├── puya:docs:lg-compile.md
│       │   │   │   │   ├── puya:docs:lg-control.md
│       │   │   │   │   ├── puya:docs:lg-errors.md
│       │   │   │   │   ├── puya:docs:lg-logs.md
│       │   │   │   │   ├── puya:docs:lg-modules.md
│       │   │   │   │   ├── puya:docs:lg-opcode-budget.md
│       │   │   │   │   ├── puya:docs:lg-ops.md
│       │   │   │   │   ├── puya:docs:lg-storage.md
│       │   │   │   │   ├── puya:docs:lg-structure.md
│       │   │   │   │   ├── puya:docs:lg-transactions.md
│       │   │   │   │   ├── puya:docs:lg-types.md
│       │   │   │   │   ├── puya:docs:lg-unsupported-python-features.md
│       │   │   │   │   ├── puya:docs:principles.md
│       │   │   │   │   ├── puya:examples:auction:README.md
│       │   │   │   │   ├── puya:python:testing:docs:algopy.md
│       │   │   │   │   ├── puya:python:testing:docs:api.md
│       │   │   │   │   ├── puya:python:testing:docs:coverage.md
│       │   │   │   │   ├── puya:python:testing:docs:examples.md
│       │   │   │   │   ├── puya:python:testing:docs:faq.md
│       │   │   │   │   ├── puya:python:testing:docs:index.md
│       │   │   │   │   ├── puya:python:testing:docs:testing-guide:arc4-types.md
│       │   │   │   │   ├── puya:python:testing:docs:testing-guide:avm-types.md
│       │   │   │   │   ├── puya:python:testing:docs:testing-guide:concepts.md
│       │   │   │   │   ├── puya:python:testing:docs:testing-guide:contract-testing.md
│       │   │   │   │   ├── puya:python:testing:docs:testing-guide:index.md
│       │   │   │   │   ├── puya:python:testing:docs:testing-guide:opcodes.md
│       │   │   │   │   ├── puya:python:testing:docs:testing-guide:signature-testing.md
│       │   │   │   │   ├── puya:python:testing:docs:testing-guide:state-management.md
│       │   │   │   │   ├── puya:python:testing:docs:testing-guide:subroutines.md
│       │   │   │   │   ├── puya:python:testing:docs:testing-guide:transactions.md
│       │   │   │   │   ├── puya:python:testing:examples:README.md
│       │   │   │   │   ├── puya:python:testing:README.md
│       │   │   │   │   ├── puya:README.md
│       │   │   │   │   ├── puya:src:puya:ARCHITECTURE.md
│       │   │   │   │   ├── puya:src:puyapy:_typeshed:README.md
│       │   │   │   │   ├── puya:src:puyapy:_vendor:mypy:typeshed:stdlib:_typeshed:README.md
│       │   │   │   │   ├── puya:src:puyapy:awst_build:README.md
│       │   │   │   │   ├── puya:stubs:README.md
│       │   │   │   │   ├── puya:tests:test_expected_output:README.md
│       │   │   │   │   ├── puya:typescript:docs:architecture-decisions:2024-05-21_primitive-bytes-and-strings.md
│       │   │   │   │   ├── puya:typescript:docs:architecture-decisions:2024-05-21_primitive-integer-types.md
│       │   │   │   │   ├── puya:typescript:docs:README.md
│       │   │   │   │   ├── puya:typescript:packages:algo-ts:readme.md
│       │   │   │   │   ├── puya:typescript:README.md
│       │   │   │   │   ├── SDKs:javascript:classes:ABIAddressType.md
│       │   │   │   │   ├── SDKs:javascript:classes:ABIArrayDynamicType.md
│       │   │   │   │   ├── SDKs:javascript:classes:ABIArrayStaticType.md
│       │   │   │   │   ├── SDKs:javascript:classes:ABIBoolType.md
│       │   │   │   │   ├── SDKs:javascript:classes:ABIByteType.md
│       │   │   │   │   ├── SDKs:javascript:classes:ABIContract.md
│       │   │   │   │   ├── SDKs:javascript:classes:ABIInterface.md
│       │   │   │   │   ├── SDKs:javascript:classes:ABIMethod.md
│       │   │   │   │   ├── SDKs:javascript:classes:ABIStringType.md
│       │   │   │   │   ├── SDKs:javascript:classes:ABITupleType.md
│       │   │   │   │   ├── SDKs:javascript:classes:ABIType.md
│       │   │   │   │   ├── SDKs:javascript:classes:ABIUfixedType.md
│       │   │   │   │   ├── SDKs:javascript:classes:ABIUintType.md
│       │   │   │   │   ├── SDKs:javascript:classes:Algodv2.md
│       │   │   │   │   ├── SDKs:javascript:classes:AtomicTransactionComposer.md
│       │   │   │   │   ├── SDKs:javascript:classes:DryrunResult.md
│       │   │   │   │   ├── SDKs:javascript:classes:Indexer.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.Account.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.AccountParticipation.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.AccountResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.AccountsResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.AccountStateDelta.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.Application.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.ApplicationLocalState.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.ApplicationLocalStatesResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.ApplicationLogData.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.ApplicationLogsResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.ApplicationParams.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.ApplicationResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.ApplicationsResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.ApplicationStateSchema.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.Asset.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.AssetBalancesResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.AssetHolding.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.AssetHoldingsResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.AssetParams.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.AssetResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.AssetsResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.Block.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.BlockRewards.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.BlockUpgradeState.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.BlockUpgradeVote.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.Box.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.BoxDescriptor.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.BoxesResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.ErrorResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.EvalDelta.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.EvalDeltaKeyValue.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.HashFactory.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.HealthCheck.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.IndexerStateProofMessage.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.MerkleArrayProof.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.MiniAssetHolding.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.ParticipationUpdates.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.StateProofFields.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.StateProofParticipant.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.StateProofReveal.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.StateProofSignature.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.StateProofSigSlot.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.StateProofTracking.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.StateProofVerifier.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.StateSchema.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.TealKeyValue.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.TealValue.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.Transaction.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.TransactionApplication.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.TransactionAssetConfig.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.TransactionAssetFreeze.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.TransactionAssetTransfer.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.TransactionKeyreg.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.TransactionPayment.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.TransactionResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.TransactionSignature.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.TransactionSignatureLogicsig.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.TransactionSignatureMultisig.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.TransactionSignatureMultisigSubsignature.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.TransactionsResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:indexerModels.TransactionStateProof.md
│       │   │   │   │   ├── SDKs:javascript:classes:Kmd.md
│       │   │   │   │   ├── SDKs:javascript:classes:LogicSig.md
│       │   │   │   │   ├── SDKs:javascript:classes:LogicSigAccount.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.Account.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.AccountApplicationResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.AccountAssetHolding.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.AccountAssetResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.AccountAssetsInformationResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.AccountParticipation.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.AccountStateDelta.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.AppCallLogs.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.Application.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.ApplicationInitialStates.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.ApplicationKVStorage.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.ApplicationLocalReference.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.ApplicationLocalState.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.ApplicationParams.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.ApplicationStateOperation.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.ApplicationStateSchema.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.Asset.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.AssetHolding.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.AssetHoldingReference.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.AssetParams.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.AvmKeyValue.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.AvmValue.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.BlockHashResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.BlockLogsResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.BlockResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.BlockTxidsResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.Box.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.BoxDescriptor.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.BoxesResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.BoxReference.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.BuildVersion.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.CompileResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.DisassembleResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.DryrunRequest.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.DryrunResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.DryrunSource.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.DryrunState.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.DryrunTxnResult.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.ErrorResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.EvalDelta.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.EvalDeltaKeyValue.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.GetBlockTimeStampOffsetResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.GetSyncRoundResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.KvDelta.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.LedgerStateDeltaForTransactionGroup.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.LightBlockHeaderProof.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.NodeStatusResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.PendingTransactionResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.PendingTransactionsResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.PostTransactionsResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.ScratchChange.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.SimulateInitialStates.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.SimulateRequest.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.SimulateRequestTransactionGroup.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.SimulateResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.SimulateTraceConfig.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.SimulateTransactionGroupResult.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.SimulateTransactionResult.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.SimulateUnnamedResourcesAccessed.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.SimulationEvalOverrides.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.SimulationOpcodeTraceUnit.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.SimulationTransactionExecTrace.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.StateProof.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.StateProofMessage.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.SupplyResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.TealKeyValue.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.TealValue.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.TransactionGroupLedgerStateDeltasForRoundResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.TransactionParametersResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.TransactionProofResponse.md
│       │   │   │   │   ├── SDKs:javascript:classes:modelsv2.Version.md
│       │   │   │   │   ├── SDKs:javascript:classes:SourceMap.md
│       │   │   │   │   ├── SDKs:javascript:classes:Transaction.md
│       │   │   │   │   ├── SDKs:javascript:enums:ABIReferenceType.md
│       │   │   │   │   ├── SDKs:javascript:enums:ABITransactionType.md
│       │   │   │   │   ├── SDKs:javascript:enums:AtomicTransactionComposerStatus.md
│       │   │   │   │   ├── SDKs:javascript:enums:IntDecoding.md
│       │   │   │   │   ├── SDKs:javascript:enums:OnApplicationComplete.md
│       │   │   │   │   ├── SDKs:javascript:enums:TransactionType.md
│       │   │   │   │   ├── SDKs:javascript:examples:README.md
│       │   │   │   │   ├── SDKs:javascript:FAQ.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:ABIContractNetworkInfo.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:ABIContractNetworks.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:ABIContractParams.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:ABIInterfaceParams.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:ABIMethodArgParams.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:ABIMethodParams.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:ABIMethodReturnParams.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:ABIResult.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:Account.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:Address.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:AlgodTokenHeader.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:BaseHTTPClient.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:BaseHTTPClientError.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:BaseHTTPClientResponse.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:BoxReference.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:CustomTokenHeader.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:EncodedAssetParams.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:EncodedBoxReference.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:EncodedGlobalStateSchema.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:EncodedLocalStateSchema.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:EncodedLogicSig.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:EncodedLogicSigAccount.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:EncodedMultisig.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:EncodedSignedTransaction.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:EncodedSubsig.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:EncodedTransaction.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:IndexerTokenHeader.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:KMDTokenHeader.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:MultisigMetadata.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:SignedTransaction.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:SuggestedParams.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:TransactionParams.md
│       │   │   │   │   ├── SDKs:javascript:interfaces:TransactionWithSigner.md
│       │   │   │   │   ├── SDKs:javascript:modules:indexerModels.md
│       │   │   │   │   ├── SDKs:javascript:modules:modelsv2.md
│       │   │   │   │   ├── SDKs:javascript:modules.md
│       │   │   │   │   ├── SDKs:javascript:README.md
│       │   │   │   │   ├── SDKs:python:algosdk:v2client:harness:README.md
│       │   │   │   │   ├── SDKs:python:examples:README.md
│       │   │   │   │   ├── SDKs:python:README.md
│       │   │   │   │   ├── tealscript:examples_amm_README.md
│       │   │   │   │   ├── tealscript:examples_auction_README.md
│       │   │   │   │   ├── tealscript:examples_big_box_README.md
│       │   │   │   │   ├── tealscript:examples_itxns_README.md
│       │   │   │   │   ├── tealscript:examples_lsig_with_app_README.md
│       │   │   │   │   ├── tealscript:examples_reti_README.md
│       │   │   │   │   ├── tealscript:FEATURES.md
│       │   │   │   │   ├── tealscript:guides_atomic_txn.md
│       │   │   │   │   ├── tealscript:guides_features.md
│       │   │   │   │   ├── tealscript:guides_getting_started.md
│       │   │   │   │   ├── tealscript:guides_inner_transactions.md
│       │   │   │   │   ├── tealscript:guides_lifecycle.md
│       │   │   │   │   ├── tealscript:guides_math.md
│       │   │   │   │   ├── tealscript:guides_methods.md
│       │   │   │   │   ├── tealscript:guides_multiple_contracts.md
│       │   │   │   │   ├── tealscript:guides_pyteal.md
│       │   │   │   │   ├── tealscript:guides_storage.md
│       │   │   │   │   ├── tealscript:guides_Supported Types_arrays.md
│       │   │   │   │   ├── tealscript:guides_Supported Types_numbers.md
│       │   │   │   │   ├── TEALScript:README.md
│       │   │   │   │   ├── tealscript:tests_test_package_README.md
│       │   │   │   │   ├── tealscript:tutorials_Hello World_0001-intro.md
│       │   │   │   │   ├── tealscript:tutorials_Hello World_0002-init.md
│       │   │   │   │   ├── tealscript:tutorials_Hello World_0003-contract.md
│       │   │   │   │   ├── tealscript:tutorials_Hello World_0004-artifacts.md
│       │   │   │   │   ├── tealscript:tutorials_Hello World_0005-hello.md
│       │   │   │   │   └── tealscript:tutorials_Hello World_0006-test.md
│       │   │   │   └── taxonomy-categories
│       │   │   │       ├── algokit-utils.json
│       │   │   │       ├── algokit.json
│       │   │   │       ├── arcs.json
│       │   │   │       ├── clis.json
│       │   │   │       ├── details.json
│       │   │   │       ├── developers.json
│       │   │   │       ├── liquid-auth.json
│       │   │   │       ├── nodes.json
│       │   │   │       ├── puya.json
│       │   │   │       ├── python.json
│       │   │   │       ├── sdks.json
│       │   │   │       └── tealscript.json
│       │   │   └── wallet
│       │   │       └── index.ts
│       │   ├── tools
│       │   │   ├── accountManager.ts
│       │   │   ├── algodManager.ts
│       │   │   ├── apiManager
│       │   │   │   ├── algod
│       │   │   │   │   ├── account.ts
│       │   │   │   │   ├── application.ts
│       │   │   │   │   ├── asset.ts
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── transaction.ts
│       │   │   │   ├── example
│       │   │   │   │   ├── get-balance.ts
│       │   │   │   │   └── index.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── indexer
│       │   │   │   │   ├── account.ts
│       │   │   │   │   ├── application.ts
│       │   │   │   │   ├── asset.ts
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── transaction.ts
│       │   │   │   ├── nfd
│       │   │   │   │   └── index.ts
│       │   │   │   ├── tinyman
│       │   │   │   │   ├── analytics.ts
│       │   │   │   │   ├── bootstrap.ts
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── liquidity.ts
│       │   │   │   │   ├── opt_in.ts
│       │   │   │   │   ├── pool.ts
│       │   │   │   │   ├── remove_liquidity.ts
│       │   │   │   │   └── swap.ts
│       │   │   │   ├── ultrade
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── market.ts
│       │   │   │   │   ├── system.ts
│       │   │   │   │   └── wallet.ts
│       │   │   │   └── vestige
│       │   │   │       ├── assets.ts
│       │   │   │       ├── balances.ts
│       │   │   │       ├── index.ts
│       │   │   │       ├── networks.ts
│       │   │   │       ├── notes.ts
│       │   │   │       ├── pools.ts
│       │   │   │       ├── protocols.ts
│       │   │   │       ├── swaps.ts
│       │   │   │       └── vaults.ts
│       │   │   ├── arc26Manager.ts
│       │   │   ├── index.ts
│       │   │   ├── knowledgeManager.ts
│       │   │   ├── transactionManager
│       │   │   │   ├── accountTransactions.ts
│       │   │   │   ├── appTransactions
│       │   │   │   │   ├── callTxn.ts
│       │   │   │   │   ├── clearTxn.ts
│       │   │   │   │   ├── closeOutTxn.ts
│       │   │   │   │   ├── createTxn.ts
│       │   │   │   │   ├── deleteTxn.ts
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── optInTxn.ts
│       │   │   │   │   ├── test
│       │   │   │   │   │   ├── counter_approval.teal
│       │   │   │   │   │   ├── counter_clear.teal
│       │   │   │   │   │   ├── storage_test_approval_v2.teal
│       │   │   │   │   │   ├── storage_test_approval.teal
│       │   │   │   │   │   └── storage_test_clear.teal
│       │   │   │   │   ├── types.ts
│       │   │   │   │   └── updateTxn.ts
│       │   │   │   ├── assetTransactions.ts
│       │   │   │   ├── generalTransaction.ts
│       │   │   │   └── index.ts
│       │   │   └── utilityManager.ts
│       │   ├── types.ts
│       │   └── utils
│       │       └── responseProcessor.ts
│       ├── tests
│       │   ├── resources
│       │   │   ├── algod
│       │   │   │   ├── account.test.ts
│       │   │   │   ├── application.test.ts
│       │   │   │   ├── asset.test.ts
│       │   │   │   └── transaction.test.ts
│       │   │   └── indexer
│       │   │       ├── account.test.ts
│       │   │       ├── application.test.ts
│       │   │       ├── asset.test.ts
│       │   │       └── transaction.test.ts
│       │   └── tools
│       │       ├── accountManager.test.ts
│       │       ├── algodManager.test.ts
│       │       ├── apiManager
│       │       │   └── example
│       │       │       └── get-balance.test.ts
│       │       ├── transactionManager
│       │       │   ├── accountTransactionManager.test.ts
│       │       │   ├── appTransactionManager.test.ts
│       │       │   ├── assetTransactionManager.test.ts
│       │       │   ├── generalTransactionManager.test.ts
│       │       │   └── transactionManager.test.ts
│       │       └── utilityManager.test.ts
│       └── tsconfig.json
├── README.md
├── rename_files.sh
└── tsconfig.json
```

# Files

--------------------------------------------------------------------------------
/packages/server/tests/resources/indexer/transaction.test.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
  2 | import { 
  3 |   transactionResources,
  4 |   transactionResourceSchemas,
  5 |   lookupTransactionByID,
  6 |   lookupAccountTransactions,
  7 |   searchForTransactions,
  8 |   handleTransactionResources
  9 | } from '../../../src/resources/indexer/transaction.js';
 10 | import { indexerClient } from '../../../src/algorand-client.js';
 11 | 
 12 | // Mock algosdk client
 13 | jest.mock('../../../src/algorand-client.js', () => ({
 14 |   indexerClient: {
 15 |     lookupTransactionByID: jest.fn(),
 16 |     lookupAccountTransactions: jest.fn(),
 17 |     searchForTransactions: jest.fn()
 18 |   },
 19 |   API_URIS: {
 20 |     TRANSACTION_DETAILS: 'algorand://transaction/{txid}',
 21 |     TRANSACTION_SEARCH: 'algorand://transactions/search'
 22 |   }
 23 | }));
 24 | 
 25 | describe('Indexer Transaction Resources', () => {
 26 |   beforeEach(() => {
 27 |     jest.clearAllMocks();
 28 |   });
 29 | 
 30 |   describe('Resource Definitions', () => {
 31 |     it('should define transaction resources', () => {
 32 |       expect(transactionResources).toHaveLength(2);
 33 |       expect(transactionResources.map(r => r.name)).toEqual([
 34 |         'Transaction Details',
 35 |         'Search Transactions'
 36 |       ]);
 37 |     });
 38 | 
 39 |     it('should define resource schemas', () => {
 40 |       expect(Object.keys(transactionResourceSchemas)).toHaveLength(2);
 41 |       expect(transactionResourceSchemas).toHaveProperty('algorand://transaction/{txid}');
 42 |       expect(transactionResourceSchemas).toHaveProperty('algorand://transactions/search');
 43 |     });
 44 |   });
 45 | 
 46 |   describe('Transaction Information', () => {
 47 |     const mockTxId = 'MOCK_TX_ID';
 48 |     const mockResponse = {
 49 |       transaction: {
 50 |         id: mockTxId,
 51 |         type: 'pay',
 52 |         sender: 'MOCK_SENDER',
 53 |         receiver: 'MOCK_RECEIVER',
 54 |         amount: 1000
 55 |       },
 56 |       currentRound: 1234
 57 |     };
 58 | 
 59 |     beforeEach(() => {
 60 |       (indexerClient.lookupTransactionByID as jest.Mock).mockReturnValue({
 61 |         do: jest.fn().mockResolvedValue(mockResponse)
 62 |       });
 63 |     });
 64 | 
 65 |     it('should fetch transaction information', async () => {
 66 |       const result = await lookupTransactionByID(mockTxId);
 67 |       expect(result).toEqual(mockResponse);
 68 |       expect(indexerClient.lookupTransactionByID).toHaveBeenCalledWith(mockTxId);
 69 |     });
 70 | 
 71 |     it('should handle errors', async () => {
 72 |       const error = new Error('Network error');
 73 |       (indexerClient.lookupTransactionByID as jest.Mock).mockReturnValue({
 74 |         do: jest.fn().mockRejectedValue(error)
 75 |       });
 76 | 
 77 |       await expect(lookupTransactionByID(mockTxId))
 78 |         .rejects
 79 |         .toThrow('Failed to get transaction: Network error');
 80 |     });
 81 |   });
 82 | 
 83 |   describe('Account Transactions', () => {
 84 |     const mockAddress = 'MOCK_ADDRESS';
 85 |     const mockResponse = {
 86 |       transactions: [{ id: 'txn1', type: 'pay' }],
 87 |       currentRound: 1234
 88 |     };
 89 | 
 90 |     beforeEach(() => {
 91 |       (indexerClient.lookupAccountTransactions as jest.Mock).mockReturnValue({
 92 |         limit: jest.fn().mockReturnThis(),
 93 |         beforeTime: jest.fn().mockReturnThis(),
 94 |         afterTime: jest.fn().mockReturnThis(),
 95 |         minRound: jest.fn().mockReturnThis(),
 96 |         maxRound: jest.fn().mockReturnThis(),
 97 |         txType: jest.fn().mockReturnThis(),
 98 |         assetID: jest.fn().mockReturnThis(),
 99 |         do: jest.fn().mockResolvedValue(mockResponse)
100 |       });
101 |     });
102 | 
103 |     it('should fetch account transactions', async () => {
104 |       const result = await lookupAccountTransactions(mockAddress);
105 |       expect(result).toEqual(mockResponse);
106 |       expect(indexerClient.lookupAccountTransactions).toHaveBeenCalledWith(mockAddress);
107 |     });
108 | 
109 |     it('should handle search parameters', async () => {
110 |       const params = {
111 |         limit: 10,
112 |         beforeTime: '2023-01-01',
113 |         afterTime: '2022-01-01',
114 |         minRound: 1000,
115 |         maxRound: 2000,
116 |         txType: 'pay',
117 |         assetId: 123
118 |       };
119 | 
120 |       await lookupAccountTransactions(mockAddress, params);
121 |       const mock = indexerClient.lookupAccountTransactions as jest.Mock;
122 |       const chain = mock.mock.results[0].value;
123 | 
124 |       expect(chain.limit).toHaveBeenCalledWith(params.limit);
125 |       expect(chain.beforeTime).toHaveBeenCalledWith(params.beforeTime);
126 |       expect(chain.afterTime).toHaveBeenCalledWith(params.afterTime);
127 |       expect(chain.minRound).toHaveBeenCalledWith(params.minRound);
128 |       expect(chain.maxRound).toHaveBeenCalledWith(params.maxRound);
129 |       expect(chain.txType).toHaveBeenCalledWith(params.txType);
130 |       expect(chain.assetID).toHaveBeenCalledWith(params.assetId);
131 |     });
132 | 
133 |     it('should handle errors', async () => {
134 |       const error = new Error('Network error');
135 |       (indexerClient.lookupAccountTransactions as jest.Mock).mockReturnValue({
136 |         do: jest.fn().mockRejectedValue(error)
137 |       });
138 | 
139 |       await expect(lookupAccountTransactions(mockAddress))
140 |         .rejects
141 |         .toThrow('Failed to get account transactions: Network error');
142 |     });
143 |   });
144 | 
145 |   describe('Search Transactions', () => {
146 |     const mockResponse = {
147 |       transactions: [{ id: 'txn1', type: 'pay' }],
148 |       currentRound: 1234
149 |     };
150 | 
151 |     beforeEach(() => {
152 |       (indexerClient.searchForTransactions as jest.Mock).mockReturnValue({
153 |         limit: jest.fn().mockReturnThis(),
154 |         beforeTime: jest.fn().mockReturnThis(),
155 |         afterTime: jest.fn().mockReturnThis(),
156 |         minRound: jest.fn().mockReturnThis(),
157 |         maxRound: jest.fn().mockReturnThis(),
158 |         address: jest.fn().mockReturnThis(),
159 |         addressRole: jest.fn().mockReturnThis(),
160 |         txType: jest.fn().mockReturnThis(),
161 |         assetID: jest.fn().mockReturnThis(),
162 |         applicationID: jest.fn().mockReturnThis(),
163 |         currencyGreaterThan: jest.fn().mockReturnThis(),
164 |         currencyLessThan: jest.fn().mockReturnThis(),
165 |         round: jest.fn().mockReturnThis(),
166 |         nextToken: jest.fn().mockReturnThis(),
167 |         do: jest.fn().mockResolvedValue(mockResponse)
168 |       });
169 |     });
170 | 
171 |     it('should search transactions', async () => {
172 |       const result = await searchForTransactions();
173 |       expect(result).toEqual(mockResponse);
174 |       expect(indexerClient.searchForTransactions).toHaveBeenCalled();
175 |     });
176 | 
177 |     it('should handle search parameters', async () => {
178 |       const params = {
179 |         limit: 10,
180 |         beforeTime: '2023-01-01',
181 |         afterTime: '2022-01-01',
182 |         minRound: 1000,
183 |         maxRound: 2000,
184 |         address: 'addr1',
185 |         addressRole: 'sender',
186 |         txType: 'pay',
187 |         assetId: 123,
188 |         applicationId: 456,
189 |         currencyGreaterThan: 1000,
190 |         currencyLessThan: 2000,
191 |         round: 1234,
192 |         nextToken: 'token123'
193 |       };
194 | 
195 |       await searchForTransactions(params);
196 |       const mock = indexerClient.searchForTransactions as jest.Mock;
197 |       const chain = mock.mock.results[0].value;
198 | 
199 |       expect(chain.limit).toHaveBeenCalledWith(params.limit);
200 |       expect(chain.beforeTime).toHaveBeenCalledWith(params.beforeTime);
201 |       expect(chain.afterTime).toHaveBeenCalledWith(params.afterTime);
202 |       expect(chain.minRound).toHaveBeenCalledWith(params.minRound);
203 |       expect(chain.maxRound).toHaveBeenCalledWith(params.maxRound);
204 |       expect(chain.address).toHaveBeenCalledWith(params.address);
205 |       expect(chain.addressRole).toHaveBeenCalledWith(params.addressRole);
206 |       expect(chain.txType).toHaveBeenCalledWith(params.txType);
207 |       expect(chain.assetID).toHaveBeenCalledWith(params.assetId);
208 |       expect(chain.applicationID).toHaveBeenCalledWith(params.applicationId);
209 |       expect(chain.currencyGreaterThan).toHaveBeenCalledWith(params.currencyGreaterThan);
210 |       expect(chain.currencyLessThan).toHaveBeenCalledWith(params.currencyLessThan);
211 |       expect(chain.round).toHaveBeenCalledWith(params.round);
212 |       expect(chain.nextToken).toHaveBeenCalledWith(params.nextToken);
213 |     });
214 | 
215 |     it('should handle errors', async () => {
216 |       const error = new Error('Network error');
217 |       (indexerClient.searchForTransactions as jest.Mock).mockReturnValue({
218 |         do: jest.fn().mockRejectedValue(error)
219 |       });
220 | 
221 |       await expect(searchForTransactions())
222 |         .rejects
223 |         .toThrow('Failed to search transactions: Network error');
224 |     });
225 |   });
226 | 
227 |   describe('Resource Handler', () => {
228 |     const mockTxId = 'MOCK_TX_ID';
229 | 
230 |     beforeEach(() => {
231 |       (indexerClient.lookupTransactionByID as jest.Mock).mockReturnValue({
232 |         do: jest.fn().mockResolvedValue({
233 |           transaction: { id: mockTxId },
234 |           currentRound: 1234
235 |         })
236 |       });
237 |       (indexerClient.searchForTransactions as jest.Mock).mockReturnValue({
238 |         do: jest.fn().mockResolvedValue({
239 |           transactions: [{ id: 'txn1' }],
240 |           currentRound: 1234
241 |         })
242 |       });
243 |     });
244 | 
245 |     it('should handle transaction details URI', async () => {
246 |       const uri = `algorand://transaction/${mockTxId}`;
247 |       const result = await handleTransactionResources(uri);
248 |       expect(result).toHaveLength(1);
249 |       expect(JSON.parse(result[0].text)).toHaveProperty('transaction');
250 |       expect(JSON.parse(result[0].text)).toHaveProperty('currentRound');
251 |     });
252 | 
253 |     it('should handle transaction search URI', async () => {
254 |       const uri = 'algorand://transactions/search';
255 |       const result = await handleTransactionResources(uri);
256 |       expect(result).toHaveLength(1);
257 |       expect(JSON.parse(result[0].text)).toHaveProperty('transactions');
258 |       expect(JSON.parse(result[0].text)).toHaveProperty('currentRound');
259 |     });
260 | 
261 |     it('should return empty array for unknown URI', async () => {
262 |       const uri = 'algorand://unknown';
263 |       const result = await handleTransactionResources(uri);
264 |       expect(result).toHaveLength(0);
265 |     });
266 | 
267 |     it('should handle errors with McpError', async () => {
268 |       const error = new Error('Network error');
269 |       (indexerClient.lookupTransactionByID as jest.Mock).mockReturnValue({
270 |         do: jest.fn().mockRejectedValue(error)
271 |       });
272 | 
273 |       const uri = `algorand://transaction/${mockTxId}`;
274 |       await expect(handleTransactionResources(uri))
275 |         .rejects
276 |         .toThrow(new McpError(ErrorCode.InternalError, 'Network error'));
277 |     });
278 |   });
279 | });
280 | 
```

--------------------------------------------------------------------------------
/packages/server/tests/resources/indexer/account.test.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
  2 | import { 
  3 |   accountResources,
  4 |   accountResourceSchemas,
  5 |   lookupAccountByID,
  6 |   lookupAccountTransactions,
  7 |   lookupAccountAssets,
  8 |   searchAccounts,
  9 |   handleAccountResources
 10 | } from '../../../src/resources/indexer/account.js';
 11 | import { indexerClient } from '../../../src/algorand-client.js';
 12 | 
 13 | // Mock algosdk client
 14 | jest.mock('../../../src/algorand-client.js', () => ({
 15 |   indexerClient: {
 16 |     lookupAccountByID: jest.fn(),
 17 |     lookupAccountTransactions: jest.fn(),
 18 |     lookupAccountAssets: jest.fn(),
 19 |     searchAccounts: jest.fn()
 20 |   },
 21 |   API_URIS: {
 22 |     TRANSACTION_HISTORY: 'algorand://account/{address}/transactions',
 23 |     ASSET_HOLDINGS: 'algorand://account/{address}/assets'
 24 |   }
 25 | }));
 26 | 
 27 | describe('Indexer Account Resources', () => {
 28 |   beforeEach(() => {
 29 |     jest.clearAllMocks();
 30 |   });
 31 | 
 32 |   describe('Resource Definitions', () => {
 33 |     it('should define account resources', () => {
 34 |       expect(accountResources).toHaveLength(2);
 35 |       expect(accountResources.map(r => r.name)).toEqual([
 36 |         'Transaction History',
 37 |         'Asset Holdings'
 38 |       ]);
 39 |     });
 40 | 
 41 |     it('should define resource schemas', () => {
 42 |       expect(Object.keys(accountResourceSchemas)).toHaveLength(2);
 43 |       expect(accountResourceSchemas).toHaveProperty('algorand://account/{address}/transactions');
 44 |       expect(accountResourceSchemas).toHaveProperty('algorand://account/{address}/assets');
 45 |     });
 46 |   });
 47 | 
 48 |   describe('Account Information', () => {
 49 |     const mockAddress = 'MOCK_ADDRESS';
 50 |     const mockResponse = {
 51 |       account: {
 52 |         address: mockAddress,
 53 |         amount: 1000000,
 54 |         assets: []
 55 |       },
 56 |       currentRound: 1234
 57 |     };
 58 | 
 59 |     beforeEach(() => {
 60 |       (indexerClient.lookupAccountByID as jest.Mock).mockReturnValue({
 61 |         do: jest.fn().mockResolvedValue(mockResponse)
 62 |       });
 63 |     });
 64 | 
 65 |     it('should fetch account information', async () => {
 66 |       const result = await lookupAccountByID(mockAddress);
 67 |       expect(result).toEqual(mockResponse);
 68 |       expect(indexerClient.lookupAccountByID).toHaveBeenCalledWith(mockAddress);
 69 |     });
 70 | 
 71 |     it('should handle errors', async () => {
 72 |       const error = new Error('Network error');
 73 |       (indexerClient.lookupAccountByID as jest.Mock).mockReturnValue({
 74 |         do: jest.fn().mockRejectedValue(error)
 75 |       });
 76 | 
 77 |       await expect(lookupAccountByID(mockAddress))
 78 |         .rejects
 79 |         .toThrow('Failed to get account info: Network error');
 80 |     });
 81 |   });
 82 | 
 83 |   describe('Account Transactions', () => {
 84 |     const mockAddress = 'MOCK_ADDRESS';
 85 |     const mockResponse = {
 86 |       transactions: [{ id: 'txn1' }],
 87 |       currentRound: 1234
 88 |     };
 89 | 
 90 |     beforeEach(() => {
 91 |       (indexerClient.lookupAccountTransactions as jest.Mock).mockReturnValue({
 92 |         limit: jest.fn().mockReturnThis(),
 93 |         beforeTime: jest.fn().mockReturnThis(),
 94 |         afterTime: jest.fn().mockReturnThis(),
 95 |         nextToken: jest.fn().mockReturnThis(),
 96 |         do: jest.fn().mockResolvedValue(mockResponse)
 97 |       });
 98 |     });
 99 | 
100 |     it('should fetch account transactions', async () => {
101 |       const result = await lookupAccountTransactions(mockAddress);
102 |       expect(result).toEqual(mockResponse);
103 |       expect(indexerClient.lookupAccountTransactions).toHaveBeenCalledWith(mockAddress);
104 |     });
105 | 
106 |     it('should handle search parameters', async () => {
107 |       const params = {
108 |         limit: 10,
109 |         beforeTime: '2023-01-01',
110 |         afterTime: '2022-01-01',
111 |         nextToken: 'token123'
112 |       };
113 | 
114 |       await lookupAccountTransactions(mockAddress, params);
115 |       const mock = indexerClient.lookupAccountTransactions as jest.Mock;
116 |       const chain = mock.mock.results[0].value;
117 | 
118 |       expect(chain.limit).toHaveBeenCalledWith(params.limit);
119 |       expect(chain.beforeTime).toHaveBeenCalledWith(params.beforeTime);
120 |       expect(chain.afterTime).toHaveBeenCalledWith(params.afterTime);
121 |       expect(chain.nextToken).toHaveBeenCalledWith(params.nextToken);
122 |     });
123 | 
124 |     it('should handle errors', async () => {
125 |       const error = new Error('Network error');
126 |       (indexerClient.lookupAccountTransactions as jest.Mock).mockReturnValue({
127 |         do: jest.fn().mockRejectedValue(error)
128 |       });
129 | 
130 |       await expect(lookupAccountTransactions(mockAddress))
131 |         .rejects
132 |         .toThrow('Failed to get account transactions: Network error');
133 |     });
134 |   });
135 | 
136 |   describe('Account Assets', () => {
137 |     const mockAddress = 'MOCK_ADDRESS';
138 |     const mockResponse = {
139 |       assets: [{ assetId: 1, amount: 100 }],
140 |       currentRound: 1234
141 |     };
142 | 
143 |     beforeEach(() => {
144 |       (indexerClient.lookupAccountAssets as jest.Mock).mockReturnValue({
145 |         limit: jest.fn().mockReturnThis(),
146 |         assetId: jest.fn().mockReturnThis(),
147 |         nextToken: jest.fn().mockReturnThis(),
148 |         do: jest.fn().mockResolvedValue(mockResponse)
149 |       });
150 |     });
151 | 
152 |     it('should fetch account assets', async () => {
153 |       const result = await lookupAccountAssets(mockAddress);
154 |       expect(result).toEqual(mockResponse);
155 |       expect(indexerClient.lookupAccountAssets).toHaveBeenCalledWith(mockAddress);
156 |     });
157 | 
158 |     it('should handle search parameters', async () => {
159 |       const params = {
160 |         limit: 10,
161 |         assetId: 123,
162 |         nextToken: 'token123'
163 |       };
164 | 
165 |       await lookupAccountAssets(mockAddress, params);
166 |       const mock = indexerClient.lookupAccountAssets as jest.Mock;
167 |       const chain = mock.mock.results[0].value;
168 | 
169 |       expect(chain.limit).toHaveBeenCalledWith(params.limit);
170 |       expect(chain.assetId).toHaveBeenCalledWith(params.assetId);
171 |       expect(chain.nextToken).toHaveBeenCalledWith(params.nextToken);
172 |     });
173 | 
174 |     it('should handle errors', async () => {
175 |       const error = new Error('Network error');
176 |       (indexerClient.lookupAccountAssets as jest.Mock).mockReturnValue({
177 |         do: jest.fn().mockRejectedValue(error)
178 |       });
179 | 
180 |       await expect(lookupAccountAssets(mockAddress))
181 |         .rejects
182 |         .toThrow('Failed to get account assets: Network error');
183 |     });
184 |   });
185 | 
186 |   describe('Search Accounts', () => {
187 |     const mockResponse = {
188 |       accounts: [{ address: 'addr1' }],
189 |       currentRound: 1234
190 |     };
191 | 
192 |     beforeEach(() => {
193 |       (indexerClient.searchAccounts as jest.Mock).mockReturnValue({
194 |         limit: jest.fn().mockReturnThis(),
195 |         assetID: jest.fn().mockReturnThis(),
196 |         applicationID: jest.fn().mockReturnThis(),
197 |         currencyGreaterThan: jest.fn().mockReturnThis(),
198 |         currencyLessThan: jest.fn().mockReturnThis(),
199 |         nextToken: jest.fn().mockReturnThis(),
200 |         do: jest.fn().mockResolvedValue(mockResponse)
201 |       });
202 |     });
203 | 
204 |     it('should search accounts', async () => {
205 |       const result = await searchAccounts();
206 |       expect(result).toEqual(mockResponse);
207 |       expect(indexerClient.searchAccounts).toHaveBeenCalled();
208 |     });
209 | 
210 |     it('should handle search parameters', async () => {
211 |       const params = {
212 |         limit: 10,
213 |         assetId: 123,
214 |         applicationId: 456,
215 |         currencyGreaterThan: 1000,
216 |         currencyLessThan: 2000,
217 |         nextToken: 'token123'
218 |       };
219 | 
220 |       await searchAccounts(params);
221 |       const mock = indexerClient.searchAccounts as jest.Mock;
222 |       const chain = mock.mock.results[0].value;
223 | 
224 |       expect(chain.limit).toHaveBeenCalledWith(params.limit);
225 |       expect(chain.assetID).toHaveBeenCalledWith(params.assetId);
226 |       expect(chain.applicationID).toHaveBeenCalledWith(params.applicationId);
227 |       expect(chain.currencyGreaterThan).toHaveBeenCalledWith(params.currencyGreaterThan);
228 |       expect(chain.currencyLessThan).toHaveBeenCalledWith(params.currencyLessThan);
229 |       expect(chain.nextToken).toHaveBeenCalledWith(params.nextToken);
230 |     });
231 | 
232 |     it('should handle errors', async () => {
233 |       const error = new Error('Network error');
234 |       (indexerClient.searchAccounts as jest.Mock).mockReturnValue({
235 |         do: jest.fn().mockRejectedValue(error)
236 |       });
237 | 
238 |       await expect(searchAccounts())
239 |         .rejects
240 |         .toThrow('Failed to search accounts: Network error');
241 |     });
242 |   });
243 | 
244 |   describe('Resource Handler', () => {
245 |     const mockAddress = 'MOCK_ADDRESS';
246 | 
247 |     beforeEach(() => {
248 |       (indexerClient.lookupAccountTransactions as jest.Mock).mockReturnValue({
249 |         do: jest.fn().mockResolvedValue({
250 |           transactions: [],
251 |           currentRound: 1234
252 |         })
253 |       });
254 |       (indexerClient.lookupAccountAssets as jest.Mock).mockReturnValue({
255 |         do: jest.fn().mockResolvedValue({
256 |           assets: [],
257 |           currentRound: 1234
258 |         })
259 |       });
260 |     });
261 | 
262 |     it('should handle transaction history URI', async () => {
263 |       const uri = `algorand://account/${mockAddress}/transactions`;
264 |       const result = await handleAccountResources(uri);
265 |       expect(result).toHaveLength(1);
266 |       expect(JSON.parse(result[0].text)).toHaveProperty('transactions');
267 |       expect(JSON.parse(result[0].text)).toHaveProperty('currentRound');
268 |     });
269 | 
270 |     it('should handle asset holdings URI', async () => {
271 |       const uri = `algorand://account/${mockAddress}/assets`;
272 |       const result = await handleAccountResources(uri);
273 |       expect(result).toHaveLength(1);
274 |       expect(JSON.parse(result[0].text)).toHaveProperty('assets');
275 |       expect(JSON.parse(result[0].text)).toHaveProperty('currentRound');
276 |     });
277 | 
278 |     it('should return empty array for unknown URI', async () => {
279 |       const uri = 'algorand://unknown';
280 |       const result = await handleAccountResources(uri);
281 |       expect(result).toHaveLength(0);
282 |     });
283 | 
284 |     it('should handle errors with McpError', async () => {
285 |       const error = new Error('Network error');
286 |       (indexerClient.lookupAccountTransactions as jest.Mock).mockReturnValue({
287 |         do: jest.fn().mockRejectedValue(error)
288 |       });
289 | 
290 |       const uri = `algorand://account/${mockAddress}/transactions`;
291 |       await expect(handleAccountResources(uri))
292 |         .rejects
293 |         .toThrow(new McpError(ErrorCode.InternalError, 'Failed to get transaction history: Network error'));
294 |     });
295 |   });
296 | });
297 | 
```

--------------------------------------------------------------------------------
/packages/server/tests/tools/transactionManager/assetTransactionManager.test.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
  2 | import { AssetTransactionManager, assetTransactionTools } from '../../../src/tools/transactionManager/assetTransactions.js';
  3 | import { algodClient } from '../../../src/algorand-client.js';
  4 | import algosdk from 'algosdk';
  5 | 
  6 | // Mock algosdk
  7 | jest.mock('algosdk', () => ({
  8 |   makeAssetCreateTxnWithSuggestedParamsFromObject: jest.fn(),
  9 |   makeAssetConfigTxnWithSuggestedParamsFromObject: jest.fn(),
 10 |   makeAssetDestroyTxnWithSuggestedParamsFromObject: jest.fn(),
 11 |   makeAssetFreezeTxnWithSuggestedParamsFromObject: jest.fn(),
 12 |   makeAssetTransferTxnWithSuggestedParamsFromObject: jest.fn(),
 13 | }));
 14 | 
 15 | // Mock algodClient
 16 | jest.mock('../../../src/algorand-client.js', () => ({
 17 |   algodClient: {
 18 |     getTransactionParams: jest.fn().mockReturnValue({
 19 |       do: jest.fn().mockResolvedValue({
 20 |         firstRound: 1000,
 21 |         lastRound: 2000,
 22 |         genesisHash: 'hash',
 23 |         genesisID: 'testnet-v1.0',
 24 |         fee: 1000,
 25 |         flatFee: true,
 26 |       }),
 27 |     }),
 28 |   },
 29 | }));
 30 | 
 31 | describe('AssetTransactionManager', () => {
 32 |   const mockSuggestedParams = {
 33 |     firstRound: 1000,
 34 |     lastRound: 2000,
 35 |     genesisHash: 'hash',
 36 |     genesisID: 'testnet-v1.0',
 37 |     fee: 1000,
 38 |     flatFee: true,
 39 |   };
 40 | 
 41 |   beforeEach(() => {
 42 |     jest.clearAllMocks();
 43 |     (algodClient.getTransactionParams as jest.Mock)().do.mockResolvedValue(mockSuggestedParams);
 44 |   });
 45 | 
 46 |   describe('Tool Schemas', () => {
 47 |     it('should have valid tool schemas', () => {
 48 |       expect(assetTransactionTools).toHaveLength(5);
 49 |       expect(assetTransactionTools.map((t: { name: string }) => t.name)).toEqual([
 50 |         'make_asset_create_txn',
 51 |         'make_asset_config_txn',
 52 |         'make_asset_destroy_txn',
 53 |         'make_asset_freeze_txn',
 54 |         'make_asset_transfer_txn',
 55 |       ]);
 56 |     });
 57 |   });
 58 | 
 59 |   describe('Asset Creation', () => {
 60 |     const mockAssetCreateTxn = { type: 'acfg', from: 'sender' };
 61 | 
 62 |     beforeEach(() => {
 63 |       (algosdk.makeAssetCreateTxnWithSuggestedParamsFromObject as jest.Mock).mockReturnValue(mockAssetCreateTxn);
 64 |     });
 65 | 
 66 |     it('should create a basic asset creation transaction', async () => {
 67 |       const args = {
 68 |         from: 'sender',
 69 |         total: 1000000,
 70 |         decimals: 6,
 71 |         defaultFrozen: false,
 72 |       };
 73 | 
 74 |       const result = await AssetTransactionManager.handleTool('make_asset_create_txn', args);
 75 | 
 76 |       expect(result).toEqual({
 77 |         content: [{
 78 |           type: 'text',
 79 |           text: JSON.stringify(mockAssetCreateTxn, null, 2),
 80 |         }],
 81 |       });
 82 | 
 83 |       expect(algosdk.makeAssetCreateTxnWithSuggestedParamsFromObject).toHaveBeenCalledWith(
 84 |         expect.objectContaining({
 85 |           from: 'sender',
 86 |           total: 1000000,
 87 |           decimals: 6,
 88 |           defaultFrozen: false,
 89 |           suggestedParams: expect.objectContaining(mockSuggestedParams),
 90 |         })
 91 |       );
 92 |     });
 93 | 
 94 |     it('should create an asset with optional parameters', async () => {
 95 |       const args = {
 96 |         from: 'sender',
 97 |         total: 1000000,
 98 |         decimals: 6,
 99 |         defaultFrozen: false,
100 |         unitName: 'TEST',
101 |         assetName: 'Test Asset',
102 |         assetURL: 'https://test.com',
103 |         assetMetadataHash: 'hash',
104 |         manager: 'manager-addr',
105 |         reserve: 'reserve-addr',
106 |         freeze: 'freeze-addr',
107 |         clawback: 'clawback-addr',
108 |         note: 'test note',
109 |         rekeyTo: 'rekey-addr',
110 |       };
111 | 
112 |       const result = await AssetTransactionManager.handleTool('make_asset_create_txn', args);
113 | 
114 |       expect(algosdk.makeAssetCreateTxnWithSuggestedParamsFromObject).toHaveBeenCalledWith(
115 |         expect.objectContaining({
116 |           ...args,
117 |           note: new TextEncoder().encode(args.note),
118 |           suggestedParams: expect.any(Object)
119 |         })
120 |       );
121 |     });
122 |   });
123 | 
124 |   describe('Asset Configuration', () => {
125 |     const mockAssetConfigTxn = { type: 'acfg', from: 'sender' };
126 | 
127 |     beforeEach(() => {
128 |       (algosdk.makeAssetConfigTxnWithSuggestedParamsFromObject as jest.Mock).mockReturnValue(mockAssetConfigTxn);
129 |     });
130 | 
131 |     it('should create an asset configuration transaction', async () => {
132 |       const args = {
133 |         from: 'sender',
134 |         assetIndex: 123,
135 |         strictEmptyAddressChecking: true,
136 |         manager: 'new-manager',
137 |       };
138 | 
139 |       const result = await AssetTransactionManager.handleTool('make_asset_config_txn', args);
140 | 
141 |       expect(result).toEqual({
142 |         content: [{
143 |           type: 'text',
144 |           text: JSON.stringify(mockAssetConfigTxn, null, 2),
145 |         }],
146 |       });
147 | 
148 |       expect(algosdk.makeAssetConfigTxnWithSuggestedParamsFromObject).toHaveBeenCalledWith(
149 |         expect.objectContaining(args)
150 |       );
151 |     });
152 |   });
153 | 
154 |   describe('Asset Destruction', () => {
155 |     const mockAssetDestroyTxn = { type: 'acfg', from: 'sender' };
156 | 
157 |     beforeEach(() => {
158 |       (algosdk.makeAssetDestroyTxnWithSuggestedParamsFromObject as jest.Mock).mockReturnValue(mockAssetDestroyTxn);
159 |     });
160 | 
161 |     it('should create an asset destroy transaction', async () => {
162 |       const args = {
163 |         from: 'sender',
164 |         assetIndex: 123,
165 |       };
166 | 
167 |       const result = await AssetTransactionManager.handleTool('make_asset_destroy_txn', args);
168 | 
169 |       expect(result).toEqual({
170 |         content: [{
171 |           type: 'text',
172 |           text: JSON.stringify(mockAssetDestroyTxn, null, 2),
173 |         }],
174 |       });
175 | 
176 |       expect(algosdk.makeAssetDestroyTxnWithSuggestedParamsFromObject).toHaveBeenCalledWith(
177 |         expect.objectContaining(args)
178 |       );
179 |     });
180 |   });
181 | 
182 |   describe('Asset Freeze', () => {
183 |     const mockAssetFreezeTxn = { type: 'afrz', from: 'sender' };
184 | 
185 |     beforeEach(() => {
186 |       (algosdk.makeAssetFreezeTxnWithSuggestedParamsFromObject as jest.Mock).mockReturnValue(mockAssetFreezeTxn);
187 |     });
188 | 
189 |     it('should create an asset freeze transaction', async () => {
190 |       const args = {
191 |         from: 'sender',
192 |         assetIndex: 123,
193 |         freezeTarget: 'target-addr',
194 |         freezeState: true,
195 |       };
196 | 
197 |       const result = await AssetTransactionManager.handleTool('make_asset_freeze_txn', args);
198 | 
199 |       expect(result).toEqual({
200 |         content: [{
201 |           type: 'text',
202 |           text: JSON.stringify(mockAssetFreezeTxn, null, 2),
203 |         }],
204 |       });
205 | 
206 |       expect(algosdk.makeAssetFreezeTxnWithSuggestedParamsFromObject).toHaveBeenCalledWith(
207 |         expect.objectContaining(args)
208 |       );
209 |     });
210 |   });
211 | 
212 |   describe('Asset Transfer', () => {
213 |     const mockAssetTransferTxn = { type: 'axfer', from: 'sender' };
214 | 
215 |     beforeEach(() => {
216 |       (algosdk.makeAssetTransferTxnWithSuggestedParamsFromObject as jest.Mock).mockReturnValue(mockAssetTransferTxn);
217 |     });
218 | 
219 |     it('should create an asset transfer transaction', async () => {
220 |       const args = {
221 |         from: 'sender',
222 |         to: 'receiver',
223 |         assetIndex: 123,
224 |         amount: 1000,
225 |       };
226 | 
227 |       const result = await AssetTransactionManager.handleTool('make_asset_transfer_txn', args);
228 | 
229 |       expect(result).toEqual({
230 |         content: [{
231 |           type: 'text',
232 |           text: JSON.stringify(mockAssetTransferTxn, null, 2),
233 |         }],
234 |       });
235 | 
236 |       expect(algosdk.makeAssetTransferTxnWithSuggestedParamsFromObject).toHaveBeenCalledWith(
237 |         expect.objectContaining(args)
238 |       );
239 |     });
240 | 
241 |     it('should create an asset transfer with optional parameters', async () => {
242 |       const args = {
243 |         from: 'sender',
244 |         to: 'receiver',
245 |         assetIndex: 123,
246 |         amount: 1000,
247 |         closeRemainderTo: 'close-to',
248 |         note: 'test note',
249 |         rekeyTo: 'rekey-to',
250 |       };
251 | 
252 |       const result = await AssetTransactionManager.handleTool('make_asset_transfer_txn', args);
253 | 
254 |       expect(algosdk.makeAssetTransferTxnWithSuggestedParamsFromObject).toHaveBeenCalledWith(
255 |         expect.objectContaining({
256 |           ...args,
257 |           note: new TextEncoder().encode('test note'),
258 |         })
259 |       );
260 |     });
261 |   });
262 | 
263 |   describe('Error Handling', () => {
264 |     it('should throw error for unknown tool', async () => {
265 |       await expect(AssetTransactionManager.handleTool('unknown_tool', {}))
266 |         .rejects
267 |         .toThrow(new McpError(ErrorCode.MethodNotFound, 'Unknown asset transaction tool: unknown_tool'));
268 |     });
269 | 
270 |     it('should throw error for missing asset creation parameters', async () => {
271 |       await expect(AssetTransactionManager.handleTool('make_asset_create_txn', {}))
272 |         .rejects
273 |         .toThrow(new McpError(ErrorCode.InvalidParams, 'Invalid asset creation parameters'));
274 |     });
275 | 
276 |     it('should throw error for missing asset config parameters', async () => {
277 |       await expect(AssetTransactionManager.handleTool('make_asset_config_txn', {}))
278 |         .rejects
279 |         .toThrow(new McpError(ErrorCode.InvalidParams, 'Invalid asset configuration parameters'));
280 |     });
281 | 
282 |     it('should throw error for missing asset destroy parameters', async () => {
283 |       await expect(AssetTransactionManager.handleTool('make_asset_destroy_txn', {}))
284 |         .rejects
285 |         .toThrow(new McpError(ErrorCode.InvalidParams, 'Invalid asset destroy parameters'));
286 |     });
287 | 
288 |     it('should throw error for missing asset freeze parameters', async () => {
289 |       await expect(AssetTransactionManager.handleTool('make_asset_freeze_txn', {}))
290 |         .rejects
291 |         .toThrow(new McpError(ErrorCode.InvalidParams, 'Invalid asset freeze parameters'));
292 |     });
293 | 
294 |     it('should throw error for missing asset transfer parameters', async () => {
295 |       await expect(AssetTransactionManager.handleTool('make_asset_transfer_txn', {}))
296 |         .rejects
297 |         .toThrow(new McpError(ErrorCode.InvalidParams, 'Invalid asset transfer parameters'));
298 |     });
299 | 
300 |     it('should handle algod client errors', async () => {
301 |       const error = new Error('Network error');
302 |       (algodClient.getTransactionParams as jest.Mock)().do.mockRejectedValue(error);
303 | 
304 |       await expect(AssetTransactionManager.handleTool('make_asset_create_txn', {
305 |         from: 'sender',
306 |         total: 1000000,
307 |         decimals: 6,
308 |         defaultFrozen: false,
309 |       }))
310 |         .rejects
311 |         .toThrow(error);
312 |     });
313 |   });
314 | });
315 | 
```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/puya:python:testing:docs:testing-guide:contract-testing.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Smart Contract Testing
  2 | 
  3 | This guide provides an overview of how to test smart contracts using the Algorand Python SDK (`algopy`). We will cover the basics of testing `ARC4Contract` and `Contract` classes, focusing on `abimethod` and `baremethod` decorators.
  4 | 
  5 | ![](https://mermaid.ink/img/pako:eNqVkrFugzAQhl_Fujnp1ImhEiJrJNREWeoOV9sNVsFG9iEVBd69R5w0JE2llsk2n7-7_-AAymsDGewDtpXYrqQT_GyKFwl5vfcBnRZlT5V3IjYYSCjvKKAiCa-JzXfrObyzgTqsxRpVZZ25YOX2nnRrIomCneZzpszLkllktu0f8ratrUKyjFsXCZ1K2gTH7i01_8dGUjOT_55YeLdUFVr3zRunf5b6R5hZoFnBq9cX72_Br_Cj8bl4vJCHaVucvowYxHk5Xg_sfPkY6SbbphDL5dMgQZu29n0U5DMJwzTVGyApySKZKFSNMXKVxPJYYAGNCQ1azX_VYboqgSrTcAcZLzWGDwnSjcxhR37TOwUZhc4sIPhuX0H2jnXkXddqrrCyyKNpTqfjF5m74B8?type=png)
  6 | 
  7 | ```{note}
  8 | The code snippets showcasing the contract testing capabilities are using [pytest](https://docs.pytest.org/en/latest/) as the test framework. However, note that the `algorand-python-testing` package can be used with any other test framework that supports Python. `pytest` is used for demonstration purposes in this documentation.
  9 | ```
 10 | 
 11 | ```{testsetup}
 12 | import algopy
 13 | import algopy_testing
 14 | from algopy_testing import algopy_testing_context
 15 | 
 16 | # Create the context manager for snippets below
 17 | ctx_manager = algopy_testing_context()
 18 | 
 19 | # Enter the context
 20 | context = ctx_manager.__enter__()
 21 | ```
 22 | 
 23 | ## `algopy.ARC4Contract`
 24 | 
 25 | Subclasses of `algopy.ARC4Contract` are **required** to be instantiated with an active test context. As part of instantiation, the test context will automatically create a matching `algopy.Application` object instance.
 26 | 
 27 | Within the class implementation, methods decorated with `algopy.arc4.abimethod` and `algopy.arc4.baremethod` will automatically assemble an `algopy.gtxn.ApplicationCallTransaction` transaction to emulate the AVM application call. This behavior can be overriden by setting the transaction group manually as part of test setup, this is done via implicit invocation of `algopy_testing.context.any_application()` _value generator_ (refer to [APIs](../apis.md) for more details).
 28 | 
 29 | ```{testcode}
 30 | class SimpleVotingContract(algopy.ARC4Contract):
 31 |     def __init__(self) -> None:
 32 |         self.topic = algopy.GlobalState(algopy.Bytes(b"default_topic"), key="topic", description="Voting topic")
 33 |         self.votes = algopy.GlobalState(
 34 |             algopy.UInt64(0),
 35 |             key="votes",
 36 |             description="Votes for the option",
 37 |         )
 38 |         self.voted = algopy.LocalState(algopy.UInt64, key="voted", description="Tracks if an account has voted")
 39 | 
 40 |     @algopy.arc4.abimethod(create="require")
 41 |     def create(self, initial_topic: algopy.Bytes) -> None:
 42 |         self.topic.value = initial_topic
 43 |         self.votes.value = algopy.UInt64(0)
 44 | 
 45 |     @algopy.arc4.abimethod
 46 |     def vote(self) -> algopy.UInt64:
 47 |         assert self.voted[algopy.Txn.sender] == algopy.UInt64(0), "Account has already voted"
 48 |         self.votes.value += algopy.UInt64(1)
 49 |         self.voted[algopy.Txn.sender] = algopy.UInt64(1)
 50 |         return self.votes.value
 51 | 
 52 |     @algopy.arc4.abimethod(readonly=True)
 53 |     def get_votes(self) -> algopy.UInt64:
 54 |         return self.votes.value
 55 | 
 56 |     @algopy.arc4.abimethod
 57 |     def change_topic(self, new_topic: algopy.Bytes) -> None:
 58 |         assert algopy.Txn.sender == algopy.Txn.application_id.creator, "Only creator can change topic"
 59 |         self.topic.value = new_topic
 60 |         self.votes.value = algopy.UInt64(0)
 61 |         # Reset user's vote (this is simplified per single user for the sake of example)
 62 |         self.voted[algopy.Txn.sender] = algopy.UInt64(0)
 63 | 
 64 | # Arrange
 65 | initial_topic = algopy.Bytes(b"initial_topic")
 66 | contract = SimpleVotingContract()
 67 | contract.voted[context.default_sender] = algopy.UInt64(0)
 68 | 
 69 | # Act - Create the contract
 70 | contract.create(initial_topic)
 71 | 
 72 | # Assert - Check initial state
 73 | assert contract.topic.value == initial_topic
 74 | assert contract.votes.value == algopy.UInt64(0)
 75 | 
 76 | # Act - Vote
 77 | # The method `.vote()` is decorated with `algopy.arc4.abimethod`, which means it will assemble a transaction to emulate the AVM application call
 78 | result = contract.vote()
 79 | 
 80 | # Assert - you can access the corresponding auto generated application call transaction via test context
 81 | assert len(context.txn.last_group.txns) == 1
 82 | 
 83 | # Assert - Note how local and global state are accessed via regular python instance attributes
 84 | assert result == algopy.UInt64(1)
 85 | assert contract.votes.value == algopy.UInt64(1)
 86 | assert contract.voted[context.default_sender] == algopy.UInt64(1)
 87 | 
 88 | # Act - Change topic
 89 | new_topic = algopy.Bytes(b"new_topic")
 90 | contract.change_topic(new_topic)
 91 | 
 92 | # Assert - Check topic changed and votes reset
 93 | assert contract.topic.value == new_topic
 94 | assert contract.votes.value == algopy.UInt64(0)
 95 | assert contract.voted[context.default_sender] == algopy.UInt64(0)
 96 | 
 97 | # Act - Get votes (should be 0 after reset)
 98 | votes = contract.get_votes()
 99 | 
100 | # Assert - Check votes
101 | assert votes == algopy.UInt64(0)
102 | 
103 | ```
104 | 
105 | For more examples of tests using `algopy.ARC4Contract`, see the [examples](../examples.md) section.
106 | 
107 | ## `algopy.Contract``
108 | 
109 | Subclasses of `algopy.Contract` are **required** to be instantiated with an active test context. As part of instantiation, the test context will automatically create a matching `algopy.Application` object instance. This behavior is identical to `algopy.ARC4Contract` class instances.
110 | 
111 | Unlike `algopy.ARC4Contract`, `algopy.Contract` requires manual setup of the transaction context and explicit method calls. Alternatively, you can use `active_txn_overrides` to specify application arguments and foreign arrays without needing to create a full transaction group if your aim is to patch a specific active transaction related metadata.
112 | 
113 | Here's an updated example demonstrating how to test a `Contract` class:
114 | 
115 | ```{testcode}
116 | import algopy
117 | import pytest
118 | from algopy_testing import AlgopyTestContext, algopy_testing_context
119 | 
120 | class CounterContract(algopy.Contract):
121 |     def __init__(self):
122 |         self.counter = algopy.UInt64(0)
123 | 
124 |     @algopy.subroutine
125 |     def increment(self):
126 |         self.counter += algopy.UInt64(1)
127 |         return algopy.UInt64(1)
128 | 
129 |     @algopy.arc4.baremethod
130 |     def approval_program(self):
131 |         return self.increment()
132 | 
133 |     @algopy.arc4.baremethod
134 |     def clear_state_program(self):
135 |         return algopy.UInt64(1)
136 | 
137 | @pytest.fixture()
138 | def context():
139 |     with algopy_testing_context() as ctx:
140 |         yield ctx
141 | 
142 | def test_counter_contract(context: AlgopyTestContext):
143 |     # Instantiate contract
144 |     contract = CounterContract()
145 | 
146 |     # Set up the transaction context using active_txn_overrides
147 |     with context.txn.create_group(
148 |         active_txn_overrides={
149 |             "sender": context.default_sender,
150 |             "app_args": [algopy.Bytes(b"increment")],
151 |         }
152 |     ):
153 |         # Invoke approval program
154 |         result = contract.approval_program()
155 | 
156 |         # Assert approval program result
157 |         assert result == algopy.UInt64(1)
158 | 
159 |         # Assert counter value
160 |         assert contract.counter == algopy.UInt64(1)
161 | 
162 |     # Test clear state program
163 |     assert contract.clear_state_program() == algopy.UInt64(1)
164 | 
165 | def test_counter_contract_multiple_txns(context: AlgopyTestContext):
166 |     contract = CounterContract()
167 | 
168 |     # For scenarios with multiple transactions, you can still use gtxns
169 |     extra_payment = context.any.txn.payment()
170 | 
171 |     with context.txn.create_group(
172 |         gtxns=[
173 |             extra_payment,
174 |             context.any.txn.application_call(
175 |                 sender=context.default_sender,
176 |                 app_id=contract.app_id,
177 |                 app_args=[algopy.Bytes(b"increment")],
178 |             ),
179 |         ],
180 |         active_txn_index=1  # Set the application call as the active transaction
181 |     ):
182 |         result = contract.approval_program()
183 | 
184 |         assert result == algopy.UInt64(1)
185 |         assert contract.counter == algopy.UInt64(1)
186 | 
187 |     assert len(context.txn.last_group.txns) == 2
188 | ```
189 | 
190 | In this updated example:
191 | 
192 | 1. We use `context.txn.create_group()` with `active_txn_overrides` to set up the transaction context for a single application call. This simplifies the process when you don't need to specify a full transaction group.
193 | 
194 | 2. The `active_txn_overrides` parameter allows you to specify `app_args` and other transaction fields directly, without creating a full `ApplicationCallTransaction` object.
195 | 
196 | 3. For scenarios involving multiple transactions, you can still use the `gtxns` parameter to create a transaction group, as shown in the `test_counter_contract_multiple_txns` function.
197 | 
198 | 4. The `app_id` is automatically set to the contract's application ID, so you don't need to specify it explicitly when using `active_txn_overrides`.
199 | 
200 | This approach provides more flexibility in setting up the transaction context for testing `Contract` classes, allowing for both simple single-transaction scenarios and more complex multi-transaction tests.
201 | 
202 | ## Defer contract method invocation
203 | 
204 | You can create deferred application calls for more complex testing scenarios where order of transactions needs to be controlled:
205 | 
206 | ```python
207 | def test_deferred_call(context):
208 |     contract = MyARC4Contract()
209 | 
210 |     extra_payment = context.any.txn.payment()
211 |     extra_asset_transfer = context.any.txn.asset_transfer()
212 |     implicit_payment = context.any.txn.payment()
213 |     deferred_call = context.txn.defer_app_call(contract.some_method, implicit_payment)
214 | 
215 |     with context.txn.create_group([extra_payment, deferred_call, extra_asset_transfer]):
216 |         result = deferred_call.submit()
217 | 
218 |     print(context.txn.last_group) # [extra_payment, implicit_payment, app call, extra_asset_transfer]
219 | ```
220 | 
221 | A deferred application call prepares the application call transaction without immediately executing it. The call can be executed later by invoking the `.submit()` method on the deferred application call instance. As demonstrated in the example, you can also include the deferred call in a transaction group creation context manager to execute it as part of a larger transaction group. When `.submit()` is called, only the specific method passed to `defer_app_call()` will be executed.
222 | 
223 | ```{testcleanup}
224 | ctx_manager.__exit__(None, None, None)
225 | ```
226 | 
```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/developer:docs:details:accounts:index.md:
--------------------------------------------------------------------------------

```markdown
  1 | title: Overview
  2 | 
  3 | This section is an overview of **Accounts** on Algorand. It reviews core terminology and guides developers on how to interpret these terms in different contexts. 
  4 | 
  5 | 
  6 | 
  7 | 
  8 | # Quick start videos
  9 | 
 10 | If you prefer videos, take a look at this 6 minute guide to Learn How to Manage Private / Public Algorand Account Keys.
 11 | 
 12 | <iframe width="100%" style="aspect-ratio:16/9" src="https://www.youtube-nocookie.com/embed/SewNDCBvk58" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
 13 | 
 14 | # Terminology
 15 | ## Keys and Addresses
 16 | 
 17 | Algorand uses Ed25519 high-speed, high-security elliptic-curve signatures. The keys are produced through standard, open-source cryptographic libraries packaged with each of the SDKs. The key generation algorithm takes a random value as input and outputs two 32-byte arrays, representing a public key and its associated private key. These are also referred to as a public/private key pair. These keys perform important cryptographic functions like signing data and verifying signatures. 
 18 | 
 19 | <center> ![Key Generation](../../imgs/accounts-0.png) </center>
 20 | <center>*Public/Private Key Generation* </center>
 21 | 
 22 | For reasons that include the need to make the keys human-readable and robust to human error when transferred, both the public and private keys undergo transformations. The output of these transformations is what the majority of developers, and usually all end-users, see. In fact, the Algorand developer tools actively seek to mask the complexity involved in these transformations. So unless you are a protocol-level developer modifying cryptographic-related source code, you may never actually encounter the true public/private key pair. 
 23 | 
 24 | 
 25 | ### Transformation: Public Key to Algorand Address
 26 | 
 27 | The **public key** is transformed into an Algorand address, by adding a 4-byte checksum to the end of the public key and then encoding it in base32. The result is what both the developer and end-user recognize as an **Algorand address**. The address is 58 characters long.
 28 | 
 29 | <center> ![Algorand Address](../../imgs/accounts-1.png) </center>
 30 | <center>*Public Key to Algorand Address* </center>
 31 | 
 32 | !!! info
 33 | 	Since users almost never see the true public key, and the Algorand address is a unique mapping back to the public key, the use of the term **public key** is frequently (and inaccurately) used to mean **address**. 
 34 | 	
 35 | !!! tip
 36 | 	Assuming the [Python SDK is installed](../../sdks/python/#install-sdk), it is possible to convert addresses to (base32-encoded) public keys and vice-versa using the following one-liners (here used on the address `VCMJKWOY5P5P7SKMZFFOCEROPJCZOTIJMNIYNUCKH7LRO45JMJP6UYBIJA`):
 37 | 	```bash
 38 | 	python3 -c "import base64, sys, algosdk; [print(base64.b32encode(algosdk.encoding.decode_address(line.strip())).decode()) for line in sys.stdin if line.strip()]" <<< VCMJKWOY5P5P7SKMZFFOCEROPJCZOTIJMNIYNUCKH7LRO45JMJP6UYBIJA
 39 | 
 40 | 	python3 -c "import base64, sys, algosdk; [print(algosdk.encoding.encode_address(base64.b32decode(line.strip()))) for line in sys.stdin if line.strip()]" <<< VCMJKWOY5P5P7SKMZFFOCEROPJCZOTIJMNIYNUCKH7LRO45JMJPQ====
 41 | 	```
 42 | 
 43 | ### Transformation: Private Key to base64 private key
 44 | 
 45 | A base64 encoded concatenation of the private and public keys is a representation of the private key most commonly used by developers interfacing with the SDKs. It is likely not a representation familiar to end users.
 46 | 
 47 | <center> ![base64 private key](../../imgs/accounts-2.png) </center>
 48 | <center>*Base64 Private Key* </center>
 49 | 
 50 | ### Transformation: Private Key to 25-word mnemonic
 51 | 
 52 | The 25-word mnemonic is the most user-friendly representation of the private key. It is generated by converting the private key bytes into 11-bit integers and then mapping those integers to the [bip-0039 English word list](https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/english.txt), where integer _n_ maps to the word in the _nth_ position in the list. By itself, this creates a 24-word mnemonic. A checksum is added by taking the first two bytes of the hash of the private key and converting them to 11-bit integers and then to their corresponding word in the word list. This word is added to the end of the 24 words to create a 25-word mnemonic.
 53 | 
 54 | This representation is called the private key **mnemonic**. You may also see it referred to as a **passphrase**. 
 55 | 
 56 | <center> ![Mnemonic](../../imgs/accounts-3.png) </center>
 57 | <center>*Private Key Mnemonic* </center>
 58 | 
 59 | !!! info
 60 | 	Both the base64 representation of a private key and the private key mnemonic are considered **private keys**. It is important to disambiguate in contexts where the representation is important. 
 61 | 
 62 | ## Wallets
 63 | 
 64 | Wallets, in the context of Algorand developer tools, refer to wallets generated and managed by the Key Management Daemon (kmd) process. A wallet stores a collection of keys. kmd stores collections of wallets and allows users to perform operations using the keys stored within these wallets. Every wallet is associated with a master key, represented as a 25-word mnemonic, from which all accounts in that wallet are derived. This allows the owner of the wallet to only need to remember a single passphrase for all of their accounts. Wallets are stored encrypted on disk. 
 65 | 
 66 | See [Wallet-derived (kmd)](./create.md#wallet-derived-kmd) accounts in the [Creation Methods](./create.md) section for more details.
 67 | 
 68 | ## Accounts
 69 | Accounts are entities on the Algorand blockchain associated with specific onchain data, like a balance. An Algorand Address is the identifier for an Algorand account. 
 70 | 
 71 | After generating a private key and corresponding address, sending Algos to the address on Algorand will initialize its state on the Algorand blockchain. 
 72 | 
 73 | <center> ![Account](../../imgs/accounts-4.png) </center>
 74 | <center>*Initializing an Account* </center>
 75 | 
 76 | ### Attributes
 77 | #### Minimum Balance
 78 | Every account on Algorand must have a minimum balance of 100,000 microAlgos. If ever a transaction is sent that would result in a balance lower than the minimum, the transaction will fail. The minimum balance increases with each asset holding the account has (whether the asset was created or owned by the account) and with each application the account created or opted in. Destroying a created asset, opting out/closing out an owned asset, destroying a created app, or opting out an opted in app decreases accordingly the minimum balance.
 79 | 
 80 | Read more about assets, applications, and changes to the minimum balance requirement in the [Algorand Standard Assets](../asa) and [Smart contracts details](../dapps/smart-contracts/apps) sections.
 81 | 
 82 | #### Online/Offline
 83 | By default, Algorand accounts are set to **offline**. An **online** account is one that participates in Algorand consensus. For an account to go online, it must generate a participation key and send a special key registration transaction. Read more about how to register an account online in the [Network Participation](../../run-a-node/participate/index.md) section.
 84 | 
 85 | ### Other Account Types
 86 | Creating an Algorand address from a public key is not the only way. A valid address can also be produced from a compiled TEAL contract and through multisignature accounts. These accounts differ in how they authorize spends, but they look like any other account on Algorand. Read more about contract accounts in the [Algorand Smart Contracts](/docs/get-details/dapps/smart-contracts/apps/#application-account) section. Multisignature accounts are described [below](create#multisignature).
 87 | 
 88 | ### Special Accounts
 89 | 
 90 | Two accounts carry special meaning on the Algorand blockchain. They are the **FeeSink** and the **RewardsPool**. The FeeSink is where all fees from transactions are sent. The FeeSink can only spend to the RewardsPool account. The RewardsPool was first used to distribute rewards to balance holding accounts. Currently this account is not used. 
 91 | 
 92 | In addition, the ZeroAddress `AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ` is an address that represents a blank byte array. It is used when you leave an address field in a transaction blank.
 93 | 
 94 | _MainNet [FeeSink](../algorand-networks/mainnet#feesink-address) and [RewardsPool](../algorand-networks/mainnet#rewardspool-address) addresses_
 95 | 
 96 | _TestNet [FeeSink](../algorand-networks/testnet#feesink-address) and [RewardsPool](../algorand-networks/testnet#rewardspool-address) addresses_
 97 | 
 98 | ## A note about term usage in these docs
 99 | Even in these docs, use of these terms may be inconsistent. At times this is a deliberate style choice to ensure clarity around a broader concept. Sometimes it is to emphasize the inherent pairing of the public and private portions of a key. (e.g. In code examples, it is sometimes clearer to name variables as such to emphasize the connection between these two entities). Other times it is to abstract away from complexity related to generating an account on Algorand. For example, code samples may use terms like "generateAccount" to generate a private key and Algorand address. There is an underlying assumption that this pair will be used as an Algorand account even though on generation it is not yet represented on the blockchain and therefore is not yet technically an Algorand account.
100 | 
101 | 
102 | ??? tip "Interpretation Guide"
103 | 	Here are a few examples of the way these terms appear in the wild and suggestions on how to interpret them. It is always best to ask for clarification when the terms are ambiguous.
104 | 
105 | 	1. A developer says they are looking to create a wallet for Algorand and are asking about kmd. - _In this situation, it is probably best to direct them to this page so they understand all the ways to create accounts on Algorand. They may want to support more than one generation method, including kmd._
106 | 	2. A consumer says: "I have 5 accounts in my wallet." - _Consumers are likely referring to mobile or web wallets, and probably not the underlying kmd wallet mechanism._
107 | 	3. A protocol developer wants to explore the signature validation mechanism in the Algorand protocol. - _This developer will most definitely encounter the true public/private key pairs as well as many of the concepts detailed above._
108 | 
```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/ARCs:specs:arc-0034.md:
--------------------------------------------------------------------------------

```markdown
  1 | ---
  2 | arc: 34
  3 | title: xGov Pilot - Proposal Process
  4 | description: Criteria for the creation of proposals.
  5 | author: Stéphane Barroso (@SudoWeezy), Adriana Belotti, Michel Treccani
  6 | discussions-to: https://github.com/algorandfoundation/ARCs/issues/151
  7 | status: Deprecated
  8 | type: Meta
  9 | created: 2022-11-22
 10 | ---
 11 | 
 12 | ## Abstract
 13 | 
 14 | The Goal of this ARC is to clearly define the steps involved in submitting proposals for the xGov Program, to increase transparency and efficiency, ensuring all proposals are given proper consideration. The goal of this grants scheme is to fund proposals that will help us in our goal of increasing the adoption of the Algorand network, as the most advanced layer 1 blockchain to date. The program aims to fund proposals to develop open source software, including tooling, as well as educational resources to help inform and grow the Algorand community.
 15 | 
 16 | ## Specification
 17 | 
 18 | The key words "**MUST**", "**MUST NOT**", "**REQUIRED**", "**SHALL**", "**SHALL NOT**", "**SHOULD**", "**SHOULD NOT**", "**RECOMMENDED**", "**MAY**", and "**OPTIONAL**" in this document are to be interpreted as described in <a href="https://www.ietf.org/rfc/rfc2119.txt">RFC-2119</a>.
 19 | 
 20 | ### What is a proposal
 21 | 
 22 | The xGov program aims to provide funding for individuals or teams to:
 23 | 
 24 | - Develop of open source applications and tools (eg. an open source AMM or contributing content to an Algorand software library).
 25 | - Develop Algorand education resources, preferably in languages where the resources are not yet available(eg. a video series teaching developers about Algorand in Portuguese or Indonesian).
 26 | 
 27 | The remainder of the xGov program pilot will not fund proposals for:
 28 | 
 29 | - Supplying liquidity.
 30 | - Reserving funds to pay for ad-hoc open-source development (devs can apply directly for an xGov grant).
 31 | - Buying ASAs, including NFTs.
 32 | 
 33 | Proposals **SHALL NOT** be divided in small chunks.
 34 | > Issues requiring resolution may have been discussed on various online platforms such as forums, discord, and social media networks.
 35 | > Proposals requesting a large amount of funds **MUST BE** split into a milestone-based plan. See [Submit a proposal](./arc-0034.md#submit-a-proposal)
 36 | 
 37 | ### Duty of a proposer
 38 | 
 39 | Having the ability to propose measures for a vote is a significant privilege, which requires:
 40 | 
 41 | - A thorough understanding of the needs of the community.
 42 | - Alignment of personal interests with the advancement of the Algorand ecosystem.
 43 | - Promoting good behavior amongst proposers and discouraging "gaming the system".
 44 | - Reporting flaws and discussing possible solutions with the AF team and community using either the Algorand Forum or the xGov Discord channels.
 45 | 
 46 | ### Life of a proposal
 47 | 
 48 | The proposal process will follow the steps below:
 49 | 
 50 | - Anyone can submit a proposal at any time.
 51 | - Proposals will be evaluated and refined by the community and xGovs before they are available for voting.
 52 | - Up to one month is allocated for voting on proposals.
 53 | - The community will vote on proposals that have passed the refinement and temperature check stage.
 54 | 
 55 | > If too many proposals are received in a short period of time. xGovs can elect to close proposals, in order to be able to handle the volume appropriately.
 56 | 
 57 | ### Submit a proposal
 58 | 
 59 | In order to submit a proposal, a proposer needs to create a pull request on the following repository: <a href="https://github.com/algorandfoundation/xGov">xGov Proposals</a>.
 60 | 
 61 | Proposals **MUST**:
 62 | 
 63 | - Be posted on the <a href="https://forum.algorand.org/">Algorand Forum</a> (using tags: Governance and xGov Proposals) and discussed with the community during the review phased. Proposals without a discussion thread WILL NOT be included in the voting session.
 64 | - Follow the [template form provided](../assets/arc-0034/TemplateForm.md), filling all the template sections
 65 | - Follow the rules of the xGov Proposals Repository.
 66 | - The minimum requested Amount is 10000 Algo
 67 | - Have the status `Final` before the end of the temperature check.
 68 | - Be either Proactive (the content of the proposal is yet to be created) or Retroactive (the content of the proposal is already created)
 69 | - Milestone-based grants must submit a proposal for one milestone at a time.
 70 | - Milestones need to follow the governance periods cycle. With the current 3-months cycle, a milestone could be 3-months, 6 months, 9 months etc.
 71 | - The proposal must display all milestones with clear deliverables and the amount requested must match the 1st milestone. If a second milestone proposal is submitted, it must display the first completed milestone, linking all deliverables. If a third milestone proposal is submitted, it must display the first and second completed milestone, linking all deliverables. This repeats until all milestones are completed.
 72 | - Funding will only be disbursed upon the completion of deliverables.
 73 | - A proposal must specify how its delivery can be verified,  so that it can be checked prior to payment.
 74 | - Proposals must include clear, non-technical descriptions of deliverables. We encourage the use of multimedia (blog/video) to help explain your proposal’s benefits to the community.
 75 | - Contain the maintenance period, availability, and sustainability plans. This includes information on potential costs and the duration for which services will be offered at no or reduced cost.
 76 | 
 77 | Proposals **MUST NOT**:
 78 | 
 79 | - Request funds for marketing campaigns or organizing future meetups.
 80 | 
 81 | > Each entity, individual, or project can submit at most two proposals (one proactive proposal and one retroactive proposal). Attempts to circumvent this rule may lead to disqualification or denial of funds.
 82 | 
 83 | ### Disclaimer jurisdictions and exclusions
 84 | 
 85 | To be eligible to apply for a grant, projects must abide by the <a href="https://www.algorand.foundation/disclaimers">Disclaimers</a> (in particular the “Excluded Jurisdictions” section) and be willing to enter into <a href="https://drive.google.com/file/d/1dsKwQGhnS3h_PrSkoidhnvqlX7soLpZ-/view">a binding contract with the Algorand Foundation</a>.
 86 | Additionally, applications promoting gambling, adult content, drug use, and violence of any kind are not permitted.
 87 | 
 88 | > We are currently accepting grant applications from US-based individual/business. If the grant is approved, Algos will be converted to USDCa upon payment. This exception will be reviewed periodically.
 89 | 
 90 | ### Voting Power
 91 | 
 92 | When an account participates in its first session, the voting power assigned to it will be equivalent to the total governance rewards it would have received. For all following sessions, the account's voting power will adjust based on the rewards lost by members in their pool who did not meet their obligations.
 93 | 
 94 | The voting power for an upcoming session is computed as:
 95 | `new_account_voting_power = (initial_pool_voting_power * initial_account_voting_power) / pool_voting_power_used`
 96 | 
 97 | Where:
 98 | 
 99 | - `new_account_voting_power`: Voting power allocated to an account for the next session.
100 | - `initial_account_voting_power`: The voting power originally assigned to an account, based on the governance rewards.
101 | - `initial_pool_voting_power`: The total voting power of the pool during its initial phase. This is the sum of governance rewards for all pool participants.
102 | - `pool_voting_power_used`: The voting power from the pool that was actually used in the last session.
103 | 
104 | ### Proposal Approval Threshold
105 | 
106 | In order for a proposal to be approved, it is necessary for the number of votes in favor of the proposal to be proportionate to the amount of funds requested. This ensures that the allocation of funds is in line with the community's consensus and in accordance with democratic principles.
107 | 
108 | The formula to calculate the voting power needed to pass a proposal is as follows:
109 | `voting_power_needed = (amount_requested) / (amount_available) * (current_session_voting_power_used)`
110 | 
111 | Where:
112 | 
113 | - `voting_power_needed`: Voting power required for a proposal to be accepted.
114 | - `amount_requested`: The requested amount a proposal is seeking.
115 | - `amount_available`: The entire grant funds available for the current session.
116 | - `current_session_voting_power_used`: The voting power used in the current session.
117 | 
118 | > eg. 2 000 000 Algo are available to be given away as grants, 300 000 000 Algo are committed to the xGov Process, 200 000 000 Algo are used during the vote:
119 | >
120 | > - Proposal A request 100 000 Algos (5 % of the Amount available)
121 | > - Proposal A needs 5 % of the used votes (10 000 000 Votes) to go through
122 | 
123 | ### Voting on proposal
124 | 
125 | At the start of the voting period xGovs [ARC-33](arc-0033.md) will vote on proposals using the voting tool hosted at <a href="https://xgov.algorand.foundation/">https://xgov.algorand.foundation/</a>.
126 | 
127 | Vote will refer to the PR number and a cid hash of the proposal itself.
128 | 
129 | The CID MUST:
130 | 
131 | - Represent the file.
132 | 
133 | - Be a version V1 CID
134 |   - E.g., use the option --cid-version=1 of ipfs add
135 | 
136 | - Use SHA-256 hash algorithm
137 |   - E.g., use the option --hash=sha2-256 of ipfs add
138 | 
139 | ### Grants calculation
140 | 
141 | The allocation of grants will consider the funding request amounts and the available amount of ALGO to be distributed.
142 | 
143 | ### Grants contract & payment
144 | 
145 | - Once grants are approved, the Algorand Foundation team will handle the applicable contract and payment.
146 | - **Before submitting your grant proposal**, review the contract template and ensure you're comfortable with its terms: <a href="https://drive.google.com/file/d/1dsKwQGhnS3h_PrSkoidhnvqlX7soLpZ-/view">Contract Template</a>.
147 | 
148 | > For milestone-based grants, please also refer to the [Submit a proposal section](./arc-0034.md#submit-a-proposal)
149 | 
150 | ## Rationale
151 | 
152 | The current status of the proposal process includes the following elements:
153 | 
154 | - Proposals will be submitted off-chain and linked to the on-chain voting through a hash.
155 | - Projects that require multiple funding rounds will need to submit separate proposals.
156 | - The allocation of funds will be subject to review and adjustment during each governance period.
157 | - Voting on proposals will take place on-chain.
158 | 
159 | We encourage the community to continue to provide input on this topic through the submission of questions and ideas in this ARC document.
160 | 
161 | ## Security Considerations
162 | 
163 | None
164 | 
165 | ## Copyright
166 | 
167 | Copyright and related rights waived via <a href="https://creativecommons.org/publicdomain/zero/1.0/">CCO</a>.
168 | 
```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/algokit:cli:architecture-decisions:2024-01-13_native_binaries.md:
--------------------------------------------------------------------------------

```markdown
  1 | # AlgoKit CLI native binaries
  2 | 
  3 | - **Status**: Approved
  4 | - **Owner:** Altynbek Orumbayev (MakerX), Negar Abbasi (MakerX)
  5 | - **Deciders**: Alessandro (Algorand Foundation), MakerX
  6 | - **Date created**: 2024-01-13
  7 | - **Date decided:** 2024-01-25
  8 | - **Date updated**: 2024-01-16
  9 | 
 10 | ## Context
 11 | 
 12 | The primary motivation for this decision is to streamline the installation process of AlgoKit CLI and reduce the friction associated with installing it on various operating systems. Currently, users often encounter minor environment-specific bugs during installation, which can be a significant deterrent. By providing native binaries, we aim to speed up the installation time and eliminate these bugs by **removing requirements to install python by the user**, thereby improving the overall user experience.
 13 | 
 14 | The north star for this decision is to provide a distribution model that can be described as:
 15 | 
 16 | ```mermaid
 17 | graph TD
 18 |     A[GitHub Runners] -->|Windows| B[Packaging tool]
 19 |     A -->|Mac| C[Packaging tool]
 20 |     A -->|Linux| D[Packaging tool]
 21 |     B --> E[Windows Binary]
 22 |     C --> F[Mac Binary]
 23 |     D --> G[Linux Binary]
 24 |     E -->|Winget| H[Windows Users]
 25 |     F -->|Brew| I[Mac Users]
 26 |     G -->|Snap| J[Linux Users]
 27 |     A -->|Wheel Build| K[Poetry]
 28 |     K --> L[PyPi]
 29 |     L -->|pipx| M[Python Users]
 30 | ```
 31 | 
 32 | > ⚠️⚠️⚠️ Please note diagram above is a draft and is to be separately discussed in a follow up ADR that will focus on distribution of the binaries.
 33 | 
 34 | The scope of this ADR only concerns the packaging for the CLI. The distribution via `snap`, `winget` and etc will be handled separately/in-parallel after decision and implementation of this ADR is in place.
 35 | 
 36 | ## Requirements
 37 | 
 38 | - The native binaries should be easy to maintain and understand from a CI/CD deployment perspective.
 39 | - The solution should support a wide variety of Linux distributions, macOS (both Apple Silicon and Intel architectures), and Windows.
 40 | - The solution should integrate seamlessly with existing installation options, including Homebrew, or provide an easier alternative.
 41 | - The solution should be designed with future scalability in mind, allowing for the addition of support for other variations of architectures or else as needed.
 42 | - The solution should not significantly increase the complexity of the build process.
 43 | - The solution should provide clear error messages and debugging information to assist in troubleshooting any issues that may arise.
 44 | - You don't need to install Python on your system to use AlgoKit if you aren't creating a Python project.
 45 | 
 46 | ## Options
 47 | 
 48 | ### Option 1 - PyInstaller
 49 | 
 50 | **Pros**
 51 | 
 52 | - Easy to use and configure
 53 | - Supports multiple platforms and architectures
 54 | - Can handle complex packages and dependencies
 55 | - Generates a single file executable
 56 | - Active development and community support
 57 | - Fairly fast build time via ci - ~3-4 minutes
 58 | - Fairly small executable size (see benchmarking results below)
 59 | - Marginally equal executable load time in `onedir` mode compared to `onefile` mode
 60 | 
 61 | **Cons**
 62 | 
 63 | - Occasionally requires manual configuration for more complex packages
 64 | - Requires complex build packaging matrix to support multiple platforms and architectures
 65 | - Requires minor tweaks in algokit cli to account for the fact that features relying on `sys.executable` will point to algokit cli executable instead of python interpreter. This is a minor change and can be done in a backwards compatible way however still a con to consider.
 66 | - Requires minor tweaks in algokit cli to introduce `multiprocessing.freeze_support()` to avoid issues with `vanity-address` task when executing via binary.
 67 | 
 68 | #### PoC
 69 | 
 70 | The PoC is available [here](https://github.com/algorandfoundation/algokit-cli/pull/382). It outlines a simple github action with extra setup that compiles algokit cli as a single file executable on latest versions of Windows, Mac and Linux github runners.
 71 | 
 72 | ### Option 2 - Nuitka
 73 | 
 74 | **Pros**
 75 | 
 76 | - Nuitka translates Python code into C and then compiles it, which can result in performance improvements.
 77 | - Cross-Platform: Supports multiple platforms including Windows, macOS, and Linux.
 78 | - More cross compilations options than PyInstaller
 79 | - Official github action simplifies the process of building executables for different platforms.
 80 | 
 81 | **Cons**
 82 | 
 83 | - Compilation Time: The process of converting Python to C and then compiling can be time-consuming. Up to ~30 minutes on github with 3 parallel jobs.
 84 | - Size of Executable: The resulting executables can be larger due to the inclusion of the Python interpreter and the compiled C code (see benchmarking results below).
 85 | - Does not support Python 3.12.
 86 | - Requires minor tweaks in algokit cli to account for the fact that features relying on `sys.executable` will point to algokit cli executable instead of python interpreter. This is a minor change and can be done in a backwards compatible way however still a con to consider.
 87 | - Requires minor tweaks in algokit cli to introduce `multiprocessing.freeze_support()` to avoid issues with `vanity-address` task when executing via binary.
 88 | 
 89 | #### PoC
 90 | 
 91 | The PoC is available [here](https://github.com/algorandfoundation/algokit-cli/pull/393). It outlines a simple github action with extra setup that compiles algokit cli as a single file executable on latest versions of Windows, Mac and Linux github runners.
 92 | 
 93 | ### Benchmarking `pyinstaller` vs `nuitka` vs pipx installed `algokit`
 94 | 
 95 | #### Methodology
 96 | 
 97 | `hyperfine` was used to benchmark 5 different executables:
 98 | 
 99 | - Nuitka Onefile - Nuitka compiled executable with `--onefile` flag, which produces a single file executable.
100 | - Nuitka Onedir - Nuitka compiled executable with `--onedir` flag, which produces a directory with the executable and other dependencies unzipped.
101 | - PyInstaller Onedir - PyInstaller compiled executable with `--standalone` flag, which produces a directory with the executable and other dependencies unzipped.
102 | - PyInstaller Onefile - PyInstaller compiled executable with `--onefile` flag, which produces a single file executable.
103 | - AlgoKit from `pipx` - AlgoKit CLI installed via `pipx` with all dependencies frozen (current latest stable release).
104 | 
105 | The benchmarking was performed on a MacBook M2 running macOS 14.2.1 and an ARM based Ubuntu 20.04.3 LTS running on a Parallels Desktop on the same machine.
106 | 
107 | #### Results
108 | 
109 | | Method              | macOS M2 | Ubuntu 20 ARM Linux VM | Windows 11 ARM |
110 | | ------------------- | -------- | ---------------------- | -------------- |
111 | | nuitka_onefile      | 3.634    | 1.465                  | 3.874          |
112 | | nuitka_onedir       | 0.2515   | 0.6200                 | 0.5136         |
113 | | pyinstaller_onedir  | 0.3228   | 0.7927                 | 0.6668         |
114 | | pyinstaller_onefile | 3.031    | 1.466                  | 1.875          |
115 | | algokit             | 0.3126   | 0.6111                 | 0.7579         |
116 | 
117 | ![Benchmarking Results](./assets/2024-01-13_native_binaries/image_1.png)
118 | _Figure: Benchmarking results comparing the performance of Nuitka (onefile, onedir modes), PyInstaller (onefile, onedir modes), and pipx installed Algokit CLI on macOS M2, Windows 11 ARM VM, Ubuntu 20 ARM VM._
119 | 
120 | | Method              | Windows (MB) | Ubuntu (MB) | macOS (MB) |
121 | | ------------------- | ------------ | ----------- | ---------- |
122 | | nuitka_onedir       | 92.10        | 106         | 166        |
123 | | nuitka_onefile      | 22.48        | 23          | 41         |
124 | | pyinstaller_onedir  | 46.07        | 52          | 113        |
125 | | pyinstaller_onefile | 26.47        | 25          | 45         |
126 | 
127 | ![Bundle sizes](./assets/2024-01-13_native_binaries/image_2.png)
128 | _Figure: Bundle sizes of folders with executables build with Nuitka (onefile, onedir modes), PyInstaller (onefile, onedir modes)._
129 | 
130 | #### Preliminary Observations
131 | 
132 | - Nuitka's warmed up execution time is **fast**
133 | - Nuitka produces largest executables in `onedir` mode
134 | - Nuitka is the slowest to build (no charts for build benchmarks, this is observations based on CI build time from PoC, see links above)
135 | - PyInstaller produces smallest executables in `onedir` mode
136 | - PyInstaller is the fastest to build (no charts for build benchmarks, this is observations based on CI build time from PoC, see links above)
137 | 
138 | ### Honorable Mentions
139 | 
140 | #### cx_Freeze
141 | 
142 | cx_Freeze is a set of scripts and modules for freezing Python scripts into executables. It is similar to PyInstaller in many ways, but PyInstaller is preferred due to its more mature and comprehensive documentation.
143 | 
144 | #### PyOxidizer
145 | 
146 | PyOxidizer is a utility for producing binaries that embed Python. However, it is no longer actively maintained, which makes it a less desirable option for our needs.
147 | 
148 | ## Preferred option
149 | 
150 | Based on observations so far we are leaning towards an Option 1. Where we would use PyInstaller to build native binaries for Windows, Mac and Linux.
151 | 
152 | While `nuitka` in `onedir` mode is even faster than pip installed algokit, it generates larger executables, and is the slowest option in terms of build time. Pyinstaller is only marginally slower than `nuitka` or pip installed algokit in terms of execution time, has mature documentation, and is the fastest option to build (in `onedir` mode) and produces smaller executables than `nuitka`. Given that and the fact that `nuitka` does not support Python 3.12 yet and has a lot of `magical` optimizations hidden under the hood, we are leaning towards PyInstaller as the preferred option for building native binaries given its maturity and straightforwardness despite marginally slower execution time (which is not a big deal given that we are talking of deviations of 5-10 milliseconds).
153 | 
154 | ## Selected option
155 | 
156 | The team has formally pre-discussed this ADR and has agreed to proceed with Option 1 - PyInstaller.
157 | 
158 | ## Next Steps
159 | 
160 | - [ ] Finalize the decision on the preferred option.
161 | - [ ] Expand PoC and polish the github action to build native binaries for Windows, Mac and Linux for x86, x86-64 and ARM architectures.
162 | - [ ] Implement portability snapshot tests, expanding existing algokit cli snapshot tests by running against real executable covering main functionality to test and ensure that the native binaries are portable and behave the same way as pip installed algokit cli.
163 | - [ ] Submit follow up ADR to discuss strategies on how to distribute the binaries in most accessible, user friendly and secure way.
164 | 
```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/algokit:utils:typescript:code:modules:types_app_arc56.md:
--------------------------------------------------------------------------------

```markdown
  1 | [@algorandfoundation/algokit-utils](../README.md) / types/app-arc56
  2 | 
  3 | # Module: types/app-arc56
  4 | 
  5 | ## Table of contents
  6 | 
  7 | ### Classes
  8 | 
  9 | - [Arc56Method](../classes/types_app_arc56.Arc56Method.md)
 10 | 
 11 | ### Interfaces
 12 | 
 13 | - [Arc56Contract](../interfaces/types_app_arc56.Arc56Contract.md)
 14 | - [Event](../interfaces/types_app_arc56.Event.md)
 15 | - [Method](../interfaces/types_app_arc56.Method.md)
 16 | - [ProgramSourceInfo](../interfaces/types_app_arc56.ProgramSourceInfo.md)
 17 | - [StorageKey](../interfaces/types_app_arc56.StorageKey.md)
 18 | - [StorageMap](../interfaces/types_app_arc56.StorageMap.md)
 19 | - [StructField](../interfaces/types_app_arc56.StructField.md)
 20 | 
 21 | ### Type Aliases
 22 | 
 23 | - [ABIStruct](types_app_arc56.md#abistruct)
 24 | - [ABIType](types_app_arc56.md#abitype)
 25 | - [AVMBytes](types_app_arc56.md#avmbytes)
 26 | - [AVMString](types_app_arc56.md#avmstring)
 27 | - [AVMType](types_app_arc56.md#avmtype)
 28 | - [AVMUint64](types_app_arc56.md#avmuint64)
 29 | - [Arc56MethodArg](types_app_arc56.md#arc56methodarg)
 30 | - [Arc56MethodReturnType](types_app_arc56.md#arc56methodreturntype)
 31 | - [StructName](types_app_arc56.md#structname)
 32 | 
 33 | ### Functions
 34 | 
 35 | - [getABIDecodedValue](types_app_arc56.md#getabidecodedvalue)
 36 | - [getABIEncodedValue](types_app_arc56.md#getabiencodedvalue)
 37 | - [getABIStructFromABITuple](types_app_arc56.md#getabistructfromabituple)
 38 | - [getABITupleFromABIStruct](types_app_arc56.md#getabituplefromabistruct)
 39 | - [getABITupleTypeFromABIStructDefinition](types_app_arc56.md#getabitupletypefromabistructdefinition)
 40 | - [getArc56Method](types_app_arc56.md#getarc56method)
 41 | - [getArc56ReturnValue](types_app_arc56.md#getarc56returnvalue)
 42 | 
 43 | ## Type Aliases
 44 | 
 45 | ### ABIStruct
 46 | 
 47 | Ƭ **ABIStruct**: `Object`
 48 | 
 49 | Decoded ARC-56 struct as a struct rather than a tuple.
 50 | 
 51 | #### Index signature
 52 | 
 53 | ▪ [key: `string`]: [`ABIStruct`](types_app_arc56.md#abistruct) \| `algosdk.ABIValue`
 54 | 
 55 | #### Defined in
 56 | 
 57 | [src/types/app-arc56.ts:108](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L108)
 58 | 
 59 | ___
 60 | 
 61 | ### ABIType
 62 | 
 63 | Ƭ **ABIType**: `string`
 64 | 
 65 | An ABI-encoded type
 66 | 
 67 | #### Defined in
 68 | 
 69 | [src/types/app-arc56.ts:436](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L436)
 70 | 
 71 | ___
 72 | 
 73 | ### AVMBytes
 74 | 
 75 | Ƭ **AVMBytes**: ``"AVMBytes"``
 76 | 
 77 | Raw byteslice without the length prefixed that is specified in ARC-4
 78 | 
 79 | #### Defined in
 80 | 
 81 | [src/types/app-arc56.ts:442](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L442)
 82 | 
 83 | ___
 84 | 
 85 | ### AVMString
 86 | 
 87 | Ƭ **AVMString**: ``"AVMString"``
 88 | 
 89 | A utf-8 string without the length prefix that is specified in ARC-4
 90 | 
 91 | #### Defined in
 92 | 
 93 | [src/types/app-arc56.ts:445](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L445)
 94 | 
 95 | ___
 96 | 
 97 | ### AVMType
 98 | 
 99 | Ƭ **AVMType**: [`AVMBytes`](types_app_arc56.md#avmbytes) \| [`AVMString`](types_app_arc56.md#avmstring) \| [`AVMUint64`](types_app_arc56.md#avmuint64)
100 | 
101 | A native AVM type
102 | 
103 | #### Defined in
104 | 
105 | [src/types/app-arc56.ts:451](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L451)
106 | 
107 | ___
108 | 
109 | ### AVMUint64
110 | 
111 | Ƭ **AVMUint64**: ``"AVMUint64"``
112 | 
113 | A 64-bit unsigned integer
114 | 
115 | #### Defined in
116 | 
117 | [src/types/app-arc56.ts:448](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L448)
118 | 
119 | ___
120 | 
121 | ### Arc56MethodArg
122 | 
123 | Ƭ **Arc56MethodArg**: [`Expand`](types_expand.md#expand)\<`Omit`\<[`Method`](../interfaces/types_app_arc56.Method.md)[``"args"``][`number`], ``"type"``\> & \{ `type`: `algosdk.ABIArgumentType`  }\>
124 | 
125 | Type to describe an argument within an `Arc56Method`.
126 | 
127 | #### Defined in
128 | 
129 | [src/types/app-arc56.ts:6](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L6)
130 | 
131 | ___
132 | 
133 | ### Arc56MethodReturnType
134 | 
135 | Ƭ **Arc56MethodReturnType**: [`Expand`](types_expand.md#expand)\<`Omit`\<[`Method`](../interfaces/types_app_arc56.Method.md)[``"returns"``], ``"type"``\> & \{ `type`: `algosdk.ABIReturnType`  }\>
136 | 
137 | Type to describe a return type within an `Arc56Method`.
138 | 
139 | #### Defined in
140 | 
141 | [src/types/app-arc56.ts:13](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L13)
142 | 
143 | ___
144 | 
145 | ### StructName
146 | 
147 | Ƭ **StructName**: `string`
148 | 
149 | The name of a defined struct
150 | 
151 | #### Defined in
152 | 
153 | [src/types/app-arc56.ts:439](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L439)
154 | 
155 | ## Functions
156 | 
157 | ### getABIDecodedValue
158 | 
159 | ▸ **getABIDecodedValue**(`value`, `type`, `structs`): `algosdk.ABIValue` \| [`ABIStruct`](types_app_arc56.md#abistruct)
160 | 
161 | Returns the decoded ABI value (or struct for a struct type)
162 | for the given raw Algorand value given an ARC-56 type and defined ARC-56 structs.
163 | 
164 | #### Parameters
165 | 
166 | | Name | Type | Description |
167 | | :------ | :------ | :------ |
168 | | `value` | `number` \| `bigint` \| `Uint8Array` | The raw Algorand value (bytes or uint64) |
169 | | `type` | `string` | The ARC-56 type - either an ABI Type string or a struct name |
170 | | `structs` | `Record`\<`string`, [`StructField`](../interfaces/types_app_arc56.StructField.md)[]\> | The defined ARC-56 structs |
171 | 
172 | #### Returns
173 | 
174 | `algosdk.ABIValue` \| [`ABIStruct`](types_app_arc56.md#abistruct)
175 | 
176 | The decoded ABI value or struct
177 | 
178 | #### Defined in
179 | 
180 | [src/types/app-arc56.ts:120](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L120)
181 | 
182 | ___
183 | 
184 | ### getABIEncodedValue
185 | 
186 | ▸ **getABIEncodedValue**(`value`, `type`, `structs`): `Uint8Array`
187 | 
188 | Returns the ABI-encoded value for the given value.
189 | 
190 | #### Parameters
191 | 
192 | | Name | Type | Description |
193 | | :------ | :------ | :------ |
194 | | `value` | `ABIValue` \| [`ABIStruct`](types_app_arc56.md#abistruct) | The value to encode either already in encoded binary form (`Uint8Array`), a decoded ABI value or an ARC-56 struct |
195 | | `type` | `string` | The ARC-56 type - either an ABI Type string or a struct name |
196 | | `structs` | `Record`\<`string`, [`StructField`](../interfaces/types_app_arc56.StructField.md)[]\> | The defined ARC-56 structs |
197 | 
198 | #### Returns
199 | 
200 | `Uint8Array`
201 | 
202 | The binary ABI-encoded value
203 | 
204 | #### Defined in
205 | 
206 | [src/types/app-arc56.ts:142](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L142)
207 | 
208 | ___
209 | 
210 | ### getABIStructFromABITuple
211 | 
212 | ▸ **getABIStructFromABITuple**\<`TReturn`\>(`decodedABITuple`, `structFields`, `structs`): `TReturn`
213 | 
214 | Converts a decoded ABI tuple as a struct.
215 | 
216 | #### Type parameters
217 | 
218 | | Name | Type |
219 | | :------ | :------ |
220 | | `TReturn` | extends [`ABIStruct`](types_app_arc56.md#abistruct) = `Record`\<`string`, `any`\> |
221 | 
222 | #### Parameters
223 | 
224 | | Name | Type | Description |
225 | | :------ | :------ | :------ |
226 | | `decodedABITuple` | `ABIValue`[] | The decoded ABI tuple value |
227 | | `structFields` | [`StructField`](../interfaces/types_app_arc56.StructField.md)[] | The struct fields from an ARC-56 app spec |
228 | | `structs` | `Record`\<`string`, [`StructField`](../interfaces/types_app_arc56.StructField.md)[]\> | - |
229 | 
230 | #### Returns
231 | 
232 | `TReturn`
233 | 
234 | The struct as a Record<string, any>
235 | 
236 | #### Defined in
237 | 
238 | [src/types/app-arc56.ts:70](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L70)
239 | 
240 | ___
241 | 
242 | ### getABITupleFromABIStruct
243 | 
244 | ▸ **getABITupleFromABIStruct**(`struct`, `structFields`, `structs`): `algosdk.ABIValue`[]
245 | 
246 | Converts an ARC-56 struct as an ABI tuple.
247 | 
248 | #### Parameters
249 | 
250 | | Name | Type | Description |
251 | | :------ | :------ | :------ |
252 | | `struct` | [`ABIStruct`](types_app_arc56.md#abistruct) | The struct to convert |
253 | | `structFields` | [`StructField`](../interfaces/types_app_arc56.StructField.md)[] | The struct fields from an ARC-56 app spec |
254 | | `structs` | `Record`\<`string`, [`StructField`](../interfaces/types_app_arc56.StructField.md)[]\> | - |
255 | 
256 | #### Returns
257 | 
258 | `algosdk.ABIValue`[]
259 | 
260 | The struct as a decoded ABI tuple
261 | 
262 | #### Defined in
263 | 
264 | [src/types/app-arc56.ts:94](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L94)
265 | 
266 | ___
267 | 
268 | ### getABITupleTypeFromABIStructDefinition
269 | 
270 | ▸ **getABITupleTypeFromABIStructDefinition**(`struct`, `structs`): `algosdk.ABITupleType`
271 | 
272 | Returns the `ABITupleType` for the given ARC-56 struct definition
273 | 
274 | #### Parameters
275 | 
276 | | Name | Type | Description |
277 | | :------ | :------ | :------ |
278 | | `struct` | [`StructField`](../interfaces/types_app_arc56.StructField.md)[] | The ARC-56 struct definition |
279 | | `structs` | `Record`\<`string`, [`StructField`](../interfaces/types_app_arc56.StructField.md)[]\> | - |
280 | 
281 | #### Returns
282 | 
283 | `algosdk.ABITupleType`
284 | 
285 | The `ABITupleType`
286 | 
287 | #### Defined in
288 | 
289 | [src/types/app-arc56.ts:48](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L48)
290 | 
291 | ___
292 | 
293 | ### getArc56Method
294 | 
295 | ▸ **getArc56Method**(`methodNameOrSignature`, `appSpec`): [`Arc56Method`](../classes/types_app_arc56.Arc56Method.md)
296 | 
297 | Returns the ARC-56 ABI method object for a given method name or signature and ARC-56 app spec.
298 | 
299 | #### Parameters
300 | 
301 | | Name | Type | Description |
302 | | :------ | :------ | :------ |
303 | | `methodNameOrSignature` | `string` | The method name or method signature to call if an ABI call is being emitted. e.g. `my_method` or `my_method(unit64,string)bytes` |
304 | | `appSpec` | [`Arc56Contract`](../interfaces/types_app_arc56.Arc56Contract.md) | The app spec for the app |
305 | 
306 | #### Returns
307 | 
308 | [`Arc56Method`](../classes/types_app_arc56.Arc56Method.md)
309 | 
310 | The `Arc56Method`
311 | 
312 | #### Defined in
313 | 
314 | [src/types/app-arc56.ts:172](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L172)
315 | 
316 | ___
317 | 
318 | ### getArc56ReturnValue
319 | 
320 | ▸ **getArc56ReturnValue**\<`TReturn`\>(`returnValue`, `method`, `structs`): `TReturn`
321 | 
322 | Checks for decode errors on the AppCallTransactionResult and maps the return value to the specified generic type
323 | 
324 | #### Type parameters
325 | 
326 | | Name | Type |
327 | | :------ | :------ |
328 | | `TReturn` | extends `undefined` \| `ABIValue` \| [`ABIStruct`](types_app_arc56.md#abistruct) |
329 | 
330 | #### Parameters
331 | 
332 | | Name | Type | Description |
333 | | :------ | :------ | :------ |
334 | | `returnValue` | `undefined` \| [`ABIReturn`](types_app.md#abireturn) | The smart contract response |
335 | | `method` | [`Method`](../interfaces/types_app_arc56.Method.md) \| [`Arc56Method`](../classes/types_app_arc56.Arc56Method.md) | The method that was called |
336 | | `structs` | `Record`\<`string`, [`StructField`](../interfaces/types_app_arc56.StructField.md)[]\> | The struct fields from the app spec |
337 | 
338 | #### Returns
339 | 
340 | `TReturn`
341 | 
342 | The smart contract response with an updated return value
343 | 
344 | #### Defined in
345 | 
346 | [src/types/app-arc56.ts:203](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L203)
347 | 
```
Page 34/93FirstPrevNextLast