Skip to content

x402 Facilitator

The SBC facilitator is a hosted service that verifies and settles x402 payments. It never holds funds — it receives a signed authorization from the payer and executes the on-chain transfer atomically.

Base URL: https://x402.stablecoin.xyz

Mainnet requires an API key (X-API-Key header). Get yours at dashboard.stablecoin.xyz. Testnet is open.


Using the SDK

FacilitatorClient is the SDK wrapper around the HTTP API. You rarely need to call it directly — x402Middleware and createX402Client use it internally — but it's useful for custom integrations.

import { FacilitatorClient } from '@stablecoin.xyz/x402'
 
const facilitator = new FacilitatorClient({
  apiKey: process.env.API_KEY,                    // required for mainnet
  facilitatorUrl: 'https://x402.stablecoin.xyz',  // default
})
 
// verify without settling
const result = await facilitator.verify(paymentPayload, paymentRequirements)
// { isValid: true, payer: '0x...', invalidReason: null }
 
// verify + settle (executes on-chain transfer)
const settled = await facilitator.settle(paymentPayload, paymentRequirements)
// { success: true, transaction: '0xTxHash', network: 'eip155:8453', payer: '0x...' }

HTTP API

GET /supported

Returns the supported payment kinds and facilitator signer addresses. No auth required.

curl https://x402.stablecoin.xyz/supported

kinds is an array of objects — one entry per network, asset, and x402 version. Both x402 v1 and v2 are advertised: v2 entries carry a CAIP-2 network, v1 entries carry the legacy network name.

{
  "kinds": [
    {
      "x402Version": 2,
      "scheme": "exact",
      "network": "eip155:8453",
      "extra": {
        "assetTransferMethod": "erc2612",
        "name": "Stable Coin",
        "version": "1"
      }
    },
    {
      "x402Version": 2,
      "scheme": "exact",
      "network": "eip155:8453",
      "extra": {
        "assetTransferMethod": "erc2612",
        "name": "USD Coin",
        "version": "2"
      }
    },
    {
      "x402Version": 2,
      "scheme": "exact",
      "network": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
      "extra": {
        "assetTransferMethod": "delegated-spl",
        "name": "SBC",
        "version": "1"
      }
    }
  ],
  "extensions": [],
  "signers": {
    "eip155:*": ["0xdeE710bB6a3b652C35B5cB74E7bdb03EE1F641E6"],
    "solana:*": ["2mSjKVjzRGXcipq3DdJCijbepugfNSJCN1yVN2tgdw5K"]
  }
}

POST /verify

Verifies a payment payload without executing it on-chain. Checks signature validity, amount, deadline, and payer balance.

Headers:
  • Content-Type: application/json
  • X-API-Key: sbc-... (mainnet only)
Request:
{
  "paymentPayload": {
    "x402Version": 2,
    "accepted": { "scheme": "exact", "network": "eip155:8453" },
    "payload": {
      "signature": "0x...",
      "authorization": {
        "from": "0xPayer",
        "to": "0xFacilitator",
        "value": "1000000000000000",
        "validAfter": "0",
        "validBefore": "1700000000",
        "nonce": "0"
      }
    }
  },
  "paymentRequirements": {
    "scheme": "exact",
    "network": "eip155:8453",
    "maxAmountRequired": "1000000000000000",
    "asset": "0xfdcC3dd6671eaB0709A4C0f3F53De9a333d80798",
    "payTo": "0xMerchant",
    "maxTimeoutSeconds": 300,
    "extra": { "name": "Stable Coin", "version": "1" }
  }
}
Response:
{ "isValid": true, "payer": "0xPayer", "invalidReason": null }

POST /settle

Executes the on-chain transfer. For EVM: calls permit() + transferFrom(). For Solana: executes the delegated SPL transfer.

Same request format as /verify. Response:

{
  "success": true,
  "transaction": "0xTxHash",
  "network": "eip155:8453",
  "payer": "0xPayer"
}

GET /health

curl https://x402.stablecoin.xyz/health
# {"status":"ok","service":"SBC x402 Facilitator"}

Network Reference

NetworkCAIP-2StatusAssetDecimalsAddress
Baseeip155:8453MainnetSBC180xfdcC3dd6671eaB0709A4C0f3F53De9a333d80798
Baseeip155:8453MainnetUSDC60x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
Base Sepoliaeip155:84532Testnet (free)SBC60xf9FB20B8E097904f0aB7d12e9DbeE88f2dcd0F16
Base Sepoliaeip155:84532Testnet (free)USDC60x036CbD53842c5426634e7929541eC2318f3dCF7e
Radiuseip155:723487MainnetSBC60x33ad9e4BD16B69B5BFdED37D8B5D9fF9aba014Fb
Radius Testneteip155:72344Testnet (free)SBC60x33ad9e4BD16B69B5BFdED37D8B5D9fF9aba014Fb
Solanasolana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpMainnetSBC9DBAzBUXaLj1qANCseUPZz4sp9F8d2sc78C4vKjhbTGMA

Mainnet networks (base, radius, solana) require an API key. Testnet networks are open.


Payment Mechanisms

EVM — ERC-2612 Permit

The payer signs an off-chain EIP-712 permit message authorizing the facilitator to transfer the token on their behalf. The payer pays no gas.

The facilitator calls:

  1. token.permit(owner, spender, value, deadline, v, r, s)
  2. token.transferFrom(owner, payTo, value)

Both happen atomically in a single transaction. The facilitator pays the gas.

Solana — Delegated SPL Transfer

The payer signs an off-chain ed25519 message with the format:

from:{from}|to:{to}|amount:{amount}|nonce:{nonce}|deadline:{deadline}

The facilitator executes token.transferChecked() using a pre-approved SPL token delegation.

One-time setup required per payer wallet. The payer must approve the facilitator address as a delegate for their SBC token account:

# using @solana/spl-token CLI
spl-token approve \
  <YOUR_SBC_TOKEN_ACCOUNT> \
  <AMOUNT> \
  2mSjKVjzRGXcipq3DdJCijbepugfNSJCN1yVN2tgdw5K

Or programmatically, using the SDK example:

# in examples/solana-demo/
cp .env.example .env   # add SOLANA_PRIVATE_KEY
pnpm approve           # runs approve-delegate.ts once

The facilitator address is 2mSjKVjzRGXcipq3DdJCijbepugfNSJCN1yVN2tgdw5K.


Self-Hosting

The facilitator is open source: github.com/stablecoinxyz/x402-facilitator

git clone https://github.com/stablecoinxyz/x402-facilitator
cp .env.example .env
npm install
npm run dev

Signer keys are configured per network, not globally:

VariableDescription
FACILITATOR_PORTServer port
BASE_RPC_URL · BASE_SEPOLIA_RPC_URLEVM RPC endpoints
BASE_FACILITATOR_PRIVATE_KEY · BASE_FACILITATOR_ADDRESSBase signer
BASE_SEPOLIA_FACILITATOR_PRIVATE_KEY · BASE_SEPOLIA_FACILITATOR_ADDRESSBase Sepolia signer
RADIUS_FACILITATOR_PRIVATE_KEY · RADIUS_FACILITATOR_ADDRESSRadius signer
RADIUS_TESTNET_FACILITATOR_PRIVATE_KEY · RADIUS_TESTNET_FACILITATOR_ADDRESSRadius testnet signer
SOLANA_RPC_URL · SOLANA_FACILITATOR_PRIVATE_KEY · SOLANA_FACILITATOR_ADDRESSSolana signer
SBC_TOKEN_ADDRESSSolana SBC mint

Token addresses and decimals for each EVM network are also overridable — see .env.example for the full list.

x402 v2 compatibility: 36/36 conformance checks passing. See x402-COMPATIBILITY.md.


Next

  • Overview → — how x402 works and which networks are supported
  • SDK → — integrate as a server (middleware) or client