Skip to content

Commit 04ae17f

Browse files
add x402-payments SKILL
Adds SKILL for x402 Payments
2 parents c2194c0 + cc3c791 commit 04ae17f

4 files changed

Lines changed: 353 additions & 0 deletions

File tree

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
name: x402-payments
3+
description: Build x402 payment flows using MetaMask Smart Accounts Kit, machine to machine payments over HTTP with ERC-7710 delegations and ERC-7715 Advanced Permissions
4+
---
5+
6+
# x402 Payments
7+
8+
x402 is an open payment protocol that uses the HTTP 402 status code to enable programmatic, machine-to-machine payments over HTTP. It lets servers charge for API access without requiring traditional payment infrastructure, buyer accounts, or API keys.
9+
10+
## When to use
11+
12+
- You want to charge for API access using onchain payments.
13+
- You want to build AI agents that pay per request for API resources.
14+
- You want to enable micro payments for premium data or services.
15+
- You want to set up recurring payments with periodic budgets.
16+
- You want to use MetaMask smart account delegations for x402 settlement.
17+
18+
## Installation
19+
20+
```bash
21+
npm install @x402/core @x402/fetch @metamask/x402 @metamask/smart-accounts-kit
22+
```
23+
24+
For seller endpoints:
25+
26+
```bash
27+
npm install @x402/core @x402/express @metamask/x402
28+
```
29+
30+
## How x402 works
31+
32+
1. The buyer sends a request to a protected endpoint.
33+
2. The server responds with HTTP 402 and a `PAYMENT-REQUIRED` header containing payment terms.
34+
3. The buyer creates a payment payload (delegation or permission) matching the terms.
35+
4. The buyer resends the request with the payment in the `PAYMENT-SIGNATURE` header.
36+
5. The server validates the payment through a facilitator and returns the resource.
37+
38+
## x402 ERC-7710 payments
39+
40+
The standard x402 protocol supports direct token transfers (using ERC-20 Permit2 or EIP-3009). ERC-7710 extends this by enabling delegation-based payments from MetaMask smart accounts.
41+
42+
With ERC-7710, a buyer's smart account creates a delegation that authorizes the facilitator to transfer tokens on their behalf. The buyer doesn't sign a direct token approval. Instead, they sign a delegation that the facilitator redeems during settlement.
43+
44+
This approach enables buyers to pay from MetaMask wallet. Buyers can restrict delegations to specific facilitator addresses, amounts, and time windows using delegation scopes. They can also create long-lived delegations that allow recurring payments without re-signing for each request.
45+
46+
## Workflows
47+
48+
| Workflow | Use case |
49+
|----------|----------|
50+
| [Seller endpoint setup](./workflows/seller-endpoint-setup.md) | You want to protect API endpoints with x402 payment requirements. |
51+
| [Delegation payments](./workflows/delegation-payments.md) | You control the buyer smart account and want to automate payments programmatically. |
52+
| [Advanced Permissions (recurring)](./workflows/recurring-payments.md) | You want to request a periodic budget from a MetaMask user for ongoing API access. Best for subscriptions and recurring usage. |
53+
54+
If the user hasn't specified which payment method they need, present the options.
55+
56+
## Supported networks
57+
58+
| Network | Chain ID | Facilitator URL |
59+
|---------|----------|-----------------|
60+
| Base | eip155:8453 | `https://tx-sentinel-base-mainnet.dev-api.cx.metamask.io/platform/v2/x402` |
61+
| Base Sepolia | eip155:84532 | `https://tx-sentinel-base-sepolia.dev-api.cx.metamask.io/platform/v2/x402` |
62+
| Monad | eip155:143 | `https://tx-sentinel-monad-mainnet.dev-api.cx.metamask.io/platform/v2/x402` |
63+
64+
## Resources
65+
66+
- x402 protocol: https://www.x402.org/
67+
- Smart Accounts Kit docs: https://docs.metamask.io/smart-accounts-kit
68+
- [x402 overview](https://docs.metamask.io/smart-accounts-kit/guides/x402/overview.md)
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
---
2+
name: Delegation payments
3+
description: Pay for x402-protected APIs using ERC-7710 delegations from a smart account
4+
---
5+
6+
# Delegation payments
7+
8+
Use this workflow when you control the buyer smart account and want to automate payments programmatically. Best for AI agents and backend services.
9+
10+
## Install dependencies
11+
12+
```bash
13+
npm install @x402/core @x402/fetch @metamask/x402 @metamask/smart-accounts-kit
14+
```
15+
16+
## Create the buyer smart account
17+
18+
Create a public client for your target network, then create a MetaMask smart account. Ensure the smart account is funded with the required token (typically USDC):
19+
20+
```typescript
21+
import { createPublicClient, http } from 'viem'
22+
import { baseSepolia } from 'viem/chains'
23+
import { Implementation, toMetaMaskSmartAccount } from '@metamask/smart-accounts-kit'
24+
import { privateKeyToAccount } from 'viem/accounts'
25+
26+
const chain = baseSepolia
27+
const publicClient = createPublicClient({ chain, transport: http() })
28+
29+
const account = privateKeyToAccount('<BUYER_PRIVATE_KEY>')
30+
31+
const buyerSmartAccount = await toMetaMaskSmartAccount({
32+
client: publicClient,
33+
implementation: Implementation.Hybrid,
34+
deployParams: [account.address, [], [], []],
35+
deploySalt: '0x',
36+
signer: { account },
37+
})
38+
```
39+
40+
## Create the x402 delegation provider
41+
42+
Use `createx402DelegationProvider` to create an ERC-7710 client that automatically creates, signs, and encodes open root delegations with the required caveats:
43+
44+
```typescript
45+
import { createx402DelegationProvider } from '@metamask/smart-accounts-kit/experimental'
46+
import { x402Erc7710Client } from '@metamask/x402'
47+
48+
const erc7710Client = new x402Erc7710Client({
49+
delegationProvider: createx402DelegationProvider({
50+
account: buyerSmartAccount,
51+
}),
52+
})
53+
```
54+
55+
For API reference, see [`createx402DelegationProvider`](https://docs.metamask.io/smart-accounts-kit/reference/x402.md).
56+
57+
## Register the client and wrap fetch
58+
59+
Register the ERC-7710 client for all EVM networks, then create an HTTP client and wrap `fetch` with automatic payment handling:
60+
61+
```typescript
62+
import { x402Client, x402HTTPClient } from '@x402/core/client'
63+
import { wrapFetchWithPayment } from '@x402/fetch'
64+
65+
const coreClient = new x402Client().register('eip155:*', erc7710Client)
66+
const httpClient = new x402HTTPClient(coreClient)
67+
const fetchWithPayment = wrapFetchWithPayment(fetch, httpClient)
68+
```
69+
70+
## Make paid requests
71+
72+
Call protected endpoints using the wrapped fetch. It automatically handles 402 responses, creates the delegation payment, and retries the request:
73+
74+
```typescript
75+
const response = await fetchWithPayment('https://api.example.com/paid-endpoint')
76+
const data = await response.json()
77+
```
78+
79+
For more details, see the [delegation payments guide](https://docs.metamask.io/smart-accounts-kit/development/guides/x402/buyer/delegations.md).
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
---
2+
name: Recurring payments
3+
description: Set up recurring x402 payments using ERC-7715 Advanced Permissions with periodic budgets
4+
---
5+
6+
# Recurring payments
7+
8+
Use this workflow when you want to request a periodic budget from a MetaMask user for ongoing API access. The permission resets each period, enabling subscription-style payment flows.
9+
10+
## Install dependencies
11+
12+
```bash
13+
npm install @x402/core @x402/fetch @metamask/x402 @metamask/smart-accounts-kit
14+
```
15+
16+
## Set up the wallet client
17+
18+
Create a viem wallet client connected to MetaMask and extend it with ERC-7715 actions. This enables the `requestExecutionPermissions` method needed to request periodic spending budgets from the user:
19+
20+
```typescript
21+
import { createWalletClient, custom } from 'viem'
22+
import { baseSepolia } from 'viem/chains'
23+
import { erc7715ProviderActions } from '@metamask/smart-accounts-kit/actions'
24+
25+
const chain = baseSepolia
26+
27+
const walletClient = createWalletClient({
28+
chain,
29+
transport: custom(window.ethereum),
30+
}).extend(erc7715ProviderActions())
31+
```
32+
33+
## Create a session account
34+
35+
Generate a session key that will act on behalf of the user within the granted permission. This account signs x402 payment delegations without requiring the user's approval for each individual payment:
36+
37+
```typescript
38+
import { privateKeyToAccount } from 'viem/accounts'
39+
40+
const sessionAccount = privateKeyToAccount('<SESSION_PRIVATE_KEY>')
41+
```
42+
43+
## Request periodic permissions
44+
45+
Request a periodic ERC-20 permission that resets each period. This example requests 10 USDC per week for 30 days:
46+
47+
```typescript
48+
import { parseUnits } from 'viem'
49+
50+
const currentTime = Math.floor(Date.now() / 1000)
51+
52+
const grantedPermissions = await walletClient.requestExecutionPermissions([
53+
{
54+
chainId: chain.id,
55+
expiry: currentTime + 30 * 86400,
56+
to: sessionAccount.address,
57+
permission: {
58+
type: 'erc20-token-periodic',
59+
data: {
60+
tokenAddress: '<TOKEN_ADDRESS>',
61+
periodAmount: parseUnits('10', 6),
62+
periodDuration: 604800,
63+
justification: 'Weekly budget for API access',
64+
},
65+
isAdjustmentAllowed: true,
66+
},
67+
},
68+
])
69+
```
70+
71+
## Create the x402 delegation provider
72+
73+
Use `createx402DelegationProvider` with the granted permission context. This sets up open redelegation so facilitators can redeem payments within the granted budget:
74+
75+
```typescript
76+
import { createx402DelegationProvider } from '@metamask/smart-accounts-kit/experimental'
77+
import { x402Erc7710Client } from '@metamask/x402'
78+
79+
const permission = grantedPermissions[0]
80+
81+
const erc7710Client = new x402Erc7710Client({
82+
delegationProvider: createx402DelegationProvider({
83+
account: sessionAccount,
84+
parentPermissionContext: permission.context,
85+
from: permission.from,
86+
}),
87+
})
88+
```
89+
90+
For API reference, see [`createx402DelegationProvider`](https://docs.metamask.io/smart-accounts-kit/reference/x402.md).
91+
92+
## Register and wrap fetch
93+
94+
Register the ERC-7710 client for all EVM networks, then create an HTTP client and wrap `fetch` with automatic payment handling. When a server responds with HTTP 402, the wrapped fetch creates a payment within the granted budget and retries the request:
95+
96+
```typescript
97+
import { x402Client, x402HTTPClient } from '@x402/core/client'
98+
import { wrapFetchWithPayment } from '@x402/fetch'
99+
100+
const coreClient = new x402Client().register('eip155:*', erc7710Client)
101+
const httpClient = new x402HTTPClient(coreClient)
102+
const fetchWithPayment = wrapFetchWithPayment(fetch, httpClient)
103+
```
104+
105+
## Make recurring paid requests
106+
107+
Each call automatically handles x402 payment within the granted periodic budget:
108+
109+
```typescript
110+
const response = await fetchWithPayment('https://api.example.com/paid-endpoint')
111+
const data = await response.json()
112+
```
113+
114+
The periodic budget resets at the start of each new period. The user doesn't need to approve each individual payment.
115+
116+
For more details, see the [recurring payments guide](https://docs.metamask.io/smart-accounts-kit/development/guides/x402/buyer/recurring-payments.md).
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
name: Seller endpoint setup
3+
description: Set up an Express server with x402 payment middleware for ERC-7710 payments
4+
---
5+
6+
# Seller endpoint setup
7+
8+
## Install dependencies
9+
10+
```bash
11+
npm install @metamask/x402 @x402/core @x402/express cors express
12+
```
13+
14+
## Create the Express server
15+
16+
Set up an Express app with CORS configured to expose the x402 payment headers:
17+
18+
```typescript
19+
import express from 'express'
20+
import cors from 'cors'
21+
22+
const app = express()
23+
24+
app.use(cors({
25+
exposedHeaders: ['PAYMENT-REQUIRED', 'PAYMENT-RESPONSE'],
26+
}))
27+
```
28+
29+
## Configure the facilitator client and resource server
30+
31+
Initialize an `HTTPFacilitatorClient` pointing to the MetaMask facilitator for your network, then create an `x402ResourceServer` and register the ERC-7710 server scheme so the middleware can parse and validate delegation-based payment payloads:
32+
33+
```typescript
34+
import { HTTPFacilitatorClient } from '@x402/core/server'
35+
import { paymentMiddleware, x402ResourceServer } from '@x402/express'
36+
import { x402ExactEvmErc7710ServerScheme } from '@metamask/x402'
37+
38+
const facilitatorClient = new HTTPFacilitatorClient({
39+
url: '<FACILITATOR_URL>',
40+
})
41+
42+
const resourceServer = new x402ResourceServer(facilitatorClient).register(
43+
'eip155:84532',
44+
new x402ExactEvmErc7710ServerScheme(),
45+
)
46+
```
47+
48+
MetaMask facilitator URLs by network:
49+
- Base Sepolia: `https://tx-sentinel-base-sepolia.dev-api.cx.metamask.io/platform/v2/x402`
50+
- Base: `https://tx-sentinel-base-mainnet.dev-api.cx.metamask.io/platform/v2/x402`
51+
- Monad: `https://tx-sentinel-monad-mainnet.dev-api.cx.metamask.io/platform/v2/x402`
52+
53+
## Add payment middleware to protected routes
54+
55+
Define the payment requirements for each route and apply the middleware with the resource server:
56+
57+
```typescript
58+
app.use(
59+
paymentMiddleware(
60+
{
61+
'GET /api/hello': {
62+
accepts: [{
63+
scheme: 'exact',
64+
price: '$0.01',
65+
network: 'eip155:84532',
66+
payTo: '<SELLER_ADDRESS>',
67+
extra: { assetTransferMethod: 'erc7710' },
68+
}],
69+
description: 'A paid hello endpoint',
70+
mimeType: 'application/json',
71+
},
72+
},
73+
resourceServer,
74+
),
75+
)
76+
```
77+
78+
## Add the protected route handler
79+
80+
Define the route handler as usual. The payment middleware runs before your handler — by the time your handler executes, the payment has already been verified and settled through the facilitator:
81+
82+
```typescript
83+
app.get('/api/hello', (req, res) => {
84+
res.json({ message: 'Hello, paid user!' })
85+
})
86+
87+
app.listen(3000)
88+
```
89+
90+
For more details, see the [seller endpoint guide](https://docs.metamask.io/smart-accounts-kit/development/guides/x402/seller.md).

0 commit comments

Comments
 (0)