Client Usage
The @shade402/client package provides HTTP clients for making X402 payment requests. It offers two client types: explicit (manual control) and automatic (automatic payment handling).
Installation
pnpm add @shade402/client @shade402/core @solana/web3.jsClient Types
Explicit Client
The X402Client provides manual control over the payment flow. You explicitly check for 402 responses, create payments, and retry requests.
Automatic Client
The X402AutoClient automatically handles the payment flow. When it receives a 402 response, it automatically creates a payment and retries the request.
Explicit Client
Basic Usage
import { X402Client } from '@shade402/client';
import { Keypair } from '@solana/web3.js';
const wallet = Keypair.generate();
const client = new X402Client(wallet, process.env.SOLANA_RPC_URL);
try {
// Make initial request
let response = await client.get('https://api.example.com/data');
// Check if payment required
if (client.paymentRequired(response)) {
// Parse payment request
const paymentRequest = client.parsePaymentRequest(response);
// Create payment
const authorization = await client.createPayment(paymentRequest);
// Retry with payment
response = await client.get('https://api.example.com/data', {
payment: authorization,
});
}
// Process response
console.log(response.data);
} finally {
// Always close the client
await client.close();
}HTTP Methods
The explicit client supports all HTTP methods:
// GET request
const getResponse = await client.get(url, options);
// POST request
const postResponse = await client.post(url, data, options);
// PUT request
const putResponse = await client.put(url, data, options);
// DELETE request
const deleteResponse = await client.delete(url, options);
// Generic request
const response = await client.request('GET', url, options);Options
Request options include standard Axios options plus:
interface RequestOptions {
payment?: PaymentAuthorization; // Payment authorization for retry
encryptedResource?: string; // Encrypted resource field
// ... standard Axios options
}Local Development
For local development with localhost URLs, enable allowLocal:
const client = new X402Client(
wallet,
process.env.SOLANA_RPC_URL,
undefined,
true // allowLocal - only for development!
);Automatic Client
Basic Usage
import { X402AutoClient } from '@shade402/client';
import { Keypair } from '@solana/web3.js';
const wallet = Keypair.generate();
const client = new X402AutoClient(wallet, process.env.SOLANA_RPC_URL, {
maxPaymentAmount: '1.0', // Safety limit
autoRetry: true,
});
try {
// Payment is handled automatically
const response = await client.get('https://api.example.com/data');
console.log(response.data);
} finally {
await client.close();
}Configuration Options
interface X402AutoClientOptions {
maxRetries?: number; // Maximum retry attempts (default: 1)
autoRetry?: boolean; // Auto-retry after payment (default: true)
maxPaymentAmount?: string; // Maximum payment amount (safety limit)
allowLocal?: boolean; // Allow localhost URLs (development only)
}HTTP Methods
// GET request
const getResponse = await client.get(url, options);
// POST request
const postResponse = await client.post(url, data, options);
// PUT request
const putResponse = await client.put(url, data, options);
// DELETE request
const deleteResponse = await client.delete(url, options);
// Generic fetch
const response = await client.fetch(url, {
method: 'GET',
// ... options
});Error Handling
The automatic client throws errors for payment issues:
import { PaymentRequiredError, InsufficientFundsError } from '@shade402/core';
try {
const response = await client.get(url);
} catch (error) {
if (error instanceof PaymentRequiredError) {
// Payment required but autoRetry is false
console.log('Payment required:', error.paymentRequest);
} else if (error instanceof InsufficientFundsError) {
console.log('Insufficient funds');
} else {
console.error('Other error:', error);
}
}Resource Encryption
Both clients support resource encryption:
// Explicit client
const client = new X402Client(wallet);
// Get 402 response (includes server public key)
let response = await client.get(url);
const paymentRequest = client.parsePaymentRequest(response);
// Encrypt resource
const encryptedResource = client.encryptResource(paymentRequest.resource);
// Retry with encrypted resource
response = await client.get(url, {
payment: authorization,
encryptedResource: encryptedResource,
});
// Automatic client handles encryption automatically
const autoClient = new X402AutoClient(wallet);
const response = await autoClient.get(url); // Encryption handled automaticallyPayment Amount Control
You can specify a custom payment amount:
// Explicit client
const paymentRequest = client.parsePaymentRequest(response);
const authorization = await client.createPayment(
paymentRequest,
'0.05' // Custom amount (must be <= max_amount_required)
);
// Automatic client uses maxPaymentAmount as safety limit
const client = new X402AutoClient(wallet, rpcUrl, {
maxPaymentAmount: '1.0', // Won't pay more than 1.0 tokens
});URL Validation
The client validates URLs to prevent SSRF attacks:
Only allows
http://andhttps://schemesBlocks localhost and private IPs (unless
allowLocalis enabled)Validates URL format
For local development, enable allowLocal:
const client = new X402Client(wallet, rpcUrl, undefined, true);Cleanup
Always close the client when done to cleanup connections:
try {
// Use client
} finally {
await client.close();
}Complete Example
import { X402AutoClient } from '@shade402/client';
import { Keypair } from '@solana/web3.js';
async function fetchPremiumData() {
// Load wallet from secure storage
const wallet = Keypair.fromSecretKey(
Buffer.from(process.env.WALLET_SECRET_KEY!, 'base64')
);
// Create client
const client = new X402AutoClient(wallet, process.env.SOLANA_RPC_URL, {
maxPaymentAmount: '1.0',
autoRetry: true,
});
try {
// Make request - payment handled automatically
const response = await client.post(
'https://api.example.com/premium-analysis',
{ text: 'Analyze this text' },
{
headers: {
'Content-Type': 'application/json',
},
}
);
return response.data;
} catch (error) {
console.error('Error fetching data:', error);
throw error;
} finally {
await client.close();
}
}Best Practices
Always close the client when done
Use maximum payment amounts as safety limits
Store wallet keys securely (never in code)
Use
allowLocalonly for local developmentHandle errors appropriately
Monitor payment amounts and transactions
Use the automatic client for simpler workflows
Use the explicit client for fine-grained control
Next Steps
Learn about Explicit Client in detail
Explore Automatic Client features
Check out Security best practices
Last updated
