@dexterai/x402 1.5.0 → 1.5.1

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
@@ -24,7 +24,7 @@
24
24
 
25
25
  x402 is a protocol for HTTP-native micropayments. When a server returns HTTP status `402 Payment Required`, it includes payment details in a `PAYMENT-REQUIRED` header. The client signs a payment transaction and retries the request with a `PAYMENT-SIGNATURE` header. The server verifies and settles the payment, then returns the protected content.
26
26
 
27
- This SDK handles the entire flow automatically—you just call `fetch()` and payments happen transparently.
27
+ This SDK handles the entire flow automatically—you just call `fetch()` and payments happen transparently. With **Access Pass** mode, buyers pay once and get unlimited access for a time window—no per-request signing needed.
28
28
 
29
29
  ---
30
30
 
@@ -36,6 +36,8 @@ This SDK handles the entire flow automatically—you just call `fetch()` and pay
36
36
 
37
37
  **Token-accurate LLM pricing.** Built-in [tiktoken](https://github.com/openai/tiktoken) support prices AI requests by actual token count. Works with OpenAI models out of the box, or bring your own rates for Anthropic, Gemini, Mistral, or local models.
38
38
 
39
+ **Access Pass.** Pay once, get unlimited access for a time window. Buyers connect a wallet, make one payment, and receive a JWT token that works like an API key—no per-request signing, no private keys in code. The Stripe replacement for crypto-native APIs.
40
+
39
41
  **Full-stack.** Client SDK for browsers, server SDK for backends. React hooks, Express middleware patterns, facilitator client—everything you need.
40
42
 
41
43
  **Multi-chain.** Solana and Base (Ethereum L2) with the same API. Add wallets for both and the SDK picks the right one automatically.
@@ -158,12 +160,18 @@ import { useX402Payment } from '@dexterai/x402/react';
158
160
  // Server - Express middleware
159
161
  import { x402Middleware } from '@dexterai/x402/server';
160
162
 
163
+ // Server - Access Pass (pay once, unlimited requests)
164
+ import { x402AccessPass } from '@dexterai/x402/server';
165
+
161
166
  // Server - manual control
162
167
  import { createX402Server } from '@dexterai/x402/server';
163
168
 
164
169
  // Server - dynamic pricing
165
170
  import { createDynamicPricing, createTokenPricing } from '@dexterai/x402/server';
166
171
 
172
+ // React - Access Pass hook
173
+ import { useAccessPass } from '@dexterai/x402/react';
174
+
167
175
  // Chain adapters (advanced)
168
176
  import { createSolanaAdapter, createEvmAdapter } from '@dexterai/x402/adapters';
169
177
 
@@ -221,6 +229,96 @@ Options:
221
229
  - `facilitatorUrl` — Override facilitator (default: x402.dexter.cash)
222
230
  - `verbose` — Enable debug logging
223
231
 
232
+ ### Access Pass — Pay Once, Unlimited Requests
233
+
234
+ Replace API keys with time-limited access passes. Buyers make one payment and get a JWT token for unlimited requests during a time window.
235
+
236
+ **Server:**
237
+
238
+ ```typescript
239
+ import express from 'express';
240
+ import { x402AccessPass } from '@dexterai/x402/server';
241
+
242
+ const app = express();
243
+
244
+ // Protect all /api routes with access pass
245
+ app.use('/api', x402AccessPass({
246
+ payTo: 'YourSolanaAddress...',
247
+ tiers: {
248
+ '1h': '0.50', // $0.50 for 1 hour
249
+ '24h': '2.00', // $2.00 for 24 hours
250
+ },
251
+ ratePerHour: '0.50', // also accept custom durations
252
+ }));
253
+
254
+ app.get('/api/data', (req, res) => {
255
+ // Only runs with a valid access pass
256
+ res.json({ data: 'premium content' });
257
+ });
258
+ ```
259
+
260
+ **Client (Node.js):**
261
+
262
+ ```typescript
263
+ import { wrapFetch } from '@dexterai/x402/client';
264
+
265
+ const x402Fetch = wrapFetch(fetch, {
266
+ walletPrivateKey: process.env.SOLANA_PRIVATE_KEY,
267
+ accessPass: { preferTier: '1h', maxSpend: '1.00' },
268
+ });
269
+
270
+ // First call: auto-purchases a 1-hour pass ($0.50 USDC)
271
+ const res1 = await x402Fetch('https://api.example.com/api/data');
272
+
273
+ // All subsequent calls for the next hour: uses cached JWT, zero payment
274
+ const res2 = await x402Fetch('https://api.example.com/api/data');
275
+ const res3 = await x402Fetch('https://api.example.com/api/data');
276
+ ```
277
+
278
+ **React:**
279
+
280
+ ```tsx
281
+ import { useAccessPass } from '@dexterai/x402/react';
282
+
283
+ function Dashboard() {
284
+ const { tiers, pass, isPassValid, purchasePass, fetch: apFetch } = useAccessPass({
285
+ wallets: { solana: solanaWallet },
286
+ resourceUrl: 'https://api.example.com',
287
+ });
288
+
289
+ return (
290
+ <div>
291
+ {!isPassValid && tiers?.map(t => (
292
+ <button key={t.id} onClick={() => purchasePass(t.id)}>
293
+ {t.label} — ${t.price}
294
+ </button>
295
+ ))}
296
+ {isPassValid && <p>Pass active! {pass?.remainingSeconds}s remaining</p>}
297
+ <button onClick={() => apFetch('/api/data')}>Fetch Data</button>
298
+ </div>
299
+ );
300
+ }
301
+ ```
302
+
303
+ **How it works:**
304
+ 1. Client requests a protected endpoint → Server returns `402` with `X-ACCESS-PASS-TIERS` header
305
+ 2. Client selects a tier and pays via x402 → Server verifies, settles, issues a JWT
306
+ 3. Server returns `200` with `ACCESS-PASS` header containing the JWT
307
+ 4. Client caches the JWT and includes it as `Authorization: Bearer <token>` on all subsequent requests
308
+ 5. Server validates the JWT locally (no facilitator call) → instant response
309
+
310
+ Options:
311
+ - `payTo` — Address to receive payments
312
+ - `tiers` — Named duration tiers with prices (e.g., `{ '1h': '0.50' }`)
313
+ - `ratePerHour` — Rate for custom durations (buyer sends `?duration=<seconds>`)
314
+ - `network` — CAIP-2 network (default: Solana mainnet)
315
+ - `secret` — HMAC secret for JWT signing (auto-generated if not provided)
316
+ - `facilitatorUrl` — Override facilitator (default: x402.dexter.cash)
317
+
318
+ **[Live demo →](https://dexter.cash/access-pass)**
319
+
320
+ ---
321
+
224
322
  ### Manual Server (Advanced)
225
323
 
226
324
  For more control over the payment flow:
@@ -429,6 +527,18 @@ tiktoken's default encoding works well for most transformer models. Only use a c
429
527
  | `maxAmountAtomic` | `string` | No | Maximum payment cap |
430
528
  | `verbose` | `boolean` | No | Enable debug logging |
431
529
 
530
+ ### `x402AccessPass(options)`
531
+
532
+ | Option | Type | Required | Description |
533
+ |--------|------|----------|-------------|
534
+ | `payTo` | `string` | Yes | Address to receive payments |
535
+ | `tiers` | `Record<string, string>` | One of `tiers` or `ratePerHour` | Named tiers (e.g., `{ '1h': '0.50' }`) |
536
+ | `ratePerHour` | `string` | One of `tiers` or `ratePerHour` | USD rate for custom durations |
537
+ | `network` | `string` | No | CAIP-2 network (default: Solana mainnet) |
538
+ | `secret` | `Buffer` | No | HMAC secret for JWT (auto-generated) |
539
+ | `facilitatorUrl` | `string` | No | Facilitator URL (default: x402.dexter.cash) |
540
+ | `verbose` | `boolean` | No | Enable debug logging |
541
+
432
542
  ### `useX402Payment(options)`
433
543
 
434
544
  Returns:
@@ -444,6 +554,27 @@ Returns:
444
554
  | `balances` | `Balance[]` | Token balances per chain |
445
555
  | `refreshBalances` | `function` | Manual refresh |
446
556
  | `reset` | `function` | Clear state |
557
+ | `accessPass` | `object?` | Active pass state (tier, expiresAt, remainingSeconds) |
558
+
559
+ ### `useAccessPass(options)`
560
+
561
+ | Option | Type | Required | Description |
562
+ |--------|------|----------|-------------|
563
+ | `wallets` | `{ solana?, evm? }` | Yes | Multi-chain wallets |
564
+ | `resourceUrl` | `string` | Yes | The x402 resource base URL |
565
+ | `preferredNetwork` | `string` | No | Prefer this network |
566
+ | `autoConnect` | `boolean` | No | Auto-fetch tiers on mount (default: true) |
567
+
568
+ Returns:
569
+
570
+ | Property | Type | Description |
571
+ |----------|------|-------------|
572
+ | `tiers` | `AccessPassTier[]?` | Available tiers from server |
573
+ | `pass` | `object?` | Active pass (jwt, tier, expiresAt, remainingSeconds) |
574
+ | `isPassValid` | `boolean` | Whether pass is active and not expired |
575
+ | `purchasePass` | `function` | Buy a pass for a tier or custom duration |
576
+ | `isPurchasing` | `boolean` | Purchase in progress |
577
+ | `fetch` | `function` | Fetch with auto pass inclusion |
447
578
 
448
579
  ---
449
580
 
@@ -466,5 +597,6 @@ MIT — see [LICENSE](./LICENSE)
466
597
  <p align="center">
467
598
  <a href="https://x402.dexter.cash">Dexter Facilitator</a> ·
468
599
  <a href="https://dexter.cash/sdk">Live Demo</a> ·
600
+ <a href="https://dexter.cash/access-pass">Access Pass Demo</a> ·
469
601
  <a href="https://dexter.cash/onboard">Become a Seller</a>
470
602
  </p>
@@ -771,8 +771,10 @@ function createX402Client(config) {
771
771
  const paymentSignatureHeader = btoa(JSON.stringify(paymentSignature));
772
772
  const passResponse = await customFetch(passUrl, {
773
773
  ...init,
774
+ method: "POST",
774
775
  headers: {
775
776
  ...init?.headers || {},
777
+ "Content-Type": "application/json",
776
778
  "PAYMENT-SIGNATURE": paymentSignatureHeader
777
779
  }
778
780
  });