Skip to main content

EOA-based test harness for x402 micropayments — sign and send EIP-712 TransferWithAuthorization payments without CDP dependency

Project description

x402 Payment Harness

EOA-based test harness for x402 micropayments. Sign and send EIP-712 TransferWithAuthorization payments from a local private key — no CDP dependencies, no wallet API, no cloud signing.

PyPI Python License: MIT x402


What is this?

x402 is an HTTP-native micropayment protocol built by Coinbase. It uses HTTP 402 responses to gate API access behind USDC payments on Base mainnet.

The standard x402 payment flow requires an EIP-712 TransferWithAuthorization signature — but most tutorials assume you're using the Coinbase CDP API for signing. If you want to test x402 payments from a simple EOA wallet (e.g. a fresh test key, a Hardhat account, or a script), there's no clean tool for it.

This harness fills that gap.


Proven on Base mainnet

This harness was used to execute the first known end-to-end x402 payment test from a Python script:

Field Value
TX Hash 0xb0ef774a7a26cdb370c305a625b2cf1bd6d7bb98f2ca16119d953bdcebc7e860
Network Base mainnet (eip155:8453)
Amount 0.005000 USDC
Block 42707833 ✅
Gas 62,147 units / ~$0.002

Install

pip install x402-payment-harness

Quick start

CLI

# Pay and call an x402-protected URL
x402-pay \
  --key 0xYOUR_PRIVATE_KEY \
  --to 0xRECIPIENT_ADDRESS \
  --amount 0.005 \
  https://x402-discovery-api.onrender.com/discover?query=search

# Output:
# ✅ Status: 200
#    TX Hash:   0xabc123...
#    Explorer:  https://basescan.org/tx/0xabc123...
# Use env var for private key (recommended)
export X402_PRIVATE_KEY=0xYOUR_PRIVATE_KEY
x402-pay --to 0xRECIPIENT --amount 0.005 https://api.example.com/resource
# Generate only the X-PAYMENT header (no HTTP call)
x402-pay --sign-only --key 0xYOUR_KEY --to 0xRECIPIENT --amount 0.005
# X-PAYMENT: eyJ4NDAyVmVyc2lvbiI6MSwic2NoZW1lIjoiZXhhY3QiLC...
# JSON output for scripting
x402-pay --json --key 0xYOUR_KEY --to 0xRECIPIENT --amount 0.005 https://api.example.com/
# { "success": true, "status_code": 200, "tx_hash": "0x...", ... }

Python library

from x402_harness import X402Client, PaymentConfig

config = PaymentConfig(
    private_key="0xYOUR_PRIVATE_KEY",
    pay_to="0xRECIPIENT_ADDRESS",
    amount_usdc=0.005,
    network="eip155:8453",  # Base mainnet
)

client = X402Client()
result = client.get("https://api.example.com/resource", config)

if result.success:
    print(f"Payment confirmed! TX: {result.tx_hash}")
else:
    print(f"Failed: {result.error}")

Sign only (no HTTP)

from x402_harness import sign_payment, PaymentConfig

config = PaymentConfig(
    private_key="0xYOUR_PRIVATE_KEY",
    pay_to="0xRECIPIENT_ADDRESS",
    amount_usdc=0.005,
)

header_value = sign_payment(config)  # base64-encoded JSON
# Use as: headers={"X-PAYMENT": header_value}

How x402 works

Client                          Server
  |                               |
  |-- GET /resource ------------> |
  |                               |
  |<-- 402 Payment Required ------|
  |    { "accepts": [{            |
  |        "scheme": "exact",     |
  |        "network": "eip155:8453",|
  |        "payTo": "0x...",      |
  |        "amount": "5000"       |
  |      }] }                     |
  |                               |
  | [sign EIP-712 locally]        |
  |                               |
  |-- GET /resource ------------> |
  |   X-PAYMENT: base64(...)      |
  |                               |
  |<-- 200 OK --------------------|  
  |   X-PAYMENT-RESPONSE: ...     |
  |   { ...resource data... }     |

This harness implements the client side: signs the EIP-712 TransferWithAuthorization payload and attaches it as the X-PAYMENT header on the retry.


API reference

PaymentConfig

Field Type Default Description
private_key str required 0x-prefixed hex private key
pay_to str required Recipient address
amount_usdc float required Amount in USDC (e.g. 0.005)
network str "eip155:8453" Base mainnet
usdc_contract str Base USDC USDC contract address
valid_for_seconds int 300 Authorization validity window
scheme str "exact" Payment scheme

X402Client.get(url, config, params=None)

Makes a GET request with automatic x402 payment. Returns PaymentResult.

sign_payment(config)str

Signs payment without making any HTTP requests. Returns base64-encoded X-PAYMENT header value.

PaymentResult

Field Type Description
success bool True if server returned 200
status_code int HTTP status code
tx_hash str|None On-chain transaction hash
receipt dict|None Decoded X-PAYMENT-RESPONSE
response_body dict|None Response JSON body
error str|None Error message if failed

Why no CDP dependency?

Coinbase CDP wallets require CDP_WALLET_SECRET — a base64-encoded private key that must be stored correctly and passed to the CDP signing API. For test environments:

  • Secrets can be truncated in storage (common in .env files)
  • CDP API requires network calls, adding latency and failure modes
  • EOA wallets are simpler: sign locally with eth_account, submit directly

This harness uses pure eth_account signing. If you have a private key, you can sign.


Compatibility

Network USDC Contract Chain ID
Base mainnet 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 8453
Base Sepolia 0x036CbD53842c5426634e7929541eC2318f3dCF7e 84532

For Base Sepolia:

config = PaymentConfig(
    private_key="0xYOUR_KEY",
    pay_to="0xRECIPIENT",
    amount_usdc=0.001,
    network="eip155:84532",
    usdc_contract="0x036CbD53842c5426634e7929541eC2318f3dCF7e",
)

Related projects


License

MIT

Project details


Download files

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

Source Distribution

x402_payment_harness-1.0.0.tar.gz (12.4 kB view details)

Uploaded Source

Built Distribution

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

x402_payment_harness-1.0.0-py3-none-any.whl (11.3 kB view details)

Uploaded Python 3

File details

Details for the file x402_payment_harness-1.0.0.tar.gz.

File metadata

  • Download URL: x402_payment_harness-1.0.0.tar.gz
  • Upload date:
  • Size: 12.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for x402_payment_harness-1.0.0.tar.gz
Algorithm Hash digest
SHA256 934e1bf6ac25a1f86c8f99652accf732206ae7506321a28d59ace4576c3acca6
MD5 682e80fb95ac9df186e4e99e121b2240
BLAKE2b-256 bf47f28a15f2e2fcd03f9b8f7ba1b6576e6fa35375c0e41f463b300ce7017275

See more details on using hashes here.

File details

Details for the file x402_payment_harness-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for x402_payment_harness-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f166533062c42e14a76adf608e2745cca361cadbfe4282795046c2cfd6afe684
MD5 43762a8f8a500df12e21850fa76322a0
BLAKE2b-256 4deeb1495c4b39581e381dd5c020d5a48b46c0917350eb5b42e3a8fba6577230

See more details on using hashes here.

Supported by

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