#
tokens: 48652/50000 10/942 files (page 31/93)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 31 of 93. Use http://codebase.md/goplausible/algorand-mcp?lines=true&page={x} to view the full context.

# Directory Structure

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

# Files

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/developer:docs:sdks:javascript:index.md:
--------------------------------------------------------------------------------

```markdown
  1 | title: JS SDK: Your First Transaction
  2 | 
  3 | This section is a quick start guide for interacting with the Algorand network using JavaScript. This guide will help to install the [Algorand sandbox](https://github.com/algorand/sandbox){target=blank}, which provides a node for testing and development. This guide will also help to install the JavaScript SDK, create an account and submit your first transaction using different JavaScript Runtimes.
  4 | ​
  5 | # Install Sandbox
  6 | 
  7 | !!! info
  8 |     This step is only required if you are not using AlgoKit. If you are using AlgoKit, you can spin up a sandbox using the LocalNet, see [AlgoKit getting started guide](/docs/get-started/algokit/#start-a-localnet) for more information. 
  9 | 
 10 | !!! Prerequisites
 11 |     - Docker Compose ([install guide](https://docs.docker.com/compose/install/))
 12 |     - Git ([install guide](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)) 
 13 |  
 14 | Algorand provides a docker instance for setting up a node, which can be used to get started developing quickly. To install and use this instance, follow these instructions.
 15 | ​
 16 | ```bash
 17 | git clone https://github.com/algorand/sandbox.git
 18 | cd sandbox
 19 | ./sandbox up dev
 20 | ```
 21 | 
 22 | This will install and start private network. To read more about Algorand networks see [Algorand Networks](../../get-details/algorand-networks/index.md){target=_blank}. 
 23 | 
 24 | [More Information about the sandbox](https://developer.algorand.org/articles/introducing-sandbox-20/) and [how to use](https://developer.algorand.org/tutorials/exploring-the-algorand-sandbox/) it.
 25 | ​
 26 | ​
 27 | 
 28 | # Install JavaScript SDK
 29 | Algorand provides an [SDK for JavaScript](https://github.com/algorand/js-algorand-sdk). The instructions for installing the SDK will depend on what runtime you plan on using. 
 30 | 
 31 | !!! Prerequisites
 32 |    - Install [Node.js](https://nodejs.org/download)
 33 | ​
 34 | ```bash 
 35 | # initialize project
 36 | npm init
 37 | # install Algorand sdk
 38 | npm install algosdk
 39 | # list the version
 40 | npm list algosdk
 41 | 
 42 | # This package provides TypeScript types, but you will need TypeScript version 4.2 or higher to use them properly.
 43 | ```
 44 | 
 45 | The [GitHub repository](https://github.com/algorand/js-algorand-sdk){target=_blank} contains additional documentation and examples.
 46 | 
 47 | See the JavaScript SDK [reference documentation](https://algorand.github.io/js-algorand-sdk/){target=_blank} for more information on methods.  
 48 | 
 49 | The SDK is installed and can now interact with the running Algorand Sandbox environment, as configured above.
 50 | 
 51 | !!! Info
 52 |     Using a Web Runtime requires the AlgoSigner extension or other web-based private key management software. For more information see [community wallets](https://developer.algorand.org/docs/community/#wallets). 
 53 | ​
 54 | # Create an Account
 55 | In order to interact with the Algorand blockchain, you must have a funded account. To quickly create a test account use the following code.
 56 | 
 57 | <!-- ===JSSDK_ACCOUNT_GENERATE=== -->
 58 | ```javascript
 59 | const generatedAccount = algosdk.generateAccount();
 60 | const passphrase = algosdk.secretKeyToMnemonic(generatedAccount.sk);
 61 | console.log(`My address: ${generatedAccount.addr}`);
 62 | console.log(`My passphrase: ${passphrase}`);
 63 | ```
 64 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/accounts.ts#L80-L84)
 65 | <!-- ===JSSDK_ACCOUNT_GENERATE=== -->
 66 | 
 67 | [`More Information`](../../get-details/accounts/create.md#standalone){target=_blank}  
 68 |  
 69 | !!! Warning 
 70 |     Never share mnemonic private keys. Production environments require stringent private key management. For more information on key management in community wallets, click [here](https://developer.algorand.org/docs/community/#wallets). For the [Algorand open source wallet](https://developer.algorand.org/articles/algorand-wallet-now-open-source/), click [here](https://github.com/algorand/algorand-wallet).
 71 | 
 72 | ​
 73 | # Fund the Account
 74 | Before sending transactions to the Algorand network, the account must be funded to cover the minimal transaction fees that exist on Algorand. In this example, we'll be using prefunded accounts available in the Sandbox. To fund an account on Testnet account use the [Algorand faucet](https://dispenser.testnet.aws.algodev.network/){target=_blank}. 
 75 | ​
 76 | !!! Info
 77 |     All Algorand accounts require a minimum balance to be registered in the ledger. To read more about Algorand minimum balance see [Account Overview](https://developer.algorand.org/docs/features/accounts/#minimum-balance)
 78 |  
 79 | ​
 80 | # Connect Your Client
 81 | An Algod client must be instantiated prior to making calls to the API endpoints. You must provide values for `<algod-address>` and `<algod-token>`. The CLI tools implement the client natively. By default, the `algodToken` for each [sandbox](https://github.com/algorand/sandbox) is set to its `aaa...` value and the `algodAddress` corresponds to `http://localhost:4001`.
 82 | 
 83 | 
 84 | <!-- ===JSSDK_ALGOD_CREATE_CLIENT=== -->
 85 | ```javascript
 86 | const algodToken = 'a'.repeat(64);
 87 | const algodServer = 'http://localhost';
 88 | const algodPort = 4001;
 89 | 
 90 | const algodClient = new algosdk.Algodv2(algodToken, algodServer, algodPort);
 91 | ```
 92 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/overview.ts#L7-L12)
 93 | <!-- ===JSSDK_ALGOD_CREATE_CLIENT=== -->
 94 |  
 95 | !!! Info
 96 |     The example code connects to the sandbox Algod client. If you want to connect to a public API client, change the host, port, and token parameters to match the API service. See some service available [here](https://developer.algorand.org/ecosystem-projects/?tags=api-services)
 97 | 
 98 | !!! Info
 99 |     If you are connecting to the Testnet, a dispenser is available [here](https://dispenser.testnet.aws.algodev.network/){target=_blank}
100 |  
101 | # Check Your Balance
102 | Before moving on to the next step, make sure your account has been funded by the faucet.
103 |  
104 | <!-- ===JSSDK_ALGOD_FETCH_ACCOUNT_INFO=== -->
105 | ```javascript
106 | const acctInfo = await algodClient.accountInformation(acct.addr).do();
107 | console.log(`Account balance: ${acctInfo.amount} microAlgos`);
108 | ```
109 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/overview.ts#L46-L48)
110 | <!-- ===JSSDK_ALGOD_FETCH_ACCOUNT_INFO=== -->
111 | 
112 |  
113 | # Build First Transaction
114 | Transactions are used to interact with the Algorand network. To create a payment transaction use the following code.
115 | 
116 | <!-- ===JSSDK_TRANSACTION_PAYMENT_CREATE=== -->
117 | ```javascript
118 | const suggestedParams = await algodClient.getTransactionParams().do();
119 | const ptxn = algosdk.makePaymentTxnWithSuggestedParamsFromObject({
120 |   from: acct.addr,
121 |   suggestedParams,
122 |   to: acct2.addr,
123 |   amount: 10000,
124 |   note: new Uint8Array(Buffer.from('hello world')),
125 | });
126 | ```
127 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/overview.ts#L23-L31)
128 | <!-- ===JSSDK_TRANSACTION_PAYMENT_CREATE=== -->
129 | 
130 | !!! Info
131 |     Algorand supports many transaction types. To see what types are supported see [Transactions](https://developer.algorand.org/docs/get-details/transactions/).
132 | ​
133 | # Sign First Transaction
134 | Before the transaction is considered valid, it must be signed by a private key. Use the following code to sign the transaction.
135 | ​
136 | <!-- ===JSSDK_TRANSACTION_PAYMENT_SIGN=== -->
137 | ```javascript
138 | const signedTxn = ptxn.signTxn(acct.privateKey);
139 | ```
140 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/overview.ts#L34-L35)
141 | <!-- ===JSSDK_TRANSACTION_PAYMENT_SIGN=== -->
142 | 
143 | !!! Info
144 |     Algorand provides many ways to sign transactions. To see other ways see [Authorization](https://developer.algorand.org/docs/features/transactions/signatures/#single-signatures).
145 |  
146 | 
147 |  
148 | # Submit the Transaction
149 | The signed transaction can now be submitted to the network.`waitForConfirmation` is called after the transaction is submitted to wait until the transaction is broadcast to the Algorand blockchain and is confirmed. The below snippet also shows how you can decode the data in the node field again to make it readable.
150 |  
151 |  
152 |  <!-- ===JSSDK_TRANSACTION_PAYMENT_SUBMIT=== -->
153 | ```javascript
154 | const { txId } = await algodClient.sendRawTransaction(signedTxn).do();
155 | const result = await algosdk.waitForConfirmation(algodClient, txId, 4);
156 | console.log(result);
157 | console.log(`Transaction Information: ${result.txn}`);
158 | console.log(`Decoded Note: ${Buffer.from(result.txn.txn.note).toString()}`);
159 | ```
160 | [Snippet Source](https://github.com/algorand/js-algorand-sdk/blob/examples/examples/overview.ts#L38-L43)
161 |  <!-- ===JSSDK_TRANSACTION_PAYMENT_SUBMIT=== -->
162 |  
163 | ​
164 | # View the Transaction
165 | 
166 | To view the transaction we submitted to the sandbox Algod, open [Lora](https://lora.algokit.io/localnet){target=_blank} and choose `LocalNet` configuration option, then search for the transaction ID. 
167 | 
168 | To view a transaction submitted to public network like testnet, open [Lora](https://lora.algokit.io/testnet){target=_blank} or [Pera Explorer](https://testnet.explorer.perawallet.app/){target=blank} and paste the transaction ID into the search bar.
169 | 
```

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

```markdown
  1 | title: CLI smart signatures
  2 | 
  3 | This guide covers working with the `goal` command-line tool with smart signatures.
  4 | 
  5 | TEAL programs can be written with any editor and are compiled using the `goal` command-line tool. They can also be built using python with the [PyTeal Library](/docs/get-details/dapps/writing-contracts/pyteal). The command-line tool provides the ability to use these compiled programs within transactions. 
  6 | 
  7 | # Simple TEAL example
  8 | The simplest program you can write in TEAL is probably the following:
  9 | 
 10 | ```go
 11 | // simple.teal
 12 | // Do not use this in a real application
 13 | int 0
 14 | ```
 15 | This simplistic example always returns false and should never be used in a real transaction. 
 16 | 
 17 | The following command illustrates compiling this program:
 18 | 
 19 | ```
 20 | goal clerk compile simple.teal
 21 | // Compile output
 22 | simple.teal: 6Z3C3LDVWGMX23BMSYMANACQOSINPFIRF77H7N3AWJZYV6OH6GWTJKVMXY
 23 | ```
 24 | 
 25 | The compilation returns an Algorand Address. This is the contract account address if the TEAL program is used as a contract account. If the TEAL program is intended to be used as a delegated signature, the logic should be signed with a private key. This is done using the `-s` option with the `goal clerk compile` command. The following example shows using goal to compile and sign the TEAL program in one operation.
 26 | 
 27 | ```
 28 | goal clerk compile simple.teal -o mydelegatedsig.lsig -s -a C3MKH24QL3GHSD5CDQ47ZNQZMNZRX4MUTV6LVPAXMWAXMIISYSOWPGH674 -d ~/node/data
 29 | ```
 30 | 
 31 | Logic is signed with a specific address specified with the `-a` option. If no default wallet is assigned, the `-w` option is used to specify the wallet that contains the account that is signing the logic.
 32 | 
 33 | The `-o` option specifies the name of the logic signature file. In this example, the file mydelegatedsig.lsig is created. This file can be shared to let others submit transactions with the authority of the original signer. When this logic signature is used in a transaction the logic will determine if the transaction is approved. The following example shows how the logic signature is used in a transaction with `goal`
 34 | 
 35 | ```
 36 | goal clerk send -f C3MKH24QL3GHSD5CDQ47ZNQZMNZRX4MUTV6LVPAXMWAXMIISYSOWPGH674 -a 1000000 -t STF6TH6PKINM4CDIQHNSC7QEA4DM5OJKKSACAPWGTG776NWSQOMAYVGOQE -L mydelegatedsig.lsig -d ~/node/data
 37 | ```
 38 | The `-f` option specifies the account that signed the logic signature and the -t option specifies the receiver of the transaction. The transaction fee is paid by the account that signed the logic signature. 
 39 | 
 40 | # Compiling TEAL options
 41 | Compiling a teal program using the `goal clerk compile` compiles and writes the binary raw bytes to a file with the same name as the source file with a `.tok` extension. Specifying the `-n` option will compile the TEAL program, but not write out the binary. The console will display the compiled TEAL's address.
 42 | 
 43 | ```
 44 | $ goal clerk compile -n simple.teal
 45 | simple.teal: KI4DJG2OOFJGUERJGSWCYGFZWDNEU2KWTU56VRJHITP62PLJ5VYMBFDBFE
 46 | ```
 47 | 
 48 | Removing the `-n` option writes the binary to a file named simple.teal.tok. Supplying the `-o` option allows the binary to be written to a specific location and filename.
 49 | 
 50 | ```
 51 | goal clerk compile  simple.teal -o /tmp/mytealbinary.tealc
 52 | ```
 53 | 
 54 | The raw binary TEAL program can be disassembled using the `-D` option.
 55 | 
 56 | ```
 57 | $ goal clerk compile -D /tmp/mytealbinary.tealc
 58 | // Terminal Output
 59 | // version 1
 60 | intcblock 0
 61 | intc_0
 62 | ```
 63 | 
 64 | In the above examples, the TEAL program is compiled and can be used as a contract account as discussed in the [Usage Modes](../modes) documentation. To use TEAL for account [delegation](../modes#delegated-account), the program must be signed by an account or a multi-signature account. This can be done with `goal` using the `-s` option. The following will produce a LogicSig file.
 65 | 
 66 | ```
 67 | goal clerk compile  simple.teal -o /tmp/simple.lsig -s -d ~/node/data
 68 | ```
 69 | 
 70 | In the example above, the `-o` option is used to produce the logic signature file, which contains the raw program binary and the signature as discussed in the [Logic Signature](../modes#logic-signatures) documentation. Using the `-a` option allows the TEAL program to be signed by a specific account.
 71 | 
 72 | ```
 73 | goal clerk compile  simple.teal -o /tmp/simple.lsig -s -a LSJY4JD5J626BMJY2NMODBP64WDQP5OS4M6YF2F5BWQUS22I3YJYCXHHIA -d ~/node/data
 74 | ```
 75 | 
 76 | A logic signature file can be disassembled in the same way as the standard binary.
 77 | 
 78 | ```
 79 | goal clerk compile -D /tmp/simple.lsig
 80 | // Console Output
 81 | // version 1
 82 | intcblock 0
 83 | intc_0
 84 | LogicSig: {
 85 |   "sig": "45on5JUofgMjxL9e7IiPzCwutMHj3hFS1bKnCpxjgQ06dhikUgQSadqxcSOMKlcpN31W88hzkv3AeUUDLc4qAg=="
 86 | }
 87 | ```
 88 | 
 89 | # Creating a multi-signature delegated logic sig
 90 | In the previous section, a logic signature was created using a single account. As discussed in the [Logic Signature](../modes#logic-signatures) documentation, LogicSigs can also be created using a multi-signature account. For example, a three account multi-signature account with a threshold level of 2 can be created using the following command.
 91 | 
 92 | ```
 93 | goal account multisig new -T 2 DFPKC2SJP3OTFVJFMCD356YB7BOT4SJZTGWLIPPFEWL3ZABUFLTOY6ILYE LSJY4JD5J626BMJY2NMODBP64WDQP5OS4M6YF2F5BWQUS22I3YJYCXHHIA YYKRMERAFXMXCDWMBNR6BUUWQXDCUR53FPUGXLUYS7VNASRTJW2ENQ7BMQ -d ~/node/data
 94 | ```
 95 | 
 96 | This creates a multi-sig account that requires at least two signatures to authorize a transaction. To create a logic signature, any one of the three accounts can sign the logic and create a logic signature file. This is done using the `goal clerk multisig signprogram` command.
 97 | 
 98 | ```
 99 | goal clerk multisig signprogram -p /tmp/simple.teal -a YYKRMERAFXMXCDWMBNR6BUUWQXDCUR53FPUGXLUYS7VNASRTJW2ENQ7BMQ -A 5DLEJBZHDG4XTIILEEJ6HSLG2YFGHNDAKIUAFASMFV234CJGEDQYMJ6LMI -o /tmp/simple.lsig -d ~/node/data
100 | ```
101 | 
102 | In the above example, the `-p` option specifies the TEAL program file. The TEAL program bytes can also be passed directly using the `-P` option. The `-a` option specifies which account is signing the logic and the `-A` specifies the multi-signature address. 
103 | 
104 | At this point the logic signature file only contains one signature and the threshold is set to two. This means that in order for the logic signature to be used, one of the two remaining accounts must also sign the logic signature file. This is done using the `-L` option with the `goal clerk multisig signprogram` command.
105 | 
106 | ```
107 | goal clerk multisig signprogram -L /tmp/simple.lsig -a LSJY4JD5J626BMJY2NMODBP64WDQP5OS4M6YF2F5BWQUS22I3YJYCXHHIA -A 5DLEJBZHDG4XTIILEEJ6HSLG2YFGHNDAKIUAFASMFV234CJGEDQYMJ6LMI -d ~/node/data
108 | ```
109 | 
110 | Decompiling the logic signature shows the number of current signatures.
111 | 
112 | ```
113 | $ goal clerk compile -D /tmp/simple.lsig
114 | // Console Output
115 | // version 1
116 | intcblock 0
117 | intc_0
118 | LogicSig: {
119 |   "msig": {
120 |     "subsig": [
121 |       {
122 |         "pk": "YYKRMERAFXMXCDWMBNR6BUUWQXDCUR53FPUGXLUYS7VNASRTJW2ENQ7BMQ",
123 |         "s": "h7/CyM7aiJnDnXOjyNeY2DlOZhqieaWafO0n2Hi4d9IfyFozjKQL9/kB2x7QQV+bPRTORdbYCXpL2x6c5razAw=="
124 |       },
125 |       {
126 |         "pk": "LSJY4JD5J626BMJY2NMODBP64WDQP5OS4M6YF2F5BWQUS22I3YJYCXHHIA",
127 |         "s": "/s/BsHGK+RThEmrc2Wre/VVBX6jtqcMS/pZQTA0iBE3S5d+D4BFeD2JXRSAW/oD78V9SlLXSfOYGAfEnianaDw=="
128 |       }
129 |     ],
130 |     "thr": 2,
131 |     "v": 1
132 |   }
133 | }
134 | ```
135 | # Passing parameters to TEAL with goal
136 | Parameters can be passed to a TEAL program using `goal`. The parameters must be passed as base64 encoded strings. For example, to pass “mystringargument” to a stateless TEAL program, the argument can be encoded using an `echo` command with base64. The `-w0` argument disables wrapping that defaults to 76 characters. 
137 | 
138 | ```
139 | $ echo -n mystringargument | base64 -w0
140 | bXlzdHJpbmdhcmd1bWVudA==
141 | ```
142 | 
143 | The base64 encoded string is passed to the TEAL program using the `--argb64` option. The `goal` command line can be passed multiple parameters using the `--argb64` option multiple times. The parameter order is specific and will directly map to the TEAL parameters array.
144 | 
145 | ```
146 | goal clerk send -a 1000 -c closeaccountotaddress --to toaddr --from-program myteal.teal --argb64 "bXlzdHJpbmdhcmd1bWVudA==" -d ~/node/data
147 | ```
148 | 
149 | The example above also illustrates using the `--from-program` option. This option instructs the compiler to compile a specific TEAL program and set it as the sender of the transaction. Because the `-s` option is not used, this account must be a contract account.
150 | 
151 | Passing an integer to a TEAL program requires that it must be converted to a base64 encoded string as well when using `goal`. This can be done in many ways. The following example illustrates the conversion using a simple python command. 
152 | 
153 | ``` python
154 | $ python3 -c "import base64;print(base64.b64encode((123).to_bytes(8,'big')).decode('ascii'))"
155 | ```
156 | 
157 | The example above converts the integer value of 123 to a base64 encoded string. TEAL currently does not support negative numbers. 
158 | 
159 | Each SDK provides facilities for passing parameters as well. These processes are described in the [Interact with smart signatures](../frontend/smartsigs.md) Usage documentation.
160 | 
```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/developer:docs:sdks:go:index.md:
--------------------------------------------------------------------------------

```markdown
  1 | title: Go SDK: Your First Transaction
  2 | 
  3 | This section is a quick start guide for interacting with the Algorand network using Go. This guide will help to install [Algorand sandbox](https://github.com/algorand/sandbox){target=blank}, which provides a node for testing and development. This guide will also help to install the Go SDK, create an account and submit your first transaction on Algorand.  
  4 |  
  5 | # Install Sandbox
  6 | 
  7 | !!! info
  8 |     This step is only required if you are not using AlgoKit. If you are using AlgoKit, you can spin up a sandbox using the LocalNet, see [AlgoKit getting started guide](/docs/get-started/algokit/#start-a-localnet) for more information. 
  9 | 	
 10 | !!! Prerequisites
 11 |     - Docker Compose ([install guide](https://docs.docker.com/compose/install/))
 12 |     - Git ([install guide](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git))
 13 | 
 14 | Algorand provides a docker instance for setting up a node, which can be used to get started developing quickly. To install and use this instance, follow these instructions.
 15 | 
 16 | ```bash
 17 | git clone https://github.com/algorand/sandbox.git
 18 | cd sandbox
 19 | ./sandbox up dev 
 20 | ```
 21 | 
 22 | This will install and start private network. To read more about Algorand networks see [Algorand Networks](../../get-details/algorand-networks/index.md){target=_blank}. 
 23 | 
 24 | [More Information about the sandbox](https://developer.algorand.org/articles/introducing-sandbox-20/) and [how to use](https://developer.algorand.org/tutorials/exploring-the-algorand-sandbox/) it.
 25 | 
 26 |  
 27 | 
 28 | # Install Go SDK
 29 | Algorand provides an SDK for Go. 
 30 | 
 31 | !!! Prerequisites
 32 |     - Go programming language ([install guide](https://golang.org/doc/install))
 33 | 
 34 | From a terminal window, install the Go SDK:
 35 | 
 36 | ```bash
 37 | go get -u github.com/algorand/go-algorand-sdk/v2
 38 | ```
 39 | 
 40 | The [GitHub repository](https://github.com/algorand/go-algorand-sdk){target=_blank} contains additional documentation and examples.
 41 | 
 42 | See the JavaScript SDK [reference documentation](https://pkg.go.dev/github.com/algorand/go-algorand-sdk/v2){target=_blank} for more information on methods.  
 43 | 
 44 | The SDK is installed and can now interact with the running Algorand Sandbox environment, as configured above.
 45 | 
 46 | # Create an account
 47 | In order to interact with the Algorand blockchain, you must have a funded account on the network. To quickly create a test account use the following code.
 48 | 
 49 | <!-- ===GOSDK_ACCOUNT_GENERATE=== -->
 50 | ```go
 51 | account := crypto.GenerateAccount()
 52 | mn, err := mnemonic.FromPrivateKey(account.PrivateKey)
 53 | 
 54 | if err != nil {
 55 | 	log.Fatalf("failed to generate account: %s", err)
 56 | }
 57 | 
 58 | log.Printf("Address: %s\n", account.Address)
 59 | log.Printf("Mnemonic: %s\n", mn)
 60 | ```
 61 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/account/main.go#L16-L25)
 62 | <!-- ===GOSDK_ACCOUNT_GENERATE=== -->
 63 | 
 64 | [`More Information`](../../get-details/accounts/create.md#standalone){target=_blank}  
 65 | 
 66 | !!! Warning 
 67 |     Never share your mnemonic passphrase or private keys. Production environments require stringent private key management. For more information on key management in community Wallets, click [here](https://developer.algorand.org/docs/community/#wallets). For the open source [Algorand Wallet](https://developer.algorand.org/articles/algorand-wallet-now-open-source/), click [here](https://github.com/algorand/algorand-wallet).
 68 | 
 69 |  
 70 | # Fund the account
 71 | Before sending transactions to the Algorand network, the account must be funded to cover the minimal transaction fees that exist on Algorand. In this example, we'll be using prefunded accounts available in the Sandbox. To fund an account on Testnet account use the [Algorand faucet](https://dispenser.testnet.aws.algodev.network/){target=_blank}. 
 72 | 
 73 | !!! Info
 74 |     All Algorand accounts require a minimum balance to be registered in the ledger. To read more about Algorand minimum balance see [Account Overview](https://developer.algorand.org/docs/features/accounts/#minimum-balance)
 75 | 
 76 | 
 77 | # Connect Your Client
 78 | An Algod client must be instantiated prior to making calls to the API endpoints. You must provide values for `<algod-address>` and `<algod-token>`. The CLI tools implement the client natively. By default, the `algodToken` for each [sandbox](https://github.com/algorand/sandbox) is set to its `aaa...` value and the `algodAddress` corresponds to `http://localhost:4001`.
 79 | 
 80 | 
 81 | <!-- ===GOSDK_ALGOD_CREATE_CLIENT=== -->
 82 | ```go
 83 | // Create a new algod client, configured to connect to out local sandbox
 84 | var algodAddress = "http://localhost:4001"
 85 | var algodToken = strings.Repeat("a", 64)
 86 | algodClient, _ := algod.MakeClient(
 87 | 	algodAddress,
 88 | 	algodToken,
 89 | )
 90 | 
 91 | // Or, if necessary, pass alternate headers
 92 | 
 93 | var algodHeader common.Header
 94 | algodHeader.Key = "X-API-Key"
 95 | algodHeader.Value = algodToken
 96 | algodClientWithHeaders, _ := algod.MakeClientWithHeaders(
 97 | 	algodAddress,
 98 | 	algodToken,
 99 | 	[]*common.Header{&algodHeader},
100 | )
101 | ```
102 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/overview/main.go#L18-L36)
103 | <!-- ===GOSDK_ALGOD_CREATE_CLIENT=== -->
104 |  
105 | !!! Info
106 |     The example code connects to the sandbox Algod client. If you want to connect to a public API client, change the host, port, and token parameters to match the API service. See some service available [here](https://developer.algorand.org/ecosystem-projects/?tags=api-services)
107 | 
108 | !!! Info
109 |     If you are connecting to the Testnet, a dispenser is available [here](https://dispenser.testnet.aws.algodev.network/){target=_blank}
110 | 
111 | # Check Your Balance
112 | Before moving on to the next step, make sure your account has been funded.
113 |  
114 |  <!-- ===GOSDK_ALGOD_FETCH_ACCOUNT_INFO=== -->
115 | ```go
116 | acctInfo, err := algodClient.AccountInformation(acct.Address.String()).Do(context.Background())
117 | if err != nil {
118 | 	log.Fatalf("failed to fetch account info: %s", err)
119 | }
120 | log.Printf("Account balance: %d microAlgos", acctInfo.Amount)
121 | ```
122 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/overview/main.go#L51-L56)
123 |  <!-- ===GOSDK_ALGOD_FETCH_ACCOUNT_INFO=== -->
124 | 
125 | 
126 | # Build First Transaction
127 | Transactions are used to interact with the Algorand network. To create a payment transaction use the following code.
128 | 
129 | <!-- ===GOSDK_TRANSACTION_PAYMENT_CREATE=== -->
130 | ```go
131 | sp, err := algodClient.SuggestedParams().Do(context.Background())
132 | if err != nil {
133 | 	log.Fatalf("failed to get suggested params: %s", err)
134 | }
135 | // payment from account to itself
136 | ptxn, err := transaction.MakePaymentTxn(acct.Address.String(), acct.Address.String(), 100000, nil, "", sp)
137 | if err != nil {
138 | 	log.Fatalf("failed creating transaction: %s", err)
139 | }
140 | ```
141 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/overview/main.go#L59-L68)
142 | <!-- ===GOSDK_TRANSACTION_PAYMENT_CREATE=== -->
143 | 
144 | !!! Info
145 |     Algorand supports many transaction types. To see what types are supported see [Transactions](https://developer.algorand.org/docs/features/transactions/).
146 | 
147 | 
148 | # Sign First transaction
149 | Before the transaction is considered valid, it must be signed by a private key. Use the following code to sign the transaction.
150 | 
151 | <!-- ===GOSDK_TRANSACTION_PAYMENT_SIGN=== -->
152 | ```go
153 | _, sptxn, err := crypto.SignTransaction(acct.PrivateKey, ptxn)
154 | if err != nil {
155 | 	fmt.Printf("Failed to sign transaction: %s\n", err)
156 | 	return
157 | }
158 | ```
159 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/overview/main.go#L71-L76)
160 | <!-- ===GOSDK_TRANSACTION_PAYMENT_SIGN=== -->
161 | 
162 | !!! Info
163 |     Algorand provides many ways to sign transactions. To see other ways see [Authorization](https://developer.algorand.org/docs/features/transactions/signatures/#single-signatures).
164 | 
165 | 
166 | # Submit transaction
167 | The signed transaction can now be broadcast to the network for validation and inclusion in a future block. The `waitForConfirmation` SDK method polls the `algod` node for the transaction ID to ensure it succeeded.
168 | 
169 | <!-- ===GOSDK_TRANSACTION_PAYMENT_SUBMIT=== -->
170 | ```go
171 | pendingTxID, err := algodClient.SendRawTransaction(sptxn).Do(context.Background())
172 | if err != nil {
173 | 	fmt.Printf("failed to send transaction: %s\n", err)
174 | 	return
175 | }
176 | confirmedTxn, err := transaction.WaitForConfirmation(algodClient, pendingTxID, 4, context.Background())
177 | if err != nil {
178 | 	fmt.Printf("Error waiting for confirmation on txID: %s\n", pendingTxID)
179 | 	return
180 | }
181 | fmt.Printf("Confirmed Transaction: %s in Round %d\n", pendingTxID, confirmedTxn.ConfirmedRound)
182 | ```
183 | [Snippet Source](https://github.com/algorand/go-algorand-sdk/blob/examples/examples/overview/main.go#L79-L90)
184 | <!-- ===GOSDK_TRANSACTION_PAYMENT_SUBMIT=== -->
185 |  
186 | # Viewing the Transaction
187 | To view the transaction we submitted to the sandbox Algod, open [Lora](https://lora.algokit.io/localnet){target=_blank} and choose `LocalNet` configuration option, then search for the transaction ID. 
188 | 
189 | To view a transaction submitted to public network like testnet, open [Lora](https://lora.algokit.io/testnet){target=_blank} or [Pera Explorer](https://testnet.explorer.perawallet.app/){target=blank} and paste the transaction ID into the search bar.
190 | 
```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/algokit:cli:architecture-decisions:2024-03-06_local_dev_ui_packaging.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Local dev UI packaging
  2 | 
  3 | - **Status**: Draft
  4 | - **Owner:** Patrick Dinh (MakerX), Negar Abbasi (MakerX)
  5 | - **Deciders**: Alessandro (Algorand Foundation), Rob Moore (MakerX), MakerX team
  6 | - **Date created**: 2024-03-06
  7 | 
  8 | ## Context
  9 | 
 10 | We are building a web-based local development interface to support:
 11 | 
 12 | - Exploring transactions, assets and accounts
 13 | - Visualising transactions
 14 | - Launching a VS Code debug session from an application call transaction
 15 | - Integrating and using a dev wallet via KMD
 16 | - Network switching between LocalNet, TestNet and MainNet
 17 | - Calling deployed ABI apps
 18 | - Integration with the AlgoKit CLI to perform any relevant actions
 19 | - Launching the interface from the AlgoKit CLI
 20 | 
 21 | ## Requirements
 22 | 
 23 | The local development interface should have:
 24 | 
 25 | - Support for a wide variety of Linux distributions, macOS (both Apple Silicon and Intel architectures), and Windows 10+.
 26 | - Local system access to:
 27 |   - The user home directory on the file system.
 28 |   - Launch child processes.
 29 |   - Launch the UI from the AlgoKit CLI.
 30 |   - Launch shell commands.
 31 | - The ability for the explorer portion to be deployed to a static web host.
 32 | - The ability to be installed via the following channels:
 33 |   - Winget for Windows.
 34 |   - Homebrew for macOS.
 35 |   - Snapcraft for Linux.
 36 | - The ability for users to see a notification when a new version is available and can update.
 37 | 
 38 | ## Out of scope
 39 | 
 40 | - Support for ARM processors on Linux or Windows.
 41 | 
 42 | ## Options
 43 | 
 44 | ### Option 1 - Electron
 45 | 
 46 | [Electron](https://www.electronjs.org/) is a framework for creating native applications with web technologies like JavaScript, HTML, and CSS. It allows developers to build cross-platform desktop apps using their existing web development skills.
 47 | 
 48 | Link to PoC is here: [Electron PoC](https://github.com/negar-abbasi/electron-poc).
 49 | 
 50 | **Pros**
 51 | 
 52 | - Electron is a mature framework with a large community and a lot of resources available.
 53 | - Uses standard JavaScript and Node APIs, which most developers are very familiar with.
 54 | - It supports all the local system access requirements via [icpMain](https://www.electronjs.org/docs/latest/api/ipc-main), allowing asynchronous communication from the main process to renderer processes.
 55 |   - File system access is enabled using the Node.js `fs` module. See [Node.js File System (fs) module docs](https://nodejs.org/api/fs.html).
 56 |   - Launching processes is enabled using the Node.js `child_process` module to spawn new processes. [Node.js Child Processes](https://nodejs.org/api/child_process.html). Specifically, well use the `spawn` or `exec` functions.
 57 |   - Running shell commands is enabled via the Node.js `child_process` module's `exec` function.
 58 | - Electron supports an [auto update](https://www.electronjs.org/docs/latest/api/auto-updater) for windows and macOS only. For Linux, if the explorer is distributed via Snapcraft, it should get auto updated.
 59 | - Electron does not have any built in tooling for packaging and distribution. There are however several third-party tools available for packaging and distribution, such as [electron-builder](https://www.electron.build/), [electron-packager](https://www.npmjs.com/package/electron-packager), and [electron-forge](https://www.electronforge.io/).
 60 | - Electron Forge is an all-in-one tool that handles the packaging and distribution of Electron apps. Under the hood, it combines a lot of existing Electron tools (e.g. @electron/packager, @electron/osx-sign, electron-winstaller, etc.) into a single interface so we do not have to worry about wiring them all together. [docs](https://www.electronjs.org/docs/latest/tutorial/tutorial-packaging#using-electron-forge)
 61 |   - It can package the app into format that we are interested in:
 62 |     - `.deb`, `.snap` for Linux
 63 |     - `.msi` for Windows
 64 |     - `.dmg` for macOS
 65 | 
 66 | **Cons**
 67 | 
 68 | - Electron is resource hungry, for a small test app (Hello World) it uses 146.0 MB of memory and 0.47% of CPU (running on macOS M2 CPU with 12 cores and 16GB RAM)
 69 | - When built on a local dev machine, the package size for macOS is ~250MB.
 70 | 
 71 | ### Option 2 - Tauri
 72 | 
 73 | [Tauri](https://tauri.app/about/intro) is a toolkit that helps developers make applications for the major desktop platforms - using virtually any frontend framework in existence. The core is built with Rust, and the CLI leverages Node.js making Tauri a genuinely polyglot approach to creating and maintaining great apps.
 74 | 
 75 | **Pros**
 76 | 
 77 | - Tauri supports all requirements for the local development interface via their JavaScript API without the need to write any Rust.
 78 | - It can manage the [file systems](https://tauri.app/v1/api/js/fs), launch another [process](https://tauri.app/v1/api/js/process), run a [shell command](https://tauri.app/v1/api/js/shell).
 79 | - Tauri integrates well with major web frameworks. [`create-tauri-app`](https://github.com/tauri-apps/create-tauri-app) and a good template project can be bootstrapped and working within minutes.
 80 | 
 81 |   - Once bootstrapped, the web app can be bundled individually and deployed as a website. Below is the `npm script` Tauri generates for a Vite project, we can see that it supports `vite build`
 82 | 
 83 |   ```json
 84 |   "scripts": {
 85 |     "dev": "vite",
 86 |     "build": "tsc && vite build",
 87 |     "preview": "vite preview",
 88 |     "tauri": "tauri"
 89 |   },
 90 |   ```
 91 | 
 92 | - For [compiling binaries](https://tauri.app/v1/guides/building/), the Tauri Bundler supports
 93 |   - Windows: setup.exe, .msi
 94 |   - macOS: .app, .dmg
 95 |   - Linux: .deb, .appimage
 96 | - The Tauri Bundler supports code signing for:
 97 |   - [Windows](https://tauri.app/v1/guides/distribution/sign-windows)
 98 |   - [Linux](https://tauri.app/v1/guides/distribution/sign-linux)
 99 |   - [macOS](https://tauri.app/v1/guides/distribution/sign-macos)
100 | - Tauri offers a [built-in updater](https://tauri.app/v1/guides/distribution/updater) for the NSIS (Windows), MSI (Windows), AppImage (Linux) and App bundle (macOS) distribution formats.
101 | - Tauri is reasonably efficient, for a small test app (Hello World) it uses 30 MB of RAM and 0.1% CPU (running on macOS M1 CPU and 32GB RAM).
102 | - When built on a local dev machine, the package size for macOS is ~5MB.
103 | 
104 | **Cons**
105 | 
106 | - If we need to extend the functionality beyond the support of Tauri's JavaScript API, we will need to write the code in Rust, which would be a new language in the AlgoKit ecosystem and a less common skill in the team.
107 | - At the point of writing, building with `snap` (for Linux) isn't officially supported by Tauri. There is a open [PR](https://github.com/tauri-apps/tauri/pull/6532). We can however support snap by packaging the Linux build output ourselves.
108 | - Tauri relies on [Webview](https://tauri.app/v1/references/webview-versions/) which are not the same across platforms. This means that we'll need to perform more testing on the styling and rendering, to ensure a consistent experience across the different platform Webviews and the supported versions.
109 |   - For reference, [here](https://github.com/tauri-apps/tauri/issues?q=is%3Aissue+webview+css) are Tauri's issues related to CSS.
110 | - For some versions of Windows 10, WebView2 needs to be installed. This process requires internet connection whilst installing.
111 | 
112 | ### Option 3 - Wails
113 | 
114 | [Wails](https://wails.io/) is similar to Tauri but the core is written in Go.
115 | 
116 | **Pros**
117 | 
118 | - Wails has init templates for major web framework. React + TypeScript + Vite is supported.
119 | - Wails has an auto codegen to generate the contract between the main process and the renderer process.
120 | - Wails doesn't have built-in code signing for Windows and Mac. However, the document on how to do code signing with GitHub actions is very detailed.
121 | - Wails is reasonably efficient, for a small test app (Hello World) it uses 30 MB of RAM and 0.1% CPU (running on macOS M1 CPU and 32GB RAM).
122 | - When built on a local dev machine, the package size for macOS is ~5MB.
123 | 
124 | **Cons**
125 | 
126 | - Documentation isn't as comprehensive as Electron and Tauri. Because of this, I didn't investigate much further into Wails. Tauri seems to be a more supported project, Wails doesn't give us anything additional.
127 | - The code to interact with file systems, shell and child processes will be written in Go, which would be a new language in the AlgoKit ecosystem and a less common skill in the team.
128 | - No built-in updater. It is tracked in this [issue](https://github.com/wailsapp/wails/issues/1178).
129 | - Wails is based on WebView, therefore, it has the same cross-platform issues with Tauri.
130 | - Wails supports building for Windows, Mac and Linux. The documentation however isn't super clear:
131 |   - I could build Windows binaries from Mac.
132 |   - I couldn't build Linux binaries from Mac.
133 |   - The document doesn't mention options to build installers.
134 | 
135 | ## Preferred option
136 | 
137 | - **Option2** Tauri is the preferred option because it is well documented and has a big community behind it. Tauri supports all of our use cases and is less resource hungry than Electron.
138 | 
139 | ## Selected option
140 | 
141 | Option 2
142 | 
143 | Given the good community support, great docs, low resource consumption and not needing to write much (if any) Rust, Tauri (Option 2) appears to fit our needs very well.
144 | 
```

--------------------------------------------------------------------------------
/packages/server/tests/tools/utilityManager.test.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
  2 | import { UtilityManager } from '../../src/tools/utilityManager';
  3 | import algosdk from 'algosdk';
  4 | 
  5 | // Rest of the file remains the same...
  6 | // Mock algosdk
  7 | jest.mock('algosdk', () => ({
  8 |   isValidAddress: jest.fn(),
  9 |   encodeAddress: jest.fn(),
 10 |   decodeAddress: jest.fn(),
 11 |   getApplicationAddress: jest.fn(),
 12 | }));
 13 | 
 14 | describe('UtilityManager', () => {
 15 |   beforeEach(() => {
 16 |     jest.clearAllMocks();
 17 |   });
 18 | 
 19 |   describe('Tool Schemas', () => {
 20 |     it('should have valid tool schemas', () => {
 21 |       expect(UtilityManager.utilityTools).toHaveLength(8);
 22 |       expect(UtilityManager.utilityTools.map((t: { name: string; }) => t.name)).toEqual([
 23 |         'validate_address',
 24 |         'encode_address',
 25 |         'decode_address',
 26 |         'get_application_address',
 27 |         'bytes_to_bigint',
 28 |         'bigint_to_bytes',
 29 |         'encode_uint64',
 30 |         'decode_uint64',
 31 |       ]);
 32 |     });
 33 |   });
 34 | 
 35 |   describe('Address Operations', () => {
 36 |     const testAddress = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
 37 |     const testPublicKey = Buffer.from('0'.repeat(64), 'hex');
 38 | 
 39 |     it('should validate address', () => {
 40 |       (algosdk.isValidAddress as jest.Mock).mockReturnValue(true);
 41 |       
 42 |       const result = UtilityManager.isValidAddress(testAddress);
 43 |       
 44 |       expect(result).toBe(true);
 45 |       expect(algosdk.isValidAddress).toHaveBeenCalledWith(testAddress);
 46 |     });
 47 | 
 48 |     it('should encode address', () => {
 49 |       (algosdk.encodeAddress as jest.Mock).mockReturnValue(testAddress);
 50 |       
 51 |       const result = UtilityManager.encodeAddress(testPublicKey);
 52 |       
 53 |       expect(result).toBe(testAddress);
 54 |       expect(algosdk.encodeAddress).toHaveBeenCalledWith(testPublicKey);
 55 |     });
 56 | 
 57 |     it('should decode address', () => {
 58 |       (algosdk.decodeAddress as jest.Mock).mockReturnValue({ publicKey: testPublicKey });
 59 |       
 60 |       const result = UtilityManager.decodeAddress(testAddress);
 61 |       
 62 |       expect(result).toBe(testPublicKey);
 63 |       expect(algosdk.decodeAddress).toHaveBeenCalledWith(testAddress);
 64 |     });
 65 | 
 66 |     it('should get application address', () => {
 67 |       const appId = 123;
 68 |       const appAddress = 'APP_ADDRESS';
 69 |       (algosdk.getApplicationAddress as jest.Mock).mockReturnValue(appAddress);
 70 |       
 71 |       const result = UtilityManager.getApplicationAddress(appId);
 72 |       
 73 |       expect(result).toBe(appAddress);
 74 |       expect(algosdk.getApplicationAddress).toHaveBeenCalledWith(appId);
 75 |     });
 76 |   });
 77 | 
 78 |   describe('BigInt Operations', () => {
 79 |     it('should convert bytes to BigInt', () => {
 80 |       const bytes = Buffer.from('0001', 'hex');
 81 |       const result = UtilityManager.bytesToBigInt(bytes);
 82 |       expect(result.toString()).toBe('1');
 83 |     });
 84 | 
 85 |     it('should convert BigInt to bytes', () => {
 86 |       const value = BigInt(1);
 87 |       const size = 2;
 88 |       const result = UtilityManager.bigIntToBytes(value, size);
 89 |       expect(Buffer.from(result).toString('hex')).toBe('0001');
 90 |     });
 91 | 
 92 |     it('should encode uint64', () => {
 93 |       const value = BigInt(1);
 94 |       const result = UtilityManager.encodeUint64(value);
 95 |       expect(Buffer.from(result).toString('hex')).toBe('0000000000000001');
 96 |     });
 97 | 
 98 |     it('should decode uint64', () => {
 99 |       const bytes = Buffer.from('0000000000000001', 'hex');
100 |       const result = UtilityManager.decodeUint64(bytes);
101 |       expect(result.toString()).toBe('1');
102 |     });
103 |   });
104 | 
105 |   describe('handleTool', () => {
106 |     it('should handle validate_address', async () => {
107 |       (algosdk.isValidAddress as jest.Mock).mockReturnValue(true);
108 |       
109 |       const result = await UtilityManager.handleTool('validate_address', {
110 |         address: 'test-address',
111 |       });
112 | 
113 |       expect(result).toEqual({
114 |         content: [{
115 |           type: 'text',
116 |           text: JSON.stringify({ isValid: true }, null, 2),
117 |         }],
118 |       });
119 |     });
120 | 
121 |     it('should handle encode_address', async () => {
122 |       const testAddress = 'encoded-address';
123 |       (algosdk.encodeAddress as jest.Mock).mockReturnValue(testAddress);
124 |       
125 |       const result = await UtilityManager.handleTool('encode_address', {
126 |         publicKey: '00',
127 |       });
128 | 
129 |       expect(result).toEqual({
130 |         content: [{
131 |           type: 'text',
132 |           text: JSON.stringify({ address: testAddress }, null, 2),
133 |         }],
134 |       });
135 |     });
136 | 
137 |     it('should handle decode_address', async () => {
138 |       const testPublicKey = Buffer.from('00', 'hex');
139 |       (algosdk.decodeAddress as jest.Mock).mockReturnValue({ publicKey: testPublicKey });
140 |       
141 |       const result = await UtilityManager.handleTool('decode_address', {
142 |         address: 'test-address',
143 |       });
144 | 
145 |       expect(result).toEqual({
146 |         content: [{
147 |           type: 'text',
148 |           text: JSON.stringify({ publicKey: '00' }, null, 2),
149 |         }],
150 |       });
151 |     });
152 | 
153 |     it('should handle get_application_address', async () => {
154 |       const appAddress = 'app-address';
155 |       (algosdk.getApplicationAddress as jest.Mock).mockReturnValue(appAddress);
156 |       
157 |       const result = await UtilityManager.handleTool('get_application_address', {
158 |         appId: 123,
159 |       });
160 | 
161 |       expect(result).toEqual({
162 |         content: [{
163 |           type: 'text',
164 |           text: JSON.stringify({ address: appAddress }, null, 2),
165 |         }],
166 |       });
167 |     });
168 | 
169 |     it('should handle bytes_to_bigint', async () => {
170 |       const result = await UtilityManager.handleTool('bytes_to_bigint', {
171 |         bytes: '0001',
172 |       });
173 | 
174 |       expect(result).toEqual({
175 |         content: [{
176 |           type: 'text',
177 |           text: JSON.stringify({ value: '1' }, null, 2),
178 |         }],
179 |       });
180 |     });
181 | 
182 |     it('should handle bigint_to_bytes', async () => {
183 |       const result = await UtilityManager.handleTool('bigint_to_bytes', {
184 |         value: '1',
185 |         size: 2,
186 |       });
187 | 
188 |       expect(result).toEqual({
189 |         content: [{
190 |           type: 'text',
191 |           text: JSON.stringify({ bytes: '0001' }, null, 2),
192 |         }],
193 |       });
194 |     });
195 | 
196 |     it('should handle encode_uint64', async () => {
197 |       const result = await UtilityManager.handleTool('encode_uint64', {
198 |         value: '1',
199 |       });
200 | 
201 |       expect(result).toEqual({
202 |         content: [{
203 |           type: 'text',
204 |           text: JSON.stringify({ bytes: '0000000000000001' }, null, 2),
205 |         }],
206 |       });
207 |     });
208 | 
209 |     it('should handle decode_uint64', async () => {
210 |       const result = await UtilityManager.handleTool('decode_uint64', {
211 |         bytes: '0000000000000001',
212 |       });
213 | 
214 |       expect(result).toEqual({
215 |         content: [{
216 |           type: 'text',
217 |           text: JSON.stringify({ value: '1' }, null, 2),
218 |         }],
219 |       });
220 |     });
221 | 
222 |     describe('Error Handling', () => {
223 |       it('should throw error for unknown tool', async () => {
224 |         await expect(UtilityManager.handleTool('unknown_tool', {}))
225 |           .rejects
226 |           .toThrow(new McpError(ErrorCode.MethodNotFound, 'Unknown tool: unknown_tool'));
227 |       });
228 | 
229 |       it('should throw error for missing address in validate_address', async () => {
230 |         await expect(UtilityManager.handleTool('validate_address', {}))
231 |           .rejects
232 |           .toThrow(new McpError(ErrorCode.InvalidParams, 'Address is required'));
233 |       });
234 | 
235 |       it('should throw error for missing public key in encode_address', async () => {
236 |         await expect(UtilityManager.handleTool('encode_address', {}))
237 |           .rejects
238 |           .toThrow(new McpError(ErrorCode.InvalidParams, 'Public key is required'));
239 |       });
240 | 
241 |       it('should throw error for missing address in decode_address', async () => {
242 |         await expect(UtilityManager.handleTool('decode_address', {}))
243 |           .rejects
244 |           .toThrow(new McpError(ErrorCode.InvalidParams, 'Address is required'));
245 |       });
246 | 
247 |       it('should throw error for missing app ID in get_application_address', async () => {
248 |         await expect(UtilityManager.handleTool('get_application_address', {}))
249 |           .rejects
250 |           .toThrow(new McpError(ErrorCode.InvalidParams, 'Application ID is required'));
251 |       });
252 | 
253 |       it('should throw error for missing bytes in bytes_to_bigint', async () => {
254 |         await expect(UtilityManager.handleTool('bytes_to_bigint', {}))
255 |           .rejects
256 |           .toThrow(new McpError(ErrorCode.InvalidParams, 'Bytes are required'));
257 |       });
258 | 
259 |       it('should throw error for missing value or size in bigint_to_bytes', async () => {
260 |         await expect(UtilityManager.handleTool('bigint_to_bytes', {}))
261 |           .rejects
262 |           .toThrow(new McpError(ErrorCode.InvalidParams, 'Value and size are required'));
263 |       });
264 | 
265 |       it('should throw error for missing value in encode_uint64', async () => {
266 |         await expect(UtilityManager.handleTool('encode_uint64', {}))
267 |           .rejects
268 |           .toThrow(new McpError(ErrorCode.InvalidParams, 'Value is required'));
269 |       });
270 | 
271 |       it('should throw error for missing bytes in decode_uint64', async () => {
272 |         await expect(UtilityManager.handleTool('decode_uint64', {}))
273 |           .rejects
274 |           .toThrow(new McpError(ErrorCode.InvalidParams, 'Bytes are required'));
275 |       });
276 |     });
277 |   });
278 | });
279 | 
```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/ARCs:specs:arc-0069.md:
--------------------------------------------------------------------------------

```markdown
  1 | ---
  2 | arc: 69
  3 | title: ASA Parameters Conventions, Digital Media
  4 | description: Alternatives conventions for ASAs containing digital media.
  5 | author: Chris Antaki (@ChrisAntaki), AlgoKittens (@algokittens), TommyAlex79 (@TommyAlex79)
  6 | discussions-to: https://github.com/algorandfoundation/ARCs/issues/64
  7 | status: Final
  8 | type: Standards Track
  9 | category: ARC
 10 | sub-category: Asa
 11 | created: 2021-08-07
 12 | ---
 13 | 
 14 | # Community Algorand Standard Asset Parameters Conventions for Digital Media Tokens
 15 | 
 16 | We introduce community conventions for the parameters of Algorand Standard Assets (ASAs) containing digital media.
 17 | 
 18 | ## Abstract
 19 | 
 20 | The goal of these conventions is to make it simpler to display the properties of a given ASA. This ARC differs from [ARC-3](./arc-0003.md) by focusing on optimization for fetching of digital media, as well as the use of onchain metadata. Furthermore, since asset configuration transactions are used to store the metadata, this ARC can be applied to existing ASAs.
 21 | 
 22 | While mutability helps with backwards compatibility and other use cases, like leveling up an RPG character, some use cases call for immutability. In these cases, the ASA manager MAY remove the manager address, after which point the Algorand network won't allow anyone to send asset configuration transactions for the ASA. This effectively makes the latest valid [ARC-69](./arc-0069.md) metadata immutable.
 23 | 
 24 | 
 25 | ## Specification
 26 | 
 27 | The key words "**MUST**", "**MUST NOT**", "**REQUIRED**", "**SHALL**", "**SHALL NOT**", "**SHOULD**", "**SHOULD NOT**", "**RECOMMENDED**", "**MAY**", and "**OPTIONAL**" in this document are to be interpreted as described in <a href="https://www.ietf.org/rfc/rfc2119.txt">RFC-2119</a>.
 28 | 
 29 | An ARC-69 ASA has an associated JSON Metadata file, formatted as specified below, that is stored on-chain in the note field of the most recent asset configuration transaction (that contains a note field with a valid ARC-69 JSON metadata).
 30 | 
 31 | ### ASA Parameters Conventions
 32 | 
 33 | The ASA parameters should follow the following conventions:
 34 | 
 35 | * *Unit Name* (`un`): no restriction.
 36 | * *Asset Name* (`an`): no restriction.
 37 | * *Asset URL* (`au`): a URI pointing to digital media file. This URI:
 38 |     * **SHOULD** be persistent.
 39 |     * **SHOULD** link to a file small enough to fetch quickly in a gallery view.
 40 |     * **MUST** follow <a href="https://www.ietf.org/rfc/rfc3986.txt">RFC-3986</a> and **MUST NOT** contain any whitespace character.
 41 |     * **SHOULD** specify media type with `#` fragment identifier at end of URL. This format **MUST** follow: `#i` for images, `#v` for videos, `#a` for audio, `#p` for PDF, or `#h` for HTML/interactive digital media.  If unspecified, assume Image.
 42 |     * **SHOULD** use one of the following URI schemes (for compatibility and security): *https* and *ipfs*:
 43 |         * When the file is stored on IPFS, the `ipfs://...` URI **SHOULD** be used. IPFS Gateway URI (such as `https://ipfs.io/ipfs/...`) **SHOULD NOT** be used.
 44 |     * **SHOULD NOT** use the following URI scheme: *http* (due to security concerns).
 45 | * *Asset Metadata Hash* (`am`): the SHA-256 digest of the full resolution media file as a 32-byte string (as defined in <a href="https://doi.org/10.6028/NIST.FIPS.180-4">NIST FIPS 180-4</a> )
 46 |     * **OPTIONAL**
 47 | * *Freeze Address* (`f`):
 48 |     * **SHOULD** be empty, unless needed for royalties or other use cases
 49 | * *Clawback Address* (`c`):
 50 |     * **SHOULD** be empty, unless needed for royalties or other use cases
 51 | 
 52 | 
 53 | There are no requirements regarding the manager account of the ASA, or the reserve account. However, if immutability is required the manager address **MUST** be removed.
 54 | 
 55 | Furthermore, the manager address, if present, **SHOULD** be under the control of the ASA creator, as the manager address can unilaterally change the metadata. Some advanced use cases **MAY** use a logicsig as ASA manager, if the logicsig only allows to set the note fields by the ASA creator.
 56 | 
 57 | ### JSON Metadata File Schema
 58 | 
 59 | ```json
 60 | {
 61 |     "title": "Token Metadata",
 62 |     "type": "object",
 63 |     "properties": {
 64 |         "standard": {
 65 |             "type": "string",
 66 |             "value": "arc69",
 67 |             "description": "(Required) Describes the standard used."
 68 |         },
 69 |         "description": {
 70 |             "type": "string",
 71 |             "description": "Describes the asset to which this token represents."
 72 |         },
 73 |         "external_url": {
 74 |             "type": "string",
 75 |             "description": "A URI pointing to an external website. Borrowed from Open Sea's metadata format (https://docs.opensea.io/docs/metadata-standards)."
 76 |         },
 77 |         "media_url": {
 78 |             "type": "string",
 79 |             "description": "A URI pointing to a high resolution version of the asset's media."
 80 |         },
 81 |         "properties": {
 82 |             "type": "object",
 83 |             "description": "Properties following the EIP-1155 'simple properties' format. (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1155.md#erc-1155-metadata-uri-json-schema)"
 84 |         },
 85 |         "mime_type": {
 86 |             "type": "string",
 87 |             "description": "Describes the MIME type of the ASA's URL (`au` field)."
 88 |         },
 89 |         "attributes": {
 90 |             "type": "array",
 91 |             "description": "(Deprecated. New NFTs should define attributes with the simple `properties` object. Marketplaces should support both the `properties` object and the `attributes` array). The `attributes` array follows Open Sea's format: https://docs.opensea.io/docs/metadata-standards#attributes"
 92 |         }
 93 |     },
 94 |     "required":[
 95 |         "standard"
 96 |     ]
 97 | }
 98 | ```
 99 | The `standard` field is **REQUIRED** and **MUST** equal `arc69`. All other fields are **OPTIONAL**. If provided, the other fields **MUST** match the description in the JSON schema.
100 | 
101 | The URI field (`external_url`) is defined similarly to the Asset URL parameter `au`.
102 | However, contrary to the Asset URL, the `external_url` does not need to link to the digital media file.
103 | 
104 | #### MIME Type
105 | 
106 | In addition to specifying a data type in the ASA's URL (`au` field) with a URI fragment (ex: `#v` for video), the JSON Metadata schema also allows indication of the URL's MIME type (ex: `video/mp4`) via the `mime_type` field.
107 | 
108 | #### Examples
109 | 
110 | ##### Basic Example
111 | 
112 | An example of an ARC-69 JSON Metadata file for a song follows. The properties array proposes some **SUGGESTED** formatting for token-specific display properties and metadata.
113 | 
114 | ```json
115 | {
116 |   "standard": "arc69",
117 |   "description": "arc69 theme song",
118 |   "external_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
119 |   "mime_type": "video/mp4",
120 |   "properties": {
121 |     "Bass":"Groovy",
122 |     "Vibes":"Funky",
123 |     "Overall":"Good stuff"
124 |   }
125 | }
126 | ```
127 | 
128 | An example of possible ASA parameters would be:
129 | 
130 | * *Asset Name*: `ARC-69 theme song` for example.
131 | * *Unit Name*: `69TS` for example.
132 | * *Asset URL*: `ipfs://QmWS1VAdMD353A6SDk9wNyvkT14kyCiZrNDYAad4w1tKqT#v`
133 | * *Metadata Hash*: the 32 bytes of the SHA-256 digest of the high resolution media file.
134 | * *Total Number of Units*: 1
135 | * *Number of Digits after the Decimal Point*: 0
136 | 
137 | #### Mutability
138 | 
139 | ##### Rendering
140 | 
141 | Clients **SHOULD** render an ASA's latest ARC-69 metadata. Clients **MAY** render an ASA's previous ARC-69 metadata for changelogs or other historical features.
142 | 
143 | ##### Updating ARC-69 metadata
144 | 
145 | If an ASA has a manager address, then the manager **MAY** update an ASA's ARC-69 metadata. To do so, the manager sends a new `acfg` transaction with the entire metadata represented as JSON in the transaction's `note` field.
146 | 
147 | ##### Making ARC-69 metadata immutable
148 | 
149 | Managers MAY make an ASA's ARC-69 immutable. To do so, they MUST remove the ASA's manager address with an `acfg` transaction.
150 | 
151 | ##### ARC-69 attribute deprecation
152 | 
153 | The initial version of ARC-69 followed the Open Sea attributes format https://docs.opensea.io/docs/metadata-standards#attributes. As illustrated below:
154 | ```
155 | "attributes": {
156 | "type": "array",
157 | "description": "Attributes following Open Sea's attributes format (https://docs.opensea.io/docs/metadata-standards#attributes)."
158 | }
159 | ```
160 | This format is now deprecated. New NFTs **SHOULD** use the simple `properties` format, since it significantly reduces the metadata size.
161 | 
162 | To be fully compliant with the ARC-69 standard, both the `properties` object and the `attributes` array **SHOULD** be supported.
163 | 
164 | ## Rationale
165 | 
166 | These conventions take inspiration from <a href="https://docs.opensea.io/docs/metadata-standards">Open Sea's metadata standards</a> and <a href="https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1155.md#erc-1155-metadata-uri-json-schema">EIP-1155</a>
167 | 
168 | to facilitate interoperobility.
169 | 
170 | The main differences are highlighted below:
171 | 
172 | * Asset Name, Unit Name, and URL are specified in the ASA parameters. This allows applications to efficiently display meaningful information, even if they aren't aware of ARC-69 metadata.
173 | * MIME types help clients more effectively fetch and render media.
174 | * All asset metadata is stored onchain.
175 | * Metadata can be either mutable or immutable.
176 | 
177 | ## Security Considerations
178 | 
179 | None.
180 | 
181 | ## Copyright
182 | 
183 | Copyright and related rights waived via <a href="https://creativecommons.org/publicdomain/zero/1.0/">CCO</a>.
184 | 
```

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

```markdown
 1 | title: Algorand State Proofs Overview
 2 | 
 3 | A State Proof is a cryptographic proof of state changes that occur in a given set of blocks. While other interoperability solutions use intermediaries to “prove” blockchain activity, State Proofs are created and signed by the Algorand network itself. The same participants that reach consensus on new blocks sign a message attesting to a summary of recent Algorand transactions. These signatures are then compressed into a [compact certificate of collective knowledge](https://people.csail.mit.edu/nickolai/papers/micali-compactcert-eprint.pdf), also known as a State Proof.
 4 | 
 5 | After a State Proof is created, a State Proof transaction, which includes the State Proof and the message it proves, is created and sent to the Algorand network for validation. The transaction goes through [consensus](../algorand_consensus.md) like any other pending Algorand transaction: it gets validated by participation nodes, included in a block proposal, and written to the blockchain.
 6 | 
 7 | Each State Proof can be used to power lightweight services that verify Algorand transactions without running consensus or storing a copy of the Algorand ledger. These external services, or “Light Clients'', can efficiently verify proofs of Algorand state (either State Proofs or State Proof derived zk-SNARK proofs) in low-power environments like a smartphone, IoT device, or even inside a blockchain smart contract. For each verified State Proof, the Light Client can store the message’s transaction summary, giving it a light, verified history of Algorand state. Depending on its storage budget, a Light Client could store all State Proof history, giving it the ability to efficiently, cryptographically verify any Algorand transaction which occurred since the first State Proof was written on-chain.
 8 | 
 9 | Since Algorand users already trust the Algorand network’s ability to reach consensus on new blocks, we call these State Proof transactions, and the Light Clients they power, “trustless.” By providing simple interfaces to verify Algorand transactions, these Light Clients make it safer and easier to develop and use cross-chain products and services which want to leverage the state of the Algorand blockchain.
10 | 
11 | # How State Proofs are Generated
12 | Each State Proof represents a collection of weighted signatures that attest to a specific message. In Algorand’s case, each State Proof message contains a commitment to all transactions that occurred over a period of 256 rounds, known as the State Proof Interval. Each proof convinces verifiers that participating accounts who jointly have a sufficient total portion of online Algorand stake have attested to this message, without seeing or verifying all of the signatures.
13 | 
14 | Every block that is processed on the Algorand chain has a header containing a commitment to all transactions in that block. This Transaction Commitment is the root of a tree with all transactions in that block as leaves. At the end of each State Proof Interval, nodes assemble the block interval commitment by using each of the 256 Transaction Commitments from this interval as leaves. This commitment is then included in the State Proofs message, which is signed by network participants.
15 | 
16 | The process for generating a State Proof for a specific block interval actually starts at the generation of the previous State Proof. For example, if a State Proof is being generated for round 768, the following steps will occur:
17 | 
18 | 1. On round 512 (=768 - 256), every participating node would create a participation commitment for the top N online accounts, composed of their public state proof keys and relative online stake. When a node is elected to propose a block through consensus, it includes this commitment in the block header. 
19 | 2. On round 769, every participating node executes the following steps for each online account it manages:
20 |    
21 |     A. Build a Block Interval commitment tree based on all the blocks in the interval. This tree’s leaves are created using the transaction commitment from each of the blocks’ headers. This block interval will include rounds [513,...,768]. 
22 | 
23 |     B. Assemble a [message](https://github.com/algorand/go-algorand/blob/fd488f806dcbc2586f585155eea0180c30287f70/daemon/algod/api/server/v2/generated/types.go#L470) containing this Block Interval Commitment and some other metadata, sign the message, and propagate it to the network using the standard protocol gossip framework.
24 | 
25 | 3. Relay nodes receive the signed messages and verify them. These signatures are accumulated based on the signer's weight and added to a Signature array. Once the relay node has sufficient signed weight accumulated, the relay node constructs a State Proof that contains a randomized sample of accumulated signatures which can convince a verifier that at least 30% of the top N accounts have signed the State Proof message.
26 | 4. After creating the proof, the relay node constructs a State Proof transaction, composed of the message and its corresponding proof, and submits it to the network. This transaction (first in wins) is processed with normal consensus. Participation nodes run the state proof verification algorithm to make sure that this State Proof is valid, using the expected signers from round 512’s on-chain participation commitment as reference. Once through consensus, the transaction is written to the blockchain.
27 | 
28 | For a deeper dive into the cryptography behind State Proofs, check out this [presentation](https://www.youtube.com/watch?v=gbk74npcs-g).
29 | 
30 | Note that each State Proof is linked together by a series of participation commitments indicating which accounts should produce signatures for the next State Proof, and their weights. These commitments form a chain linking the most recent proof written on-chain to the genesis State Proof from launch day. Since the set of participants is committed ahead of time, and each participants’ signature is produced using quantum-safe Falcon keys, we can have confidence that each verifiable State Proof was produced by actual network participants. This means that any State Proof verifier can have full confidence that the transactions committed to in each State Proof message are in fact legitimate, even in an age where powerful quantum computers attempt attacks. By producing quantum-safe proofs of the history of the blockchain, Algorand reaches its first milestone towards post-quantum security.
31 | 
32 | # Using State Proofs
33 | State Proofs allow others to verify Algorand transactions while taking on minimal trust assumptions. Specifically, someone verifying Algorand transactions via a State Proof Light Client needs to trust the following:
34 | 
35 | 1. The Algorand blockchain’s ability to reach consensus on valid transactions.
36 | 2. The first “participants” commitment that initialized the Light Client was obtained in a trustworthy way (this specifies the eligible voters for the genesis State Proof).
37 | 3. The State Proof verifier code inside the Light Client was implemented correctly.
38 | 4. Algorand’s new cryptographic primitives are secure ([Sumhash](https://github.com/algorand/go-sumhash/blob/master/cryptanalysis/merging-trees-ss.pdf), [Falcon](https://github.com/algorand/falcon)).
39 | 5. (Depending on the use case): The environment where the Algorand Light Client code is running is secure (e.g. another blockchain’s smart contract).
40 | 
41 | To verify an Algorand transaction outside of the Algorand blockchain, external processes need to understand the structure of how transactions are hashed into the Block Interval commitment. This is done using two commitment trees that are explained below.
42 | 
43 | ## Transaction Commitment
44 | A transaction commitment is created for every block that occurs on the Algorand blockchain. The root of this tree is stored in the block header.
45 | 
46 | <center>
47 | ![Transaction Commitment](../../imgs/transaction_commitment.png)
48 | </center>
49 | 
50 | The leaf nodes in this tree are sequenced in the same order as the transactions in the block.  
51 | 
52 | ## Block Interval Commitment Tree
53 | Once all of the blocks in a 256-round state proof interval have been certified on-chain, participating nodes generate a Block Interval commitment tree to attest to all transactions for the blocks in the period. The leaves of this block interval commitment are made of light block headers for each round contained within the interval. Each light block header contains the round number and the transaction commitment root for the given block.
54 | 
55 | Participating accounts add the root of this commitment tree to a State Proof message, sign the message with their State Proof keys, and then propagate it to the network. The root of this commitment tree can be used in conjunction with a set of transaction and block interval proofs to verify any transaction in this period.
56 | 
57 | <center>
58 | ![Block Interval Commitment](../../imgs/block_interval_commitment.png)
59 | </center>
60 | 
61 | The Algorand SDK provides clients that can make API calls to retrieve these commitment roots and proofs for verifying specific transactions. For more information on implementing a verifier or using the SDKs, continue reading on [How to Build an Algorand Light Client](light_client.md).
62 | 
```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/algokit:utils:python:markdown:capabilities:app-deploy.md:
--------------------------------------------------------------------------------

```markdown
  1 | # App deployment
  2 | 
  3 | Idempotent (safely retryable) deployment of an app, including deploy-time immutability and permanence control and TEAL template substitution
  4 | 
  5 | App deployment is a higher-order use case capability provided by AlgoKit Utils that builds on top of the core capabilities,
  6 | particularly [App management](app-client.md). It allows you to idempotently (with safe retryability) deploy an app, including deploy-time immutability and permanence control and
  7 | TEAL template substitution.
  8 | 
  9 | To see some usage examples check out the [automated tests](https://github.com/algorandfoundation/algokit-utils-py/blob/main/tests/test_deploy_scenarios.py).
 10 | 
 11 | <a id="design"></a>
 12 | 
 13 | ## Design
 14 | 
 15 | The architecture design behind app deployment is articulated in an [architecture decision record](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/architecture-decisions/2023-01-12_smart-contract-deployment.md).
 16 | While the implementation will naturally evolve over time and diverge from this record, the principles and design goals behind the design are comprehensively explained.
 17 | 
 18 | Namely, it described the concept of a smart contract development lifecycle:
 19 | 
 20 | 1. Development
 21 |    1. **Write** smart contracts
 22 |    2. **Transpile** smart contracts with development-time parameters (code configuration) to TEAL Templates
 23 |    3. **Verify** the TEAL Templates maintain [output stability](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/articles/output_stability.md) and any other static code quality checks
 24 | 2. Deployment
 25 |    1. **Substitute** deploy-time parameters into TEAL Templates to create final TEAL code
 26 |    2. **Compile** the TEAL to create byte code using algod
 27 |    3. **Deploy** the byte code to one or more Algorand networks (e.g. LocalNet, TestNet, MainNet) to create Deployed Application(s)
 28 | 3. Runtime
 29 |    1. **Validate** the deployed app via automated testing of the smart contracts to provide confidence in their correctness
 30 |    2. **Call** deployed smart contract with runtime parameters to utilise it
 31 | 
 32 | ![App deployment lifecycle](images/lifecycle.jpg)
 33 | 
 34 | The App deployment capability provided by AlgoKit Utils helps implement **#2 Deployment**.
 35 | 
 36 | Furthermore, the implementation contains the following implementation characteristics per the original architecture design:
 37 | 
 38 | - Deploy-time parameters can be provided and substituted into a TEAL Template by convention (by replacing `TMPL_{KEY}`)
 39 | - Contracts can be built by any smart contract framework that supports [ARC-0032](https://arc.algorand.foundation/ARCs/arc-0032) and
 40 |   [ARC-0004](https://arc.algorand.foundation/ARCs/arc-0004) ([Beaker](https://beaker.algo.xyz/) or otherwise), which also means the deployment language can be
 41 |   different to the development language e.g. you can deploy a Python smart contract with TypeScript for instance
 42 | - There is explicit control of the immutability (updatability / upgradeability) and permanence (deletability) of the smart contract, which can be varied per environment to allow for easier
 43 |   development and testing in non-MainNet environments (by replacing `TMPL_UPDATABLE` and `TMPL_DELETABLE` at deploy-time by convention, if present)
 44 | - Contracts are resolvable by a string “name” for a given creator to allow automated determination of whether that contract had been deployed previously or not, but can also be resolved by ID
 45 |   instead
 46 | 
 47 | ## Finding apps by creator
 48 | 
 49 | There is a method `algokit.get_creator_apps(creatorAccount, indexer)`, which performs a series of indexer lookups that return all apps created by the given creator. These are indexed by the name it
 50 | was deployed under if the creation transaction contained the following payload in the transaction note field:
 51 | 
 52 | ```default
 53 | ALGOKIT_DEPLOYER:j{name:string, version:string, updatable?:boolean, deletable?:boolean}
 54 | ```
 55 | 
 56 | Any creation transactions or update transactions are then retrieved and processed in chronological order to result in an `AppLookup` object
 57 | 
 58 | Given there are a number of indexer calls to retrieve this data it’s a non-trivial object to create, and it’s recommended that for the duration you are performing a single deployment
 59 | you hold a value of it rather than recalculating it. Most AlgoKit Utils functions that need it will also take an optional value of it that will be used in preference to retrieving a
 60 | fresh version.
 61 | 
 62 | ## Deploying an application
 63 | 
 64 | The method that performs the deployment logic is the instance method `ApplicationClient.deploy`. It performs an idempotent (safely retryable) deployment. It will detect if the app already
 65 | exists and if it doesn’t it will create it. If the app does already exist then it will:
 66 | 
 67 | - Detect if the app has been updated (i.e. the logic has changed) and either fail or perform either an update or a replacement based on the deployment configuration.
 68 | - Detect if the app has a breaking schema change (i.e. more global or local storage is needed than was originally requested) and either fail or perform a replacement based on the
 69 |   deployment configuration.
 70 | 
 71 | It will automatically add metadata to the transaction note of the create or update calls that indicates the name, version, updatability and deletability of the contract.
 72 | This metadata works in concert with `get_creator_apps` to allow the app to be reliably retrieved against that creator in it’s currently deployed state.
 73 | 
 74 | `deploy` automatically executes [template substitution]() including deploy-time control of permanence and immutability.
 75 | 
 76 | ### Input parameters
 77 | 
 78 | The following inputs are used when deploying an App
 79 | 
 80 | - `version`: The version string for the app defined in app_spec, if not specified the version will automatically increment for existing apps that are updated, and set to 1.0 for new apps
 81 | - `signer`, `sender`: Optional signer and sender for deployment operations, sender must be the same as the creator specified
 82 | - `allow_update`, `allow_delete`: Control the updatability and deletability of the app, used to populate `TMPL_UPDATABLE` and `TMPL_DELETABLE` template values
 83 | - `on_update`: Determines what should happen if an update to the smart contract is detected (e.g. the TEAL code has changed since last deployment)
 84 | - `on_schema_break`: Determines what should happen if a breaking change to the schema is detected (e.g. if you need more global or local state that was previously requested when the contract was originally created)
 85 | - `create_args`: Args to use if a create operation is performed
 86 | - `update_args`: Args to use if an update operation is performed
 87 | - `delete_args`: Args to use if a delete operation is performed
 88 | - `template_values`: Values to use for automatic substitution of [deploy-time parameter values]() is mapping of `key: value` that will result in `TMPL_{key}` being replaced with `value`
 89 | 
 90 | ### Idempotency
 91 | 
 92 | `deploy` is idempotent which means you can safely call it again multiple times, and it will only apply any changes it detects. If you call it again straight after calling it then it will
 93 | do nothing. This also means it can be used to find an existing app based on the supplied creator and app_spec or name.
 94 | 
 95 | <a id="compilation-and-template-substitution"></a>
 96 | 
 97 | ### Compilation and template substitution
 98 | 
 99 | When compiling TEAL template code, the capabilities described in the [design above]() are present, namely the ability to supply deploy-time parameters and the ability to control immutability and permanence of the smart contract at deploy-time.
100 | 
101 | In order for a smart contract to be able to use this functionality, it must have a TEAL Template that contains the following:
102 | 
103 | - `TMPL_{key}` - Which can be replaced with a number or a string / byte array which wil be automatically hexadecimal encoded
104 | - `TMPL_UPDATABLE` - Which will be replaced with a `1` if an app should be updatable and `0` if it shouldn’t (immutable)
105 | - `TMPL_DELETABLE` - Which will be replaced with a `1` if an app should be deletable and `0` if it shouldn’t (permanent)
106 | 
107 | If you are building a smart contract using the [beaker_production AlgoKit template](https://github.com/algorandfoundation/algokit-beaker-default-template) if provides a reference implementation out of the box for the deploy-time immutability and permanence control.
108 | 
109 | ### Return value
110 | 
111 | `deploy` returns a `DeployResponse` object, that describes the action taken.
112 | 
113 | - `action_taken`: Describes what happened during deployment
114 |   - `Create` - The smart contract app is created.
115 |   - `Update` - The smart contract app is updated
116 |   - `Replace` - The smart contract app was deleted and created again (in an atomic transaction)
117 |   - `Nothing` - Nothing was done since an existing up-to-date app was found
118 | - `create_response`: If action taken was `Create` or `Replace`, the result of the create transaction. Can be a `TransactionResponse` or `ABITransactionResponse` depending on the method used
119 | - `update_response`: If action taken was `Update`, the result of the update transaction. Can be a `TransactionResponse` or `ABITransactionResponse` depending on the method used
120 | - `delete_response`: If action taken was `Replace`, the result of the delete transaction. Can be a `TransactionResponse` or `ABITransactionResponse` depending on the method used
121 | - `app`: An `AppMetaData` object, describing the final app state
122 | 
```

--------------------------------------------------------------------------------
/packages/server/src/resources/knowledge/taxonomy/algokit:utils:python:source:capabilities:app-deploy.md:
--------------------------------------------------------------------------------

```markdown
  1 | # App deployment
  2 | 
  3 | Idempotent (safely retryable) deployment of an app, including deploy-time immutability and permanence control and TEAL template substitution
  4 | 
  5 | App deployment is a higher-order use case capability provided by AlgoKit Utils that builds on top of the core capabilities,
  6 | particularly [App management](./app-client.md). It allows you to idempotently (with safe retryability) deploy an app, including deploy-time immutability and permanence control and
  7 | TEAL template substitution.
  8 | 
  9 | To see some usage examples check out the [automated tests](https://github.com/algorandfoundation/algokit-utils-py/blob/main/tests/test_deploy_scenarios.py).
 10 | 
 11 | (design)=
 12 | 
 13 | ## Design
 14 | 
 15 | The architecture design behind app deployment is articulated in an [architecture decision record](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/architecture-decisions/2023-01-12_smart-contract-deployment.md).
 16 | While the implementation will naturally evolve over time and diverge from this record, the principles and design goals behind the design are comprehensively explained.
 17 | 
 18 | Namely, it described the concept of a smart contract development lifecycle:
 19 | 
 20 | 1. Development
 21 |    1. **Write** smart contracts
 22 |    2. **Transpile** smart contracts with development-time parameters (code configuration) to TEAL Templates
 23 |    3. **Verify** the TEAL Templates maintain [output stability](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/articles/output_stability.md) and any other static code quality checks
 24 | 2. Deployment
 25 |    1. **Substitute** deploy-time parameters into TEAL Templates to create final TEAL code
 26 |    2. **Compile** the TEAL to create byte code using algod
 27 |    3. **Deploy** the byte code to one or more Algorand networks (e.g. LocalNet, TestNet, MainNet) to create Deployed Application(s)
 28 | 3. Runtime
 29 |    1. **Validate** the deployed app via automated testing of the smart contracts to provide confidence in their correctness
 30 |    2. **Call** deployed smart contract with runtime parameters to utilise it
 31 | 
 32 | ![App deployment lifecycle](../images/lifecycle.jpg)
 33 | 
 34 | The App deployment capability provided by AlgoKit Utils helps implement **#2 Deployment**.
 35 | 
 36 | Furthermore, the implementation contains the following implementation characteristics per the original architecture design:
 37 | 
 38 | - Deploy-time parameters can be provided and substituted into a TEAL Template by convention (by replacing `TMPL_{KEY}`)
 39 | - Contracts can be built by any smart contract framework that supports [ARC-0032](https://arc.algorand.foundation/ARCs/arc-0032) and
 40 |   [ARC-0004](https://arc.algorand.foundation/ARCs/arc-0004) ([Beaker](https://beaker.algo.xyz/) or otherwise), which also means the deployment language can be
 41 |   different to the development language e.g. you can deploy a Python smart contract with TypeScript for instance
 42 | - There is explicit control of the immutability (updatability / upgradeability) and permanence (deletability) of the smart contract, which can be varied per environment to allow for easier
 43 |   development and testing in non-MainNet environments (by replacing `TMPL_UPDATABLE` and `TMPL_DELETABLE` at deploy-time by convention, if present)
 44 | - Contracts are resolvable by a string "name" for a given creator to allow automated determination of whether that contract had been deployed previously or not, but can also be resolved by ID
 45 |   instead
 46 | 
 47 | ## Finding apps by creator
 48 | 
 49 | There is a method `algokit.get_creator_apps(creatorAccount, indexer)`, which performs a series of indexer lookups that return all apps created by the given creator. These are indexed by the name it
 50 | was deployed under if the creation transaction contained the following payload in the transaction note field:
 51 | 
 52 | ```
 53 | ALGOKIT_DEPLOYER:j{name:string, version:string, updatable?:boolean, deletable?:boolean}
 54 | ```
 55 | 
 56 | Any creation transactions or update transactions are then retrieved and processed in chronological order to result in an `AppLookup` object
 57 | 
 58 | Given there are a number of indexer calls to retrieve this data it's a non-trivial object to create, and it's recommended that for the duration you are performing a single deployment
 59 | you hold a value of it rather than recalculating it. Most AlgoKit Utils functions that need it will also take an optional value of it that will be used in preference to retrieving a
 60 | fresh version.
 61 | 
 62 | ## Deploying an application
 63 | 
 64 | The method that performs the deployment logic is the instance method `ApplicationClient.deploy`. It performs an idempotent (safely retryable) deployment. It will detect if the app already
 65 | exists and if it doesn't it will create it. If the app does already exist then it will:
 66 | 
 67 | - Detect if the app has been updated (i.e. the logic has changed) and either fail or perform either an update or a replacement based on the deployment configuration.
 68 | - Detect if the app has a breaking schema change (i.e. more global or local storage is needed than was originally requested) and either fail or perform a replacement based on the
 69 |   deployment configuration.
 70 | 
 71 | It will automatically add metadata to the transaction note of the create or update calls that indicates the name, version, updatability and deletability of the contract.
 72 | This metadata works in concert with `get_creator_apps` to allow the app to be reliably retrieved against that creator in it's currently deployed state.
 73 | 
 74 | `deploy` automatically executes [template substitution](#compilation-and-template-substitution) including deploy-time control of permanence and immutability.
 75 | 
 76 | ### Input parameters
 77 | 
 78 | The following inputs are used when deploying an App
 79 | 
 80 | - `version`: The version string for the app defined in app_spec, if not specified the version will automatically increment for existing apps that are updated, and set to 1.0 for new apps
 81 | - `signer`, `sender`: Optional signer and sender for deployment operations, sender must be the same as the creator specified
 82 | - `allow_update`, `allow_delete`: Control the updatability and deletability of the app, used to populate `TMPL_UPDATABLE` and `TMPL_DELETABLE` template values
 83 | - `on_update`: Determines what should happen if an update to the smart contract is detected (e.g. the TEAL code has changed since last deployment)
 84 | - `on_schema_break`: Determines what should happen if a breaking change to the schema is detected (e.g. if you need more global or local state that was previously requested when the contract was originally created)
 85 | - `create_args`: Args to use if a create operation is performed
 86 | - `update_args`: Args to use if an update operation is performed
 87 | - `delete_args`: Args to use if a delete operation is performed
 88 | - `template_values`: Values to use for automatic substitution of [deploy-time parameter values](#design) is mapping of `key: value` that will result in `TMPL_{key}` being replaced with `value`
 89 | 
 90 | ### Idempotency
 91 | 
 92 | `deploy` is idempotent which means you can safely call it again multiple times, and it will only apply any changes it detects. If you call it again straight after calling it then it will
 93 | do nothing. This also means it can be used to find an existing app based on the supplied creator and app_spec or name.
 94 | 
 95 | (compilation-and-template-substitution)=
 96 | 
 97 | ### Compilation and template substitution
 98 | 
 99 | When compiling TEAL template code, the capabilities described in the [design above](#design) are present, namely the ability to supply deploy-time parameters and the ability to control immutability and permanence of the smart contract at deploy-time.
100 | 
101 | In order for a smart contract to be able to use this functionality, it must have a TEAL Template that contains the following:
102 | 
103 | - `TMPL_{key}` - Which can be replaced with a number or a string / byte array which wil be automatically hexadecimal encoded
104 | - `TMPL_UPDATABLE` - Which will be replaced with a `1` if an app should be updatable and `0` if it shouldn't (immutable)
105 | - `TMPL_DELETABLE` - Which will be replaced with a `1` if an app should be deletable and `0` if it shouldn't (permanent)
106 | 
107 | If you are building a smart contract using the [beaker_production AlgoKit template](https://github.com/algorandfoundation/algokit-beaker-default-template) if provides a reference implementation out of the box for the deploy-time immutability and permanence control.
108 | 
109 | ### Return value
110 | 
111 | `deploy` returns a `DeployResponse` object, that describes the action taken.
112 | 
113 | - `action_taken`: Describes what happened during deployment
114 |   - `Create` - The smart contract app is created.
115 |   - `Update` - The smart contract app is updated
116 |   - `Replace` - The smart contract app was deleted and created again (in an atomic transaction)
117 |   - `Nothing` - Nothing was done since an existing up-to-date app was found
118 | - `create_response`: If action taken was `Create` or `Replace`, the result of the create transaction. Can be a `TransactionResponse` or `ABITransactionResponse` depending on the method used
119 | - `update_response`: If action taken was `Update`, the result of the update transaction. Can be a `TransactionResponse` or `ABITransactionResponse` depending on the method used
120 | - `delete_response`: If action taken was `Replace`, the result of the delete transaction. Can be a `TransactionResponse` or `ABITransactionResponse` depending on the method used
121 | - `app`: An `AppMetaData` object, describing the final app state
122 | 
```

--------------------------------------------------------------------------------
/packages/server/src/utils/responseProcessor.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { Buffer } from 'buffer';
  2 | import { env } from '../env.js';
  3 | 
  4 | export interface PaginationMetadata {
  5 |   totalItems: number;
  6 |   itemsPerPage: number;
  7 |   currentPage: number;
  8 |   totalPages: number;
  9 |   hasNextPage: boolean;
 10 |   pageToken?: string;
 11 | }
 12 | 
 13 | export interface PaginatedResponse<T> {
 14 |   data: T;
 15 |   metadata: PaginationMetadata & {
 16 |     arrayField?: string;
 17 |   };
 18 | }
 19 | 
 20 | export interface ProcessedResponse {
 21 |   [key: string]: any;
 22 |   content?: any[];
 23 |   metadata?: PaginationMetadata & {
 24 |     arrayField?: string;
 25 |   };
 26 | }
 27 | 
 28 | export class ResponseProcessor {
 29 |   private static generateNextPageToken(page: number): string {
 30 |     const token = Buffer.from(`page_${page}`).toString('base64');
 31 |     console.log('[Pagination] Generated token:', { page, token });
 32 |     return token;
 33 |   }
 34 | 
 35 |   private static decodePageToken(token: string): number {
 36 |     console.log('[Pagination] Decoding token:', token);
 37 |     try {
 38 |       const decoded = Buffer.from(token, 'base64').toString();
 39 |       console.log('[Pagination] Decoded token string:', decoded);
 40 |       const page = parseInt(decoded.replace('page_', ''));
 41 |       console.log('[Pagination] Parsed page number:', page);
 42 |       return isNaN(page) ? 1 : page;
 43 |     } catch (error) {
 44 |       console.log('[Pagination] Error decoding token:', error);
 45 |       return 1;
 46 |     }
 47 |   }
 48 | 
 49 |   private static shouldPaginateArray(array: any[]): boolean {
 50 |     const should = array.length > env.items_per_page;
 51 |     console.log('[Pagination] Should paginate array?', { 
 52 |       arrayLength: array.length, 
 53 |       itemsPerPage: env.items_per_page,
 54 |       shouldPaginate: should 
 55 |     });
 56 |     return should;
 57 |   }
 58 | 
 59 |   private static shouldPaginateObject(obj: any): boolean {
 60 |     const should = Object.keys(obj).length > env.items_per_page;
 61 |     console.log('[Pagination] Should paginate object?', {
 62 |       objectKeys: Object.keys(obj).length,
 63 |       itemsPerPage: env.items_per_page,
 64 |       shouldPaginate: should
 65 |     });
 66 |     return should;
 67 |   }
 68 | 
 69 |   private static paginateObject(
 70 |     obj: { [key: string]: any },
 71 |     pageToken?: string
 72 |   ): { items: { [key: string]: any }; metadata: PaginationMetadata } {
 73 |     console.log('[Pagination] Starting object pagination', { pageToken });
 74 |     const entries = Object.entries(obj);
 75 |     const totalItems = entries.length;
 76 |     const totalPages = Math.ceil(totalItems / env.items_per_page);
 77 |     const currentPage = pageToken
 78 |       ? this.decodePageToken(pageToken)
 79 |       : 1;
 80 |     
 81 |     console.log('[Pagination] Object pagination state:', { totalItems, totalPages, currentPage });
 82 |     
 83 |     const startIndex = (currentPage - 1) * env.items_per_page;
 84 |     const endIndex = startIndex + env.items_per_page;
 85 |     const hasNextPage = endIndex < totalItems;
 86 | 
 87 |     const paginatedEntries = entries.slice(startIndex, endIndex);
 88 |     const paginatedObject = Object.fromEntries(paginatedEntries);
 89 | 
 90 |     console.log('[Pagination] Object pagination result:', {
 91 |       startIndex,
 92 |       endIndex,
 93 |       hasNextPage,
 94 |       paginatedEntriesLength: paginatedEntries.length
 95 |     });
 96 | 
 97 |     return {
 98 |       items: paginatedObject,
 99 |       metadata: {
100 |         totalItems,
101 |         itemsPerPage: env.items_per_page,
102 |         currentPage,
103 |         totalPages,
104 |         hasNextPage,
105 |         ...(hasNextPage && {
106 |           pageToken: this.generateNextPageToken(currentPage + 1),
107 |         }),
108 |       }
109 |     };
110 |   }
111 | 
112 |   private static paginateArray<T>(
113 |     array: T[],
114 |     pageToken?: string
115 |   ): { items: T[]; metadata: PaginationMetadata } {
116 |     console.log('[Pagination] Starting array pagination', { 
117 |       arrayLength: array.length,
118 |       pageToken 
119 |     });
120 |     const totalItems = array.length;
121 |     const totalPages = Math.ceil(totalItems / env.items_per_page);
122 |     const currentPage = pageToken
123 |       ? this.decodePageToken(pageToken)
124 |       : 1;
125 |     
126 |     console.log('[Pagination] Array pagination state:', { totalItems, totalPages, currentPage });
127 |     
128 |     const startIndex = (currentPage - 1) * env.items_per_page;
129 |     const endIndex = startIndex + env.items_per_page;
130 |     const hasNextPage = endIndex < totalItems;
131 | 
132 |     const paginatedItems = array.slice(startIndex, endIndex);
133 |     console.log('[Pagination] Array pagination result:', {
134 |       startIndex,
135 |       endIndex,
136 |       hasNextPage,
137 |       itemsCount: paginatedItems.length
138 |     });
139 | 
140 |     return {
141 |       items: paginatedItems,
142 |       metadata: {
143 |         totalItems,
144 |         itemsPerPage: env.items_per_page,
145 |         currentPage,
146 |         totalPages,
147 |         hasNextPage,
148 |         ...(hasNextPage && {
149 |           pageToken: this.generateNextPageToken(currentPage + 1),
150 |         }),
151 |       }
152 |     };
153 |   }
154 | 
155 |   private static shouldSkipPagination(obj: any, key: string): boolean {
156 |     // Skip pagination for application global-state and other special arrays
157 |     if (obj.id && obj.params && key === 'global-state') {
158 |       return true;
159 |     }
160 |     return false;
161 |   }
162 | 
163 |   static processResponse(response: any, pageToken?: string): any {
164 |     console.log('[ResponseProcessor] Processing response', { 
165 |       type: Array.isArray(response) ? 'array' : typeof response,
166 |       pageToken
167 |     });
168 |     // Handle array responses
169 |     if (Array.isArray(response)) {
170 |       const arrayResponse = response as any[];
171 |       const { items, metadata } = this.paginateArray(arrayResponse, pageToken);
172 |       const wrappedResponse = {
173 |         data: items,
174 |         metadata
175 |       };
176 |       console.log('[ResponseProcessor] Array response result:', {
177 |         itemsCount: items.length,
178 |         metadata
179 |       });
180 |       return {
181 |         content: [{
182 |           type: 'text',
183 |           text: JSON.stringify(wrappedResponse, null, 2)
184 |         }]
185 |       };
186 |     }
187 |   
188 |     // Handle object responses with array values
189 |     if (typeof response === 'object' && response !== null) {
190 |       console.log('[ResponseProcessor] Processing object response');
191 |       // Create a deep copy to avoid modifying the original object
192 |       const processed = JSON.parse(JSON.stringify(response));
193 |       let paginatedField: string | undefined;
194 |       let paginationMetadata: PaginationMetadata | undefined;
195 |       
196 |       // Process each property of the object
197 |       for (const key in processed) {
198 |         console.log('[ResponseProcessor] Processing field:', key);
199 |         if (Array.isArray(processed[key])) {
200 |           if (this.shouldPaginateArray(processed[key])) {
201 |             const result = this.paginateArray(processed[key], pageToken);
202 |             processed[key] = result.items;
203 |             if (result.metadata) {
204 |               paginatedField = key;
205 |               paginationMetadata = result.metadata;
206 |             }
207 |           }
208 |         } else if (typeof processed[key] === 'object' && processed[key] !== null) {
209 |           // Check if the object needs pagination
210 |           if (this.shouldPaginateObject(processed[key])) {
211 |             const result = this.paginateObject(processed[key], pageToken);
212 |             processed[key] = result.items;
213 |             if (result.metadata) {
214 |               paginatedField = key;
215 |               paginationMetadata = result.metadata;
216 |             }
217 |           }
218 |           // Recursively process nested objects
219 |           const nestedResult = this.processResponse(processed[key], pageToken);
220 |           
221 |           // If the nested processing returned content with a wrapped response
222 |           if (nestedResult.content && nestedResult.content[0] && nestedResult.content[0].text) {
223 |             try {
224 |               const parsedNested = JSON.parse(nestedResult.content[0].text);
225 |               // If the nested result has data/metadata structure, preserve it
226 |               if (parsedNested.data) {
227 |                 processed[key] = parsedNested;
228 |               } else {
229 |                 processed[key] = parsedNested;
230 |               }
231 |             } catch (e) {
232 |               processed[key] = nestedResult.content[0].text;
233 |             }
234 |           }
235 |         }
236 |       }
237 | 
238 |       // If any array was paginated, wrap the response
239 |       if (paginationMetadata) {
240 |         const wrappedResponse = {
241 |           data: processed,
242 |           metadata: {
243 |             ...paginationMetadata,
244 |             arrayField: paginatedField
245 |           }
246 |         };
247 |         console.log('[ResponseProcessor] Object response result with pagination:', {
248 |           paginatedField,
249 |           metadata: paginationMetadata
250 |         });
251 |         return {
252 |           content: [{
253 |             type: 'text',
254 |             text: JSON.stringify(wrappedResponse, null, 2)
255 |           }]
256 |         };
257 |       }
258 |   
259 |       // If no pagination occurred, wrap in data property for consistency
260 |       const wrappedResponse = {
261 |         data: processed
262 |       };
263 |       console.log('[ResponseProcessor] Object response result without pagination');
264 |       return {
265 |         content: [{
266 |           type: 'text',
267 |           text: JSON.stringify(wrappedResponse, null, 2)
268 |         }]
269 |       };
270 |     }
271 |   
272 |     // Return other values wrapped in data property
273 |     const wrappedResponse = {
274 |       data: response
275 |     };
276 |     console.log('[ResponseProcessor] Simple value response');
277 |     return {
278 |       content: [{
279 |         type: 'text',
280 |         text: JSON.stringify(wrappedResponse, null, 2)
281 |       }]
282 |     };
283 |   }
284 | 
285 |   // Higher-order function to wrap resource tool handlers
286 |   static wrapResourceHandler<T extends (...args: any[]) => Promise<any>>(
287 |     handler: T
288 |   ): T {
289 |     return ((...args: Parameters<T>) => {
290 |       return handler(...args);
291 |     }) as T;
292 |   }
293 | }
294 | 
```
Page 31/93FirstPrevNextLast