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 a custom ERC-7710 scheme that routes verification and settlement through the MetaMask facilitator.

Prerequisites

Steps

1. Install the dependencies

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

2. Create the ERC-7710 scheme

Create a custom scheme that extends ExactEvmScheme from @x402/evm to add ERC-7710 delegation support.

The scheme overrides enhancePaymentRequirements to set assetTransferMethod to erc7710 and include the facilitator addresses so buyers can scope their delegation to specific set of facilitators before creating the payment payload.

import { ExactEvmScheme } from '@x402/evm/exact/server'
import type {
PaymentRequirements,
Network,
Price,
AssetAmount,
SupportedKind,
SchemeNetworkServer,
} from '@x402/core/types'
import type { FacilitatorClient } from '@x402/core/server'

export class Erc7710EvmScheme implements SchemeNetworkServer {
readonly scheme = 'exact'
private readonly inner = new ExactEvmScheme()

constructor(private readonly facilitatorClient: FacilitatorClient) {}

async parsePrice(price: Price, network: Network): Promise<AssetAmount> {
return this.inner.parsePrice(price, network)
}

getAssetDecimals(asset: string, network: Network): number {
return this.inner.getAssetDecimals?.(asset, network) ?? 6
}

async enhancePaymentRequirements(
paymentRequirements: PaymentRequirements,
supportedKind: SupportedKind,
facilitatorExtensions: string[]
): Promise<PaymentRequirements> {
const enhanced = await this.inner.enhancePaymentRequirements(
paymentRequirements,
supportedKind,
facilitatorExtensions
)

const supported = await this.facilitatorClient.getSupported()
const facilitators =
supported.signers[paymentRequirements.network] ?? supported.signers['eip155:*'] ?? []

return {
...enhanced,
extra: {
...enhanced.extra,
assetTransferMethod: 'erc7710',
facilitators,
},
}
}
}

3. Configure the server

Set up the Express server with the x402 paymentMiddleware and the custom ERC-7710 scheme. 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 mainnet. 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 } from '@x402/express'
import { x402ResourceServer } from '@x402/core/server'
import { Erc7710EvmScheme } from './scheme.js'
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,
},
],
description: 'Access to protected resource',
mimeType: 'application/json',
},
},
new x402ResourceServer(facilitatorClient).register(
NETWORK_ID,
new Erc7710EvmScheme(facilitatorClient)
)
)
)

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