diff --git a/examples/generators/production_python_smart_contract_python/.tours/getting-started-with-your-algokit-project.tour b/examples/generators/production_python_smart_contract_python/.tours/getting-started-with-your-algokit-project.tour index 2c210ee..6d0f8b2 100644 --- a/examples/generators/production_python_smart_contract_python/.tours/getting-started-with-your-algokit-project.tour +++ b/examples/generators/production_python_smart_contract_python/.tours/getting-started-with-your-algokit-project.tour @@ -47,5 +47,10 @@ "description": "Uncomment the following lines to enable complementary utilities that will generate artifacts required for the [AlgoKit AVM Debugger](https://github.com/algorandfoundation/algokit-avm-vscode-debugger) VSCode plugin available on the [VSCode Extension Marketplace](https://marketplace.visualstudio.com/items?itemName=algorandfoundation.algokit-avm-vscode-debugger). A new folder will be automatically created in the `.algokit` directory with source maps of all TEAL contracts in this workspace, as well as traces that will appear in a folder at the root of the workspace. You can then use the traces as entry points to trigger the debug extension. Make sure to have the `.algokit.toml` file available at the root of the workspace.", "line": 15 } + { + "file": "smart_contracts/_helpers/__init__.py", + "description": "This folder contains helper scripts for contract management. These automate tasks like compiling, generating clients, and deploying. Usually, you won't need to edit these files, but advanced users can expand them for custom needs.", + "line": 1 + } ] } diff --git a/examples/generators/production_python_smart_contract_python/smart_contracts/__main__.py b/examples/generators/production_python_smart_contract_python/smart_contracts/__main__.py index f14eb5d..ab2e910 100644 --- a/examples/generators/production_python_smart_contract_python/smart_contracts/__main__.py +++ b/examples/generators/production_python_smart_contract_python/smart_contracts/__main__.py @@ -4,10 +4,9 @@ from dotenv import load_dotenv -from smart_contracts.config import contracts -from smart_contracts.helpers.build import build -from smart_contracts.helpers.deploy import deploy -from smart_contracts.helpers.util import find_app_spec_file +from smart_contracts._helpers.build import build +from smart_contracts._helpers.config import contracts +from smart_contracts._helpers.deploy import deploy # Uncomment the following lines to enable auto generation of AVM Debugger compliant sourcemap and simulation trace file. # Learn more about using AlgoKit AVM Debugger to debug your TEAL source codes and inspect various kinds of @@ -36,7 +35,14 @@ def main(action: str) -> None: for contract in contracts: logger.info(f"Deploying app {contract.name}") output_dir = artifact_path / contract.name - app_spec_file_name = find_app_spec_file(output_dir) + app_spec_file_name = next( + ( + file.name + for file in output_dir.iterdir() + if file.is_file() and file.suffixes == [".arc32", ".json"] + ), + None, + ) if app_spec_file_name is None: raise Exception("Could not deploy app, .arc32.json file not found") app_spec_path = output_dir / app_spec_file_name diff --git a/examples/generators/production_python_smart_contract_python/smart_contracts/helpers/__init__.py b/examples/generators/production_python_smart_contract_python/smart_contracts/_helpers/__init__.py similarity index 100% rename from examples/generators/production_python_smart_contract_python/smart_contracts/helpers/__init__.py rename to examples/generators/production_python_smart_contract_python/smart_contracts/_helpers/__init__.py diff --git a/examples/generators/production_python_smart_contract_python/smart_contracts/helpers/build.py b/examples/generators/production_python_smart_contract_python/smart_contracts/_helpers/build.py similarity index 93% rename from examples/generators/production_python_smart_contract_python/smart_contracts/helpers/build.py rename to examples/generators/production_python_smart_contract_python/smart_contracts/_helpers/build.py index a123086..771b585 100644 --- a/examples/generators/production_python_smart_contract_python/smart_contracts/helpers/build.py +++ b/examples/generators/production_python_smart_contract_python/smart_contracts/_helpers/build.py @@ -3,8 +3,6 @@ from pathlib import Path from shutil import rmtree -from smart_contracts.helpers.util import find_app_spec_files - logger = logging.getLogger(__name__) deployment_extension = "py" @@ -41,7 +39,7 @@ def build(output_dir: Path, contract_path: Path) -> Path: if build_result.returncode: raise Exception(f"Could not build contract:\n{build_result.stdout}") - app_spec_file_names = find_app_spec_files(output_dir) + app_spec_file_names = [file.name for file in output_dir.glob("*.arc32.json")] for app_spec_file_name in app_spec_file_names: if app_spec_file_name is None: @@ -73,4 +71,4 @@ def build(output_dir: Path, contract_path: Path) -> Path: f"Could not generate typed client:\n{generate_result.stdout}" ) - return output_dir + return output_dir / app_spec_file_name diff --git a/examples/generators/production_python_smart_contract_python/smart_contracts/config.py b/examples/generators/production_python_smart_contract_python/smart_contracts/_helpers/config.py similarity index 100% rename from examples/generators/production_python_smart_contract_python/smart_contracts/config.py rename to examples/generators/production_python_smart_contract_python/smart_contracts/_helpers/config.py diff --git a/examples/generators/production_python_smart_contract_python/smart_contracts/helpers/deploy.py b/examples/generators/production_python_smart_contract_python/smart_contracts/_helpers/deploy.py similarity index 100% rename from examples/generators/production_python_smart_contract_python/smart_contracts/helpers/deploy.py rename to examples/generators/production_python_smart_contract_python/smart_contracts/_helpers/deploy.py diff --git a/examples/generators/production_python_smart_contract_python/smart_contracts/helpers/util.py b/examples/generators/production_python_smart_contract_python/smart_contracts/helpers/util.py deleted file mode 100644 index 4670226..0000000 --- a/examples/generators/production_python_smart_contract_python/smart_contracts/helpers/util.py +++ /dev/null @@ -1,12 +0,0 @@ -from pathlib import Path - - -def find_app_spec_file(output_dir: Path) -> str | None: - for file in output_dir.iterdir(): - if file.is_file() and file.suffixes == [".arc32", ".json"]: - return file.name - return None - - -def find_app_spec_files(output_dir: Path) -> list[str]: - return [file.name for file in output_dir.glob("*.arc32.json")] diff --git a/examples/generators/production_python_smart_contract_typescript/.tours/getting-started-with-your-algokit-project.tour b/examples/generators/production_python_smart_contract_typescript/.tours/getting-started-with-your-algokit-project.tour index c166a39..2eb8a76 100644 --- a/examples/generators/production_python_smart_contract_typescript/.tours/getting-started-with-your-algokit-project.tour +++ b/examples/generators/production_python_smart_contract_typescript/.tours/getting-started-with-your-algokit-project.tour @@ -42,5 +42,10 @@ "description": "Uncomment the following lines to enable complementary utilities that will generate artifacts required for the [AlgoKit AVM Debugger](https://github.com/algorandfoundation/algokit-avm-vscode-debugger) VSCode plugin available on the [VSCode Extension Marketplace](https://marketplace.visualstudio.com/items?itemName=algorandfoundation.algokit-avm-vscode-debugger). A new folder will be automatically created in the `.algokit` directory with source maps of all TEAL contracts in this workspace, as well as traces that will appear in a folder at the root of the workspace. You can then use the traces as entry points to trigger the debug extension. Make sure to have the `.algokit.toml` file available at the root of the workspace.", "line": 15 } + { + "file": "smart_contracts/_helpers/__init__.py", + "description": "This folder contains helper scripts for contract management. These automate tasks like compiling, generating clients, and deploying. Usually, you won't need to edit these files, but advanced users can expand them for custom needs.", + "line": 1 + } ] } diff --git a/examples/generators/production_python_smart_contract_typescript/smart_contracts/__main__.py b/examples/generators/production_python_smart_contract_typescript/smart_contracts/__main__.py index cf91c3a..6cf51e4 100644 --- a/examples/generators/production_python_smart_contract_typescript/smart_contracts/__main__.py +++ b/examples/generators/production_python_smart_contract_typescript/smart_contracts/__main__.py @@ -4,8 +4,8 @@ from dotenv import load_dotenv -from smart_contracts.config import contracts -from smart_contracts.helpers.build import build +from smart_contracts._helpers.build import build +from smart_contracts._helpers.config import contracts logging.basicConfig( level=logging.DEBUG, format="%(asctime)s %(levelname)-10s: %(message)s" diff --git a/examples/generators/production_python_smart_contract_typescript/smart_contracts/helpers/__init__.py b/examples/generators/production_python_smart_contract_typescript/smart_contracts/_helpers/__init__.py similarity index 100% rename from examples/generators/production_python_smart_contract_typescript/smart_contracts/helpers/__init__.py rename to examples/generators/production_python_smart_contract_typescript/smart_contracts/_helpers/__init__.py diff --git a/examples/generators/production_python_smart_contract_typescript/smart_contracts/helpers/build.py b/examples/generators/production_python_smart_contract_typescript/smart_contracts/_helpers/build.py similarity index 93% rename from examples/generators/production_python_smart_contract_typescript/smart_contracts/helpers/build.py rename to examples/generators/production_python_smart_contract_typescript/smart_contracts/_helpers/build.py index fe55280..a78f2d9 100644 --- a/examples/generators/production_python_smart_contract_typescript/smart_contracts/helpers/build.py +++ b/examples/generators/production_python_smart_contract_typescript/smart_contracts/_helpers/build.py @@ -3,8 +3,6 @@ from pathlib import Path from shutil import rmtree -from smart_contracts.helpers.util import find_app_spec_files - logger = logging.getLogger(__name__) deployment_extension = "ts" @@ -41,7 +39,7 @@ def build(output_dir: Path, contract_path: Path) -> Path: if build_result.returncode: raise Exception(f"Could not build contract:\n{build_result.stdout}") - app_spec_file_names = find_app_spec_files(output_dir) + app_spec_file_names = [file.name for file in output_dir.glob("*.arc32.json")] for app_spec_file_name in app_spec_file_names: if app_spec_file_name is None: @@ -73,4 +71,4 @@ def build(output_dir: Path, contract_path: Path) -> Path: f"Could not generate typed client:\n{generate_result.stdout}" ) - return output_dir + return output_dir / app_spec_file_name diff --git a/examples/generators/production_python_smart_contract_typescript/smart_contracts/config.py b/examples/generators/production_python_smart_contract_typescript/smart_contracts/_helpers/config.py similarity index 100% rename from examples/generators/production_python_smart_contract_typescript/smart_contracts/config.py rename to examples/generators/production_python_smart_contract_typescript/smart_contracts/_helpers/config.py diff --git a/examples/generators/production_python_smart_contract_typescript/smart_contracts/helpers/util.py b/examples/generators/production_python_smart_contract_typescript/smart_contracts/helpers/util.py deleted file mode 100644 index 4670226..0000000 --- a/examples/generators/production_python_smart_contract_typescript/smart_contracts/helpers/util.py +++ /dev/null @@ -1,12 +0,0 @@ -from pathlib import Path - - -def find_app_spec_file(output_dir: Path) -> str | None: - for file in output_dir.iterdir(): - if file.is_file() and file.suffixes == [".arc32", ".json"]: - return file.name - return None - - -def find_app_spec_files(output_dir: Path) -> list[str]: - return [file.name for file in output_dir.glob("*.arc32.json")] diff --git a/examples/generators/starter_python_smart_contract_python/.tours/getting-started-with-your-algokit-project.tour b/examples/generators/starter_python_smart_contract_python/.tours/getting-started-with-your-algokit-project.tour index 445db2a..a82b9c9 100644 --- a/examples/generators/starter_python_smart_contract_python/.tours/getting-started-with-your-algokit-project.tour +++ b/examples/generators/starter_python_smart_contract_python/.tours/getting-started-with-your-algokit-project.tour @@ -42,5 +42,10 @@ "description": "Uncomment the following lines to enable complementary utilities that will generate artifacts required for the [AlgoKit AVM Debugger](https://github.com/algorandfoundation/algokit-avm-vscode-debugger) VSCode plugin available on the [VSCode Extension Marketplace](https://marketplace.visualstudio.com/items?itemName=algorandfoundation.algokit-avm-vscode-debugger). A new folder will be automatically created in the `.algokit` directory with source maps of all TEAL contracts in this workspace, as well as traces that will appear in a folder at the root of the workspace. You can then use the traces as entry points to trigger the debug extension. Make sure to have the `.algokit.toml` file available at the root of the workspace.", "line": 15 } + { + "file": "smart_contracts/_helpers/__init__.py", + "description": "This folder contains helper scripts for contract management. These automate tasks like compiling, generating clients, and deploying. Usually, you won't need to edit these files, but advanced users can expand them for custom needs.", + "line": 1 + } ] } diff --git a/examples/generators/starter_python_smart_contract_python/smart_contracts/__main__.py b/examples/generators/starter_python_smart_contract_python/smart_contracts/__main__.py index f14eb5d..ab2e910 100644 --- a/examples/generators/starter_python_smart_contract_python/smart_contracts/__main__.py +++ b/examples/generators/starter_python_smart_contract_python/smart_contracts/__main__.py @@ -4,10 +4,9 @@ from dotenv import load_dotenv -from smart_contracts.config import contracts -from smart_contracts.helpers.build import build -from smart_contracts.helpers.deploy import deploy -from smart_contracts.helpers.util import find_app_spec_file +from smart_contracts._helpers.build import build +from smart_contracts._helpers.config import contracts +from smart_contracts._helpers.deploy import deploy # Uncomment the following lines to enable auto generation of AVM Debugger compliant sourcemap and simulation trace file. # Learn more about using AlgoKit AVM Debugger to debug your TEAL source codes and inspect various kinds of @@ -36,7 +35,14 @@ def main(action: str) -> None: for contract in contracts: logger.info(f"Deploying app {contract.name}") output_dir = artifact_path / contract.name - app_spec_file_name = find_app_spec_file(output_dir) + app_spec_file_name = next( + ( + file.name + for file in output_dir.iterdir() + if file.is_file() and file.suffixes == [".arc32", ".json"] + ), + None, + ) if app_spec_file_name is None: raise Exception("Could not deploy app, .arc32.json file not found") app_spec_path = output_dir / app_spec_file_name diff --git a/examples/generators/starter_python_smart_contract_python/smart_contracts/helpers/__init__.py b/examples/generators/starter_python_smart_contract_python/smart_contracts/_helpers/__init__.py similarity index 100% rename from examples/generators/starter_python_smart_contract_python/smart_contracts/helpers/__init__.py rename to examples/generators/starter_python_smart_contract_python/smart_contracts/_helpers/__init__.py diff --git a/examples/generators/starter_python_smart_contract_python/smart_contracts/helpers/build.py b/examples/generators/starter_python_smart_contract_python/smart_contracts/_helpers/build.py similarity index 93% rename from examples/generators/starter_python_smart_contract_python/smart_contracts/helpers/build.py rename to examples/generators/starter_python_smart_contract_python/smart_contracts/_helpers/build.py index a123086..771b585 100644 --- a/examples/generators/starter_python_smart_contract_python/smart_contracts/helpers/build.py +++ b/examples/generators/starter_python_smart_contract_python/smart_contracts/_helpers/build.py @@ -3,8 +3,6 @@ from pathlib import Path from shutil import rmtree -from smart_contracts.helpers.util import find_app_spec_files - logger = logging.getLogger(__name__) deployment_extension = "py" @@ -41,7 +39,7 @@ def build(output_dir: Path, contract_path: Path) -> Path: if build_result.returncode: raise Exception(f"Could not build contract:\n{build_result.stdout}") - app_spec_file_names = find_app_spec_files(output_dir) + app_spec_file_names = [file.name for file in output_dir.glob("*.arc32.json")] for app_spec_file_name in app_spec_file_names: if app_spec_file_name is None: @@ -73,4 +71,4 @@ def build(output_dir: Path, contract_path: Path) -> Path: f"Could not generate typed client:\n{generate_result.stdout}" ) - return output_dir + return output_dir / app_spec_file_name diff --git a/examples/generators/starter_python_smart_contract_python/smart_contracts/config.py b/examples/generators/starter_python_smart_contract_python/smart_contracts/_helpers/config.py similarity index 100% rename from examples/generators/starter_python_smart_contract_python/smart_contracts/config.py rename to examples/generators/starter_python_smart_contract_python/smart_contracts/_helpers/config.py diff --git a/examples/generators/starter_python_smart_contract_python/smart_contracts/helpers/deploy.py b/examples/generators/starter_python_smart_contract_python/smart_contracts/_helpers/deploy.py similarity index 100% rename from examples/generators/starter_python_smart_contract_python/smart_contracts/helpers/deploy.py rename to examples/generators/starter_python_smart_contract_python/smart_contracts/_helpers/deploy.py diff --git a/examples/generators/starter_python_smart_contract_python/smart_contracts/helpers/util.py b/examples/generators/starter_python_smart_contract_python/smart_contracts/helpers/util.py deleted file mode 100644 index 4670226..0000000 --- a/examples/generators/starter_python_smart_contract_python/smart_contracts/helpers/util.py +++ /dev/null @@ -1,12 +0,0 @@ -from pathlib import Path - - -def find_app_spec_file(output_dir: Path) -> str | None: - for file in output_dir.iterdir(): - if file.is_file() and file.suffixes == [".arc32", ".json"]: - return file.name - return None - - -def find_app_spec_files(output_dir: Path) -> list[str]: - return [file.name for file in output_dir.glob("*.arc32.json")] diff --git a/examples/generators/starter_python_smart_contract_typescript/.tours/getting-started-with-your-algokit-project.tour b/examples/generators/starter_python_smart_contract_typescript/.tours/getting-started-with-your-algokit-project.tour index c166a39..2eb8a76 100644 --- a/examples/generators/starter_python_smart_contract_typescript/.tours/getting-started-with-your-algokit-project.tour +++ b/examples/generators/starter_python_smart_contract_typescript/.tours/getting-started-with-your-algokit-project.tour @@ -42,5 +42,10 @@ "description": "Uncomment the following lines to enable complementary utilities that will generate artifacts required for the [AlgoKit AVM Debugger](https://github.com/algorandfoundation/algokit-avm-vscode-debugger) VSCode plugin available on the [VSCode Extension Marketplace](https://marketplace.visualstudio.com/items?itemName=algorandfoundation.algokit-avm-vscode-debugger). A new folder will be automatically created in the `.algokit` directory with source maps of all TEAL contracts in this workspace, as well as traces that will appear in a folder at the root of the workspace. You can then use the traces as entry points to trigger the debug extension. Make sure to have the `.algokit.toml` file available at the root of the workspace.", "line": 15 } + { + "file": "smart_contracts/_helpers/__init__.py", + "description": "This folder contains helper scripts for contract management. These automate tasks like compiling, generating clients, and deploying. Usually, you won't need to edit these files, but advanced users can expand them for custom needs.", + "line": 1 + } ] } diff --git a/examples/generators/starter_python_smart_contract_typescript/smart_contracts/__main__.py b/examples/generators/starter_python_smart_contract_typescript/smart_contracts/__main__.py index cf91c3a..6cf51e4 100644 --- a/examples/generators/starter_python_smart_contract_typescript/smart_contracts/__main__.py +++ b/examples/generators/starter_python_smart_contract_typescript/smart_contracts/__main__.py @@ -4,8 +4,8 @@ from dotenv import load_dotenv -from smart_contracts.config import contracts -from smart_contracts.helpers.build import build +from smart_contracts._helpers.build import build +from smart_contracts._helpers.config import contracts logging.basicConfig( level=logging.DEBUG, format="%(asctime)s %(levelname)-10s: %(message)s" diff --git a/examples/generators/starter_python_smart_contract_typescript/smart_contracts/helpers/__init__.py b/examples/generators/starter_python_smart_contract_typescript/smart_contracts/_helpers/__init__.py similarity index 100% rename from examples/generators/starter_python_smart_contract_typescript/smart_contracts/helpers/__init__.py rename to examples/generators/starter_python_smart_contract_typescript/smart_contracts/_helpers/__init__.py diff --git a/examples/generators/starter_python_smart_contract_typescript/smart_contracts/helpers/build.py b/examples/generators/starter_python_smart_contract_typescript/smart_contracts/_helpers/build.py similarity index 93% rename from examples/generators/starter_python_smart_contract_typescript/smart_contracts/helpers/build.py rename to examples/generators/starter_python_smart_contract_typescript/smart_contracts/_helpers/build.py index fe55280..a78f2d9 100644 --- a/examples/generators/starter_python_smart_contract_typescript/smart_contracts/helpers/build.py +++ b/examples/generators/starter_python_smart_contract_typescript/smart_contracts/_helpers/build.py @@ -3,8 +3,6 @@ from pathlib import Path from shutil import rmtree -from smart_contracts.helpers.util import find_app_spec_files - logger = logging.getLogger(__name__) deployment_extension = "ts" @@ -41,7 +39,7 @@ def build(output_dir: Path, contract_path: Path) -> Path: if build_result.returncode: raise Exception(f"Could not build contract:\n{build_result.stdout}") - app_spec_file_names = find_app_spec_files(output_dir) + app_spec_file_names = [file.name for file in output_dir.glob("*.arc32.json")] for app_spec_file_name in app_spec_file_names: if app_spec_file_name is None: @@ -73,4 +71,4 @@ def build(output_dir: Path, contract_path: Path) -> Path: f"Could not generate typed client:\n{generate_result.stdout}" ) - return output_dir + return output_dir / app_spec_file_name diff --git a/examples/generators/starter_python_smart_contract_typescript/smart_contracts/config.py b/examples/generators/starter_python_smart_contract_typescript/smart_contracts/_helpers/config.py similarity index 100% rename from examples/generators/starter_python_smart_contract_typescript/smart_contracts/config.py rename to examples/generators/starter_python_smart_contract_typescript/smart_contracts/_helpers/config.py diff --git a/examples/generators/starter_python_smart_contract_typescript/smart_contracts/helpers/util.py b/examples/generators/starter_python_smart_contract_typescript/smart_contracts/helpers/util.py deleted file mode 100644 index 4670226..0000000 --- a/examples/generators/starter_python_smart_contract_typescript/smart_contracts/helpers/util.py +++ /dev/null @@ -1,12 +0,0 @@ -from pathlib import Path - - -def find_app_spec_file(output_dir: Path) -> str | None: - for file in output_dir.iterdir(): - if file.is_file() and file.suffixes == [".arc32", ".json"]: - return file.name - return None - - -def find_app_spec_files(output_dir: Path) -> list[str]: - return [file.name for file in output_dir.glob("*.arc32.json")] diff --git a/examples/production_python/.tours/getting-started-with-your-algokit-project.tour b/examples/production_python/.tours/getting-started-with-your-algokit-project.tour index 2c210ee..6d0f8b2 100644 --- a/examples/production_python/.tours/getting-started-with-your-algokit-project.tour +++ b/examples/production_python/.tours/getting-started-with-your-algokit-project.tour @@ -47,5 +47,10 @@ "description": "Uncomment the following lines to enable complementary utilities that will generate artifacts required for the [AlgoKit AVM Debugger](https://github.com/algorandfoundation/algokit-avm-vscode-debugger) VSCode plugin available on the [VSCode Extension Marketplace](https://marketplace.visualstudio.com/items?itemName=algorandfoundation.algokit-avm-vscode-debugger). A new folder will be automatically created in the `.algokit` directory with source maps of all TEAL contracts in this workspace, as well as traces that will appear in a folder at the root of the workspace. You can then use the traces as entry points to trigger the debug extension. Make sure to have the `.algokit.toml` file available at the root of the workspace.", "line": 15 } + { + "file": "smart_contracts/_helpers/__init__.py", + "description": "This folder contains helper scripts for contract management. These automate tasks like compiling, generating clients, and deploying. Usually, you won't need to edit these files, but advanced users can expand them for custom needs.", + "line": 1 + } ] } diff --git a/examples/production_python/smart_contracts/__main__.py b/examples/production_python/smart_contracts/__main__.py index f14eb5d..ab2e910 100644 --- a/examples/production_python/smart_contracts/__main__.py +++ b/examples/production_python/smart_contracts/__main__.py @@ -4,10 +4,9 @@ from dotenv import load_dotenv -from smart_contracts.config import contracts -from smart_contracts.helpers.build import build -from smart_contracts.helpers.deploy import deploy -from smart_contracts.helpers.util import find_app_spec_file +from smart_contracts._helpers.build import build +from smart_contracts._helpers.config import contracts +from smart_contracts._helpers.deploy import deploy # Uncomment the following lines to enable auto generation of AVM Debugger compliant sourcemap and simulation trace file. # Learn more about using AlgoKit AVM Debugger to debug your TEAL source codes and inspect various kinds of @@ -36,7 +35,14 @@ def main(action: str) -> None: for contract in contracts: logger.info(f"Deploying app {contract.name}") output_dir = artifact_path / contract.name - app_spec_file_name = find_app_spec_file(output_dir) + app_spec_file_name = next( + ( + file.name + for file in output_dir.iterdir() + if file.is_file() and file.suffixes == [".arc32", ".json"] + ), + None, + ) if app_spec_file_name is None: raise Exception("Could not deploy app, .arc32.json file not found") app_spec_path = output_dir / app_spec_file_name diff --git a/examples/production_python/smart_contracts/helpers/__init__.py b/examples/production_python/smart_contracts/_helpers/__init__.py similarity index 100% rename from examples/production_python/smart_contracts/helpers/__init__.py rename to examples/production_python/smart_contracts/_helpers/__init__.py diff --git a/examples/production_python/smart_contracts/helpers/build.py b/examples/production_python/smart_contracts/_helpers/build.py similarity index 93% rename from examples/production_python/smart_contracts/helpers/build.py rename to examples/production_python/smart_contracts/_helpers/build.py index a123086..771b585 100644 --- a/examples/production_python/smart_contracts/helpers/build.py +++ b/examples/production_python/smart_contracts/_helpers/build.py @@ -3,8 +3,6 @@ from pathlib import Path from shutil import rmtree -from smart_contracts.helpers.util import find_app_spec_files - logger = logging.getLogger(__name__) deployment_extension = "py" @@ -41,7 +39,7 @@ def build(output_dir: Path, contract_path: Path) -> Path: if build_result.returncode: raise Exception(f"Could not build contract:\n{build_result.stdout}") - app_spec_file_names = find_app_spec_files(output_dir) + app_spec_file_names = [file.name for file in output_dir.glob("*.arc32.json")] for app_spec_file_name in app_spec_file_names: if app_spec_file_name is None: @@ -73,4 +71,4 @@ def build(output_dir: Path, contract_path: Path) -> Path: f"Could not generate typed client:\n{generate_result.stdout}" ) - return output_dir + return output_dir / app_spec_file_name diff --git a/examples/production_python/smart_contracts/config.py b/examples/production_python/smart_contracts/_helpers/config.py similarity index 100% rename from examples/production_python/smart_contracts/config.py rename to examples/production_python/smart_contracts/_helpers/config.py diff --git a/examples/production_python/smart_contracts/helpers/deploy.py b/examples/production_python/smart_contracts/_helpers/deploy.py similarity index 100% rename from examples/production_python/smart_contracts/helpers/deploy.py rename to examples/production_python/smart_contracts/_helpers/deploy.py diff --git a/examples/production_python/smart_contracts/helpers/util.py b/examples/production_python/smart_contracts/helpers/util.py deleted file mode 100644 index 4670226..0000000 --- a/examples/production_python/smart_contracts/helpers/util.py +++ /dev/null @@ -1,12 +0,0 @@ -from pathlib import Path - - -def find_app_spec_file(output_dir: Path) -> str | None: - for file in output_dir.iterdir(): - if file.is_file() and file.suffixes == [".arc32", ".json"]: - return file.name - return None - - -def find_app_spec_files(output_dir: Path) -> list[str]: - return [file.name for file in output_dir.glob("*.arc32.json")] diff --git a/examples/starter_python/.algokit.toml b/examples/starter_python/.algokit.toml deleted file mode 100644 index ead1544..0000000 --- a/examples/starter_python/.algokit.toml +++ /dev/null @@ -1,42 +0,0 @@ -[algokit] -min_version = "v2.0.0" - -[generate.smart-contract] -description = "Generate a new smart contract for existing project" -path = ".algokit/generators/create_contract" - -[generate.env-file] -description = "Generate a new generic or Algorand network specific .env file" -path = ".algokit/generators/create_env_file" - -[project] -type = 'contract' -name = 'starter_python' -artifacts = 'smart_contracts/artifacts' - -[project.deploy] -command = "poetry run python -m smart_contracts deploy" -environment_secrets = [ - "DEPLOYER_MNEMONIC", -] - -[project.deploy.localnet] -environment_secrets = [] - -[project.run] -# Commands intented for use locally and in CI -build = { commands = [ - 'poetry run python -m smart_contracts build', -], description = 'Build all smart contracts in the project' } -lint = { commands = [ -], description = 'Perform linting' } -audit-teal = { commands = [ - # 🚨 IMPORTANT 🚨: For strict TEAL validation, remove --exclude statements. The default starter contract is not for production. Ensure thorough testing and adherence to best practices in smart contract development. This is not a replacement for a professional audit. - 'algokit task analyze smart_contracts/artifacts --recursive --force --exclude rekey-to --exclude is-updatable --exclude missing-fee-check --exclude is-deletable --exclude can-close-asset --exclude can-close-account --exclude unprotected-deletable --exclude unprotected-updatable', -], description = 'Audit TEAL files' } - -# Commands intented for CI only, prefixed with `ci-` by convention -ci-teal-diff = { commands = [ - 'git add -N ./smart_contracts/artifacts', - 'git diff --exit-code --minimal ./smart_contracts/artifacts', -], description = 'Check TEAL files for differences' } diff --git a/examples/starter_python/.editorconfig b/examples/starter_python/.editorconfig deleted file mode 100644 index e2fda34..0000000 --- a/examples/starter_python/.editorconfig +++ /dev/null @@ -1,10 +0,0 @@ -root=true - -[*] -indent_style = space -indent_size = 2 -end_of_line = lf -insert_final_newline = true - -[*.py] -indent_size = 4 diff --git a/examples/starter_python/.gitattributes b/examples/starter_python/.gitattributes deleted file mode 100644 index 6313b56..0000000 --- a/examples/starter_python/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -* text=auto eol=lf diff --git a/examples/starter_python/.gitignore b/examples/starter_python/.gitignore deleted file mode 100644 index a858d63..0000000 --- a/examples/starter_python/.gitignore +++ /dev/null @@ -1,180 +0,0 @@ -# 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/ -coverage/ - -# 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/ -.env.* -!.env.*.template -!.env.template -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/ -.idea/* -!.idea/runConfigurations/ - -# macOS -.DS_Store - -# Received approval test files -*.received.* - -# NPM -node_modules - -# AlgoKit -debug_traces/ -.algokit/static-analysis/tealer/ -.algokit/sources diff --git a/examples/starter_python/.tours/getting-started-with-your-algokit-project.tour b/examples/starter_python/.tours/getting-started-with-your-algokit-project.tour deleted file mode 100644 index 445db2a..0000000 --- a/examples/starter_python/.tours/getting-started-with-your-algokit-project.tour +++ /dev/null @@ -1,46 +0,0 @@ -{ - "$schema": "https://aka.ms/codetour-schema", - "title": "Getting Started with Your AlgoKit Project", - "steps": [ - { - "file": "README.md", - "description": "Welcome to your brand new AlgoKit template-based project. In this tour, we will guide you through the main features and capabilities included in the template.", - "line": 3 - }, - { - "file": "README.md", - "description": "Start by ensuring you have followed the setup of pre-requisites.", - "line": 9 - }, - { - "file": ".algokit.toml", - "description": "This is the main configuration file used by algokit-cli to manage the project. The default template includes a starter 'Hello World' contract that is deployed via the `algokit-utils` package (either `ts` or `py`, depending on your choice). To create a new smart contract, you can use the [`algokit generate`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/generate.md) command and invoke a pre-bundled generator template by running `algokit generate smart-contract` (see how it is defined in the `.algokit.toml`, you can create your own generators if needed). This action will create a new folder in the `smart_contracts` directory, named after your project. Each folder contains a `contract.py` file, which is the entry point for your contract implementation, and `deploy_config.py` | `deployConfig.ts` files (depending on the language chosen for the template), that perform the deployment of the contract. Additionally you can define custom commands to run (similar to `npm` scripts), see definitions under `[project]` section in `.algokit.toml`.", - "line": 1 - }, - { - "file": "smart_contracts/hello_world/deploy_config.py", - "description": "The default deployment scripts invoke a sample method on the starter contract that demonstrates how to interact with your deployed Algorand on-chain applications using the [`AlgoKit Typed Clients`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/generate.md#1-typed-clients) feature. The invocation if deploy is aliased in `.algokit.toml` file, allowing simple deployments via `algokit project deploy` command.", - "line": 32 - }, - { - "file": ".env.localnet.template", - "description": "Environment files are a crucial mechanism that allows you to set up the [`algokit deploy`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/deploy.md) feature to simplify deploying your contracts in CI/CD environments (please note we still recommend careful evaluation when it comes to deployment to MainNet). Clone the file and remove the `.template` suffix to apply the changes to deployment scripts and launch configurations. The network prefix `localnet|testnet|mainnet` is primarily optimized for `algokit deploy`. The order of loading the variables is `.env.{network}` < `.env`.", - "line": 2 - }, - { - "file": ".vscode/launch.json", - "description": "Refer to the pre-bundled Visual Studio launch configurations, offering various options on how to execute the build and deployment of your smart contracts. Alternatively execute `algokit project run` to see list of available custom commands.", - "line": 5 - }, - { - "file": ".vscode/extensions.json", - "description": "We highly recommend installing the recommended extensions to get the most out of this template starter project in your VSCode IDE.", - "line": 3 - }, - { - "file": "smart_contracts/__main__.py", - "description": "Uncomment the following lines to enable complementary utilities that will generate artifacts required for the [AlgoKit AVM Debugger](https://github.com/algorandfoundation/algokit-avm-vscode-debugger) VSCode plugin available on the [VSCode Extension Marketplace](https://marketplace.visualstudio.com/items?itemName=algorandfoundation.algokit-avm-vscode-debugger). A new folder will be automatically created in the `.algokit` directory with source maps of all TEAL contracts in this workspace, as well as traces that will appear in a folder at the root of the workspace. You can then use the traces as entry points to trigger the debug extension. Make sure to have the `.algokit.toml` file available at the root of the workspace.", - "line": 15 - } - ] -} diff --git a/examples/starter_python/.vscode/extensions.json b/examples/starter_python/.vscode/extensions.json deleted file mode 100644 index e16b76b..0000000 --- a/examples/starter_python/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "ms-python.python", - "tamasfe.even-better-toml", - "editorconfig.editorconfig", - "vsls-contrib.codetour", - "algorandfoundation.algokit-avm-vscode-debugger" - ] -} diff --git a/examples/starter_python/.vscode/launch.json b/examples/starter_python/.vscode/launch.json deleted file mode 100644 index dbaea6e..0000000 --- a/examples/starter_python/.vscode/launch.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Build & Deploy contracts", - "type": "python", - "request": "launch", - "module": "smart_contracts", - "cwd": "${workspaceFolder}", - "preLaunchTask": "Start AlgoKit LocalNet", - "env": { - "ALGOD_TOKEN": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "ALGOD_SERVER": "http://localhost", - "ALGOD_PORT": "4001", - "INDEXER_TOKEN": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "INDEXER_SERVER": "http://localhost", - "INDEXER_PORT": "8980" - } - }, - { - "name": "Deploy contracts", - "type": "python", - "request": "launch", - "module": "smart_contracts", - "args": ["deploy"], - "cwd": "${workspaceFolder}", - "env": { - "ALGOD_TOKEN": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "ALGOD_SERVER": "http://localhost", - "ALGOD_PORT": "4001", - "INDEXER_TOKEN": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "INDEXER_SERVER": "http://localhost", - "INDEXER_PORT": "8980" - } - }, - { - "name": "Build contracts", - "type": "python", - "request": "launch", - "module": "smart_contracts", - "args": ["build"], - "cwd": "${workspaceFolder}" - }, - { - "type": "avm", - "request": "launch", - "name": "Debug TEAL via AlgoKit AVM Debugger", - "simulateTraceFile": "${workspaceFolder}/${command:PickSimulateTraceFile}", - "stopOnEntry": true - } - ] -} diff --git a/examples/starter_python/.vscode/settings.json b/examples/starter_python/.vscode/settings.json deleted file mode 100644 index 687f930..0000000 --- a/examples/starter_python/.vscode/settings.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - // General - see also /.editorconfig - "editor.formatOnSave": true, - "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.analysis.extraPaths": ["${workspaceFolder}/smart_contracts"], - "python.analysis.diagnosticSeverityOverrides": { - "reportMissingModuleSource": "none" - }, - "python.defaultInterpreterPath": "${workspaceFolder}/.venv", - "[python]": { - "editor.codeActionsOnSave": { - "source.fixAll": "explicit", - // Prevent default import sorting from running; Ruff will sort imports for us anyway - "source.organizeImports": "never" - }, - "editor.defaultFormatter": null, - }, - - // On Windows, if execution policy is set to Signed (default) then it won't be able to activate the venv - // so instead let's set it to RemoteSigned for VS Code terminal - "terminal.integrated.shellArgs.windows": ["-ExecutionPolicy", "RemoteSigned"], -} diff --git a/examples/starter_python/.vscode/tasks.json b/examples/starter_python/.vscode/tasks.json deleted file mode 100644 index eb1e767..0000000 --- a/examples/starter_python/.vscode/tasks.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Build contracts", - "command": "${workspaceFolder}/.venv/bin/python", - "windows": { - "command": "${workspaceFolder}/.venv/Scripts/python.exe" - }, - "args": ["-m", "smart_contracts", "build"], - "options": { - "cwd": "${workspaceFolder}" - }, - "group": { - "kind": "build", - "isDefault": true - }, - "problemMatcher": [] - }, - { - "label": "Build contracts (+ LocalNet)", - "command": "${workspaceFolder}/.venv/bin/python", - "windows": { - "command": "${workspaceFolder}/.venv/Scripts/python.exe" - }, - "args": ["-m", "smart_contracts", "build"], - "options": { - "cwd": "${workspaceFolder}" - }, - "dependsOn": "Start AlgoKit LocalNet", - "problemMatcher": [] - }, - { - "label": "Start AlgoKit LocalNet", - "command": "algokit", - "args": ["localnet", "start"], - "type": "shell", - "options": { - "cwd": "${workspaceFolder}" - }, - "problemMatcher": [] - }, - { - "label": "Stop AlgoKit LocalNet", - "command": "algokit", - "args": ["localnet", "stop"], - "type": "shell", - "options": { - "cwd": "${workspaceFolder}" - }, - "problemMatcher": [] - }, - { - "label": "Reset AlgoKit LocalNet", - "command": "algokit", - "args": ["localnet", "reset"], - "type": "shell", - "options": { - "cwd": "${workspaceFolder}" - }, - "problemMatcher": [] - }, - { - "label": "Analyze TEAL contracts with AlgoKit Tealer integration", - "command": "algokit", - "args": [ - "task", - "analyze", - "${workspaceFolder}/.algokit", - "--recursive", - "--force" - ], - "options": { - "cwd": "${workspaceFolder}" - }, - "problemMatcher": [] - } - ] -} diff --git a/examples/starter_python/README.md b/examples/starter_python/README.md deleted file mode 100644 index d0f66e1..0000000 --- a/examples/starter_python/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# starter_python - -This project has been generated using AlgoKit. See below for default getting started instructions. - -# Setup - -### Pre-requisites - -- [Python 3.12](https://www.python.org/downloads/) or later -- [Docker](https://www.docker.com/) (only required for LocalNet) - -> For interactive tour over the codebase, download [vsls-contrib.codetour](https://marketplace.visualstudio.com/items?itemName=vsls-contrib.codetour) extension for VS Code, then open the [`.codetour.json`](./.tours/getting-started-with-your-algokit-project.tour) file in code tour extension. - -### Initial Setup - -#### 1. Clone the Repository -Start by cloning this repository to your local machine. - -#### 2. Install Pre-requisites -Ensure the following pre-requisites are installed and properly configured: - -- **Docker**: Required for running a local Algorand network. [Install Docker](https://www.docker.com/). -- **AlgoKit CLI**: Essential for project setup and operations. Install the latest version from [AlgoKit CLI Installation Guide](https://github.com/algorandfoundation/algokit-cli#install). Verify installation with `algokit --version`, expecting `2.0.0` or later. - -#### 3. Bootstrap Your Local Environment -Run the following commands within the project folder: - -- **Install Poetry**: Required for Python dependency management. [Installation Guide](https://python-poetry.org/docs/#installation). Verify with `poetry -V` to see version `1.2`+. -- **Setup Project**: Execute `algokit project bootstrap all` to install dependencies and setup a Python virtual environment in `.venv`. -- **Configure environment**: Execute `algokit generate env-file -a target_network localnet` to create a `.env.localnet` file with default configuration for `localnet`. -- **Start LocalNet**: Use `algokit localnet start` to initiate a local Algorand network. - -### Development Workflow - -#### Terminal -Directly manage and interact with your project using AlgoKit commands: - -1. **Build Contracts**: `algokit project run build` compiles all smart contracts. -2. **Deploy**: Use `algokit project deploy localnet` to deploy contracts to the local network. - -#### VS Code -For a seamless experience with breakpoint debugging and other features: - -1. **Open Project**: In VS Code, open the repository root. -2. **Install Extensions**: Follow prompts to install recommended extensions. -3. **Debugging**: - - Use `F5` to start debugging. - - **Windows Users**: Select the Python interpreter at `./.venv/Scripts/python.exe` via `Ctrl/Cmd + Shift + P` > `Python: Select Interpreter` before the first run. - -#### JetBrains IDEs -While primarily optimized for VS Code, JetBrains IDEs are supported: - -1. **Open Project**: In your JetBrains IDE, open the repository root. -2. **Automatic Setup**: The IDE should configure the Python interpreter and virtual environment. -3. **Debugging**: Use `Shift+F10` or `Ctrl+R` to start debugging. Note: Windows users may encounter issues with pre-launch tasks due to a known bug. See [JetBrains forums](https://youtrack.jetbrains.com/issue/IDEA-277486/Shell-script-configuration-cannot-run-as-before-launch-task) for workarounds. - -## AlgoKit Workspaces and Project Management -This project supports both standalone and monorepo setups through AlgoKit workspaces. Leverage [`algokit project run`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/run.md) commands for efficient monorepo project orchestration and management across multiple projects within a workspace. - -## AlgoKit Generators - -This template provides a set of [algokit generators](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/generate.md) that allow you to further modify the project instantiated from the template to fit your needs, as well as giving you a base to build your own extensions to invoke via the `algokit generate` command. - -### Generate Smart Contract - -By default the template creates a single `HelloWorld` contract under hello_world folder in the `smart_contracts` directory. To add a new contract: - -1. From the root of the project (`../`) execute `algokit generate smart-contract`. This will create a new starter smart contract and deployment configuration file under `{your_contract_name}` subfolder in the `smart_contracts` directory. -2. Each contract potentially has different creation parameters and deployment steps. Hence, you need to define your deployment logic in `deploy_config.py`file. -3. `config.py` file will automatically build all contracts in the `smart_contracts` directory. If you want to build specific contracts manually, modify the default code provided by the template in `config.py` file. - -> Please note, above is just a suggested convention tailored for the base configuration and structure of this template. The default code supplied by the template in `config.py` and `index.ts` (if using ts clients) files are tailored for the suggested convention. You are free to modify the structure and naming conventions as you see fit. - -### Generate '.env' files - -By default the template instance does not contain any env files. Using [`algokit project deploy`](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/deploy.md) against `localnet` | `testnet` | `mainnet` will use default values for `algod` and `indexer` unless overwritten via `.env` or `.env.{target_network}`. - -To generate a new `.env` or `.env.{target_network}` file, run `algokit generate env-file` - -# Tools - -This project makes use of Algorand Python to build Algorand smart contracts. The following tools are in use: - -- [Algorand](https://www.algorand.com/) - Layer 1 Blockchain; [Developer portal](https://developer.algorand.org/), [Why Algorand?](https://developer.algorand.org/docs/get-started/basics/why_algorand/) -- [AlgoKit](https://github.com/algorandfoundation/algokit-cli) - One-stop shop tool for developers building on the Algorand network; [docs](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/algokit.md), [intro tutorial](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/tutorials/intro.md) -- [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); [docs](https://github.com/algorandfoundation/puya), [examples](https://github.com/algorandfoundation/puya/tree/main/examples) -- [AlgoKit Utils](https://github.com/algorandfoundation/algokit-utils-py) - A set of core Algorand utilities that make it easier to build solutions on Algorand. -- [Poetry](https://python-poetry.org/): Python packaging and dependency management. -It has also been configured to have a productive dev experience out of the box in [VS Code](https://code.visualstudio.com/), see the [.vscode](./.vscode) folder. - diff --git a/examples/starter_python/poetry.toml b/examples/starter_python/poetry.toml deleted file mode 100644 index ab1033b..0000000 --- a/examples/starter_python/poetry.toml +++ /dev/null @@ -1,2 +0,0 @@ -[virtualenvs] -in-project = true diff --git a/examples/starter_python/pyproject.toml b/examples/starter_python/pyproject.toml deleted file mode 100644 index e03f88a..0000000 --- a/examples/starter_python/pyproject.toml +++ /dev/null @@ -1,22 +0,0 @@ -[tool.poetry] -name = "starter_python" -version = "0.1.0" -description = "Algorand smart contracts" -authors = ["None "] -readme = "README.md" - -[tool.poetry.dependencies] -python = "^3.12" -algokit-utils = "^2.3.0" -python-dotenv = "^1.0.0" -algorand-python = "^1.0.0" -algorand-python-testing = "^0.2.1" - -[tool.poetry.group.dev.dependencies] -algokit-client-generator = "^1.1.3" -puyapy = "*" - -[build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" - diff --git a/examples/starter_python/smart_contracts/__main__.py b/examples/starter_python/smart_contracts/__main__.py deleted file mode 100644 index f14eb5d..0000000 --- a/examples/starter_python/smart_contracts/__main__.py +++ /dev/null @@ -1,58 +0,0 @@ -import logging -import sys -from pathlib import Path - -from dotenv import load_dotenv - -from smart_contracts.config import contracts -from smart_contracts.helpers.build import build -from smart_contracts.helpers.deploy import deploy -from smart_contracts.helpers.util import find_app_spec_file - -# Uncomment the following lines to enable auto generation of AVM Debugger compliant sourcemap and simulation trace file. -# Learn more about using AlgoKit AVM Debugger to debug your TEAL source codes and inspect various kinds of -# Algorand transactions in atomic groups -> https://github.com/algorandfoundation/algokit-avm-vscode-debugger -# from algokit_utils.config import config -# config.configure(debug=True, trace_all=True) -logging.basicConfig( - level=logging.DEBUG, format="%(asctime)s %(levelname)-10s: %(message)s" -) -logger = logging.getLogger(__name__) -logger.info("Loading .env") -# For manual script execution (bypassing `algokit project deploy`) with a custom .env, -# modify `load_dotenv()` accordingly. For example, `load_dotenv('.env.localnet')`. -load_dotenv() -root_path = Path(__file__).parent - - -def main(action: str) -> None: - artifact_path = root_path / "artifacts" - match action: - case "build": - for contract in contracts: - logger.info(f"Building app at {contract.path}") - build(artifact_path / contract.name, contract.path) - case "deploy": - for contract in contracts: - logger.info(f"Deploying app {contract.name}") - output_dir = artifact_path / contract.name - app_spec_file_name = find_app_spec_file(output_dir) - if app_spec_file_name is None: - raise Exception("Could not deploy app, .arc32.json file not found") - app_spec_path = output_dir / app_spec_file_name - if contract.deploy: - deploy(app_spec_path, contract.deploy) - case "all": - for contract in contracts: - logger.info(f"Building app at {contract.path}") - app_spec_path = build(artifact_path / contract.name, contract.path) - logger.info(f"Deploying {contract.path.name}") - if contract.deploy: - deploy(app_spec_path, contract.deploy) - - -if __name__ == "__main__": - if len(sys.argv) > 1: - main(sys.argv[1]) - else: - main("all") diff --git a/examples/starter_python/smart_contracts/config.py b/examples/starter_python/smart_contracts/config.py deleted file mode 100644 index 8f3ca93..0000000 --- a/examples/starter_python/smart_contracts/config.py +++ /dev/null @@ -1,61 +0,0 @@ -import dataclasses -import importlib -from collections.abc import Callable -from pathlib import Path - -from algokit_utils import Account, ApplicationSpecification -from algosdk.v2client.algod import AlgodClient -from algosdk.v2client.indexer import IndexerClient - - -@dataclasses.dataclass -class SmartContract: - path: Path - name: str - deploy: ( - Callable[[AlgodClient, IndexerClient, ApplicationSpecification, Account], None] - | None - ) = None - - -def import_contract(folder: Path) -> Path: - """Imports the contract from a folder if it exists.""" - contract_path = folder / "contract.py" - if contract_path.exists(): - return contract_path - else: - raise Exception(f"Contract not found in {folder}") - - -def import_deploy_if_exists( - folder: Path, -) -> ( - Callable[[AlgodClient, IndexerClient, ApplicationSpecification, Account], None] - | None -): - """Imports the deploy function from a folder if it exists.""" - try: - deploy_module = importlib.import_module( - f"{folder.parent.name}.{folder.name}.deploy_config" - ) - return deploy_module.deploy # type: ignore - except ImportError: - return None - - -def has_contract_file(directory: Path) -> bool: - """Checks whether the directory contains contract.py file.""" - return (directory / "contract.py").exists() - - -# define contracts to build and/or deploy -base_dir = Path("smart_contracts") -contracts = [ - SmartContract( - path=import_contract(folder), - name=folder.name, - deploy=import_deploy_if_exists(folder), - ) - for folder in base_dir.iterdir() - if folder.is_dir() and has_contract_file(folder) -] diff --git a/examples/starter_python/smart_contracts/hello_world/contract.py b/examples/starter_python/smart_contracts/hello_world/contract.py deleted file mode 100644 index 8a8d12b..0000000 --- a/examples/starter_python/smart_contracts/hello_world/contract.py +++ /dev/null @@ -1,8 +0,0 @@ -from algopy import ARC4Contract, String -from algopy.arc4 import abimethod - - -class HelloWorld(ARC4Contract): - @abimethod() - def hello(self, name: String) -> String: - return "Hello, " + name diff --git a/examples/starter_python/smart_contracts/hello_world/deploy_config.py b/examples/starter_python/smart_contracts/hello_world/deploy_config.py deleted file mode 100644 index 36dda16..0000000 --- a/examples/starter_python/smart_contracts/hello_world/deploy_config.py +++ /dev/null @@ -1,36 +0,0 @@ -import logging - -import algokit_utils -from algosdk.v2client.algod import AlgodClient -from algosdk.v2client.indexer import IndexerClient - -logger = logging.getLogger(__name__) - - -# define deployment behaviour based on supplied app spec -def deploy( - algod_client: AlgodClient, - indexer_client: IndexerClient, - app_spec: algokit_utils.ApplicationSpecification, - deployer: algokit_utils.Account, -) -> None: - from smart_contracts.artifacts.hello_world.hello_world_client import ( - HelloWorldClient, - ) - - app_client = HelloWorldClient( - algod_client, - creator=deployer, - indexer_client=indexer_client, - ) - - app_client.deploy( - on_schema_break=algokit_utils.OnSchemaBreak.AppendApp, - on_update=algokit_utils.OnUpdate.AppendApp, - ) - name = "world" - response = app_client.hello(name=name) - logger.info( - f"Called hello on {app_spec.contract.name} ({app_client.app_id}) " - f"with name={name}, received: {response.return_value}" - ) diff --git a/examples/starter_python/smart_contracts/helpers/__init__.py b/examples/starter_python/smart_contracts/helpers/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/examples/starter_python/smart_contracts/helpers/build.py b/examples/starter_python/smart_contracts/helpers/build.py deleted file mode 100644 index a123086..0000000 --- a/examples/starter_python/smart_contracts/helpers/build.py +++ /dev/null @@ -1,76 +0,0 @@ -import logging -import subprocess -from pathlib import Path -from shutil import rmtree - -from smart_contracts.helpers.util import find_app_spec_files - -logger = logging.getLogger(__name__) -deployment_extension = "py" - - -def _get_output_path(output_dir: Path, deployment_extension: str) -> Path: - return output_dir / Path( - "{contract_name}" - + ("_client" if deployment_extension == "py" else "Client") - + f".{deployment_extension}" - ) - - -def build(output_dir: Path, contract_path: Path) -> Path: - output_dir = output_dir.resolve() - if output_dir.exists(): - rmtree(output_dir) - output_dir.mkdir(exist_ok=True, parents=True) - logger.info(f"Exporting {contract_path} to {output_dir}") - - build_result = subprocess.run( - [ - "algokit", - "--no-color", - "compile", - "python", - contract_path.absolute(), - f"--out-dir={output_dir}", - "--output-arc32", - ], - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - text=True, - ) - if build_result.returncode: - raise Exception(f"Could not build contract:\n{build_result.stdout}") - - app_spec_file_names = find_app_spec_files(output_dir) - - for app_spec_file_name in app_spec_file_names: - if app_spec_file_name is None: - raise Exception( - "Could not generate typed client, .arc32.json file not found" - ) - print(app_spec_file_name) - generate_result = subprocess.run( - [ - "algokit", - "generate", - "client", - output_dir, - "--output", - _get_output_path(output_dir, deployment_extension), - ], - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - text=True, - ) - if generate_result.returncode: - if "No such command" in generate_result.stdout: - raise Exception( - "Could not generate typed client, requires AlgoKit 2.0.0 or " - "later. Please update AlgoKit" - ) - else: - raise Exception( - f"Could not generate typed client:\n{generate_result.stdout}" - ) - - return output_dir diff --git a/examples/starter_python/smart_contracts/helpers/deploy.py b/examples/starter_python/smart_contracts/helpers/deploy.py deleted file mode 100644 index 10185a9..0000000 --- a/examples/starter_python/smart_contracts/helpers/deploy.py +++ /dev/null @@ -1,53 +0,0 @@ -# mypy: disable-error-code="no-untyped-call, misc" - - -import logging -from collections.abc import Callable -from pathlib import Path - -from algokit_utils import ( - Account, - ApplicationSpecification, - EnsureBalanceParameters, - ensure_funded, - get_account, - get_algod_client, - get_indexer_client, -) -from algosdk.util import algos_to_microalgos -from algosdk.v2client.algod import AlgodClient -from algosdk.v2client.indexer import IndexerClient - -logger = logging.getLogger(__name__) - - -def deploy( - app_spec_path: Path, - deploy_callback: Callable[ - [AlgodClient, IndexerClient, ApplicationSpecification, Account], None - ], - deployer_initial_funds: int = 2, -) -> None: - # get clients - # by default client configuration is loaded from environment variables - algod_client = get_algod_client() - indexer_client = get_indexer_client() - - # get app spec - app_spec = ApplicationSpecification.from_json(app_spec_path.read_text()) - - # get deployer account by name - deployer = get_account(algod_client, "DEPLOYER", fund_with_algos=0) - - minimum_funds_micro_algos = algos_to_microalgos(deployer_initial_funds) - ensure_funded( - algod_client, - EnsureBalanceParameters( - account_to_fund=deployer, - min_spending_balance_micro_algos=minimum_funds_micro_algos, - min_funding_increment_micro_algos=minimum_funds_micro_algos, - ), - ) - - # use provided callback to deploy the app - deploy_callback(algod_client, indexer_client, app_spec, deployer) diff --git a/examples/starter_python/smart_contracts/helpers/util.py b/examples/starter_python/smart_contracts/helpers/util.py deleted file mode 100644 index 4670226..0000000 --- a/examples/starter_python/smart_contracts/helpers/util.py +++ /dev/null @@ -1,12 +0,0 @@ -from pathlib import Path - - -def find_app_spec_file(output_dir: Path) -> str | None: - for file in output_dir.iterdir(): - if file.is_file() and file.suffixes == [".arc32", ".json"]: - return file.name - return None - - -def find_app_spec_files(output_dir: Path) -> list[str]: - return [file.name for file in output_dir.glob("*.arc32.json")] diff --git a/template_content/smart_contracts/__main__.py.jinja b/template_content/smart_contracts/__main__.py.jinja index f40cb95..dc3e78a 100644 --- a/template_content/smart_contracts/__main__.py.jinja +++ b/template_content/smart_contracts/__main__.py.jinja @@ -4,11 +4,10 @@ from pathlib import Path from dotenv import load_dotenv -from smart_contracts.config import contracts -from smart_contracts.helpers.build import build +from smart_contracts._helpers.build import build +from smart_contracts._helpers.config import contracts {% if deployment_language == 'python' -%} -from smart_contracts.helpers.deploy import deploy -from smart_contracts.helpers.util import find_app_spec_file +from smart_contracts._helpers.deploy import deploy # Uncomment the following lines to enable auto generation of AVM Debugger compliant sourcemap and simulation trace file. # Learn more about using AlgoKit AVM Debugger to debug your TEAL source codes and inspect various kinds of @@ -39,7 +38,14 @@ def main(action: str) -> None: for contract in contracts: logger.info(f"Deploying app {contract.name}") output_dir = artifact_path / contract.name - app_spec_file_name = find_app_spec_file(output_dir) + app_spec_file_name = next( + ( + file.name + for file in output_dir.iterdir() + if file.is_file() and file.suffixes == [".arc32", ".json"] + ), + None, + ) if app_spec_file_name is None: raise Exception("Could not deploy app, .arc32.json file not found") app_spec_path = output_dir / app_spec_file_name diff --git a/examples/starter_python/smart_contracts/__init__.py b/template_content/smart_contracts/_helpers/__init__.py similarity index 100% rename from examples/starter_python/smart_contracts/__init__.py rename to template_content/smart_contracts/_helpers/__init__.py diff --git a/template_content/smart_contracts/helpers/build.py.jinja b/template_content/smart_contracts/_helpers/build.py.jinja similarity index 94% rename from template_content/smart_contracts/helpers/build.py.jinja rename to template_content/smart_contracts/_helpers/build.py.jinja index 5699f25..fd1e9fa 100644 --- a/template_content/smart_contracts/helpers/build.py.jinja +++ b/template_content/smart_contracts/_helpers/build.py.jinja @@ -3,8 +3,6 @@ import subprocess from pathlib import Path from shutil import rmtree -from smart_contracts.helpers.util import find_app_spec_files - logger = logging.getLogger(__name__) {% if deployment_language == 'python' -%} deployment_extension = "py" @@ -44,7 +42,7 @@ def build(output_dir: Path, contract_path: Path) -> Path: if build_result.returncode: raise Exception(f"Could not build contract:\n{build_result.stdout}") - app_spec_file_names = find_app_spec_files(output_dir) + app_spec_file_names = [file.name for file in output_dir.glob("*.arc32.json")] for app_spec_file_name in app_spec_file_names: if app_spec_file_name is None: @@ -76,4 +74,4 @@ def build(output_dir: Path, contract_path: Path) -> Path: f"Could not generate typed client:\n{generate_result.stdout}" ) - return output_dir + return output_dir / app_spec_file_name diff --git a/template_content/smart_contracts/config.py.jinja b/template_content/smart_contracts/_helpers/config.py.jinja similarity index 100% rename from template_content/smart_contracts/config.py.jinja rename to template_content/smart_contracts/_helpers/config.py.jinja diff --git a/template_content/smart_contracts/helpers/{% if deployment_language == 'python' %}deploy.py{% endif %}.jinja b/template_content/smart_contracts/_helpers/{% if deployment_language == 'python' %}deploy.py{% endif %}.jinja similarity index 100% rename from template_content/smart_contracts/helpers/{% if deployment_language == 'python' %}deploy.py{% endif %}.jinja rename to template_content/smart_contracts/_helpers/{% if deployment_language == 'python' %}deploy.py{% endif %}.jinja diff --git a/template_content/smart_contracts/helpers/__init__.py b/template_content/smart_contracts/helpers/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/template_content/smart_contracts/helpers/util.py b/template_content/smart_contracts/helpers/util.py deleted file mode 100644 index 4670226..0000000 --- a/template_content/smart_contracts/helpers/util.py +++ /dev/null @@ -1,12 +0,0 @@ -from pathlib import Path - - -def find_app_spec_file(output_dir: Path) -> str | None: - for file in output_dir.iterdir(): - if file.is_file() and file.suffixes == [".arc32", ".json"]: - return file.name - return None - - -def find_app_spec_files(output_dir: Path) -> list[str]: - return [file.name for file in output_dir.glob("*.arc32.json")] diff --git a/template_content/{% if code_tours %}.tours{% endif %}/getting-started-with-your-algokit-project.tour.jinja b/template_content/{% if code_tours %}.tours{% endif %}/getting-started-with-your-algokit-project.tour.jinja index 2ba5c47..f484b33 100644 --- a/template_content/{% if code_tours %}.tours{% endif %}/getting-started-with-your-algokit-project.tour.jinja +++ b/template_content/{% if code_tours %}.tours{% endif %}/getting-started-with-your-algokit-project.tour.jinja @@ -49,5 +49,10 @@ "description": "Uncomment the following lines to enable complementary utilities that will generate artifacts required for the [AlgoKit AVM Debugger](https://github.com/algorandfoundation/algokit-avm-vscode-debugger) VSCode plugin available on the [VSCode Extension Marketplace](https://marketplace.visualstudio.com/items?itemName=algorandfoundation.algokit-avm-vscode-debugger). A new folder will be automatically created in the `.algokit` directory with source maps of all TEAL contracts in this workspace, as well as traces that will appear in a folder at the root of the workspace. You can then use the traces as entry points to trigger the debug extension. Make sure to have the `.algokit.toml` file available at the root of the workspace.", "line": 15 } + { + "file": "smart_contracts/_helpers/__init__.py", + "description": "This folder contains helper scripts for contract management. These automate tasks like compiling, generating clients, and deploying. Usually, you won't need to edit these files, but advanced users can expand them for custom needs.", + "line": 1 + } ] }