This is page 61 of 93. Use http://codebase.md/goplausible/algorand-mcp?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── llms-install.md
├── llms.txt
├── package.json
├── packages
│ ├── client
│ │ ├── .env.example
│ │ ├── package.json
│ │ ├── README.md
│ │ ├── src
│ │ │ ├── env.ts
│ │ │ ├── index.ts
│ │ │ └── LocalWallet.ts
│ │ └── tsconfig.json
│ └── server
│ ├── .env.example
│ ├── API specs
│ │ ├── algod_api.json
│ │ ├── indexer_api.json
│ │ ├── mcp.json
│ │ ├── nfd_api.json
│ │ ├── ultrade_api.json
│ │ ├── vestige_api.json
│ │ └── vestige_free_api.json
│ ├── Dockerfile
│ ├── jest.config.js
│ ├── package.json
│ ├── README.md
│ ├── smithery.yaml
│ ├── src
│ │ ├── algorand-client.ts
│ │ ├── env.ts
│ │ ├── index.ts
│ │ ├── resources
│ │ │ ├── index.ts
│ │ │ ├── knowledge
│ │ │ │ ├── ARCs.txt
│ │ │ │ ├── developers-algokit-architecture-decisions.txt
│ │ │ │ ├── developers-algokit-cli.txt
│ │ │ │ ├── developers-algokit-utils-python.txt
│ │ │ │ ├── developers-algokit-utils-typescript.txt
│ │ │ │ ├── developers-clis.txt
│ │ │ │ ├── developers-details.txt
│ │ │ │ ├── developers-liquid-auth.txt
│ │ │ │ ├── developers-nodes.txt
│ │ │ │ ├── developers-puya.txt
│ │ │ │ ├── developers-python.txt
│ │ │ │ ├── developers-sdks-js.txt
│ │ │ │ ├── developers-sdks-python.txt
│ │ │ │ ├── developers-tealscript.txt
│ │ │ │ ├── developers.txt
│ │ │ │ ├── index.ts
│ │ │ │ ├── taxonomy
│ │ │ │ │ ├── algokit-cli:README.md
│ │ │ │ │ ├── algokit:cli:algokit.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2022-11-14_sandbox-approach.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2022-11-22_beaker-testing-strategy.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2023-01-11_beaker_productionisation_review.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2023-01-11_brew_install.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2023-01-12_smart-contract-deployment.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2023-06-06_frontend-templates.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2023-07-19_advanced_generate_command.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2024-01-13_native_binaries.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2024-01-23_init-wizard-v2.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2024-01-31_binary_distribution.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2024-03-06_local_dev_ui_packaging.md
│ │ │ │ │ ├── algokit:cli:articles:output_stability.md
│ │ │ │ │ ├── algokit:cli:cli:index.md
│ │ │ │ │ ├── algokit:cli:features:compile.md
│ │ │ │ │ ├── algokit:cli:features:completions.md
│ │ │ │ │ ├── algokit:cli:features:config.md
│ │ │ │ │ ├── algokit:cli:features:dispenser.md
│ │ │ │ │ ├── algokit:cli:features:doctor.md
│ │ │ │ │ ├── algokit:cli:features:explore.md
│ │ │ │ │ ├── algokit:cli:features:generate.md
│ │ │ │ │ ├── algokit:cli:features:goal.md
│ │ │ │ │ ├── algokit:cli:features:init.md
│ │ │ │ │ ├── algokit:cli:features:localnet.md
│ │ │ │ │ ├── algokit:cli:features:project:bootstrap.md
│ │ │ │ │ ├── algokit:cli:features:project:deploy.md
│ │ │ │ │ ├── algokit:cli:features:project:link.md
│ │ │ │ │ ├── algokit:cli:features:project:list.md
│ │ │ │ │ ├── algokit:cli:features:project:run.md
│ │ │ │ │ ├── algokit:cli:features:project.md
│ │ │ │ │ ├── algokit:cli:features:tasks:analyze.md
│ │ │ │ │ ├── algokit:cli:features:tasks:ipfs.md
│ │ │ │ │ ├── algokit:cli:features:tasks:mint.md
│ │ │ │ │ ├── algokit:cli:features:tasks:nfd.md
│ │ │ │ │ ├── algokit:cli:features:tasks:opt.md
│ │ │ │ │ ├── algokit:cli:features:tasks:send.md
│ │ │ │ │ ├── algokit:cli:features:tasks:sign.md
│ │ │ │ │ ├── algokit:cli:features:tasks:transfer.md
│ │ │ │ │ ├── algokit:cli:features:tasks:vanity_address.md
│ │ │ │ │ ├── algokit:cli:features:tasks:wallet.md
│ │ │ │ │ ├── algokit:cli:features:tasks.md
│ │ │ │ │ ├── algokit:cli:tutorials:algokit-template.md
│ │ │ │ │ ├── algokit:cli:tutorials:intro.md
│ │ │ │ │ ├── algokit:cli:tutorials:smart-contracts.md
│ │ │ │ │ ├── algokit:docs:testnet_api.md
│ │ │ │ │ ├── algokit:lora:README.md
│ │ │ │ │ ├── algokit:README.md
│ │ │ │ │ ├── algokit:utils:python:markdown:apidocs:algokit_utils:algokit_utils.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:account.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:app-client.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:app-deploy.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:client.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:debugger.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:dispenser-client.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:transfer.md
│ │ │ │ │ ├── algokit:utils:python:markdown:index.md
│ │ │ │ │ ├── algokit:utils:python:README.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:account.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:app-client.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:app-deploy.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:client.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:debugger.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:dispenser-client.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:transfer.md
│ │ │ │ │ ├── algokit:utils:python:source:index.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:account.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:algorand-client.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:amount.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:app-client.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:app-deploy.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:app.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:asset.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:client.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:debugging.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:dispenser-client.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:event-emitter.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:indexer.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:testing.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:transaction-composer.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:transaction.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:transfer.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:typed-app-clients.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:testing.TestLogger.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:testing.TransactionLogger.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_account_manager.AccountManager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_account.MultisigAccount.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_account.SigningAccount.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_algo_http_client_with_retry.AlgoHttpClientWithRetry.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_algorand_client_transaction_creator.AlgorandClientTransactionCreator.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_algorand_client_transaction_sender.AlgorandClientTransactionSender.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_algorand_client.AlgorandClient.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_amount.AlgoAmount.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_app_arc56.Arc56Method.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_app_client.AppClient.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_app_client.ApplicationClient.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_app_deployer.AppDeployer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_app_factory.AppFactory.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_app_manager.AppManager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_asset_manager.AssetManager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_async_event_emitter.AsyncEventEmitter.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_client_manager.ClientManager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_composer.TransactionComposer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_config.UpdatableConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_dispenser_client.TestNetDispenserApiClient.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_kmd_account_manager.KmdAccountManager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_logic_error.LogicError.md
│ │ │ │ │ ├── algokit:utils:typescript:code:enums:types_app.OnSchemaBreak.md
│ │ │ │ │ ├── algokit:utils:typescript:code:enums:types_app.OnUpdate.md
│ │ │ │ │ ├── algokit:utils:typescript:code:enums:types_indexer.AccountStatus.md
│ │ │ │ │ ├── algokit:utils:typescript:code:enums:types_indexer.ApplicationOnComplete.md
│ │ │ │ │ ├── algokit:utils:typescript:code:enums:types_indexer.SignatureType.md
│ │ │ │ │ ├── algokit:utils:typescript:code:enums:types_lifecycle_events.EventType.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_account_manager.EnsureFundedResult.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_account.AccountConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_account.TransactionSignerAccount.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_algorand_client_interface.AlgorandClientInterface.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.Arc56Contract.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.Event.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.Method.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.ProgramSourceInfo.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.StorageKey.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.StorageMap.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.StructField.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientCallABIArgs.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientCallCoreParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientCompilationParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientCompilationResult.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientDeployCallInterfaceParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientDeployCoreParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientDeployParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppSourceMaps.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.FundAppAccountParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.ResolveAppById.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.ResolveAppByIdBase.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.SourceMapExport.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_deployer.AppLookup.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_deployer.AppMetadata.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_factory.AppFactoryParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_manager.AppInformation.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_manager.BoxReference.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_manager.BoxValueRequestParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_manager.BoxValuesRequestParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.AppSources.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.AppSpec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.CallConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.DeclaredSchemaValueSpec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.Hint.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.ReservedSchemaValueSpec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.Schema.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.SchemaSpec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.StateSchemaSpec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.Struct.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppCallParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppCallTransactionResultOfType.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppCompilationResult.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppDeploymentParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppDeployMetadata.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppLookup.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppMetadata.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppReference.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppState.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppStorageSchema.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.BoxName.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.BoxReference.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.BoxValueRequestParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.BoxValuesRequestParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.CompiledTeal.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.CoreAppCallArgs.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.CreateAppParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.RawAppCallArgs.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.TealTemplateParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.UpdateAppParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_asset_manager.AssetInformation.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_asset_manager.BulkAssetOptInOutResult.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_asset.AssetBulkOptInOutParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_asset.AssetOptInParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_asset.AssetOptOutParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_asset.CreateAssetParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_client_manager.AlgoSdkClients.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_client_manager.TypedAppClient.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_client_manager.TypedAppFactory.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_composer.BuiltTransactions.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_config.Config.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_debugging.AVMTracesEventData.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_debugging.TealSourceDebugEventData.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_debugging.TealSourcesDebugEventData.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_dispenser_client.DispenserFundResponse.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_dispenser_client.DispenserLimitResponse.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_dispenser_client.TestNetDispenserApiClientParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_indexer.LookupAssetHoldingsOptions.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_logic_error.LogicErrorDetails.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_network_client.AlgoClientConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_network_client.AlgoConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_network_client.NetworkDetails.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_testing.AlgoKitLogCaptureFixture.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_testing.AlgorandFixture.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_testing.AlgorandFixtureConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_testing.AlgorandTestAutomationContext.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_testing.GetTestAccountParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_testing.LogSnapshotConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.AtomicTransactionComposerToSend.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.ConfirmedTransactionResult.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.ConfirmedTransactionResults.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.SendAtomicTransactionComposerResults.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.SendParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.SendTransactionParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.SendTransactionResult.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.SendTransactionResults.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.TransactionGroupToSend.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.TransactionToSign.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transfer.AlgoRekeyParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transfer.AlgoTransferParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transfer.EnsureFundedParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transfer.EnsureFundedReturnType.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transfer.TransferAssetParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:index.indexer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:index.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:testing.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_account_manager_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_account_manager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_account.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algo_http_client_with_retry.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client_asset_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client_interface.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client_transaction_creator.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client_transaction_sender.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client_transfer_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_amount_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_amount.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_arc56.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_client_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_client.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_deployer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_factory_and_client_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_factory.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_manager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_asset_manager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_asset.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_async_event_emitter_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_async_event_emitter.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_client_manager_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_client_manager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_composer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_config.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_debugging.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_dispenser_client_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_dispenser_client.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_expand.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_indexer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_kmd_account_manager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_lifecycle_events.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_logging.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_logic_error.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_network_client.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_testing.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_transaction.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_transfer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:README.md
│ │ │ │ │ ├── algokit:utils:typescript:README.md
│ │ │ │ │ ├── algokit:utils:typescript:v7-migration.md
│ │ │ │ │ ├── algokit:utils:typescript:v8-migration.md
│ │ │ │ │ ├── ARCs:ARC-template.md
│ │ │ │ │ ├── ARCs:assets:arc-0012:README.md
│ │ │ │ │ ├── ARCs:assets:arc-0034:TemplateForm.md
│ │ │ │ │ ├── ARCs:assets:arc-0062:README.md
│ │ │ │ │ ├── ARCs:pages:nfts.md
│ │ │ │ │ ├── ARCs:pages:wallets.md
│ │ │ │ │ ├── ARCs:README.md
│ │ │ │ │ ├── ARCs:specs:arc-0000.md
│ │ │ │ │ ├── ARCs:specs:arc-0001.md
│ │ │ │ │ ├── ARCs:specs:arc-0002.md
│ │ │ │ │ ├── ARCs:specs:arc-0003.md
│ │ │ │ │ ├── ARCs:specs:arc-0004.md
│ │ │ │ │ ├── ARCs:specs:arc-0005.md
│ │ │ │ │ ├── ARCs:specs:arc-0006.md
│ │ │ │ │ ├── ARCs:specs:arc-0007.md
│ │ │ │ │ ├── ARCs:specs:arc-0008.md
│ │ │ │ │ ├── ARCs:specs:arc-0009.md
│ │ │ │ │ ├── ARCs:specs:arc-0010.md
│ │ │ │ │ ├── ARCs:specs:arc-0011.md
│ │ │ │ │ ├── ARCs:specs:arc-0012.md
│ │ │ │ │ ├── ARCs:specs:arc-0015.md
│ │ │ │ │ ├── ARCs:specs:arc-0016.md
│ │ │ │ │ ├── ARCs:specs:arc-0018.md
│ │ │ │ │ ├── ARCs:specs:arc-0019.md
│ │ │ │ │ ├── ARCs:specs:arc-0020.md
│ │ │ │ │ ├── ARCs:specs:arc-0021.md
│ │ │ │ │ ├── ARCs:specs:arc-0022.md
│ │ │ │ │ ├── ARCs:specs:arc-0023.md
│ │ │ │ │ ├── ARCs:specs:arc-0025.md
│ │ │ │ │ ├── ARCs:specs:arc-0026.md
│ │ │ │ │ ├── ARCs:specs:arc-0028.md
│ │ │ │ │ ├── ARCs:specs:arc-0032.md
│ │ │ │ │ ├── ARCs:specs:arc-0033.md
│ │ │ │ │ ├── ARCs:specs:arc-0034.md
│ │ │ │ │ ├── ARCs:specs:arc-0035.md
│ │ │ │ │ ├── ARCs:specs:arc-0036.md
│ │ │ │ │ ├── ARCs:specs:arc-0042.md
│ │ │ │ │ ├── ARCs:specs:arc-0047.md
│ │ │ │ │ ├── ARCs:specs:arc-0048.md
│ │ │ │ │ ├── ARCs:specs:arc-0049.md
│ │ │ │ │ ├── ARCs:specs:arc-0054.md
│ │ │ │ │ ├── ARCs:specs:arc-0055.md
│ │ │ │ │ ├── ARCs:specs:arc-0056.md
│ │ │ │ │ ├── ARCs:specs:arc-0059.md
│ │ │ │ │ ├── ARCs:specs:arc-0062.md
│ │ │ │ │ ├── ARCs:specs:arc-0065.md
│ │ │ │ │ ├── ARCs:specs:arc-0069.md
│ │ │ │ │ ├── ARCs:specs:arc-0072.md
│ │ │ │ │ ├── ARCs:specs:arc-0073.md
│ │ │ │ │ ├── ARCs:specs:arc-0074.md
│ │ │ │ │ ├── ARCs:specs:arc-0076.md
│ │ │ │ │ ├── ARCs:specs:arc-0078.md
│ │ │ │ │ ├── ARCs:specs:arc-0079.md
│ │ │ │ │ ├── ARCs:specs:arc-0200.md
│ │ │ │ │ ├── clis_index.md
│ │ │ │ │ ├── developer:docs:about.md
│ │ │ │ │ ├── developer:docs:clis:algokey:algokey.md
│ │ │ │ │ ├── developer:docs:clis:algokey:generate.md
│ │ │ │ │ ├── developer:docs:clis:algokey:import.md
│ │ │ │ │ ├── developer:docs:clis:algokey:multisig:append-auth-addr.md
│ │ │ │ │ ├── developer:docs:clis:algokey:multisig:multisig.md
│ │ │ │ │ ├── developer:docs:clis:algokey:part:info.md
│ │ │ │ │ ├── developer:docs:clis:algokey:part:part.md
│ │ │ │ │ ├── developer:docs:clis:algokey:part:reparent.md
│ │ │ │ │ ├── developer:docs:clis:algokey:sign.md
│ │ │ │ │ ├── developer:docs:clis:conduit:conduit.md
│ │ │ │ │ ├── developer:docs:clis:conduit:init.md
│ │ │ │ │ ├── developer:docs:clis:conduit:list:exporters.md
│ │ │ │ │ ├── developer:docs:clis:conduit:list:importers.md
│ │ │ │ │ ├── developer:docs:clis:conduit:list:list.md
│ │ │ │ │ ├── developer:docs:clis:conduit:list:processors.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:diagcfg.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:metric:disable.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:metric:enable.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:metric:metric.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:metric:status.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:telemetry:disable.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:telemetry:enable.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:telemetry:endpoint.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:telemetry:name.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:telemetry:status.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:telemetry:telemetry.md
│ │ │ │ │ ├── developer:docs:clis:goal:node:restart.md
│ │ │ │ │ ├── developer:docs:clis:goal:node:start.md
│ │ │ │ │ ├── developer:docs:clis:goal:node:status.md
│ │ │ │ │ ├── developer:docs:clis:goal:node:stop.md
│ │ │ │ │ ├── developer:docs:clis:goal:node:wait.md
│ │ │ │ │ ├── developer:docs:clis:goal:protocols.md
│ │ │ │ │ ├── developer:docs:clis:goal:report.md
│ │ │ │ │ ├── developer:docs:clis:goal:version.md
│ │ │ │ │ ├── developer:docs:clis:goal:wallet:list.md
│ │ │ │ │ ├── developer:docs:clis:goal:wallet:new.md
│ │ │ │ │ ├── developer:docs:clis:goal:wallet:wallet.md
│ │ │ │ │ ├── developer:docs:clis:indexer:api-config.md
│ │ │ │ │ ├── developer:docs:clis:indexer:daemon.md
│ │ │ │ │ ├── developer:docs:clis:indexer:indexer.md
│ │ │ │ │ ├── developer:docs:clis:indexer:util:util.md
│ │ │ │ │ ├── developer:docs:clis:indexer:util:validator.md
│ │ │ │ │ ├── developer:docs:clis:kmd.md
│ │ │ │ │ ├── developer:docs:clis:tealdbg:debug.md
│ │ │ │ │ ├── developer:docs:clis:tealdbg:remote.md
│ │ │ │ │ ├── developer:docs:clis:tealdbg:tealdbg.md
│ │ │ │ │ ├── developer:docs:details:accounts:create.md
│ │ │ │ │ ├── developer:docs:details:accounts:index.md
│ │ │ │ │ ├── developer:docs:details:accounts:rekey.md
│ │ │ │ │ ├── developer:docs:details:algorand_consensus.md
│ │ │ │ │ ├── developer:docs:details:algorand-networks:betanet.md
│ │ │ │ │ ├── developer:docs:details:algorand-networks:index.md
│ │ │ │ │ ├── developer:docs:details:algorand-networks:mainnet.md
│ │ │ │ │ ├── developer:docs:details:algorand-networks:testnet.md
│ │ │ │ │ ├── developer:docs:details:asa.md
│ │ │ │ │ ├── developer:docs:details:atc.md
│ │ │ │ │ ├── developer:docs:details:atomic_transfers.md
│ │ │ │ │ ├── developer:docs:details:conduit.md
│ │ │ │ │ ├── developer:docs:details:crust.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:guidelines.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:jsonspec.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v1.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v10.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v2.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v3.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v4.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v5.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v6.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v7.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v8.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v9.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:specification.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:ABI:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:apps:create.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:apps:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:apps:innertx.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:apps:state.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:apps:txs.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:debugging.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:frontend:apps.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:frontend:smartsigs.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:guidelines.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:smartsigs:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:smartsigs:modes.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:smartsigs:walkthrough.md
│ │ │ │ │ ├── developer:docs:details:dapps:writing-contracts:beaker.md
│ │ │ │ │ ├── developer:docs:details:dapps:writing-contracts:pyteal.md
│ │ │ │ │ ├── developer:docs:details:dapps:writing-contracts:python.md
│ │ │ │ │ ├── developer:docs:details:encoding.md
│ │ │ │ │ ├── developer:docs:details:ethereum_to_algorand.md
│ │ │ │ │ ├── developer:docs:details:index.md
│ │ │ │ │ ├── developer:docs:details:indexer.md
│ │ │ │ │ ├── developer:docs:details:parameter_tables.md
│ │ │ │ │ ├── developer:docs:details:stateproofs:index.md
│ │ │ │ │ ├── developer:docs:details:stateproofs:light_client.md
│ │ │ │ │ ├── developer:docs:details:technical_faq.md
│ │ │ │ │ ├── developer:docs:details:transactions:index.md
│ │ │ │ │ ├── developer:docs:details:transactions:offline_transactions.md
│ │ │ │ │ ├── developer:docs:details:transactions:payment_prompts.md
│ │ │ │ │ ├── developer:docs:details:transactions:signatures.md
│ │ │ │ │ ├── developer:docs:details:transactions:transactions.md
│ │ │ │ │ ├── developer:docs:details:useful_resources.md
│ │ │ │ │ ├── developer:docs:get-started:algokit.md
│ │ │ │ │ ├── developer:docs:get-started:basics:what_is_blockchain.md
│ │ │ │ │ ├── developer:docs:get-started:basics:whats_a_dapp.md
│ │ │ │ │ ├── developer:docs:get-started:basics:where_to_start.md
│ │ │ │ │ ├── developer:docs:get-started:basics:why_algorand.md
│ │ │ │ │ ├── developer:docs:get-started:tokenization:ft.md
│ │ │ │ │ ├── developer:docs:get-started:tokenization:nft.md
│ │ │ │ │ ├── developer:docs:index.md
│ │ │ │ │ ├── developer:docs:rest-apis:algod.md
│ │ │ │ │ ├── developer:docs:rest-apis:indexer.md
│ │ │ │ │ ├── developer:docs:rest-apis:kmd.md
│ │ │ │ │ ├── developer:docs:rest-apis:restendpoints.md
│ │ │ │ │ ├── developer:docs:run-a-node:operations:catchup.md
│ │ │ │ │ ├── developer:docs:run-a-node:operations:switch_networks.md
│ │ │ │ │ ├── developer:docs:run-a-node:participate:generate_keys.md
│ │ │ │ │ ├── developer:docs:run-a-node:participate:index.md
│ │ │ │ │ ├── developer:docs:run-a-node:participate:offline.md
│ │ │ │ │ ├── developer:docs:run-a-node:participate:online.md
│ │ │ │ │ ├── developer:docs:run-a-node:participate:renew.md
│ │ │ │ │ ├── developer:docs:run-a-node:reference:artifacts.md
│ │ │ │ │ ├── developer:docs:run-a-node:reference:config.md
│ │ │ │ │ ├── developer:docs:run-a-node:reference:relay.md
│ │ │ │ │ ├── developer:docs:run-a-node:reference:telemetry-config.md
│ │ │ │ │ ├── developer:docs:run-a-node:setup:indexer.md
│ │ │ │ │ ├── developer:docs:run-a-node:setup:install.md
│ │ │ │ │ ├── developer:docs:run-a-node:setup:node-troubleshooting.md
│ │ │ │ │ ├── developer:docs:run-a-node:setup:types.md
│ │ │ │ │ ├── developer:docs:sdks:go:index.md
│ │ │ │ │ ├── developer:docs:sdks:index.md
│ │ │ │ │ ├── developer:docs:sdks:java:index.md
│ │ │ │ │ ├── developer:docs:sdks:javascript:index.md
│ │ │ │ │ ├── developer:docs:sdks:python:index.md
│ │ │ │ │ ├── developer:python:code:example:accounts.md
│ │ │ │ │ ├── developer:python:code:example:arc4_types.md
│ │ │ │ │ ├── developer:python:code:example:assets.md
│ │ │ │ │ ├── developer:python:code:example:box_storage.md
│ │ │ │ │ ├── developer:python:code:example:control_flow.md
│ │ │ │ │ ├── developer:python:code:example:crypto:merkle_tree.md
│ │ │ │ │ ├── developer:python:code:example:defi:amm.md
│ │ │ │ │ ├── developer:python:code:example:defi:auction.md
│ │ │ │ │ ├── developer:python:code:example:defi:htlc_logicsig.md
│ │ │ │ │ ├── developer:python:code:example:defi:marketplace.md
│ │ │ │ │ ├── developer:python:code:example:events:arc28_events.md
│ │ │ │ │ ├── developer:python:code:example:global_storage.md
│ │ │ │ │ ├── developer:python:code:example:governance:simple_voting.md
│ │ │ │ │ ├── developer:python:code:example:hello_world.md
│ │ │ │ │ ├── developer:python:code:example:inner_transactions.md
│ │ │ │ │ ├── developer:python:code:example:local_storage.md
│ │ │ │ │ ├── developer:python:code:example:nft:proof_of_attendance.md
│ │ │ │ │ ├── developer:python:code:example:privacy:zk_whitelist.md
│ │ │ │ │ ├── developer:python:code:example:scratch_storage.md
│ │ │ │ │ ├── developer:python:code:example:self_payment.md
│ │ │ │ │ ├── developer:python:code:example:struct_in_box.md
│ │ │ │ │ ├── developer:python:code:example:subsidize_app_call.md
│ │ │ │ │ ├── developer:python:code:example:transactions.md
│ │ │ │ │ ├── developer:python:code:example:utility:calculator.md
│ │ │ │ │ ├── devportal-code-examples:projects:python-contract-examples:README.md
│ │ │ │ │ ├── devportal-code-examples:README.md
│ │ │ │ │ ├── docs:.walletconnect:index.md
│ │ │ │ │ ├── docs:.walletconnect:walletconnect-schema.md
│ │ │ │ │ ├── docs:README.md
│ │ │ │ │ ├── docs:scripts:example_tracker:example_list.md
│ │ │ │ │ ├── docs:scripts:README.md
│ │ │ │ │ ├── index.md
│ │ │ │ │ ├── liquid_auth_index.md
│ │ │ │ │ ├── liquid-auth:ARCHITECTURE.md
│ │ │ │ │ ├── liquid-auth:decisions:1-Service-Authentication.md
│ │ │ │ │ ├── liquid-auth:decisions:2-Bidirectional-Communication.md
│ │ │ │ │ ├── liquid-auth:decisions:3-Peer-to-Peer-Signaling.md
│ │ │ │ │ ├── liquid-auth:decisions:4-Fido-Extension.md
│ │ │ │ │ ├── liquid-auth:decisions:README.md
│ │ │ │ │ ├── liquid-auth:docs:architecture.md
│ │ │ │ │ ├── liquid-auth:docs:clients:android:provider-service:authenticate.md
│ │ │ │ │ ├── liquid-auth:docs:clients:android:provider-service:register.md
│ │ │ │ │ ├── liquid-auth:docs:clients:browser:authentication.md
│ │ │ │ │ ├── liquid-auth:docs:clients:browser:example.md
│ │ │ │ │ ├── liquid-auth:docs:introduction.md
│ │ │ │ │ ├── liquid-auth:docs:README.md
│ │ │ │ │ ├── liquid-auth:docs:server:environment-variables.md
│ │ │ │ │ ├── liquid-auth:docs:server:integrations.md
│ │ │ │ │ ├── liquid-auth:docs:server:introduction.md
│ │ │ │ │ ├── liquid-auth:docs:server:running-locally.md
│ │ │ │ │ ├── liquid-auth:README.md
│ │ │ │ │ ├── liquid-auth:SEQUENCE.md
│ │ │ │ │ ├── liquid-auth:services:liquid-auth-api-js:src:assertion:assertion.controller.post.request.md
│ │ │ │ │ ├── liquid-auth:services:liquid-auth-api-js:src:assertion:assertion.controller.post.response.md
│ │ │ │ │ ├── liquid-auth:services:liquid-auth-api-js:src:attestation:attestation.controller.post.request.md
│ │ │ │ │ ├── liquid-auth:services:liquid-auth-api-js:src:auth:auth.controller.get.user.md
│ │ │ │ │ ├── liquid-auth:sites:express-dapp:README.md
│ │ │ │ │ ├── liquid-auth:VISION.md
│ │ │ │ │ ├── puya_index.md
│ │ │ │ │ ├── puya:docs:algopy_testing:index.md
│ │ │ │ │ ├── puya:docs:api-algopy.arc4.md
│ │ │ │ │ ├── puya:docs:api-algopy.gtxn.md
│ │ │ │ │ ├── puya:docs:api-algopy.itxn.md
│ │ │ │ │ ├── puya:docs:api-algopy.md
│ │ │ │ │ ├── puya:docs:api-algopy.op.md
│ │ │ │ │ ├── puya:docs:api.md
│ │ │ │ │ ├── puya:docs:compiler.md
│ │ │ │ │ ├── puya:docs:index.md
│ │ │ │ │ ├── puya:docs:language-guide.md
│ │ │ │ │ ├── puya:docs:lg-arc28.md
│ │ │ │ │ ├── puya:docs:lg-arc4.md
│ │ │ │ │ ├── puya:docs:lg-builtins.md
│ │ │ │ │ ├── puya:docs:lg-calling-apps.md
│ │ │ │ │ ├── puya:docs:lg-compile.md
│ │ │ │ │ ├── puya:docs:lg-control.md
│ │ │ │ │ ├── puya:docs:lg-errors.md
│ │ │ │ │ ├── puya:docs:lg-logs.md
│ │ │ │ │ ├── puya:docs:lg-modules.md
│ │ │ │ │ ├── puya:docs:lg-opcode-budget.md
│ │ │ │ │ ├── puya:docs:lg-ops.md
│ │ │ │ │ ├── puya:docs:lg-storage.md
│ │ │ │ │ ├── puya:docs:lg-structure.md
│ │ │ │ │ ├── puya:docs:lg-transactions.md
│ │ │ │ │ ├── puya:docs:lg-types.md
│ │ │ │ │ ├── puya:docs:lg-unsupported-python-features.md
│ │ │ │ │ ├── puya:docs:principles.md
│ │ │ │ │ ├── puya:examples:auction:README.md
│ │ │ │ │ ├── puya:python:testing:docs:algopy.md
│ │ │ │ │ ├── puya:python:testing:docs:api.md
│ │ │ │ │ ├── puya:python:testing:docs:coverage.md
│ │ │ │ │ ├── puya:python:testing:docs:examples.md
│ │ │ │ │ ├── puya:python:testing:docs:faq.md
│ │ │ │ │ ├── puya:python:testing:docs:index.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:arc4-types.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:avm-types.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:concepts.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:contract-testing.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:index.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:opcodes.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:signature-testing.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:state-management.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:subroutines.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:transactions.md
│ │ │ │ │ ├── puya:python:testing:examples:README.md
│ │ │ │ │ ├── puya:python:testing:README.md
│ │ │ │ │ ├── puya:README.md
│ │ │ │ │ ├── puya:src:puya:ARCHITECTURE.md
│ │ │ │ │ ├── puya:src:puyapy:_typeshed:README.md
│ │ │ │ │ ├── puya:src:puyapy:_vendor:mypy:typeshed:stdlib:_typeshed:README.md
│ │ │ │ │ ├── puya:src:puyapy:awst_build:README.md
│ │ │ │ │ ├── puya:stubs:README.md
│ │ │ │ │ ├── puya:tests:test_expected_output:README.md
│ │ │ │ │ ├── puya:typescript:docs:architecture-decisions:2024-05-21_primitive-bytes-and-strings.md
│ │ │ │ │ ├── puya:typescript:docs:architecture-decisions:2024-05-21_primitive-integer-types.md
│ │ │ │ │ ├── puya:typescript:docs:README.md
│ │ │ │ │ ├── puya:typescript:packages:algo-ts:readme.md
│ │ │ │ │ ├── puya:typescript:README.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIAddressType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIArrayDynamicType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIArrayStaticType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIBoolType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIByteType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIContract.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIInterface.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIMethod.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIStringType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABITupleType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIUfixedType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIUintType.md
│ │ │ │ │ ├── SDKs:javascript:classes:Algodv2.md
│ │ │ │ │ ├── SDKs:javascript:classes:AtomicTransactionComposer.md
│ │ │ │ │ ├── SDKs:javascript:classes:DryrunResult.md
│ │ │ │ │ ├── SDKs:javascript:classes:Indexer.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.Account.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AccountParticipation.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AccountResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AccountsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AccountStateDelta.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.Application.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationLocalState.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationLocalStatesResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationLogData.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationLogsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationParams.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationStateSchema.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.Asset.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AssetBalancesResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AssetHolding.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AssetHoldingsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AssetParams.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AssetResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AssetsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.Block.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.BlockRewards.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.BlockUpgradeState.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.BlockUpgradeVote.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.Box.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.BoxDescriptor.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.BoxesResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ErrorResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.EvalDelta.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.EvalDeltaKeyValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.HashFactory.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.HealthCheck.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.IndexerStateProofMessage.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.MerkleArrayProof.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.MiniAssetHolding.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ParticipationUpdates.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofFields.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofParticipant.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofReveal.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofSignature.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofSigSlot.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofTracking.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofVerifier.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateSchema.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TealKeyValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TealValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.Transaction.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionApplication.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionAssetConfig.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionAssetFreeze.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionAssetTransfer.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionKeyreg.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionPayment.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionSignature.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionSignatureLogicsig.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionSignatureMultisig.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionSignatureMultisigSubsignature.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionStateProof.md
│ │ │ │ │ ├── SDKs:javascript:classes:Kmd.md
│ │ │ │ │ ├── SDKs:javascript:classes:LogicSig.md
│ │ │ │ │ ├── SDKs:javascript:classes:LogicSigAccount.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.Account.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AccountApplicationResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AccountAssetHolding.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AccountAssetResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AccountAssetsInformationResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AccountParticipation.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AccountStateDelta.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AppCallLogs.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.Application.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationInitialStates.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationKVStorage.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationLocalReference.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationLocalState.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationParams.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationStateOperation.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationStateSchema.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.Asset.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AssetHolding.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AssetHoldingReference.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AssetParams.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AvmKeyValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AvmValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BlockHashResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BlockLogsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BlockResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BlockTxidsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.Box.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BoxDescriptor.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BoxesResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BoxReference.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BuildVersion.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.CompileResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.DisassembleResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.DryrunRequest.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.DryrunResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.DryrunSource.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.DryrunState.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.DryrunTxnResult.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ErrorResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.EvalDelta.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.EvalDeltaKeyValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.GetBlockTimeStampOffsetResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.GetSyncRoundResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.KvDelta.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.LedgerStateDeltaForTransactionGroup.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.LightBlockHeaderProof.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.NodeStatusResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.PendingTransactionResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.PendingTransactionsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.PostTransactionsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ScratchChange.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateInitialStates.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateRequest.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateRequestTransactionGroup.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateTraceConfig.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateTransactionGroupResult.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateTransactionResult.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateUnnamedResourcesAccessed.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulationEvalOverrides.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulationOpcodeTraceUnit.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulationTransactionExecTrace.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.StateProof.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.StateProofMessage.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SupplyResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.TealKeyValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.TealValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.TransactionGroupLedgerStateDeltasForRoundResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.TransactionParametersResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.TransactionProofResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.Version.md
│ │ │ │ │ ├── SDKs:javascript:classes:SourceMap.md
│ │ │ │ │ ├── SDKs:javascript:classes:Transaction.md
│ │ │ │ │ ├── SDKs:javascript:enums:ABIReferenceType.md
│ │ │ │ │ ├── SDKs:javascript:enums:ABITransactionType.md
│ │ │ │ │ ├── SDKs:javascript:enums:AtomicTransactionComposerStatus.md
│ │ │ │ │ ├── SDKs:javascript:enums:IntDecoding.md
│ │ │ │ │ ├── SDKs:javascript:enums:OnApplicationComplete.md
│ │ │ │ │ ├── SDKs:javascript:enums:TransactionType.md
│ │ │ │ │ ├── SDKs:javascript:examples:README.md
│ │ │ │ │ ├── SDKs:javascript:FAQ.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIContractNetworkInfo.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIContractNetworks.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIContractParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIInterfaceParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIMethodArgParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIMethodParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIMethodReturnParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIResult.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:Account.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:Address.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:AlgodTokenHeader.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:BaseHTTPClient.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:BaseHTTPClientError.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:BaseHTTPClientResponse.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:BoxReference.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:CustomTokenHeader.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedAssetParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedBoxReference.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedGlobalStateSchema.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedLocalStateSchema.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedLogicSig.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedLogicSigAccount.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedMultisig.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedSignedTransaction.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedSubsig.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedTransaction.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:IndexerTokenHeader.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:KMDTokenHeader.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:MultisigMetadata.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:SignedTransaction.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:SuggestedParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:TransactionParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:TransactionWithSigner.md
│ │ │ │ │ ├── SDKs:javascript:modules:indexerModels.md
│ │ │ │ │ ├── SDKs:javascript:modules:modelsv2.md
│ │ │ │ │ ├── SDKs:javascript:modules.md
│ │ │ │ │ ├── SDKs:javascript:README.md
│ │ │ │ │ ├── SDKs:python:algosdk:v2client:harness:README.md
│ │ │ │ │ ├── SDKs:python:examples:README.md
│ │ │ │ │ ├── SDKs:python:README.md
│ │ │ │ │ ├── tealscript:examples_amm_README.md
│ │ │ │ │ ├── tealscript:examples_auction_README.md
│ │ │ │ │ ├── tealscript:examples_big_box_README.md
│ │ │ │ │ ├── tealscript:examples_itxns_README.md
│ │ │ │ │ ├── tealscript:examples_lsig_with_app_README.md
│ │ │ │ │ ├── tealscript:examples_reti_README.md
│ │ │ │ │ ├── tealscript:FEATURES.md
│ │ │ │ │ ├── tealscript:guides_atomic_txn.md
│ │ │ │ │ ├── tealscript:guides_features.md
│ │ │ │ │ ├── tealscript:guides_getting_started.md
│ │ │ │ │ ├── tealscript:guides_inner_transactions.md
│ │ │ │ │ ├── tealscript:guides_lifecycle.md
│ │ │ │ │ ├── tealscript:guides_math.md
│ │ │ │ │ ├── tealscript:guides_methods.md
│ │ │ │ │ ├── tealscript:guides_multiple_contracts.md
│ │ │ │ │ ├── tealscript:guides_pyteal.md
│ │ │ │ │ ├── tealscript:guides_storage.md
│ │ │ │ │ ├── tealscript:guides_Supported Types_arrays.md
│ │ │ │ │ ├── tealscript:guides_Supported Types_numbers.md
│ │ │ │ │ ├── TEALScript:README.md
│ │ │ │ │ ├── tealscript:tests_test_package_README.md
│ │ │ │ │ ├── tealscript:tutorials_Hello World_0001-intro.md
│ │ │ │ │ ├── tealscript:tutorials_Hello World_0002-init.md
│ │ │ │ │ ├── tealscript:tutorials_Hello World_0003-contract.md
│ │ │ │ │ ├── tealscript:tutorials_Hello World_0004-artifacts.md
│ │ │ │ │ ├── tealscript:tutorials_Hello World_0005-hello.md
│ │ │ │ │ └── tealscript:tutorials_Hello World_0006-test.md
│ │ │ │ └── taxonomy-categories
│ │ │ │ ├── algokit-utils.json
│ │ │ │ ├── algokit.json
│ │ │ │ ├── arcs.json
│ │ │ │ ├── clis.json
│ │ │ │ ├── details.json
│ │ │ │ ├── developers.json
│ │ │ │ ├── liquid-auth.json
│ │ │ │ ├── nodes.json
│ │ │ │ ├── puya.json
│ │ │ │ ├── python.json
│ │ │ │ ├── sdks.json
│ │ │ │ └── tealscript.json
│ │ │ └── wallet
│ │ │ └── index.ts
│ │ ├── tools
│ │ │ ├── accountManager.ts
│ │ │ ├── algodManager.ts
│ │ │ ├── apiManager
│ │ │ │ ├── algod
│ │ │ │ │ ├── account.ts
│ │ │ │ │ ├── application.ts
│ │ │ │ │ ├── asset.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── transaction.ts
│ │ │ │ ├── example
│ │ │ │ │ ├── get-balance.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── indexer
│ │ │ │ │ ├── account.ts
│ │ │ │ │ ├── application.ts
│ │ │ │ │ ├── asset.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── transaction.ts
│ │ │ │ ├── nfd
│ │ │ │ │ └── index.ts
│ │ │ │ ├── tinyman
│ │ │ │ │ ├── analytics.ts
│ │ │ │ │ ├── bootstrap.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── liquidity.ts
│ │ │ │ │ ├── opt_in.ts
│ │ │ │ │ ├── pool.ts
│ │ │ │ │ ├── remove_liquidity.ts
│ │ │ │ │ └── swap.ts
│ │ │ │ ├── ultrade
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── market.ts
│ │ │ │ │ ├── system.ts
│ │ │ │ │ └── wallet.ts
│ │ │ │ └── vestige
│ │ │ │ ├── assets.ts
│ │ │ │ ├── balances.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── networks.ts
│ │ │ │ ├── notes.ts
│ │ │ │ ├── pools.ts
│ │ │ │ ├── protocols.ts
│ │ │ │ ├── swaps.ts
│ │ │ │ └── vaults.ts
│ │ │ ├── arc26Manager.ts
│ │ │ ├── index.ts
│ │ │ ├── knowledgeManager.ts
│ │ │ ├── transactionManager
│ │ │ │ ├── accountTransactions.ts
│ │ │ │ ├── appTransactions
│ │ │ │ │ ├── callTxn.ts
│ │ │ │ │ ├── clearTxn.ts
│ │ │ │ │ ├── closeOutTxn.ts
│ │ │ │ │ ├── createTxn.ts
│ │ │ │ │ ├── deleteTxn.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── optInTxn.ts
│ │ │ │ │ ├── test
│ │ │ │ │ │ ├── counter_approval.teal
│ │ │ │ │ │ ├── counter_clear.teal
│ │ │ │ │ │ ├── storage_test_approval_v2.teal
│ │ │ │ │ │ ├── storage_test_approval.teal
│ │ │ │ │ │ └── storage_test_clear.teal
│ │ │ │ │ ├── types.ts
│ │ │ │ │ └── updateTxn.ts
│ │ │ │ ├── assetTransactions.ts
│ │ │ │ ├── generalTransaction.ts
│ │ │ │ └── index.ts
│ │ │ └── utilityManager.ts
│ │ ├── types.ts
│ │ └── utils
│ │ └── responseProcessor.ts
│ ├── tests
│ │ ├── resources
│ │ │ ├── algod
│ │ │ │ ├── account.test.ts
│ │ │ │ ├── application.test.ts
│ │ │ │ ├── asset.test.ts
│ │ │ │ └── transaction.test.ts
│ │ │ └── indexer
│ │ │ ├── account.test.ts
│ │ │ ├── application.test.ts
│ │ │ ├── asset.test.ts
│ │ │ └── transaction.test.ts
│ │ └── tools
│ │ ├── accountManager.test.ts
│ │ ├── algodManager.test.ts
│ │ ├── apiManager
│ │ │ └── example
│ │ │ └── get-balance.test.ts
│ │ ├── transactionManager
│ │ │ ├── accountTransactionManager.test.ts
│ │ │ ├── appTransactionManager.test.ts
│ │ │ ├── assetTransactionManager.test.ts
│ │ │ ├── generalTransactionManager.test.ts
│ │ │ └── transactionManager.test.ts
│ │ └── utilityManager.test.ts
│ └── tsconfig.json
├── README.md
├── rename_files.sh
└── tsconfig.json
```
# Files
--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/developer:docs:run-a-node:reference:config.md:
--------------------------------------------------------------------------------
```markdown
1 | title: Node configuration settings
2 | Nodes can be configured with different options. These options will determine some of the capabilities of the node and whether it functions as a relay node or a non-relay node. This involves setting parameters in the configuration file for either the `algod` or `kmd` process.
3 |
4 | The configuration file (`config.json`) for the `algod` process is located in the node's `data` directory.
5 | If it does not exist, it needs to be created.
6 | A full example is provided as `config.json.example`.
7 | However, it is strongly recommended to only specify the parameters with non-default values in a custom `config.json` file, otherwise, when the algod software is updated, you may be using older non-recommended values for some of the parameters.
8 |
9 | Concretely, the `config.json` for an archival node should usually just be:
10 | ```json
11 | {
12 | "Archival": true
13 | }
14 | ```
15 |
16 | The configuration file (`kmd_config.json`) for `kmd` is located in the nodes `data/kmd-version` (rename `kmd_config.json.example') directory.
17 |
18 | !!! info
19 | Archival nodes retain a full copy of the ledger (blockchain). Non-Archival nodes will delete old blocks and only retain what's needed to properly validate blockchain messages (currently the last 1000 blocks). Archival nodes can be used to populate indexer data. See chart below for more details.
20 |
21 |
22 | See [Node Types](../../run-a-node/setup/types.md) for more information.
23 |
24 | !!! info
25 | All changes require the node to be restarted to take effect.
26 |
27 | !!! warning
28 | Changing some parameter values can have drastic negative impact on performance. In particular, never set `IsIndexerActive` to `true`. This activates the very slow deprecated V1 indexer. If indexer is required, use the [V2 indexer](../../../get-details/indexer).
29 |
30 | # algod Configuration Settings
31 | The `algod` process configuration parameters are shown in the table below.
32 |
33 | | Property| Description | Default Value |
34 | |------|------|------|
35 | | Version | Version tracks the current version of the defaults so we can migrate old -> new<br>This is specifically important whenever we decide to change the default value<br>for an existing parameter. This field tag must be updated any time we add a new version. | 35 |
36 | | Archival | Archival nodes retain a full copy of the block history. Non-Archival nodes will delete old blocks and only retain what's need to properly validate blockchain messages (the precise number of recent blocks depends on the consensus parameters. Currently the last 1321 blocks are required). This means that non-Archival nodes require significantly less storage than Archival nodes. If setting this to true for the first time, the existing ledger may need to be deleted to get the historical values stored as the setting only affects current blocks forward. To do this, shutdown the node and delete all .sqlite files within the data/testnet-version directory, except the crash.sqlite file. Restart the node and wait for the node to sync. | false |
37 | | GossipFanout | GossipFanout sets the maximum number of peers the node will connect to with outgoing connections. If the list of peers is less than this setting, fewer connections will be made. The node will not connect to the same peer multiple times (with outgoing connections). | 4 |
38 | | NetAddress | NetAddress is the address and/or port on which a node listens for incoming connections, or blank to ignore incoming connections. Specify an IP and port or just a port. For example, 127.0.0.1:0 will listen on a random port on the localhost. | |
39 | | ReconnectTime | ReconnectTime is deprecated and unused. | 60000000000 |
40 | | PublicAddress | PublicAddress is the public address to connect to that is advertised to other nodes.<br>For MainNet relays, make sure this entry includes the full SRV host name<br>plus the publicly-accessible port number.<br>A valid entry will avoid "self-gossip" and is used for identity exchange<br>to de-duplicate redundant connections | |
41 | | MaxConnectionsPerIP | MaxConnectionsPerIP is the maximum number of connections allowed per IP address. | 8 |
42 | | PeerPingPeriodSeconds | PeerPingPeriodSeconds is deprecated and unused. | 0 |
43 | | TLSCertFile | TLSCertFile is the certificate file used for the websocket network if povided. | |
44 | | TLSKeyFile | TLSKeyFile is the key file used for the websocket network if povided. | |
45 | | BaseLoggerDebugLevel | BaseLoggerDebugLevel specifies the logging level for algod (node.log). The levels range from 0 (critical error / silent) to 5 (debug / verbose). The default value is 4 (‘Info’ - fairly verbose). | 4 |
46 | | CadaverSizeTarget | CadaverSizeTarget specifies the maximum size of the agreement.cfv file in bytes. Once full the file will be renamed to agreement.archive.log and a new agreement.cdv will be created. | 0 |
47 | | CadaverDirectory | if this is not set, MakeService will attempt to use ColdDataDir instead | |
48 | | HotDataDir | HotDataDir is an optional directory to store data that is frequently accessed by the node.<br>For isolation, the node will create a subdirectory in this location, named by the genesis-id of the network.<br>If not specified, the node will use the runtime supplied datadir to store this data.<br>Individual resources may have their own override specified, which would override this setting for that resource.<br>Setting HotDataDir to a dedicated high performance disk allows for basic disc tuning. | |
49 | | ColdDataDir | ColdDataDir is an optional directory to store data that is infrequently accessed by the node.<br>For isolation, the node will create a subdirectory in this location, named by the genesis-id of the network.<br>If not specified, the node will use the runtime supplied datadir.<br>Individual resources may have their own override specified, which would override this setting for that resource.<br>Setting ColdDataDir to a less critical or cheaper disk allows for basic disc tuning. | |
50 | | TrackerDBDir | TrackerDbDir is an optional directory to store the tracker database.<br>For isolation, the node will create a subdirectory in this location, named by the genesis-id of the network.<br>If not specified, the node will use the HotDataDir. | |
51 | | BlockDBDir | BlockDBDir is an optional directory to store the block database.<br>For isolation, the node will create a subdirectory in this location, named by the genesis-id of the network.<br>If not specified, the node will use the ColdDataDir. | |
52 | | CatchpointDir | CatchpointDir is an optional directory to store catchpoint files,<br>except for the in-progress temp file, which will use the HotDataDir and is not separately configurable.<br>For isolation, the node will create a subdirectory in this location, named by the genesis-id of the network.<br>If not specified, the node will use the ColdDataDir. | |
53 | | StateproofDir | StateproofDir is an optional directory to persist state about observed and issued state proof messages.<br>For isolation, the node will create a subdirectory in this location, named by the genesis-id of the network.<br>If not specified, the node will use the HotDataDir. | |
54 | | CrashDBDir | CrashDBDir is an optional directory to persist agreement's consensus participation state.<br>For isolation, the node will create a subdirectory in this location, named by the genesis-id of the network.<br>If not specified, the node will use the HotDataDir | |
55 | | LogFileDir | LogFileDir is an optional directory to store the log, node.log<br>If not specified, the node will use the HotDataDir.<br>The -o command line option can be used to override this output location. | |
56 | | LogArchiveDir | LogArchiveDir is an optional directory to store the log archive.<br>If not specified, the node will use the ColdDataDir. | |
57 | | IncomingConnectionsLimit | IncomingConnectionsLimit specifies the max number of incoming connections<br>for the gossip protocol configured in NetAddress. 0 means no connections allowed. Must be non-negative.<br>Estimating 1.5MB per incoming connection, 1.5MB*2400 = 3.6GB | 2400 |
58 | | P2PHybridIncomingConnectionsLimit | P2PHybridIncomingConnectionsLimit is used as IncomingConnectionsLimit for P2P connections in hybrid mode.<br>For pure P2P nodes IncomingConnectionsLimit is used. | 1200 |
59 | | BroadcastConnectionsLimit | BroadcastConnectionsLimit specifies the number of connections that<br>will receive broadcast (gossip) messages from this node. If the<br>node has more connections than this number, it will send broadcasts<br>to the top connections by priority (outgoing connections first, then<br>by money held by peers based on their participation key). 0 means<br>no outgoing messages (not even transaction broadcasting to outgoing<br>peers). -1 means unbounded (default). | -1 |
60 | | AnnounceParticipationKey | AnnounceParticipationKey specifies that this node should announce its<br>participation key (with the largest stake) to its gossip peers. This<br>allows peers to prioritize our connection, if necessary, in case of a<br>DoS attack. Disabling this means that the peers will not have any<br>additional information to allow them to prioritize our connection. | true |
61 | | PriorityPeers | PriorityPeers specifies peer IP addresses that should always get<br>outgoing broadcast messages from this node. | |
62 | | ReservedFDs | ReservedFDs is used to make sure the algod process does not run out of file descriptors (FDs). Algod ensures<br>that RLIMIT_NOFILE >= IncomingConnectionsLimit + RestConnectionsHardLimit +<br>ReservedFDs. ReservedFDs are meant to leave room for short-lived FDs like<br>DNS queries, SQLite files, etc. This parameter shouldn't be changed.<br>If RLIMIT_NOFILE < IncomingConnectionsLimit + RestConnectionsHardLimit + ReservedFDs<br>then either RestConnectionsHardLimit or IncomingConnectionsLimit decreased. | 256 |
63 | | EndpointAddress | EndpointAddress configures the address the node listens to for REST API calls. Specify an IP and port or just port. For example, 127.0.0.1:0 will listen on a random port on the localhost (preferring 8080). | 127.0.0.1 |
64 | | EnablePrivateNetworkAccessHeader | Respond to Private Network Access preflight requests sent to the node. Useful when a public website is trying to access a node that's hosted on a local network. | false |
65 | | RestReadTimeoutSeconds | RestReadTimeoutSeconds is passed to the API servers rest http.Server implementation. | 15 |
66 | | RestWriteTimeoutSeconds | RestWriteTimeoutSeconds is passed to the API servers rest http.Server implementation. | 120 |
67 | | DNSBootstrapID | DNSBootstrapID specifies the names of a set of DNS SRV records that identify the set of nodes available to connect to.<br>This is applicable to both relay and archival nodes - they are assumed to use the same DNSBootstrapID today.<br>When resolving the bootstrap ID <network> will be replaced by the genesis block's network name. This string uses a URL<br>parsing library and supports optional backup and dedup parameters. 'backup' is used to provide a second DNS entry to use<br>in case the primary is unavailable. dedup is intended to be used to deduplicate SRV records returned from the primary<br>and backup DNS address. If the <name> macro is used in the dedup mask, it must be at the beginning of the expression.<br>This is not typically something a user would configure. For more information see config/dnsbootstrap.go. | <network>.algorand.network?backup=<network>.algorand.net&dedup=<name>.algorand-<network>.(network|net) |
68 | | LogSizeLimit | LogSizeLimit is the log file size limit in bytes. When set to 0 logs will be written to stdout. | 1073741824 |
69 | | LogArchiveName | LogArchiveName text/template for creating log archive filename.<br>Available template vars:<br>Time at start of log: {{.Year}} {{.Month}} {{.Day}} {{.Hour}} {{.Minute}} {{.Second}}<br>Time at end of log: {{.EndYear}} {{.EndMonth}} {{.EndDay}} {{.EndHour}} {{.EndMinute}} {{.EndSecond}}<br><br>If the filename ends with .gz or .bz2 it will be compressed.<br><br>default: "node.archive.log" (no rotation, clobbers previous archive) | node.archive.log |
70 | | LogArchiveMaxAge | LogArchiveMaxAge will be parsed by time.ParseDuration().<br>Valid units are 's' seconds, 'm' minutes, 'h' hours | |
71 | | CatchupFailurePeerRefreshRate | CatchupFailurePeerRefreshRate is the maximum number of consecutive attempts to catchup after which we replace the peers we're connected to. | 10 |
72 | | NodeExporterListenAddress | NodeExporterListenAddress is used to set the specific address for publishing metrics; the Prometheus server connects to this incoming port to retrieve metrics. | |
73 | | EnableMetricReporting | EnableMetricReporting determines if the metrics service for a node is to be enabled. This setting controls metrics being collected from this specific instance of algod. If any instance has metrics enabled, machine-wide metrics are also collected. | false |
74 | | EnableTopAccountsReporting | EnableTopAccountsReporting enable top accounts reporting flag. Deprecated, do not use. | false |
75 | | EnableAgreementReporting | EnableAgreementReporting controls the agreement reporting flag. Currently only prints additional period events. | false |
76 | | EnableAgreementTimeMetrics | EnableAgreementTimeMetrics controls the agreement timing metrics flag. | false |
77 | | NodeExporterPath | NodeExporterPath is the path to the node_exporter binary. | ./node_exporter |
78 | | FallbackDNSResolverAddress | FallbackDNSResolverAddress defines the fallback DNS resolver address that would be used if the system resolver would fail to retrieve SRV records. | |
79 | | TxPoolExponentialIncreaseFactor | TxPoolExponentialIncreaseFactor exponential increase factor of transaction pool's fee threshold, should always be 2 in production. | 2 |
80 | | SuggestedFeeBlockHistory | SuggestedFeeBlockHistory is deprecated and unused. | 3 |
81 | | TxBacklogServiceRateWindowSeconds | TxBacklogServiceRateWindowSeconds is the window size used to determine the service rate of the txBacklog | 10 |
82 | | TxBacklogReservedCapacityPerPeer | TxBacklogReservedCapacityPerPeer determines how much dedicated serving capacity the TxBacklog gives each peer | 20 |
83 | | TxBacklogAppTxRateLimiterMaxSize | TxBacklogAppTxRateLimiterMaxSize denotes a max size for the tx rate limiter<br>calculated as "a thousand apps on a network of thousand of peers" | 1048576 |
84 | | TxBacklogAppTxPerSecondRate | TxBacklogAppTxPerSecondRate determines a target app per second rate for the app tx rate limiter | 100 |
85 | | TxBacklogRateLimitingCongestionPct | TxBacklogRateLimitingCongestionRatio determines the backlog filling threshold percentage at which the app limiter kicks in<br>or the tx backlog rate limiter kicks off. | 50 |
86 | | EnableTxBacklogAppRateLimiting | EnableTxBacklogAppRateLimiting controls if an app rate limiter should be attached to the tx backlog enqueue process | true |
87 | | TxBacklogAppRateLimitingCountERLDrops | TxBacklogAppRateLimitingCountERLDrops feeds messages dropped by the ERL congestion manager & rate limiter (enabled by<br>EnableTxBacklogRateLimiting) to the app rate limiter (enabled by EnableTxBacklogAppRateLimiting), so that all TX messages<br>are counted. This provides more accurate rate limiting for the app rate limiter, at the potential expense of additional<br>deserialization overhead. | false |
88 | | EnableTxBacklogRateLimiting | EnableTxBacklogRateLimiting controls if a rate limiter and congestion manager should be attached to the tx backlog enqueue process<br>if enabled, the over-all TXBacklog Size will be larger by MAX_PEERS*TxBacklogReservedCapacityPerPeer | true |
89 | | TxBacklogSize | TxBacklogSize is the queue size used for receiving transactions. default of 26000 to approximate 1 block of transactions<br>if EnableTxBacklogRateLimiting enabled, the over-all size will be larger by MAX_PEERS*TxBacklogReservedCapacityPerPeer | 26000 |
90 | | TxPoolSize | TxPoolSize is the number of transactions in the transaction pool buffer. | 75000 |
91 | | TxSyncTimeoutSeconds | number of seconds allowed for syncing transactions | 30 |
92 | | TxSyncIntervalSeconds | TxSyncIntervalSeconds number of seconds between transaction synchronizations. | 60 |
93 | | IncomingMessageFilterBucketCount | IncomingMessageFilterBucketCount is the number of incoming message hash buckets. | 5 |
94 | | IncomingMessageFilterBucketSize | IncomingMessageFilterBucketSize is the size of each incoming message hash bucket. | 512 |
95 | | OutgoingMessageFilterBucketCount | OutgoingMessageFilterBucketCount is the number of outgoing message hash buckets. | 3 |
96 | | OutgoingMessageFilterBucketSize | OutgoingMessageFilterBucketSize is the size of each outgoing message hash bucket. | 128 |
97 | | EnableOutgoingNetworkMessageFiltering | EnableOutgoingNetworkMessageFiltering enable the filtering of outgoing messages | true |
98 | | EnableIncomingMessageFilter | EnableIncomingMessageFilter enable the filtering of incoming messages. | false |
99 | | DeadlockDetection | DeadlockDetection controls enabling or disabling deadlock detection.<br>negative (-1) to disable, positive (1) to enable, 0 for default. | 0 |
100 | | DeadlockDetectionThreshold | DeadlockDetectionThreshold is the threshold used for deadlock detection, in seconds. | 30 |
101 | | RunHosted | RunHosted configures whether to run algod in Hosted mode (under algoh). Observed by `goal` for now. | false |
102 | | CatchupParallelBlocks | CatchupParallelBlocks is the maximum number of blocks that catchup will fetch in parallel.<br>If less than Protocol.SeedLookback, then Protocol.SeedLookback will be used as to limit the catchup.<br>Setting this variable to 0 would disable the catchup | 16 |
103 | | EnableAssembleStats | EnableAssembleStats specifies whether or not to emit the AssembleBlockMetrics telemetry event. | |
104 | | EnableProcessBlockStats | EnableProcessBlockStats specifies whether or not to emit the ProcessBlockMetrics telemetry event. | |
105 | | SuggestedFeeSlidingWindowSize | SuggestedFeeSlidingWindowSize is deprecated and unused. | 50 |
106 | | TxSyncServeResponseSize | TxSyncServeResponseSize the max size the sync server would return. | 1000000 |
107 | | UseXForwardedForAddressField | UseXForwardedForAddressField indicates whether or not the node should use the X-Forwarded-For HTTP Header when<br>determining the source of a connection. If used, it should be set to the string "X-Forwarded-For", unless the<br>proxy vendor provides another header field. In the case of CloudFlare proxy, the "CF-Connecting-IP" header<br>field can be used.<br>This setting does not support multiple X-Forwarded-For HTTP headers or multiple values in in the header and always uses the last value<br>from the last X-Forwarded-For HTTP header that corresponds to a single reverse proxy (even if it received the request from another reverse proxy or adversary node).<br><br>WARNING: By enabling this option, you are trusting peers to provide accurate forwarding addresses.<br>Bad actors can easily spoof these headers to circumvent this node's rate and connection limiting<br>logic. Do not enable this if your node is publicly reachable or used by untrusted parties. | |
108 | | ForceRelayMessages | ForceRelayMessages indicates whether the network library should relay messages even in the case that no NetAddress was specified. | false |
109 | | ConnectionsRateLimitingWindowSeconds | ConnectionsRateLimitingWindowSeconds is being used along with ConnectionsRateLimitingCount;<br>see ConnectionsRateLimitingCount description for further information. Providing a zero value<br>in this variable disables the connection rate limiting. | 1 |
110 | | ConnectionsRateLimitingCount | ConnectionsRateLimitingCount is being used along with ConnectionsRateLimitingWindowSeconds to determine if<br>a connection request should be accepted or not. The gossip network examines all the incoming requests in the past<br>ConnectionsRateLimitingWindowSeconds seconds that share the same origin. If the total count exceed the ConnectionsRateLimitingCount<br>value, the connection is refused. | 60 |
111 | | EnableRequestLogger | EnableRequestLogger enabled the logging of the incoming requests to the telemetry server. | false |
112 | | PeerConnectionsUpdateInterval | PeerConnectionsUpdateInterval defines the interval at which the peer connections information is sent to<br>telemetry (when enabled). Defined in seconds. | 3600 |
113 | | HeartbeatUpdateInterval | HeartbeatUpdateInterval defines the interval at which the heartbeat information is being sent to the<br>telemetry (when enabled). Defined in seconds. Minimum value is 60. | 600 |
114 | | EnableProfiler | EnableProfiler enables the go pprof endpoints, should be false if<br>the algod api will be exposed to untrusted individuals | false |
115 | | EnableRuntimeMetrics | EnableRuntimeMetrics exposes Go runtime metrics in /metrics and via node_exporter. | false |
116 | | EnableNetDevMetrics | EnableNetDevMetrics exposes network interface total bytes sent/received metrics in /metrics | false |
117 | | TelemetryToLog | TelemetryToLog configures whether to record messages to node.log that are normally only sent to remote event monitoring. | true |
118 | | DNSSecurityFlags | DNSSecurityFlags instructs algod validating DNS responses.<br>Possible fla values<br>0x00 - disabled<br>0x01 (dnssecSRV) - validate SRV response<br>0x02 (dnssecRelayAddr) - validate relays' names to addresses resolution<br>0x04 (dnssecTelemetryAddr) - validate telemetry and metrics names to addresses resolution<br>0x08 (dnssecTXT) - validate TXT response<br>... | 9 |
119 | | EnablePingHandler | EnablePingHandler controls whether the gossip node would respond to ping messages with a pong message. | true |
120 | | DisableOutgoingConnectionThrottling | DisableOutgoingConnectionThrottling disables the connection throttling of the network library, which<br>allow the network library to continuously disconnect relays based on their relative (and absolute) performance. | false |
121 | | NetworkProtocolVersion | NetworkProtocolVersion overrides network protocol version ( if present ) | |
122 | | CatchpointInterval | CatchpointInterval sets the interval at which catchpoint are being generated. Setting this to 0 disables the catchpoint from being generated.<br>See CatchpointTracking for more details. | 10000 |
123 | | CatchpointFileHistoryLength | CatchpointFileHistoryLength defines how many catchpoint files to store.<br>0 means don't store any, -1 mean unlimited and positive number suggest the maximum number of most recent catchpoint files to store. | 365 |
124 | | EnableGossipService | EnableGossipService enables the gossip network HTTP websockets endpoint. The functionality of this depends on NetAddress, which must also be provided.<br>This functionality is required for serving gossip traffic. | true |
125 | | EnableLedgerService | EnableLedgerService enables the ledger serving service. The functionality of this depends on NetAddress, which must also be provided.<br>This functionality is required for the catchpoint catchup. | false |
126 | | EnableBlockService | EnableBlockService controls whether to enables the block serving service. The functionality of this depends on NetAddress, which must also be provided.<br>This functionality is required for catchup. | false |
127 | | EnableGossipBlockService | EnableGossipBlockService enables the block serving service over the gossip network. The functionality of this depends on NetAddress, which must also be provided.<br>This functionality is required for the relays to perform catchup from nodes. | true |
128 | | CatchupHTTPBlockFetchTimeoutSec | CatchupHTTPBlockFetchTimeoutSec controls how long the http query for fetching a block from a relay would take before giving up and trying another relay. | 4 |
129 | | CatchupGossipBlockFetchTimeoutSec | CatchupGossipBlockFetchTimeoutSec controls how long the gossip query for fetching a block from a relay would take before giving up and trying another relay. | 4 |
130 | | CatchupLedgerDownloadRetryAttempts | CatchupLedgerDownloadRetryAttempts controls the number of attempt the ledger fetching would be attempted before giving up catching up to the provided catchpoint. | 50 |
131 | | CatchupBlockDownloadRetryAttempts | CatchupBlockDownloadRetryAttempts controls the number of attempts the block fetcher would make before giving up on a provided catchpoint. | 1000 |
132 | | EnableDeveloperAPI | EnableDeveloperAPI enables teal/compile and teal/dryrun API endpoints.<br>This functionality is disabled by default. | false |
133 | | OptimizeAccountsDatabaseOnStartup | OptimizeAccountsDatabaseOnStartup controls whether the accounts database would be optimized<br>on algod startup. | false |
134 | | CatchpointTracking | CatchpointTracking determines if catchpoints are going to be tracked. The value is interpreted as follows:<br>A value of -1 means "don't track catchpoints".<br>A value of 1 means "track catchpoints as long as CatchpointInterval > 0".<br>A value of 2 means "track catchpoints and always generate catchpoint files as long as CatchpointInterval > 0".<br>A value of 0 means automatic, which is the default value. In this mode, a non archival node would not track the catchpoints, and an archival node would track the catchpoints as long as CatchpointInterval > 0.<br>Other values of CatchpointTracking would behave as if the default value was provided. | 0 |
135 | | LedgerSynchronousMode | LedgerSynchronousMode defines the synchronous mode used by the ledger database. The supported options are:<br>0 - SQLite continues without syncing as soon as it has handed data off to the operating system.<br>1 - SQLite database engine will still sync at the most critical moments, but less often than in FULL mode.<br>2 - SQLite database engine will use the xSync method of the VFS to ensure that all content is safely written to the disk surface prior to continuing. On Mac OS, the data is additionally syncronized via fullfsync.<br>3 - In addition to what being done in 2, it provides additional durability if the commit is followed closely by a power loss.<br>for further information see the description of SynchronousMode in dbutil.go | 2 |
136 | | AccountsRebuildSynchronousMode | AccountsRebuildSynchronousMode defines the synchronous mode used by the ledger database while the account database is being rebuilt. This is not a typical operational use-case,<br>and is expected to happen only on either startup (after enabling the catchpoint interval, or on certain database upgrades) or during fast catchup. The values specified here<br>and their meanings are identical to the ones in LedgerSynchronousMode. | 1 |
137 | | MaxCatchpointDownloadDuration | MaxCatchpointDownloadDuration defines the maximum duration a client will be keeping the outgoing connection of a catchpoint download request open for processing before<br>shutting it down. Networks that have large catchpoint files, slow connection or slow storage could be a good reason to increase this value. Note that this is a client-side only<br>configuration value, and it's independent of the actual catchpoint file size. | 43200000000000 |
138 | | MinCatchpointFileDownloadBytesPerSecond | MinCatchpointFileDownloadBytesPerSecond defines the minimal download speed that would be considered to be "acceptable" by the catchpoint file fetcher, measured in bytes per seconds. If the<br>provided stream speed drops below this threshold, the connection would be recycled. Note that this field is evaluated per catchpoint "chunk" and not on it's own. If this field is zero,<br>the default of 20480 would be used. | 20480 |
139 | | NetworkMessageTraceServer | NetworkMessageTraceServer is a host:port address to report graph propagation trace info to. | |
140 | | VerifiedTranscationsCacheSize | VerifiedTranscationsCacheSize defines the number of transactions that the verified transactions cache would hold before cycling the cache storage in a round-robin fashion. | 150000 |
141 | | DisableLocalhostConnectionRateLimit | DisableLocalhostConnectionRateLimit controls whether the incoming connection rate limit would apply for<br>connections that are originating from the local machine. Setting this to "true", allow to create large<br>local-machine networks that won't trip the incoming connection limit observed by relays. | true |
142 | | BlockServiceCustomFallbackEndpoints | BlockServiceCustomFallbackEndpoints is a comma delimited list of endpoints which the block service uses to<br>redirect the http requests to in case it does not have the round. If empty, the block service will return<br>StatusNotFound (404) | |
143 | | CatchupBlockValidateMode | CatchupBlockValidateMode is a development and testing configuration used by the catchup service.<br>It can be used to omit certain validations to speed up the catchup process, or to apply extra validations which are redundant in normal operation.<br>This field is a bit-field with:<br>bit 0: (default 0) 0: verify the block certificate; 1: skip this validation<br>bit 1: (default 0) 0: verify payset committed hash in block header matches payset hash; 1: skip this validation<br>bit 2: (default 0) 0: don't verify the transaction signatures on the block are valid; 1: verify the transaction signatures on block<br>bit 3: (default 0) 0: don't verify that the hash of the recomputed payset matches the hash of the payset committed in the block header; 1: do perform the above verification<br>Note: not all permutations of the above bitset are currently functional. In particular, the ones that are functional are:<br>0 : default behavior.<br>3 : speed up catchup by skipping necessary validations<br>12 : perform all validation methods (normal and additional). These extra tests helps to verify the integrity of the compiled executable against<br> previously used executabled, and would not provide any additional security guarantees. | 0 |
144 | | EnableAccountUpdatesStats | EnableAccountUpdatesStats specifies whether or not to emit the AccountUpdates telemetry event. | false |
145 | | AccountUpdatesStatsInterval | AccountUpdatesStatsInterval is the time interval in nanoseconds between accountUpdates telemetry events. | 5000000000 |
146 | | ParticipationKeysRefreshInterval | ParticipationKeysRefreshInterval is the duration between two consecutive checks to see if new participation<br>keys have been placed on the genesis directory. Deprecated and unused. | 60000000000 |
147 | | DisableNetworking | DisableNetworking disables all the incoming and outgoing communication a node would perform. This is useful<br>when we have a single-node private network, where there are no other nodes that need to be communicated with.<br>Features like catchpoint catchup would be rendered completely non-operational, and many of the node inner<br>working would be completely dis-functional. | false |
148 | | ForceFetchTransactions | ForceFetchTransactions allows to explicitly configure a node to retrieve all the transactions<br>into it's transaction pool, even if those would not be required as the node doesn't<br>participate in consensus and is not used to relay transactions. | false |
149 | | EnableVerbosedTransactionSyncLogging | EnableVerbosedTransactionSyncLogging enables the transaction sync to write extensive<br>message exchange information to the log file. This option is disabled by default,<br>so that the log files would not grow too rapidly. | false |
150 | | TransactionSyncDataExchangeRate | TransactionSyncDataExchangeRate overrides the auto-calculated data exchange rate between each<br>two peers. The unit of the data exchange rate is in bytes per second. Setting the value to<br>zero implies allowing the transaction sync to dynamically calculate the value. | 0 |
151 | | TransactionSyncSignificantMessageThreshold | TransactionSyncSignificantMessageThreshold define the threshold used for a transaction sync<br>message before it can be used for calculating the data exchange rate. Setting this to zero<br>would use the default values. The threshold is defined in units of bytes. | 0 |
152 | | ProposalAssemblyTime | ProposalAssemblyTime is the max amount of time to spend on generating a proposal block. | 500000000 |
153 | | RestConnectionsSoftLimit | RestConnectionsSoftLimit is the maximum number of active requests the API server<br>When the number of http connections to the REST layer exceeds the soft limit,<br>we start returning http code 429 Too Many Requests. | 1024 |
154 | | RestConnectionsHardLimit | RestConnectionsHardLimit is the maximum number of active connections the API server will accept before closing requests with no response. | 2048 |
155 | | MaxAPIResourcesPerAccount | MaxAPIResourcesPerAccount sets the maximum total number of resources (created assets, created apps,<br>asset holdings, and application local state) per account that will be allowed in AccountInformation<br>REST API responses before returning a 400 Bad Request. Set zero for no limit. | 100000 |
156 | | AgreementIncomingVotesQueueLength | AgreementIncomingVotesQueueLength sets the size of the buffer holding incoming votes. | 20000 |
157 | | AgreementIncomingProposalsQueueLength | AgreementIncomingProposalsQueueLength sets the size of the buffer holding incoming proposals. | 50 |
158 | | AgreementIncomingBundlesQueueLength | AgreementIncomingBundlesQueueLength sets the size of the buffer holding incoming bundles. | 15 |
159 | | MaxAcctLookback | MaxAcctLookback sets the maximum lookback range for account states,<br>i.e. the ledger can answer account states questions for the range Latest-MaxAcctLookback...Latest | 4 |
160 | | MaxBlockHistoryLookback | BlockHistoryLookback sets the max lookback range for block information.<br>i.e. the block DB can return transaction IDs for questions for the range Latest-MaxBlockHistoryLookback...Latest | 0 |
161 | | EnableUsageLog | EnableUsageLog enables 10Hz log of CPU and RAM usage.<br>Also adds 'algod_ram_usage` (number of bytes in use) to /metrics | false |
162 | | MaxAPIBoxPerApplication | MaxAPIBoxPerApplication defines the maximum total number of boxes per application that will be returned<br>in GetApplicationBoxes REST API responses. | 100000 |
163 | | TxIncomingFilteringFlags | TxIncomingFilteringFlags instructs algod filtering incoming tx messages<br>Flag values:<br>0x00 - disabled<br>0x01 (txFilterRawMsg) - check for raw tx message duplicates<br>0x02 (txFilterCanonical) - check for canonical tx group duplicates | 1 |
164 | | EnableExperimentalAPI | EnableExperimentalAPI enables experimental API endpoint. Note that these endpoints have no<br>guarantees in terms of functionality or future support. | false |
165 | | DisableLedgerLRUCache | DisableLedgerLRUCache disables LRU caches in ledger.<br>Setting it to TRUE might result in significant performance degradation<br>and SHOULD NOT be used for other reasons than testing. | false |
166 | | EnableFollowMode | EnableFollowMode launches the node in "follower" mode. This turns off the agreement service,<br>and APIs related to broadcasting transactions, and enables APIs which can retrieve detailed information<br>from ledger caches and can control the ledger round. | false |
167 | | EnableTxnEvalTracer | EnableTxnEvalTracer turns on features in the BlockEvaluator which collect data on transactions, exposing them via algod APIs.<br>It will store txn deltas created during block evaluation, potentially consuming much larger amounts of memory, | false |
168 | | StorageEngine | StorageEngine allows to control which type of storage to use for the ledger.<br>Available options are:<br>- sqlite (default)<br>- pebbledb (experimental, in development) | sqlite |
169 | | TxIncomingFilterMaxSize | TxIncomingFilterMaxSize sets the maximum size for the de-duplication cache used by the incoming tx filter<br>only relevant if TxIncomingFilteringFlags is non-zero | 500000 |
170 | | BlockServiceMemCap | BlockServiceMemCap is the memory capacity in bytes which is allowed for the block service to use for HTTP block requests.<br>When it exceeds this capacity, it redirects the block requests to a different node | 500000000 |
171 | | EnableP2P | EnableP2P turns on the peer to peer network.<br>When both EnableP2P and EnableP2PHybridMode (below) are set, EnableP2PHybridMode takes precedence. | false |
172 | | EnableP2PHybridMode | EnableP2PHybridMode turns on both websockets and P2P networking.<br>Enabling this setting also requires PublicAddress to be set. | false |
173 | | P2PHybridNetAddress | P2PHybridNetAddress sets the listen address used for P2P networking, if hybrid mode is set. | |
174 | | EnableDHTProviders | EnableDHT will turn on the hash table for use with capabilities advertisement | false |
175 | | P2PPersistPeerID | P2PPersistPeerID will write the private key used for the node's PeerID to the P2PPrivateKeyLocation.<br>This is only used when P2PEnable is true. If P2PPrivateKey is not specified, it uses the default location. | false |
176 | | P2PPrivateKeyLocation | P2PPrivateKeyLocation allows the user to specify a custom path to the private key used for the node's PeerID.<br>The private key provided must be an ed25519 private key.<br>This is only used when P2PEnable is true. If the parameter is not set, it uses the default location. | |
177 | | DisableAPIAuth | DisableAPIAuth turns off authentication for public (non-admin) API endpoints. | false |
178 | | GoMemLimit | GoMemLimit provides the Go runtime with a soft memory limit. The default behavior is no limit,<br>unless the GOMEMLIMIT environment variable is set. | 0 |
179 |
180 |
181 |
182 |
183 | # kmd Configuration Settings
184 | The `kmd` process configuration parameters are shown in the table below.
185 |
186 | | Property| Description | Default Value |
187 | |------|------|------|
188 | | address | Configures the address the node listens to for REST API calls. Specify an IP and port or just port. For example, 127.0.0.1:0 will listen on a random port on the localhost | 127.0.0.1:0 |
189 | | allowed_origins | Configures the whitelist for allowed domains which can access the kmd process. Specify an array of urls that will be white listed. ie {“allowed_origins”: [“https://othersite1.com“, “https://othersite2.com”]} | |
190 | | session_lifetime_secs | Number of seconds for session expirations.| 60 |
191 |
```
--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/developer:docs:details:dapps:smart-contracts:debugging.md:
--------------------------------------------------------------------------------
```markdown
1 | title: Debugging smart contracts
2 |
3 | Since the release of go-algorand 3.15.0 the simulate endpoint for evaluating transactions has been made available to nodes. This feature allows users to submit a single transaction or a transaction group to the node, and be returned with the expected outcome (success or failure). In addition it can also supply a full or simple trace of the evaluated programs, along with changes to the stack, scratch space, and global and local states. Furthermore it can return a list of named resources which must be provided in the transaction if you choose not to include them during the simulation.
4 |
5 | # Simulate
6 |
7 | The simulate endpoint is the most recent addition when it comes to debugging smart contracts. Whether it's for helping with development, analysising existing deployed contracts, or even integrating it as part of the user experience someone has when interacting with a project, the simulate endpoint can be utilised for a variety of different workflows. Below we'll demonstrate a few of these use cases by interacting with the command-line interface as well as the RESTful API against a locally running node.
8 |
9 | When using more advance features such as `--trace` the type of data that's returned can be a bit overwhelming if you've developed the smart contract in a higher level language. But if you start out by simply submitting your transactions and checking what the `"failure-message"` says in the response you should be able to figure out the most common issues.
10 |
11 | You should also consider using these simulate responses with third-party tooling such as the community created [TEAL for VSCode](//marketplace.visualstudio.com/items?itemName=DragMZ.teal), which allows you to step through the TEAL smart contract and see the state of the AVM change after each instruction. Additionally there is [sim-stack-parser](//github.com/joe-p/sim-stack-parser), which will not only help visulise the stack, it will also map the compiled TEAL program back to the original PyTeal contract to further help with debugging.
12 |
13 | ## Command Line
14 |
15 | Using the command line tool `goal` you can simply run a simulation against an individual or group transaction file. Select the file using the `--txfile` argument and a simulate response will be returned. This can be extremely useful when quickly prototyping ideas or learning how various TEAL opcodes work.
16 |
17 | Example:
18 | ```sh
19 | $ goal app create --creator VPUJC6ZJCKDEATYRUJRNS5EMOIQGPBXRYEOMAZGKBURUPFEZXKYQZ34LQQ --approval-prog demo.teal --clear-prog clear.teal --sign -o demo.txn
20 | $ goal clerk simulate --txfile demo.txn
21 | {
22 | "last-round": 555,
23 | "txn-groups": [
24 | {
25 | "app-budget-added": 700,
26 | "app-budget-consumed": 7,
27 | "txn-results": [
28 | {
29 | "app-budget-consumed": 7,
30 | "txn-result": {
31 | "application-index": 1005,
32 | "logs": [
33 | "VGhpcyBkZW1vIGlzIGRvaW5nIGEgdGhpbmc="
34 | ],
35 | "pool-error": "",
36 | "txn": {
37 | "sig": "jMBrEx/IkH0Ctirl2RZMamxnh7VSV/uiEEWUO6pAHz2ohg/WLUOLUc4l7ZEuLHKaDoJZtzJh5dEXHw/V3/xqCQ==",
38 | "txn": {
39 | "apap": "CYAaVGhpcyBkZW1vIGlzIGRvaW5nIGEgdGhpbmewgSiBAghEgQE=",
40 | "apsu": "CYEB",
41 | "fee": 1000,
42 | "fv": 552,
43 | "gh": "0OS+d50dm6lo1k0tW5sDLvog4EeAZX8KwisnNW2EMG8=",
44 | "lv": 1552,
45 | "note": "0EbOk27RDgs=",
46 | "snd": "VPUJC6ZJCKDEATYRUJRNS5EMOIQGPBXRYEOMAZGKBURUPFEZXKYQZ34LQQ",
47 | "type": "appl"
48 | }
49 | }
50 | }
51 | }
52 | ]
53 | }
54 | ],
55 | "version": 2
56 | }
57 | ```
58 |
59 | Should an error be raised, you'll be presented with information about what happened and which transaction of the group caused the failure. If you want a more technical breakdown of what happened during execution of your program you can enable tracing with the argument `--trace`, which will present you with a step-by-step trace of the program via the program counter (PC) value. Alternatively you can use `--full-trace` for yet more information such as stack manipulations.
60 |
61 | ## Direct API Endpoint
62 |
63 | If you're looking for a more programmatic way to interface with simulate, the API endpoint is for you. This will also be how most tooling will interact with it.
64 |
65 | Below is the same example as above, however there's an additional step we must do before we can simulate the transaction. We need to create a simulate request, which essentially just wraps the transaction(s) in a parent "txn-groups" array and includes any of the optional parameters such as `--allow-empty-signatures` if you don't have the private key to the account you're testing with. Once the simulate request has been created, we then call the API and pass it with the request.
66 |
67 | !!! note
68 | You may be required to set the API token if your algod config doesn't have `DisableAPIToken` set to `true`. This can be achieved by adding the curl argument `-H 'X-Algo-API-Token: YOU_TOKEN_HERE'`
69 |
70 | Example:
71 | ```sh
72 | $ goal clerk simulate --txfile group.txn --request-only-out request.json
73 | $ curl http://127.0.0.1:4001/v2/transactions/simulate --data @demo.json
74 | {
75 | "last-round": 566,
76 | "txn-groups": [
77 | {
78 | "app-budget-added": 700,
79 | "app-budget-consumed": 7,
80 | "txn-results": [
81 | {
82 | "app-budget-consumed": 7,
83 | "txn-result": {
84 | "application-index": 1005,
85 | "logs": [
86 | "VGhpcyBkZW1vIGlzIGRvaW5nIGEgdGhpbmc="
87 | ],
88 | "pool-error": "",
89 | "txn": {
90 | "sig": "jMBrEx/IkH0Ctirl2RZMamxnh7VSV/uiEEWUO6pAHz2ohg/WLUOLUc4l7ZEuLHKaDoJZtzJh5dEXHw/V3/xqCQ==",
91 | "txn": {
92 | "apap": "CYAaVGhpcyBkZW1vIGlzIGRvaW5nIGEgdGhpbmewgSiBAghEgQE=",
93 | "apsu": "CYEB",
94 | "fee": 1000,
95 | "fv": 552,
96 | "gh": "0OS+d50dm6lo1k0tW5sDLvog4EeAZX8KwisnNW2EMG8=",
97 | "lv": 1552,
98 | "note": "0EbOk27RDgs=",
99 | "snd": "VPUJC6ZJCKDEATYRUJRNS5EMOIQGPBXRYEOMAZGKBURUPFEZXKYQZ34LQQ",
100 | "type": "appl"
101 | }
102 | }
103 | }
104 | }
105 | ]
106 | }
107 | ],
108 | "version": 2
109 | }
110 | ```
111 |
112 | ## JavaScript SDK
113 |
114 | To use the simulate endpoint within JavaScript the [js-algorand-sdk](//github.com/algorand/js-algorand-sdk) has some built-in features to help you. The most popular route will be using the AtomicTransactionComposer's `.simulate()` [method call](//algorand.github.io/js-algorand-sdk/classes/AtomicTransactionComposer.html#simulate). To learn more about the ATC please refer to [this section](../../atc.md).
115 |
116 | The code below is a complete example that walks through the entire process of constructing a transaction, calling the simulate endpoint, and printing out the simulate response.
117 |
118 | ```js
119 | import algosdk from 'algosdk';
120 |
121 | const client = new algosdk.Algodv2(
122 | 'a'.repeat(64),
123 | 'http://127.0.0.1',
124 | 4001,
125 | );
126 |
127 | const mn = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon invest';
128 | const acct = algosdk.mnemonicToSecretKey(mn);
129 | const signer = algosdk.makeBasicAccountTransactionSigner(acct);
130 |
131 | const approval_b64 = "CTEYSIAgOM54YO9NPIFpGWulHHE7cVNZ0dbwigCRgyDrG94ypjJgFrCBAQ==";
132 | const clear_b64 = "CYEB";
133 |
134 | (async () => {
135 | const sp = await client.getTransactionParams().do();
136 | const txn = algosdk.makeApplicationCreateTxnFromObject({
137 | from: acct.addr,
138 | suggestedParams: sp,
139 | approvalProgram: new Uint8Array(Buffer.from(approval_b64, "base64")),
140 | clearProgram: new Uint8Array(Buffer.from(clear_b64, "base64")),
141 | });
142 |
143 | const atc = new algosdk.AtomicTransactionComposer;
144 | const tws = {
145 | txn: txn,
146 | signer: signer,
147 | };
148 | atc.addTransaction(tws);
149 |
150 | const simreq = new algosdk.modelsv2.SimulateRequest({
151 | allowEmptySignatures: true,
152 | allowUnnamedResources: true,
153 | execTraceConfig: new algosdk.modelsv2.SimulateTraceConfig({
154 | enable: true,
155 | scratchChange: true,
156 | stackChange: true,
157 | stateChange: true,
158 | }),
159 | });
160 | const simres = await atc.simulate(client, simreq);
161 |
162 | console.log(JSON.stringify(simres, null, 2));
163 | })();
164 | ```
165 |
166 | ## Python SDK
167 |
168 | To use the simulate endpoint within Python the [py-algorand-sdk](//github.com/algorand/py-algorand-sdk) has some built-in features to help you. The most popular route will be using the AtomicTransactionComposer's `.simulate()` [method call](//py-algorand-sdk.readthedocs.io/en/latest/algosdk/atomic_transaction_composer.html#algosdk.atomic_transaction_composer.AtomicTransactionComposer.simulate). To learn more about the ATC please refer to [this section](../../atc.md).
169 |
170 | The code below is a complete example that walks through the entire process of constructing a transaction, calling the simulate endpoint, and printing out the simulate response.
171 |
172 | ```py
173 | #!/usr/bin/env python3
174 |
175 | import json
176 | from base64 import b64decode
177 |
178 | from algosdk.v2client.algod import AlgodClient
179 | from algosdk.v2client.models import simulate_request, SimulateRequestTransactionGroup
180 | from algosdk.transaction import ApplicationCreateTxn, OnComplete, StateSchema
181 | from algosdk import account, mnemonic, atomic_transaction_composer
182 |
183 | client = AlgodClient('a' * 64, "http://127.0.0.1:4001")
184 |
185 | mn = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon invest';
186 | sk = mnemonic.to_private_key(mn)
187 | pk = account.address_from_private_key(sk)
188 | signer = atomic_transaction_composer.AccountTransactionSigner(sk)
189 |
190 | approval_b64 = "CTEYSIAgOM54YO9NPIFpGWulHHE7cVNZ0dbwigCRgyDrG94ypjJgFrCBAQ=="
191 | clear_b64 = "CYEB"
192 |
193 | sp = client.suggested_params()
194 | txn = ApplicationCreateTxn(
195 | sender = pk,
196 | sp = sp,
197 | approval_program = b64decode(approval_b64),
198 | clear_program = b64decode(clear_b64),
199 | on_complete = OnComplete.NoOpOC,
200 | global_schema = StateSchema(0, 0),
201 | local_schema = StateSchema(0, 0),
202 | accounts = ["HDHHQYHPJU6IC2IZNOSRY4J3OFJVTUOW6CFABEMDEDVRXXRSUYZHZ2ZL4I"]
203 | )
204 |
205 | atc = atomic_transaction_composer.AtomicTransactionComposer()
206 | tws = atomic_transaction_composer.TransactionWithSigner(txn = txn, signer = signer)
207 | atc.add_transaction(tws)
208 |
209 | simreq = simulate_request.SimulateRequest(
210 | txn_groups = SimulateRequestTransactionGroup(txns = []),
211 | allow_empty_signatures = True,
212 | exec_trace_config= simulate_request.SimulateTraceConfig(
213 | enable = True,
214 | stack_change = True,
215 | scratch_change = True,
216 | )
217 | )
218 | simres = atc.simulate(client)
219 |
220 | print(json.dumps(simres.__dict__))
221 | ```
222 |
223 | ## Advanced Simulate Tracing
224 |
225 | Once you're familiar with the basics of simulate you may be after more technical details about how your smart contract is operating within the AVM. This can be done by using the `--trace` and `--full-trace` arguments when creating the simulate request. Upon submitting the request to the node you'll be presented with an extra `"exec-trace"` element in the response. This new structure will detail the steps the AVM took during evaluation of the smart contract, and in the case of using `--full-trace` it will display manipulations to the stack, scratch space, and global and local states. Be aware that what it's stepping through is the lowest level of bytecode, so you will need to use additional tooling to map these traces back to a higher level language you may have written your smart contract in.
226 |
227 | Below is an example smart contract which utilises the stack, scratch space, global and local state, and box storage. Giving you a very detailed simulate response of exactly what's being changed during evaluation of the contract. By using the `--allow-unnamed-resources` option, I am able to submit the transaction without providing the box name, and in the simulate response I am told what box name I must provide when submitting the transaction to the network. This is extremely useful when you have large complex transaction groups that share resources.
228 |
229 | ```sh
230 | $ goal app create --creator WONFHT5BPHIAU5D4YZXGY2BLTQ5YOLUNRODZ4XQRG3RSQSB6ZVZ2I2F3AI --approval-prog full.teal --clear-prog clear.teal --global-ints 1 --local-ints 1 --on-completion optin -o full.txn
231 | $ goal clerk simulate --txfile full.txn --allow-empty-signatures --full-trace --allow-unnamed-resources
232 | {
233 | "eval-overrides": {
234 | "allow-empty-signatures": true,
235 | "allow-unnamed-resources": true
236 | },
237 | "exec-trace-config": {
238 | "enable": true,
239 | "scratch-change": true,
240 | "stack-change": true,
241 | "state-change": true
242 | },
243 | "last-round": 16938,
244 | "txn-groups": [
245 | {
246 | "app-budget-added": 700,
247 | "app-budget-consumed": 18,
248 | "txn-results": [
249 | {
250 | "app-budget-consumed": 18,
251 | "exec-trace": {
252 | "approval-program-hash": "EwlhQwuh35HJQ6lELdPi53mkqlJ1z/kMRGW1mdRTBWI=",
253 | "approval-program-trace": [
254 | {
255 | "pc": 1
256 | },
257 | {
258 | "pc": 13,
259 | "stack-additions": [
260 | {
261 | "type": 2,
262 | "uint": 123
263 | }
264 | ]
265 | },
266 | {
267 | "pc": 15,
268 | "scratch-changes": [
269 | {
270 | "new-value": {
271 | "type": 2,
272 | "uint": 123
273 | },
274 | "slot": 0
275 | }
276 | ],
277 | "stack-pop-count": 1
278 | },
279 | {
280 | "pc": 17,
281 | "stack-additions": [
282 | {
283 | "bytes": "Z2xvYmFsX3ZhbHVl",
284 | "type": 1
285 | }
286 | ]
287 | },
288 | {
289 | "pc": 31,
290 | "stack-additions": [
291 | {
292 | "type": 2,
293 | "uint": 123
294 | }
295 | ]
296 | },
297 | {
298 | "pc": 33,
299 | "stack-pop-count": 2,
300 | "state-changes": [
301 | {
302 | "app-state-type": "g",
303 | "key": "Z2xvYmFsX3ZhbHVl",
304 | "new-value": {
305 | "type": 2,
306 | "uint": 123
307 | },
308 | "operation": "w"
309 | }
310 | ]
311 | },
312 | {
313 | "pc": 34,
314 | "stack-additions": [
315 | {
316 | "bytes": "s5pTz6F50Ap0fMZubGgrnDuHLo2Lh55eETbjKEg+zXM=",
317 | "type": 1
318 | }
319 | ]
320 | },
321 | {
322 | "pc": 36,
323 | "stack-additions": [
324 | {
325 | "bytes": "bG9jYWxfdmFsdWU=",
326 | "type": 1
327 | }
328 | ]
329 | },
330 | {
331 | "pc": 49,
332 | "stack-additions": [
333 | {
334 | "type": 2,
335 | "uint": 123
336 | }
337 | ]
338 | },
339 | {
340 | "pc": 51,
341 | "stack-pop-count": 3,
342 | "state-changes": [
343 | {
344 | "account": "WONFHT5BPHIAU5D4YZXGY2BLTQ5YOLUNRODZ4XQRG3RSQSB6ZVZ2I2F3AI",
345 | "app-state-type": "l",
346 | "key": "bG9jYWxfdmFsdWU=",
347 | "new-value": {
348 | "type": 2,
349 | "uint": 123
350 | },
351 | "operation": "w"
352 | }
353 | ]
354 | },
355 | {
356 | "pc": 52,
357 | "stack-additions": [
358 | {
359 | "bytes": "Ym94X3ZhbHVl",
360 | "type": 1
361 | }
362 | ]
363 | },
364 | {
365 | "pc": 53,
366 | "stack-additions": [
367 | {
368 | "type": 2,
369 | "uint": 123
370 | }
371 | ]
372 | },
373 | {
374 | "pc": 55,
375 | "stack-additions": [
376 | {
377 | "type": 2,
378 | "uint": 1
379 | }
380 | ],
381 | "stack-pop-count": 2,
382 | "state-changes": [
383 | {
384 | "app-state-type": "b",
385 | "key": "Ym94X3ZhbHVl",
386 | "new-value": {
387 | "bytes": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
388 | "type": 1
389 | },
390 | "operation": "w"
391 | }
392 | ]
393 | },
394 | {
395 | "pc": 56,
396 | "stack-pop-count": 1
397 | },
398 | {
399 | "pc": 57,
400 | "stack-additions": [
401 | {
402 | "bytes": "Ym94X3ZhbHVl",
403 | "type": 1
404 | }
405 | ]
406 | },
407 | {
408 | "pc": 58,
409 | "stack-additions": [
410 | {
411 | "type": 2,
412 | "uint": 1
413 | }
414 | ],
415 | "stack-pop-count": 1,
416 | "state-changes": [
417 | {
418 | "app-state-type": "b",
419 | "key": "Ym94X3ZhbHVl",
420 | "operation": "d"
421 | }
422 | ]
423 | },
424 | {
425 | "pc": 59,
426 | "stack-pop-count": 1
427 | },
428 | {
429 | "pc": 60,
430 | "stack-additions": [
431 | {
432 | "type": 2,
433 | "uint": 1
434 | }
435 | ]
436 | }
437 | ]
438 | },
439 | "txn-result": {
440 | "application-index": 1069,
441 | "global-state-delta": [
442 | {
443 | "key": "Z2xvYmFsX3ZhbHVl",
444 | "value": {
445 | "action": 2,
446 | "uint": 123
447 | }
448 | }
449 | ],
450 | "local-state-delta": [
451 | {
452 | "address": "WONFHT5BPHIAU5D4YZXGY2BLTQ5YOLUNRODZ4XQRG3RSQSB6ZVZ2I2F3AI",
453 | "delta": [
454 | {
455 | "key": "bG9jYWxfdmFsdWU=",
456 | "value": {
457 | "action": 2,
458 | "uint": 123
459 | }
460 | }
461 | ]
462 | }
463 | ],
464 | "pool-error": "",
465 | "txn": {
466 | "txn": {
467 | "apan": 1,
468 | "apap": "CSYBCWJveF92YWx1ZYF7NQCADGdsb2JhbF92YWx1ZTQAZzEAgAtsb2NhbF92YWx1ZTQAZig0ALlEKLxEgQE=",
469 | "apgs": {
470 | "nui": 1
471 | },
472 | "apls": {
473 | "nui": 1
474 | },
475 | "apsu": "CYEB",
476 | "fee": 1000,
477 | "fv": 16936,
478 | "gh": "0OS+d50dm6lo1k0tW5sDLvog4EeAZX8KwisnNW2EMG8=",
479 | "lv": 17936,
480 | "note": "IRCmDp1ak60=",
481 | "snd": "WONFHT5BPHIAU5D4YZXGY2BLTQ5YOLUNRODZ4XQRG3RSQSB6ZVZ2I2F3AI",
482 | "type": "appl"
483 | }
484 | }
485 | }
486 | }
487 | ],
488 | "unnamed-resources-accessed": {
489 | "boxes": [
490 | {
491 | "app": 1069,
492 | "name": "Ym94X3ZhbHVl"
493 | }
494 | ]
495 | }
496 | }
497 | ],
498 | "version": 2
499 | }
500 | ```
501 |
502 | # Historical Debugging
503 |
504 | Below are two ways debugging used to be achieved with Algorand smart contracts. Whilst it's still possible to use these techniques today, there are limitations associated with them and certain features haven't been updated to support the latest AVM capabilities.
505 |
506 | !!! warning
507 | As of AVMv8, `dryrun` will no longer work with any contract that uses box storage. A new endpoint to replace `dryrun` along with a new tool to replace `tealdbg` is currently in development.
508 |
509 | Smart contracts can be debugged using two different methods. The first is an interactive debugger that uses the `tealdbg` command-line tool to launch a debug session where the smart contract can be examined as the contract is being evaluated. The second method uses the `goal clerk dryrun-remote` command which outputs a line by line result of the evaluation of the smart contract. These two methods are described below.
510 |
511 | # Using the TEAL debugger
512 | Algorand provides the `tealdbg` command-line tool to launch an interactive session to debug smart contracts. This tool is explained in the project’s [README](https://github.com/algorand/go-algorand/blob/master/cmd/tealdbg/README.md).
513 |
514 | This debugger can debug local smart contracts or connect remotely to an on-chain smart contract. The examples below illustrate using the debugger locally, which will be the predominant use case for developers when they are developing smart contracts. For more information on the `tealdbg` utility and how you can use it remotely, see the project’s [README](https://github.com/algorand/go-algorand/blob/master/cmd/tealdbg/README.md) which covers in detail the different debugging options. The `tealdbg` command can also be called through a [sandbox](https://github.com/algorand/sandbox) with `./sandbox tealdbg {OPTIONS}`.
515 |
516 | The debugger process supports both Chrome Developer Tools and a simple Web Frontend.
517 |
518 | To launch the debugger locally, for use with the CDT, execute the following command from a terminal.
519 |
520 | ```
521 | $ tealdbg debug program.teal
522 | .
523 | .
524 | 2020/08/25 14:05:38 CDT debugger listening on: ws://localhost:9392/091d04a69152223ae84c8b40271c3d62f8490ea9b795aae95868932163f89735
525 | 2020/08/25 14:05:38 Or open in Chrome:
526 | 2020/08/25 14:05:38 devtools://devtools/bundled/js_app.html?experiments=true&v8only=false&ws=localhost:9392/091d04a69152223ae84c8b40271c3d62f8490ea9b795aae95868932163f89735
527 | ```
528 |
529 | This will launch the debugger process and return an endpoint that is listening for connections. This process can be connected to directly with the Chrome Developer Tools (CDT). The simplest way to do this is to enter `chrome://inspect/` into the address bar of the browser, click “Configure” to add “localhost:9392”, and select the Algorand TEAL Debugger in the Remote Target Section (click on the inspect link).
530 |
531 | !!! note "A note about ports"
532 | You may have to pass a specific port to the tealdbg command line tool to prevent it from trying to use a port that is already being used. For example if you have the sandbox running and you'd like to run the tealdbg on the host machine.
533 | ```
534 | tealdbg debug program.teal --remote-debugging-port 9393
535 | ```
536 |
537 | 
538 | <center>*Configure CDT Remote Connection*</center>
539 |
540 | This will launch the debugger and allow the smart contract to be inspected. The debugger provides standard debugger controls, like single-stepping, pausing, breakpoints etc.
541 |
542 | !!! note "A note on viewing TEAL source"
543 | The TEAL source file may not open immediately but you can bring up a menu with the source files by pressing CTRL+P or CMD+P on mac
544 |
545 | 
546 | <center>*TEAL Debugger*</center>
547 |
548 | The Scope pane contains the current stack and is useful for determining what values the current line of code is processing. When a smart contract returns, if anything other than one positive value is left on the stack or the `return` opcode is used with a nonpositive value on the top of the stack, the program will fail. The Scope pane also displays the current transaction with all its properties, the current scratch space, global variables, and any state associated with the contract. If this transaction is part of an atomic transfer, all transactions will also be available in the Scope pane.
549 |
550 | The debugging session runs in a mock version of the ledger so the context including; balance records of the accounts, application parameters, and assets used during program evaluation must be supplied. Exactly what context is needed for a debug session will depend on the type of contract that is being debugged and what opcodes are used in the program.
551 |
552 | Most frequently, a [Dryrun Dump](#creating-a-dryrun-dump-file) file is used to pass all this context information in a single payload.
553 |
554 | It can be supplied directly by calling `tealdbg` with arguments including:
555 |
556 | - Transaction(s) - Supply one or more transactions to the debug session.
557 | - Balance Records - Account balance records of accounts used in the contract. Needed when debugging smart contracts that make use of state.
558 | - Latest Timestamp - Set the latest timestamp for debugging smart contracts that make use of time values.
559 | - Protocol - Set the protocol of consensus that the debug session uses when evaluating the contract.
560 | - Round - Set the current round for the debug session.
561 | Group Index - If using more than one transaction, the specific index that is being processed can be set.
562 | - Mode - The debugger can debug both smart signatures (Signature) and smart contracts (Application). The mode can be set to determine which type is being processed. By default, the debugger scans the program to determine the type of contract.
563 | - Application ID - Manually set the application ID of the current smart contract.
564 | - Program - Pass the program to debug
565 |
566 | To learn more about setting individual context items, see the `tealdbg` [documentation](https://github.com/algorand/go-algorand/blob/master/cmd/tealdbg/README.md).
567 |
568 | The context can also be read directly from an instance of the Indexer. See the `tealdbg` [documentation](https://github.com/algorand/go-algorand/blob/master/cmd/tealdbg/README.md) for more information.
569 |
570 | ## Creating a dryrun dump file
571 |
572 | This file may be msgpack or json and can be created using goal or the SDKs
573 |
574 | === "Python"
575 | <!-- ===PYSDK_DEBUG_DRYRUN_DUMP=== -->
576 | ```python
577 | sp = algod_client.suggested_params()
578 |
579 | atc = atomic_transaction_composer.AtomicTransactionComposer()
580 | atc.add_method_call(
581 | app_id, my_method, acct1.address, sp, acct1.signer, method_args=[1, 2]
582 | )
583 | txns = atc.gather_signatures()
584 |
585 | drr = transaction.create_dryrun(algod_client, txns)
586 |
587 | # Write the file as binary result of msgpack encoding
588 | with open("dryrun.msgp", "wb") as f:
589 | f.write(base64.b64decode(encoding.msgpack_encode(drr)))
590 | ```
591 | [Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/debug.py#L31-L44)
592 | <!-- ===PYSDK_DEBUG_DRYRUN_DUMP=== -->
593 |
594 | === "JavaScript"
595 | <!-- ===JSSDK_DEBUG_DRYRUN_DUMP=== -->
596 | ```javascript
597 | const suggestedParams = await algodClient.getTransactionParams().do();
598 |
599 | const atc = new algosdk.AtomicTransactionComposer();
600 | atc.addMethodCall({
601 | appID: appId,
602 | method: contract.getMethodByName('sub'),
603 | methodArgs: [1, 2],
604 | sender: sender.addr,
605 | signer: sender.signer,
606 | suggestedParams,
607 | });
608 |
609 | const signedTxns = (await atc.gatherSignatures()).map((stxn) =>
610 | algosdk.decodeSignedTransaction(stxn)
611 | );
612 |
613 | const dryrunRequest = await algosdk.createDryrun({
614 | client: algodClient,
615 | txns: signedTxns,
616 | });
617 |
618 | console.log('Dryrun:', dryrunRequest.get_obj_for_encoding());
619 | ```
620 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/debug.ts#L24-L46)
621 | <!-- ===JSSDK_DEBUG_DRYRUN_DUMP=== -->
622 |
623 | === "Go"
624 | <!-- ===GOSDK_DEBUG_DRYRUN_DUMP=== -->
625 | ```go
626 | var (
627 | args [][]byte
628 | accounts []string
629 | apps []uint64
630 | assets []uint64
631 | )
632 |
633 | sp, err := algodClient.SuggestedParams().Do(context.Background())
634 | if err != nil {
635 | log.Fatalf("failed to get suggested params: %s", err)
636 | }
637 |
638 | appCallTxn, err := transaction.MakeApplicationNoOpTx(
639 | appID, args, accounts, apps, assets, sp, acct1.Address,
640 | nil, types.Digest{}, [32]byte{}, types.Address{},
641 | )
642 | if err != nil {
643 | log.Fatalf("Failed to create app call txn: %+v", err)
644 | }
645 |
646 | _, stxn, err := crypto.SignTransaction(acct1.PrivateKey, appCallTxn)
647 | if err != nil {
648 | log.Fatalf("Failed to sign app txn: %+v", err)
649 | }
650 |
651 | signedAppCallTxn := types.SignedTxn{}
652 | msgpack.Decode(stxn, &signedAppCallTxn)
653 |
654 | drr, err := transaction.CreateDryrun(algodClient, []types.SignedTxn{signedAppCallTxn}, nil, context.Background())
655 | if err != nil {
656 | log.Fatalf("Failed to create dryrun: %+v", err)
657 | }
658 |
659 | os.WriteFile("dryrun.msgp", msgpack.Encode(drr), 0666)
660 | ```
661 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/debug/main.go#L27-L61)
662 | <!-- ===GOSDK_DEBUG_DRYRUN_DUMP=== -->
663 |
664 | === "Java"
665 | <!-- ===JAVASDK_DEBUG_DRYRUN_DUMP=== -->
666 | ```java
667 | // Set up the transactions we'd like to dryrun
668 | AtomicTransactionComposer atc = new AtomicTransactionComposer();
669 |
670 | List<Object> methodArgs = new ArrayList<Object>();
671 | methodArgs.add(1);
672 | methodArgs.add(1);
673 |
674 | TransactionParametersResponse sp = algodClient.TransactionParams().execute().body();
675 |
676 | MethodCallTransactionBuilder<?> mctb = MethodCallTransactionBuilder.Builder();
677 | MethodCallParams mcp = mctb.applicationId(appId).signer(acct.getTransactionSigner())
678 | .suggestedParams(sp)
679 | .sender(acct.getAddress())
680 | .method(contract.getMethodByName("add"))
681 | .methodArguments(methodArgs)
682 | .onComplete(Transaction.OnCompletion.NoOpOC)
683 | .build();
684 | atc.addMethodCall(mcp);
685 |
686 | DryrunRequest drr = Utils.createDryrun(algodClient, atc.gatherSignatures(), "", 0L, 0L);
687 |
688 | FileOutputStream outfile = new FileOutputStream("my-dryrun.msgpack");
689 | outfile.write(Encoder.encodeToMsgPack(drr));
690 | outfile.close();
691 | ```
692 | [Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/Debug.java#L36-L60)
693 | <!-- ===JAVASDK_DEBUG_DRYRUN_DUMP=== -->
694 |
695 | === "goal"
696 | <!-- ===GOAL_DEBUG_DRYRUN_DUMP=== -->
697 | ```sh
698 |
699 | $ goal app call --app-id {appid} --from {ACCOUNT} --out=dryrun.json --dryrun-dump
700 | # or if you already have a transaction file
701 | $ goal clerk dryrun --dryrun-dump -t transaction.txn -o dryrun.json
702 |
703 | ```
704 | <!-- ===GOAL_DEBUG_DRYRUN_DUMP=== -->
705 |
706 | ## Calling the debugger with context
707 |
708 | ```
709 | $ tealdbg debug -d dryrun.msgp
710 | ```
711 |
712 | !!! note "a note on supplying the Teal code"
713 | The `tealdbg` command does not require the Teal program above as the decompiled version is available in the dryrun-req dump file. In this example it is supplied for easier readability while in the debugger. Supplying the program will allow debugging the original source and not the decompiled version.
714 |
715 | The scope panel will now have the proper context data for the debugging session.
716 |
717 | 
718 | <center>*TEAL Debugger Scope*</center>
719 |
720 | One or more transactions that are stored in a file can be debugged by dumping the context data with the `goal clerk dryrun` command. For example, two smart contracts are grouped below and the context data is generated using the `dryrun-dump` option. The `tealdbg` command is then used to start the debugger.
721 |
722 | ```
723 | #generate calls
724 | $ goal app call --app-id 1 --app-arg "str:test1" --from {ACCOUNT} --out=unsginedtransaction1.tx
725 | $ goal app call --app-id 1 --app-arg "str:test2" --from {ACCOUNT} --out=unsginedtransaction2.tx
726 |
727 | # atomically group them
728 | $ cat unsginedtransaction1.tx unsginedtransaction2.tx > combinedtransactions.tx
729 | $ goal clerk group -i combinedtransactions.tx -o groupedtransactions.tx
730 | $ goal clerk split -i groupedtransactions.tx -o split.tx
731 |
732 | # sign individual transactions
733 | $ goal clerk sign -i split-0.tx -o signout-0.tx
734 | $ goal clerk sign -i split-1.tx -o signout-1.tx
735 |
736 | # concatenate the two signed transactions
737 | $ cat signout-0.tx signout-1.tx > signout.tx
738 |
739 | # generate context debug file
740 | $ goal clerk dryrun -t signout.tx --dryrun-dump -o dryrun.json
741 |
742 | # debug first transaction. Change index to 1 to debug second transaction
743 | $ tealdbg debug program.teal -d dryrun.json --group-index 0
744 | ```
745 |
746 | A similar flow may be implemented in any of the sdks, passing the list of transactions to the `create_dryrun` function will produce the DryrunDump object and either write the object out to a file as shown above or send it directly to the [/v2/teal/dryrun](../../../rest-apis/algod.md#post-v2tealdryrun) endpoint
747 |
748 | Debugging a smart signature functions identically to the process described above except the state is not required. For example, a smart signature may act as an escrow account. The following call exports the transaction for debugging purposes. This call will not execute on the blockchain as it is not submitted to the network but is written to the output file.
749 |
750 | ```
751 | $ goal clerk send -a=0 -c={ACCOUNT_1} --to={ACCOUNT_2} --from-program=stateless.teal --out=statelesstx.tx --dryrun-dump
752 | ```
753 |
754 | This contract can then be debugged by using the following command.
755 |
756 | ```
757 | $ tealdbg debug stateless.teal -d statelesstx.tx
758 | ```
759 |
760 | The `tealdbg` utility has many more options for setting specific context items. For information on these capabilities, see the project’s [README](https://github.com/algorand/go-algorand/blob/master/cmd/tealdbg/README.md).
761 |
762 |
763 | # Dryrun REST endpoint
764 |
765 | !!! important "enabling dryrun-remote"
766 | The dryrun REST API is only available on a node if it has been enabled in the node's configuration. This can be done using the following commands.
767 |
768 | ```
769 | $ algocfg set -p EnableDeveloperAPI -v true
770 | $ goal node restart
771 | ```
772 |
773 | Using the [Dryrun](../../../rest-apis/algod.md#post-v2tealdryrun) REST endpoint to debug programs can be very helpful for debugging or even running unit tests.
774 |
775 | The payload for [creating a dryrun request](#creating-a-dryrun-dump-file) has the same contents as the dryrun dump file. After Sending the Dryrun Request object to the server the response will contain evaluation results for all the transactions that invoked smart contracts including a Stack Trace, cost (as budget-*), logs (if successful) and errors encountered.
776 |
777 |
778 | === "Python"
779 | <!-- ===PYSDK_DEBUG_DRYRUN_SUBMIT=== -->
780 | ```python
781 | # Create the dryrun request object
782 | dryrun_request = transaction.create_dryrun(algod_client, txns)
783 |
784 | # Pass dryrun request to algod server
785 | dryrun_result = algod_client.dryrun(dryrun_request)
786 | drr = dryrun_results.DryrunResponse(dryrun_result)
787 |
788 | for txn in drr.txns:
789 | if txn.app_call_rejected():
790 | print(txn.app_trace())
791 | ```
792 | [Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/debug.py#L48-L58)
793 | <!-- ===PYSDK_DEBUG_DRYRUN_SUBMIT=== -->
794 |
795 | === "JavaScript"
796 | <!-- ===JSSDK_DEBUG_DRYRUN_SUBMIT=== -->
797 | ```javascript
798 | const dryrunResponse = await algodClient.dryrun(dryrunRequest).do();
799 | dryrunResponse.txns.forEach((txn) => {
800 | console.log('Txn:', txn.txn);
801 | console.log('Txn Results:', txn.txnresults);
802 | });
803 | ```
804 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/debug.ts#L49-L54)
805 | <!-- ===JSSDK_DEBUG_DRYRUN_SUBMIT=== -->
806 |
807 | === "Go"
808 | <!-- ===GOSDK_DEBUG_DRYRUN_SUBMIT=== -->
809 | ```go
810 | // Create the dryrun request object
811 | drReq, err := transaction.CreateDryrun(algodClient, []types.SignedTxn{signedAppCallTxn}, nil, context.Background())
812 | if err != nil {
813 | log.Fatalf("Failed to create dryrun: %+v", err)
814 | }
815 |
816 | // Pass dryrun request to algod server
817 | dryrunResponse, err := algodClient.TealDryrun(drReq).Do(context.Background())
818 | if err != nil {
819 | log.Fatalf("failed to dryrun request: %s", err)
820 | }
821 |
822 | // Inspect the response to check result
823 | for _, txn := range dryrunResponse.Txns {
824 | log.Printf("%+v", txn.AppCallTrace)
825 | }
826 | ```
827 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/debug/main.go#L64-L80)
828 | <!-- ===GOSDK_DEBUG_DRYRUN_SUBMIT=== -->
829 |
830 | === "Java"
831 | <!-- ===JAVASDK_DEBUG_DRYRUN_SUBMIT=== -->
832 | ```java
833 | Response<DryrunResponse> resp = algodClient.TealDryrun().request(drr).execute();
834 | DryrunResponse drResp = resp.body();
835 | DryrunTxnResult dryrunTxnResult = drResp.txns.get(0);
836 | System.out.println(dryrunTxnResult.appCallMessages);
837 | System.out.println(Utils.appTrace(dryrunTxnResult));
838 | ```
839 | [Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/Debug.java#L63-L68)
840 | <!-- ===JAVASDK_DEBUG_DRYRUN_SUBMIT=== -->
841 |
842 |
843 | === "Shell"
844 | ```sh
845 | # With a dryrun object as dryrun.msgp
846 |
847 | $ curl -XPOST "http://localhost:4001/v2/teal/dryrun" \
848 | -H "X-Algo-API-Token: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
849 | --data-binary @dryrun.msgp
850 |
851 | ```
852 |
853 | Example of DryrunResponse payload:
854 |
855 | ```js
856 | {
857 | "error": "error string if failure occurred",
858 | "protocol-version": "",
859 | "txns":[
860 | {
861 | "app-call-messages":["string array of messages", "will contain reject if relevant"],
862 | "app-call-trace":[
863 | {
864 | "line":1,
865 | "pc":2,
866 | "stack":[{ // Each stack value at this pc
867 | "type":1 //1 is bytes, 2 is int
868 | "bytes":"the bytes on the stack"
869 | "int":0
870 | }]
871 | },
872 | // ...
873 | ],
874 | "budget-consumed":1337,
875 | "budget-added":1400,
876 |
877 | // Disassembled program line by line.
878 | "disassembly":["disassembled", "program", "broken", "out", "by", "line"],
879 |
880 | // The changes to the global state ths program would have caused
881 | "global-delta": {},
882 |
883 | // The changes to local state this program would have caused
884 | "local-deltas":[{}],
885 |
886 | // Any messages caused by the logic sig evaluation
887 | "logic-sig-messages":[],
888 |
889 | // Any trace from a logic sig
890 | "logic-sig-trace":[],
891 |
892 | // Any logs from application call output
893 | "logs":["base64", "encoding", "of", "logged", "bytes"],
894 | }
895 | ]
896 | }
897 | ```
898 |
```