Overview
The x402 client automatically handles HTTP 402 responses. When a server requires payment, the client:
- Parses the payment requirement from the
PAYMENT-REQUIRED header
- Validates the amount against your configured limits
- Signs the payment using your Starknet account
- Retries the request with the
X-PAYMENT header
React — useX402Payment Hook
The easiest way to use x402 in a React/Next.js app:
import { useX402Payment } from "@chipi-stack/nextjs"; // or chipi-react
function PremiumContent() {
const { x402Fetch, isPaying, lastTxHash, paymentCount, error } = useX402Payment({
wallet,
encryptKey: pin,
getBearerToken: getToken,
maxPaymentAmount: "1.00", // Max $1 per request
onPaymentComplete: (txHash, amount) => {
console.log(`Paid ${amount} USDC — tx: ${txHash}`);
},
});
const fetchData = async () => {
const response = await x402Fetch("https://api.example.com/premium");
const data = await response.json();
// data is available — payment was handled automatically
};
return (
<div>
<button onClick={fetchData} disabled={isPaying}>
{isPaying ? "Paying..." : "Get Premium Data"}
</button>
{lastTxHash && <p>Last payment: {lastTxHash}</p>}
<p>Total payments: {paymentCount}</p>
</div>
);
}
Hook Configuration
| Property | Type | Description |
|---|
wallet | WalletData | Wallet data from useChipiWallet |
encryptKey | string | User’s PIN/password for signing |
getBearerToken | () => Promise<string> | Auth token provider |
maxPaymentAmount | string? | Max USDC per request (e.g. "1.00") |
allowedRecipients | string[]? | Whitelist of allowed merchant addresses |
session | SessionKeyData? | Session key for automatic payments |
onPaymentComplete | (txHash, amount) => void | Callback after successful payment |
Hook Return Values
| Property | Type | Description |
|---|
x402Fetch | (url, init?) => Promise<Response> | Drop-in fetch replacement |
signPayment | (requirement) => Promise<PaymentPayload> | Manual payment signing |
isPaying | boolean | Payment in progress |
lastTxHash | string | null | Last payment transaction hash |
lastAmount | string | null | Last payment amount (USDC) |
error | Error | null | Last error |
paymentCount | number | Total payments this session |
Node.js — X402Client
For server-side or CLI applications:
import { X402Client, DirectSigner, createAccount } from "@chipi-stack/core";
import { RpcProvider } from "starknet";
// Create account from private key (server-side only)
const signer = new DirectSigner(process.env.PRIVATE_KEY!);
const provider = new RpcProvider({ nodeUrl: "https://starknet-mainnet.infura.io/..." });
const account = await createAccount({ signer, provider });
// Create x402 client with safety limits
const client = new X402Client(account, {
maxPaymentAmount: "0.50", // Max $0.50 per request
allowedRecipients: ["0xTRUSTED_MERCHANT"], // Only pay trusted servers
});
// Automatic 402 handling
const response = await client.fetch("https://api.example.com/ai-endpoint");
const data = await response.json();
Configuration Options
| Option | Type | Default | Description |
|---|
maxPaymentAmount | string? | undefined (no limit) | Max USDC per request |
allowedRecipients | string[]? | [] (allow all) | Whitelist of merchant addresses |
headerName | string? | "X-PAYMENT" | Custom payment header name |
Always set maxPaymentAmount in production. Without it, a compromised or malicious server
could request an arbitrarily large payment. Set it to the maximum amount you expect to pay per
request (e.g. "1.00" for $1 USDC).
Python
from chipi_sdk import ChipiSDK, X402Client, X402ClientConfig
sdk = ChipiSDK(config)
client = X402Client(sdk, X402ClientConfig(
max_payment_amount="0.10", # Max $0.10 per request
))
# Sync
response = client.fetch("https://api.example.com/data", bearer_token="...")
# Async
response = await client.afetch("https://api.example.com/data", bearer_token="...")
Safety Features
Amount Limits
Always set maxPaymentAmount to prevent unexpected charges:
const client = new X402Client(account, {
maxPaymentAmount: "0.10", // Never pay more than $0.10 per request
});
If a server requests more than your limit, the client throws an error instead of signing.
Recipient Whitelist
Restrict which servers can charge you:
const client = new X402Client(account, {
allowedRecipients: [
"0xTRUSTED_API_1",
"0xTRUSTED_API_2",
],
});
Asset Validation
The client only accepts payments in native USDC on Starknet mainnet. Requests for any other token are automatically rejected.
Error Handling
try {
const response = await client.fetch("https://api.example.com/data");
} catch (error) {
if (error.message.includes("exceeds maximum")) {
// Payment too expensive
} else if (error.message.includes("not in the allowed")) {
// Unknown merchant
} else if (error.message.includes("PAYMENT-REQUIRED")) {
// Server misconfigured (no payment requirement header)
}
}