x402 — USDC on Base

Pay for oracle attestations with USDC on Base L2. Designed for AI agents, EVM-native applications, and any system with a Base wallet.

Overview

x402 is an HTTP payment protocol where the server returns a 402 Payment Required response with USDC payment instructions. The client signs an EIP-3009 transferWithAuthorization on Base, then retries the request with payment proof. Settlement is verified via the Coinbase CDP facilitator.

How It Works

1

Request an oracle endpoint

Send a GET request to any paid endpoint without payment headers.

bash
curl -i https://api.myceliasignal.com/oracle/btcusd
2

Receive 402 Payment Required

The server responds with HTTP 402 and a JSON body containing payment requirements. The PAYMENT-REQUIRED header contains a base64-encoded version of the same requirements.

json — 402 response body
{
  "x402Version": 1,
  "accepts": [
    {
      "scheme": "exact",
      "network": "base",
      "maxAmountRequired": "1000",
      "resource": "https://api.myceliasignal.com/oracle/btcusd",
      "description": "BTC/USD spot price — Ed25519-signed attestation",
      "mimeType": "application/json",
      "payTo": "0x...payment_address...",
      "maxTimeoutSeconds": 60,
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "extra": { "name": "USD Coin", "version": "2" }
    }
  ],
  "error": "X-PAYMENT header is required"
}
3

Sign an EIP-3009 transferWithAuthorization

Using the payment requirements, construct and sign an EIP-3009 transferWithAuthorization for the specified USDC amount on Base. The maxAmountRequired is in USDC atomic units (6 decimals), so "1000" = $0.001 USDC.

Amount format

USDC on Base uses 6 decimal places. 1000 atomic units = $0.001. For VWAP endpoints, the amount is 2000 ($0.002).

4

Retry with X-PAYMENT header

Base64-encode the payment payload (including the signed authorization) and send it in the X-PAYMENT header.

bash
curl https://api.myceliasignal.com/oracle/btcusd \
  -H "X-PAYMENT: <base64-encoded-payment-payload>"

The server verifies and settles the payment through the Coinbase CDP facilitator, then returns the signed attestation.

5

Receive Ed25519-signed attestation

On successful payment, the oracle returns the price attestation re-signed with Ed25519.

json — success response
{
  "domain": "BTCUSD",
  "canonical": "v1|BTCUSD|84231.50|USD|2|2026-02-28T07:51:00Z|890123|binance,...|median",
  "signature": "<base64-ed25519-signature>",
  "signing_scheme": "ed25519",
  "pubkey": "<hex-ed25519-public-key>"
}

Programmatic Integration (Python)

Here's a complete example using the x402-python library with Coinbase CDP wallet:

python — pip install x402 cdp-sdk httpx
import httpx
import json, base64, hashlib
from nacl.signing import VerifyKey
from nacl.encoding import HexEncoder

async def query_oracle(pair: str, wallet) -> dict:
    """Query an oracle endpoint via x402, handling the full payment flow."""
    url = f"https://api.myceliasignal.com/oracle/{pair}"

    async with httpx.AsyncClient(timeout=15) as client:
        # Step 1: Request endpoint, get 402
        resp = await client.get(url)

        if resp.status_code != 402:
            raise Exception(f"Expected 402, got {resp.status_code}")

        # Step 2: Parse payment requirements
        requirements = resp.json()["accepts"][0]

        # Step 3: Sign EIP-3009 authorization with your wallet
        payment = wallet.sign_x402_payment(requirements)

        # Step 4: Retry with payment
        payment_header = base64.b64encode(
            json.dumps(payment).encode()
        ).decode()

        resp = await client.get(
            url,
            headers={"X-PAYMENT": payment_header}
        )

        if resp.status_code != 200:
            raise Exception(f"Payment failed: {resp.text}")

        data = resp.json()

        # Step 5: Verify Ed25519 signature
        msg_hash = hashlib.sha256(data["canonical"].encode()).digest()
        vk = VerifyKey(data["pubkey"], encoder=HexEncoder)
        vk.verify(msg_hash, base64.b64decode(data["signature"]))

        # Parse price from canonical string
        fields = data["canonical"].split("|")
        return {
            "price": fields[2],
            "sources": fields[7].split(","),
            "timestamp": fields[5],
            "verified": True,
        }

Discovery Endpoint

Before making paid requests, you can discover payment terms and the Ed25519 public key:

bash
curl https://api.myceliasignal.com/sho/info

This returns the signing public key, payment address, USDC contract address, facilitator URL, depeg status, and per-endpoint pricing — everything you need to build the payment client.

Pricing

Endpoint TypeUSDC AmountAtomic Units
Spot pairs (BTC/USD, ETH/USD, etc.)$0.0011000
VWAP pairs (BTC/USD VWAP, BTC/EUR VWAP)$0.0022000

Safety Mechanisms

USDC Depeg Circuit Breaker

The x402 proxy monitors the USDC/USD peg across 5 exchange sources (Kraken, Bitstamp, Coinbase, Gemini, Bitfinex). If the median USDC rate deviates beyond the threshold, all paid endpoints return 503 and suspend USDC payments until the peg is restored. This protects both the oracle operator and consumers from accepting or paying depegged stablecoins.

json — depeg circuit breaker response
{
  "error": "depeg_circuit_breaker",
  "message": "USDC payment suspended — stablecoin deviation exceeds threshold",
  "usdc_rate": 0.9847,
  "threshold": 0.02
}

Tiered Enforcement

The x402 proxy tracks payment failures per wallet address. Repeated failures trigger escalating enforcement:

TierTriggerEffect
0 — NormalFull access
1 — CooldownRecent failure10-minute cooldown before retrying
3 — Hard Block10+ failures in 7 daysAddress permanently blocked

You can check the enforcement status of any address:

bash
curl https://api.myceliasignal.com/sho/enforcement/0xYourAddress

Error Responses

StatusErrorMeaning
402X-PAYMENT header is requiredNo payment provided — parse the requirements and pay
402payment_verification_failedPayment signature invalid or insufficient amount
403payment_address_blockedAddress blocked due to repeated failures
502oracle_backend_errorUpstream oracle backend unreachable
502backend_missing_canonicalBackend returned response without canonical string
503depeg_circuit_breakerUSDC payments suspended due to depeg — try L402 instead
Tip

If x402 returns 503 due to a depeg event, consider falling back to the L402 (Lightning) protocol, which is not affected by stablecoin depegs. Both protocols serve the same oracle data.

x402 Protocol Details

ParameterValue
Protocol versionx402Version: 1
Payment schemeexact
Networkbase (Base L2)
AssetUSDC — 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
Payment methodEIP-3009 transferWithAuthorization
SettlementCoinbase CDP Facilitator
Signing schemeEd25519 (SHA-256 pre-hashed)
Payment timeout60 seconds