Public networks

Base mainnet (PayAI)

The cheapest mainnet proving run: an unauthenticated public facilitator.

The cheapest way to prove the mainnet path end to end. PayAI's public facilitator serves x402 v2 exact on eip155:8453 and takes no credential — no account, no SDK, no @coinbase/x402.

examples/base-mainnet-payai/config.yamlyaml
version: 1

merchant:
  id: base-mainnet-payai-example
  name: Base Mainnet (PayAI) Example
  publicBaseUrl: ${GATEWAY_PUBLIC_BASE_URL:-http://localhost:8080}

server:
  port: ${GATEWAY_PORT:-8080}
  host: 0.0.0.0
  allowedOrigins: []

storage:
  receipts:
    driver: sqlite
    path: ${RECEIPT_STORE_PATH:-./data/receipts.sqlite}

protocols:
  http:
    enabled: true
  mcp:
    enabled: true
    mountPath: /mcp

resources:
  premium_report:
    name: Premium Report
    description: One paid endpoint, settled in USDC on Base.
    input:
      type: object
      properties: {}
      additionalProperties: false
    backend:
      type: http
      method: GET
      url: ${MERCHANT_API_BASE_URL:-http://localhost:3000}/api/report
      timeoutMs: 10000
    pricing:
      type: fixed
      amount: "0.01"
      currency: USDC
    expose: [http, mcp]
    payments: [x402]

payments:
  x402:
    enabled: true
    network: eip155:8453
    rpcUrl: ${X402_RPC_URL:-https://base.drpc.org}
    asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
    assetName: "USD Coin"
    assetVersion: "2"
    assetDecimals: 6
    payTo: ${MERCHANT_WALLET}
    maxTimeoutSeconds: 600
    # "I meant to use real money."
    allowMainnet: ${ALLOW_X402_MAINNET}
    # "I accept THIS counterparty, with no account and no terms."
    allowUnauthenticatedFacilitator: true
    facilitator:
      mode: remote
      url: https://facilitator.payai.network
      auth:
        type: none

Two acknowledgements, not one

yaml
allowMainnet: true                     # I meant to use real money
allowUnauthenticatedFacilitator: true  # I accept THIS counterparty

Neither implies the other, and dropping either fails config loading:

console
FAIL  CONFIG_INVALID: payments.x402: facilitator https://facilitator.payai.network
      takes no credential, and this is a mainnet deployment. It will see every
      payment authorisation you handle, with no account, terms or support behind
      it. Set payments.x402.allowUnauthenticatedFacilitator: true to accept that,
      or configure facilitator.auth.

doctor reports it as WARN, not a pass, for as long as it stays this way.

What you are exposed to

Not your money: an EIP-3009 authorisation names its recipient, amount and chain, so the facilitator can broadcast exactly that transfer or nothing. At risk: availability (no SLA — every paid call fails closed if it disappears), your payment graph (it sees every authorisation), and continuity. Fine for a proving run; think harder before production.

Run it

bash
ALLOW_X402_MAINNET=true MERCHANT_WALLET=0xYourWallet \
  npm run agent-commerce -- validate --config examples/base-mainnet-payai/config.yaml

# to actually settle — spends real USDC every run
export ALLOW_X402_MAINNET=true
export X402_MAINNET_BUYER_PRIVATE_KEY=0x...   # funded with USDC on Base
export X402_MAINNET_MERCHANT_ADDRESS=0x...
export X402_FACILITATOR_URL=https://facilitator.payai.network
npm run test:mainnet

Source: examples/base-mainnet-payai