# x402-sdk

Repository: <https://github.com/fastxyz/x402-sdk>

### What is x402?

x402 is a payment protocol built on HTTP status code `402 Payment Required`. It enables:

* **Pay-per-request APIs**: Charge for individual API calls
* **No accounts needed**: Just sign and pay
* **Instant settlement**: Sub-second on Fast, \~15s on EVM
* **Multi-chain**: Fast, Arbitrum, Base, and more

### Packages

| Package                                                                                                        | Description                                      | npm                               |
| -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | --------------------------------- |
| [x402-client](https://github.com/fastxyz/x402-sdk/blob/refactor/use-allset-sdk/packages/x402-client)           | Client SDK - sign and pay for 402 content        | `npm i @fastxyz/x402-client`      |
| [x402-server](https://github.com/fastxyz/x402-sdk/blob/refactor/use-allset-sdk/packages/x402-server)           | Server SDK - protect routes, verify payments     | `npm i @fastxyz/x402-server`      |
| [x402-facilitator](https://github.com/fastxyz/x402-sdk/blob/refactor/use-allset-sdk/packages/x402-facilitator) | Facilitator - verify signatures, settle on-chain | `npm i @fastxyz/x402-facilitator` |

### Dependencies

Network and token configurations are imported from the canonical Fast SDKs:

* [**@fastxyz/allset-sdk**](https://www.npmjs.com/package/@fastxyz/allset-sdk) — Bridge configs, USDC addresses, Fast token IDs
* [**@fastxyz/sdk**](https://www.npmjs.com/package/@fastxyz/sdk) — Fast RPC endpoints, transaction encoding

EIP-3009 metadata (`usdcName`, `usdcVersion`) is maintained locally in x402-sdk as it's specific to the x402 payment flow.

### Quick Start

#### 1. \[For Facilitator] Run a Facilitator

The facilitator verifies payment signatures and settles EVM payments on-chain.

```typescript
import express from 'express';
import { createFacilitatorServer } from '@fastxyz/x402-facilitator';

const app = express();
app.use(express.json());

app.use(createFacilitatorServer({
  // Private key for settling EVM payments (pays gas)
  evmPrivateKey: process.env.FACILITATOR_KEY as `0x${string}`,
}));

app.listen(4020, () => console.log('Facilitator on :4020'));
```

#### 2. \[For Merchant] Protect Your API (Server)

```typescript
import express from 'express';
import { paymentMiddleware } from '@fastxyz/x402-server';

const app = express();

app.use(paymentMiddleware(
  '0x1234...',  // Your payment address
  {
    'GET /api/premium/*': { price: '$0.10', network: 'arbitrum-sepolia' },
  },
  { url: 'http://localhost:4020' }  // Facilitator URL
));

app.get('/api/premium/data', (req, res) => {
  res.json({ data: 'Premium content!' });
});

app.listen(3000);
```

#### 3. \[For Buyer] Pay for Content (Client)

```typescript
import { x402Pay } from '@fastxyz/x402-client';

const result = await x402Pay({
  url: 'https://api.example.com/api/premium/data',
  wallet: {
    type: 'evm',
    privateKey: '0x...',
    address: '0x...',
  },
});

console.log(result.body); // Your paid content
```

#### 4. \[For Buyer] Auto-Bridge: Pay EVM with Fast Funds

Provide both wallets to automatically bridge fastUSDC → USDC when paying for EVM endpoints:

```typescript
import { x402Pay } from '@fastxyz/x402-client';

const result = await x402Pay({
  url: 'https://api.example.com/api/premium/data',  // EVM endpoint
  wallet: [
    {
      type: 'fast',
      privateKey: '...',      // 32-byte Ed25519 key (hex)
      publicKey: '...',       // 32-byte pubkey (hex)
      address: 'fast1...',    // bech32m address
    },
    {
      type: 'evm',
      privateKey: '0x...',
      address: '0x...',
    },
  ],
  verbose: true,  // See bridge progress logs
});

// Flow:
// 1. Detects EVM endpoint requires USDC
// 2. Checks EVM USDC balance (insufficient)
// 3. Bridges fastUSDC → USDC via AllSet (~3-4s)
// 4. Signs EIP-3009 authorization
// 5. Sends payment → 200 OK
```

### Protocol Flow

```
┌─────────┐                    ┌─────────┐                    ┌─────────────┐
│  Client │                    │  Server │                    │ Facilitator │
└────┬────┘                    └────┬────┘                    └──────┬──────┘
     │                              │                                │
     │  GET /api/data               │                                │
     │─────────────────────────────>│                                │
     │                              │                                │
     │  402 Payment Required        │                                │
     │  { accepts: [...] }          │                                │
     │<─────────────────────────────│                                │
     │                              │                                │
     │  Sign payment                │                                │
     │  (EIP-3009 or Fast tx)    │                                │
     │                              │                                │
     │  GET /api/data               │                                │
     │  X-PAYMENT: <signed>         │                                │
     │─────────────────────────────>│                                │
     │                              │                                │
     │                              │  POST /verify                  │
     │                              │─────────────────────────────────>
     │                              │                                │
     │                              │  { isValid: true }             │
     │                              │<─────────────────────────────────
     │                              │                                │
     │  200 OK (Fast)            │                                │
     │<─────────────────────────────│                                │
     │                              │                                │
     │                              │  POST /settle (EVM only)       │
     │                              │─────────────────────────────────>
     │                              │                                │
     │  200 OK (EVM)                │  { txHash: 0x... }             │
     │<─────────────────────────────│<─────────────────────────────────
```

### Payment Flows

#### EVM (Arbitrum, Base, Ethereum)

Uses **EIP-3009 `transferWithAuthorization`** - client signs, facilitator settles.

```
Client                          Server                         Facilitator
  │                               │                                │
  │ Sign EIP-3009 authorization   │                                │
  │ (EIP-712 typed data)          │                                │
  │                               │                                │
  │ X-PAYMENT: { signature,       │                                │
  │   authorization: {from,to,    │                                │
  │   value,validAfter,           │                                │
  │   validBefore,nonce} }        │                                │
  │──────────────────────────────>│                                │
  │                               │  /verify                       │
  │                               │  - Recover signer from sig     │
  │                               │  - Check recipient matches     │
  │                               │  - Check amount sufficient     │
  │                               │  - Check timing valid          │
  │                               │  - Check on-chain balance      │
  │                               │────────────────────────────────>
  │                               │  { isValid: true }             │
  │                               │<────────────────────────────────
  │                               │                                │
  │                               │  /settle                       │
  │                               │  - Re-verify payment           │
  │                               │  - Check nonce not used        │
  │                               │  - Call transferWithAuth()     │
  │                               │  - Wait for confirmation       │
  │                               │────────────────────────────────>
  │                               │  { txHash: 0x... }             │
  │                               │<────────────────────────────────
  │  200 OK + content             │                                │
  │<──────────────────────────────│                                │
```

#### Fast (Instant Settlement)

Client submits transaction directly, sends **certificate** as proof.

The Fast client and facilitator both use the canonical `@fastxyz/sdk` transaction codec, including Fast `network_id` validation for `fast-testnet` and `fast-mainnet`.

```
Client                          Server                         Facilitator
  │                               │                                │
  │ Submit TokenTransfer to       │                                │
  │ Fast network               │                                │
  │ (transaction already on-chain)│                                │
  │                               │                                │
  │ X-PAYMENT: {                  │                                │
  │   transactionCertificate: {   │                                │
  │     envelope: {               │                                │
  │       transaction: {...},     │                                │
  │       signature: {...}        │                                │
  │     },                        │                                │
  │     signatures: [...]         │                                │
  │   }                           │                                │
  │ }                             │                                │
  │──────────────────────────────>│                                │
  │                               │  /verify                       │
  │                               │  - Verify sender signature     │
  │                               │  - Verify committee signatures │
  │                               │  - Check recipient/amount/token│
  │                               │────────────────────────────────>
  │                               │  { isValid: true }             │
  │                               │<────────────────────────────────
  │                               │                                │
  │  200 OK + content             │  (no /settle needed -          │
  │<──────────────────────────────│   already on-chain)            │
```

### Supported Networks

| Network            | Type | Chain ID | Token    |
| ------------------ | ---- | -------- | -------- |
| `fast-testnet`     | Fast | -        | testUSDC |
| `fast-mainnet`     | Fast | -        | USDC     |
| `ethereum-sepolia` | EVM  | 11155111 | USDC     |
| `arbitrum-sepolia` | EVM  | 421614   | USDC     |
| `arbitrum`         | EVM  | 42161    | USDC     |
| `base`             | EVM  | 8453     | USDC     |

## x402 Agent Skill

| Skill             | Package                     | Description                                  |
| ----------------- | --------------------------- | -------------------------------------------- |
| client-skill      | `@fastxyz/x402-client`      | Pay for 402-protected content                |
| server-skill      | `@fastxyz/x402-server`      | Protect API routes with payment requirements |
| facilitator-skill | `@fastxyz/x402-facilitator` | Verify signatures and settle on-chain        |
