UNPKG

oneie

Version:

Build apps, websites, and AI agents in English. Zero-interaction setup for AI agents (Claude Code, Cursor, Windsurf). Download to your computer, run in the cloud, deploy to the edge. Open source and free forever.

1,354 lines (1,168 loc) 39.3 kB
--- title: X402 dimension: connections category: x402.md tags: agent, ai, blockchain, protocol related_dimensions: events, knowledge, people, things scope: global created: 2025-11-03 updated: 2025-11-03 version: 1.0.0 ai_context: | This document is part of the connections dimension in the x402.md category. Location: one/connections/x402.md Purpose: Documents x402 protocol integration - http-native payments Related dimensions: events, knowledge, people, things For AI agents: Read this to understand x402. --- # X402 Protocol Integration - HTTP-Native Payments **Version:** 1.0.0 **Purpose:** Integrate X402 protocol for instant, frictionless digital payments across ONE platform agents and services **Protocol:** https://www.x402.org/ **GitHub:** https://github.com/coinbase/x402 --- ## Overview **X402** is an open protocol for internet-native payments built around the HTTP 402 "Payment Required" status code. It enables instant digital transactions without complex registration processes, making it ideal for AI agent-to-agent payments, API monetization, and micropayments. **Key Benefits:** - ✅ **Zero fees** for customers and merchants - ✅ **Instant settlement** (~2 seconds on blockchain) - ✅ **Minimal integration** (1 line of middleware code) - ✅ **Blockchain agnostic** (Solana, Ethereum, Base, etc.) - ✅ **No account creation** required - ✅ **Micropayments** as low as $0.001 - ✅ **HTTP-native** (works with existing web infrastructure) **Use Cases in ONE Platform:** 1. AI agent API calls (pay-per-request) 2. External agent integrations (ElizaOS, AutoGen, etc.) 3. N8N workflow executions (pay-per-run) 4. Cloud storage access (pay-per-GB) 5. Content creator micropayments 6. Multi-agent collaboration billing --- ## Architecture: X402 + Effect.ts + Convex ``` ┌─────────────────────────────────────────────────────────────────┐ │ FRONTEND (React + Astro) │ ├─────────────────────────────────────────────────────────────────┤ │ Payment UI Components │ │ ├─ <PaymentPrompt> - Show 402 payment required │ │ ├─ <WalletConnect> - Connect crypto wallet │ │ ├─ <PaymentHistory> - View transaction history │ │ └─ <BalanceDisplay> - Show wallet balance │ └──────────────────┬──────────────────────────────────────────────┘ │ ↓ X-PAYMENT HTTP Header ┌──────────────────┐ │ Astro API Route │ │ (X402 Handler) │ └────────┬─────────┘ │ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ Convex Backend │ ├─────────────────────────────────────────────────────────────────┤ │ X402PaymentService (Effect.ts) │ │ ├─ verifyPayment(paymentPayload) → boolean │ │ ├─ createPaymentRequest(resource, amount) → PaymentRequired │ │ ├─ settlePayment(paymentId) → Transaction │ │ └─ getPaymentHistory(userId) → Payment[] │ │ │ │ X402FacilitatorService (Effect.ts) │ │ ├─ POST /verify - Validate payment │ │ ├─ POST /settle - Execute blockchain transaction │ │ ├─ GET /supported - List supported schemes/networks │ │ └─ Integrates with blockchain providers │ └──────────────────┬──────────────────────────────────────────────┘ │ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ Blockchain Layer (Multi-Chain) │ ├─────────────────────────────────────────────────────────────────┤ │ Base (Coinbase L2) │ │ ├─ USDC transfers │ │ ├─ Low gas fees │ │ └─ Fast settlement │ │ │ │ Ethereum Mainnet │ │ ├─ USDC, DAI, USDT │ │ └─ Permit-based transfers │ │ │ │ Solana │ │ ├─ USDC (SPL token) │ │ └─ Ultra-low fees │ └─────────────────────────────────────────────────────────────────┘ ``` **Key Integration Points:** 1. Astro API routes handle X402 protocol (402 responses, X-PAYMENT headers) 2. Effect.ts services manage payment verification and settlement 3. Convex stores payment records and transaction history 4. Multi-chain support via Effect.ts providers (Base, Ethereum, Solana) --- ## Part 1: X402 Protocol Specification ### HTTP 402 Flow **1. Client Requests Protected Resource** ```http GET /api/agent/execute?taskId=123 HTTP/1.1 Host: one.ie Authorization: Bearer user-token-123 ``` **2. Server Responds with 402 Payment Required** ```http HTTP/1.1 402 Payment Required Content-Type: application/json { "x402Version": 1, "accepts": [ { "scheme": "permit", "network": "base", "maxAmountRequired": "0.01", "resource": "/api/agent/execute?taskId=123", "payTo": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e", "asset": "USDC", "decimals": 6 }, { "scheme": "permit", "network": "ethereum", "maxAmountRequired": "0.01", "resource": "/api/agent/execute?taskId=123", "payTo": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e", "asset": "USDC", "decimals": 6 }, { "scheme": "transfer", "network": "solana", "maxAmountRequired": "0.01", "resource": "/api/agent/execute?taskId=123", "payTo": "DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK", "asset": "USDC", "decimals": 6 } ], "error": null } ``` **3. Client Creates Payment and Retries Request** ```http POST /api/agent/execute?taskId=123 HTTP/1.1 Host: one.ie Authorization: Bearer user-token-123 X-PAYMENT: {"x402Version":1,"scheme":"permit","network":"base","payload":{"permit":{"..."},"signature":"0x..."}} Content-Type: application/json { "parameters": { "action": "analyze_metrics", "userId": "user-123" } } ``` **4. Server Verifies Payment and Returns Resource** ```http HTTP/1.1 200 OK Content-Type: application/json X-PAYMENT-ID: pay_1234567890 { "result": { "analysis": "...", "metrics": {...} } } ``` ### TypeScript Protocol Interfaces **File:** `convex/protocols/x402.ts` ```typescript import { v } from "convex/values"; /** * X402 Protocol Version */ export const X402_VERSION = 1; /** * Payment Required Response (HTTP 402) */ export interface PaymentRequired { x402Version: number; accepts: PaymentRequirement[]; error?: string; } /** * Payment Requirement for a specific scheme/network */ export interface PaymentRequirement { scheme: PaymentScheme; network: BlockchainNetwork; maxAmountRequired: string; // Decimal string (e.g., "0.01") resource: string; // API endpoint path payTo: string; // Recipient address asset: string; // Token symbol (e.g., "USDC") decimals?: number; // Token decimals (default 6 for USDC) facilitator?: string; // Facilitator server URL metadata?: { description?: string; // Payment description invoiceId?: string; // Invoice reference [key: string]: any; }; } /** * Payment Schemes */ export type PaymentScheme = | "permit" // ERC-2612 permit (gasless approval + transfer) | "transfer" // Direct token transfer | "signature" // Signature-based payment | "invoice"; // Invoice-based payment /** * Supported Blockchain Networks */ export type BlockchainNetwork = | "base" // Coinbase Base L2 | "ethereum" // Ethereum mainnet | "solana" // Solana mainnet | "arbitrum" // Arbitrum L2 | "optimism" // Optimism L2 | "polygon"; // Polygon PoS /** * Payment Payload (sent in X-PAYMENT header) */ export interface PaymentPayload { x402Version: number; scheme: PaymentScheme; network: BlockchainNetwork; payload: PermitPayload | TransferPayload | SignaturePayload | InvoicePayload; } /** * Permit-based Payment (ERC-2612) */ export interface PermitPayload { permit: { owner: string; // Sender address spender: string; // Facilitator contract address value: string; // Amount (in token units) nonce: number; // Permit nonce deadline: number; // Unix timestamp }; signature: string; // EIP-712 signature transferData?: { recipient: string; // Final recipient amount: string; // Transfer amount }; } /** * Direct Transfer Payment */ export interface TransferPayload { txHash: string; // Transaction hash from: string; // Sender address to: string; // Recipient address amount: string; // Amount transferred token: string; // Token contract address timestamp: number; // Transaction timestamp } /** * Signature-based Payment */ export interface SignaturePayload { message: string; // Signed message signature: string; // Signature signer: string; // Signer address nonce: string; // Unique nonce } /** * Invoice-based Payment */ export interface InvoicePayload { invoiceId: string; // Invoice identifier proof: string; // Payment proof amount: string; // Amount paid timestamp: number; // Payment timestamp } /** * Facilitator Endpoints */ export interface FacilitatorEndpoints { verify: string; // POST /verify - Validate payment settle: string; // POST /settle - Execute settlement supported: string; // GET /supported - List schemes/networks } /** * Payment Verification Request */ export interface VerifyPaymentRequest { paymentPayload: PaymentPayload; requirement: PaymentRequirement; resource: string; timestamp: number; } /** * Payment Verification Response */ export interface VerifyPaymentResponse { valid: boolean; paymentId?: string; txHash?: string; error?: string; metadata?: { blockNumber?: number; confirmations?: number; gasUsed?: string; [key: string]: any; }; } /** * Settlement Request */ export interface SettlePaymentRequest { paymentId: string; paymentPayload: PaymentPayload; requirement: PaymentRequirement; } /** * Settlement Response */ export interface SettlePaymentResponse { settled: boolean; txHash: string; blockNumber?: number; error?: string; } /** * Supported Schemes Response */ export interface SupportedSchemesResponse { schemes: Array<{ scheme: PaymentScheme; networks: BlockchainNetwork[]; tokens: Array<{ symbol: string; address: string; decimals: number; networks: BlockchainNetwork[]; }>; }>; } /** * Convex validators for X402 protocol */ export const paymentRequirementValidator = { scheme: v.union( v.literal("permit"), v.literal("transfer"), v.literal("signature"), v.literal("invoice") ), network: v.union( v.literal("base"), v.literal("ethereum"), v.literal("solana"), v.literal("arbitrum"), v.literal("optimism"), v.literal("polygon") ), maxAmountRequired: v.string(), resource: v.string(), payTo: v.string(), asset: v.string(), decimals: v.optional(v.number()), facilitator: v.optional(v.string()), metadata: v.optional(v.any()), }; export const paymentPayloadValidator = { x402Version: v.number(), scheme: v.union( v.literal("permit"), v.literal("transfer"), v.literal("signature"), v.literal("invoice") ), network: v.union( v.literal("base"), v.literal("ethereum"), v.literal("solana"), v.literal("arbitrum"), v.literal("optimism"), v.literal("polygon") ), payload: v.any(), }; ``` --- ## Part 2: Effect.ts Service Implementation ### X402PaymentService **File:** `convex/services/x402-payment.ts` ```typescript import { Effect } from "effect"; import { ConvexDatabase } from "./convex-database"; import type { Id } from "../_generated/dataModel"; import type { PaymentRequired, PaymentRequirement, PaymentPayload, VerifyPaymentRequest, VerifyPaymentResponse, X402_VERSION, } from "../protocols/x402"; /** * X402PaymentService - Implements X402 protocol for HTTP-native payments */ export class X402PaymentService extends Effect.Service<X402PaymentService>()( "X402PaymentService", { effect: Effect.gen(function* () { const db = yield* ConvexDatabase; return { /** * Create a 402 Payment Required response */ createPaymentRequest: (args: { resource: string; amount: string; description?: string; userId?: Id<"entities">; }) => Effect.gen(function* () { // Get platform payment addresses const paymentConfig = yield* getPaymentConfig(); // Create payment requirements for all supported networks const accepts: PaymentRequirement[] = [ // Base (Coinbase L2) - Preferred { scheme: "permit", network: "base", maxAmountRequired: args.amount, resource: args.resource, payTo: paymentConfig.base.address, asset: "USDC", decimals: 6, facilitator: paymentConfig.facilitatorUrl, metadata: { description: args.description, preferredNetwork: true, }, }, // Ethereum mainnet { scheme: "permit", network: "ethereum", maxAmountRequired: args.amount, resource: args.resource, payTo: paymentConfig.ethereum.address, asset: "USDC", decimals: 6, facilitator: paymentConfig.facilitatorUrl, metadata: { description: args.description, }, }, // Solana { scheme: "transfer", network: "solana", maxAmountRequired: args.amount, resource: args.resource, payTo: paymentConfig.solana.address, asset: "USDC", decimals: 6, metadata: { description: args.description, }, }, ]; const paymentRequired: PaymentRequired = { x402Version: X402_VERSION, accepts, error: null, }; // Log payment request yield* db.insert("events", { type: "payment_requested", actorId: args.userId, targetId: null, timestamp: Date.now(), metadata: { protocol: "x402", resource: args.resource, amount: args.amount, networks: accepts.map((a) => a.network), }, }); return paymentRequired; }), /** * Verify payment from X-PAYMENT header */ verifyPayment: (args: { paymentPayload: PaymentPayload; requirement: PaymentRequirement; resource: string; userId?: Id<"entities">; }) => Effect.gen(function* () { // Validate payload version if (args.paymentPayload.x402Version !== X402_VERSION) { return { valid: false, error: `Unsupported X402 version: ${args.paymentPayload.x402Version}`, } as VerifyPaymentResponse; } // Validate scheme matches if (args.paymentPayload.scheme !== args.requirement.scheme) { return { valid: false, error: `Payment scheme mismatch: expected ${args.requirement.scheme}, got ${args.paymentPayload.scheme}`, } as VerifyPaymentResponse; } // Validate network matches if (args.paymentPayload.network !== args.requirement.network) { return { valid: false, error: `Network mismatch: expected ${args.requirement.network}, got ${args.paymentPayload.network}`, } as VerifyPaymentResponse; } // Call facilitator to verify payment const facilitatorUrl = args.requirement.facilitator || process.env.X402_FACILITATOR_URL; const verifyRequest: VerifyPaymentRequest = { paymentPayload: args.paymentPayload, requirement: args.requirement, resource: args.resource, timestamp: Date.now(), }; const response = yield* Effect.tryPromise({ try: () => fetch(`${facilitatorUrl}/verify`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(verifyRequest), }).then((res) => res.json()), catch: (error) => new Error(`Facilitator verification failed: ${error}`), }); const verifyResponse = response as VerifyPaymentResponse; if (!verifyResponse.valid) { // Log failed verification yield* db.insert("events", { type: "payment_failed", actorId: args.userId, targetId: null, timestamp: Date.now(), metadata: { protocol: "x402", resource: args.resource, error: verifyResponse.error, scheme: args.paymentPayload.scheme, network: args.paymentPayload.network, }, }); return verifyResponse; } // Store verified payment const paymentId = yield* db.insert("entities", { type: "payment", name: `X402 Payment - ${args.resource}`, properties: { protocol: "x402", scheme: args.paymentPayload.scheme, network: args.paymentPayload.network, amount: args.requirement.maxAmountRequired, asset: args.requirement.asset, resource: args.resource, payTo: args.requirement.payTo, txHash: verifyResponse.txHash, paymentId: verifyResponse.paymentId, status: "verified", userId: args.userId, verifiedAt: Date.now(), metadata: verifyResponse.metadata, }, status: "active", createdAt: Date.now(), updatedAt: Date.now(), }); // Log successful payment yield* db.insert("events", { type: "payment_verified", actorId: args.userId, targetId: paymentId, timestamp: Date.now(), metadata: { protocol: "x402", resource: args.resource, amount: args.requirement.maxAmountRequired, scheme: args.paymentPayload.scheme, network: args.paymentPayload.network, txHash: verifyResponse.txHash, }, }); return { ...verifyResponse, paymentId: paymentId as string, }; }), /** * Get payment history for a user */ getPaymentHistory: (args: { userId: Id<"entities">; limit?: number }) => Effect.gen(function* () { const payments = yield* db.query("entities", { filter: (q) => q.and( q.eq(q.field("type"), "payment"), q.eq(q.field("properties.protocol"), "x402"), q.eq(q.field("properties.userId"), args.userId) ), limit: args.limit || 100, }); return payments; }), /** * Get total amount paid by user */ getTotalPaid: (args: { userId: Id<"entities">; asset?: string }) => Effect.gen(function* () { const payments = yield* db.query("entities", { filter: (q) => { const conditions = [ q.eq(q.field("type"), "payment"), q.eq(q.field("properties.protocol"), "x402"), q.eq(q.field("properties.userId"), args.userId), ]; if (args.asset) { conditions.push( q.eq(q.field("properties.asset"), args.asset) ); } return q.and(...conditions); }, }); const total = payments.reduce((sum, payment) => { const amount = parseFloat(payment.properties.amount as string); return sum + amount; }, 0); return { total: total.toFixed(6), asset: args.asset || "USDC", count: payments.length, }; }), }; }), dependencies: [ConvexDatabase.Default], } ) {} /** * Helper: Get payment configuration */ const getPaymentConfig = () => Effect.gen(function* () { return { facilitatorUrl: process.env.X402_FACILITATOR_URL || "https://facilitator.x402.org", base: { address: process.env.X402_BASE_ADDRESS || "0x742d35Cc6634C0532925a3b844Bc454e4438f44e", usdcContract: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC on Base }, ethereum: { address: process.env.X402_ETHEREUM_ADDRESS || "0x742d35Cc6634C0532925a3b844Bc454e4438f44e", usdcContract: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC on Ethereum }, solana: { address: process.env.X402_SOLANA_ADDRESS || "DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK", usdcMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC on Solana }, }; }); ``` --- ## Part 3: Astro API Route Integration ### X402 Middleware **File:** `src/pages/api/x402/middleware.ts` ```typescript import type { APIRoute } from "astro"; import { X402PaymentService } from "@/convex/services/x402-payment"; import type { PaymentPayload, PaymentRequired } from "@/convex/protocols/x402"; /** * X402 Middleware - Handle payment verification for protected routes */ export async function x402Middleware( request: Request, resource: string, amount: string, userId?: string ): Promise<Response | null> { const paymentHeader = request.headers.get("X-PAYMENT"); // If no payment header, return 402 Payment Required if (!paymentHeader) { const paymentService = new X402PaymentService(); const paymentRequired = await paymentService.createPaymentRequest({ resource, amount, description: `Access to ${resource}`, userId, }); return new Response(JSON.stringify(paymentRequired), { status: 402, headers: { "Content-Type": "application/json", "X-PAYMENT-REQUIRED": "true", }, }); } // Parse payment payload let paymentPayload: PaymentPayload; try { paymentPayload = JSON.parse(paymentHeader); } catch (error) { return new Response( JSON.stringify({ error: "Invalid X-PAYMENT header format" }), { status: 400, headers: { "Content-Type": "application/json" }, } ); } // Verify payment const paymentService = new X402PaymentService(); const verification = await paymentService.verifyPayment({ paymentPayload, requirement: { scheme: paymentPayload.scheme, network: paymentPayload.network, maxAmountRequired: amount, resource, payTo: process.env.X402_BASE_ADDRESS!, asset: "USDC", }, resource, userId, }); if (!verification.valid) { return new Response( JSON.stringify({ error: verification.error || "Payment verification failed", }), { status: 402, headers: { "Content-Type": "application/json", "X-PAYMENT-FAILED": "true", }, } ); } // Payment verified - return null to continue processing return null; } ``` ### Protected API Route Example **File:** `src/pages/api/agent/execute.ts` ```typescript import type { APIRoute } from "astro"; import { x402Middleware } from "./x402/middleware"; import { IntelligenceAgent } from "@/convex/services/intelligence-agent"; export const POST: APIRoute = async ({ request, locals }) => { const resource = "/api/agent/execute"; const amount = "0.01"; // $0.01 per request const userId = locals.user?.id; // X402 payment check const paymentResponse = await x402Middleware( request, resource, amount, userId ); if (paymentResponse) { return paymentResponse; // Return 402 or payment error } // Payment verified - execute agent task const { taskId, parameters } = await request.json(); const intelligenceAgent = new IntelligenceAgent(); const result = await intelligenceAgent.executeTask({ taskId, userId, parameters, }); return new Response(JSON.stringify(result), { status: 200, headers: { "Content-Type": "application/json", "X-PAYMENT-VERIFIED": "true", }, }); }; ``` --- ## Multi-Tenancy & Groups All entities, connections, and events in this protocol are scoped to a `groupId`: ```typescript // Every entity { groupId: Id<"groups">, // Required for multi-tenancy type: "payment" | "x402_service", // ... rest of fields } // Every connection { groupId: Id<"groups">, // Required for multi-tenancy fromEntityId: Id<"entities">, toEntityId: Id<"entities">, relationshipType: "paid_via" | "uses_service", // ... rest of fields } // Every event { groupId: Id<"groups">, // Required for multi-tenancy type: "payment_requested" | "payment_verified" | "payment_failed", // ... rest of fields } ``` ## Part 4: Ontology Integration ### Entity Types Uses existing types (no new types needed): ```typescript // Payment entity (existing) | 'payment' ``` **Payment Properties for X402:** ```typescript { protocol: 'x402', scheme: 'permit' | 'transfer' | 'signature' | 'invoice', network: 'base' | 'ethereum' | 'solana' | 'arbitrum' | 'optimism' | 'polygon', amount: string, // Decimal amount (e.g., "0.01") asset: string, // Token symbol (e.g., "USDC") resource: string, // API endpoint payTo: string, // Recipient address txHash?: string, // Blockchain transaction hash paymentId?: string, // X402 payment ID status: 'pending' | 'verified' | 'settled' | 'failed', userId?: Id<'entities'>, // Payer user ID verifiedAt?: number, // Verification timestamp settledAt?: number, // Settlement timestamp metadata: { blockNumber?: number, confirmations?: number, gasUsed?: string, [key: string]: any, }, } ``` ### Event Types Uses existing types: ```typescript // Payment requested { type: 'payment_requested', // Existing type actorId: userId, targetId: null, timestamp: Date.now(), metadata: { protocol: 'x402', resource: '/api/agent/execute', amount: '0.01', networks: ['base', 'ethereum', 'solana'], } } // Payment verified { type: 'payment_verified', // Existing type actorId: userId, targetId: paymentId, timestamp: Date.now(), metadata: { protocol: 'x402', resource: '/api/agent/execute', amount: '0.01', scheme: 'permit', network: 'base', txHash: '0x...', } } // Payment failed { type: 'payment_failed', // Existing type actorId: userId, targetId: null, timestamp: Date.now(), metadata: { protocol: 'x402', resource: '/api/agent/execute', error: 'Insufficient balance', scheme: 'permit', network: 'base', } } ``` --- ## Part 5: Frontend Integration ### PaymentPrompt Component **File:** `src/components/payment/PaymentPrompt.tsx` ```tsx import React, { useState } from "react"; import type { PaymentRequired } from "@/convex/protocols/x402"; import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter, } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Wallet, Check, X } from "lucide-react"; interface PaymentPromptProps { paymentRequired: PaymentRequired; onPaymentComplete: (paymentPayload: any) => void; onCancel: () => void; } export function PaymentPrompt({ paymentRequired, onPaymentComplete, onCancel, }: PaymentPromptProps) { const [selectedNetwork, setSelectedNetwork] = useState( paymentRequired.accepts[0] ); const [processing, setProcessing] = useState(false); const [error, setError] = useState<string | null>(null); const handlePayment = async () => { setProcessing(true); setError(null); try { // Connect wallet (using Web3 provider) const provider = await getWeb3Provider(selectedNetwork.network); // Create payment payload based on scheme let paymentPayload; if (selectedNetwork.scheme === "permit") { paymentPayload = await createPermitPayload(provider, selectedNetwork); } else if (selectedNetwork.scheme === "transfer") { paymentPayload = await createTransferPayload(provider, selectedNetwork); } onPaymentComplete(paymentPayload); } catch (err) { setError(err instanceof Error ? err.message : "Payment failed"); } finally { setProcessing(false); } }; return ( <Card className="w-full max-w-md"> <CardHeader> <CardTitle className="flex items-center gap-2"> <Wallet className="h-5 w-5" /> Payment Required </CardTitle> <CardDescription> This resource requires payment to access </CardDescription> </CardHeader> <CardContent className="space-y-4"> {/* Payment amount */} <div className="rounded-lg border bg-muted p-4"> <div className="text-sm text-muted-foreground">Amount</div> <div className="text-2xl font-bold"> ${selectedNetwork.maxAmountRequired} {selectedNetwork.asset} </div> <div className="text-sm text-muted-foreground"> {selectedNetwork.metadata?.description || selectedNetwork.resource} </div> </div> {/* Network selection */} <div className="space-y-2"> <div className="text-sm font-medium">Select Network</div> <div className="grid gap-2"> {paymentRequired.accepts.map((requirement, i) => ( <button key={i} onClick={() => setSelectedNetwork(requirement)} className={`flex items-center justify-between rounded-lg border p-3 transition-colors ${ selectedNetwork === requirement ? "border-primary bg-primary/10" : "hover:border-primary/50" }`} > <div> <div className="font-medium capitalize"> {requirement.network} </div> <div className="text-xs text-muted-foreground"> {requirement.scheme} </div> </div> {selectedNetwork === requirement && ( <Check className="h-4 w-4 text-primary" /> )} </button> ))} </div> </div> {/* Error display */} {error && ( <Alert variant="destructive"> <X className="h-4 w-4" /> <AlertDescription>{error}</AlertDescription> </Alert> )} </CardContent> <CardFooter className="flex gap-2"> <Button variant="outline" onClick={onCancel} className="flex-1"> Cancel </Button> <Button onClick={handlePayment} disabled={processing} className="flex-1" > {processing ? "Processing..." : `Pay $${selectedNetwork.maxAmountRequired}`} </Button> </CardFooter> </Card> ); } // Helper functions (implement with Web3 libraries) async function getWeb3Provider(network: string) { // Implementation depends on wallet provider (MetaMask, WalletConnect, etc.) return {} as any; } async function createPermitPayload(provider: any, requirement: any) { // Create ERC-2612 permit signature return {} as any; } async function createTransferPayload(provider: any, requirement: any) { // Create direct transfer transaction return {} as any; } ``` --- ## Part 6: Use Cases ### 1. AI Agent Pay-Per-Request ```typescript // Protected AI agent endpoint // File: src/pages/api/agent/intelligence/analyze.ts export const POST: APIRoute = async ({ request, locals }) => { // Require $0.01 payment per analysis const paymentCheck = await x402Middleware( request, "/api/agent/intelligence/analyze", "0.01", locals.user?.id ); if (paymentCheck) return paymentCheck; // Execute analysis (payment verified) const { userId, metrics } = await request.json(); const result = await intelligenceAgent.analyzeMetrics({ userId, metrics }); return new Response(JSON.stringify(result), { status: 200 }); }; ``` ### 2. External Agent Integration (ElizaOS) ```typescript // Charge for ElizaOS agent collaboration // File: src/pages/api/eliza/send-message.ts export const POST: APIRoute = async ({ request, locals }) => { // Require $0.005 per message to ElizaOS agent const paymentCheck = await x402Middleware( request, "/api/eliza/send-message", "0.005", locals.user?.id ); if (paymentCheck) return paymentCheck; // Send message (payment verified) const { agentId, message } = await request.json(); const result = await elizaOSService.sendMessage({ agentId, message }); return new Response(JSON.stringify(result), { status: 200 }); }; ``` ### 3. N8N Workflow Execution ```typescript // Charge for workflow execution // File: src/pages/api/workflow/execute.ts export const POST: APIRoute = async ({ request, locals }) => { const { workflowId } = await request.json(); // Get workflow pricing const workflow = await getWorkflow(workflowId); const price = workflow.properties.price || "0.10"; const paymentCheck = await x402Middleware( request, `/api/workflow/execute?id=${workflowId}`, price, locals.user?.id ); if (paymentCheck) return paymentCheck; // Execute workflow (payment verified) const result = await n8nService.executeWorkflow({ workflowId }); return new Response(JSON.stringify(result), { status: 200 }); }; ``` ### 4. Cloud Storage Access ```typescript // Pay-per-GB storage // File: src/pages/api/storage/upload.ts export const POST: APIRoute = async ({ request, locals }) => { const contentLength = request.headers.get("content-length"); const sizeGB = parseInt(contentLength || "0") / 1_000_000_000; const price = (sizeGB * 0.05).toFixed(3); // $0.05 per GB const paymentCheck = await x402Middleware( request, "/api/storage/upload", price, locals.user?.id ); if (paymentCheck) return paymentCheck; // Upload file (payment verified) const result = await storageService.upload(request.body); return new Response(JSON.stringify(result), { status: 200 }); }; ``` --- ## Benefits ### 1. Instant Micropayments - Payments settle in ~2 seconds on blockchain - No waiting for traditional payment processors - Enables pay-per-use business models ### 2. Zero Fees - No processing fees for merchants - No transaction fees for customers (except gas) - Better economics than Stripe, PayPal, etc. ### 3. Global Access - No geographic restrictions - No account verification needed - Crypto wallets work worldwide ### 4. Privacy-Preserving - No personal information required - Blockchain addresses only - GDPR-compliant by design ### 5. Agent-to-Agent Payments - AI agents can autonomously pay for services - Machine-to-machine transactions - Programmable payment logic --- ## Summary **X402 Protocol Integration:** - HTTP-native payment protocol (402 status code) - Effect.ts services (X402PaymentService) - Astro API middleware (x402Middleware) - Multi-chain support (Base, Ethereum, Solana) - Frontend payment UI (PaymentPrompt component) - Complete type safety (TypeScript protocols) **Use Cases:** - AI agent API monetization - External agent integration billing - N8N workflow pay-per-execution - Cloud storage pay-per-GB - Content creator micropayments **Non-Breaking:** - Uses existing `payment` entity type - Uses existing event types - No schema changes needed - Append-only integration 🎉 **Result:** Instant, frictionless digital payments for the ONE platform with zero fees and global access.