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

# Client

This guide shows how to pay for x402-protected resources using a [WDK](https://docs.wallet.tether.io) self-custodial wallet on Plasma or Stable. By the end you'll have a working `fetch` wrapper that automatically handles `402 Payment Required` responses with USD₮.

<Info>
  See a full working demo at [github.com/SemanticPay/x402-usdt0-demo](https://github.com/SemanticPay/x402-usdt0-demo)
</Info>

## Install

```bash theme={null}
npm install @x402/fetch @x402/evm @tetherto/wdk-wallet-evm
```

## Create a wallet

Create a `WalletAccountEvm` pointed at the chain you want to pay on. The account derives keys locally from your seed phrase.

```typescript theme={null}
import { WalletAccountEvm } from "@tetherto/wdk-wallet-evm";

const account = new WalletAccountEvm(process.env.SEED_PHRASE, {
  provider: "https://rpc.plasma.to", // or "https://rpc.stable.xyz"
});

const address = await account.getAddress();
console.log("Buyer address:", address);
```

## Register with x402

`WalletAccountEvm` already satisfies the signer interface that x402 expects.

```typescript theme={null}
import { x402Client, wrapFetchWithPayment } from "@x402/fetch";
import { registerExactEvmScheme } from "@x402/evm/exact/client";

const client = new x402Client();
registerExactEvmScheme(client, { signer: account });

const fetchWithPayment = wrapFetchWithPayment(fetch, client);
```

That's it. `fetchWithPayment` now intercepts any `402 Payment Required` response, signs an EIP-3009 `transferWithAuthorization` using your WDK wallet, and retries the request with the payment header attached.

## Make a paid request

```typescript theme={null}
const response = await fetchWithPayment("https://api.example.com/weather", {
  method: "GET",
});

const data = await response.json();
console.log("Response:", data);
```

If the endpoint requires payment, the x402 client handles the full flow automatically:

1. Initial request returns `402` with a `PAYMENT-REQUIRED` header
2. Client parses the payment requirements (amount, token, network, recipient)
3. Client signs an EIP-3009 authorization with your WDK wallet
4. Client retries the request with the `PAYMENT-SIGNATURE` header
5. The facilitator settles the payment on-chain and the server returns the resource

## Full example

```typescript theme={null}
import { WalletAccountEvm } from "@tetherto/wdk-wallet-evm";
import { x402Client, wrapFetchWithPayment, x402HTTPClient } from "@x402/fetch";
import { registerExactEvmScheme } from "@x402/evm/exact/client";

// --- Config ---
const SEED_PHRASE = process.env.SEED_PHRASE;
const RPC = process.env.RPC_URL || "https://rpc.plasma.to";
const ENDPOINT = process.env.ENDPOINT || "https://api.example.com/weather";

// --- Wallet ---
const account = new WalletAccountEvm(SEED_PHRASE, {
  provider: RPC,
});

console.log("Address:", await account.getAddress());

// --- x402 client ---
const client = new x402Client();
registerExactEvmScheme(client, { signer: account });
const fetchWithPayment = wrapFetchWithPayment(fetch, client);

// --- Request ---
const response = await fetchWithPayment(ENDPOINT, { method: "GET" });
const body = await response.json();
console.log("Response:", body);

// --- Receipt ---
if (response.ok) {
  const httpClient = new x402HTTPClient(client);
  const receipt = httpClient.getPaymentSettleResponse(
    (name) => response.headers.get(name),
  );
  console.log("Payment receipt:", JSON.stringify(receipt, null, 2));
}
```

## Environment variables

```bash theme={null}
# .env
SEED_PHRASE="your twelve word seed phrase here"
RPC_URL="https://rpc.plasma.to"         # Plasma mainnet
# RPC_URL="https://rpc.stable.xyz"      # Stable mainnet
ENDPOINT="https://api.example.com/weather"
```

<Warning>
  Your seed phrase controls your funds. Never commit it to version control. Use environment variables or a secrets manager.
</Warning>

## Checking your balance

Before making paid requests, verify your wallet has USDT0 on the target chain:

```typescript theme={null}
const USDT0_PLASMA = "0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb";
const USDT0_STABLE = "0x779Ded0c9e1022225f8E0630b35a9b54bE713736";

const balance = await account.getTokenBalance(USDT0_PLASMA);
console.log("USDT0 balance:", Number(balance) / 1e6, "USD₮");
```

USDT0 uses 6 decimals. A balance of `1000000` equals 1.00 USD₮.

## Using Axios instead of fetch

```typescript theme={null}
import { x402Client, wrapAxiosWithPayment } from "@x402/axios";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import axios from "axios";

const client = new x402Client();
registerExactEvmScheme(client, { signer: account });

const api = wrapAxiosWithPayment(
  axios.create({ baseURL: "https://api.example.com" }),
  client,
);

const response = await api.get("/weather");
console.log("Response:", response.data);
```

## What happens under the hood

x402 uses EIP-3009 (`transferWithAuthorization`) for payment settlement. When your WDK wallet signs a payment, it creates an off-chain authorization that allows the facilitator to transfer a specific amount of USDT0 from your address to the seller's address. The facilitator then submits this authorization on-chain in a single transaction.

Because Plasma and Stable both support EIP-3009 natively on their USDT0 contracts, the facilitator can settle payments without any gas cost to the buyer. The buyer only pays the exact amount specified in the payment requirements.
