#
tokens: 48504/50000 11/942 files (page 24/74)
lines: off (toggle) GitHub
raw markdown copy
This is page 24 of 74. Use http://codebase.md/goplausible/algorand-mcp?lines=false&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/src/tools/apiManager/indexer/application.ts:
--------------------------------------------------------------------------------

```typescript
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
import { indexerClient } from '../../../algorand-client.js';
import { ResponseProcessor } from '../../../utils/responseProcessor.js';
import type { 
  ApplicationResponse,
  ApplicationsResponse,
  ApplicationLogsResponse,
  Box
} from 'algosdk/dist/types/client/v2/indexer/models/types';
import algosdk from 'algosdk';

export const applicationTools = [
  {
    name: 'api_indexer_lookup_applications',
    description: 'Get application information from indexer',
    inputSchema: {
      type: 'object',
      properties: {
        appId: {
          type: 'integer',
          description: 'Application ID'
        }
      },
      required: ['appId']
    }
  },
  {
    name: 'api_indexer_lookup_application_logs',
    description: 'Get application log messages',
    inputSchema: {
      type: 'object',
      properties: {
        appId: {
          type: 'integer',
          description: 'Application ID'
        },
        limit: {
          type: 'integer',
          description: 'Maximum number of logs to return'
        },
        minRound: {
          type: 'integer',
          description: 'Only return logs after this round'
        },
        maxRound: {
          type: 'integer',
          description: 'Only return logs before this round'
        },
        txid: {
          type: 'string',
          description: 'Filter by transaction ID'
        },
        sender: {
          type: 'string',
          description: 'Filter by sender address'
        },
        nextToken: {
          type: 'string',
          description: 'Token for retrieving the next page of results'
        }
      },
      required: ['appId']
    }
  },
  {
    name: 'api_indexer_search_for_applications',
    description: 'Search for applications with various criteria',
    inputSchema: {
      type: 'object',
      properties: {
        limit: {
          type: 'integer',
          description: 'Maximum number of applications to return'
        },
        creator: {
          type: 'string',
          description: 'Filter by creator address'
        },
        nextToken: {
          type: 'string',
          description: 'Token for retrieving the next page of results'
        }
      }
    }
  },
  {
    name: 'api_indexer_lookup_application_box',
    description: 'Get application box by name',
    inputSchema: {
      type: 'object',
      properties: {
        appId: {
          type: 'integer',
          description: 'Application ID'
        },
        boxName: {
          type: 'string',
          description: 'Box name Buffer'
        }
      },
      required: ['appId', 'boxName']
    }
  },
  {
    name: 'api_indexer_lookup_application_boxes',
    description: 'Get all application boxes',
    inputSchema: {
      type: 'object',
      properties: {
        appId: {
          type: 'integer',
          description: 'Application ID'
        },
        maxBoxes: {
          type: 'integer',
          description: 'Maximum number of boxes to return'
        }
      },
      required: ['appId']
    }
  }
];

export async function lookupApplications(appId: number): Promise<ApplicationResponse> {
  try {
    console.log(`Looking up application info for ID ${appId}`);
    const response = await indexerClient.lookupApplications(appId).do() as ApplicationResponse;
    console.log('Application response:', JSON.stringify(response, null, 2));
    return response;
  } catch (error) {
    console.error('Application lookup error:', error);
    if (error instanceof McpError) {
      throw error;
    }
    throw new McpError(
      ErrorCode.InternalError,
      `Failed to get application info: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

export async function lookupApplicationLogs(appId: number, params?: {
  limit?: number;
  minRound?: number;
  maxRound?: number;
  txid?: string;
  sender?: string;
  nextToken?: string;
}): Promise<ApplicationLogsResponse> {
  try {
    console.log(`Looking up logs for application ${appId}`);
    let search = indexerClient.lookupApplicationLogs(appId);

    if (params?.limit) {
      search = search.limit(params.limit);
    }
    if (params?.minRound) {
      search = search.minRound(params.minRound);
    }
    if (params?.maxRound) {
      search = search.maxRound(params.maxRound);
    }
    if (params?.txid) {
      search = search.txid(params.txid);
    }
    if (params?.sender) {
      search = search.sender(params.sender);
    }
    if (params?.nextToken) {
      search = search.nextToken(params.nextToken);
    }

    const response = await search.do() as ApplicationLogsResponse;
    console.log('Application logs response:', JSON.stringify(response, null, 2));
    return response;
  } catch (error) {
    console.error('Application logs lookup error:', error);
    if (error instanceof McpError) {
      throw error;
    }
    throw new McpError(
      ErrorCode.InternalError,
      `Failed to get application logs: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

export async function searchForApplications(params?: {
  limit?: number;
  creator?: string;
  nextToken?: string;
}): Promise<ApplicationsResponse> {
  try {
    console.log('Searching applications with params:', params);
    let search = indexerClient.searchForApplications();

    if (params?.limit) {
      search = search.limit(params.limit);
    }
    if (params?.creator) {
      search = search.creator(params.creator);
    }
    if (params?.nextToken) {
      search = search.nextToken(params.nextToken);
    }

    const response = await search.do() as ApplicationsResponse;
    console.log('Search applications response:', JSON.stringify(response, null, 2));
    return response;
  } catch (error) {
    console.error('Search applications error:', error);
    if (error instanceof McpError) {
      throw error;
    }
    throw new McpError(
      ErrorCode.InternalError,
      `Failed to search applications: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

export async function lookupApplicationBoxByIDandName(appId: number, boxName: string): Promise<Box> {
  try {
    let boxNameBytes: Buffer;

    // Check if string is a valid number
    if (!isNaN(Number(boxName))) {
      boxNameBytes = Buffer.from(boxName);
    }
    // Check if string is a valid Algorand address
    else if (algosdk.isValidAddress(boxName)) {
      boxNameBytes = Buffer.from(boxName);
    }
    // Try to decode as base64, if it fails then treat as regular string
    else {
      try {
        // Test if the string is valid base64
        Buffer.from(boxName, 'base64').toString('base64');
        // If we get here, it's valid base64
        boxNameBytes = Buffer.from(boxName, 'base64');
      } catch {
        // If base64 decoding fails, treat as regular string
        boxNameBytes = Buffer.from(boxName);
      }
    }

    console.log('Box name bytes:', boxNameBytes);
    const response = await indexerClient.lookupApplicationBoxByIDandName(appId, boxNameBytes).do() as Box;
    console.log('Box response:', JSON.stringify(response, null, 2));
    return response;
  } catch (error) {
    console.error('Box fetch error:', error);
    if (error instanceof McpError) {
      throw error;
    }
    throw new McpError(
      ErrorCode.InternalError,
      `Failed to get application box: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

export async function searchForApplicationBoxes(appId: number, maxBoxes?: number): Promise<any> {
  try {
    console.log(`Searching boxes for application ${appId}`);
    let search = indexerClient.searchForApplicationBoxes(appId);
    if (maxBoxes !== undefined) {
      search = search.limit(maxBoxes);
    }
    const response = await search.do();
    console.log('Application boxes response:', JSON.stringify(response, null, 2));
    return response;
  } catch (error) {
    console.error('Application boxes fetch error:', error);
    if (error instanceof McpError) {
      throw error;
    }
    throw new McpError(
      ErrorCode.InternalError,
      `Failed to get application boxes: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

export const handleApplicationTools = ResponseProcessor.wrapResourceHandler(async function handleApplicationTools(args: any): Promise<any> {
  const name = args.name;
  
  switch (name) {
    case 'api_indexer_lookup_applications': {
      const { appId } = args;
      const info = await lookupApplications(appId);
      return info.application;
    }
    case 'api_indexer_lookup_application_logs': {
      const { appId, ...params } = args;
      const logs = await lookupApplicationLogs(appId, params);
      return logs;
    }
    case 'api_indexer_search_for_applications': {
      const info = await searchForApplications(args);
      return info.applications;
    }
    case 'api_indexer_lookup_application_box': {
      const { appId, boxName } = args;
      const box = await lookupApplicationBoxByIDandName(appId, boxName);
      return box;
    }
    case 'api_indexer_lookup_application_boxes': {
      const { appId, maxBoxes } = args;
      const boxes = await searchForApplicationBoxes(appId, maxBoxes);
      return boxes.boxes;
    }
    default:
      throw new McpError(
        ErrorCode.MethodNotFound,
        `Unknown tool: ${name}`
      );
  }
});

```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/tealscript:FEATURES.md:
--------------------------------------------------------------------------------

```markdown
# Supported AVM Features

## ARCS
| ARC | Name | Description |
| --- | --- | --- |
| 4 | Application Binary Interface (ABI)	 | ABI method routing is automatically down for public methods. All ABI types are natively supported. Compiler outputs ARC4 JSON |
| 22 | Add `read-only` annotation to ABI methods | Decorating a method with `@abi.readonly` will mark it as readonly |
| 28 | Algorand Event Log Spec | Use `EventLogger` to log ARC28 events |
| 32 | Application Specification | Compiler generates an arc32 JSON file |

## ABI Types
| ABI Type | TEALScript |
| --- | --- |
| `address` | `Address` |
| `uintN` | `uint64`, `uint32`, `uint16`, `uint8`, `uint128`, `uint256`, or `uint<N>`. `AssetID` and `AppID` are encoded as `uint64` |
| `bool` | `boolean` |
| `ufixedNxM` | `ufixed<N, M>` |
| `T[]` | `T[]` |
| `T[N]` | `StaticArray<T, N>`. `bytes32`, `bytes64`, or `bytes<N> for static byte arrays` |
| `[T1, T2, ..., TN]` | `[T1, T2, ..., TN]` or `{keyone: T1, keytwo: T2, ..., keyN: TN}` |
| `string` | `string` |
| `application` | `AppReference` |
| `asset` | `AssetReference` |
| `account` | `AccountReference` |
| `txn` | `Txn` |
| `pay` | `PayTxn` |
| `keyreg` | `KeyRegTxn` |
| `acfg` | `AssetConfigTxn` |
| `axfer` | `AssetTransferTxn` |
| `afrz` | `AssetFreezeTxn` |
## Opcodes

### Flow Control
| Opcode | TEALScript |
| --- | --- |
| `err` | `throw Error()` |
| `bnz` | Used automatically in loops and conditionals |
| `bz` | Used automatically in loops and conditionals |
| `b` | Used automatically in loops and conditionals |
| `return` | Used when the top-level function returns |
| `assert` | `assert` |
| `bury` | Stack manipulation is not officially supported |
| `popn` | Stack manipulation is not officially supported |
| `dupn` | Stack manipulation is not officially supported |
| `pop` | Stack manipulation is not officially supported |
| `dup` | Stack manipulation is not officially supported |
| `dup2` | Stack manipulation is not officially supported |
| `dig` | Stack manipulation is not officially supported |
| `swap` | Stack manipulation is not officially supported |
| `select` | Not officially supported yet, but could be used to optimize conditionals in the future |
| `cover` | Stack manipulation is not officially supported |
| `uncover` | Stack manipulation is not officially supported |
| `callsub` | Used when calling a function |
| `retsub` | `return` |
| `proto` | Used automatically in functions |
| `frame_dig` | Used automatically in functions |
| `frame_bury` | Used automatically in functions |
| `switch` | Not officially supported yet, but could be used to optimize conditionals in the future |
| `match` | Not officially supported yet, but could be used to optimize conditionals in the future |

### Cryptography
| Opcode | TEALScript |
| --- | --- |
| `sha256` | `sha256` |
| `keccak256` | `keccak256` |
| `sha512_256` | `sha512_256` |
| `ed25519verify` | `ed25519Verify` |
| `ecdsa_verify` | `ecdsaVerify` |
| `ecdsa_pk_decompress` | `ecdsaPkDecompress` |
| `ecdsa_pk_recover` | `ecdsaPkRecover` |
| `ed25519verify_bare` | `ed25519VerifyBare` |
| `sha3_256` | `sha3_256` |
| `vrf_verify` | `vrfVerify` |
| `ec_add` | `ecAdd` |
| `ec_scalar_mul` | `ecScalarMul` |
| `ec_pairing_check` | `ecPairingCheck` |
| `ec_multi_scalar_mul` | `ecMultiScalarMul` |
| `ec_subgroup_check` | `ecSubgroupCheck` |
| `ec_map_to` | `ecMapTo` |

### Arithmetic
| Opcode | TEALScript |
| --- | --- |
| `+` | Natively supported |
| `-` | Natively supported |
| `/` | Natively supported |
| `*` | Natively supported |
| `<` | Natively supported |
| `>` | Natively supported |
| `<=` | Natively supported |
| `>=` | Natively supported |
| `&&` | Natively supported |
| `\|\|` | Natively supported |
| `==` | Natively supported |
| `!=` | Natively supported |
| `!` | Natively supported |
| `itob` | Natively supported |
| `btoi` | Natively supported |
| `%` | Natively supported |
| `\|` | Natively supported |
| `&` | Natively supported |
| `^` | Natively supported |
| `~` | Natively supported |
| `mulw` | `mulw` |
| `addw` | `addw` |
| `divmodw` | `divmodw` |
| `shl` | `<<` |
| `shr` | `>>` |
| `sqrt` | Natively supported |
| `bitlen` | `bitlen` |
| `exp` | `**` |
| `expw` | `expw` |
| `divw` | `divw` |

### Byte Array Manipulation
| Opcode | TEALScript |
| --- | --- |
| `len` | `.length` on bytes |
| `concat` | `concat` or `+` |
| `substring` | `String.substring` or `substring` |
| `substring3` | `String.substring` or `substring` |
| `getbit` | `getbit` |
| `setbit` | `setbit` |
| `getbyte` | `getbyte` |
| `setbyte` | `setbyte` |
| `extract` | `extract3` |
| `extract3` | `extract3` |
| `extract_uint16` | `extractUint16` |
| `extract_uint32` | `extractUint32` |
| `extract_uint64` | `extractUint64` |
| `replace2` | `replace3` |
| `replace3` | `replace3` |
| `base64_decode` | `base64Decode` |
| `json_ref` | `jsonRef` |

### Loading Values
| Opcode | TEALScript |
| --- | --- |
| `intcblock` | Constant block not officially supported |
| `intc` | Constant block not officially supported |
| `intc_0` | Constant block not officially supported |
| `intc_1` | Constant block not officially supported |
| `intc_2` | Constant block not officially supported |
| `intc_3` | Constant block not officially supported |
| `bytecblock` | Constant block not officially supported |
| `bytec` | Constant block not officially supported |
| `bytec_0` | Constant block not officially supported |
| `bytec_1` | Constant block not officially supported |
| `bytec_2` | Constant block not officially supported |
| `bytec_3` | Constant block not officially supported |
| `arg` | `LogicSig.logic` arguments |
| `arg_0` | `LogicSig.logic` arguments |
| `arg_1` | `LogicSig.logic` arguments |
| `arg_2` | `LogicSig.logic` arguments |
| `arg_3` | `LogicSig.logic` arguments |
| `txn` | `this.txn` |
| `global` | `globals` |
| `gtxn` | `this.txnGroup` or transaction argument |
| `load` | `ScratchSlot` |
| `store` | `ScratchSlot` |
| `txna` | `this.txn` |
| `gtxna` | `this.txnGroup` or transaction argument |
| `gtxns` | `this.txnGroup` or transaction argument |
| `gtxnsa` | `this.txnGroup` or transaction argument |
| `gload` | `Txn.load` |
| `gloads` | `Txn.load` |
| `gaid` | `this.txnGroup` or transaction argument |
| `gaids` | `this.txnGroup` or transaction argument |
| `loads` | `ScratchSlot` |
| `stores` | `ScratchSlot` |
| `pushbytes` | Used by `TemplateVar` |
| `pushint` | Used by `TemplateVar` |
| `pushbytess` | Not used yet, but could be used for optimizations in future |
| `pushints` | Not used yet, but could be used for optimizations in future |
| `bzero` | `bzero` |
| `txnas` | `this.txn` |
| `gtxnas` | `this.txnGroup` or transaction argument |
| `gtxnsas` | `this.txnGroup` or transaction argument |
| `args` | `LogicSig.logic` arguments |
| `gloadss` | `Txn.load` |

### State Access
| Opcode | TEALScript |
| --- | --- |
| `balance` | `Address.balance` and `Address.hasBalance` |
| `app_opted_in` | `Address.isOptedInToApp()` |
| `app_local_get` | Method call on LocalStateKey on `LocalStateMap` |
| `app_local_get_ex` | `Application.local()` |
| `app_global_get` | Method call on `GlobalStateKey` on `GlobalStateMap` |
| `app_global_get_ex` | `Application.global()` |
| `app_local_put` | Method call on LocalStateKey on `LocalStateMap` |
| `app_global_put` | Method call on `GlobalStateKey` on `GlobalStateMap` |
| `app_local_del` | Method call on LocalStateKey on `LocalStateMap` |
| `app_global_del` | Method call on `GlobalStateKey` on `GlobalStateMap` |
| `asset_holding_get` | `Address.assetBalance` and `Address.hasAsset` |
| `asset_params_get` | Method calls on `Asset` |
| `app_params_get` | Method calls on `Application` |
| `acct_params_get` | Method calls on `Address` |
| `min_balance` | `Address.minBalance` |
| `log` | `log` or `EventEmitter` |
| `block` | `blocks` |

### Byte Array Arithmetic
| Opcode | TEALScript |
| --- | --- |
| `bsqrt` | Natively supported |
| `b+` | Natively supported |
| `b-` | Natively supported |
| `b/` | Natively supported |
| `b*` | Natively supported |
| `b<` | Natively supported |
| `b>` | Natively supported |
| `b<=` | Natively supported |
| `b>=` | Natively supported |
| `b==` | Natively supported |
| `b!=` | Natively supported |
| `b%` | Natively supported |

### Byte Array Logic
| Opcode | TEALScript |
| --- | --- |
| `b\|` | Natively supported |
| `b&` | Natively supported |
| `b^` | Natively supported |
| `b~` | Natively supported |

### Inner Transactions
| Opcode | TEALScript |
| --- | --- |
| `itxn_begin` | `this.pendingGroup.add...` or `send...` |
| `itxn_field` | `this.pendingGroup.add...` or `send...` |
| `itxn_submit` | `this.pendingGroup.execute` or `send...` |
| `itxn` | `this.itxn` |
| `itxna` | `this.itxn` |
| `itxn_next` | `this.pendingGroup.add...` |
| `gitxn` | `this.lastInnerGroup` |
| `gitxna` | `this.lastInnerGroup` |
| `itxnas` | `this.itxn` |
| `gitxnas` | `this.lastInnerGroup` |

### Box Access
| Opcode | TEALScript |
| --- | --- |
| `box_create` | Method call on `BoxKey` or `BoxMap` |
| `box_extract` | Method call on `BoxKey` or `BoxMap` |
| `box_replace` | Method call on `BoxKey` or `BoxMap` |
| `box_del` | Method call on `BoxKey` or `BoxMap` |
| `box_len` | Method call on `BoxKey` or `BoxMap` |
| `box_get` | Method call on `BoxKey` or `BoxMap` |
| `box_put` | Method call on `BoxKey` or `BoxMap` |
| `box_splice` | Method call on `BoxKey` or `BoxMap` |
| `box_resize` | Method call on `BoxKey` or `BoxMap` |
```

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

```markdown
[@algorandfoundation/algokit-utils](../README.md) / types/app

# Module: types/app

## Table of contents

### Enumerations

- [OnSchemaBreak](../enums/types_app.OnSchemaBreak.md)
- [OnUpdate](../enums/types_app.OnUpdate.md)

### Interfaces

- [AppCallParams](../interfaces/types_app.AppCallParams.md)
- [AppCallTransactionResultOfType](../interfaces/types_app.AppCallTransactionResultOfType.md)
- [AppCompilationResult](../interfaces/types_app.AppCompilationResult.md)
- [AppDeployMetadata](../interfaces/types_app.AppDeployMetadata.md)
- [AppDeploymentParams](../interfaces/types_app.AppDeploymentParams.md)
- [AppLookup](../interfaces/types_app.AppLookup.md)
- [AppMetadata](../interfaces/types_app.AppMetadata.md)
- [AppReference](../interfaces/types_app.AppReference.md)
- [AppState](../interfaces/types_app.AppState.md)
- [AppStorageSchema](../interfaces/types_app.AppStorageSchema.md)
- [BoxName](../interfaces/types_app.BoxName.md)
- [BoxReference](../interfaces/types_app.BoxReference.md)
- [BoxValueRequestParams](../interfaces/types_app.BoxValueRequestParams.md)
- [BoxValuesRequestParams](../interfaces/types_app.BoxValuesRequestParams.md)
- [CompiledTeal](../interfaces/types_app.CompiledTeal.md)
- [CoreAppCallArgs](../interfaces/types_app.CoreAppCallArgs.md)
- [CreateAppParams](../interfaces/types_app.CreateAppParams.md)
- [RawAppCallArgs](../interfaces/types_app.RawAppCallArgs.md)
- [TealTemplateParams](../interfaces/types_app.TealTemplateParams.md)
- [UpdateAppParams](../interfaces/types_app.UpdateAppParams.md)

### Type Aliases

- [ABIAppCallArg](types_app.md#abiappcallarg)
- [ABIAppCallArgs](types_app.md#abiappcallargs)
- [ABIReturn](types_app.md#abireturn)
- [AppCallArgs](types_app.md#appcallargs)
- [AppCallTransactionResult](types_app.md#appcalltransactionresult)
- [AppCallType](types_app.md#appcalltype)
- [AppReturn](types_app.md#appreturn)
- [BoxIdentifier](types_app.md#boxidentifier)
- [SendAppCreateTransactionResult](types_app.md#sendappcreatetransactionresult)
- [SendAppTransactionResult](types_app.md#sendapptransactionresult)
- [SendAppUpdateTransactionResult](types_app.md#sendappupdatetransactionresult)

### Variables

- [ABI\_RETURN\_PREFIX](types_app.md#abi_return_prefix)
- [APP\_DEPLOY\_NOTE\_DAPP](types_app.md#app_deploy_note_dapp)
- [APP\_PAGE\_MAX\_SIZE](types_app.md#app_page_max_size)
- [DELETABLE\_TEMPLATE\_NAME](types_app.md#deletable_template_name)
- [UPDATABLE\_TEMPLATE\_NAME](types_app.md#updatable_template_name)

## Type Aliases

### ABIAppCallArg

Ƭ **ABIAppCallArg**: `ABIArgument` \| [`TransactionToSign`](../interfaces/types_transaction.TransactionToSign.md) \| `Transaction` \| `Promise`\<[`SendTransactionResult`](../interfaces/types_transaction.SendTransactionResult.md)\> \| [`SendTransactionResult`](../interfaces/types_transaction.SendTransactionResult.md) \| `undefined`

An argument for an ABI method, either a primitive value, or a transaction with or without signer, or the unawaited async return value of an algokit method that returns a `SendTransactionResult`

#### Defined in

[src/types/app.ts:102](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app.ts#L102)

___

### ABIAppCallArgs

Ƭ **ABIAppCallArgs**: [`CoreAppCallArgs`](../interfaces/types_app.CoreAppCallArgs.md) & \{ `method`: `ABIMethodParams` \| `ABIMethod` ; `methodArgs`: [`ABIAppCallArg`](types_app.md#abiappcallarg)[]  }

App call args for an ABI call

#### Defined in

[src/types/app.ts:113](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app.ts#L113)

___

### ABIReturn

Ƭ **ABIReturn**: \{ `decodeError`: `undefined` ; `method`: `ABIMethod` ; `rawReturnValue`: `Uint8Array` ; `returnValue`: `ABIValue`  } \| \{ `decodeError`: `Error` ; `method?`: `undefined` ; `rawReturnValue?`: `undefined` ; `returnValue?`: `undefined`  }

The return value of an ABI method call

#### Defined in

[src/types/app.ts:235](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app.ts#L235)

___

### AppCallArgs

Ƭ **AppCallArgs**: [`RawAppCallArgs`](../interfaces/types_app.RawAppCallArgs.md) \| [`ABIAppCallArgs`](types_app.md#abiappcallargs)

Arguments to pass to an app call either:
  * The raw app call values to pass through into the transaction (after processing); or
  * An ABI method definition (method and args)

#### Defined in

[src/types/app.ts:124](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app.ts#L124)

___

### AppCallTransactionResult

Ƭ **AppCallTransactionResult**: [`AppCallTransactionResultOfType`](../interfaces/types_app.AppCallTransactionResultOfType.md)\<[`ABIReturn`](types_app.md#abireturn)\>

Result from calling an app

#### Defined in

[src/types/app.ts:232](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app.ts#L232)

___

### AppCallType

Ƭ **AppCallType**: ``"no_op"`` \| ``"opt_in"`` \| ``"close_out"`` \| ``"clear_state"`` \| ``"update_application"`` \| ``"delete_application"``

**`Deprecated`**

Use `algosdk.OnApplicationComplete` directly instead.

The type of call / [on-completion action](https://developer.algorand.org/docs/get-details/dapps/smart-contracts/apps/#the-lifecycle-of-a-smart-contract) for a smart contract call.

Equivalent of `algosdk.OnApplicationComplete`, but as a more convenient string enum.

* `no_op`: Normal smart contract call, no special on-complete action
* `opt_in`: Opt-in to smart contract local storage
* `close_out`: Close-out local storage storage
* `clear_state`: Clear local storage state
* `update_application`: Update the smart contract
* `delete_application`: Delete the smart contract

#### Defined in

[src/types/app.ts:180](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app.ts#L180)

___

### AppReturn

Ƭ **AppReturn**\<`TReturn`\>: `Object`

#### Type parameters

| Name |
| :------ |
| `TReturn` |

#### Type declaration

| Name | Type | Description |
| :------ | :------ | :------ |
| `return?` | `TReturn` | The ABI method call return value |

#### Defined in

[src/types/app.ts:340](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app.ts#L340)

___

### BoxIdentifier

Ƭ **BoxIdentifier**: `string` \| `Uint8Array` \| [`SendTransactionFrom`](types_transaction.md#sendtransactionfrom)

**`Deprecated`**

Use `types/app-manager/BoxIdentifier` instead.

Something that identifies a box name - either a:
 * `Uint8Array`
 * `string` (that will be encoded to a Uint8Array)
 * `SendTransactionFrom` (encoded into the public key address of the corresponding account)

#### Defined in

[src/types/app.ts:70](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app.ts#L70)

___

### SendAppCreateTransactionResult

Ƭ **SendAppCreateTransactionResult**: [`Expand`](types_expand.md#expand)\<[`SendAppUpdateTransactionResult`](types_app.md#sendappupdatetransactionresult) & \{ `appAddress`: `Address` ; `appId`: `bigint`  }\>

Result from sending a single app transaction.

#### Defined in

[src/types/app.ts:357](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app.ts#L357)

___

### SendAppTransactionResult

Ƭ **SendAppTransactionResult**: [`Expand`](types_expand.md#expand)\<[`SendSingleTransactionResult`](types_transaction.md#sendsingletransactionresult) & \{ `return?`: [`ABIReturn`](types_app.md#abireturn)  }\>

Result from sending a single app transaction.

#### Defined in

[src/types/app.ts:346](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app.ts#L346)

___

### SendAppUpdateTransactionResult

Ƭ **SendAppUpdateTransactionResult**: [`Expand`](types_expand.md#expand)\<[`SendAppTransactionResult`](types_app.md#sendapptransactionresult) & `Partial`\<[`AppCompilationResult`](../interfaces/types_app.AppCompilationResult.md)\>\>

Result from sending a single app transaction.

#### Defined in

[src/types/app.ts:354](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app.ts#L354)

## Variables

### ABI\_RETURN\_PREFIX

• `Const` **ABI\_RETURN\_PREFIX**: `Uint8Array`

First 4 bytes of SHA-512/256 hash of "return" for retrieving ABI return values

#### Defined in

[src/types/app.ts:36](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app.ts#L36)

___

### APP\_DEPLOY\_NOTE\_DAPP

• `Const` **APP\_DEPLOY\_NOTE\_DAPP**: ``"ALGOKIT_DEPLOYER"``

The app create/update [ARC-2](https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0002.md) transaction note prefix

#### Defined in

[src/types/app.ts:30](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app.ts#L30)

___

### APP\_PAGE\_MAX\_SIZE

• `Const` **APP\_PAGE\_MAX\_SIZE**: ``2048``

The maximum number of bytes in a single app code page

#### Defined in

[src/types/app.ts:33](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app.ts#L33)

___

### DELETABLE\_TEMPLATE\_NAME

• `Const` **DELETABLE\_TEMPLATE\_NAME**: ``"TMPL_DELETABLE"``

The name of the TEAL template variable for deploy-time permanence control

#### Defined in

[src/types/app.ts:27](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app.ts#L27)

___

### UPDATABLE\_TEMPLATE\_NAME

• `Const` **UPDATABLE\_TEMPLATE\_NAME**: ``"TMPL_UPDATABLE"``

The name of the TEAL template variable for deploy-time immutability control

#### Defined in

[src/types/app.ts:24](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app.ts#L24)

```

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

```markdown
# Transactions

The testing framework follows the Transaction definitions described in [`algorand-python` docs](https://algorand-python.readthedocs.io/en/latest/algorand_sdk/transactions.html). This section focuses on _value generators_ and interactions with inner transactions, it also explains how the framework identifies _active_ transaction group during contract method/subroutine/logicsig invocation.

```{testsetup}
import algopy
import algopy_testing
from algopy_testing import algopy_testing_context

# Create the context manager for snippets below
ctx_manager = algopy_testing_context()

# Enter the context
context = ctx_manager.__enter__()
```

## Group Transactions

Refers to test implementation of transaction stubs available under `algopy.gtxn.*` namespace. Available under [`algopy.TxnValueGenerator`](../api.md) instance accessible via `context.any.txn` property:

```{mermaid}
graph TD
    A[TxnValueGenerator] --> B[payment]
    A --> C[asset_transfer]
    A --> D[application_call]
    A --> E[asset_config]
    A --> F[key_registration]
    A --> G[asset_freeze]
    A --> H[transaction]
```

```{testcode}
... # instantiate test context

# Generate a random payment transaction
pay_txn = context.any.txn.payment(
    sender=context.any.account(),  # Optional: Defaults to context's default sender if not provided
    receiver=context.any.account(),  # Required
    amount=algopy.UInt64(1000000)  # Required
)

# Generate a random asset transfer transaction
asset_transfer_txn = context.any.txn.asset_transfer(
    sender=context.any.account(),  # Optional: Defaults to context's default sender if not provided
    receiver=context.any.account(),  # Required
    asset_id=algopy.UInt64(1),  # Required
    amount=algopy.UInt64(1000)  # Required
)

# Generate a random application call transaction
app_call_txn = context.any.txn.application_call(
    app_id=context.any.application(),  # Required
    app_args=[algopy.Bytes(b"arg1"), algopy.Bytes(b"arg2")],  # Optional: Defaults to empty list if not provided
    accounts=[context.any.account()],  # Optional: Defaults to empty list if not provided
    assets=[context.any.asset()],  # Optional: Defaults to empty list if not provided
    apps=[context.any.application()],  # Optional: Defaults to empty list if not provided
    approval_program_pages=[algopy.Bytes(b"approval_code")],  # Optional: Defaults to empty list if not provided
    clear_state_program_pages=[algopy.Bytes(b"clear_code")],  # Optional: Defaults to empty list if not provided
    scratch_space={0: algopy.Bytes(b"scratch")}  # Optional: Defaults to empty dict if not provided
)

# Generate a random asset config transaction
asset_config_txn = context.any.txn.asset_config(
    sender=context.any.account(),  # Optional: Defaults to context's default sender if not provided
    asset_id=algopy.UInt64(1),  # Optional: If not provided, creates a new asset
    total=1000000,  # Required for new assets
    decimals=0,  # Required for new assets
    default_frozen=False,  # Optional: Defaults to False if not provided
    unit_name="UNIT",  # Optional: Defaults to empty string if not provided
    asset_name="Asset",  # Optional: Defaults to empty string if not provided
    url="http://asset-url",  # Optional: Defaults to empty string if not provided
    metadata_hash=b"metadata_hash",  # Optional: Defaults to empty bytes if not provided
    manager=context.any.account(),  # Optional: Defaults to sender if not provided
    reserve=context.any.account(),  # Optional: Defaults to zero address if not provided
    freeze=context.any.account(),  # Optional: Defaults to zero address if not provided
    clawback=context.any.account()  # Optional: Defaults to zero address if not provided
)

# Generate a random key registration transaction
key_reg_txn = context.any.txn.key_registration(
    sender=context.any.account(),  # Optional: Defaults to context's default sender if not provided
    vote_pk=algopy.Bytes(b"vote_pk"),  # Optional: Defaults to empty bytes if not provided
    selection_pk=algopy.Bytes(b"selection_pk"),  # Optional: Defaults to empty bytes if not provided
    vote_first=algopy.UInt64(1),  # Optional: Defaults to 0 if not provided
    vote_last=algopy.UInt64(1000),  # Optional: Defaults to 0 if not provided
    vote_key_dilution=algopy.UInt64(10000)  # Optional: Defaults to 0 if not provided
)

# Generate a random asset freeze transaction
asset_freeze_txn = context.any.txn.asset_freeze(
    sender=context.any.account(),  # Optional: Defaults to context's default sender if not provided
    asset_id=algopy.UInt64(1),  # Required
    freeze_target=context.any.account(),  # Required
    freeze_state=True  # Required
)

# Generate a random transaction of a specified type
generic_txn = context.any.txn.transaction(
    type=algopy.TransactionType.Payment,  # Required
    sender=context.any.account(),  # Optional: Defaults to context's default sender if not provided
    receiver=context.any.account(),  # Required for Payment
    amount=algopy.UInt64(1000000)  # Required for Payment
)
```

## Preparing for execution

When a smart contract instance (application) is interacted with on the Algorand network, it must be performed in relation to a specific transaction or transaction group where one or many transactions are application calls to target smart contract instances.

To emulate this behaviour, the `create_group` context manager is available on [`algopy.TransactionContext`](../api.md) instance that allows setting temporary transaction fields within a specific scope, passing in emulated transaction objects and identifying the active transaction index within the transaction group

```{testcode}
import algopy
from algopy_testing import AlgopyTestContext, algopy_testing_context

class SimpleContract(algopy.ARC4Contract):
    @algopy.arc4.abimethod
    def check_sender(self) -> algopy.arc4.Address:
        return algopy.arc4.Address(algopy.Txn.sender)
...

# Create a contract instance
contract = SimpleContract()
# Use active_txn_overrides to change the sender
test_sender = context.any.account()
with context.txn.create_group(active_txn_overrides={"sender": test_sender}):
    # Call the contract method
    result = contract.check_sender()
assert result == test_sender

# Assert that the sender is the test_sender after exiting the
# transaction group context
assert context.txn.last_active.sender == test_sender
# Assert the size of last transaction group
assert len(context.txn.last_group.txns) == 1
```

## Inner Transaction

Inner transactions are AVM transactions that are signed and executed by AVM applications (instances of deployed smart contracts or signatures).

When testing smart contracts, to stay consistent with AVM, the framework \_does not allow you to submit inner transactions outside of contract/subroutine invocation, but you can interact with and manage inner transactions using the test context manager as follows:

```{testcode}
class MyContract(algopy.ARC4Contract):
    @algopy.arc4.abimethod
    def pay_via_itxn(self, asset: algopy.Asset) -> None:
        algopy.itxn.Payment(
            receiver=algopy.Txn.sender,
            amount=algopy.UInt64(1)
        ).submit()

... # setup context (below assumes available under 'context' variable)

# Create a contract instance
contract = MyContract()

# Generate a random asset
asset = context.any.asset()

# Execute the contract method
contract.pay_via_itxn(asset=asset)

# Access the last submitted inner transaction
payment_txn = context.txn.last_group.last_itxn.payment

# Assert properties of the inner transaction
assert payment_txn.receiver == context.txn.last_active.sender
assert payment_txn.amount == algopy.UInt64(1)

# Access all inner transactions in the last group
for itxn in context.txn.last_group.itxn_groups[-1]:
    # Perform assertions on each inner transaction
    ...

# Access a specific inner transaction group
first_itxn_group = context.txn.last_group.get_itxn_group(0)
first_payment_txn = first_itxn_group.payment(0)
```

In this example, we define a contract method `pay_via_itxn` that creates and submits an inner payment transaction. The test context automatically captures and stores the inner transactions submitted by the contract method.

Note that we don't need to wrap the execution in a `create_group` context manager because the method is decorated with `@algopy.arc4.abimethod`, which automatically creates a transaction group for the method. The `create_group` context manager is only needed when you want to create more complex transaction groups or patch transaction fields for various transaction-related opcodes in AVM.

To access the submitted inner transactions:

1. Use `context.txn.last_group.last_itxn` to access the last submitted inner transaction of a specific type.
2. Iterate over all inner transactions in the last group using `context.txn.last_group.itxn_groups[-1]`.
3. Access a specific inner transaction group using `context.txn.last_group.get_itxn_group(index)`.

These methods provide type validation and will raise an error if the requested transaction type doesn't match the actual type of the inner transaction.

## References

-   [API](../api.md) for more details on the test context manager and inner transactions related methods that perform implicit inner transaction type validation.
-   [Examples](../examples.md) for more examples of smart contracts and associated tests that interact with inner transactions.

```{testcleanup}
ctx_manager.__exit__(None, None, None)
```

```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/puya:docs:lg-storage.md:
--------------------------------------------------------------------------------

```markdown
# Storing data on-chain

Algorand smart contracts have [three different types of on-chain storage](https://developer.algorand.org/docs/get-details/dapps/smart-contracts/apps/state/)
they can utilise: [Global storage](#global-storage), [Local storage](#local-storage), [Box Storage](#box-storage), and [Scratch storage](#scratch-storage).

The life-cycle of a smart contract matches the semantics of Python classes when you consider
deploying a smart contract as "instantiating" the class. Any calls to that smart contract are made
to that instance of the smart contract, and any state assigned to `self.` variables will persist
across different invocations (provided the transaction it was a part of succeeds, of course). You can
deploy the same contract class multiple times, each will become a distinct and isolated instance.

During a single smart contract execution there is also the ability to use "temporary" storage
either global to the contract execution via [Scratch storage](#scratch-storage), or local to
the current method via [local variables and subroutine params](./lg-structure.md#subroutines).

## Global storage

Global storage is state that is stored against the contract instance and can be retrieved
by key. There are [AVM limits to the amount of global storage that can be allocated to a contract](https://developer.algorand.org/docs/get-details/dapps/smart-contracts/apps/state/#global-storage).

This is represented in Algorand Python by either:

1. Assigning any [Algorand Python typed](./lg-types.md) value to an instance variable (e.g. `self.value = UInt64(3)`)
2. Using an instance of `GlobalState`, which gives [some extra features](./api-algopy.md#algopy.GlobalState) to understand
   and control the value and the metadata of it (which propagates to the ARC-32 app spec file)

For example:

```python
self.global_int_full = GlobalState(UInt64(55), key="gif", description="Global int full")
self.global_int_simplified = UInt64(33)
self.global_int_no_default = GlobalState(UInt64)

self.global_bytes_full = GlobalState(Bytes(b"Hello"))
self.global_bytes_simplified = Bytes(b"Hello")
self.global_bytes_no_default = GlobalState(Bytes)

global_int_full_set = bool(self.global_int_full)
bytes_with_default_specified = self.global_bytes_no_default.get(b"Default if no value set")
int, is_set = self.global_int_simplified.maybe()
error_if_not_set = self.global_int_no_default.value
```

These values can be assigned anywhere you have access to `self` i.e. any instance methods/subroutines. The information about
global storage is automatically included in the ARC-32 app spec file and thus will automatically appear within
any [generated typed clients](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/generate.md#1-typed-clients).

## Local storage

Local storage is state that is stored against the contract instance for a specific account and can be retrieved
by key and account address. There are [AVM limits to the amount of local storage that can be allocated to a contract](https://developer.algorand.org/docs/get-details/dapps/smart-contracts/apps/state/#local-storage).

This is represented in Algorand Python by using an instance of [`LocalState`](./api-algopy.md#algopy.LocalState).

For example:

```python
def __init__(self) -> None:
    self.local = LocalState(Bytes)
    self.local_with_metadata = LocalState(UInt64, key = "lwm", description = "Local with metadata")

@subroutine
def get_guaranteed_data(self, for_account: Account) -> Bytes:
    return self.local[for_account]

@subroutine
def get_data_with_default(self, for_account: Account, default: Bytes) -> Bytes:
    return self.local.get(for_account, default)

@subroutine
def get_data_or_assert(self, for_account: Account) -> Bytes:
    result, exists = self.local.maybe(for_account)
    assert exists, "no data for account"
    return result

@subroutine
def set_data(self, for_account: Account, value: Bytes) -> None:
    self.local[for_account] = value

@subroutine
def delete_data(self, for_account: Account) -> None:
    del self.local[for_account]
```

These values can be assigned anywhere you have access to `self` i.e. any instance methods/subroutines. The information about
local storage is automatically included in the ARC-32 app spec file and thus will automatically appear within
any [generated typed clients](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/generate.md#1-typed-clients).

## Box storage

We provide 3 different types for accessing box storage: [Box](./api-algopy.md#algopy.Box), [BoxMap](./api-algopy.md#algopy.BoxMap), and [BoxRef](./api-algopy.md#algopy.BoxBlob). We also expose raw operations via the [AVM ops](./lg-ops.md) module.

Before using box storage, be sure to familiarise yourself with the [requirements and restrictions](https://developer.algorand.org/articles/smart-contract-storage-boxes/) of the underlying API.

The `Box` type provides an abstraction over storing a single value in a single box. A box can be declared against `self`
in an `__init__` method (in which case the key must be a compile time constant); or as a local variable within any 
subroutine. `Box` proxy instances can be passed around like any other value. 

Once declared, you can interact with the box via its instance methods.


```python
import typing as t
from algopy import Box, arc4, Contract, op


class MyContract(Contract):
    def __init__(self) -> None:
        self.box_a = Box(arc4.StaticArray[arc4.UInt32, t.Literal[20]], key=b"a")
    
    def approval_program(self) -> bool:
        box_b = Box(arc4.String, key=b"b")
        box_b.value = arc4.String("Hello")
        # Check if the box exists
        if self.box_a:
            # Reassign the value
            self.box_a.value[2] = arc4.UInt32(40)
        else:
            # Assign a new value
            self.box_a.value = arc4.StaticArray[arc4.UInt32, t.Literal[20]].from_bytes(op.bzero(20 * 4))
        # Read a value
        return self.box_a.value[4] == arc4.UInt32(2)    
```

`BoxMap` is similar to the `Box` type, but allows for grouping a set of boxes with a common key and content type. 
A custom `key_prefix` can optionally be provided, with the default being to use the variable name as the prefix. 
The key can be a `Bytes` value, or anything that can be converted to `Bytes`. The final box name is the combination of `key_prefix + key`.

```python
from algopy import BoxMap, Contract, Account, Txn, String

class MyContract(Contract):
    def __init__(self) -> None:
        self.my_map = BoxMap(Account, String, key_prefix=b"a_")
    
    def approval_program(self) -> bool:        
        # Check if the box exists
        if Txn.sender in self.my_map:
            # Reassign the value
            self.my_map[Txn.sender] = String(" World")
        else:
            # Assign a new value
            self.my_map[Txn.sender] = String("Hello")
        # Read a value
        return self.my_map[Txn.sender] == String("Hello World")
```

`BoxRef` is a specialised type for interacting with boxes which contain binary data. In addition to being able to set and read the box value, there are operations for extracting and replacing just a portion of the box data which 
is useful for minimizing the amount of reads and writes required, but also allows you to interact with byte arrays which are longer than the AVM can support (currently 4096).

```python
from algopy import BoxRef, Contract, Global, Txn


class MyContract(Contract):
    def approval_program(self) -> bool:
        my_blob = BoxRef(key=b"blob")

        sender_bytes = Txn.sender.bytes
        app_address = Global.current_application_address.bytes
        assert my_blob.create(8000)
        my_blob.replace(0, sender_bytes)
        my_blob.splice(0, 0, app_address)
        first_64 = my_blob.extract(0, 32 * 2)
        assert first_64 == app_address + sender_bytes
        assert my_blob.delete()
        value, exists = my_blob.maybe()
        assert not exists
        assert my_blob.get(default=sender_bytes) == sender_bytes
        my_blob.create(sender_bytes + app_address)
        assert my_blob, "Blob exists"
        assert my_blob.length == 64
        return True
```



If none of these abstractions suit your needs, you can use the box storage [AVM ops](./lg-ops.md) to interact with box storage. These ops match closely to the opcodes available on the AVM. 

For example:

```python
op.Box.create(b"key", size)
op.Box.put(Txn.sender.bytes, answer_ids.bytes)
(votes, exists) = op.Box.get(Txn.sender.bytes)
op.Box.replace(TALLY_BOX_KEY, index, op.itob(current_vote + 1))
```

See the [voting contract example](https://github.com/algorandfoundation/puya/tree/main/examples/voting/voting.py) for a real-world example that uses box storage.

## Scratch storage

To use stratch storage you need to [register the scratch storage that you want to use](./lg-structure.md#contract-class-configuration) and then you can use the scratch storage [AVM ops](./lg-ops.md).

For example:

```python
from algopy import Bytes, Contract, UInt64, op, urange

TWO = 2
TWENTY = 20


class MyContract(Contract, scratch_slots=(1, TWO, urange(3, TWENTY))):
    def approval_program(self) -> bool:
        op.Scratch.store(1, UInt64(5))

        op.Scratch.store(2, Bytes(b"Hello World"))

        for i in urange(3, 20):
            op.Scratch.store(i, i)

        assert op.Scratch.load_uint64(1) == UInt64(5)

        assert op.Scratch.load_bytes(2) == b"Hello World"

        assert op.Scratch.load_uint64(5) == UInt64(5)
        return True

    def clear_state_program(self) -> bool:
        return True
```

```

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

```markdown
[@algorandfoundation/algokit-utils](../README.md) / [types/app-arc56](../modules/types_app_arc56.md) / Arc56Contract

# Interface: Arc56Contract

[types/app-arc56](../modules/types_app_arc56.md).Arc56Contract

Describes the entire contract. This interface is an extension of the interface described in ARC-4

## Table of contents

### Properties

- [arcs](types_app_arc56.Arc56Contract.md#arcs)
- [bareActions](types_app_arc56.Arc56Contract.md#bareactions)
- [byteCode](types_app_arc56.Arc56Contract.md#bytecode)
- [compilerInfo](types_app_arc56.Arc56Contract.md#compilerinfo)
- [desc](types_app_arc56.Arc56Contract.md#desc)
- [events](types_app_arc56.Arc56Contract.md#events)
- [methods](types_app_arc56.Arc56Contract.md#methods)
- [name](types_app_arc56.Arc56Contract.md#name)
- [networks](types_app_arc56.Arc56Contract.md#networks)
- [scratchVariables](types_app_arc56.Arc56Contract.md#scratchvariables)
- [source](types_app_arc56.Arc56Contract.md#source)
- [sourceInfo](types_app_arc56.Arc56Contract.md#sourceinfo)
- [state](types_app_arc56.Arc56Contract.md#state)
- [structs](types_app_arc56.Arc56Contract.md#structs)
- [templateVariables](types_app_arc56.Arc56Contract.md#templatevariables)

## Properties

### arcs

• **arcs**: `number`[]

The ARCs used and/or supported by this contract. All contracts implicitly support ARC4 and ARC56

#### Defined in

[src/types/app-arc56.ts:233](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L233)

___

### bareActions

• **bareActions**: `Object`

Supported bare actions for the contract. An action is a combination of call/create and an OnComplete

#### Type declaration

| Name | Type | Description |
| :------ | :------ | :------ |
| `call` | (``"NoOp"`` \| ``"OptIn"`` \| ``"DeleteApplication"`` \| ``"CloseOut"`` \| ``"ClearState"`` \| ``"UpdateApplication"``)[] | OnCompletes this method allows when appID !== 0 |
| `create` | (``"NoOp"`` \| ``"OptIn"`` \| ``"DeleteApplication"``)[] | OnCompletes this method allows when appID === 0 |

#### Defined in

[src/types/app-arc56.ts:281](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L281)

___

### byteCode

• `Optional` **byteCode**: `Object`

The compiled bytecode for the application. MUST be omitted if included as part of ARC23

#### Type declaration

| Name | Type | Description |
| :------ | :------ | :------ |
| `approval` | `string` | The approval program |
| `clear` | `string` | The clear program |

#### Defined in

[src/types/app-arc56.ts:302](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L302)

___

### compilerInfo

• `Optional` **compilerInfo**: `Object`

Information used to get the given byteCode and/or PC values in sourceInfo. MUST be given if byteCode or PC values are present

#### Type declaration

| Name | Type | Description |
| :------ | :------ | :------ |
| `compiler` | ``"algod"`` \| ``"puya"`` | The name of the compiler |
| `compilerVersion` | \{ `commitHash?`: `string` ; `major`: `number` ; `minor`: `number` ; `patch`: `number`  } | Compiler version information |
| `compilerVersion.commitHash?` | `string` | - |
| `compilerVersion.major` | `number` | - |
| `compilerVersion.minor` | `number` | - |
| `compilerVersion.patch` | `number` | - |

#### Defined in

[src/types/app-arc56.ts:309](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L309)

___

### desc

• `Optional` **desc**: `string`

Optional, user-friendly description for the interface

#### Defined in

[src/types/app-arc56.ts:237](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L237)

___

### events

• `Optional` **events**: [`Event`](types_app_arc56.Event.md)[]

ARC-28 events that MAY be emitted by this contract

#### Defined in

[src/types/app-arc56.ts:321](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L321)

___

### methods

• **methods**: [`Method`](types_app_arc56.Method.md)[]

All of the methods that the contract implements

#### Defined in

[src/types/app-arc56.ts:254](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L254)

___

### name

• **name**: `string`

A user-friendly name for the contract

#### Defined in

[src/types/app-arc56.ts:235](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L235)

___

### networks

• `Optional` **networks**: `Object`

Optional object listing the contract instances across different networks.
The key is the base64 genesis hash of the network, and the value contains
information about the deployed contract in the network indicated by the
key. A key containing the human-readable name of the network MAY be
included, but the corresponding genesis hash key MUST also be defined

#### Index signature

▪ [network: `string`]: \{ `appID`: `number`  }

#### Defined in

[src/types/app-arc56.ts:245](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L245)

___

### scratchVariables

• `Optional` **scratchVariables**: `Object`

The scratch variables used during runtime

#### Index signature

▪ [name: `string`]: \{ `slot`: `number` ; `type`: [`ABIType`](../modules/types_app_arc56.md#abitype) \| [`AVMType`](../modules/types_app_arc56.md#avmtype) \| [`StructName`](../modules/types_app_arc56.md#structname)  }

#### Defined in

[src/types/app-arc56.ts:332](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L332)

___

### source

• `Optional` **source**: `Object`

The pre-compiled TEAL that may contain template variables. MUST be omitted if included as part of ARC23

#### Type declaration

| Name | Type | Description |
| :------ | :------ | :------ |
| `approval` | `string` | The approval program |
| `clear` | `string` | The clear program |

#### Defined in

[src/types/app-arc56.ts:295](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L295)

___

### sourceInfo

• `Optional` **sourceInfo**: `Object`

Information about the TEAL programs

#### Type declaration

| Name | Type | Description |
| :------ | :------ | :------ |
| `approval` | [`ProgramSourceInfo`](types_app_arc56.ProgramSourceInfo.md) | Approval program information |
| `clear` | [`ProgramSourceInfo`](types_app_arc56.ProgramSourceInfo.md) | Clear program information |

#### Defined in

[src/types/app-arc56.ts:288](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L288)

___

### state

• **state**: `Object`

#### Type declaration

| Name | Type | Description |
| :------ | :------ | :------ |
| `keys` | \{ `box`: \{ `[name: string]`: [`StorageKey`](types_app_arc56.StorageKey.md);  } ; `global`: \{ `[name: string]`: [`StorageKey`](types_app_arc56.StorageKey.md);  } ; `local`: \{ `[name: string]`: [`StorageKey`](types_app_arc56.StorageKey.md);  }  } | Mapping of human-readable names to StorageKey objects |
| `keys.box` | \{ `[name: string]`: [`StorageKey`](types_app_arc56.StorageKey.md);  } | - |
| `keys.global` | \{ `[name: string]`: [`StorageKey`](types_app_arc56.StorageKey.md);  } | - |
| `keys.local` | \{ `[name: string]`: [`StorageKey`](types_app_arc56.StorageKey.md);  } | - |
| `maps` | \{ `box`: \{ `[name: string]`: [`StorageMap`](types_app_arc56.StorageMap.md);  } ; `global`: \{ `[name: string]`: [`StorageMap`](types_app_arc56.StorageMap.md);  } ; `local`: \{ `[name: string]`: [`StorageMap`](types_app_arc56.StorageMap.md);  }  } | Mapping of human-readable names to StorageMap objects |
| `maps.box` | \{ `[name: string]`: [`StorageMap`](types_app_arc56.StorageMap.md);  } | - |
| `maps.global` | \{ `[name: string]`: [`StorageMap`](types_app_arc56.StorageMap.md);  } | - |
| `maps.local` | \{ `[name: string]`: [`StorageMap`](types_app_arc56.StorageMap.md);  } | - |
| `schema` | \{ `global`: \{ `bytes`: `number` ; `ints`: `number`  } ; `local`: \{ `bytes`: `number` ; `ints`: `number`  }  } | Defines the values that should be used for GlobalNumUint, GlobalNumByteSlice, LocalNumUint, and LocalNumByteSlice when creating the application |
| `schema.global` | \{ `bytes`: `number` ; `ints`: `number`  } | - |
| `schema.global.bytes` | `number` | - |
| `schema.global.ints` | `number` | - |
| `schema.local` | \{ `bytes`: `number` ; `ints`: `number`  } | - |
| `schema.local.bytes` | `number` | - |
| `schema.local.ints` | `number` | - |

#### Defined in

[src/types/app-arc56.ts:255](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L255)

___

### structs

• **structs**: `Object`

Named structs used by the application. Each struct field appears in the same order as ABI encoding.

#### Index signature

▪ [structName: [`StructName`](../modules/types_app_arc56.md#structname)]: [`StructField`](types_app_arc56.StructField.md)[]

#### Defined in

[src/types/app-arc56.ts:252](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L252)

___

### templateVariables

• `Optional` **templateVariables**: `Object`

A mapping of template variable names as they appear in the TEAL (not including TMPL_ prefix) to their respective types and values (if applicable)

#### Index signature

▪ [name: `string`]: \{ `type`: [`ABIType`](../modules/types_app_arc56.md#abitype) \| [`AVMType`](../modules/types_app_arc56.md#avmtype) \| [`StructName`](../modules/types_app_arc56.md#structname) ; `value?`: `string`  }

#### Defined in

[src/types/app-arc56.ts:323](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/app-arc56.ts#L323)

```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/algokit:utils:python:markdown:capabilities:app-client.md:
--------------------------------------------------------------------------------

```markdown
# App client

Application client that works with ARC-0032 application spec defined smart contracts (e.g. via Beaker).

App client is a high productivity application client that works with ARC-0032 application spec defined smart contracts, which you can use to create, update, delete, deploy and call a smart contract and access state data for it.

To see some usage examples check out the [automated tests](https://github.com/algorandfoundation/algokit-utils-py/blob/main/tests/test_app_client_call.py).

## Design

The design for the app client is based on a wrapper for parsing an [ARC-0032](https://github.com/algorandfoundation/ARCs/pull/150) application spec and wrapping the [App deployment](app-deploy.md) functionality and corresponding [design](app-deploy.md#id1).

## Creating an application client

There are two key ways of instantiating an ApplicationClient:

1. By app ID - When needing to call an existing app by app ID or unconditionally create a new app.
   The signature `ApplicationClient(algod_client, app_spec, app_id=..., ...)` requires:
   * `algod_client`: An `AlgodClient`
   * `app_spec`: An `ApplicationSpecification`
   * `app_id`: The app_id of an existing application, or 0 if creating a new app
2. By creator and app name - When needing to deploy or find an app associated with a specific creator account and app name.
   The signature `ApplicationClient(algod_client, app_spec, creator=..., indexer=..., app_lookup)` requires:
   * `algod_client`: An `AlgodClient`
   * `app_spec`: An `ApplicationSpecification`
   * `creator`: The address or `Account` of the creator of the app for which to search for the deployed app under
   * `indexer`:
   * `app_lookup`: Optional if an indexer is provided,
   * `app_name`: An overridden name to identify the contract with, otherwise `contract.name` is used from the app spec

Both approaches also allow specifying the following parameters that will be used as defaults for all application calls:

* `signer`: `TransactionSigner` to sign transactions with.
* `sender`: Address to use for transaction signing, will be derived from the signer if not provided.
* `suggested_params`: Default `SuggestedParams` to use, will use current network suggested params by default

Both approaches also allow specifying a mapping of template values via the `template_values` parameter, this will be used before compiling the application to replace any
`TMPL_` variables that may be in the TEAL. The `TMPL_UPDATABLE` and `TMPL_DELETABLE` variables used in some AlgoKit templates are handled by the `deploy` method, but should be included if
using `create` or `update` directly.

## Calling methods on the app

There are various methods available on `ApplicationClient` that can be used to call an app:

* `call`: Used to call methods with an on complete action of `no_op`
* `create`: Used to create an instance of the app, by using an `app_id` of 0, includes the approval and clear programs in the call
* `update`: Used to update an existing app, includes the approval and clear programs in the call, and is called with an on complete action of `update_application`
* `delete`: Used to remove an existing app, is called with an on complete action of `delete_application`
* `opt_in`: Used to opt in to an existing app, is called with an on complete action of `opt_in`
* `close_out`: Used to close out of an existing app, is called with an on complete action of `opt_in`
* `clear_state`: Used to unconditionally close out from an app, calls the clear program of an app

### Specifying which method

All methods for calling an app that support ABI methods (everything except `clear_state`) take a parameter `call_abi_method` which can be used to specify which method to call.
The method selected can be specified explicitly, or allow the client to infer the method where possible, supported values are:

* `None`: The default value, when `None` is passed the client will attempt to find any ABI method or bare method that is compatible with the provided arguments
* `False`: Indicates that an ABI method should not be used, and instead a bare method call is made
* `True`: Indicates that an ABI method should be used, and the client will attempt to find an ABI method that is compatible with the provided arguments
* `str`: If a string is provided, it will be interpreted as either an ABI signature specifying a method, or as an ABI method name
* `algosdk.abi.Method`: The specified ABI method will be called
* `ABIReturnSubroutine`: Any type that has a `method_spec` function that returns an `algosd.abi.Method`

### ABI arguments

ABI arguments are passed as python keyword arguments e.g. to pass the ABI parameter `name` for the ABI method `hello` the following syntax is used `client.call("hello", name="world")`

### Transaction Parameters

All methods for calling an app take an optional `transaction_parameters` argument, with the following supported parameters:

* `signer`: The `TransactionSigner` to use on the call. This overrides any signer specified on the client
* `sender`: The address of the sender to use on the call, must be able to be signed for by the `signer`. This overrides any sender specified on the client
* `suggested_params`: `SuggestedParams` to use on the call. This overrides any suggested_params specified on the client
* `note`: Note to include in the transaction
* `lease`: Lease parameter for the transaction
* `boxes`: A sequence of boxes to use in the transaction, this is a list of (app_index, box_name) tuples `[(0, "box_name"), (0, ...)]`
* `accounts`: Account references to include in the transaction
* `foreign_apps`: Foreign apps to include in the transaction
* `foreign_assets`: Foreign assets to include in the transaction
* `on_complete`: The on complete action to use for the transaction, only available when using `call` or `create`
* `extra_pages`: Additional pages to allocate when calling `create`, by default a sufficient amount will be calculated based on the current approval and clear. This can be overridden, if more is required
  for a future update

Parameters can be passed as one of the dataclasses `CommonCallParameters`, `OnCompleteCallParameters`, `CreateCallParameters` (exact type depends on method used)

```python
client.call("hello", transaction_parameters=algokit_utils.OnCompleteCallParameters(signer=...))
```

Alternatively, parameters can be passed as a dictionary e.g.

```python
client.call("hello", transaction_parameters={"signer":...})
```

## Composing calls

If multiple calls need to be made in a single transaction, the `compose_` method variants can be used. All these methods take an `AtomicTransactionComposer` as their first argument.
Once all the calls have been added to the ATC, it can then be executed. For example:

```python
from algokit_utils import ApplicationClient
from algosdk.atomic_transaction_composer import AtomicTransactionComposer

client = ApplicationClient(...)
atc = AtomicTransactionComposer()
client.compose_call(atc, "hello", name="world")
... # additional compose calls

response = client.execute_atc(atc)
```

## Reading state

There are various methods defined that let you read state from the smart contract app:

* `get_global_state` - Gets the current global state of the app
* `get_local_state` - Gets the current local state for the given account address

## Handling logic errors and diagnosing errors

Often when calling a smart contract during development you will get logic errors that cause an exception to throw. This may be because of a failing assertion, a lack of fees,
exhaustion of opcode budget, or any number of other reasons.

When this occurs, you will generally get an error that looks something like: `TransactionPool.Remember: transaction {TRANSACTION_ID}: logic eval error: {ERROR_MESSAGE}. Details: pc={PROGRAM_COUNTER_VALUE}, opcodes={LIST_OF_OP_CODES}`.

The information in that error message can be parsed and when combined with the [source map from compilation](app-deploy.md#id2) you can expose debugging
information that makes it much easier to understand what’s happening.

When an error is thrown then the resulting error that is re-thrown will be a `LogicError`, which has the following fields:

* `logic_error`: Original exception
* `program`: Program source (if available)
* `source_map`: Source map used (if available)
* `transaction_id`: Transaction ID of failing transaction
* `message`: The error message
* `line_no`: The line number in the TEAL program that
* `traces`: A list of Trace objects providing additional insights on simulation when debug mode is active.

The function `trace()` will provide a formatted output of the surrounding TEAL where the error occurred.

#### NOTE
The extended information will only show if the Application Client has a source map. This will occur if:

1.) The ApplicationClient instance has already called, `create, `update`or`deploy`OR 2.)`template_values`are provided when creating the ApplicationClient, so a SourceMap can be obtained automatically OR 3.)`approval_source_map`on`ApplicationClient`has been set from a previously compiled approval program OR 4.) A source map has been exported/imported using`export_source_map`/`import_source_map\`”””

### Debug Mode and traces Field

When debug mode is active, the LogicError will contain a field named traces. This field will include raw simulate execution traces, providing a detailed account of the transaction simulation. These traces are crucial for diagnosing complex issues and are automatically included in all application client calls when debug mode is active.

#### NOTE
Remember to enable debug mode (`config.debug = True`) to include raw simulate execution traces in the `LogicError`.

```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/algokit:utils:python:source:capabilities:app-client.md:
--------------------------------------------------------------------------------

```markdown
# App client

Application client that works with ARC-0032 application spec defined smart contracts (e.g. via Beaker).

App client is a high productivity application client that works with ARC-0032 application spec defined smart contracts, which you can use to create, update, delete, deploy and call a smart contract and access state data for it.

To see some usage examples check out the [automated tests](https://github.com/algorandfoundation/algokit-utils-py/blob/main/tests/test_app_client_call.py).

## Design

The design for the app client is based on a wrapper for parsing an [ARC-0032](https://github.com/algorandfoundation/ARCs/pull/150) application spec and wrapping the [App deployment](./app-deploy.md) functionality and corresponding [design](./app-deploy.md#design).

## Creating an application client

There are two key ways of instantiating an ApplicationClient:

1. By app ID - When needing to call an existing app by app ID or unconditionally create a new app.
The signature `ApplicationClient(algod_client, app_spec, app_id=..., ...)` requires:
   * `algod_client`: An `AlgodClient`
   * `app_spec`: An `ApplicationSpecification`
   * `app_id`: The app_id of an existing application, or 0 if creating a new app

2. By creator and app name - When needing to deploy or find an app associated with a specific creator account and app name.
The signature `ApplicationClient(algod_client, app_spec, creator=..., indexer=..., app_lookup)` requires:
   * `algod_client`: An `AlgodClient`
   * `app_spec`: An `ApplicationSpecification`
   * `creator`: The address or `Account` of the creator of the app for which to search for the deployed app under
   * `indexer`:
   * `app_lookup`: Optional if an indexer is provided,
   * `app_name`: An overridden name to identify the contract with, otherwise `contract.name` is used from the app spec

Both approaches also allow specifying the following parameters that will be used as defaults for all application calls:
* `signer`: `TransactionSigner` to sign transactions with.
* `sender`: Address to use for transaction signing, will be derived from the signer if not provided.
* `suggested_params`: Default `SuggestedParams` to use, will use current network suggested params by default
 
Both approaches also allow specifying a mapping of template values via the `template_values` parameter, this will be used before compiling the application to replace any 
`TMPL_` variables that may be in the TEAL. The `TMPL_UPDATABLE` and `TMPL_DELETABLE` variables used in some AlgoKit templates are handled by the `deploy` method, but should be included if 
using `create` or `update` directly.

## Calling methods on the app

There are various methods available on `ApplicationClient` that can be used to call an app:  

* `call`: Used to call methods with an on complete action of `no_op`
* `create`: Used to create an instance of the app, by using an `app_id` of 0, includes the approval and clear programs in the call
* `update`: Used to update an existing app, includes the approval and clear programs in the call, and is called with an on complete action of `update_application`
* `delete`: Used to remove an existing app, is called with an on complete action of `delete_application`
* `opt_in`: Used to opt in to an existing app, is called with an on complete action of `opt_in`
* `close_out`: Used to close out of an existing app, is called with an on complete action of `opt_in`
* `clear_state`: Used to unconditionally close out from an app, calls the clear program of an app

### Specifying which method

All methods for calling an app that support ABI methods (everything except `clear_state`) take a parameter `call_abi_method` which can be used to specify which method to call. 
The method selected can be specified explicitly, or allow the client to infer the method where possible, supported values are:

* `None`: The default value, when `None` is passed the client will attempt to find any ABI method or bare method that is compatible with the provided arguments
* `False`: Indicates that an ABI method should not be used, and instead a bare method call is made
* `True`: Indicates that an ABI method should be used, and the client will attempt to find an ABI method that is compatible with the provided arguments
* `str`: If a string is provided, it will be interpreted as either an ABI signature specifying a method, or as an ABI method name
* `algosdk.abi.Method`: The specified ABI method will be called
* `ABIReturnSubroutine`: Any type that has a `method_spec` function that returns an `algosd.abi.Method`

### ABI arguments

ABI arguments are passed as python keyword arguments e.g. to pass the ABI parameter `name` for the ABI method `hello` the following syntax is used `client.call("hello", name="world")`

### Transaction Parameters

All methods for calling an app take an optional `transaction_parameters` argument, with the following supported parameters:

* `signer`: The `TransactionSigner` to use on the call. This overrides any signer specified on the client
* `sender`: The address of the sender to use on the call, must be able to be signed for by the `signer`. This overrides any sender specified on the client
* `suggested_params`: `SuggestedParams` to use on the call. This overrides any suggested_params specified on the client
* `note`: Note to include in the transaction
* `lease`: Lease parameter for the transaction 
* `boxes`: A sequence of boxes to use in the transaction, this is a list of (app_index, box_name) tuples `[(0, "box_name"), (0, ...)]`
* `accounts`: Account references to include in the transaction
* `foreign_apps`: Foreign apps to include in the transaction
* `foreign_assets`: Foreign assets to include in the transaction
* `on_complete`: The on complete action to use for the transaction, only available when using `call` or `create`
* `extra_pages`: Additional pages to allocate when calling `create`, by default a sufficient amount will be calculated based on the current approval and clear. This can be overridden, if more is required
 for a future update

Parameters can be passed as one of the dataclasses `CommonCallParameters`, `OnCompleteCallParameters`, `CreateCallParameters` (exact type depends on method used) 
```python
client.call("hello", transaction_parameters=algokit_utils.OnCompleteCallParameters(signer=...))
```

Alternatively, parameters can be passed as a dictionary e.g.
```python
client.call("hello", transaction_parameters={"signer":...})
```

## Composing calls

If multiple calls need to be made in a single transaction, the `compose_` method variants can be used. All these methods take an `AtomicTransactionComposer` as their first argument.
Once all the calls have been added to the ATC, it can then be executed. For example:

```python
from algokit_utils import ApplicationClient
from algosdk.atomic_transaction_composer import AtomicTransactionComposer

client = ApplicationClient(...)
atc = AtomicTransactionComposer()
client.compose_call(atc, "hello", name="world")
... # additional compose calls

response = client.execute_atc(atc)
```


## Reading state

There are various methods defined that let you read state from the smart contract app:

* `get_global_state` - Gets the current global state of the app
* `get_local_state` - Gets the current local state for the given account address

## Handling logic errors and diagnosing errors

Often when calling a smart contract during development you will get logic errors that cause an exception to throw. This may be because of a failing assertion, a lack of fees, 
exhaustion of opcode budget, or any number of other reasons.

When this occurs, you will generally get an error that looks something like: `TransactionPool.Remember: transaction {TRANSACTION_ID}: logic eval error: {ERROR_MESSAGE}. Details: pc={PROGRAM_COUNTER_VALUE}, opcodes={LIST_OF_OP_CODES}`.

The information in that error message can be parsed and when combined with the [source map from compilation](./app-deploy.md#compilation-and-template-substitution) you can expose debugging 
information that makes it much easier to understand what's happening.

When an error is thrown then the resulting error that is re-thrown will be a `LogicError`, which has the following fields:

* `logic_error`: Original exception
* `program`: Program source (if available)
* `source_map`: Source map used (if available)
* `transaction_id`: Transaction ID of failing transaction
* `message`: The error message
* `line_no`: The line number in the TEAL program that
* `traces`: A list of Trace objects providing additional insights on simulation when debug mode is active.

The function `trace()` will provide a formatted output of the surrounding TEAL where the error occurred.

```{note}
The extended information will only show if the Application Client has a source map. This will occur if:

1.) The ApplicationClient instance has already called, `create, `update` or `deploy` OR
2.) `template_values` are provided when creating the ApplicationClient, so a SourceMap can be obtained automatically OR
3.) `approval_source_map` on `ApplicationClient` has been set from a previously compiled approval program OR
4.) A source map has been exported/imported using `export_source_map`/`import_source_map`"""
```

### Debug Mode and traces Field
When debug mode is active, the LogicError will contain a field named traces. This field will include raw simulate execution traces, providing a detailed account of the transaction simulation. These traces are crucial for diagnosing complex issues and are automatically included in all application client calls when debug mode is active.

```{note}
Remember to enable debug mode (`config.debug = True`) to include raw simulate execution traces in the `LogicError`.
```
```

--------------------------------------------------------------------------------
/packages/server/src/tools/apiManager/vestige/assets.ts:
--------------------------------------------------------------------------------

```typescript
import { Tool, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
import { ResponseProcessor } from '../../../utils/responseProcessor.js';
import { env } from '../../../env.js';

export const assetTools: Tool[] = [
  // Asset List and Search
  {
    name: 'api_vestige_view_assets',
    description: 'Get data about assets',
    inputSchema: {
      type: 'object',
      properties: {
        network_id: {
          type: 'integer',
          description: 'Network ID'
        },
        asset_ids: {
          type: 'string',
          description: 'Comma-separated list of asset IDs'
        }
      },
      required: ['network_id', 'asset_ids']
    }
  },
  {
    name: 'api_vestige_view_assets_list',
    description: 'Get asset list',
    inputSchema: {
      type: 'object',
      properties: {
        network_id: {
          type: 'integer',
          description: 'Network ID'
        },
        asset_ids: {
          type: 'string',
          description: 'Optional comma-separated list of asset IDs'
        },
        denominating_asset_id: {
          type: 'integer',
          description: 'Optional denominating asset ID',
          default: 0
        },
        include_labels: {
          type: 'string',
          description: 'Optional comma-separated list of labels to include'
        },
        exclude_labels: {
          type: 'string',
          description: 'Optional comma-separated list of labels to exclude'
        },
        limit: {
          type: 'integer',
          description: 'Maximum number of results',
          default: 50,
          maximum: 250,
          minimum: 1
        },
        offset: {
          type: 'integer',
          description: 'Number of results to skip',
          default: 0,
          minimum: 0
        },
        order_by: {
          type: 'string',
          description: 'Field to order by'
        },
        order_dir: {
          type: 'string',
          description: 'Order direction (asc/desc)',
          default: 'desc',
          pattern: '^(asc|desc)$'
        },
        tvl__lt: {
          type: 'number',
          description: 'Filter by TVL less than'
        },
        tvl__gt: {
          type: 'number',
          description: 'Filter by TVL greater than'
        },
        market_cap__lt: {
          type: 'number',
          description: 'Filter by market cap less than'
        },
        market_cap__gt: {
          type: 'number',
          description: 'Filter by market cap greater than'
        },
        fully_diluted_market_cap__lt: {
          type: 'number',
          description: 'Filter by fully diluted market cap less than'
        },
        fully_diluted_market_cap__gt: {
          type: 'number',
          description: 'Filter by fully diluted market cap greater than'
        },
        volume1d__lt: {
          type: 'number',
          description: 'Filter by 24h volume less than'
        },
        volume1d__gt: {
          type: 'number',
          description: 'Filter by 24h volume greater than'
        },
        created_at__lt: {
          type: 'integer',
          description: 'Filter by creation time less than'
        },
        created_at__gt: {
          type: 'integer',
          description: 'Filter by creation time greater than'
        }
      },
      required: ['network_id']
    }
  },
  {
    name: 'api_vestige_view_assets_search',
    description: 'Search assets by query',
    inputSchema: {
      type: 'object',
      properties: {
        network_id: {
          type: 'integer',
          description: 'Network ID'
        },
        query: {
          type: 'string',
          description: 'Search query'
        },
        protocol_id: {
          type: 'integer',
          description: 'Optional protocol ID filter'
        },
        denominating_asset_id: {
          type: 'integer',
          description: 'Optional denominating asset ID',
          default: 0
        },
        limit: {
          type: 'integer',
          description: 'Maximum number of results',
          default: 50,
          maximum: 250,
          minimum: 1
        },
        offset: {
          type: 'integer',
          description: 'Number of results to skip',
          default: 0,
          minimum: 0
        },
        order_by: {
          type: 'string',
          description: 'Field to order by'
        },
        order_dir: {
          type: 'string',
          description: 'Order direction (asc/desc)',
          default: 'desc',
          pattern: '^(asc|desc)$'
        }
      },
      required: ['network_id', 'query']
    }
  },

  // Asset Details and Price
  {
    name: 'api_vestige_view_asset_price',
    description: 'Get asset prices',
    inputSchema: {
      type: 'object',
      properties: {
        network_id: {
          type: 'integer',
          description: 'Network ID'
        },
        asset_ids: {
          type: 'string',
          description: 'Comma-separated list of asset IDs'
        },
        denominating_asset_id: {
          type: 'integer',
          description: 'Optional denominating asset ID',
          default: 0
        }
      },
      required: ['network_id', 'asset_ids']
    }
  },

  // Asset History and Candles
  {
    name: 'api_vestige_view_asset_candles',
    description: 'Get asset candles',
    inputSchema: {
      type: 'object',
      properties: {
        network_id: {
          type: 'integer',
          description: 'Network ID'
        },
        asset_id: {
          type: 'integer',
          description: 'Asset ID'
        },
        interval: {
          type: 'integer',
          description: 'Candle interval in seconds'
        },
        start: {
          type: 'integer',
          description: 'Start timestamp'
        },
        end: {
          type: 'integer',
          description: 'Optional end timestamp'
        },
        denominating_asset_id: {
          type: 'integer',
          description: 'Optional denominating asset ID',
          default: 0
        },
        volume_in_denominating_asset: {
          type: 'boolean',
          description: 'Whether to return volume in denominating asset',
          default: false
        }
      },
      required: ['network_id', 'asset_id', 'interval', 'start']
    }
  },
  {
    name: 'api_vestige_view_asset_history',
    description: 'Get asset volume, swaps, total lockup, vwap and confidence history',
    inputSchema: {
      type: 'object',
      properties: {
        network_id: {
          type: 'integer',
          description: 'Network ID'
        },
        asset_id: {
          type: 'integer',
          description: 'Asset ID'
        },
        interval: {
          type: 'integer',
          description: 'History interval in seconds'
        },
        start: {
          type: 'integer',
          description: 'Start timestamp'
        },
        end: {
          type: 'integer',
          description: 'Optional end timestamp'
        },
        denominating_asset_id: {
          type: 'integer',
          description: 'Optional denominating asset ID',
          default: 0
        },
        volume_in_denominating_asset: {
          type: 'boolean',
          description: 'Whether to return volume in denominating asset',
          default: false
        }
      },
      required: ['network_id', 'asset_id', 'interval', 'start']
    }
  },

  // Asset Composition
  {
    name: 'api_vestige_view_asset_composition',
    description: 'Get asset lockups based on protocol and pair',
    inputSchema: {
      type: 'object',
      properties: {
        network_id: {
          type: 'integer',
          description: 'Network ID'
        },
        asset_id: {
          type: 'integer',
          description: 'Asset ID'
        }
      },
      required: ['network_id', 'asset_id']
    }
  }
];



export const handleAssetTools = ResponseProcessor.wrapResourceHandler(async function handleAssetTools(args: any): Promise<any> {
  const name = args.name;
  const baseUrl = env.vestige_api_url;
  let endpoint = '';

  switch (name) {
    case 'api_vestige_view_assets':
      endpoint = '/assets';
      break;
    case 'api_vestige_view_assets_list':
      endpoint = '/assets/list';
      break;
    case 'api_vestige_view_assets_search':
      endpoint = '/assets/search';
      break;
    case 'api_vestige_view_asset_price':
      endpoint = '/assets/price';
      break;
    case 'api_vestige_view_asset_candles':
      endpoint = `/assets/${args.asset_id}/candles`;
      break;
    case 'api_vestige_view_asset_history':
      endpoint = `/assets/${args.asset_id}/history`;
      break;
    case 'api_vestige_view_asset_composition':
      endpoint = `/assets/${args.asset_id}/composition`;
      break;
    default:
      throw new McpError(
        ErrorCode.MethodNotFound,
        `Unknown tool: ${name}`
      );
  }

  try {
    // Add query parameters if they exist
    const queryParams = new URLSearchParams();
    for (const [key, value] of Object.entries(args)) {
      if (value !== undefined && key !== 'asset_id') {
        queryParams.append(key, String(value));
      }
    }
    const url = `${baseUrl}${endpoint}${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;

    const response = await fetch(url);
    if (!response.ok) {
      throw new McpError(
        ErrorCode.InternalError,
        `Vestige API error: ${response.status} ${response.statusText}`
      );
    }
    const data = await response.json();
    return data;
  } catch (error) {
    if (error instanceof McpError) {
      throw error;
    }
    throw new McpError(
      ErrorCode.InternalError,
      `Failed to fetch asset data: ${error instanceof Error ? error.message : String(error)}`
    );
  }
});

```

--------------------------------------------------------------------------------
/packages/server/src/tools/apiManager/indexer/asset.ts:
--------------------------------------------------------------------------------

```typescript
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
import { indexerClient } from '../../../algorand-client.js';
import { ResponseProcessor } from '../../../utils/responseProcessor.js';
import type { 
  AssetResponse,
  AssetsResponse,
  AssetBalancesResponse,
  TransactionsResponse
} from 'algosdk/dist/types/client/v2/indexer/models/types';

export const assetTools = [
  {
    name: 'api_indexer_lookup_asset_by_id',
    description: 'Get asset information and configuration',
    inputSchema: {
      type: 'object',
      properties: {
        assetId: {
          type: 'integer',
          description: 'Asset ID'
        }
      },
      required: ['assetId']
    }
  },
  {
    name: 'api_indexer_lookup_asset_balances',
    description: 'Get accounts holding this asset and their balances',
    inputSchema: {
      type: 'object',
      properties: {
        assetId: {
          type: 'integer',
          description: 'Asset ID'
        },
        limit: {
          type: 'integer',
          description: 'Maximum number of balances to return'
        },
        currencyGreaterThan: {
          type: 'integer',
          description: 'Filter by minimum balance'
        },
        currencyLessThan: {
          type: 'integer',
          description: 'Filter by maximum balance'
        },
        nextToken: {
          type: 'string',
          description: 'Token for retrieving the next page of results'
        },
        address: {
          type: 'string',
          description: 'Filter by account address'
        }
      },
      required: ['assetId']
    }
  },
  {
    name: 'api_indexer_lookup_asset_transactions',
    description: 'Get transactions involving this asset',
    inputSchema: {
      type: 'object',
      properties: {
        assetId: {
          type: 'integer',
          description: 'Asset ID'
        },
        limit: {
          type: 'integer',
          description: 'Maximum number of transactions to return'
        },
        beforeTime: {
          type: 'string',
          description: 'Only return transactions before this time'
        },
        afterTime: {
          type: 'string',
          description: 'Only return transactions after this time'
        },
        minRound: {
          type: 'integer',
          description: 'Only return transactions after this round'
        },
        maxRound: {
          type: 'integer',
          description: 'Only return transactions before this round'
        },
        address: {
          type: 'string',
          description: 'Filter by account address'
        },
        addressRole: {
          type: 'string',
          description: 'Filter by address role (sender or receiver)'
        },
        excludeCloseTo: {
          type: 'boolean',
          description: 'Whether to exclude close-to transactions'
        },
        nextToken: {
          type: 'string',
          description: 'Token for retrieving the next page of results'
        },
        txid: {
          type: 'string',
          description: 'Filter by transaction ID'
        }
      },
      required: ['assetId']
    }
  },
  {
    name: 'api_indexer_search_for_assets',
    description: 'Search for assets with various criteria',
    inputSchema: {
      type: 'object',
      properties: {
        limit: {
          type: 'integer',
          description: 'Maximum number of assets to return'
        },
        creator: {
          type: 'string',
          description: 'Filter by creator address'
        },
        name: {
          type: 'string',
          description: 'Filter by asset name'
        },
        unit: {
          type: 'string',
          description: 'Filter by asset unit name'
        },
        assetId: {
          type: 'integer',
          description: 'Filter by asset ID'
        },
        nextToken: {
          type: 'string',
          description: 'Token for retrieving the next page of results'
        }
      }
    }
  }
];

export async function lookupAssetByID(assetId: number): Promise<AssetResponse> {
  try {
    console.log(`Looking up asset info for ID ${assetId}`);
    const response = await indexerClient.lookupAssetByID(assetId).do() as AssetResponse;
    console.log('Asset response:', JSON.stringify(response, null, 2));
    return response;
  } catch (error) {
    console.error('Asset lookup error:', error);
    if (error instanceof McpError) {
      throw error;
    }
    throw new McpError(
      ErrorCode.InternalError,
      `Failed to get asset info: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

export async function lookupAssetBalances(assetId: number, params?: {
  limit?: number;
  currencyGreaterThan?: number;
  currencyLessThan?: number;
  nextToken?: string;
  address?: string;
}): Promise<AssetBalancesResponse> {
  try {
    console.log(`Looking up balances for asset ${assetId}`);
    let search = indexerClient.lookupAssetBalances(assetId);

    if (params?.limit) {
      search = search.limit(params.limit);
    }
    if (params?.currencyGreaterThan) {
      search = search.currencyGreaterThan(params.currencyGreaterThan);
    }
    if (params?.currencyLessThan) {
      search = search.currencyLessThan(params.currencyLessThan);
    }
    if (params?.nextToken) {
      search = search.nextToken(params.nextToken);
    }

    const response = await search.do() as AssetBalancesResponse;
    console.log('Asset balances response:', JSON.stringify(response, null, 2));
    return response;
  } catch (error) {
    console.error('Asset balances lookup error:', error);
    if (error instanceof McpError) {
      throw error;
    }
    throw new McpError(
      ErrorCode.InternalError,
      `Failed to get asset balances: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

export async function lookupAssetTransactions(assetId: number, params?: {
  limit?: number;
  beforeTime?: string;
  afterTime?: string;
  minRound?: number;
  maxRound?: number;
  address?: string;
  addressRole?: string;
  excludeCloseTo?: boolean;
  nextToken?: string;
  txid?: string;
}): Promise<TransactionsResponse> {
  try {
    console.log(`Looking up transactions for asset ${assetId}`);
    let search = indexerClient.lookupAssetTransactions(assetId);

    if (params?.limit) {
      search = search.limit(params.limit);
    }
    if (params?.beforeTime) {
      search = search.beforeTime(params.beforeTime);
    }
    if (params?.afterTime) {
      search = search.afterTime(params.afterTime);
    }
    if (params?.minRound) {
      search = search.minRound(params.minRound);
    }
    if (params?.maxRound) {
      search = search.maxRound(params.maxRound);
    }
    if (params?.address) {
      search = search.address(params.address);
    }
    if (params?.addressRole) {
      search = search.addressRole(params.addressRole);
    }
    if (params?.excludeCloseTo) {
      search = search.excludeCloseTo(params.excludeCloseTo);
    }
    if (params?.nextToken) {
      search = search.nextToken(params.nextToken);
    }

    const response = await search.do() as TransactionsResponse;
    console.log('Asset transactions response:', JSON.stringify(response, null, 2));
    return response;
  } catch (error) {
    console.error('Asset transactions lookup error:', error);
    if (error instanceof McpError) {
      throw error;
    }
    throw new McpError(
      ErrorCode.InternalError,
      `Failed to get asset transactions: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

export async function searchForAssets(params?: {
  limit?: number;
  creator?: string;
  name?: string;
  unit?: string;
  assetId?: number;
  nextToken?: string;
}): Promise<AssetsResponse> {
  try {
    console.log('Searching assets with params:', params);
    let search = indexerClient.searchForAssets();

    if (params?.limit) {
      search = search.limit(params.limit);
    }
    if (params?.creator) {
      search = search.creator(params.creator);
    }
    if (params?.name) {
      search = search.name(params.name);
    }
    if (params?.unit) {
      search = search.unit(params.unit);
    }
    if (params?.assetId) {
      search = search.index(params.assetId);
    }
    if (params?.nextToken) {
      search = search.nextToken(params.nextToken);
    }

    const response = await search.do() as AssetsResponse;
    console.log('Search assets response:', JSON.stringify(response, null, 2));
    return response;
  } catch (error) {
    console.error('Search assets error:', error);
    if (error instanceof McpError) {
      throw error;
    }
    throw new McpError(
      ErrorCode.InternalError,
      `Failed to search assets: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

export const handleAssetTools = ResponseProcessor.wrapResourceHandler(async function handleAssetTools(args: any): Promise<any> {
  const name = args.name;
  
  switch (name) {
    case 'api_indexer_lookup_asset_by_id': {
      const { assetId } = args;
      const info = await lookupAssetByID(assetId);
      return info.asset;
    }
    case 'api_indexer_lookup_asset_balances': {
      const { assetId, ...params } = args;
      const balances = await lookupAssetBalances(assetId, params);
      return balances.balances;
    }
    case 'api_indexer_lookup_asset_transactions': {
      const { assetId, ...params } = args;
      const transactions = await lookupAssetTransactions(assetId, params);
      return transactions.transactions;
    }
    case 'api_indexer_search_for_assets': {
      const assets = await searchForAssets(args);
      return assets.assets;
    }
    default:
      throw new McpError(
        ErrorCode.MethodNotFound,
        `Unknown tool: ${name}`
      );
  }
});

```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/puya:typescript:docs:architecture-decisions:2024-05-21_primitive-bytes-and-strings.md:
--------------------------------------------------------------------------------

```markdown
# Architecture Decision Record - Primitive bytes and strings

- **Status**: Draft
- **Owner:** Tristan Menzel
- **Deciders**: Alessandro Cappellato (Algorand Foundation), Joe Polny (Algorand Foundation), Rob Moore (MakerX)
- **Date created**: 2024-05-21
- **Date decided**: N/A
- **Date updated**: 2024-05-31

## Context

See [Architecture Decision Record - Primitive integer types](./2024-05-21_primitive-integer-types.md) for related decision and context.

The AVM's only non-integer type is a variable length byte array. When *not* being interpreted as a `biguint`, leading zeros are significant and length is constant unless explicitly manipulated. Strings can only be represented in the AVM if they are encoded as bytes. The AVM supports byte literals in the form of base16, base64, and UTF-8 encoded strings. Once a literal has been parsed, the AVM has no concept of the original encoding or of UTF-8 characters. As a result, whilst a byte array can be indexed to receive a single byte (or a slice of bytes); it cannot be indexed to return a single UTF-8 *character* - unless one assumes all characters in the original string were ASCII (i.e. single byte) characters.

Algorand Python has specific [Bytes and String types](https://algorandfoundation.github.io/puya/lg-types.html#avm-types) that have semantics that exactly match the AVM semantics. Python allows for operator overloading so these types also use native operators (where they align to functionality in the underlying AVM).


## Requirements

- Support bytes AVM type and a string type that supports ASCII UTF-8 strings
- Use idiomatic TypeScript expressions for string expressions
- Semantic compatibility between AVM execution and TypeScript execution (e.g. in unit tests)

## Principles

- **[AlgoKit Guiding Principles](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/algokit.md#guiding-principles)** - specifically Seamless onramp, Leverage existing ecosystem, Meet devs where they are
- **[Algorand Python Principles](https://algorandfoundation.github.io/puya/principles.html#principles)**
- **[Algorand TypeScript Guiding Principles](../README.md#guiding-principals)**

## Options


### Option 1 - Direct use of native EcmaScript types


EcmaScript provides two relevant types for bytes and strings.

 - **string**: The native string type. Supports arbitrary length, concatenation, indexation/slicing of characters plus many utility methods (upper/lower/startswith/endswith/charcodeat/trim etc). Supports concat with binary `+` operator.
 - **Uint8Array**: A variable length mutable array of 8-bit numbers. Supports indexing/slicing of 'bytes'.


```ts
const b1 = "somebytes"

const b2 = new Uint8Array([1, 2, 3, 4])

const b3 = b1 + b1
```

Whilst binary data is often a representation of a utf-8 string, it is not always - so direct use of the string type is not a natural fit. It doesn't allow us to represent alternative encodings (b16/b64) and the existing api surface is very 'string' centric. Much of the api would also be expensive to implement on the AVM leading to a bunch of 'dead' methods hanging off the type (or a significant amount of work implementing all the methods). The signatures of these methods also use `number` which is [not a semantically relevant type](./2024-05-21_primitive-integer-types.md).

Achieving semantic compatability with EcmaScript's `String` type would also be very expensive as it uses utf-16 encoding underneath whilst an ABI string is utf-8 encoded. A significant number of ops (and program size) would be required to convert between the two. If we were to ignore this and use utf-8 at runtime, apis such as `.length` would return different results. For example `"😄".length` in ES returns `2` whilst utf-8 encoding would yield `1` codepoint or `4` bytes, similarly indexing and slicing would yield different results.

The Uint8Array type is fit for purpose as an encoding mechanism but the API is not as friendly as it could be for writing declarative contracts. The `new` keyword feels unnatural for something that is ostensibly a primitive type. The fact that it is mutable also complicates the implementation the compiler produces for the AVM.



### Option 2 - Branded strings (TEALScript approach)


TEALScript uses a branded `string` to represent `bytes` and native `string` to represent UTF-8 bytes. Base64/Base16 encoding/decoding is performed with specific methods.

```typescript
const someString = "foo"
const someHexValue = hex("0xdeadbeef") // branded "bytes"
```

Bytes and UTF-8 strings are typed via branded `string` types. UTF-8 strings are the most common use case for strings, thus have the JavaScript `String` prototype functions when working with byteslice, which provides a familiar set of function signatures. This option also enables the usage of `+` for concatenation.

To differentiate between ABI `string` and AVM `byteslice`, a branded type, `bytes`, can be used to represent non-encoded byteslices that may or may not be UTF-8 strings.

Additional functions can be used when wanting to have string literals of a specific encoding represent a string or byteslice.


The downsides of using `string` are listed in Option 1.


### Option 3 - Define a class to represent Bytes

A `Bytes` class and `Str` (Name TBD) class are defined with a very specific API tailored to operations which are available on the AVM:

```ts
class Bytes {
  constructor(v: string) {
    this.v = v
  }

  concat(other: Bytes): Bytes {
    return new Bytes(this.v + other.v)
  }

  at(x: uint64): Bytes {
    return new Bytes(this.v[x])
  }

  /* etc */
}

class Str {
    /* implementation */
}

```

This solution provides great type safety and requires no transpilation to run _correctly_ on Node.js. However, non-primitive types in Node.js have equality checked by reference. Again the `new` keyword feels unnatural. Due to lack of overloading, `+` will not work as expected however concatenations do not require the same understanding of "order of operations" and nesting as numeric operations, so a `concat` method isn't as unwieldy (but still isn't idiomatic).

```ts
const a = new Bytes("Hello")
const b = new Bytes("World")
const c = new Str("Example string")
const ab = a.concat(b)

function testValue(x: Bytes) {
  // No compile error, but will work on reference not value
  switch(x) {
    case a:
      return b
    case b:
      return a
  }
  return new Bytes("default")
}
```

To have equality checks behave as expected we would need a transpilation step to replace bytes values in certain expressions with a primitive type.

### Option 4 - Implement bytes as a class but define it as a type + factory

We can iron out some of the rough edges of using a class by only exposing a factory method for `Bytes`/`Str` and a resulting type `bytes`/`str`. This removes the need for the `new` keyword and lets us use a 'primitive looking' type alias (`bytes` versus `Bytes`, `str` versus `Str` - much like `string` and `String`). We can use [tagged templates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates) to improve the user experience of multipart concat expressions in lieu of having the `+` operator.

```ts

export type bytes = {
    readonly length: uint64

    at(i: Uint64Compat): bytes

    concat(other: BytesCompat): bytes
} & symbol

export function Bytes(value: TemplateStringsArray, ...replacements: BytesCompat[]): bytes
export function Bytes(value: BytesCompat): bytes
export function Bytes(value: BytesCompat | TemplateStringsArray, ...replacements: BytesCompat[]): bytes {
    /* implementation */
}

const a = Bytes("Hello")
const b = Bytes.fromHex("ABFF")
const c = Bytes.fromBase64("...")
const d = Bytes.fromInts(255, 123, 28, 20)
const e = Bytes`${a} World!`


function testValue(x: bytes, y: bytes): bytes {
  return Bytes`${x} and ${y}`
}

const f = Str`Example string`

```

Whilst we still can't accept string literals on their own, the tagged template is almost as concise. 

Having `bytes` and `str` behave like a primitive value type (value equality) whilst not _actually_ being a primitive is not strictly semantically compatible with EcmaScript however the lowercase type names (plus factory with no `new` keyword) communicates the intention of it being a primitive value type and there is an existing precedence of introducing new value types to the language in a similar pattern (`bigint` and `BigInt`). Essentially - if EcmaScript were to have a primitive bytes type, this is most likely what it would look like.

## Preferred option

Option 3 can be excluded because the requirement for a `new` keyword feels unnatural for representing a primitive value type. 

Option 1 and 2 are not preferred as they make maintaining semantic compatability with EcmaScript impractical.

Option 4 gives us the most natural feeling api whilst still giving us full control over the api surface. It doesn't support the `+` operator, but supports interpolation and `.concat` which gives us most of what `+` provides other than augmented assignment (ie. `+=`). 

We should select an appropriate name for the type representing an AVM string. It should not conflict with the semantically incompatible EcmaScript type `string`. 
 - `str`/`Str`: 
   - ✅ Short
   - ✅ obvious what it is
   - ✅ obvious equivalent in ABI types
   - ❌ NOT obvious how it differs from EcmaScript `string`
 - `utf8`/`Utf8`:
   - ✅ Short
   - ✅ reasonably obvious what it is
   - 🤔 less obvious equivalent in ABI types
   - ✅ obvious how it differs to `string`
 - `utf8string`/`Utf8String`
   - ❌ Verbose
   - ✅ obvious equivalent in ABI types
   - ✅ very obvious what it is
   - ✅ obvious how it differs to `string`



## Selected option

Option 4 has been selected as the best option
```
Page 24/74FirstPrevNextLast