@x402-checkpoint/sdk
v2.0.0
Published
TypeScript SDK for CheckPoint x402 payment facilitator - Multi-chain: Base + Solana
Maintainers
Readme
@x402-checkpoint/sdk
TypeScript SDK for the CheckPoint x402 payment facilitator.
Multi-chain support: Base (EVM) + Solana
Installation
npm install @x402-checkpoint/sdk
# or
pnpm add @x402-checkpoint/sdk
# or
yarn add @x402-checkpoint/sdkSupported Networks
| Chain | Network ID | USDC Address |
|-------|------------|--------------|
| Base Mainnet | eip155:8453 | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 |
| Base Sepolia | eip155:84532 | 0x036CbD53842c5426634e7929541eC2318f3dCF7e |
| Solana Mainnet | solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v |
| Solana Devnet | solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1 | 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU |
Quick Start
import { CheckPointClient } from '@x402-checkpoint/sdk';
const checkpoint = new CheckPointClient();
// Check platform health
const health = await checkpoint.health();
console.log('Status:', health.status);Payment Flow
1. Verify Payment
Verify a payment signature before serving content:
const result = await checkpoint.verify({
paymentPayload: {
x402Version: 2,
resource: {
url: 'https://api.yourservice.com/premium/data',
description: 'Premium API access',
mimeType: 'application/json'
},
accepted: {
scheme: 'exact',
network: 'eip155:8453',
amount: '10000', // 0.01 USDC (6 decimals)
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC on Base
payTo: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', // Your merchant wallet
maxTimeoutSeconds: 3600
},
payload: {
signature: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1b',
authorization: {
from: '0x742d35Cc6634C0532925a3b844Bc9e7595f2bD00', // Payer wallet
to: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', // Merchant wallet (same as payTo)
value: '10000',
validAfter: '0',
validBefore: '1999999999',
nonce: '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
}
}
},
paymentRequirements: {
scheme: 'exact',
network: 'eip155:8453',
amount: '10000',
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
payTo: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
maxTimeoutSeconds: 3600
}
});
if (result.valid) {
console.log('Payment valid from:', result.payer);
}2. Settle Payment
Execute the USDC transfer on-chain:
const settlement = await checkpoint.settle({
paymentPayload: { /* same as verify */ },
paymentRequirements: { /* same as verify */ }
});
if (settlement.success) {
console.log('TX Hash:', settlement.txHash);
console.log('Block:', settlement.blockNumber);
}3. Verify and Settle (Convenience)
const result = await checkpoint.verifyAndSettle({
paymentPayload: { ... },
paymentRequirements: { ... }
});Solana Payment Flow
Solana payments use Ed25519 signatures and the SPL Token delegate pattern.
1. Setup Delegate Approval (One-time)
Users must approve CheckPoint as a delegate for their USDC tokens:
import { fetchDelegateSetup, SOLANA_NETWORKS } from '@x402-checkpoint/sdk';
// Fetch the approve instruction
const setup = await fetchDelegateSetup({
facilitatorUrl: 'https://checkpoint-pied.vercel.app',
payer: wallet.publicKey.toBase58(),
network: SOLANA_NETWORKS.DEVNET,
amount: '1000000000', // 1000 USDC
});
// User signs and submits the approve transaction using their wallet2. Create and Sign Payment
import {
createSolanaAuthorization,
signSolanaPayment,
createSolanaPaymentPayload,
SOLANA_NETWORKS,
} from '@x402-checkpoint/sdk';
// Create authorization
const authorization = createSolanaAuthorization({
from: wallet.publicKey.toBase58(),
to: merchantWallet,
amount: '1000000', // 1 USDC (6 decimals)
timeoutSeconds: 3600,
});
// Sign with wallet adapter
const signature = await signSolanaPayment(
authorization,
async (msg) => await wallet.signMessage!(msg)
);
// Create payload
const payload = createSolanaPaymentPayload({
authorization,
signature,
network: SOLANA_NETWORKS.DEVNET,
});3. Verify and Settle
const checkpoint = new CheckPointClient();
// Verify the payment signature
const verification = await checkpoint.verify({
paymentPayload: payload,
paymentRequirements: {
scheme: 'exact',
network: SOLANA_NETWORKS.DEVNET,
amount: '1000000',
asset: SOLANA_DEVNET_USDC,
payTo: merchantWallet,
maxTimeoutSeconds: 3600,
},
});
if (verification.valid) {
// Settle the payment
const settlement = await checkpoint.settle({
paymentPayload: payload,
paymentRequirements: { ... },
});
console.log('TX Hash:', settlement.txHash);
}Network Detection
import { isSolanaNetwork, isEVMNetwork } from '@x402-checkpoint/sdk';
function handlePayment(networkId: string) {
if (isSolanaNetwork(networkId)) {
// Use Solana signing flow
} else if (isEVMNetwork(networkId)) {
// Use EIP-712 signing flow
}
}Batch Settlements
Settle multiple payments in one call (60-80% gas savings):
const batch = await checkpoint.batchSettle({
payments: [
{ paymentPayload: payload1, paymentRequirements: req1 },
{ paymentPayload: payload2, paymentRequirements: req2 }
]
});
console.log(`Settled ${batch.summary.succeeded} of ${batch.summary.total}`);
console.log('Total gas:', batch.summary.gasTotal);Cancellable Requests
Cancel in-flight requests when needed:
const { promise, cancel, isCancelled } = checkpoint.verifyCancellable(request);
// Cancel after timeout
const timeout = setTimeout(() => {
console.log('Request taking too long, cancelling...');
cancel();
}, 5000);
try {
const result = await promise;
clearTimeout(timeout);
console.log('Verified:', result.valid);
} catch (error) {
if (error.code === 'CANCELLED') {
console.log('Request was cancelled');
}
}Also available: settleCancellable()
Rate Limit Awareness
Get rate limit information with responses:
const { data, rateLimit } = await checkpoint.verifyWithRateLimit(request);
console.log('Valid:', data.valid);
console.log('Requests remaining:', rateLimit.remaining);
console.log('Limit resets at:', new Date(rateLimit.reset * 1000));
if (rateLimit.remaining < 10) {
console.log('Warning: approaching rate limit');
}Also available: settleWithRateLimit()
Webhook Management
Manage webhook subscriptions (requires API key):
const checkpoint = new CheckPointClient({ apiKey: 'your-api-key' });
// List webhooks
const { webhooks } = await checkpoint.webhooks.list();
// Register a webhook
const { id, secret } = await checkpoint.webhooks.register({
url: 'https://yourserver.com/webhook',
events: ['payment.settled', 'payment.failed']
});
console.log('Webhook secret:', secret); // Store this securely
// Rotate secret (if compromised)
const { secret: newSecret } = await checkpoint.webhooks.rotateSecret(id);
// Delete webhook
await checkpoint.webhooks.delete(id);Webhook Events
payment.verified— Payment signature validatedpayment.settled— USDC transfer completed on-chainpayment.failed— Settlement failedpayment.expired— Authorization expired before settlement
Error Handling
Error Codes
The SDK provides typed error codes for precise error handling:
import { CheckPointClient, CheckPointError } from '@x402-checkpoint/sdk';
try {
const result = await checkpoint.verify({ ... });
} catch (error) {
if (error instanceof CheckPointError) {
switch (error.code) {
// Verification Errors
case 'INVALID_SIGNATURE':
console.log('EIP-712 signature verification failed');
break;
case 'AUTHORIZATION_EXPIRED':
console.log('validBefore timestamp has passed - re-sign');
break;
case 'AUTHORIZATION_NOT_YET_VALID':
console.log('validAfter timestamp not yet reached');
break;
case 'INSUFFICIENT_BALANCE':
console.log('Payer needs more USDC');
break;
case 'AMOUNT_MISMATCH':
console.log('Amount doesnt match requirements');
break;
case 'NONCE_ALREADY_USED':
console.log('Replay detected - generate new nonce');
break;
// Settlement Errors
case 'VERIFICATION_REQUIRED':
console.log('Must verify before settling');
break;
case 'NONCE_ALREADY_SETTLED':
console.log('Payment already processed');
break;
case 'INSUFFICIENT_GAS':
console.log('Facilitator needs ETH for gas');
break;
case 'TRANSACTION_REVERTED':
console.log('On-chain transaction reverted');
break;
}
}
}Automatic Retry
The SDK automatically retries on network errors and 5xx responses:
const checkpoint = new CheckPointClient({
retry: {
maxRetries: 3, // Default: 3
baseDelay: 1000, // Default: 1000ms
maxDelay: 10000 // Default: 10000ms (exponential backoff capped)
}
});Error Properties
catch (error) {
if (error instanceof CheckPointError) {
console.log('HTTP Status:', error.status); // 0 for network errors
console.log('Error Code:', error.code); // Typed error code
console.log('Message:', error.message); // Human-readable message
if (error.isRetryable) {
console.log('Can retry this error');
}
if (error.isClientError) {
console.log('Client-side error (4xx)');
}
}
}Payment Status
Check the status of a payment by nonce:
const status = await checkpoint.status({
nonce: '0x...',
network: 'eip155:8453',
payer: '0x...'
});
switch (status.status) {
case 'pending': console.log('Not yet verified'); break;
case 'verified': console.log('Ready to settle'); break;
case 'settling': console.log('Settlement in progress'); break;
case 'settled': console.log('TX:', status.txHash); break;
case 'failed': console.log('Error:', status.error); break;
}Receipts
Get a signed receipt for a settled payment:
const receipt = await checkpoint.receipt('0x...txHash');
console.log('Payer:', receipt.receipt.payer);
console.log('Amount:', receipt.receipt.amount);
console.log('Block:', receipt.receipt.blockNumber);Service Discovery
// List all x402-enabled services
const { services, count } = await checkpoint.discovery.list();
// Register a service (requires API key)
const checkpoint = new CheckPointClient({
apiKey: 'your-api-key'
});
const service = await checkpoint.discovery.register({
name: 'My AI Service',
description: 'GPT-powered analysis',
url: 'https://api.myservice.com',
paymentEndpoint: '/v1/analyze',
networks: ['eip155:8453'],
assets: [{
network: 'eip155:8453',
address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
symbol: 'USDC'
}],
pricing: {
model: 'per_request',
amount: '10000',
currency: 'USDC'
},
categories: ['AI'],
owner: '0xYourWallet'
});TypeScript Types
All types are exported:
import type {
// Core payment types
PaymentPayload,
PaymentRequirements,
EIP3009Authorization,
// Request/Response types
VerifyRequest,
VerifyResponse,
SettleRequest,
SettleResponse,
BatchSettleRequest,
BatchSettleResponse,
// Error codes
VerificationErrorCode,
SettlementErrorCode,
// Status types
PaymentStatus,
StatusRequest,
StatusResponse,
ReceiptResponse,
// Health & Discovery
HealthResponse,
Service,
// Rate limiting
RateLimitInfo,
// Webhooks
WebhookEventType,
WebhookConfig,
Webhook,
WebhookListResponse,
// Cancellable requests
CancellableRequest,
ResponseWithRateLimit,
// Helpers
SupportedNetwork
} from '@x402-checkpoint/sdk';Constants
import { USDC_ADDRESSES, DEFAULT_CHECKPOINT_URL } from '@x402-checkpoint/sdk';
console.log(USDC_ADDRESSES['eip155:8453']); // Base Mainnet USDC
console.log(USDC_ADDRESSES['eip155:84532']); // Base Sepolia USDC
console.log(DEFAULT_CHECKPOINT_URL); // https://checkpoint-pied.vercel.appConfiguration
const checkpoint = new CheckPointClient({
baseUrl: 'https://checkpoint-pied.vercel.app', // Default
apiKey: 'your-api-key', // For authenticated endpoints
timeout: 30000, // Request timeout (ms)
retry: {
maxRetries: 3,
baseDelay: 1000,
maxDelay: 10000
}
});Links
License
MIT
