Skip to main content

Create an x402 server with ERC-7710

In this guide, you build a Node.js server that charges for HTTP API access using x402 and accepts ERC-7710 delegation payments verified through the MetaMask facilitator.

You use the official @x402/express middleware with the @metamask/x402 package, which provides an ERC-7710 server scheme that routes verification and settlement through the MetaMask facilitator.

Prerequisites

Facilitator URLs

The following table lists the available MetaMask facilitator endpoints:

NameIDURL
Baseeip155:8453https://tx-sentinel-base-mainnet.api.cx.metamask.io/platform/v2/x402
Base Sepoliaeip155:84532https://tx-sentinel-base-sepolia.api.cx.metamask.io/platform/v2/x402
Monadeip155:143https://tx-sentinel-monad-mainnet.api.cx.metamask.io/platform/v2/x402

Steps

1. Install the dependencies

npm install @metamask/x402 @x402/core @x402/evm @x402/express cors express

2. Configure middleware

Set up the Express server with the x402 paymentMiddleware and the x402ExactEvmErc7710ServerScheme from @metamask/x402. The scheme automatically adds payment requirements with ERC-7710 fields when assetTransferMethod is set to erc7710 in the route configuration.

The paymentMiddleware intercepts requests to protected routes and handles the full x402 payment flow, including requirements advertisement, verification, and settlement.

In this example, you create a protected GET /api/hello endpoint that charges 0.01 USDC on Base Sepolia. Replace the payout address in src/config.ts with your own seller wallet address.

import express, { type Request, type Response } from 'express'
import cors from 'cors'
import { paymentMiddleware, x402ResourceServer } from '@x402/express'
import { x402ExactEvmErc7710ServerScheme } from '@metamask/x402'
import { NETWORK_ID, PORT, payToAddress, facilitatorClient } from './config.js'

const app = express()
app.use(cors({ exposedHeaders: ['PAYMENT-REQUIRED', 'PAYMENT-RESPONSE'] }))

app.use(
paymentMiddleware(
{
'GET /api/hello': {
accepts: [
{
scheme: 'exact',
price: '$0.01',
network: NETWORK_ID,
payTo: payToAddress,
extra: {
assetTransferMethod: 'erc7710',
},
},
],
description: 'Access to protected resource',
mimeType: 'application/json',
},
},
new x402ResourceServer(facilitatorClient).register(
NETWORK_ID,
new x402ExactEvmErc7710ServerScheme()
)
)
)

app.get('/api/hello', (_req: Request, res: Response) => {
res.json({ message: 'Hello!' })
})

app.listen(PORT, () => {
console.log(`[seller] Server running on http://localhost:${PORT}`)
})

Next steps