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

# Directory Structure

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

# Files

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

```markdown
title: Offline signatures

This section explains how to authorize transactions with private keys that are kept **offline**. In particular, this guide shows how to create and save transactions to a file that can then be transferred to an offline device for signing. To learn about the structure of transactions and how to authorize them in general visit the [Transactions Structure](../../transactions/) and [Authorizing Transactions](../../transactions/signatures/) sections, respectively.

The same methodology described here can also be used to work with [LogicSignatures](../../transactions/signatures/#logic-signatures) and [Multisignatures](../../transactions/signatures/#multisignatures). All objects in the following examples use msgpack to store the transaction object ensuring interoperability with the SDKs and `goal`.

!!! info
    Storing keys _offline_ is also referred to as placing them in **cold storage**. An _online_ device that stores private keys is often referred to as a **hot wallet**.  

# Unsigned Transaction File Operations
Algorand SDK's and `goal` support writing and reading both signed and unsigned transactions to a file. Examples of these scenarios are shown in the following code snippets.

Unsigned transactions require the transaction object to be created before writing to a file.

=== "JavaScript"
	<!-- ===JSSDK_CODEC_TRANSACTION_UNSIGNED=== -->
	```javascript
	const txn = algosdk.makePaymentTxnWithSuggestedParamsFromObject({
	  from: sender.addr,
	  to: receiver.addr,
	  amount: 1e6,
	  suggestedParams,
	});
	
	const txnBytes = algosdk.encodeUnsignedTransaction(txn);
	const txnB64 = Buffer.from(txnBytes).toString('base64');
	// ...
	const restoredTxn = algosdk.decodeUnsignedTransaction(
	  Buffer.from(txnB64, 'base64')
	);
	console.log(restoredTxn);
	```
	[Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/codec.ts#L37-L51)
	<!-- ===JSSDK_CODEC_TRANSACTION_UNSIGNED=== -->

=== "Python"
	<!-- ===PYSDK_CODEC_TRANSACTION_UNSIGNED=== -->
	```python
	sp = algod_client.suggested_params()
	pay_txn = transaction.PaymentTxn(acct.address, sp, acct.address, 10000)
	
	# Write message packed transaction to disk
	with open("pay.txn", "w") as f:
	    f.write(encoding.msgpack_encode(pay_txn))
	
	# Read message packed transaction and decode it to a Transaction object
	with open("pay.txn", "r") as f:
	    recovered_txn = encoding.msgpack_decode(f.read())
	
	print(recovered_txn.dictify())
	```
	[Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/codec.py#L40-L52)
	<!-- ===PYSDK_CODEC_TRANSACTION_UNSIGNED=== -->

=== "Java"
	<!-- ===JAVASDK_CODEC_TRANSACTION_UNSIGNED=== -->
	```java
	Response<TransactionParametersResponse> rsp = algodClient.TransactionParams().execute();
	TransactionParametersResponse sp = rsp.body();
	Transaction ptxn = Transaction.PaymentTransactionBuilder().suggestedParams(sp)
	        .sender(acct.getAddress()).receiver(acct.getAddress()).amount(100).build();
	
	byte[] encodedTxn = Encoder.encodeToMsgPack(ptxn);
	
	Transaction decodedTxn = Encoder.decodeFromMsgPack(encodedTxn, Transaction.class);
	assert decodedTxn.equals(ptxn);
	```
	[Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/CodecExamples.java#L49-L58)
	<!-- ===JAVASDK_CODEC_TRANSACTION_UNSIGNED=== -->

=== "Go"
	<!-- ===GOSDK_CODEC_TRANSACTION_UNSIGNED=== -->
	```go
	// Error handling omitted for brevity
	sp, _ := algodClient.SuggestedParams().Do(context.Background())
	ptxn, _ := transaction.MakePaymentTxn(
		acct1.Address.String(), acct1.Address.String(), 10000, nil, "", sp,
	)
	
	// Encode the txn as bytes,
	// if sending over the wire (like to a frontend) it should also be b64 encoded
	encodedTxn := msgpack.Encode(ptxn)
	os.WriteFile("pay.txn", encodedTxn, 0655)
	
	var recoveredPayTxn = types.Transaction{}
	
	msgpack.Decode(encodedTxn, &recoveredPayTxn)
	log.Printf("%+v", recoveredPayTxn)
	```
	[Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/codec/main.go#L28-L43)
	<!-- ===GOSDK_CODEC_TRANSACTION_UNSIGNED=== -->

=== "goal"
	<!-- ===GOAL_CODEC_TRANSACTION_UNSIGNED=== -->
    ``` goal
    $ goal clerk send --from=<my-account> --to=GD64YIY3TWGDMCNPP553DZPPR6LDUSFQOIJVFDPPXWEG3FVOJCCDBBHU5A --fee=1000 --amount=1000000 --out="unsigned.txn"

    $ goal clerk sign --infile unsigned.txn --outfile signed.txn

    $ goal clerk rawsend --filename signed.txn

    ```
	<!-- ===GOAL_CODEC_TRANSACTION_UNSIGNED=== -->
# Signed Transaction File Operations 
Signed Transactions are similar, but require an account to sign the transaction before writing it to a file.

=== "JavaScript"
	<!-- ===JSSDK_CODEC_TRANSACTION_SIGNED=== -->
	```javascript
	const signedTxn = txn.signTxn(sender.privateKey);
	const signedB64Txn = Buffer.from(signedTxn).toString('base64');
	const restoredSignedTxn = algosdk.decodeSignedTransaction(
	  Buffer.from(signedB64Txn, 'base64')
	);
	console.log(restoredSignedTxn);
	```
	[Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/codec.ts#L54-L60)
	<!-- ===JSSDK_CODEC_TRANSACTION_SIGNED=== -->

=== "Python"
	<!-- ===PYSDK_CODEC_TRANSACTION_SIGNED=== -->
	```python
	# Sign transaction
	spay_txn = pay_txn.sign(acct.private_key)
	# write message packed signed transaction to disk
	with open("signed_pay.txn", "w") as f:
	    f.write(encoding.msgpack_encode(spay_txn))
	
	# read message packed signed transaction into a SignedTransaction object
	with open("signed_pay.txn", "r") as f:
	    recovered_signed_txn = encoding.msgpack_decode(f.read())
	
	print(recovered_signed_txn.dictify())
	```
	[Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/codec.py#L57-L68)
	<!-- ===PYSDK_CODEC_TRANSACTION_SIGNED=== -->

=== "Java"
	<!-- ===JAVASDK_CODEC_TRANSACTION_SIGNED=== -->
	```java
	SignedTransaction signedTxn = acct.signTransaction(ptxn);
	byte[] encodedSignedTxn = Encoder.encodeToMsgPack(signedTxn);
	
	SignedTransaction decodedSignedTransaction = Encoder.decodeFromMsgPack(encodedSignedTxn,
	        SignedTransaction.class);
	assert decodedSignedTransaction.equals(signedTxn);
	```
	[Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/CodecExamples.java#L61-L67)
	<!-- ===JAVASDK_CODEC_TRANSACTION_SIGNED=== -->

=== "Go"
	<!-- ===GOSDK_CODEC_TRANSACTION_SIGNED=== -->
	```go
	// Assuming we already have a pay transaction `ptxn`
	
	// Sign the transaction
	_, signedTxn, err := crypto.SignTransaction(acct1.PrivateKey, ptxn)
	if err != nil {
		log.Fatalf("failed to sign transaction: %s", err)
	}
	
	// Save the signed transaction to file
	os.WriteFile("pay.stxn", signedTxn, 0644)
	
	signedPayTxn := types.SignedTxn{}
	err = msgpack.Decode(signedTxn, &signedPayTxn)
	if err != nil {
		log.Fatalf("failed to decode signed transaction: %s", err)
	}
	```
	[Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/codec/main.go#L46-L62)
	<!-- ===GOSDK_CODEC_TRANSACTION_SIGNED=== -->

=== "goal"
	<!-- ===GOAL_CODEC_TRANSACTION_SIGNED=== -->
    ``` goal
    $ goal clerk rawsend --filename signed.txn
    ```
	<!-- ===GOAL_CODEC_TRANSACTION_SIGNED=== -->

## Signature Verification

Sometimes a transaction is signed by a third party, and you want to verify that the signature is valid. This can be done by decoding the signed transaction into a `SignedTransaction` object using one of the SDKs and then running and ed25519 verify on the signature.

=== "JavaScript"
	<!-- ===JSSDK_OFFLINE_VERIFY_SIG=== -->
	```javascript
	const stxn = algosdk.decodeSignedTransaction(rawSignedTxn);
	if (stxn.sig === undefined) return false;
	
	// Get the txn object
	const txnObj = stxn.txn.get_obj_for_encoding();
	if (txnObj === undefined) return false;
	
	// Encode as msgpack
	const txnBytes = algosdk.encodeObj(txnObj);
	// Create byte array with TX prefix
	const msgBytes = new Uint8Array(txnBytes.length + 2);
	msgBytes.set(Buffer.from('TX'));
	msgBytes.set(txnBytes, 2);
	
	// Grab the other things we need to verify
	const pkBytes = stxn.txn.from.publicKey;
	const sigBytes = new Uint8Array(stxn.sig);
	
	// Return the result of the verification
	const valid = nacl.sign.detached.verify(msgBytes, sigBytes, pkBytes);
	console.log('Valid? ', valid);
	```
	[Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/verify_signature.ts#L6-L27)
	<!-- ===JSSDK_OFFLINE_VERIFY_SIG=== -->

=== "Python"
	<!-- ===PYSDK_OFFLINE_VERIFY_SIG=== -->
	```python
	# decode the signed transaction
	stxn = encoding.msgpack_decode(raw_stxn)
	if stxn.signature is None or len(stxn.signature) == 0:
	    return False
	
	public_key = stxn.transaction.sender
	if stxn.authorizing_address is not None:
	    public_key = stxn.authorizing_address
	
	# Create a VerifyKey from nacl using the 32 byte public key
	verify_key = VerifyKey(encoding.decode_address(public_key))
	
	# Generate the message that was signed with TX prefix
	prefixed_message = b"TX" + base64.b64decode(
	    encoding.msgpack_encode(stxn.transaction)
	)
	
	try:
	    # Verify the signature
	    verify_key.verify(prefixed_message, base64.b64decode(stxn.signature))
	    return True
	except BadSignatureError:
	    return False
	```
	[Snippet Source](https://github.com/algorand/py-algorand-sdk/blob/examples/examples/verify_signature.py#L9-L32)
	<!-- ===PYSDK_OFFLINE_VERIFY_SIG=== -->

=== "Go"
	<!-- ===GOSDK_OFFLINE_VERIFY_SIG=== -->
	```go
	signedTxn := types.SignedTxn{}
	msgpack.Decode(stxn, &signedTxn)
	
	from := signedTxn.Txn.Sender[:]
	
	encodedTx := msgpack.Encode(signedTxn.Txn)
	
	msgParts := [][]byte{txidPrefix, encodedTx}
	msg := bytes.Join(msgParts, nil)
	
	valid := ed25519.Verify(from, msg, signedTxn.Sig[:])
	
	log.Printf("Valid? %t", valid)
	```
	[Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/verify_signature/main.go#L31-L44)
	<!-- ===GOSDK_OFFLINE_VERIFY_SIG=== -->

=== "Java"
	<!-- ===JAVASDK_OFFLINE_VERIFY_SIG=== -->
	```java
	// decode the signature
	SignedTransaction decodedSignedTransaction = Encoder.decodeFromMsgPack(rawSignedTxn,
	        SignedTransaction.class);
	Transaction txn = decodedSignedTransaction.tx;
	
	// get the bytes that were signed
	byte[] signedBytes = txn.bytesToSign();
	// get the pubkey that signed them
	PublicKey pk = txn.sender.toVerifyKey();
	
	// set up the sig checker
	java.security.Signature sigChecker = java.security.Signature.getInstance("Ed25519");
	sigChecker.initVerify(pk);
	sigChecker.update(signedBytes);
	// verify the signature 
	boolean valid = sigChecker.verify(decodedSignedTransaction.sig.getBytes());
	System.out.printf("Valid? %b\n", valid);
	```
	[Snippet Source](https://github.com/algorand/java-algorand-sdk/blob/examples/examples/src/main/java/com/algorand/examples/VerifySignature.java#L33-L50)
	<!-- ===JAVASDK_OFFLINE_VERIFY_SIG=== -->

    
??? example "Saving Signed and Unsigned Multisig Transactions to a File using goal"
    
    
    Create a multisig account by listing all of the accounts in the multisig and specifying the threshold number of accounts to sign with the -T flag

    ```bash
    goal account multisig new <my-account1> <my-account2> <my-account3> etc… -T 2    
    ```

    Create an unsigned transaction and write to file

    ```bash
    goal clerk send --from <my-multisig-account>  --to AZLR2XP4O2WFHLX6TX7AZVY23HLVLG3K5K3FRIKIYDOYN6ISIF54SA4RNY --fee=1000 --amount=1000000 --out="unsigned.txn"
    ```

    Sign by the required number of accounts to meet the threshold. 

    ```bash
    goal clerk multisig sign -a F <my-account1> -t=unsigned.txn
    goal clerk multisig sign -a F <my-account2> -t=unsigned.txn
    ```

    Merge signings 
    ```bash
    goal clerk multisig merge --out signed.txn unsigned.txn
    ```

    Broadcast

    ```bash
    goal clerk rawsend --filename signed.txn
    ```
```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/algokit:utils:typescript:code:interfaces:types_asset.CreateAssetParams.md:
--------------------------------------------------------------------------------

```markdown
[@algorandfoundation/algokit-utils](../README.md) / [types/asset](../modules/types_asset.md) / CreateAssetParams

# Interface: CreateAssetParams

[types/asset](../modules/types_asset.md).CreateAssetParams

**`Deprecated`**

Parameters for `createAsset` call.

## Hierarchy

- [`SendTransactionParams`](types_transaction.SendTransactionParams.md)

  ↳ **`CreateAssetParams`**

## Table of contents

### Properties

- [atc](types_asset.CreateAssetParams.md#atc)
- [clawbackAccount](types_asset.CreateAssetParams.md#clawbackaccount)
- [creator](types_asset.CreateAssetParams.md#creator)
- [decimals](types_asset.CreateAssetParams.md#decimals)
- [fee](types_asset.CreateAssetParams.md#fee)
- [freezeAccount](types_asset.CreateAssetParams.md#freezeaccount)
- [frozenByDefault](types_asset.CreateAssetParams.md#frozenbydefault)
- [lease](types_asset.CreateAssetParams.md#lease)
- [manager](types_asset.CreateAssetParams.md#manager)
- [maxFee](types_asset.CreateAssetParams.md#maxfee)
- [maxRoundsToWaitForConfirmation](types_asset.CreateAssetParams.md#maxroundstowaitforconfirmation)
- [metadataHash](types_asset.CreateAssetParams.md#metadatahash)
- [name](types_asset.CreateAssetParams.md#name)
- [note](types_asset.CreateAssetParams.md#note)
- [populateAppCallResources](types_asset.CreateAssetParams.md#populateappcallresources)
- [reserveAccount](types_asset.CreateAssetParams.md#reserveaccount)
- [skipSending](types_asset.CreateAssetParams.md#skipsending)
- [skipWaiting](types_asset.CreateAssetParams.md#skipwaiting)
- [suppressLog](types_asset.CreateAssetParams.md#suppresslog)
- [total](types_asset.CreateAssetParams.md#total)
- [transactionParams](types_asset.CreateAssetParams.md#transactionparams)
- [unit](types_asset.CreateAssetParams.md#unit)
- [url](types_asset.CreateAssetParams.md#url)

## Properties

### atc

• `Optional` **atc**: `AtomicTransactionComposer`

An optional `AtomicTransactionComposer` to add the transaction to, if specified then `skipSending: undefined` has the same effect as `skipSending: true`

#### Inherited from

[SendTransactionParams](types_transaction.SendTransactionParams.md).[atc](types_transaction.SendTransactionParams.md#atc)

#### Defined in

[src/types/transaction.ts:36](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L36)

___

### clawbackAccount

• `Optional` **clawbackAccount**: `string` \| [`SendTransactionFrom`](../modules/types_transaction.md#sendtransactionfrom)

The optional account that can clawback holdings of this asset. If empty, clawback is not permitted.
If not set at asset creation or subsequently set to empty by the manager the field is permanently empty.

#### Defined in

[src/types/asset.ts:57](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/asset.ts#L57)

___

### creator

• **creator**: [`SendTransactionFrom`](../modules/types_transaction.md#sendtransactionfrom)

The account to create the asset.

This account automatically is opted in to the asset and holds all units after creation.

#### Defined in

[src/types/asset.ts:11](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/asset.ts#L11)

___

### decimals

• **decimals**: `number`

The number of digits to use after the decimal point when displaying the asset.
If 0, the asset is not divisible.
If 1, the base unit of the asset is in tenths.
If 2, the base unit of the asset is in hundredths.
If 3, the base unit of the asset is in thousandths, and so on up to 19 decimal places.
This field can only be specified upon asset creation.

#### Defined in

[src/types/asset.ts:26](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/asset.ts#L26)

___

### fee

• `Optional` **fee**: [`AlgoAmount`](../classes/types_amount.AlgoAmount.md)

The flat fee you want to pay, useful for covering extra fees in a transaction group or app call

#### Inherited from

[SendTransactionParams](types_transaction.SendTransactionParams.md).[fee](types_transaction.SendTransactionParams.md#fee)

#### Defined in

[src/types/transaction.ts:40](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L40)

___

### freezeAccount

• `Optional` **freezeAccount**: `string` \| [`SendTransactionFrom`](../modules/types_transaction.md#sendtransactionfrom)

The optional account that can be used to freeze holdings of this asset. If empty, freezing is not permitted.
If not set at asset creation or subsequently set to empty by the manager the field is permanently empty.

#### Defined in

[src/types/asset.ts:53](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/asset.ts#L53)

___

### frozenByDefault

• `Optional` **frozenByDefault**: `boolean`

Whether to freeze holdings for this asset by default. If `true` then for anyone apart from the creator to hold the asset it needs to be unfrozen per account using `freeze`. Defaults to `false`.

#### Defined in

[src/types/asset.ts:59](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/asset.ts#L59)

___

### lease

• `Optional` **lease**: `string` \| `Uint8Array`

An (optional) [transaction lease](https://developer.algorand.org/articles/leased-transactions-securing-advanced-smart-contract-design/) to apply

#### Defined in

[src/types/asset.ts:66](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/asset.ts#L66)

___

### manager

• `Optional` **manager**: `string` \| [`SendTransactionFrom`](../modules/types_transaction.md#sendtransactionfrom)

The optional account that can manage the configuration of the asset and destroy it.
If not set at asset creation or subsequently set to empty by the manager the asset becomes immutable.

#### Defined in

[src/types/asset.ts:43](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/asset.ts#L43)

___

### maxFee

• `Optional` **maxFee**: [`AlgoAmount`](../classes/types_amount.AlgoAmount.md)

The maximum fee that you are happy to pay (default: unbounded) - if this is set it's possible the transaction could get rejected during network congestion

#### Inherited from

[SendTransactionParams](types_transaction.SendTransactionParams.md).[maxFee](types_transaction.SendTransactionParams.md#maxfee)

#### Defined in

[src/types/transaction.ts:42](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L42)

___

### maxRoundsToWaitForConfirmation

• `Optional` **maxRoundsToWaitForConfirmation**: `number`

The maximum number of rounds to wait for confirmation, only applies if `skipWaiting` is `undefined` or `false`, default: wait up to 5 rounds

#### Inherited from

[SendTransactionParams](types_transaction.SendTransactionParams.md).[maxRoundsToWaitForConfirmation](types_transaction.SendTransactionParams.md#maxroundstowaitforconfirmation)

#### Defined in

[src/types/transaction.ts:44](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L44)

___

### metadataHash

• `Optional` **metadataHash**: `string` \| `Uint8Array`

This field is intended to be a 32-byte hash of some metadata that is relevant to your asset and/or asset holders.
The format of this metadata is up to the application. This field can only be specified upon asset creation.

#### Defined in

[src/types/asset.ts:39](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/asset.ts#L39)

___

### name

• `Optional` **name**: `string`

The optional name of the asset. Max size if 32 bytes. This field can only be specified upon asset creation.

#### Defined in

[src/types/asset.ts:29](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/asset.ts#L29)

___

### note

• `Optional` **note**: [`TransactionNote`](../modules/types_transaction.md#transactionnote)

The (optional) transaction note

#### Defined in

[src/types/asset.ts:64](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/asset.ts#L64)

___

### populateAppCallResources

• `Optional` **populateAppCallResources**: `boolean`

Whether to use simulate to automatically populate app call resources in the txn objects. Defaults to true when there are app calls in the group.

#### Inherited from

[SendTransactionParams](types_transaction.SendTransactionParams.md).[populateAppCallResources](types_transaction.SendTransactionParams.md#populateappcallresources)

#### Defined in

[src/types/transaction.ts:46](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L46)

___

### reserveAccount

• `Optional` **reserveAccount**: `string` \| [`SendTransactionFrom`](../modules/types_transaction.md#sendtransactionfrom)

The optional account that holds the reserve (non-minted) units of the asset. This address has no specific authority in the protocol itself and is informational.
Some standards like [ARC-19](https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0019.md) rely on this field to hold meaningful data.
It is used in the case where you want to signal to holders of your asset that the non-minted units of the asset reside in an account that is different from the default creator account.
If not set at asset creation or subsequently set to empty by the manager the field is permanently empty.

#### Defined in

[src/types/asset.ts:49](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/asset.ts#L49)

___

### skipSending

• `Optional` **skipSending**: `boolean`

Whether to skip signing and sending the transaction to the chain (default: transaction signed and sent to chain, unless `atc` specified)
and instead just return the raw transaction, e.g. so you can add it to a group of transactions

#### Inherited from

[SendTransactionParams](types_transaction.SendTransactionParams.md).[skipSending](types_transaction.SendTransactionParams.md#skipsending)

#### Defined in

[src/types/transaction.ts:32](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L32)

___

### skipWaiting

• `Optional` **skipWaiting**: `boolean`

Whether to skip waiting for the submitted transaction (only relevant if `skipSending` is `false` or unset)

#### Inherited from

[SendTransactionParams](types_transaction.SendTransactionParams.md).[skipWaiting](types_transaction.SendTransactionParams.md#skipwaiting)

#### Defined in

[src/types/transaction.ts:34](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L34)

___

### suppressLog

• `Optional` **suppressLog**: `boolean`

Whether to suppress log messages from transaction send, default: do not suppress

#### Inherited from

[SendTransactionParams](types_transaction.SendTransactionParams.md).[suppressLog](types_transaction.SendTransactionParams.md#suppresslog)

#### Defined in

[src/types/transaction.ts:38](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/transaction.ts#L38)

___

### total

• **total**: `number` \| `bigint`

The total number of base (decimal) units of the asset to create.
If decimal is, say, 2, then for every 100 `total` there would be 1 whole unit.
This field can only be specified upon asset creation.

#### Defined in

[src/types/asset.ts:17](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/asset.ts#L17)

___

### transactionParams

• `Optional` **transactionParams**: `SuggestedParams`

Optional transaction parameters

#### Defined in

[src/types/asset.ts:62](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/asset.ts#L62)

___

### unit

• `Optional` **unit**: `string`

The optional name of the unit of this asset. Max size is 8 bytes. This field can only be specified upon asset creation.

#### Defined in

[src/types/asset.ts:31](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/asset.ts#L31)

___

### url

• `Optional` **url**: `string`

Specifies an optional URL where more information about the asset can be retrieved. Max size is 96 bytes.
This field can only be specified upon asset creation.

#### Defined in

[src/types/asset.ts:35](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/asset.ts#L35)

```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/SDKs:javascript:classes:indexerModels.Account.md:
--------------------------------------------------------------------------------

```markdown
[algosdk](../README.md) / [Exports](../modules.md) / [indexerModels](../modules/indexerModels.md) / Account

# Class: Account

[indexerModels](../modules/indexerModels.md).Account

Account information at a given round.
Definition:
data/basics/userBalance.go : AccountData

## Hierarchy

- `default`

  ↳ **`Account`**

## Table of contents

### Constructors

- [constructor](indexerModels.Account.md#constructor)

### Properties

- [address](indexerModels.Account.md#address)
- [amount](indexerModels.Account.md#amount)
- [amountWithoutPendingRewards](indexerModels.Account.md#amountwithoutpendingrewards)
- [appsLocalState](indexerModels.Account.md#appslocalstate)
- [appsTotalExtraPages](indexerModels.Account.md#appstotalextrapages)
- [appsTotalSchema](indexerModels.Account.md#appstotalschema)
- [assets](indexerModels.Account.md#assets)
- [attribute\_map](indexerModels.Account.md#attribute_map)
- [authAddr](indexerModels.Account.md#authaddr)
- [closedAtRound](indexerModels.Account.md#closedatround)
- [createdApps](indexerModels.Account.md#createdapps)
- [createdAssets](indexerModels.Account.md#createdassets)
- [createdAtRound](indexerModels.Account.md#createdatround)
- [deleted](indexerModels.Account.md#deleted)
- [incentiveEligible](indexerModels.Account.md#incentiveeligible)
- [lastHeartbeat](indexerModels.Account.md#lastheartbeat)
- [lastProposed](indexerModels.Account.md#lastproposed)
- [minBalance](indexerModels.Account.md#minbalance)
- [participation](indexerModels.Account.md#participation)
- [pendingRewards](indexerModels.Account.md#pendingrewards)
- [rewardBase](indexerModels.Account.md#rewardbase)
- [rewards](indexerModels.Account.md#rewards)
- [round](indexerModels.Account.md#round)
- [sigType](indexerModels.Account.md#sigtype)
- [status](indexerModels.Account.md#status)
- [totalAppsOptedIn](indexerModels.Account.md#totalappsoptedin)
- [totalAssetsOptedIn](indexerModels.Account.md#totalassetsoptedin)
- [totalBoxBytes](indexerModels.Account.md#totalboxbytes)
- [totalBoxes](indexerModels.Account.md#totalboxes)
- [totalCreatedApps](indexerModels.Account.md#totalcreatedapps)
- [totalCreatedAssets](indexerModels.Account.md#totalcreatedassets)

### Methods

- [get\_obj\_for\_encoding](indexerModels.Account.md#get_obj_for_encoding)
- [from\_obj\_for\_encoding](indexerModels.Account.md#from_obj_for_encoding)

## Constructors

### constructor

• **new Account**(`«destructured»`)

Creates a new `Account` object.

#### Parameters

| Name | Type |
| :------ | :------ |
| `«destructured»` | `Object` |
| › `address` | `string` |
| › `amount` | `number` \| `bigint` |
| › `amountWithoutPendingRewards` | `number` \| `bigint` |
| › `appsLocalState?` | [`ApplicationLocalState`](indexerModels.ApplicationLocalState.md)[] |
| › `appsTotalExtraPages?` | `number` \| `bigint` |
| › `appsTotalSchema?` | [`ApplicationStateSchema`](indexerModels.ApplicationStateSchema.md) |
| › `assets?` | [`AssetHolding`](indexerModels.AssetHolding.md)[] |
| › `authAddr?` | `string` |
| › `closedAtRound?` | `number` \| `bigint` |
| › `createdApps?` | [`Application`](indexerModels.Application.md)[] |
| › `createdAssets?` | [`Asset`](indexerModels.Asset.md)[] |
| › `createdAtRound?` | `number` \| `bigint` |
| › `deleted?` | `boolean` |
| › `incentiveEligible?` | `boolean` |
| › `lastHeartbeat?` | `number` \| `bigint` |
| › `lastProposed?` | `number` \| `bigint` |
| › `minBalance` | `number` \| `bigint` |
| › `participation?` | [`AccountParticipation`](indexerModels.AccountParticipation.md) |
| › `pendingRewards` | `number` \| `bigint` |
| › `rewardBase?` | `number` \| `bigint` |
| › `rewards` | `number` \| `bigint` |
| › `round` | `number` \| `bigint` |
| › `sigType?` | `string` |
| › `status` | `string` |
| › `totalAppsOptedIn` | `number` \| `bigint` |
| › `totalAssetsOptedIn` | `number` \| `bigint` |
| › `totalBoxBytes` | `number` \| `bigint` |
| › `totalBoxes` | `number` \| `bigint` |
| › `totalCreatedApps` | `number` \| `bigint` |
| › `totalCreatedAssets` | `number` \| `bigint` |

#### Overrides

BaseModel.constructor

#### Defined in

client/v2/indexer/models/types.ts:248

## Properties

### address

• **address**: `string`

the account public key

#### Defined in

client/v2/indexer/models/types.ts:18

___

### amount

• **amount**: `number` \| `bigint`

total number of MicroAlgos in the account

#### Defined in

client/v2/indexer/models/types.ts:23

___

### amountWithoutPendingRewards

• **amountWithoutPendingRewards**: `number` \| `bigint`

specifies the amount of MicroAlgos in the account, without the pending rewards.

#### Defined in

client/v2/indexer/models/types.ts:28

___

### appsLocalState

• `Optional` **appsLocalState**: [`ApplicationLocalState`](indexerModels.ApplicationLocalState.md)[]

application local data stored in this account.
Note the raw object uses `map[int] -> AppLocalState` for this type.

#### Defined in

client/v2/indexer/models/types.ts:99

___

### appsTotalExtraPages

• `Optional` **appsTotalExtraPages**: `number` \| `bigint`

the sum of all extra application program pages for this account.

#### Defined in

client/v2/indexer/models/types.ts:104

___

### appsTotalSchema

• `Optional` **appsTotalSchema**: [`ApplicationStateSchema`](indexerModels.ApplicationStateSchema.md)

the sum of all of the local schemas and global schemas in this account.
Note: the raw account uses `StateSchema` for this type.

#### Defined in

client/v2/indexer/models/types.ts:110

___

### assets

• `Optional` **assets**: [`AssetHolding`](indexerModels.AssetHolding.md)[]

assets held by this account.
Note the raw object uses `map[int] -> AssetHolding` for this type.

#### Defined in

client/v2/indexer/models/types.ts:116

___

### attribute\_map

• **attribute\_map**: `Record`\<`string`, `string`\>

#### Inherited from

BaseModel.attribute\_map

#### Defined in

client/v2/basemodel.ts:56

___

### authAddr

• `Optional` **authAddr**: `string`

The address against which signing should be checked. If empty, the address of
the current account is used. This field can be updated in any transaction by
setting the RekeyTo field.

#### Defined in

client/v2/indexer/models/types.ts:123

___

### closedAtRound

• `Optional` **closedAtRound**: `number` \| `bigint`

Round during which this account was most recently closed.

#### Defined in

client/v2/indexer/models/types.ts:128

___

### createdApps

• `Optional` **createdApps**: [`Application`](indexerModels.Application.md)[]

parameters of applications created by this account including app global data.
Note: the raw account uses `map[int] -> AppParams` for this type.

#### Defined in

client/v2/indexer/models/types.ts:134

___

### createdAssets

• `Optional` **createdAssets**: [`Asset`](indexerModels.Asset.md)[]

parameters of assets created by this account.
Note: the raw account uses `map[int] -> Asset` for this type.

#### Defined in

client/v2/indexer/models/types.ts:140

___

### createdAtRound

• `Optional` **createdAtRound**: `number` \| `bigint`

Round during which this account first appeared in a transaction.

#### Defined in

client/v2/indexer/models/types.ts:145

___

### deleted

• `Optional` **deleted**: `boolean`

Whether or not this account is currently closed.

#### Defined in

client/v2/indexer/models/types.ts:150

___

### incentiveEligible

• `Optional` **incentiveEligible**: `boolean`

can the account receive block incentives if its balance is in range at proposal
time.

#### Defined in

client/v2/indexer/models/types.ts:156

___

### lastHeartbeat

• `Optional` **lastHeartbeat**: `number` \| `bigint`

The round in which this account last went online, or explicitly renewed their
online status.

#### Defined in

client/v2/indexer/models/types.ts:162

___

### lastProposed

• `Optional` **lastProposed**: `number` \| `bigint`

The round in which this account last proposed the block.

#### Defined in

client/v2/indexer/models/types.ts:167

___

### minBalance

• **minBalance**: `number` \| `bigint`

MicroAlgo balance required by the account.
The requirement grows based on asset and application usage.

#### Defined in

client/v2/indexer/models/types.ts:34

___

### participation

• `Optional` **participation**: [`AccountParticipation`](indexerModels.AccountParticipation.md)

AccountParticipation describes the parameters used by this account in consensus
protocol.

#### Defined in

client/v2/indexer/models/types.ts:173

___

### pendingRewards

• **pendingRewards**: `number` \| `bigint`

amount of MicroAlgos of pending rewards in this account.

#### Defined in

client/v2/indexer/models/types.ts:39

___

### rewardBase

• `Optional` **rewardBase**: `number` \| `bigint`

used as part of the rewards computation. Only applicable to accounts which are
participating.

#### Defined in

client/v2/indexer/models/types.ts:179

___

### rewards

• **rewards**: `number` \| `bigint`

total rewards of MicroAlgos the account has received, including pending rewards.

#### Defined in

client/v2/indexer/models/types.ts:44

___

### round

• **round**: `number` \| `bigint`

The round for which this information is relevant.

#### Defined in

client/v2/indexer/models/types.ts:49

___

### sigType

• `Optional` **sigType**: `string`

the type of signature used by this account, must be one of:
* sig
* msig
* lsig
* or null if unknown

#### Defined in

client/v2/indexer/models/types.ts:188

___

### status

• **status**: `string`

voting status of the account's MicroAlgos
* Offline - indicates that the associated account is delegated.
* Online - indicates that the associated account used as part of the delegation
pool.
* NotParticipating - indicates that the associated account is neither a
delegator nor a delegate.

#### Defined in

client/v2/indexer/models/types.ts:59

___

### totalAppsOptedIn

• **totalAppsOptedIn**: `number` \| `bigint`

The count of all applications that have been opted in, equivalent to the count
of application local data (AppLocalState objects) stored in this account.

#### Defined in

client/v2/indexer/models/types.ts:65

___

### totalAssetsOptedIn

• **totalAssetsOptedIn**: `number` \| `bigint`

The count of all assets that have been opted in, equivalent to the count of
AssetHolding objects held by this account.

#### Defined in

client/v2/indexer/models/types.ts:71

___

### totalBoxBytes

• **totalBoxBytes**: `number` \| `bigint`

For app-accounts only. The total number of bytes allocated for the keys and
values of boxes which belong to the associated application.

#### Defined in

client/v2/indexer/models/types.ts:77

___

### totalBoxes

• **totalBoxes**: `number` \| `bigint`

For app-accounts only. The total number of boxes which belong to the associated
application.

#### Defined in

client/v2/indexer/models/types.ts:83

___

### totalCreatedApps

• **totalCreatedApps**: `number` \| `bigint`

The count of all apps (AppParams objects) created by this account.

#### Defined in

client/v2/indexer/models/types.ts:88

___

### totalCreatedAssets

• **totalCreatedAssets**: `number` \| `bigint`

The count of all assets (AssetParams objects) created by this account.

#### Defined in

client/v2/indexer/models/types.ts:93

## Methods

### get\_obj\_for\_encoding

▸ **get_obj_for_encoding**(`binary?`): `Record`\<`string`, `any`\>

Get an object ready for encoding to either JSON or msgpack.

#### Parameters

| Name | Type | Default value | Description |
| :------ | :------ | :------ | :------ |
| `binary` | `boolean` | `false` | Use true to indicate that the encoding can handle raw binary objects (Uint8Arrays). Use false to indicate that raw binary objects should be converted to base64 strings. True should be used for objects that will be encoded with msgpack, and false should be used for objects that will be encoded with JSON. |

#### Returns

`Record`\<`string`, `any`\>

#### Inherited from

BaseModel.get\_obj\_for\_encoding

#### Defined in

client/v2/basemodel.ts:65

___

### from\_obj\_for\_encoding

▸ `Static` **from_obj_for_encoding**(`data`): [`Account`](indexerModels.Account.md)

#### Parameters

| Name | Type |
| :------ | :------ |
| `data` | `Record`\<`string`, `any`\> |

#### Returns

[`Account`](indexerModels.Account.md)

#### Defined in

client/v2/indexer/models/types.ts:378

```

--------------------------------------------------------------------------------
/packages/server/src/tools/accountManager.ts:
--------------------------------------------------------------------------------

```typescript
import algosdk, { Transaction } from 'algosdk';
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
import { algodClient } from '../algorand-client.js';

// Tool schemas
export const accountToolSchemas = {
  createAccount: {
    type: 'object',
    properties: {},
    required: []
  },
  rekeyAccount: {
    type: 'object',
    properties: {
      sourceAddress: { type: 'string', description: 'Sender address in standard Algorand format (58 characters)' },
      targetAddress: { type: 'string', description: 'Address to rekey the sender account to' }
    },
    required: ['sourceAddress', 'targetAddress']
  },
  mnemonicToMdk: {
    type: 'object',
    properties: {
      mnemonic: { type: 'string', description: 'The mnemonic phrase to convert to a master derivation key' }
    },
    required: ['mnemonic']
  },
  mdkToMnemonic: {
    type: 'object',
    properties: {
      mdk: { type: 'string', description: 'The master derivation key in hexadecimal format' }
    },
    required: ['mdk']
  },
  secretKeyToMnemonic: {
    type: 'object',
    properties: {
      secretKey: { type: 'string', description: 'The secret key in hexadecimal format' }
    },
    required: ['secretKey']
  },
  mnemonicToSecretKey: {
    type: 'object',
    properties: {
      mnemonic: { type: 'string', description: 'The mnemonic phrase to convert to a secret key' }
    },
    required: ['mnemonic']
  },
  seedFromMnemonic: {
    type: 'object',
    properties: {
      mnemonic: { type: 'string', description: 'The mnemonic phrase to generate a seed from' }
    },
    required: ['mnemonic']
  },
  mnemonicFromSeed: {
    type: 'object',
    properties: {
      seed: { type: 'string', description: 'The seed in hexadecimal format to generate a mnemonic from' }
    },
    required: ['seed']
  }
};

export class AccountManager {
  static readonly accountTools = [
    {
      name: 'create_account',
      description: 'Create a new Algorand account',
      inputSchema: accountToolSchemas.createAccount,
    },
    {
      name: 'rekey_account',
      description: 'Rekey an Algorand account to a new address',
      inputSchema: accountToolSchemas.rekeyAccount,
    },
    {
      name: 'mnemonic_to_mdk',
      description: 'Convert a mnemonic to a master derivation key',
      inputSchema: accountToolSchemas.mnemonicToMdk,
    },
    {
      name: 'mdk_to_mnemonic',
      description: 'Convert a master derivation key to a mnemonic',
      inputSchema: accountToolSchemas.mdkToMnemonic,
    },
    {
      name: 'secret_key_to_mnemonic',
      description: 'Convert a secret key to a mnemonic',
      inputSchema: accountToolSchemas.secretKeyToMnemonic,
    },
    {
      name: 'mnemonic_to_secret_key',
      description: 'Convert a mnemonic to a secret key',
      inputSchema: accountToolSchemas.mnemonicToSecretKey,
    },
    {
      name: 'seed_from_mnemonic',
      description: 'Generate a seed from a mnemonic',
      inputSchema: accountToolSchemas.seedFromMnemonic,
    },
    {
      name: 'mnemonic_from_seed',
      description: 'Generate a mnemonic from a seed',
      inputSchema: accountToolSchemas.mnemonicFromSeed,
    }
  ];

  // Tool handlers
  static async handleTool(name: string, args: Record<string, unknown>) {
    try {
      switch (name) {
      case 'create_account':
        return {
          content: [{
            type: 'text',
            text: JSON.stringify(AccountManager.createAccount(), null, 2),
          }],
        };

      case 'rekey_account':
        if (!args.sourceAddress || !args.targetAddress || 
            typeof args.sourceAddress !== 'string' ||
            typeof args.targetAddress !== 'string') {
          throw new McpError(
            ErrorCode.InvalidParams,
            'Invalid rekey account parameters'
          );
        }
        const rekeyTxn = await AccountManager.createRekeyTransaction(
          args.sourceAddress,
          args.targetAddress
        );
        return {
          content: [{
            type: 'text',
            text: JSON.stringify(rekeyTxn, null, 2),
          }],
        };

      case 'mnemonic_to_mdk':
        if (!args.mnemonic || typeof args.mnemonic !== 'string') {
          throw new McpError(ErrorCode.InvalidParams, 'Mnemonic is required');
        }
        const mdk = AccountManager.mnemonicToMasterDerivationKey(args.mnemonic);
        return {
          content: [{
            type: 'text',
            text: JSON.stringify({ mdk: Buffer.from(mdk).toString('hex') }, null, 2),
          }],
        };

      case 'mdk_to_mnemonic':
        if (!args.mdk || typeof args.mdk !== 'string') {
          throw new McpError(ErrorCode.InvalidParams, 'Master derivation key is required');
        }
        const mdkMnemonic = AccountManager.masterDerivationKeyToMnemonic(Buffer.from(args.mdk, 'hex'));
        return {
          content: [{
            type: 'text',
            text: JSON.stringify({ mnemonic: mdkMnemonic }, null, 2),
          }],
        };

      case 'secret_key_to_mnemonic':
        if (!args.secretKey || typeof args.secretKey !== 'string') {
          throw new McpError(ErrorCode.InvalidParams, 'Secret key is required');
        }
        const skMnemonic = AccountManager.secretKeyToMnemonic(Buffer.from(args.secretKey, 'hex'));
        return {
          content: [{
            type: 'text',
            text: JSON.stringify({ mnemonic: skMnemonic }, null, 2),
          }],
        };

      case 'mnemonic_to_secret_key':
        if (!args.mnemonic || typeof args.mnemonic !== 'string') {
          throw new McpError(ErrorCode.InvalidParams, 'Mnemonic is required');
        }
        const sk = AccountManager.mnemonicToSecretKey(args.mnemonic);
        return {
          content: [{
            type: 'text',
            text: JSON.stringify({
              secretKey: Buffer.from(sk.sk).toString('hex'),
              address: sk.addr
            }, null, 2),
          }],
        };

      case 'seed_from_mnemonic':
        if (!args.mnemonic || typeof args.mnemonic !== 'string') {
          throw new McpError(ErrorCode.InvalidParams, 'Mnemonic is required');
        }
        const seed = AccountManager.seedFromMnemonic(args.mnemonic);
        return {
          content: [{
            type: 'text',
            text: JSON.stringify({ seed: Buffer.from(seed).toString('hex') }, null, 2),
          }],
        };

      case 'mnemonic_from_seed':
        if (!args.seed || typeof args.seed !== 'string') {
          throw new McpError(ErrorCode.InvalidParams, 'Seed is required');
        }
        const seedMnemonic = AccountManager.mnemonicFromSeed(Buffer.from(args.seed, 'hex'));
        return {
          content: [{
            type: 'text',
            text: JSON.stringify({ mnemonic: seedMnemonic }, null, 2),
          }],
        };

      default:
        console.error(`[MCP Error] Unknown tool requested: ${name}`);
        throw new McpError(
          ErrorCode.MethodNotFound,
          `Unknown tool: ${name}`
        );
    }
    } catch (error) {
      if (error instanceof McpError) {
        console.error(`[MCP Error] ${error.code}: ${error.message}`);
        throw error;
      }
      console.error('[MCP Error] Unexpected error:', error);
      throw new McpError(
        ErrorCode.InternalError,
        `Operation failed: ${error instanceof Error ? error.message : 'Unknown error'}`
      );
    }
  }

  /**
   * Creates a new account
   * @returns Object containing the address and mnemonic
   */
  static createAccount(): { address: string; mnemonic: string } {
    try {
      const account = algosdk.generateAccount();
      const mnemonic = algosdk.secretKeyToMnemonic(account.sk);
      return {
        address: account.addr,
        mnemonic,
      };
    } catch (error) {
      console.error('[MCP Error] Failed to create account:', error);
      throw new McpError(
        ErrorCode.InternalError,
        `Failed to create account: ${error instanceof Error ? error.message : 'Unknown error'}`
      );
    }
  }

  /**
   * Rekeys an account to a new address
   * @param fromAddress The address to rekey from
   * @param toAddress The address to rekey to
   * @returns The rekey transaction object
   */
  static async createRekeyTransaction(fromAddress: string, toAddress: string): Promise<algosdk.Transaction> {
    try {
      const params = await algodClient.getTransactionParams().do();
      const suggestedParams = { ...params, flatFee: true, fee: params.minFee };

      return algosdk.makePaymentTxnWithSuggestedParamsFromObject({
        from: fromAddress,
        to: fromAddress,
        amount: 0,
        rekeyTo: toAddress,
        suggestedParams,
      });
    } catch (error) {
      console.error('[MCP Error] Failed to create rekey transaction:', error);
      throw new McpError(
        ErrorCode.InternalError,
        `Failed to create rekey transaction: ${error instanceof Error ? error.message : 'Unknown error'}`
      );
    }
  }

  /**
   * Converts a mnemonic to a master derivation key
   * @param mnemonic The mnemonic to convert
   * @returns The master derivation key
   */
  static mnemonicToMasterDerivationKey(mnemonic: string): Uint8Array {
    try {
      return algosdk.mnemonicToMasterDerivationKey(mnemonic);
    } catch (error) {
      console.error('[MCP Error] Failed to convert mnemonic to MDK:', error);
      throw new McpError(
        ErrorCode.InvalidParams,
        `Invalid mnemonic provided: ${error instanceof Error ? error.message : 'Unknown error'}`
      );
    }
  }

  /**
   * Converts a master derivation key to a mnemonic
   * @param mdk The master derivation key to convert
   * @returns The mnemonic
   */
  static masterDerivationKeyToMnemonic(mdk: Uint8Array): string {
    try {
      return algosdk.masterDerivationKeyToMnemonic(mdk);
    } catch (error) {
      console.error('[MCP Error] Failed to convert MDK to mnemonic:', error);
      throw new McpError(
        ErrorCode.InvalidParams,
        `Invalid master derivation key provided: ${error instanceof Error ? error.message : 'Unknown error'}`
      );
    }
  }

  /**
   * Converts a secret key to a mnemonic
   * @param secretKey The secret key to convert
   * @returns The mnemonic
   */
  static secretKeyToMnemonic(secretKey: Uint8Array): string {
    try {
      return algosdk.secretKeyToMnemonic(secretKey);
    } catch (error) {
      console.error('[MCP Error] Failed to convert secret key to mnemonic:', error);
      throw new McpError(
        ErrorCode.InvalidParams,
        `Invalid secret key provided: ${error instanceof Error ? error.message : 'Unknown error'}`
      );
    }
  }

  /**
   * Converts a mnemonic to a secret key
   * @param mnemonic The mnemonic to convert
   * @returns The secret key
   */
  static mnemonicToSecretKey(mnemonic: string): { sk: Uint8Array; addr: string } {
    try {
      return algosdk.mnemonicToSecretKey(mnemonic);
    } catch (error) {
      console.error('[MCP Error] Failed to convert mnemonic to secret key:', error);
      throw new McpError(
        ErrorCode.InvalidParams,
        `Invalid mnemonic provided: ${error instanceof Error ? error.message : 'Unknown error'}`
      );
    }
  }

  /**
   * Generates a seed from a mnemonic
   * @param mnemonic The mnemonic to generate the seed from
   * @returns The seed
   */
  static seedFromMnemonic(mnemonic: string): Uint8Array {
    try {
      return algosdk.seedFromMnemonic(mnemonic);
    } catch (error) {
      console.error('[MCP Error] Failed to generate seed from mnemonic:', error);
      throw new McpError(
        ErrorCode.InvalidParams,
        `Invalid mnemonic provided: ${error instanceof Error ? error.message : 'Unknown error'}`
      );
    }
  }

  /**
   * Generates a mnemonic from a seed
   * @param seed The seed to generate the mnemonic from
   * @returns The mnemonic
   */
  static mnemonicFromSeed(seed: Uint8Array): string {
    try {
      return algosdk.mnemonicFromSeed(seed);
    } catch (error) {
      console.error('[MCP Error] Failed to generate mnemonic from seed:', error);
      throw new McpError(
        ErrorCode.InvalidParams,
        `Invalid seed provided: ${error instanceof Error ? error.message : 'Unknown error'}`
      );
    }
  }
}

```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/SDKs:javascript:interfaces:TransactionParams.md:
--------------------------------------------------------------------------------

```markdown
[algosdk](../README.md) / [Exports](../modules.md) / TransactionParams

# Interface: TransactionParams

A full list of all available transaction parameters

The full documentation is available at:
https://developer.algorand.org/docs/reference/transactions/#common-fields-header-and-type

## Table of contents

### Properties

- [amount](TransactionParams.md#amount)
- [appAccounts](TransactionParams.md#appaccounts)
- [appApprovalProgram](TransactionParams.md#appapprovalprogram)
- [appArgs](TransactionParams.md#appargs)
- [appClearProgram](TransactionParams.md#appclearprogram)
- [appForeignApps](TransactionParams.md#appforeignapps)
- [appForeignAssets](TransactionParams.md#appforeignassets)
- [appGlobalByteSlices](TransactionParams.md#appglobalbyteslices)
- [appGlobalInts](TransactionParams.md#appglobalints)
- [appIndex](TransactionParams.md#appindex)
- [appLocalByteSlices](TransactionParams.md#applocalbyteslices)
- [appLocalInts](TransactionParams.md#applocalints)
- [appOnComplete](TransactionParams.md#apponcomplete)
- [assetClawback](TransactionParams.md#assetclawback)
- [assetDecimals](TransactionParams.md#assetdecimals)
- [assetDefaultFrozen](TransactionParams.md#assetdefaultfrozen)
- [assetFreeze](TransactionParams.md#assetfreeze)
- [assetIndex](TransactionParams.md#assetindex)
- [assetManager](TransactionParams.md#assetmanager)
- [assetMetadataHash](TransactionParams.md#assetmetadatahash)
- [assetName](TransactionParams.md#assetname)
- [assetReserve](TransactionParams.md#assetreserve)
- [assetRevocationTarget](TransactionParams.md#assetrevocationtarget)
- [assetTotal](TransactionParams.md#assettotal)
- [assetURL](TransactionParams.md#asseturl)
- [assetUnitName](TransactionParams.md#assetunitname)
- [boxes](TransactionParams.md#boxes)
- [closeRemainderTo](TransactionParams.md#closeremainderto)
- [extraPages](TransactionParams.md#extrapages)
- [fee](TransactionParams.md#fee)
- [firstRound](TransactionParams.md#firstround)
- [flatFee](TransactionParams.md#flatfee)
- [freezeAccount](TransactionParams.md#freezeaccount)
- [freezeState](TransactionParams.md#freezestate)
- [from](TransactionParams.md#from)
- [genesisHash](TransactionParams.md#genesishash)
- [genesisID](TransactionParams.md#genesisid)
- [lastRound](TransactionParams.md#lastround)
- [lease](TransactionParams.md#lease)
- [nonParticipation](TransactionParams.md#nonparticipation)
- [note](TransactionParams.md#note)
- [reKeyTo](TransactionParams.md#rekeyto)
- [selectionKey](TransactionParams.md#selectionkey)
- [stateProof](TransactionParams.md#stateproof)
- [stateProofKey](TransactionParams.md#stateproofkey)
- [stateProofMessage](TransactionParams.md#stateproofmessage)
- [stateProofType](TransactionParams.md#stateprooftype)
- [suggestedParams](TransactionParams.md#suggestedparams)
- [to](TransactionParams.md#to)
- [type](TransactionParams.md#type)
- [voteFirst](TransactionParams.md#votefirst)
- [voteKey](TransactionParams.md#votekey)
- [voteKeyDilution](TransactionParams.md#votekeydilution)
- [voteLast](TransactionParams.md#votelast)

## Properties

### amount

• **amount**: `number` \| `bigint`

Integer amount to send

#### Defined in

types/transactions/base.ts:180

___

### appAccounts

• `Optional` **appAccounts**: `string`[]

Array of Address strings, any additional accounts to supply to the application

#### Defined in

types/transactions/base.ts:370

___

### appApprovalProgram

• **appApprovalProgram**: `Uint8Array`

The compiled TEAL that approves a transaction

#### Defined in

types/transactions/base.ts:355

___

### appArgs

• `Optional` **appArgs**: `Uint8Array`[]

Array of Uint8Array, any additional arguments to the application

#### Defined in

types/transactions/base.ts:365

___

### appClearProgram

• **appClearProgram**: `Uint8Array`

The compiled TEAL program that runs when clearing state

#### Defined in

types/transactions/base.ts:360

___

### appForeignApps

• `Optional` **appForeignApps**: `number`[]

Array of int, any other apps used by the application, identified by index

#### Defined in

types/transactions/base.ts:375

___

### appForeignAssets

• `Optional` **appForeignAssets**: `number`[]

Array of int, any assets used by the application, identified by index

#### Defined in

types/transactions/base.ts:380

___

### appGlobalByteSlices

• **appGlobalByteSlices**: `number`

Restricts number of byte slices in global state

#### Defined in

types/transactions/base.ts:350

___

### appGlobalInts

• **appGlobalInts**: `number`

Restricts number of ints in global state

#### Defined in

types/transactions/base.ts:345

___

### appIndex

• **appIndex**: `number`

A unique application index

#### Defined in

types/transactions/base.ts:325

___

### appLocalByteSlices

• **appLocalByteSlices**: `number`

Restricts number of byte slices in per-user local state

#### Defined in

types/transactions/base.ts:340

___

### appLocalInts

• **appLocalInts**: `number`

Restricts number of ints in per-user local state

#### Defined in

types/transactions/base.ts:335

___

### appOnComplete

• **appOnComplete**: [`OnApplicationComplete`](../enums/OnApplicationComplete.md)

What application should do once the program has been run

#### Defined in

types/transactions/base.ts:330

___

### assetClawback

• `Optional` **assetClawback**: `string`

String representation of Algorand address with power to revoke asset holdings

#### Defined in

types/transactions/base.ts:285

___

### assetDecimals

• **assetDecimals**: `number`

Integer number of decimals for asset unit calcuation

#### Defined in

types/transactions/base.ts:260

___

### assetDefaultFrozen

• **assetDefaultFrozen**: `boolean`

Whether asset accounts should default to being frozen

#### Defined in

types/transactions/base.ts:265

___

### assetFreeze

• `Optional` **assetFreeze**: `string`

String representation of Algorand address with power to freeze/unfreeze asset holdings

#### Defined in

types/transactions/base.ts:280

___

### assetIndex

• **assetIndex**: `number`

Asset index uniquely specifying the asset

#### Defined in

types/transactions/base.ts:250

___

### assetManager

• `Optional` **assetManager**: `string`

String representation of Algorand address in charge of reserve, freeze, clawback, destruction, etc.

#### Defined in

types/transactions/base.ts:270

___

### assetMetadataHash

• `Optional` **assetMetadataHash**: `string` \| `Uint8Array`

Uint8Array or UTF-8 string representation of a hash commitment with respect to the asset. Must be exactly 32 bytes long.

#### Defined in

types/transactions/base.ts:304

___

### assetName

• `Optional` **assetName**: `string`

Name for this asset

#### Defined in

types/transactions/base.ts:294

___

### assetReserve

• `Optional` **assetReserve**: `string`

String representation of Algorand address representing asset reserve

#### Defined in

types/transactions/base.ts:275

___

### assetRevocationTarget

• `Optional` **assetRevocationTarget**: `string`

String representation of Algorand address – if provided, and if "from" is
the asset's revocation manager, then deduct from "revocationTarget" rather than "from"

#### Defined in

types/transactions/base.ts:320

___

### assetTotal

• **assetTotal**: `number` \| `bigint`

Total supply of the asset

#### Defined in

types/transactions/base.ts:255

___

### assetURL

• `Optional` **assetURL**: `string`

URL relating to this asset

#### Defined in

types/transactions/base.ts:299

___

### assetUnitName

• `Optional` **assetUnitName**: `string`

Unit name for this asset

#### Defined in

types/transactions/base.ts:290

___

### boxes

• `Optional` **boxes**: [`BoxReference`](BoxReference.md)[]

A grouping of the app ID and name of the box in an Uint8Array

#### Defined in

types/transactions/base.ts:419

___

### closeRemainderTo

• `Optional` **closeRemainderTo**: `string`

Close out remaining account balance to this account

#### Defined in

types/transactions/base.ts:215

___

### extraPages

• `Optional` **extraPages**: `number`

Int representing extra pages of memory to rent during an application create transaction.

#### Defined in

types/transactions/base.ts:414

___

### fee

• **fee**: `number`

Integer fee per byte, in microAlgos. For a flat fee, set flatFee to true

#### Defined in

types/transactions/base.ts:175

___

### firstRound

• **firstRound**: `number`

Integer first protocol round on which this txn is valid

#### Defined in

types/transactions/base.ts:185

___

### flatFee

• `Optional` **flatFee**: `boolean`

Set this to true to specify fee as microalgos-per-txn.

If the final calculated fee is lower than the protocol minimum fee, the fee will be increased to match the minimum

#### Defined in

types/transactions/base.ts:392

___

### freezeAccount

• **freezeAccount**: `string`

String representation of Algorand address being frozen or unfrozen

#### Defined in

types/transactions/base.ts:309

___

### freezeState

• **freezeState**: `boolean`

true if freezeTarget should be frozen, false if freezeTarget should be allowed to transact

#### Defined in

types/transactions/base.ts:314

___

### from

• **from**: `string`

String representation of Algorand address of sender

#### Defined in

types/transactions/base.ts:165

___

### genesisHash

• **genesisHash**: `string`

Specifies hash genesis block of network in use

#### Defined in

types/transactions/base.ts:205

___

### genesisID

• **genesisID**: `string`

Specifies genesis ID of network in use

#### Defined in

types/transactions/base.ts:200

___

### lastRound

• **lastRound**: `number`

Integer last protocol round on which this txn is valid

#### Defined in

types/transactions/base.ts:190

___

### lease

• `Optional` **lease**: `Uint8Array`

Lease a transaction. The sender cannot send another txn with that same lease until the last round of original txn has passed

#### Defined in

types/transactions/base.ts:210

___

### nonParticipation

• `Optional` **nonParticipation**: `boolean`

Set this value to true to mark this account as nonparticipating.

All new Algorand accounts are participating by default. This means they earn rewards.

#### Defined in

types/transactions/base.ts:409

___

### note

• `Optional` **note**: `Uint8Array`

Arbitrary data for sender to store

#### Defined in

types/transactions/base.ts:195

___

### reKeyTo

• `Optional` **reKeyTo**: `string`

String representation of the Algorand address that will be used to authorize all future transactions

#### Defined in

types/transactions/base.ts:402

___

### selectionKey

• **selectionKey**: `string` \| `Uint8Array`

Selection key bytes. For key deregistration, leave undefined

#### Defined in

types/transactions/base.ts:225

___

### stateProof

• `Optional` **stateProof**: `Uint8Array`

Byte array containing the state proof.

#### Defined in

types/transactions/base.ts:429

___

### stateProofKey

• **stateProofKey**: `string` \| `Uint8Array`

State proof key bytes. For key deregistration, leave undefined

#### Defined in

types/transactions/base.ts:230

___

### stateProofMessage

• `Optional` **stateProofMessage**: `Uint8Array`

Byte array containing the state proof message.

#### Defined in

types/transactions/base.ts:434

___

### stateProofType

• `Optional` **stateProofType**: `number` \| `bigint`

#### Defined in

types/transactions/base.ts:424

___

### suggestedParams

• **suggestedParams**: [`SuggestedParams`](SuggestedParams.md)

A dict holding common-to-all-txns arguments

#### Defined in

types/transactions/base.ts:397

___

### to

• **to**: `string`

String representation of Algorand address of recipient

#### Defined in

types/transactions/base.ts:170

___

### type

• `Optional` **type**: [`TransactionType`](../enums/TransactionType.md)

Transaction type

#### Defined in

types/transactions/base.ts:385

___

### voteFirst

• **voteFirst**: `number`

First round on which voteKey is valid

#### Defined in

types/transactions/base.ts:235

___

### voteKey

• **voteKey**: `string` \| `Uint8Array`

Voting key bytes. For key deregistration, leave undefined

#### Defined in

types/transactions/base.ts:220

___

### voteKeyDilution

• **voteKeyDilution**: `number`

The dilution fo the 2-level participation key

#### Defined in

types/transactions/base.ts:245

___

### voteLast

• **voteLast**: `number`

Last round on which voteKey is valid

#### Defined in

types/transactions/base.ts:240

```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/puya:typescript:docs:architecture-decisions:2024-05-21_primitive-integer-types.md:
--------------------------------------------------------------------------------

```markdown
# Architecture Decision Record - Primitive integer types

- **Status**: Draft
- **Owner:** Tristan Menzel
- **Deciders**: Alessandro Cappellato (Algorand Foundation), Joe Polny (Algorand Foundation), Rob Moore (MakerX)
- **Date created**: 2024-05-21
- **Date decided**: N/A
- **Date updated**: 2024-05-31

## Context

The AVM supports two integer types in its standard set of ops.

* **uint64**: An unsigned 64-bit integer where the AVM will error on over or under flows
* **biguint**: An unsigned variable bit, big-endian integer represented as an array of bytes with an indeterminate number of leading zeros which are truncated by several math ops. The max size of a biguint is 512-bits. Over and under flows will cause errors.

EcmaScript supports two numeric types.

* **number**: A floating point signed value with 64 bits of precision capable of a max safe integer value of 2^53 - 1. A number can be declared with a numeric literal, or with the `Number(...)` factory method.
* **bigint**: A signed arbitrary-precision integer with an implementation defined limit based on the platform. In practice this is greater than 512-bit. A bigint can be declared with a numeric literal and `n` suffix, or with the `BigInt(...)` factory method.

EcmaScript and TypeScript both do not support operator overloading, despite some [previous](https://github.com/tc39/notes/blob/main/meetings/2023-11/november-28.md#withdrawing-operator-overloading) [attempts](https://github.com/microsoft/TypeScript/issues/2319) to do so.

TealScript [makes use of branded `number` types](https://tealscript.netlify.app/guides/supported-types/numbers/) for all bit sizes from 8 => 512, although it doesn't allow `number` variables, you must specify the actual type you want (e.g. `uint64`). Since the source code is never executed, the safe limits of the `number` type are not a concern. Compiled code does not perform overflow checks on calculations until a return value is being encoded meaning a uint<8> is effectively a uint<64> until it's returned.

Algorand Python has specific [UInt64 and BigUint types](https://algorandfoundation.github.io/puya/lg-types.html#avm-types) that have semantics that exactly match the AVM semantics. Python allows for operator overloading so these types also use native operators (where they align to functionality in the underlying AVM).


## Requirements

- Support uint64 and biguint AVM types
- Use idiomatic TypeScript expressions for numeric expressions, including mathematical operators (`+`, `-`, `*`, `/`, etc.)
- Semantic compatibility between AVM execution and TypeScript execution (e.g. in unit tests)

## Principles

- **[AlgoKit Guiding Principles](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/algokit.md#guiding-principles)** - specifically Seamless onramp, Leverage existing ecosystem, Meet devs where they are
- **[Algorand Python Principles](https://algorandfoundation.github.io/puya/principles.html#principles)**
- **[Algorand TypeScript Guiding Principles](../README.md#guiding-principals)**

## Options

### Option 1 - Native types

EcmaScript's `number` type is ill-suited to representing either AVM type reliably as it does not have the safe range to cover the full range of a uint64. Being a floating point number, it would also require truncating after division.

EcmaScript's `bigint` is a better fit for both types but does not underflow when presented with a negative number, nor does it overflow at any meaningful limit for the AVM types.

If we solved the over/under flow checking with a custom TypeScript transformer we still face an issue that `uint64` and `biguint` would not have discrete types for the compiler to know the difference between them and also we would have no type safety against accidentally passing a `biguint` to a method that expects a `uint64` and vice versa.

### Option 2 - Wrapper classes

A `UInt64` and `BigUint` class could be defined which make use of `bigint` internally to perform maths operations and check for over or under flows after each op.

```ts
class UInt64 {

  private value: bigint

  constructor(value: bigint | number) {
    this.value = this.checkBounds(value)
  }

  add(other: UInt64): UInt64 {
    return new UInt64(this.value + other.value)
  }

  /* etc */
}

```

This solution provides the ultimate in type safety and semantic/syntactic compatibility, and requires no custom TypeScript transformer to run _correctly_ on Node.js. The semantics should be obvious to anyone familiar with Object Oriented Programming. The downside is that neither EcmaScript nor TypeScript support operator overloading which results in more verbose and unwieldy math expressions. The lack of idiomatic TypeScript mathematical operators is a deal breaker that rules this option out.

```ts
const a = UInt64(500n)
const b = Uint64(256)

// Not supported (a compile error in TS)
const c1 = a + b
// Works, but is verbose and unwieldy for more complicated expressions and isn't idiomatic TypeScript
const c2 = a.add(b)

```

### Option 3 - Branded `bigint`

TypeScript allows you to intersect primitive types with a simple interface to brand a value in a way which is incompatible with another primitive branded with a different value within the type system. In this option the base type that is branded is `bigint`, which aligns to th discussion in Option 1 about the logical type to represent `uint64` and `biguint`.

```ts
// Constructors
declare function UInt64(v): uint64
declare function BigUint(v): uint64

// Branded types
type uint64 = bigint & { __type?: 'uint64' }
type biguint = bigint & { __type?: 'biguint' }


const a: uint64 = 323n // Declare with type annotation and raw `bigint` literal
const b = UInt64(12n) // Declare with factory
const b2 = UInt64(12) // Factory could also take `number` literals (compiler could check they aren't negative and are integers)

// c1 type is `bigint`, but we can mandate a type hint with the compiler (c2)
const c1 = a + b
const c2: uint64 = a + b

// No TypeScript type error, but semantically ambiguous - is a+b performed as a biguint op or a uint64 one and then converted?
// (We could detect this as a compiler error though)
const c3: biguint = a + b

// Type error on b: Argument of type 'uint64' is not assignable to parameter of type 'biguint'. Nice!
test(a, b)
function test(x: uint64, y: biguint) {
  // ...
}

```

This solution looks like normal TypeScript and results in math expressions that are much easier to read. The factory methods (e.g. `UInt64(4n)`) mimics native equivalents and should be familiar to existing developers.

The drawbacks of this solution are:
 - Less implicit type safety for branded types as TypeScript will infer the type of any binary math expression to be the base numeric type (a type annotation will be required where ever an identifier is declared, and the compiler will need to enforce this)
 - In order to have TypeScript execution semantics of a `uint64` or `biguint` match the AVM, a custom TypeScript transformer will be required to wrap numeric operations in logic that checks for over and under flows line-by-line; this is straightforward to write though and has been successfully spiked out
 - Additional type checking will be required by the compiler to catch instances of assigning one numeric type to the other (accidental implicit assignment) e.g. assigning a `uint64` value to `biguint`.
 - Literals will require an `n` suffix
 - `bigint` cannot be used to index an object/array (only `number | string | symbol`)


### Option 4 Explicitly tagged brand types

A variation of option 3 with non-optional `__type` tags would prevent accidental implicit assignment errors when assigning between (say) `uint64` and `biguint`, but require explicit casting on all ops and any methods that return the base type.

```ts
declare function Uint64(v): uint64
declare function BigUint(v): uint64

type uint64 = bigint & { __type: 'uint64' }
type biguint = bigint & { __type: 'biguint' }

// Require factory or cast on declaration
const a: uint64 = 323n as uint64
const b = Uint64(12n)

// Also require factory or cast on math
let c2: uint64

c2 = a + b // error
c2 = Uint64(a + b) // ok
c2 = (a + b) as uint64 // ok
```

This introduces a degree of type safety with the in-built TypeScript type system at the significant expense of legibility and writability.


### Option 5 Branded `number` (TEALScript approach)

TEALScript uses a similar approach to option 3, but uses `number` as the underlying type rather than `bigint`. This has the advantage of being directly compatible with casting raw numbers (e.g. `const x: uint64 = 3` rather than `const x: uint64 = 3n`).

Furthermore, any JavaScript prototype methods that return `number` like `array.length` will be similarly able to be directly used and casted to `uint64` rather than wrapping in a factory method (e.g. `const x: uint64 = [1, 2, 3].length` rather than `const x = UInt64([1, 2, 3].length)`). It's not currently clear if any such methods will be exposed within the stub types that emerge in Algorand TypeScript though; if option 1 isn't chosen then ideally we would want to avoid exposing `number` within Algorand TypeScript altogether. Key prototypes that have `number` include `string` (see [Primitive bytes and strings](./2024-05-21_primitive-bytes-and-strings.md)) and array (but TypeScript allows you to define wrapper classes that support [iteration](https://www.typescriptlang.org/docs/handbook/iterators-and-generators.html) [and](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) [spreading](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable) so we can likely avoid `Array<T>` prototype).

If `number` is used as the base brand type for `uint64` and `bigint` is used as the base brand type for `biguint` (a type that TEALScript doesn't implement, so not a breaking change) then accidental implicit assignment errors are prevented by the TypeScript type system.

A key issue with using `number` as the base type is that per option 1, it's semantically a floating point number, not an integer. It is possible for the compiler to check for and disallow non-integer constant literals though, which would prevent a non-integer value appearing outside of division. A custom TypeScript transformer will need to wrap division operations to allow the result to be truncated as an integer; this is a violation of the semantic compatibility principle, but given a branded type would be used rather than `number` (the fact the base type is `number` is largely hidden from the developer) it probably doesn't violate the principle of least surprise and may be considered an acceptable compromise.

The other problem with use of `number` as the base brand type is that you will lose precision and get linting errors when representing a number greater than 53-bits as a constant literal e.g. `const x: uint64 = 9007199254740992`. It *may* be possible for a custom TypeScript transformer to get the value before precision is lost (needs investigation) and then disable that particular linting tool, but that is a fairly clear violation of semantic compatibility. The workaround would have to be that the compiler detects numbers > `Number.MAX_SAFE_INTEGER` and complains and instead you would have to use the factory syntax with a `bigint` constant literal e.g. `const x = UInt64(9007199254740992n)`.


## Preferred option

Either option 3 or option 5 depending on comfort level in using a floating point number type as the base type for `uint64`, requiring extra compiler checks & more complex custom transformers to overcome this, and not being able to cleanly represent very large integers as a constant literal vs lack of TypeScript protection against accidental implicit assignment of `uint64` and `biguint` (but can be checked by the compiler), and needing to avoid prototype methods that return `number` (although this matches semantic compatibility so may be a good idea anyway).

Option 3 is also a breaking change for TEALScript, which would require `number` literals to either be suffixed with the `bigint` suffix (`n`) or be wrapped in a `UInt64()` factory call.

Option 1 and 2 are excluded because they don't meet the requirements of semantic compatibility and least surprise. Option 4 is excluded, because the resulting syntax is unpractical.

## Selected option

Option 5 has been selected as the best option
```

--------------------------------------------------------------------------------
/packages/server/tests/resources/algod/transaction.test.ts:
--------------------------------------------------------------------------------

```typescript
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
import { 
  transactionResources,
  transactionResourceSchemas,
  pendingTransactionInformation,
  pendingTransactionsByAddress,
  pendingTransactions,
  getTransactionParams,
  status,
  statusAfterBlock,
  handleTransactionResources
} from '../../../src/resources/algod/transaction.js';
import { algodClient } from '../../../src/algorand-client.js';

// Mock algosdk client
jest.mock('../../../src/algorand-client.js', () => ({
  algodClient: {
    pendingTransactionInformation: jest.fn(),
    pendingTransactionByAddress: jest.fn(),
    pendingTransactionsInformation: jest.fn(),
    getTransactionParams: jest.fn(),
    status: jest.fn(),
    statusAfterBlock: jest.fn()
  },
  API_URIS: {
    PENDING_TRANSACTION: 'algorand://transaction/{txid}/pending',
    PENDING_TRANSACTIONS_BY_ADDRESS: 'algorand://account/{address}/transactions/pending',
    PENDING_TRANSACTIONS: 'algorand://transactions/pending',
    TRANSACTION_PARAMS: 'algorand://transaction/params',
    NODE_STATUS: 'algorand://node/status',
    NODE_STATUS_AFTER_BLOCK: 'algorand://node/status/after/{round}'
  }
}));

describe('Algod Transaction Resources', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  describe('Resource Definitions', () => {
    it('should define transaction resources', () => {
      expect(transactionResources).toHaveLength(6);
      expect(transactionResources.map(r => r.name)).toEqual([
        'Pending Transaction',
        'Pending Transactions By Address',
        'All Pending Transactions',
        'Transaction Parameters',
        'Node Status',
        'Node Status After Block'
      ]);
    });

    it('should define resource schemas', () => {
      expect(Object.keys(transactionResourceSchemas)).toHaveLength(6);
      expect(transactionResourceSchemas).toHaveProperty('algorand://transaction/{txid}/pending');
      expect(transactionResourceSchemas).toHaveProperty('algorand://account/{address}/transactions/pending');
      expect(transactionResourceSchemas).toHaveProperty('algorand://transactions/pending');
      expect(transactionResourceSchemas).toHaveProperty('algorand://transaction/params');
      expect(transactionResourceSchemas).toHaveProperty('algorand://node/status');
      expect(transactionResourceSchemas).toHaveProperty('algorand://node/status/after/{round}');
    });
  });

  describe('Pending Transaction Information', () => {
    const mockTxId = 'MOCK_TX_ID';
    const mockResponse = {
      poolError: '',
      txn: { type: 'pay' },
      confirmedRound: 1234
    };

    beforeEach(() => {
      (algodClient.pendingTransactionInformation as jest.Mock).mockReturnValue({
        do: jest.fn().mockResolvedValue(mockResponse)
      });
    });

    it('should fetch pending transaction information', async () => {
      const result = await pendingTransactionInformation(mockTxId);
      expect(result).toEqual(mockResponse);
      expect(algodClient.pendingTransactionInformation).toHaveBeenCalledWith(mockTxId);
    });

    it('should handle errors', async () => {
      const error = new Error('Network error');
      (algodClient.pendingTransactionInformation as jest.Mock).mockReturnValue({
        do: jest.fn().mockRejectedValue(error)
      });

      await expect(pendingTransactionInformation(mockTxId))
        .rejects
        .toThrow('Failed to get pending transaction: Network error');
    });
  });

  describe('Pending Transactions By Address', () => {
    const mockAddress = 'MOCK_ADDRESS';
    const mockResponse = {
      topTransactions: [{ txn: { type: 'pay' } }],
      totalTransactions: 1
    };

    beforeEach(() => {
      (algodClient.pendingTransactionByAddress as jest.Mock).mockReturnValue({
        do: jest.fn().mockResolvedValue(mockResponse)
      });
    });

    it('should fetch pending transactions by address', async () => {
      const result = await pendingTransactionsByAddress(mockAddress);
      expect(result).toEqual(mockResponse);
      expect(algodClient.pendingTransactionByAddress).toHaveBeenCalledWith(mockAddress);
    });

    it('should handle errors', async () => {
      const error = new Error('Network error');
      (algodClient.pendingTransactionByAddress as jest.Mock).mockReturnValue({
        do: jest.fn().mockRejectedValue(error)
      });

      await expect(pendingTransactionsByAddress(mockAddress))
        .rejects
        .toThrow('Failed to get pending transactions by address: Network error');
    });
  });

  describe('All Pending Transactions', () => {
    const mockResponse = {
      topTransactions: [{ txn: { type: 'pay' } }],
      totalTransactions: 1
    };

    beforeEach(() => {
      (algodClient.pendingTransactionsInformation as jest.Mock).mockReturnValue({
        max: jest.fn().mockReturnThis(),
        do: jest.fn().mockResolvedValue(mockResponse)
      });
    });

    it('should fetch all pending transactions', async () => {
      const result = await pendingTransactions();
      expect(result).toEqual(mockResponse);
      expect(algodClient.pendingTransactionsInformation).toHaveBeenCalled();
    });

    it('should handle max transactions parameter', async () => {
      const maxTxns = 10;
      await pendingTransactions(maxTxns);
      const mockMax = (algodClient.pendingTransactionsInformation as jest.Mock).mock.results[0].value.max;
      expect(mockMax).toHaveBeenCalledWith(maxTxns);
    });

    it('should handle errors', async () => {
      const error = new Error('Network error');
      (algodClient.pendingTransactionsInformation as jest.Mock).mockReturnValue({
        max: jest.fn().mockReturnThis(),
        do: jest.fn().mockRejectedValue(error)
      });

      await expect(pendingTransactions())
        .rejects
        .toThrow('Failed to get pending transactions: Network error');
    });
  });

  describe('Transaction Parameters', () => {
    const mockResponse = {
      fee: 1000,
      firstRound: 1234,
      lastRound: 1235,
      genesisHash: 'hash',
      genesisID: 'testnet-v1.0'
    };

    beforeEach(() => {
      (algodClient.getTransactionParams as jest.Mock).mockReturnValue({
        do: jest.fn().mockResolvedValue(mockResponse)
      });
    });

    it('should fetch transaction parameters', async () => {
      const result = await getTransactionParams();
      expect(result).toEqual(mockResponse);
      expect(algodClient.getTransactionParams).toHaveBeenCalled();
    });

    it('should handle errors', async () => {
      const error = new Error('Network error');
      (algodClient.getTransactionParams as jest.Mock).mockReturnValue({
        do: jest.fn().mockRejectedValue(error)
      });

      await expect(getTransactionParams())
        .rejects
        .toThrow('Failed to get transaction params: Network error');
    });
  });

  describe('Node Status', () => {
    const mockResponse = {
      lastRound: 1234,
      catchupTime: 0,
      hasSyncedSinceStartup: true
    };

    beforeEach(() => {
      (algodClient.status as jest.Mock).mockReturnValue({
        do: jest.fn().mockResolvedValue(mockResponse)
      });
    });

    it('should fetch node status', async () => {
      const result = await status();
      expect(result).toEqual(mockResponse);
      expect(algodClient.status).toHaveBeenCalled();
    });

    it('should handle errors', async () => {
      const error = new Error('Network error');
      (algodClient.status as jest.Mock).mockReturnValue({
        do: jest.fn().mockRejectedValue(error)
      });

      await expect(status())
        .rejects
        .toThrow('Failed to get status: Network error');
    });
  });

  describe('Status After Block', () => {
    const mockRound = 1234;
    const mockResponse = {
      lastRound: mockRound + 1,
      catchupTime: 0,
      hasSyncedSinceStartup: true
    };

    beforeEach(() => {
      (algodClient.statusAfterBlock as jest.Mock).mockReturnValue({
        do: jest.fn().mockResolvedValue(mockResponse)
      });
    });

    it('should fetch status after block', async () => {
      const result = await statusAfterBlock(mockRound);
      expect(result).toEqual(mockResponse);
      expect(algodClient.statusAfterBlock).toHaveBeenCalledWith(mockRound);
    });

    it('should handle errors', async () => {
      const error = new Error('Network error');
      (algodClient.statusAfterBlock as jest.Mock).mockReturnValue({
        do: jest.fn().mockRejectedValue(error)
      });

      await expect(statusAfterBlock(mockRound))
        .rejects
        .toThrow('Failed to get status after block: Network error');
    });
  });

  describe('Resource Handler', () => {
    const mockTxId = 'MOCK_TX_ID';
    const mockAddress = 'MOCK_ADDRESS';
    const mockRound = 1234;

    beforeEach(() => {
      // Reset all mocks with success responses
      (algodClient.pendingTransactionInformation as jest.Mock).mockReturnValue({
        do: jest.fn().mockResolvedValue({ txn: { type: 'pay' }, confirmedRound: mockRound })
      });
      (algodClient.pendingTransactionByAddress as jest.Mock).mockReturnValue({
        do: jest.fn().mockResolvedValue({ topTransactions: [], totalTransactions: 0 })
      });
      (algodClient.pendingTransactionsInformation as jest.Mock).mockReturnValue({
        max: jest.fn().mockReturnThis(),
        do: jest.fn().mockResolvedValue({ topTransactions: [], totalTransactions: 0 })
      });
      (algodClient.getTransactionParams as jest.Mock).mockReturnValue({
        do: jest.fn().mockResolvedValue({ fee: 1000 })
      });
      (algodClient.status as jest.Mock).mockReturnValue({
        do: jest.fn().mockResolvedValue({ lastRound: mockRound })
      });
      (algodClient.statusAfterBlock as jest.Mock).mockReturnValue({
        do: jest.fn().mockResolvedValue({ lastRound: mockRound + 1 })
      });
    });

    it('should handle pending transaction URI', async () => {
      const uri = `algorand://transaction/${mockTxId}/pending`;
      const result = await handleTransactionResources(uri);
      expect(result).toHaveLength(1);
      expect(JSON.parse(result[0].text)).toHaveProperty('transaction');
      expect(JSON.parse(result[0].text)).toHaveProperty('currentRound');
    });

    it('should handle pending transactions by address URI', async () => {
      const uri = `algorand://account/${mockAddress}/transactions/pending`;
      const result = await handleTransactionResources(uri);
      expect(result).toHaveLength(1);
      expect(JSON.parse(result[0].text)).toHaveProperty('transactions');
      expect(JSON.parse(result[0].text)).toHaveProperty('totalTransactions');
    });

    it('should handle all pending transactions URI', async () => {
      const uri = 'algorand://transactions/pending';
      const result = await handleTransactionResources(uri);
      expect(result).toHaveLength(1);
      expect(JSON.parse(result[0].text)).toHaveProperty('transactions');
      expect(JSON.parse(result[0].text)).toHaveProperty('totalTransactions');
    });

    it('should handle transaction parameters URI', async () => {
      const uri = 'algorand://transaction/params';
      const result = await handleTransactionResources(uri);
      expect(result).toHaveLength(1);
      expect(JSON.parse(result[0].text)).toHaveProperty('params');
    });

    it('should handle node status URI', async () => {
      const uri = 'algorand://node/status';
      const result = await handleTransactionResources(uri);
      expect(result).toHaveLength(1);
      expect(JSON.parse(result[0].text)).toHaveProperty('status');
    });

    it('should handle status after block URI', async () => {
      const uri = `algorand://node/status/after/${mockRound}`;
      const result = await handleTransactionResources(uri);
      expect(result).toHaveLength(1);
      expect(JSON.parse(result[0].text)).toHaveProperty('status');
    });

    it('should return empty array for unknown URI', async () => {
      const uri = 'algorand://unknown';
      const result = await handleTransactionResources(uri);
      expect(result).toHaveLength(0);
    });

    it('should handle errors with McpError', async () => {
      const error = new Error('Network error');
      (algodClient.pendingTransactionInformation as jest.Mock).mockReturnValue({
        do: jest.fn().mockRejectedValue(error)
      });

      const uri = `algorand://transaction/${mockTxId}/pending`;
      await expect(handleTransactionResources(uri))
        .rejects
        .toThrow(new McpError(ErrorCode.InternalError, 'Network error'));
    });
  });
});

```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/algokit:utils:typescript:capabilities:testing.md:
--------------------------------------------------------------------------------

```markdown
# Automated testing

Automated testing is a higher-order use case capability provided by AlgoKit Utils that builds on top of the core capabilities. It allows you to use terse, robust automated testing primitives that work across any testing framework (including jest and vitest) to facilitate fixture management, quickly generating isolated and funded test accounts, transaction logging, indexer wait management and log capture.

To see some usage examples check out the all of the [automated tests](../../src/) and the various \*.spec.ts files (AlgoKit Utils [dogfoods](https://en.wikipedia.org/wiki/Eating_your_own_dog_food) it's own testing library). Alternatively, you can see an example of using this library to test a smart contract with [the tests](https://github.com/algorandfoundation/nft_voting_tool/blob/main/src/algorand/smart_contracts/tests/voting.spec.ts) for the [on-chain voting tool](https://github.com/algorandfoundation/nft_voting_tool#readme).

## Module import

The testing capability is not exposed from the [root algokit module](../code/modules/index.md) so there is a clear separation between testing functionality and non-testing functionality.

To access all of the functionality in the testing capability individually, you can import the [testing module](../code/modules/testing.md):

```typescript
import * as algotesting from '@algorandfoundation/algokit-utils/testing'
```

## Algorand fixture

In general, the only entrypoint you will need to use the testing capability is just by importing the `algorandFixture` since it exposes the rest of the functionality in a manner that is easy to integrate with an underlying test framework like Jest or vitest:

```typescript
import { algorandFixture } from '@algorandfoundation/algokit-utils/testing'
```

### Using with Jest

To integrate with [Jest](https://jestjs.io/) you need to pass the `fixture.beforeEach` method into Jest's `beforeEach` method and then within each test you can access `fixture.context` to access per-test isolated fixture values.

```typescript
import { describe, test, beforeEach } from '@jest/globals'
import { algorandFixture } from './testing'

describe('MY MODULE', () => {
  const fixture = algorandFixture()
  beforeEach(fixture.beforeEach, 10_000)

  test('MY TEST', async () => {
    const { algorand, testAccount /* ... */ } = fixture.context

    // Test stuff!
  })
})
```

Occasionally there may be a delay when first running the fixture setup so we add a 10s timeout to avoid intermittent test failures (`10_000`).

### Using with vitest

To integrate with [vitest](https://vitest.dev/) you need to pass the `fixture.beforeEach` method into vitest's `beforeEach` method and then within each test you can access `fixture.context` to access per-test isolated fixture values.

```typescript
import { describe, test, beforeEach } from 'vitest'
import { algorandFixture } from './testing'

describe('MY MODULE', () => {
  const fixture = algorandFixture()
  beforeEach(fixture.beforeEach, 10_000)

  test('MY TEST', async () => {
    const { algorand, testAccount /* ... */ } = fixture.context

    // Test stuff!
  })
})
```

### Fixture configuration

When calling `algorandFixture()` you can optionally pass in some fixture configuration, with any of these properties (all optional):

- `algod?: Algodv2` - An optional algod client, if not specified then it will create one against environment variables defined network (if present) or default LocalNet
- `indexer?: Indexer` - An optional indexer client, if not specified then it will create one against environment variables defined network (if present) or default LocalNet
- `kmd?: Kmd` - An optional kmd client, if not specified then it will create one against environment variables defined network (if present) or default LocalNet
- `testAccountFunding?: AlgoAmount` - The [amount](./amount.md) of funds to allocate to the default testing account, if not specified then it will get `10` ALGO

### Using the fixture context

The `fixture.context` property is of type [`AlgorandTestAutomationContext`](../code/interfaces/types_testing.AlgorandTestAutomationContext.md) exposes the following properties from which you can pick which ones you want in a given test using an object [destructuring assignment](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment):

- `algorand: AlgorandClient` - An [`AlgorandClient`](./algorand-client.md) instance
- `algod: Algodv2` - Proxy Algod client instance that will log sent transactions in `transactionLogger`
- `indexer: Indexer` - Indexer client instance
- `kmd: Kmd` - KMD client instance
- `transactionLogger: TransactionLogger` - Transaction logger that will log transaction IDs for all transactions issued by `algod`
- `testAccount: Account` - Funded test account that is ephemerally created for each test
- `generateAccount: (params: GetTestAccountParams) => Promise<Account>` - Generate and fund an additional ephemerally created account
- `waitForIndexer: () => Promise<void>` - Wait for the indexer to catch up with all transactions logged by transactionLogger
- `waitForIndexerTransaction: (transactionId: string) => Promise<TransactionLookupResult>` - Wait for the indexer to catch up with the given transaction ID

## Log capture fixture

If you want to capture log messages from AlgoKit that are issued within your test so that you can assert on them or parse them for debugging information etc. then you can use the log capture fixture.

```typescript
import { algoKitLogCaptureFixture } from '@algorandfoundation/algokit-utils/testing'
```

The log capture fixture works by setting the logger within the AlgoKit configuration to be a [`TestLogger`](../code/classes/testing.TestLogger.md) during the test run.

### Using with Jest

To integrate with [Jest](https://jestjs.io/) you need to pass the `fixture.beforeEach` method into Jest's `beforeEach` method and then within each test you can access `fixture.context` to access per-test isolated fixture values.

```typescript
import { describe, test, beforeEach, afterEach } from '@jest/globals'
import { algoKitLogCaptureFixture } from './testing'

describe('MY MODULE', () => {
  const logs = algoKitLogCaptureFixture()
  beforeEach(logs.beforeEach)
  afterEach(logs.afterEach)

  test('MY TEST', async () => {
    const { algorand, testAccount } = fixture.context
    // Test stuff!

    const capturedLogs = logs.testLogger.capturedLogs
    // do stuff with the logs
  })
})
```

### Using with vitest

To integrate with [vitest](https://vitest.dev/) you need to pass the `fixture.beforeEach` method into vitest's `beforeEach` method and then within each test you can access `fixture.context` to access per-test isolated fixture values.

```typescript
import { describe, test, beforeEach, afterEach } from 'vitest'
import { algoKitLogCaptureFixture } from './testing'

describe('MY MODULE', () => {
  const logs = algoKitLogCaptureFixture()
  beforeEach(logs.beforeEach)
  afterEach(logs.afterEach)

  test('MY TEST', async () => {
    const { algorand, testAccount } = fixture.context
    // Test stuff!

    const capturedLogs = logs.testLogger.capturedLogs
    // do stuff with the logs
  })
})
```

### Snapshot testing the logs

If you want to quickly pin some behaviour of what logic you have does in terms of invoking AlgoKit methods you can do a [snapshot test](https://jestjs.io/docs/snapshot-testing) / [approval test](https://approvaltests.com/) of the captured log output. The only problem is this output will contain identifiers that will change for every test run and thus will constantly break the snapshot. In order to work around this you can use the `getLogSnapshot` method on the `TestLogger`, which will replace those changing values with predictable strings to keep the snapshot integrity intact.

This might look something like this:

```typescript
const { algorand, testAccount } = fixture.context
const result = await algorand.client.getTypedClientById(HelloWorldContractClient, { id: 0 }).deploy()
expect(
  logging.testLogger.getLogSnapshot({
    accounts: [testAccount],
    transactions: [result.transaction],
    apps: [result.appId],
  }),
).toMatchSnapshot()
```

## Waiting for indexer

Often there will be things that you do in your test that you may want to assert in using data that is exclusively in indexer such as transaction notes. The problem is indexer asynchronously indexes the data in algod, even when devmode is turned on and algod instantly confirms transactions.

This means it's easy to create tests that are flaky and have intermittent test failures (sometimes indexer is up to date and other times it hasn't caught up yet).

The testing capability provides mechanisms for waiting for indexer to catch up, namely:

- `algotesting.runWhenIndexerCaughtUp(run: () => Promise<T>)` - Executes the given action every 200ms up to 20 times until there is no longer an error with a `status` property with `404` and then returns the result of the action; this will work for any call that calls indexer APIs expecting to return a single record
- `algorandFixture.waitForIndexer()` - Waits for indexer to catch up with all transactions that have been captured by the `transactionLogger` in the Algorand fixture
- `algorandFixture.waitForIndexerTransaction(transactionId)` - Waits for indexer to catch up with the single transaction of the given ID

## Logging transactions

When testing, it can be useful to capture all of the transactions that have been issued with a given test run. They can then be asserted on, or used for [waiting for indexer](#waiting-for-indexer), etc.

The testing capability provides the ability to capture transactions via the [`TransactionLogger`](../code/classes/testing.TransactionLogger.md) class.

The `TransactionLogger` has the following methods:

- `logRawTransaction(signedTransactions: Uint8Array | Uint8Array[])` - Logs the IDs of the given signed transaction(s)
- `capture(algod)` - Returns a proxy `algosdk.Algodv2` instance that wraps the given `algod` client that will call `logRawTransaction` for every call to `sendRawTransaction` on that algod instance
- `sentTransactionIds` - Returns the currently captured list of transaction IDs that have been logged
- `clear()` - Clears the current list of transaction IDs
- `waitForIndexer(indexer)` - [Waits for the given indexer instance to catch up](#waiting-for-indexer) with the currently logged transaction IDs

The easiest way to use this functionality is via the [Algorand fixture](#algorand-fixture), which automatically provides a `transactionLogger` and a proxy `algod` connected to that `transactionLogger`.

## Getting a test account

When testing, it's often useful to ephemerally generate random accounts, fund them with some number of Algo and then use that account to perform transactions. By creating an ephemeral, random account you naturally get isolation between tests and test runs and don't need to start from a specific blockchain network state. This makes test less flakey, and also means the same test can be run against LocalNet and (say) TestNet.

The key when generating a test account is getting hold of a [dispenser](./transfer.md#dispenser) and then [ensuring the test account is funded](./transfer.md#ensurefunded).

To make it easier to quickly get a test account the testing capability provides the following mechanisms:

- [`algotesting.getTestAccount(testAccountParams, algod, kmd?)`](../code/modules/testing.md#gettestaccount) - Generates a random new account, logs the mnemonic of the account (unless suppressed), funds it from the [dispenser](./transfer.md#dispenser)
- `algorandFixture.testAccount` - A test account that is always generated for every test (log output suppressed to reduce noise, but worth noting that means the mnemonic isn't logged for this account), by default it is given 10 Algo unless overridden in the [fixture config](#fixture-configuration)
- [`algorandFixture.generateAccount(testAccountParams)`](../code/interfaces/types_testing.AlgorandTestAutomationContext.md#generateaccount) - Allows you to quickly generate a test account with the `algod` and `kmd` instances that are part of the given fixture

The parameters object that controls test account generation, [`GetTestAccountParams`](../code/interfaces/types_testing.GetTestAccountParams.md), has the following properties:

- `initialFunds: AlgoAmount` - Initial funds to ensure the account has
- `suppressLog?: boolean` - Whether to suppress the log (which includes a mnemonic) or not (default: do not suppress the log)

```

--------------------------------------------------------------------------------
/packages/server/tests/resources/indexer/asset.test.ts:
--------------------------------------------------------------------------------

```typescript
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
import { 
  assetResources,
  assetResourceSchemas,
  lookupAssetByID,
  lookupAssetBalances,
  lookupAssetTransactions,
  searchForAssets,
  handleAssetResources
} from '../../../src/resources/indexer/asset.js';
import { indexerClient } from '../../../src/algorand-client.js';

// Mock algosdk client
jest.mock('../../../src/algorand-client.js', () => ({
  indexerClient: {
    lookupAssetByID: jest.fn(),
    lookupAssetBalances: jest.fn(),
    lookupAssetTransactions: jest.fn(),
    searchForAssets: jest.fn()
  },
  API_URIS: {
    ASSET_DETAILS: 'algorand://asset/{asset-id}',
    ASSET_BALANCES: 'algorand://asset/{asset-id}/balances',
    ASSET_TRANSACTIONS: 'algorand://asset/{asset-id}/transactions',
    ASSET_BALANCES_BY_ID: 'algorand://asset/{asset-id}/balances/{address}',
    ASSET_TRANSACTIONS_BY_ID: 'algorand://asset/{asset-id}/transactions/{txid}'
  }
}));

describe('Indexer Asset Resources', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  describe('Resource Definitions', () => {
    it('should define asset resources', () => {
      expect(assetResources).toHaveLength(5);
      expect(assetResources.map(r => r.name)).toEqual([
        'Asset Details',
        'Asset Balances',
        'Asset Transactions',
        'Asset Balance By Address',
        'Asset Transaction By ID'
      ]);
    });

    it('should define resource schemas', () => {
      expect(Object.keys(assetResourceSchemas)).toHaveLength(5);
      expect(assetResourceSchemas).toHaveProperty('algorand://asset/{asset-id}');
      expect(assetResourceSchemas).toHaveProperty('algorand://asset/{asset-id}/balances');
      expect(assetResourceSchemas).toHaveProperty('algorand://asset/{asset-id}/transactions');
      expect(assetResourceSchemas).toHaveProperty('algorand://asset/{asset-id}/balances/{address}');
      expect(assetResourceSchemas).toHaveProperty('algorand://asset/{asset-id}/transactions/{txid}');
    });
  });

  describe('Asset Information', () => {
    const mockAssetId = 123;
    const mockResponse = {
      asset: {
        index: mockAssetId,
        params: {
          creator: 'MOCK_ADDRESS',
          name: 'Test Asset',
          unitName: 'TEST',
          total: 1000000,
          decimals: 6
        }
      },
      currentRound: 1234
    };

    beforeEach(() => {
      (indexerClient.lookupAssetByID as jest.Mock).mockReturnValue({
        do: jest.fn().mockResolvedValue(mockResponse)
      });
    });

    it('should fetch asset information', async () => {
      const result = await lookupAssetByID(mockAssetId);
      expect(result).toEqual(mockResponse);
      expect(indexerClient.lookupAssetByID).toHaveBeenCalledWith(mockAssetId);
    });

    it('should handle errors', async () => {
      const error = new Error('Network error');
      (indexerClient.lookupAssetByID as jest.Mock).mockReturnValue({
        do: jest.fn().mockRejectedValue(error)
      });

      await expect(lookupAssetByID(mockAssetId))
        .rejects
        .toThrow('Failed to get asset info: Network error');
    });
  });

  describe('Asset Balances', () => {
    const mockAssetId = 123;
    const mockResponse = {
      balances: [{ address: 'addr1', amount: 100 }],
      currentRound: 1234
    };

    beforeEach(() => {
      (indexerClient.lookupAssetBalances as jest.Mock).mockReturnValue({
        limit: jest.fn().mockReturnThis(),
        currencyGreaterThan: jest.fn().mockReturnThis(),
        currencyLessThan: jest.fn().mockReturnThis(),
        nextToken: jest.fn().mockReturnThis(),
        do: jest.fn().mockResolvedValue(mockResponse)
      });
    });

    it('should fetch asset balances', async () => {
      const result = await lookupAssetBalances(mockAssetId);
      expect(result).toEqual(mockResponse);
      expect(indexerClient.lookupAssetBalances).toHaveBeenCalledWith(mockAssetId);
    });

    it('should handle search parameters', async () => {
      const params = {
        limit: 10,
        currencyGreaterThan: 1000,
        currencyLessThan: 2000,
        nextToken: 'token123'
      };

      await lookupAssetBalances(mockAssetId, params);
      const mock = indexerClient.lookupAssetBalances as jest.Mock;
      const chain = mock.mock.results[0].value;

      expect(chain.limit).toHaveBeenCalledWith(params.limit);
      expect(chain.currencyGreaterThan).toHaveBeenCalledWith(params.currencyGreaterThan);
      expect(chain.currencyLessThan).toHaveBeenCalledWith(params.currencyLessThan);
      expect(chain.nextToken).toHaveBeenCalledWith(params.nextToken);
    });

    it('should handle errors', async () => {
      const error = new Error('Network error');
      (indexerClient.lookupAssetBalances as jest.Mock).mockReturnValue({
        do: jest.fn().mockRejectedValue(error)
      });

      await expect(lookupAssetBalances(mockAssetId))
        .rejects
        .toThrow('Failed to get asset balances: Network error');
    });
  });

  describe('Asset Transactions', () => {
    const mockAssetId = 123;
    const mockResponse = {
      transactions: [{ id: 'txn1' }],
      currentRound: 1234
    };

    beforeEach(() => {
      (indexerClient.lookupAssetTransactions as jest.Mock).mockReturnValue({
        limit: jest.fn().mockReturnThis(),
        beforeTime: jest.fn().mockReturnThis(),
        afterTime: jest.fn().mockReturnThis(),
        minRound: jest.fn().mockReturnThis(),
        maxRound: jest.fn().mockReturnThis(),
        address: jest.fn().mockReturnThis(),
        addressRole: jest.fn().mockReturnThis(),
        excludeCloseTo: jest.fn().mockReturnThis(),
        nextToken: jest.fn().mockReturnThis(),
        do: jest.fn().mockResolvedValue(mockResponse)
      });
    });

    it('should fetch asset transactions', async () => {
      const result = await lookupAssetTransactions(mockAssetId);
      expect(result).toEqual(mockResponse);
      expect(indexerClient.lookupAssetTransactions).toHaveBeenCalledWith(mockAssetId);
    });

    it('should handle search parameters', async () => {
      const params = {
        limit: 10,
        beforeTime: '2023-01-01',
        afterTime: '2022-01-01',
        minRound: 1000,
        maxRound: 2000,
        address: 'addr1',
        addressRole: 'sender',
        excludeCloseTo: true,
        nextToken: 'token123'
      };

      await lookupAssetTransactions(mockAssetId, params);
      const mock = indexerClient.lookupAssetTransactions as jest.Mock;
      const chain = mock.mock.results[0].value;

      expect(chain.limit).toHaveBeenCalledWith(params.limit);
      expect(chain.beforeTime).toHaveBeenCalledWith(params.beforeTime);
      expect(chain.afterTime).toHaveBeenCalledWith(params.afterTime);
      expect(chain.minRound).toHaveBeenCalledWith(params.minRound);
      expect(chain.maxRound).toHaveBeenCalledWith(params.maxRound);
      expect(chain.address).toHaveBeenCalledWith(params.address);
      expect(chain.addressRole).toHaveBeenCalledWith(params.addressRole);
      expect(chain.excludeCloseTo).toHaveBeenCalledWith(params.excludeCloseTo);
      expect(chain.nextToken).toHaveBeenCalledWith(params.nextToken);
    });

    it('should handle errors', async () => {
      const error = new Error('Network error');
      (indexerClient.lookupAssetTransactions as jest.Mock).mockReturnValue({
        do: jest.fn().mockRejectedValue(error)
      });

      await expect(lookupAssetTransactions(mockAssetId))
        .rejects
        .toThrow('Failed to get asset transactions: Network error');
    });
  });

  describe('Search Assets', () => {
    const mockResponse = {
      assets: [{ index: 1, params: { name: 'Test' } }],
      currentRound: 1234
    };

    beforeEach(() => {
      (indexerClient.searchForAssets as jest.Mock).mockReturnValue({
        limit: jest.fn().mockReturnThis(),
        creator: jest.fn().mockReturnThis(),
        name: jest.fn().mockReturnThis(),
        unit: jest.fn().mockReturnThis(),
        index: jest.fn().mockReturnThis(),
        nextToken: jest.fn().mockReturnThis(),
        do: jest.fn().mockResolvedValue(mockResponse)
      });
    });

    it('should search assets', async () => {
      const result = await searchForAssets();
      expect(result).toEqual(mockResponse);
      expect(indexerClient.searchForAssets).toHaveBeenCalled();
    });

    it('should handle search parameters', async () => {
      const params = {
        limit: 10,
        creator: 'addr1',
        name: 'Test',
        unit: 'TEST',
        assetId: 123,
        nextToken: 'token123'
      };

      await searchForAssets(params);
      const mock = indexerClient.searchForAssets as jest.Mock;
      const chain = mock.mock.results[0].value;

      expect(chain.limit).toHaveBeenCalledWith(params.limit);
      expect(chain.creator).toHaveBeenCalledWith(params.creator);
      expect(chain.name).toHaveBeenCalledWith(params.name);
      expect(chain.unit).toHaveBeenCalledWith(params.unit);
      expect(chain.index).toHaveBeenCalledWith(params.assetId);
      expect(chain.nextToken).toHaveBeenCalledWith(params.nextToken);
    });

    it('should handle errors', async () => {
      const error = new Error('Network error');
      (indexerClient.searchForAssets as jest.Mock).mockReturnValue({
        do: jest.fn().mockRejectedValue(error)
      });

      await expect(searchForAssets())
        .rejects
        .toThrow('Failed to search assets: Network error');
    });
  });

  describe('Resource Handler', () => {
    const mockAssetId = 123;
    const mockAddress = 'MOCK_ADDRESS';
    const mockTxId = 'MOCK_TX_ID';

    beforeEach(() => {
      // Reset all mocks with success responses
      (indexerClient.lookupAssetByID as jest.Mock).mockReturnValue({
        do: jest.fn().mockResolvedValue({
          asset: { index: mockAssetId },
          currentRound: 1234
        })
      });
      (indexerClient.lookupAssetBalances as jest.Mock).mockReturnValue({
        do: jest.fn().mockResolvedValue({
          balances: [{ address: mockAddress }],
          currentRound: 1234
        })
      });
      (indexerClient.lookupAssetTransactions as jest.Mock).mockReturnValue({
        do: jest.fn().mockResolvedValue({
          transactions: [{ id: mockTxId }],
          currentRound: 1234
        })
      });
    });

    it('should handle asset details URI', async () => {
      const uri = `algorand://asset/${mockAssetId}`;
      const result = await handleAssetResources(uri);
      expect(result).toHaveLength(1);
      expect(JSON.parse(result[0].text)).toHaveProperty('asset');
      expect(JSON.parse(result[0].text)).toHaveProperty('currentRound');
    });

    it('should handle asset balances URI', async () => {
      const uri = `algorand://asset/${mockAssetId}/balances`;
      const result = await handleAssetResources(uri);
      expect(result).toHaveLength(1);
      expect(JSON.parse(result[0].text)).toHaveProperty('balances');
      expect(JSON.parse(result[0].text)).toHaveProperty('currentRound');
    });

    it('should handle asset transactions URI', async () => {
      const uri = `algorand://asset/${mockAssetId}/transactions`;
      const result = await handleAssetResources(uri);
      expect(result).toHaveLength(1);
      expect(JSON.parse(result[0].text)).toHaveProperty('transactions');
      expect(JSON.parse(result[0].text)).toHaveProperty('currentRound');
    });

    it('should handle asset balance by address URI', async () => {
      const uri = `algorand://asset/${mockAssetId}/balances/${mockAddress}`;
      const result = await handleAssetResources(uri);
      expect(result).toHaveLength(1);
      expect(JSON.parse(result[0].text)).toHaveProperty('balance');
      expect(JSON.parse(result[0].text)).toHaveProperty('currentRound');
    });

    it('should handle asset transaction by ID URI', async () => {
      const uri = `algorand://asset/${mockAssetId}/transactions/${mockTxId}`;
      const result = await handleAssetResources(uri);
      expect(result).toHaveLength(1);
      expect(JSON.parse(result[0].text)).toHaveProperty('transaction');
      expect(JSON.parse(result[0].text)).toHaveProperty('currentRound');
    });

    it('should return empty array for unknown URI', async () => {
      const uri = 'algorand://unknown';
      const result = await handleAssetResources(uri);
      expect(result).toHaveLength(0);
    });

    it('should handle errors with McpError', async () => {
      const error = new Error('Network error');
      (indexerClient.lookupAssetByID as jest.Mock).mockReturnValue({
        do: jest.fn().mockRejectedValue(error)
      });

      const uri = `algorand://asset/${mockAssetId}`;
      await expect(handleAssetResources(uri))
        .rejects
        .toThrow(new McpError(ErrorCode.InternalError, 'Failed to get asset details: Network error'));
    });
  });
});

```
Page 28/74FirstPrevNextLast