Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: puya debugger support; algokit v7 updates #71

Merged
merged 16 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,7 @@ By default the template creates a single `HelloWorld` contract under hello_world

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`### Continuous Integration / Continuous Deployment (CI/CD)

This project uses [GitHub Actions](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions) to define CI/CD workflows, which are located in the [.github/workflows](`.github/workflows`) folder.

> Please note, if you instantiated the project with --workspace flag in `algokit init` it will automatically attempt to move the contents of the `.github` folder to the root of the workspace.

### AlgoKit Workspaces

To define custom `algokit project run` commands refer to [documentation](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/run.md). This allows orchestration of commands spanning across multiple projects within an algokit workspace based project (monorepo).
To generate a new `.env` or `.env.{target_network}` file, run `algokit generate env-file`

### Debugging Smart Contracts

Expand All @@ -94,7 +86,15 @@ Refer to the commented header in the `__main__.py` file in the `smart_contracts`

If you have opted in to include VSCode launch configurations in your project, you can also use the `Debug TEAL via AlgoKit AVM Debugger` launch configuration to interactively select an available trace file and launch the debug session for your smart contract.

For information on using and setting up the `AlgoKit AVM Debugger` VSCode extension refer [here](https://github.com/algorandfoundation/algokit-avm-vscode-debugger). To install the extension from the VSCode Marketplace, use the following link: [AlgoKit AVM Debugger extension](https://marketplace.visualstudio.com/items?itemName=algorandfoundation.algokit-avm-vscode-debugger).
For information on using and setting up the `AlgoKit AVM Debugger` VSCode extension refer [here](https://github.com/algorandfoundation/algokit-avm-vscode-debugger). To install the extension from the VSCode Marketplace, use the following link: [AlgoKit AVM Debugger extension](https://marketplace.visualstudio.com/items?itemName=algorandfoundation.algokit-avm-vscode-debugger).### Continuous Integration / Continuous Deployment (CI/CD)

This project uses [GitHub Actions](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions) to define CI/CD workflows, which are located in the [.github/workflows](`.github/workflows`) folder.

> Please note, if you instantiated the project with --workspace flag in `algokit init` it will automatically attempt to move the contents of the `.github` folder to the root of the workspace.

### AlgoKit Workspaces

To define custom `algokit project run` commands refer to [documentation](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/run.md). This allows orchestration of commands spanning across multiple projects within an algokit workspace based project (monorepo).

#### Setting up GitHub for CI/CD workflow and TestNet deployment

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ package-mode = false

[tool.poetry.dependencies]
python = "^3.12"
algokit-utils = "^2.3.0"
algokit-utils = { git = "https://github.com/algorandfoundation/algokit-utils-py.git", branch = "feat/puya-debugging" }
python-dotenv = "^1.0.0"
algorand-python = "^2.0.0"
algorand-python-testing = "^0.4.0"
Expand All @@ -17,12 +17,12 @@ algorand-python-testing = "^0.4.0"
algokit-client-generator = "^1.1.3"
black = {extras = ["d"], version = "*"}
ruff = "^0.1.6"
mypy = "*"
mypy = "1.11.0"
pytest = "*"
pytest-cov = "*"
pip-audit = "*"
pre-commit = "*"
puyapy = "*"
puyapy = { git = "https://github.com/algorandfoundation/puya.git", branch = "puya-debug-info" }

[build-system]
requires = ["poetry-core"]
Expand Down Expand Up @@ -58,7 +58,7 @@ warn_redundant_casts = true
warn_unused_ignores = true
warn_return_any = true
strict_equality = true
strict_concatenate = true
extra_checks = true
disallow_any_unimported = true
disallow_any_expr = true
disallow_any_decorated = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ def build(output_dir: Path, contract_path: Path) -> Path:
contract_path.absolute(),
f"--out-dir={output_dir}",
"--output-arc32",
"--debug-level=0",
],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
import * as algokit from '@algorandfoundation/algokit-utils'
import { {{ contract_name.split('_')|map('capitalize')|join }}Client } from '../artifacts/{{ contract_name }}/{{ contract_name.split('_')|map('capitalize')|join }}Client'
import { {{ contract_name.split('_')|map('capitalize')|join }}Factory } from '../artifacts/{{ contract_name }}/{{ contract_name.split('_')|map('capitalize')|join }}Client'

// Below is a showcase of various deployment options you can use in TypeScript Client
export async function deploy() {
console.log('=== Deploying {{ contract_name.split('_')|map('capitalize')|join }} ===')

const algorand = algokit.AlgorandClient.fromEnvironment()
const deployer = await algorand.account.fromEnvironment('DEPLOYER')

const appClient = algorand.client.getTypedAppClientByCreatorAndName({{ contract_name.split('_')|map('capitalize')|join }}Client, {
sender: deployer,
creatorAddress: deployer.addr,
})

const app = await appClient.deploy({
onSchemaBreak: 'append',
onUpdate: 'append',
const factory = algorand.client.getTypedAppFactory({{ contract_name.split('_')|map('capitalize')|join }}Factory, {
defaultSender: deployer.addr,
})

const { appClient, result } = await factory.deploy({ onUpdate: 'append', onSchemaBreak: 'append' })

// If app was just created fund the app account
if (['create', 'replace'].includes(app.operationPerformed)) {
if (['create', 'replace'].includes(result.operationPerformed)) {
await algorand.send.payment({
amount: algokit.algos(1),
amount: (1).algo(),
sender: deployer.addr,
receiver: app.appAddress,
})
}

const method = 'hello'
const response = await appClient.hello({ name: 'world' })
console.log(`Called ${method} on ${app.name} (${app.appId}) with name = world, received: ${response.return}`)
const method = 'hello'
const response = await appClient.send.hello({
args: { name: 'world' },
})
console.log(
`Called ${method} on ${appClient.appClient.appName} (${appClient.appClient.appId}) with name = world, received: ${response.return}`,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,7 @@ By default the template creates a single `HelloWorld` contract under hello_world

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`### Continuous Integration / Continuous Deployment (CI/CD)

This project uses [GitHub Actions](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions) to define CI/CD workflows, which are located in the [.github/workflows](`.github/workflows`) folder.

> Please note, if you instantiated the project with --workspace flag in `algokit init` it will automatically attempt to move the contents of the `.github` folder to the root of the workspace.

### AlgoKit Workspaces

To define custom `algokit project run` commands refer to [documentation](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/run.md). This allows orchestration of commands spanning across multiple projects within an algokit workspace based project (monorepo).
To generate a new `.env` or `.env.{target_network}` file, run `algokit generate env-file`

### Debugging Smart Contracts

Expand All @@ -95,7 +87,15 @@ Refer to the commented header in the `index.ts` file in the `smart_contracts` fo

If you have opted in to include VSCode launch configurations in your project, you can also use the `Debug TEAL via AlgoKit AVM Debugger` launch configuration to interactively select an available trace file and launch the debug session for your smart contract.

For information on using and setting up the `AlgoKit AVM Debugger` VSCode extension refer [here](https://github.com/algorandfoundation/algokit-avm-vscode-debugger). To install the extension from the VSCode Marketplace, use the following link: [AlgoKit AVM Debugger extension](https://marketplace.visualstudio.com/items?itemName=algorandfoundation.algokit-avm-vscode-debugger).
For information on using and setting up the `AlgoKit AVM Debugger` VSCode extension refer [here](https://github.com/algorandfoundation/algokit-avm-vscode-debugger). To install the extension from the VSCode Marketplace, use the following link: [AlgoKit AVM Debugger extension](https://marketplace.visualstudio.com/items?itemName=algorandfoundation.algokit-avm-vscode-debugger).### Continuous Integration / Continuous Deployment (CI/CD)

This project uses [GitHub Actions](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions) to define CI/CD workflows, which are located in the [.github/workflows](`.github/workflows`) folder.

> Please note, if you instantiated the project with --workspace flag in `algokit init` it will automatically attempt to move the contents of the `.github` folder to the root of the workspace.

### AlgoKit Workspaces

To define custom `algokit project run` commands refer to [documentation](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/project/run.md). This allows orchestration of commands spanning across multiple projects within an algokit workspace based project (monorepo).

#### Setting up GitHub for CI/CD workflow and TestNet deployment

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
"npm": ">=9.0"
},
"dependencies": {
"@algorandfoundation/algokit-utils": "^6.0.2",
"@algorandfoundation/algokit-utils": "7.0.0-beta.15",
"@algorandfoundation/algokit-utils-debug": "v1.0.2-beta.3",
"algosdk": "^2.7.0"
},
"devDependencies": {
"@algorandfoundation/algokit-client-generator": "^3.0.3",
"@algorandfoundation/algokit-client-generator": "v4.0.0-beta.5",
"@types/jest": "^29.5.11",
"dotenv": "^16.0.3",
"prettier": "^2.8.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ package-mode = false

[tool.poetry.dependencies]
python = "^3.12"
algokit-utils = "^2.3.0"
algokit-utils = { git = "https://github.com/algorandfoundation/algokit-utils-py.git", branch = "feat/puya-debugging" }
python-dotenv = "^1.0.0"
algorand-python = "^2.0.0"
algorand-python-testing = "^0.4.0"

[tool.poetry.group.dev.dependencies]
black = {extras = ["d"], version = "*"}
ruff = "^0.1.6"
mypy = "*"
mypy = "1.11.0"
pip-audit = "*"
pre-commit = "*"
puyapy = "*"
puyapy = { git = "https://github.com/algorandfoundation/puya.git", branch = "puya-debug-info" }

[build-system]
requires = ["poetry-core"]
Expand Down Expand Up @@ -52,7 +52,7 @@ warn_redundant_casts = true
warn_unused_ignores = true
warn_return_any = true
strict_equality = true
strict_concatenate = true
extra_checks = true
disallow_any_unimported = true
disallow_any_expr = true
disallow_any_decorated = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ def build(output_dir: Path, contract_path: Path) -> Path:
contract_path.absolute(),
f"--out-dir={output_dir}",
"--output-arc32",
"--debug-level=0",
],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
import * as algokit from '@algorandfoundation/algokit-utils'
import { CoolContractClient } from '../artifacts/cool_contract/CoolContractClient'
import { CoolContractFactory } from '../artifacts/cool_contract/CoolContractClient'

// Below is a showcase of various deployment options you can use in TypeScript Client
export async function deploy() {
console.log('=== Deploying CoolContract ===')

const algorand = algokit.AlgorandClient.fromEnvironment()
const deployer = await algorand.account.fromEnvironment('DEPLOYER')

const appClient = algorand.client.getTypedAppClientByCreatorAndName(CoolContractClient, {
sender: deployer,
creatorAddress: deployer.addr,
})

const app = await appClient.deploy({
onSchemaBreak: 'append',
onUpdate: 'append',
const factory = algorand.client.getTypedAppFactory(CoolContractFactory, {
defaultSender: deployer.addr,
})

const { appClient, result } = await factory.deploy({ onUpdate: 'append', onSchemaBreak: 'append' })

// If app was just created fund the app account
if (['create', 'replace'].includes(app.operationPerformed)) {
if (['create', 'replace'].includes(result.operationPerformed)) {
await algorand.send.payment({
amount: algokit.algos(1),
amount: (1).algo(),
sender: deployer.addr,
receiver: app.appAddress,
})
}

const method = 'hello'
const response = await appClient.hello({ name: 'world' })
console.log(`Called ${method} on ${app.name} (${app.appId}) with name = world, received: ${response.return}`)
const method = 'hello'
const response = await appClient.send.hello({
args: { name: 'world' },
})
console.log(
`Called ${method} on ${appClient.appClient.appName} (${appClient.appClient.appId}) with name = world, received: ${response.return}`,
)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as algokit from '@algorandfoundation/algokit-utils'
import { HelloWorldClient } from '../artifacts/hello_world/HelloWorldClient'
import { HelloWorldFactory } from '../artifacts/hello_world/HelloWorldClient'

// Below is a showcase of various deployment options you can use in TypeScript Client
export async function deploy() {
Expand All @@ -8,26 +8,26 @@ export async function deploy() {
const algorand = algokit.AlgorandClient.fromEnvironment()
const deployer = await algorand.account.fromEnvironment('DEPLOYER')

const appClient = algorand.client.getTypedAppClientByCreatorAndName(HelloWorldClient, {
sender: deployer,
creatorAddress: deployer.addr,
const factory = algorand.client.getTypedAppFactory(HelloWorldFactory, {
defaultSender: deployer.addr,
})

const app = await appClient.deploy({
onSchemaBreak: 'append',
onUpdate: 'append',
})
const { appClient, result } = await factory.deploy({ onUpdate: 'append', onSchemaBreak: 'append' })

// If app was just created fund the app account
if (['create', 'replace'].includes(app.operationPerformed)) {
if (['create', 'replace'].includes(result.operationPerformed)) {
await algorand.send.payment({
amount: algokit.algos(1),
amount: (1).algo(),
sender: deployer.addr,
receiver: app.appAddress,
receiver: appClient.appAddress,
})
}

const method = 'hello'
const response = await appClient.hello({ name: 'world' })
console.log(`Called ${method} on ${app.name} (${app.appId}) with name = world, received: ${response.return}`)
const method = 'hello'
const response = await appClient.send.hello({
args: { name: 'world' },
})
console.log(
`Called ${method} on ${appClient.appClient.appName} (${appClient.appClient.appId}) with name = world, received: ${response.return}`,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as fs from 'fs'
import * as path from 'path'
import { consoleLogger } from '@algorandfoundation/algokit-utils/types/logging'
import * as algokit from '@algorandfoundation/algokit-utils'
// import { registerDebugEventHandlers } from '@algorandfoundation/algokit-utils-debug' // Uncomment to enable persisting artifacts required by AlgoKit AVM Debugger

// Uncomment the debug and traceAll options 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
Expand All @@ -11,6 +12,7 @@ algokit.Config.configure({
// debug: true,
// traceAll: true,
})
// registerDebugEventHandlers() // Uncomment to enable persisting artifacts required by AlgoKit AVM Debugger

// base directory
const baseDir = path.resolve(__dirname)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { algorandFixture } from '@algorandfoundation/algokit-utils/testing'
import { HelloWorldClient } from '../smart_contracts/artifacts/hello_world/HelloWorldClient'
import { HelloWorldFactory } from '../smart_contracts/artifacts/hello_world/HelloWorldClient'
import { Account, Algodv2, Indexer } from 'algosdk'
import * as algokit from '@algorandfoundation/algokit-utils'
import { TransactionSignerAccount } from '@algorandfoundation/algokit-utils/types/account'

describe('hello world contract', () => {
const localnet = algorandFixture()
Expand All @@ -13,39 +14,36 @@ describe('hello world contract', () => {
})
beforeEach(localnet.beforeEach)

const deploy = async (account: Account, algod: Algodv2, indexer: Indexer) => {
const client = new HelloWorldClient(
{
resolveBy: 'creatorAndName',
findExistingUsing: indexer,
sender: account,
creatorAddress: account.addr,
},
algod,
)
await client.deploy({
onSchemaBreak: 'append',
onUpdate: 'append',
const deploy = async (account: Account & TransactionSignerAccount) => {
const factory = localnet.algorand.client.getTypedAppFactory(HelloWorldFactory, {
defaultSender: account.addr,
defaultSigner: account.signer,
})
return { client }

const { appClient } = await factory.deploy({ onUpdate: 'append', onSchemaBreak: 'append' })
return { client: appClient }
}

test('says hello', async () => {
const { algod, indexer, testAccount } = localnet.context
const { client } = await deploy(testAccount, algod, indexer)
const { testAccount } = localnet.context
const { client } = await deploy(testAccount)

const result = await client.hello({ name: 'World' })
const result = await client.send.hello({ args: { name: 'World' } })

expect(result.return).toBe('Hello, World')
})

test('simulate says hello with correct budget consumed', async () => {
const { algod, indexer, testAccount } = localnet.context
const { client } = await deploy(testAccount, algod, indexer)
const result = await client.compose().hello({ name: 'World' }).hello({ name: 'Jane' }).simulate()
const { testAccount } = localnet.context
const { client } = await deploy(testAccount)
const result = await client
.newGroup()
.hello({ args: { name: 'World' } })
.hello({ args: { name: 'Jane' } })
.simulate()

expect(result.methodResults[0].returnValue).toBe('Hello, World')
expect(result.methodResults[1].returnValue).toBe('Hello, Jane')
expect(result.returns[0]).toBe('Hello, World')
expect(result.returns[1]).toBe('Hello, Jane')
expect(result.simulateResponse.txnGroups[0].appBudgetConsumed).toBeLessThan(100)
})
})
Loading