🔗 x402 Pay-Per-Use File Upload
Introduction
x402 is a payment protocol that enables pay-per-use APIs, allowing developers to charge users for each API request using on-chain payments. This tutorial demonstrates how to upload files to IPFS via Lighthouse using the x402 payment system, where you pay only for what you use instead of maintaining a subscription or API key balance.
Traditional file upload APIs typically require users to maintain API key balances or subscriptions, which can be cumbersome for occasional users or applications with variable usage patterns. The x402 protocol eliminates these barriers by enabling micro-payments for each upload, making it ideal for pay-as-you-go scenarios.
Why Use x402 for File Uploads?
The x402 payment protocol offers several advantages over traditional API key-based systems:
- Pay-as-you-go: Only pay for actual file uploads, no subscription fees
- No balance management: No need to pre-fund API key balances
- Transparent pricing: Dynamic pricing based on file size
- Blockchain-native: Uses USDC on Base mainnet
- Automatic payment handling: The
x402-fetchlibrary handles the entire payment flow
How it works
You x402 Client Server
│ │ │
│ npm run upload -- file.png │ │
│ ─────────────────────────────►│ │
│ │ POST /api/upload + file │
│ │ ────────────────────────────►│
│ │ ◄──────── 402 (price + payTo)│
│ │ │
│ │ pay USDC on Base (auto) │
│ │ │
│ │ POST /api/upload + payment │
│ │ ────────────────────────────►│
│ │ ◄──────── 200 { cid, ipfsUrl}│
│ │ │
│ ◄── CID: QmXoypiz… │ │
The x402 client library handles the entire payment flow automatically. You just run the upload command — it sends the file, receives the price, pays USDC on-chain, and retries with payment proof.
Upload File Function
You can import the same pattern in your own Node.js / TypeScript project:
import { x402Client, wrapFetchWithPayment } from "@x402/fetch";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
import { statSync, openAsBlob } from "fs";
// Setup
const signer = privateKeyToAccount("0xYourPrivateKey");
const client = new x402Client();
registerExactEvmScheme(client, { signer });
const fetchWithPayment = wrapFetchWithPayment(fetch, client);
// Upload — openAsBlob streams from disk, no memory buffering
const filePath = "./myfile.pdf";
const fileBlob = await openAsBlob(filePath);
const fileSize = statSync(filePath).size;
const response = await fetchWithPayment("http://localhost:12000/api/upload", {
method: "POST",
headers: {
"Content-Type": "application/octet-stream",
"Content-Length": String(fileSize),
"x-file-name": "myfile.pdf",
},
body: fileBlob,
});
const { cid, ipfsUrl } = await response.json();
console.log("Uploaded:", ipfsUrl);
Refer: lighthouse_x402_client
Pricing
The x402 API uses dynamic pricing based on file size:
- Price: 0.004$ per mb
- Payment: USDC on Base mainnet