All skills

Builds x402 HTTP-native payment applications on Algorand using Python. Covers clients (httpx, requests), servers (FastAPI, Flask), facilitators, Bazaar discovery, and the x402-avm library. Use when implementing x402 payment flows in Python, creating payment-gated APIs, building x402 facilitators, or integrating the x402-avm package.

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

This session only. Nothing lands on disk.

referencesexplain-algorand-x402-python-reference.md

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

x402-avm Python Package Reference

Detailed reference for the x402-avm Python package covering package structure, extras, async/sync variants, signer protocols, registration functions, constants, utilities, and algosdk encoding.

Package Structure

The package is published on PyPI as x402-avm but all imports use the x402 namespace:

x402/
  __init__.py                  # x402Client, x402ClientSync, x402Facilitator, etc.
  server.py                    # x402ResourceServer, x402ResourceServerSync
  schemas.py                   # AssetAmount, Network, PaymentRequirements, etc.
  http/
    __init__.py                # HTTPFacilitatorClient, HTTPFacilitatorClientSync, PaymentOption, etc.
    types.py                   # RouteConfig, RoutesConfig, FacilitatorConfig
    clients/
      __init__.py              # Lazy imports for httpx/requests
      httpx.py                 # x402HttpxClient, wrapHttpxWithPayment, etc.
      requests.py              # x402_requests, wrapRequestsWithPayment, etc.
    middleware/
      __init__.py              # Lazy imports for fastapi/flask
      fastapi.py               # PaymentMiddlewareASGI, payment_middleware, etc.
      flask.py                 # PaymentMiddleware, payment_middleware, etc.
  mechanisms/
    avm/
      __init__.py              # Re-exports constants
      constants.py             # Network IDs, USDC config, algod URLs
      signer.py                # ClientAvmSigner, FacilitatorAvmSigner Protocols
      utils.py                 # Address validation, encoding, network utils
      exact/
        __init__.py            # ExactAvmClientScheme, ExactAvmServerScheme, etc.
        register.py            # register_exact_avm_client, register_exact_avm_server, etc.
    evm/                       # EVM mechanism (same structure)
    svm/                       # SVM mechanism (same structure)

Extras

Extra Installs Use Case
[avm] py-algorand-sdk>=2.0.0 Algorand transaction signing
[evm] web3, eth-account Ethereum/EVM transaction signing
[svm] solders, solana-py Solana/SVM transaction signing
[fastapi] fastapi[standard]>=0.115.0, starlette>=0.27.0 FastAPI async middleware
[flask] flask>=3.0.0 Flask sync middleware
[httpx] httpx>=0.28.1 Async HTTP client
[requests] requests>=2.31.0 Sync HTTP client
[mechanisms] All mechanism extras All blockchain mechanisms
[clients] httpx, requests All HTTP clients
[servers] fastapi, flask All server frameworks
[extensions] Extensions dependencies Optional extensions
[all] Everything Full installation

Installation examples:

pip install "x402-avm[avm]"
pip install "x402-avm[fastapi,avm]"
pip install "x402-avm[flask,avm]"
pip install "x402-avm[httpx,avm]"
pip install "x402-avm[requests,avm]"
pip install "x402-avm[avm,httpx,requests]"

Async vs Sync Component Table

Component Async (FastAPI/httpx) Sync (Flask/requests)
x402 Client x402Client x402ClientSync
Resource Server x402ResourceServer x402ResourceServerSync
Facilitator Client HTTPFacilitatorClient HTTPFacilitatorClientSync
HTTP Resource Server x402HTTPResourceServer x402HTTPResourceServerSync
HTTP Client wrapper x402HTTPClient x402HTTPClientSync
Middleware (FastAPI) PaymentMiddlewareASGI N/A
Middleware (Flask) N/A PaymentMiddleware
HTTP Client (httpx) x402HttpxClient N/A
HTTP Client (requests) N/A x402_requests
Payment info storage request.state.payment_payload flask.g.payment_payload

ClientAvmSigner Protocol

Defined in x402.mechanisms.avm.signer. Structural typing -- no inheritance required.

class ClientAvmSigner(Protocol):
    @property
    def address(self) -> str:
        """58-character Algorand address."""
        ...

    def sign_transactions(
        self,
        unsigned_txns: list[bytes],
        indexes_to_sign: list[int],
    ) -> list[bytes | None]:
        """Sign specified transactions in a group.

        Args:
            unsigned_txns: Raw msgpack-encoded unsigned transactions.
            indexes_to_sign: Indexes this signer should sign.

        Returns:
            Parallel list: signed bytes at signed indexes, None elsewhere.
        """
        ...

Implementation Notes

  • unsigned_txns contains raw msgpack bytes, not base64 strings
  • Convert at boundary: base64.b64encode(txn_bytes).decode() before msgpack_decode
  • Transaction.sign(key) expects base64-encoded private key string
  • Convert back: base64.b64decode(msgpack_encode(signed)) to return raw bytes

FacilitatorAvmSigner Protocol

Defined in x402.mechanisms.avm.signer. Required for facilitator services.

class FacilitatorAvmSigner(Protocol):
    def get_addresses(self) -> list[str]: ...
    def sign_transaction(self, txn_bytes: bytes, fee_payer: str, network: str) -> bytes: ...
    def sign_group(self, group_bytes: list[bytes], fee_payer: str, indexes_to_sign: list[int], network: str) -> list[bytes]: ...
    def simulate_group(self, group_bytes: list[bytes], network: str) -> None: ...
    def send_group(self, group_bytes: list[bytes], network: str) -> str: ...
    def confirm_transaction(self, txid: str, network: str, rounds: int = 4) -> None: ...

Implementation Patterns

Method Key Pattern
simulate_group Wrap unsigned Transaction with SignedTransaction(txn, None), use allow_empty_signatures=True
send_group Use send_raw_transaction(base64.b64encode(b"".join(group_bytes)))
confirm_transaction Use transaction.wait_for_confirmation(client, txid, rounds)

Registration Functions

register_exact_avm_client(client, signer, networks=None, algod_url=None)

Registers AVM payment scheme on an x402 client.

Parameter Type Default Description
client x402Client | x402ClientSync required The x402 client instance
signer ClientAvmSigner required Signer implementation
networks str | list[str] | None None Specific networks; default registers "algorand:*" wildcard + V1 names
algod_url str | None None Custom algod endpoint

register_exact_avm_server(server)

Registers AVM scheme on a resource server.

Parameter Type Description
server x402ResourceServer | x402ResourceServerSync The resource server

register_exact_avm_facilitator(facilitator, signer, networks)

Registers AVM scheme on a facilitator.

Parameter Type Description
facilitator x402Facilitator The facilitator instance
signer FacilitatorAvmSigner Facilitator signer implementation
networks list[str] CAIP-2 network identifiers to support

Constants

Defined in x402.mechanisms.avm.constants:

Network Identifiers

Constant Value
ALGORAND_MAINNET_CAIP2 "algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=" (as of x402-avm 2.0.2; the TypeScript @x402/avm package ≥2.20.0 uses the 32-char form algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73k)
ALGORAND_TESTNET_CAIP2 "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=" (as of x402-avm 2.0.2; note the TypeScript @x402/avm package ≥2.20.0 uses the 32-char form algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDe — a TS server/client and a Python facilitator (or vice-versa) will not match until x402-avm adopts the same form)
SUPPORTED_NETWORKS [MAINNET_CAIP2, TESTNET_CAIP2]
MAINNET_GENESIS_HASH "wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8="
TESTNET_GENESIS_HASH "SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI="
V1_NETWORKS ["algorand-mainnet", "algorand-testnet"]

USDC Configuration

Constant Value
USDC_MAINNET_ASA_ID 31566704
USDC_TESTNET_ASA_ID 10458941
DEFAULT_DECIMALS 6

Algod Endpoints

Constant Default Value
MAINNET_ALGOD_URL env ALGOD_MAINNET_URL or "https://mainnet-api.algonode.cloud"
TESTNET_ALGOD_URL env ALGOD_TESTNET_URL or "https://testnet-api.algonode.cloud"
FALLBACK_ALGOD_MAINNET "https://mainnet-api.algonode.cloud"
FALLBACK_ALGOD_TESTNET "https://testnet-api.algonode.cloud"

Transaction Limits

Constant Value
MAX_GROUP_SIZE 16
MIN_TXN_FEE 1000 (microAlgos)

Utility Functions

Defined in x402.mechanisms.avm.utils:

Function Signature Returns
is_valid_address(addr) str -> bool Whether address is valid 58-char Algorand address
to_atomic_amount(amount) float -> int Decimal to atomic units (e.g., 1.50 -> 1500000)
from_atomic_amount(amount) int -> float Atomic units to decimal (e.g., 1500000 -> 1.5)
decode_transaction_bytes(raw) bytes -> DecodedTransactionInfo Decoded transaction details
decode_base64_transaction(b64) str -> DecodedTransactionInfo Decode from base64 string
decode_payment_group(group, index) list[str], int -> PaymentGroupInfo Full group analysis
encode_transaction_group(txns) list[bytes] -> list[str] Encode raw bytes to base64 strings
normalize_network(network) str -> str Normalize V1 name to CAIP-2
is_valid_network(network) str -> bool Check if network is recognized
get_network_config(network) str -> dict Full config for network
get_usdc_asa_id(network) str -> int USDC ASA ID for network
get_genesis_hash(network) str -> str Genesis hash for network
network_from_genesis_hash(hash) str -> str CAIP-2 from genesis hash
validate_no_security_risks(info) DecodedTransactionInfo -> str | None Error code or None
validate_fee_payer_transaction(info, addr) DecodedTransactionInfo, str -> str | None Error code or None
is_blocked_transaction_type(type) str -> bool Whether type is blocked (e.g., keyreg)

algosdk Encoding Notes (v2.11.1)

The Python algosdk has different encoding conventions than TypeScript algosdk:

Operation Python algosdk TypeScript algosdk
msgpack_decode(s) Expects base64 string N/A (uses decodeUnsignedTransaction(Uint8Array))
msgpack_encode(obj) Returns base64 string N/A (uses txn.toByte() returning Uint8Array)
Transaction.sign(key) Expects base64 string key signTransaction(txn, Uint8Array)
SDK protocol Passes raw msgpack bytes Passes raw Uint8Array

Boundary conversions:

# Raw bytes -> algosdk object
txn_obj = encoding.msgpack_decode(base64.b64encode(raw_bytes).decode("utf-8"))

# algosdk object -> raw bytes
raw_bytes = base64.b64decode(encoding.msgpack_encode(txn_obj))

Environment Variables

Variable Description Default
AVM_PRIVATE_KEY Base64-encoded 64-byte key (32-byte seed + 32-byte pubkey) Required
ALGOD_MAINNET_URL Custom algod mainnet endpoint https://mainnet-api.algonode.cloud
ALGOD_TESTNET_URL Custom algod testnet endpoint https://testnet-api.algonode.cloud
INDEXER_MAINNET_URL Custom indexer mainnet endpoint https://mainnet-idx.algonode.cloud
INDEXER_TESTNET_URL Custom indexer testnet endpoint https://testnet-idx.algonode.cloud
ALGOD_SERVER Algod URL for facilitator examples N/A
ALGOD_TOKEN Algod token for facilitator examples N/A

Private Key Format

The AVM_PRIVATE_KEY is a Base64-encoded 64-byte key:

  • First 32 bytes: Ed25519 seed (private key)
  • Last 32 bytes: Ed25519 public key
  • Address derivation: encoding.encode_address(secret_key[32:])

Payment Flow

Client -> Resource Server -> Facilitator -> Algorand Network
  |          |                  |                |
  | 1. GET   |                  |                |
  |--------->|                  |                |
  | 2. 402   |                  |                |
  |<---------|                  |                |
  | 3. Build |                  |                |
  |   payload|                  |                |
  | 4. GET + |                  |                |
  | PAYMENT- |                  |                |
  | SIGNATURE|                  |                |
  |--------->| 5. verify()      |                |
  |          |----------------->| 6. simulate    |
  |          |                  |--------------->|
  |          |                  |<---------------|
  |          |<-----------------|                |
  |          | 7. settle()      |                |
  |          |----------------->| 8. sign + send |
  |          |                  |--------------->|
  |          |                  |<---------------|
  |          |<-----------------| 9. txId        |
  | 10. 200  |                  |                |
  |<---------|                  |                |

Testing Notes

  • Use Algorand TestNet for development with free test ALGO from the Algorand Faucet
  • USDC on TestNet uses ASA ID 10458941 -- ensure receiver has opted in
  • Simulation (simulate_group) validates transactions without submitting
  • Algorand has instant finality -- once confirmed, transactions are permanent
  • AlgoNode public endpoints require no authentication token

External Resources

Source: SKILL.md on GitHub

2 warnings16d3 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    This skill provides documentation and Python code examples for implementing the x402 payment protocol on the Algorand blockchain, using the x402-avm package.

  • Socket16d

    2 alerts: gptAnomaly

  • Snyk16d

    Risk: MEDIUM · 1 issue

Signed by skilld at a0546cc. 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 3 weeks ago

README badge

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