@zauthx402/sdk 0.1.9 → 0.1.12
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 +213 -22
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5 -4
- package/dist/index.mjs.map +1 -1
- package/dist/middleware/index.js +5 -4
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/index.mjs +5 -4
- package/dist/middleware/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,9 +43,11 @@ app.get('/api/paid', ...);
|
|
|
43
43
|
|
|
44
44
|
- **Non-invasive** - Observes requests/responses without interfering with payments
|
|
45
45
|
- **Implementation agnostic** - Works with any x402 implementation (V1/V2)
|
|
46
|
+
- **Multi-network** - Supports EVM (Base, Ethereum) and Solana out of the box
|
|
46
47
|
- **Full telemetry** - Request params, response bodies, timing, payment details
|
|
47
48
|
- **Response validation** - Detect empty, invalid, or error responses
|
|
48
49
|
- **Auto-refunds** (optional) - Trigger refunds when responses are bad
|
|
50
|
+
- **Per-endpoint config** - Customize validation and refund behavior per route
|
|
49
51
|
|
|
50
52
|
## How It Works
|
|
51
53
|
|
|
@@ -76,6 +78,8 @@ The SDK:
|
|
|
76
78
|
|
|
77
79
|
## Configuration
|
|
78
80
|
|
|
81
|
+
### Full Example
|
|
82
|
+
|
|
79
83
|
```typescript
|
|
80
84
|
import { createZauthMiddleware } from '@zauthx402/sdk/middleware';
|
|
81
85
|
|
|
@@ -83,43 +87,54 @@ app.use(createZauthMiddleware({
|
|
|
83
87
|
apiKey: 'your-api-key',
|
|
84
88
|
mode: 'provider',
|
|
85
89
|
|
|
86
|
-
//
|
|
90
|
+
// Route filtering
|
|
91
|
+
includeRoutes: ['/api/.*'], // Only monitor these routes
|
|
92
|
+
excludeRoutes: ['/health'], // Skip these routes
|
|
93
|
+
|
|
94
|
+
// Response validation
|
|
87
95
|
validation: {
|
|
88
|
-
requiredFields: ['data'], //
|
|
89
|
-
errorFields: ['error', 'errors'], // These indicate errors
|
|
90
|
-
minResponseSize: 10, // Minimum response size
|
|
96
|
+
requiredFields: ['data'], // Response must have these fields
|
|
97
|
+
errorFields: ['error', 'errors'], // These fields indicate errors
|
|
98
|
+
minResponseSize: 10, // Minimum response size in bytes
|
|
91
99
|
rejectEmptyCollections: true, // Reject empty arrays/objects
|
|
92
100
|
},
|
|
93
101
|
|
|
94
|
-
//
|
|
95
|
-
includeRoutes: ['/api/.*'], // Only monitor these
|
|
96
|
-
excludeRoutes: ['/health'], // Skip these
|
|
97
|
-
|
|
98
|
-
// Telemetry options
|
|
102
|
+
// Telemetry
|
|
99
103
|
telemetry: {
|
|
100
104
|
includeRequestBody: true,
|
|
101
105
|
includeResponseBody: true,
|
|
102
|
-
maxBodySize: 10000,
|
|
103
|
-
redactHeaders: ['authorization'],
|
|
106
|
+
maxBodySize: 10000, // Truncate bodies larger than this
|
|
107
|
+
redactHeaders: ['authorization'], // Strip sensitive headers
|
|
104
108
|
redactFields: ['password', 'secret'],
|
|
105
|
-
sampleRate: 1.0, // 1.0 = all, 0.1 = 10%
|
|
109
|
+
sampleRate: 1.0, // 1.0 = all events, 0.1 = 10%
|
|
106
110
|
},
|
|
107
111
|
|
|
108
|
-
// Auto-refunds (
|
|
112
|
+
// Auto-refunds (see Refunds section below)
|
|
109
113
|
refund: {
|
|
110
114
|
enabled: true,
|
|
111
115
|
privateKey: process.env.ZAUTH_REFUND_PRIVATE_KEY,
|
|
112
|
-
|
|
113
|
-
|
|
116
|
+
solanaPrivateKey: process.env.ZAUTH_SOLANA_PRIVATE_KEY,
|
|
117
|
+
maxRefundUsd: 1.00,
|
|
118
|
+
dailyCapUsd: 50.00,
|
|
119
|
+
monthlyCapUsd: 500.00,
|
|
114
120
|
},
|
|
115
121
|
|
|
116
122
|
debug: true,
|
|
117
123
|
}));
|
|
118
124
|
```
|
|
119
125
|
|
|
126
|
+
### Environment Variables
|
|
127
|
+
|
|
128
|
+
| Variable | Description | Required |
|
|
129
|
+
|---|---|---|
|
|
130
|
+
| `ZAUTH_API_KEY` | Your zauthx402 API key | Yes |
|
|
131
|
+
| `ZAUTH_REFUND_PRIVATE_KEY` | EVM hot wallet private key (hex, `0x...`) | If refunds enabled on EVM |
|
|
132
|
+
| `ZAUTH_SOLANA_PRIVATE_KEY` | Solana hot wallet private key (base58) | If refunds enabled on Solana |
|
|
133
|
+
| `ZAUTH_API_ENDPOINT` | Custom API endpoint (default: `https://back.zauthx402.com`) | No |
|
|
134
|
+
|
|
120
135
|
## Auto-Refunds
|
|
121
136
|
|
|
122
|
-
When enabled, the SDK
|
|
137
|
+
When enabled, the SDK automatically refunds users who receive bad responses.
|
|
123
138
|
|
|
124
139
|
```mermaid
|
|
125
140
|
%%{init: {'theme': 'dark', 'themeVariables': { 'actorBkg': '#1a1a1a', 'actorTextColor': '#fff', 'actorLineColor': '#666', 'signalColor': '#666', 'signalTextColor': '#fff', 'labelBoxBkgColor': '#1a1a1a', 'labelTextColor': '#fff', 'altSectionBkgColor': '#2d2d2d' }}}%%
|
|
@@ -143,21 +158,187 @@ sequenceDiagram
|
|
|
143
158
|
end
|
|
144
159
|
```
|
|
145
160
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
161
|
+
### Refund Triggers
|
|
162
|
+
|
|
163
|
+
The SDK can trigger refunds based on these conditions:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
refund: {
|
|
167
|
+
enabled: true,
|
|
168
|
+
triggers: {
|
|
169
|
+
serverError: true, // 5xx status codes
|
|
170
|
+
timeout: true, // Request timeouts
|
|
171
|
+
emptyResponse: true, // Empty or meaningless response body
|
|
172
|
+
schemaValidation: false, // Response doesn't match expected schema
|
|
173
|
+
minMeaningfulness: 0.3, // AI-scored meaningfulness threshold (0-1)
|
|
174
|
+
},
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### EVM-Only Setup (Base)
|
|
179
|
+
|
|
180
|
+
If your endpoint only accepts EVM payments:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
npm install viem
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
app.use(zauthProvider('your-api-key', {
|
|
188
|
+
refund: {
|
|
189
|
+
enabled: true,
|
|
190
|
+
privateKey: process.env.ZAUTH_REFUND_PRIVATE_KEY,
|
|
191
|
+
network: 'base',
|
|
192
|
+
maxRefundUsd: 1.00,
|
|
193
|
+
},
|
|
194
|
+
}));
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
# .env
|
|
199
|
+
ZAUTH_REFUND_PRIVATE_KEY=0xYourEvmPrivateKeyHex
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Solana-Only Setup
|
|
203
|
+
|
|
204
|
+
If your endpoint only accepts Solana payments:
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
app.use(zauthProvider('your-api-key', {
|
|
208
|
+
refund: {
|
|
209
|
+
enabled: true,
|
|
210
|
+
solanaPrivateKey: process.env.ZAUTH_SOLANA_PRIVATE_KEY,
|
|
211
|
+
network: 'solana',
|
|
212
|
+
maxRefundUsd: 1.00,
|
|
213
|
+
},
|
|
214
|
+
}));
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# .env
|
|
219
|
+
ZAUTH_SOLANA_PRIVATE_KEY=YourSolanaPrivateKeyBase58
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Dual-Network Setup (EVM + Solana)
|
|
223
|
+
|
|
224
|
+
If your endpoint accepts both EVM and Solana payments (x402 V2), provide both keys. The SDK automatically routes refunds to the correct network based on how the user originally paid.
|
|
150
225
|
|
|
151
226
|
```bash
|
|
152
227
|
npm install viem
|
|
153
|
-
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
app.use(zauthProvider('your-api-key', {
|
|
232
|
+
refund: {
|
|
233
|
+
enabled: true,
|
|
234
|
+
privateKey: process.env.ZAUTH_REFUND_PRIVATE_KEY,
|
|
235
|
+
solanaPrivateKey: process.env.ZAUTH_SOLANA_PRIVATE_KEY,
|
|
236
|
+
maxRefundUsd: 1.00,
|
|
237
|
+
dailyCapUsd: 50.00,
|
|
238
|
+
},
|
|
239
|
+
}));
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# .env
|
|
244
|
+
ZAUTH_REFUND_PRIVATE_KEY=0xYourEvmPrivateKeyHex
|
|
245
|
+
ZAUTH_SOLANA_PRIVATE_KEY=YourSolanaPrivateKeyBase58
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
If a user pays via Base and gets a bad response, the refund goes out on Base using your EVM key. If they pay via Solana, it goes out on Solana using your Solana key. If you only configure one key, refunds on the other network will fail gracefully with a log message.
|
|
249
|
+
|
|
250
|
+
### Safety Limits
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
refund: {
|
|
254
|
+
enabled: true,
|
|
255
|
+
maxRefundUsd: 1.00, // Max per single refund
|
|
256
|
+
dailyCapUsd: 50.00, // Max total refunds per day
|
|
257
|
+
monthlyCapUsd: 500.00, // Max total refunds per month
|
|
258
|
+
},
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Refund Callbacks
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
refund: {
|
|
265
|
+
enabled: true,
|
|
266
|
+
onRefund: (refund) => {
|
|
267
|
+
console.log(`Refunded $${refund.amountUsd} to ${refund.recipient} on ${refund.network}`);
|
|
268
|
+
console.log(`Tx: ${refund.txHash}`);
|
|
269
|
+
},
|
|
270
|
+
onRefundError: (error) => {
|
|
271
|
+
console.error(`Refund failed for ${error.url}: ${error.error}`);
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Per-Endpoint Configuration
|
|
277
|
+
|
|
278
|
+
You can customize validation and refund behavior for individual endpoints using `expectedResponse` and per-endpoint overrides.
|
|
279
|
+
|
|
280
|
+
### `expectedResponse`
|
|
281
|
+
|
|
282
|
+
The `expectedResponse` field is a plain-text description of what a valid response looks like. It's used for AI-powered validation — the SDK scores how "meaningful" a response is relative to what was expected.
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
app.use(createZauthMiddleware({
|
|
286
|
+
apiKey: 'your-api-key',
|
|
287
|
+
mode: 'provider',
|
|
288
|
+
|
|
289
|
+
refund: {
|
|
290
|
+
enabled: true,
|
|
291
|
+
privateKey: process.env.ZAUTH_REFUND_PRIVATE_KEY,
|
|
292
|
+
solanaPrivateKey: process.env.ZAUTH_SOLANA_PRIVATE_KEY,
|
|
293
|
+
maxRefundUsd: 1.00,
|
|
294
|
+
|
|
295
|
+
endpoints: {
|
|
296
|
+
'/api/weather': {
|
|
297
|
+
expectedResponse: 'JSON object with temperature, humidity, wind speed, and forecast for the requested location',
|
|
298
|
+
maxRefundUsd: 0.50,
|
|
299
|
+
triggers: {
|
|
300
|
+
emptyResponse: true,
|
|
301
|
+
minMeaningfulness: 0.5,
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
'/api/translate': {
|
|
305
|
+
expectedResponse: 'JSON with translated_text field containing the translation in the target language',
|
|
306
|
+
maxRefundUsd: 0.10,
|
|
307
|
+
},
|
|
308
|
+
'/api/expensive-report': {
|
|
309
|
+
maxRefundUsd: 5.00, // Higher cap for expensive endpoint
|
|
310
|
+
enabled: true,
|
|
311
|
+
},
|
|
312
|
+
'/api/beta-endpoint': {
|
|
313
|
+
enabled: false, // Disable refunds for this endpoint
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
}));
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Custom Refund Logic
|
|
321
|
+
|
|
322
|
+
For full control, use `shouldRefund` to decide per-request:
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
endpoints: {
|
|
326
|
+
'/api/data': {
|
|
327
|
+
shouldRefund: (response, statusCode, validationResult) => {
|
|
328
|
+
// Only refund if the response is truly empty
|
|
329
|
+
if (statusCode >= 500) return true;
|
|
330
|
+
if (!response || Object.keys(response).length === 0) return true;
|
|
331
|
+
return false;
|
|
332
|
+
},
|
|
333
|
+
},
|
|
334
|
+
},
|
|
154
335
|
```
|
|
155
336
|
|
|
156
337
|
## Examples
|
|
157
338
|
|
|
158
339
|
See the `/examples` directory:
|
|
159
340
|
|
|
160
|
-
- `provider-express/` - Express server with monitoring
|
|
341
|
+
- `provider-express/` - Express server with monitoring and refunds
|
|
161
342
|
|
|
162
343
|
## Local Development
|
|
163
344
|
|
|
@@ -190,6 +371,16 @@ export { RefundHandler, createRefundHandler } from '@zauthx402/sdk';
|
|
|
190
371
|
export * from '@zauthx402/sdk'; // All types
|
|
191
372
|
```
|
|
192
373
|
|
|
374
|
+
### Supported Networks
|
|
375
|
+
|
|
376
|
+
| Network | Value | Key Config |
|
|
377
|
+
|---|---|---|
|
|
378
|
+
| Base (mainnet) | `'base'` | `privateKey` |
|
|
379
|
+
| Base Sepolia (testnet) | `'base-sepolia'` | `privateKey` |
|
|
380
|
+
| Solana (mainnet) | `'solana'` | `solanaPrivateKey` |
|
|
381
|
+
| Solana Devnet | `'solana-devnet'` | `solanaPrivateKey` |
|
|
382
|
+
| Solana Testnet | `'solana-testnet'` | `solanaPrivateKey` |
|
|
383
|
+
|
|
193
384
|
## Get Your API Key
|
|
194
385
|
|
|
195
386
|
Sign up at [zauthx402.com](https://zauthx402.com) to get your API key and access the monitoring dashboard.
|
package/dist/index.js
CHANGED
|
@@ -4600,7 +4600,8 @@ function decodePaymentHeader(paymentHeader) {
|
|
|
4600
4600
|
if (!payer && parsed.payload?.transaction) {
|
|
4601
4601
|
payer = extractSolanaFeePayer(parsed.payload.transaction);
|
|
4602
4602
|
}
|
|
4603
|
-
const amount = parsed.payload?.authorization?.value || // x402 V2
|
|
4603
|
+
const amount = parsed.payload?.authorization?.value || // x402 V2 EVM
|
|
4604
|
+
parsed.accepted?.amount || // x402 V2 (accepted payment requirements)
|
|
4604
4605
|
parsed.amount || parsed.payload?.amount || null;
|
|
4605
4606
|
let network = parsed.payload?.authorization?.network || // x402 V2 EVM
|
|
4606
4607
|
parsed.network || parsed.payload?.network || null;
|
|
@@ -5678,11 +5679,11 @@ function createZauthMiddleware(options) {
|
|
|
5678
5679
|
let paymentResponse = reqPaymentInfo || headerPaymentResponse;
|
|
5679
5680
|
if (facilitatorResponse?.payer) {
|
|
5680
5681
|
const defaultAmount = options.defaultPaymentAmountUsdc;
|
|
5682
|
+
const decodedAmountUsdc = decodedPayment?.amount ? baseUnitsToUsdc(decodedPayment.amount) : null;
|
|
5681
5683
|
paymentResponse = {
|
|
5682
5684
|
transactionHash: facilitatorResponse.transaction || null,
|
|
5683
|
-
amountPaid: null,
|
|
5684
|
-
|
|
5685
|
-
amountPaidUsdc: defaultAmount || null,
|
|
5685
|
+
amountPaid: decodedPayment?.amount || null,
|
|
5686
|
+
amountPaidUsdc: decodedAmountUsdc || defaultAmount || null,
|
|
5686
5687
|
network: facilitatorResponse.network || "base",
|
|
5687
5688
|
payTo: null,
|
|
5688
5689
|
asset: "USDC",
|