x402 protocol for Aptos blockchain
Aptos-x402 is an early-stage TypeScript project in the AI payments / x402 ecosystem, focused on x402. It currently has 10 GitHub stars and 3 forks, and sits alongside related tools like nofx, ClawRouter, bitterbot-desktop, internet-court-skill, Franklin, daydreams.
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).
PAYMENT-SIGNATURE headers (removed "X-").Performance: Latest optimizations deliver faster settlement with verification caching, async confirmation, and smart deduplication.
| 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 |
npm install aptos-x402
Access x402-protected APIs with zero configuration. The x402axios client automatically detects payment requirements, builds transactions, and handles the entire payment flow.
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);
// 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...' });
The client automatically handles the complete payment flow:
Protect Next.js API routes with x402 middleware - zero payment code required in your route handlers.
Create .env.local in your project root:
PAYMENT_RECIPIENT_ADDRESS=0xYOUR_APTOS_WALLET_ADDRESS
FACILITATOR_URL=https://aptos-x402.org/api/facilitator
Getting a Wallet Address:
Install Petra Wallet or generate programmatically with@aptos-labs/ts-sdk
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*']
};
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...'
});
}
| 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 |
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 Octas
Start your development server and verify payment protection:
npm run dev
# Test without payment (should return 402)
curl http://localhost:3000/api/premium/weather
Expected 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
});
┌──────────┐ ┌──────────┐ ┌────────────┐ ┌───────────┐
│ 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: {...} │ │ │
│ │ │ │
| 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 |
paymentMiddleware()Creates Next.js middleware for x402 payment enforcement.
Signature:
function paymentMiddleware(
recipientAddress: string,
routes: Record<string, RouteConfig>,
facilitatorConfig: FacilitatorConfig
): NextMiddleware
Parameters:
| 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')
}
x402axiosAxios-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;
};
}
Import types for full type safety:
import type {
RouteConfig,
FacilitatorConfig,
PaymentRequiredResponse,
PaymentRequirements,
PaymentPayload
} from 'aptos-x402/types';
ARC-8004 provides identity, reputation, and validation for AI agents on Aptos. It integrates with x402 payments to build trust signals from paid interactions.
| 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 |
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"
// 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 },
});
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'),
});
# .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=true
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();
}
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);
Try the complete payment flow: aptos-x402.org
| Example | Description | Path |
|---|---|---|
| Simple Seller | Basic middleware setup | examples/simple-seller/ |
| Facilitator | Self-hosted facilitator guide | examples/facilitator/ |
| Full Demo | Complete implementation | app/ |
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.ts
The facilitator handles blockchain operations (verification and settlement) separately from your API server.
| 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 |
See Facilitator Setup Guide for detailed deployment instructions.
| Operation | Time |
|---|---|
| Verification | < 50ms |
| Settlement | 1-3 seconds |
| Total | ~1-3 seconds |
| Party | Cost |
|---|---|
| Client | Gas (~$0.0001) + API price |
| Server | Facilitator hosting only |
| Protocol | Free, open source |
Yes, with proper testing:
This SDK is Aptos-specific. x402 protocol supports any blockchain. Other implementations coming soon.
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
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.
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}`);
Run the included benchmark to measure your setup:
APTOS_PRIVATE_KEY=0x... npx tsx scripts/benchmark-payment-flow.ts
Expected Performance:
Optimization Details: See PERFORMANCE_OPTIMIZATIONS.md for complete breakdown of the 5-10x performance improvements.
Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests.
Built for the Aptos Ecosystem
Documentation • GitHub • NPM
Your AI trading terminal assistant for US stocks, commodities, forex, and crypto.
The agent-native LLM router for autonomous agents. 55+ models (8 free), <1ms local routing, USDC payments on Base & Solana via x402.
A local-first AI agent with persistent memory, emotional intelligence, and a peer-to-peer skills economy.
The trust layer for agent-to-agent commerce — natural-language mandates, ERC-7710 delegated permissions, x402 payments, escrow, and dispute resolution as one open, catch-all Agent Skill / Claude Code plugin.
The AI agent with a wallet — spends USDC autonomously to get real work done. Apache-2.0, TypeScript.
Daydreams is a set of tools for building agents for commerce
A payments protocol for the internet. Built on HTTP.
Self-healing infrastructure for AI agent payments. 90.3% auto-recovery.
Open Source AI trading agent that operates autonomously across 1000+ markets - Polymarket, Kalshi, Binance, Hyperliquid, Solana DEXs, 5 EVM chains. Scans for edge, executes instantly, manages risk while you sleep. Agent commerce protocol for machine-to-machine payments. Self-hosted. Built on Claude.
The world's first privacy layer for AI agents on Solana — stealth addresses + x402 payments. Every payment lands at a fresh, unlinkable address.
Live data for AI agents — search, research, markets, crypto, X/Twitter. Pay-per-call via x402 micropayments.
x402 Ecosystem Explorer