Documentation

x402 facilitator runbook.

Section 01

Developer setup

Get the facilitator running locally with minimal ceremony.

Prerequisites

  • Node.js 18+ and npm (or pnpm)
  • EVM wallet private key with testnet funds
  • RPC endpoint for your target chain

Install

bash
git clone <repository-url>
cd polkadot-x402
npm install

Environment

Drop a .env.local in the project root:

.env.local
bash
EVM_PRIVATE_KEY=0x...
RPC_URL=https://testnet-passet-hub-eth-rpc.polkadot.io
NETWORK=polkadot-hub-testnet

# Optional overrides
CHAIN_ID=420420422
CHAIN_NAME=Polkadot Hub TestNet
CHAIN_RPC_URL=https://testnet-passet-hub-eth-rpc.polkadot.io
NATIVE_CURRENCY_NAME=PAS
NATIVE_CURRENCY_SYMBOL=PAS
NATIVE_CURRENCY_DECIMALS=18
GAS_LIMIT=500000
GAS_PRICE_MULTIPLIER=1.0
Keep the file out of version control. It belongs in .gitignore.

Run

bash
npm run dev

Visit http://localhost:3000. Production build:

bash
npm run build
npm start

Section 02

API reference

Three endpoints. All JSON. All CORS-enabled.

GET

/api/facilitator/supported

Returns supported payment configurations.

json
GET /api/facilitator/supported

[
  {
    "x402Version": 1,
    "scheme": "exact",
    "network": "polkadot-hub-testnet",
    "extra": {}
  }
]

POST

/api/facilitator/verify

json
POST /api/facilitator/verify
Content-Type: application/json

{
  "payload": "0x...",
  "details": {
    "x402Version": 1,
    "scheme": "exact",
    "network": "polkadot-hub-testnet",
    "extra": {}
  }
}

// Response
{
  "valid": true,
  "details": {
    "amount": "1000000000000000000",
    "token": "0x...",
    "from": "0x...",
    "to": "0x..."
  }
}

POST

/api/facilitator/settle

json
POST /api/facilitator/settle
Content-Type: application/json

{
  "payload": "0x...",
  "details": {
    "x402Version": 1,
    "scheme": "exact",
    "network": "polkadot-hub-testnet",
    "extra": {}
  }
}

// Response
{
  "success": true,
  "transactionHash": "0x..."
}

Errors

json
{
  "error": "Error message",
  "code": "INVALID_PAYLOAD",
  "details": {}
}

Codes: INVALID_PAYLOAD · INVALID_DETAILS · INVALID_VERSION · MISSING_SCHEME · MISSING_NETWORK · INTERNAL_ERROR

Section 03

Integration guide

Drop-in fetch examples for verify and settle flows.

typescript
async function getSupportedPayments() {
  const res = await fetch('https://your-facilitator.com/api/facilitator/supported');
  return res.json();
}

async function verifyPayment(payload, details) {
  const res = await fetch('https://your-facilitator.com/api/facilitator/verify', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ payload, details }),
  });
  if (!res.ok) throw new Error('Verification failed');
  return res.json();
}

async function settlePayment(payload, details) {
  const res = await fetch('https://your-facilitator.com/api/facilitator/settle', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ payload, details }),
  });
  if (!res.ok) throw new Error('Settlement failed');
  return res.json();
}
typescript
async function processPayment(payload) {
  const details = {
    x402Version: 1,
    scheme: 'exact',
    network: 'polkadot-hub-testnet',
  };

  const verification = await verifyPayment(payload, details);
  if (!verification.valid) throw new Error(verification.error || 'Verification failed');

  const settlement = await settlePayment(payload, details);
  if (!settlement.success) throw new Error(settlement.error || 'Settlement failed');

  return settlement.transactionHash;
}
bash
# Custom chain configuration
CHAIN_ID=12345
CHAIN_NAME=My Custom Chain
CHAIN_RPC_URL=https://rpc.example.com
NATIVE_CURRENCY_NAME=ETH
NATIVE_CURRENCY_SYMBOL=ETH
NATIVE_CURRENCY_DECIMALS=18
json
{
  "x402Version": 1,
  "scheme": "exact",
  "network": "my-custom-chain",
  "extra": {}
}