x402 HTTP Client Reference
Detailed API reference for @x402-avm/fetch, @x402-avm/axios, and @x402-avm/avm client packages.
Package: @x402-avm/fetch
Installation
npm install @x402-avm/fetch @x402-avm/avm algosdk
Exports
| Export | Type | Description |
|---|---|---|
wrapFetchWithPayment |
Function | Wraps fetch with automatic 402 payment handling |
wrapFetchWithPaymentFromConfig |
Function | Config-based variant of the above |
x402Client |
Class | Core client for managing payment schemes |
x402HTTPClient |
Class | HTTP-level payment client |
decodePaymentResponseHeader |
Function | Decodes the PAYMENT-RESPONSE header |
PaymentPolicy |
Type | Policy function type for filtering requirements |
SchemeRegistration |
Type | Scheme registration configuration |
x402ClientConfig |
Type | Configuration object type |
PaymentRequired |
Type | 402 response structure |
PaymentRequirements |
Type | Individual payment requirement |
PaymentPayload |
Type | Signed payment payload |
Network |
Type | Network identifier string type |
SchemeNetworkClient |
Type | Client-side scheme interface |
wrapFetchWithPayment
Wraps a standard fetch function with automatic 402 payment handling.
function wrapFetchWithPayment(
fetch: typeof globalThis.fetch,
client: x402Client | x402HTTPClient,
): (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
Flow:
- Makes the initial HTTP request normally
- If the server responds with 402, parses payment requirements from the response
- Selects a suitable payment method based on registered schemes
- Creates a payment payload by signing a transaction group
- Retries the request with the
PAYMENT-SIGNATUREheader - If the response is anything other than 402, returns it as-is
wrapFetchWithPaymentFromConfig
Config-based variant that creates the x402Client internally.
function wrapFetchWithPaymentFromConfig(
fetch: typeof globalThis.fetch,
config: x402ClientConfig,
): (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
x402ClientConfig
interface x402ClientConfig {
schemes: Array<{
network: string; // CAIP-2 identifier or wildcard ("algorand:*")
client: SchemeNetworkClient;
}>;
policies?: PaymentPolicy[];
}
PaymentPolicy
type PaymentPolicy = (
version: number,
requirements: PaymentRequirements[],
) => PaymentRequirements[];
Policies are applied in registration order. Each policy receives the remaining requirements and returns a filtered/transformed list.
decodePaymentResponseHeader
function decodePaymentResponseHeader(header: string): any;
Decodes the PAYMENT-RESPONSE or X-PAYMENT-RESPONSE header returned by the server after settlement.
Package: @x402-avm/axios
Installation
npm install @x402-avm/axios @x402-avm/avm algosdk axios
Exports
| Export | Type | Description |
|---|---|---|
wrapAxiosWithPayment |
Function | Wraps Axios instance with 402 payment interceptor |
wrapAxiosWithPaymentFromConfig |
Function | Config-based variant of the above |
x402Client |
Class | Core client for managing payment schemes |
x402HTTPClient |
Class | HTTP-level payment client |
decodePaymentResponseHeader |
Function | Decodes the PAYMENT-RESPONSE header |
PaymentPolicy |
Type | Policy function type for filtering requirements |
SchemeRegistration |
Type | Scheme registration configuration |
x402ClientConfig |
Type | Configuration object type |
PaymentRequired |
Type | 402 response structure |
PaymentRequirements |
Type | Individual payment requirement |
PaymentPayload |
Type | Signed payment payload |
Network |
Type | Network identifier string type |
SchemeNetworkClient |
Type | Client-side scheme interface |
wrapAxiosWithPayment
Adds a response interceptor that handles 402 responses by signing and submitting payment transactions.
function wrapAxiosWithPayment(
axiosInstance: AxiosInstance,
client: x402Client | x402HTTPClient,
): AxiosInstance;
Returns the same Axios instance (mutated with the interceptor). The interceptor:
- Catches 402 responses
- Parses payment requirements (headers for V2, body for V1)
- Creates payment payload via
x402Client - Marks the request with
__is402Retry = trueto prevent infinite loops - Retries with
PAYMENT-SIGNATUREheader
wrapAxiosWithPaymentFromConfig
function wrapAxiosWithPaymentFromConfig(
axiosInstance: AxiosInstance,
config: x402ClientConfig,
): AxiosInstance;
Interceptor Behavior
Client Request --> Axios sends request --> Server Response
|
Status != 402 -------> Return response normally
Status == 402 -------> Already retried? --> Reject
|
Parse PaymentRequired
Create payment payload
Retry with PAYMENT-SIGNATURE
Return retried response
Key details:
- Single retry: Only retries once per 402
- Request mutation: Modifies original config and retries via
axiosInstance.request() - Concurrent requests: Each 402 is handled independently
- Interceptor order: Payment interceptor should be added last
Package: @x402-avm/avm
Installation
npm install @x402-avm/avm algosdk
Exports
| Export | Type | Description |
|---|---|---|
ExactAvmScheme |
Class | Algorand exact payment scheme (client) |
ClientAvmSigner |
Interface | Signer interface for client wallets |
ClientAvmConfig |
Interface | Algod client configuration |
ALGORAND_TESTNET_CAIP2 |
Constant | "algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=" |
ALGORAND_MAINNET_CAIP2 |
Constant | "algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=" |
isAvmSignerWallet |
Function | Type guard for ClientAvmSigner |
ClientAvmSigner Interface
The interface that bridges wallets (browser or server) to the x402 payment system.
interface ClientAvmSigner {
/** The Algorand address of the payer */
address: string;
/**
* Sign one or more transactions in a group.
* @param txns - Array of unsigned transaction bytes (msgpack)
* @param indexesToSign - Optional indices of transactions to sign.
* If omitted, sign all transactions.
* @returns Array where signed transactions contain the signed blob,
* and skipped transactions are null
*/
signTransactions(
txns: Uint8Array[],
indexesToSign?: number[],
): Promise<(Uint8Array | null)[]>;
}
Subpath: @x402-avm/avm/exact/client
| Export | Type | Description |
|---|---|---|
registerExactAvmScheme |
Function | Registers AVM schemes (V1 + V2) to an x402Client |
AvmClientConfig |
Interface | Configuration for AVM client registration |
registerExactAvmScheme
function registerExactAvmScheme(
client: x402Client,
config: AvmClientConfig,
): void;
AvmClientConfig
interface AvmClientConfig {
/** The client signer implementation */
signer: ClientAvmSigner;
/** Optional Algod configuration */
algodConfig?: {
/** Algod URL (defaults to AlgoNode testnet/mainnet) */
algodUrl?: string;
/** Algod API token */
algodToken?: string;
/** Pre-configured Algodv2 client */
algodClient?: algosdk.Algodv2;
};
/** Optional: restrict to specific networks */
networks?: string[];
}
x402Client Class
Constructor
const client = new x402Client(selector?: PaymentRequirementsSelector);
Optional selector overrides default selection logic for choosing among payment requirements.
Methods
| Method | Signature | Description |
|---|---|---|
registerPolicy |
(policy: PaymentPolicy) => x402Client |
Register a payment policy (chainable) |
onBeforePaymentCreation |
(hook: BeforePaymentHook) => void |
Register pre-payment hook |
onAfterPaymentCreation |
(hook: AfterPaymentHook) => void |
Register post-payment hook |
onPaymentCreationFailure |
(hook: PaymentFailureHook) => void |
Register failure hook |
Lifecycle Hooks
BeforePaymentCreation:
client.onBeforePaymentCreation(async (context) => {
// context.selectedRequirements - the chosen payment requirements
// context.paymentRequired - full 402 response
// Return { abort: true, reason: "..." } to cancel payment
});
AfterPaymentCreation:
client.onAfterPaymentCreation(async (context) => {
// context.paymentPayload - the signed payload
// context.paymentRequired - full 402 response
});
PaymentCreationFailure:
client.onPaymentCreationFailure(async (context) => {
// context.error - the error that occurred
// Return { recovered: true, payload: ... } to provide fallback
});
Environment Variables
| Variable | Description | Format |
|---|---|---|
AVM_PRIVATE_KEY |
Algorand private key | Base64-encoded 64-byte key (32-byte seed + 32-byte pubkey) |
ALGOD_TESTNET_URL |
Custom Algod testnet URL | URL string (default: https://testnet-api.algonode.cloud) |
ALGOD_MAINNET_URL |
Custom Algod mainnet URL | URL string (default: https://mainnet-api.algonode.cloud) |
Network Constants
| Constant | Value |
|---|---|
ALGORAND_TESTNET_CAIP2 |
"algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=" |
ALGORAND_MAINNET_CAIP2 |
"algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=" |
V1_ALGORAND_TESTNET |
"algorand-testnet" |
V1_ALGORAND_MAINNET |
"algorand-mainnet" |
Testing
Unit Testing a Client
import { x402Client } from "@x402-avm/fetch";
import { registerExactAvmScheme } from "@x402-avm/avm/exact/client";
// Create a mock signer for testing
const mockSigner = {
address: "TEST_ADDRESS_58_CHARS_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
signTransactions: async (txns: Uint8Array[], indexesToSign?: number[]) => {
return txns.map((_, i) => {
if (indexesToSign && !indexesToSign.includes(i)) return null;
return new Uint8Array([0x80]); // mock signed bytes
});
},
};
const client = new x402Client();
registerExactAvmScheme(client, { signer: mockSigner });
Integration Testing with Real Transactions
# Set up environment
export AVM_PRIVATE_KEY="your-base64-key-here"
# Run with tsx
npx tsx client-test.ts https://api.example.com/paid-endpoint
Important Notes
AVM_PRIVATE_KEYis a Base64-encoded 64-byte key. The first 32 bytes are the seed, the last 32 bytes are the public key.- Address derivation always uses
algosdk.encodeAddress(secretKey.slice(32))-- the public key portion. - The
algorand:*wildcard in config-based setups matches any Algorand network (testnet or mainnet). - Policies are composable and applied in order. An empty result from any policy means no payment options are available.
- The Axios interceptor modifies the instance in place and returns it. Do not create a new instance after wrapping.