Documentation

Python SDK

Add x402 payments to Python applications. Supports Flask and FastAPI.

pypi primer-x402

Installation

bash
pip install primer-x402

With optional dependencies:

bash
pip install primer-x402[flask]     # Flask middleware
pip install primer-x402[fastapi]   # FastAPI middleware
pip install primer-x402[httpx]     # Async HTTP client
pip install primer-x402[all]       # All optional dependencies

Quick Start (CLI)

New in v0.5.0 — manage wallets, probe URLs, and make payments from the command line:

bash
# Create a new wallet
x402 wallet create

# Check wallet balance
x402 wallet balance 0xYourAddress

# Check if a URL requires payment (and get price)
x402 probe https://api.example.com/paid

# Preview payment without paying
x402 pay https://api.example.com/paid --dry-run

# Make a payment
X402_PRIVATE_KEY=0x... x402 pay https://api.example.com/paid --max-amount 0.10

CLI Commands

Command Description
wallet createCreate a new wallet (address, private key, mnemonic)
wallet balance <address>Check USDC balance
wallet from-mnemonicRestore wallet from mnemonic
probe <url>Check if URL requires payment
pay <url>Make a payment (requires X402_PRIVATE_KEY)
pay <url> --dry-runPreview payment without paying
networksList supported networks
openclaw initSet up for OpenClaw agents

Environment Variables

Variable Description
X402_PRIVATE_KEYWallet private key (required for payments)
X402_NETWORKDefault network (default: base)
X402_MAX_AMOUNTDefault max payment amount in USDC
X402_FACILITATORCustom facilitator URL

Wallet Utilities

New in v0.5.0 — programmatic wallet management:

python
from primer_x402 import create_wallet, wallet_from_mnemonic, get_balance, x402_probe

# Create a new wallet
wallet = create_wallet()
print(wallet.address)      # 0x...
print(wallet.private_key)  # 0x...
print(wallet.mnemonic)     # "word1 word2 ..."

# Restore from mnemonic
restored = wallet_from_mnemonic('word1 word2 ...')

# Check balance
balance = get_balance('0x...', 'base', 'USDC')
print(balance.balance)  # "100.50"

# Probe a URL for x402 support
probe = x402_probe('https://api.example.com/paid')
if probe.supports_402:
    print('Payment required:', probe.requirements)

Error Handling

New in v0.5.0 — structured errors for programmatic handling:

python
from primer_x402 import X402Error, ErrorCodes

try:
    response = x402_fetch(url, signer, max_amount='0.10')
except X402Error as e:
    if e.code == ErrorCodes.INSUFFICIENT_FUNDS:
        print('Need more funds:', e.details)
    elif e.code == ErrorCodes.AMOUNT_EXCEEDS_MAX:
        print('Payment too expensive:', e.details)
    elif e.code == ErrorCodes.SETTLEMENT_FAILED:
        print('Settlement failed:', e.details)

Error Codes

Code Description
INSUFFICIENT_FUNDSWallet balance too low
AMOUNT_EXCEEDS_MAXPayment exceeds max_amount
SETTLEMENT_FAILEDFacilitator settlement failed
INVALID_RESPONSEMalformed 402 response
MISSING_PRIVATE_KEYPrivate key not provided
UNSUPPORTED_NETWORKNetwork not supported

Payer (Client)

Wrap your HTTP client to automatically handle 402 responses:

python
import os
from primer_x402 import create_signer, x402_requests

# Create a signer with your wallet
signer = create_signer('eip155:8453', os.environ['PRIVATE_KEY'])

# Create a session that handles 402 payments automatically
with x402_requests(signer, max_amount='1.00') as session:
    response = session.get('https://api.example.com/paid-endpoint')
    print(response.json())

When the server returns 402 Payment Required, the SDK automatically:

  1. Parses the payment requirements from the response
  2. Creates a signed payment authorization (no gas required)
  3. Retries the request with the payment header
  4. Returns the successful response

Async with httpx

python
from primer_x402 import create_signer, x402_httpx

signer = create_signer('eip155:8453', os.environ['PRIVATE_KEY'])

async with x402_httpx(signer, max_amount='1.00') as client:
    response = await client.get('https://api.example.com/paid-endpoint')
    print(response.json())

Payee (Server)

Flask

python
from flask import Flask, jsonify
from primer_x402 import x402_flask

app = Flask(__name__)

@app.before_request
@x402_flask('0xYourWalletAddress', {
    '/api/premium': {
        'amount': '0.01',                                     # $0.01 USDC
        'asset': '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',  # USDC on Base
        'network': 'eip155:8453'                              # Base mainnet
    }
})
def require_payment():
    pass

@app.route('/api/premium')
def premium_content():
    return jsonify({'data': 'premium content'})

FastAPI

python
from fastapi import FastAPI
from primer_x402 import x402_fastapi

app = FastAPI()

app.add_middleware(x402_fastapi(
    '0xYourWalletAddress',
    {
        '/api/premium': {
            'amount': '0.01',
            'asset': '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
            'network': 'eip155:8453'
        }
    }
))

@app.get('/api/premium')
async def premium():
    return {'data': 'premium content'}

Single Route Decorator

For protecting individual routes without full middleware:

python
from primer_x402 import x402_protect

@app.route('/api/premium')
@x402_protect('0xYourWallet', '0.01', '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', 'eip155:8453')
def premium():
    return jsonify({'data': 'premium content'})

Token Approval (ERC-20)

For non-EIP-3009 tokens, approve the Prism contract once:

python
from primer_x402 import create_signer, approve_token

signer = create_signer('eip155:8453', os.environ['PRIVATE_KEY'])

# One-time approval (requires gas)
receipt = approve_token(signer, '0xTokenAddress')

# Now payments with this token are gasless

Custom Facilitator

For non-Base networks, specify your own facilitator:

python
# Payer
session = x402_requests(
    signer,
    max_amount='1.00',
    facilitator='https://your-facilitator.com'
)

# Payee
@x402_flask('0xAddress', routes, facilitator='https://your-facilitator.com')

Testing

The SDK includes utilities for testing without real payments:

python
import pytest
from primer_x402.testing import create_mock_facilitator, create_test_payment

@pytest.fixture
def mock_facilitator():
    mock = create_mock_facilitator(mode='approve')
    yield mock
    mock.close()

def test_paid_endpoint(client, mock_facilitator):
    payment = create_test_payment(amount='10000')  # 0.01 USDC

    response = client.get(
        '/api/premium',
        headers={'PAYMENT-SIGNATURE': payment}
    )

    assert response.status_code == 200

Debug Logging

python
import logging
logging.getLogger('x402').setLevel(logging.DEBUG)

OpenClaw Integration

This SDK is compatible with OpenClaw AI agents. Set up your agent with one command:

bash
x402 openclaw init

This creates a wallet, configures the network, and installs the x402 skill. Check status with:

bash
x402 openclaw status