Use NodeJS when you want to protect paid routes, call paid APIs, or support both sides of the 4Mica x402 flow from the same app.
Start with Base Sepolia (eip155:84532) and a small price. Once the route returns a paid response end to end, move shared values such as PRIVATE_KEY, PAY_TO, and NETWORK into environment variables.
Prerequisites
Before you build, you need:
- Node.js 18 or later.
- A package manager such as
pnpm, npm, yarn, or bun.
- A dedicated EVM wallet for your app or agent.
- Testnet gas for the network you want to use.
- Collateral deposited into 4Mica before the wallet signs paid requests.
Use a test wallet while you develop. Do not commit private keys.
PRIVATE_KEY=0xYourPrivateKey
PAY_TO=0xYourSellerAddress
NETWORK=eip155:84532
Use the private key only for buyer-side signing. Use PAY_TO as the seller
address advertised by protected routes. Never commit the private key.
Install
Install the 4Mica server package when you protect routes. Install the x402 client wrappers when your app needs to pay protected routes.
npm install @4mica/x402 @x402/fetch @x402/axios viem
Create wallet
Create a dedicated EVM wallet for the buyer, seller, or agent. For wallet setup, see Wallet.
For local development, convert the private key into a viem account:
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
Use a separate service wallet in production. Keep your main wallet away from automated signing flows.
Deposit collateral
Deposit collateral before the buyer signs 4Mica payment guarantees. Collateral backs each guarantee and covers unpaid net positions according to protocol rules.
To learn more about collateral setup, see Deposits and Withdrawals.
Protect a route
For seller-side protection, use paymentMiddlewareFromConfig from @4mica/x402/server/express. The middleware returns HTTP 402 responses, verifies retried payment headers, settles the guarantee, and serves the protected route after payment succeeds.
import express from "express";
import { paymentMiddlewareFromConfig } from "@4mica/x402/server/express";
const app = express();
app.use(express.json());
app.use(
paymentMiddlewareFromConfig({
"GET /premium-content": {
accepts: {
scheme: "4mica-credit",
price: "$0.10",
network: "eip155:84532",
payTo: "0xYourAddress",
},
description: "Access to premium content",
},
}),
);
app.get("/premium-content", (req, res) => {
res.json({ message: "This is premium content behind a paywall" });
});
app.listen(3030, () => {
console.log("Server running on http://localhost:3030");
});
Support payment
Use @x402/fetch or @x402/axios to wrap your HTTP client with automatic 402 handling. The wrappers create unique request IDs, sign payment guarantees using FourMicaEvmScheme, and retry requests without any additional code.
If you are already using Coinbase x402 clients, keep the same wrapper and swap in FourMicaEvmScheme instead of the exact scheme.
Using wrapFetchWithPaymentFromConfig
The convenience config wrapper is the quickest way to get started. Pass your scheme registrations and the wrapper handles everything else.
import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
import { FourMicaEvmScheme } from "@4mica/x402/client";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount("0xYourPrivateKey");
// This scheme client handles the 4Mica x402 flow for fetch:
// 1. request the protected resource
// 2. receive a 402 with payment requirements
// 3. create a unique request ID
// 4. sign the payment and retry the request
const scheme = await FourMicaEvmScheme.create(account);
const fetchWithPayment = wrapFetchWithPaymentFromConfig(fetch, {
schemes: [
{
network: "eip155:84532", // Base Sepolia
client: scheme,
},
],
});
const response = await fetchWithPayment("http://localhost:3000/premium-content");
const data = await response.json();
console.log(data);
Using wrapAxiosWithPaymentFromConfig
Wrap an existing Axios instance and use it exactly as before.
import axios from "axios";
import { wrapAxiosWithPaymentFromConfig } from "@x402/axios";
import { FourMicaEvmScheme } from "@4mica/x402/client";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount("0xYourPrivateKey");
const scheme = await FourMicaEvmScheme.create(account);
const api = wrapAxiosWithPaymentFromConfig(axios.create(), {
schemes: [
{
network: "eip155:84532", // Base Sepolia
client: scheme,
},
],
});
const response = await api.get("http://localhost:3000/premium-content");
console.log(response.data);
Multi-Network setup
Register multiple networks to route payments to the right scheme based on what the server advertises in its 402 response.
import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
import { FourMicaEvmScheme } from "@4mica/x402/client";
import { privateKeyToAccount } from "viem/accounts";
const ethSepoliaScheme = await FourMicaEvmScheme.create(
privateKeyToAccount("0xEthSepoliaPrivateKey"),
);
const baseSepoliaScheme = await FourMicaEvmScheme.create(
privateKeyToAccount("0xBaseSepoliaPrivateKey"),
);
const fetchWithPayment = wrapFetchWithPaymentFromConfig(fetch, {
schemes: [
{ network: "eip155:11155111", client: ethSepoliaScheme },
{ network: "eip155:84532", client: baseSepoliaScheme },
],
});
Builder pattern
Build a reusable x402Client registry when you need to share the client across multiple wrappers or want explicit control over scheme registration.
import { wrapFetchWithPayment, x402Client } from "@x402/fetch";
import { FourMicaEvmScheme } from "@4mica/x402/client";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount("0xYourPrivateKey");
const scheme = await FourMicaEvmScheme.create(account);
const client = new x402Client().register("eip155:84532", scheme);
const fetchWithPayment = wrapFetchWithPayment(fetch, client);