#
tokens: 48014/50000 6/942 files (page 33/74)
lines: off (toggle) GitHub
raw markdown copy
This is page 33 of 74. Use http://codebase.md/goplausible/algorand-mcp?lines=false&page={x} to view the full context.

# Directory Structure

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

# Files

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

```markdown
Title: Creation 


# Creating the smart contract
Before creating a smart contract, the code for the `ApprovalProgram` and the `ClearStateProgram` program should be written. The SDKs and the `goal` CLI tool can be used to create a smart contract application. To create the application with `goal` use a command similar to the following.

```bash
$ goal app create --creator [address]  --approval-prog [approval_program.teal] --clear-prog [clear_state_program.teal] --global-byteslices [number-of-global-byteslices] --global-ints [number-of-global-ints] --local-byteslices [number-of-local-byteslices] --local-ints [number-local-ints] --extra-pages [number of extra 2KB pages]
```

!!!note
	See [Creating the smart contract](../frontend/apps.md#create) for details on using the SDKs to deploy a smart contract.

The creator is the account that is creating the application and this transaction is signed by this account. The approval program and the clear state program should also be provided. The number of global and local byte slices (byte-array value) and integers also needs to be specified. These represent the absolute on-chain amount of space that the smart contract will use. Once set, these values can never be changed. The key is limited to 64 bytes. The key plus the value is limited to 128 bytes total. When the smart contract is created the network will return a unique ApplicationID. This ID can then be used to make `ApplicationCall` transactions to the smart contract. The smart contract will also have a unique Algorand address that is generated from this ID. This address allows the contract to function as an escrow account.  

When creating a smart contract, there is a limit of 64 key-value pairs that can be used by the contract for global storage and 16 key-value pairs that can be used for local storage. When creating the smart contract the amount of storage can never be changed once the contract is created. Additionally, the minimum balance is raised for any account that participates in the contract. See [Minimum Balance Requirement for Smart Contracts](index.md#minimum-balance-requirement-for-a-smart-contract) described below for more detail.

Smart contracts are limited to 2KB total for the compiled approval and clear programs. This size can be increased up to 3 additional 2KB pages, which would result in an 8KB limit for both programs. Note the size increases will also increase the minimum balance requirement for creating the application. To request additional pages, the setting (`extra-pages`) is available when creating the smart contract using `goal`. These extra pages can also be requested using the SDKs. This setting allows setting up to 3 additional 2KB pages.

# Opt into the smart contract
Before any account, including the creator of the smart contract, can begin to make Application Transaction calls that use local state, it must first opt into the smart contract. This prevents accounts from being spammed with smart contracts. To opt in, an `ApplicationCall` transaction of type `OptIn` needs to be signed and submitted by the account desiring to opt into the smart contract. This can be done with the `goal` CLI or the SDKs.

```bash
$ goal app optin  --app-id [ID-of-Contract] --from [ADDRESS]
```

!!!note
	See [Opt-in](../frontend/apps.md#opt-in) for details on using the SDKs to opt into a smart contract.

When this transaction is submitted, the `ApprovalProgram` of the smart contract is called and if the call succeeds the account will be opted into the smart contract. The simplest program to handle this call would just put 1 on the stack and return. 

=== "PyTeal"
	<!-- ===PYTEAL_APPL_OPTIN=== -->
	```python
	    # this would reject _ANY_ transaction that isn't an opt-in
	    # and approve _ANY_ transaction that is an opt-in
	    program = If(OnComplete.OptIn == Txn.on_completion(), Approve(), Reject())
	    print(compileTeal(program, Mode.Application))
	```
	[Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/txn.py#L108-L112)
	<!-- ===PYTEAL_APPL_OPTIN=== -->

=== "TEAL"
	<!-- ===TEAL_APPL_OPTIN=== -->
	```teal
	txn OnCompletion
	int OptIn
	==
	bz not_optin
	
	// Allow OptIn
	int 1
	return
	
	not_optin:
	// additional checks...
	```
	[Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/opting_in/approval.teal#L13-L24)
	<!-- ===TEAL_APPL_OPTIN=== -->

Other contracts may have much more complex opt in logic. TEAL also provides an opcode to check whether an account has already opted into the contract.

=== "PyTeal"

	```python
	    program = App.optedIn(Txn.sender(), Txn.application_id())
	    print(compileTeal(program, Mode.Application))
	```

=== "TEAL"
	<!-- ===TEAL_APPL_CHECK_OPTEDIN=== -->
	```teal
	txn Sender
	txn ApplicationID
	app_opted_in
	```
	[Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/opting_in/approval.teal#L6-L9)
	<!-- ===TEAL_APPL_CHECK_OPTEDIN=== -->

In the above example, `txn Sender` is the address of the transaction sender. The address can be any account in the accounts array. The `txn ApplicationID` refers to the current application ID, but technically any application ID could be used as long as its ID is in the applications array. See [Reference arrays](index.md#reference-arrays) for more details.

!!! info
    Applications that only use global state do not require accounts to opt in.

# Passing arguments to smart contracts
Arguments can be passed to any of the supported application transaction calls, including create. The number and type can also be different for any subsequent calls to the smart contract. The `goal` CLI supports passing strings, ints, base64 encoded data, and addresses as parameters. To pass a parameter supply the `--app-arg` option to the call and supply the value according to the format shown below.

Argument Type | Example
------------ | ------------- 
String | `goal app call --app-arg "str:mystring".....` 
Integer | `goal app create --app-arg "int:5".....` 
Address | `goal app call --app-arg "addr:address-string".....`
Base64 | `goal app call --app-arg "b64:A==".....`

!!!note
	See [Call with arguments](../frontend/apps.md#call-with-arguments), for more information on passing parmeters with SDKs.

These parameters are loaded into the arguments array. TEAL opcodes are available to get the values within the array. The primary argument opcode is the `ApplicationArgs` opcode and can be used as shown below.

=== "PyTeal"
	<!-- ===PYTEAL_TXN_APP_ARGS=== -->
	```python
	    program = Txn.application_args[1] == Bytes("claim")
	    print(compileTeal(program, Mode.Application))
	```
	[Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/txn.py#L27-L29)
	<!-- ===PYTEAL_TXN_APP_ARGS=== -->

=== "TEAL"
	<!-- ===TEAL_TXN_APP_ARGS=== -->
	```teal
	txna ApplicationArgs 1
	byte "claim"
	==
	```
	[Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/appargs/approval.teal#L16-L19)
	<!-- ===TEAL_TXN_APP_ARGS=== -->

This call gets the second passed in argument and compares it to the string "claim".

A global variable is also available to check the size of the transaction argument array. This size can be checked with the following contract code.


=== "PyTeal"
	<!-- ===PYTEAL_TXN_NUM_APP_ARGS=== -->
	```python
	    program = Txn.application_args.length() == Int(4)
	    print(compileTeal(program, Mode.Application))
	```
	[Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/txn.py#L34-L36)
	<!-- ===PYTEAL_TXN_NUM_APP_ARGS=== -->

=== "TEAL"
	<!-- ===TEAL_TXN_NUM_APP_ARGS=== -->
	```teal
	txn NumAppArgs
	int 4
	==
	```
	[Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/appargs/approval.teal#L3-L6)
	<!-- ===TEAL_TXN_NUM_APP_ARGS=== -->

The above contract code will push a 0 on the top of the stack if the number of parameters in this specific transaction is anything other than 4, else it will push a 1 on the top of the stack. Internally all transaction parameters are stored as byte slices (byte-array value). Integers can be converted using the `btoi` opcode.

=== "PyTeal"
	<!-- ===PYTEAL_TXN_APP_ARG_TO_INT=== -->
	```python
	    program = Btoi(Txn.application_args[0])
	    print(compileTeal(program, Mode.Application))
	```
	[Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/txn.py#L41-L43)
	<!-- ===PYTEAL_TXN_APP_ARG_TO_INT=== -->

=== "TEAL"
	<!-- ===TEAL_TXN_APP_ARG_TO_INT=== -->
	```teal
	txna ApplicationArgs 0
	btoi
	```
	[Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/appargs/approval.teal#L10-L12)
	<!-- ===TEAL_TXN_APP_ARG_TO_INT=== -->


!!! info
    Argument passing for smart contracts is very different from passing arguments to smart signatures. 

The total size of all parameters is limited to 2KB in size.


# Call the smart contract
Any account can make a call to the smart contract. These calls will be in the form of `ApplicationCall` transactions that can be submitted with `goal` or the SDKs. Depending on the individual type of transaction as described in [The Lifecycle of a Smart Contract](index.md#the-lifecycle-of-a-smart-contract), either the `ApprovalProgram` or the `ClearStateProgram` will be called. Generally, individual calls will supply application arguments. See [Passing Arguments to a Smart Contract](#passing-arguments-to-smart-contracts) for details on passing arguments.

```bash
$ goal app call --app-id 1 --app-arg "str:myparam"  --from [ADDRESS]
```

!!!note
    See [Call(NoOp)](../frontend/apps.md#call-noop) for details on using the SDKs to call a smart contract. If using [ABI](/docs/get-details/dapps/smart-contracts/ABI/) compliant contracts, use the [AtomicTransactionComposer](../../../../atc) to interact with the smart contract.


The call must specify the intended contract using the `--app-id` option. Additionally, the `--from` option specifies the sender’s address. 


=== "PyTeal"
	<!-- ===PYTEAL_APPL_CALL=== -->
	```python
	    # this would approve _ANY_ transaction that has its
	    # first app arg set to the byte string "myparam"
	    # and reject all others
	    program = If(Bytes("myparm") == Txn.application_args[0], Approve(), Reject())
	    print(compileTeal(program, Mode.Application))
	```
	[Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/txn.py#L76-L81)
	<!-- ===PYTEAL_APPL_CALL=== -->

=== "Teal"
	<!-- ===TEAL_APPL_CALL=== -->
	```teal
	byte "myparam"
	txna ApplicationArgs 0
	==
	bz not_myparam
	// handle my_param
	
	not_myparam:
	// handle not_myparam
	```
	[Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/calling/approval.teal#L6-L14)
	<!-- ===TEAL_APPL_CALL=== -->

# Update smart contract
A smart contract’s programs can be updated at any time. This is done by an `ApplicationCall` transaction type of `UpdateApplication`. This operation can be done with `goal` or the SDKs and requires passing the new programs and specifying the application ID.

```bash
goal app update --app-id=[APPID] --from [ADDRESS]  --approval-prog [new_approval_program.teal]   --clear-prog [new_clear_state_program.teal]
```

!!!note
    See [Update](../frontend/apps.md#update) for details on using the SDKs to update a smart contract.

The one caveat to this operation is that global or local state requirements for the smart contract can never be updated. Updating a smart contract's programs does not affect any values currently in state.

As stated earlier, anyone can update the program. If this is not desired and you want only the original creator to be able to update the programs, code must be added to your `ApprovalProgram` to handle this situation. This can be done by comparing the global `CreatorAddress` to the sender address.

=== "PyTeal"
	<!-- ===PYTEAL_APPL_UPDATE=== -->
	```python
	    program = Assert(
	        Txn.on_completion() == OnComplete.UpdateApplication,
	        Global.creator_address() == Txn.sender(),
	    )
	    print(compileTeal(program, Mode.Application))
	```
	[Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/txn.py#L86-L91)
	<!-- ===PYTEAL_APPL_UPDATE=== -->

=== "TEAL"
	<!-- ===TEAL_APPL_UPDATE=== -->
	```teal
	byte "update"
	txna ApplicationArgs 0
	==
	bz not_update
	
	// Only Creator may update
	global CreatorAddress
	txn Sender
	==
	return
	
	not_update:
	```
	[Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/calling/approval.teal#L17-L29)
	<!-- ===TEAL_APPL_UPDATE=== -->

Or alternatively, the contract code can always return a 0 when an `UpdateApplication` application call is made to prevent anyone from ever updating the application code.

=== "PyTeal"
	<!-- ===PYTEAL_APPL_UPDATE_REJECT=== -->
	```python
	    program = If(
	        OnComplete.UpdateApplication == Txn.on_completion(),
	        Reject(),
	        # placeholder, update with actual logic
	        Approve(),
	    )
	    print(compileTeal(program, Mode.Application))
	```
	[Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/txn.py#L96-L103)
	<!-- ===PYTEAL_APPL_UPDATE_REJECT=== -->

=== "TEAL"
	<!-- ===TEAL_APPL_UPDATE_REJECT=== -->
	```teal
	txn OnCompletion
	int UpdateApplication
	==
	bz not_update
	
	// Reject Update
	int 0
	return
	
	not_update:
	```
	[Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/calling/approval.teal#L32-L42)
	<!-- ===TEAL_APPL_UPDATE_REJECT=== -->

# Delete smart contract
To delete a smart contract, an `ApplicationCall` transaction of type `DeleteApplication` must be submitted to the blockchain. The `ApprovalProgram` handles this transaction type and if the call returns true, the application will be deleted. This can be done using `goal` or the SDKs. 

```bash
$ goal app delete --app-id=[APPID] --from [ADDRESS]
```

!!!note
    See [Delete](../frontend/apps.md#delete) for details on using the SDKs to delete a smart contract.

When making this call the `--app-id` and the `--from` options are required. Anyone can delete a smart contract. If this is not desired, logic in the program must reject the call. Using a method described in [Update Smart Contract](#update-smart-contract) must be supplied. 

# Boilerplate smart contract

As a way of getting started writing smart contracts, the following boilerplate template is supplied. The code provides labels or handling different `ApplicationCall` transactions and also prevents updating and deleting the smart contract.


=== "PyTEAL"
	<!-- ===PYTEAL_BOILERPLATE=== -->
	```python
	    # Handle each possible OnCompletion type. We don't have to worry about
	    # handling ClearState, because the ClearStateProgram will execute in that
	    # case, not the ApprovalProgram.
	    def approval_program():
	        handle_noop = Seq([Return(Int(1))])
	
	        handle_optin = Seq([Return(Int(1))])
	
	        handle_closeout = Seq([Return(Int(1))])
	
	        handle_updateapp = Err()
	
	        handle_deleteapp = Err()
	
	        program = Cond(
	            [Txn.on_completion() == OnComplete.NoOp, handle_noop],
	            [Txn.on_completion() == OnComplete.OptIn, handle_optin],
	            [Txn.on_completion() == OnComplete.CloseOut, handle_closeout],
	            [Txn.on_completion() == OnComplete.UpdateApplication, handle_updateapp],
	            [Txn.on_completion() == OnComplete.DeleteApplication, handle_deleteapp],
	        )
	        return program
	
	    with open("boilerplate_approval_pyteal.teal", "w") as f:
	        compiled = compileTeal(approval_program(), Mode.Application, version=5)
	        f.write(compiled)
	```
	[Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/application.py#L32-L58)
	<!-- ===PYTEAL_BOILERPLATE=== -->

=== "TEAL"
	<!-- ===TEAL_BOILERPLATE=== -->
	```teal
	#pragma version 8
	
	// Handle each possible OnCompletion type. We don't have to worry about
	// handling ClearState, because the ClearStateProgram will execute in that
	// case, not the ApprovalProgram.
	
	txn OnCompletion
	int NoOp
	==
	bnz handle_noop
	
	txn OnCompletion
	int OptIn
	==
	bnz handle_optin
	
	txn OnCompletion
	int CloseOut
	==
	bnz handle_closeout
	
	txn OnCompletion
	int UpdateApplication
	==
	bnz handle_updateapp
	
	txn OnCompletion
	int DeleteApplication
	==
	bnz handle_deleteapp
	
	// Unexpected OnCompletion value. Should be unreachable.
	err
	
	handle_noop:
	// Handle NoOp
	int 1
	return
	
	handle_optin:
	// Handle OptIn
	int 1
	return
	
	handle_closeout:
	// Handle CloseOut
	int 1
	return
	
	// By default, disallow updating or deleting the app. Add custom authorization
	// logic below to allow updating or deletion in certain circumstances.
	handle_updateapp:
	handle_deleteapp:
	err
	```
	[Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/misc/boilerplate.teal#L1-L55)
	<!-- ===TEAL_BOILERPLATE=== -->

```

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

```markdown
title: Transaction reference

Each table below specifies the **field name**, whether it is optional or required, its **type** within the protocol code (note that SDKs input types for these fields may differ), the **codec**, which is the name of the field when viewed within a transaction, and a **description** of the field. 

# Common Fields (`Header` and `Type`)
These fields are common to all transactions.


|Field|Required|Type|codec| Description|
|---|---|---|---|---|
|<a name="fee">Fee</a>| _required_| uint64|`"fee"`|Paid by the sender to the FeeSink to prevent denial-of-service. The minimum fee on Algorand is currently 1000 microAlgos.|
|<a name="firstvalid">FirstValid</a>| _required_ | uint64 | `"fv"`|The first round for when the transaction is valid. If the transaction is sent prior to this round it will be rejected by the network.|
|<a name="genesishash">GenesisHash</a>|_required_|[32]byte|`"gh"`|The hash of the genesis block of the network for which the transaction is valid. See the genesis hash for [MainNet](../../algorand-networks/mainnet#genesis-hash), [TestNet](../../algorand-networks/testnet#genesis-hash), and [BetaNet](../../algorand-networks/betanet#genesis-hash).
|<a name="lastvalid">LastValid</a>| _required_ | uint64 | `"lv"`|The ending round for which the transaction is valid. After this round, the transaction will be rejected by the network.|
|<a name="sender">Sender</a>| _required_ |Address|`"snd"`|The address of the account that pays the fee and amount.|
|<a name="type">TxType</a>|_required_|string|`"type"`| Specifies the type of transaction. This value is automatically generated using any of the developer tools.|
|<a name="genesisid">GenesisID</a>|_optional_|string|`"gen"`| The human-readable string that identifies the network for the transaction. The genesis ID is found in the genesis block. See the genesis ID for [MainNet](../../algorand-networks/mainnet#genesis-id), [TestNet](../../algorand-networks/testnet#genesis_id), and [BetaNet](../../algorand-networks/betanet#genesis-id). |
<a name="group">Group</a>|_optional_|[32]byte|`"grp"`|The group specifies that the transaction is part of a group and, if so, specifies the hash of the transaction group. Assign a group ID to a transaction through the workflow described in the [Atomic Transfers Guide](../../atomic_transfers).|
<a name="lease">Lease</a>|_optional_|[32]byte|`"lx"`|A lease enforces mutual exclusion of transactions. If this field is nonzero, then once the transaction is confirmed, it acquires the lease identified by the (Sender, Lease) pair of the transaction until the LastValid round passes. While this transaction possesses the lease, no other transaction specifying this lease can be confirmed.  A lease is often used in the context of Algorand Smart Contracts to prevent replay attacks. Read more about [Algorand Smart Contracts](../../dapps/smart-contracts/). Leases can also be used to safeguard against unintended duplicate spends. For example, if I send a transaction to the network and later realize my fee was too low, I could send another transaction with a higher fee, but the same lease value. This would ensure that only one of those transactions ends up getting confirmed during the validity period. |
|<a name="note">Note</a>|_optional_|[]byte|`"note"`| Any data up to 1000 bytes. |
|<a name="rekeyto">RekeyTo</a>|_optional_|Address|`"rekey"`| Specifies the authorized address. This address will be used to authorize all future transactions. Learn more about [Rekeying](../../accounts/rekey) accounts. |

# Payment Transaction
Transaction Object Type: `PaymentTx`

Includes all fields in [Header](#common-fields-header-and-type) and `"type"` is `"pay"`.

|Field|Required|Type|codec| Description|
|---|---|---|---|---|
|<a name="receiver">Receiver</a>| _required_ |Address|`"rcv"`|The address of the account that receives the [amount](#amount).|
|<a name="amount">Amount</a>|_required_|uint64|`"amt"`| The total amount to be sent in microAlgos.|
|<a name="closeremainderto">CloseRemainderTo</a>|_optional_|Address|`"close"`|When set, it indicates that the transaction is requesting that the [Sender](#sender) account should be closed, and all remaining funds, after the [fee](#fee) and [amount](#amount) are paid, be transferred to this address.|

# Key Registration Transaction
Transaction Object Type: `KeyRegistrationTx`

Includes all fields in [Header](#common-fields-header-and-type) and `"type"` is `"keyreg"`.

|Field|Required|Type|codec| Description|
|---|---|---|---|---|
|<a name="votepk">VotePk</a>| _required for online_ |ed25519PublicKey|`"votekey"`|The root participation public key. See [Generate a Participation Key](../../run-a-node/participate/generate_keys.md) to learn more.|
|<a name="selectionpk">SelectionPK</a>|_required for online_|VrfPubkey|`"selkey"`| The VRF public key.|
|<a name="stateproofpk">StateProofPk</a>|_required for online_|MerkleSignature Verifier (64 bytes)|`"sprfkey"`| The 64 byte state proof public key commitment.|
|<a name="votefirst">VoteFirst</a>|_required for online_|uint64|`"votefst"`|The first round that the *participation key* is valid. Not to be confused with the [FirstValid](#firstvalid) round of the keyreg transaction.|
|<a name="votelast">VoteLast</a>|_required for online_|uint64|`"votelst"`|The last round that the *participation key* is valid. Not to be confused with the [LastValid](#lastvalid) round of the keyreg transaction.|
|<a name="votekeydilution">VoteKeyDilution</a>|_required for online_|uint64|`"votekd"`|This is the dilution for the 2-level participation key. It determines the interval (number of rounds) for generating new ephemeral keys. |
|<a name="nonparticipation">Nonparticipation</a>|_optional_|bool|`"nonpart"`| All new Algorand accounts are participating by default. This means that they earn rewards. Mark an account nonparticipating by setting this value to `true` and this account will no longer earn rewards. It is unlikely that you will ever need to do this and exists mainly for economic-related functions on the network.|

# Asset Configuration Transaction
Transaction Object Type: `AssetConfigTx`

Includes all fields in [Header](#common-fields-header-and-type) and `"type"` is `"acfg"`.

This is used to create, configure and destroy an asset depending on which fields are set.

|Field|Required|Type|codec| Description|
|---|---|---|---|---|
|<a name="configasset">ConfigAsset</a>| _required, except on create_ |uint64|`"caid"`|For re-configure or destroy transactions, this is the unique asset ID. On asset creation, the ID is set to zero.|
|[AssetParams](#asset-parameters) |_required, except on destroy_|[AssetParams](#asset-parameters)|`"apar"`| See AssetParams table for all available fields.|

## Asset Parameters
Object Name: `AssetParams`

|Field|Required|Type|codec| Description|
|---|---|---|---|---|
|<a name="total">Total</a>|_required on creation_|uint64|`"t"`| The total number of base units of the asset to create. This number cannot be changed.|
|<a name="decimals">Decimals</a>|_required on creation_|uint32|`"dc"`| The number of digits to use after the decimal point when displaying the asset. If 0, the asset is not divisible. If 1, the base unit of the asset is in tenths. If 2, the base unit of the asset is in hundredths, if 3, the base unit of the asset is in thousandths, and so on up to 19 decimal places |
|<a name="defaultfrozen">DefaultFrozen</a>|_required on creation_|bool|`"df"`| True to freeze holdings for this asset by default. |
|<a name="unitname">UnitName</a>|_optional_|string|`"un"`| The name of a unit of this asset. Supplied on creation. Max size is 8 bytes. Example: USDT |
|<a name="assetname">AssetName</a>|_optional_|string|`"an"`| The name of the asset. Supplied on creation. Max size is 32 bytes. Example: Tether|
|<a name="url">URL</a>|_optional_|string|`"au"`| Specifies a URL where more information about the asset can be retrieved. Max size is 96 bytes. |
|<a name="metadatahash">MetaDataHash</a>|_optional_|[]byte|`"am"`| This field is intended to be a 32-byte hash of some metadata that is relevant to your asset and/or asset holders. The format of this metadata is up to the application. This field can _only_ be specified upon creation. An example might be the hash of some certificate that acknowledges the digitized asset as the official representation of a particular real-world asset.  |
|<a name="manageraddr">ManagerAddr</a>|_optional_|Address|`"m"`| The address of the account that can manage the configuration of the asset and destroy it. |
|<a name="reserveaddr">ReserveAddr</a>|_optional_|Address|`"r"`| The address of the account that holds the reserve (non-minted) units of the asset. This address has no specific authority in the protocol itself. It is used in the case where you want to signal to holders of your asset that the non-minted units of the asset reside in an account that is different from the default creator account (the sender). |
|<a name="freezeaddr">FreezeAddr</a>|_optional_|Address|`"f"`| The address of the account used to freeze holdings of this asset. If empty, freezing is not permitted. |
|<a name="clawbackaddr">ClawbackAddr</a>|_optional_|Address|`"c"`| The address of the account that can clawback holdings of  this asset. If empty, clawback is not permitted. |

# Asset Transfer Transaction 
Transaction Object Type: `AssetTransferTx`

Includes all fields in [Header](#common-fields-header-and-type) and `"type"` is `"axfer"`.

|Field|Required|Type|codec| Description|
|---|---|---|---|---|
|<a name="xferasset">XferAsset</a>| _required_ |uint64|`"xaid"`|The unique ID of the asset to be transferred.|
|<a name="assetamount">AssetAmount</a>|_required_|uint64|`"aamt"`| The amount of the asset to be transferred. A zero amount transferred to self allocates that asset in the account's Asset map.|
|<a name="assetsender">AssetSender</a>|_required_|Address|`"asnd"`|The sender of the transfer. The regular [sender](#sender) field should be used and this one set to the zero value for regular transfers between accounts. If this value is nonzero, it indicates a clawback transaction where the [sender](#sender) is the asset's clawback address and the asset sender is the address from which the funds will be withdrawn.|
|<a name="assetreceiver">AssetReceiver</a>|_required_|Address|`"arcv"`| The recipient of the asset transfer.|
|<a name="assetcloseto">AssetCloseTo</a>|_optional_|Address|`"aclose"`|Specify this field to remove the asset holding from the [sender](#sender) account and reduce the account's minimum balance (i.e. opt-out of the asset). |

# Asset OptIn Transaction 
Transaction Object Type: `AssetTransferTx`

Includes all fields in [Header](#common-fields-header-and-type) and `"type"` is `"axfer"`.

This is a special form of an Asset Transfer Transaction.

|Field|Required|Type|codec| Description|
|---|---|---|---|---|
|<a name="xferasset">XferAsset</a>| _required_ |uint64|`"xaid"`|The unique ID of the asset to opt-in to.|
|<a name="sender">Sender</a>|_required_|Address|`"snd"`| The account which is allocating the asset to their account's Asset map.|
|<a name="assetreceiver">AssetReceiver</a>|_required_|Address|`"arcv"`| The account which is allocating the asset to their account's Asset map.|

# Asset Clawback Transaction 
Transaction Object Type: `AssetTransferTx`

Includes all fields in [Header](#common-fields-header-and-type) and `"type"` is `"axfer"`.

This is a special form of an Asset Transfer Transaction.

|Field|Required|Type|codec| Description|
|---|---|---|---|---|
|<a name="sender">Sender</a>| _required_ |Address|`"snd"`|The sender of this transaction must be the clawback account specified in the asset configuration.|
|<a name="xferasset">XferAsset</a>| _required_ |uint64|`"xaid"`|The unique ID of the asset to be transferred.|
|<a name="assetamount">AssetAmount</a>|_required_|uint64|`"aamt"`| The amount of the asset to be transferred.|
|<a name="assetsender">AssetSender</a>|_required_|Address|`"asnd"`| The address from which the funds will be withdrawn.|
|<a name="assetreceiver">AssetReceiver</a>|_required_|Address|`"arcv"`| The recipient of the asset transfer.|

# Asset Freeze Transaction
Transaction Object Type: `AssetFreezeTx`

Includes all fields in [Header](#common-fields-header-and-type) and `"type"` is `"afrz"`.

|Field|Required|Type|codec| Description|
|---|---|---|---|---|
|<a name="freezeaccount">FreezeAccount</a>| _required_ |Address|`"fadd"`|The address of the account whose asset is being frozen or unfrozen.|
|<a name="freezeasset">FreezeAsset</a>|_required_|uint64|`"faid"`| The asset ID being frozen or unfrozen.|
|<a name="assetfrozen">AssetFrozen</a>|_required_|bool|`"afrz"`| True to freeze the asset.|

# Application Call Transaction
Transaction Object Type: `ApplicationCallTx`

Includes all fields in [Header](#common-fields-header-and-type) and `"type"` is `"appl"`.

|Field|Required|Type|codec| Description|
|---|---|---|---|---|
| <a name="">Application ID</a>| _required_| uint64| `"apid"`| ID of the application being configured or empty if creating.|
| <a name="">OnComplete</a>| _required_| uint64| `"apan"`| Defines what additional actions occur with the transaction. See the [OnComplete](../../dapps/avm/teal/specification#oncomplete) section of the TEAL spec for details.|
| <a name="">Accounts</a>| _optional_| []Address| `"apat"`| List of accounts in addition to the sender that may be accessed from the application's approval-program and clear-state-program.|
| <a name="">Approval Program</a>| _optional_| []byte | `"apap"`| Logic executed for every application transaction, except when on-completion is set to "clear". It can read and write global state for the application, as well as account-specific local state. Approval programs may reject the transaction.|
| <a name="">App Arguments</a>| _optional_| [][]byte | `"apaa"`| Transaction specific arguments accessed from the application's approval-program and clear-state-program.|
| <a name="">Clear State Program</a>| _optional_| []byte | `"apsu"`| Logic executed for application transactions with on-completion set to "clear". It can read and write global state for the application, as well as account-specific local state. Clear state programs cannot reject the transaction.|
| <a name="">Foreign Apps</a>| _optional_| []uint64 | `"apfa"`| Lists the applications in addition to the application-id whose global states may be accessed by this application's approval-program and clear-state-program. The access is read-only.|
| <a name="">Foreign Assets</a>| _optional_| []uint64 | `"apas"`| Lists the assets whose AssetParams may be accessed by this application's approval-program and clear-state-program. The access is read-only.|
| <a name="">GlobalStateSchema</a>| _optional_| <a href=#storage-state-schema>StateSchema</a>| `"apgs"`| Holds the maximum number of global state values defined within a <a href=#storage-state-schema>StateSchema</a> object.|
| <a name="">LocalStateSchema</a>| _optional_| <a href=#storage-state-schema>StateSchema</a>| `"apls"`| Holds the maximum number of local state values defined within a <a href=#storage-state-schema>StateSchema</a> object.|
| <a name="">ExtraProgramPages</a>| _optional_| uint64 | `"apep"`| Number of additional pages allocated to the application's approval and clear state programs. Each `ExtraProgramPages` is 2048 bytes. The sum of `ApprovalProgram` and `ClearStateProgram` may not exceed 2048*(1+`ExtraProgramPages`) bytes. |
| <a name="">Boxes</a>| _optional_| []BoxRef | `"apbx"`| The boxes that should be made available for the runtime of the program. |

## Storage State Schema
Object Name: `StateSchema`

The `StateSchema` object is only required for the create application call transaction. The `StateSchema` object must be fully populated for both the `GlobalStateSchema` and `LocalStateSchema` objects.  

|Field|Required|Type|codec| Description|
|---|---|---|---|---|
| <a name="">Number Ints</a>| _required_| uint64| `"nui"`| Maximum number of integer values that may be stored in the [global \|\| local] application key/value store. Immutable.|
| <a name="">Number ByteSlices</a>| _required_| uint64| `"nbs"`| Maximum number of byte slices values that may be stored in the [global \|\| local] application key/value store. Immutable.|

# Signed Transaction
Transaction Object Type: `SignedTxn`

|Field|Required|Type|codec| Description|
|---|---|---|---|---|
|<a name="sig">Sig</a>| _required, if no other sig specified_ |crypto.Signature|`"sig"`||
|<a name="msig">Msig</a>|_required, if no other sig specified_|crypto.MultisigSig|`"msig"`||
|<a name="lsig">LogicSig</a>|_required, if no other sig specified_|LogicSig|`"lsig"`| |
|<a name="txn">Transaction</a>|_required_|Transaction|`"txn"`| [`PaymentTx`](#payment-transaction), [`KeyRegistrationTx`](#key-registration-transaction), [`AssetConfigTx`](#asset-configuration-transaction), [`AssetTransferTx`](#asset-transfer-transaction), [`AssetFreezeTx`](#asset-freeze-transaction) or [`ApplicationCallTx`](#application-call-transaction)

```

--------------------------------------------------------------------------------
/packages/server/src/tools/apiManager/nfd/index.ts:
--------------------------------------------------------------------------------

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

export const nfdTools = [
  {
    name: 'api_nfd_get_nfd',
    description: 'Get a specific NFD by name or by its application ID',
    inputSchema: {
      type: 'object',
      properties: {
        nameOrID: {
          type: 'string',
          description: 'Name of NFD or application ID'
        },
        view: {
          type: 'string',
          enum: ['tiny', 'brief', 'full'],
          description: 'View of data to return'
        },
        poll: {
          type: 'boolean',
          description: 'Use if polling waiting for state change'
        },
        nocache: {
          type: 'boolean',
          description: 'Set to true to return a never-cached result'
        }
      },
      required: ['nameOrID']
    }
  },
  {
    name: 'api_nfd_get_nfds_for_addresses',
    description: 'Get NFDs for specific addresses',
    inputSchema: {
      type: 'object',
      properties: {
        address: {
          type: 'array',
          items: {
            type: 'string'
          },
          description: 'Array of addresses to look up'
        },
        limit: {
          type: 'integer',
          description: 'Limit the number of results'
        },
        view: {
          type: 'string',
          enum: ['tiny', 'thumbnail', 'brief', 'full'],
          description: 'View of data to return'
        }
      },
      required: ['address']
    }
  },
  {
    name: 'api_nfd_get_nfd_activity',
    description: 'Get activity/changes for NFDs',
    inputSchema: {
      type: 'object',
      properties: {
        name: {
          type: 'array',
          items: {
            type: 'string'
          },
          description: 'Array of NFD names to get activity for'
        },
        type: {
          type: 'string',
          enum: ['changes'],
          description: 'Type of activity to retrieve'
        },
        afterTime: {
          type: 'string',
          format: 'date-time',
          description: 'Get activity after this time'
        },
        limit: {
          type: 'integer',
          description: 'Limit the number of results'
        },
        sort: {
          type: 'string',
          enum: ['timeDesc', 'timeAsc'],
          description: 'Sort order'
        }
      },
      required: ['name']
    }
  },
  {
    name: 'api_nfd_get_nfd_analytics',
    description: 'Get analytics data for NFDs',
    inputSchema: {
      type: 'object',
      properties: {
        name: {
          type: 'string',
          description: 'NFD name to filter on'
        },
        buyer: {
          type: 'string',
          description: 'Buyer address to filter on'
        },
        seller: {
          type: 'string',
          description: 'Seller address to filter on'
        },
        event: {
          type: 'array',
          items: {
            type: 'string'
          },
          description: 'Events to filter on'
        },
        requireBuyer: {
          type: 'boolean',
          description: 'Whether buyer must be present'
        },
        includeOwner: {
          type: 'boolean',
          description: 'Whether to include current owner'
        },
        excludeNFDAsSeller: {
          type: 'boolean',
          description: 'Whether to exclude NFDomains as seller'
        },
        category: {
          type: 'array',
          items: {
            type: 'string',
            enum: ['curated', 'premium', 'common']
          }
        },
        minPrice: {
          type: 'integer',
          description: 'Minimum price'
        },
        maxPrice: {
          type: 'integer',
          description: 'Maximum price'
        },
        limit: {
          type: 'integer',
          description: 'Limit the number of results'
        },
        offset: {
          type: 'integer',
          description: 'Offset for pagination'
        },
        sort: {
          type: 'string',
          enum: ['timeDesc', 'priceAsc', 'priceDesc'],
          description: 'Sort order'
        }
      }
    }
  },
  {
    name: 'api_nfd_browse_nfds',
    description: 'Browse NFDs with various filters',
    inputSchema: {
      type: 'object',
      properties: {
        name: {
          type: 'string',
          description: 'Name to filter on'
        },
        category: {
          type: 'array',
          items: {
            type: 'string',
            enum: ['curated', 'premium', 'common']
          }
        },
        saleType: {
          type: 'array',
          items: {
            type: 'string',
            enum: ['auction', 'buyItNow']
          }
        },
        state: {
          type: 'array',
          items: {
            type: 'string',
            enum: ['reserved', 'forSale', 'owned', 'expired']
          }
        },
        owner: {
          type: 'string',
          description: 'Owner address to filter on'
        },
        minPrice: {
          type: 'integer',
          description: 'Minimum price'
        },
        maxPrice: {
          type: 'integer',
          description: 'Maximum price'
        },
        limit: {
          type: 'integer',
          description: 'Limit the number of results'
        },
        offset: {
          type: 'integer',
          description: 'Offset for pagination'
        },
        sort: {
          type: 'string',
          enum: ['createdDesc', 'timeChangedDesc', 'soldDesc', 'priceAsc', 'priceDesc', 'highestSaleDesc', 'saleTypeAsc'],
          description: 'Sort order'
        },
        view: {
          type: 'string',
          enum: ['tiny', 'brief', 'full'],
          description: 'View of data to return'
        }
      }
    }
  },
  {
    name: 'api_nfd_search_nfds',
    description: 'Search NFDs with various filters',
    inputSchema: {
      type: 'object',
      properties: {
        name: {
          type: 'string',
          description: 'Name to search for'
        },
        category: {
          type: 'array',
          items: {
            type: 'string',
            enum: ['curated', 'premium', 'common']
          }
        },
        saleType: {
          type: 'array',
          items: {
            type: 'string',
            enum: ['auction', 'buyItNow']
          }
        },
        state: {
          type: 'array',
          items: {
            type: 'string',
            enum: ['reserved', 'forSale', 'owned', 'expired']
          }
        },
        owner: {
          type: 'string',
          description: 'Owner address to filter on'
        },
        minPrice: {
          type: 'integer',
          description: 'Minimum price'
        },
        maxPrice: {
          type: 'integer',
          description: 'Maximum price'
        },
        limit: {
          type: 'integer',
          description: 'Limit the number of results'
        },
        offset: {
          type: 'integer',
          description: 'Offset for pagination'
        },
        sort: {
          type: 'string',
          enum: ['createdDesc', 'timeChangedDesc', 'soldDesc', 'priceAsc', 'priceDesc', 'highestSaleDesc', 'saleTypeAsc'],
          description: 'Sort order'
        },
        view: {
          type: 'string',
          enum: ['tiny', 'brief', 'full'],
          description: 'View of data to return'
        }
      }
    }
  }
];

interface NFDProperties {
  internal?: Record<string, string>;
  userDefined?: Record<string, string>;
  verified?: Record<string, string>;
}

interface NFDRecord {
  name: string;
  appID?: number;
  asaID?: number;
  avatarOutdated?: boolean;
  caAlgo?: string[];
  category?: 'curated' | 'premium' | 'common';
  currentAsOfBlock?: number;
  depositAccount?: string;
  expired?: boolean;
  metaTags?: string[];
  nfdAccount?: string;
  owner?: string;
  parentAppID?: number;
  properties?: NFDProperties;
  reservedFor?: string;
  saleType?: 'auction' | 'buyItNow';
  sellAmount?: number;
  seller?: string;
  sigNameAddress?: string;
  state?: 'available' | 'minting' | 'reserved' | 'forSale' | 'owned' | 'expired';
  tags?: string[];
  timeChanged?: string;
  timeCreated?: string;
  timeExpires?: string;
  timePurchased?: string;
  unverifiedCa?: Record<string, string[]>;
  unverifiedCaAlgo?: string[];
}



async function getNFD(
  params: { nameOrID: string; view?: 'tiny' | 'brief' | 'full'; poll?: boolean; nocache?: boolean }
): Promise<NFDRecord> {
  try {
    const searchParams = new URLSearchParams();
    if (params.view) searchParams.append('view', params.view);
    if (params.poll) searchParams.append('poll', params.poll.toString());
    if (params.nocache) searchParams.append('nocache', params.nocache.toString());
    
    const response = await fetch(`${env.nfd_api_url}/nfd/${params.nameOrID}?${searchParams}`);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return await response.json();
  } catch (error) {
    if (error instanceof McpError) {
      throw error;
    }
    throw new McpError(
      ErrorCode.InternalError,
      `Failed to get NFD: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

async function getNFDsForAddressesV2(
  params: {
    address: string[];
    limit?: number;
    view?: 'tiny' | 'thumbnail' | 'brief' | 'full';
  }
): Promise<Record<string, NFDRecord[]>> {
  try {
    const searchParams = new URLSearchParams();
    params.address.forEach(addr => searchParams.append('address', addr));
    if (params.limit) searchParams.append('limit', params.limit.toString());
    if (params.view) searchParams.append('view', params.view);
    
    const response = await fetch(`${env.nfd_api_url}/nfd/v2/address?${searchParams}`);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return await response.json();
  } catch (error) {
    if (error instanceof McpError) {
      throw error;
    }
    throw new McpError(
      ErrorCode.InternalError,
      `Failed to get NFDs for addresses: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

async function searchNFDsV2(
  params: {
    name?: string;
    category?: ('curated' | 'premium' | 'common')[];
    saleType?: ('auction' | 'buyItNow')[];
    state?: ('reserved' | 'forSale' | 'owned' | 'expired')[];
    parentAppID?: number;
    length?: string[];
    traits?: ('emoji' | 'pristine' | 'segment')[];
    owner?: string;
    reservedFor?: string;
    prefix?: string;
    substring?: string;
    vproperty?: string;
    vvalue?: string;
    minPrice?: number;
    maxPrice?: number;
    changedAfter?: string;
    limit?: number;
    offset?: number;
    sort?: string;
    view?: 'tiny' | 'brief' | 'full';
  }
): Promise<{ total: number; nfds: NFDRecord[] }> {
  try {
    const searchParams = new URLSearchParams();
    Object.entries(params).forEach(([key, value]) => {
      if (value !== undefined) {
        if (Array.isArray(value)) {
          value.forEach(v => searchParams.append(key, v.toString()));
        } else {
          searchParams.append(key, value.toString());
        }
      }
    });
    
    const response = await fetch(`${env.nfd_api_url}/nfd/v2/search?${searchParams}`);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return await response.json();
  } catch (error) {
    if (error instanceof McpError) {
      throw error;
    }
    throw new McpError(
      ErrorCode.InternalError,
      `Failed to search NFDs: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

async function browseNFDs(
  params: {
    name?: string;
    category?: ('curated' | 'premium' | 'common')[];
    saleType?: ('auction' | 'buyItNow')[];
    state?: ('reserved' | 'forSale' | 'owned' | 'expired')[];
    parentAppID?: number;
    length?: string[];
    traits?: ('emoji' | 'pristine' | 'segment')[];
    owner?: string;
    reservedFor?: string;
    prefix?: string;
    substring?: string;
    vproperty?: string;
    vvalue?: string;
    minPrice?: number;
    maxPrice?: number;
    changedAfter?: string;
    limit?: number;
    offset?: number;
    sort?: string;
    view?: 'tiny' | 'brief' | 'full';
  }
): Promise<NFDRecord[]> {
  try {
    const searchParams = new URLSearchParams();
    Object.entries(params).forEach(([key, value]) => {
      if (value !== undefined) {
        if (Array.isArray(value)) {
          value.forEach(v => searchParams.append(key, v.toString()));
        } else {
          searchParams.append(key, value.toString());
        }
      }
    });
    
    const response = await fetch(`${env.nfd_api_url}/nfd/browse?${searchParams}`);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return await response.json();
  } catch (error) {
    if (error instanceof McpError) {
      throw error;
    }
    throw new McpError(
      ErrorCode.InternalError,
      `Failed to browse NFDs: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

async function getNFDActivity(
  params: {
    name: string[];
    type?: 'changes';
    afterTime?: string;
    limit?: number;
    sort?: 'timeDesc' | 'timeAsc';
  }
): Promise<{
  block: number;
  changes: Record<string, string>;
  name: string;
  timeChanged: string;
}[]> {
  try {
    const searchParams = new URLSearchParams();
    params.name.forEach(n => searchParams.append('name', n));
    if (params.type) searchParams.append('type', params.type);
    if (params.afterTime) searchParams.append('afterTime', params.afterTime);
    if (params.limit) searchParams.append('limit', params.limit.toString());
    if (params.sort) searchParams.append('sort', params.sort);
    
    const response = await fetch(`${env.nfd_api_url}/nfd/activity?${searchParams}`);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return await response.json();
  } catch (error) {
    if (error instanceof McpError) {
      throw error;
    }
    throw new McpError(
      ErrorCode.InternalError,
      `Failed to get NFD activity: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

async function getNFDAnalytics(
  params: {
    name?: string;
    buyer?: string;
    seller?: string;
    event?: string[];
    requireBuyer?: boolean;
    includeOwner?: boolean;
    excludeNFDAsSeller?: boolean;
    category?: string[];
    saleType?: string[];
    length?: string[];
    traits?: string[];
    parentAppID?: number;
    minPrice?: number;
    maxPrice?: number;
    afterTime?: string;
    limit?: number;
    offset?: number;
    sort?: 'timeDesc' | 'priceAsc' | 'priceDesc';
  }
): Promise<{
  total: number;
  results: {
    data: {
      block: number;
      buyer?: string;
      carryCost?: number;
      category?: string;
      currentOwner?: string;
      event: string;
      groupID?: string;
      metaTags?: string[];
      name: string;
      newExpTime?: string;
      note?: string;
      oneYearRenewalPrice?: number;
      saleType?: string;
      seller?: string;
    };
    price: number;
    priceUsd?: number;
    timestamp: string;
  }[];
}> {
  try {
    const searchParams = new URLSearchParams();
    Object.entries(params).forEach(([key, value]) => {
      if (value !== undefined) {
        if (Array.isArray(value)) {
          value.forEach(v => searchParams.append(key, v.toString()));
        } else {
          searchParams.append(key, value.toString());
        }
      }
    });
    
    const response = await fetch(`${env.nfd_api_url}/nfd/analytics?${searchParams}`);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return await response.json();
  } catch (error) {
    if (error instanceof McpError) {
      throw error;
    }
    throw new McpError(
      ErrorCode.InternalError,
      `Failed to get NFD analytics: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

export async function handleNFDTools(name: string, args: any): Promise<any> {
  try {
    let result;
    switch (name) {
      case 'api_nfd_get_nfd': {
        result = await getNFD(args);
        break;
      }
      case 'api_nfd_get_nfds_for_addresses': {
        result = await getNFDsForAddressesV2(args);
        break;
      }
      case 'api_nfd_get_nfd_activity': {
        result = await getNFDActivity(args);
        break;
      }
      case 'api_nfd_get_nfd_analytics': {
        result = await getNFDAnalytics(args);
        break;
      }
      case 'api_nfd_browse_nfds': {
        result = await browseNFDs(args);
        break;
      }
      case 'api_nfd_search_nfds': {
        result = await searchNFDsV2(args);
        break;
      }
      default:
        throw new McpError(
          ErrorCode.MethodNotFound,
          `Unknown tool: ${name}`
        );
    }
    return result
  } catch (error) {
    if (error instanceof McpError) {
      throw error;
    }
    throw new McpError(
      ErrorCode.InternalError,
      `Failed to handle NFD tool: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

```

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

```markdown
title: Atomic transfers

In traditional finance, trading assets generally requires a trusted intermediary, like a bank or an exchange, to make sure that both sides receive what they agreed to. On the Algorand blockchain, this type of trade is implemented within the protocol as an **Atomic Transfer**. This simply means that transactions that are part of the transfer either all succeed or all fail. Atomic transfers allow complete strangers to trade assets without the need for a trusted intermediary, all while guaranteeing that each party will receive what they agreed to. 

On Algorand, atomic transfers are implemented as irreducible batch operations, where a group of [transactions](../transactions) are submitted as a unit and all transactions in the batch either pass or fail. This also eliminates the need for more complex solutions like [hashed timelock contracts](https://en.bitcoinwiki.org/wiki/Hashed_Timelock_Contracts) that are implemented on other blockchains. An atomic transfer on Algorand is confirmed in less than 4 seconds, just like any other transaction. Transactions can contain Algos or Algorand Standard Assets and may also be governed by Algorand Smart Contracts. 

# Quick start videos

If you prefer videos, take a look at this 10 minute guide to learn about Atomic Transactions.

<iframe width="100%" style="aspect-ratio:16/9" src="https://www.youtube-nocookie.com/embed/65I0wyq7XoI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

# Use cases

Atomic transfers enable use cases such as:

**Circular trades** - Alice pays Bob if and only if Bob pays Claire if and only if Claire pays Alice.

**Group payments** - Everyone pays or no one pays.

**Decentralized exchanges** - Trade one asset for another without going through a centralized exchange. 

**Distributed payments** - Payments to multiple recipients. 

**Pooled transaction fees** - One transaction pays the fees of others. 

# Process overview

To implement an atomic transfer, generate all of the transactions that will be involved in the transfer and then group those transactions together. The result of grouping is that each transaction is assigned the same group ID. Once all transactions contain this group ID, the transactions can be split up and sent to their respective senders to be authorized. A single party can then collect all the authorized transactions and submit them to the network together. 

!!! info
    An individual account involved in an atomic transfer can verify that all the correct transfers are involved by creating the same set of [unsigned] transactions and grouping them in the same order. The group ID is a hash of the group of transactions and should match if the configuration is the same.

<center>![Atomic Transfer Flow](../imgs/atomic_transfers-1.png)</center>
<center>*Atomic Transfer Flow*</center>

Below you will find examples for creating and sending group transactions to the network in each of the available SDKs and with `goal`. 

!!! tip
    The following processes may be simplified with the SDKs use of the [atomic transaction composer (ATC)](atc.md). The ATC supports ABI compliant smart contract calls with Argument and Return Value encoding/decoding.

# Step-by-step guide

## Create transactions
Create two or more (up to 16 total) unsigned transactions of any type. Read about transaction types in the [Transactions Overview](../transactions) section. 

This could be done by a service or by each party involved in the transaction. For example, an asset exchange application can create the entire atomic transfer and allow individual parties to sign from their location.

The example below illustrates creating, grouping, and signing transactions atomically and submitting to the network.


=== "JavaScript"
    <!-- ===JSSDK_ATOMIC_CREATE_TXNS=== -->
	```javascript
	const suggestedParams = await client.getTransactionParams().do();
	
	const alicesTxn = algosdk.makePaymentTxnWithSuggestedParamsFromObject({
	  from: acct1.addr,
	  to: acct2.addr,
	  amount: 1e6,
	  suggestedParams,
	});
	
	const bobsTxn = algosdk.makePaymentTxnWithSuggestedParamsFromObject({
	  from: acct2.addr,
	  to: acct1.addr,
	  amount: 1e6,
	  suggestedParams,
	});
	```
	[Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/atomics.ts#L15-L30)
    <!-- ===JSSDK_ATOMIC_CREATE_TXNS=== -->

=== "Python"
    <!-- ===PYSDK_ATOMIC_CREATE_TXNS=== -->
	```python
	# payment from account 1 to account 2
	txn_1 = transaction.PaymentTxn(addr1, suggested_params, addr2, 100000)
	# payment from account 2 to account 1
	txn_2 = transaction.PaymentTxn(addr2, suggested_params, addr1, 200000)
	```
	[Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/atomic_transfers.py#L16-L20)
    <!-- ===PYSDK_ATOMIC_CREATE_TXNS=== -->

=== "Java"
    <!-- ===JAVASDK_ATOMIC_CREATE_TXNS=== -->
	```java
	Response<TransactionParametersResponse> rsp = algodClient.TransactionParams().execute();
	
	// payment from account 1 to account 2
	Transaction ptxn1 = Transaction.PaymentTransactionBuilder().sender(acct1.getAddress())
	                .amount(1000000).receiver(acct2.getAddress()).suggestedParams(rsp.body()).build();
	// txn_1 = transaction.PaymentTxn(addr1, suggested_params, addr2, 100000)
	
	// payment from account 2 to account 1
	Transaction ptxn2 = Transaction.PaymentTransactionBuilder().sender(acct2.getAddress())
	                .amount(2000000).receiver(acct1.getAddress()).suggestedParams(rsp.body()).build();
	```
	[Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AtomicTransfers.java#L26-L36)
    <!-- ===JAVASDK_ATOMIC_CREATE_TXNS=== -->

=== "Go"
    <!-- ===GOSDK_ATOMIC_CREATE_TXNS=== -->
	```go
	sp, err := algodClient.SuggestedParams().Do(context.Background())
	if err != nil {
		log.Fatalf("failed to get suggested params: %s", err)
	}
	
	tx1, err := transaction.MakePaymentTxn(acct1.Address.String(), acct2.Address.String(), 100000, nil, "", sp)
	if err != nil {
		log.Fatalf("failed creating transaction: %s", err)
	}
	
	// from account 2 to account 1
	tx2, err := transaction.MakePaymentTxn(acct2.Address.String(), acct1.Address.String(), 100000, nil, "", sp)
	if err != nil {
		log.Fatalf("failed creating transaction: %s", err)
	}
	```
	[Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/atomic_transactions/main.go#L24-L39)
    <!-- ===GOSDK_ATOMIC_CREATE_TXNS=== -->

=== "goal"
    <!-- ===GOAL_ATOMIC_CREATE_TXNS=== -->
	``` goal
    $ goal clerk send --from=my-account-a<PLACEHOLDER> --to=my-account-c<PLACEHOLDER> --fee=1000 --amount=100000 --out=unsginedtransaction1.txn"

    $ goal clerk send --from=my-account-b<PLACEHOLDER> --to=my-account-a<PLACEHOLDER> --fee=1000 --amount=200000 --out=unsginedtransaction2.txn"
    ```
    <!-- ===GOAL_ATOMIC_CREATE_TXNS=== -->

At this point, these are just individual transactions. The next critical step is to combine them and then calculate the group ID.

See [Authorizing Transactions Offline](../transactions/offline_transactions#saving-unsigned-transactions-to-file) to learn how to create and save individual **unsigned** transactions to a file. This method can be used to distribute group transactions for signing.

## Group transactions

The result of this step is what ultimately guarantees that a particular transaction belongs to a group and is not valid if sent alone (even if properly signed). A group-id is calculated by hashing the concatenation of a set of related transactions. The resulting hash is assigned to the [Group](../transactions/transactions#group) field within each transaction. This mechanism allows anyone to recreate all transactions and recalculate the group ID to verify that the contents are as agreed upon by all parties. Ordering of the transaction set must be maintained.

=== "JavaScript"
    <!-- ===JSSDK_ATOMIC_GROUP_TXNS=== --->
	```javascript
	const txnArray = [alicesTxn, bobsTxn];
	// assignGroupID returns the same txns with the group ID set
	const txnGroup = algosdk.assignGroupID(txnArray);
	```
	[Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/atomics.ts#L33-L36)
    <!-- ===JSSDK_ATOMIC_GROUP_TXNS=== --->

=== "Python"
    <!-- ===PYSDK_ATOMIC_GROUP_TXNS=== --->
	```python
	# Assign group id to the transactions (order matters!)
	transaction.assign_group_id([txn_1, txn_2])
	# Or, equivalently
	# get group id and assign it to transactions
	# gid = transaction.calculate_group_id([txn_1, txn_2])
	# txn_1.group = gid
	# txn_2.group = gid
	```
	[Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/atomic_transfers.py#L24-L31)
    <!-- ===PYSDK_ATOMIC_GROUP_TXNS=== --->

=== "Java"
    <!-- ===JAVASDK_ATOMIC_GROUP_TXNS=== --->
	```java
	// Assign group id to the transactions (order matters!)
	Transaction[] txs = TxGroup.assignGroupID(ptxn1, ptxn2);
	
	// Or, equivalently
	// compute group id and assign it to transactions
	Digest gid = TxGroup.computeGroupID(txs);
	ptxn1.group = gid;
	ptxn2.group = gid;
	```
	[Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AtomicTransfers.java#L39-L47)
    <!-- ===JAVASDK_ATOMIC_GROUP_TXNS=== --->

=== "Go"
    <!-- ===GOSDK_ATOMIC_GROUP_TXNS=== --->
	```go
	// compute group id and put it into each transaction
	gid, _ := crypto.ComputeGroupID([]types.Transaction{tx1, tx2})
	tx1.Group = gid
	tx2.Group = gid
	```
	[Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/atomic_transactions/main.go#L42-L46)
    <!-- ===GOSDK_ATOMIC_GROUP_TXNS=== --->

=== "goal"
    <!-- ===GOAL_ATOMIC_GROUP_TXNS=== --->
	```goal
    $ cat unsignedtransaction1.tx unsignedtransaction2.tx > combinedtransactions.tx
    $ goal clerk group -i combinedtransactions.tx -o groupedtransactions.tx -d data -w yourwallet 
    ```
    <!-- ===GOAL_ATOMIC_GROUP_TXNS=== --->

## Split transactions (Goal only)

At this point the transaction set must be split to allow distributing each component transaction to the appropriate wallet for authorization. 

=== "goal"
    <!-- ===GOAL_ATOMIC_GROUP_SPLIT=== -->
	```goal
    # keys in distinct wallets
    $ goal clerk split -i groupedtransactions.tx -o splitfiles -d data -w yourwallet 

    Wrote transaction 0 to splitfiles-0
    Wrote transaction 1 to splitfiles-1

    # distribute files for authorization
    ```
    <!-- ===GOAL_ATOMIC_GROUP_SPLIT=== -->

## Sign transactions
With a group ID assigned, each transaction sender must authorize their respective transaction. 

=== "JavaScript"
    <!-- ===JSSDK_ATOMIC_GROUP_SIGN=== -->
	```javascript
	const alicesSignedTxn = txnGroup[0].signTxn(acct1.privateKey);
	const bobsSignedTxn = txnGroup[1].signTxn(acct2.privateKey);
	```
	[Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/atomics.ts#L39-L41)
    <!-- ===JSSDK_ATOMIC_GROUP_SIGN=== -->

=== "Python"
    <!-- ===PYSDK_ATOMIC_GROUP_SIGN=== -->
	```python
	# sign transactions
	stxn_1 = txn_1.sign(sk1)
	stxn_2 = txn_2.sign(sk2)
	```
	[Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/atomic_transfers.py#L34-L37)
    <!-- ===PYSDK_ATOMIC_GROUP_SIGN=== -->

=== "Java"
    <!-- ===JAVASDK_ATOMIC_GROUP_SIGN=== -->
	```java
	// sign transactions
	SignedTransaction signedPtxn1 = acct1.signTransaction(ptxn1);
	SignedTransaction signedPtxn2 = acct2.signTransaction(ptxn2);
	```
	[Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AtomicTransfers.java#L50-L53)
    <!-- ===JAVASDK_ATOMIC_GROUP_SIGN=== -->

=== "Go"
    <!-- ===GOSDK_ATOMIC_GROUP_SIGN=== -->
	```go
	_, stx1, err := crypto.SignTransaction(acct1.PrivateKey, tx1)
	if err != nil {
		fmt.Printf("Failed to sign transaction: %s\n", err)
		return
	}
	_, stx2, err := crypto.SignTransaction(acct2.PrivateKey, tx2)
	if err != nil {
		fmt.Printf("Failed to sign transaction: %s\n", err)
	}
	```
	[Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/atomic_transactions/main.go#L49-L58)
    <!-- ===GOSDK_ATOMIC_GROUP_SIGN=== -->

=== "goal"
    <!-- ===GOAL_ATOMIC_GROUP_SIGN=== -->
	```goal
    # sign from single wallet containing all keys
    $ goal clerk sign -i groupedtransactions.tx -o signout.tx -d data -w yourwallet

    # -- OR --

    # sign from distinct wallets
    $ goal clerk sign -i splitfiles-0 -o splitfiles-0.sig -d data -w my_wallet_1
    $ goal clerk sign -i splitfiles-1 -o splitfiles-1.sig -d data -w my_wallet_2
    ```
    <!-- ===GOAL_ATOMIC_GROUP_SIGN=== -->

## Assemble transaction group

All authorized transactions are now assembled into an array, maintaining the original transaction ordering, which represents the transaction group.

=== "JavaScript"
    <!-- ===JSSDK_ATOMIC_GROUP_ASSEMBLE=== -->
	```javascript
	const signedTxns = [alicesSignedTxn, bobsSignedTxn];
	```
	[Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/atomics.ts#L44-L45)
    <!-- ===JSSDK_ATOMIC_GROUP_ASSEMBLE=== -->

=== "Python"
    <!-- ===PYSDK_ATOMIC_GROUP_ASSEMBLE=== -->
	```python
	# combine the signed transactions into a single list
	signed_group = [stxn_1, stxn_2]
	```
	[Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/atomic_transfers.py#L40-L42)
    <!-- ===PYSDK_ATOMIC_GROUP_ASSEMBLE=== -->

=== "Java"
    <!-- ===JAVASDK_ATOMIC_GROUP_ASSEMBLE=== -->
	```java
	// combine the signed transactions into a single list
	SignedTransaction[] stxns = new SignedTransaction[] { signedPtxn1, signedPtxn2 };
	```
	[Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AtomicTransfers.java#L56-L58)
    <!-- ===JAVASDK_ATOMIC_GROUP_ASSEMBLE=== -->

=== "Go"
    <!-- ===GOSDK_ATOMIC_GROUP_ASSEMBLE=== -->
	```go
	var signedGroup []byte
	signedGroup = append(signedGroup, stx1...)
	signedGroup = append(signedGroup, stx2...)
	
	```
	[Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/atomic_transactions/main.go#L61-L65)
    <!-- ===GOSDK_ATOMIC_GROUP_ASSEMBLE=== -->

=== "goal"
    <!-- ===GOAL_ATOMIC_GROUP_ASSEMBLE=== -->
	``` goal
    # combine signed transactions files
    cat splitfiles-0.sig splitfiles-1.sig > signout.tx
    ```
    <!-- ===GOAL_ATOMIC_GROUP_ASSEMBLE=== -->

## Send transaction group
The transaction group is now broadcast to the network. 

=== "JavaScript"
    <!-- ===JSSDK_ATOMIC_GROUP_SEND=== -->
	```javascript
	await client.sendRawTransaction(signedTxns).do();
	await algosdk.waitForConfirmation(client, alicesTxn.txID().toString(), 3);
	```
	[Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/atomics.ts#L48-L50)
    <!-- ===JSSDK_ATOMIC_GROUP_SEND=== -->

=== "Python"
    <!-- ===PYSDK_ATOMIC_GROUP_SEND=== -->
	```python
	
	# Only the first transaction id is returned
	tx_id = algod_client.send_transactions(signed_group)
	
	# wait for confirmation
	result: Dict[str, Any] = transaction.wait_for_confirmation(
	    algod_client, tx_id, 4
	)
	print(f"txID: {tx_id} confirmed in round: {result.get('confirmed-round', 0)}")
	```
	[Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/atomic_transfers.py#L45-L54)
    <!-- ===PYSDK_ATOMIC_GROUP_SEND=== -->

=== "Java"
    <!-- ===JAVASDK_ATOMIC_GROUP_SEND=== -->
	```java
	// Only the first transaction id is returned
	Response<PostTransactionsResponse> txResponse = algodClient.RawTransaction()
	                .rawtxn(Encoder.encodeToMsgPack(stxns)).execute();
	String txid = txResponse.body().txId;
	
	// Wait for the transaction id to be confirmed
	// If the results from other transactions are needed, grab the txid from those
	// directly and
	// call waitForConfirmation on each
	PendingTransactionResponse txResult = Utils.waitForConfirmation(algodClient, txid, 4);
	System.out.printf("Transaction %s confirmed in round %d\n", txid, txResult.confirmedRound);
	```
	[Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AtomicTransfers.java#L61-L72)
    <!-- ===JAVASDK_ATOMIC_GROUP_SEND=== -->

=== "Go"
    <!-- ===GOSDK_ATOMIC_GROUP_SEND=== -->
	```go
	pendingTxID, err := algodClient.SendRawTransaction(signedGroup).Do(context.Background())
	if err != nil {
		fmt.Printf("failed to send transaction: %s\n", err)
		return
	}
	confirmedTxn, err := transaction.WaitForConfirmation(algodClient, pendingTxID, 4, context.Background())
	if err != nil {
		fmt.Printf("Error waiting for confirmation on txID: %s\n", pendingTxID)
		return
	}
	fmt.Printf("Confirmed Transaction: %s in Round %d\n", pendingTxID, confirmedTxn.ConfirmedRound)
	```
	[Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/atomic_transactions/main.go#L68-L79)
    <!-- ===GOSDK_ATOMIC_GROUP_SEND=== -->

=== "goal"
    <!-- ===GOAL_ATOMIC_GROUP_SEND=== -->
	```goal
    goal clerk rawsend -f signout.tx -d data -w yourwallet
    ```
    <!-- ===GOAL_ATOMIC_GROUP_SEND=== -->
```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/developer:docs:details:dapps:avm:teal:index.md:
--------------------------------------------------------------------------------

```markdown
title: The smart contract language

Smart contracts and smart signatures are written in Transaction Execution Approval Language (TEAL). These contracts can be written directly or with Python using the [PyTeal library](/docs/get-details/dapps/writing-contracts/pyteal).

TEAL is an assembly-like language and is processed by the Algorand Virtual Machine (AVM). The language is a Turing-complete language that supports looping and subroutines, but limits the amount of time the contract has to execute using a dynamic opcode cost evaluation algorithm.  TEAL programs are processed one line at a time pushing and popping values on and off the stack. These stack values are either unsigned 64 bit integers or byte strings. TEAL provides a set of operators that operate on the values within the stack. TEAL also allows arguments to be passed into the program from a transaction, a scratch space to temporarily store values for use later in the program, access to grouped or single transaction properties, global values, a couple of pseudo operators, constants and flow control functions like `bnz` for branching and `callsub` for calling subroutines. Smart contracts can read and write global storage for the contract and local storage for accounts that opt-in to the contract. Smart contracts also have the ability to generate both asset and payment transactions within the logic. Using this ability, they can function as escrow accounts. See [TEAL Specification Reference](specification) for more details.

Some of the opcodes in TEAL are only valid for a specific contract type. These are denoted in the [TEAL Opcodes](opcodes) documentation with a `Mode` attribute. This attribute will be set to `Signature` for smart signatures and `Application` for smart contracts. For example, reading account assets or Algo balances is only available in smart contracts. 

<center>![TEAL Architecture](../../../../imgs/teal_overview-1.png)</center>
<center>*TEAL Architecture Overview*</center>

!!! warning
    When writing smart contracts, make sure to follow [TEAL guidelines](guidelines). This is very important in order to prevent smart contracts from being compromised.

# Program versions
Currently, Algorand supports versions 1 through 8 of TEAL. When writing contracts with program version 2 or higher, make sure to add `#pragma version #` where # should be replaced by the specific number, as the first line of the program. If this line does not exist, the protocol will treat the contract as a version 1 contract. If upgrading a contract to version 2 or higher, it is important to verify you are checking the `RekeyTo` property of all transactions that are attached to the contract. See the [TEAL guidelines](guidelines) for more suggestions to help prevent a contract from being compromised. 

# Getting transaction properties
The primary purpose of a TEAL program is to return either true or false. When the program completes, if there is a non-zero value on the stack then it returns true. If there is a zero value or the stack is empty, it will return false. If the stack has more than one value the program also returns false unless the `return` opcode is used. The following diagram illustrates how the stack machine processes the program.

Program line number 1:

<center>![Transaction Properties](../../../../imgs/teal_overview-2.png)</center>
<center>*Getting Transaction Properties*</center>

The program uses the `txn` to reference the current transaction's list of properties. Grouped transaction properties are referenced using `gtxn` and `gtxns`. The number of transactions in a grouped transaction is available in the global variable `GroupSize`. To get the first transaction's receiver use `gtxn 0 Receiver`. See [TEAL Specification Reference](specification) for more transaction properties.

# Pseudo opcodes
The TEAL specification provides several pseudo opcodes for convenience.  For example, the second line in the program below uses the `addr` pseudo opcode.

<center>![Pseudo Opcodes](../../../../imgs/teal_overview-3.png)</center>
<center>*Pseudo Opcodes*</center>

The `addr` pseudo opcode converts Algorand addresses to a byte constant and pushes the result to the stack. See [TEAL Specification Reference](specification) for additional pseudo opcodes.

# Operators
TEAL provides operators to work with data that is on the stack. For example, the `==` operator evaluates if the last two values on the stack are equal and pushes either a 1 or 0 depending on the result. The number of values used by an operator will depend on the operator. The [TEAL Opcodes](opcodes) documentation explains arguments and return values. See [TEAL Specification Reference](specification) for a list of all operators.

<center>![Operators](../../../../imgs/teal_overview-4.png)</center>
<center>*Operators*</center>

# Argument passing
TEAL supports program arguments. Smart contracts and smart signatures handle these parameters with different opcodes. For information on passing parameters to smart contracts, see the smart contract [Overview](../../smart-contracts/apps/index.md) documentation. Passing parameters to a smart signature is explained in the [Interact with smart signatures](../../smart-contracts/frontend/smartsigs.md) documentation. The [CLI smart signatures](../../smart-contracts/smartsigs/walkthrough.md) documentation explains a simple example of passing a parameter to a smart signature with the `goal` command-line tool. 

The diagram below shows an example of logic that is loading a parameter onto the stack within a smart signature. 

<center>![Arguments](../../../../imgs/teal_overview-5.png)</center>
<center>*Arguments*</center>

All argument parameters to a TEAL program are byte arrays. The order that parameters are passed is specific. In the diagram above, The first parameter is pushed onto the stack. The SDKs provide standard language functions that allow you to convert parameters to a byte array. 

# Storing and loading from scratchspace
TEAL provides a scratch space as a way of temporarily storing values for use later in your code. The diagram below illustrates a small TEAL program that loads 12 onto the stack and then duplicates it. These values are multiplied together and result (144) is pushed to the top of the stack. The store command stores the value in the scratch space 1 slot.

<center>![Storing Values](../../../../imgs/teal_overview-6.png)</center>
<center>*Storing Values*</center>

The load command is used to retrieve a value from the scratch space as illustrated in the diagram below. Note that this operation does not clear the scratch space slot, which allows a stored value to be loaded many times if necessary.

<center>![Loading Values](../../../../imgs/teal_overview-7.png)</center>
<center>*Loading Values*</center>

# Looping and subroutines
TEAL contracts written in version 4 or higher can use loops and subroutines. Loops can be performed using any of the branching opcodes `b`, `bz`, and `bnz`. For example the TEAL below loops ten times.

```teal
#pragma version 4
// loop 1 - 10
// init loop var
int 0 
loop:
int 1
+
dup
// implement loop code
// ...
// check upper bound
int 10
<=
bnz loop
// once the loop exits, the last counter value will be left on stack
```

Subroutines can be implemented using labels and the `callsub` and `retsub` opcodes. The sample below illustrates a sample subroutine call.

```teal
#pragma version 4
// jump to main loop
b main

// subroutine
my_subroutine:
// implement subroutine code
// with the two args
retsub

main:
int 1
int 5
callsub my_subroutine
return
```

# Dynamic operational cost of TEAL opcodes
Smart signature are limited to 1000 bytes in size. Size encompasses the compiled program plus arguments. Smart contracts are limited to 2KB total for the compiled approval and clear programs. This size can be increased in 2KB increments, up to an 8KB limit for both programs. 

For optimal performance, smart contracts and smart signatures are also limited in opcode cost. This cost is evaluated when a smart contract runs and is representative of it’s computational expense. Every opcode executed by the AVM has a numeric value that represents its computational cost. Most opcodes have a computational cost of 1. Some, such as `SHA256` (cost 35) or `ed25519verify` (cost 1900) have substantially larger computational costs. The [TEAL Opcodes](opcodes) reference lists the opcode cost for every opcode.

Smart signatures are limited to 20,000 for total computational cost. 

Smart contracts invoked by a single application transaction are limited to 700 for either of the programs associated with the contract. However, if the smart contract is invoked via a group of application transactions, the computational budget for approval programs is considered pooled. The total opcode budget will be 700 multiplied by the number of application transactions within the group (including inner transactions). So if the maximum transaction group size is used (i.e., 16 transactions) and the maximum number of inner transactions is used (i.e., 256 inner transactions) and all are application transactions, the computational budget would be 700x(16+256)=190,400. 

!!! info
    Executions of clear state programs are more stringent than approval programs, in order to ensure that applications may be closed out, but that applications also are assured a chance to clean up their internal state. At the beginning of the execution of a clear state program, the pooled budget available must be 700 or higher. If it is not, the containing transaction group fails without clearing the app's state. During the execution of the clear state program, no more than 700 cost may be drawn. If further execution is attempted, the clear state program fails, and the app's state is cleared.


# Example walkthrough of a TEAL program
The example covered in this tutorial is for a smart signature contract account TEAL program. The account is set up where all tokens are removed from the account with one successful transaction and delivered to one of two accounts. Unsuccessful transactions leave the funds in the contract account.

The example uses two addresses (addr1 and addr2). The variables have the values of addr1 = `RFGEHKTFSLPIEGZYNVYALM6J4LJX4RPWERDWYS2PFKNVDWW3NG7MECQTJY` and addr2 = `SOEI4UA72A7ZL5P25GNISSVWW724YABSGZ7GHW5ERV4QKK2XSXLXGXPG5Y`.  The variable addr1 represents the creator of the contact account. The addr1 account funds the contract account after creation. The variable addr2 is the intended recipient of the funds, but only if addr2 supplies a proper secret key and the transaction must be submitted within a time limit (represented with a number of blocks). If addr2 does not submit the transaction in time or can’t supply the proper secret key, addr1 can submit the transaction and retrieve all the tokens. The transaction fee for the transaction is limited to no more than 1 Algo and this must not be a rekey transaction. The pseudo-code for this example is represented with the following logic:

``` go
((addr2 and secret) || (addr1 and timeout)) && (ok fee and !rekey)
```

The example uses the `CloseRemainderTo` field to close out the account and move all funds to either addr1 or addr2 on a successful transaction.

The first clause of the pseudo logic is implemented with the following TEAL.

```teal
// Are used to comment in TEAL
// htlc.teal
// Push the CloseRemainderTo property of the current transaction onto the stack
txn CloseRemainderTo

// Push addr2 onto the stack as the intended recipient
addr SOEI4UA72A7ZL5P25GNISSVWW724YABSGZ7GHW5ERV4QKK2XSXLXGXPG5Y

// The == operator is used to verify that both of these are the same
// This pops the two values off the stack and pushes the result 0 or 1
==

// Push the current transaction’s Receiver property onto the stack
// In this example it should be addr2
txn Receiver

// Push addr2 on the stack using the addr constant
addr SOEI4UA72A7ZL5P25GNISSVWW724YABSGZ7GHW5ERV4QKK2XSXLXGXPG5Y

// Use the == to verify that these are equal which pops off the top two values of the stack
// and returns 0 or 1
==

// The stack should currently have two values from the two top conditions
// These will be either 0s or 1s
// Push the && operator which will AND the two previous conditions and return
// either 0 or 1, which leaves one value on the stack either a 0 or a 1
&&

// Push the first argument to the transaction onto the stack
arg 0

// The len operator pops the arg off the stack and 
// pushes the length of the argument onto the stack
len

// Push a constant int of value 46 onto the stack
int 46

// The == operator verifies that the length of the argument
// is equal to 46. This pops the two values and returns a 0 or 1
// The stack now contains two values with a value of 0 or 1
==

// The && operator will AND the two values in the stack
// which pops both values off the stack and returns a 0 or 1
// The stack should now only have one value on the stack, 0 or 1
&&

// arg 0 is pushed back onto the stack
// This represents the hashed passcode
arg 0

// The sha256 operator pops the arg 0 off the stack
// and pushes the hash value of the argument onto the stack
sha256

// The constant byte array of the base64 version of our secret is pushed onto the stack
byte base64 QzYhq9JlYbn2QdOMrhyxVlNtNjeyvyJc/I8d8VAGfGc=

// The == operator pops the two values and pushes 0 or 1 onto the stack
// If arg0 is equal to the secret this value will be 1 and if not it will be 0
==

// Two values are now on the stack. The && operator is used 
// to pop the last two values and push either 0 or 1
// This will AND all previous conditions to this one.
// The stack should only have a 0 or 1 value now
&&

```

The second clause of the pseudo logic is implemented with the following TEAL.

```teal

// The following six lines of teal check if the 
// transaction receiver is set to addr1 and that the CloseRemainderTo
// transaction property is also set to addr1.
// Once completed the stack will have the 0 or 1 
// from the previous clause and a 1 or 0 from the 
// the beginning of the second clause. 
txn CloseRemainderTo
addr RFGEHKTFSLPIEGZYNVYALM6J4LJX4RPWERDWYS2PFKNVDWW3NG7MECQTJY
==
txn Receiver
addr RFGEHKTFSLPIEGZYNVYALM6J4LJX4RPWERDWYS2PFKNVDWW3NG7MECQTJY
==
&&

// The FirstValid parameter from the transaction is pushed onto the stack
txn FirstValid

// The constant int value of 67240 is pushed onto the stack
// This is a hard coded round number and is only used here as an example
int 67240

// The > operator is used to check if First Valid is greater than 67240
// This is used to see if the transaction is timed out and if so addr1 can
// Submit the transaction to return the funds.
// This pops the last two values and returns a 0 or 1
// At the end of this operation, we should have 
// three values on the stack. One for the first clause, and two for the second clause
>

// The && operator is used to AND the last two options in the second clause which pops the
// last two values and pushes a 1 or 0. This will leave only two values on the stack
&&

```

This completes the second clause. Clause 1 and 2 are ORed together.

```teal
// The || operator is pushed onto the stack which ORs
// the first two clauses
// and pops the two values and pushes a 0 or 1 
|| 
```

The third clause is responsible for verifying that the transaction fee is below 1 Algo and that no rekey operation is happening. This is an important check to prevent an account from being cleared by an errant transaction fee requirement or assigned to a new private key.

```teal

// The current transaction fee is pushed onto the stack
txn Fee

// The constant integer of value 1000000 is pushed
// onto the stack, which is specified in micro Algos
// In this example this equates to 1 Algo
int 1000000 

// The < operator is used to pop those last two values and replace with a 
// 0 or 1. This just verifies that the fee is not greater than 1 Algo 
<

// Next the transaction RekeyTo property is pushed onto the stack.
txn RekeyTo

// The global zero address is then pushed onto the stack. 
global ZeroAddress

// the == operator will replace the last two fields with a 0 or a 1. If the value is 1, this is not a rekey transaction.
==

// next the && operator is used to AND the two conditions in the third clause.
// At this point there will be two values on the stack
&&
```

The && is the final operator used in this example. This ANDs the third clause with the result of the OR operation between the first and second clauses.

```teal
// The && operator is used to pop those values by anding them and pushing either 
// a 1 or 0
// Since this is the end of the program this value represents the return value
// and determines if the transaction executed successfully 
&&
```

Full example is presented below.

```teal

txn CloseRemainderTo
addr SOEI4UA72A7ZL5P25GNISSVWW724YABSGZ7GHW5ERV4QKK2XSXLXGXPG5Y
==
txn Receiver
addr SOEI4UA72A7ZL5P25GNISSVWW724YABSGZ7GHW5ERV4QKK2XSXLXGXPG5Y
==
&&
arg 0
len
int 46
==
&&
arg 0
sha256
byte base64 QzYhq9JlYbn2QdOMrhyxVlNtNjeyvyJc/I8d8VAGfGc=
==
&&
txn CloseRemainderTo
addr RFGEHKTFSLPIEGZYNVYALM6J4LJX4RPWERDWYS2PFKNVDWW3NG7MECQTJY
==
txn Receiver
addr RFGEHKTFSLPIEGZYNVYALM6J4LJX4RPWERDWYS2PFKNVDWW3NG7MECQTJY
==
&&
txn FirstValid
int 67240
>
&&
||
txn Fee
int 1000000
<
txn RekeyTo
global ZeroAddress
==
&&
&&
```

```

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

```markdown
title: Overview

# Introduction

Algorand smart contracts are pieces of logic that reside on the Algorand blockchain and are remotely callable. These contracts are primarily responsible for implementing the logic associated with a distributed application. Smart contracts are referred to as stateful smart contracts or applications in the Algorand documentation. Smart contracts can generate asset and payment transactions allowing them to function as Escrow accounts on the Algorand blockchain. Smart contracts can also store values on the blockchain. This storage can be global, local, or box storage. Local storage refers to storing values in an accounts balance record if that account participates in the contract. Global storage is data that is specifically stored on the blockchain for the contract globally. Box storage is also global and allows contracts to use larger segments of storage. Like smart signatures, smart contracts are written in Python using PyTeal or TEAL and can be deployed to the blockchain using either the `goal` command-line tool or the SDKs. The recommended approach for writing smart contracts is to use the Python SDK with the PyTeal library.  

See the [*PyTeal Documentation*](/docs/get-details/dapps/writing-contracts/pyteal) for information on building smart contracts in Python.

See the [*TEAL Reference Guide*](../../avm/teal/specification.md) to understand how to write TEAL and the [*TEAL Opcodes*](../../avm/teal/opcodes) documentation that describes the opcodes available. This guide assumes that the reader is familiar with [TEAL](../../avm/teal/index.md).

!!! important "A note about PyTeal"
    Where possible, TEAL code snippets are accompanied by their counterparts in PyTeal. Here are a few things to be aware of when comparing across these two languages:
     
    - Each PyTeal code snippet ends with the action to compile the program and write it to a file so the user can view the underlying TEAL code.
    - Sometimes the compiled version of a PyTeal code snippet will differ slightly from the TEAL version. However, the resulting function should be equivalent for the particular area of focus in the documentation. In larger more complex programs, this may not always be the case.
    - When a TEAL code snippet includes comments as placeholders for code, the PyTeal example will often use a placeholder of `Seq([Return(Int(1))])` with a comment describing this as a placeholder. This allows the user to compile the program for learning purposes. However, returning 1 is a very permissive action and should be carefully updated when used in a production application.


# The lifecycle of a smart contract
Smart contracts are implemented using two programs:

* The `ApprovalProgram` is responsible for processing all application calls to the contract, with the exception of the clear call (described in the next bullet). This program is responsible for implementing most of the logic of an application. Like smart signatures, this program will succeed only if one nonzero value is left on the stack upon program completion or the `return` opcode is called with a positive value on the top of the stack.
* The `ClearStateProgram` is used to handle accounts using the clear call to remove the smart contract from their balance record. This program will pass or fail the same way the `ApprovalProgram` does. 

In either program, if a global, box, or local state variable is modified and the program fails, the state changes will not be applied. 

Having two programs allows an account to clear the contract from its state, whether the logic passes or not. When the clear call is made to the contract, whether the logic passes or fails, the contract will be removed from the account's balance record. Note the similarity to the CloseOut transaction call which can fail to remove the contract from the account, which is described below.

Calls to smart contracts are implemented using `ApplicationCall` transactions. These transaction types are as follows:

* NoOp - Generic application calls to execute the `ApprovalProgram`.
* OptIn - Accounts use this transaction to begin participating in a smart contract.  Participation enables local storage usage.
* DeleteApplication - Transaction to delete the application.
* UpdateApplication - Transaction to update TEAL Programs for a contract.
* CloseOut - Accounts use this transaction to close out their participation in the contract. This call can fail based on the TEAL logic, preventing the account from removing the contract from its balance record.
* ClearState - Similar to CloseOut, but the transaction will always clear a contract from the account’s balance record whether the program succeeds or fails.

The `ClearStateProgram` handles the `ClearState` transaction and the `ApprovalProgram` handles all other `ApplicationCall` transactions. These transaction types can be created with either `goal` or the SDKs. In the following sections, details on the individual capabilities of a smart contract will be explained.

<center>![Smart Contract](/docs/imgs/stateful-1.png)</center>
<center>*Application Transaction Types*</center>

# Reference arrays

When smart contracts execute, they may require data stored within the ledger for evaluation. The following sections define how data access by a smart contract is achieved as of version 9 of the AVM. For previous versions of the AVM see the [TEAL specification](https://github.com/algorandfoundation/specs/blob/master/dev/TEAL.md#resource-availability).

<center>![Smart Contract](/docs/imgs/refarray_1.png)</center>


## Resource availability
The AVM provides several opcodes(functions) that support reading ledger data. The primary ledger data items that can be read are accounts, assets(ASAs), applications(smart contracts), and boxes. These ledger items allow the contract to look at specific information about each of these components such as reading an accounts’s Algo balance or examining the immutable properties of an ASA. These items are stored in the ledger in what can be thought of as large lists.

<center>![Smart Contract](/docs/imgs/refarray_2.png)</center>


Two of these components ( accounts and applications ) also contain sublists of potentially large datasets. For example, an account can opt into potentially an unlimited set of assets or applications (which store user local state). Additionally, smart contracts allow boxes of data to be stored within the ledger and are also potentially unlimited. For example, a smart contract may create a unique box of arbitrary data for every user of the smart contract.

<center>![Smart Contract](/docs/imgs/refarray_3.png)</center>

To maintain a high level of performance, the AVM restricts how much of the ledger can be viewed within a given contract execution. This is implemented with a set of reference arrays passed with each application transaction that define the specific ledger items that are **available** during execution. These arrays are the Account, Asset, Application, and Boxes arrays. 

These four arrays are limited to eight total values combined (per application transaction). The accounts array can have no more than four accounts. The values passed in using these arrays can change per application transaction. 

Additionally, when accessing one of the sublists of items, the application transaction must include both the top level item and the nested list item within the same call. For example, to read an ASA balance for a specific account, the account and the asset must both be present in the respective accounts and assets arrays for the given transaction.

<center>![Smart Contract](/docs/imgs/refarray_4.png)</center>

By default the reference arrays are empty with the exception of the accounts array and the applications array. The Accounts array contains the transaction sender's address, and the Application array contains the called smart contract ID.

<center>![Smart Contract](/docs/imgs/refarray_5.png)</center>

If a specific ledger item (account, asset, application, account+asset, account+application, application+box) can be read during a smart contract’s execution, it is said to be **available**. These four arrays determine the **availability** of these six unique ledger items.

AVM opcodes that require an address, asset ID, or application ID can access the value of these from the reference arrays using slot referencing or by passing the actual address or ID. Using the actual address or ID is the preferred method as shown in the example below.

```python
@app.external
def asa_balance_with_reference_type(
    account: abi.Account, asa: abi.Asset, *, output: abi.Uint64
) -> Expr:
    asset_balance = AssetHolding.balance(account.address(), asa.asset_id())
    return Seq(
        asset_balance,
        Assert(asset_balance.hasValue()),
        output.set(asset_balance.value()),
    )

```
 
Slot referencing can be used as well, but will not benefit from resource sharing.

```python
@app.external
def asa_balance_with_slot_referencing(*, output: abi.Uint64) -> Expr:
    asset_balance = AssetHolding.balance(Txn.accounts[0], Txn.assets[0])
    return Seq(
        asset_balance,
        Assert(asset_balance.hasValue()),
        output.set(asset_balance.value()),
    )

```

!!! info
    Since V9 of the AVM, resource sharing is now available. Specific addresses/IDs should be used and not slot references. Slot referencing may be deprecated in the future.  Read more about resource sharing below.

!!! info
    If a smart contract uses an inner transaction to initiate a call to another smart contract, the inner contract automatically inherits the resource **availability** of the top level smart contract.

## Resource sharing
Resources are shared across atomically grouped transactions. This means that if two smart contracts are in the same atomic group, they share **availability**. 

For example, say you have two smart contract call transactions grouped together, transaction #1 and transaction #2. Transaction #1 has asset 123456 in its assets array, and transaction #2 has asset 555555 in its assets array. Both assets are **available** to both smart contract calls during evaluation. 

<center>![Smart Contract](/docs/imgs/refarray_6.png)</center>

Note that when accessing a sublist item (account+asa, account+application local state, application+box), both items need to be in the same transaction’s set of arrays. For example, you cannot have account A in transaction #1 and asset Z in transaction #2 and then try to get the balance of asset Z for account A. Asset Z and account A must be in the same application transaction. If both asset Z and account A are in transaction #1’s arrays, then A’s balance for Z is **available** to both transactions during evaluation. 

Because Algorand supports grouping up to 16 transactions simultaneously, this pushes the **available** resources up to 8x16 or 128 items, if all 16 transactions are application transactions.

If an application transaction is grouped with other types of transactions, other resources will be made **available** to the smart contract called in the application transaction. For example, if an application transaction is grouped with a payment transaction, the payment transaction’s sender and receiver accounts are **available** to the smart contract. Additionally, if the `CloseRemainderTo` field is set, that account will also be **available** to the smart contract. The table below summarizes what each transaction type adds to resource **availability**.

| Transaction | Type | Availability Notes | 
|------|------|------|
| Payment | `pay` | `txn.Sender`, `txn.Receiver`, and `txn.CloseRemainderTo` (if set)|
| Key Registration | `keyreg` | `txn.Sender` |
| Asset Config/Create | `acfg` | `txn.Sender`, `txn.ConfigAsset`, and the `txn.ConfigAsset` holding of `txn.Sender`|
| Asset Transfer | `axfer` | `txn.Sender`, `txn.AssetReceiver`, `txn.AssetSender` (if set), `txnAssetCloseTo` (if set), `txn.XferAsset`, and the `txn.XferAsset` holding of each of those accounts. |
| Asset Freeze | `afrz` | `txn.Sender`, `txn.FreezeAccount`, `txn.FreezeAsset`, and the `txn.FreezeAsset` holding of `txn.FreezeAccount`. The `txn.FreezeAsset` holding of `txn.Sender` is not made available. |

!!! info
    In future versions of the AVM, the Atomic Transaction Composer may be enhanced to automatically generate reference arrays for specific transaction groups

!!! info
	If any application or asset is created within a group of transactions, they are **available** resources as long as they are created before they are accessed.

## Boxes Array
Boxes function similar to the other arrays but differ is significant ways which are explained in detail in the [Boxes section of the documentation](state.md#box-details).

## Loading the Reference Arrays 
For information on adding entries to reference arrays when calling a smart contract see the [ATC documentation](https://developer.algorand.org/docs/get-details/atc/#foreign-references).

# Application Account
Since September 2021 all deployed smart contracts are given their own application account with an associated Algorand public address. These accounts are used by issuing [inner transactions](/docs/get-details/dapps/smart-contracts/apps/innertx/) from within the smart contract.

The public address is devised by taking the application ID as an 8-byte big-endian array, prefixing it with `appID`, and then encoding it using the standard encoding method for Algorand addresses. The Algorand SDKs provide helpful utilities to do this for you given just the application ID.

=== "Python"
    <!-- ===PYSDK_CODEC_APPLICATION_ACCOUNT=== -->
    ```python
    app_id = 123
    app_addr = logic.get_application_address(app_id)

    print(f"Application ID:   {app_id}")
    print(f"Application Addr: {app_addr}")
    ```
    [Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/codec.py#L16-L21)
    <!-- ===PYSDK_CODEC_APPLICATION_ACCOUNT=== -->

=== "JavaScript"
    <!-- ===JSSDK_CODEC_APPLICATION_ACCOUNT=== -->
    ```javascript
    const appId = 123;
    const appAddr = algosdk.getApplicationAddress(appId);

    console.log(`Application ID:      ${  appId}`);
    console.log(`Application Address: ${  appAddr}`);
    ```
    [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/codec.ts#L23-L28)
    <!-- ===JSSDK_CODEC_APPLICATION_ACCOUNT=== -->

=== "Go"
    <!-- ===GOSDK_CODEC_APPLICATION_ACCOUNT=== -->
    ```go
    var appId uint64 = 123
    var appAddr types.Address = crypto.GetApplicationAddress(appId)

    fmt.Println("Application ID:      ", appId)
    fmt.Println("Application Address: ", appAddr)
    ```
    [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/codec/main.go#L76-L81)
    <!-- ===GOSDK_CODEC_APPLICATION_ACCOUNT=== -->


# Minimum balance requirement for a smart contract
When creating or opting into a smart contract your minimum balance will be raised. The amount at which it is raised will depend on the amount of on-chain storage that is used. This minimum balance requirement is associated with the account that creates or opts into the smart contract.

Calculation for increase in min-balance during creation or opt-in is as follows:

=== "Application Create"

    ```
    100,000*(1+ExtraProgramPages) + (25,000+3,500)*schema.NumUint + (25,000+25,000)*schema.NumByteSlice
    ```

    In words:

    - 100,000 microAlgo base fee for each page requested. 
    - 25,000 + 3,500 = 28,500 for each Uint in the *Global State* schema
    - 25,000 + 25,000 = 50,000 for each byte-slice in the *Global State* schema

=== "Application Opt-In"

    ```
    100,000 + (25,000+3,500)*schema.NumUint + (25,000+25,000)*schema.NumByteSlice
    ```

    In words:

    - 100,000 microAlgo base fee of opt-in
    - 25,000 + 3,500 = 28,500 for each Uint in the *Local State* schema
    - 25,000 + 25,000 = 50,000 for each byte-slice in the *Local State* schema


!!! note 
    Global storage is actually stored in the creator account, so that account is responsible for the global storage minimum balance.  When an account opts-in, it is responsible for the minimum balance of local storage. 
## Example
Given a smart contract with 1 *global* key-value-pair of type byteslice and 1 *local* storage key-value pair of type integer and no Extra Pages. 


=== "Creator"

    The creator of the Application would have its minimum balance raised by *150,000 microAlgos*.
    ```
    100,000 + 50,000  = 150,000
    ```

=== "Account"

    The account opting into the Application would have minimum balance raised *128,500 microAlgos*.

    ```
    100,000 + 28,500 = 128,500
    ```

# Minimum Balance Requirement For Boxes
Boxes are created by a smart contract and raise the minimum balance requirement (MBR) that must be in the contract's ledger balance. This means that a contract that intends to use boxes, must be funded beforehand.

When a box with name `n` and size `s` is created, the MBR is raised by `2500 + 400 * (len(n)+s)` microAlgos. When the box is destroyed, the minimum balance requirement is decremented by the same amount.

Notice that the key (name) is included as part of the MBR calculation. 

For example, if a box is created with the name “BoxA” (a 4 byte long key) and with a size of 1024 bytes, the MBR for the app account increases by 413,700 microAlgos:

    (2500 per box) + (400 * (box size + key size))
    (2500) + (400 * (1024+4)) = 413,700 microAlgos 

```
Page 33/74FirstPrevNextLast