> ## Documentation Index
> Fetch the complete documentation index at: https://docs.x402x.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# x402x-fetch

> Extend fetch to automatically handle 402 payments and retries

## Overview

`x402x-fetch` extends native `fetch`. When encountering HTTP 402 (Payment Required), it automatically parses the server’s payment requirements, creates a signature (Permit / EIP-3009 / Permit2), and retries the original request with the `X-Payment` header.

### Key features

* Seamless integration: compatible with native fetch API
* Multiple authorization types: EIP-3009 / EIP-2612 Permit / Permit2
* Multi-chain support: common EVM chains built-in, custom chains supported
* Safety: max amount cap, signature validation

## Install and dependencies

```bash theme={null}
npm i x402x-fetch viem
```

Dependencies (example versions):

```json theme={null}
{
  "viem": "^2.21.26",
  "zod": "^3.24.2",
  "x402x": "workspace:^"
}
```

## Quick start

### One-liner wrapper

```ts theme={null}
import { wrapFetchWithPayment } from "x402x-fetch";
const fetchWithPay = wrapFetchWithPayment(fetch, walletClient, "1000000");
```

### Full example

```ts theme={null}
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { wrapFetchWithPayment } from "x402x-fetch";
import { bscTestnet } from "viem/chains";

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const client = createWalletClient({ account, transport: http(), chain: bscTestnet });

// Pay up to 10 USDC (6 decimals)
const fetchWithPay = wrapFetchWithPayment(fetch, client, "10000000");

const response = await fetchWithPay("https://api.example.com/premium", { method: "GET" });
const data = await response.json();
console.log("✅", data);
```

## Parameters

* `walletClient`: to sign
* `maxValue`: maximum allowed payment amount (highly recommended)
* `paymentRequirementsSelector`: custom selection for multi-option resources

## Workflow

```
1) Request a paid resource
2) Receive 402 response (contains x402Version and accepts list)
3) Select/validate payment requirements (amount ≤ maxValue)
4) Generate X-Payment header (signature)
5) Automatically retry the original request with the payment header
6) Receive 200 and data (server verifies and settles)
```

## Typical use cases

* Access paid APIs/content
* Consistent UX across environments (Browser / Node)

## API reference (condensed)

```ts theme={null}
function wrapFetchWithPayment(
  fetch: typeof globalThis.fetch,
  walletClient: WalletClient,
  maxValue?: string,
  paymentRequirementsSelector?: (response: Response402) => PaymentRequirements
): typeof globalThis.fetch
```

Supported `paymentType`: `eip3009` | `permit` | `permit2`

## Multi-chain support

You can create a signer by chain name / viem Chain / custom config:

```ts theme={null}
import { createEvmSigner, wrapFetchWithPayment } from "x402x-fetch";
import { polygon } from "viem/chains";

// Chain name
const signer1 = createEvmSigner("bsc-testnet", "0xYourPrivateKey");

// viem Chain
const signer2 = createEvmSigner(polygon, "0xYourPrivateKey");

// Custom
const signer3 = createEvmSigner({ chainId: 56, name: "BSC", rpcUrl: "https://rpc" }, "0xKey");

const fetchWithPay = wrapFetchWithPayment(fetch, signer1);
```

## Usage examples

### GET

```ts theme={null}
const res = await fetchWithPay("https://api.example.com/premium-data");
const data = await res.json();
```

### POST (with body)

```ts theme={null}
const res = await fetchWithPay("https://api.example.com/compute", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ complexity: 10 }),
});
```

### Custom headers

```ts theme={null}
await fetchWithPay("https://api.example.com/data", {
  headers: {
    Authorization: "Bearer token",
    "X-Custom": "value",
  },
});
```

### Error handling and amount protection

```ts theme={null}
const fetchPay = wrapFetchWithPayment(fetch, client, "1000000");
try {
  const res = await fetchPay("https://api.example.com/data");
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  const data = await res.json();
} catch (e) {
  if (e instanceof Error && e.message.includes("exceeds maximum")) {
    // Server asked for an amount exceeding the cap
  }
}
```

### Read payment response header

```ts theme={null}
const res = await fetchWithPay("https://api.example.com/premium");
const header = res.headers.get("X-Payment-Response");
if (header) {
  const info = JSON.parse(Buffer.from(header, "base64").toString());
  console.log(info.transactionHash, info.payer);
}
```

## Best practices

* Set a reasonable `maxValue` in production
* Centralize logging and error classification for debugging
* In browsers, use a wallet connection (don’t expose private keys)

## Resources

* Source: `https://github.com/WTFLabs-WTF/x402x/tree/main/typescript/packages/x402x-fetch`
* Issues: `https://github.com/WTFLabs-WTF/x402x/issues`
