soulink402
v0.2.0
Published
One-call x402 Express middleware — turn any route into a paid API
Maintainers
Readme
soulink402
One-call x402 Express middleware. Turn any route into a paid API.
Install
npm install soulink402Quick Start
import express from 'express'
import { x402 } from 'soulink402'
const app = express()
app.use(await x402({
payTo: '0xYourWalletAddress',
network: 'base',
routes: {
'POST /api/register': {
price: '1',
description: 'Register an agent',
},
'GET /api/premium': {
price: '0.5',
description: 'Premium content',
},
},
}))API
x402(config): Promise<ExpressMiddleware>
Creates Express middleware that enforces x402 payments on matched routes.
| Field | Type | Description |
|-------|------|-------------|
| payTo | string | Wallet address to receive payments |
| network | 'base' \| 'base-sepolia' \| NetworkId | Target blockchain network |
| routes | Record<string, SimpleRouteConfig> | Route pattern to payment config map |
SimpleRouteConfig
| Field | Type | Description |
|-------|------|-------------|
| price | string \| (ctx) => string | USDC price (static or dynamic) |
| description | string | Human-readable route description |
buildRoutes(config): RoutesConfig
Transforms X402Config into the low-level RoutesConfig format used by @x402/express. Useful if you need the route config without the middleware.
resolveNetwork(name): NetworkId
Resolves a friendly network name to a CAIP-2 identifier.
Networks
| Name | CAIP-2 ID |
|------|-----------|
| base | eip155:8453 |
| base-sepolia | eip155:84532 |
Raw CAIP-2 strings (e.g. eip155:1) pass through unchanged.
Dynamic Pricing
Price can be a function that receives the HTTP request context:
app.use(await x402({
payTo: '0x...',
network: 'base',
routes: {
'POST /api/register': {
price: (context) => {
const body = context.adapter.getBody?.() as { tier?: string }
return body?.tier === 'premium' ? '10' : '1'
},
description: 'Register with tiered pricing',
},
},
}))What it replaces
Before (25 lines of ceremony):
import { paymentMiddlewareFromHTTPServer, x402HTTPResourceServer, x402ResourceServer } from '@x402/express'
import { HTTPFacilitatorClient } from '@x402/core/http'
import { ExactEvmScheme } from '@x402/evm/exact/server'
import { facilitator } from '@coinbase/x402'
const client = new HTTPFacilitatorClient(facilitator)
const routes = { 'POST /api/register': { accepts: { scheme: 'exact', network: 'eip155:8453', payTo: '0x...', price: '1' }, description: '...' } }
const server = new x402ResourceServer(client).register('eip155:8453', new ExactEvmScheme())
const http = new x402HTTPResourceServer(server, routes)
app.use(paymentMiddlewareFromHTTPServer(http))After (6 lines):
import { x402 } from 'soulink402'
app.use(await x402({
payTo: '0x...',
network: 'base',
routes: { 'POST /api/register': { price: '1', description: '...' } },
}))License
MIT
