Public networks

Solana devnet

USDC on Solana devnet: the buyer signs a transfer, the facilitator pays the fee and broadcasts it.

x402 exact on Solana devnet (solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1). The buyer signs a USDC transfer. The facilitator adds its fee payer signature and broadcasts it; no gateway or merchant key is needed for payment. Omitting the asset fields selects Circle's devnet USDC mint.

The gateway loads Solana support only when a Solana offer is configured:

bash
npm install @x402/[email protected] @solana/[email protected]
examples/solana-devnet/config.yamlyaml
version: 1

merchant:
  id: solana-devnet-example
  name: Solana Devnet Example
  publicBaseUrl: ${GATEWAY_PUBLIC_BASE_URL:-http://localhost:8080}

server:
  port: ${GATEWAY_PORT:-8080}
  host: 0.0.0.0
  # Operator routes (receipts, events) 404 without this. Uncomment and set it
  # before exposing the gateway anywhere.
  # adminToken: ${ADMIN_TOKEN}

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 Solana devnet.
    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: solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1
    # No asset fields: Circle's devnet USDC mint, from the built-in profile.
    # The transfer goes to this wallet's USDC token account, which must exist.
    payTo: ${SOLANA_MERCHANT_WALLET}
    networks:
      # Only for health checks: the genesis hash, the mint and its decimals
      solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1:
        rpcUrl: ${X402_RPC_URL:-https://api.devnet.solana.com}
    # A blockhash expires in about 60 to 90 seconds; a slower backend should
    # use `paymentFlow: upfront`
    maxTimeoutSeconds: 300
    facilitator:
      mode: remote
      # Its /supported names the fee payer each challenge carries
      url: ${X402_FACILITATOR_URL:-https://x402.org/facilitator}
      auth:
        type: none

What you need

A merchant walletSOLANA_MERCHANT_WALLET. Its USDC token account must exist; send it any amount of devnet USDC once.
A funded buyerdevnet USDC from faucet.circle.com. No SOL: the facilitator pays the fee.
A Solana facilitatorone whose /supported lists the devnet network. On 2026-10-07 x402.org's and PayAI's did.

Run it

bash
SOLANA_MERCHANT_WALLET=YourWalletAddress \
  npm run agent-commerce -- validate --config examples/solana-devnet/config.yaml

Run it as in the Base Sepolia example, with AGENT_COMMERCE_CONFIG=examples/solana-devnet/config.yaml.

Slow handlersA handler that can take longer than about a minute should use paymentFlow: upfront: the signed transaction's blockhash expires before an authorization flow settles it.

Prove it settles

bash
X402_SMOKE_TARGETS=solana-devnet \
X402_SOLANA_DEVNET_BUYER_SECRET_KEY='[...]' \
X402_SOLANA_DEVNET_MERCHANT_ADDRESS=YourWalletAddress \
  npm run test:testnet

The buyer key is the 64-byte secret key, as the JSON array solana-keygen writes or the base58 string a wallet exports. The run reads the token balance changes from the confirmed transaction itself; see smoke tests.

It has been run: 5289xbeyHJ… settled 0.01 USDC on 2026-10-10.

Source: examples/solana-devnet