Package Exports
- aptos-x402
- aptos-x402/arc8004
- aptos-x402/server
- aptos-x402/types
Readme
Aptos x402
Overview
Aptos x402 is a TypeScript SDK implementing the x402 v2 protocol (spec) for the Aptos blockchain. Enable your APIs to require cryptocurrency payments before serving responses using the standardized HTTP 402 status code.
✅ x402 v2 compliant
Built for machine-to-machine micropayments, this SDK provides zero-friction payment integration for Next.js applications with automatic payment handling, cryptographic verification, and sub-second settlement times (optimized from 2-3s to 200-500ms).
What’s new in 2.2.0
- 🛡️ ARC-8004 Agent Trust Layer: Agent identity, reputation, and task validation (Aptos-native).
- ⛽ Geomi Gas Sponsorship: Native support for gasless transactions (facilitator pays gas).
- 📋 Protocol Updates: Standardized
PAYMENT-SIGNATUREheaders (removed "X-"). - 💰 Fungible Assets: Direct USDC/FA transfer support.
- 🚚 Header-Based Spec: Payment specs and proofs handling moved entirely to headers.
- ⚡ Performance: Significant speed improvements with bug fixes and optimizations.
⚡ Performance: Latest optimizations deliver faster settlement with verification caching, async confirmation, and smart deduplication.
Use Cases
| Use Case | Description |
|---|---|
| Pay-per-API-Call | Monetize APIs without subscriptions or rate limits |
| AI Agent Payments | Enable autonomous agents to pay for resources |
| Metered Services | Charge exactly for what's consumed in real-time |
| Micropayments | Enable sub-cent transactions economically |
| Decentralized Access | Replace API keys with cryptographic payments |
Quick Start
Installation
npm install aptos-x402Requirements
- Next.js: 15.0.0 or higher
- Node.js: 20.0.0 or higher
- TypeScript: 5.x (recommended)
- Aptos SDK: 1.26.0 or higher (included as peer dependency)
🛒 Client Integration (Consuming Paid APIs)
Access x402-protected APIs with zero configuration. The x402axios client automatically detects payment requirements, builds transactions, and handles the entire payment flow.
Basic Usage
import { x402axios } from 'aptos-x402';
const response = await x402axios.get('https://api.example.com/premium/data', {
privateKey: process.env.APTOS_PRIVATE_KEY
});
// Access response data
console.log(response.data);
// Verify payment details
console.log('Transaction:', response.paymentInfo?.transactionHash);
console.log('Amount:', response.paymentInfo?.amount);Supported HTTP Methods
// GET with parameters
await x402axios.get('/data', {
privateKey: process.env.APTOS_PRIVATE_KEY,
params: { filter: 'active' }
});
// POST with body
await x402axios.post('/analyze',
{ text: 'Content to analyze' },
{ privateKey: process.env.APTOS_PRIVATE_KEY }
);
// PUT, PATCH, DELETE
await x402axios.put('/resource/123', data, { privateKey: '0x...' });
await x402axios.patch('/resource/123', updates, { privateKey: '0x...' });
await x402axios.delete('/resource/123', { privateKey: '0x...' });How It Works
The client automatically handles the complete payment flow:
- Initial Request - Sends HTTP request to protected endpoint
- 402 Detection - Identifies payment requirement from response
- Transaction Building - Constructs Aptos transfer transaction
- Client Signing - Signs transaction locally (keys never leave client)
- Payment Retry - Resubmits request with X-PAYMENT header
- Settlement - Server verifies and submits to blockchain
- Response - Receives data after confirmed payment
🏪 Server Integration (Monetizing Your APIs)
Protect Next.js API routes with x402 middleware - zero payment code required in your route handlers.
Step 1: Configure Environment
Create .env.local in your project root:
PAYMENT_RECIPIENT_ADDRESS=0xYOUR_APTOS_WALLET_ADDRESS
FACILITATOR_URL=https://aptos-x402.org/api/facilitatorGetting a Wallet Address:
Install Petra Wallet or generate programmatically with@aptos-labs/ts-sdk
Step 2: Create Middleware
Create middleware.ts in your project root (same level as app/ directory):
import { paymentMiddleware } from 'aptos-x402';
export const middleware = paymentMiddleware(
process.env.PAYMENT_RECIPIENT_ADDRESS!,
{
'/api/premium/weather': {
price: '1000000', // 0.01 APT (1 APT = 100,000,000 Octas)
network: 'testnet',
config: {
description: 'Premium weather data access',
mimeType: 'application/json'
}
},
'/api/premium/stocks': {
price: '5000000', // 0.05 APT
network: 'testnet',
config: { description: 'Real-time stock data' }
}
},
{
// Use the official public facilitator for free
url: "https://aptos-x402.org/api/facilitator"
}
);
export const config = {
matcher: ['/api/premium/:path*']
};Step 3: Create Protected Routes
Your API routes require zero payment logic - the middleware handles everything:
// app/api/premium/weather/route.ts
import { NextResponse } from 'next/server';
export const dynamic = 'force-dynamic';
export async function GET(request: Request) {
// Execution only reaches here AFTER successful payment settlement
return NextResponse.json({
location: 'San Francisco',
temperature: 72,
condition: 'Sunny',
forecast: '7-day detailed forecast data...'
});
}Middleware Behavior
| Scenario | Response |
|---|---|
| No payment header | 402 Payment Required with payment instructions |
| Invalid payment | 403 Forbidden with error details |
| Valid payment | Verifies → Settles → Executes route → 200 OK |
Price Configuration
Aptos uses Octas as the smallest unit (like satoshis or wei):
1 APT = 100,000,000 Octas
Common prices:
0.001 APT = 100,000 Octas
0.01 APT = 1,000,000 Octas
0.1 APT = 10,000,000 Octas
1 APT = 100,000,000 OctasTesting Your Integration
Start your development server and verify payment protection:
npm run dev
# Test without payment (should return 402)
curl http://localhost:3000/api/premium/weatherExpected 402 response:
{
"x402Version": 1,
"accepts": [{
"scheme": "exact",
"network": "aptos-testnet",
"maxAmountRequired": "1000000",
"payTo": "0xYOUR_WALLET_ADDRESS",
"description": "Premium weather data access",
"resource": "http://localhost:3000/api/premium/weather"
}]
}Test with payment using the client:
import { x402axios } from 'aptos-x402';
const response = await x402axios.get('http://localhost:3000/api/premium/weather', {
privateKey: process.env.APTOS_PRIVATE_KEY
});Architecture
Protocol Flow
┌──────────┐ ┌──────────┐ ┌────────────┐ ┌───────────┐
│ Client │ │ API │ │ Facilitator│ │ Aptos │
│ (Buyer) │ │ (Seller) │ │ Service │ │Blockchain │
└────┬─────┘ └────┬─────┘ └─────┬──────┘ └─────┬─────┘
│ │ │ │
│ GET /api/premium/data │ │ │
│───────────────────────────>│ │ │
│ │ │ │
│ 402 Payment Required │ │ │
│<───────────────────────────│ │ │
│ {scheme, amount, payTo} │ │ │
│ │ │ │
│ [Build & Sign Transaction] │ │ │
│ (Client-side, offline) │ │ │
│ │ │ │
│ GET /api/premium/data │ │ │
│ X-PAYMENT: <signed_tx> │ │ │
│───────────────────────────>│ │ │
│ │ │ │
│ │ POST /verify │ │
│ │─────────────────────────>│ │
│ │ {isValid: true} │ │
│ │<─────────────────────────│ │
│ │ │ │
│ │ POST /settle │ │
│ │─────────────────────────>│ │
│ │ │ Submit Transaction │
│ │ │────────────────────>│
│ │ │ Confirmed (1-3s) │
│ │ │<────────────────────│
│ │ {success, txHash} │ │
│ │<─────────────────────────│ │
│ │ │ │
│ 200 OK + Data │ │ │
│<───────────────────────────│ │ │
│ X-PAYMENT-RESPONSE: {...} │ │ │
│ │ │ │Components
| Component | Responsibility | Location |
|---|---|---|
| Client | Request resources, sign transactions | Your application/agent |
| Middleware | Intercept requests, enforce payment | Your Next.js server |
| Facilitator | Verify & settle payments | Shared service or self-hosted |
| Aptos Blockchain | Final settlement & verification | Decentralized network |
Key Design Principles
- Client-Side Signing - Private keys never leave the client
- Stateless Protocol - No sessions, cookies, or stored state
- Atomic Operations - Payment settles or request fails (no partial states)
- Transparent - All transactions verifiable on-chain
- HTTP Native - Uses standard status codes and headers
API Reference
Server-Side API
paymentMiddleware()
Creates Next.js middleware for x402 payment enforcement.
Signature:
function paymentMiddleware(
recipientAddress: string,
routes: Record<string, RouteConfig>,
facilitatorConfig: FacilitatorConfig
): NextMiddlewareParameters:
| Parameter | Type | Description |
|---|---|---|
recipientAddress |
string |
Aptos wallet address to receive payments |
routes |
Record<string, RouteConfig> |
Map of route paths to payment configs |
facilitatorConfig |
FacilitatorConfig |
Facilitator service configuration |
RouteConfig:
interface RouteConfig {
price: string; // Amount in Octas
network?: 'testnet' | 'mainnet'; // Default: 'testnet'
config?: {
description?: string; // Human-readable description
mimeType?: string; // Response content type
outputSchema?: object; // Optional JSON schema
maxTimeoutSeconds?: number; // Request timeout
};
}FacilitatorConfig:
interface FacilitatorConfig {
url: string; // Base URL (e.g., 'https://example.com/api/facilitator')
}Client-Side API
x402axios
Axios-compatible HTTP client with automatic x402 payment handling.
Methods:
x402axios.get(url, config?)
x402axios.post(url, data?, config?)
x402axios.put(url, data?, config?)
x402axios.patch(url, data?, config?)
x402axios.delete(url, config?)
x402axios.request(config)
x402axios.create(defaultConfig)Configuration:
interface X402AxiosConfig extends AxiosRequestConfig {
privateKey?: string; // Aptos private key (hex string)
account?: Account; // Or Aptos Account object
}Response:
interface X402Response<T = any> extends AxiosResponse<T> {
paymentInfo?: {
transactionHash: string;
amount: string;
recipient: string;
network: string;
settled: boolean;
};
}TypeScript Types
Import types for full type safety:
import type {
RouteConfig,
FacilitatorConfig,
PaymentRequiredResponse,
PaymentRequirements,
PaymentPayload
} from 'aptos-x402/types';🛡️ ARC-8004: Agent Trust Layer
ARC-8004 provides identity, reputation, and validation for AI agents on Aptos. It integrates with x402 payments to build trust signals from paid interactions.
Features
| Feature | Description |
|---|---|
| Identity Registry | Agent Cards with metadata, capabilities, and verification status |
| Reputation Registry | Trust scores based on feedback from interactions |
| Validation Registry | Task completion verification before payments |
| Flexible Storage | Memory (default), PostgreSQL, or custom backends |
| Optional On-Chain | Enable NFT minting and attestations when needed |
Quick Start (v2.0 - Recommended)
import { createARC8004Client } from 'aptos-x402/arc8004';
// Create client - works with zero config (memory storage)
const client = await createARC8004Client();
// Register an agent identity
const { identity } = await client.identity.register({
agentId: 'my-agent',
agentCard: {
name: 'WeatherBot',
description: 'Provides weather data',
version: '1.0.0',
capabilities: ['payment', 'data-fetch'],
protocols: ['x402'],
supportedNetworks: ['aptos-testnet'],
owner: { address: '0x...', publicKey: '0x...' },
},
});
// Submit feedback after payment
await client.reputation.submitFeedback({
agentId: 'my-agent',
clientAddress: '0xclient',
overallScore: 5,
paymentHash: '0xPAYMENT_TX',
feedback: { comment: 'Fast response!' },
});
// Get reputation
const rep = await client.reputation.getReputation('my-agent');
console.log('Trust Level:', rep?.trustLevel); // "excellent"Storage Options
// Memory (default) - No database required
const client = await createARC8004Client({
config: { storageType: 'memory', skipAgentValidation: true },
});
// Database - PostgreSQL with Drizzle ORM
const client = await createARC8004Client({
config: { storageType: 'database' },
});
// Custom - Bring your own storage
const client = await createARC8004Client({
config: { storageType: 'custom' },
storage: { identity: myStorage, reputation: myRepStorage, validation: myValStorage },
});On-Chain Integration (Optional)
import { createARC8004Client, AptosOnChainProvider } from 'aptos-x402/arc8004';
const client = await createARC8004Client({
config: {
storageType: 'memory',
moduleAddress: '0xYOUR_CONTRACT',
network: 'aptos-testnet',
},
onChain: new AptosOnChainProvider('aptos-testnet', '0xYOUR_CONTRACT'),
});Configuration
# .env.local
ARC8004_AUTO_REGISTER=true # Auto-register agents on creation
ARC8004_ONCHAIN_ENABLED=false # DB-only mode (recommended)For on-chain NFT minting (optional):
ARC8004_MODULE_ADDRESS=0xa6cfe253f864c0eca623058c7ec2e80c645c5b0a5745c853e7082ee4daad077f
ARC8004_ONCHAIN_ENABLED=trueDocumentation
- ARC-8004 Integration Guide - Full SDK usage (NEW)
- ARC-8004 Core Concepts - Architecture overview
- ARC-8004 Use Cases - Practical examples
- Self-Hosting Guide - Deploy your own contracts
Advanced Usage
Manual Payment Flow
For full control over the payment process:
import { Aptos, AptosConfig, Network, Account, Ed25519PrivateKey } from '@aptos-labs/ts-sdk';
async function manualPaymentFlow(url: string, privateKey: string) {
// 1. Request without payment
let response = await fetch(url);
if (response.status === 402) {
const paymentReqs = await response.json();
const requirement = paymentReqs.accepts[0];
// 2. Initialize Aptos client
const config = new AptosConfig({
network: requirement.network === 'aptos-testnet' ? Network.TESTNET : Network.MAINNET
});
const aptos = new Aptos(config);
const account = Account.fromPrivateKey({
privateKey: new Ed25519PrivateKey(privateKey)
});
// 3. Build and sign transaction
const transaction = await aptos.transaction.build.simple({
sender: account.accountAddress,
data: {
function: '0x1::aptos_account::transfer',
functionArguments: [requirement.payTo, requirement.maxAmountRequired]
}
});
const authenticator = aptos.transaction.sign({ signer: account, transaction });
// 4. Create payment payload
const paymentPayload = {
x402Version: 1,
scheme: requirement.scheme,
network: requirement.network,
payload: {
signature: Buffer.from(authenticator.bcsToBytes()).toString('base64'),
transaction: Buffer.from(transaction.bcsToBytes()).toString('base64')
}
};
// 5. Retry with payment
response = await fetch(url, {
headers: {
'Payment': Buffer.from(JSON.stringify(paymentPayload)).toString('base64')
}
});
}
return await response.json();
}Wallet Integration
For browser applications, integrate with Aptos wallets:
// Petra Wallet
import { useWallet } from '@aptos-labs/wallet-adapter-react';
const { signTransaction } = useWallet();
const signedTx = await signTransaction(transaction);Examples & Demo
Interactive Demo
Try the complete payment flow: aptos-x402.org
Example Code
| Example | Description | Path |
|---|---|---|
| Simple Seller | Basic middleware setup | examples/simple-seller/ |
| Facilitator | Self-hosted facilitator guide | examples/facilitator/ |
| Full Demo | Complete implementation | app/ |
CLI Demo
git clone https://github.com/adipundir/Aptos-x402
cd Aptos-x402
npm install
npm run dev # In one terminal
# In another terminal
npx tsx scripts/test-x402-axios.tsFacilitator
The facilitator handles blockchain operations (verification and settlement) separately from your API server.
Options
| Option | Best For | Setup |
|---|---|---|
| Public Facilitator | Development, testing, POCs | url: "https://aptos-x402.org/api/facilitator" |
| Self-Hosted (Same App) | Small to medium deployments | Copy facilitator routes to your Next.js app |
| Self-Hosted (Separate) | Production, high scale | Deploy as standalone service |
Why Separate?
- Security - Isolate blockchain operations
- Scalability - Share across multiple APIs
- Flexibility - Upgrade independently
See Facilitator Setup Guide for detailed deployment instructions.
FAQ
Why use x402 instead of API keys?
- No secrets to manage, rotate, or leak
- True pay-per-use with no subscriptions
- Decentralized with no auth server
- Instant monetization without payment processors
How fast are payments?
| Operation | Time |
|---|---|
| Verification | < 50ms |
| Settlement | 1-3 seconds |
| Total | ~1-3 seconds |
What are the costs?
| Party | Cost |
|---|---|
| Client | Gas (~$0.0001) + API price |
| Server | Facilitator hosting only |
| Protocol | Free, open source |
Is this production-ready?
Yes, with proper testing:
- Start on testnet for development
- Thorough testing before mainnet
- Monitor facilitator health
- Implement error handling
Can I use other blockchains?
This SDK is Aptos-specific. x402 protocol supports any blockchain. Other implementations coming soon.
Do I need a blockchain wallet?
Sellers: Need wallet address to receive payments (no private key on server)
Buyers: Need funded wallet to make payments
Generate testnet wallets: npx tsx scripts/generate-account.ts
How do AI agents use this?
Agents can autonomously make payments:
const agent = createAgent({ privateKey: process.env.AGENT_KEY });
const data = await x402axios.get(apiUrl, { privateKey: agent.key });No human intervention required.
Performance Monitoring
Track payment performance with built-in timing headers:
const response = await x402axios.get(url, { privateKey });
// Check performance metrics
const verifyTime = response.headers['verification-time'];
const settleTime = response.headers['settlement-time'];
const cached = response.headers['cached'] === 'true';
console.log(`Verification: ${verifyTime}ms`);
console.log(`Settlement: ${settleTime}ms`);
console.log(`Cached: ${cached}`);Performance Benchmarks
Run the included benchmark to measure your setup:
APTOS_PRIVATE_KEY=0x... npx tsx scripts/benchmark-payment-flow.tsExpected Performance:
- First request (uncached): ~800-1000ms
- Cached requests: ~650-800ms
- Settlement alone: ~200-300ms
- Legacy (pre-optimization): ~2000-3000ms
Optimization Details: See PERFORMANCE_OPTIMIZATIONS.md for complete breakdown of the 5-10x performance improvements.
Resources
Documentation
Links
Support
Contributing
Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests.
Built for the Aptos Ecosystem
Documentation • GitHub • NPM