Skip to main content

x402-client

PyPI version Python 3.10+ License: MIT

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:

  1. Makes your HTTP request to a paid endpoint
  2. If the server responds with 402, reads payment requirements from the payment-required header
  3. Signs an EIP-3009 TransferWithAuthorization message using your wallet
  4. Retries the request with the signed payment in the payment-signature header
  5. 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

  1. Initial Request: Client makes a request to a paid endpoint
  2. 402 Response: Server responds with HTTP 402 and includes payment options in the payment-required header
  3. Payment Signing: Client selects a payment option and signs an EIP-3009 TransferWithAuthorization message
  4. Retry with Payment: Client retries the original request with the payment-signature header
  5. Settlement: Server verifies the signature and settles the payment on-chain
  6. 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 TransferWithAuthorization for 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

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

x402_client-0.1.0.tar.gz (9.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

x402_client-0.1.0-py3-none-any.whl (7.5 kB view details)

Uploaded Python 3

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

Hashes for x402_client-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d36c647667371384338118e7fa762a47ceba91a70be40f88095900e0156105be
MD5 e57dcbbdeacad53aa01f655cbe767042
BLAKE2b-256 2ac7a3993f28b0938537972551d0901b5809fbaa7939cbfdd01e219886969930

See more details on using hashes here.

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

Hashes for x402_client-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c070a92466fde6b5757138de6d7d0c0b14480b98529b3c70d9e8a494c50187f4
MD5 eebeade126ae796b0a5532076163c2fd
BLAKE2b-256 1a70d963978edc8b067eb5e0f99b8bdce365d6d07800b98dc4188b9484f51896

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page