x402-sui
v2.0.1
Published
x402 Payment Protocol (V2) for Sui blockchain
Maintainers
Readme
x402-sui
x402 Payment Protocol (V2) for Sui blockchain - HTTP 402 Payment Required implementation for decentralized micropayments.
The x402 protocol enables automatic, pay-per-use API access using the Sui blockchain. When a client makes a request to a payment-gated API endpoint, the server responds with 402 Payment Required along with payment instructions. The x402-sui client automatically handles the payment on Sui and retries the request.
🚀 Features
- 🔐 Payment Verification - Server-side verification of Sui transactions
- 🌐 Express Middleware - Easy integration with Express.js APIs
- 📡 Axios Interceptor - Client-side automatic payment handling
- 💳 Flexible Payment Flows - Support for various payment patterns
- ⚡ TypeScript First - Full type definitions included
- 🔄 Automatic Retry - Seamless payment + retry flow
📦 Installation
npm install x402-sui🎯 Quick Start
Client-Side: Automatic Payment Handling
Use wrapAxiosWithPayment() to automatically handle 402 payment responses:
import axios from 'axios';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import { wrapAxiosWithPayment, keypairToAccount } from 'x402-sui';
// Create or load your Sui keypair
const keypair = Ed25519Keypair.fromSecretKey(process.env.SUI_PRIVATE_KEY!);
const account = keypairToAccount(keypair, 'testnet');
// Wrap your axios instance with automatic x402 payment handling
const api = wrapAxiosWithPayment(
axios.create({ baseURL: 'https://api.example.com' }),
keypair,
account
);
// Make requests normally - payments are handled automatically
const response = await api.post('/protected/resource', {
data: 'your request data'
});
console.log('Response:', response.data);When the API returns 402 Payment Required, the client will:
- Extract payment details from the response headers
- Sign and submit a payment transaction on Sui
- Automatically retry the original request with payment proof
Server-Side: Payment-Gated API
Create payment-gated endpoints using Express middleware:
import express from 'express';
import { paymentMiddleware } from 'x402-sui';
const app = express();
app.use('/protected', paymentMiddleware({
network: 'testnet',
price: '10000000', // 0.01 SUI in MIST
recipient: '0xYOUR_ADDRESS_HERE'
}));
app.post('/protected/resource', async (req, res) => {
// This endpoint requires payment
res.json({ success: true, data: 'Protected content' });
});
app.listen(4022, () => {
console.log('Server running on http://localhost:4022');
});📚 Complete Examples
Example 1: Creating a Sui Wallet
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import { requestSuiFromFaucetV0 } from '@mysten/sui/faucet';
// Generate a new keypair
const keypair = new Ed25519Keypair();
const address = keypair.toSuiAddress();
const secretKey = keypair.getSecretKey();
console.log('Address:', address);
console.log('Private Key:', secretKey);
// Request testnet SUI from faucet
await requestSuiFromFaucetV0({
host: 'https://faucet.testnet.sui.io',
recipient: address,
});Example 2: Client Making Payment-Gated Requests
import 'dotenv/config';
import axios from 'axios';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import {
wrapAxiosWithPayment,
keypairToAccount,
getPaymentResponseFromHeaders,
} from 'x402-sui';
async function main() {
const keypair = Ed25519Keypair.fromSecretKey(process.env.SUI_PRIVATE_KEY!);
const account = keypairToAccount(keypair, 'testnet');
console.log('Agent address:', account.address);
console.log('Network:', account.network);
// Create x402-wrapped client
const api = wrapAxiosWithPayment(
axios.create({ baseURL: 'http://localhost:4022' }),
keypair,
account
);
// Make a payment-gated request
console.log('Posting task (will auto-pay on 402)...');
const response = await api.post('/tasks', {
title: 'Test Task',
description: 'Verify website functionality',
rewardAmount: '1000000', // 0.001 SUI
});
console.log('Task created:', response.data);
// Extract payment receipt from headers
const receipt = getPaymentResponseFromHeaders(response);
if (receipt) {
console.log('Payment details:');
console.log(' Payer:', receipt.payer);
console.log(' Transaction:', receipt.transaction);
console.log(' Network:', receipt.network);
}
}
main().catch(console.error);Example 3: Server with Multiple Payment Tiers
import express from 'express';
import { paymentMiddleware } from 'x402-sui';
const app = express();
app.use(express.json());
// Free endpoint
app.get('/health', (req, res) => {
res.json({ status: 'ok' });
});
// Basic tier: 0.001 SUI
app.use('/basic', paymentMiddleware({
network: 'testnet',
price: '1000000',
recipient: process.env.RECIPIENT_ADDRESS!
}));
app.get('/basic/data', (req, res) => {
res.json({ tier: 'basic', data: 'Basic content' });
});
// Premium tier: 0.01 SUI
app.use('/premium', paymentMiddleware({
network: 'testnet',
price: '10000000',
recipient: process.env.RECIPIENT_ADDRESS!
}));
app.post('/premium/ai-analysis', (req, res) => {
res.json({ tier: 'premium', analysis: 'Advanced AI results' });
});
app.listen(4022);🔧 API Reference
Client Functions
wrapAxiosWithPayment(axiosInstance, keypair, account)
Wraps an axios instance to automatically handle 402 payment responses.
Parameters:
axiosInstance- Axios instance to wrapkeypair- Sui Ed25519Keypair for signing transactionsaccount- Account object with address and network info
Returns: Wrapped axios instance with payment handling
keypairToAccount(keypair, network)
Converts a Sui keypair to an account object.
Parameters:
keypair- Sui Ed25519Keypairnetwork- Network name ('testnet', 'mainnet', 'devnet')
Returns: Account object with address and network
getPaymentResponseFromHeaders(response)
Extracts payment receipt from response headers.
Parameters:
response- Axios response object
Returns: Payment receipt object or null
{
success: boolean;
payer: string;
transaction: string;
network: string;
}Server Middleware
paymentMiddleware(options)
Express middleware for payment-gated endpoints.
Options:
{
network: 'testnet' | 'mainnet' | 'devnet';
price: string; // Amount in MIST (1 SUI = 1e9 MIST)
recipient: string; // Your Sui address to receive payments
}🌐 Real-World Use Case: AI Agent + Human-in-the-Loop
The included demo shows an AI agent that:
- Posts QA tasks to a human-in-the-loop API (payment-gated)
- Pays testers for completed work (also payment-gated)
- Handles all payments automatically using x402
// Agent posts a task (pays 0.01 SUI to the API)
const taskRes = await api.post('/tasks', {
title: 'Test website functionality',
description: 'Verify the website works correctly',
url: 'https://example.com',
rewardAmount: '1000000', // Reward for the human tester
});
// Later: Agent pays the tester for completed work
const completeRes = await api.post(`/tasks/${taskId}/complete`);
// ^ This triggers a 402 response that transfers the reward to the tester💰 Price Conversion
Sui uses MIST as the smallest unit (1 SUI = 1,000,000,000 MIST):
const MIST_PER_SUI = 1_000_000_000;
// Convert SUI to MIST
const priceInMIST = (0.01 * MIST_PER_SUI).toString(); // "10000000"
// Convert MIST to SUI
const priceInSUI = Number(mist) / MIST_PER_SUI;🔐 Environment Setup
Create a .env file:
SUI_PRIVATE_KEY=suiprivkey1q_YOUR_PRIVATE_KEY_HERE
RECIPIENT_ADDRESS=0xYOUR_SUI_ADDRESS
API_URL=http://localhost:4022📖 How It Works
Payment Flow
sequenceDiagram
Client->>API: POST /protected/resource
API->>Client: 402 Payment Required + payment details
Client->>Sui: Submit payment transaction
Sui->>Client: Transaction receipt
Client->>API: POST /protected/resource + proof
API->>Sui: Verify transaction
API->>Client: 200 OK + protected contentResponse Headers
When a 402 response is returned, the server includes:
X-Payment-Required: true
X-Payment-Amount: 10000000
X-Payment-Recipient: 0xRECIPIENT_ADDRESS
X-Payment-Network: testnetAfter successful payment, the client includes:
X-Payment-Receipt: {"payer":"0xPAYER","transaction":"DIGEST","network":"testnet"}🧪 Testing
# Run the demo examples
npm run post-task # Client: Create a task (pays API)
npm run pay-testers # Client: Pay testers for work
npm run create-wallet # Utility: Generate a new wallet🔗 Dependencies
- @mysten/sui - Sui blockchain SDK for transactions and keypairs
- axios - HTTP client for API requests
- express - Web framework (peer dependency for server-side)
📝 License
MIT
🤝 Contributing
Contributions welcome! This protocol demonstrates how to build decentralized payment systems for API access using blockchain technology.
🔗 Resources
Built for ETHGlobal HackMoney 2026 🚀
