Repository: algorandfoundation/algokit-cli
Branch: main
Commit: 472eb87eaed1
Files: 755
Total size: 1.8 MB
Directory structure:
gitextract_vthf3g10/
├── .editorconfig
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ ├── actions/
│ │ ├── build-binaries/
│ │ │ ├── linux/
│ │ │ │ └── action.yaml
│ │ │ ├── macos/
│ │ │ │ └── action.yaml
│ │ │ └── windows/
│ │ │ └── action.yaml
│ │ ├── install-apple-dev-id-cert/
│ │ │ └── action.yaml
│ │ └── setup-poetry/
│ │ └── action.yaml
│ ├── dependabot.yml
│ ├── pull_request_template.md
│ └── workflows/
│ ├── build-binaries.yaml
│ ├── build-python.yaml
│ ├── cd.yaml
│ ├── check-python.yaml
│ ├── clear-caches.yaml
│ ├── pr.yaml
│ └── publish-release-packages.yaml
├── .gitignore
├── .idea/
│ └── runConfigurations/
│ └── Run_AlgoKit_CLI.xml
├── .pre-commit-config.yaml
├── .vscode/
│ ├── extensions.json
│ ├── launch.json
│ └── settings.json
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── debug.py
├── docs/
│ ├── algokit.md
│ ├── architecture-decisions/
│ │ ├── 2022-11-14_sandbox-approach.md
│ │ ├── 2022-11-22_beaker-testing-strategy.md
│ │ ├── 2023-01-11_beaker_productionisation_review.md
│ │ ├── 2023-01-11_brew_install.md
│ │ ├── 2023-01-12_smart-contract-deployment.md
│ │ ├── 2023-06-06_frontend-templates.md
│ │ ├── 2023-07-19_advanced_generate_command.md
│ │ ├── 2024-01-13_native_binaries.md
│ │ ├── 2024-01-23_init-wizard-v2.md
│ │ ├── 2024-01-31_binary_distribution.md
│ │ └── 2024-03-06_local_dev_ui_packaging.md
│ ├── articles/
│ │ └── output_stability.md
│ ├── cli/
│ │ └── index.md
│ ├── features/
│ │ ├── compile.md
│ │ ├── completions.md
│ │ ├── config.md
│ │ ├── dispenser.md
│ │ ├── doctor.md
│ │ ├── explore.md
│ │ ├── generate.md
│ │ ├── goal.md
│ │ ├── init.md
│ │ ├── localnet.md
│ │ ├── project/
│ │ │ ├── bootstrap.md
│ │ │ ├── deploy.md
│ │ │ ├── link.md
│ │ │ ├── list.md
│ │ │ └── run.md
│ │ ├── project.md
│ │ ├── tasks/
│ │ │ ├── analyze.md
│ │ │ ├── ipfs.md
│ │ │ ├── mint.md
│ │ │ ├── nfd.md
│ │ │ ├── opt.md
│ │ │ ├── send.md
│ │ │ ├── sign.md
│ │ │ ├── transfer.md
│ │ │ ├── vanity_address.md
│ │ │ └── wallet.md
│ │ └── tasks.md
│ ├── sphinx/
│ │ ├── conf.py
│ │ └── index.rst
│ └── tutorials/
│ ├── algokit-template.md
│ ├── intro.md
│ └── smart-contracts.md
├── entitlements.xml
├── misc/
│ └── multiformats_config/
│ ├── multibase-table.json
│ └── multicodec-table.json
├── poetry.toml
├── pyproject.toml
├── scripts/
│ ├── package_mac.sh
│ ├── package_windows.bat
│ ├── snap/
│ │ └── create-snapcraft-yaml.sh
│ ├── update-brew-cask.sh
│ └── winget/
│ ├── build-installer.ps1
│ ├── installer/
│ │ ├── AppxManifest.xml
│ │ └── priconfig.xml
│ └── update-package.ps1
├── src/
│ └── algokit/
│ ├── __init__.py
│ ├── __main__.py
│ ├── cli/
│ │ ├── __init__.py
│ │ ├── codespace.py
│ │ ├── common/
│ │ │ ├── __init__.py
│ │ │ ├── constants.py
│ │ │ └── utils.py
│ │ ├── compile.py
│ │ ├── compilers/
│ │ │ ├── __init__.py
│ │ │ ├── python.py
│ │ │ └── typescript.py
│ │ ├── completions.py
│ │ ├── config.py
│ │ ├── dispenser.py
│ │ ├── doctor.py
│ │ ├── explore.py
│ │ ├── generate.py
│ │ ├── goal.py
│ │ ├── init/
│ │ │ ├── __init__.py
│ │ │ ├── command.py
│ │ │ ├── example.py
│ │ │ └── helpers.py
│ │ ├── localnet.py
│ │ ├── project/
│ │ │ ├── __init__.py
│ │ │ ├── bootstrap.py
│ │ │ ├── deploy.py
│ │ │ ├── link.py
│ │ │ ├── list.py
│ │ │ └── run.py
│ │ ├── task.py
│ │ ├── tasks/
│ │ │ ├── __init__.py
│ │ │ ├── analyze.py
│ │ │ ├── assets.py
│ │ │ ├── ipfs.py
│ │ │ ├── mint.py
│ │ │ ├── nfd.py
│ │ │ ├── send_transaction.py
│ │ │ ├── sign_transaction.py
│ │ │ ├── transfer.py
│ │ │ ├── utils.py
│ │ │ ├── vanity_address.py
│ │ │ └── wallet.py
│ │ └── tui/
│ │ ├── __init__.py
│ │ └── init/
│ │ ├── __init__.py
│ │ ├── example_selector.py
│ │ └── screens/
│ │ ├── __init__.py
│ │ └── example_selector_screen.py
│ ├── core/
│ │ ├── __init__.py
│ │ ├── _toml.py
│ │ ├── _vendor/
│ │ │ ├── __init__.py
│ │ │ └── auth0/
│ │ │ ├── __init__.py
│ │ │ └── authentication/
│ │ │ ├── __init__.py
│ │ │ └── token_verifier.py
│ │ ├── atomic_write.py
│ │ ├── codespace.py
│ │ ├── compilers/
│ │ │ ├── python.py
│ │ │ └── typescript.py
│ │ ├── conf.py
│ │ ├── config_commands/
│ │ │ ├── __init__.py
│ │ │ ├── container_engine.py
│ │ │ ├── js_package_manager.py
│ │ │ ├── py_package_manager.py
│ │ │ └── version_prompt.py
│ │ ├── dispenser.py
│ │ ├── doctor.py
│ │ ├── generate.py
│ │ ├── goal.py
│ │ ├── init.py
│ │ ├── log_handlers.py
│ │ ├── proc.py
│ │ ├── project/
│ │ │ ├── __init__.py
│ │ │ ├── bootstrap.py
│ │ │ ├── deploy.py
│ │ │ └── run.py
│ │ ├── questionary_extensions.py
│ │ ├── sandbox.py
│ │ ├── tasks/
│ │ │ ├── __init__.py
│ │ │ ├── analyze.py
│ │ │ ├── ipfs.py
│ │ │ ├── mint/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── mint.py
│ │ │ │ └── models.py
│ │ │ ├── nfd.py
│ │ │ ├── vanity_address.py
│ │ │ └── wallet.py
│ │ ├── typed_client_generation.py
│ │ └── utils.py
│ ├── py.typed
│ └── resources/
│ └── distribution-method
└── tests/
├── __init__.py
├── compile/
│ ├── __init__.py
│ ├── conftest.py
│ ├── test_python.py
│ ├── test_python.test_compile_py_help.approved.txt
│ ├── test_python.test_puyapy_is_installed_globally.approved.txt
│ ├── test_python.test_puyapy_is_installed_in_project.approved.txt
│ ├── test_python.test_puyapy_is_not_installed_anywhere.approved.txt
│ ├── test_python.test_specificed_puyapy_version_is_not_installed.approved.txt
│ ├── test_typescript.py
│ ├── test_typescript.test_compile_py_help.approved.txt
│ ├── test_typescript.test_puyats_is_installed_globally.approved.txt
│ ├── test_typescript.test_puyats_is_installed_in_project.approved.txt
│ ├── test_typescript.test_puyats_is_not_installed_anywhere.approved.txt
│ └── test_typescript.test_specificed_puyats_version_is_not_installed.approved.txt
├── completions/
│ ├── __init__.py
│ ├── test_completions.py
│ ├── test_completions.test_completions_help.approved.txt
│ ├── test_completions.test_completions_install_handles_config_outside_home.approved.txt
│ ├── test_completions.test_completions_install_handles_no_profile.approved.txt
│ ├── test_completions.test_completions_install_handles_unsupported_bash_gracefully.approved.txt
│ ├── test_completions.test_completions_install_is_idempotent.approved.txt
│ ├── test_completions.test_completions_installs_correctly_with_detected_shell.approved.txt
│ ├── test_completions.test_completions_installs_correctly_with_specified_shell.bash.approved.txt
│ ├── test_completions.test_completions_installs_correctly_with_specified_shell.zsh.approved.txt
│ ├── test_completions.test_completions_subcommands_help.install.approved.txt
│ ├── test_completions.test_completions_subcommands_help.uninstall.approved.txt
│ ├── test_completions.test_completions_subcommands_with_unknown_shell_fails_gracefully.install.approved.txt
│ ├── test_completions.test_completions_subcommands_with_unknown_shell_fails_gracefully.uninstall.approved.txt
│ ├── test_completions.test_completions_subcommands_with_unsupported_shell_fails_gracefully.install.approved.txt
│ ├── test_completions.test_completions_subcommands_with_unsupported_shell_fails_gracefully.uninstall.approved.txt
│ ├── test_completions.test_completions_uninstall_handles_no_profile.approved.txt
│ ├── test_completions.test_completions_uninstall_is_idempotent.approved.txt
│ ├── test_completions.test_completions_uninstalls_correctly.bash.approved.txt
│ └── test_completions.test_completions_uninstalls_correctly.zsh.approved.txt
├── config/
│ ├── __init__.py
│ ├── test_package_managers.py
│ ├── test_package_managers.test_js_package_manager_help.approved.txt
│ ├── test_package_managers.test_js_package_manager_invalid_argument.approved.txt
│ ├── test_package_managers.test_js_package_manager_set_npm.approved.txt
│ ├── test_package_managers.test_js_package_manager_set_pnpm.approved.txt
│ ├── test_package_managers.test_py_package_manager_help.approved.txt
│ ├── test_package_managers.test_py_package_manager_invalid_argument.approved.txt
│ ├── test_package_managers.test_py_package_manager_set_poetry.approved.txt
│ └── test_package_managers.test_py_package_manager_set_uv.approved.txt
├── conftest.py
├── dispenser/
│ ├── TestFundCommand.test_fund_command_address_invalid.approved.txt
│ ├── TestFundCommand.test_fund_command_alias_invalid.approved.txt
│ ├── TestFundCommand.test_fund_command_from_alias_successful.approved.txt
│ ├── TestFundCommand.test_fund_command_http_error.approved.txt
│ ├── TestFundCommand.test_fund_command_invalid_args.approved.txt
│ ├── TestFundCommand.test_fund_command_not_authenticated.approved.txt
│ ├── TestFundCommand.test_fund_command_success.False.False.approved.txt
│ ├── TestFundCommand.test_fund_command_success.False.True.approved.txt
│ ├── TestFundCommand.test_fund_command_success.True.False.approved.txt
│ ├── TestFundCommand.test_fund_command_success.True.True.approved.txt
│ ├── TestLimitCommand.test_limit_command_http_error.approved.txt
│ ├── TestLimitCommand.test_limit_command_not_authenticated.approved.txt
│ ├── TestLimitCommand.test_limit_command_success.False.False.approved.txt
│ ├── TestLimitCommand.test_limit_command_success.False.True.approved.txt
│ ├── TestLimitCommand.test_limit_command_success.True.False.approved.txt
│ ├── TestLimitCommand.test_limit_command_success.True.True.approved.txt
│ ├── TestLoginCommand.test_login_command_already_logged_in.approved.txt
│ ├── TestLoginCommand.test_login_command_cancelled_timeout.approved.txt
│ ├── TestLoginCommand.test_login_command_expired_token_refresh.False.approved.txt
│ ├── TestLoginCommand.test_login_command_expired_token_refresh.True.approved.txt
│ ├── TestLoginCommand.test_login_command_success_ci.file.None.approved.txt
│ ├── TestLoginCommand.test_login_command_success_ci.file.custom_file.txt.approved.txt
│ ├── TestLoginCommand.test_login_command_success_ci.stdout.None.approved.txt
│ ├── TestLoginCommand.test_login_command_success_user.approved.txt
│ ├── TestLogoutCommand.test_logout_command_already_logged_out.approved.txt
│ ├── TestLogoutCommand.test_logout_command_revoke_exception.approved.txt
│ ├── TestLogoutCommand.test_logout_command_success.approved.txt
│ ├── TestRefundCommand.test_refund_command_http_error.approved.txt
│ ├── TestRefundCommand.test_refund_command_invalid_args.approved.txt
│ ├── TestRefundCommand.test_refund_command_not_authenticated.approved.txt
│ ├── TestRefundCommand.test_refund_command_success.False.approved.txt
│ ├── TestRefundCommand.test_refund_command_success.True.approved.txt
│ └── test_dispenser.py
├── doctor/
│ ├── __init__.py
│ ├── test_doctor.py
│ ├── test_doctor.test_doctor_all_commands_bad_exit[linux].approved.txt
│ ├── test_doctor.test_doctor_all_commands_bad_exit[macOS].approved.txt
│ ├── test_doctor.test_doctor_all_commands_bad_exit[windows].approved.txt
│ ├── test_doctor.test_doctor_all_commands_not_found[linux].approved.txt
│ ├── test_doctor.test_doctor_all_commands_not_found[macOS].approved.txt
│ ├── test_doctor.test_doctor_all_commands_not_found[windows].approved.txt
│ ├── test_doctor.test_doctor_help.approved.txt
│ ├── test_doctor.test_doctor_successful[linux].approved.txt
│ ├── test_doctor.test_doctor_successful[macOS].approved.txt
│ ├── test_doctor.test_doctor_successful[windows].approved.txt
│ ├── test_doctor.test_doctor_with_copy.approved.txt
│ ├── test_doctor.test_doctor_with_docker_compose_version_gitpod.approved.txt
│ ├── test_doctor.test_doctor_with_docker_compose_version_unparseable.approved.txt
│ ├── test_doctor.test_doctor_with_docker_compose_version_warning.approved.txt
│ ├── test_doctor.test_doctor_with_weird_values_on_mac.approved.txt
│ ├── test_doctor.test_doctor_with_weird_values_on_windows.approved.txt
│ ├── test_doctor.test_new_algokit_version_available.approved.txt
│ ├── test_doctor.test_npm_permission_denied.approved.txt
│ ├── test_doctor.test_unexpected_exception_locating_executable.approved.txt
│ └── test_doctor.test_unparseable_python_version.approved.txt
├── explore/
│ ├── __init__.py
│ ├── test_explore.py
│ ├── test_explore.test_explore.localnet.approved.txt
│ ├── test_explore.test_explore.mainnet.approved.txt
│ └── test_explore.test_explore.testnet.approved.txt
├── generate/
│ ├── __init__.py
│ ├── app.arc32.json
│ ├── app.arc56.json
│ ├── application.json
│ ├── test_generate_client.py
│ ├── test_generate_client.test_generate_client_no_app_spec_found.approved.txt
│ ├── test_generate_client.test_generate_client_output_path_is_dir.approved.txt
│ ├── test_generate_client.test_generate_client_python[--output {contract_name}.py-hello_world_app.py].approved.txt
│ ├── test_generate_client.test_generate_client_python[-l python -v 1.1.0-hello_world_app_client.py].approved.txt
│ ├── test_generate_client.test_generate_client_python[-l python-hello_world_app_client.py].approved.txt
│ ├── test_generate_client.test_generate_client_python[-o client.py --language python --version 1.1.2-client.py].approved.txt
│ ├── test_generate_client.test_generate_client_python[-o client.py -p --mode minimal-client.py].approved.txt
│ ├── test_generate_client.test_generate_client_python[-o client.py-client.py].approved.txt
│ ├── test_generate_client.test_generate_client_python[-o client.ts --language python-client.ts].approved.txt
│ ├── test_generate_client.test_generate_client_python_arc32_filename.-o.client.py.approved.txt
│ ├── test_generate_client.test_generate_client_python_arc56_filename.-o.client.py.approved.txt
│ ├── test_generate_client.test_generate_client_python_multiple_app_specs_in_directory.-o.client.py.approved.txt
│ ├── test_generate_client.test_generate_client_recursive.approved.txt
│ ├── test_generate_client.test_generate_client_typescript[linux---output {contract_name}.ts-HelloWorldApp.ts].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[linux--l typescript -v 2.6.0-HelloWorldAppClient.ts].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[linux--l typescript-HelloWorldAppClient.ts].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[linux--o client.py --language typescript-client.py].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[linux--o client.ts --language typescript --version 3.0.0-client.ts].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[linux--o client.ts -pn --mode minimal-client.ts].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[linux--o client.ts-client.ts].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[macOS---output {contract_name}.ts-HelloWorldApp.ts].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[macOS--l typescript -v 2.6.0-HelloWorldAppClient.ts].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[macOS--l typescript-HelloWorldAppClient.ts].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[macOS--o client.py --language typescript-client.py].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[macOS--o client.ts --language typescript --version 3.0.0-client.ts].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[macOS--o client.ts -pn --mode minimal-client.ts].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[macOS--o client.ts-client.ts].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[windows---output {contract_name}.ts-HelloWorldApp.ts].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[windows--l typescript -v 2.6.0-HelloWorldAppClient.ts].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[windows--l typescript-HelloWorldAppClient.ts].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[windows--o client.py --language typescript-client.py].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[windows--o client.ts --language typescript --version 3.0.0-client.ts].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[windows--o client.ts -pn --mode minimal-client.ts].approved.txt
│ ├── test_generate_client.test_generate_client_typescript[windows--o client.ts-client.ts].approved.txt
│ ├── test_generate_client.test_generate_help.approved.txt
│ ├── test_generate_client.test_generate_no_options.approved.txt
│ ├── test_generate_client.test_npx_failed[linux].approved.txt
│ ├── test_generate_client.test_npx_failed[macOS].approved.txt
│ ├── test_generate_client.test_npx_failed[windows].approved.txt
│ ├── test_generate_client.test_npx_missing.approved.txt
│ ├── test_generate_client.test_pipx_missing.approved.txt
│ ├── test_generate_client.test_python_generator_is_installed_globally.approved.txt
│ ├── test_generate_client.test_python_generator_is_installed_in_project.approved.txt
│ ├── test_generate_client.test_python_generator_version_is_not_installed_anywhere.approved.txt
│ ├── test_generate_client.test_typescript_generator_is_installed_globally[linux].approved.txt
│ ├── test_generate_client.test_typescript_generator_is_installed_globally[macOS].approved.txt
│ ├── test_generate_client.test_typescript_generator_is_installed_globally[windows].approved.txt
│ ├── test_generate_client.test_typescript_generator_is_installed_in_project[linux].approved.txt
│ ├── test_generate_client.test_typescript_generator_is_installed_in_project[macOS].approved.txt
│ ├── test_generate_client.test_typescript_generator_is_installed_in_project[windows].approved.txt
│ ├── test_generate_client.test_typescript_generator_version_is_not_installed_anywhere[linux].approved.txt
│ ├── test_generate_client.test_typescript_generator_version_is_not_installed_anywhere[macOS].approved.txt
│ ├── test_generate_client.test_typescript_generator_version_is_not_installed_anywhere[windows].approved.txt
│ ├── test_generate_custom_generate_commands.py
│ ├── test_generate_custom_generate_commands.test_generate_custom_generate_command_missing_git_valid_generator.approved.txt
│ ├── test_generate_custom_generate_commands.test_generate_custom_generate_command_no_git_valid_generator.approved.txt
│ ├── test_generate_custom_generate_commands.test_generate_custom_generate_commands_invalid_generic_generator.approved.txt
│ ├── test_generate_custom_generate_commands.test_generate_custom_generate_commands_no_toml.approved.txt
│ ├── test_generate_custom_generate_commands.test_generate_custom_generate_commands_valid_generator.approved.txt
│ ├── test_generate_custom_generate_commands.test_generate_custom_generate_commands_valid_generator_invalid_path.approved.txt
│ ├── test_generate_custom_generate_commands.test_generate_custom_generate_commands_valid_generator_no_description.approved.txt
│ ├── test_generate_custom_generate_commands.test_generate_custom_generate_commands_valid_generator_run.approved.txt
│ └── test_generate_custom_generate_commands.test_generate_custom_generate_commands_valid_generator_run_with_python_path.approved.txt
├── goal/
│ ├── __init__.py
│ ├── test_goal.py
│ ├── test_goal.test_goal_complex_args.approved.txt
│ ├── test_goal.test_goal_compose_outdated.approved.txt
│ ├── test_goal.test_goal_console.approved.txt
│ ├── test_goal.test_goal_console_algod_not_created.approved.txt
│ ├── test_goal.test_goal_console_failed.approved.txt
│ ├── test_goal.test_goal_help.approved.txt
│ ├── test_goal.test_goal_no_args.approved.txt
│ ├── test_goal.test_goal_simple_args.approved.txt
│ ├── test_goal.test_goal_simple_args_on_named_localnet.approved.txt
│ ├── test_goal.test_goal_simple_args_with_input_file.approved.txt
│ ├── test_goal.test_goal_simple_args_with_input_output_files.approved.txt
│ ├── test_goal.test_goal_simple_args_with_input_output_files_with_dot_convention_name.approved.txt
│ ├── test_goal.test_goal_simple_args_with_multiple_input_output_files.approved.txt
│ ├── test_goal.test_goal_simple_args_with_output_file.approved.txt
│ ├── test_goal.test_goal_simple_args_without_file_error.approved.txt
│ ├── test_goal.test_goal_start_without_docker.approved.txt
│ └── test_goal.test_goal_start_without_docker_engine_running.approved.txt
├── init/
│ ├── __init__.py
│ ├── copier-helloworld.bundle
│ ├── example/
│ │ ├── __init__.py
│ │ ├── test_example.py
│ │ ├── test_example.test_example_command_help.approved.txt
│ │ ├── test_example.test_example_command_list_option.approved.txt
│ │ ├── test_example.test_example_command_tui_select_nothing.approved.txt
│ │ ├── test_example.test_example_command_tui_select_valid.approved.txt
│ │ ├── test_example.test_example_command_tui_select_valid_but_source_missing.approved.txt
│ │ ├── test_example.test_example_command_with_invalid_id.approved.txt
│ │ ├── test_example.test_example_command_with_valid_id.approved.txt
│ │ └── test_example.test_example_command_with_valid_id_source_not_exist.approved.txt
│ ├── test_init.py
│ ├── test_init.test_init_ask_about_git.approved.txt
│ ├── test_init.test_init_blessed_template_url_get_community_warning.approved.txt
│ ├── test_init.test_init_bootstrap_no.approved.txt
│ ├── test_init.test_init_bootstrap_yes.approved.txt
│ ├── test_init.test_init_do_not_use_existing_folder.approved.txt
│ ├── test_init.test_init_existing_filename_same_as_folder_name.approved.txt
│ ├── test_init.test_init_help.approved.txt
│ ├── test_init.test_init_input_template_url.approved.txt
│ ├── test_init.test_init_invalid_template_url.approved.txt
│ ├── test_init.test_init_minimal_interaction_required_no_git_no_network_no_bootstrap.approved.txt
│ ├── test_init.test_init_minimal_interaction_required_yes_git_no_network.approved.txt
│ ├── test_init.test_init_missing_git.approved.txt
│ ├── test_init.test_init_no_community_template.approved.txt
│ ├── test_init.test_init_no_interaction_required_defaults_no_git_no_network.approved.txt
│ ├── test_init.test_init_no_interaction_required_no_git_no_network.approved.txt
│ ├── test_init.test_init_no_interaction_required_no_git_no_network_with_no_ide.approved.txt
│ ├── test_init.test_init_no_interaction_required_no_git_no_network_with_vscode.approved.txt
│ ├── test_init.test_init_no_interaction_required_no_git_no_network_with_vscode_and_readme.approved.txt
│ ├── test_init.test_init_project_name.approved.txt
│ ├── test_init.test_init_project_name_not_empty.approved.txt
│ ├── test_init.test_init_project_name_reenter_folder_name.approved.txt
│ ├── test_init.test_init_template_selection.approved.txt
│ ├── test_init.test_init_template_url_and_template_name.approved.txt
│ ├── test_init.test_init_template_with_python_task_fails_on_missing_python.approved.txt
│ ├── test_init.test_init_template_with_python_task_works.approved.txt
│ ├── test_init.test_init_use_existing_folder.approved.txt
│ ├── test_init.test_init_with_any_template_url_get_community_warning.approved.txt
│ ├── test_init.test_init_with_any_template_url_get_community_warning_with_unsafe_tag.approved.txt
│ ├── test_init.test_init_with_custom_env.approved.txt
│ ├── test_init.test_init_with_official_template_name.approved.txt
│ ├── test_init.test_init_with_official_template_name_and_hash.approved.txt
│ ├── test_init.test_init_wizard_v2_append_to_vscode_workspace.approved.txt
│ ├── test_init.test_init_wizard_v2_flow.Custom Template.approved.txt
│ ├── test_init.test_init_wizard_v2_flow.DApp Frontend.approved.txt
│ ├── test_init.test_init_wizard_v2_flow.Full Stack.approved.txt
│ ├── test_init.test_init_wizard_v2_flow.Smart Contract.approved.txt
│ ├── test_init.test_init_wizard_v2_github_folder_no_workspace.approved.txt
│ ├── test_init.test_init_wizard_v2_github_folder_with_workspace.approved.txt
│ ├── test_init.test_invalid_name.approved.txt
│ ├── test_init_with_bootstrap.py
│ ├── test_init_with_bootstrap.test_init_bootstrap_broken_poetry.approved.txt
│ └── test_init_with_bootstrap.test_init_bootstrap_version_fail.approved.txt
├── localnet/
│ ├── __init__.py
│ ├── conftest.py
│ ├── test_localnet.py
│ ├── test_localnet.test_localnet_help.approved.txt
│ ├── test_localnet_codespace.py
│ ├── test_localnet_codespace.test_install_gh_not_installed_failed_install.approved.txt
│ ├── test_localnet_codespace.test_install_gh_unix.approved.txt
│ ├── test_localnet_codespace.test_install_gh_windows.approved.txt
│ ├── test_localnet_codespace.test_invalid_scope_auth.approved.txt
│ ├── test_localnet_console.py
│ ├── test_localnet_console.test_goal_console.approved.txt
│ ├── test_localnet_reset.py
│ ├── test_localnet_reset.test_localnet_reset_with_existing_sandbox_with_out_of_date_config.approved.txt
│ ├── test_localnet_reset.test_localnet_reset_with_existing_sandbox_with_up_to_date_config.approved.txt
│ ├── test_localnet_reset.test_localnet_reset_with_existing_sandbox_with_up_to_date_config_with_pull.approved.txt
│ ├── test_localnet_reset.test_localnet_reset_with_named_sandbox_config.approved.txt
│ ├── test_localnet_reset.test_localnet_reset_without_docker.approved.txt
│ ├── test_localnet_reset.test_localnet_reset_without_docker_compose.approved.txt
│ ├── test_localnet_reset.test_localnet_reset_without_docker_engine_running.approved.txt
│ ├── test_localnet_reset.test_localnet_reset_without_existing_sandbox.approved.txt
│ ├── test_localnet_start.py
│ ├── test_localnet_start.test_localnet_img_check_cmd_error.approved.txt
│ ├── test_localnet_start.test_localnet_start.approved.txt
│ ├── test_localnet_start.test_localnet_start_failure.approved.txt
│ ├── test_localnet_start.test_localnet_start_health_bad_status.approved.txt
│ ├── test_localnet_start.test_localnet_start_health_failure.approved.txt
│ ├── test_localnet_start.test_localnet_start_out_date.approved.txt
│ ├── test_localnet_start.test_localnet_start_out_of_date_definition.approved.txt
│ ├── test_localnet_start.test_localnet_start_out_of_date_definition_and_missing_config.approved.txt
│ ├── test_localnet_start.test_localnet_start_up_to_date_definition.approved.txt
│ ├── test_localnet_start.test_localnet_start_with_custom_config_dir.approved.txt
│ ├── test_localnet_start.test_localnet_start_with_gitpod_docker_compose_version.approved.txt
│ ├── test_localnet_start.test_localnet_start_with_name.approved.txt
│ ├── test_localnet_start.test_localnet_start_with_no_dev_mode.approved.txt
│ ├── test_localnet_start.test_localnet_start_with_old_docker_compose_version.approved.txt
│ ├── test_localnet_start.test_localnet_start_with_unparseable_docker_compose_version.approved.txt
│ ├── test_localnet_start.test_localnet_start_without_docker.approved.txt
│ ├── test_localnet_start.test_localnet_start_without_docker_compose.approved.txt
│ ├── test_localnet_start.test_localnet_start_without_docker_engine_running.approved.txt
│ ├── test_localnet_status.py
│ ├── test_localnet_status.test_localnet_status_docker_error.approved.txt
│ ├── test_localnet_status.test_localnet_status_failure.approved.txt
│ ├── test_localnet_status.test_localnet_status_http_error.approved.txt
│ ├── test_localnet_status.test_localnet_status_missing_service.approved.txt
│ ├── test_localnet_status.test_localnet_status_no_existing_definition.approved.txt
│ ├── test_localnet_status.test_localnet_status_service_not_started.approved.txt
│ ├── test_localnet_status.test_localnet_status_successful.approved.txt
│ ├── test_localnet_status.test_localnet_status_unexpected_port.approved.txt
│ ├── test_localnet_status.test_localnet_status_without_docker.approved.txt
│ ├── test_localnet_status.test_localnet_status_without_docker_compose.approved.txt
│ ├── test_localnet_status.test_localnet_status_without_docker_engine_running.approved.txt
│ ├── test_localnet_stop.py
│ ├── test_localnet_stop.test_localnet_stop.approved.txt
│ ├── test_localnet_stop.test_localnet_stop_failure.approved.txt
│ ├── test_localnet_stop.test_localnet_stop_no_existing_definition.approved.txt
│ ├── test_localnet_stop.test_localnet_stop_with_name.approved.txt
│ ├── test_localnet_stop.test_localnet_stop_without_docker.approved.txt
│ ├── test_localnet_stop.test_localnet_stop_without_docker_compose.approved.txt
│ ├── test_localnet_stop.test_localnet_stop_without_docker_engine_running.approved.txt
│ ├── test_sandbox.py
│ ├── test_sandbox.test_algod_network_template_json.approved.txt
│ ├── test_sandbox.test_get_conduit_yaml.approved.txt
│ ├── test_sandbox.test_get_config_json.approved.txt
│ └── test_sandbox.test_get_docker_compose_yml.approved.txt
├── portability/
│ └── test_pyinstaller_binary.py
├── project/
│ ├── __init__.py
│ ├── bootstrap/
│ │ ├── __init__.py
│ │ ├── test_bootstrap.py
│ │ ├── test_bootstrap.test_bootstrap_help.approved.txt
│ │ ├── test_bootstrap_all.py
│ │ ├── test_bootstrap_all.test_bootstrap_all_algokit_min_version.approved.txt
│ │ ├── test_bootstrap_all.test_bootstrap_all_algokit_min_version_ignore_error.approved.txt
│ │ ├── test_bootstrap_all.test_bootstrap_all_empty.approved.txt
│ │ ├── test_bootstrap_all.test_bootstrap_all_env.approved.txt
│ │ ├── test_bootstrap_all.test_bootstrap_all_npm[linux].approved.txt
│ │ ├── test_bootstrap_all.test_bootstrap_all_npm[macOS].approved.txt
│ │ ├── test_bootstrap_all.test_bootstrap_all_npm[windows].approved.txt
│ │ ├── test_bootstrap_all.test_bootstrap_all_poetry.approved.txt
│ │ ├── test_bootstrap_all.test_bootstrap_all_poetry_via_pyproject.approved.txt
│ │ ├── test_bootstrap_all.test_bootstrap_all_projects_filter.approved.txt
│ │ ├── test_bootstrap_all.test_bootstrap_all_projects_filter_not_found.approved.txt
│ │ ├── test_bootstrap_all.test_bootstrap_all_projects_name_filter.approved.txt
│ │ ├── test_bootstrap_all.test_bootstrap_all_projects_name_filter_not_found.approved.txt
│ │ ├── test_bootstrap_all.test_bootstrap_all_projects_type_filter.approved.txt
│ │ ├── test_bootstrap_all.test_bootstrap_all_projects_type_filter_not_found.approved.txt
│ │ ├── test_bootstrap_all.test_bootstrap_all_skip_dirs.approved.txt
│ │ ├── test_bootstrap_all.test_bootstrap_all_sub_dir.approved.txt
│ │ ├── test_bootstrap_env.py
│ │ ├── test_bootstrap_env.test_bootstrap_env_dotenv_different_prompt_scenarios.approved.txt
│ │ ├── test_bootstrap_env.test_bootstrap_env_dotenv_exists.approved.txt
│ │ ├── test_bootstrap_env.test_bootstrap_env_dotenv_missing_template_exists.approved.txt
│ │ ├── test_bootstrap_env.test_bootstrap_env_dotenv_with_values.approved.txt
│ │ ├── test_bootstrap_env.test_bootstrap_env_multiple_templates.approved.txt
│ │ ├── test_bootstrap_env.test_bootstrap_env_no_files.approved.txt
│ │ ├── test_bootstrap_env.test_bootstrap_network_prefixed_env_dotenv_exists.approved.txt
│ │ ├── test_bootstrap_env.test_bootstrap_network_prefixed_envs..env.approved.txt
│ │ ├── test_bootstrap_env.test_bootstrap_network_prefixed_envs..env.localnet.approved.txt
│ │ ├── test_bootstrap_env.test_bootstrap_network_prefixed_envs..env.localnet.template.approved.txt
│ │ ├── test_bootstrap_env.test_bootstrap_network_prefixed_envs..env.template.approved.txt
│ │ ├── test_bootstrap_npm.py
│ │ ├── test_bootstrap_npm.test_bootstrap_npm_ci_mode_with_lock_file[linux].approved.txt
│ │ ├── test_bootstrap_npm.test_bootstrap_npm_ci_mode_with_lock_file[macOS].approved.txt
│ │ ├── test_bootstrap_npm.test_bootstrap_npm_ci_mode_with_lock_file[windows].approved.txt
│ │ ├── test_bootstrap_npm.test_bootstrap_npm_ci_mode_without_lock_file[linux].approved.txt
│ │ ├── test_bootstrap_npm.test_bootstrap_npm_ci_mode_without_lock_file[macOS].approved.txt
│ │ ├── test_bootstrap_npm.test_bootstrap_npm_ci_mode_without_lock_file[windows].approved.txt
│ │ ├── test_bootstrap_npm.test_bootstrap_npm_happy_path[linux].approved.txt
│ │ ├── test_bootstrap_npm.test_bootstrap_npm_happy_path[macOS].approved.txt
│ │ ├── test_bootstrap_npm.test_bootstrap_npm_happy_path[windows].approved.txt
│ │ ├── test_bootstrap_npm.test_bootstrap_npm_without_npm[linux].approved.txt
│ │ ├── test_bootstrap_npm.test_bootstrap_npm_without_npm[macOS].approved.txt
│ │ ├── test_bootstrap_npm.test_bootstrap_npm_without_npm[windows].approved.txt
│ │ ├── test_bootstrap_npm.test_bootstrap_npm_without_npm_and_package_file[linux].approved.txt
│ │ ├── test_bootstrap_npm.test_bootstrap_npm_without_npm_and_package_file[macOS].approved.txt
│ │ ├── test_bootstrap_npm.test_bootstrap_npm_without_npm_and_package_file[windows].approved.txt
│ │ ├── test_bootstrap_npm.test_bootstrap_npm_without_package_file[linux].approved.txt
│ │ ├── test_bootstrap_npm.test_bootstrap_npm_without_package_file[macOS].approved.txt
│ │ ├── test_bootstrap_npm.test_bootstrap_npm_without_package_file[windows].approved.txt
│ │ ├── test_bootstrap_package_manager_selection.py
│ │ ├── test_bootstrap_package_manager_selection.test_bootstrap_respects_configured_package_managers[linux].approved.txt
│ │ ├── test_bootstrap_package_manager_selection.test_bootstrap_respects_configured_package_managers[macOS].approved.txt
│ │ ├── test_bootstrap_package_manager_selection.test_bootstrap_respects_configured_package_managers[windows].approved.txt
│ │ ├── test_bootstrap_package_manager_selection.test_interactive_prompt_fallback_with_preference_saving.approved.txt
│ │ ├── test_bootstrap_package_manager_selection.test_project_override_takes_precedence_over_user_preference.approved.txt
│ │ ├── test_bootstrap_package_manager_selection.test_project_override_takes_precedence_over_user_preference[linux].approved.txt
│ │ ├── test_bootstrap_package_manager_selection.test_project_override_takes_precedence_over_user_preference[macOS].approved.txt
│ │ ├── test_bootstrap_package_manager_selection.test_project_override_takes_precedence_over_user_preference[windows].approved.txt
│ │ ├── test_bootstrap_package_manager_selection.test_smart_defaults_when_no_user_preference.approved.txt
│ │ ├── test_bootstrap_pnpm.py
│ │ ├── test_bootstrap_pnpm.test_bootstrap_pnpm_ci_mode_without_lock_file.approved.txt
│ │ ├── test_bootstrap_pnpm.test_bootstrap_pnpm_happy_path[linux].approved.txt
│ │ ├── test_bootstrap_pnpm.test_bootstrap_pnpm_happy_path[macOS].approved.txt
│ │ ├── test_bootstrap_pnpm.test_bootstrap_pnpm_happy_path[windows].approved.txt
│ │ ├── test_bootstrap_pnpm.test_bootstrap_pnpm_without_package_file.approved.txt
│ │ ├── test_bootstrap_poetry.py
│ │ ├── test_bootstrap_poetry.test_bootstrap_poetry_with_poetry.approved.txt
│ │ ├── test_bootstrap_poetry.test_bootstrap_poetry_without_poetry.approved.txt
│ │ ├── test_bootstrap_poetry.test_bootstrap_poetry_without_poetry_failed_install.approved.txt
│ │ ├── test_bootstrap_poetry.test_bootstrap_poetry_without_poetry_failed_poetry_path.approved.txt
│ │ ├── test_bootstrap_poetry.test_bootstrap_poetry_without_poetry_or_pipx_path[no_system_pythons].approved.txt
│ │ ├── test_bootstrap_poetry.test_bootstrap_poetry_without_poetry_or_pipx_path[python3_only].approved.txt
│ │ ├── test_bootstrap_poetry.test_bootstrap_poetry_without_poetry_or_pipx_path[python_and_python3].approved.txt
│ │ ├── test_bootstrap_poetry.test_bootstrap_poetry_without_poetry_or_pipx_path[python_only].approved.txt
│ │ ├── test_bootstrap_poetry.test_bootstrap_poetry_without_poetry_or_pipx_path_failed_install.approved.txt
│ │ ├── test_bootstrap_poetry.test_bootstrap_poetry_without_poetry_or_pipx_path_failed_poetry_path.approved.txt
│ │ ├── test_bootstrap_poetry.test_bootstrap_poetry_without_poetry_or_pipx_path_or_pipx_module.approved.txt
│ │ ├── test_bootstrap_translation.py
│ │ ├── test_bootstrap_uv.py
│ │ ├── test_bootstrap_uv.test_bootstrap_uv_happy_path.approved.txt
│ │ ├── test_bootstrap_uv.test_bootstrap_uv_poetry_project_migration_declined.approved.txt
│ │ ├── test_bootstrap_uv.test_bootstrap_uv_user_declines_install.approved.txt
│ │ └── test_precedence_hierarchy.py
│ ├── deploy/
│ │ ├── __init__.py
│ │ ├── test_deploy.py
│ │ ├── test_deploy.test_algokit_config_empty_array.approved.txt
│ │ ├── test_deploy.test_algokit_config_invalid_syntax.approved.txt
│ │ ├── test_deploy.test_algokit_config_name_no_base.approved.txt
│ │ ├── test_deploy.test_algokit_config_name_overrides.approved.txt
│ │ ├── test_deploy.test_algokit_deploy_only_base_deploy_config.approved.txt
│ │ ├── test_deploy.test_algokit_env_and_name_correct_set.approved.txt
│ │ ├── test_deploy.test_algokit_env_name_missing.approved.txt
│ │ ├── test_deploy.test_ci_flag_interactivity_mode_via_cli.approved.txt
│ │ ├── test_deploy.test_ci_flag_interactivity_mode_via_env.approved.txt
│ │ ├── test_deploy.test_command_bad_exit_code.approved.txt
│ │ ├── test_deploy.test_command_invocation_and_command_splitting.approved.txt
│ │ ├── test_deploy.test_command_not_executable.approved.txt
│ │ ├── test_deploy.test_command_not_found_and_no_config.approved.txt
│ │ ├── test_deploy.test_command_splitting_from_config.approved.txt
│ │ ├── test_deploy.test_command_without_splitting_from_config.approved.txt
│ │ ├── test_deploy.test_deploy_custom_project_dir.approved.txt
│ │ ├── test_deploy.test_deploy_dispenser_alias.deployer.approved.txt
│ │ ├── test_deploy.test_deploy_dispenser_alias.dispenser.approved.txt
│ │ ├── test_deploy.test_deploy_shutil_command_not_found.approved.txt
│ │ ├── test_deploy.test_deploy_windows_command_not_found.approved.txt
│ │ ├── test_deploy.test_deploy_with_extra_args.approved.txt
│ │ ├── test_deploy.test_deploy_with_extra_args_and_custom_command.approved.txt
│ │ └── test_deploy.test_secrets_prompting_via_stdin.approved.txt
│ ├── link/
│ │ ├── application.json
│ │ ├── test_link.py
│ │ ├── test_link.test_link_command_all_success.approved.txt
│ │ ├── test_link.test_link_command_by_name_success.approved.txt
│ │ ├── test_link.test_link_command_empty_folder.approved.txt
│ │ ├── test_link.test_link_command_multiple_names_no_specs_success.approved.txt
│ │ ├── test_link.test_link_command_multiple_names_success.approved.txt
│ │ ├── test_link.test_link_command_name_not_found.approved.txt
│ │ ├── test_link.test_link_runtime_error.approved.txt
│ │ └── test_link.test_list_command_from_workspace_success.approved.txt
│ ├── list/
│ │ ├── test_list.py
│ │ ├── test_list.test_list_command_from_empty_folder.approved.txt
│ │ ├── test_list.test_list_command_from_workspace_success.approved.txt
│ │ ├── test_list.test_list_command_no_args.approved.txt
│ │ ├── test_list.test_list_command_verbose_from_workspace_success.approved.txt
│ │ └── test_list.test_run_command_from_workspace_success.approved.txt
│ └── run/
│ ├── __init__.py
│ ├── test_run.py
│ ├── test_run.test_list_all_commands_in_workspace.approved.txt
│ ├── test_run.test_run_command_from_standalone.approved.txt
│ ├── test_run.test_run_command_from_standalone_execution_error.approved.txt
│ ├── test_run.test_run_command_from_standalone_pass_env.approved.txt
│ ├── test_run.test_run_command_from_standalone_resolution_error.approved.txt
│ ├── test_run.test_run_command_from_standalone_with_extra_args.approved.txt
│ ├── test_run.test_run_command_from_workspace_execution_error.approved.txt
│ ├── test_run.test_run_command_from_workspace_filtered.approved.txt
│ ├── test_run.test_run_command_from_workspace_filtered_no_project.approved.txt
│ ├── test_run.test_run_command_from_workspace_resolution_error.approved.txt
│ ├── test_run.test_run_command_from_workspace_sequential_success.approved.txt
│ ├── test_run.test_run_command_from_workspace_success.approved.txt
│ ├── test_run.test_run_command_from_workspace_with_extra_args.approved.txt
│ ├── test_run.test_run_command_from_workspace_with_extra_args_and_project_filter.approved.txt
│ └── test_run.test_run_command_help_works_without_path_resolution.approved.txt
├── tasks/
│ ├── TestAddAlias.test_wallet_add_account_successful.approved.txt
│ ├── TestAddAlias.test_wallet_add_address_successful.approved.txt
│ ├── TestAddAlias.test_wallet_add_alias_exists.approved.txt
│ ├── TestAddAlias.test_wallet_add_alias_generic_error.approved.txt
│ ├── TestAddAlias.test_wallet_add_alias_limit_error.approved.txt
│ ├── TestAddAlias.test_wallet_add_alias_mnemonic_differs.approved.txt
│ ├── TestAddAlias.test_wallet_add_invalid_address.approved.txt
│ ├── TestGetAlias.test_wallet_get_alias_not_found.approved.txt
│ ├── TestGetAlias.test_wallet_get_alias_successful.approved.txt
│ ├── TestIpfsLogin.test_ipfs_login_exists.approved.txt
│ ├── TestIpfsLogin.test_ipfs_login_successful.approved.txt
│ ├── TestIpfsLogout.test_ipfs_logout.approved.txt
│ ├── TestIpfsUpload.test_ipfs_upload_http_error.approved.txt
│ ├── TestIpfsUpload.test_ipfs_upload_successful.approved.txt
│ ├── TestListAliases.test_wallet_list_aliases_not_found.approved.txt
│ ├── TestListAliases.test_wallet_list_aliases_successful.approved.txt
│ ├── TestRemoveAlias.test_wallet_remove_alias_generic_error.approved.txt
│ ├── TestRemoveAlias.test_wallet_remove_alias_not_found.approved.txt
│ ├── TestRemoveAlias.test_wallet_remove_alias_successful.approved.txt
│ ├── TestResetAliases.test_wallet_reset_aliases_generic_error.approved.txt
│ ├── TestResetAliases.test_wallet_reset_aliases_not_found.approved.txt
│ ├── TestResetAliases.test_wallet_reset_aliases_successful.approved.txt
│ ├── __init__.py
│ ├── conftest.py
│ ├── test_analyze.py
│ ├── test_analyze.test_analyze_abort_disclaimer.approved.txt
│ ├── test_analyze.test_analyze_diff_flag.approved.txt
│ ├── test_analyze.test_analyze_diff_flag_missing_old_report.approved.txt
│ ├── test_analyze.test_analyze_error_in_tealer.approved.txt
│ ├── test_analyze.test_analyze_error_no_pipx.approved.txt
│ ├── test_analyze.test_analyze_multiple_files.approved.txt
│ ├── test_analyze.test_analyze_multiple_files_recursive.approved.txt
│ ├── test_analyze.test_analyze_single_file.approved.txt
│ ├── test_analyze.test_analyze_skipping_tmpl_vars.approved.txt
│ ├── test_analyze.test_exclude_vulnerabilities.approved.txt
│ ├── test_asset.py
│ ├── test_asset.test_opt_in_invalid_network.approved.txt
│ ├── test_asset.test_opt_in_no_args.approved.txt
│ ├── test_asset.test_opt_in_of_assets_from_account_alias_successful.approved.txt
│ ├── test_asset.test_opt_in_to_assets_from_account_address_failed.approved.txt
│ ├── test_asset.test_opt_in_to_assets_from_account_address_successful.approved.txt
│ ├── test_asset.test_opt_out_assets_from_account_address_failed.approved.txt
│ ├── test_asset.test_opt_out_invalid_network.approved.txt
│ ├── test_asset.test_opt_out_no_args.approved.txt
│ ├── test_asset.test_opt_out_of_all_assets_from_account_address_successful.approved.txt
│ ├── test_asset.test_opt_out_of_assets_from_account_address_successful.approved.txt
│ ├── test_asset.test_opt_out_of_assets_from_account_alias_successful.approved.txt
│ ├── test_ipfs.py
│ ├── test_mint.py
│ ├── test_mint.test_mint_token_acfg_token_metadata_mismatch.approved.txt
│ ├── test_mint.test_mint_token_generic_error.approved.txt
│ ├── test_mint.test_mint_token_no_pinata_jwt_error.approved.txt
│ ├── test_mint.test_mint_token_pinata_error.approved.txt
│ ├── test_mint.test_mint_token_successful.address.False.localnet.approved.txt
│ ├── test_mint.test_mint_token_successful.address.False.mainnet.approved.txt
│ ├── test_mint.test_mint_token_successful.address.False.testnet.approved.txt
│ ├── test_mint.test_mint_token_successful.alias.True.localnet.approved.txt
│ ├── test_mint.test_mint_token_successful.alias.True.mainnet.approved.txt
│ ├── test_mint.test_mint_token_successful.alias.True.testnet.approved.txt
│ ├── test_mint.test_mint_token_successful_on_decimals.decimals_given_params.approved.txt
│ ├── test_mint.test_mint_token_successful_on_decimals.no_decimals_given.approved.txt
│ ├── test_nfd_lookup.py
│ ├── test_nfd_lookup.test_nfd_lookup_by_address_success.approved.txt
│ ├── test_nfd_lookup.test_nfd_lookup_by_domain_success.approved.txt
│ ├── test_send_transaction.py
│ ├── test_send_transaction.test_decoding_error.approved.txt
│ ├── test_send_transaction.test_file_decoding_no_txn_error.approved.txt
│ ├── test_send_transaction.test_mutually_exclusive_options.approved.txt
│ ├── test_send_transaction.test_send_atomic_txn_group_successful.approved.txt
│ ├── test_send_transaction.test_send_from_file_successful.approved.txt
│ ├── test_send_transaction.test_send_from_piped_input_successful.approved.txt
│ ├── test_send_transaction.test_send_from_transaction_successful.approved.txt
│ ├── test_sign_transaction.py
│ ├── test_sign_transaction.test_file_decoding_errors.approved.txt
│ ├── test_sign_transaction.test_mutually_exclusive_options.approved.txt
│ ├── test_sign_transaction.test_sign_atomic_txn_group_successful.approved.txt
│ ├── test_sign_transaction.test_sign_from_stdin_with_address_successful.approved.txt
│ ├── test_sign_transaction.test_sign_from_stdin_with_alias_successful.approved.txt
│ ├── test_sign_transaction.test_sign_many_from_file_with_address_successful.approved.txt
│ ├── test_sign_transaction.test_sign_many_from_file_with_alias_successful.approved.txt
│ ├── test_sign_transaction.test_transaction_decoding_errors.approved.txt
│ ├── test_transfer.py
│ ├── test_transfer.test_transfer_algo_from_address_successful.approved.txt
│ ├── test_transfer.test_transfer_algo_from_alias_successful.approved.txt
│ ├── test_transfer.test_transfer_algo_successful.approved.txt
│ ├── test_transfer.test_transfer_asset_from_address_successful.approved.txt
│ ├── test_transfer.test_transfer_asset_from_address_to_alias_successful.approved.txt
│ ├── test_transfer.test_transfer_asset_from_alias_successful.approved.txt
│ ├── test_transfer.test_transfer_failed.approved.txt
│ ├── test_transfer.test_transfer_invalid_receiver_account.approved.txt
│ ├── test_transfer.test_transfer_invalid_sender_accoount.approved.txt
│ ├── test_transfer.test_transfer_invalid_sender_account.approved.txt
│ ├── test_transfer.test_transfer_no_amount.approved.txt
│ ├── test_transfer.test_transfer_no_args.approved.txt
│ ├── test_transfer.test_transfer_no_option.approved.txt
│ ├── test_transfer.test_transfer_on_mainnet.approved.txt
│ ├── test_transfer.test_transfer_on_testnet.approved.txt
│ ├── test_vanity_address.py
│ ├── test_vanity_address.test_vanity_address_invalid_input_on_alias.approved.txt
│ ├── test_vanity_address.test_vanity_address_invalid_input_on_file.approved.txt
│ ├── test_vanity_address.test_vanity_address_invalid_keyword.approved.txt
│ ├── test_vanity_address.test_vanity_address_no_options.approved.txt
│ └── test_wallet.py
├── test_root.py
├── test_root.test_help.approved.txt
├── utils/
│ ├── __init__.py
│ ├── app_dir_mock.py
│ ├── approvals.py
│ ├── click_invoker.py
│ ├── proc_mock.py
│ └── which_mock.py
└── version_check/
├── __init__.py
├── test_version_check.py
├── test_version_check.test_version_check_disable_version_check.approved.txt
├── test_version_check.test_version_check_enable_version_check.approved.txt
├── test_version_check.test_version_check_queries_github_when_cache_out_of_date.approved.txt
├── test_version_check.test_version_check_queries_github_when_no_cache.approved.txt
├── test_version_check.test_version_check_respects_disable_config.approved.txt
├── test_version_check.test_version_check_respects_skip_option.approved.txt
└── test_version_check.test_version_check_uses_cache.approved.txt
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
root=true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
[*.py]
indent_size = 4
================================================
FILE: .gitattributes
================================================
* text=auto eol=lf
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: "\U0001F41C Bug report"
about: Report a reproducible bug.
title: ''
labels: bug
assignees: ''
---
### Subject of the issue
### Your environment
### Steps to reproduce
1.
2.
### Expected behaviour
### Actual behaviour
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: "\U0001F514 Feature Request"
about: Suggestions for how we can improve the algorand platform.
title: ''
labels: enhancement
assignees: ''
---
## Problem
## Solution
### Proposal
### Pros and Cons
## Dependencies
================================================
FILE: .github/actions/build-binaries/linux/action.yaml
================================================
name: "Build Linux Binary Artifacts"
description: "Build Linux specific pyinstaller binary artifacts"
inputs:
package_name:
description: "The name of the package"
required: true
artifacts_dir:
description: "The directory to write artifacts you want to publish"
required: true
version:
description: "The version to use for this artifact"
runs:
using: "composite"
steps:
- name: Build binary
shell: bash
run: |
poetry run poe package_unix
- name: Package binary artifact
shell: bash
run: |
cd dist/algokit/
echo snap > ./_internal/algokit/resources/distribution-method
tar -zcf ${{ inputs.artifacts_dir }}/${{ inputs.package_name }}-snap.tar.gz *
cd ../..
- name: Upload binary artifact
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.package_name }}-snap
path: ${{ inputs.artifacts_dir }}/${{ inputs.package_name }}-snap.tar.gz
================================================
FILE: .github/actions/build-binaries/macos/action.yaml
================================================
name: "Build macOS Binary Artifacts"
description: "Build macOS specific pyinstaller binary artifacts"
inputs:
package_name:
description: "The name of the package"
required: true
artifacts_dir:
description: "The directory to write artifacts you want to publish"
required: true
version:
description: "The version to use for this artifact"
with_codesign:
description: "Flag to determine if we should sign the binary"
required: true
apple_team_id:
description: "The Apple Team ID"
required: true
apple_bundle_id:
description: "The bundle ID to be used for packaging and notarisation"
required: true
apple_cert_id:
description: "The Apple Developer ID certificate ID"
required: true
apple_notary_user:
description: "The Apple user to notarise the package"
required: true
apple_notary_password:
description: "The Apple password to notarise the package"
required: true
runs:
using: "composite"
steps:
- name: Build binary
shell: bash
run: |
export APPLE_CERT_ID="${{ inputs.with_codesign == 'true' && inputs.apple_cert_id || '' }}"
export APPLE_BUNDLE_ID="${{ inputs.with_codesign == 'true' && inputs.apple_bundle_id || format('beta.{0}', inputs.apple_bundle_id) }}"
poetry run poe package_mac
env:
APPLE_CERT_ID: ${{ inputs.with_codesign == 'true' && inputs.apple_cert_id || '' }}
APPLE_BUNDLE_ID: ${{ inputs.with_codesign == 'true' && inputs.apple_bundle_id || format('beta.{0}', inputs.apple_bundle_id) }}
- name: Add metadata to binary
shell: bash
run: |
echo brew > ${{ github.workspace }}/dist/algokit/_internal/algokit/resources/distribution-method
# Workaround an issue with PyInstaller where Python.framework was incorrectly signed during the build
- name: Codesign python.framework
if: ${{ inputs.with_codesign == 'true' }}
shell: bash
run: |
codesign --force --sign "${{ inputs.apple_cert_id }}" --timestamp "${{ github.workspace }}/dist/algokit/_internal/Python.framework"
- name: Notarize
if: ${{ inputs.with_codesign == 'true' }}
uses: lando/notarize-action@v2
with:
appstore-connect-team-id: ${{ inputs.apple_team_id }}
appstore-connect-username: ${{ inputs.apple_notary_user }}
appstore-connect-password: ${{ inputs.apple_notary_password }}
primary-bundle-id: ${{ inputs.apple_bundle_id }}
product-path: "${{ github.workspace }}/dist/algokit"
tool: notarytool
verbose: true
- name: Package binary artifact
shell: bash
run: |
cd dist/algokit/
tar -zcf ${{ inputs.artifacts_dir }}/${{ inputs.package_name }}-brew.tar.gz *
cd ../..
- name: Upload binary artifact
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.package_name }}
path: ${{ inputs.artifacts_dir }}/${{ inputs.package_name }}-brew.tar.gz
================================================
FILE: .github/actions/build-binaries/windows/action.yaml
================================================
name: "Build Windows Binary Artifacts"
description: "Build Windows specific pyinstaller binary artifacts"
inputs:
package_name:
description: "The name of the package"
required: true
version:
description: "The version to use for this artifact"
artifacts_dir:
description: "The directory to write artifacts you want to publish"
required: true
with_codesign:
description: "Flag to determine if we should sign the binary"
required: true
azure_tenant_id:
description: "The Microsoft Entra tenant (directory) ID."
required: true
azure_client_id:
description: "The client (application) ID of an App Registration in the tenant."
required: true
azure_client_secret:
description: "A client secret that was generated for the App Registration."
required: true
runs:
using: "composite"
steps:
- name: Configure build environment
shell: pwsh
run: |
# Find Windows SDK tools dynamically (works on both Windows 2022 and 2025)
$sdkPath = "C:\Program Files (x86)\Windows Kits\10\bin"
# First, try to find makepri and makeappx in PATH
$makepriCmd = Get-Command makepri -ErrorAction SilentlyContinue
$makeappxCmd = Get-Command makeappx -ErrorAction SilentlyContinue
if (-not $makepriCmd -or -not $makeappxCmd) {
Write-Host "SDK tools not in PATH, searching for Windows SDK..."
if (Test-Path $sdkPath) {
# Find the latest SDK version
$latestVersion = Get-ChildItem $sdkPath -Directory |
Where-Object { $_.Name -match '^\d+\.\d+\.\d+\.\d+$' } |
Sort-Object { [Version]$_.Name } -Descending |
Select-Object -First 1
if ($latestVersion) {
$sdkBinPath = Join-Path $latestVersion.FullName "x64"
Write-Host "Adding Windows SDK to PATH: $sdkBinPath"
echo "$sdkBinPath" >> $env:GITHUB_PATH
# Verify tools exist
$makepriPath = Join-Path $sdkBinPath "makepri.exe"
$makeappxPath = Join-Path $sdkBinPath "makeappx.exe"
if (-not (Test-Path $makepriPath)) {
throw "makepri.exe not found at $makepriPath"
}
if (-not (Test-Path $makeappxPath)) {
throw "makeappx.exe not found at $makeappxPath"
}
Write-Host "✓ Found makepri.exe at: $makepriPath"
Write-Host "✓ Found makeappx.exe at: $makeappxPath"
} else {
throw "No Windows SDK versions found in $sdkPath"
}
} else {
throw "Windows SDK not found at $sdkPath"
}
} else {
Write-Host "✓ SDK tools already in PATH"
Write-Host " makepri: $($makepriCmd.Source)"
Write-Host " makeappx: $($makeappxCmd.Source)"
}
# Set environment variables
echo 'BINARY_BUILD_DIR=dist\algokit' >> $env:GITHUB_ENV
echo 'WINGET_INSTALLER=${{ inputs.artifacts_dir }}\${{ inputs.package_name }}-winget.msix' >> $env:GITHUB_ENV
- name: Build binary
shell: bash
run: |
poetry run poe package_windows
- name: Add metadata to binary
shell: bash
run: |
echo winget > '${{ env.BINARY_BUILD_DIR }}\_internal\algokit\resources\distribution-method'
- name: Sign executable
if: ${{ inputs.with_codesign == 'true' }}
uses: azure/trusted-signing-action@v0.3.20
with:
azure-tenant-id: ${{ inputs.azure_tenant_id }}
azure-client-id: ${{ inputs.azure_client_id }}
azure-client-secret: ${{ inputs.azure_client_secret }}
endpoint: https://weu.codesigning.azure.net/
trusted-signing-account-name: algokit-signing
certificate-profile-name: algokit
files-folder: ${{ env.BINARY_BUILD_DIR }}
files-folder-filter: exe
file-digest: SHA256
timestamp-rfc3161: http://timestamp.acs.microsoft.com
timestamp-digest: SHA256
- name: Build winget installer
shell: pwsh
run: |
& .\scripts\winget\build-installer.ps1 `
-binaryDir '${{ env.BINARY_BUILD_DIR }}' `
-releaseVersion '${{ inputs.version }}' `
-outputFile '${{ env.WINGET_INSTALLER }}'
- name: Sign winget installer
if: ${{ inputs.with_codesign == 'true' }}
uses: azure/trusted-signing-action@v0.3.20
with:
azure-tenant-id: ${{ inputs.azure_tenant_id }}
azure-client-id: ${{ inputs.azure_client_id }}
azure-client-secret: ${{ inputs.azure_client_secret }}
endpoint: https://weu.codesigning.azure.net/
trusted-signing-account-name: algokit-signing
certificate-profile-name: algokit
files-folder: ${{ env.WINGET_INSTALLER }}
files-folder-filter: msix
file-digest: SHA256
timestamp-rfc3161: http://timestamp.acs.microsoft.com
timestamp-digest: SHA256
- name: Upload winget artifact
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.package_name }}-winget
path: ${{ env.WINGET_INSTALLER }}
if-no-files-found: error
================================================
FILE: .github/actions/install-apple-dev-id-cert/action.yaml
================================================
name: "Install Apple Developer ID certificate"
description: "Install Apple Developer ID certificate to macos-build keychain"
inputs:
cert_data:
description: "Base64 string represents the Apple developer ID certificate"
required: true
cert_password:
description: "The password to unlock the Apple developer ID certificate"
required: true
runs:
using: "composite"
steps:
- name: Install cert
shell: bash
env:
APPLE_CERT_DATA: ${{ inputs.cert_data }}
APPLE_CERT_PASSWORD: ${{ inputs.cert_password }}
run: |
# Export certs
echo "$APPLE_CERT_DATA" | base64 --decode > /tmp/certs.p12
# Create keychain
security create-keychain -p actions macos-build.keychain
security default-keychain -s macos-build.keychain
security unlock-keychain -p actions macos-build.keychain
security set-keychain-settings -t 3600 -u macos-build.keychain
echo "Keychain created"
# Import certs to keychain
security import /tmp/certs.p12 -k ~/Library/Keychains/macos-build.keychain -P "$APPLE_CERT_PASSWORD" -T /usr/bin/codesign -T /usr/bin/productsign
echo "Cert imported"
# Key signing
security set-key-partition-list -S apple-tool:,apple: -s -k actions macos-build.keychain
echo "Key signed"
# Delete temp file
rm /tmp/certs.p12
echo "Done"
================================================
FILE: .github/actions/setup-poetry/action.yaml
================================================
name: "Python Poetry Action"
description: "An action to setup Poetry"
runs:
using: "composite"
steps:
# A workaround for pipx isn't installed on M1 runner.
# We should remove it after this issue is resolved.
# https://github.com/actions/runner-images/issues/9256
- if: ${{ runner.os == 'macOS' && runner.arch == 'ARM64' }}
run: |
pip install poetry
pip install poetry-plugin-export
shell: bash
- if: ${{ runner.os != 'macOS' || runner.arch != 'ARM64' }}
run: |
pip install --user pipx
pipx ensurepath
pipx install poetry ${{ runner.os == 'macOS' && '--python "$Python_ROOT_DIR/bin/python"' || '' }}
pipx inject poetry poetry-plugin-export
shell: bash
- name: Get full Python version
id: full-python-version
shell: bash
run: echo "full_version=$(python -c 'import sys; print(".".join(map(str, sys.version_info[:3])))')" >> $GITHUB_OUTPUT
- name: Setup poetry cache
uses: actions/cache@v4
with:
path: ./.venv
key: venv-${{ hashFiles('poetry.lock') }}-${{ runner.os }}-${{ runner.arch }}-${{ steps.full-python-version.outputs.full_version }}
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "chore(deps)"
groups:
all:
patterns:
- "*"
update-types:
- "minor"
- "patch"
================================================
FILE: .github/pull_request_template.md
================================================
Fixes #
## Proposed Changes
-
-
-
================================================
FILE: .github/workflows/build-binaries.yaml
================================================
name: Build, Test and Publish Pyinstaller Binaries
on:
workflow_call:
inputs:
production_release:
required: true
type: string
python_version:
required: true
type: string
release_version:
required: false
type: string
jobs:
build-binaries:
runs-on: ${{ matrix.os }}
strategy:
matrix:
# macos-14 is the Apple Silicon M1 runner (mac os 14)
# macos-15-intel is the last available Intel Mac runner (mac os 15)
# See https://github.com/actions/runner-images?tab=readme-ov-file#available-images
os: [ubuntu-22.04, windows-latest, macos-15-intel, macos-14]
steps:
- name: Set signing condition
id: signing
run: |
# Allow signing on:
# 1. Main branch non-PR events when production_release is true OR
# 2. Main branch CRON triggered events
if [[ "${{ github.event_name }}" != "pull_request" && \
"${{ github.ref_name }}" == "main" && \
("${{ inputs.production_release }}" == "true" || "${{ github.event_name }}" == "schedule") ]]; then
echo "allowed=true" >> $GITHUB_OUTPUT
else
echo "allowed=false" >> $GITHUB_OUTPUT
fi
shell: bash
- name: Checkout source code
uses: actions/checkout@v4
with:
ref: ${{ inputs.release_version != '' && format('v{0}', inputs.release_version) || '' }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ inputs.python_version }}
- name: Set up Poetry
uses: ./.github/actions/setup-poetry
- name: Install dependencies
run: poetry install --no-interaction
- name: Configure build environment
shell: bash
run: |
artifacts_dir="${{ github.workspace }}${{ runner.os == 'Windows' && '\dist\artifacts' || '/dist/artifacts' }}"
mkdir -p $artifacts_dir
package_name_version="${{ inputs.release_version != '' && format('-{0}', inputs.release_version) || '' }}"
package_name="algokit${package_name_version}-${{ runner.os }}_${{ runner.arch }}"
echo "PACKAGE_NAME=`echo $package_name | tr '[:upper:]' '[:lower:]'`" >> $GITHUB_ENV
echo "ARTIFACTS_DIR=${artifacts_dir}" >> $GITHUB_ENV
# GitHub doesn't support expressions in the uses block
- name: Build windows binary
if: ${{ runner.os == 'Windows' }}
uses: ./.github/actions/build-binaries/windows
with:
package_name: ${{ env.PACKAGE_NAME }}
version: ${{ inputs.release_version }}
artifacts_dir: ${{ env.ARTIFACTS_DIR }}
with_codesign: ${{ steps.signing.outputs.allowed }}
azure_tenant_id: ${{ steps.signing.outputs.allowed == 'true' && secrets.AZURE_TENANT_ID || '' }}
azure_client_id: ${{ steps.signing.outputs.allowed == 'true' && secrets.AZURE_CLIENT_ID || '' }}
azure_client_secret: ${{ steps.signing.outputs.allowed == 'true' && secrets.AZURE_CLIENT_SECRET || '' }}
- name: Build linux binary
if: ${{ runner.os == 'Linux' }}
uses: ./.github/actions/build-binaries/linux
with:
package_name: ${{ env.PACKAGE_NAME }}
version: ${{ inputs.release_version }}
artifacts_dir: ${{ env.ARTIFACTS_DIR }}
- name: Install Apple Developer Id Cert
if: ${{ runner.os == 'macOS' && steps.signing.outputs.allowed == 'true' }}
uses: ./.github/actions/install-apple-dev-id-cert
with:
cert_data: ${{ secrets.APPLE_CERT_DATA }}
cert_password: ${{ secrets.APPLE_CERT_PASSWORD }}
- name: Build macOS binary
if: ${{ runner.os == 'macOS' }}
uses: ./.github/actions/build-binaries/macos
with:
package_name: ${{ env.PACKAGE_NAME }}
version: ${{ inputs.release_version }}
artifacts_dir: ${{ env.ARTIFACTS_DIR }}
with_codesign: ${{ steps.signing.outputs.allowed }}
apple_team_id: ${{ steps.signing.outputs.allowed == 'true' && secrets.APPLE_TEAM_ID || '' }}
apple_bundle_id: ${{ inputs.production_release == 'true' && vars.APPLE_BUNDLE_ID || format('beta.{0}', vars.APPLE_BUNDLE_ID) }}
apple_cert_id: ${{ steps.signing.outputs.allowed == 'true' && secrets.APPLE_CERT_ID || '' }}
apple_notary_user: ${{ steps.signing.outputs.allowed == 'true' && secrets.APPLE_NOTARY_USER || '' }}
apple_notary_password: ${{ steps.signing.outputs.allowed == 'true' && secrets.APPLE_NOTARY_PASSWORD || '' }}
- name: Add binary to path
run: |
echo "${{ github.workspace }}${{ runner.os == 'Windows' && '\dist\algokit' || '/dist/algokit' }}" >> $GITHUB_PATH
shell: bash
- name: Run portability tests
if: ${{ runner.os == 'Windows' }}
run: |
git config --global user.email "actions@github.com" && git config --global user.name "github-actions"
poetry run pytest tests/ -m pyinstaller_binary_tests --log-cli-level=INFO
shell: cmd
- name: Run portability tests
if: ${{ runner.os != 'Windows' }}
run: |
git config --global user.email "actions@github.com" && git config --global user.name "github-actions"
poetry run pytest tests/ -m pyinstaller_binary_tests --log-cli-level=INFO
shell: bash
# softprops/action-gh-release doesn't support the \ character in paths
- name: Adjust artifacts directory for softprops/action-gh-release
if: ${{ runner.os == 'Windows' }}
shell: pwsh
run: |
$adjusted = '${{ env.ARTIFACTS_DIR }}' -replace '\\','/'
echo "ARTIFACTS_DIR=$adjusted" >> $env:GITHUB_ENV
- name: Append artifacts to release
if: ${{ inputs.production_release == 'true' }}
uses: softprops/action-gh-release@v1
with:
fail_on_unmatched_files: true
files: |
${{ env.ARTIFACTS_DIR }}/*.*
tag_name: ${{ format('v{0}', inputs.release_version) }}
prerelease: ${{ contains(inputs.release_version, 'beta') }}
================================================
FILE: .github/workflows/build-python.yaml
================================================
name: Build, Test and Publish Python
on: [workflow_call]
jobs:
build-python:
strategy:
fail-fast: false
matrix:
os: ["ubuntu-latest", "macos-latest", "windows-latest"]
python: ["3.10", "3.11", "3.12", "3.13", "3.14"]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout source code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Set up Poetry
uses: ./.github/actions/setup-poetry
- name: Install dependencies
# TODO: remove fixed pipx dependency once 3.12 compatibility is addressed
# track here -> https://github.com/crytic/tealer/pull/209
run: poetry install --no-interaction --without docs && pipx install tealer==0.1.2
- name: Install PuyaPy
if: ${{ matrix.python == '3.12' }}
run: pipx install puyapy
- name: pytest
shell: bash
if: ${{ !(matrix.python == '3.12' && matrix.os == 'ubuntu-latest') }}
# git config is needed due to several tests relying on e2e copier invocation and copier relies on git during `copy` command
run: |
set -o pipefail
git config --global user.email "actions@github.com" && git config --global user.name "github-actions"
poetry run pytest -n auto
id: pytest
- name: pytest + coverage
shell: bash
if: matrix.python == '3.12' && matrix.os == 'ubuntu-latest'
env:
COVERAGE_CORE: sysmon
# git config is needed due to several tests relying on e2e copier invocation and copier relies on git during `copy` command
run: |
set -o pipefail
git config --global user.email "actions@github.com" && git config --global user.name "github-actions"
poetry run pytest -n auto --junitxml=pytest-junit.xml --cov-report=term-missing:skip-covered --cov=src | tee pytest-coverage.txt
id: pytest-cov
- name: Upload received snapshots (in case of failure)
if: failure() && (steps.pytest.outcome == 'failure' || steps.pytest-cov.outcome == 'failure')
uses: actions/upload-artifact@v4
with:
name: test-artifacts-${{ matrix.os }}-python${{ matrix.python }}
path: tests/**/*.received.txt
- name: pytest coverage comment - using Python 3.12 on ubuntu-latest
if: matrix.python == '3.12' && matrix.os == 'ubuntu-latest'
continue-on-error: true # forks fail to add a comment, so continue any way
uses: MishaKav/pytest-coverage-comment@main
with:
pytest-coverage-path: ./pytest-coverage.txt
junitxml-path: ./pytest-junit.xml
- name: Build Wheel
run: poetry build --format wheel
================================================
FILE: .github/workflows/cd.yaml
================================================
name: Continuous Delivery of Python package
on:
push:
branches:
- main
paths-ignore:
- "docs/**"
- "**.md"
- ".vscode/**"
- ".idea/**"
- ".gitignore"
- ".editorconfig"
- ".pre-commit-config.yaml"
- ".github/**"
- "tests/**"
- "scripts/**"
workflow_dispatch:
inputs:
production_release:
description: "Production release?"
required: true
default: "true"
concurrency: release
permissions:
contents: write
packages: read
jobs:
ci-check-python:
name: Check Python
uses: ./.github/workflows/check-python.yaml
ci-build-python:
name: Build Python
uses: ./.github/workflows/build-python.yaml
needs: ci-check-python
release:
name: Release wheels to pypi
needs: ci-build-python
runs-on: ubuntu-latest
outputs:
release_version: ${{ steps.get_release_version.outputs.RELEASE_VERSION }}
steps:
- name: Generate bot token
uses: actions/create-github-app-token@v1
id: app_token
with:
app-id: ${{ secrets.BOT_ID }}
private-key: ${{ secrets.BOT_SK }}
- uses: actions/checkout@v4
with:
# Fetch entire repository history so we can determine version number from it
fetch-depth: 0
token: ${{ steps.app_token.outputs.token }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Set up Poetry
uses: ./.github/actions/setup-poetry
- name: Install dependencies
run: poetry install --no-interaction --no-root
- name: Get branch name
shell: bash
run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT
id: get_branch
- name: Set Git user as GitHub actions
run: git config --global user.email "179917785+engineering-ci[bot]@users.noreply.github.com" && git config --global user.name "engineering-ci[bot]"
- name: Create Continuous Deployment - Feature Branch
if: steps.get_branch.outputs.branch != 'main' && inputs.production_release != 'true'
run: |
poetry run semantic-release \
-v DEBUG \
--prerelease \
--patch \
--define=prerelease_tag=beta+${{ steps.get_branch.outputs.branch }} \
--define=branch=${{ steps.get_branch.outputs.branch }} \
publish
release_version_tag="$(git describe $(git rev-list --tags --max-count=1))"
gh release edit --prerelease $release_version_tag
echo "RELEASE_VERSION=${release_version_tag:1}" >> $GITHUB_ENV
env:
GH_TOKEN: ${{ steps.app_token.outputs.token }}
REPOSITORY_USERNAME: __token__
REPOSITORY_PASSWORD: ${{ secrets.PYPI_API_KEY }}
- name: Create Continuous Deployment - Beta (non-prod)
if: steps.get_branch.outputs.branch == 'main' && inputs.production_release != 'true'
run: |
poetry run semantic-release \
-v DEBUG \
--prerelease \
--define=branch=main \
publish
release_version="$(poetry run semantic-release print-version --current)"
gh release edit --prerelease "v$release_version"
echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV
env:
GH_TOKEN: ${{ steps.app_token.outputs.token }}
REPOSITORY_USERNAME: __token__
REPOSITORY_PASSWORD: ${{ secrets.PYPI_API_KEY }}
- name: Create Continuous Deployment - Production
if: steps.get_branch.outputs.branch == 'main' && inputs.production_release == 'true'
run: |
poetry run semantic-release \
-v DEBUG \
--define=version_source="commit" \
--define=patch_without_tag=true \
--define=upload_to_repository=true \
--define=branch=main \
publish
release_version="$(poetry run semantic-release print-version --current)"
echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV
env:
GH_TOKEN: ${{ steps.app_token.outputs.token }}
REPOSITORY_USERNAME: __token__
REPOSITORY_PASSWORD: ${{ secrets.PYPI_API_KEY }}
- name: Get release version
shell: bash
run: echo "RELEASE_VERSION=$RELEASE_VERSION" >> $GITHUB_OUTPUT
id: get_release_version
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: algokit-cli
path: dist/algokit*-py3-none-any.whl
if-no-files-found: error
build-and-upload-binaries:
name: Build and Upload Binaries
if: ${{ github.ref_name == 'main' }}
uses: ./.github/workflows/build-binaries.yaml
needs: release
with:
production_release: ${{ inputs.production_release }}
python_version: "3.12"
release_version: ${{ needs.release.outputs.release_version }}
secrets: inherit
cd-publish-release-packages:
name: Release binaries via distribution channels
needs:
- release
- build-and-upload-binaries
if: ${{ github.ref_name == 'main' && inputs.production_release == 'true' }} # Might want to adjust this to publish (pre-release) on merge as well.
uses: ./.github/workflows/publish-release-packages.yaml
with:
artifactName: algokit-cli
release_version: ${{ needs.release.outputs.release_version }}
secrets: inherit
================================================
FILE: .github/workflows/check-python.yaml
================================================
name: Check Python Code
on:
workflow_call:
jobs:
check-python:
runs-on: "ubuntu-latest"
steps:
- name: Checkout source code
uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Set up Poetry
uses: ./.github/actions/setup-poetry
- name: Install dependencies
run: poetry install --no-interaction --with docs
- name: Audit with pip-audit
run: |
poetry export --without=dev --without=docs -o requirements.txt
poetry run pip-audit -r requirements.txt
# If a vulnerability is found in a dependency without an available fix,
# it can be temporarily ignored by adding --ignore-vuln e.g. poetry run pip-audit -r requirements.txt --ignore-vuln 'GHSA-xxxxx'
- name: Check formatting with Ruff
run: |
# stop the build if there are files that don't meet formatting requirements
poetry run ruff format --check .
- name: Check linting with Ruff
run: |
# stop the build if there are Python syntax errors or undefined names
poetry run ruff check .
- name: Check types with mypy
run: poetry run mypy
- name: Check docs are up to date
run: |
poetry run poe docs
[ $(git status --porcelain docs/ | wc -l) -eq "0" ]
================================================
FILE: .github/workflows/clear-caches.yaml
================================================
name: Clear Repository Caches
on:
schedule:
# Run every 5 days at 2 AM UTC
- cron: "0 2 */5 * *"
workflow_dispatch: # Allow manual trigger
permissions:
actions: write
jobs:
clear-caches:
name: Clear Repository Caches
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Clear all repository caches
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "🧹 Starting cache cleanup process..."
if gh cache delete --all --succeed-on-no-caches; then
echo "🎉 Cache cleanup completed!"
else
echo "❌ Failed to clear caches"
exit 1
fi
================================================
FILE: .github/workflows/pr.yaml
================================================
name: Codebase validation
on:
pull_request:
paths-ignore:
- "README.md"
schedule:
- cron: "0 8 * * 1" # Each monday 8 AM UTC
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
pr-check:
name: Check Python
uses: ./.github/workflows/check-python.yaml
pr-build:
name: Build & Test Python
needs: pr-check
uses: ./.github/workflows/build-python.yaml
pr-binaries-build:
name: Build & Test Binaries
needs: pr-check
uses: ./.github/workflows/build-binaries.yaml
with:
production_release: "false"
python_version: "3.12"
secrets: inherit
================================================
FILE: .github/workflows/publish-release-packages.yaml
================================================
name: Publish packages to public repositories
on:
workflow_call:
inputs:
artifactName:
required: true
type: string
description: "The github artifact holding the wheel file which will be published"
release_version:
required: true
type: string
description: "The release version that will be published (e.g. 0.1.0)"
do_brew:
required: false
default: true
type: boolean
description: "Publish to brew repository"
do_snap:
required: false
default: true
type: boolean
description: "Publish to snap repository"
do_winget:
required: false
default: true
type: boolean
description: "Publish to Winget repository"
workflow_dispatch:
inputs:
artifactName:
required: true
type: string
description: "The github artifact holding the wheel file which will be published"
release_version:
required: true
type: string
description: "The release version that will be published (e.g. 0.1.0)"
do_brew:
required: false
default: true
type: boolean
description: "Publish to brew repository"
do_snap:
required: false
default: true
type: boolean
description: "Publish to snap repository"
do_winget:
required: false
default: true
type: boolean
description: "Publish to Winget repository"
jobs:
publish-brew:
runs-on: ubuntu-latest
if: ${{ inputs.do_brew }}
steps:
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ secrets.BOT_ID }}
private-key: ${{ secrets.BOT_SK }}
repositories: homebrew-tap
owner: algorandfoundation
- name: Checkout source code
uses: actions/checkout@v4
- name: Download wheel from release
run: gh release download v${{ inputs.release_version }} --pattern "*.whl" --dir dist
env:
GH_TOKEN: ${{ github.token }}
- name: Download binary artifact from release
run: gh release download v${{ inputs.release_version }} --pattern "*-brew.tar.gz" --dir dist
env:
GH_TOKEN: ${{ github.token }}
- name: Set Git user as GitHub actions
run: git config --global user.email "179917785+engineering-ci[bot]@users.noreply.github.com" && git config --global user.name "engineering-ci[bot]"
- name: Update homebrew cask
run: scripts/update-brew-cask.sh "dist/algokit*-py3-none-any.whl" "dist/algokit*-macos_arm64-brew.tar.gz" "dist/algokit*-macos_x64-brew.tar.gz" "algorandfoundation/homebrew-tap"
env:
TAP_GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
publish-winget:
runs-on: windows-latest
if: ${{ inputs.do_winget }}
steps:
- name: Checkout source code
uses: actions/checkout@v4
- name: Publish to winget
shell: pwsh
env:
WINGET_GITHUB_TOKEN: ${{ secrets.WINGET_GITHUB_TOKEN }}
run: |
echo 'Publishing to winget'
& .\scripts\winget\update-package.ps1 `
-releaseVersion '${{ inputs.release_version }}'
publish-snap:
runs-on: ubuntu-latest
if: ${{ inputs.do_snap }}
steps:
- name: Checkout source code
uses: actions/checkout@v4
- name: Download binary artifact from release
run: |
gh release download v${{ inputs.release_version }} --pattern "*-snap.tar.gz" --dir dist
BINARY_PATH=$(ls dist/*-snap.tar.gz)
echo "BINARY_PATH=$BINARY_PATH" >> $GITHUB_ENV
env:
GH_TOKEN: ${{ github.token }}
- name: Generate snapcraft.yaml
run: |
./scripts/snap/create-snapcraft-yaml.sh ${{ github.workspace }} ${{ inputs.release_version }} ${{ env.BINARY_PATH }} "stable"
- name: Upload snapcraft.yaml as reference artifact
uses: actions/upload-artifact@v4
with:
name: snapcraft-yaml
path: ${{ github.workspace }}/snap/snapcraft.yaml
- name: Build snap
uses: snapcore/action-build@v1
with:
snapcraft-args: --target-arch amd64
- name: Set path to snap binary
shell: bash
run: |
echo "SNAP_BINARY_PATH=$(find ${{ github.workspace }} -name '*.snap')" >> $GITHUB_ENV
- name: Publish snap
uses: snapcore/action-publish@v1
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_RELEASE_TOKEN }}
with:
snap: ${{ env.SNAP_BINARY_PATH }}
release: stable
================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
pytest-coverage.txt
pytest-junit.xml
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Ruff (linter)
.ruff_cache/
# Cython debug symbols
cython_debug/
# PyCharm
.idea/
!.idea/runConfigurations
# macOS
.DS_Store
# we use this file for quickly editing run/debug args, it shouldn't be committed
/args.in
# Received approval test files
*.received.*
#Sphinx
.doctrees/
docs/cli/temp.md
# Miscellaneous
ci_token.txt
.algokit/
temp/
================================================
FILE: .idea/runConfigurations/Run_AlgoKit_CLI.xml
================================================
================================================
FILE: .pre-commit-config.yaml
================================================
repos:
- repo: local
hooks:
- id: ruff-format
name: ruff-format
description: "Run 'ruff format' for extremely fast Python formatting"
entry: poetry run ruff format
language: system
types: [python]
args: [--no-cache]
require_serial: true
exclude: ^src/.*core/_vendor/
- id: ruff
name: ruff
description: "Run 'ruff' for extremely fast Python linting"
entry: poetry run ruff check
language: system
"types": [python]
args: [--fix, --no-cache]
require_serial: false
files: "^(src|tests)/"
exclude: "^src/algokit/core/_vendor/"
- id: mypy
name: mypy
description: "`mypy` will check Python types for correctness"
entry: poetry run mypy
language: system
types_or: [python, pyi]
require_serial: true
files: "^(src|tests)/"
exclude: "^src/algokit/core/_vendor/"
================================================
FILE: .vscode/extensions.json
================================================
{
"recommendations": [
"esbenp.prettier-vscode",
"ms-python.python",
"ms-python.vscode-pylance",
"charliermarsh.ruff",
"tamasfe.even-better-toml",
"editorconfig.editorconfig",
"matangover.mypy"
]
}
================================================
FILE: .vscode/launch.json
================================================
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Module",
"type": "debugpy",
"cwd": "${workspaceFolder}",
"request": "launch",
"module": "debug",
"justMyCode": false,
"console": "integratedTerminal"
},
{
"name": "Python: Debug Pytest",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"purpose": ["debug-test"],
"console": "integratedTerminal",
"justMyCode": false,
"env": {
"PYTHONPATH": "${workspaceFolder}/src",
"PYTEST_ADDOPTS": "--no-cov"
}
}
]
}
================================================
FILE: .vscode/settings.json
================================================
{
// General - see also /.editorconfig
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": "explicit"
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"files.exclude": {
"**/.git": true,
"**/.DS_Store": true,
"**/Thumbs.db": true,
".mypy_cache": true,
".pytest_cache": true,
".ruff_cache": true,
"**/__pycache__": true,
".idea": true
},
// Python
"python.defaultInterpreterPath": "${workspaceFolder}/.venv",
"python.analysis.extraPaths": ["${workspaceFolder}/src"],
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff"
},
"python.analysis.typeCheckingMode": "basic",
"ruff.enable": true,
"ruff.lint.run": "onSave",
"ruff.lint.args": ["--config=pyproject.toml"],
"ruff.importStrategy": "fromEnvironment",
"ruff.fixAll": true, //lint and fix all files in workspace
"ruff.organizeImports": true, //organize imports on save
"ruff.codeAction.disableRuleComment": {
"enable": true
},
"ruff.codeAction.fixViolation": {
"enable": true
},
"mypy.configFile": "pyproject.toml",
// set to empty array to use config from project
"mypy.targets": [],
"mypy.runUsingActiveInterpreter": true,
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
// PowerShell
"[powershell]": {
"editor.defaultFormatter": "ms-vscode.powershell"
},
"powershell.codeFormatting.preset": "Stroustrup",
"python.testing.pytestArgs": ["."]
}
================================================
FILE: CHANGELOG.md
================================================
# Changelog
## v2.10.2 (2026-01-30)
## v2.10.1 (2026-01-29)
### Fix
* Update versioning constraint to support 3.14 ([#706](https://github.com/algorandfoundation/algokit-cli/issues/706)) ([`b6be55a`](https://github.com/algorandfoundation/algokit-cli/commit/b6be55ac219fcc6f46bc938644a272586efa4ff8))
## v2.10.0 (2025-12-12)
### Feature
* Update to use the localnet specific conduit algod importer ([#700](https://github.com/algorandfoundation/algokit-cli/issues/700)) ([`c9b423a`](https://github.com/algorandfoundation/algokit-cli/commit/c9b423afa96e6ae91d29064fea09a4b5293c4c55))
* Add check flag to control when image update checks are run ([`dc39e49`](https://github.com/algorandfoundation/algokit-cli/commit/dc39e495b489bb110261cc5199d12a684fae2870))
* Reduce frequency of localnet image update checks ([`3de015e`](https://github.com/algorandfoundation/algokit-cli/commit/3de015e60a32f810891b7f8d6d475f9595ff9bda))
### Documentation
* Updated invalid links and fixed some typos in the docs ([#693](https://github.com/algorandfoundation/algokit-cli/issues/693)) ([`35518c3`](https://github.com/algorandfoundation/algokit-cli/commit/35518c332b789ca7b3a70ed3321e8d295d5c3ab9))
* Removed obsolete info and fixed typos ([#687](https://github.com/algorandfoundation/algokit-cli/issues/687)) ([`330cc05`](https://github.com/algorandfoundation/algokit-cli/commit/330cc059bf7bf1966a093edc333d3d4d87047276))
## v2.9.1 (2025-09-11)
### Fix
* Dynamically detect Windows SDK tools for GitHub Actions compatibility ([#686](https://github.com/algorandfoundation/algokit-cli/issues/686)) ([`db88fb9`](https://github.com/algorandfoundation/algokit-cli/commit/db88fb9129061f7fcb8282c7745a9bd3178b872d))
* Enables package manager command translation ([#684](https://github.com/algorandfoundation/algokit-cli/issues/684)) ([`a08eae5`](https://github.com/algorandfoundation/algokit-cli/commit/a08eae534cd9898687ba80400ba132221fcea69d))
## v2.9.0 (2025-09-03)
### Feature
* Pnpm and uv support ([#672](https://github.com/algorandfoundation/algokit-cli/issues/672)) ([`52293f4`](https://github.com/algorandfoundation/algokit-cli/commit/52293f43e7d0c441fb2863f5871a3ae7461119cd))
### Fix
* Pin prompt_toolkit as the latest version breaks algokit init ([`d1dc658`](https://github.com/algorandfoundation/algokit-cli/commit/d1dc658f4fada935d8e8ccc31067ce695bd487fb))
## v2.8.0 (2025-07-29)
### Feature
* Replace GITHUB_TOKEN with engineering-ci bot token in release workflows ([`4070cb0`](https://github.com/algorandfoundation/algokit-cli/commit/4070cb013b9af77fc4ae66cbb6edb8de7c431ce2))
### Fix
* Update the brew cask to not require sudo on install ([`a82f74b`](https://github.com/algorandfoundation/algokit-cli/commit/a82f74ba90d3ab61ddba98356ed512579d158e38))
* Bust cache by tweaking the poetry lock ([#662](https://github.com/algorandfoundation/algokit-cli/issues/662)) ([`a137989`](https://github.com/algorandfoundation/algokit-cli/commit/a137989f1d679ed47e6219998f488bbf5571a74c))
## v2.7.1 (2025-06-19)
### Fix
* Adds health check for indexer ([#653](https://github.com/algorandfoundation/algokit-cli/issues/653)) ([`ceed902`](https://github.com/algorandfoundation/algokit-cli/commit/ceed902315770a8af68219e1eca52a37d4af7cf2))
## v2.7.0 (2025-05-15)
### Feature
* Add algokit init example command ([`70ed744`](https://github.com/algorandfoundation/algokit-cli/commit/70ed744574a8689374b3396c224c636966848e47))
* Added the choose example selector ([`da5cc9e`](https://github.com/algorandfoundation/algokit-cli/commit/da5cc9e538dae458230a0ff78ff3ab7671777ddb))
* Adding new init command structure with example subcommand ([`3fb110a`](https://github.com/algorandfoundation/algokit-cli/commit/3fb110afa867a65d67aeb605a3a5c23f651d278f))
### Fix
* Add fallback for browser opening in explore command ([`71088cf`](https://github.com/algorandfoundation/algokit-cli/commit/71088cf031c6575c7368f60ad2d2ea20311fe1cd))
* Add fallback for browser opening in explore command ([`d1be606`](https://github.com/algorandfoundation/algokit-cli/commit/d1be606cc252affb5de0516c9c973ab176b574b8))
* Compile ts hangs when puya-ts is detected but not installed in the project ([#628](https://github.com/algorandfoundation/algokit-cli/issues/628)) ([`f3cd199`](https://github.com/algorandfoundation/algokit-cli/commit/f3cd19967068e4310eaae5acbf85d8ec445e5181))
## v2.6.2 (2025-03-28)
### Fix
* Raise min required copier version to 3.6.0 ([#623](https://github.com/algorandfoundation/algokit-cli/issues/623)) ([`9ef7b51`](https://github.com/algorandfoundation/algokit-cli/commit/9ef7b51112cdf4e27a4ef89d1df6dedeecf9448e))
## v2.6.1 (2025-03-27)
### Fix
* Handle non zero exit code when running npm ls ([#622](https://github.com/algorandfoundation/algokit-cli/issues/622)) ([`3d6f3c9`](https://github.com/algorandfoundation/algokit-cli/commit/3d6f3c967302398dbbfab41ba96216e412d068a8))
* Resolve project run issue by forcing utf-8 encoding on windows ([#620](https://github.com/algorandfoundation/algokit-cli/issues/620)) ([`b837417`](https://github.com/algorandfoundation/algokit-cli/commit/b837417e7f6b01c6ea5abda3dc664cd7c4531e85))
### Documentation
* AK-194: Updated dev portal links ([#615](https://github.com/algorandfoundation/algokit-cli/issues/615)) ([`52bb519`](https://github.com/algorandfoundation/algokit-cli/commit/52bb5191fd7153a7f2ec32b6646a33d3deabdec3))
* Clarify when python is needed ([#617](https://github.com/algorandfoundation/algokit-cli/issues/617)) ([`4661f71`](https://github.com/algorandfoundation/algokit-cli/commit/4661f71a97293f3697476a90fea4054b1f516dec))
## v2.6.0 (2025-03-19)
### Feature
* Add typescript template integration ([#614](https://github.com/algorandfoundation/algokit-cli/issues/614)) ([`7fc345c`](https://github.com/algorandfoundation/algokit-cli/commit/7fc345c783258325de3231de9488191e4b2932aa))
* Puya-ts support under `compile` command group ([#612](https://github.com/algorandfoundation/algokit-cli/issues/612)) ([`9bd9056`](https://github.com/algorandfoundation/algokit-cli/commit/9bd90560da69cf511b0452d771d53a0c588214c2))
* Npm runs `ci` instead of `install` when CI flag is present or passed explicitly ([#605](https://github.com/algorandfoundation/algokit-cli/issues/605)) ([`cc8a95d`](https://github.com/algorandfoundation/algokit-cli/commit/cc8a95d529452467d3e2849f9d998ae55178a2b5))
### Fix
* Fix configured localnet ([#610](https://github.com/algorandfoundation/algokit-cli/issues/610)) ([`ba91e82`](https://github.com/algorandfoundation/algokit-cli/commit/ba91e82a226867cb764bf36fc43654924ea5ba4c))
### Documentation
* Removed mentions to dappflow from ADR document. ([#601](https://github.com/algorandfoundation/algokit-cli/issues/601)) ([`6691cc7`](https://github.com/algorandfoundation/algokit-cli/commit/6691cc70e1cbf812e95cbab6b3ce3143a3b6fd77))
* Update map image ([#602](https://github.com/algorandfoundation/algokit-cli/issues/602)) ([`eb03bf7`](https://github.com/algorandfoundation/algokit-cli/commit/eb03bf7f7541286097627fe424c64070bd59f108))
## v2.5.2 (2025-01-07)
### Fix
* Handle client generation in a dir containing multiple app spec types ([#599](https://github.com/algorandfoundation/algokit-cli/issues/599)) ([`1a479a1`](https://github.com/algorandfoundation/algokit-cli/commit/1a479a1e33ae4ba0e03a12c12210372cb8f59be1))
### Documentation
* Add info about keyring in wsl2 ([#600](https://github.com/algorandfoundation/algokit-cli/issues/600)) ([`5e5df31`](https://github.com/algorandfoundation/algokit-cli/commit/5e5df31c79b99f375726a57780c0732f2bafcf73))
## v2.5.1 (2024-11-28)
### Fix
* Duplicate code-workspace declarations ([#596](https://github.com/algorandfoundation/algokit-cli/issues/596)) ([`505c6c6`](https://github.com/algorandfoundation/algokit-cli/commit/505c6c624d869d4bef9adaa973dad7d735b7bae0))
## v2.5.0 (2024-11-25)
### Feature
* Add support for ARC56 typed client generation ([#595](https://github.com/algorandfoundation/algokit-cli/issues/595)) ([`72807c3`](https://github.com/algorandfoundation/algokit-cli/commit/72807c3b7e8114528e026a0fa34b8ba07a49fc8a))
### Documentation
* Adding extra troubleshooting case; extra prereq for winget installation ([#591](https://github.com/algorandfoundation/algokit-cli/issues/591)) ([`84d7690`](https://github.com/algorandfoundation/algokit-cli/commit/84d769014bf71ddd798cace122bad141b1429416))
## v2.4.3 (2024-10-29)
### Fix
* Edge cases for running interactive goal commands with --tty flag ([#589](https://github.com/algorandfoundation/algokit-cli/issues/589)) ([`e280a7f`](https://github.com/algorandfoundation/algokit-cli/commit/e280a7f9e6208b4a15f384809a2f0c8607ed9fb7))
## v2.4.2 (2024-10-10)
### Documentation
* More details on snap install in README.md ([#577](https://github.com/algorandfoundation/algokit-cli/issues/577)) ([`44f900f`](https://github.com/algorandfoundation/algokit-cli/commit/44f900ffdf7a9021aa2ddcf97a45a384852ce6f8))
## v2.4.1 (2024-09-19)
### Fix
* Pinning requests dependency ([#575](https://github.com/algorandfoundation/algokit-cli/issues/575)) ([`2fc2dfe`](https://github.com/algorandfoundation/algokit-cli/commit/2fc2dfe71d195aaadd3c0d20017ce3ceb2f0d414))
## v2.4.0 (2024-09-19)
### Feature
* Adding flags to enable dev mode; flags for custom path to localnet config ([#569](https://github.com/algorandfoundation/algokit-cli/issues/569)) ([`09c2c10`](https://github.com/algorandfoundation/algokit-cli/commit/09c2c107d037c40a85c545bce9fc97de79c2c157))
## v2.3.0 (2024-08-23)
### Feature
* Explicit sequential execution; extra args param for run/deploy commands ([#557](https://github.com/algorandfoundation/algokit-cli/issues/557)) ([`41f5c7b`](https://github.com/algorandfoundation/algokit-cli/commit/41f5c7b631a90a06d51676efd1f437416c8cb750))
## v2.2.3 (2024-08-02)
### Fix
* Add warning for cases when `algokit explore` is used within wsl ([#549](https://github.com/algorandfoundation/algokit-cli/issues/549)) ([`3e2d017`](https://github.com/algorandfoundation/algokit-cli/commit/3e2d0170bcc8870dda3d62141b93866fe8bcad1d))
* Build binaries with the correct version information ([#550](https://github.com/algorandfoundation/algokit-cli/issues/550)) ([`0725d8f`](https://github.com/algorandfoundation/algokit-cli/commit/0725d8f16c5999f706de486852c96a2f0d16603e))
## v2.2.2 (2024-07-29)
## v2.2.1 (2024-07-23)
### Documentation
* Extra notes on edge case with python installation on debian ([#539](https://github.com/algorandfoundation/algokit-cli/issues/539)) ([`f358e24`](https://github.com/algorandfoundation/algokit-cli/commit/f358e24122df759585034c7e3541f5a8f4c446f1))
## v2.2.0 (2024-07-08)
### Feature
* Adding default algorand network configs to use when no .env.{network} found ([#533](https://github.com/algorandfoundation/algokit-cli/issues/533)) ([`a726756`](https://github.com/algorandfoundation/algokit-cli/commit/a726756b2f96557a8e54e1f89c4926dc206265d3))
### Fix
* Given that .copier-answers.yml is now expected at .algokit folder, improve defaults lookup ([#535](https://github.com/algorandfoundation/algokit-cli/issues/535)) ([`5d319d3`](https://github.com/algorandfoundation/algokit-cli/commit/5d319d323a5a38e77d65895048e6a2a30e8b64d8))
## v2.1.4 (2024-06-27)
### Fix
* Filter null values from asset metadata ([#529](https://github.com/algorandfoundation/algokit-cli/issues/529)) ([`05411d6`](https://github.com/algorandfoundation/algokit-cli/commit/05411d638c0ef7600df3428a5da74f8666d226a7))
## v2.1.3 (2024-06-25)
### Fix
* Some localnet proxy tweaks ([#526](https://github.com/algorandfoundation/algokit-cli/issues/526)) ([`2c7999d`](https://github.com/algorandfoundation/algokit-cli/commit/2c7999daefc5071dd89a6dcdc2f0a3f7f3ef819b))
## v2.1.2 (2024-06-20)
### Fix
* Localnet status and proxy dns issue ([#525](https://github.com/algorandfoundation/algokit-cli/issues/525)) ([`a0c5bc6`](https://github.com/algorandfoundation/algokit-cli/commit/a0c5bc69e71fc64864f9f10ddd92f8c967f03416))
* Add localnet proxy to add Access-Control-Allow-Private-Network header ([#523](https://github.com/algorandfoundation/algokit-cli/issues/523)) ([`2267e9e`](https://github.com/algorandfoundation/algokit-cli/commit/2267e9e2ff2b707dc246021578b8dbc6bd43a021))
### Documentation
* Moving descriptions of workspace vs standalone to project.md ([#522](https://github.com/algorandfoundation/algokit-cli/issues/522)) ([`946c53a`](https://github.com/algorandfoundation/algokit-cli/commit/946c53a3d90fad983a21856c0cad969f37d90e6f))
* Minor revamp in project/config docs ([#521](https://github.com/algorandfoundation/algokit-cli/issues/521)) ([`872f6b1`](https://github.com/algorandfoundation/algokit-cli/commit/872f6b1dd01f843255fa2b76cb7e857c23aee4aa))
## v2.1.1 (2024-06-17)
### Fix
* Ensure utf-8 is used as part of cli animate method invocation (windows compatibility) ([#518](https://github.com/algorandfoundation/algokit-cli/issues/518)) ([`ba9e090`](https://github.com/algorandfoundation/algokit-cli/commit/ba9e0902880298beb6a883096d26b25e77d31422))
## v2.1.0 (2024-06-12)
### Feature
* GitHub Codespaces support in LocalNet command group ([#456](https://github.com/algorandfoundation/algokit-cli/issues/456)) ([`7eeaead`](https://github.com/algorandfoundation/algokit-cli/commit/7eeaeadc577dd12fa93c87cae18da497770d6f35))
### Documentation
* Updated docs to include updated links for project features ([`7c56b18`](https://github.com/algorandfoundation/algokit-cli/commit/7c56b181d984f3301e2abc59ea91128f2845ec66))
## v2.0.6 (2024-05-22)
### Fix
* Remove ConsensusProtocol = future; unpin algod ([#505](https://github.com/algorandfoundation/algokit-cli/issues/505)) ([`55fbda5`](https://github.com/algorandfoundation/algokit-cli/commit/55fbda511310c094675dca7ff45131006083df66))
## v2.0.5 (2024-05-21)
### Fix
* Pin localnet algod container to fix conduit issue in latest algod ([#502](https://github.com/algorandfoundation/algokit-cli/issues/502)) ([`6e760e9`](https://github.com/algorandfoundation/algokit-cli/commit/6e760e9c887187f053ea6a11b969ddc8cda3fb6a))
## v2.0.4 (2024-05-20)
### Fix
* Task transfer on rekeyed account and update dependencies ([#498](https://github.com/algorandfoundation/algokit-cli/issues/498)) ([`8592cbf`](https://github.com/algorandfoundation/algokit-cli/commit/8592cbff4b9c45b4394eb853761255a8d11b7510))
### Documentation
* Add troubleshooting section ([#496](https://github.com/algorandfoundation/algokit-cli/issues/496)) ([`ef1a504`](https://github.com/algorandfoundation/algokit-cli/commit/ef1a5046a7b3ba6ddf22e65a4b1fe7868196e625))
* Refine quick start ([#487](https://github.com/algorandfoundation/algokit-cli/issues/487)) ([`1964dec`](https://github.com/algorandfoundation/algokit-cli/commit/1964decd340a7847005cab4be408f6273fd5cb53))
* Remove spelling mistake in intro.md instalation docs ([#491](https://github.com/algorandfoundation/algokit-cli/issues/491)) ([`70c55e0`](https://github.com/algorandfoundation/algokit-cli/commit/70c55e050caf4309c76ae5aae1dd7a284db93382))
## v2.0.3 (2024-04-16)
### Fix
* Remove deprecated version from localnet compose file ([#476](https://github.com/algorandfoundation/algokit-cli/issues/476)) ([`4a3b1f0`](https://github.com/algorandfoundation/algokit-cli/commit/4a3b1f0c2dec5d03d12b42617ff546bd94d1da57))
### Documentation
* Minor refinements in npm min version spec ([#474](https://github.com/algorandfoundation/algokit-cli/issues/474)) ([`a887430`](https://github.com/algorandfoundation/algokit-cli/commit/a8874304319efc3449336a4bbb817471613d6743))
## v2.0.2 (2024-04-02)
### Fix
* Pin pyyaml-include transitive dep ([#472](https://github.com/algorandfoundation/algokit-cli/issues/472)) ([`970536c`](https://github.com/algorandfoundation/algokit-cli/commit/970536cb7246fcaf6b84aacda95a74f8ff9bc285))
### Documentation
* Adding node.js to prerequisites for installation as FYI ([`8147173`](https://github.com/algorandfoundation/algokit-cli/commit/8147173ba827ac3be4c4dec28a97abc16abbd2cf))
## v2.0.1 (2024-03-29)
### Documentation
* Few tweaks post release ([#465](https://github.com/algorandfoundation/algokit-cli/issues/465)) ([`a4a5645`](https://github.com/algorandfoundation/algokit-cli/commit/a4a5645c11790eba1162f7d80ade26fe40f83944))
## v2.0.0 (2024-03-27)
### Feature
* Algokit-cli v2 ([#462](https://github.com/algorandfoundation/algokit-cli/issues/462)) ([`182c449`](https://github.com/algorandfoundation/algokit-cli/commit/182c449544e4a23e17919e9629dfdc5ddbf399a5))
* LocalNet should run as an archival node so that you can access all blocks (useful for testing) ([#461](https://github.com/algorandfoundation/algokit-cli/issues/461)) ([`794cccc`](https://github.com/algorandfoundation/algokit-cli/commit/794cccce2bb4aeccfe56813af754406b87ba5112))
### Breaking
* 2.0 release ([`182c449`](https://github.com/algorandfoundation/algokit-cli/commit/182c449544e4a23e17919e9629dfdc5ddbf399a5))
## v1.13.1 (2024-03-20)
### Fix
* Create the npm dir in the app data directory on windows, as npx needs it ([#458](https://github.com/algorandfoundation/algokit-cli/issues/458)) ([`3195a1c`](https://github.com/algorandfoundation/algokit-cli/commit/3195a1c8cd21835d04a472d0d156ca08ef9030ec))
## v1.13.0 (2024-03-13)
### Feature
* Add command to compile python to TEAL with Puyapy ([`1030799`](https://github.com/algorandfoundation/algokit-cli/commit/10307990a07fd3fa8ba60f6886f5b4be722dc065))
### Fix
* Adjust how we run npx, so it supports all windows versions ([#454](https://github.com/algorandfoundation/algokit-cli/issues/454)) ([`a997953`](https://github.com/algorandfoundation/algokit-cli/commit/a997953871251b0f1dfed3ad6e2cb8901c2c5cd3))
### Documentation
* Ref commit for snapcraft ([#452](https://github.com/algorandfoundation/algokit-cli/issues/452)) ([`0ab21bc`](https://github.com/algorandfoundation/algokit-cli/commit/0ab21bcd2b7a6d188791a3480eab7fe1b885667d))
* Update playground init docs ([#451](https://github.com/algorandfoundation/algokit-cli/issues/451)) ([`1a15d5d`](https://github.com/algorandfoundation/algokit-cli/commit/1a15d5def4e610f0b10a41918f5d4055dea19efc))
* Change last name in 2023-07-19_advanced_generate_command.md ([#448](https://github.com/algorandfoundation/algokit-cli/issues/448)) ([`8df02df`](https://github.com/algorandfoundation/algokit-cli/commit/8df02df981c0b68cfea2a4dc4698759d5e393974))
## v1.12.3 (2024-03-06)
### Fix
* Path resolution to ensure git is initialized at workspace level ([#447](https://github.com/algorandfoundation/algokit-cli/issues/447)) ([`4fa1eaf`](https://github.com/algorandfoundation/algokit-cli/commit/4fa1eafe604129bb0595d0774ee4eb1484d3c13b))
### Documentation
* Updating dockerhub links on localnet docs ([#445](https://github.com/algorandfoundation/algokit-cli/issues/445)) ([`9d4df31`](https://github.com/algorandfoundation/algokit-cli/commit/9d4df31abe1de07909c7d03de1dc2dcc4334d7dc))
## v1.12.2 (2024-03-01)
### Fix
* Algod container proper SIGTERM handling ([#438](https://github.com/algorandfoundation/algokit-cli/issues/438)) ([`1a654ca`](https://github.com/algorandfoundation/algokit-cli/commit/1a654ca6b1519beda0a1d23fefb9673591cd5eea))
### Documentation
* Update named localnet documents on config file locations ([#444](https://github.com/algorandfoundation/algokit-cli/issues/444)) ([`643ab01`](https://github.com/algorandfoundation/algokit-cli/commit/643ab011bae488d24c18e8351e29de439a31c24e))
* Minor patch in the badge ([#440](https://github.com/algorandfoundation/algokit-cli/issues/440)) ([`7d82db0`](https://github.com/algorandfoundation/algokit-cli/commit/7d82db08a127ef486f31687affca184f1229039b))
## v1.12.1 (2024-02-26)
## v1.12.0 (2024-02-26)
### Feature
* Init wizard v2 ([#415](https://github.com/algorandfoundation/algokit-cli/issues/415)) ([`55d6922`](https://github.com/algorandfoundation/algokit-cli/commit/55d6922e5ae1c8b1f6e42a910f387739344f53a5))
### Fix
* Upload windows artifact to release ([#429](https://github.com/algorandfoundation/algokit-cli/issues/429)) ([`d922a49`](https://github.com/algorandfoundation/algokit-cli/commit/d922a493f8f92c61ae56df0043a356f8fd523f4d))
## v1.11.4 (2024-02-19)
### Fix
* Fix issue of goal command interacting with filename containing dot ([#424](https://github.com/algorandfoundation/algokit-cli/issues/424)) ([`22ece81`](https://github.com/algorandfoundation/algokit-cli/commit/22ece811af63c69734169029db1a477730d1e0ad))
### Documentation
* Adr init wizard v2 and related improvements ([#411](https://github.com/algorandfoundation/algokit-cli/issues/411)) ([`8c5445a`](https://github.com/algorandfoundation/algokit-cli/commit/8c5445a558e503590fee636a9e5826026a5aacaf))
## v1.11.3 (2024-02-08)
### Fix
* Binary execution mode compatibility ([#406](https://github.com/algorandfoundation/algokit-cli/issues/406)) ([`5cb9b1f`](https://github.com/algorandfoundation/algokit-cli/commit/5cb9b1f8e1f7fc3cc7114cba5cef78c9fcc7df95))
### Documentation
* ADR - native binaries distribution via snap/winget/brew ([#404](https://github.com/algorandfoundation/algokit-cli/issues/404)) ([`b7301bf`](https://github.com/algorandfoundation/algokit-cli/commit/b7301bf7ef4d776aa0b0b16e061f2a546780cabb))
* Improve onboarding experience ([`a4d6bb5`](https://github.com/algorandfoundation/algokit-cli/commit/a4d6bb502ed5bbfe87682ea863590c47393aed6a))
## v1.11.2 (2024-02-01)
### Fix
* Bump algokit-client-generator to 1.1.1 ([#403](https://github.com/algorandfoundation/algokit-cli/issues/403)) ([`28dd709`](https://github.com/algorandfoundation/algokit-cli/commit/28dd709314b5557b1351a6db6f2305e168438d28))
## v1.11.1 (2024-01-30)
### Fix
* Patching tealer 3.12 compatibility ([#401](https://github.com/algorandfoundation/algokit-cli/issues/401)) ([`05ea554`](https://github.com/algorandfoundation/algokit-cli/commit/05ea554fcad9fdf3eb5b038231eaf1155f9e5ce7))
* Patch cd pipeline merge conflict ([#399](https://github.com/algorandfoundation/algokit-cli/issues/399)) ([`806d0e2`](https://github.com/algorandfoundation/algokit-cli/commit/806d0e269f9e621c3ed8f47a8fd3d4e24a5a366c))
## v1.11.0 (2024-01-28)
### Feature
* Upgrading to latest version of algokit-client-generator-ts ([#398](https://github.com/algorandfoundation/algokit-cli/issues/398)) ([`1b6773b`](https://github.com/algorandfoundation/algokit-cli/commit/1b6773b1bbfcc5191e0da86af4e445de29ae3058))
### Documentation
* Adr on native binaries ([#395](https://github.com/algorandfoundation/algokit-cli/issues/395)) ([`42f61d1`](https://github.com/algorandfoundation/algokit-cli/commit/42f61d1a5ffdb411947a7581a36df1ed53786a25))
## v1.10.0 (2024-01-24)
### Feature
* Adding algokit analyze - perform static analysis with tealer integration ([#370](https://github.com/algorandfoundation/algokit-cli/issues/370)) ([`3e56a4b`](https://github.com/algorandfoundation/algokit-cli/commit/3e56a4b4e1f59d747cd7eb4e2cfea8b8d9c7c670))
### Fix
* Installation process for tealer (windows compatibility) ([#396](https://github.com/algorandfoundation/algokit-cli/issues/396)) ([`971aff4`](https://github.com/algorandfoundation/algokit-cli/commit/971aff46a6b5502135122bff951ee2d9c15fa80f))
## v1.9.3 (2024-01-11)
## v1.9.2 (2024-01-09)
### Fix
* Run localnet on goal command ([#380](https://github.com/algorandfoundation/algokit-cli/issues/380)) ([`5a06ddc`](https://github.com/algorandfoundation/algokit-cli/commit/5a06ddce965716ea4fb47a1d8a19b8cb65d17b77))
### Documentation
* Update the list of AlgoKit CLI high-level features in the docs ([`8e3b827`](https://github.com/algorandfoundation/algokit-cli/commit/8e3b8273d65a1fbcd7e3bf600b96c82500eef538))
## v1.9.1 (2023-12-29)
## v1.9.0 (2023-12-29)
### Feature
* Add support for a customisable named localnet ([#373](https://github.com/algorandfoundation/algokit-cli/issues/373)) ([`41c4946`](https://github.com/algorandfoundation/algokit-cli/commit/41c4946fce6894a9f6548bf4a2cbdd499dec4cb4))
## v1.8.2 (2023-12-20)
## v1.8.1 (2023-12-19)
### Fix
* Update multiformats version as it needs to be in sync with multiformats-config ([#372](https://github.com/algorandfoundation/algokit-cli/issues/372)) ([`67a5966`](https://github.com/algorandfoundation/algokit-cli/commit/67a59662c67d7f1d2e5eedeb1e8d62289e0ad5ac))
## v1.8.0 (2023-12-14)
### Feature
* Update generators to support generating typed clients with simulate functionality ([#368](https://github.com/algorandfoundation/algokit-cli/issues/368)) ([`90c876b`](https://github.com/algorandfoundation/algokit-cli/commit/90c876b819f4f9bba040e8630584cedc13678f5a))
* Use Pinata ipfs instead of web3.storage ([#367](https://github.com/algorandfoundation/algokit-cli/issues/367)) ([`fc7ee5d`](https://github.com/algorandfoundation/algokit-cli/commit/fc7ee5d36c09b91251c46ab2be670015ac106164))
### Fix
* Replacing Yaspin with Simplified Spinners for Windows Systems ([#369](https://github.com/algorandfoundation/algokit-cli/issues/369)) ([`e12311e`](https://github.com/algorandfoundation/algokit-cli/commit/e12311e3be087e78aed092dd9b2670f8183afea3))
## v1.7.3 (2023-12-08)
### Fix
* Adding confirmation prompt prior to execution of algokit generators ([#366](https://github.com/algorandfoundation/algokit-cli/issues/366)) ([`eeb5bae`](https://github.com/algorandfoundation/algokit-cli/commit/eeb5bae18c4ffb2384f92627d19a4308a46bfdf0))
## v1.7.2 (2023-12-04)
### Fix
* Removing outdated reference to `algokit sandbox` command ([#362](https://github.com/algorandfoundation/algokit-cli/issues/362)) ([`e6cd395`](https://github.com/algorandfoundation/algokit-cli/commit/e6cd395bf600485be6edbe4e68c9ba4885598000))
* Fixing Localnet status ([#365](https://github.com/algorandfoundation/algokit-cli/issues/365)) ([`8277572`](https://github.com/algorandfoundation/algokit-cli/commit/8277572db58d14bfcbda5e8bda18673d536b84a0))
* Update vulnerable package dependency versions ([#361](https://github.com/algorandfoundation/algokit-cli/issues/361)) ([`450e02d`](https://github.com/algorandfoundation/algokit-cli/commit/450e02ddba02c98d9c8fe8a6baedaf84ef7e9460))
## v1.7.1 (2023-11-22)
### Fix
* Hotfixing conduit path for localnet windows compatibility ([#360](https://github.com/algorandfoundation/algokit-cli/issues/360)) ([`897e335`](https://github.com/algorandfoundation/algokit-cli/commit/897e33554252083ed2b0d8a18a49969ef82a097b))
## v1.7.0 (2023-11-22)
### Feature
* Migrating localnet to latest indexer v3.x images ([#351](https://github.com/algorandfoundation/algokit-cli/issues/351)) ([`04ef300`](https://github.com/algorandfoundation/algokit-cli/commit/04ef3008366028118358e342c0e83e08f3c095ba))
## v1.6.3 (2023-11-14)
### Fix
* Correctly convert list of tuple to dictionary ([#353](https://github.com/algorandfoundation/algokit-cli/issues/353)) ([`ad71719`](https://github.com/algorandfoundation/algokit-cli/commit/ad717190f5822964d726555b7d7f8e1f5453cdfa))
## v1.6.2 (2023-11-10)
### Fix
* Support detect ~/test.txt as valid goal paths ([#347](https://github.com/algorandfoundation/algokit-cli/issues/347)) ([`8ac5ec5`](https://github.com/algorandfoundation/algokit-cli/commit/8ac5ec5843cf243fb051e504d821b719c37cbe38))
* Support the multiple file outputs of goal clerk split ([#346](https://github.com/algorandfoundation/algokit-cli/issues/346)) ([`fd9cd54`](https://github.com/algorandfoundation/algokit-cli/commit/fd9cd54137ca40595220fe916799eb682971387b))
## v1.6.1 (2023-11-08)
### Documentation
* Typo resolved ([#341](https://github.com/algorandfoundation/algokit-cli/issues/341)) ([`e71ff96`](https://github.com/algorandfoundation/algokit-cli/commit/e71ff964a9879a30689be049d3af3ec3002c3198))
* Fixing typo in docs ([#339](https://github.com/algorandfoundation/algokit-cli/issues/339)) ([`e8eba42`](https://github.com/algorandfoundation/algokit-cli/commit/e8eba421b32767ae9d57d8bbe75f86c268f5cbf7))
## v1.6.0 (2023-10-26)
### Feature
* Algokit tasks - 1.6.0 release ([#334](https://github.com/algorandfoundation/algokit-cli/issues/334)) ([`e35f4f8`](https://github.com/algorandfoundation/algokit-cli/commit/e35f4f836f5433449a6685d1aeca01b8fd416fe2))
### Fix
* Pinning aiohttp beta to hotfix 3.12 support ([#338](https://github.com/algorandfoundation/algokit-cli/issues/338)) ([`96fc7e6`](https://github.com/algorandfoundation/algokit-cli/commit/96fc7e668c3a5b4fb9f00216ee6278b8ded1cf87))
## v1.5.3 (2023-10-23)
## v1.5.2 (2023-10-20)
### Fix
* Docker compose ps parsing for version >= 2.21 ([#336](https://github.com/algorandfoundation/algokit-cli/issues/336)) ([`06ba5e9`](https://github.com/algorandfoundation/algokit-cli/commit/06ba5e908a879a45ab793ffbc6c9436eeeb5b370))
### Documentation
* Updating docs for the issue on python 3.12 ([#332](https://github.com/algorandfoundation/algokit-cli/issues/332)) ([`288b561`](https://github.com/algorandfoundation/algokit-cli/commit/288b5617f284b5135f272cdb4c1c160c2aa6fc33))
## v1.5.1 (2023-10-17)
## v1.5.0 (2023-10-04)
### Feature
* Algokit `dispenser` ([#309](https://github.com/algorandfoundation/algokit-cli/issues/309)) ([`6b7a514`](https://github.com/algorandfoundation/algokit-cli/commit/6b7a51421d42d90192c866ff7ce7307a4b180b9c))
### Documentation
* Explicit reference on how to obtain the dispenser address ([#321](https://github.com/algorandfoundation/algokit-cli/issues/321)) ([`d7db09c`](https://github.com/algorandfoundation/algokit-cli/commit/d7db09c50e41ec8840f908f6a3db223622562269))
## v1.4.2 (2023-09-29)
### Documentation
* Adding tealscript template ([#318](https://github.com/algorandfoundation/algokit-cli/issues/318)) ([`a855530`](https://github.com/algorandfoundation/algokit-cli/commit/a855530923a308e3826d4203b851cfbc49420bed))
* Fixed links to tutorials ([`8207043`](https://github.com/algorandfoundation/algokit-cli/commit/820704305d7bb66d3f5e7c6627e53594a74f9e45))
## v1.4.1 (2023-08-21)
### Fix
* Localnet displays a warning when image is out of date ([#308](https://github.com/algorandfoundation/algokit-cli/issues/308)) ([`be5a5df`](https://github.com/algorandfoundation/algokit-cli/commit/be5a5df0883b378a0dd889b9996ff68850df5698))
* Adding fixes to allow working with local filesystem files when interacting with algokit goal commands ([#304](https://github.com/algorandfoundation/algokit-cli/issues/304)) ([`caca2b5`](https://github.com/algorandfoundation/algokit-cli/commit/caca2b59b07817648ae7d8f208fe02f895cee92e))
## v1.4.0 (2023-08-14)
### Feature
* Advanced algokit generate command ([#306](https://github.com/algorandfoundation/algokit-cli/issues/306)) ([`0381862`](https://github.com/algorandfoundation/algokit-cli/commit/038186239c6787b0e80d49ea6a0e5e4135ce4240))
## v1.3.0 (2023-08-01)
### Feature
* Add new "deploy" command to execute user/template defined logic to deploy smart contracts to an Algorand network ([#295](https://github.com/algorandfoundation/algokit-cli/issues/295)) ([`6673f80`](https://github.com/algorandfoundation/algokit-cli/commit/6673f8062989172674471056baf1e8a7f34753b7))
### Fix
* Pip-audit dependencies ([#307](https://github.com/algorandfoundation/algokit-cli/issues/307)) ([`142dba3`](https://github.com/algorandfoundation/algokit-cli/commit/142dba3651731003936c32ff9a6144c58289c829))
* Handle deploy commands on windows that are actually `.cmd` files or similar ([#303](https://github.com/algorandfoundation/algokit-cli/issues/303)) ([`17791c7`](https://github.com/algorandfoundation/algokit-cli/commit/17791c7ca7f5aabe510b1dcaa1d09b9ed403233b))
### Documentation
* Advanced algokit generate command ADR ([#305](https://github.com/algorandfoundation/algokit-cli/issues/305)) ([`cb0ac17`](https://github.com/algorandfoundation/algokit-cli/commit/cb0ac17e9afda66e74ae2c63d0729c3b34f2a4b7))
* Adding algokit template documentation ([#300](https://github.com/algorandfoundation/algokit-cli/issues/300)) ([`6e19743`](https://github.com/algorandfoundation/algokit-cli/commit/6e19743bacf3856f91e2610cff58676a17e99deb))
## v1.2.0 (2023-07-04)
### Feature
* Detecting whether opening folder contains *.code-workspace file ([#294](https://github.com/algorandfoundation/algokit-cli/issues/294)) ([`e902d55`](https://github.com/algorandfoundation/algokit-cli/commit/e902d55a6077d60eb3c5b3fa809e1ba80b61b37e))
* Adding react and fullstack templates ([#291](https://github.com/algorandfoundation/algokit-cli/issues/291)) ([`5af81f1`](https://github.com/algorandfoundation/algokit-cli/commit/5af81f100b16ce1281980ff3067df648fb5c9b4f))
### Fix
* Hotfixing a bug that is caused by pydantic v2 being installed as a copier dependency ([#297](https://github.com/algorandfoundation/algokit-cli/issues/297)) ([`31b580b`](https://github.com/algorandfoundation/algokit-cli/commit/31b580b2364e123fd81fdab14da93b704ea4bdda))
* Update algokit-client-generators ([#293](https://github.com/algorandfoundation/algokit-cli/issues/293)) ([`cf0f46f`](https://github.com/algorandfoundation/algokit-cli/commit/cf0f46ffba9c3a33e75bad56195589bed3c5dc3a))
### Documentation
* Switching to more reliable visitors badge provider ([`51dce8b`](https://github.com/algorandfoundation/algokit-cli/commit/51dce8be83f0b72765ddffc9ea67886235d83fbb))
* Fixing underline caused by whitespace in html tags on readme ([`f824596`](https://github.com/algorandfoundation/algokit-cli/commit/f824596d845fce31fe6d32fd9dc14fa0086746ca))
## v1.1.6 (2023-06-21)
### Fix
* Increase timeout when doing algod health check ([#290](https://github.com/algorandfoundation/algokit-cli/issues/290)) ([`2b39970`](https://github.com/algorandfoundation/algokit-cli/commit/2b39970c53d358050639fbcb02ab6e99c1808d98))
### Documentation
* Adding readme assets ([`e300fa9`](https://github.com/algorandfoundation/algokit-cli/commit/e300fa929850b1f3677cb3545b8f284e8f3a7ef9))
## v1.1.5 (2023-06-15)
### Fix
* Update typescript algokit-client-generator to 2.2.1 ([#286](https://github.com/algorandfoundation/algokit-cli/issues/286)) ([`bbb86b4`](https://github.com/algorandfoundation/algokit-cli/commit/bbb86b4049ed6d81f3bd73a0e207deae8f200459))
## v1.1.4 (2023-06-14)
### Fix
* Update typescript algokit-client-generator ([#284](https://github.com/algorandfoundation/algokit-cli/issues/284)) ([`37d5082`](https://github.com/algorandfoundation/algokit-cli/commit/37d5082f86fd3db43ebb7c96558a484267883067))
## v1.1.3 (2023-06-13)
### Fix
* Update python algokit-client-generator ([#283](https://github.com/algorandfoundation/algokit-cli/issues/283)) ([`5330baa`](https://github.com/algorandfoundation/algokit-cli/commit/5330baaf8617a1b5b640d5efecdcbe05fd2ea2a3))
## v1.1.2 (2023-06-13)
### Fix
* Use /v2/status for algod health check ([#282](https://github.com/algorandfoundation/algokit-cli/issues/282)) ([`91e5e36`](https://github.com/algorandfoundation/algokit-cli/commit/91e5e36886edfa5d90f6aaf77f9db6a666bbdc43))
## v1.1.1 (2023-06-13)
### Fix
* Add check for localnet start to wait for algod to be ready ([#281](https://github.com/algorandfoundation/algokit-cli/issues/281)) ([`dff0a5d`](https://github.com/algorandfoundation/algokit-cli/commit/dff0a5d45fb79317509f6a44fa3fc37b93a2d8af))
### Documentation
* Updating adr header to reflect status and deciders ([`b84a07d`](https://github.com/algorandfoundation/algokit-cli/commit/b84a07dee0c1b5fc9060b806feeb07c41b4cd4fd))
## v1.1.0 (2023-06-07)
### Feature
* Adding minimum required version for algokit. ([#273](https://github.com/algorandfoundation/algokit-cli/issues/273)) ([`10aacc2`](https://github.com/algorandfoundation/algokit-cli/commit/10aacc2c17acc55c47d69674e9ace780313aee46))
* Use official Algorand Docker images for LocalNet ([#268](https://github.com/algorandfoundation/algokit-cli/issues/268)) ([`fc5106c`](https://github.com/algorandfoundation/algokit-cli/commit/fc5106cc773a4672eb1ec8614bb60ed2dc61be42))
* Add generate client command ([#266](https://github.com/algorandfoundation/algokit-cli/issues/266)) ([`b885fb1`](https://github.com/algorandfoundation/algokit-cli/commit/b885fb16b3b9a49231a6b786d1156bd7b202fb12))
### Fix
* Don't reset localnet if only algod_config.json is missing ([#269](https://github.com/algorandfoundation/algokit-cli/issues/269)) ([`ff3ef56`](https://github.com/algorandfoundation/algokit-cli/commit/ff3ef560565bdb92951fa7d6e3bbf4437db873a0))
* Bootstrap failure during init now shows the error to avoid confusion ([`8a36e82`](https://github.com/algorandfoundation/algokit-cli/commit/8a36e82497cc342082d71df5c327837ddad221a4))
* Workaround ValueError raised when using --defaults flag with copier 7.1 ([#256](https://github.com/algorandfoundation/algokit-cli/issues/256)) ([`e224070`](https://github.com/algorandfoundation/algokit-cli/commit/e22407074bf8c8ce2b1576379c90df76a70f6df9))
### Documentation
* Document typed client dependency ([#275](https://github.com/algorandfoundation/algokit-cli/issues/275)) ([`87d7233`](https://github.com/algorandfoundation/algokit-cli/commit/87d7233bd35a1b896d15e0aea3f63e738738254f))
* Add example usage for typed clients ([`16d91f5`](https://github.com/algorandfoundation/algokit-cli/commit/16d91f5d3e5ef0115826780bc1daa918fbf031a8))
* Add generate docs ([#270](https://github.com/algorandfoundation/algokit-cli/issues/270)) ([`da8e46d`](https://github.com/algorandfoundation/algokit-cli/commit/da8e46dfda97e514be17955ad39986f42b93b5e2))
* Update localnet docs to include links to AlgoKit Utils ([`6e937a8`](https://github.com/algorandfoundation/algokit-cli/commit/6e937a8ff487955063ac1023c51ac3c83f5cbb01))
* README update ([`8702e45`](https://github.com/algorandfoundation/algokit-cli/commit/8702e45c25eb2ec422587e307151037fbf6c1914))
* Changes to wording of output stability snippet ([`f378013`](https://github.com/algorandfoundation/algokit-cli/commit/f378013db7b52c5d69f71ba606fbe3f8f50fa843))
* Added output stability article content ([`c3a89f1`](https://github.com/algorandfoundation/algokit-cli/commit/c3a89f14b461ec2a22b23f3e423d107bff72fbb9))
* Include note about pipx ensurepath ([`847013d`](https://github.com/algorandfoundation/algokit-cli/commit/847013d1733f3b11ed6d3c64b223e84dd7bc1124))
* Link to repo search, fixes #240 ([`2550f6f`](https://github.com/algorandfoundation/algokit-cli/commit/2550f6ff147fd3de9f5da6dee470e9f214500c20))
## v1.0.1 (2023-03-29)
### Documentation
* Reference overview image with absolute url ([`c987f84`](https://github.com/algorandfoundation/algokit-cli/commit/c987f84d3079cf88c262e21a542e60c74a71829a))
* Added overview image ([`4c387ee`](https://github.com/algorandfoundation/algokit-cli/commit/4c387ee7fbbae2c01498dec83fa76ffd4d4990fa))
* Make README.md links absolute ([`8435bc7`](https://github.com/algorandfoundation/algokit-cli/commit/8435bc7faaddd33e4bb204f8c965365aee097b42))
## v1.0.0 (2023-03-29)
### Feature
* **localnet:** Changing the default reset behaviour to not pull images ([`6d3f10e`](https://github.com/algorandfoundation/algokit-cli/commit/6d3f10e5690f15d04d03bc38290f2c670905ba24))
### Breaking
* 1.0 release ([`68b02ad`](https://github.com/algorandfoundation/algokit-cli/commit/68b02ad49de0c8da083fcce542a76f6342ac0020))
### Documentation
* Remove mention of virtualenv when describing bootstrap command ([`302498f`](https://github.com/algorandfoundation/algokit-cli/commit/302498f21cb59eea4e01b482d3f07eecada34909))
* Explain what running bootstrap during init will do ([`4bd58bd`](https://github.com/algorandfoundation/algokit-cli/commit/4bd58bd981eef9a382c2a16f9d0bd06ebe397ba3))
* Added file copy advice ([`2b4882c`](https://github.com/algorandfoundation/algokit-cli/commit/2b4882c1878c07da7933d9a266f80560395fbb5f))
* Added note about algokit explore after a localnet start ([`7a068b1`](https://github.com/algorandfoundation/algokit-cli/commit/7a068b1d90592e5eebd3f7af5a5f6d216c45ec1f))
* Provide feedback when calling algokit explore ([`def4ef5`](https://github.com/algorandfoundation/algokit-cli/commit/def4ef5ce5bb2eb3e7b7c0dbcdbf0d4c4f8f6b1d))
* Update --bootstrap help text on algokit init ([`ce9ebea`](https://github.com/algorandfoundation/algokit-cli/commit/ce9ebeaf9bb636f6af4cd2b98d6a32a4b4e10f15))
* Updating auto-generated docs ([`637d534`](https://github.com/algorandfoundation/algokit-cli/commit/637d534b14c92fa3b4be27f58a0e3a950ad5d75e))
* Command help text improvements for bootstrap and init ([`67eb3f6`](https://github.com/algorandfoundation/algokit-cli/commit/67eb3f6b79ac47abe4f4d1497db66acda5d0d4fd))
* Update config and completions help text ([`7e0c087`](https://github.com/algorandfoundation/algokit-cli/commit/7e0c0872c1ca9ae531c69ae37dce43f44bc74634))
* Update doctor help text ([`111bf2e`](https://github.com/algorandfoundation/algokit-cli/commit/111bf2e874fff0960ed7faf5c073dd44d8b487cd))
* Removing incorrect references to sandbox ([`7179eb8`](https://github.com/algorandfoundation/algokit-cli/commit/7179eb8c67160671d549bd8f7114f54fb03b3fad))
* Improving doctor command feature description ([`a8a2862`](https://github.com/algorandfoundation/algokit-cli/commit/a8a2862efc03448022df9fd2f9fa42e3ad883cde))
* Updating bootstrap command descriptions ([`07a5fdb`](https://github.com/algorandfoundation/algokit-cli/commit/07a5fdbaa2653ab6505fd67432fac3c36ee5d711))
* Fixing heading order in intro tutorial ([`46b5023`](https://github.com/algorandfoundation/algokit-cli/commit/46b50235b965f1e9736d3e8c67d1a95c9a13923c))
* Getting README.md ready for 1.0 ([`815712f`](https://github.com/algorandfoundation/algokit-cli/commit/815712f83a2b56172c3cc51c7615bb33cae32b2f))
## v0.6.0 (2023-03-28)
### Feature
* Prompt for template first ([`91326f3`](https://github.com/algorandfoundation/algokit-cli/commit/91326f339650f9ea33ff4746f6707f507364b81a))
### Documentation
* Autogen docs ([`9803ff7`](https://github.com/algorandfoundation/algokit-cli/commit/9803ff7764090b4d5b1d661f8e7ead3b74a49d0f))
* Added the intro tutorial ([`087852b`](https://github.com/algorandfoundation/algokit-cli/commit/087852b9be034daddca3a609bb7fd9ff0b476b6e))
## v0.5.0 (2023-03-24)
### Feature
* Change playground template to point to new repo ([`805d63c`](https://github.com/algorandfoundation/algokit-cli/commit/805d63c10be3c62a3ef8d78bd2d40d1e6d1c8c5c))
* **init:** Added --no-ide flag to allow user to prevent IDE opening ([#211](https://github.com/algorandfoundation/algokit-cli/issues/211)) ([`cd9f015`](https://github.com/algorandfoundation/algokit-cli/commit/cd9f01549fc460641bd7a64f606963efb7f4082a))
## v0.4.1 (2023-03-22)
### Fix
* **init:** Resolving issue with opening VS Code automatically on windows ([`691543d`](https://github.com/algorandfoundation/algokit-cli/commit/691543dfb7748dcb0495ceb0593dfe14e500d8fc))
## v0.4.0 (2023-03-22)
### Feature
* Increase max content width to 120 for easier reading in wider terminals ([`cadc615`](https://github.com/algorandfoundation/algokit-cli/commit/cadc6150fb0a6c7d5f1ae60ccd7bccee89fb38fb))
* Include "extra version info" in all commands not just docker compose ([`f1c1d69`](https://github.com/algorandfoundation/algokit-cli/commit/f1c1d6992faefa26c8656121e30b894dfce32c03))
* Detect if code is on path && .vscode exists and try to launch ([`78f8b3f`](https://github.com/algorandfoundation/algokit-cli/commit/78f8b3f7f655d7286b4c090002e09edc52f3009a))
* Add a command to see logs from localnet docker containers ([`31c9cc4`](https://github.com/algorandfoundation/algokit-cli/commit/31c9cc4d44f2df2abcb8014dad6633232781f6e0))
### Fix
* Make failure to run npm install during bootstrap error message more explicit ([`468a186`](https://github.com/algorandfoundation/algokit-cli/commit/468a18683ebe80f671438df6a2f4bcf1d0c7c4a5))
* When executing goal/bash inside algod container only show localnet hint if it looks like the container doesn't exist or isn't running ([`b9dc57f`](https://github.com/algorandfoundation/algokit-cli/commit/b9dc57fe24a0f28df0b4399f0f579c39ab5336d8))
* Allow going back to template selection from custom url ([`929eefb`](https://github.com/algorandfoundation/algokit-cli/commit/929eefbd9bb8b4e38b24423980d18c0bbc09e9a3))
### Documentation
* **localnet:** Removing known LocalNet issue that is fixed ([`6747642`](https://github.com/algorandfoundation/algokit-cli/commit/6747642cc2a6b79e5cfa7b71418dfbaadbbf6659))
## v0.3.3 (2023-03-09)
### Fix
* Use /v2/status when querying localnet algod container ([#198](https://github.com/algorandfoundation/algokit-cli/issues/198)) ([`0fb0488`](https://github.com/algorandfoundation/algokit-cli/commit/0fb0488e7a5ebd7da22f764e9047df9c6ef7ac31))
### Documentation
* Fix references to renamed sandbox command ([#194](https://github.com/algorandfoundation/algokit-cli/issues/194)) ([`8b2910b`](https://github.com/algorandfoundation/algokit-cli/commit/8b2910b465e67c0e428cc4dde65e7a502f2fc7c0))
* Added step in install instructions to restart terminal ([`f8e47a5`](https://github.com/algorandfoundation/algokit-cli/commit/f8e47a5ea47e6f78a39dee436381b615c794d5d5))
* Update windows install instructions ([`e9d0a9d`](https://github.com/algorandfoundation/algokit-cli/commit/e9d0a9dc2ffc7f0998978e1fa5eceb6c94a9ce52))
## v0.3.2 (2023-03-03)
### Fix
* Resolve config paths in case of folder redirection e.g. UWP python ([#191](https://github.com/algorandfoundation/algokit-cli/issues/191)) ([`0c2b291`](https://github.com/algorandfoundation/algokit-cli/commit/0c2b29179d003b17909a8dc22f655dc2b11bcdb8))
## v0.3.1 (2023-02-24)
### Fix
* Git versions prior to 2.28 no longer fail on algokit init ([#184](https://github.com/algorandfoundation/algokit-cli/issues/184)) ([`0559582`](https://github.com/algorandfoundation/algokit-cli/commit/0559582ba9fb27df9ab98b2a66606ddaeeaf6da0))
* Fix version comparison when checking for new versions ([#183](https://github.com/algorandfoundation/algokit-cli/issues/183)) ([`c272658`](https://github.com/algorandfoundation/algokit-cli/commit/c2726589b2699832844d2c67c452c01ecf742824))
## v0.3.0 (2023-02-23)
### Feature
* Add init --template-url-ref option to allow using a specific commit, tag or branch ([`5bf19a3`](https://github.com/algorandfoundation/algokit-cli/commit/5bf19a38eee8b621010956a64e2d2f9e318af9e8))
* Rename sandbox command to localnet ([`7ee55bd`](https://github.com/algorandfoundation/algokit-cli/commit/7ee55bdd5d0a87cd3aa7af1281c0867798be79ed))
### Fix
* **doctor:** Ensuring full docker version information is visible in Doctor output to improve debugging, fixes comment in #164 ([#173](https://github.com/algorandfoundation/algokit-cli/issues/173)) ([`a2c51e8`](https://github.com/algorandfoundation/algokit-cli/commit/a2c51e8018ba7b8049dc1230f7f9c1e02c24cd15))
* Handle git not being installed when running algokit ([`ccc5eb0`](https://github.com/algorandfoundation/algokit-cli/commit/ccc5eb0369892bb640914a5cf370072d28502d7f))
* **doctor:** Docker compose version parsing, fixes #164 ([`c3f4ef8`](https://github.com/algorandfoundation/algokit-cli/commit/c3f4ef80f7ca0e3da0d4841c06d81d8abe0c078d))
* Updating gitpython to resolve pip-audit vulnerability warning ([#169](https://github.com/algorandfoundation/algokit-cli/issues/169)) ([`2a10d67`](https://github.com/algorandfoundation/algokit-cli/commit/2a10d676e20f4f7d3b7d28ea24d6f5ded099d3ae))
### Documentation
* Gave context to Sandbox and PyTEAL ([`0a96e13`](https://github.com/algorandfoundation/algokit-cli/commit/0a96e13c16284dfdc8d9525310119a1351ff862a))
* Updated use cases -> capabilities ([`ef0527a`](https://github.com/algorandfoundation/algokit-cli/commit/ef0527a87f11651efb3061711749049d36ed6d04))
* Added missing recommendation for type-safe client ([`26a6717`](https://github.com/algorandfoundation/algokit-cli/commit/26a6717e763811e0f9c23818d842ab0ea2fb2a99))
* Completed draft for architecture decision for smart contract deployment ([`40faf83`](https://github.com/algorandfoundation/algokit-cli/commit/40faf83cc97f75005f54bc344999848055f70b84))
* First draft of architecture decision for smart contract deployment ([`9e77817`](https://github.com/algorandfoundation/algokit-cli/commit/9e778170e9b4924d10b73a2fbea08accf38e3b33))
* Rename sandbox to localnet ([`aa35da7`](https://github.com/algorandfoundation/algokit-cli/commit/aa35da72f67f3dcd35adb0866a8b1ddad17fc4fe))
* Update example output for Verify installation section ([`14f6f90`](https://github.com/algorandfoundation/algokit-cli/commit/14f6f9058c3ffd69d8c3ce9b4b1160bdeb017a0b))
* Fixing incorrect description for Sandbox command ([`4bea5fa`](https://github.com/algorandfoundation/algokit-cli/commit/4bea5fa06be10a1282c1627b7979380aebc6e297))
* Fix init description in algokit.md ([#156](https://github.com/algorandfoundation/algokit-cli/issues/156)) ([`39eee95`](https://github.com/algorandfoundation/algokit-cli/commit/39eee9508f28799856692b0729bebf8b923af687))
## v0.2.0 (2023-01-16)
### Feature
* Update windows install instructions and bump version so PyPi will accept new release ([#154](https://github.com/algorandfoundation/algokit-cli/issues/154)) ([`5ff5223`](https://github.com/algorandfoundation/algokit-cli/commit/5ff52237172bddf06d3ff845b18e77c31dce9b11))
## v0.1.3 (2023-01-16)
### Documentation
* Update pipx install instructions ([`e91a06a`](https://github.com/algorandfoundation/algokit-cli/commit/e91a06a38f5b278e9ac26dfef5d7c4833633e750))
## v0.1.2 (2023-01-11)
### Documentation
* Approved ([`19eb063`](https://github.com/algorandfoundation/algokit-cli/commit/19eb063a2d8327884a5856939db4e0ea157ac26f))
* Remove --cask from Option 3 ([`cfa3b73`](https://github.com/algorandfoundation/algokit-cli/commit/cfa3b73099f6da94420bdfc9541bbce4d521993d))
## v0.1.1 (2023-01-10)
### Fix
* Adding installation documentation update re: pipx ([`75d3590`](https://github.com/algorandfoundation/algokit-cli/commit/75d359022f9fc3a3cf3ac8d21b16a449e42b1857))
* Temporarily turning off PyPi publishing while we decide on the final package name ([`6c1a2e2`](https://github.com/algorandfoundation/algokit-cli/commit/6c1a2e25d2de00a9052b7db700d8681d75b09e6a))
## v0.1.0 (2023-01-09)
### Feature
* Windows Chocolatey package ([#80](https://github.com/algorandfoundation/algokit-cli/issues/80)) ([`3f4bb04`](https://github.com/algorandfoundation/algokit-cli/commit/3f4bb04ee3ce09e7ca9ab843453f50f6a3eab98c))
* **bootstrap:** Prompt for env tokens ([#114](https://github.com/algorandfoundation/algokit-cli/issues/114)) ([`a6fe18f`](https://github.com/algorandfoundation/algokit-cli/commit/a6fe18fded0bddec91959998916fc96ac6af5008))
* **explore:** Add explore command for launching Dappflow Explorer ([#112](https://github.com/algorandfoundation/algokit-cli/issues/112)) ([`4db26b0`](https://github.com/algorandfoundation/algokit-cli/commit/4db26b08c6919fb980afa6afbb233d8793feeec1))
* **version-check:** Added check to periodically check for new releases on GitHub and inform when found ([#111](https://github.com/algorandfoundation/algokit-cli/issues/111)) ([`1772439`](https://github.com/algorandfoundation/algokit-cli/commit/1772439b02190dce159e75da110c76b200774c00))
* **doctor:** Use sys.version for fuller output (vs version_info tuple) ([#101](https://github.com/algorandfoundation/algokit-cli/issues/101)) ([`55fe4fc`](https://github.com/algorandfoundation/algokit-cli/commit/55fe4fc6984b7fecfe3e417a87cc3a1c0c0ee070))
* **completions:** Add completions support for bash and zsh ([`e7c50e5`](https://github.com/algorandfoundation/algokit-cli/commit/e7c50e58c6b371475fb6d7d2f45e85790289eadb))
* **doctor:** Tweak commands for windows ([`8f79629`](https://github.com/algorandfoundation/algokit-cli/commit/8f79629a358eb71cb28b4e739bbe445c2ec74646))
* **doctor:** Fix timezone in tests ([`d9fe303`](https://github.com/algorandfoundation/algokit-cli/commit/d9fe303934f3c093d7548228fce74c83286fa1f2))
* **doctor:** Adding tests ([`58d5708`](https://github.com/algorandfoundation/algokit-cli/commit/58d57080e53b24f60e6a4315e09e920032fdf0b0))
* **doctor:** Refactor ([`b0fe39a`](https://github.com/algorandfoundation/algokit-cli/commit/b0fe39aafe34b74bf8aebba1e9ec5f4e8048923e))
* **doctor:** Colouring output ([`6bfb300`](https://github.com/algorandfoundation/algokit-cli/commit/6bfb30093e005cb59e92aefe4714ff492ec2582b))
* **doctor:** Address pr comments and add more logic ([`e7a3090`](https://github.com/algorandfoundation/algokit-cli/commit/e7a309024d2fc5704950e1138eb44b0f242f8bdb))
* **.env file:** Add tests for default and custom values ([`58511dc`](https://github.com/algorandfoundation/algokit-cli/commit/58511dc598ac1ec4b388c45d680d9075a5650b98))
* **init:** Add `.env` file to template and passing custom values (if required) ([`e77eca8`](https://github.com/algorandfoundation/algokit-cli/commit/e77eca8bde7e5c6faa80375d6b11f44c0579be6e))
* **init:** Implemented ability to specify a commit hash so you can anchor templates from semi-trusted sources to a known good version ([#77](https://github.com/algorandfoundation/algokit-cli/issues/77)) ([`772d420`](https://github.com/algorandfoundation/algokit-cli/commit/772d420ea73a7878ef5ac9d446c79b9bfd1fbbf2))
* **sandbox:** Added `algokit sandbox console` ([`95565df`](https://github.com/algorandfoundation/algokit-cli/commit/95565dff45a6751f960ebfba64fb9ed001a67260))
* **goal:** Added algokit goal --console ([`8dd947b`](https://github.com/algorandfoundation/algokit-cli/commit/8dd947bdb4f7029bf043cb0cfebe494c17bf2729))
* **algokit:** Implementing automated, semantic versioning ([`e4859d4`](https://github.com/algorandfoundation/algokit-cli/commit/e4859d496c61ea4e4c16e9a1c910dff4e896037a))
### Fix
* **docs:** Tweaks to the reference documentation ([`6d872a1`](https://github.com/algorandfoundation/algokit-cli/commit/6d872a17bf00820c78c5e8c52caf20cd9efe9c94))
* Expression on Publish Release Packages action ([`1c08f95`](https://github.com/algorandfoundation/algokit-cli/commit/1c08f95d568b8a9264b319cf40b87b0af05a8c72))
* Attempting to isolate main branch versioning ([`5ab7089`](https://github.com/algorandfoundation/algokit-cli/commit/5ab7089a21c431eba2965f1af895eb5d4b6c6ae6))
* Improve documentation and argument values for version-prompt config ([`aee3a1a`](https://github.com/algorandfoundation/algokit-cli/commit/aee3a1a74a921659ec60e28a1b48c11d4a14d2da))
* **completions:** Explicitly use utf8 for Windows compat ([`5033f8e`](https://github.com/algorandfoundation/algokit-cli/commit/5033f8e26cd27374228a983eebb3e5c88c841958))
* **bootstrap:** Improving robustness and test coverage for bootstrap poetry command ([#89](https://github.com/algorandfoundation/algokit-cli/issues/89)) ([`a4a6823`](https://github.com/algorandfoundation/algokit-cli/commit/a4a6823b4c5015e5d0f2d361a7373820e641835d))
* **init:** Don't prompt for project name in the template - take it from the directry name in the root init command ([`fc84791`](https://github.com/algorandfoundation/algokit-cli/commit/fc847911e58bd969428c0dc6e3117501181f545d))
* Windows weird error on GitHub Actions ([`0b81808`](https://github.com/algorandfoundation/algokit-cli/commit/0b8180829be53e26b998e4c723c0d8a384d95b91))
* **git:** Update gitattributes to ensure EOL=LF ([`b13a972`](https://github.com/algorandfoundation/algokit-cli/commit/b13a97202ddeefe81c8eda5d3b058cc4a136291e))
* **build:** Run black with --check ([`e4e3875`](https://github.com/algorandfoundation/algokit-cli/commit/e4e3875b864557f86edabe2851a3f2f8f2071fa3))
* **logging:** Ensure log files get opened in UTF-8 encoding ([`bc666fe`](https://github.com/algorandfoundation/algokit-cli/commit/bc666fe7e3aed8d250d997946188f8f70b01b4d5))
* Removing deleted folder from beaker template from assert ([`8b4b46a`](https://github.com/algorandfoundation/algokit-cli/commit/8b4b46a75b6a4794d9ceb41f80f80415ef44d503))
* Temporary fix for excessive build minutes consumption and commenting out PyPi publishing code since it errors out ([`399ca0e`](https://github.com/algorandfoundation/algokit-cli/commit/399ca0eca85751c245a07abe2cbe9a73cce4172b))
### Breaking
* --ok-exit-code no longer exists on algokit bootstrap poetry, no need for copier templates to call algokit now so no need for this feature ([`a4a6823`](https://github.com/algorandfoundation/algokit-cli/commit/a4a6823b4c5015e5d0f2d361a7373820e641835d))
================================================
FILE: CONTRIBUTING.md
================================================
# AlgoKit CLI for contributors
## Commits
We are using the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#summary) standard for commit messages. This allows us to automatically generate release notes and version numbers. We do this via [Python Semantic Release](https://python-semantic-release.readthedocs.io/en/latest/) and [GitHub actions](.github/workflows/cd.yaml).
## Guiding Principles
AlgoKit development is done within the [AlgoKit Guiding Principles](./docs/algokit.md#guiding-principles).
## Setup (AlgoKit CLI development)
### Initial setup
1. Clone this repository: `git clone https://github.com/algorandfoundation/algokit-cli`
2. Install pre-requisites:
- Manually:
- Install `Python` - [Link](https://www.python.org/downloads/): The minimum required version is `3.10`, but `3.11` is recommended.)
- Install `Poetry` - [Link](https://python-poetry.org/docs/#installation): The minimum required version is `1.2`.
- If you're not using PyCharm, then run `poetry install` in the repository root directory (this should set up `.venv` and install all Python dependencies - PyCharm will do this for you on startup)
- Via AlgoKit CLI:
- [Install AlgoKit CLI](./README.md#install) and run `algokit project bootstrap poetry` in the root directory
- Install `tealer` - by running `pipx install tealer==0.1.2`. This is a prerequisite to running `pytest`, tealer is a third party tool for static analysis of TEAL code, algokit uses it in `task analyse` command. AlgoKit uses `pytest-xdist` to speed up the test suite execution by running tests in parallel, this requires `tealer` to be installed globally to avoid race conditions.
3. Install pre-commit hooks (optional but recommended):
[pre-commit](https://pre-commit.com/) is configured in this repository. To enable it, make sure that `poetry install` has been run and the virtual-env is activated by running `poetry shell`. Then execute `pre-commit install` to install the git hook scripts.
Once it is done, git will ensure formatting, linting, and static typing (via `mypy`) is correct when you perform a commit.
4. Open the project and start debugging / developing via:
- VS Code
1. Open the repository root in VS Code.
2. Install recommended extensions.
3. Hit F5 (or whatever you have debug mapped to) and it should start running with breakpoint debugging.
> **Note**
> The first time you run, VS Code may prompt you to select the Python Interpreter, or if you are having issues running you may need to select it via the `Python: Select Interpreter` pallette command. You should select the Python Interpreter with the ./.venv path)
- IDEA (e.g. PyCharm)
1. Open the repository root in the IDE
2. Hit Shift+F9 (or whatever you have debug mapped to) and it should start running with breakpoint debugging
- Other
1. Open the repository root in your text editor of choice
2. In a terminal run `poetry shell`
3. Run `./debug.py` through your debugger of choice
- In each of the above cases, an `args.in` file will be created in the source root.
Each line will be executed in order, with the arguments passed to the cli.
For example, you could have:
```
version
--help
version --help
```
Not a terribly useful sequence of commands, but hopefully this helps illustrate the usage.
### Subsequently
1. If you update to the latest source code and there are new dependencies you will need to run `poetry install` again
2. Follow step 3 above
### Documentation
Markdown documentation can be found within the docs directory of the repo, there is a mixture of handwritten documentation and autogenerated documentation for the CLI tool itself.
To autogenerate the CLI documentation from the click source:
1. Install the docs dependencies: `poetry install --with docs`
2. Run the docs generation: `poetry run poe docs`
Note: this command won't work on Windows.
The CLI docs are generated using Sphinx, and its configuration can be found in `docs\sphinx`. The generated Markdown output is post processed to add a Table of Contents and top level title and the final Markdown is output to `docs\cli`. The commands to achieve this are defined in `pyproject.toml` under `[tool.poe.tasks]`
### Libraries and Tools
AlgoKit uses Python as a main language and many Python libraries and tools. This section lists all of them with a tiny brief.
- [Poetry](https://python-poetry.org/): Python packaging and dependency management.
- [pipx](https://github.com/pypa/pipx): Install and Run Python Applications in Isolated Environments
- [Click](https://palletsprojects.com/p/click/): A Python package for creating beautiful command line interfaces.
- [Black](https://github.com/psf/black): A Python code formatter.
- [Tox](https://tox.wiki/en/latest/): Automate and standardize testing in Python.
## Architecture decisions
As part of developing AlgoKit we are documenting key architecture decisions using [Architecture Decision Records (ADRs)](https://adr.github.io/). The following are the key decisions that have been made thus far:
- [2022-11-14: AlgoKit sandbox approach](docs/architecture-decisions/2022-11-14_sandbox-approach.md)
- [2022-11-22: Beaker testing strategy](docs/architecture-decisions/2022-11-22_beaker-testing-strategy.md)
- [2023-01-11: HomeBrew install strategy](docs/architecture-decisions/2023-01-11_brew_install.md)
- [2023-01-11: Beaker productionisation review](docs/architecture-decisions/2023-01-11_beaker_productionisation_review.md)
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2022-2023 Algorand Foundation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
---
The Algorand AlgoKit CLI is the one-stop shop tool for developers building on the [Algorand network](https://www.algorand.com/).
AlgoKit gets developers of all levels up and running with a familiar, fun and productive development environment in minutes. The goal of AlgoKit is to help developers build and launch secure, automated production-ready applications rapidly.
[Install AlgoKit](#install) | [Quick Start Tutorial](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/tutorials/intro.md) | [Documentation](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/algokit.md)
## What is AlgoKit?
AlgoKit compromises of a number of components that make it the one-stop shop tool for developers building on the [Algorand network](https://www.algorand.com/).

AlgoKit can help you [**learn**](#learn), [**develop**](#develop) and [**operate**](#operate) Algorand solutions. It consists of [a number of repositories](https://github.com/search?q=org%3Aalgorandfoundation+algokit-&type=repositories), including this one.
### Learn
There are many learning resources on the [Algorand Developer Portal](https://dev.algorand.co/) and the [AlgoKit landing page](https://dev.algorand.co/algokit/algokit-intro) has a range of links to more learning materials. In particular, check out the [quick start tutorial](https://dev.algorand.co/getting-started/algokit-quick-start/).
If you need help you can access both the [Algorand Discord](https://discord.gg/84AActu3at) (pro-tip: check out the algokit channel!) and the [Algorand Forum](https://forum.algorand.org/).
We have also developed an [AlgoKit video series](https://www.youtube.com/@algodevs/playlists).
### Develop
AlgoKit helps you develop Algorand solutions:
- **Interaction**: AlgoKit exposes a number of interaction methods, namely:
- [**AlgoKit CLI**](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/algokit.md): A Command Line Interface (CLI) so you can quickly access AlgoKit capabilities
- [VS Code](https://code.visualstudio.com/): All AlgoKit project templates include VS Code configurations so you have a smooth out-of-the-box development experience using VS Code
- [lora](https://lora.algokit.io/): AlgoKit has integrations with lora; a web-based user interface that let's you visualise and interact with an Algorand network
- **Getting Started**: AlgoKit helps you get started quickly when building new solutions:
- [**AlgoKit Templates**](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/init.md): Template libraries to get you started faster and quickly set up a productive dev experience
- **Development**: AlgoKit provides SDKs, tools and libraries that help you quickly and effectively build high quality Algorand solutions:
- **AlgoKit Utils** ([Python](https://github.com/algorandfoundation/algokit-utils-py#readme) | [TypeScript](https://github.com/algorandfoundation/algokit-utils-ts#readme)): A set of utility libraries so you can develop, test, build and deploy Algorand solutions quickly and easily
- [Algorand SDKs](https://dev.algorand.co/reference/sdks/sdk-list/) - The core Algorand SDK providing Algorand protocol API calls, which AlgoKit Utils wraps, but still exposes for advanced scenarios
- [**Algorand Python**](https://github.com/algorandfoundation/puya): A semantically and syntactically compatible, typed Python language that works with standard Python tooling and allows you to express smart contracts (apps) and smart signatures (logic signatures) for deployment on the Algorand Virtual Machine (AVM).
- [**Algorand TypeScript (Beta)**](https://github.com/algorandfoundation/puya-ts): A semantically and syntactically compatible, typed TypeScript language that works with standard TypeScript tooling and allows you to express smart contracts (apps) and smart signatures (logic signatures) for deployment on the Algorand Virtual Machine (AVM). This language is currently in beta.
- [**TEALScript**](https://github.com/algorandfoundation/TEALScript): A subset of TypeScript that can be used to express smart contracts (apps) and smart signatures (logic signatures) for deployment on the Algorand Virtual Machine (AVM).
- [**AlgoKit LocalNet**](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/localnet.md): A local isolated Algorand network so you can simulate real transactions and workloads on your computer
### Operate
AlgoKit can help you deploy and operate Algorand solutions.
AlgoKit comes with out-of-the-box [Continuous Integration / Continuous Deployment (CI/CD) templates](https://github.com/algorandfoundation/algokit-python-template) that help you rapidly set up best-practice software delivery processes that ensure you build quality in and have a solution that can evolve
## What can AlgoKit help me do?
The set of capabilities supported by AlgoKit will evolve over time, but currently includes:
- Quickly run, explore and interact with an isolated local Algorand network (LocalNet)
- Building, testing, deploying and calling [Algorand Python](https://github.com/algorandfoundation/puya) / [Algorand TypeScript (Beta)](https://github.com/algorandfoundation/puya-ts) / [TEALScript](https://github.com/algorandfoundation/TEALScript) smart contracts
For a user guide and guidance on how to use AlgoKit, please refer to the [docs](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/algokit.md).
Future capabilities are likely to include:
- Quickly deploy [standardised](https://github.com/algorandfoundation/ARCs/#arcs-algorand-requests-for-comments), audited smart contracts
- Building and deploying Algorand dApps
## Is this for me?
The target audience for this tool is software developers building applications on the Algorand network. A working knowledge of using a command line interfaces and experience using the supported programming languages is assumed.
## How can I contribute?
This is an open source project managed by the Algorand Foundation. See the [contributing page](https://github.com/algorandfoundation/algokit-cli/blob/main/CONTRIBUTING.md) to learn about making improvements to the CLI tool itself, including developer setup instructions.
# Install
> **Note** Refer to [Troubleshooting](#troubleshooting) for more details on mitigation of known edge cases when installing AlgoKit.
## Prerequisites
The installation pre-requisites change depending on the method you use to install. Please refer to [Installation Methods](#installation-methods).
Depending on the features you choose to leverage from the AlgoKit CLI, additional dependencies may be required.
The AlgoKit CLI will tell you if you are missing one for a given command. These optional dependencies are:
- **Git**: Essential for creating and updating projects from templates. Installation guide available at [Git Installation](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git).
- **Docker**: Necessary for running the AlgoKit LocalNet environment. Docker Compose version 2.5.0 or higher is required. See [Docker Installation](https://docs.docker.com/get-docker/).
- **Python**: For those installing the AlgoKit CLI via `pipx` or building contracts using Algorand Python. **Minimum required version is Python 3.12+ when working with Algorand Python**. See [Python Installation](https://www.python.org/downloads/).
- **Node.js**: For those working on frontend templates or building contracts using Algorand TypeScript or TEALScript. **Minimum required versions are Node.js `v22` and npm `v10`**. See [Node.js Installation](https://nodejs.org/en/download/).
> **Note**
> If you have previously installed AlgoKit using `pipx` and would like to switch to a different installation method, please ensure that
> you first uninstall the existing version by running `pipx uninstall algokit`. Once uninstalled, you can follow the installation instructions for your preferred platform.
## Cross-platform installation
AlgoKit can be installed using OS specific package managers, or using the python tool [pipx](https://pypa.github.io/pipx/).
See below for specific installation instructions.
### Installation Methods
- [Windows](#install-algokit-on-windows)
- [Mac](#install-algokit-on-mac)
- [Linux](#install-algokit-on-linux)
- [Universal via pipx](#install-algokit-with-pipx-on-any-os)
## Install AlgoKit on Windows
> **Note**
> AlgoKit is supported on Windows 10 1709 (build 16299) and later.
> We only publish an x64 binary, however it also runs on ARM devices by default using the built in x64 emulation feature.
1. Ensure prerequisites are installed
- [WinGet](https://learn.microsoft.com/en-us/windows/package-manager/winget/) (should be installed by default on recent Windows 10 or later)
- [Git](https://github.com/git-guides/install-git#install-git-on-windows) (or `winget install git.git`)
- [Docker](https://docs.docker.com/desktop/install/windows-install/) (or `winget install docker.dockerdesktop`)
> **Note**
> See [our LocalNet documentation](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/localnet.md#prerequisites) for more tips on installing Docker on Windows
- [Microsoft C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/)
2. Install using winget
```shell
winget install algokit
```
3. [Verify installation](#verify-installation)
### Maintenance
Some useful commands for updating or removing AlgoKit in the future.
- To update AlgoKit: `winget upgrade algokit`
- To remove AlgoKit: `winget uninstall algokit`
## Install AlgoKit on Mac
> **Note**
> AlgoKit is supported on macOS Big Sur (11) and later for both x64 and ARM (Apple Silicon)
1. Ensure prerequisites are installed
- [Homebrew](https://docs.brew.sh/Installation)
- [Git](https://github.com/git-guides/install-git#install-git-on-mac) (should already be available if `brew` is installed)
- [Docker](https://docs.docker.com/desktop/install/mac-install/), (or `brew install --cask docker`)
> **Note**
> Docker requires MacOS 11+
2. Install using Homebrew
```shell
brew install algorandfoundation/tap/algokit
```
3. Restart the terminal to ensure AlgoKit is available on the path
4. [Verify installation](#verify-installation)
### Maintenance
Some useful commands for updating or removing AlgoKit in the future.
- To update AlgoKit: `brew upgrade algokit`
- To remove AlgoKit: `brew uninstall algokit`
## Install AlgoKit on Linux
> **Note**
> AlgoKit is compatible with Ubuntu 16.04 and later, Debian, RedHat, and any distribution that supports [Snap](https://snapcraft.io/docs/installing-snapd), but it is only supported on x64 architecture; ARM is not supported.
1. Ensure prerequisites are installed
- [Snap](https://snapcraft.io/docs/installing-snapd) (should be installed by default on Ubuntu 16.04.4 LTS (Xenial Xerus) or later)
- [Git](https://github.com/git-guides/install-git#install-git-on-linux)
- [Docker](https://docs.docker.com/desktop/install/linux-install/)
2. Install using snap
```shell
sudo snap install algokit --classic
```
> For detailed guidelines per each supported linux distro, refer to [Snap Store](https://snapcraft.io/algokit).
3. [Verify installation](#verify-installation)
### Maintenance
Some useful commands for updating or removing AlgoKit in the future.
- To update AlgoKit: `snap refresh algokit`
- To remove AlgoKit: `snap remove --purge algokit`
## Install AlgoKit with pipx on any OS
1. Ensure desired prerequisites are installed
- [Python 3.10 - 3.14](https://www.python.org/downloads/)
- [pipx](https://pypa.github.io/pipx/installation/)
- [Git](https://github.com/git-guides/install-git)
- [Docker](https://docs.docker.com/get-docker/)
2. Install using pipx
```shell
pipx install algokit
```
3. Restart the terminal to ensure AlgoKit is available on the path
4. [Verify installation](#verify-installation)
### Maintenance
Some useful commands for updating or removing AlgoKit in the future.
- To update AlgoKit: `pipx upgrade algokit`
- To remove AlgoKit: `pipx uninstall algokit`
## Verify installation
Verify AlgoKit is installed correctly by running `algokit --version` and you should see output similar to:
```
algokit, version 1.0.1
```
> **Note**
> If you get receive one of the following errors:
>
> - `command not found: algokit` (bash/zsh)
> - `The term 'algokit' is not recognized as the name of a cmdlet, function, script file, or operable program.` (PowerShell)
>
> Then ensure that `algokit` is available on the PATH by running `pipx ensurepath` and restarting the terminal.
It is also recommended that you run `algokit doctor` to verify there are no issues in your local environment and to diagnose any problems if you do have difficulties running AlgoKit. The output of this command will look similar to:
```
timestamp: 2023-03-27T01:23:45+00:00
AlgoKit: 1.0.1
AlgoKit Python: 3.11.1 (main, Dec 23 2022, 09:28:24) [Clang 14.0.0 (clang-1400.0.29.202)] (location: /Users/algokit/.local/pipx/venvs/algokit)
OS: macOS-13.1-arm64-arm-64bit
docker: 20.10.21
docker compose: 2.13.0
git: 2.37.1
python: 3.10.9 (location: /opt/homebrew/bin/python)
python3: 3.10.9 (location: /opt/homebrew/bin/python3)
pipx: 1.1.0
poetry: 1.3.2
node: 18.12.1
npm: 8.19.2
brew: 3.6.18
If you are experiencing a problem with AlgoKit, feel free to submit an issue via:
https://github.com/algorandfoundation/algokit-cli/issues/new
Please include this output, if you want to populate this message in your clipboard, run `algokit doctor -c`
```
Per the above output, the doctor command output is a helpful tool if you need to ask for support or [raise an issue](https://github.com/algorandfoundation/algokit-cli/issues/new).
## Troubleshooting
This section addresses specific edge cases and issues that some users might encounter when interacting with the CLI. The following table provides solutions to known edge cases:
| Issue Description | OS(s) with observed behaviour | Steps to mitigate | References |
| --------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
| This scenario may arise if installed `python` was build without `--with-ssl` flag enabled, causing pip to fail when trying to install dependencies. | Debian 12 | Run `sudo apt-get install -y libssl-dev` to install the required openssl dependency. Afterwards, ensure to reinstall python with `--with-ssl` flag enabled. This includes options like [building python from source code](https://medium.com/@enahwe/how-to-06bc8a042345) or using tools like [pyenv](https://github.com/pyenv/pyenv). | |
| `poetry install` invoked directly or via `algokit project bootstrap all` fails on `Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE)`. | `MacOS` >=14 using `python` 3.13 installed via `homebrew` | Install dependencies deprecated in `3.13` and latest MacOS versions via `brew install pkg-config`, delete the virtual environment folder and retry the `poetry install` command invocation. | N/A |
================================================
FILE: debug.py
================================================
"""
This script is for invoking algokit from your IDE with a dynamic set of args,
defined in args.in (which is in .gitignore)
"""
import os
import subprocess
import sys
from pathlib import Path
try:
import click
except ImportError:
print( # noqa: T201
"ERROR: Couldn't import click, make sure you've run 'poetry install' and activated the virtual environment.\n"
"For tips on getting started with developing AlgoKit CLI itself see CONTRIBUTING.md.\n",
file=sys.stderr,
)
raise
if sys.prefix == sys.base_prefix:
click.echo(
click.style(
"WARNING: virtualenv not activated, this is unexpected and you probably want to activate it first",
fg="red",
),
err=True,
)
vcs_root = Path(__file__).parent
args_file = vcs_root / "args.in"
if not args_file.exists():
click.echo(
click.style(
"arg.in does not exist, creating an empty file.\n"
"Edit this file to change what runs - each line should contain the command line arguments to algokit.\n"
"\n",
fg="yellow",
),
err=True,
)
args_file.touch(exist_ok=False)
args_file.write_text("--version")
commands_sequence = args_file.read_text().splitlines()
# change to src directory so algokit is in path
os.chdir(vcs_root / "src")
for command in commands_sequence or [""]:
click.echo(click.style(f"> algokit -v {command}", bold=True), err=True)
run_result = subprocess.run([sys.executable, "-m", "algokit", "-v", *command.split()], check=False)
if run_result.returncode != 0:
click.echo(
click.style(
f"command failed, return code was: {run_result.returncode}",
bold=True,
fg="red",
),
err=True,
)
sys.exit(run_result.returncode)
================================================
FILE: docs/algokit.md
================================================
# AlgoKit
The Algorand AlgoKit CLI is the one-stop shop tool for developers building on the Algorand network. The goal of AlgoKit is to help developers build and launch secure, automated production-ready applications rapidly.
## AlgoKit CLI commands
For details on how to use individual features see the following
- [Bootstrap](./features/project/bootstrap.md) - Bootstrap AlgoKit project dependencies
- [Compile](./features/compile.md) - Compile Algorand Python code
- [Completions](./features/completions.md) - Install shell completions for AlgoKit
- [Deploy](./features/project/deploy.md) - Deploy your smart contracts effortlessly to various networks
- [Dispenser](./features/dispenser.md) - Fund your TestNet account with ALGOs from the AlgoKit TestNet Dispenser
- [Doctor](./features/doctor.md) - Check AlgoKit installation and dependencies
- [Explore](./features/explore.md) - Explore Algorand Blockchains using lora
- [Generate](./features/generate.md) - Generate code for an Algorand project
- [Goal](./features/goal.md) - Run the Algorand goal CLI against the AlgoKit Sandbox
- [Init](./features/init.md) - Quickly initialize new projects using official Algorand Templates or community provided templates
- [LocalNet](./features/localnet.md) - Manage a locally sandboxed private Algorand network
- [Project](./features/project.md) - Manage an AlgoKit project workspace on your file system
- [Tasks](./features/tasks.md) - Perform a variety of useful operations on the Algorand blockchain
## Common AlgoKit CLI options
AlgoKit has a number of global options that can impact all commands. Note: these global options must be appended to `algokit` and appear before a command, e.g. `algokit -v localnet start`, but not `algokit localnet start -v`. The exception to this is `-h`, which can be appended to any command or sub-command to see contextual help information.
- `-h, --help` The help option can be used on any command to get details on any command, its sub-commands and options.
- `-v, --verbose` Enables DEBUG logging, useful when troubleshooting or if you want to peek under the covers and learn what AlgoKit CLI is doing.
- `--color / --no-color` Enables or disables output of console styling, we also support the [NO_COLOR](https://no-color.org) environment variable.
- `--skip-version-check` Skips updated AlgoKit version checking and prompting for that execution, this can also be disabled [permanently on a given machine](./cli/index.md#version-prompt) with `algokit config version-prompt disable`.
See also the [AlgoKit CLI Reference](./cli/index.md), which details every command, sub-command and option.
## AlgoKit Tutorials
The following tutorials guide you through various scenarios:
- [AlgoKit quick start](https://dev.algorand.co/algokit/algokit-intro)
- [Creating AlgoKit templates](https://dev.algorand.co/algokit/custom-algokit-templates)
## Guiding Principles
AlgoKit is guided by the following solution principles which flow through to the applications created by developers.
1. **Cohesive developer tool suite**: Using AlgoKit should feel professional and cohesive, like it was designed to work together, for the developer; not against them. Developers are guided towards delivering end-to-end, high quality outcomes on MainNet so they and Algorand are more likely to be successful.
2. **Seamless onramp**: New developers have a seamless experience to get started and they are guided into a pit of success with best practices, supported by great training collateral; you should be able to go from nothing to debugging code in 5 minutes.
3. **Leverage existing ecosystem**: AlgoKit functionality gets into the hands of Algorand developers quickly by building on top of the existing ecosystem wherever possible and aligned to these principles.
4. **Sustainable**: AlgoKit should be built in a flexible fashion with long-term maintenance in mind. Updates to latest patches in dependencies, Algorand protocol development updates, and community contributions and feedback will all feed in to the evolution of the software.
5. **Secure by default**: Include defaults, patterns and tooling that help developers write secure code and reduce the likelihood of security incidents in the Algorand ecosystem. This solution should help Algorand be the most secure Blockchain ecosystem.
6. **Extensible**: Be extensible for community contribution rather than stifling innovation, bottle-necking all changes through the Algorand Foundation and preventing the opportunity for other ecosystems being represented (e.g. Go, Rust, etc.). This helps make developers feel welcome and is part of the developer experience, plus it makes it easier to add features sustainably.
7. **Meet developers where they are**: Make Blockchain development mainstream by giving all developers an idiomatic development experience in the operating system, IDE and language they are comfortable with so they can dive in quickly and have less they need to learn before being productive.
8. **Modular components**: Solution components should be modular and loosely coupled to facilitate efficient parallel development by small, effective teams, reduced architectural complexity and allowing developers to pick and choose the specific tools and capabilities they want to use based on their needs and what they are comfortable with.
================================================
FILE: docs/architecture-decisions/2022-11-14_sandbox-approach.md
================================================
# AlgoKit sandbox approach
- **Status**: Approved
- **Owner:** Rob Moore
- **Deciders**: Anne Kenyon (Algorand Inc.), Alessandro Cappellato (Algorand Foundation), Will Winder (Algorand Inc.)
- **Date created**: 2022-11-14
- **Date decided:** 2022-11-14
- **Date updated**: 2022-11-16
## Context
In order for AlgoKit to facilitate a productive development experience it needs to provide a managed Algorand sandbox experience. This allows developers to run an offline (local-only) private instance of Algorand that they can privately experiment with, run automated tests against and reset at will.
## Requirements
- The sandbox works cross-platform (i.e. runs natively on Windows, Mac and Linux)
- You can spin up algod and indexer since both have useful use cases when developing
- The sandbox is kept up to date with the latest version of algod / indexer
- There is access to KMD so that you can programmatically fund accounts to improve the developer experience and reduce manual effort
- There is access to the tealdbg port outside of algod so you can attach a debugger to it
- The sandbox is isolated and (once running) works offline so the workload is private, allows development when there is no internet (e.g. when on a plane) and allows for multiple instances to be run in parallel (e.g. when developing multiple independent projects simultaneously)
- Works in continuous integration and local development environments so you can facilitate automated testing
## Principles
- **[AlgoKit Guiding Principles](../../docs/algokit.md#Guiding-Principles)** - specifically Seamless onramp, Leverage existing ecosystem, Meet devs where they are
- **Lightweight** - the solution should have as low an impact as possible on resources on the developers machine
- **Fast** - the solution should start quickly, which makes for a nicer experience locally and also allows it to be used for continuous integration automation testing
## Options
### Option 1 - Pre-built DockerHub images
Pre-built application developer-optimised DockerHub images that work cross-platform; aka an evolved AlgoKit version of .
**Pros**
- It's quick to download the images and quick to start the container since you don't need to compile Algod / indexer and the images are optimised for small size
- The only dependency needed is Docker, which is a fairly common dependency for most developers to use these days
- The images are reasonably lightweight
- The images provide an optimised application developer experience with: (devmode) algo, KMD, tealdbg, indexer
- It natively works cross-platform
**Cons**
- Some people have reported problems running WSL 2 on a small proportion of Windows environments (to get the latest Docker experience)
- Docker within Docker can be a problem in some CI environments that run agents on Docker in the first place
- Work needs to be done to create an automated CI/CD that automatically releases new versions to keep it up to date with latest algod/indexer versions
### Option 2 - Lightweight algod client implementation
Work with the Algorand Inc. team to get a lightweight algod client that can run outside of a Docker container cross-platform.
**Pros**
- Likely to be the most lightweight and fastest option - opening up better/easier isolated/parallelised automated testing options
- Wouldn't need Docker as a dependency
**Cons**
- Indexer wouldn't be supported (Postgres would require Docker anyway)
- Algorand Inc. does not distribute Windows binaries.
### Option 3 - Sandbox
Use the existing [Algorand Sandbox](https://github.com/algorand/sandbox).
**Pros**
- Implicitly kept up to date with Algorand - no extra thing to maintain
- Battle-tested by the core Algorand team day-in-day-out
- Supports all environments including unreleased feature branches (because it can target a git repo / commit hash)
**Cons**
- Sandbox is designed for network testing, not application development - it's much more complex than the needs of application developers
- Slow to start because it has to download and built algod and indexer (this is particularly problematic for ephemeral CI/CD build agents)
- It's not cross-platform (it requires bash to run sandbox.sh, although a sandbox.ps1 version could be created)
## Preferred option
Option 1 and Option 2.
Option 1 provides a fully-featured experience that will work great in most scenarios, having option 2 as a second option would open up more advanced parallel automated testing scenarios in addition to that.
## Selected option
Option 1
We're aiming to release the first version of AlgoKit within a short timeframe, which won't give time for Option 2 to be developed. Sandbox itself has been ruled out since it's not cross-platform and is too slow for both development and continuous integration.
Option 1 also results in a similar result to running Sandbox, so existing Algorand documentation, libraries and approaches should work well with this option making it a good slot-in replacement for Sandbox for application developers.
AlgoKit is designed to be modular: we can add in other approaches over time such as Option 2 when/if it becomes available.
================================================
FILE: docs/architecture-decisions/2022-11-22_beaker-testing-strategy.md
================================================
# Beaker testing strategy
- **Status**: Draft
- **Owner:** Rob Moore
- **Deciders**: Anne Kenyon (Algorand Inc.), Alessandro Cappellato (Algorand Foundation), Michael Diamant (Algorand Inc.), Benjamin Guidarelli (Algorand Foundation)
- **Date created**: 2022-11-22
- **Date decided:** TBD
- **Date updated**: 2022-11-28
## Context
AlgoKit will be providing a smart contract development experience built on top of [PyTEAL](https://pyteal.readthedocs.io/en/stable/) and [Beaker](https://developer.algorand.org/articles/hello-beaker/). Beaker is currently in a pre-production state and needs to be productionised to provide confidence for use in generating production-ready smart contracts by AlgoKit users. One of the key things to resolve to productionisation of Beaker is to improve the automated test coverage.
Beaker itself is currently split into the PyTEAL generation related code and the deployment and invocation related code (including interacting with Sandbox). This decision is solely focussed on the PyTEAL generation components of Beaker. The current automated test coverage of this part of the codebase is ~50% and is largely based on compiling and/or executing smart contracts against Algorand Sandbox. While it's generally not best practice to try and case a specific code coverage percentage, a coverage of ~80%+ is likely indicative of good coverage in a dynamic language such as Python.
The Sandbox tests provide a great deal of confidence, but are also slow to execute, which can potentially impair Beaker development and maintenance experience, especially as the coverage % is grown and/or features are added over time.
Beaker, like PyTEAL, can be considered to be a transpiler on top of TEAL. When generating smart contracts, the individual TEAL opcodes are significant, since security audits will often consider the impact at that level, and it can have impacts on (limited!) resource usage of the smart contract. As such, "output stability" is potentially an important characteristic to test for.
## Requirements
- We have a high degree of confidence that writing smart contracts in Beaker leads to expected results for production smart contracts
- We have reasonable regression coverage so features are unlikely to break as new features and refactorings are added over time
- We have a level of confidence in the "output stability" of the TEAL code generated from a Beaker smart contract
## Principles
- **Fast development feedback loops** - The feedback loop during normal development should be as fast as possible to improve the development experience of developing Beaker itself
- **Low overhead** - The overhead of writing and maintaining tests is as low as possible; tests should be quick to read and write
- **Implementation decoupled** - Tests aren't testing the implementation details of Beaker, but rather the user-facing experience and output of it; this reduces the likelihood of needing to rewrite tests when performing refactoring of the codebase
## Options
### Option 1: TEAL Approval tests
Writing [approval tests](https://approvaltests.com/) of the TEAL output generated from a given Beaker smart contract.
**Pros**
- Ensures TEAL output stability and focussing on asserting the output of Beaker rather than testing whether Algorand Protocol is working
- Runs in-memory/in-process so will execute in low 10s of milliseconds making it easy to provide high coverage with low developer feedback loop overhead
- Tests are easy to write - the assertion is a single line of code (no tedious assertions)
- The tests go from Beaker contract -> TEAL approval so don't bake implementation detail and thus allow full Beaker refactoring with regression confidence without needing to modify the tests
- Excellent regression coverage characteristics - fast test run and quick to write allows for high coverage and anchoring assertions to TEAL output is a very clear regression marker
**Cons**
- The tests rely on the approver to understand the TEAL opcodes that are emitted and verify they match the intent of the Beaker contract - anecdotally this can be difficult at times even for experienced (Py)TEAL developers
- Doesn't assert the correctness of the TEAL output, just that it matches the previously manually approved output
### Option 2: Sandbox compile tests
Writing Beaker smart contracts and checking that the TEAL output successfully compiles against algod.
**Pros**
- Ensures that the TEAL output compiles, giving some surety about the intactness of it and focussing on asserting the output of Beaker rather than testing whether Algorand Protocol is working
- Faster than executing the contract
- Tests are easy to write - the assertion is a single line of code (no tedious assertions)
**Cons**
- Order of magnitude slower than asserting TEAL output (out of process communication)
- Doesn't assert the correctness of the TEAL output, just that it compiles
### Option 3: Sandbox execution tests
Execute the smart contracts and assert the output is as expected. This can be done using dry run and/or actual transactions.
**Pros**
- Asserts that the TEAL output _executes_ correctly giving the highest confidence
- Doesn't require the test writer to understand the TEAL output
- Tests don't bake implementation detail and do assert on output so give a reasonable degree of refactoring confidence without modifying tests
**Cons**
- Tests are more complex to write
- Tests take an order of magnitude longer to run than just compilation (two orders of magnitude to run than checking TEAL output)
- Harder to get high regression coverage since it's slower to write and run the tests making it impractical to get full coverage
- Doesn't ensure output stability
- Is testing that the Algorand Protocol itself works (TEAL `x` when executed does `y`) so the testing scope is broader than just Beaker itself
## Preferred option
Option 1 (combined with Option 2 to ensure the approved TEAL actually compiles, potentially only run on CI by default to ensure fast local dev loop) for the bulk of testing to provide a rapid feedback loop for developers as well as ensuring output stability and great regression coverage.
## Selected option
Combination of option 1, 2 and 3:
- While Option 1 + 2 provides high confidence with fast feedback loop, it relies on the approver being able to determine the TEAL output does what they think it does, which isn't always the case
- Option 3 will be used judiciously to provide that extra level of confidence that the fundamentals of the Beaker output are correct for each main feature; this will involve key scenarios being tested with execution based tests, the goal isn't to get combinatorial coverage, which would be slow and time-consuming, but to give a higher degree of confidence
- The decision of when to use Option 3 as well as Option 1+2 will be made on a per-feature basis and reviewed via pull request, over time a set of principles may be able to be revised that outline a clear delineation
- Use of PyTest markers to separate execution so by default the dev feedback loop is still fast, but the full suite is always run against pull requests and merges to main
================================================
FILE: docs/architecture-decisions/2023-01-11_beaker_productionisation_review.md
================================================
# Beaker productionisation review
- **Status**: Approved
- **Owners:** Rob Moore, Adam Chidlow
- **Deciders**: Anne Kenyon (Algorand Inc.), Alessandro Cappellato (Algorand Foundation), Jason Weathersby (Algorand Foundation), Benjamin Guidarelli (Algorand Foundation), Bob Broderick (Algorand Inc.)
- **Date created**: 2023-01-11
- **Date decided:** 2023-02-04
- **Date updated**: 2023-02-04
## Context
Beaker is a smart contract development framework for [Algorand](https://www.algorand.com/) that provides a wrapper over [PyTeal](https://pyteal.readthedocs.io/en/stable/) that focusses on providing a great developer experience through terse, expressive language constructs and making common tasks easier. Beaker is useful because it creates a higher level programming construct from PyTEAL that is easier to get started when learning and results in code that is terser and easier to read and write.
Beaker is an important part of the [AlgoKit strategy](https://github.com/algorandfoundation/algokit-cli/#algokit-cli). It helps create a more seamless onramp to Algorand development by providing an easier starting point for developers. As part of the lead up to releasing AlgoKit, it was desired to perform a v1.0 release of Beaker and explicitly mark it as being production ready. In order to provide confidence a productionisation review was conducted by [MakerX](https://www.makerx.com.au/); this document summarises the recommendations from that review.
An architecture decision was made in the lead up to this review on a [testing strategy for Beaker](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/architecture-decisions/2022-11-22_beaker-testing-strategy.md).
## Goal
The goals of this productionisation review are to:
- Get Beaker ready for production use
- Gain confidence in Beaker's software architecture and maintainability
- Reduce the likelihood of need for breaking changes soon after release by getting key recommended breaking changes identified now
## Findings summary
The Beaker codebase is well factored and had a decent initial test coverage (albeit some of that test coverage is via a series of examples that while they provide high code coverage, don't actually validate all of the functionality).
A series of changes have been landed to improve some of the fundamentals of Beaker in preparation for production launch:
- [Various improvements](https://github.com/algorand-devrel/beaker/pull/142) - Improved test coverage, improved dev experience (setup + ongoing) via Poetry, improvements to the code quality setup (linting, automatic formatting, typing), allowed Windows development on Beaker itself, significantly improved CI/CD pipeline speed, removing the examples directory and tests from being distributed wit hthe PyPi package
- [Typing improvements](https://github.com/algorand-devrel/beaker/pull/147)
- [Removed inline imports](https://github.com/algorand-devrel/beaker/pull/148)
- [Removed dead code](https://github.com/algorand-devrel/beaker/pull/149/files)
- [Added automated release management and versioning](https://github.com/algorand-devrel/beaker/pull/161)
In addition, there are a remaining set of more major (breaking) changes that are recommended. The recommendations are split into 2 categories, recommendations for immediate improvement (i.e. included in v1.0) and future suggestions that can be addressed post v1.0 launch.
The recommended additional areas for immediate improvement are:
- **Replace the class-based structure with an instance based one** - remove some areas of potential surprise for developers and simplify the Beaker codebase by moving to a composable instance-based structure rather than a static class-based structure
- **Defer PyTEAL compilation** - improve flexibility and future contract output stability by deferring PyTEAL compilation (i.e. Beaker -> TEAL transpilation) to not happen when the Beaker contract is initialised
- **Renamings** - There are some clear parameters that make sense to rename for various reasons
- **Key decorator improvements** - Refactor some of the Beaker decorators to fix some bugs and improve user experience
- **Beaker state refactor** - Refactor of the Beaker state interfaces to improve user extensibility and significantly simplify the Beaker codebase to improve maintainability
The recommended areas for future improvement are:
- Typed client generation from app spec to improve deploy-time and run-time dev experience
- `Tmpl` values in app spec so you can have type-safe deployment clients that substitute any template values reliably at contract deploy time
- Refactor storage types (blob, reserved, etc.) to allow use of in-built Python types and operators (terser, more intuitive)
- Box storage implementation improved to match local/global behaviour and also automatically delete itself on contract deletion
- Composable and stackable authorization and `@authorize` as a standalone decorator
- PyTEAL typings to be improved to support types beyond `Expr` where a more explicit type can be specified (improves typing and extensibility)
- Support referencing an app/lsig via ID/address (deployed separately, potentially automatically as part reading a Directed Acyclic Graph (DAG) in application.json of application dependencies) or bytes (deployed inline, what was previously called precompile, noting this would be deploy-time substitution, not smart contract run-time substitute like `TemplateVariable`), this also may allow precompile to be deprecated (it's a very complex implementation for what we believe to be an advanced edge case)
## Immediate recommendations
### (1) Replace the class-based structure with an instance based one
#### What?
Beaker is currently structured around users sub-classing the `beaker.Application` class. They then hold state variables (from `beaker.state.*`) as [class variables](https://pynative.com/python-class-variables/) and also contain methods which are forwarded to the `pyteal.abi.Router` instance created during `Application.compile(...)` based on decorators from `beaker.decorators.*`. We propose replacing this with an "instance based structure", drawing inspiration from highly popular Python web frameworks such as `flask` ([example](https://flask.palletsprojects.com/en/2.2.x/quickstart/#a-minimal-application)).
This change will simplify Beaker's code (improving maintainability) and, more importantly, reduce the potential for end-user error and confusion.
#### Why?
**User-facing benefits**
1. The current structure, by encouraging and supporting [bound instance methods](https://www.geeksforgeeks.org/bound-methods-python/) alongside [class variables](https://pynative.com/python-class-variables/), is a potential source of confusion for users new to writing smart contracts or PyTEAL. The distinction between what runs on `beaker.Application` instantiation, evaluation by PyTeal during compile, and finally what runs on-chain, can be difficult to grasp at first. One might assume (wrongly) that Beaker is somehow maintaining the state of `self.*` between methods, but this is not the case. Contrast this with Solidity, for example, where state can be directly manipulated because it's help within the class instance.
2. Currently, actually using `self.*` can easily lead to problems, since if they are not defined before calling `super().__init__(...)` they won't be defined when compiling. This can be fixed by not automatically compiling in `Application.__init__()` (which is also proposed in (2) below) for simple constants, however another issue is that using `self.foo = `, would not currently work with the introspection beaker is performing. This could potentially be fixed by itself, but developers will still need to define these values _before_ calling `super().__init__()` which is a source of confusion. Usually, idiomatic Python will call super init sooner rather than later so this is something that can trip up experienced Python developers.
3. In order to compose applications together, say if there were two ARC standard implementations that we wanted to combine into the same contract, the user doesn't need to understand Python's multiple-inheritance idiosyncrasies like [Method Resolution Order](https://www.geeksforgeeks.org/method-resolution-order-in-python-inheritance/). Additionally, by taking a functional composition approach, we can have easy to understand entry points where you can check any pre-conditions.
4. Since state variables are currently defined as class variables, this makes them "globals", which can lead to errors/bugs that are non-obvious.
For instance, consider:
```python
class MyBaseApp(beaker.Application):
counter = beaker.ApplicationStateValue(stack_type=pyteal.TealType.uint64)
@beaker.create
def create(self) -> pyteal.Expr:
return self.initialize_application_state()
class MyApp(MyBaseApp):
pass
MyApp.counter.default = pyteal.Int(10)
class MyOtherApp(MyBaseApp):
pass
app1 = MyApp()
app2 = MyOtherApp()
assert app1.approval_program != app2.approval_program # fails
```
5. Setting parameters that control the program creation is awkward with the current approach of extending `beaker.Application`, currently this impacts just the `version` parameter (which specifies the TEAL version), but there are clear examples we can see for other variables that are useful to define at this point in the future (e.g. a state allocation override if you know that the state a contract will need grows in the future).
6. There are bugs in beaker which are directly caused by the class-based structure. For example, bare methods are currently evaluated as a subroutine only once:
```python
class MyApp(beaker.Application):
price = beaker.ApplicationStateValue(stack_type=pyteal.TealType.uint64)
def __init__(self, default_price: int, version: int = pyteal.MAX_TEAL_VERSION):
self.price.default = pyteal.Int(default_price)
super().__init__(version=version)
class CorrectApp(MyApp):
@beaker.create
def create(self, *, output: pyteal.abi.Uint64) -> pyteal.Expr:
return pyteal.Seq(self.initialize_application_state(), output.set(self.price))
class IncorrectApp(MyApp):
@beaker.create
def create(self) -> pyteal.Expr:
return self.initialize_application_state()
correct_app1 = CorrectApp(default_price=123)
correct_app2 = CorrectApp(default_price=456)
incorrect_app1 = IncorrectApp(default_price=123)
incorrect_app2 = IncorrectApp(default_price=456)
assert correct_app1.approval_program != correct_app2.approval_program # success
assert incorrect_app1.approval_program != incorrect_app2.approval_program # failure
```
**Beaker maintainability benefit**
The main benefit to Beaker is the removal the complex code that modifies function signatures to remove `self` before passing to PyTEAL. Removing the instance method implementation will significantly reduce the complexity of the code and likelihood of unknown bugs surfacing from that part of the codebase.
#### Before & After (user's perspective)
While the proposed changes are fairly substantial internally, and propose a radically different architecture conceptually for beaker Applications, the migration should actually be relatively straight forward for users with existing Beaker code:
The following examples assume the import of relevant names from `beaker` and/or `pyteal` are present to simplify the code.
**Before:**
```python
class CounterApp(Application):
counter = ApplicationStateValue(
stack_type=TealType.uint64,
descr="A counter for showing how to use application state",
)
@create
def create(self):
return self.initialize_application_state()
@external(authorize=Authorize.only(Global.creator_address()))
def increment(self, *, output: abi.Uint64):
"""increment the counter"""
return Seq(
self.counter.set(self.counter + Int(1)),
output.set(self.counter),
)
@external(authorize=Authorize.only(Global.creator_address()))
def decrement(self, *, output: abi.Uint64):
"""decrement the counter"""
return Seq(
self.counter.set(self.counter - Int(1)),
output.set(self.counter),
)
```
**After:**
The changes are:
- State is moved into a dedicated class `CounterState`
- `beaker.Application` is directly instantiated (along with the state, and optionally the teal `version`)
- Class methods are de-indented, `self` is removed and the decorator is prefixed with `app.` (which in turn reduces the number of imports needed from the `beaker` namespace and provides better exploratory intellisense for users)
```python
class CounterState(beaker.State):
counter = ApplicationStateValue(
stack_type=TealType.uint64,
descr="A counter for showing how to use application state",
)
app = beaker.Application(state=CounterState())
@app.create
def create():
return app.state.initialize_application_state()
@app.external(authorize=Authorize.only(Global.creator_address()))
def increment(*, output: abi.Uint64):
"""increment the counter"""
return Seq(
app.state.counter.set(app.state.counter + Int(1)),
output.set(app.state.counter),
)
@app.external(authorize=Authorize.only(Global.creator_address()))
def decrement(*, output: abi.Uint64):
"""decrement the counter"""
return Seq(
app.state.counter.set(app.state.counter - Int(1)),
output.set(app.state.counter),
)
```
### (2) Defer PyTEAL compilation
#### What?
Currently, `beaker.Application.compile()` is called as part of `__init__()`, assuming there are no `precompiles` defined. We recommend that `compile()` always be deferred to a later point, and further that `compile()` does not mutate `Application` in any way, but instead returns a new object.
#### Why?
The deferment of the `compile()` call is actually a necessary part of recommendation #1 that we have skipped over thus far, but would be recommended anyway.
The immediate `compile()` has issues such as requiring implementors (i.e. subclasses) to call `super().__init__()` as a **final** step in their own `__init__` method - any code that runs after the super init call will have no effect on the application produced!
Immediate compilation also reduces the control the user has over the output. Although currently the only parameter that `compile` takes is a `client`, it might be useful to add (optional) parameters here to control the compilation. For example, if you can pass in the list of optimisations that should be applied, that allows you to have [output stability](../articles/output_stability.md) of your smart contract code if new optimisations are added in the future.
The separation of compiled state outside of `Application` simplifies the design, and can be done mostly transparently to end-users.
The separation of compiled state will also benefit future interoperability. It allows for more explicit decoupling of PyTEAL compilation (Beaker / PyTEAL transpilation -> TEAL) and deploment (TEAL -> compiled byte code -> Algorand network). Once `beaker.client` is split into a separate package, if the compiled state can be both generated from a beaker Application object _or_ loaded from disk (or similar), this means Beaker's ApplicationClient could be used in more situations, such as for a (say) tealish smart contract, or a C# smart contract, or a raw PyTEAL or TEAL smart contract, etc. This conforms better to the modularity principle in AlgoKit and also vice versa allows for a Beaker smart contract to be deployed by a TypeScript deployer, or C# deployer, etc.
#### Before & After - user's perspective
For most use cases, this should be a relatively small and probably imperceptible change.
We believe there are two common usage scenarios that use the output of PyTEAL compilation currently:
1. Output the `Application` via `Application.dump(...)`
2. Interact with the `Application` by passing it to `ApplicationClient(app=..., ...)`.
We propose maintaining those two scenarios without any immediate external changes, but internally:
1. `Application.dump(...)` will call `Application.compile().dump()`, and potentially trigger a `DeprecationWarning` if we decide that we want users to always explicitly call compile.
2. `ApplicationClient(app=..., ...)` will call `Application.compile()` and not retain any reference to `app`.
To make use of scenarios 1 _and_ 2, or to control compilation parameters, a user should also be able to (for instance):
```python
app = Application(...)
compiled_app: CompiledApplication = app.compile(...)
compiled_app.dump(...)
client = ApplicationClient(app=compiled_app, ...)
```
We suggest also potentially renaming `CompiledApplication.dump()`, perhaps to something along the lines of `serialize()`.
The `compile()` call is actually a transpilation call (Beaker / PyTEAL transpilation -> TEAL), although it's called compile in PyTEAL so consideration should be made to either keep consistency with PyTEAL or use the more accurate `transpile()` (which also reduces confusion around the fact that you then have to call `compile` on algod to compile the TEAL to byte code before deployment).
The exact details of what `CompiledApplication` will look like are TBD, but should be driven by the principles outlined in the "Why?" section above. Broadly, it stands to reason it would contain the approval and clear TEAL, the ABI spec and the app spec though at least.
Finally, there is likely need to use metadata from transpilation such as the mapping of source code to line numbers, but we are confident these use cases will be able to be implemented on top of the proposed change.
### (3) Renamings
Renaming `version` parameter in `Application.__init__(version: int = pyteal.MAX_VERSION)` to (e.g.) `avm_version`, to be more explicit. Otherwise developers may be confused that it's the version of the specific smart contract. It may be desirable to allow `version` to continue to be specified for some time, but to raise a `DeprecationWarning`.
Rename methods in `beaker.lib.*` to start with an uppercase. Although going against PEP-8, this prevents collisions with `builtins` such as `min` and `max`, and also follows the useful convention from PyTeal where methods that produce TEAL code (vs just running Python code at transpilation time) start with uppercase such as `Add`, `Or`, `Concat`, etc.
### (4) Key decorator improvements
Refactor some of the Beaker decorators to fix some bugs and improve user experience.
End state:
```python
# for user convenience, rather than having to import + use MethodConfig
OnCompleteActionName: TypeAlias = Literal[
"no_op",
"opt_in",
"close_out",
"clear_state",
"update_application",
"delete_application",
]
HandlerFunc: TypeAlias = Callable[..., Expr]
DecoratorFunc: TypeAlias = Callable[[HandlerFunc], HandlerFunc]
class Application:
# the main decorator, capable of handling both ABI and Bare method registration
def external(
self,
fn: HandlerFunc | None = None,
/,
*,
# note: retain existing behaviour of if method_config is None, default to no_op with CallConfig.CALL
method_config: MethodConfig | dict[OnCompleteActionName, CallConfig] | None = None,
name: str | None = None,
authorize: SubroutineFnWrapper | None = None,
bare: bool = False,
read_only: bool = False,
override: bool | None = False,
) -> HandlerFunc | DecoratorFunc:
...
# the below are just "shortcuts" to @external for simple/common use cases
def create(
self,
fn: HandlerFunc | None = None,
/,
*,
allow_call: bool = False,
name: str | None = None,
authorize: SubroutineFnWrapper | None = None,
bare: bool = False,
read_only: bool = False,
override: bool | None = False,
) -> HandlerFunc | DecoratorFunc:
...
def (
self,
fn: HandlerFunc | None = None,
/,
*,
allow_call: bool = True,
allow_create: bool = False,
name: str | None = None,
authorize: SubroutineFnWrapper | None = None,
bare: bool = False,
read_only: bool = False,
override: bool | None = False,
) -> HandlerFunc | DecoratorFunc:
...
```
For reference, the current state:
```python
def internal(
return_type_or_handler: TealType | HandlerFunc,
) -> HandlerFunc | DecoratorFunc:
...
def external(
func: HandlerFunc | None = None,
/,
*,
name: str | None = None,
authorize: SubroutineFnWrapper | None = None,
method_config: MethodConfig | None = None,
read_only: bool = False,
) -> HandlerFunc | DecoratorFunc:
...
def bare_external(
no_op: CallConfig | None = None,
opt_in: CallConfig | None = None,
clear_state: CallConfig | None = None,
delete_application: CallConfig | None = None,
update_application: CallConfig | None = None,
close_out: CallConfig | None = None,
) -> Callable[..., HandlerFunc]:
...
def create(
fn: HandlerFunc | None = None,
/,
*,
authorize: SubroutineFnWrapper | None = None,
method_config: Optional[MethodConfig] | None = None,
) -> HandlerFunc | DecoratorFunc:
...
def (
fn: HandlerFunc | None = None, /, *, authorize: SubroutineFnWrapper | None = None
) -> HandlerFunc | DecoratorFunc:
...
```
Changes:
- Remove `@internal`:
- if you don't pass a TealType parameter to it, i.e. intend to create an ABI internal routine, it actually just inlines the code currently due to a bug
- when passing in a TealType parameter to it, i.e. intent to create a normal subroutine, then in combination with (1) it will be unneeded since you can use `Subroutine` from PyTEAL (since the methods don't need to be artificially modified to remove `self` anymore)
- Add `bare: bool` option:
- Currently, this is not able to be controlled by the user - for `` decorators, they will create a bare method if the function takes no parameters other than maybe a `self` parameter. This has some down-sides:
1. The user might want an ABI method rather than a bare method. In this case, currently they could use `@external(method_config=...)`, but for simple cases this is not as easy to read/type and is not intuitive to discover in the first place.
2. The user might have more than one method that takes no parameters that is able to be called with a given `OnCompletionAction`, currently this would produce a `BareOverwriteError` in Beaker. Again, the work-around exists of calling `@external` instead, but it would be nicer and more intuitive to add a `bare` option to control this explicitly.
- The above Python methods have `bare: bool = False`. An alternative option would be to make this `bare: bool | None = None`, where `None` would retain the current behaviour of inspecting the method signature to see if it takes parameters or not.
- Remove `@bare_external`:
- Mostly unused, and doesn't provide the same options as the other decorators (e.g. `authorize`)
- Instead, we can replace the case of a single option being passed to it, with the equivalent named method: for example `@bare_external(opt_in=CallConfig.CALL)` becomes `@opt_in(bare=True)`
- For the multi-argument case: `@bare_external(no_op=CallConfig.CREATE, opt_in=CallConfig.CALL)` becomes `@external(method_config={"no_op": CallConfig.CREATE, "opt_in": CallConfig.CALL}, bare=True)`
* Add optional `name` option to all decorators, not just `@external`.
* Add `allow_call` and `allow_create` options to shortcut methods (except `@create` shortcut which should always allow `CallConfig.CREATE`).
* Remove `method_config` from `@create` shortcut - the default behaviour will remain unchanged, but any usages with `method_config` specified would be equivalent to just using `@external` directly.
* Add `override: bool | None = False` parameter.
- If `False` (the suggested default), an error will be raised if an ABI or Bare method would replace one already registered in the Application. For bare methods, this would be keyed on the `OnCompleteAction`, and for ABI methods should be based on the method signature (ie `ABIReturnSubroutine.method_signature()`). This is suggested as the default to prevent unexpected cases of overriding, especially when using blueprints/templates from the future Smart Contracts Library.
- If `True`, then an error will be raised if it _does not_ replace an already registered ABI or Bare method. This is similar to Java's `@Override` annotation, and can allow the user to be explicit and thus prevent unexpectedly _not_ replacing an existing method.
- If `None`, then methods will be overwritten if present, and no error will be raised if not already present. This option is here for maximum flexibility, but should perhaps be discouraged.
### (5) Beaker state refactor
Refactor of the `beaker.state` internal interfaces to simplify Beaker code base, make it easier to add new state wrappers, and to pave the way for future enhancements. This will have a side effect of allowing users to create their own state wrappers without having to modify `beaker` itself, although we recommend marking these interfaces as internal and subject to change - at least initially.
================================================
FILE: docs/architecture-decisions/2023-01-11_brew_install.md
================================================
# HomeBrew install strategy
- **Status**: Approved
- **Owner:** Daniel McGregor
- **Deciders**: Daniel McGregor, Rob Moore, John Woods, Alessandro Cappellato
- **Date created**: 2023-01-11
- **Date decided:** 2023-01-11
## Context
HomeBrew (brew) is a MacOS package manager, and is commonly used on MacOS systems to install applications and tools like AlgoKit. Brew offers two main installation methods.
* Formula - A source based install, this is typically recommended for open source and command line based applications. Formula can also be "bottled" to provide pre built packages for quick installs on supported MacOS platforms.
* Cask - A binary based install, this is typically recommended for closed source or GUI based applications.
Additionally there are also two options for how the brew install scripts could be distributed.
* Homebrew repository - This is the official repository for homebrew installs, and provides bottle support for all moderns MacOS platforms (MacOS 11+, Intel and ARM)
* Algorand hosted repository - A homebrew repository managed by Algorand Foundation.
Creating a HomeBrew Formula initially seemed like the best option for AlgoKit as it meets the [criteria](https://docs.brew.sh/Acceptable-Formulae) for a Formula. However there is a much higher maintenance cost with this approach as everything is built from source. We encountered an issue where one of our newly added python dependencies (pyclip) did not build from source [correctly](https://github.com/algorandfoundation/homebrew-tap/actions/runs/3884956190/jobs/6628201057#step:8:2871).
The alternative install method of a cask was then considered, and while AlgoKit does not meet the [criteria](https://docs.brew.sh/Acceptable-Casks) for a cask, it does remove the need for a source build on each MacOS platform and the additional maintenance overhead of the Formula approach.
## Requirements
- **Low maintenance**: The ongoing maintenance for supporting brew installs of AlgoKit should be low and not require manual effort for each release.
- **Fast and easy install experience**: The install experience for end users of AlgoKit should be easy and not require multiple complicated steps, additionally it should install in seconds, not minutes.
## Options
### Option 1: Formula on Official Homebrew Repo
This would be the preferred option except for the two notable issues. Firstly there is a high risk of ongoing maintenance overhead due to the need to support source building all the dependencies. Ideally this would not be an issue, but we have already hit a problem with a dependency (pyclip) early on in AlgoKit's development. Secondly inclusion into the official repo is subject to Homebrew's criteria, which AlgoKit won't reach until it is more mature.
**Pros**
* Most discoverable option for end users `brew install algokit`.
* Homebrew supports automatically bottling on all modern MacOS platforms (MacOS 11+ both Intel and ARM variants) meaning fast installs for users.
**Cons**
* Inclusion is subject to Homebrew's approval process, which algokit won't meet for now at least.
* Higher maintenance cost given the source build is more fragile and is likely to break and require investigation, plus build and install approach differs significantly from Chocolatey and pipx
* Longer build time on release
* Not possible to fully automate release, it relies on a Brew maintainer approving the pull request, so there's extra operational overhead to keep track of the release pull requests
### Option 2: Formula on Algorand Repo
This option is similar to Option 1, but allows Algorand to self publish the installer without meeting Homebrews formula criteria. However one issue is that Platform support is more limited, GitHub provides action runners for intel variants for MacOS 11 + 12, but [MacOS 13](https://github.com/github/roadmap/issues/620) and [ARM](https://github.com/github/roadmap/issues/528) support are not yet available. Additional platforms could be supported by using a combination of self-hosted runners and/or third party solutions. This means pre-built bottles aren't easy to build for ARM or MacOS 13 and installation on those environments will take 5+ minutes.
**Pros**
* Algorand Foundation has control over this process and it can be fully automated
* It's what we have already implemented and working today
* Easier to move to the official Brew core repository once AlgoKit is stable and demonstrably popular (thus meeting the constraints Brew place)
**Cons**
* Supporting all modern MacOS platforms may require use of a 3rd party service and more effort, in the meantime the installation experience on ARM and MacOS 13 is slow (5+ min install)
* Less discoverable install for end users `brew install algorandfoundation/algokit` (relies on them following documentation)
* Higher maintenance cost given the source build is more fragile and is likely to break and require investigation, plus build and install approach differs significantly from Chocolatey and pipx
* Longer build time on release
### Option 3: Cask on Algorand Repo
This option uses a cask which does not have the maintenance overhead of a formula, and can be hosted in an Algorand Foundation repo to get around the fact AlgoKit does not meet the normal cask criteria.
**Pros**
* Algorand Foundation has control over this process and it can be fully automated
* Lower maintenance cost as we do not need to support source builds of dependencies and it's consistent with how algokit cli is installed via Chocolatey and pipx
* Fast install for all MacOS platforms
* Fast build time on release
**Cons**
* Less discoverable install for end users `brew install algorandfoundation/algokit`
* AlgoKit does not meet the stated criteria for a cask and as such it would unlikely to be approved as a cask in the official Homebrew Repo if that was a desired future state
* More effort to implement a new way of installing via brew
### Option 4: Cask on Official Homebrew Repo
This is not a viable option as AlgoKit does not meet the criteria for an official cask.
## Preferred option
Option 1 because it would be the best end user experience.
## Selected option
Option 3 because Option 1 isn't possible right now and it's also a higher overhead to maintain. The install experience for end users is similar with option 3 (just with a bit more typing).
================================================
FILE: docs/architecture-decisions/2023-01-12_smart-contract-deployment.md
================================================
# Smart Contract Deployment
- **Status**: Approved
- **Owner:** Rob Moore
- **Deciders**: Anne Kenyon (Algorand Inc.), Alessandro Cappellato (Algorand Foundation), Fabrice Benhamouda (Algorand Foundation)
- **Date created**: 2023-01-12
- **Date decided:** 2023-02-04
- **Date updated**: 2023-02-04
## Context
AlgoKit will provide an end-to-end development and deployment experience that includes support for the end-to-end smart contract development lifecycle:
1. Development
1. **Write** smart contracts
2. **Transpile** smart contracts with development-time parameters to TEAL Templates
3. **Verify** the TEAL Templates maintain [output stability](../articles/output_stability.md) and any other static code quality checks
2. Deployment
1. **Substitute** deploy-time parameters into TEAL Templates to create final TEAL code
2. **Compile** the TEAL to create byte code using algod
3. **Deploy** the byte code to one or more Algorand networks (e.g. LocalNet, TestNet, MainNet) to create Deployed Application(s)
3. Runtime
1. **Validate** the deployed app via automated testing of the smart contracts to provide confidence in their correctness
2. **Call** deployed smart contract with runtime parameters to utilise it

The default Development experience that AlgoKit exposes will be via Beaker, however AlgoKit is modular and extensible so other tooling can also be used.
This decision record covers the different options and high level design for how AlgoKit aims to cover Deployment and Runtime.
## Requirements
- We support the different activities defined above under Deployment and Runtime: Substitute, Compile, Deploy, Validate and Call
- We support the ability to provide dev-time (e.g. static values that are passed into instances of a contract that get output), deploy-time (e.g. network specific addresses or IDs, etc.) and run-time (e.g. call arguments) values to smart contracts
- We support deploying smart contracts that have been output by any means (Beaker or otherwise) that creates TEAL templates (logic signature or approval & clear) and (for an app) an [ABI](https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0004.md) and an [app spec](https://github.com/algorandfoundation/ARCs/pull/150)
- We support calling smart contracts with multiple languages / programming ecosystems (with AlgoKit providing Python and TypeScript implementations)
- We support generating type-safe smart contract clients based on the smart contract definition
- We support deploying smart contracts to AlgoKit LocalNet, TestNet and Mainnet
- We support deploying manually and via continuous deployment pipeline
## Principles
- [AlgoKit Guiding Principles](../../docs/algokit.md#Guiding-Principles) - specifically:
- **Cohesive developer tool suite**
- **Seamless onramp**
- **Secure by default**
- **Modular components**
- **Continuous Delivery** - support the ability for software developers to adopt a [Continuous Delivery](https://continuousdelivery.com/) approach to reduce risk, namely by supporting:
- [Deployment pipelines](https://continuousdelivery.com/implementing/patterns/#the-deployment-pipeline) that build once and deploy to similar environments (that bit is nicely facilitated by the blockchain!) consistently
- [Automated testing](https://continuousdelivery.com/implementing/architecture/)
- **Facilitate correctness** - smart contract development is higher risk than many other types of development, standard practice involves deploying an immutable contract that must be right from the beginning; AlgoKit should help developers fall into the pit of success and produce higher quality output that is more likely to be correct while having flexibility to opt-in to other behaviours as needed
## Decisions and design
The following design decisions need to be considered, and are discussed below:
- TEAL Templates and deploy-time parameter substitution
- Generated / Type-safe clients
- Deployment and development decoupling
- Upgradeable and deletable contracts
- Mnemonic storage and retrieval
- Contract identification
- Automated vs manual deployments
- Output stability testing
- Validation testing
### TEAL Templates and deploy-time parameter substitution
The above diagram includes a TEAL Templates step separate from the final TEAL that gets deployed. A fair question may be to ask if this extra step is really needed?
There are two key considerations to help answer this question:
1. Should development and deployment be decoupled from each other (i.e. happen at a separate time)?
- If we couple development and deployment together then it necessitates that at deploy time you have the same programming environment running that's needed for the smart contract development. So, if you (for instance) were building a smart contract in Python using PyTEAL or Beaker, but deploying the smart contract using TypeScript that means you need a deployment environment that supports both Node.js _and_ Python. This makes it harder to follow the Modular components principle.
- If development and deployment are coupled together it rules out using Continuous Delivery since it forces you to build the deployment artifact at the same time as you are deploying it. This means you miss out on the confidence and risk benefit of knowing that when you are deploying to (say) MainNet you are deploying the same artifact that was successfully deployed and tested on (say) TestNet and AlgoKit LocalNet (let alone passes any other checks you decide to run as part of Continuous Integration like automated tests, static code analysis, etc.).
- If development and deployment are coupled together it means we aren't perform an [output stability](../articles/output_stability.md) test so we don't get notified if we make a change that results in a different smart contract (which may then affect things like hashes for smart contract auditing review comparison, unintended introduction of security vulnerabilities, etc.).
- Based on all of this, decoupling development and deployment is a very helpful thing for a smart contract and aligns with all of the above-stated principles more closely.
2. Do we need to provide deploy-time parameters?
- When deploying a smart contract to a network (say MainNet), there are likely to be certain parameters that will be different from deploying to a different network (say TestNet), e.g.:
- If you are calling another smart contract, say an Oracle, then the application ID will change between networks.
- If you have standard prices you may decide to make them smaller on the TestNet contract given it's much harder to get access to a reasonable number of ALGOs on TestNet (without knowing the right people, or painfully clicking repeatedly on a CAPTCHA on one of the dispensers repeatedly to get 10 ALGOs at a time).
- If you are providing admin permissions for a statically defined account (hardcoded for security reasons) then it's likely you would use a different account address for MainNet vs TestNet so you don't expose a production mnemonic in test infrastructure.
- etc.
- Based on all of this, being able to provide deploy-time parameters is an important feature.
Because it makes sense to decouple development and deployment, but also important to be able to provide deploy-time parameters, that means it's necessary to support deploy-time parameter substitution and thus: TEAL that is output from the development stage should be considered a template that may have deploy-time substitutions performed on it.
Thankfully, this is supported as a first-class concept in PyTEAL via the [`Tmpl` feature](https://pyteal.readthedocs.io/en/stable/api.html?highlight=TMPL#pyteal.Tmpl) and could be similarly mimicked in any other TEAL transpilation language.
### Generated / Type-safe clients
Smart contract development results in an on-chain program that can be invoked from a "client". The development of the client itself has two broad options:
1. Hand-code the client for a given smart contract using basic primitives (such as being able to issue a smart contract call of a certain type with an array of arguments)
2. Generate the client based on the smart contract definition and then call methods on the client that correspond to methods in the smart contract
The second option, while more complex, results in an easier, faster, and safer developer experience:
- You don't need to understand as much about the underlying blockchain calls since they will be constructed for you so the frontends (e.g. dApps) don't have to be constructed by smart contract / web3 experts
- You can have type-safe / intellisensed client SDKs, in multiple programming languages with no extra effort beyond writing the smart contract - making the developer experience much easier and meeting devs where they are
- Using a typed client means that smart contract calls (against the same version of the smart contract the client was generated from) will always be correct and should succeed so the client code is more likely to be correct and can be statically checked for correctness
Because of this, the desired experience for AlgoKit is to encourage and directly support a generated / type-safe client experience. The intention is to drive this from a combination of [ARC-0004](https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0004.md) and [ARC-0032](https://github.com/algorandfoundation/ARCs/pull/150).
To illustrate what the end result looks like consider the following Beaker smart contract:
```python
from beaker.application import Application
from beaker.decorators import Authorize, delete, external
from pyteal import Approve, Bytes, Concat, Expr, Global
from pyteal.ast import abi
class HelloWorld(Application):
@external(read_only=True)
def hello(self, name: abi.String, *, output: abi.String) -> Expr:
return output.set(Concat(Bytes("Hello, "), name.get()))
@delete(authorize=Authorize.only(Global.creator_address()))
def delete(self) -> Expr:
return Approve()
```
Let's say you wanted to deploy and interact with that smart contract using TypeScript; if you didn't have a client generated from that code then you would need to construct the method call:
```typescript
// Assume `appId`, `algod` and `senderAccount` are already in scope
const composer = new AtomicTransactionComposer();
composer.addMethodCall({
appID: appId,
method: new ABIMethod({
name: "hello",
args: [{ name: "name", type: "string" }],
returns: { type: "string" },
}), // Not type-safe, no intellisense
sender: senderAccount.addr,
signer: makeBasicAccountTransactionSigner(senderAccount),
suggestedParams: await algod.getTransactionParams().do(),
methodArgs: ["World!"], // Not type-safe, no intellisense
});
const result = await composer.execute(algod, 5);
console.log(result.methodResults[0].returnValue); // Hello, World!
```
If instead you generated a client you could having something like this, which gives you intellisense and is type-safe:
```typescript
// Assume `appId`, `algod` and `senderAccount` are already in scope
// HelloWorldAppClient is generated from the smart contract definition (ABI json and app spec json)
const app = new HelloWorldAppClient(appId, algod, senderAccount);
const result = app.hello({ name: "World!" }); // Type-safe and intellisense
console.log(result); // Hello, World!
```
To be fair, you could have a middle-ground and load the ABI json to populate the `method` parameter of the `addMethodCall` call, but the `methodArgs` are still problematic and there is still no intellisense.
The suggested implementation for AlgoKit v1 is to provide a basic type-safe TypeScript client (leveraging either the MakerX TypeScript generator or [beaker-ts](https://github.com/algorand-devrel/beaker-ts)) and leave Python with the semi-typed implementation that Beaker currently exposes (with implementing a fully typed Python client as a future implementation effort).
### Deployment and development decoupling
As discussed above, decoupling deployment and development of smart contracts is a useful technique.
One of the advantages is it allows you to use separate programming languages for the writing of a smart contract and the deployment and automated testing of it. Separate, but related, it also makes it easier to generate type-safe clients (per the previous point) because there is an intermediate output from the development stage that can then be used to generate a client, in a separate (or the same) programming language, before using that client to then deploy and interact with the smart contract (for an end user experience, a programmatic interaction or an automated test).
This helps us follow the "Meet devs where they are" principle and provide optionality for developers to select the programming environment they are most comfortable with for writing clients and automated tests.
### Upgradeable and deletable contracts
Smart contracts are a powerful capability that can be used for anything from locking billions of dollars of value to implementing the mechanics of a game's state storage. This means there are different risk profiles, rigour and functionality evolution characteristics in different circumstances.
These different risk profiles have an impact on the functionality that is exposed within a smart contract. Two key examples of this are:
- **Upgradeable smart contracts** - Whether or not a smart contract can be updated inline (and keep existing state and app ID / address characteristics) or they are immutable
- **Deletable smart contracts** - Whether or not a smart contract can be deleted or is permanent
Immutability and permanence are useful architectural properties in certain circumstances (similarly mutability and impermanence in others). For example:
- If you have a smart contract that locks billions of dollars of value, then allowing that smart contract to be upgradeable allows for the manager of the smart contract to make a change that lets them steal the value.
- If you have a smart contract that provides an Oracle service (say for betting odds), then allowing that smart contract to be deletable could break many other applications that are hard-coded to call that Oracle contract's app ID.
- If you have a smart contract that runs the mechanics of a game engine the players of said game may have a reasonable expectation that the game engine is evolved and enhanced over time, but they don't want to lose their state (so upgrading the smart contract is useful).
- If you have a smart contract that handles a one-off trade of value across a cross-chain bridge then it makes sense to delete it (only once trade has been concluded) to remove noise, potential confusion and operational overhead for the operators of said bridge.
All 4 scenarios above provide different situations where immutability and permanence are desired or undesired. If you choose incorrectly for your circumstance, particularly for high-risk scenarios, the consequences could be major.
If a contract is immutable, it does limit the ability to evolve the functionality over time based on user feedback and also discourages use of best practice software delivery techniques that encourage evolution and rapid deployment like Continuous Delivery.
Another consideration in favour of immutability is smart contract auditing. If a smart contract is audited for security, but then the smart contract is upgradeable or is changed between when the audit occurred and when the contract was deployed to MainNet then the smart contract audit is somewhat invalidated and certainly any hashes that are provided of the smart contract code in an audit report will no longer match.
There are techniques that can be used to allow for immutable smart contracts, but let them be evolved somewhat:
- You could release a new version of a smart contract and include an ability for that smart contract to communicate to/from the existing smart contract to migrate state.
- You could ensure that clients can dynamically find the latest smart contract so the application ID / address doesn't need to be hardcoded and the smart contract remains addressable.
- This could be done via some sort of on-chain or off-chain lookup, and/or by encoding information into the creation transaction note of the smart contract app.
- You could limit MainNet releases to major upgrades that happen infrequently and let users opt-in to whether or not they use the new version or not, and having a set of calls the user can sign to migrate their state/value from one contract to the next.
Lastly, it's worth noting that having fast development feedback loops during development and testing of smart contracts is likely a very useful feature to improve the development experience and speed. For this reason, allowing contracts to be upgraded or at the very least deleted (and then recreated) is likely very useful, but potentially when deployed to MainNet a switch could be made to disallow upgrading / deleting (as relevant).
The goal of AlgoKit is to create a development experience that is productive and easy, but also one that is secure by default and helps developers fall into the pit of success. For that reason, and given the consequences of getting this wrong the suggested approach AlgoKit takes is:
- All provided smart contract templates are by default immutable
- An immutability automated test is included by default to ensure that smart contracts can't be upgraded by the contract creator (this would have to be deleted by a developer, who is then opting in to the consequences of that)
- All provided smart contract templates are by default permanent when deployed to MainNet, but deletable elsewhere to facilitate an iterative development experience
- Client code will include mechanisms to dynamically find deployed applications in LocalNet and TestNet environments to support delete/recreate flows and improve the developer experience
- MainNet deployments will immediately (i.e. before any usage occurs) check that smart contracts are not upgradeable by the creator account by default (with an explicit opt-out option available for smart contracts that are meant to be upgradeable, which in turn will issue a warning to the developer to explain the implications)
- MainNet deployments will immediately (i.e. before any usage occurs) check that smart contracts are not deletable by the creator account by default (with an explicit opt-out option available for smart contracts that are meant to be deletable, which in turn will issue a warning to the developer to explain the implications)
### Mnemonic storage and retrieval
When deploying and interacting with a smart contract, you need to have access to the private key of an account. This is a secret and must be handled with care, as exposing a private key can be disastrous, and while [rekeying](https://developer.algorand.org/docs/get-details/accounts/rekey/) is possible if it's not done fast enough you can still lose assets, be victim to malicious calls and experience a painful user experience going forward (wallet support for rekeyed accounts is limited).
Another consideration is the network being deployed to / called. If you are interacting with the LocalNet network then mnemonics are all, but meaningless since you can simply reset the LocalNet and regenerate new accounts on the fly (and fund them with essentially unlimited ALGOs). If you are interacting with TestNet then mnemonics may hold TestNet ALGOs, which while difficult to get in large numbers, are more an inconvenience than a serious commercial problem to lose.
Finally, when interacting with LocalNet to create a smooth developer experience it's ideal to automatically generate and fund any accounts that are being used so the developer doesn't have to manually do this every time the LocalNet is reset. Even better, it's ideal if this can be done in a way that idempotently gets a consistently private key for a given "named account" so that subsequent calls use the same account (mimicking what happens in TestNet or MainNet when using a particular private key for a given "named account").
Given all of this, the suggested approach that AlgoKit takes is:
- LocalNet accounts are by default automatically and idempotently generated against a named account by using a named wallet via [Kmd](https://developer.algorand.org/docs/clis/kmd/) and are automatically funded using the LocalNet faucet account (the private key for which is automatically retrieved using Kmd).
- Where they are needed mnemonics will be provided using environment variables to follow [twelve factor app conventions](https://12factor.net/config), this is an industry standard approach to handling secrets and is easy to support cross-platform and cross-programming language as well as using encrypted secrets on CI/CD pipelines.
- An option will be provided for deployments that allows for deployments using ephemeral accounts that then get rekeyed to a separate, known [break-glass](https://www.beyondtrust.com/blog/entry/provide-security-privileged-accounts-with-break-glass-process) account (the private key of which is not available to the deploying process) will be provided to allow for developers to deploy using a break-glass setup.
- A `DISPENSER_MNEMONIC` environment variable will be expected when deploying to non-LocalNet environments, and will be encouraged to be a separate account just used for that purpose to limit [blast radius](https://www.lepide.com/blog/what-is-a-blast-radius-in-data-security-terms/), so that funds needed for deployments or calls can be automatically provided by convention, including for ephemeral accounts.
- The Algokit CLI will allow for mnemonics to be provided to it for a given project, which will get stored in a encrypted form within the .gitignore'd `.env` file with a project-specific random encryption key stored on that machine. This prevents cursory exploitation and accidental exposure through screen-sharing, but won't protect users with an exploited machine from having them exposed. For this reason, developers will be discouraged from storing MainNet mnemonics in that way and will need to acknowledge that risk.
- AlgoKit will provide example CI/CD templates that illustrate how to construct a deployment pipeline that includes MainNet deployments using secret storage for mnemonics so developers won't need to handle MainNet mnemonics on their local machine.
### Contract identification
Being able to identify an existing deployed instance of a given smart contract is very useful:
- It avoids the need to hardcode application IDs
- It makes things easier to automate, including automated deployments and testing of smart contracts and the apps that call them
- It allows the deployer of a smart contract to detect if that smart contract is already deployed and if so handle it appropriately (e.g. do nothing vs upgrade vs delete and create vs leave alone and create) depending on whether that smart contract is immutable and/or permanent and the network being deployed to (e.g. LocalNet vs TestNet vs MainNet)
As soon as a contract is not immutable, or is immutable and not permanent then the application ID of the smart contract for a given network will change over time. And, if a smart contract is immutable and permanent then net new versions may still be deployed, or at the very least the contract will change across networks (e.g. LocalNet vs TestNet vs MainNet). Because of this it's important to support dynamic resolution of application IDs.
It's important to consider whether the smart contract needs to be resolved on-chain or off-chain.
Resolving on-chain is harder to achieve dynamically, but there are some patterns that can be used, e.g.:
- Storing the application ID in (e.g. Global) state and providing a creator-only ABI method that can be called as part of deployment of the dependant contract to update the stored application ID.
- [Lookup/registry contract](https://research.csiro.au/blockchainpatterns/general-patterns/contract-structural-patterns/contract-registry/) that returns the ID of a named contract and that lookup contract allows said ID to be updated.
- [Proxy contract](https://blog.openzeppelin.com/proxy-patterns/) that mirrors the interface of the parent contract but delegates calls to an underlying contract whose ID can be updated.
- [Other patterns](https://ethereum.org/en/developers/docs/smart-contracts/upgrading/#what-is-a-smart-contract-upgrade).
Resolving off-chain can be done through a variety of ways, e.g.:
- Create a contract discovery service API that allows new contracts to be registered by API call after being deployed.
- If the contract creator account is always known (i.e. ephemeral creator accounts aren't being used) then it's possible to identify a contract by name by encoding a payload into the application creation transaction note and then using the indexer to find the application creation transactions for a given account and working backwards to find the relevant application ID.
- If the contract creator account is always known (i.e. ephemeral creator accounts aren't being used) then it's possible to identify a contract by name by encoding the name in to one of the [application params](https://developer.algorand.org/docs/rest-apis/algod/v2/#applicationparams) (e.g. approval program or using a global state variable) and looking up the `created-apps` property when [retrieving an account via algod](https://developer.algorand.org/docs/rest-apis/algod/v2/#account).
- Create a contract discovery service API that scans the blockchain transactions ([example](https://developer.algorand.org/articles/developer-preview-of-conduit-a-new-way-to-access-algorand-chain-data/)) to automatically maintain a record of smart contract IDs.
- Use CI/CD variables ([example](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter)) to propagate the deployed app ID to the configuration on the deployment of the client (assuming the same pipeline is used for deployment of smart contract and client(s)).
- Manually set the application ID via the CI/CD pipeline of the clients with environment-specific values (that are passed in via environment variables) and change them to reflect any changes to the smart contracts (note: this isn't sustainable for frequently changing contracts, but is a simple method for infrequently changing contracts).
In order to provide the simplest implementation possible to handle this complexity, AlgoKit v1 will:
- Add payloads to application creation transactions to allow them to be resolved by name for a known creator account using the indexer.
- Allow application IDs to be resolved by name using environment variables for situations where a developer is using ephemeral creator accounts.
- On-chain resolution will be left for developers to implement (likely by hardcoding or Global-state-based configurable application IDs).
More sophisticated options could potentially by implemented in the future.
### Automated vs manual deployments
In order to support Continuous Delivery for smart contracts there is a need to support automated deployments of smart contracts via deployment pipeline.
This presents a number of challenges to solve for though:
- The deployment pipeline needs to determine if the smart contract already exists or not in the network being deployed to
- Depending on whether the contract is immutable and/or permanent and if it already exists or not in the network being deployed to, the pipeline needs to handle upgrade, deletion and/or creation of the contract (and this behaviour may need to be switched depending on the network being deployed to)
- In order to protect integrity of MainNet contracts the deployment process should probably have some safeguards for MainNet that by default prevent destructive operations and require some kind of human opt-in to perform those operations
- Exposing private key mnemonics for MainNet necessitates they are "hot wallets" which may be undesirable for privileged accounts responsible for high value smart contracts (e.g. smart contracts locking $m's or $b's), alternatively low privilege scenarios may benefit from (encrypted secret) mnemonic storage to improve developer experience and operational overhead
- Supporting cold storage wallets for high privilege accounts, without resorting the manual deployments (which present their own risks) is tricky
- There are many deployment pipeline technologies available on the market and providing support for many of them is an impractical amount of effort.
- Should manual deployments be supported as well as automated deployments to make it easier for developers to perform ad hoc deployments (e.g. when quickly testing concepts, or doing a one-off deployment) and improve developer flexibility
The proposed AlgoKit implementation for v1 that provides a balance of flexibility vs implementation effort, while aligning to the principles is as follows:
- A GitHub Actions implementation is provided in the default template, since GitHub is a highly capable and prevalent option and is free for Open Source and basic private usage (the community can contribute other CI/CD implementations if desired)
- The "Contract identification" v1 implementation suggested above is followed to determine if a contract already exists for the network being deployed to
- The "Mnemonic storage and retrieval" v1 implementation suggested above is followed to facilitate a secure, but flexible implementation for how to handle private keys for ad hoc manual deployments and CI/CD pipelines
- Cold wallets won't be supported for now, but is recommended as a future exploration, in the meantime that scenario can be implemented by using the rekey technique mentioned in "Mnemonic storage and retrieval"
### Output stability testing
Ensuring [output stability](../articles/output_stability.md) is useful for smart contract development. It helps ensure that you can refactor code without making an inadvertent change to the smart contract, ensure that a smart contract output isn't changed from any output that is audited, and ensure that there is a clear mechanism to manually review the smart contract output before it's (re-)deployed.
There are three broad approaches that could be taken by AlgoKit to help facilitate output stability testing:
1. Include documentation that recommends this kind of testing and provides examples for how to implement it
2. Include a Git-based approach in default AlgoKit template(s), that requires you to stage changes to the existing smart contract output (per decoupling development and deployment) using normal Git workflows otherwise the test will fail (meaning it will fail locally and on continuous integration pipeline)
3. Include an [approval-testing](https://approvaltests.com/) based approach in default AlgoKit template(s), that results in an approved TEAL file that is committed
A documentation-only approach strays away from the "Facilitate correctness" and "Secure by default" principles where we want to help developers fall into the pit of success by default.
Approval testing is a handy technique that is established in the industry, but in this case results in the TEAL output being committed twice, which is a confusing duplication. Furthermore, by ensuring the automated test is against the output that will get deployed it ensures there is a coherence between the TEAL being tested and the TEAL being deployed.
With this in mind, the proposal is for AlgoKit to include a Git-based output stability test by default, but per the "Modular components" principle there is a template option to exclude those tests.
### Validation testing
In order to provide confidence in the correctness of a smart contract it's important to exercise testing to validate the smart contract operates as expected.
There are a few possible approaches that could be taken by AlgoKit to help facilitate this:
1. **Documentation** - Include documentation that recommends this kind of testing and provides examples for how to implement it
2. **Manual testing** - Encourage a manual testing approach using (for example) the App Lab in Lora, by providing an AlgoKit CLI command that sends the user there along with the ABI definition and contract ID resulting in a manual testing experience for the deployed contract with low friction
3. **Automated integration tests** - Facilitate automated testing by issuing real transactions against a LocalNet and/or TestNet network
4. **Automated dry run tests** - Facilitate automated testing using the [Dry Run endpoint](https://developer.algorand.org/docs/rest-apis/algod/v2/#post-v2tealdryrun) to simulate what would happen when executing the contract under certain scenarios (e.g. [Graviton](https://github.com/algorand/graviton/blob/main/graviton/README.md))
5. **TEAL emulator** - Facilitate automated testing against a TEAL emulator (e.g. [Algo Builder Runtime](https://algobuilder.dev/api/runtime/index.html))
#### Documentation
**Pros**
- Least effort to implement
**Cons**
- Doesn't follow the principles of "Seamless onramp", "Continuous Delivery" or "Facilitate correctness"
- Easy for users to miss
#### Manual testing
**Pros**
- Low effort to implement
- Facilitates a great manual testing experience for exploratory testing or situations where you want/need to manual test a contract in addition to automated testing
**Cons**
- Doesn't follow the principle of "Continuous Delivery" or "Facilitate correctness"
- Doesn't provide regression coverage as the smart contract evolves during development
#### Automated integration tests
**Pros**
- Prior art can be leveraged from MakerX (TypeScript) and [algopytest](https://github.com/DamianB-BitFlipper/algopytest) (Python), both of which provide abstractions to make it easier to produce tests that avoid intermittent failures
- High degree of confidence - exercising the smart contract in a similar way to real users means we have a high degree of confidence in the validation
- Good regression coverage
**Cons**
- This type of testing is naturally slower making it impractical to provide combinatorial coverage (relevant: [first 5 minutes of the Microtesting presentation Rob and Matt delivered in 2016](https://www.youtube.com/watch?v=pls1Vk_bw_Y))
- This type of testing can be hard to make reliable (it's easy to get intermittent timing errors if you aren't careful)
#### Automated dry run tests
**Pros**
- Faster test runs allows for testing a larger proportion of combinatorial coverage and adopting approaches like property-based testing to provide higher degree of confidence
- Allows for validation of additional properties like opcode usage etc.
**Cons**
- Verbose / unfamiliar test setup to specify the desired state of the blockchain before the dry run (which won't be shareable code with any clients like dApps since it will be test specific)
- Highly likely there will be a coherence gap between test setup and real-life call since
- High effort to implement, particularly cross-platform since there isn't existing TypeScript-based prior art
- Dry run endpoint is being replaced with a new simulate endpoint, but there isn't much available about what that endpoint will look like yet so need to decide between implementing something that is
#### TEAL emulator
**Pros**
- Likely to be the best speed properties allowing for full combinatorial coverage
**Cons**
- Requires implementation and/or maintenance of a TEAL emulator, which would duplicate effort being put in by Algorand Inc. on the simulate endpoint
- Algo Builder implementation, while being an existing solution and OpenSource requires TypeScript (so is harder to use for Python testing) and also requires a highly bespoke syntax to interact with it that won't allow for easy interoperability with AlgoKit or other things, thus not confirming with "Modular components" principle)
#### Selected option
Based on all of this the suggested option for AlgoKit v1 is **Automated integration tests** since it conforms to the principles well, has prior art across TypeScript and Python that can be utilised and provides developers with a lot of confidence.
Post v1, it's recommended that Lora integration for exploratory testing and Graviton (or similar) support should be explored to provide a range of options to empower developers with a full suite of techniques they can use.
================================================
FILE: docs/architecture-decisions/2023-06-06_frontend-templates.md
================================================
# Frontend Templates
- **Status**: Approved
- **Owner:** Altynbek Orumbayev
- **Deciders**: Rob Moore, Daniel McGregor, Adam Chidlow
- **Date created**: 2023-06-06
- **Date decided:** 2023-06-09
- **Date updated**: 2023-06-08
## Context
AlgoKit v2 aims provide an end-to-end development and deployment experience that includes support for the end-to-end smart contract and dApp development lifecycle. With the release of the typed clients feature - developers are now able to reduce the time it takes to fully integrate the interactions between the contract and the frontend components powering the end-to-end dapp user experience. Hence, as a logical continuation, the following Architecture Decision Record aims to expand on the current capabilities of AlgoKit to support the `frontend` templates, an [AlgoKit Principles](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/algokit.md#guiding-principles) compliant approach towards simplifying integrations of smart contracts with the dApp frontend components.
## Requirements
### Independent Frontend Templates
1. Create official frontend template that complies with AlgoKit's principles of modularity, maintainability, and flexibility while also serving as a reference for template builders.
2. Expand algokit functionality to provide a clear process for developers to link frontend templates with the typed clients generated by backend templates.
3. Design frontend templates such that backend and frontend have no dependencies on each other, ensuring high modularity.
### End-to-End Starter Repositories
1. Establish a starter repository that allows developers to bootstrap end-to-end dApp projects within a single command, while also serving as an example for template builders on how to efficiently couple their backend and frontend templates.
2. Implement a bundling process for backend and frontend templates in the starter repositories that reduce code duplication and maintenance overhead.
3. Develop deployment pipelines for frontend components inside end-to-end starter repository that supports TestNet, and MainNet deployments to hosting providers of choice (Netlify, Vercel and etc to be decided).
4. Ensure that the end-to-end starter repository supports both manual deployment and deployment via a continuous deployment pipeline.
## Principles
- **Modularity**: The dApp templating feature should follow guiding AlgoKit principles and expand on approaches already utilized in existing smart contract templates feature. This implies that giving developers flexibility to mix and match different `smart contract` templates with `frontend` templates should serve as key consideration.
- **Maintainability**: The dApp templating feature should be easy to maintain and extend. This implies that the feature should be implemented in a way that allows for easy addition of new templates and/or modification of existing ones as the complexity and variety of templates scale.
- **Seamless onramp**: The dApp templating feature should provide a seamless onramp for developers to get started with dApp development. This implies that the feature should provide a simple and intuitive way to get started with dApp development and deployment. Providing developers a choice on whether they want more flexibility or rely on default recommended practices.
All of the aforementioned requirements should be met in a way that is consistent with the guiding principles of AlgoKit or attempt to find a balanced trade of between the principles that satisfies the requirements. Refer to [AlgoKit Guiding Principles](../../docs/algokit.md#Guiding-Principles) for detailed reference on the principles.
## Explored options
Enhancing AlgoKit's templating capabilities involves a notable shift from managing individual templates to co-locating multiple templates or projects together. This is a marked increase in complexity that requires careful consideration of the varying trade-offs between different approaches. The subsequent sections explore these options and their associated trade-offs, providing a concise overview of this new challenge and our proposed solutions.
### Option 1: Monolithic template
This option suggests that the frontend and backend templates should be bundled together in a single repository. This approach aims to simplify the maintenance of the templates by reducing the number of repositories that need to be maintained. Both official and community templates should be build on top of this approach where frontend is always tailored for specific needs of the smart contracts that are being used.
Drawbacks:
- **Lack of flexibility**: The monorepo approach does not allow developers to choose their preferred frontend technology stack. This is because the frontend is tightly coupled with the backend and the two cannot be separated. This is a major drawback as it limits the flexibility of the templates and does not allow developers to choose their preferred frontend technology stack.
- **Increased maintenance overhead**: Despite monorepos generally being easier to maintain and collaborate on, this approach has risks of increasing the maintenance overhead as it forces for code duplication when creating new template variations.
### Option 2: Separate individual frontend templates and official full-stack starter templates as an end-to-end reference
This option suggests that the frontend and backend templates should be maintained in separate repositories. This approach aims to provide developers with the flexibility to choose their preferred frontend technology stack. It also allows the templates to be maintained independently, thereby reducing the maintenance overhead.
Drawbacks:
- **Compatibility overhead**: The separate repositories approach increases the maintenance overhead as it requires the templates to be updated independently. This can lead to issues with compatibility between the templates and the typed clients.
- **Lack of guidance**: The separate repositories approach does not provide developers with a clear process for linking the frontend templates with the typed clients generated by the backend templates. This can lead to confusion and issues with the integration of the templates.
The outlined drawbacks can be mitigated by providing a clear process or reference for template builders on how to link various combinations of frontend and backend templates. The compatibility overhead can be mitigated by ensuring that backend and frontend modules are self sufficient and completely decoupled from each other. This will ensure that the templates can be updated independently. The implementation proposal below is a detailed exploration of this approach and ways to mitigate the drawbacks.
### Implementation proposal for Option 2
The proposal consists of 2 main parts. On a high level, the ideas revolve around giving developers a choice on how they want to couple AlgoKit backend and frontend templates if they like to use custom templates. The other is focused on providing an official full-stack template that bundles both backend and frontend templates together, while also serving as an example for template builders on how to efficiently couple any combination of templates.
The addendums to the proposal also explores orthogonal ideas that can further improve the CLI tooling itself by providing a way for any existing non web-3 frontend project be converted into a full-stack dApp with minimal efforts. Lastly, it expands on improving incentives for developers to build and maintain their own templates.
---
### Part 1. Independent frontend templates
> TLDR: Independent frontend templates will be created to provide developers with a highly customizable dApp starter project, built on AlgoKit's principles of modularity, maintainability, and flexibility. The templates will also serve as a reference for template builders.
The following aims to provide a seamless onramp for developers to get started with highly customizable dApp starter projects. The idea is to create a set of separate official frontend template repositories to serve as:
a) A reference for template builders on how to create standalone frontend templates that can be then further coupled with any backend template.
b) Expand on AlgoKit principles of modularity, maintainability and flexibility by giving developers a choice of preferred technological stack.
The official standalone frontend templates can be build by reusing already established best practices and templates from official backend repositories and by continuing reliance on `copier` for template automation. Another important consideration to keep in mind is that with the introduction of frontend templates we need to establish a clear separation of concerns between the backend and frontend templates to ensure modularity.

As demonstrated on the diagram above, the only glue connecting the backend and frontend is the generated typed client. Neither backend or frontend templates should be concerned with the other but instead provide modular interfaces that clearly indicate to developers on how to integrate the two. From a perspective of a backend template, the typed client shall be seen as a static asset that can be reused by any frontend template. Frontend templates on the other hand are mostly standard web projects with an additional layer of utilities that optionally allow them to be integrated with typed clients produced by backend templates.
#### Higher level overview
The main scenario to support for this part is to allow developers to use official starter templates to bootstrap end to end dApp projects.

As demonstrated above the dev experience will consist of executing an `algokit init` command for the preferred backends and frontends.
It gives user a choice and responsibility to then decide how to integrate the two components depending on their project needs. To improve this however, we should **additionally introduce a new utility** that will serve as a tool to automate linking with the typed client that backend templates will be generating. Implementation specific details can be discussed separately is it goes out of scope of this Architecture Decision Record.
---
### Part 2. End-to-end starter repositories
> TLDR: End-to-end starter repositories are designed to offer developers an official starter template for bootstrapping dApp projects. This is achieved by efficiently bundling backend and frontend templates to facilitate easy maintenance and smooth onboarding.
#### Higher level overview
The main scenario to support for this part is to allow developers to use official starter templates to bootstrap end to end dApp projects.

As demonstrated above the user experience will consist of a single execution of `algokit init` command pointed at official full-stack template repository. The full stack templates are responsible for bundling both backend and frontend templates together and providing a seamless onramp for developers to get started with dApp development. The way repositories are bundled should be easy to maintain and should not duplicate individual backend and frontend repositories to avoid redundant maintenance, instead it should expand on metatemplating capabilities of `copier` to allow for efficient reuse of existing standalone backend/frontend templates.
### Addendum 1. Converting _ANY_ frontend projects into dApps.
> TLDR: The approach aims to enhance the algokit-cli codebase's adaptability, enabling easy transformation of existing frontend projects into web3 dApps.
This orthogonal approach proposes to improve capabilities of the algokit-cli codebase by making it adaptable to various frontend stacks to allow anyone to easily convert their existing frontend projects into web3 dApps.
The implementation specific details will consist of deriving a set of bare minimum requirements for such feature to scan and understand the structure of frontend where algokit is being embedded and performing necessary modifications to project's files. A detailed discussion can be held in a scope separate from this Architecture Decision Record.
> This approach can be explored and maintained without overlapping with main proposal on frontend templates.
### Addendum 2. Website for choosing preferred frontend and backend repositories.
> TLDR: The approach proposes a website to enhance the discoverability of official and community-based algokit templates, thereby incentivizing template builders to create and maintain their own templates.
This orthogonal approach proposes to improve discoverability of official and community based algokit templates by providing a simple static website. The website can consist of minimalistic UI components for picking preferred backend, frontend and then a `Generate` button that will output copyable algokit CLI commands to spin up a project with the selected templates.
As a specific example, the website can be hosted on [AwesomeAlgo](https://awesomealgo.com) website, thus ensuring that this is an open-source community maintained entry-point for discovering and using algokit templates. Removing the need and maintenance overhead on our teams to maintain it as official resource.
Lastly, community template builders will get a platform to increase discoverability of their templates and further incentivize them to build and maintain them. While developers using the templates can support creators of templates by donating to their projects (a simple tipping mechanism for Algo and ASAs can be embedded into the website) or by contributing to the templates themselves.
> This approach can be explored and maintained without overlapping with main proposal on frontend templates.
---
## Final decision
After several review rounds team reached a conclusion to expand on [Option 2](#option-2-separate-individual-frontend-templates-and-official-full-stack-starter-templates-as-an-end-to-end-reference) and respective [implementation proposal](#implementation-proposal-for-option-2) given better alignment with AlgoKit design principles such as flexibility and modularity. Hence, the following proposal is further exploration of ideas based on this approach and propose solution to mitigate the potential drawbacks and risks outlined.
## Open questions
- Python typed clients are not going to be too relevant for scenarios where they need to be integrated with frontends given that in majority of cases a developer would prefer a TS typed client. Hence, how do we ensure that user gets a clear information and indication on when to use Python typed clients vs TS typed clients?
- `Answer: This is a fair comment, but to my mind it's a clear dilineation in that it's dependant on what language you are using. While there are Python website libraries, we aren't using them we will use JavaScript (TypeScript).`
- Would we want to introduce a notion of non smart contract based backend templates that can be used to plug in the python typed clients and spin up servers that can be used to build APIs that interact with the smart contracts?
- `Answer: This is definitely out of scope of dApp stuff.`
## Next steps
After the final decision is made, the action items necessary to implement the described proposal can be outlined as follows:
1. **Design and Development of Independent Frontend Template**: This involves selecting appropriate technology stacks and building out the templates. The template should be able to work with the generated typed client from the backend and will be used as a dependency for end-to-end starter repository.
2. **Development of End-to-End Starter Repository**: This involves building comprehensive template that bundles both frontend and backend components. The template should be designed to be easy to maintain and should leverage the metatemplating capabilities of `copier` for efficient reuse of existing standalone templates.
3. **Integration and Testing**: Ensure proper integration between frontend and backend templates. Also, extensive testing should be done to ensure smooth functioning and a seamless onramp experience for the developers.
4. **Documentation**: Write comprehensive documentation covering the use of the new templates, how to integrate them, and the utility for linking them with the typed client. This documentation should also include how-to guides and sample applications to help developers get started.
5. **Addendum 1 - Converting ANY Frontend Projects into dApps**: Start a separate discussion and potentially a project to research the feasibility of this idea. If feasible, design and implement a method that allows developers to convert their existing non-web3 frontend projects into dApps using AlgoKit.
6. **Addendum 2 - Development of Template Selection Website**: Plan and execute the development of a minimalist UI that allows developers to easily discover and select their preferred templates. This should also allow them to easily generate the necessary AlgoKit CLI commands for their project setup.
7. **Community Engagement**: Engage the developer community to drive contributions to the template repositories. This includes encouraging template builders to contribute and supporting developers using the templates with issues and suggestions.
8. **Continuous Review and Maintenance**: Regularly review the templates to ensure they are up to date with changes in technology and AlgoKit principles. Continuous maintenance should also be carried out to ensure the templates remain functional and relevant.
Regarding the open questions, these should be discussed in detail to clarify how to handle Python typed clients and the potential introduction of non-smart contract based backend templates. These discussions may lead to additional actions as required.
================================================
FILE: docs/architecture-decisions/2023-07-19_advanced_generate_command.md
================================================
# Advanced `algokit generate` command
- **Status**: Approved
- **Owner:** Altynbek Orumbayev, Inaie Ignacio
- **Deciders**: Rob Moore, Daniel McGregor, Alessandro Cappellato
- **Date created**: 2023-07-19
- **Date decided:** 2023-07-24
- **Date updated**: 2023-07-24
## Context
The [Frontend Templates ADR](./2023-06-06_frontend-templates.md) introduced and expanded on AlgoKit's principles of Modularity and Maintainability by introducing a new set of official templates for quickly bootstrapping standalone `react` and `fullstack` projects showcasing best practices and patterns for building frontend and fullstack applications with Algorand. As a logical next step, we want to enable developers to extend existing projects instantiated from official templates with new files and features.
## Requirements
### 1. AlgoKit user should be able to use generate command to extend existing algokit compliant projects with new `files` of any kind
This implies scenarios like:
- Adding new contracts into existing algokit compliant projects.
> Algokit compliant projects are projects that were instantiated from official or community templates and follow the same structure and conventions.
- Overriding existing files with new ones.
- Adding new files into existing projects.
Overall, we want to introduce a notion of `generators` which can be viewed as a modular self-sufficient template units that are hosted within template repositories and describe how to create or update files within projects instantiated from AlgoKit templates.
Ruby on Rails has a similar concept of [generators](https://guides.rubyonrails.org/generators.html) which are used to create or update files within Rails projects. This can be used as a reference for inspiration.
### 2. Template builder should be able to access a clear guideline and refer to official templates for examples on how to create `generators`
This implies extension of existing starter guidelines available for template builders on [AlgoKit Docs](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/tutorials/algokit-template.md) and using one or several official templates as a reference point.
## Principles
- **Modularity**: Artifacts dependant on `advanced algokit generate` command capabilities embedded into templates should follow guiding AlgoKit principles and expand on approaches already utilized in `react`, `fullstack` and `beaker` templates. This implies that giving developers flexibility to define any extra templating logic, allowing to create or update any files within projects instantiated from algokit templates.
- **Maintainability**: The `advanced algokit generate` capabilities on `algokit-cli` and related artifacts on respective official templates should be easy to maintain and extend.
- **Seamless onramp**: Great developer experience for template builders to create their own `generators` and user experience to use them via `advanced algokit generate` command should be a priority.
All of the aforementioned requirements should be met in a way that is consistent with the guiding principles of AlgoKit or attempt to find a balanced trade of between the principles that satisfies the requirements. Refer to [AlgoKit Guiding Principles](../../docs/algokit.md#Guiding-Principles) for detailed reference on the principles.
## Considered Options
Based on preliminary research, all of the options below assume that:
A `generator` is a self contained copier/jinja template that is hosted within a template repository and describes how to create or update files within projects instantiated from algokit templates. Hosting it along with the template is a necessity given that community based templates can follow different conventions, patterns and structure making it hard to attempt to generalize the logic of `generators` and make them work for all templates.
### Option 1: Wrapping generators into self contained copier templates hidden within algokit templates
This option implies that `generators` are self contained copier templates that are hidden within algokit templates and are not exposed to the end user. This option is inspired by [Ruby on Rails generators](https://guides.rubyonrails.org/generators.html) and [Yeoman generators](https://yeoman.io/authoring/).
The main idea is to rely on `_templates_suffix` in copier.yamls to define 2 separate types of suffixes for `templates` and for `generators`:
- Existing templates under all official algokit templates are already prefixed with `.jinja` hence we just need to explicitly prefix it with `.jinja` on root copier
- The new generators jinja templates can be prefixed (for example) with alternative file extension for jinja files such as `.j2`. Which is also a common convention for jinja templates.
- - This only works for files though for regular folders and cases like `{% if %}folder_name{% endif %}.j2` we need to wrap them into {% raw %} to that first pass when template initially initialized unwraps the content allowing second pass via generator to then use them as jinja templates. The only downside here is slightly longer file names for folders, but I think it's a reasonable tradeoff considering simplicity of the solution.
Overview of the proposal can be summarized via the following diagram:
```mermaid
graph TB
T["Template Folder"]
T --> C["copier.yaml"]
T --> C1["..."]
T --> G[".algokit/generators"]
G --> G1["Generator 1"]
G1 --> E1["copier.yaml"]
G1 --> E2["..."]
G --> G2["..."]
G2 --> E3["..."]
G --> G3["Generator N"]
G3 --> E["copier.yaml"]
G3 --> E4["..."]
```
#### Pros
- Generators are hidden within algokit templates and are not exposed to the end user. When user runs `algokit generate` command, cli presents a list of available generators to choose from. This makes it easier for user to understand what generators are available and what they do.
- Generators are self contained copier templates giving template builders flexibility to do any kind of templating logic similar to what they can already do with regular templates.
- Majority of implementation complexity is reduced by relying on copier as a backbone for generators feature.
#### Cons
- Generators are somewhat tightly coupled with individual algokit templates, which implies its not necessarily a matter of copy pasting generators from one template to another. This can be a problem for community template builders who want to reuse generators from official templates. However, this can be mitigated by providing clear guidelines on how to create generators and referring to official templates as a reference point. Additionally, it seems like a reasonable tradeoff given that templates can vastly differ in type, structure, conventions and patterns and it's significantly harder to generalize the logic of generators to make them work for all templates.
#### Implementation details
**1. Adjusting templates structure**
For instance, if we assume existing `beaker` template, the new file/folder structure can look as follows:
```
template_content/.algokit # alternatively could be just `.algokit-generators`
└── generators
└── {generator_name} # generator name can be anything
├── copier.yaml # copier config for generator
└── smart_contracts # logic for adding new contracts to beaker template
└── {% raw %}{{ contract_name }}{% endraw %}
├── contract.py.j2
├── {% raw %}{% if language == 'python' %}deploy_config.py{% endif %}{% endraw %}.j2
└── {% raw %}{% if language == 'typescript' %}deploy-config.ts{% endif %}{% endraw %}.j2
...rest of the template is left as is
copier.yml
```
The `index.ts` and `config.py` files on beaker template need to be updated to auto import all contracts from sub folders at `smart_contracts` to eliminate the need for developers to manually import them after running the smart contract generator.
> Please note, above is just an example that assumes the generator for adding new contracts, but the proposal is generic enough to support any kind of jinja-based templating logic.
**2. Adjusting `.algokit.toml`**
The proposal for new structure for defining generators in root algokit toml is as follows:
```toml
[generators.create_contract] # [generators.]
description = "Adds new smart contract to existing project" # description of the generator, can appear in cli for extra info
path = ".algokit/generators/create_contract" # path that cli should grab to forward to copier copy
```
**3. Adjusting `algokit generate` command on cli**
Next step in implementation part of the proposal is adjusting the `generator` command on `algokit-cli` to make sure it knows how to look for generators. The available generators can be provided to user via list picker (a.k.a ruby on rails style) by letting algokit scan contents of `algokit.toml` and look for `.generators` folder.
a) Has no generators
If algokit-cli can't find any generator configured then nothing change from current implementation.
b) Has generators and user runs `algokit generate` command to see the list of available generators
A new `click` command per each generator in `.algokit.toml` is added to the list of generate commands, that will list all available generators for the user to choose from.
```bash
algokit-cli generate
---
Usage: algokit generate [OPTIONS] COMMAND [ARGS]...
Generate code for an Algorand project.
Options:
-h, --help Show this message and exit.
Commands:
client Create a typed ApplicationClient from an ARC-32 application.json
smart-contract Adds new smart contract to existing project
```
Then, to invoke the interactive flow via copier user runs:
```bash
algokit-cli generate smart-contract `name of the contract`
```
c) Has generators, user knows what to pick and wants to run it non interactively
Using the generator configuration the `generator` will automatically add new `click` commands to the existing list of generate commands allowing the user to run them in the command line.
```bash
algokit-cli generate smart-contract -a contract_name=`name of the contract` -a language=python # passing extra arguments to generator similar to algokit init
```
**4. Testing and documentation**
Lastly we need to make sure that the new feature is properly tested and documented. This includes:
- Testing the new feature works as expected on all official templates that will host generators. This will imply adding a separate test suite that picks some default template state and run generators on top of them confirming that created artifacts are placed in expected locations and have expected content. Tests should be easy to follow and expand on existing tests suite on templates without introducing extra complexity.
- Introduce new tutorial sections on [AlgoKit Docs](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/tutorials/algokit-template.md) on how to create generators and refer to official templates as a reference point.
### Option 2: Wrapping generators into self contained copier templates hosted on separate repositories
This option proposes to host `generators` on separate set of repositories and use them as a dependency for algokit templates.
`algokit.toml` can be extended on template repositories to list generators they depend on.
The only distinction between this option and option 1 is that generators are hosted on separate repositories and are not hidden within algokit templates. Implying that they are not tightly coupled with algokit templates and can be reused/forked by community template builders to build their own generators.
#### Pros
- Generators are not tightly coupled with algokit templates and can be reused/forked by community template builders to build their own generators.
- Generators can be versioned and updated independently from algokit templates.
#### Cons
- Developing and maintaining generators is significantly more complex due to the need to maintain separate repositories and versioning.
- Official maintainers and community template builders need to be put extra effort at keeping generators generic enough to be reused by other templates. Given that templates can vastly differ in type, structure, conventions and patterns, this can be a challenge.
- Given that copier is being considered as a backbone for generators feature, drawbacks outlined for hosting templates on monorepos in the [previous adr](2023-06-06_frontend-templates.md#option-1-monolithic-template) apply here as well.
## Open questions for reviewers
1. What kinds of generators other than `add new contract` do we want to support on initial release (if any)?
2. Are there any other template repositories that we want to integrate with generators other than `beaker` (`fullstack` will contain those as well as it uses `beaker` as a dependency)?
> Please note an MVP PoC is already implemented and available to play around on algokit-cli and beaker template repo under `advanced-generate-command` and `generators` branches respectively.
> To test it out checkout the branche on cli do `pipx install . --force`, navigate to beaker template repo and checkout the branch as well, then navigate to any of the sub folders in `tests_generated`. Lastly do `algokit bootstrap all`, build the contract and execute `algokit generate` from root of that folder to play around with the feature based on the implementation proposal from Option 1.
## Final Decision
The team approved the proposal for Option 1: Wrapping generators into self contained copier templates hidden within algokit templates.
## Next steps
1. Polishing the PoC on algokit-cli and adding tests
2. Polishing the PoC on beaker template and adding tests
3. Adding documentation for new capabilities of the generate command
4. Adding documentation for template builders on how to create generators
================================================
FILE: docs/architecture-decisions/2024-01-13_native_binaries.md
================================================
# AlgoKit CLI native binaries
- **Status**: Approved
- **Owner:** Altynbek Orumbayev (MakerX), Negar Abbasi (MakerX)
- **Deciders**: Alessandro (Algorand Foundation), MakerX
- **Date created**: 2024-01-13
- **Date decided:** 2024-01-25
- **Date updated**: 2024-01-16
## Context
The primary motivation for this decision is to streamline the installation process of AlgoKit CLI and reduce the friction associated with installing it on various operating systems. Currently, users often encounter minor environment-specific bugs during installation, which can be a significant deterrent. By providing native binaries, we aim to speed up the installation time and eliminate these bugs by **removing requirements to install python by the user**, thereby improving the overall user experience.
The north star for this decision is to provide a distribution model that can be described as:
```mermaid
graph TD
A[GitHub Runners] -->|Windows| B[Packaging tool]
A -->|Mac| C[Packaging tool]
A -->|Linux| D[Packaging tool]
B --> E[Windows Binary]
C --> F[Mac Binary]
D --> G[Linux Binary]
E -->|Winget| H[Windows Users]
F -->|Brew| I[Mac Users]
G -->|Snap| J[Linux Users]
A -->|Wheel Build| K[Poetry]
K --> L[PyPi]
L -->|pipx| M[Python Users]
```
> ⚠️⚠️⚠️ Please note diagram above is a draft and is to be separately discussed in a follow up ADR that will focus on distribution of the binaries.
The scope of this ADR only concerns the packaging for the CLI. The distribution via `snap`, `winget` and etc will be handled separately/in-parallel after decision and implementation of this ADR is in place.
## Requirements
- The native binaries should be easy to maintain and understand from a CI/CD deployment perspective.
- The solution should support a wide variety of Linux distributions, macOS (both Apple Silicon and Intel architectures), and Windows.
- The solution should integrate seamlessly with existing installation options, including Homebrew, or provide an easier alternative.
- The solution should be designed with future scalability in mind, allowing for the addition of support for other variations of architectures or else as needed.
- The solution should not significantly increase the complexity of the build process.
- The solution should provide clear error messages and debugging information to assist in troubleshooting any issues that may arise.
- You don't need to install Python on your system to use AlgoKit if you aren't creating a Python project.
## Options
### Option 1 - PyInstaller
**Pros**
- Easy to use and configure
- Supports multiple platforms and architectures
- Can handle complex packages and dependencies
- Generates a single file executable
- Active development and community support
- Fairly fast build time via ci - ~3-4 minutes
- Fairly small executable size (see benchmarking results below)
- Marginally equal executable load time in `onedir` mode compared to `onefile` mode
**Cons**
- Occasionally requires manual configuration for more complex packages
- Requires complex build packaging matrix to support multiple platforms and architectures
- Requires minor tweaks in algokit cli to account for the fact that features relying on `sys.executable` will point to algokit cli executable instead of python interpreter. This is a minor change and can be done in a backwards compatible way however still a con to consider.
- Requires minor tweaks in algokit cli to introduce `multiprocessing.freeze_support()` to avoid issues with `vanity-address` task when executing via binary.
#### PoC
The PoC is available [here](https://github.com/algorandfoundation/algokit-cli/pull/382). It outlines a simple github action with extra setup that compiles algokit cli as a single file executable on latest versions of Windows, Mac and Linux github runners.
### Option 2 - Nuitka
**Pros**
- Nuitka translates Python code into C and then compiles it, which can result in performance improvements.
- Cross-Platform: Supports multiple platforms including Windows, macOS, and Linux.
- More cross compilations options than PyInstaller
- Official github action simplifies the process of building executables for different platforms.
**Cons**
- Compilation Time: The process of converting Python to C and then compiling can be time-consuming. Up to ~30 minutes on github with 3 parallel jobs.
- Size of Executable: The resulting executables can be larger due to the inclusion of the Python interpreter and the compiled C code (see benchmarking results below).
- Does not support Python 3.12.
- Requires minor tweaks in algokit cli to account for the fact that features relying on `sys.executable` will point to algokit cli executable instead of python interpreter. This is a minor change and can be done in a backwards compatible way however still a con to consider.
- Requires minor tweaks in algokit cli to introduce `multiprocessing.freeze_support()` to avoid issues with `vanity-address` task when executing via binary.
#### PoC
The PoC is available [here](https://github.com/algorandfoundation/algokit-cli/pull/393). It outlines a simple github action with extra setup that compiles algokit cli as a single file executable on latest versions of Windows, Mac and Linux github runners.
### Benchmarking `pyinstaller` vs `nuitka` vs pipx installed `algokit`
#### Methodology
`hyperfine` was used to benchmark 5 different executables:
- Nuitka Onefile - Nuitka compiled executable with `--onefile` flag, which produces a single file executable.
- Nuitka Onedir - Nuitka compiled executable with `--onedir` flag, which produces a directory with the executable and other dependencies unzipped.
- PyInstaller Onedir - PyInstaller compiled executable with `--standalone` flag, which produces a directory with the executable and other dependencies unzipped.
- PyInstaller Onefile - PyInstaller compiled executable with `--onefile` flag, which produces a single file executable.
- AlgoKit from `pipx` - AlgoKit CLI installed via `pipx` with all dependencies frozen (current latest stable release).
The benchmarking was performed on a MacBook M2 running macOS 14.2.1 and an ARM based Ubuntu 20.04.3 LTS running on a Parallels Desktop on the same machine.
#### Results
| Method | macOS M2 | Ubuntu 20 ARM Linux VM | Windows 11 ARM |
| ------------------- | -------- | ---------------------- | -------------- |
| nuitka_onefile | 3.634 | 1.465 | 3.874 |
| nuitka_onedir | 0.2515 | 0.6200 | 0.5136 |
| pyinstaller_onedir | 0.3228 | 0.7927 | 0.6668 |
| pyinstaller_onefile | 3.031 | 1.466 | 1.875 |
| algokit | 0.3126 | 0.6111 | 0.7579 |

_Figure: Benchmarking results comparing the performance of Nuitka (onefile, onedir modes), PyInstaller (onefile, onedir modes), and pipx installed Algokit CLI on macOS M2, Windows 11 ARM VM, Ubuntu 20 ARM VM._
| Method | Windows (MB) | Ubuntu (MB) | macOS (MB) |
| ------------------- | ------------ | ----------- | ---------- |
| nuitka_onedir | 92.10 | 106 | 166 |
| nuitka_onefile | 22.48 | 23 | 41 |
| pyinstaller_onedir | 46.07 | 52 | 113 |
| pyinstaller_onefile | 26.47 | 25 | 45 |

_Figure: Bundle sizes of folders with executables build with Nuitka (onefile, onedir modes), PyInstaller (onefile, onedir modes)._
#### Preliminary Observations
- Nuitka's warmed up execution time is **fast**
- Nuitka produces largest executables in `onedir` mode
- Nuitka is the slowest to build (no charts for build benchmarks, this is observations based on CI build time from PoC, see links above)
- PyInstaller produces smallest executables in `onedir` mode
- PyInstaller is the fastest to build (no charts for build benchmarks, this is observations based on CI build time from PoC, see links above)
### Honorable Mentions
#### cx_Freeze
cx_Freeze is a set of scripts and modules for freezing Python scripts into executables. It is similar to PyInstaller in many ways, but PyInstaller is preferred due to its more mature and comprehensive documentation.
#### PyOxidizer
PyOxidizer is a utility for producing binaries that embed Python. However, it is no longer actively maintained, which makes it a less desirable option for our needs.
## Preferred option
Based on observations so far we are leaning towards an Option 1. Where we would use PyInstaller to build native binaries for Windows, Mac and Linux.
While `nuitka` in `onedir` mode is even faster than pip installed algokit, it generates larger executables, and is the slowest option in terms of build time. Pyinstaller is only marginally slower than `nuitka` or pip installed algokit in terms of execution time, has mature documentation, and is the fastest option to build (in `onedir` mode) and produces smaller executables than `nuitka`. Given that and the fact that `nuitka` does not support Python 3.12 yet and has a lot of `magical` optimizations hidden under the hood, we are leaning towards PyInstaller as the preferred option for building native binaries given its maturity and straightforwardness despite marginally slower execution time (which is not a big deal given that we are talking of deviations of 5-10 milliseconds).
## Selected option
The team has formally pre-discussed this ADR and has agreed to proceed with Option 1 - PyInstaller.
## Next Steps
- [ ] Finalize the decision on the preferred option.
- [ ] Expand PoC and polish the github action to build native binaries for Windows, Mac and Linux for x86, x86-64 and ARM architectures.
- [ ] Implement portability snapshot tests, expanding existing algokit cli snapshot tests by running against real executable covering main functionality to test and ensure that the native binaries are portable and behave the same way as pip installed algokit cli.
- [ ] Submit follow up ADR to discuss strategies on how to distribute the binaries in most accessible, user friendly and secure way.
================================================
FILE: docs/architecture-decisions/2024-01-23_init-wizard-v2.md
================================================
# AlgoKit Init Wizard Version 2 and Template Enhancements
- **Status:** Proposed (Revision 2)
- **Owner:** Altynbek Orumbayev
- **Deciders:** Alessandro (Algorand Foundation), Rob Moore (MakerX), MakerX team
- **Creation Date:** 2024-01-23
- **Decision Date:** 2024-02-13
- **Update Date:** 2024-02-12
## Revisions
- **Revision 1:** Initial discussions with Alessandro, Michael, Joe, Georgio, and Chris identified key issues with the existing wizards and explored ways to improve templating capabilities. These discussions led to the consideration of a unified 'monorepo' structure to consolidate template repositories into more focused, smaller generators under a single repository. The revision also sought to refine the wizard and enhance command orchestration capabilities, incorporating tools like `npm workspaces`.
- **Revision 2:** Engaged in multiple brainstorming sessions with Algorand Foundation/DevRel members and MakerX engineers to develop a pragmatic, time-bound, and prerequisite-neutral strategy. This approach resulted in splitting the ADR into two segments: one focusing on the `init` wizard enhancements and the other on template improvements and command orchestration upgrades in algokit-cli.
## Background
This ADR emerges from various discussions aimed at enhancing the `init` wizard version 2 user experience and aligning it with emerging smart contract languages/frameworks to make it more user-friendly and accessible to beginners. It builds upon prior decisions from the [Advanced algokit generate command](./2023-07-19_advanced_generate_command.md) and [Frontend Templates](./2023-06-06_frontend-templates.md) ADRs, integrating feedback from the Algorand Foundation and DevRel team.
### Main Areas for Improvement
1. **Enhancements to the `Init` Wizard:**
- Improve user experience by making the wizard more intuitive and less reliant on Algorand-specific jargon.
- Streamline the `presets` concept to minimize user inputs and simplify the process.
2. **Template Refinements:**
- Address potential complexities in maintaining the `fullstack` template with new `smart-contract` template combinations, including future `.NET` integration alongside `puya` compiler-compatible stacks.
- Implement `codespaces` configurations for simplified project setup in GitHub Codespaces.
- Consider unifying `add smart contract` generators in the `puya` and `beaker` templates into a single, generic generator managed by the CLI itself (suggestion added as part of revision 2 based on DevRel feedback). This helps solving the problem of simplifying template building experience (removing duplication of generators that are essentially generic) while still giving an option for template builders to have custom generators within templates.
3. **CLI Enhancements:**
- Enhance user experience by standardizing the use of `bootstrap`, `algokit.toml`, `.algokit` folder, and `.env` conventions, presenting a unified and intuitive CLI interface.
## Detailed Proposals
### 1. Improved `Init` Wizard Flow
Shift from a detailed, template-specific question format to a more streamlined, interactive process that focuses on the user's intent rather than specific technologies within the Algorand ecosystem.
**Current Init Wizard V1:**
```mermaid
graph TD
A[Start] --> Z[Pick an official template Puya, TealScript, React, Beaker]
Z --> B[Name for this project.]
B --> C[Package author name]
C --> D[Package author email]
D --> E[Do you want to add VSCode configuration?]
E -->|yes| F[Do you want to use ESLint and Prettier for code linting and formatting?]
E -->|no| G[Do you want to add JetBrains configuration - primarily optimized for WebStorm?]
F --> H[Do you want to use Tailwind CSS? A utility-first CSS framework for rapidly building custom designs.]
G --> H
H -->|yes| I[Do you want to use a daisyUI? Framework agnostic CSS component library for building modern websites and web applications fast.]
H -->|no| J[Do you want to include unit tests via Jest?]
I --> J
J --> K[Do you want to include end to end tests via Playwright?]
K --> L[Do you want to include Github Actions workflows for build validation?]
L -->|yes| M[Pick your website hosting provider for continuous delivery]
L -->|no| N[End]
M --> N
```
**Proposed Init Wizard V2:**
```mermaid
graph TB
A[Would you like to build a smart contract or a dapp frontend?]
B[If smart contract, which language would you like to use?]
C[If frontend, which framework would you like to use?]
D[Python, implies puya]
E[Typescript, implies TealScript]
F[React]
G[`production`/`starter`/`custom`]
I[`production`/`starter`/`custom`]
J[Would you like to include a frontend component?]
A --> B
A --> C
B --> D
D --> J
E --> J
J --> G
J --> F
B --> E
C --> F
F --> I
```
The proposal aims to simplify the question process and reduce the overall number of questions, focusing on identifying **what** the user intends to build without the additional complexity of selecting specific Algorand ecosystem tools or languages.
As illustrated in the proposed flow diagram, the initiative seeks to:
- Simplify the init wizard's questions, avoiding technical jargon and aligning with popular programming languages and frameworks, leveraging direct mappings like `python`, `typescript`, and `.net`.
- Introduce clear preset options: `starter` for a comprehensive preselection based on the Algorand Foundation's recommendations, `production` for setups aligned with production standards, and `custom` for developers seeking detailed customization through template questions.
This proposal presents no significant drawbacks, as it refines the question flow of the algokit init process without altering the command's fundamental behavior, thereby not impacting current users and enhancing the overall `init wizard` experience.
### 2. Fullstack Template and CLI Command Orchestration Enhancements
This dual-step approach suggests offloading business logic related to linking smart contracts and frontends within fullstack to a self-contained generator within the `react` template. It also introduces the concept of command orchestration in algokit-cli to manage project lifecycles more effectively.
#### 2.1 Autonomy of Frontend Template
**Fullstack Template Structure**:
| Before | After |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The current fullstack is tightly coupled with the frontend template, handling the connection between frontend and backend. This coupling necessitates additional safety checks whenever there are changes in the expected structure of the React template. | The frontend now invokes the `import-contract` generator within the React template, which autonomously manages the linkage with a smart contract project. This adjustment makes the fullstack less reliant on template-specific changes that it should not be concerned with. |
The proposal includes changes to the fullstack template's structure, enabling the frontend to autonomously manage its linkage with smart contract projects, thereby simplifying integration and enhancing maintainability.
**Benefits:**
- Simplifies integration of templates by allowing the frontend template to manage smart contract linkages independently.
- Generalizes the fullstack template, offering flexibility in choosing backend components.
**Suggested Enhancements:**
- Further generalize the `AppCalls.tsx` component, removing assumptions on default `hello world` contracts and using `resolveBy: 'id'` by default.
- Incorporate suggestions from discussions during revision 2, including the potential bundling of `add smart contract` generators directly into `algokit-cli` for reduced redundancy and enhanced template support.
#### 2.2 CLI Command Orchestration
Aims to utilize `algokit.toml` for organizing project-specific commands, enhancing project management and command execution through a more structured approach.
Example workspace root `.algokit.toml`:
```toml
[algokit]
min_version = "v1.8.0"
[project]
type = 'workspace' # informs algokit-cli that this is a workspace root that hosts multiple projects
name = 'myworkspace' # included for reference but unique identifier for the workspace can be actually be excluded as it is not required for orchestration to work
projects = ['src'] # a list of relative/absolute paths directly to folders with independent components of the project that are part of the workspace or roots of folders hosting multiple independent components
```
Example workspace of a smart contract project `.algokit.toml`:
```toml
[algokit]
min_version = "v1.8.0"
[generate.smart_contract]
description = "Adds new smart contract to existing project"
path = ".algokit/generators/create_contract"
[project]
type = 'backend'
name = '{ component_name }'
# The `deploy` command is categorized separately due to its static nature. Category names align with their root command group, hence `generate` is under [generate], while `deploy` is categorized under [project].
[project.deploy]
command = "poetry run python -m smart_contracts deploy"
environment_secrets = [
"DEPLOYER_MNEMONIC",
]
[project.deploy.localnet]
environment_secrets = []
# New category for project specific commands that can be defined arbitrarily by the user
[project.commands]
test = { command = "poetry run pytest", description = "Run unit tests for the smart contracts" }
build = { command = "poetry run python -m smart_contracts build", description = "Transpile puya smart contracts into TEAL and ABI specs" }
# Description is used as `help` text as content gets presented to user via `algokit cli` interface.
```
**Enhancements to `.algokit.toml` enable the cli to:**
- Navigate and interpret any project structure compliant with `.algokit.toml`.
- Simplify interactions with project-specific commands.
- Dynamically orchestrate command execution based on `.algokit.toml` configurations.
- For `algokit project {command_name}` executed at the workspace root, it aggregates and executes `{command_name}` from all child components either `sequentially` or `concurrently`, allowing users to choose the execution order per matching command identifier.
- When executed at a component's root, it runs the component-specific command from its `.algokit.toml`, also integrating it into the `algokit project` command group for visibility.
**Suggested Improvements:**
- Consider introducing command dependencies to ensure execution order for any command (in addition to current proposal to allow handling execution order for commands with matching 'names/identifiers'), enhancing the orchestration capabilities of the CLI.
## Reference: Alternatives Considered
### Consolidating AlgoKit Templates into a Monorepo
**Overview:** Explores the possibility of merging AlgoKit templates into a single repository, focusing on streamlined project management and orchestration within js-centric environments.
**Pros:**
- Simplifies monorepo project management and orchestration in npm-based projects.
**Cons:**
- Increases complexity and potential conflicts with existing CLI capabilities and Copier's recommendations, suggesting that a better alternative might be to consider a shift to where we have a more CLI-centric approach that handles orchestration without introducing extra dependant pre-requisites.
## Decision
A phased implementation of both proposals, starting with user-facing enhancements to the `init` wizard followed by template and CLI command orchestration improvements. This strategy allows for immediate impact and addresses urgent needs first, with potential for further simplification through subsequent enhancements.
## Next Steps
1. Break down the selected options into detailed work items.
2. Implement the proposed changes in the AlgoKit CLI and templates.
3. Update documentation and onboarding materials to reflect the new changes.
4. Announce the updates to the community and DevRel, soliciting feedback for future enhancements.
5. Tackle minor improvements that become feasible following the main proposal implementations.
### Open Questions
1. Should we implement a bidirectional query mechanism where selecting a smart contract prompts the option to add a frontend, and similarly, choosing a frontend first triggers a query about integrating a smart contract? This approach necessitates a minor modification in the wording of the initial query. In the current workflow, we don't prompt adding smart contracts part since this question is prominently positioned as the initial query in the wizard's sequence.
2. Alternative suggestions for 'type' categorization for `.algokit.toml` files? Or we are clear to proceed with `workspace` to highlight roots of full-stack/monorepo projects, `backend` to represent anything non webapp related and `frontend` to represent anything related?
================================================
FILE: docs/architecture-decisions/2024-01-31_binary_distribution.md
================================================
# AlgoKit CLI binary distribution
- **Status**: Approved
- **Owner:** Altynbek Orumbayev (MakerX)
- **Deciders**: Alessandro (Algorand Foundation), Rob Moore (MakerX), MakerX team
- **Date created**: 2024-01-31
- **Date decided:** 2024-02-01
- **Date updated**: 2024-02-05
## Context
The following ADR is a continuation of [native binaries](./2024-01-13_native_binaries.md) ADR. With initial workflows implemented, the goal is to determine the best way to distribute the native binaries to the end users.
## Requirements
- The solution should support a wide variety of Linux distributions, macOS (both Apple Silicon and Intel architectures), and Windows.
- The solution should allow distribution of native binaries via os specific package managers `brew`, `snap`, `winget`.
## Technical Constraints
- ~~Pyinstaller binaries are dependend on the architecture and the OS. Github Actions mainly support `x86-64` architectures. This means that we need a self hosted runner to build binaries for `arm64` architectures OR use an alternative CI provider which has access to `arm64` and other architectures inside runners.~~ Based on recent announcement made at the date of submission of initial draft of this ADR, GitHub now supports mac os ARM runners on all OSS plans. This means we can target arm64 macos binaries using the default macos runners and potentially reuse them to build arm64 linux binaries using QEMU and/or buildx from Docker. Hence this is no longer a constraint - see [post](https://github.blog/changelog/2024-01-30-github-actions-introducing-the-new-m1-macos-runner-available-to-open-source/).
- Codesigning is a recommended practice for secure distribution and would need to be implemented on top of the initial workflows introduced as part of the implementation of the [native binaries](./2024-01-13_native_binaries.md) ADR.
## Options
### Option 1 - Binaries are only available via dedicated package managers using OSS solutions for multi architecture support
This approach assumes that native binaries are never available for direct consumption but instead extra tailored per each selected package manager. Additionally this approach assumes using OSS solutions for multi architecture support. ~~Primarily using a QEMU/buildx based actions to build the binaries for different linux architectures, using paid m1 github runner for arm macos binaries, using default macos runner for x86 macos binaries and using default windows runner for x86-64 windows binaries~~. Based on recent announcement from [GitHub](https://github.blog/changelog/2024-01-30-github-actions-introducing-the-new-m1-macos-runner-available-to-open-source/) - ARM runners on mac are now available on all OSS plans, given that we agreed that we arent support ARM linux, mac on ARM can be compiled on ARM mac runners and windows can be compiled and targeting x86-64 using default runners. **Hence removing all major constrains and difficulties of this approach**.
Diagram:
```mermaid
flowchart
n1["Release pipeline flow"]
n1 --- n2["Python wheel build & test validation, runs on [3.10, 3.11, 3.12 on windows, mac, ubuntu]"]
n2 --- n3["Build binaries"]
n3 --- n4["Linux"]
n3 --- n5["Mac"]
n3 --- n6["Windows"]
n4 --- n7["ubuntu-latest x86-64"]
n7 --- n9["Upload artifacts"]
n5 --- n10["macos-latest x86-64"]
n5 --- n11["macos-large-latest ARM"]
n6 --- n12["windows-latest (x86-64)"]
n10 --- n9
n11 --- n9
n12 --- n9
n9 --- n13["Distribution"]
n13 --- n14["pypi pure python wheel"]
n13 --- n15["snap"]
n13 --- n16["brew"]
n13 --- n17["winget"]
n17 --- n18["refresh manifest"]
n18 --- n19["submit release PR to winget community repo"]
n16 --- n20["refresh cask definition"]
n20 --- n21["submit pr to algorandfoundation/tap"]
n15 --- n22["x86-64"]
n22 --- n23["build and submit x86-64 snap on ubuntu-latest runner"]
n23 --- n24["publish snap"]
```
#### General pros and cons
**Pros**
- Ability to rely on package manager to handle installation, updates and removal of the binaries
- OSS solutions for multi architecture support are available and can be used to build the binaries for different architectures on Linux using QEMU
**Cons**
- Assuming we are targeting x86-64/ARM64 on mac, x86-64 on Windows and x86-64 on Linux, no major cons are identified with this approach other than certain non deteministic factos around initial setup of Apple dev account, approval of PR on winget repo and setup of the Snapstore profile.
#### Snap
**Pros**
- Snap is available on all major Linux distributions
- Ubuntu provides a Launchpad platform that simplifies compiling snaps on different architectures remotely
- Snap supports distribution of pyinstaller binaries (verified in a PoC on a fork of algokit-cli)
- Has flexible configuration options over release channels (edge, beta, release candidate, production/stable).
**Cons**
- ~~Snap provides a native support for pyhon applications which may be simpler to use than pyinstaller rather than distributing the binaries as it allows us to rely directly on remote Launchpad builds instead of pre-building the binaries per each architecture.~~ **No longer an issue given latest decision not to support ARM64 linux given that pipx is still gonna be a first class citizen alternative.**
- ~~If we are to distribute pyinstaller binaries, the binaries itself need to be cross compiled on target architectures. Currently we get `x86-64` binaries with `ubuntu` runners, however we would need to introduce extra self hosted runners to get `arm64` binaries. In this case we would need to run building of binaries AND building of snaps in build matrices consiting of default `ubuntu` runners and self hosted `arm64` runners. This will increase the build time and complexity of the build process.~~ **No longer an issue given latest decision not to support ARM64 linux given that pipx is still gonna be a first class citizen alternative.**
#### Brew
**Pros**
- A flow for distributing algokit wheel via `brew` is already established
- Brew supports distribution of pyinstaller binaries (verified in a PoC on a fork of algokit-cli)
- Will require minor changes in the existing brew workflow to operate with binary artifacts instead of wheel artifacts
**Cons**
- ~~Algokit cli relies on dependencies that are not [`fat` binaries](https://en.wikipedia.org/wiki/Fat_binary). This means we can't use pyinstaller to target `universal2` architecture and instead need to build the binaries for each architecture separately. Hence using a paid ARM macos runner is a simple solution to get binaries for Apple Silicon.~~ **No longer an issue given announcement from Github that ARM runners are now available on all OSS plans.**
- Codesigning is required for distribution of binaries via `brew`. This means that we need to have a valid Apple Developer account and a valid certificate to sign the binaries. While this is a good practice regardless, listing this as a con given non deterministic nature of obtaining a valid certificate from Apple.
- ~~Separate ARM worker for apple silicon binaries is required. Github provides beta version of such runners for with paid billing plans.~~ **No longer paid given recent announcement from Github.**
#### Winget
**Pros**
- Winget is available on all major Windows distributions
- Winget supports distribution of pyinstaller binaries and in fact it does not support distribution of python wheels, making binaries a good candidate for winget.
- Will require minor changes in the existing brew workflow to convert pyinstaller .exe binaries to winget .msi binaries
**Cons**
- Winget requires contributing the manifest file to an open source repository which may cause potential delays in the distribution of the binaries as each PR needs to be reviewed and approved by the maintainers of the repository.
#### Conclusion
All of the above package managers are viable and can be used to distribute the pyinstaller build binaries. ~~Requirement on supporting additional architectures like `arm64` introduce unique challenges that ideally should be addressed by introducing custom self hosted runners to the build matrix. This will increase the complexity of the build process and will require additional maintenance of the runners.~~ **Given recent decisions around ARM linux support, we can safely assume that this is the most balanced approach that will allow us to distribute the binaries for all supported architectures without introducing additional complexity of maintaining self hosted runners or implementing an in-house self-update mechanism for binaries.**
### Option 2 - Binaries are only available via dedicated package managers using self hosted runners for multi architecture support
This is identical to the option 1 with the exception that we are using self hosted runners to build the binaries for different architectures.
Diagram:
```mermaid
flowchart
n1["Release pipeline flow"]
n1 --- n2["Python wheel build & test validation (runs on [3.10, 3.11, 3.12 on windows, mac, ubuntu]"]
n2 --- n3["Build binaries"]
n3 --- n4["Linux"]
n3 --- n5["Mac"]
n3 --- n6["Windows"]
n4 --- n7["self-hosted aarch64-ubuntu22.04"]
n4 --- n8["self-hosted armv7-ubuntu22.04"]
n7 --- n9["Upload artifacts"]
n5 --- n10["macos-latest x86-64"]
n5 --- n11["macos-large-latest ARM (paid worker)"]
n6 --- n12["windows-latest (x86-64)"]
n8 --- n9
n10 --- n9
n11 --- n9
n12 --- n9
n9 --- n13["Distribution"]
n13 --- n14["pypi pure python wheel"]
n13 --- n15["snap"]
n13 --- n16["brew"]
n13 --- n17["winget"]
n17 --- n18["refresh manifest"]
n18 --- n19["submit release PR to winget community repo "]
n16 --- n20["refresh cask definition (can use conditional that auto picks either ARM or Intel based artifacts)"]
n20 --- n21["submit pr to algorandfoundation/tap"]
n15 --- n22["aarch64"]
n15 --- n23["armv7"]
n22 --- n24["build snap on self hosted runner for aarch64 architecture"]
n23 --- n25["build snap on self hosted runner for armv7 architecture"]
n24 --- n26["publish snap"]
n25 --- n26
```
#### General pros and cons
**Pros**
- Simplified build matrix as we can simply define additional `runs-on` for each architecture we want to support to target our custom self hosted runners
- Same pros as option 1
**Cons**
- The main drawback for self hosted runners is requirements on additional maintenance, very careful configuration and security considerations. This is a non trivial task and will require additional resources to maintain implement. Github itself generally does not recommend using them for public repositories as forked repositories can potentially gain access to the self hosted runners. There is a lot of workarounds to this issue, but it is still a non trivial task to implement and maintain.
### Option 3 - Binaries are available for direct consumption as self contained executables
This approach assumes that native binaries are available for direct consumption as self contained executables. This means that the binaries are not distributed via package managers but instead are available for direct download from the Algorand Foundation website/dedicated installer script that needs to be introduce. The script can figure out the operating system, architecture and pull the correct binary from public github releases page.
Diagram:
```mermaid
flowchart
n1["Release pipeline flow"]
n1 --- n2["Python wheel build & test validation (runs on [3.10, 3.11, 3.12 on windows, mac, ubuntu]"]
n2 --- n3["Build binaries"]
n3 --- n4["Linux"]
n3 --- n5["Mac"]
n3 --- n6["Windows"]
n4 --- n7["ubuntu-latest"]
n7 --- n9["Upload artifacts"]
n5 --- n10["macos-latest x86-64"]
n5 --- n11["macos-large-latest ARM"]
n6 --- n12["windows-latest (x86-64)"]
n10 --- n9
n11 --- n9
n12 --- n9
n9 --- n13["Distribution"]
n13 --- n14["pypi pure python wheel"]
n13 --- n15["binaries"]
n15 --- n16["Windows"]
n15 --- n17["Linux"]
n15 --- n18["Mac"]
n16 --- n19["Transform to msi installer"]
n17 --- n20["codesign"]
n19 --- n20
n18 --- n21["transform to .pkg installer"]
n21 --- n20
n20 --- n22["append to github release"]
```
#### General pros and cons
**Pros**
- Ability to distribute binaries for all supported architectures without extra complexity of maintaining distributions via package managers `brew`, `snap`, `winget`
- Self update mechanism can be implemented within the algokit cli to check for updates and pull newer versions of the binaries. This will allow users to always have the latest version of the binaries without the need to wait for the package manager to update the binaries.
**Cons**
- Users who prefer to use package managers will need to manually install the binaries and keep track of the updates
- Self update mechanism will require additional maintenance and testing to ensure correct handling of the updates
### Option 4 - Binaries are available for direct consumption as self contained executables, dedicated package managers distribute the wheels
This is potentially the most complex approach and it combines option 1 and option 3. This means that we are distributing the binaries for direct consumption as self contained executables and additionally we are distributing the wheels via package managers.
**Pros**
- Ability to distribute binaries for all supported architectures without extra complexity of maintaining distributions via package managers `brew`, `snap`, `winget`
- Ability to rely on python optimizations in dedicated package managers like `snap` and `brew` to distribute the wheel artifacts
**Cons**
- **The major drawback with the approach** is that it does not eliminate dependency on python to run the algokit cli when using package managers which goes against initial goals of this outcome (removing requirement on having python installed on user's machine)
- Self update mechanism will require additional maintenance and testing to ensure correct handling of the updates and is at risk of not being used that often if users will still primarily rely on package managers or `pipx` to install the algokit cli
- Deminishes the value of having self contained binaries as users will still need to have python installed on their machines to run the algokit cli if they prefer to use package managers
## Preferred option
### Notes from discussion on 2024-02-01
- We are not supporting Windows ARM and Ubuntu ARM
- We are not using self-hosted runners approach
- Pending on key decision from Algorand Foundation on whether we want to have brew, snap, winget distribution vs self contained binary executables.
Based on the above, the most balanced option in terms of user experience and maintenance complexity is **Option 1**. This option allows us to distribute the binaries for all supported architectures without introducing additional complexity of maintaining self hosted runners or implementing an in-house self-update mechanism for binaries. Additionally each individual package manager has unique capabilities simplifying aggregation of metrics and controlling the release process.
## Selected option
Option 1
## Next Steps
1. Splitting ADR into self contained work items to parallelize the implementation of the selected option
2. Productizing PoCs implemented as part of this ADR to finalize integrations with `winget`, `snap` and `brew`
3. Aggregating requirements for obtaining accesses to the package managers and developer certificates for codesigning
4. Implementing codesigning mechanisms and finalizing implementation with detailed documentation of new installation options for users
## Open questions
~~Do we want to build the binaries for ARM based windows machines? If so, this implies that we need to introduce self hosted runners for windows as well given that there seems to be no OSS options to build the binaries for ARM based windows machines in Github Actions.~~ Clarified by decision to not support ARM versions of linux and windows given alternative options like pipx still being available as a first class citizen.
================================================
FILE: docs/architecture-decisions/2024-03-06_local_dev_ui_packaging.md
================================================
# Local dev UI packaging
- **Status**: Draft
- **Owner:** Patrick Dinh (MakerX), Negar Abbasi (MakerX)
- **Deciders**: Alessandro (Algorand Foundation), Rob Moore (MakerX), MakerX team
- **Date created**: 2024-03-06
## Context
We are building a web-based local development interface to support:
- Exploring transactions, assets and accounts
- Visualising transactions
- Launching a VS Code debug session from an application call transaction
- Integrating and using a dev wallet via KMD
- Network switching between LocalNet, TestNet and MainNet
- Calling deployed ABI apps
- Integration with the AlgoKit CLI to perform any relevant actions
- Launching the interface from the AlgoKit CLI
## Requirements
The local development interface should have:
- Support for a wide variety of Linux distributions, macOS (both Apple Silicon and Intel architectures), and Windows 10+.
- Local system access to:
- The user home directory on the file system.
- Launch child processes.
- Launch the UI from the AlgoKit CLI.
- Launch shell commands.
- The ability for the explorer portion to be deployed to a static web host.
- The ability to be installed via the following channels:
- Winget for Windows.
- Homebrew for macOS.
- Snapcraft for Linux.
- The ability for users to see a notification when a new version is available and can update.
## Out of scope
- Support for ARM processors on Linux or Windows.
## Options
### Option 1 - Electron
[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.
Link to PoC is here: [Electron PoC](https://github.com/negar-abbasi/electron-poc).
**Pros**
- Electron is a mature framework with a large community and a lot of resources available.
- Uses standard JavaScript and Node APIs, which most developers are very familiar with.
- 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.
- 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).
- 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.
- Running shell commands is enabled via the Node.js `child_process` module's `exec` function.
- 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.
- 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/).
- 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)
- It can package the app into format that we are interested in:
- `.deb`, `.snap` for Linux
- `.msi` for Windows
- `.dmg` for macOS
**Cons**
- 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)
- When built on a local dev machine, the package size for macOS is ~250MB.
### Option 2 - Tauri
[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.
**Pros**
- Tauri supports all requirements for the local development interface via their JavaScript API without the need to write any Rust.
- 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).
- 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.
- 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`
```json
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"tauri": "tauri"
},
```
- For [compiling binaries](https://tauri.app/v1/guides/building/), the Tauri Bundler supports
- Windows: setup.exe, .msi
- macOS: .app, .dmg
- Linux: .deb, .appimage
- The Tauri Bundler supports code signing for:
- [Windows](https://tauri.app/v1/guides/distribution/sign-windows)
- [Linux](https://tauri.app/v1/guides/distribution/sign-linux)
- [macOS](https://tauri.app/v1/guides/distribution/sign-macos)
- 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.
- 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).
- When built on a local dev machine, the package size for macOS is ~5MB.
**Cons**
- 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.
- 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.
- 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.
- For reference, [here](https://github.com/tauri-apps/tauri/issues?q=is%3Aissue+webview+css) are Tauri's issues related to CSS.
- For some versions of Windows 10, WebView2 needs to be installed. This process requires internet connection whilst installing.
### Option 3 - Wails
[Wails](https://wails.io/) is similar to Tauri but the core is written in Go.
**Pros**
- Wails has init templates for major web framework. React + TypeScript + Vite is supported.
- Wails has an auto codegen to generate the contract between the main process and the renderer process.
- 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.
- 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).
- When built on a local dev machine, the package size for macOS is ~5MB.
**Cons**
- 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.
- 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.
- No built-in updater. It is tracked in this [issue](https://github.com/wailsapp/wails/issues/1178).
- Wails is based on WebView, therefore, it has the same cross-platform issues with Tauri.
- Wails supports building for Windows, Mac and Linux. The documentation however isn't super clear:
- I could build Windows binaries from Mac.
- I couldn't build Linux binaries from Mac.
- The document doesn't mention options to build installers.
## Preferred option
- **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.
## Selected option
Option 2
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.
================================================
FILE: docs/articles/output_stability.md
================================================
# Smart Contract Output Stability
Smart contracts development is analogous to low level firmware software development; it's a highly constrained environment in terms of both compute power and memory storage, with a high risk of vulnerabilities due to lower level access to memory and less developer-oriented security tooling.
Because of this, the assembly language code that is output for a smart contract is important - a seemingly innocuous minor change could inadvertently add a security vulnerability, or could significantly change the execution and memory profile.
As such it is important to ensure that, even if higher level code is refactored, there are no unintended changes to the generated smart contract assembly language output.
We refer to this property as **output stability**.
We recommend having "output stability tests" that require a developer to explicitly opt-in to accepting a change in the output of a smart contract's assembly code. This can be implemented as part of an automated build process which fails if the output changes aren't committed to source control, thus preventing deployment of the smart contract without a human review taking place (assuming automated deployment).
================================================
FILE: docs/cli/index.md
================================================
# AlgoKit CLI Reference Documentation
- [algokit](#algokit)
- [Options](#options)
- [--version](#--version)
- [-v, --verbose](#-v---verbose)
- [--color, --no-color](#--color---no-color)
- [--skip-version-check](#--skip-version-check)
- [compile](#compile)
- [Options](#options-1)
- [-v, --version ](#-v---version-)
- [py](#py)
- [Arguments](#arguments)
- [PUYAPY_ARGS](#puyapy_args)
- [python](#python)
- [Arguments](#arguments-1)
- [PUYAPY_ARGS](#puyapy_args-1)
- [ts](#ts)
- [Arguments](#arguments-2)
- [PUYATS_ARGS](#puyats_args)
- [typescript](#typescript)
- [Arguments](#arguments-3)
- [PUYATS_ARGS](#puyats_args-1)
- [completions](#completions)
- [install](#install)
- [Options](#options-2)
- [--shell ](#--shell-)
- [uninstall](#uninstall)
- [Options](#options-3)
- [--shell ](#--shell--1)
- [config](#config)
- [container-engine](#container-engine)
- [Options](#options-4)
- [-f, --force](#-f---force)
- [Arguments](#arguments-4)
- [ENGINE](#engine)
- [js-package-manager](#js-package-manager)
- [Arguments](#arguments-5)
- [PACKAGE_MANAGER](#package_manager)
- [py-package-manager](#py-package-manager)
- [Arguments](#arguments-6)
- [PACKAGE_MANAGER](#package_manager-1)
- [version-prompt](#version-prompt)
- [Arguments](#arguments-7)
- [ENABLE](#enable)
- [dispenser](#dispenser)
- [fund](#fund)
- [Options](#options-5)
- [-r, --receiver ](#-r---receiver-)
- [-a, --amount ](#-a---amount-)
- [--whole-units](#--whole-units)
- [limit](#limit)
- [Options](#options-6)
- [--whole-units](#--whole-units-1)
- [login](#login)
- [Options](#options-7)
- [--ci](#--ci)
- [-o, --output ](#-o---output-)
- [-f, --file ](#-f---file-)
- [logout](#logout)
- [refund](#refund)
- [Options](#options-8)
- [-t, --txID ](#-t---txid-)
- [doctor](#doctor)
- [Options](#options-9)
- [-c, --copy-to-clipboard](#-c---copy-to-clipboard)
- [explore](#explore)
- [Arguments](#arguments-8)
- [NETWORK](#network)
- [generate](#generate)
- [client](#client)
- [Options](#options-10)
- [-o, --output ](#-o---output--1)
- [-l, --language ](#-l---language-)
- [-v, --version ](#-v---version--1)
- [Arguments](#arguments-9)
- [APP_SPEC_PATH_OR_DIR](#app_spec_path_or_dir)
- [ARGS](#args)
- [goal](#goal)
- [Options](#options-11)
- [--console](#--console)
- [--interactive](#--interactive)
- [Arguments](#arguments-10)
- [GOAL_ARGS](#goal_args)
- [init](#init)
- [Options](#options-12)
- [-n, --name ](#-n---name-)
- [-t, --template ](#-t---template-)
- [--template-url ](#--template-url-)
- [--template-url-ref ](#--template-url-ref-)
- [--UNSAFE-SECURITY-accept-template-url](#--unsafe-security-accept-template-url)
- [--git, --no-git](#--git---no-git)
- [--defaults](#--defaults)
- [--bootstrap, --no-bootstrap](#--bootstrap---no-bootstrap)
- [--ide, --no-ide](#--ide---no-ide)
- [--workspace, --no-workspace](#--workspace---no-workspace)
- [-a, --answer ](#-a---answer--)
- [example](#example)
- [Options](#options-13)
- [-l, --list](#-l---list)
- [Arguments](#arguments-11)
- [EXAMPLE_ID](#example_id)
- [localnet](#localnet)
- [codespace](#codespace)
- [Options](#options-14)
- [-m, --machine ](#-m---machine-)
- [-a, --algod-port ](#-a---algod-port-)
- [-i, --indexer-port ](#-i---indexer-port-)
- [-k, --kmd-port ](#-k---kmd-port-)
- [-n, --codespace-name ](#-n---codespace-name-)
- [-r, --repo-url ](#-r---repo-url-)
- [-t, --timeout ](#-t---timeout-)
- [-f, --force](#-f---force-1)
- [config](#config-1)
- [Options](#options-15)
- [-f, --force](#-f---force-2)
- [Arguments](#arguments-12)
- [ENGINE](#engine-1)
- [console](#console)
- [explore](#explore-1)
- [logs](#logs)
- [Options](#options-16)
- [--follow, -f](#--follow--f)
- [--tail ](#--tail-)
- [reset](#reset)
- [Options](#options-17)
- [--update, --no-update](#--update---no-update)
- [-P, --config-dir ](#-p---config-dir-)
- [--check](#--check)
- [start](#start)
- [Options](#options-18)
- [-n, --name ](#-n---name--1)
- [-P, --config-dir ](#-p---config-dir--1)
- [-d, --dev, --no-dev](#-d---dev---no-dev)
- [--force](#--force)
- [--check](#--check-1)
- [status](#status)
- [Options](#options-19)
- [--check](#--check-2)
- [stop](#stop)
- [project](#project)
- [bootstrap](#bootstrap)
- [Options](#options-20)
- [--force](#--force-1)
- [Options](#options-21)
- [--interactive, --no-ci, --non-interactive, --ci](#--interactive---no-ci---non-interactive---ci)
- [-p, --project-name ](#-p---project-name-)
- [-t, --type ](#-t---type-)
- [Options](#options-22)
- [--interactive, --non-interactive, --ci](#--interactive---non-interactive---ci)
- [Options](#options-23)
- [--ci, --no-ci](#--ci---no-ci)
- [Options](#options-24)
- [--ci, --no-ci](#--ci---no-ci-1)
- [deploy](#deploy)
- [Options](#options-25)
- [-C, -c, --command ](#-c--c---command-)
- [--interactive, --non-interactive, --ci](#--interactive---non-interactive---ci-1)
- [-P, --path ](#-p---path-)
- [--deployer ](#--deployer-)
- [--dispenser ](#--dispenser-)
- [-p, --project-name ](#-p---project-name--1)
- [Arguments](#arguments-13)
- [ENVIRONMENT_NAME](#environment_name)
- [EXTRA_ARGS](#extra_args)
- [link](#link)
- [Options](#options-26)
- [-p, --project-name ](#-p---project-name--2)
- [-l, --language ](#-l---language--1)
- [-a, --all](#-a---all)
- [-f, --fail-fast](#-f---fail-fast)
- [-v, --version ](#-v---version--2)
- [list](#list)
- [Arguments](#arguments-14)
- [WORKSPACE_PATH](#workspace_path)
- [run](#run)
- [task](#task)
- [analyze](#analyze)
- [Options](#options-27)
- [-r, --recursive](#-r---recursive)
- [--force](#--force-2)
- [--diff](#--diff)
- [-o, --output ](#-o---output--2)
- [-e, --exclude ](#-e---exclude-)
- [Arguments](#arguments-15)
- [INPUT_PATHS](#input_paths)
- [ipfs](#ipfs)
- [Options](#options-28)
- [-f, --file ](#-f---file--1)
- [-n, --name ](#-n---name--2)
- [mint](#mint)
- [Options](#options-29)
- [--creator ](#--creator-)
- [--name ](#--name-)
- [-u, --unit ](#-u---unit-)
- [-t, --total ](#-t---total-)
- [-d, --decimals ](#-d---decimals-)
- [--nft, --ft](#--nft---ft)
- [-i, --image ](#-i---image-)
- [-m, --metadata ](#-m---metadata-)
- [--mutable, --immutable](#--mutable---immutable)
- [-n, --network ](#-n---network-)
- [nfd-lookup](#nfd-lookup)
- [Options](#options-30)
- [-o, --output ](#-o---output--3)
- [Arguments](#arguments-16)
- [VALUE](#value)
- [opt-in](#opt-in)
- [Options](#options-31)
- [-a, --account ](#-a---account-)
- [-n, --network ](#-n---network--1)
- [Arguments](#arguments-17)
- [ASSET_IDS](#asset_ids)
- [opt-out](#opt-out)
- [Options](#options-32)
- [-a, --account ](#-a---account--1)
- [--all](#--all)
- [-n, --network ](#-n---network--2)
- [Arguments](#arguments-18)
- [ASSET_IDS](#asset_ids-1)
- [send](#send)
- [Options](#options-33)
- [-f, --file ](#-f---file--2)
- [-t, --transaction ](#-t---transaction-)
- [-n, --network ](#-n---network--3)
- [sign](#sign)
- [Options](#options-34)
- [-a, --account ](#-a---account--2)
- [-f, --file ](#-f---file--3)
- [-t, --transaction ](#-t---transaction--1)
- [-o, --output ](#-o---output--4)
- [--force](#--force-3)
- [transfer](#transfer)
- [Options](#options-35)
- [-s, --sender ](#-s---sender-)
- [-r, --receiver ](#-r---receiver--1)
- [--asset, --id ](#--asset---id-)
- [-a, --amount ](#-a---amount--1)
- [--whole-units](#--whole-units-2)
- [-n, --network ](#-n---network--4)
- [vanity-address](#vanity-address)
- [Options](#options-36)
- [-m, --match ](#-m---match-)
- [-o, --output ](#-o---output--5)
- [-a, --alias ](#-a---alias-)
- [--file-path ](#--file-path-)
- [-f, --force](#-f---force-3)
- [Arguments](#arguments-19)
- [KEYWORD](#keyword)
- [wallet](#wallet)
- [Options](#options-37)
- [-a, --address ](#-a---address-)
- [-m, --mnemonic](#-m---mnemonic)
- [-f, --force](#-f---force-4)
- [Arguments](#arguments-20)
- [ALIAS_NAME](#alias_name)
- [Arguments](#arguments-21)
- [ALIAS](#alias)
- [Options](#options-38)
- [-f, --force](#-f---force-5)
- [Arguments](#arguments-22)
- [ALIAS](#alias-1)
- [Options](#options-39)
- [-f, --force](#-f---force-6)
# algokit
AlgoKit is your one-stop shop to develop applications on the Algorand blockchain.
If you are getting started, please see the quick start tutorial: [https://dev.algorand.co/getting-started/algokit-quick-start/](https://dev.algorand.co/getting-started/algokit-quick-start/).
```shell
algokit [OPTIONS] COMMAND [ARGS]...
```
### Options
### --version
Show the version and exit.
### -v, --verbose
Enable logging of DEBUG messages to the console.
### --color, --no-color
Force enable or disable of console output styling.
### --skip-version-check
Skip version checking and prompting.
## compile
Compile smart contracts and smart signatures written in a supported high-level language
to a format deployable on the Algorand Virtual Machine (AVM).
```shell
algokit compile [OPTIONS] COMMAND [ARGS]...
```
### Options
### -v, --version
The compiler version to pin to, for example, 1.0.0. If no version is specified, AlgoKit checks if the compiler is installed and runs the installed version. If the compiler is not installed, AlgoKit runs the latest version. If a version is specified, AlgoKit checks if an installed version matches and runs the installed version. Otherwise, AlgoKit runs the specified version.
### py
Compile Algorand Python contract(s) using the PuyaPy compiler.
```shell
algokit compile py [OPTIONS] [PUYAPY_ARGS]...
```
### Arguments
### PUYAPY_ARGS
Optional argument(s)
### python
Compile Algorand Python contract(s) using the PuyaPy compiler.
```shell
algokit compile python [OPTIONS] [PUYAPY_ARGS]...
```
### Arguments
### PUYAPY_ARGS
Optional argument(s)
### ts
Compile Algorand TypeScript contract(s) using the PuyaTs compiler.
```shell
algokit compile ts [OPTIONS] [PUYATS_ARGS]...
```
### Arguments
### PUYATS_ARGS
Optional argument(s)
### typescript
Compile Algorand TypeScript contract(s) using the PuyaTs compiler.
```shell
algokit compile typescript [OPTIONS] [PUYATS_ARGS]...
```
### Arguments
### PUYATS_ARGS
Optional argument(s)
## completions
Install and Uninstall AlgoKit shell integrations.
```shell
algokit completions [OPTIONS] COMMAND [ARGS]...
```
### install
Install shell completions, this command will attempt to update the interactive profile script
for the current shell to support algokit completions. To specify a specific shell use --shell.
```shell
algokit completions install [OPTIONS]
```
### Options
### --shell
Specify shell to install algokit completions for.
* **Options**
bash | zsh
### uninstall
Uninstall shell completions, this command will attempt to update the interactive profile script
for the current shell to remove any algokit completions that have been added.
To specify a specific shell use --shell.
```shell
algokit completions uninstall [OPTIONS]
```
### Options
### --shell
Specify shell to install algokit completions for.
* **Options**
bash | zsh
## config
Configure settings used by AlgoKit
```shell
algokit config [OPTIONS] COMMAND [ARGS]...
```
### container-engine
Set the default container engine for use by AlgoKit CLI to run LocalNet images.
```shell
algokit config container-engine [OPTIONS] [[docker|podman]]
```
### Options
### -f, --force
Skip confirmation prompts. Defaults to 'yes' to all prompts.
### Arguments
### ENGINE
Optional argument
### js-package-manager
Set the default JavaScript package manager for use by AlgoKit CLI.
```shell
algokit config js-package-manager [OPTIONS] [[npm|pnpm]]
```
### Arguments
### PACKAGE_MANAGER
Optional argument
### py-package-manager
Set the default Python package manager for use by AlgoKit CLI.
```shell
algokit config py-package-manager [OPTIONS] [[poetry|uv]]
```
### Arguments
### PACKAGE_MANAGER
Optional argument
### version-prompt
Controls whether AlgoKit checks and prompts for new versions.
Set to [disable] to prevent AlgoKit performing this check permanently, or [enable] to resume checking.
If no argument is provided then outputs current setting.
Also see --skip-version-check which can be used to disable check for a single command.
```shell
algokit config version-prompt [OPTIONS] [[enable|disable]]
```
### Arguments
### ENABLE
Optional argument
## dispenser
Interact with the AlgoKit TestNet Dispenser.
```shell
algokit dispenser [OPTIONS] COMMAND [ARGS]...
```
### fund
Fund your wallet address with TestNet ALGOs.
```shell
algokit dispenser fund [OPTIONS]
```
### Options
### -r, --receiver
**Required** Address or alias of the receiver to fund with TestNet ALGOs.
### -a, --amount
**Required** Amount to fund. Defaults to microAlgos.
### --whole-units
Use whole units (Algos) instead of smallest divisible units (microAlgos). Disabled by default.
### limit
Get information about current fund limit on your account. Resets daily.
```shell
algokit dispenser limit [OPTIONS]
```
### Options
### --whole-units
Use whole units (Algos) instead of smallest divisible units (microAlgos). Disabled by default.
### login
Login to your Dispenser API account.
```shell
algokit dispenser login [OPTIONS]
```
### Options
### --ci
Generate an access token for CI. Issued for 30 days.
### -o, --output
Choose the output method for the access token. Defaults to stdout. Only applicable when --ci flag is set.
* **Options**
stdout | file
### -f, --file
Output filename where you want to store the generated access token.Defaults to algokit_ci_token.txt. Only applicable when --ci flag is set and --output mode is file.
### logout
Logout of your Dispenser API account.
```shell
algokit dispenser logout [OPTIONS]
```
### refund
Refund ALGOs back to the dispenser wallet address.
```shell
algokit dispenser refund [OPTIONS]
```
### Options
### -t, --txID
**Required** Transaction ID of your refund operation.
## doctor
Diagnose potential environment issues that may affect AlgoKit.
Will search the system for AlgoKit dependencies and show their versions, as well as identifying any
potential issues.
```shell
algokit doctor [OPTIONS]
```
### Options
### -c, --copy-to-clipboard
Copy the contents of the doctor message (in Markdown format) in your clipboard.
## explore
Explore the specified network using lora.
```shell
algokit explore [OPTIONS] [[localnet|testnet|mainnet]]
```
### Arguments
### NETWORK
Optional argument
## generate
Generate code for an Algorand project.
```shell
algokit generate [OPTIONS] COMMAND [ARGS]...
```
### client
Create a typed ApplicationClient from an ARC-32/56 application.json
Supply the path to an application specification file or a directory to recursively search
for "application.json" files
```shell
algokit generate client [OPTIONS] [APP_SPEC_PATH_OR_DIR] [ARGS]...
```
### Options
### -o, --output
Path to the output file. The following tokens can be used to substitute into the output path: {contract_name}, {app_spec_dir}
### -l, --language
Programming language of the generated client code
* **Options**
python | typescript
### -v, --version
The client generator version to pin to, for example, 1.0.0. If no version is specified, AlgoKit checks if the client generator is installed and runs the installed version. If the client generator is not installed, AlgoKit runs the latest version. If a version is specified, AlgoKit checks if an installed version matches and runs the installed version. Otherwise, AlgoKit runs the specified version.
### Arguments
### APP_SPEC_PATH_OR_DIR
Optional argument
### ARGS
Optional argument(s)
## goal
Run the Algorand goal CLI against the AlgoKit LocalNet.
Look at [https://dev.algorand.co/algokit/algokit-cli/goal](https://dev.algorand.co/algokit/algokit-cli/goal) for more information.
```shell
algokit goal [OPTIONS] [GOAL_ARGS]...
```
### Options
### --console
Open a Bash console so you can execute multiple goal commands and/or interact with a filesystem.
### --interactive
Force running the goal command in interactive mode.
### Arguments
### GOAL_ARGS
Optional argument(s)
## init
Initializes a new project from a template, including prompting
for template specific questions to be used in template rendering.
Templates can be default templates shipped with AlgoKit, or custom
templates in public Git repositories.
Includes ability to initialise Git repository, run algokit project bootstrap and
automatically open Visual Studio Code.
This should be run in the parent directory that you want the project folder
created in.
By default, the --workspace flag creates projects within a workspace structure or integrates them into an existing
one, promoting organized management of multiple projects. Alternatively,
to disable this behavior use the --no-workspace flag, which ensures
the new project is created in a standalone target directory. This is
suitable for isolated projects or when workspace integration is unnecessary.
```shell
algokit init [OPTIONS] COMMAND [ARGS]...
```
### Options
### -n, --name
Name of the project / directory / repository to create.
### -t, --template
Name of an official template to use. To choose interactively, run this command with no arguments.
* **Options**
tealscript | typescript | python | react | fullstack | base
### --template-url
URL to a git repo with a custom project template.
### --template-url-ref
Specific tag, branch or commit to use on git repo specified with --template-url. Defaults to latest.
### --UNSAFE-SECURITY-accept-template-url
Accept the specified template URL, acknowledging the security implications of arbitrary code execution trusting an unofficial template.
### --git, --no-git
Initialise git repository in directory after creation.
### --defaults
Automatically choose default answers without asking when creating this template.
### --bootstrap, --no-bootstrap
Whether to run algokit project bootstrap to install and configure the new project's dependencies locally.
### --ide, --no-ide
Whether to open an IDE for you if the IDE and IDE config are detected. Supported IDEs: VS Code.
### --workspace, --no-workspace
Whether to prefer structuring standalone projects as part of a workspace. An AlgoKit workspace is a conventional project structure that allows managing multiple standalone projects in a monorepo.
### -a, --answer
Answers key/value pairs to pass to the template.
### example
Initialize a new project from an example template.
Allows you to quickly create a new project by copying one of the official AlgoKit example templates.
If no example ID is provided, launches an interactive selector to choose from available examples.
The example will be copied to a new directory in your current location.
```shell
algokit init example [OPTIONS] [EXAMPLE_ID]
```
### Options
### -l, --list
List all available examples
### Arguments
### EXAMPLE_ID
Optional argument
## localnet
Manage the AlgoKit LocalNet.
```shell
algokit localnet [OPTIONS] COMMAND [ARGS]...
```
### codespace
Manage the AlgoKit LocalNet in GitHub Codespaces.
```shell
algokit localnet codespace [OPTIONS]
```
### Options
### -m, --machine
The GitHub Codespace machine type to use. Defaults to base tier.
* **Options**
basicLinux32gb | standardLinux32gb | premiumLinux | largePremiumLinux
### -a, --algod-port
The port for the Algorand daemon. Defaults to 4001.
### -i, --indexer-port
The port for the Algorand indexer. Defaults to 8980.
### -k, --kmd-port
The port for the Algorand kmd. Defaults to 4002.
### -n, --codespace-name
The name of the codespace. Defaults to 'algokit-localnet_timestamp'.
### -r, --repo-url
The URL of the repository. Defaults to algokit base template repo.
### -t, --timeout
Default max runtime timeout in minutes. Upon hitting the timeout a codespace will be shutdown to prevent accidental spending over GitHub Codespaces quota. Defaults to 4 hours.
### -f, --force
Force delete previously used codespaces with {CODESPACE_NAME_PREFIX}\* name prefix and skip prompts. Defaults to explicitly prompting for confirmation.
### config
Set the default container engine for use by AlgoKit CLI to run LocalNet images.
```shell
algokit localnet config [OPTIONS] [[docker|podman]]
```
### Options
### -f, --force
Skip confirmation prompts. Defaults to 'yes' to all prompts.
### Arguments
### ENGINE
Optional argument
### console
Run the Algorand goal CLI against the AlgoKit LocalNet via a Bash console so you can execute multiple goal commands and/or interact with a filesystem.
```shell
algokit localnet console [OPTIONS]
```
### explore
Explore the AlgoKit LocalNet using lora.
```shell
algokit localnet explore [OPTIONS]
```
### logs
See the output of the Docker containers.
```shell
algokit localnet logs [OPTIONS]
```
### Options
### --follow, -f
Follow log output.
### --tail
Number of lines to show from the end of the logs for each container.
* **Default**
`all`
### reset
Reset the AlgoKit LocalNet.
```shell
algokit localnet reset [OPTIONS]
```
### Options
### --update, --no-update
Enable or disable updating to the latest available LocalNet version, default: don't update
### -P, --config-dir
Specify the custom localnet configuration directory.
### --check
Force check the Docker registry for new LocalNet image versions, ignoring the version check cache.
### start
Start the AlgoKit LocalNet.
```shell
algokit localnet start [OPTIONS]
```
### Options
### -n, --name
Specify a name for a custom LocalNet instance. AlgoKit will not manage the configuration of named LocalNet instances, allowing developers to configure it in any way they need. Defaults to 'sandbox'.
### -P, --config-dir
Specify the custom localnet configuration directory. Defaults to '~/.config' on UNIX and 'C:\\Users\\USERNAME\\AppData\\Roaming' on Windows.
### -d, --dev, --no-dev
Control whether to launch 'algod' in developer mode or not. Defaults to 'yes'.
### --force
Ignore the prompt to stop the LocalNet if it's already running.
### --check
Force check the Docker registry for new LocalNet image versions, ignoring the version check cache.
### status
Check the status of the AlgoKit LocalNet.
```shell
algokit localnet status [OPTIONS]
```
### Options
### --check
Force check the Docker registry for new LocalNet image versions, ignoring the version check cache.
### stop
Stop the AlgoKit LocalNet.
```shell
algokit localnet stop [OPTIONS]
```
## project
Provides a suite of commands for managing your AlgoKit project.
This includes initializing project dependencies, deploying smart contracts,
and executing predefined or custom commands within your project environment.
```shell
algokit project [OPTIONS] COMMAND [ARGS]...
```
### bootstrap
Expedited initial setup for any developer by installing and configuring dependencies and other
key development environment setup activities.
```shell
algokit project bootstrap [OPTIONS] COMMAND [ARGS]...
```
### Options
### --force
Continue even if minimum AlgoKit version is not met
#### all
Runs all bootstrap sub-commands in the current directory and immediate sub directories.
```shell
algokit project bootstrap all [OPTIONS]
```
### Options
### --interactive, --no-ci, --non-interactive, --ci
Enable/disable interactive prompts. If the CI environment variable is set, defaults to non-interactive
### -p, --project-name
(Optional) Projects to execute the command on. Defaults to all projects found in the current directory.
### -t, --type
(Optional) Limit execution to specific project types if executing from workspace.
* **Options**
ProjectType.FRONTEND | ProjectType.CONTRACT | ProjectType.BACKEND
#### env
Copies .env.template file to .env in the current working directory and prompts for any unspecified values.
```shell
algokit project bootstrap env [OPTIONS]
```
### Options
### --interactive, --non-interactive, --ci
Enable/disable interactive prompts. If the CI environment variable is set, defaults to non-interactive
#### npm
Runs npm install in the current working directory to install Node.js dependencies.
```shell
algokit project bootstrap npm [OPTIONS]
```
### Options
### --ci, --no-ci
Run 'npm ci' instead of 'npm install' in CI mode (clean install).
#### pnpm
Runs pnpm install in the current working directory to install Node.js dependencies.
```shell
algokit project bootstrap pnpm [OPTIONS]
```
### Options
### --ci, --no-ci
Run 'pnpm install --frozen-lockfile' instead of 'pnpm install' in CI mode (clean install with frozen lockfile).
#### poetry
Installs Python Poetry (if not present) and runs poetry install in the current working directory to install Python dependencies.
```shell
algokit project bootstrap poetry [OPTIONS]
```
#### uv
Installs UV (if not present) and runs uv sync in the current working directory to install Python dependencies.
```shell
algokit project bootstrap uv [OPTIONS]
```
### deploy
Deploy smart contracts from AlgoKit compliant repository.
```shell
algokit project deploy [OPTIONS] [ENVIRONMENT_NAME] [EXTRA_ARGS]...
```
### Options
### -C, -c, --command
Custom deploy command. If not provided, will load the deploy command from .algokit.toml file.
### --interactive, --non-interactive, --ci
Enable/disable interactive prompts. Defaults to non-interactive if the CI environment variable is set. Interactive MainNet deployments prompt for confirmation.
### -P, --path
Specify the project directory. If not provided, current working directory will be used.
### --deployer
(Optional) Alias of the deployer account. Otherwise, will prompt the deployer mnemonic if specified in .algokit.toml file.
### --dispenser
(Optional) Alias of the dispenser account. Otherwise, will prompt the dispenser mnemonic if specified in .algokit.toml file.
### -p, --project-name
(Optional) Projects to execute the command on. Defaults to all projects found in the current directory. Option is mutually exclusive with command.
### Arguments
### ENVIRONMENT_NAME
Optional argument
### EXTRA_ARGS
Optional argument(s)
### link
Automatically invoke 'algokit generate client' on contract projects available in the workspace.
Must be invoked from the root of a standalone 'frontend' typed project.
```shell
algokit project link [OPTIONS]
```
### Options
### -p, --project-name
Specify contract projects for the command. Defaults to all in the current workspace.
### -l, --language
Programming language of the generated client code
* **Options**
python | typescript
### -a, --all
Link all contract projects with the frontend project Option is mutually exclusive with project_name.
### -f, --fail-fast
Exit immediately if at least one client generation process fails
### -v, --version
The client generator version to pin to, for example, 1.0.0. If no version is specified, AlgoKit checks if the client generator is installed and runs the installed version. If the client generator is not installed, AlgoKit runs the latest version. If a version is specified, AlgoKit checks if an installed version matches and runs the installed version. Otherwise, AlgoKit runs the specified version.
### list
List all projects in the workspace
```shell
algokit project list [OPTIONS] [WORKSPACE_PATH]
```
### Arguments
### WORKSPACE_PATH
Optional argument
### run
Define custom commands and manage their execution in you projects.
```shell
algokit project run [OPTIONS] COMMAND [ARGS]...
```
## task
Collection of useful tasks to help you develop on Algorand.
```shell
algokit task [OPTIONS] COMMAND [ARGS]...
```
### analyze
Analyze TEAL programs for common vulnerabilities using Tealer. This task uses a third party tool to suggest improvements for your TEAL programs, but remember to always test your smart contracts code, follow modern software engineering practices and use the guidelines for smart contract development. This should not be used as a substitute for an actual audit. For full list of available detectors, please refer to [https://github.com/crytic/tealer?tab=readme-ov-file#detectors](https://github.com/crytic/tealer?tab=readme-ov-file#detectors)
```shell
algokit task analyze [OPTIONS] INPUT_PATHS...
```
### Options
### -r, --recursive
Recursively search for all TEAL files within the provided directory.
### --force
Force verification without the disclaimer confirmation prompt.
### --diff
Exit with a non-zero code if differences are found between current and last reports. Reports are generated each run, but with this flag execution fails if the current report doesn't match the last report. Reports are stored in the .algokit/static-analysis/snapshots folder by default. Use --output for a custom path.
### -o, --output
Directory path where to store the results of the static analysis. Defaults to .algokit/static-analysis/snapshots.
### -e, --exclude
Exclude specific vulnerabilities from the analysis. Supports multiple exclusions in a single run.
### Arguments
### INPUT_PATHS
Required argument(s)
### ipfs
Upload files to IPFS using Pinata provider.
```shell
algokit task ipfs [OPTIONS] COMMAND [ARGS]...
```
#### login
Login to Pinata ipfs provider. You will be prompted for your JWT.
```shell
algokit task ipfs login [OPTIONS]
```
#### logout
Logout of Pinata ipfs provider.
```shell
algokit task ipfs logout [OPTIONS]
```
#### upload
Upload a file to Pinata ipfs provider. Please note, max file size is 100MB.
```shell
algokit task ipfs upload [OPTIONS]
```
### Options
### -f, --file
**Required** Path to the file to upload.
### -n, --name
Human readable name for this upload, for use in file listings.
### mint
Mint new fungible or non-fungible assets on Algorand.
```shell
algokit task mint [OPTIONS]
```
### Options
### --creator
**Required** Address or alias of the asset creator.
### --name
Asset name.
### -u, --unit
**Required** Unit name of the asset.
### -t, --total
Total supply of the asset. Defaults to 1.
### -d, --decimals
Number of decimals. Defaults to 0.
### --nft, --ft
Whether the asset should be validated as NFT or FT. Refers to NFT by default and validates canonical
definitions of pure or fractional NFTs as per ARC3 standard.
### -i, --image
**Required** Path to the asset image file to be uploaded to IPFS.
### -m, --metadata
Path to the ARC19 compliant asset metadata file to be uploaded to IPFS. If not provided,
a default metadata object will be generated automatically based on asset-name, decimals and image.
For more details refer to [https://arc.algorand.foundation/ARCs/arc-0003#json-metadata-file-schema](https://arc.algorand.foundation/ARCs/arc-0003#json-metadata-file-schema).
### --mutable, --immutable
Whether the asset should be mutable or immutable. Refers to ARC19 by default.
### -n, --network
Network to use. Refers to localnet by default.
* **Options**
localnet | testnet | mainnet
### nfd-lookup
Perform a lookup via NFD domain or address, returning the associated address or domain respectively.
```shell
algokit task nfd-lookup [OPTIONS] VALUE
```
### Options
### -o, --output