Skip to content

Repository files navigation

x402 Facilitator

Multi-chain HTTP 402 Payment Required facilitator. It verifies payment payloads off-chain and settles them on-chain, on the upstream x402 TypeScript ecosystem (@bankofai/x402-core + @bankofai/x402-tron + @bankofai/x402-evm).

A TypeScript/Node service. The earlier Python/FastAPI implementation is kept under legacy/ as a behavioral reference.

Features

  • verify / settle / supported endpoints backed by @bankofai/x402-core.
  • TRON exact (EIP-3009 / Permit2) + exact_gasfree; EVM (BSC) exact.
  • upto (Permit2 up-to-max settlement, TRON + EVM) and batch-settlement (channel deposit/voucher/claim/settle/refund, TRON + EVM).
  • Non-custodial signing — settlement keys never enter this process; wallets are resolved through @bankofai/agent-wallet and only signing crosses the boundary.
  • Settlement persistence keyed on the on-chain authorization identity, with seller-scoped query APIs.
  • API-key auth, dynamic rate limiting, Prometheus metrics.
  • 1Password-or-local secret configuration.
  • GasFree Open API transparent proxy (HMAC) for TRON exact_gasfree.

Quick start

Prerequisites

  • Node 22+
  • PostgreSQL
  • A wallet provider resolvable by @bankofai/agent-wallet (unlocked via AGENT_WALLET_PASSWORD)
  • Optional: 1Password service-account token (OP_SERVICE_ACCOUNT_TOKEN)

Install and run

npm ci
FACILITATOR_SERVICE_ENV=dev npm run dev

Default listen address: http://0.0.0.0:8001.

Scripts

Script Purpose
npm run dev Run with tsx watch (reload on change)
npm run build Compile TypeScript to dist/
npm start Run the compiled server (dist/index.js)
npm run typecheck tsc --noEmit
npm test Unit tests (vitest)

Configuration

Choose a YAML configuration source explicitly. Set FACILITATOR_SERVICE_ENV=dev or FACILITATOR_SERVICE_ENV=prod to select the matching baked-in environment config, or set FACILITATOR_CONFIG_PATH to an explicit YAML file; the explicit path takes precedence. The process fails before startup when neither is set.

Required: database.url, facilitator.networks (≥1 network, listed = enabled).

Secrets resolve env first, then 1Password (each onepassword.* value is a vault/item/field ref, used when OP_SERVICE_ACCOUNT_TOKEN / onepassword.token is set). Relevant env vars:

Var Purpose
FACILITATOR_SERVICE_ENV dev or prod; selects the matching baked-in config file
FACILITATOR_CONFIG_PATH Explicit config path; overrides FACILITATOR_SERVICE_ENV
AGENT_WALLET_PASSWORD Unlock the agent-wallet provider
TRON_GRID_API_KEY TronGrid rate limits (shared across TRON networks)
GASFREE_API_KEY[_NILE|_MAINNET] / GASFREE_API_SECRET[...] GasFree relayer creds (gate exact_gasfree)
UPSTREAM_NILE_BASE / UPSTREAM_MAINNET_BASE Override GasFree upstream bases
OP_SERVICE_ACCOUNT_TOKEN 1Password service-account token
RATE_LIMIT_STORE memory (default) or redis for shared counters across replicas
RATE_LIMIT_REDIS_URL / REDIS_URL Redis connection URL (required when RATE_LIMIT_STORE=redis; needs the optional ioredis dep)
TRUST_PROXY_FOR_RATELIMIT true to key anonymous limits on X-Forwarded-For (set only when the direct peer is a trusted proxy; the rightmost XFF entry is used, so append-style proxies like nginx $proxy_add_x_forwarded_for are safe. Default off keys on the socket peer)

BSC transaction creation and broadcast use the primary RPC. Receipt confirmation waits up to 15 seconds on the primary, then up to 45 seconds on the independent fallback for the same transaction hash; it never rebroadcasts the transaction.

Fees were removed from the TRON facilitator schemes in SDK 1.0.1 — the exact/upto proxies transfer exactly amount and the GasFree relayer handles its own fee terms. There is no base_fee config and no /fee/quote endpoint.

Endpoints

Method Path Notes
GET /health Liveness (no auth / rate-limit)
GET /supported Supported scheme/network kinds
POST /verify Verify a payment payload
POST /settle Settle on-chain; rate-limited; persists a settlement
GET /payments/tx/{hash} Lookup by settlement tx hash
GET /payments?network=&nonce=[&asset=&payer=] Lookup by authorization identity
GET /payments Authenticated seller's settlement feed (?limit=&offset=)
GET /metrics Prometheus (main port, or a separate monitoring.port)
ALL /mainnet/*, /nile/* GasFree transparent proxy (HMAC)

Lookups are seller-scoped when the request carries a valid X-API-KEY.

Database

The settlements table (created on startup) is keyed on (network, scheme, asset, payer, nonce) — the on-chain authorization identity — with a partial-unique index enforcing one successful settlement per authorization. The shared sellers / api_keys_plus tables are reused unchanged for auth and seller scoping. The legacy payment_records table is not used.

SDK consumption

The @bankofai/x402-* packages (x402-core, x402-evm, x402-tron) are consumed from npm, declared as ^1.0.1 in package.json.

Docker

docker build -t x402-facilitator .

docker run -p 8001:8001 -p 9001:9001 \
  -e FACILITATOR_SERVICE_ENV=dev \
  -e OP_SERVICE_ACCOUNT_TOKEN \
  -v "$PWD/logs:/app/logs" \
  x402-facilitator

The container runs as non-root (uid/gid 1000); make sure the host logs/ directory is writable by that uid before bind-mounting it. The agent-wallet password is resolved from OP_SERVICE_ACCOUNT_TOKEN (1Password) when set; otherwise pass it directly via AGENT_WALLET_PASSWORD. Port 9001 is only needed when monitoring.port differs from server.port.

Both config/facilitator.config.dev.yaml and config/facilitator.config.prod.yaml are baked into the image. Select one at runtime with FACILITATOR_SERVICE_ENV=dev or FACILITATOR_SERVICE_ENV=prod; no config-directory mount is required. FACILITATOR_CONFIG_PATH remains available for an explicit custom path. OP_SERVICE_ACCOUNT_TOKEN must be injected only at container runtime (for example by the deployment platform's secret environment-variable facility); it is never stored in the image or either YAML file.

Status

Feature-complete and unit-tested; not yet validated against live chains (real verify+settle on tron:0xcd8690dc / eip155:97 and GasFree end-to-end are pending), and without integration tests yet.

About

x402 facilitator server implementation

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages