All skills

Develops Algorand smart contracts in Python using PuyaPy — covers syntax, decorators, storage, transactions, types, testing with pytest, deployment, AlgoKit Utils, ARC-4/ARC-56 standards, and error troubleshooting. Use when writing algopy contracts, using @arc4.abimethod decorators, working with GlobalState or BoxMap in Python, testing with AlgorandClient, deploying or calling contracts from Python, or diagnosing PuyaPy compiler and transaction errors.

Use this Skill: https://skilld.dev/gh/algorand-devrel/algorand-agent-skills/algorand-python

This session only. Nothing lands on disk.

referencesdeploy-interaction.md

≈2.8k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Deploying and Calling Contracts (Python)

Contents

Deploy and interact with Algorand smart contracts using AlgoKit Utils Python and generated typed clients.

CLI Commands

Build Contract

algokit project run build

Compiles contracts and generates:

  • ARC-56 app spec (*.arc56.json)
  • Python typed client

Deploy Contract

# To localnet
algokit project deploy localnet

# To testnet (requires funded account)
algokit project deploy testnet

# To mainnet
algokit project deploy mainnet

Localnet Management

algokit localnet start    # Start localnet
algokit localnet status   # Check status
algokit localnet reset    # Reset (clears all data)
algokit localnet stop     # Stop

AlgorandClient API

Creating an AlgorandClient

from algokit_utils import AlgorandClient

# From environment variables (recommended for production)
algorand = AlgorandClient.from_environment()

# Default LocalNet configuration
algorand = AlgorandClient.default_localnet()

# TestNet using AlgoNode free tier
algorand = AlgorandClient.testnet()

# MainNet using AlgoNode free tier
algorand = AlgorandClient.mainnet()

# From existing clients
algorand = AlgorandClient.from_clients(algod=algod, indexer=indexer, kmd=kmd)

# From custom configuration
from algokit_utils import AlgoClientNetworkConfig

algorand = AlgorandClient.from_config(
    algod_config=AlgoClientNetworkConfig(
        server="http://localhost",
        port="4001",
        token="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    )
)

Accessing SDK Clients

algod_client = algorand.client.algod
indexer_client = algorand.client.indexer
kmd_client = algorand.client.kmd

Account Management

Getting Accounts

# From environment variable (DEPLOYER_MNEMONIC)
deployer = algorand.account.from_environment("DEPLOYER")

# Random account (for testing)
random_account = algorand.account.random()

# From mnemonic
account = algorand.account.from_mnemonic("abandon abandon...")

# From KMD (LocalNet)
kmd_account = algorand.account.from_kmd("wallet-name", "password")

Registering Signers

# Register a signer for automatic signing
algorand.set_signer_from_account(account)

# Set default signer for all transactions
algorand.set_default_signer(account.signer)

Deploy Using Typed Client Factory

from artifacts.my_contract_client import MyContractFactory

factory = algorand.client.get_typed_app_factory(
    MyContractFactory,
    default_sender=deployer.address,
)

result = factory.deploy(
    on_update="append",
    on_schema_break="append",
)
app_client = result.app_client
print(f"App ID: {app_client.app_id}")

Call Methods

# No arguments
result = app_client.send.increment()

# With arguments
result = app_client.send.set_value(value=42)

# Access return value
print(f"Return: {result.abi_return}")

Read State

# Global state
state = app_client.state.global_state.get_all()

# Local state
local = app_client.state.local_state(address).get_all()

Opt-In / Close-Out

# ABI opt-in
app_client.send.opt_in.opt_in()

# Bare opt-in
app_client.send.opt_in.bare()

# ABI close-out
app_client.send.close_out.close_out()

# Bare close-out
app_client.send.close_out.bare()

Environment Setup

For non-localnet deployments:

# .env file
ALGORAND_NETWORK=testnet
DEPLOYER_MNEMONIC="your twenty four word mnemonic phrase here"

Sending Transactions

Single Transactions

from algokit_utils import AlgoAmount, PaymentParams, AssetTransferParams
from algokit_utils import AssetOptInParams, AssetCreateParams

# Payment
result = algorand.send.payment(
    PaymentParams(
        sender="SENDERADDRESS",
        receiver="RECEIVERADDRESS",
        amount=AlgoAmount(algo=1),
    )
)

# Asset transfer
algorand.send.asset_transfer(
    AssetTransferParams(
        sender="SENDERADDRESS",
        receiver="RECEIVERADDRESS",
        asset_id=12345,
        amount=100,
    )
)

# Asset opt-in
algorand.send.asset_opt_in(
    AssetOptInParams(
        sender="SENDERADDRESS",
        asset_id=12345,
    )
)

# Asset create
create_result = algorand.send.asset_create(
    AssetCreateParams(
        sender="SENDERADDRESS",
        total=1_000_000,
        decimals=6,
        asset_name="My Token",
        unit_name="MTK",
    )
)
asset_id = create_result.asset_id

Transaction Groups

result = (
    algorand
    .new_group()
    .add_payment(
        PaymentParams(
            sender="SENDERADDRESS",
            receiver="RECEIVERADDRESS",
            amount=AlgoAmount(algo=1),
        )
    )
    .add_asset_opt_in(
        AssetOptInParams(
            sender="SENDERADDRESS",
            asset_id=12345,
        )
    )
    .send()
)

Creating Transactions (Without Sending)

payment = algorand.create_transaction.payment(
    PaymentParams(
        sender="SENDERADDRESS",
        receiver="RECEIVERADDRESS",
        amount=AlgoAmount(algo=1),
    )
)
# payment is an unsigned algosdk.Transaction

Common Transaction Parameters

All transactions support these common parameters:

algorand.send.payment(
    PaymentParams(
        sender="SENDERADDRESS",
        receiver="RECEIVERADDRESS",
        amount=AlgoAmount(algo=1),

        # Optional parameters
        note=b"My note",
        lease="unique-lease-id",
        rekey_to="NEWADDRESS",

        # Fee management
        static_fee=AlgoAmount(micro_algo=1000),
        extra_fee=AlgoAmount(micro_algo=1000),  # For covering inner txn fees
        max_fee=AlgoAmount(micro_algo=10000),

        # Validity
        validity_window=1000,
        first_valid_round=12345,
    )
)

Send Parameters

Control execution behavior when sending:

from algokit_utils import SendParams

algorand.send.payment(
    PaymentParams(
        sender="SENDERADDRESS",
        receiver="RECEIVERADDRESS",
        amount=AlgoAmount(algo=1),
    ),
    send_params=SendParams(
        max_rounds_to_wait_for_confirmation=5,
        suppress_log=True,
        populate_app_call_resources=True,
        cover_app_call_inner_transaction_fees=True,
    )
)

App Calls

Using Typed App Clients (Recommended)

# Get typed factory from generated client
factory = algorand.client.get_typed_app_factory(MyContractFactory)

# Deploy
result = factory.deploy(sender=deployer.address)
app_client = result.app_client

# Call methods
response = app_client.send.my_method(
    sender=deployer.address,
    args={"param1": "value"},
)

Generic App Calls

from algokit_utils import AppCallMethodCallParams
from algosdk.abi import Method

algorand.send.app_call_method_call(
    AppCallMethodCallParams(
        sender="SENDERADDRESS",
        app_id=12345,
        method=Method.from_signature("hello(string)string"),
        args=["World"],
    )
)

Amount Helpers

from algokit_utils import AlgoAmount

AlgoAmount(algo=1)           # 1 Algo = 1,000,000 microAlgo
AlgoAmount(algo=0.5)         # 0.5 Algo = 500,000 microAlgo
AlgoAmount(micro_algo=1000)  # 1000 microAlgo

# Access values
amount = AlgoAmount(algo=1)
amount.algo        # 1.0
amount.micro_algo  # 1000000

Auto-Populating App Call Resources (populate_app_call_resources)

Automatically discovers and populates account, asset, app, and box references via simulate. Eliminates manual reference management in most cases.

Per-Call

app_client.send.my_method(
    key=1,
    populate_app_call_resources=True,
)

Global Configuration

algorand = AlgorandClient.default_localnet()
algorand.set_default_send_params(
    populate_app_call_resources=True,
)

# Now all calls auto-populate resources
app_client.send.my_method(key=1)

Note: This uses simulate under the hood to discover required references. For performance-critical paths or when you know the exact references, pass them explicitly.


Auto-Covering Inner Transaction Fees (cover_app_call_inner_transaction_fees)

Automatically calculates the correct fee to cover inner transactions via simulate. Replaces manual extra_fee calculations.

Per-Call

app_client.send.transfer_with_inner_txn(
    receiver=bob_address,
    amount=1000,
    cover_app_call_inner_transaction_fees=True,
    max_fee=AlgoAmount(micro_algo=10_000),  # Safety cap
)

Manual Alternative (extra_fee)

If you know the exact number of inner transactions:

app_client.send.transfer_with_inner_txn(
    receiver=bob_address,
    amount=1000,
    extra_fee=AlgoAmount(micro_algo=1000),  # Cover 1 inner txn
)

deploy_config.py Pattern

The standard deployment configuration file for Python projects:

# smart_contracts/deploy_config.py
from algokit_utils import AlgorandClient, AlgoAmount
from artifacts.my_contract_client import MyContractFactory


def deploy() -> None:
    algorand = AlgorandClient.from_environment()
    deployer = algorand.account.from_environment("DEPLOYER")

    factory = algorand.client.get_typed_app_factory(
        MyContractFactory,
        default_sender=deployer.address,
    )

    result = factory.deploy(
        on_update="append",
        on_schema_break="append",
    )
    app_client = result.app_client

    # Fund app account if newly created (e.g., for box storage)
    if result.operation_performed in ("create", "replace"):
        algorand.send.payment(
            sender=deployer.address,
            receiver=app_client.app_address,
            amount=AlgoAmount(algo=1),
        )

    print(f"App ID: {app_client.app_id}")

Important Rules

  • Always build before deploying: Run algokit project run build to generate fresh artifacts
  • Use generated typed clients: They provide type safety and handle ABI encoding
  • Check App ID: Get from deployment output, don't hardcode across environments
  • Use environment variables: Store sensitive data like mnemonics in .env

References

Source: SKILL.md on GitHub

1 warning1mo3 checks · Risk SAFE
  • Gen Agent Trust Hub1mo

    This skill provides a comprehensive guide for developing Algorand smart contracts using Python. It includes documentation for the PuyaPy framework, testing with pytest, and project management with AlgoKit. No high-risk security issues were identified; however, the skill's role in processing and compiling user-provided code constitutes a standard development attack surface.

  • Socket1mo

    No alerts

  • Snyk1mo

    Risk: MEDIUM · 1 issue

Signed by skilld at 774f8a8. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 3 weeks ago.

Activeupdated 6 months ago

README badge

README badge for algorand-devrel/algorand-agent-skills/algorand-python