Python client for the x402 Payment Protocol (v2) - HTTP 402 payments made easy
Project description
x402-client
A Python client for the x402 Payment Protocol that enables seamless HTTP 402 payments using EIP-3009 gasless USDC transfers.
What it does
The x402 protocol enables payments over HTTP using the 402 Payment Required status code. This client handles the payment flow automatically:
- Makes your HTTP request to a paid endpoint
- If the server responds with
402, reads payment requirements from thepayment-requiredheader - Signs an EIP-3009
TransferWithAuthorizationmessage using your wallet - Retries the request with the signed payment in the
payment-signatureheader - Returns the successful response
You just make HTTP requests like normal - the payment handling happens transparently.
Installation
pip install x402-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
Client Server
| |
| POST /api/resource |
| ----------------------------------> |
| |
| 402 Payment Required |
| payment-required: <base64 JSON> |
| <---------------------------------- |
| |
| [Client signs EIP-3009 payment] |
| |
| POST /api/resource |
| payment-signature: <base64 JSON> |
| ----------------------------------> |
| |
| [Server settles payment on-chain] |
| |
| 200 OK |
| { "data": ... } |
| <---------------------------------- |
Payment Flow Details
- Initial Request: Client makes a request to a paid endpoint
- 402 Response: Server responds with HTTP 402 and includes payment options in the
payment-requiredheader - Payment Signing: Client selects a payment option and signs an EIP-3009
TransferWithAuthorizationmessage - Retry with Payment: Client retries the original request with the
payment-signatureheader - Settlement: Server verifies the signature and settles the payment on-chain
- Success: Server returns the requested resource
Configuration
Both clients accept standard httpx client options:
async with X402AsyncClient(
account=account,
timeout=120.0, # Request timeout in seconds (blockchain settlement can take time)
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. Networks are identified using CAIP-2 format:
| Network | CAIP-2 Identifier |
|---|---|
| Ethereum Mainnet | eip155:1 |
| Base Mainnet | eip155:8453 |
| Base Sepolia (testnet) | eip155:84532 |
| Polygon | eip155:137 |
| Arbitrum One | eip155:42161 |
The network is determined by the server's payment requirements - you don't need to configure it.
API Reference
X402AsyncClient
class X402AsyncClient:
def __init__(self, account: Account, **kwargs):
"""
Initialize async x402 client.
Args:
account: eth_account.Account instance for signing payments
debug: Enable debug logging (default: False)
**kwargs: Passed to httpx.AsyncClient (timeout, headers, etc.)
"""
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 payments
debug: Enable debug logging (default: False)
**kwargs: Passed to httpx.Client (timeout, headers, etc.)
"""
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:
- Payment Scheme:
exact- pay the exact amount requested - Authorization: EIP-3009
TransferWithAuthorizationfor gasless transfers - Signing: EIP-712 typed data signatures
- Asset: USDC (or any EIP-3009 compatible token specified by the server)
Payment Payload Structure
The payment-signature header contains a base64-encoded JSON payload:
{
"x402Version": 2,
"resource": {
"url": "https://api.example.com/paid-endpoint"
},
"accepted": {
"scheme": "exact",
"network": "eip155:84532",
"asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
"amount": "10000",
"payTo": "0x..."
},
"payload": {
"signature": "0x...",
"authorization": {
"from": "0xYourWallet",
"to": "0xRecipient",
"value": "10000",
"validAfter": "0",
"validBefore": "1734567890",
"nonce": "0x..."
}
}
}
Development
# Clone the repository
git clone https://github.com/agentokratia/x402-client.git
cd x402-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_client-0.1.0.tar.gz.
File metadata
- Download URL: x402_client-0.1.0.tar.gz
- Upload date:
- Size: 9.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 |
d36c647667371384338118e7fa762a47ceba91a70be40f88095900e0156105be
|
|
| MD5 |
e57dcbbdeacad53aa01f655cbe767042
|
|
| BLAKE2b-256 |
2ac7a3993f28b0938537972551d0901b5809fbaa7939cbfdd01e219886969930
|
File details
Details for the file x402_client-0.1.0-py3-none-any.whl.
File metadata
- Download URL: x402_client-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.5 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 |
c070a92466fde6b5757138de6d7d0c0b14480b98529b3c70d9e8a494c50187f4
|
|
| MD5 |
eebeade126ae796b0a5532076163c2fd
|
|
| BLAKE2b-256 |
1a70d963978edc8b067eb5e0f99b8bdce365d6d07800b98dc4188b9484f51896
|