@x402-crosschain/facilitator 1.0.0
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/Dockerfile +64 -0
- package/README.md +641 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +17 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +15 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +249 -0
- package/dist/index.js.map +1 -0
- package/dist/relay.d.ts +34 -0
- package/dist/relay.d.ts.map +1 -0
- package/dist/relay.js +145 -0
- package/dist/relay.js.map +1 -0
- package/dist/settlement.d.ts +24 -0
- package/dist/settlement.d.ts.map +1 -0
- package/dist/settlement.js +61 -0
- package/dist/settlement.js.map +1 -0
- package/dist/types.d.ts +46 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/docker-compose.yml +56 -0
- package/package.json +56 -0
package/Dockerfile
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Multi-stage Dockerfile for x402 Cross-Chain Facilitator
|
|
2
|
+
# Optimized for production deployment
|
|
3
|
+
|
|
4
|
+
# Stage 1: Dependencies
|
|
5
|
+
FROM node:20-alpine AS deps
|
|
6
|
+
WORKDIR /app
|
|
7
|
+
|
|
8
|
+
# Install pnpm
|
|
9
|
+
RUN npm install -g pnpm
|
|
10
|
+
|
|
11
|
+
# Copy package files
|
|
12
|
+
COPY package.json pnpm-lock.yaml* ./
|
|
13
|
+
|
|
14
|
+
# Install dependencies
|
|
15
|
+
RUN pnpm install --frozen-lockfile --prod
|
|
16
|
+
|
|
17
|
+
# Stage 2: Builder
|
|
18
|
+
FROM node:20-alpine AS builder
|
|
19
|
+
WORKDIR /app
|
|
20
|
+
|
|
21
|
+
# Install pnpm
|
|
22
|
+
RUN npm install -g pnpm
|
|
23
|
+
|
|
24
|
+
# Copy package files
|
|
25
|
+
COPY package.json pnpm-lock.yaml* tsconfig.json ./
|
|
26
|
+
|
|
27
|
+
# Install all dependencies (including devDependencies for building)
|
|
28
|
+
RUN pnpm install --frozen-lockfile
|
|
29
|
+
|
|
30
|
+
# Copy source code
|
|
31
|
+
COPY src ./src
|
|
32
|
+
|
|
33
|
+
# Build TypeScript
|
|
34
|
+
RUN pnpm build
|
|
35
|
+
|
|
36
|
+
# Stage 3: Runner
|
|
37
|
+
FROM node:20-alpine AS runner
|
|
38
|
+
WORKDIR /app
|
|
39
|
+
|
|
40
|
+
# Set environment to production
|
|
41
|
+
ENV NODE_ENV=production
|
|
42
|
+
|
|
43
|
+
# Create non-root user for security
|
|
44
|
+
RUN addgroup --system --gid 1001 nodejs && \
|
|
45
|
+
adduser --system --uid 1001 facilitator
|
|
46
|
+
|
|
47
|
+
# Copy necessary files from builder
|
|
48
|
+
COPY --from=deps --chown=facilitator:nodejs /app/node_modules ./node_modules
|
|
49
|
+
COPY --from=builder --chown=facilitator:nodejs /app/dist ./dist
|
|
50
|
+
COPY --chown=facilitator:nodejs package.json ./
|
|
51
|
+
|
|
52
|
+
# Switch to non-root user
|
|
53
|
+
USER facilitator
|
|
54
|
+
|
|
55
|
+
# Expose port
|
|
56
|
+
EXPOSE 3001
|
|
57
|
+
|
|
58
|
+
# Health check
|
|
59
|
+
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
|
|
60
|
+
CMD node -e "require('http').get('http://localhost:3001/health', (r) => { process.exit(r.statusCode === 200 ? 0 : 1); })"
|
|
61
|
+
|
|
62
|
+
# Start the application
|
|
63
|
+
CMD ["node", "dist/index.js"]
|
|
64
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,641 @@
|
|
|
1
|
+
# x402 Cross-Chain Facilitator
|
|
2
|
+
|
|
3
|
+
> **Backend service for instant cross-chain payment settlement**
|
|
4
|
+
|
|
5
|
+
The facilitator handles cross-chain payment routing, bridging via Relay Network, and on-chain settlement verification. Designed for self-hosting or managed deployment.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 🎯 **Overview**
|
|
10
|
+
|
|
11
|
+
The facilitator is the backend engine that powers cross-chain x402 payments:
|
|
12
|
+
|
|
13
|
+
1. **Quote Generation** - Calculates cross-chain routes and costs
|
|
14
|
+
2. **Bridge Coordination** - Manages Relay Network instant bridging
|
|
15
|
+
3. **Settlement Verification** - Confirms on-chain payment completion
|
|
16
|
+
4. **Status Tracking** - Monitors payment lifecycle
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## ⚡ **Key Features**
|
|
21
|
+
|
|
22
|
+
- ⚡ **Instant Bridging** - 2-3 second settlement via Relay liquidity pools
|
|
23
|
+
- 🌐 **69+ Chains** - Support for all major EVM chains + Solana, Bitcoin
|
|
24
|
+
- 🔒 **Non-Custodial** - No funds held, only coordinates transactions
|
|
25
|
+
- 📊 **Status Polling** - Automatic bridge completion tracking
|
|
26
|
+
- 🐳 **Docker Ready** - Easy deployment with Docker/Kubernetes
|
|
27
|
+
- 🔧 **Configurable** - Environment-based configuration
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 📦 **Deployment Options**
|
|
32
|
+
|
|
33
|
+
### **Option 1: Docker (Recommended)**
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Build image
|
|
37
|
+
docker build -t x402-facilitator .
|
|
38
|
+
|
|
39
|
+
# Run container
|
|
40
|
+
docker run -d \
|
|
41
|
+
-p 3001:3001 \
|
|
42
|
+
-e BASE_RPC_URL=https://mainnet.base.org \
|
|
43
|
+
-e PAYMENT_SETTLEMENT_ADDRESS=0xYourContractAddress \
|
|
44
|
+
-e SETTLER_PRIVATE_KEY=0xYourPrivateKey \
|
|
45
|
+
--name x402-facilitator \
|
|
46
|
+
x402-facilitator
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### **Option 2: Node.js**
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Install dependencies
|
|
53
|
+
pnpm install
|
|
54
|
+
|
|
55
|
+
# Build
|
|
56
|
+
pnpm build
|
|
57
|
+
|
|
58
|
+
# Start
|
|
59
|
+
pnpm start
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### **Option 3: Programmatic**
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { startFacilitator } from '@x402-crosschain/facilitator';
|
|
66
|
+
|
|
67
|
+
await startFacilitator({
|
|
68
|
+
port: 3001,
|
|
69
|
+
baseRpcUrl: 'https://mainnet.base.org',
|
|
70
|
+
paymentSettlementAddress: '0xYourContractAddress',
|
|
71
|
+
settlerPrivateKey: process.env.SETTLER_PRIVATE_KEY,
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## 🔧 **Configuration**
|
|
78
|
+
|
|
79
|
+
### **Environment Variables**
|
|
80
|
+
|
|
81
|
+
Create a `.env` file:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Required Configuration
|
|
85
|
+
BASE_RPC_URL=https://mainnet.base.org
|
|
86
|
+
PAYMENT_SETTLEMENT_ADDRESS=0xYourContractAddress
|
|
87
|
+
SETTLER_PRIVATE_KEY=0xYourPrivateKeyHere
|
|
88
|
+
|
|
89
|
+
# Optional Configuration
|
|
90
|
+
PORT=3001
|
|
91
|
+
POLL_INTERVAL=10000
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### **Configuration Options**
|
|
95
|
+
|
|
96
|
+
| Variable | Description | Default | Required |
|
|
97
|
+
|----------|-------------|---------|----------|
|
|
98
|
+
| `BASE_RPC_URL` | Base network RPC endpoint | - | ✅ Yes |
|
|
99
|
+
| `PAYMENT_SETTLEMENT_ADDRESS` | Settlement contract address on Base | - | ✅ Yes |
|
|
100
|
+
| `SETTLER_PRIVATE_KEY` | Private key with settler role | - | ✅ Yes |
|
|
101
|
+
| `PORT` | HTTP server port | 3001 | ❌ No |
|
|
102
|
+
| `POLL_INTERVAL` | Status check interval (ms) | 10000 | ❌ No |
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 📡 **API Endpoints**
|
|
107
|
+
|
|
108
|
+
### **POST /quote-route**
|
|
109
|
+
|
|
110
|
+
Get a cross-chain payment quote with transaction data.
|
|
111
|
+
|
|
112
|
+
**Request:**
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
POST http://localhost:3001/quote-route
|
|
116
|
+
Content-Type: application/json
|
|
117
|
+
|
|
118
|
+
{
|
|
119
|
+
"requirement": {
|
|
120
|
+
"chainId": 8453, // Base
|
|
121
|
+
"tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC
|
|
122
|
+
"amount": "1000000" // 1 USDC (6 decimals)
|
|
123
|
+
},
|
|
124
|
+
"payer": {
|
|
125
|
+
"fromChainId": 42161, // Arbitrum
|
|
126
|
+
"fromToken": "0x0000000000000000000000000000000000000000", // Native ETH
|
|
127
|
+
"address": "0x742d35Cc6634C0532925a3b8D9d4DB0a2D7DD5B3"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Response:**
|
|
133
|
+
|
|
134
|
+
```json
|
|
135
|
+
{
|
|
136
|
+
"paymentId": "0xabc123...",
|
|
137
|
+
"txData": {
|
|
138
|
+
"to": "0xa5F565650890fBA1824Ee0F21EbBbF660a179934",
|
|
139
|
+
"data": "0x...",
|
|
140
|
+
"value": "12345678901234",
|
|
141
|
+
"chainId": 42161
|
|
142
|
+
},
|
|
143
|
+
"route": {
|
|
144
|
+
"fromChainId": 42161,
|
|
145
|
+
"toChainId": 8453,
|
|
146
|
+
"fromToken": "0x0000000000000000000000000000000000000000",
|
|
147
|
+
"toToken": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
148
|
+
"expectedOutput": "1000000"
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Response Fields:**
|
|
154
|
+
|
|
155
|
+
| Field | Type | Description |
|
|
156
|
+
|-------|------|-------------|
|
|
157
|
+
| `paymentId` | string | Unique payment identifier for tracking |
|
|
158
|
+
| `txData.to` | string | Relay contract address to send transaction |
|
|
159
|
+
| `txData.data` | string | Encoded transaction calldata |
|
|
160
|
+
| `txData.value` | string | ETH amount to send (in wei) |
|
|
161
|
+
| `txData.chainId` | number | Source chain ID |
|
|
162
|
+
| `route.expectedOutput` | string | Expected USDC received on Base |
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
### **GET /verify**
|
|
167
|
+
|
|
168
|
+
Check if a payment has been settled on-chain.
|
|
169
|
+
|
|
170
|
+
**Request:**
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
GET http://localhost:3001/verify?paymentId=0xabc123...
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Response:**
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"settled": true
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Response Fields:**
|
|
185
|
+
|
|
186
|
+
| Field | Type | Description |
|
|
187
|
+
|-------|------|-------------|
|
|
188
|
+
| `settled` | boolean | `true` if payment settled on-chain, `false` otherwise |
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
### **POST /submit-tx**
|
|
193
|
+
|
|
194
|
+
Submit transaction hash for tracking (optional).
|
|
195
|
+
|
|
196
|
+
**Request:**
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
POST http://localhost:3001/submit-tx
|
|
200
|
+
Content-Type: application/json
|
|
201
|
+
|
|
202
|
+
{
|
|
203
|
+
"paymentId": "0xabc123...",
|
|
204
|
+
"txHash": "0xdef456..."
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Response:**
|
|
209
|
+
|
|
210
|
+
```json
|
|
211
|
+
{
|
|
212
|
+
"success": true
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
### **GET /health**
|
|
219
|
+
|
|
220
|
+
Health check endpoint.
|
|
221
|
+
|
|
222
|
+
**Request:**
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
GET http://localhost:3001/health
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Response:**
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
{
|
|
232
|
+
"ok": true,
|
|
233
|
+
"activePayments": 3,
|
|
234
|
+
"timestamp": "2025-12-17T00:21:45.123Z"
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## 🏗️ **Architecture**
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
┌──────────────────────────────────────────────┐
|
|
244
|
+
│ x402 Facilitator Service │
|
|
245
|
+
├──────────────────────────────────────────────┤
|
|
246
|
+
│ │
|
|
247
|
+
│ ┌────────────┐ ┌──────────────┐ │
|
|
248
|
+
│ │ Express │ │ Relay │ │
|
|
249
|
+
│ │ API │──│ Service │ │
|
|
250
|
+
│ │ Server │ │ │ │
|
|
251
|
+
│ └────────────┘ └──────────────┘ │
|
|
252
|
+
│ │ │ │
|
|
253
|
+
│ │ │ │
|
|
254
|
+
│ ┌──────┴────────┐ ┌───┴──────────────┐ │
|
|
255
|
+
│ │ Settlement │ │ Status │ │
|
|
256
|
+
│ │ Service │ │ Poller │ │
|
|
257
|
+
│ └───────────────┘ └──────────────────┘ │
|
|
258
|
+
│ │ │
|
|
259
|
+
└─────────┼────────────────────────────────────┘
|
|
260
|
+
│
|
|
261
|
+
▼
|
|
262
|
+
┌───────────────┐
|
|
263
|
+
│ Base Network │
|
|
264
|
+
│ Settlement │
|
|
265
|
+
│ Contract │
|
|
266
|
+
└───────────────┘
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### **Components**
|
|
270
|
+
|
|
271
|
+
1. **Express API Server** - HTTP endpoints for quote/verify/health
|
|
272
|
+
2. **Relay Service** - Integration with Relay Network for bridging
|
|
273
|
+
3. **Settlement Service** - On-chain settlement contract interactions
|
|
274
|
+
4. **Status Poller** - Background process monitoring bridge completion
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## 🔄 **Payment Flow**
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
1. Client → POST /quote-route
|
|
282
|
+
↓
|
|
283
|
+
2. Facilitator → Relay Network (get quote)
|
|
284
|
+
↓
|
|
285
|
+
3. Facilitator → Register payment on-chain
|
|
286
|
+
↓
|
|
287
|
+
4. Facilitator → Return tx data to client
|
|
288
|
+
↓
|
|
289
|
+
5. Client → Submit tx on source chain (Arbitrum)
|
|
290
|
+
↓
|
|
291
|
+
6. Relay Network → Instant bridge (2-3 seconds)
|
|
292
|
+
↓
|
|
293
|
+
7. Status Poller → Check completion
|
|
294
|
+
↓
|
|
295
|
+
8. Facilitator → Settle payment on-chain (Base)
|
|
296
|
+
↓
|
|
297
|
+
9. Client → GET /verify (returns true)
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## 🐳 **Docker Deployment**
|
|
303
|
+
|
|
304
|
+
### **Dockerfile**
|
|
305
|
+
|
|
306
|
+
See [`Dockerfile`](./Dockerfile) in this directory.
|
|
307
|
+
|
|
308
|
+
### **Docker Compose**
|
|
309
|
+
|
|
310
|
+
```yaml
|
|
311
|
+
version: '3.8'
|
|
312
|
+
|
|
313
|
+
services:
|
|
314
|
+
facilitator:
|
|
315
|
+
build: .
|
|
316
|
+
ports:
|
|
317
|
+
- "3001:3001"
|
|
318
|
+
environment:
|
|
319
|
+
- BASE_RPC_URL=https://mainnet.base.org
|
|
320
|
+
- PAYMENT_SETTLEMENT_ADDRESS=${PAYMENT_SETTLEMENT_ADDRESS}
|
|
321
|
+
- SETTLER_PRIVATE_KEY=${SETTLER_PRIVATE_KEY}
|
|
322
|
+
- PORT=3001
|
|
323
|
+
restart: unless-stopped
|
|
324
|
+
healthcheck:
|
|
325
|
+
test: ["CMD", "curl", "-f", "http://localhost:3001/health"]
|
|
326
|
+
interval: 30s
|
|
327
|
+
timeout: 10s
|
|
328
|
+
retries: 3
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### **Kubernetes Deployment**
|
|
332
|
+
|
|
333
|
+
```yaml
|
|
334
|
+
apiVersion: apps/v1
|
|
335
|
+
kind: Deployment
|
|
336
|
+
metadata:
|
|
337
|
+
name: x402-facilitator
|
|
338
|
+
spec:
|
|
339
|
+
replicas: 2
|
|
340
|
+
selector:
|
|
341
|
+
matchLabels:
|
|
342
|
+
app: x402-facilitator
|
|
343
|
+
template:
|
|
344
|
+
metadata:
|
|
345
|
+
labels:
|
|
346
|
+
app: x402-facilitator
|
|
347
|
+
spec:
|
|
348
|
+
containers:
|
|
349
|
+
- name: facilitator
|
|
350
|
+
image: your-registry/x402-facilitator:latest
|
|
351
|
+
ports:
|
|
352
|
+
- containerPort: 3001
|
|
353
|
+
env:
|
|
354
|
+
- name: BASE_RPC_URL
|
|
355
|
+
value: "https://mainnet.base.org"
|
|
356
|
+
- name: PAYMENT_SETTLEMENT_ADDRESS
|
|
357
|
+
valueFrom:
|
|
358
|
+
secretKeyRef:
|
|
359
|
+
name: facilitator-secrets
|
|
360
|
+
key: contract-address
|
|
361
|
+
- name: SETTLER_PRIVATE_KEY
|
|
362
|
+
valueFrom:
|
|
363
|
+
secretKeyRef:
|
|
364
|
+
name: facilitator-secrets
|
|
365
|
+
key: settler-key
|
|
366
|
+
livenessProbe:
|
|
367
|
+
httpGet:
|
|
368
|
+
path: /health
|
|
369
|
+
port: 3001
|
|
370
|
+
initialDelaySeconds: 30
|
|
371
|
+
periodSeconds: 10
|
|
372
|
+
---
|
|
373
|
+
apiVersion: v1
|
|
374
|
+
kind: Service
|
|
375
|
+
metadata:
|
|
376
|
+
name: x402-facilitator
|
|
377
|
+
spec:
|
|
378
|
+
selector:
|
|
379
|
+
app: x402-facilitator
|
|
380
|
+
ports:
|
|
381
|
+
- port: 80
|
|
382
|
+
targetPort: 3001
|
|
383
|
+
type: LoadBalancer
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## 🔒 **Security Considerations**
|
|
389
|
+
|
|
390
|
+
### **Private Key Management**
|
|
391
|
+
|
|
392
|
+
⚠️ **CRITICAL**: Never expose your settler private key!
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
# ✅ Good: Use environment variables
|
|
396
|
+
export SETTLER_PRIVATE_KEY=0x...
|
|
397
|
+
|
|
398
|
+
# ✅ Good: Use Docker secrets
|
|
399
|
+
docker run --env-file .env.production x402-facilitator
|
|
400
|
+
|
|
401
|
+
# ❌ Bad: Hardcode in source
|
|
402
|
+
const privateKey = "0x123..." // NEVER DO THIS
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### **Access Control**
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
408
|
+
// Add rate limiting
|
|
409
|
+
import rateLimit from 'express-rate-limit';
|
|
410
|
+
|
|
411
|
+
app.use('/quote-route', rateLimit({
|
|
412
|
+
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
413
|
+
max: 100, // limit each IP to 100 requests per window
|
|
414
|
+
}));
|
|
415
|
+
|
|
416
|
+
// Add CORS for production
|
|
417
|
+
app.use(cors({
|
|
418
|
+
origin: process.env.ALLOWED_ORIGINS?.split(','),
|
|
419
|
+
}));
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### **Monitoring**
|
|
423
|
+
|
|
424
|
+
```bash
|
|
425
|
+
# Check facilitator health
|
|
426
|
+
curl http://localhost:3001/health
|
|
427
|
+
|
|
428
|
+
# Monitor logs
|
|
429
|
+
docker logs -f x402-facilitator
|
|
430
|
+
|
|
431
|
+
# Track active payments
|
|
432
|
+
curl http://localhost:3001/health | jq '.activePayments'
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
---
|
|
436
|
+
|
|
437
|
+
## 📊 **Operational Metrics**
|
|
438
|
+
|
|
439
|
+
### **Performance**
|
|
440
|
+
|
|
441
|
+
- **Quote Generation**: < 1 second
|
|
442
|
+
- **Bridge Settlement**: 2-3 seconds (via Relay)
|
|
443
|
+
- **On-chain Settlement**: 2-5 seconds (Base finality)
|
|
444
|
+
- **Total Time**: ~5-10 seconds end-to-end
|
|
445
|
+
|
|
446
|
+
### **Reliability**
|
|
447
|
+
|
|
448
|
+
- **Uptime Target**: 99.9%
|
|
449
|
+
- **Success Rate**: > 99% (via Relay Network)
|
|
450
|
+
- **Automatic Retries**: Failed bridges automatically refunded
|
|
451
|
+
|
|
452
|
+
### **Resource Requirements**
|
|
453
|
+
|
|
454
|
+
| Resource | Minimum | Recommended |
|
|
455
|
+
|----------|---------|-------------|
|
|
456
|
+
| **CPU** | 1 core | 2 cores |
|
|
457
|
+
| **RAM** | 512 MB | 1 GB |
|
|
458
|
+
| **Storage** | 1 GB | 5 GB |
|
|
459
|
+
| **Network** | 10 Mbps | 100 Mbps |
|
|
460
|
+
|
|
461
|
+
---
|
|
462
|
+
|
|
463
|
+
## 🧪 **Testing**
|
|
464
|
+
|
|
465
|
+
### **Local Testing**
|
|
466
|
+
|
|
467
|
+
```bash
|
|
468
|
+
# Start facilitator
|
|
469
|
+
pnpm dev
|
|
470
|
+
|
|
471
|
+
# Test health endpoint
|
|
472
|
+
curl http://localhost:3001/health
|
|
473
|
+
|
|
474
|
+
# Test quote endpoint
|
|
475
|
+
curl -X POST http://localhost:3001/quote-route \
|
|
476
|
+
-H "Content-Type: application/json" \
|
|
477
|
+
-d '{
|
|
478
|
+
"requirement": {
|
|
479
|
+
"chainId": 84532,
|
|
480
|
+
"tokenAddress": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
481
|
+
"amount": "1000000"
|
|
482
|
+
},
|
|
483
|
+
"payer": {
|
|
484
|
+
"fromChainId": 421614,
|
|
485
|
+
"fromToken": "0x0000000000000000000000000000000000000000",
|
|
486
|
+
"address": "0x742d35Cc6634C0532925a3b8D9d4DB0a2D7DD5B3"
|
|
487
|
+
}
|
|
488
|
+
}'
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
### **Integration Testing**
|
|
492
|
+
|
|
493
|
+
See [`examples/`](../../examples/) directory for full integration tests.
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
## 🔧 **Troubleshooting**
|
|
498
|
+
|
|
499
|
+
### **Common Issues**
|
|
500
|
+
|
|
501
|
+
#### 1. **"Settler not authorized"**
|
|
502
|
+
|
|
503
|
+
```bash
|
|
504
|
+
# Ensure settler address matches contract deployment
|
|
505
|
+
# Settler is the address derived from SETTLER_PRIVATE_KEY
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
#### 2. **"Relay quote failed"**
|
|
509
|
+
|
|
510
|
+
```bash
|
|
511
|
+
# Check if route is supported
|
|
512
|
+
# Verify fromChainId and toChainId are valid
|
|
513
|
+
# Ensure amount is above minimum ($1.00 recommended)
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
#### 3. **"Payment not settling"**
|
|
517
|
+
|
|
518
|
+
```bash
|
|
519
|
+
# Check facilitator logs for poller status
|
|
520
|
+
# Verify Base RPC is responding
|
|
521
|
+
# Ensure settler wallet has gas for settlement txs
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
#### 4. **"Connection refused"**
|
|
525
|
+
|
|
526
|
+
```bash
|
|
527
|
+
# Verify facilitator is running
|
|
528
|
+
curl http://localhost:3001/health
|
|
529
|
+
|
|
530
|
+
# Check firewall rules
|
|
531
|
+
sudo ufw allow 3001
|
|
532
|
+
|
|
533
|
+
# Verify Docker port mapping
|
|
534
|
+
docker ps | grep facilitator
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
---
|
|
538
|
+
|
|
539
|
+
## 📈 **Scaling**
|
|
540
|
+
|
|
541
|
+
### **Horizontal Scaling**
|
|
542
|
+
|
|
543
|
+
```yaml
|
|
544
|
+
# Deploy multiple instances behind load balancer
|
|
545
|
+
replicas: 3
|
|
546
|
+
|
|
547
|
+
# Use sticky sessions for in-memory payment tracking
|
|
548
|
+
# Or migrate to Redis for shared state:
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
### **Redis Integration (Future)**
|
|
552
|
+
|
|
553
|
+
```typescript
|
|
554
|
+
// Coming soon: Shared payment state
|
|
555
|
+
import Redis from 'ioredis';
|
|
556
|
+
|
|
557
|
+
const redis = new Redis(process.env.REDIS_URL);
|
|
558
|
+
await redis.set(`payment:${paymentId}`, JSON.stringify(payment));
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
---
|
|
562
|
+
|
|
563
|
+
## 🔄 **Upgrading**
|
|
564
|
+
|
|
565
|
+
### **Version Migration**
|
|
566
|
+
|
|
567
|
+
```bash
|
|
568
|
+
# Pull latest image
|
|
569
|
+
docker pull your-registry/x402-facilitator:latest
|
|
570
|
+
|
|
571
|
+
# Rolling update
|
|
572
|
+
kubectl rollout restart deployment/x402-facilitator
|
|
573
|
+
|
|
574
|
+
# Verify health
|
|
575
|
+
kubectl rollout status deployment/x402-facilitator
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
---
|
|
579
|
+
|
|
580
|
+
## 📚 **API Client Examples**
|
|
581
|
+
|
|
582
|
+
### **JavaScript/TypeScript**
|
|
583
|
+
|
|
584
|
+
```typescript
|
|
585
|
+
// Get quote
|
|
586
|
+
const response = await fetch('https://facilitator.yourdomain.com/quote-route', {
|
|
587
|
+
method: 'POST',
|
|
588
|
+
headers: { 'Content-Type': 'application/json' },
|
|
589
|
+
body: JSON.stringify({ requirement, payer }),
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
const { paymentId, txData } = await response.json();
|
|
593
|
+
|
|
594
|
+
// Check status
|
|
595
|
+
const verifyResponse = await fetch(
|
|
596
|
+
`https://facilitator.yourdomain.com/verify?paymentId=${paymentId}`
|
|
597
|
+
);
|
|
598
|
+
const { settled } = await verifyResponse.json();
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
### **cURL**
|
|
602
|
+
|
|
603
|
+
```bash
|
|
604
|
+
# Get quote
|
|
605
|
+
curl -X POST https://facilitator.yourdomain.com/quote-route \
|
|
606
|
+
-H "Content-Type: application/json" \
|
|
607
|
+
-d '{"requirement":{...},"payer":{...}}'
|
|
608
|
+
|
|
609
|
+
# Check status
|
|
610
|
+
curl "https://facilitator.yourdomain.com/verify?paymentId=0xabc..."
|
|
611
|
+
|
|
612
|
+
# Health check
|
|
613
|
+
curl https://facilitator.yourdomain.com/health
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
---
|
|
617
|
+
|
|
618
|
+
## 📄 **License**
|
|
619
|
+
|
|
620
|
+
Apache 2.0 License
|
|
621
|
+
|
|
622
|
+
---
|
|
623
|
+
|
|
624
|
+
## 🙏 **Acknowledgments**
|
|
625
|
+
|
|
626
|
+
- [Relay Network](https://relay.link) - Instant cross-chain bridging
|
|
627
|
+
- [x402 Protocol](https://x402.org) - Open payment standard
|
|
628
|
+
- [ethers.js](https://docs.ethers.org) - Ethereum interactions
|
|
629
|
+
|
|
630
|
+
---
|
|
631
|
+
|
|
632
|
+
## 🆘 **Support**
|
|
633
|
+
|
|
634
|
+
- **Documentation**: https://docs.x402crosschain.com
|
|
635
|
+
- **GitHub Issues**: https://github.com/your-org/x402-cross-bridge-sdk/issues
|
|
636
|
+
- **Discord**: https://discord.gg/your-invite
|
|
637
|
+
- **Email**: support@x402crosschain.com
|
|
638
|
+
|
|
639
|
+
---
|
|
640
|
+
|
|
641
|
+
**Made with ❤️ by the x402 Cross-Chain Team**
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,MAAM;;;;;;CAMlB,CAAC"}
|