Pay for an x402 API with delegation
In this guide, you use a buyer account to access API data from an x402 server by creating a delegationDelegation The ability for a MetaMask smart account to authorize another account to perform specific executions on its behalf. that authorizes token transfers on your behalf.
You use createx402DelegationProvider
to set up an x402Erc7710Client with a delegation provider, register it with the x402 client,
and use wrapFetchWithPayment to automatically handle payment when calling a protected API route.
Prerequisites
Steps
1. Install the dependencies
- npm
- Yarn
- pnpm
- Bun
npm install @x402/core @x402/fetch @metamask/x402
yarn add @x402/core @x402/fetch @metamask/x402
pnpm add @x402/core @x402/fetch @metamask/x402
bun add @x402/core @x402/fetch @metamask/x402
2. Create a buyer account
Create an account to represent the buyer, the delegatorDelegator account The account that creates and signs a delegation to grant limited authority to another account. who creates a delegation.
The delegator must be a MetaMask smart accountMetaMask smart account A smart contract account created using the Smart Accounts Kit that supports programmable behavior, flexible signing options, and ERC-7710 delegations..
Use the toolkit's
toMetaMaskSmartAccount method to
create the buyer account.
Fund the smart account with USDC for the requested payment.
- example.ts
- config.ts
import { Implementation, toMetaMaskSmartAccount } from '@metamask/smart-accounts-kit'
import { publicClient, buyerAccount } from './config'
export const buyerSmartAccount = await toMetaMaskSmartAccount({
client: publicClient,
implementation: Implementation.Hybrid,
deployParams: [buyerAccount.address, [], [], []],
deploySalt: '0x',
signer: { account: buyerAccount },
})
import { createPublicClient, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { base as chain } from 'viem/chains'
export const publicClient = createPublicClient({
chain,
transport: http(),
})
export const buyerAccount = privateKeyToAccount('0x<BUYER_PRIVATE_KEY>')
3. Create an x402 ERC-7710 client
Create an x402Erc7710Client using
createx402DelegationProvider.
The provider creates an openOpen delegation A delegation that leaves the delegate unspecified, allowing any account to redeem it.
root delegationRoot delegation The first delegation in a chain, where an account delegates its own authority directly., signs it, and returns an ABI-encoded delegation chain
when the x402 client needs to pay for a request.
The provider appends redeemer,
allowedTargets, and
timestamp
caveatsCaveat A restriction attached to a delegation that limits how delegated authority can be used. if not already present.
import { createx402DelegationProvider } from '@metamask/smart-accounts-kit/experimental'
import { x402Erc7710Client } from '@metamask/x402'
const erc7710Client = new x402Erc7710Client({
delegationProvider: createx402DelegationProvider({
account: buyerSmartAccount,
}),
})
4. Register the client
Register the ERC-7710 client with the x402 core client for all EVM networks.
Create an HTTP client and a payment-aware fetch function using wrapFetchWithPayment.
import { x402Client, x402HTTPClient } from '@x402/core/client'
import { wrapFetchWithPayment } from '@x402/fetch'
const coreClient = new x402Client().register('eip155:*', erc7710Client)
const httpClient = new x402HTTPClient(coreClient)
const fetchWithPayment = wrapFetchWithPayment(fetch, httpClient)
5. Make the paid request
Call the protected endpoint using fetchWithPayment.
It handles the x402 payment flow, calling your delegation provider
to create an open delegationOpen delegation A delegation that leaves the delegate unspecified, allowing any account to redeem it. when the server returns a 402 response.
const paidResponse = await fetchWithPayment('https://api.example.com/paid-endpoint', {
method: 'GET',
})