Python client for the x402 Payment Protocol (v2) - HTTP 402 payments made easy
Project description
x402-python-client
A Python client for the x402 Payment Protocol (v2) that enables seamless HTTP 402 payments using EIP-3009 gasless USDC transfers.
Why this client?
The x402 protocol v2 sends payment requirements in the payment-required HTTP header (base64 encoded), not in the response body. This client correctly implements the v2 specification:
- Reads payment requirements from the
payment-requiredheader - Signs EIP-712 typed data for TransferWithAuthorization (EIP-3009)
- Sends payment via the
payment-signatureheader - Supports both async and sync HTTP clients
Installation
pip install x402-python-client
Quick Start
Async Client
import asyncio
from eth_account import Account
from x402_client import X402AsyncClient
account = Account.from_key("0xYOUR_PRIVATE_KEY")
async def main():
async with X402AsyncClient(account=account) as client:
response = await client.post(
"https://api.example.com/paid-endpoint",
json={"your": "params"}
)
data = response.json()
print(data)
asyncio.run(main())
Sync Client
from eth_account import Account
from x402_client import X402Client
account = Account.from_key("0xYOUR_PRIVATE_KEY")
with X402Client(account=account) as client:
response = client.post(
"https://api.example.com/paid-endpoint",
json={"your": "params"}
)
data = response.json()
print(data)
How It Works
- Initial Request: Client makes a request to a paid endpoint
- 402 Response: Server responds with HTTP 402 and a
payment-requiredheader containing payment options - Payment Signing: Client signs an EIP-3009 TransferWithAuthorization message
- Retry with Payment: Client retries the request with the
payment-signatureheader - Success: Server verifies the payment and returns the requested resource
Client Server
| |
| POST /api/resource |
| ----------------------------------> |
| |
| 402 Payment Required |
| payment-required: <base64> |
| <---------------------------------- |
| |
| POST /api/resource |
| payment-signature: <base64> |
| ----------------------------------> |
| |
| 200 OK |
| { "data": ... } |
| <---------------------------------- |
Configuration
Both clients accept standard httpx client options:
async with X402AsyncClient(
account=account,
timeout=60.0, # Request timeout in seconds
debug=True, # Enable debug logging
headers={"X-Custom": "header"},
) as client:
...
Supported Networks
The client supports any EVM chain with USDC and EIP-3009 support. Network is specified using CAIP-2 format:
eip155:1- Ethereum Mainneteip155:8453- Base Mainneteip155:84532- Base Sepolia (testnet)eip155:137- Polygoneip155:42161- Arbitrum One
API Reference
X402AsyncClient
class X402AsyncClient:
def __init__(self, account: Account, **kwargs):
"""
Initialize async x402 client.
Args:
account: eth_account.Account instance for signing
debug: Enable debug logging (default: False)
**kwargs: Passed to httpx.AsyncClient
"""
async def get(self, url: str, **kwargs) -> httpx.Response:
"""Make GET request with automatic x402 payment handling."""
async def post(self, url: str, **kwargs) -> httpx.Response:
"""Make POST request with automatic x402 payment handling."""
X402Client
class X402Client:
def __init__(self, account: Account, **kwargs):
"""
Initialize sync x402 client.
Args:
account: eth_account.Account instance for signing
debug: Enable debug logging (default: False)
**kwargs: Passed to httpx.Client
"""
def get(self, url: str, **kwargs) -> httpx.Response:
"""Make GET request with automatic x402 payment handling."""
def post(self, url: str, **kwargs) -> httpx.Response:
"""Make POST request with automatic x402 payment handling."""
Protocol Details
This client implements the x402 Payment Protocol v2:
- Payment Scheme:
exact(exact amount transfers) - Authorization: EIP-3009 TransferWithAuthorization
- Signing: EIP-712 typed data signatures
- Asset: USDC (or any EIP-3009 compatible token)
Payment Payload Structure
{
"x402Version": 2,
"resource": { "url": "..." },
"accepted": { "...PaymentRequirements..." },
"payload": {
"signature": "0x...",
"authorization": {
"from": "0x...",
"to": "0x...",
"value": "10000",
"validAfter": "0",
"validBefore": "1234567890",
"nonce": "0x..."
}
}
}
Development
# Clone the repository
git clone https://github.com/agentokratia/x402-python-client.git
cd x402-python-client
# Install development dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run linter
ruff check .
# Run type checker
mypy src/
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
License
MIT License - see LICENSE for details.
Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file x402_python_client-0.1.0.tar.gz.
File metadata
- Download URL: x402_python_client-0.1.0.tar.gz
- Upload date:
- Size: 7.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
89c7531e282879cd0133f9a1777361c3f4e96dd43d6815ab9e9a84a3d6e040e4
|
|
| MD5 |
1e1fb049d5f0a7122c593e7db9abb5ab
|
|
| BLAKE2b-256 |
f52a9639e67d063415f9adf3a72b119ad5edf0c8791c8e3e9aeb4cd24b928d8f
|
File details
Details for the file x402_python_client-0.1.0-py3-none-any.whl.
File metadata
- Download URL: x402_python_client-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3bc2b0795e28e69206b86289dea16d1fb31b9ac4dfb11266f71ef6d2277ed044
|
|
| MD5 |
199425e845fe98925515d7f05006ca83
|
|
| BLAKE2b-256 |
b6093d25b66dbdda4eca4ab70cddae4913daf0aa5cd5f68712d737e65345d88f
|