Skip to main content

Overview

The x402 client automatically handles HTTP 402 responses. When a server requires payment, the client:
  1. Parses the payment requirement from the PAYMENT-REQUIRED header
  2. Validates the amount against your configured limits
  3. Signs the payment using your Starknet account
  4. 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

PropertyTypeDescription
walletWalletDataWallet data from useChipiWallet
encryptKeystringUser’s PIN/password for signing
getBearerToken() => Promise<string>Auth token provider
maxPaymentAmountstring?Max USDC per request (e.g. "1.00")
allowedRecipientsstring[]?Whitelist of allowed merchant addresses
sessionSessionKeyData?Session key for automatic payments
onPaymentComplete(txHash, amount) => voidCallback after successful payment

Hook Return Values

PropertyTypeDescription
x402Fetch(url, init?) => Promise<Response>Drop-in fetch replacement
signPayment(requirement) => Promise<PaymentPayload>Manual payment signing
isPayingbooleanPayment in progress
lastTxHashstring | nullLast payment transaction hash
lastAmountstring | nullLast payment amount (USDC)
errorError | nullLast error
paymentCountnumberTotal 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

OptionTypeDefaultDescription
maxPaymentAmountstring?undefined (no limit)Max USDC per request
allowedRecipientsstring[]?[] (allow all)Whitelist of merchant addresses
headerNamestring?"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)
  }
}