Python SDK
Add x402 payments to Python applications. Supports Flask and FastAPI.
pypi primer-x402
Installation
pip install primer-x402
With optional dependencies:
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:
# 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 create | Create a new wallet (address, private key, mnemonic) |
wallet balance <address> | Check USDC balance |
wallet from-mnemonic | Restore wallet from mnemonic |
probe <url> | Check if URL requires payment |
pay <url> | Make a payment (requires X402_PRIVATE_KEY) |
pay <url> --dry-run | Preview payment without paying |
networks | List supported networks |
openclaw init | Set up for OpenClaw agents |
Environment Variables
| Variable | Description |
|---|---|
X402_PRIVATE_KEY | Wallet private key (required for payments) |
X402_NETWORK | Default network (default: base) |
X402_MAX_AMOUNT | Default max payment amount in USDC |
X402_FACILITATOR | Custom facilitator URL |
Wallet Utilities
New in v0.5.0 — programmatic wallet management:
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:
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_FUNDS | Wallet balance too low |
AMOUNT_EXCEEDS_MAX | Payment exceeds max_amount |
SETTLEMENT_FAILED | Facilitator settlement failed |
INVALID_RESPONSE | Malformed 402 response |
MISSING_PRIVATE_KEY | Private key not provided |
UNSUPPORTED_NETWORK | Network not supported |
Payer (Client)
Wrap your HTTP client to automatically handle 402 responses:
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:
- Parses the payment requirements from the response
- Creates a signed payment authorization (no gas required)
- Retries the request with the payment header
- Returns the successful response
Async with httpx
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
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
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:
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:
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:
# 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:
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
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:
x402 openclaw init
This creates a wallet, configures the network, and installs the x402 skill. Check status with:
x402 openclaw status