create-mantle-facilitator 0.3.3 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +373 -0
- package/package.json +1 -1
- package/template/README.md +81 -33
- package/template/.env.example +0 -25
package/README.md
ADDED
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
# create-mantle-facilitator
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/create-mantle-facilitator)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
CLI tool to scaffold a self-hosted x402 payment facilitator for Mantle blockchain.
|
|
7
|
+
|
|
8
|
+
## Quick Start
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npx create-mantle-facilitator my-facilitator
|
|
12
|
+
cd my-facilitator
|
|
13
|
+
npm install
|
|
14
|
+
npm run dev
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The CLI will guide you through the setup:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
Welcome to Mantle Facilitator Setup!
|
|
21
|
+
|
|
22
|
+
? Where should we create the facilitator? my-facilitator
|
|
23
|
+
? RPC URL for Mantle network: https://rpc.mantle.xyz
|
|
24
|
+
? Facilitator wallet private key: (optional, set later)
|
|
25
|
+
? USDC contract address: 0x09Bc4E0D864854c6aFB6eB9A9cdF58aC190D0dF9
|
|
26
|
+
? Enable telemetry? Yes
|
|
27
|
+
? Enter PROJECT_KEY from dashboard: (optional)
|
|
28
|
+
|
|
29
|
+
✓ Done! Your facilitator is ready.
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Configuration
|
|
33
|
+
|
|
34
|
+
After creation, edit the `.env` file:
|
|
35
|
+
|
|
36
|
+
```env
|
|
37
|
+
# Required
|
|
38
|
+
FACILITATOR_PRIVATE_KEY=0x... # Wallet that pays gas fees
|
|
39
|
+
RPC_URL=https://rpc.mantle.xyz # Mantle RPC endpoint
|
|
40
|
+
|
|
41
|
+
# Optional
|
|
42
|
+
USDC_ADDRESS=0x09Bc4E0D864854c6aFB6eB9A9cdF58aC190D0dF9
|
|
43
|
+
PORT=8080
|
|
44
|
+
NETWORK_ID=mantle-mainnet
|
|
45
|
+
CHAIN_ID=5000
|
|
46
|
+
|
|
47
|
+
# Telemetry (optional)
|
|
48
|
+
TELEMETRY_PROJECT_KEY=pk_xxx # Get from dashboard
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Important Notes
|
|
52
|
+
|
|
53
|
+
- **FACILITATOR_PRIVATE_KEY**: This wallet will pay gas fees for all settlements. Make sure it has MNT for gas.
|
|
54
|
+
- **Security**: Never commit `.env` to version control. The generated `.gitignore` already excludes it.
|
|
55
|
+
|
|
56
|
+
## Running Locally
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# Development mode (hot reload)
|
|
60
|
+
npm run dev
|
|
61
|
+
|
|
62
|
+
# Build for production
|
|
63
|
+
npm run build
|
|
64
|
+
|
|
65
|
+
# Run production build
|
|
66
|
+
npm start
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Facilitator runs on `http://localhost:8080` by default.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Deployment
|
|
74
|
+
|
|
75
|
+
### Railway (Recommended)
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Install Railway CLI
|
|
79
|
+
npm install -g @railway/cli
|
|
80
|
+
|
|
81
|
+
# Login and deploy
|
|
82
|
+
railway login
|
|
83
|
+
railway init
|
|
84
|
+
railway up
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Then add environment variables in Railway dashboard.
|
|
88
|
+
|
|
89
|
+
### Render
|
|
90
|
+
|
|
91
|
+
1. Push your facilitator to GitHub
|
|
92
|
+
2. Create new Web Service in Render
|
|
93
|
+
3. Connect your repository
|
|
94
|
+
4. Set build command: `npm install && npm run build`
|
|
95
|
+
5. Set start command: `npm start`
|
|
96
|
+
6. Add environment variables
|
|
97
|
+
|
|
98
|
+
### Fly.io
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# Install Fly CLI and login
|
|
102
|
+
flyctl auth login
|
|
103
|
+
|
|
104
|
+
# Launch (creates fly.toml)
|
|
105
|
+
flyctl launch
|
|
106
|
+
|
|
107
|
+
# Set secrets
|
|
108
|
+
flyctl secrets set FACILITATOR_PRIVATE_KEY=0x...
|
|
109
|
+
flyctl secrets set RPC_URL=https://rpc.mantle.xyz
|
|
110
|
+
flyctl secrets set USDC_ADDRESS=0x09Bc4E0D864854c6aFB6eB9A9cdF58aC190D0dF9
|
|
111
|
+
|
|
112
|
+
# Deploy
|
|
113
|
+
flyctl deploy
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Docker
|
|
117
|
+
|
|
118
|
+
```dockerfile
|
|
119
|
+
FROM node:20-alpine
|
|
120
|
+
WORKDIR /app
|
|
121
|
+
COPY package*.json ./
|
|
122
|
+
RUN npm install
|
|
123
|
+
COPY . .
|
|
124
|
+
RUN npm run build
|
|
125
|
+
EXPOSE 8080
|
|
126
|
+
CMD ["npm", "start"]
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
docker build -t my-facilitator .
|
|
131
|
+
docker run -p 8080:8080 --env-file .env my-facilitator
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### VPS (DigitalOcean, Hetzner, etc.)
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
# On your server
|
|
138
|
+
git clone <your-repo>
|
|
139
|
+
cd my-facilitator
|
|
140
|
+
npm install
|
|
141
|
+
npm run build
|
|
142
|
+
|
|
143
|
+
# Install PM2 for process management
|
|
144
|
+
npm install -g pm2
|
|
145
|
+
|
|
146
|
+
# Start with PM2
|
|
147
|
+
pm2 start dist/index.js --name facilitator
|
|
148
|
+
|
|
149
|
+
# Save process list and setup startup script
|
|
150
|
+
pm2 save
|
|
151
|
+
pm2 startup
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Optional: Add Nginx reverse proxy for HTTPS.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## API Endpoints
|
|
159
|
+
|
|
160
|
+
### GET /health
|
|
161
|
+
|
|
162
|
+
Returns facilitator status and wallet info.
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
curl http://localhost:8080/health
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"status": "ok",
|
|
171
|
+
"network": "mantle-mainnet",
|
|
172
|
+
"chainId": 5000,
|
|
173
|
+
"facilitatorAddress": "0x...",
|
|
174
|
+
"blockNumber": 12345678,
|
|
175
|
+
"mntBalance": "1.5"
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### GET /supported
|
|
180
|
+
|
|
181
|
+
Returns supported networks and assets.
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
curl http://localhost:8080/supported
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
```json
|
|
188
|
+
{
|
|
189
|
+
"x402Version": 1,
|
|
190
|
+
"schemes": ["exact"],
|
|
191
|
+
"networks": ["mantle-mainnet"],
|
|
192
|
+
"assets": {
|
|
193
|
+
"mantle-mainnet": [{
|
|
194
|
+
"address": "0x09Bc4E0D864854c6aFB6eB9A9cdF58aC190D0dF9",
|
|
195
|
+
"symbol": "USDC",
|
|
196
|
+
"decimals": 6
|
|
197
|
+
}]
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### POST /verify
|
|
203
|
+
|
|
204
|
+
Verifies a payment header without executing.
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
curl -X POST http://localhost:8080/verify \
|
|
208
|
+
-H "Content-Type: application/json" \
|
|
209
|
+
-d '{
|
|
210
|
+
"x402Version": 1,
|
|
211
|
+
"paymentHeader": "base64...",
|
|
212
|
+
"paymentRequirements": {...}
|
|
213
|
+
}'
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
```json
|
|
217
|
+
{
|
|
218
|
+
"isValid": true
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### POST /settle
|
|
223
|
+
|
|
224
|
+
Executes the USDC transfer on-chain.
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
curl -X POST http://localhost:8080/settle \
|
|
228
|
+
-H "Content-Type: application/json" \
|
|
229
|
+
-d '{
|
|
230
|
+
"x402Version": 1,
|
|
231
|
+
"paymentHeader": "base64...",
|
|
232
|
+
"paymentRequirements": {...}
|
|
233
|
+
}'
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
```json
|
|
237
|
+
{
|
|
238
|
+
"success": true,
|
|
239
|
+
"txHash": "0x..."
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## How It Works
|
|
246
|
+
|
|
247
|
+
```
|
|
248
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
249
|
+
│ Settlement Flow │
|
|
250
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
251
|
+
│ │
|
|
252
|
+
│ 1. Client signs EIP-712 authorization (gasless for user) │
|
|
253
|
+
│ │ │
|
|
254
|
+
│ ▼ │
|
|
255
|
+
│ 2. Client sends to facilitator POST /settle │
|
|
256
|
+
│ │ │
|
|
257
|
+
│ ▼ │
|
|
258
|
+
│ 3. Facilitator verifies signature │
|
|
259
|
+
│ │ │
|
|
260
|
+
│ ▼ │
|
|
261
|
+
│ 4. Facilitator calls USDC.transferWithAuthorization() │
|
|
262
|
+
│ - Pays gas in MNT │
|
|
263
|
+
│ - USDC transfers from user → merchant │
|
|
264
|
+
│ │ │
|
|
265
|
+
│ ▼ │
|
|
266
|
+
│ 5. Returns txHash to client │
|
|
267
|
+
│ │
|
|
268
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
The facilitator uses EIP-3009 `transferWithAuthorization` which allows:
|
|
272
|
+
- **Gasless for users**: Users only sign, never pay gas
|
|
273
|
+
- **Atomic transfers**: Signature + transfer in one transaction
|
|
274
|
+
- **Replay protection**: Nonces prevent double-spending
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Telemetry
|
|
279
|
+
|
|
280
|
+
When `TELEMETRY_PROJECT_KEY` is set, the facilitator sends anonymous analytics:
|
|
281
|
+
|
|
282
|
+
**What is sent:**
|
|
283
|
+
- Payment metadata (buyer address, amount, asset, network)
|
|
284
|
+
- Transaction hash
|
|
285
|
+
- Timestamp
|
|
286
|
+
- Facilitator address
|
|
287
|
+
|
|
288
|
+
**What is NOT sent:**
|
|
289
|
+
- Private keys
|
|
290
|
+
- Personal information
|
|
291
|
+
- Request/response payloads
|
|
292
|
+
|
|
293
|
+
Get your project key from [Dashboard](https://x402mantlesdk.xyz/dashboard).
|
|
294
|
+
|
|
295
|
+
Telemetry errors never affect payment processing — if analytics backend is down, payments continue normally.
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Security Considerations
|
|
300
|
+
|
|
301
|
+
1. **Private Key Security**
|
|
302
|
+
- Never commit `.env` to git
|
|
303
|
+
- Use secret management in production (Railway secrets, Fly secrets, etc.)
|
|
304
|
+
- Consider using hardware wallets for high-value facilitators
|
|
305
|
+
|
|
306
|
+
2. **Gas Management**
|
|
307
|
+
- Monitor MNT balance regularly
|
|
308
|
+
- Set up alerts for low balance
|
|
309
|
+
- Facilitator needs ~0.001 MNT per settlement
|
|
310
|
+
|
|
311
|
+
3. **Network Security**
|
|
312
|
+
- Use HTTPS in production
|
|
313
|
+
- Consider rate limiting
|
|
314
|
+
- Monitor for unusual patterns
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## Monitoring
|
|
319
|
+
|
|
320
|
+
Check facilitator health:
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
# Check if running
|
|
324
|
+
curl http://your-facilitator.com/health
|
|
325
|
+
|
|
326
|
+
# Check wallet balance
|
|
327
|
+
curl http://your-facilitator.com/health | jq '.mntBalance'
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Set up monitoring alerts for:
|
|
331
|
+
- Health endpoint availability
|
|
332
|
+
- Low MNT balance (< 0.1 MNT)
|
|
333
|
+
- High error rates
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Troubleshooting
|
|
338
|
+
|
|
339
|
+
### "Missing env var: FACILITATOR_PRIVATE_KEY"
|
|
340
|
+
|
|
341
|
+
Set the private key in `.env`:
|
|
342
|
+
```env
|
|
343
|
+
FACILITATOR_PRIVATE_KEY=0x...
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### "Insufficient funds for gas"
|
|
347
|
+
|
|
348
|
+
The facilitator wallet needs MNT for gas fees. Send some MNT to the facilitator address shown in `/health`.
|
|
349
|
+
|
|
350
|
+
### "Invalid signature"
|
|
351
|
+
|
|
352
|
+
- Check that the client is signing for the correct network (Mantle mainnet, chainId 5000)
|
|
353
|
+
- Verify USDC address matches: `0x09Bc4E0D864854c6aFB6eB9A9cdF58aC190D0dF9`
|
|
354
|
+
|
|
355
|
+
### Port already in use
|
|
356
|
+
|
|
357
|
+
Change the port in `.env`:
|
|
358
|
+
```env
|
|
359
|
+
PORT=8081
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## Links
|
|
365
|
+
|
|
366
|
+
- [SDK Documentation](../x402-mantle-sdk)
|
|
367
|
+
- [Full Documentation](https://x402mantlesdk.xyz/docs)
|
|
368
|
+
- [Dashboard](https://x402mantlesdk.xyz/dashboard)
|
|
369
|
+
- [GitHub](https://github.com/puga-labs/x402-mantle-sdk)
|
|
370
|
+
|
|
371
|
+
## License
|
|
372
|
+
|
|
373
|
+
MIT
|
package/package.json
CHANGED
package/template/README.md
CHANGED
|
@@ -1,50 +1,98 @@
|
|
|
1
|
-
# Mantle x402 Facilitator
|
|
1
|
+
# Mantle x402 Facilitator
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A self-hosted x402 payment facilitator for **Mantle mainnet** using **USDC (EIP-3009)**.
|
|
4
4
|
|
|
5
5
|
This facilitator:
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
6
|
+
- Verifies x402 payment headers
|
|
7
|
+
- Settles payments on-chain via `transferWithAuthorization`
|
|
8
|
+
- Pays gas from the facilitator wallet
|
|
9
|
+
|
|
10
|
+
## Quick Start
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install
|
|
14
|
+
npm run dev
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Facilitator runs on `http://localhost:8080`.
|
|
18
|
+
|
|
19
|
+
## Configuration
|
|
20
|
+
|
|
21
|
+
Edit `.env` file:
|
|
22
|
+
|
|
23
|
+
```env
|
|
24
|
+
# Required
|
|
25
|
+
FACILITATOR_PRIVATE_KEY=0x... # Wallet that pays gas
|
|
26
|
+
RPC_URL=https://rpc.mantle.xyz
|
|
27
|
+
|
|
28
|
+
# Optional
|
|
29
|
+
PORT=8080
|
|
30
|
+
USDC_ADDRESS=0x09Bc4E0D864854c6aFB6eB9A9cdF58aC190D0dF9
|
|
31
|
+
|
|
32
|
+
# Telemetry (optional)
|
|
33
|
+
TELEMETRY_PROJECT_KEY=pk_xxx # Get from https://x402mantlesdk.xyz/dashboard
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Important:** The facilitator wallet needs MNT for gas fees. Check balance at `/health`.
|
|
9
37
|
|
|
10
38
|
## Endpoints
|
|
11
39
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
40
|
+
| Endpoint | Method | Description |
|
|
41
|
+
|----------|--------|-------------|
|
|
42
|
+
| `/health` | GET | Facilitator status and wallet balance |
|
|
43
|
+
| `/supported` | GET | Supported networks and assets |
|
|
44
|
+
| `/verify` | POST | Verify payment header |
|
|
45
|
+
| `/settle` | POST | Execute USDC transfer on-chain |
|
|
16
46
|
|
|
17
|
-
##
|
|
47
|
+
## Scripts
|
|
18
48
|
|
|
19
49
|
```bash
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
npm
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
50
|
+
npm run dev # Development with hot reload
|
|
51
|
+
npm run build # Build for production
|
|
52
|
+
npm start # Run production build
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Deployment
|
|
56
|
+
|
|
57
|
+
### Railway
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
railway login
|
|
61
|
+
railway init
|
|
62
|
+
railway up
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Add environment variables in Railway dashboard.
|
|
66
|
+
|
|
67
|
+
### Docker
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
docker build -t facilitator .
|
|
71
|
+
docker run -p 8080:8080 --env-file .env facilitator
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### PM2 (VPS)
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npm run build
|
|
78
|
+
pm2 start dist/index.js --name facilitator
|
|
26
79
|
```
|
|
27
80
|
|
|
28
|
-
##
|
|
81
|
+
## Telemetry
|
|
29
82
|
|
|
30
|
-
|
|
83
|
+
When `TELEMETRY_PROJECT_KEY` is set:
|
|
84
|
+
- Settlement events are sent to analytics
|
|
85
|
+
- Track payments in [Dashboard](https://x402mantlesdk.xyz/dashboard)
|
|
86
|
+
- No sensitive data is transmitted
|
|
31
87
|
|
|
32
|
-
|
|
33
|
-
2. Add to `.env`:
|
|
34
|
-
```bash
|
|
35
|
-
TELEMETRY_PROJECT_KEY=proj_abc123xyz
|
|
36
|
-
```
|
|
88
|
+
**What is sent:** buyer address, amount, asset, txHash, timestamp
|
|
37
89
|
|
|
38
|
-
**
|
|
90
|
+
**What is NOT sent:** private keys, personal info, request payloads
|
|
39
91
|
|
|
40
|
-
|
|
41
|
-
- Payment metadata (buyer address, amount, asset, network)
|
|
42
|
-
- Transaction hash (after settlement)
|
|
43
|
-
- Timestamp
|
|
92
|
+
Telemetry errors never break payment processing.
|
|
44
93
|
|
|
45
|
-
|
|
46
|
-
- Private keys
|
|
47
|
-
- User personal information
|
|
48
|
-
- Request/response payloads from your protected endpoints
|
|
94
|
+
## Links
|
|
49
95
|
|
|
50
|
-
|
|
96
|
+
- [SDK Documentation](https://www.npmjs.com/package/@puga-labs/x402-mantle-sdk)
|
|
97
|
+
- [Full Documentation](https://x402mantlesdk.xyz/docs)
|
|
98
|
+
- [Dashboard](https://x402mantlesdk.xyz/dashboard)
|
package/template/.env.example
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# Server
|
|
2
|
-
PORT=8080
|
|
3
|
-
|
|
4
|
-
# Network
|
|
5
|
-
NETWORK_ID=mantle-mainnet
|
|
6
|
-
CHAIN_ID=5000
|
|
7
|
-
RPC_URL=https://rpc.mantle.xyz
|
|
8
|
-
|
|
9
|
-
# Asset (USDC on Mantle)
|
|
10
|
-
USDC_ADDRESS=0x09Bc4E0D864854c6aFB6eB9A9cdF58aC190D0dF9
|
|
11
|
-
USDC_DECIMALS=6
|
|
12
|
-
|
|
13
|
-
# Facilitator signer (pays gas for transferWithAuthorization)
|
|
14
|
-
FACILITATOR_PRIVATE_KEY=0xYOUR_PRIVATE_KEY
|
|
15
|
-
|
|
16
|
-
# Optional: enable verbose logs
|
|
17
|
-
LOG_LEVEL=debug
|
|
18
|
-
|
|
19
|
-
# =============================================================================
|
|
20
|
-
# Optional: Analytics & Telemetry
|
|
21
|
-
# =============================================================================
|
|
22
|
-
# Uncomment to send usage metrics to analytics backend
|
|
23
|
-
# This helps improve the x402 ecosystem and provides you with payment analytics
|
|
24
|
-
|
|
25
|
-
# TELEMETRY_PROJECT_KEY=your_project_key_here
|