Facilitator Path
Lesson 2 of 3
10 min

Using an Existing Facilitator (CDP)

Learning Objectives

  • Understand why CDP is recommended
  • Configure clients to use CDP
  • Configure servers to use CDP
  • Monitor transactions through CDP
Why Use CDP? - Production-ready, maintained by Coinbase - Supports Base mainnet (USDC) - Free to use (you only pay gas fees) - No setup required
typescript
// Client setup
import { wrapFetchWithPayment } from "@x402/fetch";
import { x402Client } from "@x402/core/client";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
import { facilitator } from '@coinbase/x402';

const evmSigner = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const client = new x402Client();
registerExactEvmScheme(client, { signer: evmSigner });
const fetchWithPayment = wrapFetchWithPayment(fetch, client);
typescript
// Server setup
import { paymentMiddleware } from '@x402/express';
import { x402ResourceServer, HTTPFacilitatorClient } from '@x402/core/server';
import { registerExactEvmScheme } from '@x402/evm/exact/server';
import express from 'express';

// Setup with CDP facilitator
const facilitatorClient = new HTTPFacilitatorClient({
  url: 'https://api.cdp.coinbase.com/platform/v2/x402'
});

const server = new x402ResourceServer(facilitatorClient);
registerExactEvmScheme(server);
const app = express();

app.use(
  paymentMiddleware(
    {
      'GET /api/data': {
        accepts: [{
          scheme: 'exact',
          price: '$0.001',
          network: 'eip155:8453',
          payTo: '0xYourWallet',
        }],
        description: 'Data endpoint',
        mimeType: 'application/json',
      },
    },
    server
  )
);

That's It!

CDP handles all the complexity: signature verification, on-chain settlement, retries, monitoring. You just import facilitator and pass it in.

typescript
// Monitoring transactions
const response = await fetchWithPayment('https://api.example.com');
const paymentResponse = response.headers.get('X-PAYMENT-RESPONSE');

if (paymentResponse) {
  const decoded = JSON.parse(Buffer.from(paymentResponse, 'base64').toString());
  console.log('Transaction hash:', decoded.transaction);
  console.log('View on Base:', `https://basescan.org/tx/${decoded.transaction}`);
}

Interactive Playground

typescript
Output

Click "Run Code" to see the output