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

# Directory Structure

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

# Files

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

```markdown
  1 | ---
  2 | arc: 4
  3 | title: Application Binary Interface (ABI)
  4 | description: Conventions for encoding method calls in Algorand Application
  5 | author: Jannotti (@jannotti), Jason Paulos (@jasonpaulos)
  6 | discussions-to: https://github.com/algorandfoundation/ARCs/issues/44
  7 | status: Final
  8 | type: Standards Track
  9 | category: Interface
 10 | sub-category: Application
 11 | created: 2021-07-29
 12 | ---
 13 | 
 14 | # Algorand Transaction Calling Conventions
 15 | 
 16 | ## Abstract
 17 | 
 18 | This document introduces conventions for encoding method calls,
 19 | including argument and return value encoding, in Algorand Application
 20 | call transactions.
 21 | The goal is to allow clients, such as wallets and
 22 | dapp frontends, to properly encode call transactions based on a description
 23 | of the interface. Further, explorers will be able to show details of
 24 | these method invocations.
 25 | 
 26 | ### Definitions
 27 | 
 28 | * **Application:** an Algorand Application, aka "smart contract",
 29 |   "stateful contract", "contract", or "app".
 30 | * **HLL:** a higher level language that compiles to TEAL bytecode.
 31 | * **dapp (frontend)**: a decentralized application frontend, interpreted here to
 32 |   mean an off-chain frontend (a webapp, native app, etc.) that interacts with
 33 |   Applications on the blockchain.
 34 | * **wallet**: an off-chain application that stores secret keys for on-chain
 35 |   accounts and can display and sign transactions for these accounts.
 36 | * **explorer**: an off-chain application that allows browsing the blockchain,
 37 |   showing details of transactions.
 38 | 
 39 | ## Specification
 40 | 
 41 | The key words "**MUST**", "**MUST NOT**", "**REQUIRED**", "**SHALL**", "**SHALL NOT**", "**SHOULD**", "**SHOULD NOT**", "**RECOMMENDED**", "**MAY**", and "**OPTIONAL**" in this document are to be interpreted as described in <a href="https://www.ietf.org/rfc/rfc2119.txt">RFC-2119</a>.
 42 | 
 43 | > Comments like this are non-normative.
 44 | 
 45 | Interfaces are defined in TypeScript. All the objects that are defined
 46 | are valid JSON objects, and all JSON `string` types are UTF-8 encoded.
 47 | 
 48 | ### Overview
 49 | 
 50 | This document makes recommendations for encoding method invocations as
 51 | Application call transactions, and for describing methods for
 52 | access by higher-level entities.  Encoding recommendations are
 53 | intended to be minimal, intended only to allow interoperability among
 54 | Applications.  Higher level recommendations are intended to enhance
 55 | user-facing interfaces, such as high-level languages, dapps, and
 56 | wallets.  Applications that follow the recommendations described here are
 57 | called _[ARC-4](./arc-0004.md) Applications_.
 58 | 
 59 | ### Methods
 60 | 
 61 | A method is a section of code intended to be invoked externally with
 62 | an Application call transaction. A method must have a name, it may
 63 | take a list of arguments as input when it is invoked, and it may
 64 | return a single value (which may be a tuple) when it finishes
 65 | running. The possible types for arguments and return values are
 66 | described later in the [Encoding](#encoding) section.
 67 | 
 68 | Invoking a method involves creating an Application call transaction to
 69 | specifically call that method. Methods are different from internal
 70 | subroutines that may exist in a contract, but are not externally
 71 | callable. Methods may be invoked by a top-level Application call
 72 | transaction from an off-chain caller, or by an Application call inner
 73 | transaction created by another Application.
 74 | 
 75 | 
 76 | #### Method Signature
 77 | 
 78 | A method signature is a unique identifier for a method. The signature
 79 | is a string that consists of the method's name, an open parenthesis, a
 80 | comma-separated list of the types of its arguments, a closing
 81 | parenthesis, and the method's return type, or `void` if it does not
 82 | return a value. The names of the arguments **MUST NOT** be included in a
 83 | method's signature, and **MUST NOT** contain any whitespace.
 84 | 
 85 | For example, `add(uint64,uint64)uint128` is the method signature for a
 86 | method named `add` which takes two uint64 parameters and returns a
 87 | uint128. Signatures are encoded in ASCII.
 88 | 
 89 | For the benefit of universal interoperability (especially in HLLs),
 90 | names **MUST** satisfy the regular expression `[_A-Za-z][A-Za-z0-9_]*`.
 91 | Names starting with an underscore are reserved and **MUST** only
 92 | be used as specified in this ARC or future ABI-related ARC.
 93 | 
 94 | 
 95 | #### Method Selector
 96 | 
 97 | Method signatures contain all the information needed to identify a
 98 | method, however the length of a signature is unbounded. Rather than
 99 | consume program space with such strings, a method selector is used to
100 | identify methods in calls. A method selector is the first four bytes of
101 | the SHA-512/256 hash of the method signature.
102 | 
103 | For example, the method selector for a method named `add` which takes
104 | two uint64 parameters and returns a uint128 can be computed as
105 | follows:
106 | 
107 | ```
108 | Method signature: add(uint64,uint64)uint128
109 | SHA-512/256 hash (in hex): 8aa3b61f0f1965c3a1cbfa91d46b24e54c67270184ff89dc114e877b1753254a
110 | Method selector (in hex): 8aa3b61f
111 | ```
112 | 
113 | 
114 | #### Method Description
115 | 
116 | A method description provides further information about a method
117 | beyond its signature. This description is encoded in JSON and consists
118 | of a method's name, description (optional), arguments (their types, and optional names and
119 | descriptions), and return type and optional description for the
120 | return type. From this structure, the method's signature and selector
121 | can be calculated. The Algorand SDKs provide convenience functions
122 | to calculate signatures and selectors from such JSON files.
123 | 
124 | These details will enable high-level languages and dapps/wallets to
125 | properly encode arguments, call methods, and decode return
126 | values. This description can populate UIs in dapps, wallets, and
127 | explorers with description of parameters, as well as populate
128 | information about methods in IDEs for HLLs.
129 | 
130 | The JSON structure for such an object is:
131 | 
132 | ```typescript
133 | interface Method {
134 |   /** The name of the method */
135 |   name: string;
136 |   /** Optional, user-friendly description for the method */
137 |   desc?: string;
138 |   /** The arguments of the method, in order */
139 |   args: Array<{
140 |     /** The type of the argument */
141 |     type: string;
142 |     /** Optional, user-friendly name for the argument */
143 |     name?: string;
144 |     /** Optional, user-friendly description for the argument */
145 |     desc?: string;
146 |   }>;
147 |   /** Information about the method's return value */
148 |   returns: {
149 |     /** The type of the return value, or "void" to indicate no return value. */
150 |     type: string;
151 |     /** Optional, user-friendly description for the return value */
152 |     desc?: string;
153 |   };
154 | }
155 | ```
156 | 
157 | For example:
158 | 
159 | ```json
160 | {
161 |   "name": "add",
162 |   "desc": "Calculate the sum of two 64-bit integers",
163 |   "args": [
164 |     { "type": "uint64", "name": "a", "desc": "The first term to add" },
165 |     { "type": "uint64", "name": "b", "desc": "The second term to add" }
166 |   ],
167 |   "returns": { "type": "uint128", "desc": "The sum of a and b" }
168 | }
169 | ```
170 | 
171 | 
172 | ### Interfaces
173 | 
174 | An Interface is a logically grouped set of methods. All method selectors in an
175 | Interface **MUST** be unique. Method names **MAY** not be unique, as long as
176 | the corresponding method selectors are different. Method names in Interfaces
177 | **MUST NOT** begin with an underscore.
178 | 
179 | An Algorand Application *implements* an Interface if it supports
180 | all of the methods from that Interface. An Application **MAY** implement
181 | zero, one, or multiple Interfaces.
182 | 
183 | Interface designers **SHOULD** try to prevent collisions of method selectors
184 | between Interfaces that are likely to be implemented together by the same
185 | Application.
186 | 
187 | > For example, an Interface `Calculator` providing addition and subtraction
188 | > of integer methods and an Interface `NumberFormatting` providing formatting
189 | > methods for numbers into strings are likely to be used together.
190 | > Interface designers should ensure that all the methods in `Calculator` and
191 | > `NumberFormatting` have distinct method selectors.
192 | 
193 | 
194 | #### Interface Description
195 | 
196 | An Interface description is a JSON object containing the JSON
197 | descriptions for each of the methods in the Interface.
198 | 
199 | The JSON structure for such an object is:
200 | 
201 | ```typescript
202 | interface Interface {
203 |   /** A user-friendly name for the interface */
204 |   name: string;
205 |   /** Optional, user-friendly description for the interface */
206 |   desc?: string;
207 |   /** All of the methods that the interface contains */
208 |   methods: Method[];
209 | }
210 | ```
211 | 
212 | Interface names **MUST** satisfy the regular expression `[_A-Za-z][A-Za-z0-9_]*`.
213 | Interface names starting with `ARC` are reserved to interfaces defined in ARC.
214 | Interfaces defined in `ARC-XXXX` (where `XXXX` is a 0-padded number) **SHOULD**
215 | start with `ARC_XXXX`.
216 | 
217 | For example:
218 | 
219 | ```json
220 | {
221 |   "name": "Calculator",
222 |   "desc": "Interface for a basic calculator supporting additions and multiplications",
223 |   "methods": [
224 |     {
225 |       "name": "add",
226 |       "desc": "Calculate the sum of two 64-bit integers",
227 |       "args": [
228 |         { "type": "uint64", "name": "a", "desc": "The first term to add" },
229 |         { "type": "uint64", "name": "b", "desc": "The second term to add" }
230 |       ],
231 |       "returns": { "type": "uint128", "desc": "The sum of a and b" }
232 |     },
233 |     {
234 |       "name": "multiply",
235 |       "desc": "Calculate the product of two 64-bit integers",
236 |       "args": [
237 |         { "type": "uint64", "name": "a", "desc": "The first factor to multiply" },
238 |         { "type": "uint64", "name": "b", "desc": "The second factor to multiply" }
239 |       ],
240 |       "returns": { "type": "uint128", "desc": "The product of a and b" }
241 |     }
242 |   ]
243 | }
244 | ```
245 | 
246 | ### Contracts
247 | 
248 | A Contract is a declaration of what an Application implements. It includes
249 | the complete list of the methods implemented by the related Application.
250 | It is similar to an Interface, but it may include further details about the
251 | concrete implementation, as well as implementation-specific methods that
252 | do not belong to any Interface. All methods in a Contract **MUST** be
253 | unique; specifically, each method **MUST** have a unique method selector.
254 | 
255 | Method names in Contracts **MAY** begin with underscore, but these
256 | names are reserved for use by this ARC and future extensions of this ARC.
257 | 
258 | #### OnCompletion Actions and Creation
259 | 
260 | In addition to the set of methods from the Contract's definition,
261 | a Contract **MAY** allow Application calls with zero arguments, also
262 | known as bare Application calls. Since method invocations with zero
263 | arguments still encode the method selector as the first Application
264 | call argument, bare Application calls are always distinguishable
265 | from method invocations.
266 | 
267 | The primary purpose of bare Application calls is to allow the
268 | execution of an OnCompletion (`apan`) action which requires no
269 | inputs and has no return value. A Contract **MAY** allow this for
270 | all of the OnCompletion actions listed below, for only a subset of
271 | them, or for none at all. Great care should be taken when allowing
272 | these operations.
273 | 
274 | Allowed OnCompletion actions:
275 | * 0: NoOp
276 | * 1: OptIn
277 | * 2: CloseOut
278 | * 4: UpdateApplication
279 | * 5: DeleteApplication
280 | 
281 | Note that OnCompletion action 3, ClearState, is **NOT** allowed to
282 | be invoked as a bare Application call.
283 | 
284 | > While ClearState is a valid OnCompletion action, its behavior differs
285 | > significantly from the other actions. Namely, an Application running during
286 | > ClearState which wishes to have any effect on the state of the chain
287 | > must never fail, since due to the unique behavior about ClearState
288 | > failure, doing so would revert any effect made by that Application.
289 | > Because of this, Applications running during ClearState are
290 | > incentivized to never fail. Accepting any user input, whether that
291 | > is an ABI method selector, method arguments, or even relying on the
292 | > absence of Application arguments to indicate a bare Application call,
293 | > is therefore a dangerous operation, since there is no way to enforce
294 | > properties or even the existence of data that is supplied by the user.
295 | 
296 | If a Contract elects to allow bare Application calls for some
297 | OnCompletion actions, then that Contract **SHOULD** also allow
298 | any of its methods to be called with those OnCompletion actions,
299 | as long as this would not cause undesirable or nonsensical behavior.
300 | 
301 | > The reason for this is because if it's acceptable to allow an
302 | > OnCompletion action to take place in isolation inside of a bare
303 | > Application call, then it's most likely acceptable to allow
304 | > the same action to take place at the same time as an ABI method
305 | > call. And since the latter can be accomplished in just one
306 | > transaction, it can be more efficient.
307 | 
308 | If a Contract requires an OnCompletion action to take inputs or
309 | to return a value, then the **RECOMMENDED** behavior of the Contract
310 | is to not allow bare Application calls for that OnCompletion
311 | action. Rather, the Contract should have one or more methods that
312 | are meant to be called with the appropriate OnCompletion action set
313 | in order to process that action.
314 | 
315 | A Contract **MUST NOT** allow any of its methods to be called with the
316 | ClearState OnCompletion action.
317 | 
318 | > To reinforce an earlier point, it is unsafe for a ClearState program
319 | > to read any user input, whether that is a method argument or even
320 | > relying on a certain method selector to be present. This behavior
321 | > makes it unsafe to use ABI calling conventions during ClearState.
322 | 
323 | If an Application is called with greater than zero Application call
324 | arguments (i.e. **NOT** a bare Application call) and the OnCompletion
325 | action is **NOT** ClearState, the Application **MUST**
326 | always treat the first argument as a method selector and invoke
327 | the specified method. This behavior **MUST** be followed for all
328 | OnCompletion actions, except for ClearState. This applies to Application
329 | creation transactions as well, where the supplied Application ID is 0.
330 | 
331 | Similar to OnCompletion actions, if a Contract requires its
332 | creation transaction to take inputs or to return a value, then
333 | the **RECOMMENDED** behavior of the Contract should be to not
334 | allow bare Application calls for creation. Rather, the Contract
335 | should have one or more methods that are meant to be called
336 | in order to create the Contract.
337 | 
338 | #### Contract Description
339 | 
340 | A Contract description is a JSON object containing the JSON
341 | descriptions for each of the methods in the Contract.
342 | 
343 | The JSON structure for such an object is:
344 | 
345 | ```typescript
346 | interface Contract {
347 |   /** A user-friendly name for the contract */
348 |   name: string;
349 |   /** Optional, user-friendly description for the interface */
350 |   desc?: string;
351 |   /**
352 |    * Optional object listing the contract instances across different networks
353 |    */
354 |   networks?: {
355 |     /**
356 |      * The key is the base64 genesis hash of the network, and the value contains
357 |      * information about the deployed contract in the network indicated by the
358 |      * key
359 |      */
360 |     [network: string]: {
361 |       /** The app ID of the deployed contract in this network */
362 |       appID: number;
363 |     }
364 |   }
365 |   /** All of the methods that the contract implements */
366 |   methods: Method[];
367 | }
368 | ```
369 | 
370 | Contract names **MUST** satisfy the regular expression `[_A-Za-z][A-Za-z0-9_]*`.
371 | 
372 | The `desc` fields of the Contract and the methods inside the Contract
373 | **SHOULD** contain information that is not explicitly encoded in the other fields,
374 | such as support of bare Application calls, requirement of specific
375 | OnCompletion action for specific methods, and methods to call for creation
376 | (if creation cannot be done via a bare Application call).
377 | 
378 | For example:
379 | 
380 | ```json
381 | {
382 |   "name": "Calculator",
383 |   "desc": "Contract of a basic calculator supporting additions and multiplications. Implements the Calculator interface.",
384 |   "networks": {
385 |     "wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=": { "appID": 1234 },
386 |     "SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=": { "appID": 5678 },
387 |   },
388 |   "methods": [
389 |     {
390 |       "name": "add",
391 |       "desc": "Calculate the sum of two 64-bit integers",
392 |       "args": [
393 |         { "type": "uint64", "name": "a", "desc": "The first term to add" },
394 |         { "type": "uint64", "name": "b", "desc": "The second term to add" }
395 |       ],
396 |       "returns": { "type": "uint128", "desc": "The sum of a and b" }
397 |     },
398 |     {
399 |       "name": "multiply",
400 |       "desc": "Calculate the product of two 64-bit integers",
401 |       "args": [
402 |         { "type": "uint64", "name": "a", "desc": "The first factor to multiply" },
403 |         { "type": "uint64", "name": "b", "desc": "The second factor to multiply" }
404 |       ],
405 |       "returns": { "type": "uint128", "desc": "The product of a and b" }
406 |     }
407 |   ]
408 | }
409 | ```
410 | 
411 | 
412 | ### Method Invocation
413 | 
414 | In order for a caller to invoke a method, the caller and the method
415 | implementation (callee) must agree on how information will be passed
416 | to and from the method. This ABI defines a standard for where this
417 | information should be stored and for its format.
418 | 
419 | This standard does not apply to Application calls with the ClearState
420 | OnCompletion action, since it is unsafe for ClearState programs to rely
421 | on user input.
422 | 
423 | #### Standard Format
424 | 
425 | The method selector must be the first Application call argument (index 0),
426 | accessible as `txna ApplicationArgs 0` from TEAL (except for bare Application
427 | calls, which use zero application call arguments).
428 | 
429 | If a method has 15 or fewer arguments, each argument **MUST** be placed in
430 | order in the following Application call argument slots (indexes 1 through
431 | 15). The arguments **MUST** be encoded as defined in the [Encoding](#encoding)
432 | section.
433 | 
434 | Otherwise, if a method has 16 or more arguments, the first 14 **MUST** be
435 | placed in order in the following Application call argument slots (indexes 1
436 | through 14), and the remaining arguments **MUST** be encoded as a tuple
437 | in the final Application call argument slot (index 15). The arguments must
438 | be encoded as defined in the [Encoding](#encoding) section.
439 | 
440 | If a method has a non-void return type, then the return value of the method
441 | **MUST** be located in the final logged value of the method's execution,
442 | using the `log` opcode. The logged value **MUST** contain a specific 4 byte
443 | prefix, followed by the encoding of the return value as defined in the
444 | [Encoding](#encoding) section. The 4 byte prefix is defined as the first 4
445 | bytes of the SHA-512/256 hash of the ASCII string `return`. In hex, this is
446 | `151f7c75`.
447 | 
448 | > For example, if the method `add(uint64,uint64)uint128` wanted to return the
449 | > value 4160, it would log the byte array `151f7c7500000000000000000000000000001040`
450 | > (shown in hex).
451 | 
452 | #### Implementing a Method
453 | 
454 | An ARC-4 Application implementing a method:
455 | 
456 | 1. **MUST** check if `txn NumAppArgs` equals 0. If true, then this is a
457 | bare Application call. If the Contract supports bare Application calls
458 | for the current transaction parameters (it **SHOULD** check the OnCompletion
459 | action and whether the transaction is creating the application), it **MUST**
460 | handle the call appropriately and either approve or reject the transaction.
461 | The following steps **MUST** be ignored in this case. Otherwise, if
462 | the Contract does not support this bare application call, the Contract
463 | **MUST** reject the transaction.
464 | 
465 | 2. **MUST** examine `txna ApplicationArgs 0` to identify the selector
466 | of the method being invoked. If the contract does not implement a method with
467 | that selector, the Contract **MUST** reject the transaction.
468 | 
469 | 3. **MUST** execute the actions required to implement the method being
470 | invoked. In general, this works by branching to the body of the method
471 | indicated by the selector.
472 | 
473 | 4. The code for that method **MAY** extract the arguments it needs, if
474 | any, from the application call arguments as described in the [Encoding](#encoding)
475 | section. If the method has more than 15 arguments and the contract
476 | needs to extract an argument beyond the 14th, it **MUST** decode
477 | `txna ApplicationArgs 15` as a tuple to access the arguments contained in it.
478 | 
479 | 5. If the method is non-void, the Application **MUST** encode the
480 | return value as described in the [Encoding](#encoding) section and then
481 | `log` it with the prefix `151f7c75`. Other values **MAY** be logged
482 | before the return value, but other values **MUST NOT** be logged after
483 | the return value.
484 | 
485 | 
486 | #### Calling a Method from Off-Chain
487 | 
488 | To invoke an ARC-4 Application, an off-chain system, such as a dapp or wallet,
489 | would first obtain the Interface or Contract description JSON object
490 | for the app. The client may now:
491 | 
492 | 1. Create an Application call transaction with the following parameters:
493 |     1. Use the ID of the desired Application whose program code
494 |        implements the method being invoked, or 0 if they wish to
495 |        create the Application.
496 |     2. Use the selector of the method being invoked as the first
497 |        Application call argument.
498 |     3. Encode all arguments for the method, if any, as described in
499 |        the [Encoding](#encoding) section. If the method has more than 15 arguments,
500 |        encode all arguments beyond (but not including) the 14th
501 |        as a tuple into the final Application call argument.
502 | 2. Submit this transaction and wait until it successfully commits to
503 |    the blockchain.
504 | 3. Decode the return value, if any, from the ApplyData's log
505 |    information.
506 | 
507 | Clients **MAY** ignore the return value.
508 | 
509 | An exception to the above instructions is if the app supports bare
510 | Application calls for some transaction parameters, and the client
511 | wishes to invoke this functionality. Then the client may simply create
512 | and submit to the network an Application call transaction with the ID of
513 | the Application (or 0 if they wish to create the application) and the
514 | desired OnCompletion value set. Application arguments **MUST NOT** be
515 | present.
516 | 
517 | ### Encoding
518 | 
519 | This section describes how ABI types can be represented as byte strings.
520 | 
521 | Like the <a href="https://docs.soliditylang.org/en/v0.8.6/abi-spec.html">EthereumABI</a>, this
522 | encoding specification is designed to have the following two
523 | properties:
524 | 
525 | 
526 | 1. The number of non-sequential "reads" necessary to access a value is
527 |    at most the depth of that value inside the encoded array
528 |    structure. For example, at most 4 reads are needed to retrieve a
529 |    value at `a[i][k][l][r]`.
530 | 2. The encoding of a value or array element is not interleaved with
531 |    other data and it is relocatable, i.e. only relative “addresses”
532 |    (indexes to other parts of the encoding) are used.
533 | 
534 | 
535 | #### Types
536 | 
537 | The following types are supported in the Algorand ABI.
538 | 
539 | * `uint<N>`: An `N`-bit unsigned integer, where `8 <= N <= 512` and `N % 8 = 0`. When this type is
540 | used as part of a method signature, `N` must be written as a base 10 number without any leading zeros.
541 | * `byte`: An alias for `uint8`.
542 | * `bool`: A boolean value that is restricted to either 0 or 1. When encoded, up to 8 consecutive
543 | `bool` values will be packed into a single byte.
544 | * `ufixed<N>x<M>`: An `N`-bit unsigned fixed-point decimal number with precision `M`, where
545 | `8 <= N <= 512`, `N % 8 = 0`, and `0 < M <= 160`, which denotes a value `v` as `v / (10^M)`. When
546 | this type is used as part of a method signature, `N` and `M` must be written as base 10 numbers
547 | without any leading zeros.
548 | * `<type>[<N>]`: A fixed-length array of length `N`, where `N >= 0`. `type` can be any other type.
549 | When this type is used as part of a method signature, `N` must be written as a base 10 number without
550 | any leading zeros, _unless_ `N` is zero, in which case only a single 0 character should be used.
551 | * `address`: Used to represent a 32-byte Algorand address. This is equivalent to `byte[32]`.
552 | * `<type>[]`: A variable-length array. `type` can be any other type.
553 | * `string`: A variable-length byte array (`byte[]`) assumed to contain UTF-8 encoded content.
554 | * `(T1,T2,…,TN)`: A tuple of the types `T1`, `T2`, …, `TN`, `N >= 0`.
555 | * reference types `account`, `asset`, `application`: **MUST NOT** be used as the return type.
556 | For encoding purposes they are an alias for `uint8`. See section "Reference Types" below.
557 | 
558 | Additional special use types are defined in [Reference Types](#reference-types)
559 | and [Transaction Types](#transaction-types).
560 | 
561 | #### Static vs Dynamic Types
562 | 
563 | For encoding purposes, the types are divided into two categories: static and dynamic.
564 | 
565 | The dynamic types are:
566 | 
567 | *  `<type>[]` for any `type`
568 |     * This includes `string` since it is an alias for `byte[]`.
569 | * `<type>[<N>]` for any dynamic `type`
570 | * `(T1,T2,...,TN)` if `Ti` is dynamic for some `1 <= i <= N`
571 | 
572 | All other types are static. For a static type, all encoded values of
573 | that type have the same length, irrespective of their actual value.
574 | 
575 | 
576 | #### Encoding Rules
577 | 
578 | Let `len(a)` be the number of bytes in the binary string `a`. The
579 | returned value shall be considered to have the ABI type `uint16`.
580 | 
581 | Let `enc` be a mapping from values of the ABI types to binary
582 | strings. This mapping defines the encoding of the ABI.
583 | 
584 | For any ABI value `x`, we recursively define `enc(x)` to be as follows:
585 | 
586 | * If `x` is a tuple of `N` types, `(T1,T2,...,TN)`, where `x[i]` is the value at index `i`, starting at 1:
587 |     * `enc(x) = head(x[1]) ... head(x[N]) tail(x[1]) ... tail(x[N])`
588 |     * Let `head` and `tail` be mappings from values in this tuple to binary strings. For each `i` such that `1 <= i <= N`, these mappings are defined as:
589 |         * If `Ti` (the type of `x[i]`) is static:
590 |             * If `Ti` is `bool`:
591 |                 * Let `after` be the largest integer such that all `T(i+j)` are `bool`, for `0 <= j <= after`.
592 |                 * Let `before` be the largest integer such that all `T(i-j)` are `bool`, for `0 <= j <= before`.
593 |                 * If `before % 8 == 0`:
594 |                     * `head(x[i]) = enc(x[i]) | (enc(x[i+1]) >> 1) | ... | (enc(x[i + min(after,7)]) >> min(after,7))`, where `>>` is bitwise right shift which pads with 0, `|` is bitwise or, and `min(x,y)` returns the minimum value of the integers `x` and `y`.
595 |                     * `tail(x[i]) = ""` (the empty string)
596 |                 * Otherwise:
597 |                     * `head(x[i]) = ""` (the empty string)
598 |                     * `tail(x[i]) = ""` (the empty string)
599 |             * Otherwise:
600 |                 * `head(x[i]) = enc(x[i])`
601 |                 * `tail(x[i]) = ""` (the empty string)
602 |         * Otherwise:
603 |             * `head(x[i]) = enc(len( head(x[1]) ... head(x[N]) tail(x[1]) ... tail(x[i-1]) ))`
604 |             * `tail(x[i]) = enc(x[i])`
605 | * If `x` is a fixed-length array `T[N]`:
606 |     * `enc(x) = enc((x[0], ..., x[N-1]))`, i.e. it’s encoded as if it were an `N` element tuple where every element is type `T`.
607 | * If `x` is a variable-length array `T[]` with `k` elements:
608 |     * `enc(x) = enc(k) enc([x[0], ..., x[k-1]])`, i.e. it’s encoded as if it were a fixed-length array of `k` elements, prefixed with its length, `k` encoded as a `uint16`.
609 | * If `x` is an `N`-bit unsigned integer, `uint<N>`:
610 |     * `enc(x)` is the `N`-bit big-endian encoding of `x`.
611 | * If `x` is an `N`-bit unsigned fixed-point decimal number with precision `M`, `ufixed<N>x<M>`:
612 |     * `enc(x) = enc(x * 10^M)`, where `x * 10^M` is interpreted as a `uint<N>`.
613 | * If `x` is a boolean value `bool`:
614 |     * `enc(x)` is a single byte whose **most significant bit** is either 1 or 0, if `x` is true or false respectively. All other bits are 0. Note: this means that a value of true will be encoded as `0x80` (`10000000` in binary) and a value of false will be encoded as `0x00`. This is in contrast to most other encoding schemes, where a value of true is encoded as `0x01`.
615 | 
616 | Other aliased types' encodings are already covered:
617 | - `string` and `address` are aliases for `byte[]` and `byte[32]` respectively
618 | - `byte` is an alias for `uint8`
619 | - each of the reference types is an alias for `uint8`
620 | 
621 | #### Reference Types
622 | 
623 | Three special types are supported _only_ as the type of an argument.
624 | They _can_ be embedded in arrays and tuples.
625 | 
626 | * `account` represents an Algorand account, stored in the Accounts (`apat`) array
627 | * `asset` represents an Algorand Standard Asset (ASA), stored in the Foreign Assets (`apas`) array
628 | * `application` represents an Algorand Application, stored in the Foreign Apps (`apfa`) array
629 | 
630 | Some AVM opcodes require specific values to be placed in the "foreign
631 | arrays" of the Application call transaction. These three types allow
632 | methods to describe these requirements. To encode method calls that
633 | have these types as arguments, the value in question is placed in the
634 | Accounts (`apat`), Foreign Assets (`apas`), or Foreign Apps (`apfa`)
635 | arrays, respectively, and a `uint8` containing the index of the value
636 | in the appropriate array is encoded in the normal location for this
637 | argument.
638 | 
639 | Note that the Accounts and Foreign Apps arrays have an implicit value
640 | at index 0, the Sender of the transaction or the called Application,
641 | respectively. Therefore, indexes of any additional values begin at 1.
642 | Additionally, for efficiency, callers of a method that wish to pass the
643 | transaction Sender as an `account` value or the called Application as
644 | an `application` value **SHOULD** use 0 as the index of these values
645 | and not explicitly add them to Accounts or Foreign Apps arrays.
646 | 
647 | When passing addresses, ASAs, or apps that are _not_ required to be
648 | accessed by such opcodes, ARC-4 Contracts **SHOULD** use the base
649 | types for passing these types: `address` for accounts and `uint64`
650 | for asset or Application IDs.
651 | 
652 | #### Transaction Types
653 | 
654 | Some apps require that they are invoked as part of a larger
655 | transaction group, containing specific additional transactions.  Seven
656 | additional special types are supported (only) as argument types to
657 | describe such requirements.
658 | 
659 | * `txn` represents any Algorand transaction
660 | * `pay` represents a PaymentTransaction (algo transfer)
661 | * `keyreg` represents a KeyRegistration transaction (configure
662 |   consensus participation)
663 | * `acfg` represent a AssetConfig transaction (create, configure, or
664 |   destroy ASAs)
665 | * `axfer` represents an AssetTransfer transaction (ASA transfer)
666 | * `afrz` represents an AssetFreezeTx transaction (freeze or unfreeze
667 |   ASAs)
668 | * `appl` represents an ApplicationCallTx transaction (create/invoke a Application)
669 | 
670 | Arguments of these types are encoded as consecutive transactions in
671 | the same transaction group as the Application call, placed in the
672 | position immediately preceding the Application call. Unlike "foreign"
673 | references, these special types are not encoded in ApplicationArgs as
674 | small integers "pointing" to the associated object.  In fact, they
675 | occupy no space at all in the Application Call transaction
676 | itself. Allowing explicit references would create opportunities for
677 | multiple transaction "values" to point to the same transaction in the
678 | group, which is undesirable. Instead, the locations of the
679 | transactions are implied entirely by the placement of the transaction
680 | types in the argument list.
681 | 
682 | For example, to invoke the method `deposit(string,axfer,pay,uint32)void`,
683 | a client would create a transaction group containing, in this order:
684 | 1. an asset transfer
685 | 2. a payment
686 | 3. the actual Application call
687 | 
688 | When encoding the other (non-transaction) arguments, the client
689 | **MUST** act as if the transaction arguments were completely absent
690 | from the method signature. The Application call would contain the method
691 | selector in ApplicationArgs[0], the first (string) argument in
692 | ApplicationArgs[1], and the fourth (uint32) argument in ApplicationArgs[2].
693 | 
694 | 
695 | ARC-4 Applications **SHOULD** be constructed to allow their invocations to be
696 | combined with other contract invocations in a single atomic group if
697 | they can do so safely. For example, they **SHOULD** use `gtxns` to examine
698 | the previous index in the group for a required `pay` transaction,
699 | rather than hardcode an index with `gtxn`.
700 | 
701 | In general, an ARC-4 Application method with `n` transactions as arguments **SHOULD**
702 | only inspect the `n` previous transactions. In particular, it **SHOULD NOT**
703 | inspect transactions after and it **SHOULD NOT** check the size of a transaction
704 | group (if this can be done safely).
705 | In addition, a given method **SHOULD** always expect the same
706 | number of transactions before itself. For example, the method
707 | `deposit(string,axfer,pay,uint32)void` is always preceded by two transactions.
708 | It is never the case that it can be called only with one asset transfer
709 | but no payment transfer.
710 | 
711 | > The reason for the above recommendation is to provide minimal
712 | > composability support while preventing obvious dangerous attacks.
713 | > For example, if some apps expect payment transactions after them
714 | > while other expect payment transaction before them, then the same
715 | > payment may be counted twice.
716 | 
717 | ## Rationale
718 | 
719 | ## Security Considerations
720 | 
721 | None.
722 | 
723 | ## Copyright
724 | 
725 | Copyright and related rights waived via <a href="https://creativecommons.org/publicdomain/zero/1.0/">CCO</a>.
726 | 
```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/developer:docs:details:dapps:smart-contracts:apps:state.md:
--------------------------------------------------------------------------------

```markdown
  1 | title: Contract storage
  2 | 
  3 | # Smart contract storage 
  4 | Smart Contracts have three different types of storage: [local storage](#local-storage), [global storage](#global-storage), and [box storage](#box-storage). 
  5 | 
  6 | Global state and boxes are associated with the app itself, whereas local state is associated with each account that opts into the application. Global and local storage are Key/Value pairs that are limited to 128 bytes per pair. Boxes are keyed storage segments up to 32kb of data per box.
  7 | 
  8 | Each storage option’s properties are described below. 
  9 | 
 10 | ## Global Storage
 11 | 
 12 | * Allocation: 
 13 |     * Can include between 0 and 64 key/value pairs for a total of 8K of memory to share among them.
 14 |     * The amount of global storage is allocated in k/v units, and determined at contract creation. This schema is immutable after creation. 
 15 |     * The contract creator address is responsible for funding the global storage (by an increase to their minimum balance requirement, see below). 
 16 | * Reading: 
 17 |     * Can be read by any app call that has specified app a’s ID in its foreign apps array.
 18 |     * Can be read on-chain using the k/v pairs defined (from off-chain, can be read using goal or APIs + SDKs). 
 19 | * Writing: 
 20 |     * Can only be written by app a. 
 21 | * Deletion: 
 22 |     * Is deleted when app a is deleted. Cannot otherwise be deallocated (though of course the contents can be cleared by app a, but this does not change the minimum balance requirement). 
 23 | 
 24 | ## Local Storage
 25 | 
 26 | * Allocation: 
 27 |     * Is allocated when account x opts in to app a (submits a transaction to opt-in to app a).
 28 |     * Can include between 0 and 16 key/value pairs for a total of 2KB of memory to share among them. 
 29 |     * The amount of local storage is allocated in k/v units, and determined at contract creation. This cannot be edited later. 
 30 |     * The opted-in user address is responsible for funding the local storage (by an increase to their minimum balance). 
 31 | * Reading: 
 32 |     * Can be read by any app call that has app a in its foreign apps array and account x in its foreign accounts array. 
 33 |     * Can be read on-chain using the k/v pairs defined (from off-chain, can be read using goal and the SDKs). 
 34 | * Writing: 
 35 |     * Is editable only by app a, but is delete-able by app a or the user x (using a ClearState call, see below). 
 36 | * Deletion: 
 37 |     * Deleting an app does not affect its local storage. Accounts must clear out of app to recover minimum balance.
 38 |     * _Clear state_. Every Smart Contract on Algorand has two programs: the _approval_ and the _clear state_ program. An account holder can clear their local state for an app at any time (deleting their data and freeing up their locked minimum balance). The purpose of the clear state program is to allow the app to handle the clearing of that local state gracefully. 
 39 |     * Account x can request to clear its local state using a [close out transaction](https://developer.algorand.org/docs/get-details/transactions/#application-close-out-transaction). 
 40 |     * Account x can clear its local state for app a using a [clear state transaction](https://developer.algorand.org/docs/get-details/transactions/#application-clear-state-transaction), which will always succeed, even after app a is deleted. 
 41 | 
 42 | 
 43 | ## Box Storage 
 44 | 
 45 | * Allocation: 
 46 |     * App a can allocate as many boxes as it needs, when it needs them.
 47 |     * App a allocates a box using the `box_create` opcode in its TEAL program, specifying the name and the size of the box being allocated. 
 48 |         * Boxes can be any size from 0 to 32K bytes. 
 49 |         * Box names must be at least 1 byte, at most 64 bytes, and must be unique within app a. 
 50 |     * The app account(the smart contract) is responsible for funding the box storage (with an increase to its minimum balance requirement, see below for details). 
 51 |     * A box name and app id must be referenced in the boxes array of the app call to be allocated. 
 52 | * Reading: 
 53 |     * App a is the only app that can read the contents of its boxes on-chain. This on-chain privacy is unique to box storage. Recall that everything can be read by anybody from off-chain using the algod or indexer APIs. 
 54 |     * To read box b from app a, the app call must include b in its boxes array. 
 55 |     * Read budget: Each box reference in the boxes array allows an app call to access 1K bytes of box state - 1K of “box read budget”. To read a box larger than 1K, multiple box references must be put in the boxes arrays. 
 56 |         * The box read budget is shared across the transaction group. 
 57 |         * The total box read budget must be larger than the sum of the sizes of all the individual boxes referenced (it is not possible to use this read budget for a part of a box - the whole box is read in).
 58 |     * Box data is unstructured. This is unique to box storage. 
 59 |     * A box is referenced by including its app ID and box name. 
 60 | * Writing: 
 61 |     * App a is the only app that can write the contents of its boxes.
 62 |     * As with reading, each box ref in the boxes array allows an app call to write 1kb of box state - 1kb of “box write budget”. 
 63 | * Deletion: 
 64 |     * App a is the only app that can delete its boxes. 
 65 |     * If an app is deleted, its boxes are not deleted. The boxes will not be modifiable but still can be queried using the SDKs. The minimum balance will also be locked. (the correct cleanup design is to look up the boxes from off-chain and call the app to delete all its boxes before deleting the app itself). 
 66 | 
 67 | 
 68 | # Manipulate global or local state in smart contract
 69 | Smart contracts can create, update, and delete values in global or local state. The number of values that can be written is limited based on how the contract was first created. See [Creating the Smart Contract](#creating-the-smart-contract) for details on configuring the initial global and local storage. State is represented with key-value pairs. The key is limited to 64 bytes. The key plus the value is limited to 128 bytes total. Using smaller keys to have more storage available for the value is possible. The keys are stored as byte slices (byte-array value) and the values are stored as either byte slices (byte-array value) or uint64s. The TEAL language provides several opcodes for facilitating reading and writing to state.
 70 | 
 71 | ## Reading local state from other accounts
 72 | Local storage values are stored in the account's balance record. Any account that sends a transaction to the smart contract can have its local storage modified by the smart contract as long as the account has opted into the smart contract. In addition, any call to the smart contract can also reference up to four additional accounts which can also have their local storage manipulated for the current smart contract as long as the account has opted into the contract. These five accounts can also have their storage values for any smart contract on Algorand read by specifying the application id of the smart contract, if the additional contract is in the applications array for the transaction. This is a read-only operation and does not allow one smart contract to modify the local state of another smart contract. The additionally referenced accounts can be changed per smart contract call (transaction). The process for reading local state from another account is described in the following sections.
 73 | 
 74 | ## Reading global state from other smart contracts
 75 | Global storage for the current contract can also be modified by the smart contract code. In addition, the global storage of any contract in the applications array can be read. This is a read-only operation. The global state can not be changed for other smart contracts. The external smart contracts can be changed per smart contract call (transaction). The process for reading global state from another smart contract is described in the following sections.
 76 | 
 77 | ## Write to state
 78 | To write to either local or global state, the opcodes `app_global_put` and `app_local_put` should be used. These calls are similar but with local storage, you provide an additional account parameter. This determines what account should have its local storage modified. In addition to the sender of the transaction, any call to the smart contract can reference up to four additional accounts. Below is an example of doing a global write. See [Reference arrays](index.md#reference-arrays) for more details.
 79 | 
 80 | === "PyTeal"
 81 | 	<!-- ===PYTEAL_WRITE_GLOBAL_STATE=== -->
 82 | 	```python
 83 | 	    program = App.globalPut(Bytes("Mykey"), Int(50))
 84 | 	    print(compileTeal(program, Mode.Application))
 85 | 	```
 86 | 	[Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/kv_state.py#L5-L7)
 87 | 	<!-- ===PYTEAL_WRITE_GLOBAL_STATE=== -->
 88 | 
 89 | === "TEAL"
 90 | 	<!-- ===TEAL_WRITE_GLOBAL_STATE=== -->
 91 | 	```teal
 92 | 	byte "GlobalKey"
 93 | 	int 42
 94 | 	app_global_put
 95 | 	```
 96 | 	[Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/state_manipulation/approval.teal#L8-L11)
 97 | 	<!-- ===TEAL_WRITE_GLOBAL_STATE=== -->
 98 | 
 99 | To store a value in local storage, the following contract code can be used.
100 | 
101 | === "PyTeal"
102 | 	```python
103 | 	    program = App.localPut(Txn.sender(), Bytes("MyLocalKey"), Int(50))
104 | 	    print(compileTeal(program, Mode.Application))
105 | 	```
106 | 
107 | 
108 | === "TEAL"
109 | 	```teal
110 | 	txn Sender
111 | 	byte "OwnLocalKey"
112 | 	int 1337
113 | 	app_local_put
114 | 	```
115 | 
116 | 
117 | In this example, the `txn Sender` represents the sender of the transaction. Any account in the accounts array can be specified. See [Reference arrays](index.md#reference-arrays) for more details.
118 | 
119 | 
120 | === "PyTeal"
121 | 	```python
122 | 	    program = App.localPut(Addr("GHZ..."), Bytes("MyLocalKey"), Int(50))
123 | 	    print(compileTeal(program, Mode.Application))
124 | 	```
125 | 
126 | 
127 | === "TEAL"
128 | 	```teal
129 | 	addr GHZ....
130 | 	byte "OtherLocalKey"
131 | 	int 200
132 | 	app_local_put
133 | 	```
134 | 
135 | 
136 | The account specified must be in the accounts array. See [Reference arrays](index.md#reference-arrays) for more details.
137 | 
138 | !!! info
139 |     Local storage writes are only allowed if the account has opted into the smart contract.
140 | 
141 | ## Read from state
142 | TEAL provides calls to read global and local state values for the current smart contract.  To read from local or global state TEAL provides the `app_local_get`, `app_global_get`, `app_local_get_ex` , and `app_global_get_ex` opcodes. The following contract code reads a value from global state for the current smart contract.
143 | 
144 | 
145 | === "PyTeal"
146 | 	<!-- ===PYTEAL_READ_GLOBAL_STATE=== -->
147 | 	```python
148 | 	    program = App.globalGet(Bytes("MyGlobalKey"))
149 | 	    print(compileTeal(program, Mode.Application))
150 | 	```
151 | 	[Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/kv_state.py#L26-L28)
152 | 	<!-- ===PYTEAL_READ_GLOBAL_STATE=== -->
153 | 
154 | === "TEAL"
155 | 	```teal
156 | 	byte "GlobalKey"
157 | 	app_global_get		
158 | 	```
159 | 
160 | 
161 | The following contract code reads the local state of the sender account.
162 | 
163 | === "PyTeal"
164 | 	```python
165 | 	    program = App.localGet(Txn.sender(), Bytes("MyLocalKey"))
166 | 	    print(compileTeal(program, Mode.Application))
167 | 	```
168 | 	
169 | 
170 | === "TEAL"
171 | 	```teal
172 | 	txn Sender
173 | 	byte "OwnLocalState"
174 | 	app_local_get
175 | 	```
176 | 
177 | The `_ex` opcodes return two values to the stack. The first value is a 0 or a 1 indicating the value was returned successfully or not, and the second value on the stack contains the actual value. These calls allow local and global states to be read from other accounts and applications (smart contracts) as long as the account and the contract are in the accounts and applications arrays. To read a local storage value with the `app_local_get_ex` opcode the following contract code should be used.
178 | 
179 | === "PyTeal"
180 | 	```python
181 | 	    program = App.localGetEx(Txn.sender(), Txn.application_id(), Bytes("MyAmountGiven"))
182 | 	    print(compileTeal(program, Mode.Application))
183 | 	```
184 | 
185 | === "TEAL"
186 | 	```teal
187 | 	txn Sender
188 | 	txn ApplicationID
189 | 	byte "MyAmountGiven"
190 | 	app_local_get_ex
191 | 	```
192 | 
193 | !!! note
194 |     The PyTeal code snippet preemptively stores the return values from `localGetEx` in scratch space for later reference. 
195 | 
196 | The `txn Sender` represents the sender of the transaction. The `txn ApplicationID` line refers to the current application, but could be any application that exists on Algorand as long as the contract's ID is in the applications array. See [Reference arrays](index.md#reference-arrays) for more details.  The top value on the stack will either return 0 or 1 depending on if the variable was found.  Most likely branching logic will be used after a call to the `_ex` opcode. The following example illustrates this concept.
197 | 
198 | === "PyTeal"
199 | 	```python
200 | 	    get_amount_given = App.localGetEx(
201 | 	        Txn.sender(), Txn.application_id(), Bytes("MyAmountGiven")
202 | 	    )
203 | 	
204 | 	    # Change these to appropriate logic for new and previous givers.
205 | 	    new_giver_logic = Seq(Return(Int(1)))
206 | 	
207 | 	    previous_giver_logic = Seq(Return(Int(1)))
208 | 	
209 | 	    program = Seq(
210 | 	        get_amount_given,
211 | 	        If(get_amount_given.hasValue(), previous_giver_logic, new_giver_logic),
212 | 	    )
213 | 	
214 | 	    print(compileTeal(program, Mode.Application))
215 | 	```
216 | 
217 | 
218 | === "TEAL"
219 | 	```teal
220 | 	txn Sender
221 | 	txn ApplicationID
222 | 	byte "deposited"
223 | 	app_local_get_ex
224 | 	bz new_deposit
225 | 	// Account has deposited before
226 | 	
227 | 	new_deposit:
228 | 	// Account is making their first deposit
229 | 	```
230 | 
231 | The `app_global_get_ex` is used to read not only the global state of the current contract but any contract that is in the applications array. To access these foreign apps, they must be passed in with the application call. See [Reference arrays](index.md#reference-arrays) for more details. 
232 | 
233 | ```bash
234 | $ goal app call --foreign-app APP1ID --foreign-app APP2ID
235 | ```
236 | 
237 | To read from the global state with the `app_global_get_ex` opcode, use the following TEAL.
238 | 
239 | === "PyTeal"
240 | 	```python
241 | 	    get_global_key = App.globalGetEx(Global.current_application_id(), Bytes("MyGlobalKey"))
242 | 	
243 | 	    # Update with appropriate logic for use case
244 | 	    increment_existing = Seq(Return(Int(1)))
245 | 	
246 | 	    program = Seq(
247 | 	        get_global_key,
248 | 	        If(get_global_key.hasValue(), increment_existing, Return(Int(1))),
249 | 	    )
250 | 	
251 | 	    print(compileTeal(program, Mode.Application))
252 | 	```
253 | 
254 | 
255 | === "TEAL"
256 | 	```teal
257 | 	global CurrentApplicationID
258 | 	byte "GlobalKey"
259 | 	app_global_get_ex
260 | 	```
261 | 
262 | The specified contract's ID must be in the applications array. See [Reference arrays](index.md#reference-arrays) for more details. Similar to the `app_local_get_ex` opcode, generally, there will be branching logic testing whether the value was found or not. 
263 | 
264 | ## Summary of global and Local state operations
265 | 
266 | | Context            | Write            | Read                | Delete           | Check If Exists     |
267 | | ---                | ---              | ---                 | ---              | ---                 |
268 | | Current App Global | `app_global_put` | `app_global_get`    | `app_global_del` | `app_global_get_ex` |
269 | | Current App Local  | `app_local_put`  | `app_local_get`     | `app_local_del`  | `app_local_get_ex`  |
270 | | Other App Global   |                  | `app_global_get_ex` |                  | `app_global_get_ex` |
271 | | Other App Local    |                  | `app_local_get_ex`  |                  | `app_local_get_ex`  |
272 | 
273 | # Box Details
274 | Boxes are useful in many scenarios:
275 | 
276 | * Applications that need larger or unbound contract storage.
277 | * Applications that want to store data per user, but do not wish to require users to opt-in to the contract or need the account data to persist even after the user closes or clears out of the application.
278 | * Applications that have dynamic storage requirements.
279 | * Applications that require larger storage blocks that can not fit in the existing global state key-value pairs.
280 | * Applications that require storing arbitrary maps or hash tables. 
281 |   
282 | The following sections cover the details of manipulating boxes within a smart contract. 
283 | 
284 | ## Box Array 
285 | The box array is an array of pairs: the first element of each pair is an integer specifying the index into the foreign application array, and the second element is the key name of the box to be accessed.
286 | 
287 | Each entry in the box array allows access to only 1kb of data. For example, if a box is sized to 4kb, the transaction must use four entries in this array. To claim an allotted entry a corresponding app Id and box name need to be added to the box ref array. If you need more than the 1kb associated with that specific box name, you can either specify the box ref entry more than once or, preferably, add “empty” box refs `[0,””]` into the array. If you specify 0 as the app Id the box ref is for the application being called. 
288 | 
289 | For example, suppose the contract needs to read “BoxA” which is 1.5kb, and “Box B” which is 2.5kb, this would require four entries in the box ref array and would look something like:
290 | 
291 | ```py
292 | boxes=[[0, "BoxA"],[0,"BoxB"], [0,""],[0,""]]
293 | ``` 
294 | 
295 | The required box I/O budget is based on the sizes of the boxes accessed, not the amount of data read or written. For example, if a contract accesses “Box A” with a size of 2kb and “Box B” with a size of 10 bytes, this requires both boxes be in the box reference array and one additional reference ( ceil((2kb + 10b) / 1kb), which can be an “empty” box reference. 
296 | 
297 | Access budgets are summed across multiple application calls in the same transaction group. For example in a group of two smart contract calls, there is room for 16 array entries (8 per app call), allowing access to 16kb of data. If an application needs to access a 16kb box named “Box A”, it will need to be grouped with one additional application call and the box reference array for each transaction in the group should look similar to this:
298 | 
299 | Transaction 0: [0,”Box A”],[0,””],[0,””],[0,””],[0,””],[0,””],[0,””],[0,””]
300 | Transaction 1: [0,””],[0,””],[0,””],[0,””],[0,””],[0,””],[0,””],[0,””]
301 | 
302 | Box refs can be added to the boxes array using `goal` or any of the SDKs.
303 | 
304 | === "Goal"
305 |     ```goal
306 |     goal app method --app-id=53 --method="add_member2()void" --box="53,str:BoxA" --from=CONP4XZSXVZYA7PGYH7426OCAROGQPBTWBUD2334KPEAZIHY7ZRR653AFY
307 |     ```
308 | 
309 | === "Python"
310 |     <!-- ===PYSDK_ATC_BOX_REF=== -->
311 | 	```python
312 | 	atc = AtomicTransactionComposer()
313 | 	atc.add_method_call(
314 | 	    app_id,
315 | 	    my_method,
316 | 	    addr,
317 | 	    sp,
318 | 	    signer,
319 | 	    boxes=[[app_id, b"key"]],
320 | 	)
321 | 	```
322 | 	[Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/atc.py#L78-L87)
323 |     <!-- ===PYSDK_ATC_BOX_REF=== -->
324 | 
325 | === "JavaScript"
326 |     <!-- ===JSSDK_ATC_BOX_REF=== -->
327 | 	```javascript
328 | 	const boxATC = new algosdk.AtomicTransactionComposer();
329 | 	const boxKey = new Uint8Array(Buffer.from('key'));
330 | 	boxATC.addMethodCall({
331 | 	  appID: appIndex,
332 | 	  method: boxAccessorMethod,
333 | 	  methodArgs: [],
334 | 	  boxes: [
335 | 	    {
336 | 	      appIndex: 0,
337 | 	      name: boxKey,
338 | 	    },
339 | 	  ],
340 | 	  sender: sender.addr,
341 | 	  signer: sender.signer,
342 | 	  suggestedParams,
343 | 	});
344 | 	```
345 | 	[Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/atc.ts#L101-L117)
346 |     <!-- ===JSSDK_ATC_BOX_REF=== -->
347 | 
348 | === "Go"
349 |     <!-- ===GOSDK_ATC_BOX_REF=== -->
350 | 	```go
351 | 	boxName := "coolBoxName"
352 | 	mcp = transaction.AddMethodCallParams{
353 | 		AppID:           appID,
354 | 		Sender:          acct1.Address,
355 | 		SuggestedParams: sp,
356 | 		OnComplete:      types.NoOpOC,
357 | 		Signer:          signer,
358 | 		Method:          addMethod,
359 | 		MethodArgs:      []interface{}{1, 1},
360 | 		// Here we're passing a box reference so our app
361 | 		// can reference it during evaluation
362 | 		BoxReferences: []types.AppBoxReference{
363 | 			{AppID: appID, Name: []byte(boxName)},
364 | 		},
365 | 	}
366 | 	// ...
367 | 	```
368 | 	[Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/atc/main.go#L95-L111)
369 |     <!-- ===GOSDK_ATC_BOX_REF=== -->
370 | 
371 | === "Java"
372 |     <!-- ===JAVASDK_ATC_BOX_REF=== -->
373 | 	```java
374 | 	MethodCallTransactionBuilder<?> mctBuilder = MethodCallTransactionBuilder.Builder();
375 | 	
376 | 	List<AppBoxReference> boxRefs = new ArrayList<>();
377 | 	boxRefs.add(new AppBoxReference(appId.intValue(), "cool-box".getBytes()));
378 | 	MethodCallParams boxRefMcp = mctBuilder
379 | 	                .suggestedParams(sp)
380 | 	                .applicationId(appId)
381 | 	                .sender(acct.getAddress())
382 | 	                .method(contract.getMethodByName("add"))
383 | 	                .methodArguments(methodArgs)
384 | 	                .signer(acct.getTransactionSigner())
385 | 	                .onComplete(Transaction.OnCompletion.NoOpOC)
386 | 	                // Include reference to a box so the app logic may
387 | 	                // use it during evaluation
388 | 	                .boxReferences(boxRefs)
389 | 	                .build();
390 | 	```
391 | 	[Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/ATC.java#L98-L114)
392 |     <!-- ===JAVASDK_ATC_BOX_REF=== -->
393 | 
394 | === "Beaker"
395 |     ```py
396 |     #Beaker framework
397 |     result = app_client.call(
398 |         Myapp.my_method,
399 |         boxes=[[app_client.app_id, "key"]],
400 |     )
401 |     ```
402 | ## Creating a Box
403 | The AVM supports two opcodes `box_create` and `box_put` that can be used to create a box. 
404 | The `box_create` opcode takes two parameters, the name and the size in bytes for the created box. The `box_put` opcode takes two parameters as well. The first parameter is the name and the second is a byte array to write. Because the AVM limits any element on the stack to 4kb, `box_put` can only be used for boxes with length <= 4kb.
405 | 
406 | === "TEAL"
407 | 	<!-- ===TEAL_BOX_CREATE=== -->
408 | 	```teal
409 | 	// 100 byte box created with box_create
410 | 	byte "Mykey"
411 | 	int 100
412 | 	box_create
413 | 	// ... OR ...
414 | 	// create with a box_put
415 | 	byte "Mykey"
416 | 	byte "My data values"
417 | 	box_put
418 | 	```
419 | 	[Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/boxes/approval.teal#L6-L15)
420 | 	<!-- ===TEAL_BOX_CREATE=== -->
421 | 
422 | === "PyTeal"
423 | 	<!-- ===PYTEAL_BOX_CREATE=== -->
424 | 	```python
425 | 	        # ...
426 | 	        # box created with box_create, size 100 bytes
427 | 	        App.box_create(Bytes("MyKey"), Int(100)),
428 | 	        # OR box created with box_put, size is implicitly the
429 | 	        # length of bytes written
430 | 	        App.box_put(Bytes("MyKey"), Bytes("My data values"))
431 | 	        # ...
432 | 	```
433 | 	[Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/box.py#L6-L13)
434 | 	<!-- ===PYTEAL_BOX_CREATE=== -->
435 | 
436 | Box names must be unique within an application. If using `box_create`, and an existing box name is passed with a different size, the creation will fail. If an existing box name is used with the existing size, the call will return a 0 without modifying the box contents. When creating a new box the call will return a 1. When using `box_put` with an existing key name, the put will fail if the size of the second argument (data array) is different from the original box size. 
437 | 
438 | !!!info
439 |     When creating a box, the key name to be created must be in the box ref array.
440 | 
441 | ## Writing to a Box  
442 | The AVM provides two opcodes, `box_put` and `box_replace`,  to write data to a box. The `box_put` opcode is described in the previous section. The `box_replace` opcode takes three parameters, the key name, the starting location and replacement bytes.
443 | 
444 | === "TEAL"
445 | 	<!-- ===TEAL_BOX_WRITE=== -->
446 | 	```teal
447 | 	byte "MyKey"
448 | 	int 10
449 | 	byte "best"
450 | 	box_replace
451 | 	```
452 | 	[Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/boxes/approval.teal#L18-L22)
453 | 	<!-- ===TEAL_BOX_WRITE=== -->
454 | 
455 | === "PyTeal"
456 | 	<!-- ===BEAKER_BOX_WRITE=== -->
457 |     ```py
458 |     #Beaker Framework
459 |         @external
460 |         def replace_string(self, ky: abi.String, start: abi.Uint64, replacement: abi.String, *, output: abi.String):
461 |             return Seq(
462 |                 App.box_replace(ky.get(), start.get(), replacement.get()),
463 |                 boxstr :=  App.box_get(ky.get()),
464 |                 Assert( boxstr.hasValue()),
465 |                 output.set(boxstr.value()),
466 |             ) 
467 | 
468 |     ```
469 | 	<!-- ===BEAKER_BOX_WRITE=== -->
470 | 
471 | When using `box_replace`, the box size can not increase. This means if the replacement bytes, when added to the start byte location, exceed the upper bounds of the box, the call will fail. 
472 | 
473 | ## Reading from a Box
474 | The AVM provides two opcodes for reading the contents of a box, `box_get` and `box_extract`. The `box_get` opcode takes one parameter which is the key name for the box. It reads the entire contents of a box. The `box_get` opcode returns two values. The top-of-stack is an integer that has the value of 1 or 0. A value of 1 means that the box was found and read. A value of 0 means that the box was not found. The next stack element contains the bytes read if the box exists, else it contains an empty byte array. `box_get` fails if the box length exceeds 4kb.
475 | 
476 | === "TEAL"
477 | 	<!-- ===TEAL_BOX_GET=== -->
478 | 	```teal
479 | 	byte "MyKey"
480 | 	box_get
481 | 	assert //verify that the read occurred and we have a value
482 | 	//box contents at the top of the stack
483 | 	```
484 | 	[Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/boxes/approval.teal#L25-L29)
485 | 	<!-- ===TEAL_BOX_GET=== -->
486 | 
487 | === "PyTeal"
488 | 	<!-- ===PYTEAL_BOX_GET=== -->
489 | 	```python
490 | 	        boxval := App.box_get(Bytes("MyKey")),
491 | 	        Assert(boxval.hasValue()),
492 | 	        # do something with boxval.value()
493 | 	        # ...
494 | 	```
495 | 	[Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/box.py#L21-L25)
496 | 	<!-- ===PYTEAL_BOX_GET=== -->
497 | 
498 | Note that when using either opcode to read the contents of a box, the AVM is limited to reading no more than 4kb at a time. This is because the stack is limited to 4kb entries. For larger boxes, the `box_extract` opcode should be used to perform multiple reads to retrieve the entire contents.
499 | 
500 | The `box_extract` opcode requires three parameters: the box key name, the starting location, and the length to read. If the box is not found or if the read exceeds the boundaries of the box the opcode will fail. 
501 | 
502 | 
503 | === "TEAL"
504 | 	<!-- ===TEAL_BOX_EXTRACT=== -->
505 | 	```teal
506 | 	byte "BoxA"
507 | 	byte "this is a test of a very very very very long string"
508 | 	box_put
509 | 	
510 | 	byte "BoxA"
511 | 	int 5
512 | 	int 9
513 | 	box_extract
514 | 	
515 | 	byte "is a test"
516 | 	==
517 | 	assert
518 | 	```
519 | 	[Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/boxes/approval.teal#L32-L44)
520 | 	<!-- ===TEAL_BOX_EXTRACT=== -->
521 | 
522 | === "PyTeal"
523 | 	<!-- ===PYTEAL_BOX_EXTRACT=== -->
524 | 	```python
525 | 	        # ...
526 | 	        App.box_put(
527 | 	            Bytes("BoxA"), Bytes("this is a test of a very very very very long string")
528 | 	        ),
529 | 	        scratchVar.store(App.box_extract(Bytes("BoxA"), Int(5), Int(9))),
530 | 	        Assert(scratchVar.load() == Bytes("is a test"))
531 | 	        # ...
532 | 	```
533 | 	[Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/box.py#L33-L40)
534 | 	<!-- ===PYTEAL_BOX_EXTRACT=== -->
535 | 
536 | ## Getting a Box Length
537 | The AVM offers the `box_len` opcode to retrieve the length of a box. This opcode can also be used to verify the existence of a particular box. The opcode takes the box key name and returns two unsigned integers (uint64). The top-of-stack is either a 0 or 1, where 1 indicates the existence of the box and 0 indicates the box does not exist. The next is the length of the box if it exists, else it is 0.
538 | 
539 | === "TEAL"
540 | 	<!-- ===TEAL_BOX_LEN=== -->
541 | 	```teal
542 | 	byte "BoxA"
543 | 	byte "this is a test of a very very very very long string"
544 | 	box_put
545 | 	
546 | 	byte "BoxA"
547 | 	box_len
548 | 	assert
549 | 	
550 | 	int 51
551 | 	==
552 | 	assert
553 | 	```
554 | 	[Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/boxes/approval.teal#L47-L58)
555 | 	<!-- ===TEAL_BOX_LEN=== -->
556 | 
557 | === "PyTeal"
558 | 	<!-- ===PYTEAL_BOX_LEN=== -->
559 | 	```python
560 | 	        App.box_put(
561 | 	            Bytes("BoxA"), Bytes("this is a test of a very very very very long string")
562 | 	        ),
563 | 	        # box length is equal to the size of the box created
564 | 	        # not a measure of how many bytes have been _written_
565 | 	        # by the smart contract
566 | 	        bt := App.box_length(Bytes("BoxA")),
567 | 	        Assert(bt.hasValue()),
568 | 	        Assert(bt.value() == 51),
569 | 	```
570 | 	[Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/box.py#L47-L56)
571 | 	<!-- ===PYTEAL_BOX_LEN=== -->
572 | 
573 | ## Deleting a Box
574 | The AVM offers the `box_del` opcode to delete a box. This opcode takes the box key name. The opcode returns one unsigned integer (uint64) with a value of 0 or 1. A value of 1 indicates the box existed and was deleted. A value of 0 indicates the box did not exist.
575 | 
576 | 
577 | === "TEAL"
578 | 	<!-- ===TEAL_BOX_DELETE=== -->
579 | 	```teal
580 | 	byte "BoxA"
581 | 	byte "this is a test of a very very very very long string"
582 | 	box_put
583 | 	
584 | 	byte "BoxA"
585 | 	box_del
586 | 	bnz existed
587 | 	```
588 | 	[Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/boxes/approval.teal#L61-L68)
589 | 	<!-- ===TEAL_BOX_DELETE=== -->
590 | 
591 | === "PyTeal"
592 | 	<!-- ===PYTEAL_BOX_DELETE=== -->
593 | 	```python
594 | 	        App.box_put(
595 | 	            Bytes("BoxA"), Bytes("this is a test of a very very very very long string")
596 | 	        ),
597 | 	        # Box delete returns a 1/0 on the stack
598 | 	        # depending on if it was successful
599 | 	        Assert(App.box_delete(Bytes("BoxA"))),
600 | 	```
601 | 	[Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/box.py#L63-L69)
602 | 	<!-- ===PYTEAL_BOX_DELETE=== -->
603 | 
604 | !!!warning
605 |     You must delete all boxes before deleting a contract. If this is not done, the minimum balance for that box is not recoverable.
606 | 
607 | ## Example: Storing Named Tuples in a Box
608 | If your contract is using the ABI and authored in PyTeaI, you might want to store a named tuple in a Box. It is preferable that the tuple only contain static data types, as that will allow easy indexing into the box. The following example creates a box for every address that calls the contract’s add_member method. This is an effective way of storing data for every user of the contract without having to have the user’s account opt-in to the contract.
609 | 
610 | === "PyTeal"
611 |     ```py
612 |     # This example uses the Beaker framework
613 | 
614 |     from algosdk import *
615 |     from pyteal import *
616 |     from beaker import *
617 | 
618 | 
619 |     class NamedTupleBox(Application):
620 | 
621 |         class MembershipRecord(abi.NamedTuple):
622 |             role: abi.Field[abi.Uint8]
623 |             voted: abi.Field[abi.Bool]
624 | 
625 |         
626 |         @external
627 |         def add_member(self, role: abi.Uint8, voted: abi.Bool,*, output: MembershipRecord):
628 |             return Seq(
629 |                 output.set(role, voted),
630 |                 App.box_put(Txn.sender(), output.encode()),
631 |             )
632 | 
633 |         @external
634 |         def del_member(self,*, output: abi.Uint64):
635 |             return Seq(
636 |                 output.set(App.box_delete(Txn.sender())),
637 |             )     
638 |             
639 |     if __name__ == "__main__":
640 |         accts = sandbox.get_accounts()
641 |         acct = accts.pop()
642 | 
643 | 
644 |         app_client = client.ApplicationClient(
645 |             sandbox.get_algod_client(), NamedTupleBox(), signer=acct.signer
646 |         )
647 | 
648 |         app_client.create()
649 |         app_client.fund(100 * consts.algo)
650 |         print("APP ID")
651 |         print(app_client.app_id)
652 |         print(acct.address)
653 |         ls = acct.address.encode()
654 | 
655 |         result = app_client.call(
656 |             NamedTupleBox.add_member,
657 |             role=2,
658 |             voted=False,
659 |             boxes=[[app_client.app_id, encoding.decode_address(acct.address)]],
660 |         )
661 |         result = app_client.call(
662 |             NamedTupleBox.del_member,
663 |             boxes=[[app_client.app_id, encoding.decode_address(acct.address)]],
664 |         )    
665 | 
666 |         print(result.return_value)
667 |         NamedTupleBox().dump('./artifacts')
668 |     ```
669 | 
670 | # Reading a smart contracts state
671 | In addition to being able to read the state of a smart contract using TEAL, these global and local values can be read externally with the SDKs and `goal`. These reads are not transactions and just query the current state of the contract. 
672 | 
673 | ```bash
674 | $ goal app read --app-id 1 --guess-format --global --from [ADDRESS]
675 | ```
676 | 
677 | In the above example, the global state of the smart contract with the application ID of 1 is returned. The `--guess-format` opt in the above example tries programmatically to display the properly formatted values of the state variables. To get the local state, replace `--global` with `--local` and note that this call will only return the local state of the `--from` account.
678 | 
679 | Here is an example output with 3 keys/values:
680 | 
681 | ```json
682 | {
683 |   "Creator": {
684 |     "tb": "FRYCPGH25DHCYQGXEB54NJ6LHQG6I2TWMUV2P3UWUU7RWP7BQ2BMBBDPD4",
685 |     "tt": 1
686 |   },
687 |   "MyBytesKey": {
688 |     "tb": "hello",
689 |     "tt": 1
690 |   },
691 |   "MyUintKey": {
692 |     "tt": 2,
693 |     "ui": 50
694 |   }
695 | }
696 | ```
697 | 
698 | Interpretation:
699 | 
700 | * the keys are `Creator`, `MyBytesKey`, `MyUintKey`.
701 | * the field `tt` is the type of the value: 1 for byte slices (byte-array value), 2 for uint.
702 | * when `tt=1`, the value is in the field `tb`. Note that because of `--guess-format`, the value for `Creator` is automatically converted to an Algorand address with checksum (as opposed to a 32-byte public key.
703 | * when `tt=2`, the value is in the field `ui`.
704 |     
```
Page 57/93FirstPrevNextLast