Media

moves the media

Money

gets both kinds of user paid on one rail

Dispatch

chooses the path

Media

Money

Dispatch

Company

x402 Facilitator

A drop-in x402 facilitator for Base.

One URL swap. WAVE recovers and binds the payer from an EIP-3009 signature, then settles USDC on Base. Your server never holds a private key or talks to an RPC node.

One-line swap

Point paymentMiddleware() at WAVE's facilitator URL. It recovers the payer from the signed authorization and broadcasts the on-chain pull from the WAVE relayer. No private key and no RPC node on your server.

EIP-3009 exact scheme

The payer signs a TransferWithAuthorization (amount, recipient, validity window, nonce) as EIP-712 typed data. The credential is cryptographically bound to the payer's wallet; no bearer secret ever leaves the client.

No gas to verify

Verification is pure EIP-712 signature recovery: no gas, no RPC round-trip, no chain dependency. It returns isValid + the recovered payer. Settlement broadcasts the signed pull on Base.

Single-use enforced on-chain

USDC itself rejects a re-used (payer, nonce) authorization per EIP-3009. The same signature can never settle twice, and that guarantee does not depend on WAVE. A Durable-Object store adds an advisory gas-dedupe layer on top.

Base USDC, mainnet + testnet

USDC on Base mainnet for production; USDC on Base Sepolia for development. Contract addresses are listed below. Verify them against your own records before you integrate.

WAVE extension fields

Responses add an optional wave.rail field (e.g. base-usdc) for observability. Further wave.* fields are reserved for compliance and MPP-receipt metadata as those ship. Coinbase-compatible consumers ignore them.

CF SDK: point your x402 server at WAVE (x402-hono / agents/x402)

import { paymentMiddleware } from "x402-hono"; // or agents/x402
app.use(paymentMiddleware(payTo, routes, {
  facilitator: { url: "https://gateway.wave.online/v1/x402/facilitator" }, // ← the only change
}));

Raw HTTP: no SDK required, sign with any EIP-712 signer

let res = await fetch(resourceUrl);
if (res.status === 402) {
  const { accepts } = await res.json();               // the exact-scheme requirement
  const requirement = accepts[0];

  // Sign the EIP-3009 TransferWithAuthorization with any EIP-712 signer (viem, ethers).
  const authorization = await signer.signTypedData(
    buildExactAuthorization(requirement, { validBefore: Math.floor(Date.now() / 1000) + 600 })
  );

  const header = Buffer.from(
    JSON.stringify({ x402Version: 1, scheme: "exact", network: requirement.network, payload: authorization })
  ).toString("base64");

  res = await fetch(resourceUrl, { headers: { "X-PAYMENT": header } }); // WAVE verifies, settles, serves
}

Endpoints

PathBehavior
POST /v1/x402/facilitator/verifyPure EIP-712 signature recovery: no gas, no RPC. Returns isValid + the recovered payer.
POST /v1/x402/facilitator/settleBroadcasts the signed EIP-3009 pull from the WAVE relayer on Base mainnet. Live.
GET /.well-known/x402Discovery manifest: facilitator URL, scheme, networks, assets.
GET /v1/x402/facilitator/supportedCAIP-2 supported networks + schemes, for facilitator-registry discovery.
POST /v1/mpp/facilitator/verifyMPP protocol alias: same handler.
POST /v1/mpp/facilitator/settleMPP protocol alias: same handler.

Supported networks & assets

NetworkChainAssetContract address
Base mainneteip155:8453USDC0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
Base Sepoliaeip155:84532USDC0x036CbD53842c5426634e7929541eC2318f3dCF7e

The gateway publishes a /.well-known/x402 discovery manifest and a CAIP-2 /supported endpoint, and a _x402 DNS TXT record points wave.online and gateway.wave.online at the manifest, so facilitator registries and clients can find WAVE automatically. You can also integrate directly by setting the facilitator URL above.

Start with one URL.

Swap the facilitator URL in your x402-hono or agents/x402 config, or sign payer authorizations over raw HTTP with any EIP-712 signer. The developer portal has the full integration path.