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.

referencescreate-python-x402-server-examples.md

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

x402 Python Server Middleware Examples

FastAPI: Basic Middleware Setup (Function-Based)

from fastapi import FastAPI, Request
from x402.server import x402ResourceServer
from x402.http import HTTPFacilitatorClient, FacilitatorConfig, PaymentOption
from x402.http.types import RouteConfig
from x402.http.middleware.fastapi import payment_middleware
from x402.mechanisms.avm import ALGORAND_TESTNET_CAIP2
from x402.mechanisms.avm.exact import ExactAvmServerScheme

app = FastAPI()

facilitator = HTTPFacilitatorClient(FacilitatorConfig(url="https://x402.org/facilitator"))
server = x402ResourceServer(facilitator)
server.register(
    ALGORAND_TESTNET_CAIP2,
    ExactAvmServerScheme(),
)

routes = {
    "GET /api/data/*": RouteConfig(
        accepts=PaymentOption(
            scheme="exact",
            network=ALGORAND_TESTNET_CAIP2,
            pay_to="YOUR_ALGORAND_ADDRESS",
            price="$0.01",
        ),
    ),
}

x402_mw = payment_middleware(routes=routes, server=server)

@app.middleware("http")
async def x402_middleware(request: Request, call_next):
    return await x402_mw(request, call_next)

@app.get("/api/data/weather")
async def get_weather():
    return {"temperature": 72, "unit": "F", "condition": "sunny"}

FastAPI: ASGI Middleware Class

from fastapi import FastAPI
from x402.server import x402ResourceServer
from x402.http import HTTPFacilitatorClient, FacilitatorConfig, PaymentOption
from x402.http.types import RouteConfig
from x402.http.middleware.fastapi import PaymentMiddlewareASGI
from x402.mechanisms.avm import ALGORAND_TESTNET_CAIP2
from x402.mechanisms.avm.exact import ExactAvmServerScheme

app = FastAPI()

facilitator = HTTPFacilitatorClient(FacilitatorConfig(url="https://x402.org/facilitator"))
server = x402ResourceServer(facilitator)
server.register(
    ALGORAND_TESTNET_CAIP2,
    ExactAvmServerScheme(),
)

routes = {
    "GET /weather": RouteConfig(
        accepts=PaymentOption(
            scheme="exact",
            pay_to="YOUR_ALGORAND_ADDRESS",
            price="$0.01",
            network=ALGORAND_TESTNET_CAIP2,
        ),
        mime_type="application/json",
        description="Weather report",
    ),
}

app.add_middleware(PaymentMiddlewareASGI, routes=routes, server=server)

@app.get("/weather")
async def get_weather():
    return {"report": {"weather": "sunny", "temperature": 70}}

FastAPI: Middleware from Config

from x402.http import HTTPFacilitatorClient, FacilitatorConfig
from x402.http.middleware.fastapi import payment_middleware_from_config
from x402.mechanisms.avm import ALGORAND_TESTNET_CAIP2
from x402.mechanisms.avm.exact import ExactAvmServerScheme

facilitator = HTTPFacilitatorClient(FacilitatorConfig(url="https://x402.org/facilitator"))

routes = {
    "GET /api/data/*": {
        "accepts": {
            "scheme": "exact",
            "network": ALGORAND_TESTNET_CAIP2,
            "payTo": "YOUR_ALGORAND_ADDRESS",
            "maxAmountRequired": "10000",
            "asset": "10458941",
        }
    }
}

mw = payment_middleware_from_config(
    routes=routes,
    facilitator_client=facilitator,
    schemes=[
        {
            "network": ALGORAND_TESTNET_CAIP2,
            "server": ExactAvmServerScheme(),
        },
    ],
)

@app.middleware("http")
async def x402_middleware(request, call_next):
    return await mw(request, call_next)

FastAPI: Simple String Price

from x402.mechanisms.avm import ALGORAND_TESTNET_CAIP2

routes = {
    "GET /api/weather": RouteConfig(
        accepts=PaymentOption(
            scheme="exact",
            network=ALGORAND_TESTNET_CAIP2,
            pay_to="RECEIVER_ALGORAND_ADDRESS",
            price="$0.01",
        ),
    ),
}

FastAPI: Explicit AssetAmount

from x402.mechanisms.avm import ALGORAND_TESTNET_CAIP2
from x402.schemas import AssetAmount

routes = {
    "GET /api/premium/*": RouteConfig(
        accepts=PaymentOption(
            scheme="exact",
            network=ALGORAND_TESTNET_CAIP2,
            pay_to="RECEIVER_ALGORAND_ADDRESS",
            price=AssetAmount(
                amount="10000",
                asset="10458941",
                extra={"name": "USDC", "decimals": 6},
            ),
        ),
    ),
}

FastAPI: Accessing Payment Info in Route Handlers

from fastapi import FastAPI, Request

@app.get("/api/paid-resource")
async def paid_resource(request: Request):
    payment_payload = getattr(request.state, "payment_payload", None)
    payment_requirements = getattr(request.state, "payment_requirements", None)

    if payment_payload:
        payer_address = payment_payload.payload.get("from", "unknown")
        return {
            "data": "premium content",
            "paid_by": payer_address,
        }

    return {"data": "premium content"}

FastAPI: Multiple Routes with Different Prices

from x402.http import PaymentOption
from x402.http.types import RouteConfig
from x402.schemas import AssetAmount

routes = {
    "GET /api/status": RouteConfig(
        accepts=PaymentOption(
            scheme="exact", pay_to=AVM_ADDRESS,
            price="$0.001", network=AVM_NETWORK,
        ),
    ),
    "GET /api/weather/*": RouteConfig(
        accepts=PaymentOption(
            scheme="exact", pay_to=AVM_ADDRESS,
            price="$0.01", network=AVM_NETWORK,
        ),
        description="Weather data",
    ),
    "GET /api/analytics/*": RouteConfig(
        accepts=PaymentOption(
            scheme="exact", pay_to=AVM_ADDRESS,
            price=AssetAmount(
                amount="100000",
                asset=str(USDC_TESTNET_ASA_ID),
                extra={"name": "USDC", "decimals": 6},
            ),
            network=AVM_NETWORK,
        ),
        description="Premium analytics",
    ),
    "POST /api/generate": RouteConfig(
        accepts=PaymentOption(
            scheme="exact", pay_to=AVM_ADDRESS,
            price="$0.05", network=AVM_NETWORK,
        ),
        description="AI generation",
    ),
}

FastAPI: Multi-Network (AVM + EVM + SVM)

import os
from dotenv import load_dotenv
from fastapi import FastAPI
from x402.http import FacilitatorConfig, HTTPFacilitatorClient, PaymentOption
from x402.http.middleware.fastapi import PaymentMiddlewareASGI
from x402.http.types import RouteConfig
from x402.mechanisms.avm import ALGORAND_TESTNET_CAIP2
from x402.mechanisms.avm.exact import ExactAvmServerScheme
from x402.mechanisms.evm.exact import ExactEvmServerScheme
from x402.mechanisms.svm.exact import ExactSvmServerScheme
from x402.schemas import Network
from x402.server import x402ResourceServer

load_dotenv()

EVM_ADDRESS = os.getenv("EVM_ADDRESS")
SVM_ADDRESS = os.getenv("SVM_ADDRESS")
AVM_ADDRESS = os.getenv("AVM_ADDRESS")
AVM_NETWORK: Network = ALGORAND_TESTNET_CAIP2
EVM_NETWORK: Network = "eip155:84532"
SVM_NETWORK: Network = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"

app = FastAPI()

facilitator = HTTPFacilitatorClient(FacilitatorConfig(url="https://x402.org/facilitator"))
server = x402ResourceServer(facilitator)
server.register(AVM_NETWORK, ExactAvmServerScheme())
server.register(EVM_NETWORK, ExactEvmServerScheme())
server.register(SVM_NETWORK, ExactSvmServerScheme())

routes = {
    "GET /weather": RouteConfig(
        accepts=[
            PaymentOption(scheme="exact", pay_to=AVM_ADDRESS, price="$0.01", network=AVM_NETWORK),
            PaymentOption(scheme="exact", pay_to=EVM_ADDRESS, price="$0.01", network=EVM_NETWORK),
            PaymentOption(scheme="exact", pay_to=SVM_ADDRESS, price="$0.01", network=SVM_NETWORK),
        ],
        mime_type="application/json",
        description="Weather report",
    ),
}

app.add_middleware(PaymentMiddlewareASGI, routes=routes, server=server)

@app.get("/weather")
async def get_weather():
    return {"report": {"weather": "sunny", "temperature": 70}}

FastAPI: Complete Algorand Example

"""FastAPI resource server accepting USDC payments on Algorand Testnet via x402."""

import os

from dotenv import load_dotenv
from fastapi import FastAPI, Request
from pydantic import BaseModel

from x402.http import FacilitatorConfig, HTTPFacilitatorClient, PaymentOption
from x402.http.middleware.fastapi import PaymentMiddlewareASGI
from x402.http.types import RouteConfig
from x402.mechanisms.avm import ALGORAND_TESTNET_CAIP2, USDC_TESTNET_ASA_ID
from x402.mechanisms.avm.exact import ExactAvmServerScheme
from x402.schemas import AssetAmount, Network
from x402.server import x402ResourceServer

load_dotenv()

AVM_ADDRESS = os.getenv("AVM_ADDRESS")
if not AVM_ADDRESS:
    raise ValueError("AVM_ADDRESS environment variable is required")

AVM_NETWORK: Network = ALGORAND_TESTNET_CAIP2
FACILITATOR_URL = os.getenv("FACILITATOR_URL", "https://x402.org/facilitator")


class WeatherReport(BaseModel):
    weather: str
    temperature: int
    unit: str


class WeatherResponse(BaseModel):
    report: WeatherReport


app = FastAPI(title="x402 AVM Resource Server")

facilitator = HTTPFacilitatorClient(FacilitatorConfig(url=FACILITATOR_URL))
server = x402ResourceServer(facilitator)
server.register(AVM_NETWORK, ExactAvmServerScheme())

routes = {
    "GET /weather": RouteConfig(
        accepts=PaymentOption(
            scheme="exact",
            pay_to=AVM_ADDRESS,
            price="$0.01",
            network=AVM_NETWORK,
        ),
        mime_type="application/json",
        description="Weather report",
    ),
    "GET /premium/*": RouteConfig(
        accepts=PaymentOption(
            scheme="exact",
            pay_to=AVM_ADDRESS,
            price=AssetAmount(
                amount="50000",
                asset=str(USDC_TESTNET_ASA_ID),
                extra={"name": "USDC", "decimals": 6},
            ),
            network=AVM_NETWORK,
        ),
        mime_type="application/json",
        description="Premium content",
    ),
}

app.add_middleware(PaymentMiddlewareASGI, routes=routes, server=server)


@app.get("/health")
async def health_check():
    return {"status": "ok"}


@app.get("/weather")
async def get_weather(request: Request):
    return WeatherResponse(
        report=WeatherReport(weather="sunny", temperature=72, unit="F")
    )


@app.get("/premium/content")
async def get_premium_content(request: Request):
    return {"content": "Premium Algorand analytics data.", "tier": "gold"}


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=4021)

Flask: Basic Middleware Setup (PaymentMiddleware Class)

from flask import Flask
from x402.server import x402ResourceServerSync
from x402.http import HTTPFacilitatorClientSync, FacilitatorConfig, PaymentOption
from x402.http.types import RouteConfig
from x402.http.middleware.flask import PaymentMiddleware
from x402.mechanisms.avm import ALGORAND_TESTNET_CAIP2
from x402.mechanisms.avm.exact import ExactAvmServerScheme

app = Flask(__name__)

facilitator = HTTPFacilitatorClientSync(FacilitatorConfig(url="https://x402.org/facilitator"))
server = x402ResourceServerSync(facilitator)
server.register(
    ALGORAND_TESTNET_CAIP2,
    ExactAvmServerScheme(),
)

routes = {
    "GET /api/data/*": RouteConfig(
        accepts=PaymentOption(
            scheme="exact",
            network=ALGORAND_TESTNET_CAIP2,
            pay_to="YOUR_ALGORAND_ADDRESS",
            price="$0.01",
        ),
    ),
}

PaymentMiddleware(app, routes, server)

@app.route("/api/data/weather")
def get_weather():
    return {"temperature": 72, "unit": "F", "condition": "sunny"}

Flask: Factory Function

from flask import Flask
from x402.server import x402ResourceServerSync
from x402.http import HTTPFacilitatorClientSync, FacilitatorConfig, PaymentOption
from x402.http.types import RouteConfig
from x402.http.middleware.flask import payment_middleware
from x402.mechanisms.avm import ALGORAND_TESTNET_CAIP2
from x402.mechanisms.avm.exact import ExactAvmServerScheme

app = Flask(__name__)

facilitator = HTTPFacilitatorClientSync(FacilitatorConfig(url="https://x402.org/facilitator"))
server = x402ResourceServerSync(facilitator)
server.register(
    ALGORAND_TESTNET_CAIP2,
    ExactAvmServerScheme(),
)

routes = {
    "GET /weather": RouteConfig(
        accepts=PaymentOption(
            scheme="exact",
            pay_to="YOUR_ALGORAND_ADDRESS",
            price="$0.01",
            network=ALGORAND_TESTNET_CAIP2,
        ),
        mime_type="application/json",
        description="Weather report",
    ),
}

middleware_instance = payment_middleware(app, routes=routes, server=server)

@app.route("/weather")
def get_weather():
    return {"report": {"weather": "sunny", "temperature": 70}}

Flask: Middleware from Config

from flask import Flask
from x402.http import HTTPFacilitatorClientSync, FacilitatorConfig
from x402.http.middleware.flask import payment_middleware_from_config
from x402.mechanisms.avm import ALGORAND_TESTNET_CAIP2
from x402.mechanisms.avm.exact import ExactAvmServerScheme

app = Flask(__name__)

facilitator = HTTPFacilitatorClientSync(FacilitatorConfig(url="https://x402.org/facilitator"))

routes = {
    "GET /api/data/*": {
        "accepts": {
            "scheme": "exact",
            "network": ALGORAND_TESTNET_CAIP2,
            "payTo": "YOUR_ALGORAND_ADDRESS",
            "maxAmountRequired": "10000",
            "asset": "10458941",
        }
    }
}

payment_middleware_from_config(
    app,
    routes=routes,
    facilitator_client=facilitator,
    schemes=[
        {
            "network": ALGORAND_TESTNET_CAIP2,
            "server": ExactAvmServerScheme(),
        },
    ],
)

@app.route("/api/data/weather")
def get_weather():
    return {"temperature": 72}

Flask: Accessing Payment Info in Route Handlers

from flask import g, jsonify

@app.route("/api/paid-resource")
def paid_resource():
    payment_payload = getattr(g, "payment_payload", None)
    payment_requirements = getattr(g, "payment_requirements", None)

    if payment_payload:
        return jsonify({
            "data": "premium content",
            "paid": True,
        })

    return jsonify({"data": "premium content"})

Flask: Multi-Network (AVM + EVM + SVM)

import os
from dotenv import load_dotenv
from flask import Flask, jsonify
from x402.http import FacilitatorConfig, HTTPFacilitatorClientSync, PaymentOption
from x402.http.middleware.flask import payment_middleware
from x402.http.types import RouteConfig
from x402.mechanisms.avm import ALGORAND_TESTNET_CAIP2
from x402.mechanisms.avm.exact import ExactAvmServerScheme
from x402.mechanisms.evm.exact import ExactEvmServerScheme
from x402.mechanisms.svm.exact import ExactSvmServerScheme
from x402.schemas import Network
from x402.server import x402ResourceServerSync

load_dotenv()

EVM_ADDRESS = os.getenv("EVM_ADDRESS")
SVM_ADDRESS = os.getenv("SVM_ADDRESS")
AVM_ADDRESS = os.getenv("AVM_ADDRESS")
AVM_NETWORK: Network = ALGORAND_TESTNET_CAIP2
EVM_NETWORK: Network = "eip155:84532"
SVM_NETWORK: Network = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"

app = Flask(__name__)

facilitator = HTTPFacilitatorClientSync(FacilitatorConfig(url="https://x402.org/facilitator"))
server = x402ResourceServerSync(facilitator)
server.register(AVM_NETWORK, ExactAvmServerScheme())
server.register(EVM_NETWORK, ExactEvmServerScheme())
server.register(SVM_NETWORK, ExactSvmServerScheme())

routes = {
    "GET /weather": RouteConfig(
        accepts=[
            PaymentOption(scheme="exact", pay_to=AVM_ADDRESS, price="$0.01", network=AVM_NETWORK),
            PaymentOption(scheme="exact", pay_to=EVM_ADDRESS, price="$0.01", network=EVM_NETWORK),
            PaymentOption(scheme="exact", pay_to=SVM_ADDRESS, price="$0.01", network=SVM_NETWORK),
        ],
        mime_type="application/json",
        description="Weather report",
    ),
}

payment_middleware(app, routes=routes, server=server)

@app.route("/weather")
def get_weather():
    return jsonify({"report": {"weather": "sunny", "temperature": 70}})

Flask: Complete Algorand Example

"""Flask resource server accepting USDC payments on Algorand Testnet via x402."""

import os

from dotenv import load_dotenv
from flask import Flask, g, jsonify

from x402.http import FacilitatorConfig, HTTPFacilitatorClientSync, PaymentOption
from x402.http.middleware.flask import payment_middleware
from x402.http.types import RouteConfig
from x402.mechanisms.avm import ALGORAND_TESTNET_CAIP2, USDC_TESTNET_ASA_ID
from x402.mechanisms.avm.exact import ExactAvmServerScheme
from x402.schemas import AssetAmount, Network
from x402.server import x402ResourceServerSync

load_dotenv()

AVM_ADDRESS = os.getenv("AVM_ADDRESS")
if not AVM_ADDRESS:
    raise ValueError("AVM_ADDRESS environment variable is required")

AVM_NETWORK: Network = ALGORAND_TESTNET_CAIP2
FACILITATOR_URL = os.getenv("FACILITATOR_URL", "https://x402.org/facilitator")

app = Flask(__name__)

facilitator = HTTPFacilitatorClientSync(FacilitatorConfig(url=FACILITATOR_URL))
server = x402ResourceServerSync(facilitator)
server.register(AVM_NETWORK, ExactAvmServerScheme())

routes = {
    "GET /weather": RouteConfig(
        accepts=PaymentOption(
            scheme="exact",
            pay_to=AVM_ADDRESS,
            price="$0.01",
            network=AVM_NETWORK,
        ),
        mime_type="application/json",
        description="Weather report",
    ),
    "GET /premium/*": RouteConfig(
        accepts=PaymentOption(
            scheme="exact",
            pay_to=AVM_ADDRESS,
            price=AssetAmount(
                amount="50000",
                asset=str(USDC_TESTNET_ASA_ID),
                extra={"name": "USDC", "decimals": 6},
            ),
            network=AVM_NETWORK,
        ),
        mime_type="application/json",
        description="Premium content",
    ),
}

payment_middleware(app, routes=routes, server=server)


@app.route("/health")
def health_check():
    return jsonify({"status": "ok"})


@app.route("/weather")
def get_weather():
    return jsonify({"report": {"weather": "sunny", "temperature": 72, "unit": "F"}})


@app.route("/premium/content")
def get_premium_content():
    payment = getattr(g, "payment_payload", None)
    return jsonify({
        "content": "Premium Algorand analytics data.",
        "tier": "gold",
        "paid": payment is not None,
    })


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=4021, debug=False)

Flask vs FastAPI: Sync/Async Comparison

# Flask (sync)
from flask import Flask, g, jsonify
from x402.server import x402ResourceServerSync
from x402.http import HTTPFacilitatorClientSync, FacilitatorConfig
from x402.http.middleware.flask import payment_middleware

app = Flask(__name__)
facilitator = HTTPFacilitatorClientSync(FacilitatorConfig(url="https://x402.org/facilitator"))
server = x402ResourceServerSync(facilitator)
server.register(AVM_NETWORK, ExactAvmServerScheme())
payment_middleware(app, routes=routes, server=server)

@app.route("/weather")
def get_weather():
    payment = getattr(g, "payment_payload", None)
    return jsonify({"weather": "sunny"})
# FastAPI (async)
from fastapi import FastAPI, Request
from x402.server import x402ResourceServer
from x402.http import HTTPFacilitatorClient, FacilitatorConfig
from x402.http.middleware.fastapi import PaymentMiddlewareASGI

app = FastAPI()
facilitator = HTTPFacilitatorClient(FacilitatorConfig(url="https://x402.org/facilitator"))
server = x402ResourceServer(facilitator)
server.register(AVM_NETWORK, ExactAvmServerScheme())
app.add_middleware(PaymentMiddlewareASGI, routes=routes, server=server)

@app.get("/weather")
async def get_weather(request: Request):
    payment = getattr(request.state, "payment_payload", None)
    return {"weather": "sunny"}

Custom Error Responses (Paywall Config)

from x402.http import PaywallConfig

# FastAPI
app.add_middleware(
    PaymentMiddlewareASGI,
    routes=routes,
    server=server,
    paywall_config=PaywallConfig(...),
)

# Flask
PaymentMiddleware(
    app,
    routes,
    server,
    paywall_config=PaywallConfig(...),
)

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