@x402-avm/core and @x402-avm/avm Reference
Detailed API reference for the x402-avm TypeScript SDK packages.
Dependencies
{
"dependencies": {
"@x402-avm/core": "latest",
"@x402-avm/avm": "latest",
"algosdk": "^3.0.0"
}
}
For browser wallet integration:
{
"dependencies": {
"@txnlab/use-wallet": "^4.0.0",
"@txnlab/use-wallet-react": "^4.0.0"
}
}
Package Exports: @x402-avm/core
| Import Path |
Exports |
@x402-avm/core/client |
x402Client, PaymentPolicy |
@x402-avm/core/server |
x402ResourceServer, x402HTTPResourceServer, HTTPFacilitatorClient, ResourceConfig, RouteConfig |
@x402-avm/core/facilitator |
x402Facilitator |
@x402-avm/core/http |
HTTP utilities and header parsing |
@x402-avm/core/types |
PaymentRequirements, PaymentRequirementsV1, PaymentPayload, PaymentRequired, Network |
Package Exports: @x402-avm/avm
| Import Path |
Exports |
@x402-avm/avm |
All constants, types, and utilities |
@x402-avm/avm/exact/client |
registerExactAvmScheme (client variant) |
@x402-avm/avm/exact/server |
registerExactAvmScheme (server variant) |
@x402-avm/avm/exact/facilitator |
registerExactAvmScheme (facilitator variant) |
x402Client
The client automatically handles HTTP 402 responses by creating payment payloads and retrying.
import { x402Client } from "@x402-avm/core/client";
const client = new x402Client({
schemes: [], // Populated via registerExactAvmScheme
});
Methods
| Method |
Signature |
Description |
fetch |
(url: string, init?: RequestInit) => Promise<Response> |
Fetch with automatic 402 handling |
registerPolicy |
(policy: PaymentPolicy) => void |
Add a payment filtering policy |
Lifecycle
- Client sends request to resource URL
- Server responds with
402 Payment Required + PaymentRequired body
- Client selects a matching
PaymentRequirements (filtered by policies)
- Registered scheme creates and signs payment
- Client retries with
X-PAYMENT header containing signed payload
PaymentPolicy
type PaymentPolicy = (
version: number,
requirements: PaymentRequirements[],
) => PaymentRequirements[];
Policies receive the full list of PaymentRequirements from the 402 response and return a filtered subset. If the filtered list is empty, the client cannot pay.
x402ResourceServer
Transport-agnostic server that creates 402 responses and processes payments.
import { x402ResourceServer } from "@x402-avm/core/server";
const server = new x402ResourceServer(facilitatorClient);
Methods
| Method |
Signature |
Description |
createPaymentRequired |
(resource, configs[]) => PaymentRequired |
Create a 402 response body |
processPayment |
(xPaymentHeader, config) => Promise<ProcessResult> |
Verify and settle a payment |
x402HTTPResourceServer
Adds HTTP route matching on top of x402ResourceServer.
import { x402HTTPResourceServer } from "@x402-avm/core/server";
const httpServer = new x402HTTPResourceServer(facilitatorClient, { routes });
Methods
| Method |
Signature |
Description |
processRequest |
(context) => Promise<{ status, body }> |
Process an HTTP request with route matching |
onProtectedRequest |
(callback) => void |
Register a hook for protected requests |
resourceServer |
Property |
Access the underlying x402ResourceServer |
Route Configuration
interface RouteConfig {
path: string; // Route pattern (supports * wildcard)
config: ResourceConfig;
description?: string;
mimeType?: string;
}
interface ResourceConfig {
scheme: "exact";
payTo: string;
price: {
asset: string;
amount: string;
extra?: { name: string; decimals: number };
};
network: string;
maxTimeoutSeconds: number;
}
HTTPFacilitatorClient
Communicates with a remote facilitator service over HTTP.
import { HTTPFacilitatorClient } from "@x402-avm/core/server";
const client = new HTTPFacilitatorClient({
url: string;
headers?: Record<string, string>;
});
Methods
| Method |
Signature |
Description |
supported |
() => Promise<{ networks }> |
Get supported networks |
verify |
(payload) => Promise<VerifyResult> |
Verify a payment |
settle |
(payload) => Promise<SettleResult> |
Settle a payment on-chain |
x402Facilitator
Local facilitator that verifies and settles payments directly.
import { x402Facilitator } from "@x402-avm/core/facilitator";
const facilitator = new x402Facilitator();
Methods
| Method |
Signature |
Description |
verify |
(payload, requirements) => Promise<VerifyResult> |
Verify payment signature and amounts |
settle |
(payload, requirements) => Promise<SettleResult> |
Sign fee payer txn and submit group |
getSupportedNetworks |
() => SupportedNetworks |
Get registered networks |
registerExactAvmScheme
Three variants exist for client, server, and facilitator.
Client Registration
import { registerExactAvmScheme } from "@x402-avm/avm/exact/client";
registerExactAvmScheme(client, {
signer: ClientAvmSigner; // Required: signer implementation
algodConfig?: { // Optional: Algod configuration
algodUrl?: string;
};
networks?: string[]; // Optional: restrict to specific networks
policies?: PaymentPolicy[]; // Optional: payment policies
});
Server Registration
import { registerExactAvmScheme } from "@x402-avm/avm/exact/server";
registerExactAvmScheme(server, {
networks?: string[]; // Optional: restrict to specific networks
});
// Default: registers for all Algorand networks (algorand:*)
registerExactAvmScheme(server);
Facilitator Registration
import { registerExactAvmScheme } from "@x402-avm/avm/exact/facilitator";
registerExactAvmScheme(facilitator, {
signer: FacilitatorAvmSigner; // Required: facilitator signer
networks: string | string[]; // Required: supported network(s)
});
ClientAvmSigner Interface
interface ClientAvmSigner {
address: string;
signTransactions(
txns: Uint8Array[],
indexesToSign?: number[],
): Promise<(Uint8Array | null)[]>;
}
Compatible with @txnlab/use-wallet's signTransactions function. The indexesToSign parameter allows selective signing in atomic groups (e.g., sign only the payment transaction, leave the fee payer unsigned for the facilitator).
FacilitatorAvmSigner Interface
interface FacilitatorAvmSigner {
getAddresses(): readonly string[];
signTransaction(txn: Uint8Array, senderAddress: string): Promise<Uint8Array>;
getAlgodClient(network: Network): unknown;
simulateTransactions(txns: Uint8Array[], network: Network): Promise<unknown>;
sendTransactions(signedTxns: Uint8Array[], network: Network): Promise<string>;
waitForConfirmation(txId: string, network: Network, waitRounds?: number): Promise<unknown>;
}
Method Details
| Method |
Purpose |
getAddresses |
Returns fee payer addresses managed by this facilitator |
signTransaction |
Signs a single unsigned transaction (fee payer txn) |
getAlgodClient |
Returns an Algod client for the given network |
simulateTransactions |
Simulates an atomic group to validate before submission |
sendTransactions |
Submits signed transaction group to the network |
waitForConfirmation |
Waits for on-chain confirmation of a transaction |
Type Guard
import { isAvmSignerWallet } from "@x402-avm/avm";
// Returns true if the object has { address: string, signTransactions: Function }
isAvmSignerWallet(wallet): wallet is ClientAvmSigner;
Constants
Network Identifiers
| Constant |
Value |
ALGORAND_MAINNET_CAIP2 |
"algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=" |
ALGORAND_TESTNET_CAIP2 |
"algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=" |
CAIP2_NETWORKS |
[ALGORAND_MAINNET_CAIP2, ALGORAND_TESTNET_CAIP2] |
ALGORAND_MAINNET_GENESIS_HASH |
"wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=" |
ALGORAND_TESTNET_GENESIS_HASH |
"SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=" |
V1_ALGORAND_MAINNET |
"algorand-mainnet" |
V1_ALGORAND_TESTNET |
"algorand-testnet" |
V1_NETWORKS |
["algorand-mainnet", "algorand-testnet"] |
V1/V2 Mapping
| Constant |
Type |
Description |
V1_TO_CAIP2 |
Record<string, string> |
V1 name to CAIP-2 |
CAIP2_TO_V1 |
Record<string, string> |
CAIP-2 to V1 name |
USDC Configuration
| Constant |
Value |
USDC_MAINNET_ASA_ID |
"31566704" |
USDC_TESTNET_ASA_ID |
"10458941" |
USDC_DECIMALS |
6 |
USDC_CONFIG |
Record<network, { asaId, name, decimals }> |
Algod Endpoints
| Constant |
Value |
DEFAULT_ALGOD_MAINNET |
env ALGOD_MAINNET_URL or "https://mainnet-api.algonode.cloud" |
DEFAULT_ALGOD_TESTNET |
env ALGOD_TESTNET_URL or "https://testnet-api.algonode.cloud" |
NETWORK_TO_ALGOD |
Record<network, url> |
FALLBACK_ALGOD_MAINNET |
"https://mainnet-api.algonode.cloud" |
FALLBACK_ALGOD_TESTNET |
"https://testnet-api.algonode.cloud" |
Transaction Limits
| Constant |
Value |
Description |
MAX_ATOMIC_GROUP_SIZE |
16 |
Max transactions per atomic group |
MIN_TXN_FEE |
1000 |
Minimum transaction fee (microAlgos) |
MAX_REASONABLE_FEE |
10_000_000 |
10 ALGO sanity check |
Address Validation
| Constant |
Value |
ALGORAND_ADDRESS_REGEX |
/^[A-Z2-7]{58}$/ |
ALGORAND_ADDRESS_LENGTH |
58 |
Utility Functions
Address Validation
isValidAlgorandAddress(address: string): boolean
Full validation including format check and algosdk checksum verification.
Amount Conversion
convertToTokenAmount(amount: string, decimals: number): string
convertFromTokenAmount(amount: string, decimals: number): string
Convert between human-readable decimal amounts and atomic integer units.
Transaction Encoding/Decoding
encodeTransaction(txnBytes: Uint8Array): string // Uint8Array -> base64
decodeTransaction(base64Str: string): Uint8Array // base64 -> Uint8Array
decodeSignedTransaction(base64Str: string): SignedTransaction
decodeUnsignedTransaction(base64Str: string): Transaction
Network Utilities
getNetworkFromCaip2(caip2: string): "testnet" | "mainnet" | null
isAlgorandNetwork(network: string): boolean // Recognizes both V1 and CAIP-2
isTestnetNetwork(network: string): boolean
v1ToCaip2(v1Name: string): string
caip2ToV1(caip2: string): string
createAlgodClient(network: string, url?: string, token?: string): Algodv2
Transaction Inspection
getSenderFromTransaction(txnBytes: Uint8Array, isSigned: boolean): string
getTransactionId(txnBytes: Uint8Array): string
hasSignature(txnBytes: Uint8Array): boolean
getGenesisHashFromTransaction(txnBytes: Uint8Array): string
validateGroupId(txnBytesArray: Uint8Array[]): boolean
assignGroupId(txns: Transaction[]): Transaction[]
Type Definitions
PaymentRequirements (V2)
interface PaymentRequirements {
scheme: "exact";
network: string; // CAIP-2 identifier
maxAmountRequired: string; // Atomic units as string
resource: string; // URL of the resource
description: string;
mimeType: string;
payTo: string; // Receiver address
maxTimeoutSeconds: number;
asset: string; // ASA ID ("0" for native ALGO)
outputSchema: unknown;
extra?: {
name: string; // Token name (e.g., "USDC")
decimals: number; // Token decimals (e.g., 6)
};
}
PaymentPayload
interface PaymentPayload {
x402Version: 2;
scheme: "exact";
network: string;
payload: {
paymentGroup: string[]; // base64-encoded msgpack transaction bytes
paymentIndex: number; // Index of the payment transaction
};
}
PaymentRequired
interface PaymentRequired {
x402Version: 2;
resource: {
url: string;
description: string;
mimeType: string;
};
accepts: PaymentRequirements[];
error: string;
}
Fee Abstraction Flow
Fee abstraction uses Algorand atomic transaction groups and pooled fees:
- Client creates a 2-transaction atomic group:
- Transaction 0: USDC/ALGO transfer from client to resource owner (fee = 0)
- Transaction 1: Self-payment by fee payer address (fee covers both transactions)
- Client signs only Transaction 0 (their payment)
- Client sends both transactions in
paymentGroup array
- Facilitator validates the fee payer transaction:
- Must be a self-payment (from == to)
- Amount must be 0
- No rekey, close-to, or other dangerous operations
- Fee must be within
MAX_REASONABLE_FEE
- Facilitator signs Transaction 1 and submits the atomic group
- Atomic execution ensures all-or-nothing on-chain
Security Guarantees
- Fee payer transaction validated for safety (no value extraction)
- Atomic group ensures both transactions succeed or both fail
- Maximum fee cap prevents excessive fee draining
- Group ID consistency validated before submission
Environment Variables
| Variable |
Description |
Default |
AVM_PRIVATE_KEY |
Base64-encoded 64-byte key |
Required for signing |
ALGOD_MAINNET_URL |
Custom mainnet Algod URL |
https://mainnet-api.algonode.cloud |
ALGOD_TESTNET_URL |
Custom testnet Algod URL |
https://testnet-api.algonode.cloud |
FACILITATOR_URL |
Facilitator service URL |
Varies |
FACILITATOR_API_KEY |
Facilitator auth token |
Optional |
Private Key Format
The AVM_PRIVATE_KEY is a Base64-encoded 64-byte key:
- Bytes 0-31: Ed25519 seed (private key)
- Bytes 32-63: Ed25519 public key
- Address derivation:
algosdk.encodeAddress(secretKey.slice(32))
Testing
Use Algorand TestNet for development:
- Get testnet ALGO from the Algorand Dispenser
- Opt in to USDC TestNet ASA (ID: 10458941)
- Get testnet USDC from TestNet USDC Dispenser
- Use
ALGORAND_TESTNET_CAIP2 as the network identifier
Import Summary
| Component |
TypeScript Import |
| Client |
x402Client from @x402-avm/core/client |
| Resource Server |
x402ResourceServer from @x402-avm/core/server |
| HTTP Resource Server |
x402HTTPResourceServer from @x402-avm/core/server |
| Facilitator |
x402Facilitator from @x402-avm/core/facilitator |
| Facilitator Client |
HTTPFacilitatorClient from @x402-avm/core/server |
| AVM Registration (Client) |
registerExactAvmScheme from @x402-avm/avm/exact/client |
| AVM Registration (Server) |
registerExactAvmScheme from @x402-avm/avm/exact/server |
| AVM Registration (Facilitator) |
registerExactAvmScheme from @x402-avm/avm/exact/facilitator |
| Types |
@x402-avm/core/types |
| Constants |
@x402-avm/avm |
| Signer Interfaces |
ClientAvmSigner, FacilitatorAvmSigner from @x402-avm/avm |
| Type Guard |
isAvmSignerWallet from @x402-avm/avm |
External Links