This is page 70 of 93. Use http://codebase.md/goplausible/algorand-mcp?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── llms-install.md
├── llms.txt
├── package.json
├── packages
│ ├── client
│ │ ├── .env.example
│ │ ├── package.json
│ │ ├── README.md
│ │ ├── src
│ │ │ ├── env.ts
│ │ │ ├── index.ts
│ │ │ └── LocalWallet.ts
│ │ └── tsconfig.json
│ └── server
│ ├── .env.example
│ ├── API specs
│ │ ├── algod_api.json
│ │ ├── indexer_api.json
│ │ ├── mcp.json
│ │ ├── nfd_api.json
│ │ ├── ultrade_api.json
│ │ ├── vestige_api.json
│ │ └── vestige_free_api.json
│ ├── Dockerfile
│ ├── jest.config.js
│ ├── package.json
│ ├── README.md
│ ├── smithery.yaml
│ ├── src
│ │ ├── algorand-client.ts
│ │ ├── env.ts
│ │ ├── index.ts
│ │ ├── resources
│ │ │ ├── index.ts
│ │ │ ├── knowledge
│ │ │ │ ├── ARCs.txt
│ │ │ │ ├── developers-algokit-architecture-decisions.txt
│ │ │ │ ├── developers-algokit-cli.txt
│ │ │ │ ├── developers-algokit-utils-python.txt
│ │ │ │ ├── developers-algokit-utils-typescript.txt
│ │ │ │ ├── developers-clis.txt
│ │ │ │ ├── developers-details.txt
│ │ │ │ ├── developers-liquid-auth.txt
│ │ │ │ ├── developers-nodes.txt
│ │ │ │ ├── developers-puya.txt
│ │ │ │ ├── developers-python.txt
│ │ │ │ ├── developers-sdks-js.txt
│ │ │ │ ├── developers-sdks-python.txt
│ │ │ │ ├── developers-tealscript.txt
│ │ │ │ ├── developers.txt
│ │ │ │ ├── index.ts
│ │ │ │ ├── taxonomy
│ │ │ │ │ ├── algokit-cli:README.md
│ │ │ │ │ ├── algokit:cli:algokit.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2022-11-14_sandbox-approach.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2022-11-22_beaker-testing-strategy.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2023-01-11_beaker_productionisation_review.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2023-01-11_brew_install.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2023-01-12_smart-contract-deployment.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2023-06-06_frontend-templates.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2023-07-19_advanced_generate_command.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2024-01-13_native_binaries.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2024-01-23_init-wizard-v2.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2024-01-31_binary_distribution.md
│ │ │ │ │ ├── algokit:cli:architecture-decisions:2024-03-06_local_dev_ui_packaging.md
│ │ │ │ │ ├── algokit:cli:articles:output_stability.md
│ │ │ │ │ ├── algokit:cli:cli:index.md
│ │ │ │ │ ├── algokit:cli:features:compile.md
│ │ │ │ │ ├── algokit:cli:features:completions.md
│ │ │ │ │ ├── algokit:cli:features:config.md
│ │ │ │ │ ├── algokit:cli:features:dispenser.md
│ │ │ │ │ ├── algokit:cli:features:doctor.md
│ │ │ │ │ ├── algokit:cli:features:explore.md
│ │ │ │ │ ├── algokit:cli:features:generate.md
│ │ │ │ │ ├── algokit:cli:features:goal.md
│ │ │ │ │ ├── algokit:cli:features:init.md
│ │ │ │ │ ├── algokit:cli:features:localnet.md
│ │ │ │ │ ├── algokit:cli:features:project:bootstrap.md
│ │ │ │ │ ├── algokit:cli:features:project:deploy.md
│ │ │ │ │ ├── algokit:cli:features:project:link.md
│ │ │ │ │ ├── algokit:cli:features:project:list.md
│ │ │ │ │ ├── algokit:cli:features:project:run.md
│ │ │ │ │ ├── algokit:cli:features:project.md
│ │ │ │ │ ├── algokit:cli:features:tasks:analyze.md
│ │ │ │ │ ├── algokit:cli:features:tasks:ipfs.md
│ │ │ │ │ ├── algokit:cli:features:tasks:mint.md
│ │ │ │ │ ├── algokit:cli:features:tasks:nfd.md
│ │ │ │ │ ├── algokit:cli:features:tasks:opt.md
│ │ │ │ │ ├── algokit:cli:features:tasks:send.md
│ │ │ │ │ ├── algokit:cli:features:tasks:sign.md
│ │ │ │ │ ├── algokit:cli:features:tasks:transfer.md
│ │ │ │ │ ├── algokit:cli:features:tasks:vanity_address.md
│ │ │ │ │ ├── algokit:cli:features:tasks:wallet.md
│ │ │ │ │ ├── algokit:cli:features:tasks.md
│ │ │ │ │ ├── algokit:cli:tutorials:algokit-template.md
│ │ │ │ │ ├── algokit:cli:tutorials:intro.md
│ │ │ │ │ ├── algokit:cli:tutorials:smart-contracts.md
│ │ │ │ │ ├── algokit:docs:testnet_api.md
│ │ │ │ │ ├── algokit:lora:README.md
│ │ │ │ │ ├── algokit:README.md
│ │ │ │ │ ├── algokit:utils:python:markdown:apidocs:algokit_utils:algokit_utils.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:account.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:app-client.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:app-deploy.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:client.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:debugger.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:dispenser-client.md
│ │ │ │ │ ├── algokit:utils:python:markdown:capabilities:transfer.md
│ │ │ │ │ ├── algokit:utils:python:markdown:index.md
│ │ │ │ │ ├── algokit:utils:python:README.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:account.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:app-client.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:app-deploy.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:client.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:debugger.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:dispenser-client.md
│ │ │ │ │ ├── algokit:utils:python:source:capabilities:transfer.md
│ │ │ │ │ ├── algokit:utils:python:source:index.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:account.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:algorand-client.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:amount.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:app-client.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:app-deploy.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:app.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:asset.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:client.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:debugging.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:dispenser-client.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:event-emitter.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:indexer.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:testing.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:transaction-composer.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:transaction.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:transfer.md
│ │ │ │ │ ├── algokit:utils:typescript:capabilities:typed-app-clients.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:testing.TestLogger.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:testing.TransactionLogger.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_account_manager.AccountManager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_account.MultisigAccount.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_account.SigningAccount.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_algo_http_client_with_retry.AlgoHttpClientWithRetry.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_algorand_client_transaction_creator.AlgorandClientTransactionCreator.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_algorand_client_transaction_sender.AlgorandClientTransactionSender.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_algorand_client.AlgorandClient.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_amount.AlgoAmount.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_app_arc56.Arc56Method.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_app_client.AppClient.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_app_client.ApplicationClient.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_app_deployer.AppDeployer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_app_factory.AppFactory.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_app_manager.AppManager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_asset_manager.AssetManager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_async_event_emitter.AsyncEventEmitter.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_client_manager.ClientManager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_composer.TransactionComposer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_config.UpdatableConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_dispenser_client.TestNetDispenserApiClient.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_kmd_account_manager.KmdAccountManager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:classes:types_logic_error.LogicError.md
│ │ │ │ │ ├── algokit:utils:typescript:code:enums:types_app.OnSchemaBreak.md
│ │ │ │ │ ├── algokit:utils:typescript:code:enums:types_app.OnUpdate.md
│ │ │ │ │ ├── algokit:utils:typescript:code:enums:types_indexer.AccountStatus.md
│ │ │ │ │ ├── algokit:utils:typescript:code:enums:types_indexer.ApplicationOnComplete.md
│ │ │ │ │ ├── algokit:utils:typescript:code:enums:types_indexer.SignatureType.md
│ │ │ │ │ ├── algokit:utils:typescript:code:enums:types_lifecycle_events.EventType.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_account_manager.EnsureFundedResult.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_account.AccountConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_account.TransactionSignerAccount.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_algorand_client_interface.AlgorandClientInterface.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.Arc56Contract.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.Event.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.Method.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.ProgramSourceInfo.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.StorageKey.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.StorageMap.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_arc56.StructField.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientCallABIArgs.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientCallCoreParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientCompilationParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientCompilationResult.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientDeployCallInterfaceParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientDeployCoreParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientDeployParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppClientParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.AppSourceMaps.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.FundAppAccountParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.ResolveAppById.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.ResolveAppByIdBase.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_client.SourceMapExport.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_deployer.AppLookup.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_deployer.AppMetadata.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_factory.AppFactoryParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_manager.AppInformation.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_manager.BoxReference.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_manager.BoxValueRequestParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_manager.BoxValuesRequestParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.AppSources.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.AppSpec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.CallConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.DeclaredSchemaValueSpec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.Hint.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.ReservedSchemaValueSpec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.Schema.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.SchemaSpec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.StateSchemaSpec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app_spec.Struct.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppCallParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppCallTransactionResultOfType.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppCompilationResult.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppDeploymentParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppDeployMetadata.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppLookup.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppMetadata.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppReference.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppState.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.AppStorageSchema.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.BoxName.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.BoxReference.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.BoxValueRequestParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.BoxValuesRequestParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.CompiledTeal.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.CoreAppCallArgs.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.CreateAppParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.RawAppCallArgs.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.TealTemplateParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_app.UpdateAppParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_asset_manager.AssetInformation.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_asset_manager.BulkAssetOptInOutResult.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_asset.AssetBulkOptInOutParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_asset.AssetOptInParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_asset.AssetOptOutParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_asset.CreateAssetParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_client_manager.AlgoSdkClients.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_client_manager.TypedAppClient.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_client_manager.TypedAppFactory.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_composer.BuiltTransactions.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_config.Config.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_debugging.AVMTracesEventData.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_debugging.TealSourceDebugEventData.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_debugging.TealSourcesDebugEventData.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_dispenser_client.DispenserFundResponse.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_dispenser_client.DispenserLimitResponse.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_dispenser_client.TestNetDispenserApiClientParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_indexer.LookupAssetHoldingsOptions.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_logic_error.LogicErrorDetails.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_network_client.AlgoClientConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_network_client.AlgoConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_network_client.NetworkDetails.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_testing.AlgoKitLogCaptureFixture.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_testing.AlgorandFixture.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_testing.AlgorandFixtureConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_testing.AlgorandTestAutomationContext.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_testing.GetTestAccountParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_testing.LogSnapshotConfig.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.AtomicTransactionComposerToSend.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.ConfirmedTransactionResult.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.ConfirmedTransactionResults.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.SendAtomicTransactionComposerResults.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.SendParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.SendTransactionParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.SendTransactionResult.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.SendTransactionResults.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.TransactionGroupToSend.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transaction.TransactionToSign.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transfer.AlgoRekeyParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transfer.AlgoTransferParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transfer.EnsureFundedParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transfer.EnsureFundedReturnType.md
│ │ │ │ │ ├── algokit:utils:typescript:code:interfaces:types_transfer.TransferAssetParams.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:index.indexer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:index.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:testing.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_account_manager_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_account_manager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_account.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algo_http_client_with_retry.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client_asset_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client_interface.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client_transaction_creator.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client_transaction_sender.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client_transfer_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_algorand_client.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_amount_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_amount.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_arc56.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_client_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_client.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_deployer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_factory_and_client_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_factory.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_manager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_app.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_asset_manager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_asset.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_async_event_emitter_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_async_event_emitter.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_client_manager_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_client_manager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_composer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_config.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_debugging.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_dispenser_client_spec.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_dispenser_client.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_expand.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_indexer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_kmd_account_manager.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_lifecycle_events.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_logging.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_logic_error.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_network_client.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_testing.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_transaction.md
│ │ │ │ │ ├── algokit:utils:typescript:code:modules:types_transfer.md
│ │ │ │ │ ├── algokit:utils:typescript:code:README.md
│ │ │ │ │ ├── algokit:utils:typescript:README.md
│ │ │ │ │ ├── algokit:utils:typescript:v7-migration.md
│ │ │ │ │ ├── algokit:utils:typescript:v8-migration.md
│ │ │ │ │ ├── ARCs:ARC-template.md
│ │ │ │ │ ├── ARCs:assets:arc-0012:README.md
│ │ │ │ │ ├── ARCs:assets:arc-0034:TemplateForm.md
│ │ │ │ │ ├── ARCs:assets:arc-0062:README.md
│ │ │ │ │ ├── ARCs:pages:nfts.md
│ │ │ │ │ ├── ARCs:pages:wallets.md
│ │ │ │ │ ├── ARCs:README.md
│ │ │ │ │ ├── ARCs:specs:arc-0000.md
│ │ │ │ │ ├── ARCs:specs:arc-0001.md
│ │ │ │ │ ├── ARCs:specs:arc-0002.md
│ │ │ │ │ ├── ARCs:specs:arc-0003.md
│ │ │ │ │ ├── ARCs:specs:arc-0004.md
│ │ │ │ │ ├── ARCs:specs:arc-0005.md
│ │ │ │ │ ├── ARCs:specs:arc-0006.md
│ │ │ │ │ ├── ARCs:specs:arc-0007.md
│ │ │ │ │ ├── ARCs:specs:arc-0008.md
│ │ │ │ │ ├── ARCs:specs:arc-0009.md
│ │ │ │ │ ├── ARCs:specs:arc-0010.md
│ │ │ │ │ ├── ARCs:specs:arc-0011.md
│ │ │ │ │ ├── ARCs:specs:arc-0012.md
│ │ │ │ │ ├── ARCs:specs:arc-0015.md
│ │ │ │ │ ├── ARCs:specs:arc-0016.md
│ │ │ │ │ ├── ARCs:specs:arc-0018.md
│ │ │ │ │ ├── ARCs:specs:arc-0019.md
│ │ │ │ │ ├── ARCs:specs:arc-0020.md
│ │ │ │ │ ├── ARCs:specs:arc-0021.md
│ │ │ │ │ ├── ARCs:specs:arc-0022.md
│ │ │ │ │ ├── ARCs:specs:arc-0023.md
│ │ │ │ │ ├── ARCs:specs:arc-0025.md
│ │ │ │ │ ├── ARCs:specs:arc-0026.md
│ │ │ │ │ ├── ARCs:specs:arc-0028.md
│ │ │ │ │ ├── ARCs:specs:arc-0032.md
│ │ │ │ │ ├── ARCs:specs:arc-0033.md
│ │ │ │ │ ├── ARCs:specs:arc-0034.md
│ │ │ │ │ ├── ARCs:specs:arc-0035.md
│ │ │ │ │ ├── ARCs:specs:arc-0036.md
│ │ │ │ │ ├── ARCs:specs:arc-0042.md
│ │ │ │ │ ├── ARCs:specs:arc-0047.md
│ │ │ │ │ ├── ARCs:specs:arc-0048.md
│ │ │ │ │ ├── ARCs:specs:arc-0049.md
│ │ │ │ │ ├── ARCs:specs:arc-0054.md
│ │ │ │ │ ├── ARCs:specs:arc-0055.md
│ │ │ │ │ ├── ARCs:specs:arc-0056.md
│ │ │ │ │ ├── ARCs:specs:arc-0059.md
│ │ │ │ │ ├── ARCs:specs:arc-0062.md
│ │ │ │ │ ├── ARCs:specs:arc-0065.md
│ │ │ │ │ ├── ARCs:specs:arc-0069.md
│ │ │ │ │ ├── ARCs:specs:arc-0072.md
│ │ │ │ │ ├── ARCs:specs:arc-0073.md
│ │ │ │ │ ├── ARCs:specs:arc-0074.md
│ │ │ │ │ ├── ARCs:specs:arc-0076.md
│ │ │ │ │ ├── ARCs:specs:arc-0078.md
│ │ │ │ │ ├── ARCs:specs:arc-0079.md
│ │ │ │ │ ├── ARCs:specs:arc-0200.md
│ │ │ │ │ ├── clis_index.md
│ │ │ │ │ ├── developer:docs:about.md
│ │ │ │ │ ├── developer:docs:clis:algokey:algokey.md
│ │ │ │ │ ├── developer:docs:clis:algokey:generate.md
│ │ │ │ │ ├── developer:docs:clis:algokey:import.md
│ │ │ │ │ ├── developer:docs:clis:algokey:multisig:append-auth-addr.md
│ │ │ │ │ ├── developer:docs:clis:algokey:multisig:multisig.md
│ │ │ │ │ ├── developer:docs:clis:algokey:part:info.md
│ │ │ │ │ ├── developer:docs:clis:algokey:part:part.md
│ │ │ │ │ ├── developer:docs:clis:algokey:part:reparent.md
│ │ │ │ │ ├── developer:docs:clis:algokey:sign.md
│ │ │ │ │ ├── developer:docs:clis:conduit:conduit.md
│ │ │ │ │ ├── developer:docs:clis:conduit:init.md
│ │ │ │ │ ├── developer:docs:clis:conduit:list:exporters.md
│ │ │ │ │ ├── developer:docs:clis:conduit:list:importers.md
│ │ │ │ │ ├── developer:docs:clis:conduit:list:list.md
│ │ │ │ │ ├── developer:docs:clis:conduit:list:processors.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:diagcfg.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:metric:disable.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:metric:enable.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:metric:metric.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:metric:status.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:telemetry:disable.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:telemetry:enable.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:telemetry:endpoint.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:telemetry:name.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:telemetry:status.md
│ │ │ │ │ ├── developer:docs:clis:diagcfg:telemetry:telemetry.md
│ │ │ │ │ ├── developer:docs:clis:goal:node:restart.md
│ │ │ │ │ ├── developer:docs:clis:goal:node:start.md
│ │ │ │ │ ├── developer:docs:clis:goal:node:status.md
│ │ │ │ │ ├── developer:docs:clis:goal:node:stop.md
│ │ │ │ │ ├── developer:docs:clis:goal:node:wait.md
│ │ │ │ │ ├── developer:docs:clis:goal:protocols.md
│ │ │ │ │ ├── developer:docs:clis:goal:report.md
│ │ │ │ │ ├── developer:docs:clis:goal:version.md
│ │ │ │ │ ├── developer:docs:clis:goal:wallet:list.md
│ │ │ │ │ ├── developer:docs:clis:goal:wallet:new.md
│ │ │ │ │ ├── developer:docs:clis:goal:wallet:wallet.md
│ │ │ │ │ ├── developer:docs:clis:indexer:api-config.md
│ │ │ │ │ ├── developer:docs:clis:indexer:daemon.md
│ │ │ │ │ ├── developer:docs:clis:indexer:indexer.md
│ │ │ │ │ ├── developer:docs:clis:indexer:util:util.md
│ │ │ │ │ ├── developer:docs:clis:indexer:util:validator.md
│ │ │ │ │ ├── developer:docs:clis:kmd.md
│ │ │ │ │ ├── developer:docs:clis:tealdbg:debug.md
│ │ │ │ │ ├── developer:docs:clis:tealdbg:remote.md
│ │ │ │ │ ├── developer:docs:clis:tealdbg:tealdbg.md
│ │ │ │ │ ├── developer:docs:details:accounts:create.md
│ │ │ │ │ ├── developer:docs:details:accounts:index.md
│ │ │ │ │ ├── developer:docs:details:accounts:rekey.md
│ │ │ │ │ ├── developer:docs:details:algorand_consensus.md
│ │ │ │ │ ├── developer:docs:details:algorand-networks:betanet.md
│ │ │ │ │ ├── developer:docs:details:algorand-networks:index.md
│ │ │ │ │ ├── developer:docs:details:algorand-networks:mainnet.md
│ │ │ │ │ ├── developer:docs:details:algorand-networks:testnet.md
│ │ │ │ │ ├── developer:docs:details:asa.md
│ │ │ │ │ ├── developer:docs:details:atc.md
│ │ │ │ │ ├── developer:docs:details:atomic_transfers.md
│ │ │ │ │ ├── developer:docs:details:conduit.md
│ │ │ │ │ ├── developer:docs:details:crust.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:guidelines.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:jsonspec.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v1.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v10.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v2.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v3.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v4.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v5.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v6.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v7.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v8.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:opcodes:v9.md
│ │ │ │ │ ├── developer:docs:details:dapps:avm:teal:specification.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:ABI:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:apps:create.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:apps:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:apps:innertx.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:apps:state.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:apps:txs.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:debugging.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:frontend:apps.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:frontend:smartsigs.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:guidelines.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:smartsigs:index.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:smartsigs:modes.md
│ │ │ │ │ ├── developer:docs:details:dapps:smart-contracts:smartsigs:walkthrough.md
│ │ │ │ │ ├── developer:docs:details:dapps:writing-contracts:beaker.md
│ │ │ │ │ ├── developer:docs:details:dapps:writing-contracts:pyteal.md
│ │ │ │ │ ├── developer:docs:details:dapps:writing-contracts:python.md
│ │ │ │ │ ├── developer:docs:details:encoding.md
│ │ │ │ │ ├── developer:docs:details:ethereum_to_algorand.md
│ │ │ │ │ ├── developer:docs:details:index.md
│ │ │ │ │ ├── developer:docs:details:indexer.md
│ │ │ │ │ ├── developer:docs:details:parameter_tables.md
│ │ │ │ │ ├── developer:docs:details:stateproofs:index.md
│ │ │ │ │ ├── developer:docs:details:stateproofs:light_client.md
│ │ │ │ │ ├── developer:docs:details:technical_faq.md
│ │ │ │ │ ├── developer:docs:details:transactions:index.md
│ │ │ │ │ ├── developer:docs:details:transactions:offline_transactions.md
│ │ │ │ │ ├── developer:docs:details:transactions:payment_prompts.md
│ │ │ │ │ ├── developer:docs:details:transactions:signatures.md
│ │ │ │ │ ├── developer:docs:details:transactions:transactions.md
│ │ │ │ │ ├── developer:docs:details:useful_resources.md
│ │ │ │ │ ├── developer:docs:get-started:algokit.md
│ │ │ │ │ ├── developer:docs:get-started:basics:what_is_blockchain.md
│ │ │ │ │ ├── developer:docs:get-started:basics:whats_a_dapp.md
│ │ │ │ │ ├── developer:docs:get-started:basics:where_to_start.md
│ │ │ │ │ ├── developer:docs:get-started:basics:why_algorand.md
│ │ │ │ │ ├── developer:docs:get-started:tokenization:ft.md
│ │ │ │ │ ├── developer:docs:get-started:tokenization:nft.md
│ │ │ │ │ ├── developer:docs:index.md
│ │ │ │ │ ├── developer:docs:rest-apis:algod.md
│ │ │ │ │ ├── developer:docs:rest-apis:indexer.md
│ │ │ │ │ ├── developer:docs:rest-apis:kmd.md
│ │ │ │ │ ├── developer:docs:rest-apis:restendpoints.md
│ │ │ │ │ ├── developer:docs:run-a-node:operations:catchup.md
│ │ │ │ │ ├── developer:docs:run-a-node:operations:switch_networks.md
│ │ │ │ │ ├── developer:docs:run-a-node:participate:generate_keys.md
│ │ │ │ │ ├── developer:docs:run-a-node:participate:index.md
│ │ │ │ │ ├── developer:docs:run-a-node:participate:offline.md
│ │ │ │ │ ├── developer:docs:run-a-node:participate:online.md
│ │ │ │ │ ├── developer:docs:run-a-node:participate:renew.md
│ │ │ │ │ ├── developer:docs:run-a-node:reference:artifacts.md
│ │ │ │ │ ├── developer:docs:run-a-node:reference:config.md
│ │ │ │ │ ├── developer:docs:run-a-node:reference:relay.md
│ │ │ │ │ ├── developer:docs:run-a-node:reference:telemetry-config.md
│ │ │ │ │ ├── developer:docs:run-a-node:setup:indexer.md
│ │ │ │ │ ├── developer:docs:run-a-node:setup:install.md
│ │ │ │ │ ├── developer:docs:run-a-node:setup:node-troubleshooting.md
│ │ │ │ │ ├── developer:docs:run-a-node:setup:types.md
│ │ │ │ │ ├── developer:docs:sdks:go:index.md
│ │ │ │ │ ├── developer:docs:sdks:index.md
│ │ │ │ │ ├── developer:docs:sdks:java:index.md
│ │ │ │ │ ├── developer:docs:sdks:javascript:index.md
│ │ │ │ │ ├── developer:docs:sdks:python:index.md
│ │ │ │ │ ├── developer:python:code:example:accounts.md
│ │ │ │ │ ├── developer:python:code:example:arc4_types.md
│ │ │ │ │ ├── developer:python:code:example:assets.md
│ │ │ │ │ ├── developer:python:code:example:box_storage.md
│ │ │ │ │ ├── developer:python:code:example:control_flow.md
│ │ │ │ │ ├── developer:python:code:example:crypto:merkle_tree.md
│ │ │ │ │ ├── developer:python:code:example:defi:amm.md
│ │ │ │ │ ├── developer:python:code:example:defi:auction.md
│ │ │ │ │ ├── developer:python:code:example:defi:htlc_logicsig.md
│ │ │ │ │ ├── developer:python:code:example:defi:marketplace.md
│ │ │ │ │ ├── developer:python:code:example:events:arc28_events.md
│ │ │ │ │ ├── developer:python:code:example:global_storage.md
│ │ │ │ │ ├── developer:python:code:example:governance:simple_voting.md
│ │ │ │ │ ├── developer:python:code:example:hello_world.md
│ │ │ │ │ ├── developer:python:code:example:inner_transactions.md
│ │ │ │ │ ├── developer:python:code:example:local_storage.md
│ │ │ │ │ ├── developer:python:code:example:nft:proof_of_attendance.md
│ │ │ │ │ ├── developer:python:code:example:privacy:zk_whitelist.md
│ │ │ │ │ ├── developer:python:code:example:scratch_storage.md
│ │ │ │ │ ├── developer:python:code:example:self_payment.md
│ │ │ │ │ ├── developer:python:code:example:struct_in_box.md
│ │ │ │ │ ├── developer:python:code:example:subsidize_app_call.md
│ │ │ │ │ ├── developer:python:code:example:transactions.md
│ │ │ │ │ ├── developer:python:code:example:utility:calculator.md
│ │ │ │ │ ├── devportal-code-examples:projects:python-contract-examples:README.md
│ │ │ │ │ ├── devportal-code-examples:README.md
│ │ │ │ │ ├── docs:.walletconnect:index.md
│ │ │ │ │ ├── docs:.walletconnect:walletconnect-schema.md
│ │ │ │ │ ├── docs:README.md
│ │ │ │ │ ├── docs:scripts:example_tracker:example_list.md
│ │ │ │ │ ├── docs:scripts:README.md
│ │ │ │ │ ├── index.md
│ │ │ │ │ ├── liquid_auth_index.md
│ │ │ │ │ ├── liquid-auth:ARCHITECTURE.md
│ │ │ │ │ ├── liquid-auth:decisions:1-Service-Authentication.md
│ │ │ │ │ ├── liquid-auth:decisions:2-Bidirectional-Communication.md
│ │ │ │ │ ├── liquid-auth:decisions:3-Peer-to-Peer-Signaling.md
│ │ │ │ │ ├── liquid-auth:decisions:4-Fido-Extension.md
│ │ │ │ │ ├── liquid-auth:decisions:README.md
│ │ │ │ │ ├── liquid-auth:docs:architecture.md
│ │ │ │ │ ├── liquid-auth:docs:clients:android:provider-service:authenticate.md
│ │ │ │ │ ├── liquid-auth:docs:clients:android:provider-service:register.md
│ │ │ │ │ ├── liquid-auth:docs:clients:browser:authentication.md
│ │ │ │ │ ├── liquid-auth:docs:clients:browser:example.md
│ │ │ │ │ ├── liquid-auth:docs:introduction.md
│ │ │ │ │ ├── liquid-auth:docs:README.md
│ │ │ │ │ ├── liquid-auth:docs:server:environment-variables.md
│ │ │ │ │ ├── liquid-auth:docs:server:integrations.md
│ │ │ │ │ ├── liquid-auth:docs:server:introduction.md
│ │ │ │ │ ├── liquid-auth:docs:server:running-locally.md
│ │ │ │ │ ├── liquid-auth:README.md
│ │ │ │ │ ├── liquid-auth:SEQUENCE.md
│ │ │ │ │ ├── liquid-auth:services:liquid-auth-api-js:src:assertion:assertion.controller.post.request.md
│ │ │ │ │ ├── liquid-auth:services:liquid-auth-api-js:src:assertion:assertion.controller.post.response.md
│ │ │ │ │ ├── liquid-auth:services:liquid-auth-api-js:src:attestation:attestation.controller.post.request.md
│ │ │ │ │ ├── liquid-auth:services:liquid-auth-api-js:src:auth:auth.controller.get.user.md
│ │ │ │ │ ├── liquid-auth:sites:express-dapp:README.md
│ │ │ │ │ ├── liquid-auth:VISION.md
│ │ │ │ │ ├── puya_index.md
│ │ │ │ │ ├── puya:docs:algopy_testing:index.md
│ │ │ │ │ ├── puya:docs:api-algopy.arc4.md
│ │ │ │ │ ├── puya:docs:api-algopy.gtxn.md
│ │ │ │ │ ├── puya:docs:api-algopy.itxn.md
│ │ │ │ │ ├── puya:docs:api-algopy.md
│ │ │ │ │ ├── puya:docs:api-algopy.op.md
│ │ │ │ │ ├── puya:docs:api.md
│ │ │ │ │ ├── puya:docs:compiler.md
│ │ │ │ │ ├── puya:docs:index.md
│ │ │ │ │ ├── puya:docs:language-guide.md
│ │ │ │ │ ├── puya:docs:lg-arc28.md
│ │ │ │ │ ├── puya:docs:lg-arc4.md
│ │ │ │ │ ├── puya:docs:lg-builtins.md
│ │ │ │ │ ├── puya:docs:lg-calling-apps.md
│ │ │ │ │ ├── puya:docs:lg-compile.md
│ │ │ │ │ ├── puya:docs:lg-control.md
│ │ │ │ │ ├── puya:docs:lg-errors.md
│ │ │ │ │ ├── puya:docs:lg-logs.md
│ │ │ │ │ ├── puya:docs:lg-modules.md
│ │ │ │ │ ├── puya:docs:lg-opcode-budget.md
│ │ │ │ │ ├── puya:docs:lg-ops.md
│ │ │ │ │ ├── puya:docs:lg-storage.md
│ │ │ │ │ ├── puya:docs:lg-structure.md
│ │ │ │ │ ├── puya:docs:lg-transactions.md
│ │ │ │ │ ├── puya:docs:lg-types.md
│ │ │ │ │ ├── puya:docs:lg-unsupported-python-features.md
│ │ │ │ │ ├── puya:docs:principles.md
│ │ │ │ │ ├── puya:examples:auction:README.md
│ │ │ │ │ ├── puya:python:testing:docs:algopy.md
│ │ │ │ │ ├── puya:python:testing:docs:api.md
│ │ │ │ │ ├── puya:python:testing:docs:coverage.md
│ │ │ │ │ ├── puya:python:testing:docs:examples.md
│ │ │ │ │ ├── puya:python:testing:docs:faq.md
│ │ │ │ │ ├── puya:python:testing:docs:index.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:arc4-types.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:avm-types.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:concepts.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:contract-testing.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:index.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:opcodes.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:signature-testing.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:state-management.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:subroutines.md
│ │ │ │ │ ├── puya:python:testing:docs:testing-guide:transactions.md
│ │ │ │ │ ├── puya:python:testing:examples:README.md
│ │ │ │ │ ├── puya:python:testing:README.md
│ │ │ │ │ ├── puya:README.md
│ │ │ │ │ ├── puya:src:puya:ARCHITECTURE.md
│ │ │ │ │ ├── puya:src:puyapy:_typeshed:README.md
│ │ │ │ │ ├── puya:src:puyapy:_vendor:mypy:typeshed:stdlib:_typeshed:README.md
│ │ │ │ │ ├── puya:src:puyapy:awst_build:README.md
│ │ │ │ │ ├── puya:stubs:README.md
│ │ │ │ │ ├── puya:tests:test_expected_output:README.md
│ │ │ │ │ ├── puya:typescript:docs:architecture-decisions:2024-05-21_primitive-bytes-and-strings.md
│ │ │ │ │ ├── puya:typescript:docs:architecture-decisions:2024-05-21_primitive-integer-types.md
│ │ │ │ │ ├── puya:typescript:docs:README.md
│ │ │ │ │ ├── puya:typescript:packages:algo-ts:readme.md
│ │ │ │ │ ├── puya:typescript:README.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIAddressType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIArrayDynamicType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIArrayStaticType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIBoolType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIByteType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIContract.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIInterface.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIMethod.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIStringType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABITupleType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIUfixedType.md
│ │ │ │ │ ├── SDKs:javascript:classes:ABIUintType.md
│ │ │ │ │ ├── SDKs:javascript:classes:Algodv2.md
│ │ │ │ │ ├── SDKs:javascript:classes:AtomicTransactionComposer.md
│ │ │ │ │ ├── SDKs:javascript:classes:DryrunResult.md
│ │ │ │ │ ├── SDKs:javascript:classes:Indexer.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.Account.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AccountParticipation.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AccountResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AccountsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AccountStateDelta.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.Application.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationLocalState.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationLocalStatesResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationLogData.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationLogsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationParams.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ApplicationStateSchema.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.Asset.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AssetBalancesResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AssetHolding.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AssetHoldingsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AssetParams.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AssetResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.AssetsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.Block.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.BlockRewards.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.BlockUpgradeState.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.BlockUpgradeVote.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.Box.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.BoxDescriptor.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.BoxesResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ErrorResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.EvalDelta.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.EvalDeltaKeyValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.HashFactory.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.HealthCheck.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.IndexerStateProofMessage.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.MerkleArrayProof.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.MiniAssetHolding.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.ParticipationUpdates.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofFields.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofParticipant.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofReveal.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofSignature.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofSigSlot.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofTracking.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateProofVerifier.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.StateSchema.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TealKeyValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TealValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.Transaction.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionApplication.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionAssetConfig.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionAssetFreeze.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionAssetTransfer.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionKeyreg.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionPayment.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionSignature.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionSignatureLogicsig.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionSignatureMultisig.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionSignatureMultisigSubsignature.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:indexerModels.TransactionStateProof.md
│ │ │ │ │ ├── SDKs:javascript:classes:Kmd.md
│ │ │ │ │ ├── SDKs:javascript:classes:LogicSig.md
│ │ │ │ │ ├── SDKs:javascript:classes:LogicSigAccount.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.Account.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AccountApplicationResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AccountAssetHolding.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AccountAssetResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AccountAssetsInformationResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AccountParticipation.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AccountStateDelta.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AppCallLogs.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.Application.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationInitialStates.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationKVStorage.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationLocalReference.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationLocalState.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationParams.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationStateOperation.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ApplicationStateSchema.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.Asset.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AssetHolding.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AssetHoldingReference.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AssetParams.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AvmKeyValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.AvmValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BlockHashResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BlockLogsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BlockResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BlockTxidsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.Box.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BoxDescriptor.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BoxesResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BoxReference.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.BuildVersion.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.CompileResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.DisassembleResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.DryrunRequest.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.DryrunResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.DryrunSource.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.DryrunState.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.DryrunTxnResult.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ErrorResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.EvalDelta.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.EvalDeltaKeyValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.GetBlockTimeStampOffsetResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.GetSyncRoundResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.KvDelta.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.LedgerStateDeltaForTransactionGroup.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.LightBlockHeaderProof.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.NodeStatusResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.PendingTransactionResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.PendingTransactionsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.PostTransactionsResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.ScratchChange.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateInitialStates.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateRequest.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateRequestTransactionGroup.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateTraceConfig.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateTransactionGroupResult.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateTransactionResult.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulateUnnamedResourcesAccessed.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulationEvalOverrides.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulationOpcodeTraceUnit.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SimulationTransactionExecTrace.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.StateProof.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.StateProofMessage.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.SupplyResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.TealKeyValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.TealValue.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.TransactionGroupLedgerStateDeltasForRoundResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.TransactionParametersResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.TransactionProofResponse.md
│ │ │ │ │ ├── SDKs:javascript:classes:modelsv2.Version.md
│ │ │ │ │ ├── SDKs:javascript:classes:SourceMap.md
│ │ │ │ │ ├── SDKs:javascript:classes:Transaction.md
│ │ │ │ │ ├── SDKs:javascript:enums:ABIReferenceType.md
│ │ │ │ │ ├── SDKs:javascript:enums:ABITransactionType.md
│ │ │ │ │ ├── SDKs:javascript:enums:AtomicTransactionComposerStatus.md
│ │ │ │ │ ├── SDKs:javascript:enums:IntDecoding.md
│ │ │ │ │ ├── SDKs:javascript:enums:OnApplicationComplete.md
│ │ │ │ │ ├── SDKs:javascript:enums:TransactionType.md
│ │ │ │ │ ├── SDKs:javascript:examples:README.md
│ │ │ │ │ ├── SDKs:javascript:FAQ.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIContractNetworkInfo.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIContractNetworks.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIContractParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIInterfaceParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIMethodArgParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIMethodParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIMethodReturnParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:ABIResult.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:Account.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:Address.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:AlgodTokenHeader.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:BaseHTTPClient.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:BaseHTTPClientError.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:BaseHTTPClientResponse.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:BoxReference.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:CustomTokenHeader.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedAssetParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedBoxReference.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedGlobalStateSchema.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedLocalStateSchema.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedLogicSig.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedLogicSigAccount.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedMultisig.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedSignedTransaction.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedSubsig.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:EncodedTransaction.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:IndexerTokenHeader.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:KMDTokenHeader.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:MultisigMetadata.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:SignedTransaction.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:SuggestedParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:TransactionParams.md
│ │ │ │ │ ├── SDKs:javascript:interfaces:TransactionWithSigner.md
│ │ │ │ │ ├── SDKs:javascript:modules:indexerModels.md
│ │ │ │ │ ├── SDKs:javascript:modules:modelsv2.md
│ │ │ │ │ ├── SDKs:javascript:modules.md
│ │ │ │ │ ├── SDKs:javascript:README.md
│ │ │ │ │ ├── SDKs:python:algosdk:v2client:harness:README.md
│ │ │ │ │ ├── SDKs:python:examples:README.md
│ │ │ │ │ ├── SDKs:python:README.md
│ │ │ │ │ ├── tealscript:examples_amm_README.md
│ │ │ │ │ ├── tealscript:examples_auction_README.md
│ │ │ │ │ ├── tealscript:examples_big_box_README.md
│ │ │ │ │ ├── tealscript:examples_itxns_README.md
│ │ │ │ │ ├── tealscript:examples_lsig_with_app_README.md
│ │ │ │ │ ├── tealscript:examples_reti_README.md
│ │ │ │ │ ├── tealscript:FEATURES.md
│ │ │ │ │ ├── tealscript:guides_atomic_txn.md
│ │ │ │ │ ├── tealscript:guides_features.md
│ │ │ │ │ ├── tealscript:guides_getting_started.md
│ │ │ │ │ ├── tealscript:guides_inner_transactions.md
│ │ │ │ │ ├── tealscript:guides_lifecycle.md
│ │ │ │ │ ├── tealscript:guides_math.md
│ │ │ │ │ ├── tealscript:guides_methods.md
│ │ │ │ │ ├── tealscript:guides_multiple_contracts.md
│ │ │ │ │ ├── tealscript:guides_pyteal.md
│ │ │ │ │ ├── tealscript:guides_storage.md
│ │ │ │ │ ├── tealscript:guides_Supported Types_arrays.md
│ │ │ │ │ ├── tealscript:guides_Supported Types_numbers.md
│ │ │ │ │ ├── TEALScript:README.md
│ │ │ │ │ ├── tealscript:tests_test_package_README.md
│ │ │ │ │ ├── tealscript:tutorials_Hello World_0001-intro.md
│ │ │ │ │ ├── tealscript:tutorials_Hello World_0002-init.md
│ │ │ │ │ ├── tealscript:tutorials_Hello World_0003-contract.md
│ │ │ │ │ ├── tealscript:tutorials_Hello World_0004-artifacts.md
│ │ │ │ │ ├── tealscript:tutorials_Hello World_0005-hello.md
│ │ │ │ │ └── tealscript:tutorials_Hello World_0006-test.md
│ │ │ │ └── taxonomy-categories
│ │ │ │ ├── algokit-utils.json
│ │ │ │ ├── algokit.json
│ │ │ │ ├── arcs.json
│ │ │ │ ├── clis.json
│ │ │ │ ├── details.json
│ │ │ │ ├── developers.json
│ │ │ │ ├── liquid-auth.json
│ │ │ │ ├── nodes.json
│ │ │ │ ├── puya.json
│ │ │ │ ├── python.json
│ │ │ │ ├── sdks.json
│ │ │ │ └── tealscript.json
│ │ │ └── wallet
│ │ │ └── index.ts
│ │ ├── tools
│ │ │ ├── accountManager.ts
│ │ │ ├── algodManager.ts
│ │ │ ├── apiManager
│ │ │ │ ├── algod
│ │ │ │ │ ├── account.ts
│ │ │ │ │ ├── application.ts
│ │ │ │ │ ├── asset.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── transaction.ts
│ │ │ │ ├── example
│ │ │ │ │ ├── get-balance.ts
│ │ │ │ │ └── index.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── indexer
│ │ │ │ │ ├── account.ts
│ │ │ │ │ ├── application.ts
│ │ │ │ │ ├── asset.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── transaction.ts
│ │ │ │ ├── nfd
│ │ │ │ │ └── index.ts
│ │ │ │ ├── tinyman
│ │ │ │ │ ├── analytics.ts
│ │ │ │ │ ├── bootstrap.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── liquidity.ts
│ │ │ │ │ ├── opt_in.ts
│ │ │ │ │ ├── pool.ts
│ │ │ │ │ ├── remove_liquidity.ts
│ │ │ │ │ └── swap.ts
│ │ │ │ ├── ultrade
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── market.ts
│ │ │ │ │ ├── system.ts
│ │ │ │ │ └── wallet.ts
│ │ │ │ └── vestige
│ │ │ │ ├── assets.ts
│ │ │ │ ├── balances.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── networks.ts
│ │ │ │ ├── notes.ts
│ │ │ │ ├── pools.ts
│ │ │ │ ├── protocols.ts
│ │ │ │ ├── swaps.ts
│ │ │ │ └── vaults.ts
│ │ │ ├── arc26Manager.ts
│ │ │ ├── index.ts
│ │ │ ├── knowledgeManager.ts
│ │ │ ├── transactionManager
│ │ │ │ ├── accountTransactions.ts
│ │ │ │ ├── appTransactions
│ │ │ │ │ ├── callTxn.ts
│ │ │ │ │ ├── clearTxn.ts
│ │ │ │ │ ├── closeOutTxn.ts
│ │ │ │ │ ├── createTxn.ts
│ │ │ │ │ ├── deleteTxn.ts
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── optInTxn.ts
│ │ │ │ │ ├── test
│ │ │ │ │ │ ├── counter_approval.teal
│ │ │ │ │ │ ├── counter_clear.teal
│ │ │ │ │ │ ├── storage_test_approval_v2.teal
│ │ │ │ │ │ ├── storage_test_approval.teal
│ │ │ │ │ │ └── storage_test_clear.teal
│ │ │ │ │ ├── types.ts
│ │ │ │ │ └── updateTxn.ts
│ │ │ │ ├── assetTransactions.ts
│ │ │ │ ├── generalTransaction.ts
│ │ │ │ └── index.ts
│ │ │ └── utilityManager.ts
│ │ ├── types.ts
│ │ └── utils
│ │ └── responseProcessor.ts
│ ├── tests
│ │ ├── resources
│ │ │ ├── algod
│ │ │ │ ├── account.test.ts
│ │ │ │ ├── application.test.ts
│ │ │ │ ├── asset.test.ts
│ │ │ │ └── transaction.test.ts
│ │ │ └── indexer
│ │ │ ├── account.test.ts
│ │ │ ├── application.test.ts
│ │ │ ├── asset.test.ts
│ │ │ └── transaction.test.ts
│ │ └── tools
│ │ ├── accountManager.test.ts
│ │ ├── algodManager.test.ts
│ │ ├── apiManager
│ │ │ └── example
│ │ │ └── get-balance.test.ts
│ │ ├── transactionManager
│ │ │ ├── accountTransactionManager.test.ts
│ │ │ ├── appTransactionManager.test.ts
│ │ │ ├── assetTransactionManager.test.ts
│ │ │ ├── generalTransactionManager.test.ts
│ │ │ └── transactionManager.test.ts
│ │ └── utilityManager.test.ts
│ └── tsconfig.json
├── README.md
├── rename_files.sh
└── tsconfig.json
```
# Files
--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/developer:docs:details:dapps:smart-contracts:frontend:apps.md:
--------------------------------------------------------------------------------
```markdown
1 | title: Interact with smart contracts
2 |
3 | This guide covers using smart contracts with the Algorand SDKs. Smart contracts form the basis for applications written in [Transaction Execution Approval Language (TEAL)](/docs/get-details/dapps/avm/teal/) or with Python using the [PyTeal](/docs/get-details/dapps/writing-contracts/pyteal) library.
4 |
5 |
6 | # Application lifecycle
7 |
8 | This guide follows an application throughout its [lifecycle](/docs/get-details/dapps/smart-contracts/apps/#the-lifecycle-of-a-smart-contract) from initial creation, to usage, to modification and finally deletion. The application stores the number of times it is called within its _global state_ and also stores the number of times each user account calls the application within their _local state_. Midway through the lifecycle, the application is upgraded to add an additional key:value pair to the user's _local storage_ for storing the call timestamp.
9 |
10 | # Environment setup
11 |
12 | This guide requires two accounts:
13 |
14 | === "Python"
15 | ```python
16 | # user declared account mnemonics
17 | creator_mnemonic = "Your first 25-word mnemonic goes here"
18 | user_mnemonic = "A second distinct 25-word mnemonic goes here"
19 | ```
20 |
21 | === "JavaScript"
22 | ```javascript
23 | // user declared account mnemonics
24 | creatorMnemonic = "Your 25-word mnemonic goes here";
25 | userMnemonic = "A second distinct 25-word mnemonic goes here";
26 | ```
27 |
28 | === "Java"
29 | ```Java
30 | // user declared account mnemonics
31 | String creatorMnemonic = "Your 25-word mnemonic goes here";
32 | String userMnemonic = "A second distinct 25-word mnemonic goes here";
33 | ```
34 |
35 | === "Go"
36 | ```go
37 | // user defined mnemonics
38 | const creatorMnemonic = "Your 25-word mnemonic goes here"
39 | const userMnemonic = "A second distinct 25-word mnemonic goes here"
40 | ```
41 |
42 | An `algod` client connection is also required. The following connects using Sandbox:
43 |
44 | === "Python"
45 | <!-- ===PYSDK_ALGOD_CREATE_CLIENT=== -->
46 | ```python
47 | # Create a new algod client, configured to connect to our local sandbox
48 | algod_address = "http://localhost:4001"
49 | algod_token = "a" * 64
50 | algod_client = algod.AlgodClient(algod_token, algod_address)
51 |
52 | # Or, if necessary, pass alternate headers
53 |
54 | # Create a new client with an alternate api key header
55 | special_algod_client = algod.AlgodClient(
56 | "", algod_address, headers={"X-API-Key": algod_token}
57 | )
58 | ```
59 | [Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/overview.py#L10-L21)
60 | <!-- ===PYSDK_ALGOD_CREATE_CLIENT=== -->
61 |
62 | === "JavaScript"
63 | <!-- ===JSSDK_ALGOD_CREATE_CLIENT=== -->
64 | ```javascript
65 | const algodToken = 'a'.repeat(64);
66 | const algodServer = 'http://localhost';
67 | const algodPort = 4001;
68 |
69 | const algodClient = new algosdk.Algodv2(algodToken, algodServer, algodPort);
70 | ```
71 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/overview.ts#L7-L12)
72 | <!-- ===JSSDK_ALGOD_CREATE_CLIENT=== -->
73 |
74 | === "Java"
75 | <!-- ===JAVASDK_ALGOD_CREATE_CLIENT=== -->
76 | ```java
77 | String algodHost = "http://localhost";
78 | int algodPort = 4001;
79 | String algodToken = "a".repeat(64);
80 | AlgodClient algodClient = new AlgodClient(algodHost, algodPort, algodToken);
81 |
82 | // OR if the API provider requires a specific header key for the token
83 | String tokenHeader = "X-API-Key";
84 | AlgodClient otherAlgodClient = new AlgodClient(algodHost, algodPort, algodToken, tokenHeader);
85 | ```
86 | [Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/Overview.java#L94-L102)
87 | <!-- ===JAVASDK_ALGOD_CREATE_CLIENT=== -->
88 |
89 | === "Go"
90 | <!-- ===GOSDK_ALGOD_CREATE_CLIENT=== -->
91 | ```go
92 | // Create a new algod client, configured to connect to out local sandbox
93 | var algodAddress = "http://localhost:4001"
94 | var algodToken = strings.Repeat("a", 64)
95 | algodClient, _ := algod.MakeClient(
96 | algodAddress,
97 | algodToken,
98 | )
99 |
100 | // Or, if necessary, pass alternate headers
101 |
102 | var algodHeader common.Header
103 | algodHeader.Key = "X-API-Key"
104 | algodHeader.Value = algodToken
105 | algodClientWithHeaders, _ := algod.MakeClientWithHeaders(
106 | algodAddress,
107 | algodToken,
108 | []*common.Header{&algodHeader},
109 | )
110 | ```
111 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/overview/main.go#L18-L36)
112 | <!-- ===GOSDK_ALGOD_CREATE_CLIENT=== -->
113 |
114 | !!! Info
115 | Ensure the `algod` node has the _"EnableDeveloperAPI"_ parameter set to **true** within the `config.json` file. This is required to enable the SDK access to the _compile_ and _dryrun_ endpoints.
116 |
117 | # Declarations
118 |
119 | All smart contracts are comprised of state storage, an approval program and a clear program. Details of each are found within the [smart contract guide](/docs/get-details/dapps/smart-contracts/apps/).
120 |
121 | ## State storage
122 | Begin by defining the application's _global_schema_ and _local_schema_ storage requirements. These values are immutable once the application is created, so they must specify the maximum number required by the initial application and any future updates.
123 |
124 | The example application defined below may hold up to one each of `bytes` and `ints` value within the _local storage_ of the user account, as well as a single `ints` value within _global storage_ of the application:
125 |
126 | === "Python"
127 | <!-- ===PYSDK_APP_SCHEMA=== -->
128 | ```python
129 | # create schema for both global and local state, specifying
130 | # how many keys of each type we need to have available
131 | local_schema = transaction.StateSchema(num_uints=1, num_byte_slices=1)
132 | global_schema = transaction.StateSchema(num_uints=1, num_byte_slices=1)
133 | ```
134 | [Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/apps.py#L11-L15)
135 | <!-- ===PYSDK_APP_SCHEMA=== -->
136 |
137 | === "JavaScript"
138 | <!-- ===JSSDK_APP_SCHEMA=== -->
139 | ```javascript
140 | // define uint64s and byteslices stored in global/local storage
141 | const numGlobalByteSlices = 1;
142 | const numGlobalInts = 1;
143 | const numLocalByteSlices = 1;
144 | const numLocalInts = 1;
145 | ```
146 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/app.ts#L47-L52)
147 | <!-- ===JSSDK_APP_SCHEMA=== -->
148 |
149 | === "Java"
150 | <!-- ===JAVASDK_APP_SCHEMA=== -->
151 | ```java
152 | int localInts = 1;
153 | int localBytes = 1;
154 | int globalInts = 1;
155 | int globalBytes = 0;
156 | StateSchema localSchema = new StateSchema(localInts, localBytes);
157 | StateSchema globalSchema = new StateSchema(globalInts, globalBytes);
158 | ```
159 | [Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AppExamples.java#L40-L46)
160 | <!-- ===JAVASDK_APP_SCHEMA=== -->
161 |
162 | === "Go"
163 | <!-- ===GOSDK_APP_SCHEMA=== -->
164 | ```go
165 | // declare application state storage (immutable)
166 | var (
167 | localInts uint64 = 1
168 | localBytes uint64 = 1
169 | globalInts uint64 = 1
170 | globalBytes uint64 = 0
171 | )
172 |
173 | // define schema
174 | globalSchema := types.StateSchema{NumUint: globalInts, NumByteSlice: globalBytes}
175 | localSchema := types.StateSchema{NumUint: localInts, NumByteSlice: localBytes}
176 | ```
177 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/apps/main.go#L55-L66)
178 | <!-- ===GOSDK_APP_SCHEMA=== -->
179 |
180 | !!! Info
181 | The example application is not allowed to hold any `bytes` value within global storage.
182 |
183 |
184 | ## Approval program
185 |
186 | The [approval program](../apps/#the-lifecycle-of-a-smart-contract) handles the main logic of the application.
187 |
188 | ## Clear program
189 |
190 | This is the most basic [clear program](../apps/#the-lifecycle-of-a-smart-contract) and returns _true_ when an account clears its participation in a smart contract:
191 |
192 | === "Python"
193 | <!-- ===PYSDK_APP_SOURCE=== -->
194 | ```python
195 | # read the `.teal` source files from disk
196 | with open("application/approval.teal", "r") as f:
197 | approval_program = f.read()
198 |
199 | with open("application/clear.teal", "r") as f:
200 | clear_program = f.read()
201 | ```
202 | [Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/apps.py#L18-L24)
203 | <!-- ===PYSDK_APP_SOURCE=== -->
204 |
205 | === "JavaScript"
206 | <!-- ===JSSDK_APP_SOURCE=== -->
207 | ```javascript
208 | // define TEAL source from string or from a file
209 | const approvalProgram = fs.readFileSync(
210 | path.join(__dirname, '/application/approval.teal'),
211 | 'utf8'
212 | );
213 | const clearProgram = fs.readFileSync(
214 | path.join(__dirname, '/application/clear.teal'),
215 | 'utf8'
216 | );
217 | ```
218 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/app.ts#L17-L26)
219 | <!-- ===JSSDK_APP_SOURCE=== -->
220 |
221 | === "Java"
222 | <!-- ===JAVASDK_APP_SOURCE=== -->
223 | ```java
224 | // Read in the `teal` source files as a string
225 | String approvalSource = Files.readString(Paths.get("application/approval.teal"));
226 | String clearSource = Files.readString(Paths.get("application/clear.teal"));
227 | ```
228 | [Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AppExamples.java#L49-L52)
229 | <!-- ===JAVASDK_APP_SOURCE=== -->
230 |
231 | === "Go"
232 | <!-- ===GOSDK_APP_SOURCE=== -->
233 | ```go
234 | approvalTeal, err := ioutil.ReadFile("application/approval.teal")
235 | if err != nil {
236 | log.Fatalf("failed to read approval program: %s", err)
237 | }
238 | clearTeal, err := ioutil.ReadFile("application/clear.teal")
239 | if err != nil {
240 | log.Fatalf("failed to read clear program: %s", err)
241 | }
242 | ```
243 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/apps/main.go#L69-L77)
244 | <!-- ===GOSDK_APP_SOURCE=== -->
245 |
246 | # Application methods
247 |
248 | ## Create
249 |
250 | The creator will deploy the application using the [create app](../apps/#creating-the-smart-contract) method. It requires 7 parameters:
251 |
252 | - sender: address, representing the creator of the app
253 | - sp: suggested parameters obtained from the network
254 | - on_complete: enum value, representing NoOp
255 | - approval_program: compiled program
256 | - clear program: compiled program
257 | - local_schema: maximum _local storage_ allocation, immutable
258 | - global_schema: maximum _global storage_ allocation, immutable
259 |
260 | Use the creator_mnemonic to define sender:
261 |
262 | === "Python"
263 | <!-- ===PYSDK_ACCOUNT_RECOVER_MNEMONIC=== -->
264 | ```python
265 | mn = "cost piano sample enough south bar diet garden nasty mystery mesh sadness convince bacon best patch surround protect drum actress entire vacuum begin abandon hair"
266 | pk = mnemonic.to_private_key(mn)
267 | print(f"Base64 encoded private key: {pk}")
268 | addr = account.address_from_private_key(pk)
269 | print(f"Address: {addr}")
270 | ```
271 | [Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/account.py#L12-L17)
272 | <!-- ===PYSDK_ACCOUNT_RECOVER_MNEMONIC=== -->
273 |
274 | === "JavaScript"
275 | <!-- ===JSSDK_ACCOUNT_RECOVER_MNEMONIC=== -->
276 | ```javascript
277 | // restore 25-word mnemonic from a string
278 | // Note the mnemonic should _never_ appear in your source code
279 | const mnemonic =
280 | 'creek phrase island true then hope employ veteran rapid hurdle above liberty tissue connect alcohol timber idle ten frog bulb embody crunch taxi abstract month';
281 | const recoveredAccount = algosdk.mnemonicToSecretKey(mnemonic);
282 | console.log('Recovered mnemonic account: ', recoveredAccount.addr);
283 | ```
284 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/accounts.ts#L16-L22)
285 | <!-- ===JSSDK_ACCOUNT_RECOVER_MNEMONIC=== -->
286 |
287 | === "Java"
288 | <!-- ===JAVASDK_ACCOUNT_RECOVER_MNEMONIC=== -->
289 | ```java
290 | // Space delimited 25 word mnemonic
291 | String mn = "cost piano sample enough south bar diet garden nasty mystery mesh sadness convince bacon best patch surround protect drum actress entire vacuum begin abandon hair";
292 | // We can get the private key
293 | byte[] key = Mnemonic.toKey(mn);
294 | // Or just init the account directly from the mnemonic
295 | Account acct = new Account(mn);
296 | ```
297 | [Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AccountExamples.java#L64-L70)
298 | <!-- ===JAVASDK_ACCOUNT_RECOVER_MNEMONIC=== -->
299 |
300 | === "Go"
301 | <!-- ===GOSDK_ACCOUNT_RECOVER_MNEMONIC=== -->
302 | ```go
303 | k, err := mnemonic.ToPrivateKey(mn)
304 | if err != nil {
305 | log.Fatalf("failed to parse mnemonic: %s", err)
306 | }
307 |
308 | recovered, err := crypto.AccountFromPrivateKey(k)
309 | if err != nil {
310 | log.Fatalf("failed to recover account from key: %s", err)
311 | }
312 |
313 | log.Printf("%+v", recovered)
314 | ```
315 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/account/main.go#L28-L39)
316 | <!-- ===GOSDK_ACCOUNT_RECOVER_MNEMONIC=== -->
317 |
318 | Compile the programs using the `compile` endpoint:
319 |
320 | === "Python"
321 | <!-- ===PYSDK_APP_COMPILE=== -->
322 | ```python
323 | # pass the `.teal` files to the compile endpoint
324 | # and b64 decode the result to bytes
325 | approval_result = algod_client.compile(approval_program)
326 | approval_binary = base64.b64decode(approval_result["result"])
327 |
328 | clear_result = algod_client.compile(clear_program)
329 | clear_binary = base64.b64decode(clear_result["result"])
330 | ```
331 | [Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/apps.py#L29-L36)
332 | <!-- ===PYSDK_APP_COMPILE=== -->
333 |
334 | === "JavaScript"
335 | <!-- ===JSSDK_APP_COMPILE=== -->
336 | ```javascript
337 | const approvalCompileResp = await algodClient
338 | .compile(Buffer.from(approvalProgram))
339 | .do();
340 |
341 | const compiledApprovalProgram = new Uint8Array(
342 | Buffer.from(approvalCompileResp.result, 'base64')
343 | );
344 |
345 | const clearCompileResp = await algodClient
346 | .compile(Buffer.from(clearProgram))
347 | .do();
348 |
349 | const compiledClearProgram = new Uint8Array(
350 | Buffer.from(clearCompileResp.result, 'base64')
351 | );
352 | ```
353 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/app.ts#L29-L44)
354 | <!-- ===JSSDK_APP_COMPILE=== -->
355 |
356 | === "Java"
357 | <!-- ===JAVASDK_APP_COMPILE=== -->
358 | ```java
359 | CompileResponse approvalResponse = algodClient.TealCompile().source(approvalSource.getBytes()).execute()
360 | .body();
361 | CompileResponse clearResponse = algodClient.TealCompile().source(clearSource.getBytes()).execute()
362 | .body();
363 |
364 | TEALProgram approvalProg = new TEALProgram(approvalResponse.result);
365 | TEALProgram clearProg = new TEALProgram(clearResponse.result);
366 | ```
367 | [Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AppExamples.java#L55-L62)
368 | <!-- ===JAVASDK_APP_COMPILE=== -->
369 |
370 | === "Go"
371 | <!-- ===GOSDK_APP_COMPILE=== -->
372 | ```go
373 | approvalResult, err := algodClient.TealCompile(approvalTeal).Do(context.Background())
374 | if err != nil {
375 | log.Fatalf("failed to compile program: %s", err)
376 | }
377 |
378 | approvalBinary, err := base64.StdEncoding.DecodeString(approvalResult.Result)
379 | if err != nil {
380 | log.Fatalf("failed to decode compiled program: %s", err)
381 | }
382 |
383 | clearResult, err := algodClient.TealCompile(clearTeal).Do(context.Background())
384 | if err != nil {
385 | log.Fatalf("failed to compile program: %s", err)
386 | }
387 |
388 | clearBinary, err := base64.StdEncoding.DecodeString(clearResult.Result)
389 | if err != nil {
390 | log.Fatalf("failed to decode compiled program: %s", err)
391 | }
392 | ```
393 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/apps/main.go#L80-L99)
394 | <!-- ===GOSDK_APP_COMPILE=== -->
395 |
396 | Construct the transaction with defined values then sign, send, and await confirmation
397 |
398 | === "Python"
399 | <!-- ===PYSDK_APP_CREATE=== -->
400 | ```python
401 | sp = algod_client.suggested_params()
402 | # create the app create transaction, passing compiled programs and schema
403 | app_create_txn = transaction.ApplicationCreateTxn(
404 | creator.address,
405 | sp,
406 | transaction.OnComplete.NoOpOC,
407 | approval_program=approval_binary,
408 | clear_program=clear_binary,
409 | global_schema=global_schema,
410 | local_schema=local_schema,
411 | )
412 | # sign transaction
413 | signed_create_txn = app_create_txn.sign(creator.private_key)
414 | txid = algod_client.send_transaction(signed_create_txn)
415 | result = transaction.wait_for_confirmation(algod_client, txid, 4)
416 | app_id = result["application-index"]
417 | print(f"Created app with id: {app_id}")
418 | ```
419 | [Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/apps.py#L39-L56)
420 | <!-- ===PYSDK_APP_CREATE=== -->
421 |
422 | === "JavaScript"
423 | <!-- ===JSSDK_APP_CREATE=== -->
424 | ```javascript
425 | const appCreateTxn = algosdk.makeApplicationCreateTxnFromObject({
426 | from: creator.addr,
427 | approvalProgram: compiledApprovalProgram,
428 | clearProgram: compiledClearProgram,
429 | numGlobalByteSlices,
430 | numGlobalInts,
431 | numLocalByteSlices,
432 | numLocalInts,
433 | suggestedParams,
434 | onComplete: algosdk.OnApplicationComplete.NoOpOC,
435 | });
436 |
437 | // Sign and send
438 | await algodClient
439 | .sendRawTransaction(appCreateTxn.signTxn(creator.privateKey))
440 | .do();
441 | const result = await algosdk.waitForConfirmation(
442 | algodClient,
443 | appCreateTxn.txID().toString(),
444 | 3
445 | );
446 | // Grab app id from confirmed transaction result
447 | const appId = result['application-index'];
448 | console.log(`Created app with index: ${appId}`);
449 | ```
450 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/app.ts#L55-L79)
451 | <!-- ===JSSDK_APP_CREATE=== -->
452 |
453 | === "Java"
454 | <!-- ===JAVASDK_APP_CREATE=== -->
455 | ```java
456 | Response<TransactionParametersResponse> rsp = algodClient.TransactionParams().execute();
457 | TransactionParametersResponse sp = rsp.body();
458 |
459 | Transaction appCreate = ApplicationCreateTransactionBuilder.Builder()
460 | .sender(creator.getAddress())
461 | .suggestedParams(sp)
462 | .approvalProgram(approvalProg)
463 | .clearStateProgram(clearProg)
464 | .localStateSchema(localSchema)
465 | .globalStateSchema(globalSchema)
466 | .build();
467 |
468 | SignedTransaction signedAppCreate = creator.signTransaction(appCreate);
469 | Response<PostTransactionsResponse> createResponse = algodClient.RawTransaction()
470 | .rawtxn(Encoder.encodeToMsgPack(signedAppCreate)).execute();
471 |
472 | PendingTransactionResponse result = Utils.waitForConfirmation(algodClient, createResponse.body().txId,
473 | 4);
474 | Long appId = result.applicationIndex;
475 | System.out.printf("Created application with id: %d\n", appId);
476 | ```
477 | [Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AppExamples.java#L65-L85)
478 | <!-- ===JAVASDK_APP_CREATE=== -->
479 |
480 | === "Go"
481 | <!-- ===GOSDK_APP_CREATE=== -->
482 | ```go
483 | // Create application
484 | sp, err := algodClient.SuggestedParams().Do(context.Background())
485 | if err != nil {
486 | log.Fatalf("error getting suggested tx params: %s", err)
487 | }
488 |
489 | txn, err := transaction.MakeApplicationCreateTx(
490 | false, approvalBinary, clearBinary, globalSchema, localSchema,
491 | nil, nil, nil, nil, sp, creator.Address, nil,
492 | types.Digest{}, [32]byte{}, types.ZeroAddress,
493 | )
494 | if err != nil {
495 | log.Fatalf("failed to make txn: %s", err)
496 | }
497 |
498 | txid, stx, err := crypto.SignTransaction(creator.PrivateKey, txn)
499 | if err != nil {
500 | log.Fatalf("failed to sign transaction: %s", err)
501 | }
502 |
503 | _, err = algodClient.SendRawTransaction(stx).Do(context.Background())
504 | if err != nil {
505 | log.Fatalf("failed to send transaction: %s", err)
506 | }
507 |
508 | confirmedTxn, err := transaction.WaitForConfirmation(algodClient, txid, 4, context.Background())
509 | if err != nil {
510 | log.Fatalf("error waiting for confirmation: %s", err)
511 | }
512 | appID := confirmedTxn.ApplicationIndex
513 | log.Printf("Created app with id: %d", appID)
514 | ```
515 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/apps/main.go#L102-L133)
516 | <!-- ===GOSDK_APP_CREATE=== -->
517 |
518 |
519 | !!! Notice
520 | Note down the app-id from the confirmed transaction response. Place this value into the `index` parameter within all remaining code samples.
521 |
522 | ## Opt-in
523 |
524 | The user must [opt-in](../apps/#opt-into-the-smart-contract) to call the application if some local state is used during evaluation of the call. This method requires 3 parameters:
525 |
526 | - sender: address, representing the user intending to opt-in to using the app
527 | - sp: suggested parameters obtained from the network
528 | - index: the app-id as defined by the create method result
529 |
530 | Use the user_mnemonic to define sender:
531 |
532 | === "Python"
533 | <!-- ===PYSDK_ACCOUNT_RECOVER_MNEMONIC=== -->
534 | ```python
535 | mn = "cost piano sample enough south bar diet garden nasty mystery mesh sadness convince bacon best patch surround protect drum actress entire vacuum begin abandon hair"
536 | pk = mnemonic.to_private_key(mn)
537 | print(f"Base64 encoded private key: {pk}")
538 | addr = account.address_from_private_key(pk)
539 | print(f"Address: {addr}")
540 | ```
541 | [Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/account.py#L12-L17)
542 | <!-- ===PYSDK_ACCOUNT_RECOVER_MNEMONIC=== -->
543 |
544 | === "JavaScript"
545 | <!-- ===JSSDK_ACCOUNT_RECOVER_MNEMONIC=== -->
546 | ```javascript
547 | // restore 25-word mnemonic from a string
548 | // Note the mnemonic should _never_ appear in your source code
549 | const mnemonic =
550 | 'creek phrase island true then hope employ veteran rapid hurdle above liberty tissue connect alcohol timber idle ten frog bulb embody crunch taxi abstract month';
551 | const recoveredAccount = algosdk.mnemonicToSecretKey(mnemonic);
552 | console.log('Recovered mnemonic account: ', recoveredAccount.addr);
553 | ```
554 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/accounts.ts#L16-L22)
555 | <!-- ===JSSDK_ACCOUNT_RECOVER_MNEMONIC=== -->
556 |
557 | === "Java"
558 | <!-- ===JAVASDK_ACCOUNT_RECOVER_MNEMONIC=== -->
559 | ```java
560 | // Space delimited 25 word mnemonic
561 | String mn = "cost piano sample enough south bar diet garden nasty mystery mesh sadness convince bacon best patch surround protect drum actress entire vacuum begin abandon hair";
562 | // We can get the private key
563 | byte[] key = Mnemonic.toKey(mn);
564 | // Or just init the account directly from the mnemonic
565 | Account acct = new Account(mn);
566 | ```
567 | [Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AccountExamples.java#L64-L70)
568 | <!-- ===JAVASDK_ACCOUNT_RECOVER_MNEMONIC=== -->
569 |
570 | === "Go"
571 | <!-- ===GOSDK_ACCOUNT_RECOVER_MNEMONIC=== -->
572 | ```go
573 | k, err := mnemonic.ToPrivateKey(mn)
574 | if err != nil {
575 | log.Fatalf("failed to parse mnemonic: %s", err)
576 | }
577 |
578 | recovered, err := crypto.AccountFromPrivateKey(k)
579 | if err != nil {
580 | log.Fatalf("failed to recover account from key: %s", err)
581 | }
582 |
583 | log.Printf("%+v", recovered)
584 | ```
585 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/account/main.go#L28-L39)
586 | <!-- ===GOSDK_ACCOUNT_RECOVER_MNEMONIC=== -->
587 |
588 | Construct the transaction with defined values then sign, send, and await confirmation:
589 |
590 | === "Python"
591 | <!-- ===PYSDK_APP_OPTIN=== -->
592 | ```python
593 | opt_in_txn = transaction.ApplicationOptInTxn(user.address, sp, app_id)
594 | signed_opt_in = opt_in_txn.sign(user.private_key)
595 | txid = algod_client.send_transaction(signed_opt_in)
596 | optin_result = transaction.wait_for_confirmation(algod_client, txid, 4)
597 | assert optin_result["confirmed-round"] > 0
598 | ```
599 | [Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/apps.py#L59-L64)
600 | <!-- ===PYSDK_APP_OPTIN=== -->
601 |
602 | === "JavaScript"
603 | <!-- ===JSSDK_APP_OPTIN=== -->
604 | ```javascript
605 | const appOptInTxn = algosdk.makeApplicationOptInTxnFromObject({
606 | from: caller.addr,
607 | appIndex: appId,
608 | suggestedParams,
609 | });
610 |
611 | await algodClient
612 | .sendRawTransaction(appOptInTxn.signTxn(caller.privateKey))
613 | .do();
614 | await algosdk.waitForConfirmation(
615 | algodClient,
616 | appOptInTxn.txID().toString(),
617 | 3
618 | );
619 | ```
620 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/app.ts#L84-L98)
621 | <!-- ===JSSDK_APP_OPTIN=== -->
622 |
623 | === "Java"
624 | <!-- ===JAVASDK_APP_OPTIN=== -->
625 | ```java
626 | Transaction optInTxn = ApplicationOptInTransactionBuilder.Builder()
627 | .sender(user.getAddress())
628 | .suggestedParams(sp)
629 | .applicationId(appId)
630 | .build();
631 |
632 | SignedTransaction signedOptIn = user.signTransaction(optInTxn);
633 | Response<PostTransactionsResponse> optInResponse = algodClient.RawTransaction()
634 | .rawtxn(Encoder.encodeToMsgPack(signedOptIn)).execute();
635 |
636 | PendingTransactionResponse optInResult = Utils.waitForConfirmation(algodClient,
637 | optInResponse.body().txId, 4);
638 | assert optInResult.confirmedRound > 0;
639 | ```
640 | [Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AppExamples.java#L88-L101)
641 | <!-- ===JAVASDK_APP_OPTIN=== -->
642 |
643 | === "Go"
644 | <!-- ===GOSDK_APP_OPTIN=== -->
645 | ```go
646 | sp, err := algodClient.SuggestedParams().Do(context.Background())
647 | if err != nil {
648 | log.Fatalf("error getting suggested tx params: %s", err)
649 | }
650 |
651 | // Create a new clawback transaction with the target of the user address and the recipient as the creator
652 | // address, being sent from the address marked as `clawback` on the asset, in this case the same as creator
653 | txn, err := transaction.MakeApplicationOptInTx(
654 | appID, nil, nil, nil, nil, sp,
655 | caller.Address, nil, types.Digest{}, [32]byte{}, types.ZeroAddress,
656 | )
657 | if err != nil {
658 | log.Fatalf("failed to make txn: %s", err)
659 | }
660 | // sign the transaction
661 | txid, stx, err := crypto.SignTransaction(caller.PrivateKey, txn)
662 | if err != nil {
663 | log.Fatalf("failed to sign transaction: %s", err)
664 | }
665 |
666 | // Broadcast the transaction to the network
667 | _, err = algodClient.SendRawTransaction(stx).Do(context.Background())
668 | if err != nil {
669 | log.Fatalf("failed to send transaction: %s", err)
670 | }
671 |
672 | // Wait for confirmation
673 | confirmedTxn, err := transaction.WaitForConfirmation(algodClient, txid, 4, context.Background())
674 | if err != nil {
675 | log.Fatalf("error waiting for confirmation: %s", err)
676 | }
677 |
678 | log.Printf("OptIn Transaction: %s confirmed in Round %d\n", txid, confirmedTxn.ConfirmedRound)
679 | ```
680 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/apps/main.go#L139-L172)
681 | <!-- ===GOSDK_APP_OPTIN=== -->
682 |
683 |
684 | ## Call (NoOp)
685 |
686 | The user may now [call](../apps/#call-the-stateful-smart-contract) the application. This method requires 3 parameters:
687 |
688 | - sender: address, representing the user intending to optin to using the app
689 | - sp: suggested parameters obtained from the network
690 | - index: the app-id as defined by the create method result
691 |
692 | === "Python"
693 | <!-- ===PYSDK_APP_NOOP=== -->
694 | ```python
695 | noop_txn = transaction.ApplicationNoOpTxn(user.address, sp, app_id)
696 | signed_noop = noop_txn.sign(user.private_key)
697 | txid = algod_client.send_transaction(signed_noop)
698 | noop_result = transaction.wait_for_confirmation(algod_client, txid, 4)
699 | assert noop_result["confirmed-round"] > 0
700 | ```
701 | [Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/apps.py#L67-L72)
702 | <!-- ===PYSDK_APP_NOOP=== -->
703 |
704 | === "JavaScript"
705 | <!-- ===JSSDK_APP_NOOP=== -->
706 | ```javascript
707 | const appNoOpTxn = algosdk.makeApplicationNoOpTxnFromObject({
708 | from: caller.addr,
709 | appIndex: appId,
710 | suggestedParams,
711 | });
712 |
713 | await algodClient
714 | .sendRawTransaction(appNoOpTxn.signTxn(caller.privateKey))
715 | .do();
716 | await algosdk.waitForConfirmation(
717 | algodClient,
718 | appNoOpTxn.txID().toString(),
719 | 3
720 | );
721 | ```
722 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/app.ts#L101-L115)
723 | <!-- ===JSSDK_APP_NOOP=== -->
724 |
725 | === "Java"
726 | <!-- ===JAVASDK_APP_NOOP=== -->
727 | ```java
728 | Transaction noopTxn = ApplicationCallTransactionBuilder.Builder()
729 | .sender(user.getAddress())
730 | .suggestedParams(sp)
731 | .applicationId(appId)
732 | .build();
733 |
734 | SignedTransaction signedNoop = user.signTransaction(noopTxn);
735 | Response<PostTransactionsResponse> noopResponse = algodClient.RawTransaction()
736 | .rawtxn(Encoder.encodeToMsgPack(signedNoop)).execute();
737 |
738 | PendingTransactionResponse noopResult = Utils.waitForConfirmation(algodClient, noopResponse.body().txId,
739 | 4);
740 | assert noopResult.confirmedRound > 0;
741 | ```
742 | [Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AppExamples.java#L104-L117)
743 | <!-- ===JAVASDK_APP_NOOP=== -->
744 |
745 | === "Go"
746 | <!-- ===GOSDK_APP_NOOP=== -->
747 | ```go
748 | sp, err := algodClient.SuggestedParams().Do(context.Background())
749 | if err != nil {
750 | log.Fatalf("error getting suggested tx params: %s", err)
751 | }
752 |
753 | var (
754 | appArgs [][]byte
755 | accts []string
756 | apps []uint64
757 | assets []uint64
758 | )
759 |
760 | // Add an arg to our app call
761 | appArgs = append(appArgs, []byte("arg0"))
762 |
763 | txn, err := transaction.MakeApplicationNoOpTx(
764 | appID, appArgs, accts, apps, assets, sp,
765 | caller.Address, nil, types.Digest{}, [32]byte{}, types.ZeroAddress,
766 | )
767 | if err != nil {
768 | log.Fatalf("failed to make txn: %s", err)
769 | }
770 |
771 | // sign the transaction
772 | txid, stx, err := crypto.SignTransaction(caller.PrivateKey, txn)
773 | if err != nil {
774 | log.Fatalf("failed to sign transaction: %s", err)
775 | }
776 |
777 | // Broadcast the transaction to the network
778 | _, err = algodClient.SendRawTransaction(stx).Do(context.Background())
779 | if err != nil {
780 | log.Fatalf("failed to send transaction: %s", err)
781 | }
782 |
783 | // Wait for confirmation
784 | confirmedTxn, err := transaction.WaitForConfirmation(algodClient, txid, 4, context.Background())
785 | if err != nil {
786 | log.Fatalf("error waiting for confirmation: %s", err)
787 | }
788 |
789 | log.Printf("NoOp Transaction: %s confirmed in Round %d\n", txid, confirmedTxn.ConfirmedRound)
790 | ```
791 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/apps/main.go#L177-L219)
792 | <!-- ===GOSDK_APP_NOOP=== -->
793 |
794 | ## Read state
795 |
796 | Anyone may read the [global state](../apps/#reading-global-state-from-other-smart-contracts) of any application or the [local state](../apps/#reading-local-state-from-other-accounts) of an application within a given user account using the REST API account_info endpoint.
797 |
798 | === "Python"
799 | <!-- ===PYSDK_APP_READ_STATE=== -->
800 | ```python
801 | acct_info = algod_client.account_application_info(user.address, app_id)
802 | # base64 encoded keys and values
803 | print(acct_info["app-local-state"]["key-value"])
804 | ```
805 | [Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/apps.py#L75-L78)
806 | <!-- ===PYSDK_APP_READ_STATE=== -->
807 |
808 | === "JavaScript"
809 | <!-- ===JSSDK_APP_READ_STATE=== -->
810 | ```javascript
811 | const appInfo = await algodClient.getApplicationByID(appId).do();
812 | const globalState = appInfo.params['global-state'][0];
813 | console.log(`Raw global state - ${JSON.stringify(globalState)}`);
814 |
815 | // decode b64 string key with Buffer
816 | const globalKey = Buffer.from(globalState.key, 'base64').toString();
817 | // decode b64 address value with encodeAddress and Buffer
818 | const globalValue = algosdk.encodeAddress(
819 | Buffer.from(globalState.value.bytes, 'base64')
820 | );
821 |
822 | console.log(`Decoded global state - ${globalKey}: ${globalValue}`);
823 |
824 | const accountAppInfo = await algodClient
825 | .accountApplicationInformation(caller.addr, appId)
826 | .do();
827 |
828 | const localState = accountAppInfo['app-local-state']['key-value'][0];
829 | console.log(`Raw local state - ${JSON.stringify(localState)}`);
830 |
831 | // decode b64 string key with Buffer
832 | const localKey = Buffer.from(localState.key, 'base64').toString();
833 | // get uint value directly
834 | const localValue = localState.value.uint;
835 |
836 | console.log(`Decoded local state - ${localKey}: ${localValue}`);
837 | ```
838 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/app.ts#L154-L180)
839 | <!-- ===JSSDK_APP_READ_STATE=== -->
840 |
841 | === "Java"
842 | <!-- ===JAVASDK_APP_READ_STATE=== -->
843 | ```java
844 |
845 | ```
846 | [Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AppExamples.java#L120-L121)
847 | <!-- ===JAVASDK_APP_READ_STATE=== -->
848 |
849 | === "Go"
850 | <!-- ===GOSDK_APP_READ_STATE=== -->
851 | ```go
852 | // grab global state and config of application
853 | appInfo, err := algodClient.GetApplicationByID(appID).Do(context.Background())
854 | if err != nil {
855 | log.Fatalf("failed to get app info: %s", err)
856 | }
857 | log.Printf("app info: %+v", appInfo)
858 |
859 | // grab local state for an app id for a single account
860 | acctInfo, err := algodClient.AccountApplicationInformation(
861 | acct1.Address.String(), appID,
862 | ).Do(context.Background())
863 | if err != nil {
864 | log.Fatalf("failed to get app info: %s", err)
865 | }
866 | log.Printf("app info: %+v", acctInfo)
867 | ```
868 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/apps/main.go#L28-L43)
869 | <!-- ===GOSDK_APP_READ_STATE=== -->
870 |
871 | ## Update
872 |
873 | The creator may [update the approval program](../apps/#update-smart-contract) using the update method (if the current approval program allows it). The refactored approval program source code adds a key/value pair to the user's local storage indicating the timestamp when the application was called. Refer to the [appendix](#refactored-approval-program) for details. The original clear program will be reused.
874 |
875 | The update method method requires 6 parameters:
876 |
877 | - sender: address, representing the user intending to opt-in to using the app
878 | - sp: suggested parameters obtained from the network
879 | - index: the app-id as defined by the create method result
880 | - approval_program: compiled program
881 | - clear program: compiled program
882 | - app_args: application arguments used by approval program
883 |
884 | Construct the update transaction and await the response:
885 |
886 | === "Python"
887 | <!-- ===PYSDK_APP_UPDATE=== -->
888 | ```python
889 | with open("application/approval_refactored.teal", "r") as f:
890 | approval_program = f.read()
891 |
892 | approval_result = algod_client.compile(approval_program)
893 | approval_binary = base64.b64decode(approval_result["result"])
894 |
895 |
896 | sp = algod_client.suggested_params()
897 | # create the app update transaction, passing compiled programs and schema
898 | # note that schema is immutable, we cant change it after create
899 | app_update_txn = transaction.ApplicationUpdateTxn(
900 | creator.address,
901 | sp,
902 | app_id,
903 | approval_program=approval_binary,
904 | clear_program=clear_binary,
905 | )
906 | signed_update = app_update_txn.sign(creator.private_key)
907 | txid = algod_client.send_transaction(signed_update)
908 | update_result = transaction.wait_for_confirmation(algod_client, txid, 4)
909 | assert update_result["confirmed-round"] > 0
910 | ```
911 | [Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/apps.py#L81-L102)
912 | <!-- ===PYSDK_APP_UPDATE=== -->
913 |
914 | === "JavaScript"
915 | <!-- ===JSSDK_APP_UPDATE=== -->
916 | ```javascript
917 | const newProgram = fs.readFileSync(
918 | path.join(__dirname, '/application/approval_refactored.teal'),
919 | 'utf8'
920 | );
921 | const compiledNewProgram = await compileProgram(algodClient, newProgram);
922 |
923 | const appUpdateTxn = algosdk.makeApplicationUpdateTxnFromObject({
924 | from: creator.addr,
925 | suggestedParams,
926 | appIndex: appId,
927 | // updates must define both approval and clear programs, even if unchanged
928 | approvalProgram: compiledNewProgram,
929 | clearProgram: compiledClearProgram,
930 | });
931 |
932 | await algodClient
933 | .sendRawTransaction(appUpdateTxn.signTxn(creator.privateKey))
934 | .do();
935 | await algosdk.waitForConfirmation(
936 | algodClient,
937 | appUpdateTxn.txID().toString(),
938 | 3
939 | );
940 | ```
941 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/app.ts#L200-L223)
942 | <!-- ===JSSDK_APP_UPDATE=== -->
943 |
944 | === "Java"
945 | <!-- ===JAVASDK_APP_UPDATE=== -->
946 | ```java
947 | String approvalSourceUpdated = Files.readString(Paths.get("application/approval_refactored.teal"));
948 | CompileResponse approvalUpdatedResponse = algodClient.TealCompile()
949 | .source(approvalSourceUpdated.getBytes())
950 | .execute()
951 | .body();
952 | TEALProgram approvalProgUpdated = new TEALProgram(approvalUpdatedResponse.result);
953 |
954 | Transaction appUpdate = ApplicationUpdateTransactionBuilder.Builder()
955 | .sender(creator.getAddress())
956 | .suggestedParams(sp)
957 | .applicationId(appId)
958 | .approvalProgram(approvalProgUpdated)
959 | .clearStateProgram(clearProg)
960 | .build();
961 |
962 | SignedTransaction signedAppUpdate = creator.signTransaction(appUpdate);
963 | Response<PostTransactionsResponse> updateResponse = algodClient.RawTransaction()
964 | .rawtxn(Encoder.encodeToMsgPack(signedAppUpdate)).execute();
965 | PendingTransactionResponse updateResult = Utils.waitForConfirmation(algodClient,
966 | updateResponse.body().txId, 4);
967 | assert updateResult.confirmedRound > 0;
968 | ```
969 | [Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AppExamples.java#L123-L144)
970 | <!-- ===JAVASDK_APP_UPDATE=== -->
971 |
972 | === "Go"
973 | <!-- ===GOSDK_APP_UPDATE=== -->
974 | ```go
975 | sp, err := algodClient.SuggestedParams().Do(context.Background())
976 | if err != nil {
977 | log.Fatalf("error getting suggested tx params: %s", err)
978 | }
979 |
980 | var (
981 | appArgs [][]byte
982 | accts []string
983 | apps []uint64
984 | assets []uint64
985 | )
986 |
987 | txn, err := transaction.MakeApplicationUpdateTx(
988 | appID, appArgs, accts, apps, assets, approvalBinary, clearBinary,
989 | sp, caller.Address, nil, types.Digest{}, [32]byte{}, types.ZeroAddress,
990 | )
991 | if err != nil {
992 | log.Fatalf("failed to make txn: %s", err)
993 | }
994 |
995 | // sign the transaction
996 | txid, stx, err := crypto.SignTransaction(caller.PrivateKey, txn)
997 | if err != nil {
998 | log.Fatalf("failed to sign transaction: %s", err)
999 | }
1000 |
1001 | // Broadcast the transaction to the network
1002 | _, err = algodClient.SendRawTransaction(stx).Do(context.Background())
1003 | if err != nil {
1004 | log.Fatalf("failed to send transaction: %s", err)
1005 | }
1006 |
1007 | // Wait for confirmation
1008 | confirmedTxn, err := transaction.WaitForConfirmation(algodClient, txid, 4, context.Background())
1009 | if err != nil {
1010 | log.Fatalf("error waiting for confirmation: %s", err)
1011 | }
1012 |
1013 | log.Printf("Update Transaction: %s confirmed in Round %d\n", txid, confirmedTxn.ConfirmedRound)
1014 | ```
1015 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/apps/main.go#L227-L266)
1016 | <!-- ===GOSDK_APP_UPDATE=== -->
1017 |
1018 | ## Call with arguments
1019 |
1020 | A program may [process arguments passed](../apps/##passing-arguments-to-smart-contracts) at run-time. The NoOp call method has an optional app_args parameter where smart contract parameters can be supplied:
1021 |
1022 | === "Python"
1023 | <!-- ===PYSDK_APP_CALL=== -->
1024 | ```python
1025 | now = datetime.datetime.now().strftime("%H:%M:%S")
1026 | app_args = [now.encode("utf-8")]
1027 | call_txn = transaction.ApplicationNoOpTxn(user.address, sp, app_id, app_args)
1028 |
1029 | signed_call = call_txn.sign(user.private_key)
1030 | txid = algod_client.send_transaction(signed_call)
1031 | call_result = transaction.wait_for_confirmation(algod_client, txid, 4)
1032 | assert call_result["confirmed-round"] > 0
1033 |
1034 | # display results
1035 | print("Called app-id: ", call_result["txn"]["txn"]["apid"])
1036 | if "global-state-delta" in call_result:
1037 | print("Global State updated :\n", call_result["global-state-delta"])
1038 | if "local-state-delta" in call_result:
1039 | print("Local State updated :\n", call_result["local-state-delta"])
1040 | ```
1041 | [Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/apps.py#L105-L120)
1042 | <!-- ===PYSDK_APP_CALL=== -->
1043 |
1044 | === "JavaScript"
1045 | <!-- ===JSSDK_APP_CALL=== -->
1046 | ```javascript
1047 | const now = new Date().toString();
1048 | const simpleAddTxn = algosdk.makeApplicationNoOpTxnFromObject({
1049 | from: caller.addr,
1050 | suggestedParams,
1051 | appIndex: appId,
1052 | appArgs: [new Uint8Array(Buffer.from(now))],
1053 | });
1054 |
1055 | await algodClient
1056 | .sendRawTransaction(simpleAddTxn.signTxn(caller.privateKey))
1057 | .do();
1058 | await algosdk.waitForConfirmation(
1059 | algodClient,
1060 | simpleAddTxn.txID().toString(),
1061 | 3
1062 | );
1063 | ```
1064 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/app.ts#L135-L151)
1065 | <!-- ===JSSDK_APP_CALL=== -->
1066 |
1067 | === "Java"
1068 | <!-- ===JAVASDK_APP_CALL=== -->
1069 | ```java
1070 | SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss");
1071 | Date date = new Date(System.currentTimeMillis());
1072 |
1073 | List<byte[]> appArgs = new ArrayList<byte[]>();
1074 | appArgs.add(formatter.format(date).toString().getBytes());
1075 |
1076 | // create unsigned transaction
1077 | Transaction callTransaction = ApplicationCallTransactionBuilder.Builder()
1078 | .sender(user.getAddress())
1079 | .suggestedParams(sp)
1080 | .applicationId(appId)
1081 | .args(appArgs)
1082 | .build();
1083 |
1084 | SignedTransaction signedCallTransaction = user.signTransaction(callTransaction);
1085 | Response<PostTransactionsResponse> callResponse = algodClient.RawTransaction()
1086 | .rawtxn(Encoder.encodeToMsgPack(signedCallTransaction)).execute();
1087 |
1088 | PendingTransactionResponse callResult = Utils.waitForConfirmation(algodClient, callResponse.body().txId,
1089 | 4);
1090 | assert callResult.confirmedRound > 0;
1091 | // display results
1092 | if (callResult.globalStateDelta != null) {
1093 | System.out.printf("\tGlobal state: %s\n", callResult.globalStateDelta);
1094 | }
1095 |
1096 | if (callResult.localStateDelta != null) {
1097 | System.out.printf("\tLocal state: %s\n", callResult.localStateDelta);
1098 | }
1099 | ```
1100 | [Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AppExamples.java#L147-L176)
1101 | <!-- ===JAVASDK_APP_CALL=== -->
1102 |
1103 | === "Go"
1104 | <!-- ===GOSDK_APP_CALL=== -->
1105 | ```go
1106 | sp, err := algodClient.SuggestedParams().Do(context.Background())
1107 | if err != nil {
1108 | log.Fatalf("error getting suggested tx params: %s", err)
1109 | }
1110 |
1111 | var (
1112 | appArgs [][]byte
1113 | accts []string
1114 | apps []uint64
1115 | assets []uint64
1116 | )
1117 |
1118 | datetime := time.Now().Format("2006-01-02 at 15:04:05")
1119 | appArgs = append(appArgs, []byte(datetime))
1120 |
1121 | txn, err := transaction.MakeApplicationNoOpTx(
1122 | appID, appArgs, accts, apps, assets, sp,
1123 | caller.Address, nil, types.Digest{}, [32]byte{}, types.ZeroAddress,
1124 | )
1125 | if err != nil {
1126 | log.Fatalf("failed to make txn: %s", err)
1127 | }
1128 |
1129 | // sign the transaction
1130 | txid, stx, err := crypto.SignTransaction(caller.PrivateKey, txn)
1131 | if err != nil {
1132 | log.Fatalf("failed to sign transaction: %s", err)
1133 | }
1134 |
1135 | // Broadcast the transaction to the network
1136 | _, err = algodClient.SendRawTransaction(stx).Do(context.Background())
1137 | if err != nil {
1138 | log.Fatalf("failed to send transaction: %s", err)
1139 | }
1140 |
1141 | // Wait for confirmation
1142 | confirmedTxn, err := transaction.WaitForConfirmation(algodClient, txid, 4, context.Background())
1143 | if err != nil {
1144 | log.Fatalf("error waiting for confirmation: %s", err)
1145 | }
1146 |
1147 | log.Printf("NoOp Transaction: %s confirmed in Round %d\n", txid, confirmedTxn.ConfirmedRound)
1148 | ```
1149 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/apps/main.go#L359-L401)
1150 | <!-- ===GOSDK_APP_CALL=== -->
1151 |
1152 | ## Close out
1153 |
1154 | The user may discontinue use of the application by sending a [close out](../apps/#the-lifecycle-of-a-smart-contract) transaction. This will remove the local state for this application from the user's account. This method requires 3 parameters:
1155 |
1156 | - sender: address, representing the user intending to optin to using the app
1157 | - sp: suggested parameters obtained from the network
1158 | - index: the app-id as defined by the create method result
1159 |
1160 | === "Python"
1161 | <!-- ===PYSDK_APP_CLOSEOUT=== -->
1162 | ```python
1163 | close_txn = transaction.ApplicationCloseOutTxn(user.address, sp, app_id)
1164 | signed_close = close_txn.sign(user.private_key)
1165 | txid = algod_client.send_transaction(signed_close)
1166 | optin_result = transaction.wait_for_confirmation(algod_client, txid, 4)
1167 | assert optin_result["confirmed-round"] > 0
1168 | ```
1169 | [Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/apps.py#L123-L128)
1170 | <!-- ===PYSDK_APP_CLOSEOUT=== -->
1171 |
1172 | === "JavaScript"
1173 | <!-- ===JSSDK_APP_CLOSEOUT=== -->
1174 | ```javascript
1175 | const appCloseOutTxn = algosdk.makeApplicationCloseOutTxnFromObject({
1176 | from: caller.addr,
1177 | appIndex: appId,
1178 | suggestedParams,
1179 | });
1180 |
1181 | await algodClient
1182 | .sendRawTransaction(appCloseOutTxn.signTxn(caller.privateKey))
1183 | .do();
1184 | await algosdk.waitForConfirmation(
1185 | algodClient,
1186 | appCloseOutTxn.txID().toString(),
1187 | 3
1188 | );
1189 | ```
1190 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/app.ts#L183-L197)
1191 | <!-- ===JSSDK_APP_CLOSEOUT=== -->
1192 |
1193 | === "Java"
1194 | <!-- ===JAVASDK_APP_CLOSEOUT=== -->
1195 | ```java
1196 | Transaction closeOutTxn = ApplicationCloseTransactionBuilder.Builder()
1197 | .sender(user.getAddress())
1198 | .suggestedParams(sp)
1199 | .applicationId(appId)
1200 | .build();
1201 |
1202 | SignedTransaction signedCloseOut = user.signTransaction(closeOutTxn);
1203 | Response<PostTransactionsResponse> closeOutResponse = algodClient.RawTransaction()
1204 | .rawtxn(Encoder.encodeToMsgPack(signedCloseOut)).execute();
1205 |
1206 | PendingTransactionResponse closeOutResult = Utils.waitForConfirmation(algodClient,
1207 | closeOutResponse.body().txId,
1208 | 4);
1209 | assert closeOutResult.confirmedRound > 0;
1210 | ```
1211 | [Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AppExamples.java#L179-L193)
1212 | <!-- ===JAVASDK_APP_CLOSEOUT=== -->
1213 |
1214 | === "Go"
1215 | <!-- ===GOSDK_APP_CLOSEOUT=== -->
1216 | ```go
1217 | sp, err := algodClient.SuggestedParams().Do(context.Background())
1218 | if err != nil {
1219 | log.Fatalf("error getting suggested tx params: %s", err)
1220 | }
1221 |
1222 | var (
1223 | appArgs [][]byte
1224 | accts []string
1225 | apps []uint64
1226 | assets []uint64
1227 | )
1228 |
1229 | txn, err := transaction.MakeApplicationCloseOutTx(
1230 | appID, appArgs, accts, apps, assets, sp,
1231 | caller.Address, nil, types.Digest{}, [32]byte{}, types.ZeroAddress,
1232 | )
1233 | if err != nil {
1234 | log.Fatalf("failed to make txn: %s", err)
1235 | }
1236 |
1237 | // sign the transaction
1238 | txid, stx, err := crypto.SignTransaction(caller.PrivateKey, txn)
1239 | if err != nil {
1240 | log.Fatalf("failed to sign transaction: %s", err)
1241 | }
1242 |
1243 | // Broadcast the transaction to the network
1244 | _, err = algodClient.SendRawTransaction(stx).Do(context.Background())
1245 | if err != nil {
1246 | log.Fatalf("failed to send transaction: %s", err)
1247 | }
1248 |
1249 | // Wait for confirmation
1250 | confirmedTxn, err := transaction.WaitForConfirmation(algodClient, txid, 4, context.Background())
1251 | if err != nil {
1252 | log.Fatalf("error waiting for confirmation: %s", err)
1253 | }
1254 |
1255 | log.Printf("Closeout Transaction: %s confirmed in Round %d\n", txid, confirmedTxn.ConfirmedRound)
1256 | ```
1257 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/apps/main.go#L271-L310)
1258 | <!-- ===GOSDK_APP_CLOSEOUT=== -->
1259 |
1260 | ## Delete
1261 |
1262 | The approval program defines the creator as the only account able to [delete the application](../apps/#delete-smart-contract). This removes the global state, but does not impact any user's local state. This method uses the same 3 parameters.
1263 |
1264 | === "Python"
1265 | <!-- ===PYSDK_APP_DELETE=== -->
1266 | ```python
1267 | delete_txn = transaction.ApplicationDeleteTxn(creator.address, sp, app_id)
1268 | signed_delete = delete_txn.sign(creator.private_key)
1269 | txid = algod_client.send_transaction(signed_delete)
1270 | optin_result = transaction.wait_for_confirmation(algod_client, txid, 4)
1271 | assert optin_result["confirmed-round"] > 0
1272 | ```
1273 | [Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/apps.py#L131-L136)
1274 | <!-- ===PYSDK_APP_DELETE=== -->
1275 |
1276 | === "JavaScript"
1277 | <!-- ===JSSDK_APP_DELETE=== -->
1278 | ```javascript
1279 | const appDeleteTxn = algosdk.makeApplicationDeleteTxnFromObject({
1280 | from: creator.addr,
1281 | suggestedParams,
1282 | appIndex: appId,
1283 | });
1284 |
1285 | await algodClient
1286 | .sendRawTransaction(appDeleteTxn.signTxn(creator.privateKey))
1287 | .do();
1288 | await algosdk.waitForConfirmation(
1289 | algodClient,
1290 | appDeleteTxn.txID().toString(),
1291 | 3
1292 | );
1293 | ```
1294 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/app.ts#L243-L257)
1295 | <!-- ===JSSDK_APP_DELETE=== -->
1296 |
1297 | === "Java"
1298 | <!-- ===JAVASDK_APP_DELETE=== -->
1299 | ```java
1300 | Transaction appDelete = ApplicationDeleteTransactionBuilder.Builder()
1301 | .sender(creator.getAddress())
1302 | .suggestedParams(sp)
1303 | .applicationId(appId)
1304 | .build();
1305 |
1306 | SignedTransaction signedAppDelete = creator.signTransaction(appDelete);
1307 | Response<PostTransactionsResponse> deleteResponse = algodClient.RawTransaction()
1308 | .rawtxn(Encoder.encodeToMsgPack(signedAppDelete)).execute();
1309 | PendingTransactionResponse deleteResult = Utils.waitForConfirmation(algodClient,
1310 | deleteResponse.body().txId, 4);
1311 | assert deleteResult.confirmedRound > 0;
1312 | ```
1313 | [Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AppExamples.java#L196-L208)
1314 | <!-- ===JAVASDK_APP_DELETE=== -->
1315 |
1316 | === "Go"
1317 | <!-- ===GOSDK_APP_DELETE=== -->
1318 | ```go
1319 | sp, err := algodClient.SuggestedParams().Do(context.Background())
1320 | if err != nil {
1321 | log.Fatalf("error getting suggested tx params: %s", err)
1322 | }
1323 |
1324 | var (
1325 | appArgs [][]byte
1326 | accts []string
1327 | apps []uint64
1328 | assets []uint64
1329 | )
1330 |
1331 | txn, err := transaction.MakeApplicationDeleteTx(
1332 | appID, appArgs, accts, apps, assets, sp,
1333 | caller.Address, nil, types.Digest{}, [32]byte{}, types.ZeroAddress,
1334 | )
1335 | if err != nil {
1336 | log.Fatalf("failed to make txn: %s", err)
1337 | }
1338 |
1339 | // sign the transaction
1340 | txid, stx, err := crypto.SignTransaction(caller.PrivateKey, txn)
1341 | if err != nil {
1342 | log.Fatalf("failed to sign transaction: %s", err)
1343 | }
1344 |
1345 | // Broadcast the transaction to the network
1346 | _, err = algodClient.SendRawTransaction(stx).Do(context.Background())
1347 | if err != nil {
1348 | log.Fatalf("failed to send transaction: %s", err)
1349 | }
1350 |
1351 | // Wait for confirmation
1352 | confirmedTxn, err := transaction.WaitForConfirmation(algodClient, txid, 4, context.Background())
1353 | if err != nil {
1354 | log.Fatalf("error waiting for confirmation: %s", err)
1355 | }
1356 |
1357 | log.Printf("Delete Transaction: %s confirmed in Round %d\n", txid, confirmedTxn.ConfirmedRound)
1358 | ```
1359 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/apps/main.go#L406-L445)
1360 | <!-- ===GOSDK_APP_DELETE=== -->
1361 |
1362 | ## Clear state
1363 |
1364 | The user may [clear the local state](../apps/#the-lifecycle-of-a-smart-contract) for an application at any time, even if the application was deleted by the creator. This method uses the same 3 parameters.
1365 |
1366 | === "Python"
1367 | <!-- ===PYSDK_APP_CLEAR=== -->
1368 | ```python
1369 | clear_txn = transaction.ApplicationClearStateTxn(user.address, sp, app_id)
1370 | # .. sign, send, wait
1371 | ```
1372 | [Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/apps.py#L139-L141)
1373 | <!-- ===PYSDK_APP_CLEAR=== -->
1374 |
1375 | === "JavaScript"
1376 | <!-- ===JSSDK_APP_CLEAR=== -->
1377 | ```javascript
1378 | const appClearTxn = algosdk.makeApplicationClearStateTxnFromObject({
1379 | from: anotherCaller.addr,
1380 | suggestedParams,
1381 | appIndex: appId,
1382 | });
1383 |
1384 | await algodClient
1385 | .sendRawTransaction(appClearTxn.signTxn(anotherCaller.privateKey))
1386 | .do();
1387 | await algosdk.waitForConfirmation(
1388 | algodClient,
1389 | appClearTxn.txID().toString(),
1390 | 3
1391 | );
1392 | ```
1393 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/app.ts#L226-L240)
1394 | <!-- ===JSSDK_APP_CLEAR=== -->
1395 |
1396 | === "Java"
1397 | <!-- ===JAVASDK_APP_CLEAR=== -->
1398 | ```java
1399 | Transaction clearTxn = ApplicationClearTransactionBuilder.Builder()
1400 | .sender(user.getAddress())
1401 | .suggestedParams(sp)
1402 | .applicationId(appId)
1403 | .build();
1404 |
1405 | SignedTransaction signedClear = user.signTransaction(clearTxn);
1406 | // ... sign, send, wait
1407 | ```
1408 | [Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/AppExamples.java#L211-L219)
1409 | <!-- ===JAVASDK_APP_CLEAR=== -->
1410 |
1411 | === "Go"
1412 | <!-- ===GOSDK_APP_CLEAR=== -->
1413 | ```go
1414 | sp, err := algodClient.SuggestedParams().Do(context.Background())
1415 | if err != nil {
1416 | log.Fatalf("error getting suggested tx params: %s", err)
1417 | }
1418 |
1419 | var (
1420 | appArgs [][]byte
1421 | accts []string
1422 | apps []uint64
1423 | assets []uint64
1424 | )
1425 |
1426 | txn, err := transaction.MakeApplicationClearStateTx(
1427 | appID, appArgs, accts, apps, assets, sp,
1428 | caller.Address, nil, types.Digest{}, [32]byte{}, types.ZeroAddress,
1429 | )
1430 | if err != nil {
1431 | log.Fatalf("failed to make txn: %s", err)
1432 | }
1433 |
1434 | // sign the transaction
1435 | txid, stx, err := crypto.SignTransaction(caller.PrivateKey, txn)
1436 | if err != nil {
1437 | log.Fatalf("failed to sign transaction: %s", err)
1438 | }
1439 |
1440 | // Broadcast the transaction to the network
1441 | _, err = algodClient.SendRawTransaction(stx).Do(context.Background())
1442 | if err != nil {
1443 | log.Fatalf("failed to send transaction: %s", err)
1444 | }
1445 |
1446 | // Wait for confirmation
1447 | confirmedTxn, err := transaction.WaitForConfirmation(algodClient, txid, 4, context.Background())
1448 | if err != nil {
1449 | log.Fatalf("error waiting for confirmation: %s", err)
1450 | }
1451 |
1452 | log.Printf("ClearState Transaction: %s confirmed in Round %d\n", txid, confirmedTxn.ConfirmedRound)
1453 | ```
1454 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/apps/main.go#L315-L354)
1455 | <!-- ===GOSDK_APP_CLEAR=== -->
1456 |
1457 | # Appendix
1458 |
1459 | ## Approval program walkthrough
1460 |
1461 | ```teal
1462 | #pragma version 4
1463 | // Handle each possible OnCompletion type. We don't have to worry about
1464 | // handling ClearState, because the ClearStateProgram will execute in that
1465 | // case, not the ApprovalProgram.
1466 |
1467 | txn OnCompletion
1468 | int NoOp
1469 | ==
1470 | bnz handle_noop
1471 |
1472 | txn OnCompletion
1473 | int OptIn
1474 | ==
1475 | bnz handle_optin
1476 |
1477 | txn OnCompletion
1478 | int CloseOut
1479 | ==
1480 | bnz handle_closeout
1481 |
1482 | txn OnCompletion
1483 | int UpdateApplication
1484 | ==
1485 | bnz handle_updateapp
1486 |
1487 | txn OnCompletion
1488 | int DeleteApplication
1489 | ==
1490 | bnz handle_deleteapp
1491 |
1492 | // Unexpected OnCompletion value. Should be unreachable.
1493 | err
1494 |
1495 | handle_noop:
1496 | // Handle NoOp
1497 | // Check for creator
1498 | addr 5XWY6RBNYHCSY2HK5HCTO62DUJJ4PT3G4L77FQEBUKE6ZYRGQAFTLZSQQ4
1499 | txn Sender
1500 | ==
1501 | bnz handle_optin
1502 |
1503 | // read global state
1504 | byte "counter"
1505 | dup
1506 | app_global_get
1507 |
1508 | // increment the value
1509 | int 1
1510 | +
1511 |
1512 | // store to scratch space
1513 | dup
1514 | store 0
1515 |
1516 | // update global state
1517 | app_global_put
1518 |
1519 | // read local state for sender
1520 | int 0
1521 | byte "counter"
1522 | app_local_get
1523 |
1524 | // increment the value
1525 | int 1
1526 | +
1527 | store 1
1528 |
1529 | // update local state for sender
1530 | int 0
1531 | byte "counter"
1532 | load 1
1533 | app_local_put
1534 |
1535 | // load return value as approval
1536 | load 0
1537 | return
1538 |
1539 | handle_optin:
1540 | // Handle OptIn
1541 | // approval
1542 | int 1
1543 | return
1544 |
1545 | handle_closeout:
1546 | // Handle CloseOut
1547 | //approval
1548 | int 1
1549 | return
1550 |
1551 | handle_deleteapp:
1552 | // Check for creator
1553 | addr 5XWY6RBNYHCSY2HK5HCTO62DUJJ4PT3G4L77FQEBUKE6ZYRGQAFTLZSQQ4
1554 | txn Sender
1555 | ==
1556 | return
1557 |
1558 | handle_updateapp:
1559 | // Check for creator
1560 | addr 5XWY6RBNYHCSY2HK5HCTO62DUJJ4PT3G4L77FQEBUKE6ZYRGQAFTLZSQQ4
1561 | txn Sender
1562 | ==
1563 | return
1564 | ```
1565 |
1566 | ## Clear program walkthrough
1567 |
1568 | ## Refactored approval program
1569 |
1570 | ```teal
1571 | #pragma version 4
1572 | // Handle each possible OnCompletion type. We don't have to worry about
1573 | // handling ClearState, because the ClearStateProgram will execute in that
1574 | // case, not the ApprovalProgram.
1575 |
1576 | txn OnCompletion
1577 | int NoOp
1578 | ==
1579 | bnz handle_noop
1580 |
1581 | txn OnCompletion
1582 | int OptIn
1583 | ==
1584 | bnz handle_optin
1585 |
1586 | txn OnCompletion
1587 | int CloseOut
1588 | ==
1589 | bnz handle_closeout
1590 |
1591 | txn OnCompletion
1592 | int UpdateApplication
1593 | ==
1594 | bnz handle_updateapp
1595 |
1596 | txn OnCompletion
1597 | int DeleteApplication
1598 | ==
1599 | bnz handle_deleteapp
1600 |
1601 | // Unexpected OnCompletion value. Should be unreachable.
1602 | err
1603 |
1604 | handle_noop:
1605 | // Handle NoOp
1606 | // Check for creator
1607 | addr 5XWY6RBNYHCSY2HK5HCTO62DUJJ4PT3G4L77FQEBUKE6ZYRGQAFTLZSQQ4
1608 | txn Sender
1609 | ==
1610 | bnz handle_optin
1611 |
1612 | // read global state
1613 | byte "counter"
1614 | dup
1615 | app_global_get
1616 |
1617 | // increment the value
1618 | int 1
1619 | +
1620 |
1621 | // store to scratch space
1622 | dup
1623 | store 0
1624 |
1625 | // update global state
1626 | app_global_put
1627 |
1628 | // read local state for sender
1629 | int 0
1630 | byte "counter"
1631 | app_local_get
1632 |
1633 | // increment the value
1634 | int 1
1635 | +
1636 | store 1
1637 |
1638 | // update local state for sender
1639 | // update "counter"
1640 | int 0
1641 | byte "counter"
1642 | load 1
1643 | app_local_put
1644 |
1645 | // update "timestamp"
1646 | int 0
1647 | byte "timestamp"
1648 | txn ApplicationArgs 0
1649 | app_local_put
1650 |
1651 | // load return value as approval
1652 | load 0
1653 | return
1654 |
1655 | handle_optin:
1656 | // Handle OptIn
1657 | // approval
1658 | int 1
1659 | return
1660 |
1661 | handle_closeout:
1662 | // Handle CloseOut
1663 | //approval
1664 | int 1
1665 | return
1666 |
1667 | handle_deleteapp:
1668 | // Check for creator
1669 | addr 5XWY6RBNYHCSY2HK5HCTO62DUJJ4PT3G4L77FQEBUKE6ZYRGQAFTLZSQQ4
1670 | txn Sender
1671 | ==
1672 | return
1673 |
1674 | handle_updateapp:
1675 | // Check for creator
1676 | addr 5XWY6RBNYHCSY2HK5HCTO62DUJJ4PT3G4L77FQEBUKE6ZYRGQAFTLZSQQ4
1677 | txn Sender
1678 | ==
1679 | return
1680 | ```
```