Tiny TypeScript client for the x402 HTTP payment protocol v2 — a Linux Foundation-hosted open standard (April 2026) that turns HTTP 402 Payment Required into a machine-readable payment handshake.
- Zero runtime deps. Uses native
fetchandglobalThis.crypto. - ESM + CJS dual build, TypeScript types included.
- Chain-neutral. Signing is a callback — wire it to
ethers,viem, or a remote signer.ethersis declared as an optional peer dep for the reference example, nothing more. - Node 18+ / modern browsers.
npm install cipher-x402-clientimport {
fetchPaid,
selectPaymentMethod,
buildPaymentHeader,
} from "cipher-x402-client";
import { Wallet } from "ethers";
const wallet = new Wallet(process.env.PRIVATE_KEY!);
const resp = await fetchPaid(
"https://cipher-x402.vercel.app/premium/mev-deep-dive",
{
onPayment: async (parsed) => {
const accept = selectPaymentMethod(parsed.accepts, {
preferredChain: "eip155:8453", // Base
maxAmountUsd: 0.05,
});
return await buildPaymentHeader(accept, wallet.address, async (authz, a) => {
const domain = {
name: "USDC",
version: "2",
chainId: 8453,
verifyingContract: a.asset,
};
const types = {
TransferWithAuthorization: [
{ name: "from", type: "address" },
{ name: "to", type: "address" },
{ name: "value", type: "uint256" },
{ name: "validAfter", type: "uint256" },
{ name: "validBefore", type: "uint256" },
{ name: "nonce", type: "bytes32" },
],
};
return await wallet.signTypedData(domain, types, authz);
});
},
},
);
console.log(resp.status, await resp.text());| Symbol | Purpose |
|---|---|
parse402(response) |
Parse a Response / object / JSON string into a ParsedAccept. Throws NotA402Error on malformed input. |
selectPaymentMethod(accepts, opts?) |
Pick the cheapest compatible payment method. opts: preferredChain, maxAmountUsd, allowedSchemes. |
buildPaymentHeader(accept, signerAddress, signer, opts?) |
Build the base64-encoded X-Payment header. signer is a callback. |
fetchPaid(url, { onPayment, ... }) |
fetch + automatic 402 retry with the X-Payment header set. |
Every symbol is exported from the root:
import {
parse402, selectPaymentMethod, buildPaymentHeader, fetchPaid,
type ParsedAccept, type PaymentAccept, type ERC3009Authorization, type Signer,
X402Error, NotA402Error, NoCompatibleMethodError, PaymentBuildError,
} from "cipher-x402-client";x402 is scheme-agnostic: erc3009, exact, and future schemes (Solana SPL, Lightning, etc.) each have their own payload. Baking ethers into the package would pin a chain choice and drag in ~1 MB of code for anyone who only needs the wire format. Callback pattern keeps this package tiny.
A worked ethers v6 signer lives in the README above; a viem equivalent is ~10 lines.
- Live x402 demo: https://cipher-x402.vercel.app
- Demo source: https://github.com/cryptomotifs/cipher-x402
- CIPHER starter: https://github.com/cryptomotifs/cipher-starter
- Python sibling package:
x402-python
MIT.