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

# How-to: Add nanopayments to an x402 buyer

> Add gas-free nanopayments to your x402 client alongside standard onchain payments

## Overview

* Add nanopayments to an existing x402 client so it can pay gas-free when a
  server supports it, while still falling back to standard onchain payments when
  it does not.
* Gas-free payments require a one-time USDC deposit into a Gateway Wallet
  contract. After depositing, all subsequent payments are offchain signatures
  with zero gas cost.
* Your existing onchain payment flows continue to work unchanged. The client
  automatically selects the right payment method based on what the server
  offers.

## Prerequisites

Before you begin, ensure you have:

* An existing x402 client using `@x402/core`.
* [Node.js](https://nodejs.org/) v18+ installed.
* An EVM wallet private key for signing.
* Testnet USDC from the [Circle Faucet](https://faucet.circle.com) (for Gateway
  deposits).

## Steps

### Step 1. Install the SDK

```shell theme={null}
npm install @circle-fin/x402-batching
```

If you plan to use `CompositeEvmScheme` (recommended for supporting both payment
methods), also install:

```shell theme={null}
npm install @x402/evm
```

### Step 2. Choose your integration approach

Pick the option that best fits your setup.

#### Option A: Support both Gateway and standard payments (recommended)

Use `CompositeEvmScheme` to route automatically based on the server's payment
requirements. When the server offers a Gateway option, the client uses
`BatchEvmScheme` for a gas-free payment. When only standard onchain options are
available, it falls back to `ExactEvmScheme`:

```ts theme={null}
import { ExactEvmScheme } from "@x402/evm/exact/client";
import {
  CompositeEvmScheme,
  BatchEvmScheme,
} from "@circle-fin/x402-batching/client";

const composite = new CompositeEvmScheme(
  new BatchEvmScheme(signer),
  new ExactEvmScheme(signer),
);

client.register("eip155:*", composite);
```

No per-request routing code is needed. `CompositeEvmScheme` checks each payment
option's `extra.name` field and delegates to the correct scheme automatically.

#### Option B: Add Gateway support to an existing client

If you already have scheme registrations and want to add Gateway support with
minimal changes while keeping standard onchain payments available:

```ts theme={null}
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { registerBatchScheme } from "@circle-fin/x402-batching/client";

registerBatchScheme(client, {
  signer: account,
  fallbackScheme: new ExactEvmScheme(account),
});
```

#### Option C: Gateway only

If you only need gas-free payments and don't need standard onchain support, use
`GatewayClient` directly. See the
[buyer quickstart](/gateway/nanopayments/quickstarts/buyer) for a full
walkthrough.

### Step 3. Deposit USDC into Gateway

Before making gas-free payments, deposit USDC from your wallet into the Gateway
Wallet contract. This is a one-time onchain transaction:

```ts theme={null}
import { GatewayClient } from "@circle-fin/x402-batching/client";

const gatewayClient = new GatewayClient({
  chain: "arcTestnet",
  privateKey: process.env.PRIVATE_KEY as `0x${string}`,
});

const balances = await gatewayClient.getBalances();
if (balances.gateway.available < 1_000_000n) {
  await gatewayClient.deposit("1");
}
```

`getBalances()` calls the
[Get Token Balances](/api-reference/gateway/all/get-token-balances) API
endpoint. After the deposit confirms, your Gateway balance is available for
gas-free payments to any server that supports nanopayments. See the discussion
at [Fast deposits](/gateway/references/supported-blockchains#fast-deposits)
about increasing deposit speeds.

### Step 4. Check support before paying

Before attempting a gas-free payment, check whether the target server supports
Gateway. The `supports()` method requests the target URL, checks for a `402`
response, and inspects the `PAYMENT-REQUIRED` header for a compatible Gateway
batching option:

```ts theme={null}
const support = await gatewayClient.supports(
  "https://api.example.com/resource",
);

if (!support.supported) {
  console.log("Server does not support Gateway -- falling back to onchain");
}
```

If you are using `CompositeEvmScheme`, this check is optional since the scheme
handles fallback automatically.

### Step 5. Understand deposit finality

When you deposit USDC into Gateway, the API waits for block confirmations before
your balance becomes available. Wait times vary by blockchain:

| Blockchain                                                                                                | Deposit time |
| --------------------------------------------------------------------------------------------------------- | ------------ |
| Arc Testnet                                                                                               | \~0.5 sec    |
| Avalanche Fuji                                                                                            | \~8 sec      |
| HyperEVM Testnet, Sei Atlantic                                                                            | \~5 sec      |
| Polygon PoS Amoy, Sonic Testnet                                                                           | \~8 sec      |
| Arbitrum Sepolia, Base Sepolia, Ethereum Sepolia, Optimism Sepolia, Unichain Sepolia, World Chain Sepolia | \~13-19 min  |

<Tip>
  To avoid long deposit wait times, see the discussion at
  [Fast deposits](/gateway/references/supported-blockchains#fast-deposits) about
  third party services that offer fast deposits. Alternatively, use
  [Bridge Kit](https://developers.circle.com/circle-mint/docs/bridgekit-quickstart)
  to bridge your USDC to a fast-finality blockchain before depositing into Gateway
  so your `GatewayClient` can deposit and pay from that chain.

  ```ts theme={null}
  import { BridgeKit } from "@circle-fin/bridge-kit";

  const bridge = new BridgeKit();

  const transfer = await bridge.transfer({
    sourceChain: "base-sepolia",
    destinationChain: "arc-testnet",
    amount: "10",
    token: "USDC",
  });
  await bridge.waitForCompletion(transfer.id);

  const client = new GatewayClient({
    chain: "arcTestnet",
    privateKey: process.env.PRIVATE_KEY as `0x${string}`,
  });
  await client.deposit("10");
  ```
</Tip>

### Step 6. Withdraw funds (optional)

Withdraw USDC from Gateway back to your wallet at any time. Withdrawals are
instant for both same-blockchain and crosschain destinations. The `withdraw()`
method calls the
[Create Transfer Attestation](/api-reference/gateway/all/create-transfer-attestation)
API endpoint:

```ts theme={null}
await gatewayClient.withdraw("5");

await gatewayClient.withdraw("5", { chain: "baseSepolia" });
```

### Step 7. Monitor transfers (optional)

After paying for resources, you can look up individual transfers using the
[Get x402 Transfer by ID](/api-reference/gateway/all/get-x402transfer-by-id) API
endpoint, or search across transfer history using the
[Search x402 Transfers](/api-reference/gateway/all/search-x402transfers) API
endpoint:

```ts theme={null}
const { transfers, pagination } = await gatewayClient.searchTransfers({
  status: "received",
  pageSize: 20,
});

const transferUUID = transfers[0]?.id;

if (transferUUID) {
  try {
    const transfer = await gatewayClient.getTransferById(transferUUID);

    console.log({
      id: transfer.id,
      status: transfer.status,
      amount: transfer.amount,
    });
  } catch (error) {
    console.error("Could not load transfer", error);
  }
}

if (pagination?.pageAfter) {
  const nextPage = await gatewayClient.searchTransfers({
    status: "received",
    pageSize: 20,
    pageAfter: pagination.pageAfter,
  });
}
```

`searchTransfers` supports filtering by sender, recipient, network, status,
token, and date range. When `network` is omitted, the client defaults to the
client's configured blockchain. See the
[SDK reference](/gateway/nanopayments/references/sdk) for the full list of
parameters.

## See also

* [Use nanopayments with x402](/gateway/nanopayments/howtos/x402-integration)
  for a summary of all integration paths
* [x402 seller integration](/gateway/nanopayments/howtos/x402-seller) for the
  server-side counterpart
* [SDK reference](/gateway/nanopayments/references/sdk) for
  `CompositeEvmScheme`, `BatchEvmScheme`, and `registerBatchScheme` API details
