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](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 supported networks and facilitator signer addresses. no auth required.

curl https://x402.stablecoin.xyz/supported
{
  "kinds": ["exact"],
  "networks": [
    "eip155:8453",
    "eip155:84532",
    "eip155:723487",
    "eip155:72344",
    "solana:5eykt4usfv8p8njdtrepy1vzqkqzkvdp"
  ],
  "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-2statusdecimalssbc token
baseeip155:8453mainnet180xfdcc3dd6671eab0709a4c0f3f53de9a333d80798
base sepoliaeip155:84532testnet (free)60xf9fb20b8e097904f0ab7d12e9dbee88f2dcd0f16
radiuseip155:723487mainnet60x33ad9e4bd16b69b5bfded37d8b5d9ff9aba014fb
radius testneteip155:72344testnet (free)60x33ad9e4bd16b69b5bfded37d8b5d9ff9aba014fb
solanasolana:5eykt4usfv8p8njdtrepy1vzqkqzkvdpmainnet9dbazbuxalj1qancseupzz4sp9f8d2sc78c4vkjhbtgma

active 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 sbc 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

key environment variables:

variabledescription
evm_private_keyfacilitator signer key for evm networks
solana_private_keyfacilitator signer key for solana
dashboard_urlapi key validation endpoint (default: https://dashboard.stablecoin.xyz)
enable_api_key_gatingset false to disable api key requirement (default: true)
portserver port (default: 3000)

x402 v2 compatibility: 36/36 spec checks passing. see compatibility.md.