@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 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
- // Validation rules
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'], // Must have these fields
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
- // Route filtering
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 (optional)
112
+ // Auto-refunds (see Refunds section below)
109
113
  refund: {
110
114
  enabled: true,
111
115
  privateKey: process.env.ZAUTH_REFUND_PRIVATE_KEY,
112
- network: 'base',
113
- maxRefundUsdc: '1.00',
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 can automatically refund users who receive bad responses:
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
- **Requirements:**
147
- - `viem` package installed
148
- - Hot wallet private key configured
149
- - Network matches endpoint network
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
- export ZAUTH_REFUND_PRIVATE_KEY=your-hot-wallet-key
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
- // Amount not in facilitator response
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",