# @nerochain/x402-client

> A fetch-API-compatible function that auto-handles 402 responses.

`@nerochain/x402-client` is the agent-side package. It returns a `fetch`-compatible function that transparently handles 402 by signing and retrying. The signer is pluggable; the package itself contains no scheme-specific logic.

## Install

```bash
pnpm add @nerochain/x402-client
```

## Usage

```ts
import { x402Fetch, readSettlementReceipt } from "@nerochain/x402-client";
import { aaNativeSigner } from "@nerochain/x402-aa";

const f = x402Fetch({
  signer: aaNativeSigner({ /* ... */ }),
});

const res = await f("https://merchant/api/resource", {
  method: "POST",
  body,
});

const receipt = readSettlementReceipt(res);
```

`f` is a drop-in for the global `fetch`. Anywhere you would call `fetch(...)`, you can call `f(...)`.

## Options

```ts
type X402FetchOptions = {
  signer: PaymentSigner;
  maxRetries?: number;             // default 1
  fetchImpl?: typeof fetch;        // default global fetch
  selectRequirement?: (req: PaymentRequirements) => boolean;
};
```

- **`signer`** — the only required option. See the [`@nerochain/x402-aa`](/docs/sdk/x402-aa) page for the canonical implementation.
- **`maxRetries`** — caps the 402 → retry cycle to prevent infinite loops if a merchant is broken.
- **`fetchImpl`** — override the underlying fetch (useful for tests, custom timeouts, or alternative HTTP clients).
- **`selectRequirement`** — predicate that lets the agent reject specific `accepts[]` entries. Use it to enforce caps ("only pay if amount ≤ X") or merchant allowlists.

## How the retry loop works

```
1. await fetch(input, init)
2. status !== 402?            -> return response
3. no PAYMENT-REQUIRED header? -> return response
4. decode header, find compatible accepts entry
5. await signer.buildPayload(entry, resource)
6. fetch(input, { ...init, headers: { ..., PAYMENT-SIGNATURE: payload } })
7. return response
```

The loop runs at most `maxRetries` times. The default is 1 — exactly one retry per call. If the second response is still 402 (verification failed at the facilitator), `x402Fetch` returns it directly to the caller.

## Reading the settlement receipt

```ts
const receipt = readSettlementReceipt(res);
if (receipt) {
  console.log("settled at:", receipt.transactionHash);
  console.log("amount:    ", receipt.amount);
  console.log("payer:     ", receipt.payer);
}
```

`readSettlementReceipt(response)` extracts and decodes the `PAYMENT-RESPONSE` header. Returns `null` if the header is missing or malformed; callers can treat that case as "the merchant served us without insisting on a receipt".

## Axios integration

For codebases that already use axios, the package exposes an interceptor that retrofits the same 402 → sign → retry behavior onto an existing axios instance. Subpath import:

```ts
import axios from "axios";
import { attachX402 } from "@nerochain/x402-client/axios";
import { aaNativeSigner } from "@nerochain/x402-aa";

const client = axios.create({ baseURL: "https://merchant" });
attachX402(client, { signer: aaNativeSigner({ ... }) });

const res = await client.post("/api/llm", { prompt: "hi" });
```

`attachX402` registers a response interceptor pair (`onFulfilled` + `onRejected`) so it works whether the instance treats 402 as a fulfilled response (`validateStatus: () => true`) or rejects 402 as an error (the axios default). For the success path everywhere, set `validateStatus: (s) => s < 500` on the instance.

`axios` is an optional peer dependency: install it explicitly when you import the subpath.

```bash
pnpm add axios
```

## Implementing a custom signer

A `PaymentSigner` has two methods:

```ts
interface PaymentSigner {
  schemes(): string[];
  buildPayload(
    requirement: PaymentRequirements,
    resource?: ResourceInfo,
  ): Promise<PaymentPayload>;
}
```

`schemes()` advertises which scheme strings this signer can satisfy. `x402Fetch` uses this to filter the merchant's `accepts[]` list before calling `buildPayload`.

`buildPayload` returns the full V2 envelope (`x402Version`, `accepted`, `payload`, `extensions`). The implementation is responsible for the inner `payload` shape, the cryptographic signing, and any external service interactions (paymaster, bundler, etc.).

The reference `aa-native` signer is `@nerochain/x402-aa`'s `aaNativeSigner`. A new scheme would write a parallel signer following the same interface.
