This is page 37 of 93. Use http://codebase.md/goplausible/algorand-mcp?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── llms-install.md
├── llms.txt
├── package.json
├── packages
│ ├── client
│ │ ├── .env.example
│ │ ├── package.json
│ │ ├── README.md
│ │ ├── src
│ │ │ ├── env.ts
│ │ │ ├── index.ts
│ │ │ └── LocalWallet.ts
│ │ └── tsconfig.json
│ └── server
│ ├── .env.example
│ ├── API specs
│ │ ├── algod_api.json
│ │ ├── indexer_api.json
│ │ ├── mcp.json
│ │ ├── nfd_api.json
│ │ ├── ultrade_api.json
│ │ ├── vestige_api.json
│ │ └── vestige_free_api.json
│ ├── Dockerfile
│ ├── jest.config.js
│ ├── package.json
│ ├── README.md
│ ├── smithery.yaml
│ ├── src
│ │ ├── algorand-client.ts
│ │ ├── env.ts
│ │ ├── index.ts
│ │ ├── resources
│ │ │ ├── index.ts
│ │ │ ├── knowledge
│ │ │ │ ├── ARCs.txt
│ │ │ │ ├── developers-algokit-architecture-decisions.txt
│ │ │ │ ├── developers-algokit-cli.txt
│ │ │ │ ├── developers-algokit-utils-python.txt
│ │ │ │ ├── developers-algokit-utils-typescript.txt
│ │ │ │ ├── developers-clis.txt
│ │ │ │ ├── developers-details.txt
│ │ │ │ ├── developers-liquid-auth.txt
│ │ │ │ ├── developers-nodes.txt
│ │ │ │ ├── developers-puya.txt
│ │ │ │ ├── developers-python.txt
│ │ │ │ ├── developers-sdks-js.txt
│ │ │ │ ├── developers-sdks-python.txt
│ │ │ │ ├── developers-tealscript.txt
│ │ │ │ ├── developers.txt
│ │ │ │ ├── index.ts
│ │ │ │ ├── taxonomy
│ │ │ │ │ ├── algokit-cli:README.md
│ │ │ │ │ ├── algokit:cli:algokit.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2022-11-14_sandbox-approach.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2022-11-22_beaker-testing-strategy.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2023-01-11_beaker_productionisation_review.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2023-01-11_brew_install.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2023-01-12_smart-contract-deployment.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2023-06-06_frontend-templates.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2023-07-19_advanced_generate_command.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2024-01-13_native_binaries.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2024-01-23_init-wizard-v2.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2024-01-31_binary_distribution.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2024-03-06_local_dev_ui_packaging.md
│ │ │ │ │ ├── algokit:cli:articles:output_stability.md
│ │ │ │ │ ├── algokit:cli:cli:index.md
│ │ │ │ │ ├── algokit:cli:features:compile.md
│ │ │ │ │ ├── algokit:cli:features:completions.md
│ │ │ │ │ ├── algokit:cli:features:config.md
│ │ │ │ │ ├── algokit:cli:features:dispenser.md
│ │ │ │ │ ├── algokit:cli:features:doctor.md
│ │ │ │ │ ├── algokit:cli:features:explore.md
│ │ │ │ │ ├── algokit:cli:features:generate.md
│ │ │ │ │ ├── algokit:cli:features:goal.md
│ │ │ │ │ ├── algokit:cli:features:init.md
│ │ │ │ │ ├── algokit:cli:features:localnet.md
│ │ │ │ │ ├── algokit:cli:features:project:bootstrap.md
│ │ │ │ │ ├── algokit:cli:features:project:deploy.md
│ │ │ │ │ ├── algokit:cli:features:project:link.md
│ │ │ │ │ ├── algokit:cli:features:project:list.md
│ │ │ │ │ ├── algokit:cli:features:project:run.md
│ │ │ │ │ ├── algokit:cli:features:project.md
│ │ │ │ │ ├── algokit:cli:features:tasks:analyze.md
│ │ │ │ │ ├── algokit:cli:features:tasks:ipfs.md
│ │ │ │ │ ├── algokit:cli:features:tasks:mint.md
│ │ │ │ │ ├── algokit:cli:features:tasks:nfd.md
│ │ │ │ │ ├── algokit:cli:features:tasks:opt.md
│ │ │ │ │ ├── algokit:cli:features:tasks:send.md
│ │ │ │ │ ├── algokit:cli:features:tasks:sign.md
│ │ │ │ │ ├── algokit:cli:features:tasks:transfer.md
│ │ │ │ │ ├── algokit:cli:features:tasks:vanity_address.md
│ │ │ │ │ ├── algokit:cli:features:tasks:wallet.md
│ │ │ │ │ ├── algokit:cli:features:tasks.md
│ │ │ │ │ ├── algokit:cli:tutorials:algokit-template.md
│ │ │ │ │ ├── algokit:cli:tutorials:intro.md
│ │ │ │ │ ├── algokit:cli:tutorials:smart-contracts.md
│ │ │ │ │ ├── algokit:docs:testnet_api.md
│ │ │ │ │ ├── algokit:lora:README.md
│ │ │ │ │ ├── algokit:README.md
│ │ │ │ │ ├── algokit:utils:python:markdown:apidocs:algokit_utils:algokit_utils.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:account.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:app-client.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:app-deploy.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:client.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:debugger.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:dispenser-client.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:transfer.md
│ │ │ │ │ ├── algokit:utils:python:markdown:index.md
│ │ │ │ │ ├── algokit:utils:python:README.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:account.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:app-client.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:app-deploy.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:client.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:debugger.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:dispenser-client.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:transfer.md
│ │ │ │ │ ├── algokit:utils:python:source:index.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:account.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:algorand-client.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:amount.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:app-client.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:app-deploy.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:app.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:asset.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:client.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:debugging.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:dispenser-client.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:event-emitter.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:indexer.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:testing.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:transaction-composer.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:transaction.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:transfer.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:typed-app-clients.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:testing.TestLogger.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:testing.TransactionLogger.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_account_manager.AccountManager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_account.MultisigAccount.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_account.SigningAccount.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_algo_http_client_with_retry.AlgoHttpClientWithRetry.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_algorand_client_transaction_creator.AlgorandClientTransactionCreator.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_algorand_client_transaction_sender.AlgorandClientTransactionSender.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_algorand_client.AlgorandClient.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_amount.AlgoAmount.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_app_arc56.Arc56Method.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_app_client.AppClient.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_app_client.ApplicationClient.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_app_deployer.AppDeployer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_app_factory.AppFactory.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_app_manager.AppManager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_asset_manager.AssetManager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_async_event_emitter.AsyncEventEmitter.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_client_manager.ClientManager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_composer.TransactionComposer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_config.UpdatableConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_dispenser_client.TestNetDispenserApiClient.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_kmd_account_manager.KmdAccountManager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_logic_error.LogicError.md
│ │ │ │ │ ├── algokit:utils:typescript:code:enums:types_app.OnSchemaBreak.md
│ │ │ │ │ ├── algokit:utils:typescript:code:enums:types_app.OnUpdate.md
│ │ │ │ │ ├── algokit:utils:typescript:code:enums:types_indexer.AccountStatus.md
│ │ │ │ │ ├── algokit:utils:typescript:code:enums:types_indexer.ApplicationOnComplete.md
│ │ │ │ │ ├── algokit:utils:typescript:code:enums:types_indexer.SignatureType.md
│ │ │ │ │ ├── algokit:utils:typescript:code:enums:types_lifecycle_events.EventType.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_account_manager.EnsureFundedResult.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_account.AccountConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_account.TransactionSignerAccount.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_algorand_client_interface.AlgorandClientInterface.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.Arc56Contract.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.Event.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.Method.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.ProgramSourceInfo.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.StorageKey.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.StorageMap.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.StructField.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientCallABIArgs.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientCallCoreParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientCompilationParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientCompilationResult.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientDeployCallInterfaceParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientDeployCoreParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientDeployParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppSourceMaps.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.FundAppAccountParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.ResolveAppById.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.ResolveAppByIdBase.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.SourceMapExport.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_deployer.AppLookup.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_deployer.AppMetadata.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_factory.AppFactoryParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_manager.AppInformation.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_manager.BoxReference.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_manager.BoxValueRequestParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_manager.BoxValuesRequestParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.AppSources.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.AppSpec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.CallConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.DeclaredSchemaValueSpec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.Hint.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.ReservedSchemaValueSpec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.Schema.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.SchemaSpec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.StateSchemaSpec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.Struct.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppCallParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppCallTransactionResultOfType.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppCompilationResult.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppDeploymentParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppDeployMetadata.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppLookup.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppMetadata.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppReference.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppState.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppStorageSchema.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.BoxName.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.BoxReference.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.BoxValueRequestParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.BoxValuesRequestParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.CompiledTeal.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.CoreAppCallArgs.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.CreateAppParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.RawAppCallArgs.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.TealTemplateParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.UpdateAppParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_asset_manager.AssetInformation.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_asset_manager.BulkAssetOptInOutResult.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_asset.AssetBulkOptInOutParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_asset.AssetOptInParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_asset.AssetOptOutParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_asset.CreateAssetParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_client_manager.AlgoSdkClients.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_client_manager.TypedAppClient.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_client_manager.TypedAppFactory.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_composer.BuiltTransactions.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_config.Config.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_debugging.AVMTracesEventData.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_debugging.TealSourceDebugEventData.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_debugging.TealSourcesDebugEventData.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_dispenser_client.DispenserFundResponse.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_dispenser_client.DispenserLimitResponse.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_dispenser_client.TestNetDispenserApiClientParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_indexer.LookupAssetHoldingsOptions.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_logic_error.LogicErrorDetails.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_network_client.AlgoClientConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_network_client.AlgoConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_network_client.NetworkDetails.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_testing.AlgoKitLogCaptureFixture.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_testing.AlgorandFixture.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_testing.AlgorandFixtureConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_testing.AlgorandTestAutomationContext.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_testing.GetTestAccountParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_testing.LogSnapshotConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.AtomicTransactionComposerToSend.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.ConfirmedTransactionResult.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.ConfirmedTransactionResults.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.SendAtomicTransactionComposerResults.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.SendParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.SendTransactionParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.SendTransactionResult.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.SendTransactionResults.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.TransactionGroupToSend.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.TransactionToSign.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transfer.AlgoRekeyParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transfer.AlgoTransferParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transfer.EnsureFundedParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transfer.EnsureFundedReturnType.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transfer.TransferAssetParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:index.indexer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:index.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:testing.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_account_manager_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_account_manager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_account.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algo_http_client_with_retry.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client_asset_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client_interface.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client_transaction_creator.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client_transaction_sender.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client_transfer_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_amount_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_amount.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_arc56.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_client_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_client.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_deployer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_factory_and_client_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_factory.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_manager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_asset_manager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_asset.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_async_event_emitter_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_async_event_emitter.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_client_manager_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_client_manager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_composer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_config.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_debugging.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_dispenser_client_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_dispenser_client.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_expand.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_indexer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_kmd_account_manager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_lifecycle_events.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_logging.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_logic_error.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_network_client.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_testing.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_transaction.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_transfer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:README.md
│ │ │ │ │ ├── algokit:utils:typescript:README.md
│ │ │ │ │ ├── algokit:utils:typescript:v7-migration.md
│ │ │ │ │ ├── algokit:utils:typescript:v8-migration.md
│ │ │ │ │ ├── ARCs:ARC-template.md
│ │ │ │ │ ├── ARCs:assets:arc-0012:README.md
│ │ │ │ │ ├── ARCs:assets:arc-0034:TemplateForm.md
│ │ │ │ │ ├── ARCs:assets:arc-0062:README.md
│ │ │ │ │ ├── ARCs:pages:nfts.md
│ │ │ │ │ ├── ARCs:pages:wallets.md
│ │ │ │ │ ├── ARCs:README.md
│ │ │ │ │ ├── ARCs:specs:arc-0000.md
│ │ │ │ │ ├── ARCs:specs:arc-0001.md
│ │ │ │ │ ├── ARCs:specs:arc-0002.md
│ │ │ │ │ ├── ARCs:specs:arc-0003.md
│ │ │ │ │ ├── ARCs:specs:arc-0004.md
│ │ │ │ │ ├── ARCs:specs:arc-0005.md
│ │ │ │ │ ├── ARCs:specs:arc-0006.md
│ │ │ │ │ ├── ARCs:specs:arc-0007.md
│ │ │ │ │ ├── ARCs:specs:arc-0008.md
│ │ │ │ │ ├── ARCs:specs:arc-0009.md
│ │ │ │ │ ├── ARCs:specs:arc-0010.md
│ │ │ │ │ ├── ARCs:specs:arc-0011.md
│ │ │ │ │ ├── ARCs:specs:arc-0012.md
│ │ │ │ │ ├── ARCs:specs:arc-0015.md
│ │ │ │ │ ├── ARCs:specs:arc-0016.md
│ │ │ │ │ ├── ARCs:specs:arc-0018.md
│ │ │ │ │ ├── ARCs:specs:arc-0019.md
│ │ │ │ │ ├── ARCs:specs:arc-0020.md
│ │ │ │ │ ├── ARCs:specs:arc-0021.md
│ │ │ │ │ ├── ARCs:specs:arc-0022.md
│ │ │ │ │ ├── ARCs:specs:arc-0023.md
│ │ │ │ │ ├── ARCs:specs:arc-0025.md
│ │ │ │ │ ├── ARCs:specs:arc-0026.md
│ │ │ │ │ ├── ARCs:specs:arc-0028.md
│ │ │ │ │ ├── ARCs:specs:arc-0032.md
│ │ │ │ │ ├── ARCs:specs:arc-0033.md
│ │ │ │ │ ├── ARCs:specs:arc-0034.md
│ │ │ │ │ ├── ARCs:specs:arc-0035.md
│ │ │ │ │ ├── ARCs:specs:arc-0036.md
│ │ │ │ │ ├── ARCs:specs:arc-0042.md
│ │ │ │ │ ├── ARCs:specs:arc-0047.md
│ │ │ │ │ ├── ARCs:specs:arc-0048.md
│ │ │ │ │ ├── ARCs:specs:arc-0049.md
│ │ │ │ │ ├── ARCs:specs:arc-0054.md
│ │ │ │ │ ├── ARCs:specs:arc-0055.md
│ │ │ │ │ ├── ARCs:specs:arc-0056.md
│ │ │ │ │ ├── ARCs:specs:arc-0059.md
│ │ │ │ │ ├── ARCs:specs:arc-0062.md
│ │ │ │ │ ├── ARCs:specs:arc-0065.md
│ │ │ │ │ ├── ARCs:specs:arc-0069.md
│ │ │ │ │ ├── ARCs:specs:arc-0072.md
│ │ │ │ │ ├── ARCs:specs:arc-0073.md
│ │ │ │ │ ├── ARCs:specs:arc-0074.md
│ │ │ │ │ ├── ARCs:specs:arc-0076.md
│ │ │ │ │ ├── ARCs:specs:arc-0078.md
│ │ │ │ │ ├── ARCs:specs:arc-0079.md
│ │ │ │ │ ├── ARCs:specs:arc-0200.md
│ │ │ │ │ ├── clis_index.md
│ │ │ │ │ ├── developer:docs:about.md
│ │ │ │ │ ├── developer:docs:clis:algokey:algokey.md
│ │ │ │ │ ├── developer:docs:clis:algokey:generate.md
│ │ │ │ │ ├── developer:docs:clis:algokey:import.md
│ │ │ │ │ ├── developer:docs:clis:algokey:multisig:append-auth-addr.md
│ │ │ │ │ ├── developer:docs:clis:algokey:multisig:multisig.md
│ │ │ │ │ ├── developer:docs:clis:algokey:part:info.md
│ │ │ │ │ ├── developer:docs:clis:algokey:part:part.md
│ │ │ │ │ ├── developer:docs:clis:algokey:part:reparent.md
│ │ │ │ │ ├── developer:docs:clis:algokey:sign.md
│ │ │ │ │ ├── developer:docs:clis:conduit:conduit.md
│ │ │ │ │ ├── developer:docs:clis:conduit:init.md
│ │ │ │ │ ├── developer:docs:clis:conduit:list:exporters.md
│ │ │ │ │ ├── developer:docs:clis:conduit:list:importers.md
│ │ │ │ │ ├── developer:docs:clis:conduit:list:list.md
│ │ │ │ │ ├── developer:docs:clis:conduit:list:processors.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:diagcfg.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:metric:disable.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:metric:enable.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:metric:metric.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:metric:status.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:telemetry:disable.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:telemetry:enable.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:telemetry:endpoint.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:telemetry:name.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:telemetry:status.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:telemetry:telemetry.md
│ │ │ │ │ ├── developer:docs:clis:goal:node:restart.md
│ │ │ │ │ ├── developer:docs:clis:goal:node:start.md
│ │ │ │ │ ├── developer:docs:clis:goal:node:status.md
│ │ │ │ │ ├── developer:docs:clis:goal:node:stop.md
│ │ │ │ │ ├── developer:docs:clis:goal:node:wait.md
│ │ │ │ │ ├── developer:docs:clis:goal:protocols.md
│ │ │ │ │ ├── developer:docs:clis:goal:report.md
│ │ │ │ │ ├── developer:docs:clis:goal:version.md
│ │ │ │ │ ├── developer:docs:clis:goal:wallet:list.md
│ │ │ │ │ ├── developer:docs:clis:goal:wallet:new.md
│ │ │ │ │ ├── developer:docs:clis:goal:wallet:wallet.md
│ │ │ │ │ ├── developer:docs:clis:indexer:api-config.md
│ │ │ │ │ ├── developer:docs:clis:indexer:daemon.md
│ │ │ │ │ ├── developer:docs:clis:indexer:indexer.md
│ │ │ │ │ ├── developer:docs:clis:indexer:util:util.md
│ │ │ │ │ ├── developer:docs:clis:indexer:util:validator.md
│ │ │ │ │ ├── developer:docs:clis:kmd.md
│ │ │ │ │ ├── developer:docs:clis:tealdbg:debug.md
│ │ │ │ │ ├── developer:docs:clis:tealdbg:remote.md
│ │ │ │ │ ├── developer:docs:clis:tealdbg:tealdbg.md
│ │ │ │ │ ├── developer:docs:details:accounts:create.md
│ │ │ │ │ ├── developer:docs:details:accounts:index.md
│ │ │ │ │ ├── developer:docs:details:accounts:rekey.md
│ │ │ │ │ ├── developer:docs:details:algorand_consensus.md
│ │ │ │ │ ├── developer:docs:details:algorand-networks:betanet.md
│ │ │ │ │ ├── developer:docs:details:algorand-networks:index.md
│ │ │ │ │ ├── developer:docs:details:algorand-networks:mainnet.md
│ │ │ │ │ ├── developer:docs:details:algorand-networks:testnet.md
│ │ │ │ │ ├── developer:docs:details:asa.md
│ │ │ │ │ ├── developer:docs:details:atc.md
│ │ │ │ │ ├── developer:docs:details:atomic_transfers.md
│ │ │ │ │ ├── developer:docs:details:conduit.md
│ │ │ │ │ ├── developer:docs:details:crust.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:guidelines.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:jsonspec.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v1.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v10.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v2.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v3.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v4.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v5.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v6.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v7.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v8.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v9.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:specification.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:ABI:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:apps:create.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:apps:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:apps:innertx.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:apps:state.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:apps:txs.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:debugging.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:frontend:apps.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:frontend:smartsigs.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:guidelines.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:smartsigs:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:smartsigs:modes.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:smartsigs:walkthrough.md
│ │ │ │ │ ├── developer:docs:details:dapps:writing-contracts:beaker.md
│ │ │ │ │ ├── developer:docs:details:dapps:writing-contracts:pyteal.md
│ │ │ │ │ ├── developer:docs:details:dapps:writing-contracts:python.md
│ │ │ │ │ ├── developer:docs:details:encoding.md
│ │ │ │ │ ├── developer:docs:details:ethereum_to_algorand.md
│ │ │ │ │ ├── developer:docs:details:index.md
│ │ │ │ │ ├── developer:docs:details:indexer.md
│ │ │ │ │ ├── developer:docs:details:parameter_tables.md
│ │ │ │ │ ├── developer:docs:details:stateproofs:index.md
│ │ │ │ │ ├── developer:docs:details:stateproofs:light_client.md
│ │ │ │ │ ├── developer:docs:details:technical_faq.md
│ │ │ │ │ ├── developer:docs:details:transactions:index.md
│ │ │ │ │ ├── developer:docs:details:transactions:offline_transactions.md
│ │ │ │ │ ├── developer:docs:details:transactions:payment_prompts.md
│ │ │ │ │ ├── developer:docs:details:transactions:signatures.md
│ │ │ │ │ ├── developer:docs:details:transactions:transactions.md
│ │ │ │ │ ├── developer:docs:details:useful_resources.md
│ │ │ │ │ ├── developer:docs:get-started:algokit.md
│ │ │ │ │ ├── developer:docs:get-started:basics:what_is_blockchain.md
│ │ │ │ │ ├── developer:docs:get-started:basics:whats_a_dapp.md
│ │ │ │ │ ├── developer:docs:get-started:basics:where_to_start.md
│ │ │ │ │ ├── developer:docs:get-started:basics:why_algorand.md
│ │ │ │ │ ├── developer:docs:get-started:tokenization:ft.md
│ │ │ │ │ ├── developer:docs:get-started:tokenization:nft.md
│ │ │ │ │ ├── developer:docs:index.md
│ │ │ │ │ ├── developer:docs:rest-apis:algod.md
│ │ │ │ │ ├── developer:docs:rest-apis:indexer.md
│ │ │ │ │ ├── developer:docs:rest-apis:kmd.md
│ │ │ │ │ ├── developer:docs:rest-apis:restendpoints.md
│ │ │ │ │ ├── developer:docs:run-a-node:operations:catchup.md
│ │ │ │ │ ├── developer:docs:run-a-node:operations:switch_networks.md
│ │ │ │ │ ├── developer:docs:run-a-node:participate:generate_keys.md
│ │ │ │ │ ├── developer:docs:run-a-node:participate:index.md
│ │ │ │ │ ├── developer:docs:run-a-node:participate:offline.md
│ │ │ │ │ ├── developer:docs:run-a-node:participate:online.md
│ │ │ │ │ ├── developer:docs:run-a-node:participate:renew.md
│ │ │ │ │ ├── developer:docs:run-a-node:reference:artifacts.md
│ │ │ │ │ ├── developer:docs:run-a-node:reference:config.md
│ │ │ │ │ ├── developer:docs:run-a-node:reference:relay.md
│ │ │ │ │ ├── developer:docs:run-a-node:reference:telemetry-config.md
│ │ │ │ │ ├── developer:docs:run-a-node:setup:indexer.md
│ │ │ │ │ ├── developer:docs:run-a-node:setup:install.md
│ │ │ │ │ ├── developer:docs:run-a-node:setup:node-troubleshooting.md
│ │ │ │ │ ├── developer:docs:run-a-node:setup:types.md
│ │ │ │ │ ├── developer:docs:sdks:go:index.md
│ │ │ │ │ ├── developer:docs:sdks:index.md
│ │ │ │ │ ├── developer:docs:sdks:java:index.md
│ │ │ │ │ ├── developer:docs:sdks:javascript:index.md
│ │ │ │ │ ├── developer:docs:sdks:python:index.md
│ │ │ │ │ ├── developer:python:code:example:accounts.md
│ │ │ │ │ ├── developer:python:code:example:arc4_types.md
│ │ │ │ │ ├── developer:python:code:example:assets.md
│ │ │ │ │ ├── developer:python:code:example:box_storage.md
│ │ │ │ │ ├── developer:python:code:example:control_flow.md
│ │ │ │ │ ├── developer:python:code:example:crypto:merkle_tree.md
│ │ │ │ │ ├── developer:python:code:example:defi:amm.md
│ │ │ │ │ ├── developer:python:code:example:defi:auction.md
│ │ │ │ │ ├── developer:python:code:example:defi:htlc_logicsig.md
│ │ │ │ │ ├── developer:python:code:example:defi:marketplace.md
│ │ │ │ │ ├── developer:python:code:example:events:arc28_events.md
│ │ │ │ │ ├── developer:python:code:example:global_storage.md
│ │ │ │ │ ├── developer:python:code:example:governance:simple_voting.md
│ │ │ │ │ ├── developer:python:code:example:hello_world.md
│ │ │ │ │ ├── developer:python:code:example:inner_transactions.md
│ │ │ │ │ ├── developer:python:code:example:local_storage.md
│ │ │ │ │ ├── developer:python:code:example:nft:proof_of_attendance.md
│ │ │ │ │ ├── developer:python:code:example:privacy:zk_whitelist.md
│ │ │ │ │ ├── developer:python:code:example:scratch_storage.md
│ │ │ │ │ ├── developer:python:code:example:self_payment.md
│ │ │ │ │ ├── developer:python:code:example:struct_in_box.md
│ │ │ │ │ ├── developer:python:code:example:subsidize_app_call.md
│ │ │ │ │ ├── developer:python:code:example:transactions.md
│ │ │ │ │ ├── developer:python:code:example:utility:calculator.md
│ │ │ │ │ ├── devportal-code-examples:projects:python-contract-examples:README.md
│ │ │ │ │ ├── devportal-code-examples:README.md
│ │ │ │ │ ├── docs:.walletconnect:index.md
│ │ │ │ │ ├── docs:.walletconnect:walletconnect-schema.md
│ │ │ │ │ ├── docs:README.md
│ │ │ │ │ ├── docs:scripts:example_tracker:example_list.md
│ │ │ │ │ ├── docs:scripts:README.md
│ │ │ │ │ ├── index.md
│ │ │ │ │ ├── liquid_auth_index.md
│ │ │ │ │ ├── liquid-auth:ARCHITECTURE.md
│ │ │ │ │ ├── liquid-auth:decisions:1-Service-Authentication.md
│ │ │ │ │ ├── liquid-auth:decisions:2-Bidirectional-Communication.md
│ │ │ │ │ ├── liquid-auth:decisions:3-Peer-to-Peer-Signaling.md
│ │ │ │ │ ├── liquid-auth:decisions:4-Fido-Extension.md
│ │ │ │ │ ├── liquid-auth:decisions:README.md
│ │ │ │ │ ├── liquid-auth:docs:architecture.md
│ │ │ │ │ ├── liquid-auth:docs:clients:android:provider-service:authenticate.md
│ │ │ │ │ ├── liquid-auth:docs:clients:android:provider-service:register.md
│ │ │ │ │ ├── liquid-auth:docs:clients:browser:authentication.md
│ │ │ │ │ ├── liquid-auth:docs:clients:browser:example.md
│ │ │ │ │ ├── liquid-auth:docs:introduction.md
│ │ │ │ │ ├── liquid-auth:docs:README.md
│ │ │ │ │ ├── liquid-auth:docs:server:environment-variables.md
│ │ │ │ │ ├── liquid-auth:docs:server:integrations.md
│ │ │ │ │ ├── liquid-auth:docs:server:introduction.md
│ │ │ │ │ ├── liquid-auth:docs:server:running-locally.md
│ │ │ │ │ ├── liquid-auth:README.md
│ │ │ │ │ ├── liquid-auth:SEQUENCE.md
│ │ │ │ │ ├── liquid-auth:services:liquid-auth-api-js:src:assertion:assertion.controller.post.request.md
│ │ │ │ │ ├── liquid-auth:services:liquid-auth-api-js:src:assertion:assertion.controller.post.response.md
│ │ │ │ │ ├── liquid-auth:services:liquid-auth-api-js:src:attestation:attestation.controller.post.request.md
│ │ │ │ │ ├── liquid-auth:services:liquid-auth-api-js:src:auth:auth.controller.get.user.md
│ │ │ │ │ ├── liquid-auth:sites:express-dapp:README.md
│ │ │ │ │ ├── liquid-auth:VISION.md
│ │ │ │ │ ├── puya_index.md
│ │ │ │ │ ├── puya:docs:algopy_testing:index.md
│ │ │ │ │ ├── puya:docs:api-algopy.arc4.md
│ │ │ │ │ ├── puya:docs:api-algopy.gtxn.md
│ │ │ │ │ ├── puya:docs:api-algopy.itxn.md
│ │ │ │ │ ├── puya:docs:api-algopy.md
│ │ │ │ │ ├── puya:docs:api-algopy.op.md
│ │ │ │ │ ├── puya:docs:api.md
│ │ │ │ │ ├── puya:docs:compiler.md
│ │ │ │ │ ├── puya:docs:index.md
│ │ │ │ │ ├── puya:docs:language-guide.md
│ │ │ │ │ ├── puya:docs:lg-arc28.md
│ │ │ │ │ ├── puya:docs:lg-arc4.md
│ │ │ │ │ ├── puya:docs:lg-builtins.md
│ │ │ │ │ ├── puya:docs:lg-calling-apps.md
│ │ │ │ │ ├── puya:docs:lg-compile.md
│ │ │ │ │ ├── puya:docs:lg-control.md
│ │ │ │ │ ├── puya:docs:lg-errors.md
│ │ │ │ │ ├── puya:docs:lg-logs.md
│ │ │ │ │ ├── puya:docs:lg-modules.md
│ │ │ │ │ ├── puya:docs:lg-opcode-budget.md
│ │ │ │ │ ├── puya:docs:lg-ops.md
│ │ │ │ │ ├── puya:docs:lg-storage.md
│ │ │ │ │ ├── puya:docs:lg-structure.md
│ │ │ │ │ ├── puya:docs:lg-transactions.md
│ │ │ │ │ ├── puya:docs:lg-types.md
│ │ │ │ │ ├── puya:docs:lg-unsupported-python-features.md
│ │ │ │ │ ├── puya:docs:principles.md
│ │ │ │ │ ├── puya:examples:auction:README.md
│ │ │ │ │ ├── puya:python:testing:docs:algopy.md
│ │ │ │ │ ├── puya:python:testing:docs:api.md
│ │ │ │ │ ├── puya:python:testing:docs:coverage.md
│ │ │ │ │ ├── puya:python:testing:docs:examples.md
│ │ │ │ │ ├── puya:python:testing:docs:faq.md
│ │ │ │ │ ├── puya:python:testing:docs:index.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:arc4-types.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:avm-types.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:concepts.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:contract-testing.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:index.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:opcodes.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:signature-testing.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:state-management.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:subroutines.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:transactions.md
│ │ │ │ │ ├── puya:python:testing:examples:README.md
│ │ │ │ │ ├── puya:python:testing:README.md
│ │ │ │ │ ├── puya:README.md
│ │ │ │ │ ├── puya:src:puya:ARCHITECTURE.md
│ │ │ │ │ ├── puya:src:puyapy:_typeshed:README.md
│ │ │ │ │ ├── puya:src:puyapy:_vendor:mypy:typeshed:stdlib:_typeshed:README.md
│ │ │ │ │ ├── puya:src:puyapy:awst_build:README.md
│ │ │ │ │ ├── puya:stubs:README.md
│ │ │ │ │ ├── puya:tests:test_expected_output:README.md
│ │ │ │ │ ├── puya:typescript:docs:architecture-decisions:2024-05-21_primitive-bytes-and-strings.md
│ │ │ │ │ ├── puya:typescript:docs:architecture-decisions:2024-05-21_primitive-integer-types.md
│ │ │ │ │ ├── puya:typescript:docs:README.md
│ │ │ │ │ ├── puya:typescript:packages:algo-ts:readme.md
│ │ │ │ │ ├── puya:typescript:README.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIAddressType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIArrayDynamicType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIArrayStaticType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIBoolType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIByteType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIContract.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIInterface.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIMethod.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIStringType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABITupleType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIUfixedType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIUintType.md
│ │ │ │ │ ├── SDKs:javascript:classes:Algodv2.md
│ │ │ │ │ ├── SDKs:javascript:classes:AtomicTransactionComposer.md
│ │ │ │ │ ├── SDKs:javascript:classes:DryrunResult.md
│ │ │ │ │ ├── SDKs:javascript:classes:Indexer.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.Account.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AccountParticipation.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AccountResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AccountsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AccountStateDelta.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.Application.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationLocalState.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationLocalStatesResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationLogData.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationLogsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationParams.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationStateSchema.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.Asset.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AssetBalancesResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AssetHolding.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AssetHoldingsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AssetParams.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AssetResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AssetsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.Block.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.BlockRewards.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.BlockUpgradeState.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.BlockUpgradeVote.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.Box.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.BoxDescriptor.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.BoxesResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ErrorResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.EvalDelta.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.EvalDeltaKeyValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.HashFactory.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.HealthCheck.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.IndexerStateProofMessage.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.MerkleArrayProof.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.MiniAssetHolding.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ParticipationUpdates.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofFields.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofParticipant.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofReveal.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofSignature.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofSigSlot.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofTracking.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofVerifier.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateSchema.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TealKeyValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TealValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.Transaction.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionApplication.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionAssetConfig.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionAssetFreeze.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionAssetTransfer.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionKeyreg.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionPayment.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionSignature.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionSignatureLogicsig.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionSignatureMultisig.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionSignatureMultisigSubsignature.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionStateProof.md
│ │ │ │ │ ├── SDKs:javascript:classes:Kmd.md
│ │ │ │ │ ├── SDKs:javascript:classes:LogicSig.md
│ │ │ │ │ ├── SDKs:javascript:classes:LogicSigAccount.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.Account.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AccountApplicationResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AccountAssetHolding.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AccountAssetResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AccountAssetsInformationResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AccountParticipation.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AccountStateDelta.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AppCallLogs.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.Application.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationInitialStates.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationKVStorage.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationLocalReference.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationLocalState.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationParams.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationStateOperation.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationStateSchema.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.Asset.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AssetHolding.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AssetHoldingReference.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AssetParams.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AvmKeyValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AvmValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BlockHashResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BlockLogsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BlockResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BlockTxidsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.Box.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BoxDescriptor.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BoxesResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BoxReference.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BuildVersion.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.CompileResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.DisassembleResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.DryrunRequest.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.DryrunResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.DryrunSource.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.DryrunState.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.DryrunTxnResult.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ErrorResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.EvalDelta.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.EvalDeltaKeyValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.GetBlockTimeStampOffsetResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.GetSyncRoundResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.KvDelta.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.LedgerStateDeltaForTransactionGroup.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.LightBlockHeaderProof.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.NodeStatusResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.PendingTransactionResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.PendingTransactionsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.PostTransactionsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ScratchChange.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateInitialStates.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateRequest.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateRequestTransactionGroup.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateTraceConfig.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateTransactionGroupResult.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateTransactionResult.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateUnnamedResourcesAccessed.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulationEvalOverrides.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulationOpcodeTraceUnit.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulationTransactionExecTrace.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.StateProof.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.StateProofMessage.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SupplyResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.TealKeyValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.TealValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.TransactionGroupLedgerStateDeltasForRoundResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.TransactionParametersResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.TransactionProofResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.Version.md
│ │ │ │ │ ├── SDKs:javascript:classes:SourceMap.md
│ │ │ │ │ ├── SDKs:javascript:classes:Transaction.md
│ │ │ │ │ ├── SDKs:javascript:enums:ABIReferenceType.md
│ │ │ │ │ ├── SDKs:javascript:enums:ABITransactionType.md
│ │ │ │ │ ├── SDKs:javascript:enums:AtomicTransactionComposerStatus.md
│ │ │ │ │ ├── SDKs:javascript:enums:IntDecoding.md
│ │ │ │ │ ├── SDKs:javascript:enums:OnApplicationComplete.md
│ │ │ │ │ ├── SDKs:javascript:enums:TransactionType.md
│ │ │ │ │ ├── SDKs:javascript:examples:README.md
│ │ │ │ │ ├── SDKs:javascript:FAQ.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIContractNetworkInfo.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIContractNetworks.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIContractParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIInterfaceParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIMethodArgParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIMethodParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIMethodReturnParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIResult.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:Account.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:Address.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:AlgodTokenHeader.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:BaseHTTPClient.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:BaseHTTPClientError.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:BaseHTTPClientResponse.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:BoxReference.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:CustomTokenHeader.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedAssetParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedBoxReference.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedGlobalStateSchema.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedLocalStateSchema.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedLogicSig.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedLogicSigAccount.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedMultisig.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedSignedTransaction.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedSubsig.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedTransaction.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:IndexerTokenHeader.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:KMDTokenHeader.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:MultisigMetadata.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:SignedTransaction.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:SuggestedParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:TransactionParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:TransactionWithSigner.md
│ │ │ │ │ ├── SDKs:javascript:modules:indexerModels.md
│ │ │ │ │ ├── SDKs:javascript:modules:modelsv2.md
│ │ │ │ │ ├── SDKs:javascript:modules.md
│ │ │ │ │ ├── SDKs:javascript:README.md
│ │ │ │ │ ├── SDKs:python:algosdk:v2client:harness:README.md
│ │ │ │ │ ├── SDKs:python:examples:README.md
│ │ │ │ │ ├── SDKs:python:README.md
│ │ │ │ │ ├── tealscript:examples_amm_README.md
│ │ │ │ │ ├── tealscript:examples_auction_README.md
│ │ │ │ │ ├── tealscript:examples_big_box_README.md
│ │ │ │ │ ├── tealscript:examples_itxns_README.md
│ │ │ │ │ ├── tealscript:examples_lsig_with_app_README.md
│ │ │ │ │ ├── tealscript:examples_reti_README.md
│ │ │ │ │ ├── tealscript:FEATURES.md
│ │ │ │ │ ├── tealscript:guides_atomic_txn.md
│ │ │ │ │ ├── tealscript:guides_features.md
│ │ │ │ │ ├── tealscript:guides_getting_started.md
│ │ │ │ │ ├── tealscript:guides_inner_transactions.md
│ │ │ │ │ ├── tealscript:guides_lifecycle.md
│ │ │ │ │ ├── tealscript:guides_math.md
│ │ │ │ │ ├── tealscript:guides_methods.md
│ │ │ │ │ ├── tealscript:guides_multiple_contracts.md
│ │ │ │ │ ├── tealscript:guides_pyteal.md
│ │ │ │ │ ├── tealscript:guides_storage.md
│ │ │ │ │ ├── tealscript:guides_Supported Types_arrays.md
│ │ │ │ │ ├── tealscript:guides_Supported Types_numbers.md
│ │ │ │ │ ├── TEALScript:README.md
│ │ │ │ │ ├── tealscript:tests_test_package_README.md
│ │ │ │ │ ├── tealscript:tutorials_Hello World_0001-intro.md
│ │ │ │ │ ├── tealscript:tutorials_Hello World_0002-init.md
│ │ │ │ │ ├── tealscript:tutorials_Hello World_0003-contract.md
│ │ │ │ │ ├── tealscript:tutorials_Hello World_0004-artifacts.md
│ │ │ │ │ ├── tealscript:tutorials_Hello World_0005-hello.md
│ │ │ │ │ └── tealscript:tutorials_Hello World_0006-test.md
│ │ │ │ └── taxonomy-categories
│ │ │ │ ├── algokit-utils.json
│ │ │ │ ├── algokit.json
│ │ │ │ ├── arcs.json
│ │ │ │ ├── clis.json
│ │ │ │ ├── details.json
│ │ │ │ ├── developers.json
│ │ │ │ ├── liquid-auth.json
│ │ │ │ ├── nodes.json
│ │ │ │ ├── puya.json
│ │ │ │ ├── python.json
│ │ │ │ ├── sdks.json
│ │ │ │ └── tealscript.json
│ │ │ └── wallet
│ │ │ └── index.ts
│ │ ├── tools
│ │ │ ├── accountManager.ts
│ │ │ ├── algodManager.ts
│ │ │ ├── apiManager
│ │ │ │ ├── algod
│ │ │ │ │ ├── account.ts
│ │ │ │ │ ├── application.ts
│ │ │ │ │ ├── asset.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── transaction.ts
│ │ │ │ ├── example
│ │ │ │ │ ├── get-balance.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── indexer
│ │ │ │ │ ├── account.ts
│ │ │ │ │ ├── application.ts
│ │ │ │ │ ├── asset.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── transaction.ts
│ │ │ │ ├── nfd
│ │ │ │ │ └── index.ts
│ │ │ │ ├── tinyman
│ │ │ │ │ ├── analytics.ts
│ │ │ │ │ ├── bootstrap.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── liquidity.ts
│ │ │ │ │ ├── opt_in.ts
│ │ │ │ │ ├── pool.ts
│ │ │ │ │ ├── remove_liquidity.ts
│ │ │ │ │ └── swap.ts
│ │ │ │ ├── ultrade
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── market.ts
│ │ │ │ │ ├── system.ts
│ │ │ │ │ └── wallet.ts
│ │ │ │ └── vestige
│ │ │ │ ├── assets.ts
│ │ │ │ ├── balances.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── networks.ts
│ │ │ │ ├── notes.ts
│ │ │ │ ├── pools.ts
│ │ │ │ ├── protocols.ts
│ │ │ │ ├── swaps.ts
│ │ │ │ └── vaults.ts
│ │ │ ├── arc26Manager.ts
│ │ │ ├── index.ts
│ │ │ ├── knowledgeManager.ts
│ │ │ ├── transactionManager
│ │ │ │ ├── accountTransactions.ts
│ │ │ │ ├── appTransactions
│ │ │ │ │ ├── callTxn.ts
│ │ │ │ │ ├── clearTxn.ts
│ │ │ │ │ ├── closeOutTxn.ts
│ │ │ │ │ ├── createTxn.ts
│ │ │ │ │ ├── deleteTxn.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── optInTxn.ts
│ │ │ │ │ ├── test
│ │ │ │ │ │ ├── counter_approval.teal
│ │ │ │ │ │ ├── counter_clear.teal
│ │ │ │ │ │ ├── storage_test_approval_v2.teal
│ │ │ │ │ │ ├── storage_test_approval.teal
│ │ │ │ │ │ └── storage_test_clear.teal
│ │ │ │ │ ├── types.ts
│ │ │ │ │ └── updateTxn.ts
│ │ │ │ ├── assetTransactions.ts
│ │ │ │ ├── generalTransaction.ts
│ │ │ │ └── index.ts
│ │ │ └── utilityManager.ts
│ │ ├── types.ts
│ │ └── utils
│ │ └── responseProcessor.ts
│ ├── tests
│ │ ├── resources
│ │ │ ├── algod
│ │ │ │ ├── account.test.ts
│ │ │ │ ├── application.test.ts
│ │ │ │ ├── asset.test.ts
│ │ │ │ └── transaction.test.ts
│ │ │ └── indexer
│ │ │ ├── account.test.ts
│ │ │ ├── application.test.ts
│ │ │ ├── asset.test.ts
│ │ │ └── transaction.test.ts
│ │ └── tools
│ │ ├── accountManager.test.ts
│ │ ├── algodManager.test.ts
│ │ ├── apiManager
│ │ │ └── example
│ │ │ └── get-balance.test.ts
│ │ ├── transactionManager
│ │ │ ├── accountTransactionManager.test.ts
│ │ │ ├── appTransactionManager.test.ts
│ │ │ ├── assetTransactionManager.test.ts
│ │ │ ├── generalTransactionManager.test.ts
│ │ │ └── transactionManager.test.ts
│ │ └── utilityManager.test.ts
│ └── tsconfig.json
├── README.md
├── rename_files.sh
└── tsconfig.json
```
# Files
--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/ARCs:specs:arc-0062.md:
--------------------------------------------------------------------------------
```markdown
1 | ---
2 | arc: 62
3 | title: ASA Circulating Supply
4 | description: Getter method for ASA circulating supply
5 | author: Cosimo Bassi (@cusma)
6 | discussions-to: https://github.com/algorandfoundation/ARCs/issues/302
7 | status: Final
8 | type: Standards Track
9 | category: Interface
10 | sub-category: Asa
11 | created: 2024-06-12
12 | requires: 2, 4, 22
13 | ---
14 |
15 | ## Abstract
16 |
17 | This ARC introduces a standard for the definition of circulating supply for Algorand
18 | Standard Assets (ASA) and its client-side retrieval. A reference implementation is
19 | suggested.
20 |
21 | ## Motivation
22 |
23 | Algorand Standard Asset (ASA) `total` supply is _defined_ upon ASA creation.
24 |
25 | Creating an ASA on the ledger _does not_ imply its `total` supply is immediately
26 | “minted” or “circulating”. In fact, the semantic of token “minting” on Algorand is
27 | slightly different from other blockchains: it is not coincident with the token units
28 | creation on the ledger.
29 |
30 | The Reserve Address, one of the 4 addresses of ASA Role-Based-Access-Control (RBAC),
31 | is conventionally used to identify the portion of `total` supply not yet in circulation.
32 | The Reserve Address has no “privilege” over the token: it is just a “logical” label
33 | used (client-side) to classify an existing amount of ASA as “not in circulation”.
34 |
35 | According to this convention, “minting” an amount of ASA units is equivalent to
36 | _moving that amount out of the Reserve Address_.
37 |
38 | > ASA may have the Reserve Address assigned to a Smart Contract to enforce specific
39 | > “minting” policies, if needed.
40 |
41 | This convention led to a simple and unsophisticated semantic of ASA circulating
42 | supply, widely adopted by clients (wallets, explorers, etc.) to provide standard
43 | information:
44 |
45 | ```text
46 | circulating_supply = total - reserve_balance
47 | ```
48 |
49 | Where `reserve_balance` is the ASA balance hold by the Reserve Address.
50 |
51 | However, the simplicity of such convention, who fostered adoption across the Algorand
52 | ecosystem, poses some limitations. Complex and sophisticated use-cases of ASA, such
53 | as regulated stable-coins and tokenized securities among others, require more
54 | detailed and expressive definitions of circulating supply.
55 |
56 | As an example, an ASA could have “burned”, “locked” or “pre-minted” amounts of token,
57 | not held in the Reserve Address, which _should not_ be considered as “circulating”
58 | supply. This is not possible with the basic ASA protocol convention.
59 |
60 | This ARC proposes a standard ABI _read-only_ method (getter) to provide the circulating
61 | supply of an ASA.
62 |
63 | ## Specification
64 |
65 | The keywords "**MUST**", "**MUST NOT**", "**REQUIRED**", "**SHALL**", "**SHALL NOT**",
66 | "**SHOULD**", "**SHOULD NOT**", "**RECOMMENDED**", "**MAY**", and "**OPTIONAL**"
67 | in this document are to be interpreted as described in <a href="https://datatracker.ietf.org/doc/html/rfc2119">RFC 2119</a>.
68 |
69 | > Notes like this are non-normative.
70 |
71 | ### ABI Method
72 |
73 | A compliant ASA, whose circulating supply definition conforms to this ARC, **MUST**
74 | implement the following method on an Application (referred as _Circulating Supply
75 | App_ in this specification):
76 |
77 | ```json
78 | {
79 | "name": "arc62_get_circulating_supply",
80 | "readonly": true,
81 | "args": [
82 | {
83 | "type": "uint64",
84 | "name": "asset_id",
85 | "desc": "ASA ID of the circulating supply"
86 | }
87 | ],
88 | "returns": {
89 | "type": "uint64",
90 | "desc": "ASA circulating supply"
91 | },
92 | "desc": "Get ASA circulating supply"
93 | }
94 | ```
95 |
96 | The `arc62_get_circulating_supply` **MUST** be a _read-only_ ([ARC-22](./arc-0022.md))
97 | method (getter).
98 |
99 | ### Usage
100 |
101 | Getter calls **SHOULD** be _simulated_.
102 |
103 | Any external resources used by the implementation **SHOULD** be discovered and
104 | auto-populated by the simulated getter call.
105 |
106 | #### Example 1
107 |
108 | > Let the ASA have `total` supply and a Reserve Address (i.e. not set to `ZeroAddress`).
109 | >
110 | > Let the Reserve Address be assigned to an account different from the Circulating
111 | > Supply App Account.
112 | >
113 | > Let `burned` be an external Burned Address dedicated to ASA burned supply.
114 | >
115 | > Let `locked` be an external Locked Address dedicated to ASA locked supply.
116 | >
117 | > The ASA issuer defines the _circulating supply_ as:
118 | >
119 | > ```text
120 | > circulating_supply = total - reserve_balance - burned_balance - locked_balance
121 | > ```
122 | >
123 | > In this case the simulated read-only method call would auto-populate 1 external
124 | > reference for the ASA and 3 external reference accounts (Reserve, Burned and Locked).
125 |
126 | #### Example 2
127 |
128 | > Let the ASA have `total` supply and _no_ Reserve Address (i.e. set to `ZeroAddress`).
129 | >
130 | > Let `non_circulating_amount` be a UInt64 Global Var defined by the implementation
131 | > of the Circulating Supply App.
132 | >
133 | > The ASA issuer defines the _circulating supply_ as:
134 | >
135 | > ```text
136 | > circulating_supply = total - non_circulating_amount
137 | > ```
138 | >
139 | > In this case the simulated read-only method call would auto-populate just 1 external
140 | > reference for the ASA.
141 |
142 | ### Circulating Supply Application discovery
143 |
144 | > Given an ASA ID, clients (wallet, explorer, etc.) need to discover the related
145 | > Circulating Supply App.
146 |
147 | An ASA conforming to this ARC **MUST** specify the Circulating Supply App ID.
148 |
149 | > To avoid ecosystem fragmentation this ARC does not propose any new method to specify
150 | > the metadata of an ASA. Instead, it only extends already existing standards.
151 |
152 | If the ASA also conforms to any ARC that supports additional `properties` ([ARC-3](./arc-0003.md),
153 | [ARC-19](./arc-0019.md), [ARC-69](./arc-0069.md)),
154 | then it **MUST** include a `arc-62` key and set the corresponding value to a map,
155 | including the ID of the Circulating Supply App as a value for the key `application-id`.
156 |
157 | #### Example
158 |
159 | ```json
160 | {
161 | //...
162 | "properties": {
163 | //...
164 | "arc-62": {
165 | "application-id": 123
166 | }
167 | }
168 | //...
169 | }
170 | ```
171 |
172 | ## Rationale
173 |
174 | The definition of _circulating supply_ for sophisticated use-cases is usually ASA-specific.
175 | It could involve, for example, complex math or external accounts’ balances, variables
176 | stored in boxes or in global state, etc..
177 |
178 | For this reason, the proposed method’s signature does not require any reference
179 | to external resources, a part form the `asset_id` of the ASA for which the circulating
180 | supply is defined.
181 |
182 | Eventual external resources can be discovered and auto-populated directly by the
183 | simulated method call.
184 |
185 | The rational of this design choice is avoiding fragmentation and integration overhead
186 | for clients (wallets, explorers, etc.).
187 |
188 | Clients just need to know:
189 |
190 | 1. The ASA ID;
191 | 1. The Circulating Supply App ID implementing the `arc62_get_circulating_supply`
192 | method for that ASA.
193 |
194 | ## Backwards Compatibility
195 |
196 | Existing ASA willing to conform to this ARC **MUST** specify the Circulating Supply
197 | App ID as [ARC-2](./arc-0002.md) `AssetConfig` transaction note field, as follows:
198 |
199 | - The `<arc-number>` **MUST** be equal to `62`;
200 | - The **RECOMMENDED** `<data-format>` are <a href="https://msgpack.org/">MsgPack</a>
201 | (`m`) or <a href="https://www.json.org/json-en.html">JSON</a> (`j`);
202 | - The `<data>` **MUST** specify `application-id` equal to the Circulating Supply
203 | App ID.
204 |
205 | > **WARNING**: To preserve the existing ASA RBAC (e.g. Manager Address, Freeze Address,
206 | > etc.) it is necessary to **include all the existing role addresses** in the `AssetConfig`.
207 | > Not doing so would irreversibly disable the RBAC roles!
208 |
209 | ### Example - JSON without version
210 |
211 | ```text
212 | arc62:j{"application-id":123}
213 | ```
214 |
215 | ## Reference Implementation
216 |
217 | > This section is non-normative.
218 |
219 | This section suggests a reference implementation of the Circulating Supply App.
220 |
221 | An Algorand-Python example is available [here](../assets/arc-0062).
222 |
223 | ### Recommendations
224 |
225 | An ASA using the reference implementation **SHOULD NOT** assign the Reserve Address
226 | to the Circulating Supply App Account.
227 |
228 | A reference implementation **SHOULD** target a version of the AVM that supports
229 | foreign resources pooling (version 9 or greater).
230 |
231 | A reference implementation **SHOULD** use 3 external addresses, in addition to the
232 | Reserve Address, to define the not circulating supply.
233 |
234 | The **RECOMMENDED** labels for not-circulating balances are: `burned`, `locked`
235 | and `generic`.
236 |
237 | > To change the labels of not circulating addresses is sufficient to rename the
238 | > following constants just in `smart_contracts/circulating_supply/config.py`:
239 | > ```python
240 | > NOT_CIRCULATING_LABEL_1: Final[str] = "burned"
241 | > NOT_CIRCULATING_LABEL_2: Final[str] = "locked"
242 | > NOT_CIRCULATING_LABEL_3: Final[str] = "generic"
243 | > ```
244 |
245 | ### State Schema
246 |
247 | A reference implementation **SHOULD** allocate, at least, the following Global State
248 | variables:
249 |
250 | - `asset_id` as UInt64, initialized to `0` and set **only once** by the ASA Manager
251 | Address;
252 | - Not circulating address 1 (`burned`) as Bytes, initialized to the Global `Zero Address`
253 | and set by the ASA Manager Address;
254 | - Not circulating address 2 (`locked`) as Bytes, initialized to the Global `Zero Address`
255 | and set by the ASA Manager Address;
256 | - Not circulating address 3 (`generic`) as Bytes, initialized to the Global `Zero Address`
257 | and set by the ASA Manager Address.
258 |
259 | A reference implementation **SHOULD** enforce that, upon setting `burned`, `locked`
260 | and `generic` addresses, the latter already opted-in the `asset_id`.
261 |
262 | ```json
263 | "state": {
264 | "global": {
265 | "num_byte_slices": 3,
266 | "num_uints": 1
267 | },
268 | "local": {
269 | "num_byte_slices": 0,
270 | "num_uints": 0
271 | }
272 | },
273 | "schema": {
274 | "global": {
275 | "declared": {
276 | "asset_id": {
277 | "type": "uint64",
278 | "key": "asset_id"
279 | },
280 | "not_circulating_label_1": {
281 | "type": "bytes",
282 | "key": "burned"
283 | },
284 | "not_circulating_label_2": {
285 | "type": "bytes",
286 | "key": "locked"
287 | },
288 | "not_circulating_label_3": {
289 | "type": "bytes",
290 | "key": "generic"
291 | }
292 | },
293 | "reserved": {}
294 | },
295 | "local": {
296 | "declared": {},
297 | "reserved": {}
298 | }
299 | },
300 | ```
301 |
302 | ### Circulating Supply Getter
303 |
304 | A reference implementation **SHOULD** enforce that the `asset_id` Global Variable
305 | is equal to the `asset_id` argument of the `arc62_get_circulating_supply` getter
306 | method.
307 |
308 | > Alternatively the reference implementation could ignore the `asset_id` argument
309 | > and use directly the `asset_id` Global Variable.
310 |
311 | A reference implementation **SHOULD** return the ASA _circulating supply_ as:
312 |
313 | ```text
314 | circulating_supply = total - reserve_balance - burned_balance - locked_balance - generic_balance
315 | ```
316 |
317 | Where:
318 |
319 | - `total` is the total supply of the ASA (`asset_id`);
320 | - `reserve_balance` is the ASA balance hold by the Reserve Address or `0` if the
321 | address is set to the Global `ZeroAddress` or not opted-in `asset_id`;
322 | - `burned_balance` is the ASA balance hold by the Burned Address or `0` if the address
323 | is set to the Global `ZeroAddress` or is not opted-in `asset_id`;
324 | - `locked_balance` is the ASA balance hold by the Locked Address or `0` if the address
325 | is set to the Global `ZeroAddress` or not opted-in `asset_id`;
326 | - `generic_balance` is the ASA balance hold by a Generic Address or `0` if the address
327 | is set to the Global `ZeroAddress` or not opted-in `asset_id`.
328 |
329 | ## Security Considerations
330 |
331 | Permissions over the Circulating Supply App setting and update **SHOULD** be granted
332 | to the ASA Manager Address.
333 |
334 | > The ASA trust-model (i.e. who sets the Reserve Address) is extended to the generalized
335 | > ASA circulating supply definition.
336 |
337 | ## Copyright
338 |
339 | Copyright and related rights waived via <a href="https://creativecommons.org/publicdomain/zero/1.0/">CCO</a>.
340 |
```
--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/developer:docs:run-a-node:setup:node-troubleshooting.md:
--------------------------------------------------------------------------------
```markdown
1 | title: Node Troubleshooting
2 |
3 | # Do you want to run a node yourself?
4 |
5 | If you are a developer, running a private network using [AlgoKit](/docs/get-started/algokit) is simpler and provide more flexibility.
6 |
7 | Running a production node for MainNet is very beneficial for decentralization.
8 | However, as any unmanaged system (and any blockchain node/indexer), to achieve high SLA, running a production node has many requirements: appropriate redundancy (some upgrades create downtime on nodes), 24/7 monitoring, regular maintenance, use of a staging environment for testing updates, ...
9 |
10 | !!! tip
11 | Subscribe to notifications on [Forum](https://forum.algorand.org/c/announcements/5) to be aware of new releases. Read carefully all release notes as some updates may create downtimes or may require some configuration changes. It is recommended to systematically update to new releases after testing in a non-production environment.
12 |
13 | You can consider using [third-party API services](https://developer.algorand.org/ecosystem-projects/?tags=api-services) or a third-party provider to help setting/maintaining a node.
14 |
15 | # First steps
16 |
17 | Be sure to have your `$PATH` and `$ALGORAND_DATA` environment variables set properly and that your node is running. In particular:
18 |
19 | ```bash
20 | goal node status
21 | ```
22 |
23 | should return something like:
24 |
25 | ```
26 | Last committed block: 23119736
27 | Time since last block: 0.1s
28 | Sync Time: 2.7s
29 | Last consensus protocol: https://github.com/algorandfoundation/specs/tree/d5ac876d7ede07367dbaa26e149aa42589aac1f7
30 | Next consensus protocol: https://github.com/algorandfoundation/specs/tree/d5ac876d7ede07367dbaa26e149aa42589aac1f7
31 | Round for next consensus protocol: 23119737
32 | Next consensus protocol supported: true
33 | Last Catchpoint:
34 | Genesis ID: testnet-v1.0
35 | Genesis hash: SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=
36 | ```
37 |
38 | Read [Install a Node](../install) to set these variables properly.
39 |
40 | If you see:
41 |
42 | * `Data directory not specified. Please use -d or set $ALGORAND_DATA in your environment. Exiting.`: `$ALGORAND_DATA` is not properly set up.
43 | * `command not found: goal`: `$PATH` is not properly set up.
44 | * `Cannot contact Algorand node: open ...: no such file or directory`: the node is not started. Starting a node is done differently depending on the installation method. See sections "Start the node" from [Install a Node](/docs/run-a-node/setup/install).
45 |
46 | # Common Issues for algod
47 |
48 | ## Most common issues: wrong version, wrong network, not caught up
49 |
50 | One of the most common issues are that the node is on the wrong network, has the wrong algod version, or is not fully synced.
51 |
52 | * **Check that the node is synced/caught up** following [Catchup and Status](/docs/run-a-node/operations/catchup). See below if the node is not syncing.
53 | * **Check that the node is on the right network**: when running `goal node status`, `Genesis ID` must be `mainnet-v1.0` for MainNet, `testnet-v1.0` for TestNet, `betanet-v1.0` for BetaNet. See [Switch Networks](/docs/run-a-node/operations/switch_networks) to solve this issue.
54 | * **Check that the version** reported of `algod -v` and `goal version -v` are the latest stable release (if using MainNet or TestNet) or the latest beta release (if using BetaNet). See the [official repo](https://github.com/algorand/go-algorand/releases) for the list of all releases. Beta releases are clearly marked as such.
55 |
56 | ## My node is not syncing/catching up at all (Last Committed Block is 0)
57 |
58 | As soon as the node is started, the `Last Committed Block` from `goal node status` should be increasing.
59 | If it stays 0, the node is not syncing/catching up at all.
60 | This is usually due to a connectivity issue or a DNS restriction imposed by the ISP.
61 |
62 | ### No connectivity
63 |
64 | First, check that the node has proper internet access.
65 | To check it with the command line, you may use `curl https://example.com`.
66 |
67 | ### DNS restrictions
68 |
69 | By default, a node gets the list of relays it needs to connect to by reading DNS SRV records.
70 | To ensure those records are not tampered with, the node uses DNSSec.
71 |
72 | The node will first try to use the system DNS. If it fails, it will use the fallback DNS from `config.json` (if provided). If this fails again, it will try hardcoded DNS from [tools/network/dnssec/config.go](https://github.com/algorand/go-algorand/blob/master/tools/network/dnssec/config.go).
73 |
74 | Some ISP, enterprise networks, or public networks only allows DNS queries to their own DNS server that may not support DNSSec.
75 | In that case, you will need to set `"DNSSecurityFlags": 0` inside `$ALGORAND_DATA/config.json`.
76 |
77 | !!! warning
78 | Setting `DNSSecurityFlags` to `0` lowers the security of the node and may allow attackers to make your node connect to untrustworthy relays. While untrustworthy relays cannot make your node accept invalid blocks or create invalid transactions, they may censor all transactions from your nodes or may prevent your node from syncing by not providing the latest blocks. It is strongly recommended to enable DNSSec in production.
79 |
80 | !!! tip
81 | Do not forget to restart `algod` after any change to the configuration.
82 |
83 | To check if your node's DNS access is correct, run the following commands in the terminal:
84 |
85 | ```
86 | dig -t SRV _algobootstrap._tcp.mainnet.algorand.network +dnssec
87 | dig -t SRV _algobootstrap._tcp.mainnet.algorand.network @8.8.8.8 +dnssec
88 | ```
89 |
90 | at least one of them must return a list of relays without any error nor warning.
91 | (The first command uses the system DNS while the second one uses Google DNS.)
92 |
93 | ### Other issues
94 |
95 | Here are other less common reasons for a node not being able to catch up at all.
96 |
97 | * Check the presence of the right `genesis.json` file in `$ALGORAND_DATA`. See the documentation on how to [switch networks](/docs/run-a-node/operations/switch_networks/).
98 | * If using BetaNet, check that `$ALGORAND_DATA/config.json` contains the right `DNSBootstrapID`. See the [configuration for BetaNet](/docs/run-a-node/operations/switch_networks/#dns-configuration-for-betanet).
99 |
100 | ## My node is syncing/catching up very slowly (without fast catchup)
101 |
102 | Syncing without fast catchup is expecting to take a 2 to 4 weeks in November 2022, due to the amount of data on the Algorand blockchain.
103 | In addition, syncing will slow down as rounds increases, as newer blocks usually contain many more transactions than older blocks.
104 |
105 | !!! tip
106 | Remember that non-archival node can be synced faster using [fast catchup](/docs/run-a-node/setup/install#sync-node-network-using-fast-catchup). Archival nodes cannot use fast catchup but algonode.io, a third-party service, provides [snapshots of archival nodes](https://algonode.io/extras/). This tip is NOT an endorsement of these snapshots and using these snapshots require careful weighting of associated risks: `algod` cannot verify that these snapshots are valid. In particular, `algod` cannot verify that these snapshots do not contain invalid data that would allow for double spending.
107 |
108 | If it looks like your node will take much longer than 4 weeks for syncing, then:
109 |
110 | 1. Check that your node has the right [hardware requirements](/docs/run-a-node/setup/install/#hardware-requirements). In particular, if your node has less than 4GB (or ideally 8GB) of RAM and/or an HDD/slow-SATA-SSD/SD, then you will not be able to catch up on MainNet.
111 | 2. Check that your node is not overused:
112 | 1. Check RAM and CPU use using `top` or `htop`
113 | 2. Check free disk using `df -h`
114 | 3. Check that your Internet connection is fast enough using a speed test. You need to have at least a 100Mbps connection and low enough latency (below 100ms is most likely needed).
115 | 4. While there are relays all over the world, some regions may have a few number of relays which may slow down catching up. Check latency to the best relays using [algonode.io](https://algonode.io/extras/) scripts (in the folder `utils` of https://snap.algonode.cloud/ --- copied below for completeness):
116 | ```
117 | #!/bin/bash
118 |
119 | # needs dig from dnsutils
120 | N=$(dig +short srv _algobootstrap._tcp.mainnet.algorand.network @1.1.1.1 |wc -l)
121 | echo "Querying $N nodes, be patient..."
122 | echo "" > report.txt
123 | for relay in $(dig +short srv _algobootstrap._tcp.mainnet.algorand.network @1.1.1.1|awk '{print $4 ":" $3}');
124 | do
125 | echo -n .
126 | curl -s -o /dev/null --max-time 1 "http://$relay/v1/urtho/ledger/0"
127 | echo -ne '\bo'
128 | curl -s -o /dev/null --max-time 1 "http://$relay/v1/urtho/ledger/0" -w %{time_total} >> report.txt
129 | echo -ne '\b+'
130 | echo "s;$relay" >> report.txt
131 | done
132 |
133 | echo "Top 20 nodes"
134 | sort -n report.txt | head -20
135 | ```
136 |
137 | Latency above 100ms to the top 20 relays may most likely cause issues.
138 | 5. Check that `$ALGORAND_DATA/config.json` is either absent or only contain the non-default parameters you actually need to change. Only change parameters if you understand the consequences, some parameter changes may significantly slow down syncing.
139 |
140 |
141 | ## My node is not syncing/catching up with fast catchup
142 |
143 | See [troubleshooting for fast catchup](/docs/run-a-node/setup/install#troubleshooting-for-fast-catchup).
144 |
145 | ## Other issues
146 |
147 | ### I get an `overspend` error when sending a transaction
148 |
149 | If sending a transaction results in an `overspend` error (i.e., the word `overspend` appears in the error):
150 | 1. Check that the account has enough Algos on a [block explorer](https://developer.algorand.org/ecosystem-projects/?tags=block-explorers).
151 | 2. Check that your node is [synced and on the right network](#Most-common-issues-wrong-version-wrong-network-not-caught-up).
152 | 3. Do not forget to take into account:
153 | 1. The [minimum balance requirement](/docs/get-details/parameter_tables/#minimum-balance) of 0.1 Algo for a basic account (more if ASA or applications are created or used).
154 | 2. The [fee](/docs/get-details/transactions/#fees) paid by the sender of the transaction.
155 |
156 |
157 | ## None of the above works
158 |
159 | If none of the above works, you can look for additional information on the [third-party algonode.io FAQ](https://algonode.io/faq/#algorand-faq).
160 |
161 | If this still does not solve your issue, please open a new post on [Forum](https://forum.algorand.org) with the following information:
162 |
163 | * what you are trying to do and what fails (with full command lines tried and outputs written in triple backquotes)
164 | * OS version
165 | * machine specs: number of CPU, size of RAM, disk type (NVMe SSD, SATA SSD, ...)
166 | * actual use: memory available, disk available, ...
167 | * algod version: `algod -v`
168 | * goal version: `goal version -v`
169 | * goal status: `goal node status`
170 | * content of `config.json` (in the data folder `$ALGORAND_DATA`)
171 | * link to the files `algod-out.log`, `algod-err.log`, `node.log` (in the data folder `$ALGORAND_DATA`) uploaded in a Github gist or equivalent system
172 |
173 |
174 | !!! tip
175 | Always write code/long outputs between triple backquotes or use the "code" button to facilitate the user reading
176 |
177 | ```
178 | $ goal node status
179 |
180 | Last committed block: 23119736
181 | Time since last block: 0.1s
182 | Sync Time: 2.7s
183 | Last consensus protocol: https://github.com/algorandfoundation/specs/tree/d5ac876d7ede07367dbaa26e149aa42589aac1f7
184 | Next consensus protocol: https://github.com/algorandfoundation/specs/tree/d5ac876d7ede07367dbaa26e149aa42589aac1f7
185 | Round for next consensus protocol: 23119737
186 | Next consensus protocol supported: true
187 | Last Catchpoint:
188 | Genesis ID: testnet-v1.0
189 | Genesis hash: SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=
190 | ```
```
--------------------------------------------------------------------------------
/packages/server/src/tools/algodManager.ts:
--------------------------------------------------------------------------------
```typescript
1 | import algosdk, { modelsv2 } from 'algosdk';
2 | import type { EncodedSignedTransaction } from 'algosdk';
3 | import type {
4 | SimulateResponse,
5 | CompileResponse,
6 | DisassembleResponse,
7 | SimulateTraceConfig,
8 | PostTransactionsResponse
9 | } from 'algosdk/dist/types/client/v2/algod/models/types';
10 | import { algodClient } from '../algorand-client.js';
11 | import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
12 |
13 | // Tool schemas
14 | export const algodToolSchemas = {
15 | compileTeal: {
16 | type: 'object',
17 | properties: {
18 | source: { type: 'string', description: 'Logic that executes when the app is called (compiled TEAL as base64)' }
19 | },
20 | required: ['source']
21 | },
22 | disassembleTeal: {
23 | type: 'object',
24 | properties: {
25 | bytecode: { type: 'string', description: 'TEAL bytecode to disassemble into source code' }
26 | },
27 | required: ['bytecode']
28 | },
29 | sendRawTransaction: {
30 | type: 'object',
31 | properties: {
32 | signedTxns: {
33 | type: 'array',
34 | items: { type: 'string', description: 'Base64-encoded signed transaction' },
35 | description: 'Array of signed transactions to submit to the network'
36 | }
37 | },
38 | required: ['signedTxns']
39 | },
40 | simulateRawTransactions: {
41 | type: 'object',
42 | properties: {
43 | txns: {
44 | type: 'array',
45 | items: { type: 'string', description: 'Base64-encoded transaction' },
46 | description: 'Array of transactions to simulate'
47 | }
48 | },
49 | required: ['txns']
50 | },
51 | simulateTransactions: {
52 | type: 'object',
53 | properties: {
54 | txnGroups: {
55 | type: 'array',
56 | items: {
57 | type: 'object',
58 | properties: {
59 | txns: {
60 | type: 'array',
61 | items: { type: 'object', description: 'Transaction object to simulate' },
62 | description: 'Array of transactions in this group'
63 | }
64 | },
65 | required: ['txns'],
66 | description: 'Group of transactions to simulate together'
67 | },
68 | description: 'Array of transaction groups to simulate'
69 | },
70 | allowEmptySignatures: { type: 'boolean', optional: true, description: 'Allow transactions without signatures' },
71 | allowMoreLogging: { type: 'boolean', optional: true, description: 'Enable additional logging during simulation' },
72 | allowUnnamedResources: { type: 'boolean', optional: true, description: 'Allow access to resources not listed in transaction' },
73 | execTraceConfig: { type: 'object', optional: true, description: 'Configuration for execution trace output' },
74 | extraOpcodeBudget: { type: 'integer', optional: true, description: 'Additional budget for TEAL program execution' },
75 | round: { type: 'integer', optional: true, description: 'Round at which to simulate the transactions' }
76 | },
77 | required: ['txnGroups']
78 | }
79 | };
80 |
81 | export class AlgodManager {
82 | static readonly algodTools = [
83 | {
84 | name: 'compile_teal',
85 | description: 'Compile TEAL source code',
86 | inputSchema: algodToolSchemas.compileTeal,
87 | },
88 | {
89 | name: 'disassemble_teal',
90 | description: 'Disassemble TEAL bytecode back to source',
91 | inputSchema: algodToolSchemas.disassembleTeal,
92 | },
93 | {
94 | name: 'send_raw_transaction',
95 | description: 'Submit signed transactions to the Algorand network',
96 | inputSchema: algodToolSchemas.sendRawTransaction,
97 | },
98 | {
99 | name: 'simulate_raw_transactions',
100 | description: 'Simulate raw transactions',
101 | inputSchema: algodToolSchemas.simulateRawTransactions,
102 | },
103 | {
104 | name: 'simulate_transactions',
105 | description: 'Simulate transactions with detailed configuration',
106 | inputSchema: algodToolSchemas.simulateTransactions,
107 | }
108 | ];
109 |
110 | // Tool handlers
111 | static async handleTool(name: string, args: Record<string, unknown>) {
112 | try {
113 | switch (name) {
114 | case 'compile_teal':
115 | if (!args.source || typeof args.source !== 'string') {
116 | throw new McpError(ErrorCode.InvalidParams, 'TEAL source code is required');
117 | }
118 | const result = await AlgodManager.compile(args.source);
119 | return {
120 | content: [{
121 | type: 'text',
122 | text: JSON.stringify(result, null, 2),
123 | }],
124 | };
125 |
126 | case 'disassemble_teal':
127 | if (!args.bytecode || typeof args.bytecode !== 'string') {
128 | throw new McpError(ErrorCode.InvalidParams, 'TEAL bytecode is required');
129 | }
130 | const disassembled = await AlgodManager.disassemble(args.bytecode);
131 | return {
132 | content: [{
133 | type: 'text',
134 | text: JSON.stringify(disassembled, null, 2),
135 | }],
136 | };
137 |
138 | case 'send_raw_transaction':
139 | if (!args.signedTxns || !Array.isArray(args.signedTxns)) {
140 | throw new McpError(ErrorCode.InvalidParams, 'Signed transactions array is required');
141 | }
142 | const txns = args.signedTxns.map(txn => {
143 | if (typeof txn !== 'string') {
144 | throw new McpError(ErrorCode.InvalidParams, 'Each transaction must be a base64 string');
145 | }
146 | return Buffer.from(txn, 'base64');
147 | });
148 | const sent = await AlgodManager.sendRawTransaction(txns);
149 | return {
150 | content: [{
151 | type: 'text',
152 | text: JSON.stringify(sent, null, 2),
153 | }],
154 | };
155 |
156 | case 'simulate_raw_transactions':
157 | if (!args.txns || !Array.isArray(args.txns)) {
158 | throw new McpError(ErrorCode.InvalidParams, 'Transactions array is required');
159 | }
160 | const rawTxns = args.txns.map(txn => {
161 | if (typeof txn !== 'string') {
162 | throw new McpError(ErrorCode.InvalidParams, 'Each transaction must be a base64 string');
163 | }
164 | return Buffer.from(txn, 'base64');
165 | });
166 | const simulated = await AlgodManager.simulateRawTransactions(rawTxns);
167 | return {
168 | content: [{
169 | type: 'text',
170 | text: JSON.stringify(simulated, null, 2),
171 | }],
172 | };
173 |
174 | case 'simulate_transactions':
175 | if (!args.txnGroups || !Array.isArray(args.txnGroups)) {
176 | throw new McpError(ErrorCode.InvalidParams, 'Transaction groups array is required');
177 | }
178 | const simulateResult = await AlgodManager.simulateTransactions(args as any);
179 | return {
180 | content: [{
181 | type: 'text',
182 | text: JSON.stringify(simulateResult, null, 2),
183 | }],
184 | };
185 |
186 | default:
187 | console.error(`[MCP Error] Unknown tool requested: ${name}`);
188 | throw new McpError(
189 | ErrorCode.MethodNotFound,
190 | `Unknown tool: ${name}`
191 | );
192 | }
193 | } catch (error) {
194 | if (error instanceof McpError) {
195 | console.error(`[MCP Error] ${error.code}: ${error.message}`);
196 | throw error;
197 | }
198 | console.error('[MCP Error] Unexpected error:', error);
199 | throw new McpError(
200 | ErrorCode.InternalError,
201 | `Operation failed: ${error instanceof Error ? error.message : 'Unknown error'}`
202 | );
203 | }
204 | }
205 |
206 | /**
207 | * Compiles TEAL source code to binary
208 | * @param source TEAL source code as string or bytes
209 | * @returns Compilation result with hash and bytecode
210 | */
211 | static async compile(source: string | Uint8Array): Promise<CompileResponse> {
212 | try {
213 | // Convert string source to Buffer
214 | if (typeof source === 'string') {
215 | // Ensure proper line endings and add final newline
216 | source = source.replace(/\r\n/g, '\n');
217 | if (!source.endsWith('\n')) {
218 | source += '\n';
219 | }
220 | source = new TextEncoder().encode(source);
221 | }
222 | const response = await algodClient.compile(source).do() as CompileResponse;
223 | return response;
224 | } catch (error) {
225 | console.error('[MCP Error] Failed to compile TEAL:', error);
226 | throw new McpError(
227 | ErrorCode.InternalError,
228 | `Failed to compile TEAL: ${error instanceof Error ? error.message : String(error)}`
229 | );
230 | }
231 | }
232 |
233 | /**
234 | * Disassembles TEAL bytecode back to source
235 | * @param bytecode TEAL bytecode as string or bytes
236 | * @returns Disassembled TEAL source code
237 | */
238 | static async disassemble(bytecode: string | Uint8Array): Promise<DisassembleResponse> {
239 | try {
240 | const response = await algodClient.disassemble(bytecode).do() as DisassembleResponse;
241 | return response;
242 | } catch (error) {
243 | console.error('[MCP Error] Failed to disassemble TEAL:', error);
244 | throw new McpError(
245 | ErrorCode.InternalError,
246 | `Failed to disassemble TEAL: ${error instanceof Error ? error.message : String(error)}`
247 | );
248 | }
249 | }
250 |
251 | /**
252 | * Broadcasts signed transactions to the network
253 | * @param signedTxns Single signed transaction or array of signed transactions
254 | * @returns Transaction ID of the submission
255 | */
256 | static async sendRawTransaction(signedTxns: Uint8Array | Uint8Array[]): Promise<PostTransactionsResponse> {
257 | try {
258 | const response = await algodClient.sendRawTransaction(signedTxns).do() as PostTransactionsResponse;
259 | return response;
260 | } catch (error) {
261 | console.error('[MCP Error] Failed to send transaction:', error);
262 | throw new McpError(
263 | ErrorCode.InternalError,
264 | `Failed to send transaction: ${error instanceof Error ? error.message : String(error)}`
265 | );
266 | }
267 | }
268 |
269 | /**
270 | * Simulates raw transactions
271 | * @param txns Single transaction or array of transactions to simulate
272 | * @returns Simulation results
273 | */
274 | static async simulateRawTransactions(txns: Uint8Array | Uint8Array[]): Promise<SimulateResponse> {
275 | try {
276 | const response = await algodClient.simulateRawTransactions(txns).do() as SimulateResponse;
277 | return response;
278 | } catch (error) {
279 | console.error('[MCP Error] Failed to simulate raw transactions:', error);
280 | throw new McpError(
281 | ErrorCode.InternalError,
282 | `Failed to simulate raw transactions: ${error instanceof Error ? error.message : String(error)}`
283 | );
284 | }
285 | }
286 |
287 | /**
288 | * Simulates transactions with detailed configuration
289 | * @param request Simulation request with transaction groups and configuration
290 | * @returns Simulation results
291 | */
292 | static async simulateTransactions(request: {
293 | txnGroups: { txns: EncodedSignedTransaction[] }[];
294 | allowEmptySignatures?: boolean;
295 | allowMoreLogging?: boolean;
296 | allowUnnamedResources?: boolean;
297 | execTraceConfig?: SimulateTraceConfig;
298 | extraOpcodeBudget?: number;
299 | round?: number;
300 | }): Promise<SimulateResponse> {
301 | try {
302 | const simulateRequest = new modelsv2.SimulateRequest({
303 | txnGroups: request.txnGroups.map(group =>
304 | new modelsv2.SimulateRequestTransactionGroup({ txns: group.txns })
305 | ),
306 | allowEmptySignatures: request.allowEmptySignatures,
307 | allowMoreLogging: request.allowMoreLogging,
308 | allowUnnamedResources: request.allowUnnamedResources,
309 | execTraceConfig: request.execTraceConfig,
310 | extraOpcodeBudget: request.extraOpcodeBudget,
311 | round: request.round,
312 | });
313 |
314 | const response = await algodClient.simulateTransactions(simulateRequest).do() as SimulateResponse;
315 | return response;
316 | } catch (error) {
317 | console.error('[MCP Error] Failed to simulate transactions:', error);
318 | throw new McpError(
319 | ErrorCode.InternalError,
320 | `Failed to simulate transactions: ${error instanceof Error ? error.message : String(error)}`
321 | );
322 | }
323 | }
324 | }
325 |
```
--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/puya:python:testing:docs:testing-guide:opcodes.md:
--------------------------------------------------------------------------------
```markdown
1 | # AVM Opcodes
2 |
3 | The [coverage](coverage.md) file provides a comprehensive list of all opcodes and their respective types, categorized as _Mockable_, _Emulated_, or _Native_ within the `algorand-python-testing` package. This section highlights a **subset** of opcodes and types that typically require interaction with the test context manager.
4 |
5 | `Native` opcodes are assumed to function as they do in the Algorand Virtual Machine, given their stateless nature. If you encounter issues with any `Native` opcodes, please raise an issue in the [`algorand-python-testing` repo](https://github.com/algorandfoundation/algorand-python-testing/issues/new/choose) or contribute a PR following the [Contributing](https://github.com/algorandfoundation/algorand-python-testing/blob/main/CONTRIBUTING.md) guide.
6 |
7 | ```{testsetup}
8 | import algopy
9 | from algopy_testing import algopy_testing_context
10 |
11 | # Create the context manager for snippets below
12 | ctx_manager = algopy_testing_context()
13 |
14 | # Enter the context
15 | context = ctx_manager.__enter__()
16 | ```
17 |
18 | ## Implemented Types
19 |
20 | These types are fully implemented in Python and behave identically to their AVM counterparts:
21 |
22 | ### 1. Cryptographic Operations
23 |
24 | The following opcodes are demonstrated:
25 |
26 | - `op.sha256`
27 | - `op.keccak256`
28 | - `op.ecdsa_verify`
29 |
30 | ```{testcode}
31 | from algopy import op
32 |
33 | # SHA256 hash
34 | data = algopy.Bytes(b"Hello, World!")
35 | hashed = op.sha256(data)
36 |
37 | # Keccak256 hash
38 | keccak_hashed = op.keccak256(data)
39 |
40 | # ECDSA verification
41 | message_hash = bytes.fromhex("f809fd0aa0bb0f20b354c6b2f86ea751957a4e262a546bd716f34f69b9516ae1")
42 | sig_r = bytes.fromhex("18d96c7cda4bc14d06277534681ded8a94828eb731d8b842e0da8105408c83cf")
43 | sig_s = bytes.fromhex("7d33c61acf39cbb7a1d51c7126f1718116179adebd31618c4604a1f03b5c274a")
44 | pubkey_x = bytes.fromhex("f8140e3b2b92f7cbdc8196bc6baa9ce86cf15c18e8ad0145d50824e6fa890264")
45 | pubkey_y = bytes.fromhex("bd437b75d6f1db67155a95a0da4b41f2b6b3dc5d42f7db56238449e404a6c0a3")
46 |
47 | result = op.ecdsa_verify(op.ECDSA.Secp256r1, message_hash, sig_r, sig_s, pubkey_x, pubkey_y)
48 | assert result
49 | ```
50 |
51 | ### 2. Arithmetic and Bitwise Operations
52 |
53 | The following opcodes are demonstrated:
54 |
55 | - `op.addw`
56 | - `op.bitlen`
57 | - `op.getbit`
58 | - `op.setbit_uint64`
59 |
60 | ```{testcode}
61 | from algopy import op
62 |
63 | # Addition with carry
64 | result, carry = op.addw(algopy.UInt64(2**63), algopy.UInt64(2**63))
65 |
66 | # Bitwise operations
67 | value = algopy.UInt64(42)
68 | bit_length = op.bitlen(value)
69 | is_bit_set = op.getbit(value, 3)
70 | new_value = op.setbit_uint64(value, 2, 1)
71 | ```
72 |
73 | For a comprehensive list of all opcodes and types, refer to the [coverage](../coverage.md) page.
74 |
75 | ## Emulated Types Requiring Transaction Context
76 |
77 | These types necessitate interaction with the transaction context:
78 |
79 | ### algopy.op.Global
80 |
81 | ```{testcode}
82 | from algopy import op
83 |
84 | class MyContract(algopy.ARC4Contract):
85 | @algopy.arc4.abimethod
86 | def check_globals(self) -> algopy.UInt64:
87 | return op.Global.min_txn_fee + op.Global.min_balance
88 |
89 | ... # setup context (below assumes available under 'ctx' variable)
90 |
91 | context.ledger.patch_global_fields(
92 | min_txn_fee=algopy.UInt64(1000),
93 | min_balance=algopy.UInt64(100000)
94 | )
95 |
96 | contract = MyContract()
97 | result = contract.check_globals()
98 | assert result == algopy.UInt64(101000)
99 | ```
100 |
101 | ### algopy.op.Txn
102 |
103 | ```{testcode}
104 | from algopy import op
105 |
106 | class MyContract(algopy.ARC4Contract):
107 | @algopy.arc4.abimethod
108 | def check_txn_fields(self) -> algopy.arc4.Address:
109 | return algopy.arc4.Address(op.Txn.sender)
110 |
111 | ... # setup context (below assumes available under 'ctx' variable)
112 |
113 | contract = MyContract()
114 | custom_sender = context.any.account()
115 | with context.txn.create_group(active_txn_overrides={"sender": custom_sender}):
116 | result = contract.check_txn_fields()
117 | assert result == custom_sender
118 | ```
119 |
120 | ### algopy.op.AssetHoldingGet
121 |
122 | ```{testcode}
123 | from algopy import op
124 |
125 | class AssetContract(algopy.ARC4Contract):
126 | @algopy.arc4.abimethod
127 | def check_asset_holding(self, account: algopy.Account, asset: algopy.Asset) -> algopy.UInt64:
128 | balance, _ = op.AssetHoldingGet.asset_balance(account, asset)
129 | return balance
130 |
131 | ... # setup context (below assumes available under 'ctx' variable)
132 |
133 | asset = context.any.asset(total=algopy.UInt64(1000000))
134 | account = context.any.account(opted_asset_balances={asset.id: algopy.UInt64(5000)})
135 | contract = AssetContract()
136 | result = contract.check_asset_holding(account, asset)
137 | assert result == algopy.UInt64(5000)
138 | ```
139 |
140 | ### algopy.op.AppGlobal
141 |
142 | ```{testcode}
143 | from algopy import op
144 |
145 | class StateContract(algopy.ARC4Contract):
146 | @algopy.arc4.abimethod
147 | def set_and_get_state(self, key: algopy.Bytes, value: algopy.UInt64) -> algopy.UInt64:
148 | op.AppGlobal.put(key, value)
149 | return op.AppGlobal.get_uint64(key)
150 |
151 | ... # setup context (below assumes available under 'ctx' variable)
152 |
153 | contract = StateContract()
154 | key, value = algopy.Bytes(b"test_key"), algopy.UInt64(42)
155 | result = contract.set_and_get_state(key, value)
156 | assert result == value
157 | stored_value = context.ledger.get_global_state(contract, key)
158 | assert stored_value == 42
159 | ```
160 |
161 | ### algopy.op.Block
162 |
163 | ```{testcode}
164 | from algopy import op
165 |
166 | class BlockInfoContract(algopy.ARC4Contract):
167 | @algopy.arc4.abimethod
168 | def get_block_seed(self) -> algopy.Bytes:
169 | return op.Block.blk_seed(1000)
170 |
171 | ... # setup context (below assumes available under 'ctx' variable)
172 |
173 | context.ledger.set_block(1000, seed=123456, timestamp=1625097600)
174 | contract = BlockInfoContract()
175 | seed = contract.get_block_seed()
176 | assert seed == algopy.op.itob(123456)
177 | ```
178 |
179 | ### algopy.op.AcctParamsGet
180 |
181 | ```{testcode}
182 | from algopy import op
183 |
184 | class AccountParamsContract(algopy.ARC4Contract):
185 | @algopy.arc4.abimethod
186 | def get_account_balance(self, account: algopy.Account) -> algopy.UInt64:
187 | balance, exists = op.AcctParamsGet.acct_balance(account)
188 | assert exists
189 | return balance
190 |
191 | ... # setup context (below assumes available under 'ctx' variable)
192 |
193 | account = context.any.account(balance=algopy.UInt64(1000000))
194 | contract = AccountParamsContract()
195 | balance = contract.get_account_balance(account)
196 | assert balance == algopy.UInt64(1000000)
197 | ```
198 |
199 | ### algopy.op.AppParamsGet
200 |
201 | ```{testcode}
202 | class AppParamsContract(algopy.ARC4Contract):
203 | @algopy.arc4.abimethod
204 | def get_app_creator(self, app_id: algopy.Application) -> algopy.arc4.Address:
205 | creator, exists = algopy.op.AppParamsGet.app_creator(app_id)
206 | assert exists
207 | return algopy.arc4.Address(creator)
208 |
209 | ... # setup context (below assumes available under 'ctx' variable)
210 |
211 | contract = AppParamsContract()
212 | app = context.any.application()
213 | creator = contract.get_app_creator(app)
214 | assert creator == context.default_sender
215 | ```
216 |
217 | ### algopy.op.AssetParamsGet
218 |
219 | ```{testcode}
220 | from algopy import op
221 |
222 | class AssetParamsContract(algopy.ARC4Contract):
223 | @algopy.arc4.abimethod
224 | def get_asset_total(self, asset_id: algopy.UInt64) -> algopy.UInt64:
225 | total, exists = op.AssetParamsGet.asset_total(asset_id)
226 | assert exists
227 | return total
228 |
229 | ... # setup context (below assumes available under 'ctx' variable)
230 |
231 | asset = context.any.asset(total=algopy.UInt64(1000000), decimals=algopy.UInt64(6))
232 | contract = AssetParamsContract()
233 | total = contract.get_asset_total(asset.id)
234 | assert total == algopy.UInt64(1000000)
235 | ```
236 |
237 | ### algopy.op.Box
238 |
239 | ```{testcode}
240 | from algopy import op
241 |
242 | class BoxStorageContract(algopy.ARC4Contract):
243 | @algopy.arc4.abimethod
244 | def store_and_retrieve(self, key: algopy.Bytes, value: algopy.Bytes) -> algopy.Bytes:
245 | op.Box.put(key, value)
246 | retrieved_value, exists = op.Box.get(key)
247 | assert exists
248 | return retrieved_value
249 |
250 | ... # setup context (below assumes available under 'ctx' variable)
251 |
252 | contract = BoxStorageContract()
253 | key, value = algopy.Bytes(b"test_key"), algopy.Bytes(b"test_value")
254 | result = contract.store_and_retrieve(key, value)
255 | assert result == value
256 | stored_value = context.ledger.get_box(contract, key)
257 | assert stored_value == value.value
258 | ```
259 |
260 | ## Mockable Opcodes
261 |
262 | These opcodes are mockable in `algorand-python-testing`, allowing for controlled testing of complex operations:
263 |
264 | ### algopy.compile_contract
265 |
266 | ```{testcode}
267 | from unittest.mock import patch, MagicMock
268 | import algopy
269 |
270 | mocked_response = MagicMock()
271 | mocked_response.local_bytes = algopy.UInt64(4)
272 |
273 | class MockContract(algopy.Contract):
274 | ...
275 |
276 | class ContractFactory(algopy.ARC4Contract):
277 | ...
278 |
279 | @algopy.arc4.abimethod
280 | def compile_and_get_bytes(self) -> algopy.UInt64:
281 | contract_response = algopy.compile_contract(MockContract)
282 | return contract_response.local_bytes
283 |
284 | ... # setup context (below assumes available under 'ctx' variable)
285 |
286 | contract = ContractFactory()
287 | with patch('algopy.compile_contract', return_value=mocked_response):
288 | assert contract.compile_and_get_bytes() == 4
289 | ```
290 |
291 | ### algopy.arc4.abi_call
292 |
293 | ```{testcode}
294 | import unittest
295 | from unittest.mock import patch, MagicMock
296 | import algopy
297 | import typing
298 |
299 | class MockAbiCall:
300 | def __call__(
301 | self, *args: typing.Any, **_kwargs: typing.Any
302 | ) -> tuple[typing.Any, typing.Any]:
303 | return (
304 | algopy.arc4.UInt64(11),
305 | MagicMock(),
306 | )
307 |
308 | def __getitem__(self, _item: object) -> typing.Self:
309 | return self
310 |
311 | class MyContract(algopy.ARC4Contract):
312 | @algopy.arc4.abimethod
313 | def my_method(self, arg1: algopy.UInt64, arg2: algopy.UInt64) -> algopy.UInt64:
314 | return algopy.arc4.abi_call[algopy.arc4.UInt64]("my_other_method", arg1, arg2)[0].native
315 |
316 | ... # setup context (below assumes available under 'ctx' variable)
317 |
318 | contract = MyContract()
319 | with patch('algopy.arc4.abi_call', MockAbiCall()):
320 | result = contract.my_method(algopy.UInt64(10), algopy.UInt64(1))
321 | assert result == 11
322 | ```
323 |
324 | ### algopy.op.vrf_verify
325 |
326 | ```{testcode}
327 | from unittest.mock import patch, MagicMock
328 | import algopy
329 |
330 | def test_mock_vrf_verify():
331 | mock_result = (algopy.Bytes(b'mock_output'), True)
332 | with patch('algopy.op.vrf_verify', return_value=mock_result) as mock_vrf_verify:
333 | result = algopy.op.vrf_verify(
334 | algopy.op.VrfVerify.VrfAlgorand,
335 | algopy.Bytes(b'proof'),
336 | algopy.Bytes(b'message'),
337 | algopy.Bytes(b'public_key')
338 | )
339 | assert result == mock_result
340 | mock_vrf_verify.assert_called_once_with(
341 | algopy.op.VrfVerify.VrfAlgorand,
342 | algopy.Bytes(b'proof'),
343 | algopy.Bytes(b'message'),
344 | algopy.Bytes(b'public_key')
345 | )
346 |
347 | test_mock_vrf_verify()
348 | ```
349 |
350 | ### algopy.op.EllipticCurve
351 |
352 | ```{testcode}
353 | from unittest.mock import patch, MagicMock
354 | import algopy
355 |
356 | def test_mock_elliptic_curve_decompress():
357 | mock_result = (algopy.Bytes(b'x_coord'), algopy.Bytes(b'y_coord'))
358 | with patch('algopy.op.EllipticCurve.decompress', return_value=mock_result) as mock_decompress:
359 | result = algopy.op.EllipticCurve.decompress(
360 | algopy.op.EC.BN254g1,
361 | algopy.Bytes(b'compressed_point')
362 | )
363 | assert result == mock_result
364 | mock_decompress.assert_called_once_with(
365 | algopy.op.EC.BN254g1,
366 | algopy.Bytes(b'compressed_point')
367 | )
368 |
369 | test_mock_elliptic_curve_decompress()
370 | ```
371 |
372 | These examples demonstrate how to mock key mockable opcodes in `algorand-python-testing`. Use similar techniques (in your preferred testing framework) for other mockable opcodes like `algopy.compile_logicsig`, `algopy.arc4.arc4_create`, and `algopy.arc4.arc4_update`.
373 |
374 | Mocking these opcodes allows you to:
375 |
376 | 1. Control complex operations' behavior not covered by _implemented_ and _emulated_ types.
377 | 2. Test edge cases and error conditions.
378 | 3. Isolate contract logic from external dependencies.
379 |
380 | ```{testcleanup}
381 | ctx_manager.__exit__(None, None, None)
382 | ```
383 |
```
--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/ARCs:specs:arc-0032.md:
--------------------------------------------------------------------------------
```markdown
1 | ---
2 | arc: 32
3 | title: Application Specification
4 | description: A specification for fully describing an Application, useful for Application clients.
5 | author: Benjamin Guidarelli (@barnjamin)
6 | discussions-to: https://github.com/algorandfoundation/ARCs/issues/150
7 | status: Final
8 | type: Standards Track
9 | category: ARC
10 | sub-category: Application
11 | created: 2022-12-01
12 | requires: 4, 21
13 | ---
14 |
15 | ## Abstract
16 |
17 | > [!NOTE]
18 | > This specification will be eventually deprecated by the <a href="https://github.com/algorandfoundation/ARCs/pull/258">`ARC-56`</a> specification.
19 |
20 | An Application is partially defined by it's [methods](./arc-0004.md) but further information about the Application should be available. Other descriptive elements of an application may include it's State Schema, the original TEAL source programs, default method arguments, and custom data types. This specification defines the descriptive elements of an Application that should be available to clients to provide useful information for an Application Client.
21 |
22 | ## Motivation
23 |
24 | As more complex Applications are created and deployed, some consistent way to specify the details of the application and how to interact with it becomes more important. A specification to allow a consistent and complete definition of an application will help developers attempting to integrate an application they've never worked with before.
25 |
26 | ## Specification
27 | The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in <a href="https://www.ietf.org/rfc/rfc822.txt">RFC 822</a>..
28 |
29 | ### Definitions
30 |
31 | - [Application Specification](#application-specification): The object containing the elements describing the Application.
32 | - [Source Specification](#source-specification): The object containing a description of the TEAL source programs that are evaluated when this Application is called.
33 | - [Schema Specification](#schema-specification): The object containing a description of the schema required by the Application.
34 | - [Bare Call Specification](#bare-call-specification): The object containing a map of on completion actions to allowable calls for bare methods
35 | - [Hints Specification](#hints-specification): The object containing a map of method signatures to meta data about each method
36 |
37 |
38 | ### Application Specification
39 |
40 | The Application Specification is composed of a number of elements that serve to fully describe the Application.
41 |
42 | ```ts
43 | type AppSpec = {
44 | // embedded contract fields, see ARC-0004 for more
45 | contract: ARC4Contract;
46 |
47 | // the original teal source, containing annotations, base64 encoded
48 | source?: SourceSpec;
49 | // the schema this application requires/provides
50 | schema?: SchemaSpec;
51 |
52 | // supplemental information for calling bare methods
53 | bare_call_config?: CallConfigSpec;
54 | // supplemental information for calling ARC-0004 ABI methods
55 | hints: HintsSpec;
56 | // storage requirements
57 | state?: StateSpec;
58 | }
59 | ```
60 |
61 | ### Source Specification
62 |
63 | Contains the source TEAL files including comments and other annotations.
64 |
65 | ```ts
66 | // Object containing the original TEAL source files
67 | type SourceSpec = {
68 | // b64 encoded approval program
69 | approval: string;
70 | // b64 encoded clear state program
71 | clear: string;
72 | }
73 | ```
74 |
75 | ### Schema Specification
76 |
77 | The schema of an application is critical to know prior to creation since it is immutable after create. It also helps clients of the application understand the data that is available to be queried from off chain. Individual fields can be referenced from the [default argument](#default-argument) to provide input data to a given ABI method.
78 |
79 | While some fields are possible to know ahead of time, others may be keyed dynamically. In both cases the data type being stored MUST be known and declared ahead of time.
80 |
81 | ```ts
82 | // The complete schema for this application
83 | type SchemaSpec = {
84 | local: Schema;
85 | global: Schema;
86 | }
87 |
88 | // Schema fields may be declared explicitly or reserved
89 | type Schema = {
90 | declared: Record<string, DeclaredSchemaValueSpec>;
91 | reserved: Record<string, ReservedSchemaValueSpec>;
92 | }
93 |
94 | // Types supported for encoding/decoding
95 | enum AVMType { uint64, bytes }
96 | // string encoded datatype name defined in arc-4
97 | type ABIType = string;
98 |
99 | // Fields that have an explicit key
100 | type DeclaredSchemaValueSpec = {
101 | type: AVMType | ABIType;
102 | key: string;
103 | descr: string;
104 | }
105 |
106 | // Fields that have an undetermined key
107 | type ReservedSchemaValueSpec = {
108 | type: AVMType | ABIType;
109 | descr: string;
110 | max_keys: number;
111 | }
112 |
113 | ```
114 |
115 | ### Bare call specification
116 |
117 | Describes the supported OnComplete actions for bare calls on the contract.
118 |
119 | ```ts
120 | // describes under what conditions an associated OnCompletion type can be used with a particular method
121 | // NEVER: Never handle the specified on completion type
122 | // CALL: Only handle the specified on completion type for application calls
123 | // CREATE: Only handle the specified on completion type for application create calls
124 | // ALL: Handle the specified on completion type for both create and normal application calls
125 | type CallConfig = 'NEVER' | 'CALL' | 'CREATE' | 'ALL'
126 |
127 | type CallConfigSpec = {
128 | // lists the supported CallConfig for each on completion type, if not specified a CallConfig of NEVER is assumed
129 | no_op?: CallConfig
130 | opt_in?: CallConfig
131 | close_out?: CallConfig
132 | update_application?: CallConfig
133 | delete_application?: CallConfig
134 | }
135 | ```
136 |
137 | ### Hints specification
138 |
139 | Contains supplemental information about [ARC-0004](./arc-0004.md) ABI methods, each record represents a single method in the [ARC-0004](./arc-0004.md) contract. The record key should be the corresponding ABI signature.
140 |
141 | NOTE: Ideally this information would be part of the [ARC-0004](./arc-0004.md) ABI specification.
142 |
143 | ```ts
144 | type HintSpec = {
145 | // indicates the method has no side-effects and can be call via dry-run/simulate
146 | read_only?: bool;
147 | // describes the structure of arguments, key represents the argument name
148 | structs?: Record<string, StructSpec>;
149 | // describes source of default values for arguments, key represents the argument name
150 | default_arguments?: Record<string, DefaultArgumentSpec>;
151 | // describes which OnCompletion types are supported
152 | call_config: CallConfigSpec;
153 | }
154 |
155 | // key represents the method signature for an ABI method defined in 'contracts'
156 | type HintsSpec = Record<string, HintSpec>
157 | ```
158 |
159 | #### Readonly Specification
160 |
161 | Indicates the method has no side-effects and can be called via dry-run/simulate
162 |
163 | NOTE: This property is made obsolete by [ARC-0022](./arc-0022.md) but is included as it is currently
164 | used by existing reference implementations such as Beaker
165 |
166 | #### Struct Specification
167 |
168 | Each defined type is specified as an array of `StructElement`s.
169 |
170 | The ABI encoding is exactly as if an ABI Tuple type defined the same element types in the same order.
171 | It is important to encode the struct elements as an array since it preserves the order of fields which is critical to encoding/decoding the data properly.
172 |
173 | ```ts
174 | // Type aliases for readability
175 | type FieldName = string
176 | // string encoded datatype name defined in ARC-0004
177 | type ABIType = string
178 |
179 | // Each field in the struct contains a name and ABI type
180 | type StructElement = [FieldName, ABIType]
181 | // Type aliases for readability
182 | type ContractDefinedType = StructElement[]
183 | type ContractDefinedTypeName = string;
184 |
185 | // represents a input/output structure
186 | type StructSpec = {
187 | name: ContractDefinedTypeName
188 | elements: ContractDefinedType
189 | }
190 | ```
191 |
192 | For example a `ContractDefinedType` that should provide an array of `StructElement`s
193 |
194 | Given the PyTeal:
195 | ```py
196 | from pyteal import abi
197 |
198 | class Thing(abi.NamedTuple):
199 | addr: abi.Field[abi.address]
200 | balance: abi.Field[abi.Uint64]
201 | ```
202 | the equivalent ABI type is `(address,uint64)` and an element in the TypeSpec is:
203 |
204 | ```js
205 | {
206 | // ...
207 | "Thing":[["addr", "address"]["balance","uint64"]],
208 | // ...
209 | }
210 | ```
211 |
212 | #### Default Argument
213 |
214 | Defines how default argument values can be obtained. The `source` field defines how a default value is obtained, the `data` field
215 | contains additional information based on the `source` value.
216 |
217 | Valid values for `source` are:
218 | * "constant" - `data` is the value to use
219 | * "global-state" - `data` is the global state key.
220 | * "local-state" - `data` is the local state key
221 | * "abi-method" - `data` is a reference to the ABI method to call. Method should be read only and return a value of the appropriate type
222 |
223 | Two scenarios where providing default arguments can be useful:
224 |
225 | 1. Providing a default value for optional arguments
226 |
227 | 2. Providing a value for required arguments such as foreign asset or application references without requiring the client to explicitly determine these values when calling the contract
228 |
229 |
230 | ```ts
231 | // ARC-0004 ABI method definition
232 | type ABIMethod = {};
233 |
234 | type DefaultArgumentSpec = {
235 | // Where to look for the default arg value
236 | source: "constant" | "global-state" | "local-state" | "abi-method"
237 | // extra data to include when looking up the value
238 | data: string | bigint | number | ABIMethod
239 | }
240 | ```
241 |
242 | ### State Specifications
243 |
244 | Describes the total storage requirements for both global and local storage, this should include both declared and reserved described in SchemaSpec.
245 |
246 | NOTE: If the Schema specification contained additional information such that the size could be calculated, then this specification would not be required.
247 |
248 | ```ts
249 | type StateSchema = {
250 | // how many byte slices are required
251 | num_byte_slices: number
252 | // how many uints are required
253 | num_uints: number
254 | }
255 |
256 | type StateSpec = {
257 | // schema specification for global storage
258 | global: StateSchema
259 | // schema specification for local storage
260 | local: StateSchema
261 | }
262 | ```
263 |
264 | ### Reference schema
265 |
266 | A full JSON schema for application.json can be found in [here](../assets/arc-0032/application.schema.json).
267 |
268 | ## Rationale
269 | The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages.
270 |
271 | ## Backwards Compatibility
272 | All ARCs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The ARC must explain how the author proposes to deal with these incompatibilities. ARC submissions without a sufficient backwards compatibility treatise may be rejected outright.
273 |
274 | ## Test Cases
275 | Test cases for an implementation are mandatory for ARCs that are affecting consensus changes. If the test suite is too large to reasonably be included inline, then consider adding it as one or more files in `../assets/arc-####/`.
276 |
277 | ## Reference Implementation
278 |
279 | `algokit-utils-py` and `algokit-utils-ts` both provide reference implementations for the specification structure and using the data in an `ApplicationClient`
280 | `Beaker` provides a reference implementation for creating an application.json from a smart contract.
281 |
282 | ## Security Considerations
283 | All ARCs must contain a section that discusses the security implications/considerations relevant to the proposed change. Include information that might be important for security discussions, surfaces risks and can be used throughout the life cycle of the proposal. E.g. include security-relevant design decisions, concerns, important discussions, implementation-specific guidance and pitfalls, an outline of threats and risks and how they are being addressed. ARC submissions missing the "Security Considerations" section will be rejected. An ARC cannot proceed to status "Final" without a Security Considerations discussion deemed sufficient by the reviewers.
284 |
285 | ## Copyright
286 | Copyright and related rights waived via <a href="https://creativecommons.org/publicdomain/zero/1.0/">CCO</a>.
287 |
```
--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/developer:docs:details:dapps:smart-contracts:apps:txs.md:
--------------------------------------------------------------------------------
```markdown
1 | title: Evaluating transactions
2 |
3 |
4 | # Checking the transaction type in a smart contract
5 |
6 | The `ApplicationCall` transaction types defined in [The Lifecycle of a Smart Contract](#the-lifecycle-of-a-smart-contract) can be checked within the TEAL code by examining the `OnCompletion` transaction property.
7 |
8 | === "PyTeal"
9 | <!-- ===PYTEAL_TXN_ONCOMPLETE=== -->
10 | ```python
11 | program = OnComplete.NoOp == Txn.on_completion()
12 | print(compileTeal(program, Mode.Application))
13 | ```
14 | [Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/txn.py#L20-L22)
15 | <!-- ===PYTEAL_TXN_ONCOMPLETE=== -->
16 |
17 | === "TEAL"
18 | <!-- ===TEAL_TXN_ONCOMPLETE=== -->
19 | ```teal
20 | txn OnCompletion
21 | int NoOp // OptIn, CloseOut, UpdateApplication, or DeleteApplication
22 | ==
23 | ```
24 | [Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/oncomplete/approval.teal#L3-L6)
25 | <!-- ===TEAL_TXN_ONCOMPLETE=== -->
26 |
27 | # Global values in smart contracts
28 | Smart contracts have access to many global variables. These variables are set for the blockchain, like the minimum transaction fee (MinTxnFee). As another example of Global variable use, in the [Atomic Transfers and Transaction Properties](#atomic-transfers-and-transaction-properties) section of this guide, `GroupSize` is used to show how to get the number of transactions that are grouped within a smart contract call. Smart contracts also have access to the `LatestTimestamp` global which represents the latest confirmed block's Unix timestamp. This is not the current time, but the time when the last block was confirmed. This can be used to set times on when the contract is allowed to do certain things. For example, a contract may only allow accounts to opt in after a start date, which is set when the contract is created and stored in global storage.
29 |
30 | === "PyTeal"
31 | <!-- ===PYTEAL_GLOBAL_LATEST_TIMESTAMP=== -->
32 | ```python
33 | program = Global.latest_timestamp() >= App.globalGet(Bytes("StartDate"))
34 | print(compileTeal(program, Mode.Application))
35 | ```
36 | [Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/application.py#L25-L27)
37 | <!-- ===PYTEAL_GLOBAL_LATEST_TIMESTAMP=== -->
38 |
39 | === "TEAL"
40 | <!-- ===TEAL_GLOBAL_LATEST_TIMESTAMP=== -->
41 | ```teal
42 | global LatestTimestamp
43 | byte "StateDate"
44 | app_global_get
45 | >=
46 | ```
47 | [Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/misc/global.teal#L3-L7)
48 | <!-- ===TEAL_GLOBAL_LATEST_TIMESTAMP=== -->
49 |
50 | # Atomic transfers and transaction properties
51 | The [TEAL opcodes](../../avm/teal/opcodes) documentation describes all transaction properties that are available within a TEAL program. These properties can be retrieved using the following contract code.
52 |
53 |
54 | === "PyTeal"
55 | <!-- ===PYTEAL_TXN_AMOUNT=== -->
56 | ```python
57 | program = Txn.amount()
58 | print(compileTeal(program, Mode.Application))
59 | ```
60 | [Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/txn.py#L48-L50)
61 | <!-- ===PYTEAL_TXN_AMOUNT=== -->
62 |
63 | === "TEAL"
64 | <!-- ===TEAL_TXN_AMOUNT=== -->
65 | ```teal
66 | txn Amount
67 | ```
68 | [Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/misc/global.teal#L13-L14)
69 | <!-- ===TEAL_TXN_AMOUNT=== -->
70 |
71 | In many common patterns, the smart contract will be combined with other Algorand technologies such as assets, atomic transfers, or smart signatures to build a complete application. In the case of atomic transfers, more than one transaction’s properties can be checked within the smart contract. The number of transactions can be checked using the `GroupSize` global property. If the value is greater than 1, then the call to the smart contract is grouped with more than one transaction.
72 |
73 | === "PyTeal"
74 | <!-- ===PYTEAL_TXN_GROUP_SIZE=== -->
75 | ```python
76 | program = Global.group_size() == Int(2)
77 | print(compileTeal(program, Mode.Application))
78 | ```
79 | [Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/txn.py#L55-L57)
80 | <!-- ===PYTEAL_TXN_GROUP_SIZE=== -->
81 |
82 | === "TEAL"
83 | <!-- ===TEAL_TXN_GROUP_SIZE=== -->
84 | ```teal
85 | global GroupSize
86 | int 2
87 | ==
88 | ```
89 | [Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/misc/global.teal#L18-L21)
90 | <!-- ===TEAL_TXN_GROUP_SIZE=== -->
91 |
92 | The above contract code will be true if there are two transactions submitted at once using an atomic transfer. To access the properties of a specific transaction in the atomic group use the `gtxn` opcode.
93 |
94 | === "PyTeal"
95 | <!-- ===PYTEAL_GTXN_TYPE_ENUM=== -->
96 | ```python
97 | program = Gtxn[1].type_enum() == TxnType.Payment
98 | print(compileTeal(program, Mode.Application))
99 | ```
100 | [Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/txn.py#L62-L64)
101 | <!-- ===PYTEAL_GTXN_TYPE_ENUM=== -->
102 |
103 | === "TEAL"
104 | <!-- ===TEAL_GTXN_TYPE_ENUM=== -->
105 | ```teal
106 | gtxn 1 TypeEnum
107 | int pay
108 | ==
109 | ```
110 | [Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/misc/global.teal#L25-L28)
111 | <!-- ===TEAL_GTXN_TYPE_ENUM=== -->
112 |
113 | In the above example, the second transaction’s type is checked, where the `int pay` references a payment transaction. See the [opcodes](../../avm/teal/opcodes) documentation for all transaction types. Note that the `gtxn` call is a zero-based index into the atomic group of transactions. The `gtxns` opcode could also have been used to retrieve the index into the atomic group from the top of the stack instead of hard coding the index. If the TEAL program fails, all transactions in the group will fail.
114 |
115 | If any transaction in a group of transactions is a call to a smart contract, the opcodes `gtxna` and `gtxnsa` can be used to access any of the transactions array values.
116 |
117 | === "PyTeal"
118 | <!-- ===PYTEAL_GTXN_APP_ARGS=== -->
119 | ```python
120 | program = Gtxn[Txn.group_index() - Int(1)].application_args[0]
121 | print(compileTeal(program, Mode.Application))
122 | ```
123 | [Snippet Source](https://github.com/barnjamin/pyteal/blob/examples-for-docs/_examples/txn.py#L69-L71)
124 | <!-- ===PYTEAL_GTXN_APP_ARGS=== -->
125 |
126 | === "TEAL"
127 | <!-- ===TEAL_GTXN_APP_ARGS=== -->
128 | ```teal
129 | txn GroupIndex
130 | int 1
131 | -
132 | gtxnsa ApplicationArgs 0
133 | ```
134 | [Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/misc/global.teal#L32-L36)
135 | <!-- ===TEAL_GTXN_APP_ARGS=== -->
136 |
137 | # Using assets in smart contracts
138 | Smart contract applications can work in conjunction with assets. In addition to normal asset transaction properties, such as asset amount, sender, and receiver, TEAL provides an opcode to interrogate an account’s asset balance and whether the asset is frozen. This opcode `asset_holding_get` can be used to retrieve an asset balance or check whether the asset is frozen for any account in the transaction accounts array. The asset must also be in the assets array. See [Reference arrays](index.md#reference-arrays) for more details.
139 |
140 | === "PyTeal"
141 | ```python
142 | asset_balance = AssetHolding.balance(Txn.sender(), Int(123456))
143 | program = Seq(
144 | asset_balance, If(asset_balance.hasValue(), Return(Int(1)), Return(Int(0)))
145 | )
146 | print(compileTeal(program, Mode.Application))
147 | ```
148 |
149 | === "TEAL"
150 | ```teal
151 | txn Sender
152 | int 123456
153 | asset_holding_get AssetBalance
154 | bnz has_balance
155 |
156 | // Reject transaction if no asset balance
157 | int 0
158 | return
159 |
160 | has_balance:
161 | //balance value is now on top of the stack
162 | ```
163 |
164 | This opcode takes two parameters. The first parameter represents the account to check. The second parameter is the Asset ID of the asset to examine. The asset must be in the assets array and the account in the accounts array for the call to be successful. See [Reference arrays](index.md#reference-arrays) for more details.
165 |
166 | This opcode supports getting the asset balance and the frozen state of the asset for the specific account. To get the frozen state, replace `AssetBalance` above with `AssetFrozen`. This opcode also returns two values to the top of the stack. The first is a 0 or 1, where 0 means the asset balance was not found and 1 means an asset balance was found in the accounts balance record.
167 |
168 | It is also possible to get an Asset’s configuration information within a smart contract if the asset ID is passed with the transaction in the assets array. To read the configuration, the `asset_params_get` opcode must be used. This opcode should be supplied with one parameter, which is the index into the assets array or the actual asset ID.
169 |
170 | === "PyTEAL"
171 | ```python
172 | program = AssetParam.total(Int(123456))
173 | print(compileTeal(program, Mode.Application))
174 | ```
175 |
176 | === "TEAL"
177 | <!-- ===TEAL_APPL_ASSET_PARAM=== -->
178 | ```teal
179 | int 123456
180 | asset_params_get AssetTotal
181 | ```
182 |
183 | This call returns two values. The first is a 0 or 1 indicating if the parameter was found and the second contains the value of the parameter. See the [opcodes](../../avm/teal/opcodes) documentation for more details on what additional parameters can be read.
184 |
185 | # Creating an asset or contract within a group of transactions
186 | The Algorand Protocol assigns an identifier (ID) when creating an asset (ASA) or a smart contract. These IDs are used to refer to the asset or the contract later when either is used in a transaction or a call to the smart contract. Because these IDs are assigned when the asset or the contract is created, the ID is not available until after the creation transaction is fully executed. In an atomic group, TEAL can retrieve the ID of a previous group transaction which created an asset or contract, enabling a smart contract to store the asset ID or another smart contract ID in its state for later usage.
187 |
188 | The ID retrieval operation can be performed by using one of two opcodes (`gaid` and `gaids`). With the `gaid` opcode, the specific transaction to read must be passed to the command. The `gaids` opcode will use the last value on the stack as the transaction index.
189 |
190 | === "TEAL"
191 | <!-- ===TEAL_APPL_CREATED_ASSET_ID=== -->
192 | ```teal
193 | // Get the created id of the asset created in the first tx
194 | gaid 0
195 | // Get the created id of the asset created in the second tx
196 | int 1
197 | gaids
198 | ```
199 | [Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/appl_asset/approval.teal#L25-L30)
200 | <!-- ===TEAL_APPL_CREATED_ASSET_ID=== -->
201 |
202 | # Sharing data between contracts
203 | In addition to reading another contract's state, data can be passed between contracts. Algorand’s AVM gives smart contracts access to scratch space that can be used to temporarily store values, while the contract is executing. TEAL allows other contracts to read this scratch space. Scratch space can only be read by other transactions that the specific transaction is grouped with atomically. Grouped transactions execute in the order they are grouped, contracts can not read scratch space for transactions that occur after the current contract transaction.
204 |
205 | This operation can be performed by using one of two opcodes (`gload` and `gloads`). With the `gload` opcode, the specific transaction to read and the slot number must be passed to the command. The `gloads` opcode will use the last value on the stack as the transaction index and must be passed the slot number to read.
206 |
207 | For example, with two grouped smart contracts the following code can be used.
208 |
209 | Store an integer in scratch space in the first transaction.
210 |
211 | === "TEAL"
212 | <!-- ===TEAL_APPL_GLOAD_T1=== -->
213 | ```teal
214 | int 777
215 | store 10
216 | ```
217 | [Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/misc/scratch_t1.teal#L3-L5)
218 | <!-- ===TEAL_APPL_GLOAD_T1=== -->
219 |
220 | In the second transaction read the stored value.
221 |
222 | === "TEAL"
223 | <!-- ===TEAL_APPL_GLOAD_T2=== -->
224 | ```teal
225 | // read the first
226 | // transaction's 10th
227 | // slot of scratch space
228 | gload 0 10
229 | ```
230 | [Snippet Source](https://github.com/nullun/algorand-teal-examples/blob/main/_examples/misc/scratch_t2.teal#L3-L7)
231 | <!-- ===TEAL_APPL_GLOAD_T2=== -->
232 |
```
--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/SDKs:javascript:classes:AtomicTransactionComposer.md:
--------------------------------------------------------------------------------
```markdown
1 | [algosdk](../README.md) / [Exports](../modules.md) / AtomicTransactionComposer
2 |
3 | # Class: AtomicTransactionComposer
4 |
5 | A class used to construct and execute atomic transaction groups
6 |
7 | ## Table of contents
8 |
9 | ### Constructors
10 |
11 | - [constructor](AtomicTransactionComposer.md#constructor)
12 |
13 | ### Properties
14 |
15 | - [methodCalls](AtomicTransactionComposer.md#methodcalls)
16 | - [signedTxns](AtomicTransactionComposer.md#signedtxns)
17 | - [status](AtomicTransactionComposer.md#status)
18 | - [transactions](AtomicTransactionComposer.md#transactions)
19 | - [txIDs](AtomicTransactionComposer.md#txids)
20 | - [MAX\_GROUP\_SIZE](AtomicTransactionComposer.md#max_group_size)
21 |
22 | ### Methods
23 |
24 | - [addMethodCall](AtomicTransactionComposer.md#addmethodcall)
25 | - [addTransaction](AtomicTransactionComposer.md#addtransaction)
26 | - [buildGroup](AtomicTransactionComposer.md#buildgroup)
27 | - [clone](AtomicTransactionComposer.md#clone)
28 | - [count](AtomicTransactionComposer.md#count)
29 | - [execute](AtomicTransactionComposer.md#execute)
30 | - [gatherSignatures](AtomicTransactionComposer.md#gathersignatures)
31 | - [getStatus](AtomicTransactionComposer.md#getstatus)
32 | - [simulate](AtomicTransactionComposer.md#simulate)
33 | - [submit](AtomicTransactionComposer.md#submit)
34 | - [parseMethodResponse](AtomicTransactionComposer.md#parsemethodresponse)
35 |
36 | ## Constructors
37 |
38 | ### constructor
39 |
40 | • **new AtomicTransactionComposer**()
41 |
42 | ## Properties
43 |
44 | ### methodCalls
45 |
46 | • `Private` **methodCalls**: `Map`\<`number`, [`ABIMethod`](ABIMethod.md)\>
47 |
48 | #### Defined in
49 |
50 | composer.ts:127
51 |
52 | ___
53 |
54 | ### signedTxns
55 |
56 | • `Private` **signedTxns**: `Uint8Array`[] = `[]`
57 |
58 | #### Defined in
59 |
60 | composer.ts:128
61 |
62 | ___
63 |
64 | ### status
65 |
66 | • `Private` **status**: [`AtomicTransactionComposerStatus`](../enums/AtomicTransactionComposerStatus.md) = `AtomicTransactionComposerStatus.BUILDING`
67 |
68 | #### Defined in
69 |
70 | composer.ts:125
71 |
72 | ___
73 |
74 | ### transactions
75 |
76 | • `Private` **transactions**: [`TransactionWithSigner`](../interfaces/TransactionWithSigner.md)[] = `[]`
77 |
78 | #### Defined in
79 |
80 | composer.ts:126
81 |
82 | ___
83 |
84 | ### txIDs
85 |
86 | • `Private` **txIDs**: `string`[] = `[]`
87 |
88 | #### Defined in
89 |
90 | composer.ts:129
91 |
92 | ___
93 |
94 | ### MAX\_GROUP\_SIZE
95 |
96 | ▪ `Static` **MAX\_GROUP\_SIZE**: `number` = `16`
97 |
98 | The maximum size of an atomic transaction group.
99 |
100 | #### Defined in
101 |
102 | composer.ts:123
103 |
104 | ## Methods
105 |
106 | ### addMethodCall
107 |
108 | ▸ **addMethodCall**(`«destructured»`): `void`
109 |
110 | Add a smart contract method call to this atomic group.
111 |
112 | An error will be thrown if the composer's status is not BUILDING, if adding this transaction
113 | causes the current group to exceed MAX_GROUP_SIZE, or if the provided arguments are invalid
114 | for the given method.
115 |
116 | #### Parameters
117 |
118 | | Name | Type | Description |
119 | | :------ | :------ | :------ |
120 | | `«destructured»` | `Object` | - |
121 | | › `appAccounts?` | `string`[] | Array of Address strings that represent external accounts supplied to this application. If accounts are provided here, the accounts specified in the method args will appear after these. |
122 | | › `appForeignApps?` | `number`[] | Array of App ID numbers that represent external apps supplied to this application. If apps are provided here, the apps specified in the method args will appear after these. |
123 | | › `appForeignAssets?` | `number`[] | Array of Asset ID numbers that represent external assets supplied to this application. If assets are provided here, the assets specified in the method args will appear after these. |
124 | | › `appID` | `number` | The ID of the smart contract to call. Set this to 0 to indicate an application creation call. |
125 | | › `approvalProgram?` | `Uint8Array` | The approval program for this application call. Only set this if this is an application creation call, or if onComplete is OnApplicationComplete.UpdateApplicationOC |
126 | | › `boxes?` | [`BoxReference`](../interfaces/BoxReference.md)[] | The box references for this application call |
127 | | › `clearProgram?` | `Uint8Array` | The clear program for this application call. Only set this if this is an application creation call, or if onComplete is OnApplicationComplete.UpdateApplicationOC |
128 | | › `extraPages?` | `number` | The number of extra pages to allocate for the application's programs. Only set this if this is an application creation call. If omitted, defaults to 0. |
129 | | › `lease?` | `Uint8Array` | The lease value for this application call |
130 | | › `method` | [`ABIMethod`](ABIMethod.md) | The method to call on the smart contract |
131 | | › `methodArgs?` | [`ABIArgument`](../modules.md#abiargument)[] | The arguments to include in the method call. If omitted, no arguments will be passed to the method. |
132 | | › `note?` | `Uint8Array` | The note value for this application call |
133 | | › `numGlobalByteSlices?` | `number` | The global byte slice schema size. Only set this if this is an application creation call. |
134 | | › `numGlobalInts?` | `number` | The global integer schema size. Only set this if this is an application creation call. |
135 | | › `numLocalByteSlices?` | `number` | The local byte slice schema size. Only set this if this is an application creation call. |
136 | | › `numLocalInts?` | `number` | The local integer schema size. Only set this if this is an application creation call. |
137 | | › `onComplete?` | [`OnApplicationComplete`](../enums/OnApplicationComplete.md) | The OnComplete action to take for this application call. If omitted, OnApplicationComplete.NoOpOC will be used. |
138 | | › `rekeyTo?` | `string` | If provided, the address that the sender will be rekeyed to at the conclusion of this application call |
139 | | › `sender` | `string` | The address of the sender of this application call |
140 | | › `signer` | [`TransactionSigner`](../modules.md#transactionsigner) | A transaction signer that can authorize this application call from sender |
141 | | › `suggestedParams` | [`SuggestedParams`](../interfaces/SuggestedParams.md) | Transactions params to use for this application call |
142 |
143 | #### Returns
144 |
145 | `void`
146 |
147 | #### Defined in
148 |
149 | composer.ts:199
150 |
151 | ___
152 |
153 | ### addTransaction
154 |
155 | ▸ **addTransaction**(`txnAndSigner`): `void`
156 |
157 | Add a transaction to this atomic group.
158 |
159 | An error will be thrown if the transaction has a nonzero group ID, the composer's status is
160 | not BUILDING, or if adding this transaction causes the current group to exceed MAX_GROUP_SIZE.
161 |
162 | #### Parameters
163 |
164 | | Name | Type |
165 | | :------ | :------ |
166 | | `txnAndSigner` | [`TransactionWithSigner`](../interfaces/TransactionWithSigner.md) |
167 |
168 | #### Returns
169 |
170 | `void`
171 |
172 | #### Defined in
173 |
174 | composer.ts:172
175 |
176 | ___
177 |
178 | ### buildGroup
179 |
180 | ▸ **buildGroup**(): [`TransactionWithSigner`](../interfaces/TransactionWithSigner.md)[]
181 |
182 | Finalize the transaction group and returned the finalized transactions.
183 |
184 | The composer's status will be at least BUILT after executing this method.
185 |
186 | #### Returns
187 |
188 | [`TransactionWithSigner`](../interfaces/TransactionWithSigner.md)[]
189 |
190 | #### Defined in
191 |
192 | composer.ts:493
193 |
194 | ___
195 |
196 | ### clone
197 |
198 | ▸ **clone**(): [`AtomicTransactionComposer`](AtomicTransactionComposer.md)
199 |
200 | Create a new composer with the same underlying transactions. The new composer's status will be
201 | BUILDING, so additional transactions may be added to it.
202 |
203 | #### Returns
204 |
205 | [`AtomicTransactionComposer`](AtomicTransactionComposer.md)
206 |
207 | #### Defined in
208 |
209 | composer.ts:149
210 |
211 | ___
212 |
213 | ### count
214 |
215 | ▸ **count**(): `number`
216 |
217 | Get the number of transactions currently in this atomic group.
218 |
219 | #### Returns
220 |
221 | `number`
222 |
223 | #### Defined in
224 |
225 | composer.ts:141
226 |
227 | ___
228 |
229 | ### execute
230 |
231 | ▸ **execute**(`client`, `waitRounds`): `Promise`\<\{ `confirmedRound`: `number` ; `methodResults`: [`ABIResult`](../interfaces/ABIResult.md)[] ; `txIDs`: `string`[] }\>
232 |
233 | Send the transaction group to the network and wait until it's committed to a block. An error
234 | will be thrown if submission or execution fails.
235 |
236 | The composer's status must be SUBMITTED or lower before calling this method, since execution is
237 | only allowed once. If submission is successful, this composer's status will update to SUBMITTED.
238 | If the execution is also successful, this composer's status will update to COMMITTED.
239 |
240 | Note: a group can only be submitted again if it fails.
241 |
242 | #### Parameters
243 |
244 | | Name | Type | Description |
245 | | :------ | :------ | :------ |
246 | | `client` | [`Algodv2`](Algodv2.md) | An Algodv2 client |
247 | | `waitRounds` | `number` | The maximum number of rounds to wait for transaction confirmation |
248 |
249 | #### Returns
250 |
251 | `Promise`\<\{ `confirmedRound`: `number` ; `methodResults`: [`ABIResult`](../interfaces/ABIResult.md)[] ; `txIDs`: `string`[] }\>
252 |
253 | A promise that, upon success, resolves to an object containing the confirmed round for
254 | this transaction, the txIDs of the submitted transactions, and an array of results containing
255 | one element for each method call transaction in this group.
256 |
257 | #### Defined in
258 |
259 | composer.ts:699
260 |
261 | ___
262 |
263 | ### gatherSignatures
264 |
265 | ▸ **gatherSignatures**(): `Promise`\<`Uint8Array`[]\>
266 |
267 | Obtain signatures for each transaction in this group. If signatures have already been obtained,
268 | this method will return cached versions of the signatures.
269 |
270 | The composer's status will be at least SIGNED after executing this method.
271 |
272 | An error will be thrown if signing any of the transactions fails.
273 |
274 | #### Returns
275 |
276 | `Promise`\<`Uint8Array`[]\>
277 |
278 | A promise that resolves to an array of signed transactions.
279 |
280 | #### Defined in
281 |
282 | composer.ts:518
283 |
284 | ___
285 |
286 | ### getStatus
287 |
288 | ▸ **getStatus**(): [`AtomicTransactionComposerStatus`](../enums/AtomicTransactionComposerStatus.md)
289 |
290 | Get the status of this composer's transaction group.
291 |
292 | #### Returns
293 |
294 | [`AtomicTransactionComposerStatus`](../enums/AtomicTransactionComposerStatus.md)
295 |
296 | #### Defined in
297 |
298 | composer.ts:134
299 |
300 | ___
301 |
302 | ### simulate
303 |
304 | ▸ **simulate**(`client`, `request?`): `Promise`\<\{ `methodResults`: [`ABIResult`](../interfaces/ABIResult.md)[] ; `simulateResponse`: [`SimulateResponse`](modelsv2.SimulateResponse.md) }\>
305 |
306 | Simulates the transaction group in the network.
307 |
308 | The composer will try to sign any transactions in the group, then simulate
309 | the results.
310 | Simulating the group will not change the composer's status.
311 |
312 | #### Parameters
313 |
314 | | Name | Type | Description |
315 | | :------ | :------ | :------ |
316 | | `client` | [`Algodv2`](Algodv2.md) | An Algodv2 client |
317 | | `request?` | [`SimulateRequest`](modelsv2.SimulateRequest.md) | SimulateRequest with options in simulation. If provided, the request's transaction group will be overrwritten by the composer's group, only simulation related options will be used. |
318 |
319 | #### Returns
320 |
321 | `Promise`\<\{ `methodResults`: [`ABIResult`](../interfaces/ABIResult.md)[] ; `simulateResponse`: [`SimulateResponse`](modelsv2.SimulateResponse.md) }\>
322 |
323 | A promise that, upon success, resolves to an object containing an
324 | array of results containing one element for each method call transaction
325 | in this group (ABIResult[]) and the SimulateResponse object.
326 |
327 | #### Defined in
328 |
329 | composer.ts:626
330 |
331 | ___
332 |
333 | ### submit
334 |
335 | ▸ **submit**(`client`): `Promise`\<`string`[]\>
336 |
337 | Send the transaction group to the network, but don't wait for it to be committed to a block. An
338 | error will be thrown if submission fails.
339 |
340 | The composer's status must be SUBMITTED or lower before calling this method. If submission is
341 | successful, this composer's status will update to SUBMITTED.
342 |
343 | Note: a group can only be submitted again if it fails.
344 |
345 | #### Parameters
346 |
347 | | Name | Type | Description |
348 | | :------ | :------ | :------ |
349 | | `client` | [`Algodv2`](Algodv2.md) | An Algodv2 client |
350 |
351 | #### Returns
352 |
353 | `Promise`\<`string`[]\>
354 |
355 | A promise that, upon success, resolves to a list of TxIDs of the submitted transactions.
356 |
357 | #### Defined in
358 |
359 | composer.ts:596
360 |
361 | ___
362 |
363 | ### parseMethodResponse
364 |
365 | ▸ `Static` **parseMethodResponse**(`method`, `methodResult`, `pendingInfo`): [`ABIResult`](../interfaces/ABIResult.md)
366 |
367 | Parses a single ABI Method transaction log into a ABI result object.
368 |
369 | #### Parameters
370 |
371 | | Name | Type |
372 | | :------ | :------ |
373 | | `method` | [`ABIMethod`](ABIMethod.md) |
374 | | `methodResult` | [`ABIResult`](../interfaces/ABIResult.md) |
375 | | `pendingInfo` | `Record`\<`string`, `any`\> |
376 |
377 | #### Returns
378 |
379 | [`ABIResult`](../interfaces/ABIResult.md)
380 |
381 | An ABIResult object
382 |
383 | #### Defined in
384 |
385 | composer.ts:775
386 |
```