@puga-labs/x402-mantle-sdk 0.3.9 → 0.3.11

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.
Files changed (40) hide show
  1. package/README.md +478 -0
  2. package/dist/chunk-3DGAB7HD.js +126 -0
  3. package/dist/chunk-3YIQEQDT.js +96 -0
  4. package/dist/chunk-HVQ2RGMT.js +126 -0
  5. package/dist/chunk-JXMWK3BO.js +96 -0
  6. package/dist/chunk-NC5OU47J.js +99 -0
  7. package/dist/chunk-NWWXJFJ4.js +293 -0
  8. package/dist/chunk-P5FKQVHW.js +99 -0
  9. package/dist/chunk-UVYA6H32.js +293 -0
  10. package/dist/express-BWE0nQty.d.cts +68 -0
  11. package/dist/express-BvuN0Lx1.d.ts +68 -0
  12. package/dist/index.cjs +58 -2
  13. package/dist/index.d.cts +3 -3
  14. package/dist/index.d.ts +3 -3
  15. package/dist/index.js +2 -2
  16. package/dist/nextjs-Bujo9Okf.d.cts +89 -0
  17. package/dist/nextjs-CzSejZe8.d.ts +89 -0
  18. package/dist/server-express.cjs +58 -2
  19. package/dist/server-express.d.cts +2 -2
  20. package/dist/server-express.d.ts +2 -2
  21. package/dist/server-express.js +2 -2
  22. package/dist/server-nextjs.cjs +58 -2
  23. package/dist/server-nextjs.d.cts +2 -2
  24. package/dist/server-nextjs.d.ts +2 -2
  25. package/dist/server-nextjs.js +2 -2
  26. package/dist/server-web.cjs +58 -2
  27. package/dist/server-web.d.cts +2 -2
  28. package/dist/server-web.d.ts +2 -2
  29. package/dist/server-web.js +2 -2
  30. package/dist/server.cjs +84 -2
  31. package/dist/server.d.cts +8 -7
  32. package/dist/server.d.ts +8 -7
  33. package/dist/server.js +4 -4
  34. package/dist/types-Ba0v9XsC.d.ts +108 -0
  35. package/dist/types-BkGUHT4x.d.cts +108 -0
  36. package/dist/types-DEpSrXCf.d.ts +112 -0
  37. package/dist/types-DrBw0xwj.d.cts +112 -0
  38. package/dist/web-standards-DsCZRJPE.d.ts +77 -0
  39. package/dist/web-standards-QCbyQ14G.d.cts +77 -0
  40. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,478 @@
1
+ # @puga-labs/x402-mantle-sdk
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@puga-labs/x402-mantle-sdk.svg)](https://www.npmjs.com/package/@puga-labs/x402-mantle-sdk)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ SDK for x402 payments on Mantle blockchain. Protect your APIs with USDC payments using a simple middleware.
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ npm install @puga-labs/x402-mantle-sdk
12
+ ```
13
+
14
+ ## Features
15
+
16
+ - React hooks (`useMantleX402`, `useEthersWallet`)
17
+ - Vanilla JS client (`createMantleClient`)
18
+ - Server middleware for Express, Next.js, Hono, Cloudflare Workers, Deno
19
+ - Full TypeScript support
20
+ - Automatic payment flow handling
21
+ - Analytics & telemetry integration
22
+
23
+ ---
24
+
25
+ ## Client-Side Usage
26
+
27
+ ### React (Recommended)
28
+
29
+ ```tsx
30
+ import { useMantleX402 } from '@puga-labs/x402-mantle-sdk/react';
31
+
32
+ function PaymentButton() {
33
+ const { postWithPayment } = useMantleX402({
34
+ facilitatorUrl: 'https://facilitator.x402mantlesdk.xyz'
35
+ });
36
+
37
+ const handlePay = async () => {
38
+ try {
39
+ const { response, txHash } = await postWithPayment('/api/generate', {
40
+ prompt: 'Hello world'
41
+ });
42
+
43
+ console.log('Result:', response);
44
+ console.log('Transaction:', txHash);
45
+ } catch (error) {
46
+ console.error('Payment failed:', error);
47
+ }
48
+ };
49
+
50
+ return <button onClick={handlePay}>Generate ($0.01)</button>;
51
+ }
52
+ ```
53
+
54
+ ### Wallet Hook
55
+
56
+ Separate hook for wallet management:
57
+
58
+ ```tsx
59
+ import { useEthersWallet } from '@puga-labs/x402-mantle-sdk/react';
60
+
61
+ function WalletConnect() {
62
+ const {
63
+ address,
64
+ isConnected,
65
+ chainId,
66
+ connect,
67
+ disconnect,
68
+ error
69
+ } = useEthersWallet({ autoConnect: false });
70
+
71
+ if (isConnected) {
72
+ return (
73
+ <div>
74
+ <p>Connected: {address}</p>
75
+ <p>Chain ID: {chainId}</p>
76
+ <button onClick={disconnect}>Disconnect</button>
77
+ </div>
78
+ );
79
+ }
80
+
81
+ return <button onClick={connect}>Connect Wallet</button>;
82
+ }
83
+ ```
84
+
85
+ ### Vanilla JavaScript
86
+
87
+ ```typescript
88
+ import { createMantleClient } from '@puga-labs/x402-mantle-sdk/client';
89
+
90
+ // Create client
91
+ const client = createMantleClient({
92
+ facilitatorUrl: 'https://facilitator.x402mantlesdk.xyz',
93
+ resourceUrl: 'https://your-api.com',
94
+ getProvider: () => window.ethereum,
95
+ getAccount: () => userAddress
96
+ });
97
+
98
+ // Make paid request
99
+ const { response, txHash } = await client.postWithPayment('/api/generate', {
100
+ prompt: 'Hello world'
101
+ });
102
+ ```
103
+
104
+ ### Low-Level Payment Client
105
+
106
+ For full control over the payment flow:
107
+
108
+ ```typescript
109
+ import { createPaymentClient } from '@puga-labs/x402-mantle-sdk/client';
110
+
111
+ const paymentClient = createPaymentClient({
112
+ resourceUrl: 'https://your-api.com',
113
+ facilitatorUrl: 'https://facilitator.x402mantlesdk.xyz',
114
+ provider: window.ethereum,
115
+ userAddress: '0x...' // Optional
116
+ });
117
+
118
+ const result = await paymentClient.callWithPayment('/api/endpoint', {
119
+ data: 'payload'
120
+ });
121
+ ```
122
+
123
+ ---
124
+
125
+ ## Server-Side Usage
126
+
127
+ ### Express.js
128
+
129
+ ```typescript
130
+ import express from 'express';
131
+ import { mantlePaywall } from '@puga-labs/x402-mantle-sdk/server/express';
132
+
133
+ const app = express();
134
+ app.use(express.json());
135
+
136
+ // Create paywall middleware
137
+ const pay = mantlePaywall({
138
+ priceUsd: 0.01,
139
+ payTo: '0xYourWalletAddress',
140
+ facilitatorUrl: 'https://facilitator.x402mantlesdk.xyz'
141
+ });
142
+
143
+ // Protected route
144
+ app.post('/api/generate', pay, async (req, res) => {
145
+ const { prompt } = req.body;
146
+ // Your logic here - only runs after payment
147
+ res.json({ result: 'Generated content' });
148
+ });
149
+
150
+ // Unprotected route
151
+ app.get('/api/health', (req, res) => {
152
+ res.json({ status: 'ok' });
153
+ });
154
+
155
+ app.listen(3000);
156
+ ```
157
+
158
+ ### Next.js (App Router)
159
+
160
+ ```typescript
161
+ // app/api/generate/route.ts
162
+ import { mantlePaywall } from '@puga-labs/x402-mantle-sdk/server/nextjs';
163
+ import { NextRequest, NextResponse } from 'next/server';
164
+
165
+ const pay = mantlePaywall({
166
+ priceUsd: 0.01,
167
+ payTo: '0xYourWalletAddress',
168
+ facilitatorUrl: 'https://facilitator.x402mantlesdk.xyz'
169
+ });
170
+
171
+ export const POST = pay(async (req: NextRequest) => {
172
+ const { prompt } = await req.json();
173
+ // Your logic here
174
+ return NextResponse.json({ result: 'Generated content' });
175
+ });
176
+ ```
177
+
178
+ ### Hono
179
+
180
+ ```typescript
181
+ import { Hono } from 'hono';
182
+ import { mantlePaywall } from '@puga-labs/x402-mantle-sdk/server/web';
183
+
184
+ const app = new Hono();
185
+
186
+ const pay = mantlePaywall({
187
+ priceUsd: 0.01,
188
+ payTo: '0xYourWalletAddress',
189
+ facilitatorUrl: 'https://facilitator.x402mantlesdk.xyz'
190
+ });
191
+
192
+ app.post('/api/generate', pay(async (c) => {
193
+ const { prompt } = await c.req.json();
194
+ return c.json({ result: 'Generated content' });
195
+ }));
196
+
197
+ export default app;
198
+ ```
199
+
200
+ ### Cloudflare Workers
201
+
202
+ ```typescript
203
+ import { mantlePaywall } from '@puga-labs/x402-mantle-sdk/server/web';
204
+
205
+ const pay = mantlePaywall({
206
+ priceUsd: 0.01,
207
+ payTo: '0xYourWalletAddress',
208
+ facilitatorUrl: 'https://facilitator.x402mantlesdk.xyz'
209
+ });
210
+
211
+ export default {
212
+ async fetch(request: Request): Promise<Response> {
213
+ if (request.method === 'POST') {
214
+ return pay(async (req) => {
215
+ const body = await req.json();
216
+ return new Response(JSON.stringify({ result: 'success' }), {
217
+ headers: { 'Content-Type': 'application/json' }
218
+ });
219
+ })(request);
220
+ }
221
+ return new Response('Method not allowed', { status: 405 });
222
+ }
223
+ };
224
+ ```
225
+
226
+ ### Deno
227
+
228
+ ```typescript
229
+ import { mantlePaywall } from '@puga-labs/x402-mantle-sdk/server/web';
230
+
231
+ const pay = mantlePaywall({
232
+ priceUsd: 0.01,
233
+ payTo: '0xYourWalletAddress',
234
+ facilitatorUrl: 'https://facilitator.x402mantlesdk.xyz'
235
+ });
236
+
237
+ Deno.serve(pay(async (req) => {
238
+ const body = await req.json();
239
+ return new Response(JSON.stringify({ result: 'success' }), {
240
+ headers: { 'Content-Type': 'application/json' }
241
+ });
242
+ }));
243
+ ```
244
+
245
+ ---
246
+
247
+ ## Configuration
248
+
249
+ ### Client Options
250
+
251
+ | Option | Type | Default | Description |
252
+ |--------|------|---------|-------------|
253
+ | `facilitatorUrl` | `string` | `http://localhost:8080` | Facilitator service URL |
254
+ | `resourceUrl` | `string` | `window.location.origin` | Your API base URL |
255
+ | `projectKey` | `string` | - | Project key for hosted facilitator billing |
256
+ | `getProvider` | `() => EIP1193Provider` | - | Function returning wallet provider |
257
+ | `getAccount` | `() => string` | - | Function returning user address |
258
+
259
+ ### Server Options (mantlePaywall)
260
+
261
+ | Option | Type | Required | Description |
262
+ |--------|------|----------|-------------|
263
+ | `priceUsd` | `number` | Yes | Price in USD (e.g., `0.01` for 1 cent) |
264
+ | `payTo` | `string` | Yes | Your wallet address to receive payments |
265
+ | `facilitatorUrl` | `string` | No | Facilitator URL (default: localhost:8080) |
266
+ | `apiKey` | `string` | No | API key for hosted facilitator |
267
+ | `network` | `string` | No | Network ID (default: `mantle-mainnet`) |
268
+ | `onPaymentSettled` | `function` | No | Callback when payment is verified |
269
+ | `telemetry` | `object` | No | Analytics configuration |
270
+
271
+ ---
272
+
273
+ ## Hosted vs Self-Hosted Facilitator
274
+
275
+ ### Hosted Facilitator (Recommended)
276
+
277
+ Use our managed facilitator service:
278
+
279
+ ```typescript
280
+ const pay = mantlePaywall({
281
+ priceUsd: 0.01,
282
+ payTo: '0xYourWallet',
283
+ facilitatorUrl: 'https://facilitator.x402mantlesdk.xyz',
284
+ apiKey: 'your-api-key' // Get from dashboard
285
+ });
286
+ ```
287
+
288
+ Get your API key from [Dashboard](https://x402mantlesdk.xyz/dashboard).
289
+
290
+ ### Self-Hosted Facilitator
291
+
292
+ Run your own facilitator:
293
+
294
+ ```typescript
295
+ const pay = mantlePaywall({
296
+ priceUsd: 0.01,
297
+ payTo: '0xYourWallet',
298
+ facilitatorUrl: 'https://your-facilitator.com'
299
+ // No apiKey needed for self-hosted
300
+ });
301
+ ```
302
+
303
+ Create a facilitator with:
304
+ ```bash
305
+ npx create-mantle-facilitator my-facilitator
306
+ ```
307
+
308
+ ---
309
+
310
+ ## Analytics & Telemetry
311
+
312
+ Track payments with built-in analytics:
313
+
314
+ ```typescript
315
+ const pay = mantlePaywall({
316
+ priceUsd: 0.01,
317
+ payTo: '0x...',
318
+ facilitatorUrl: 'https://facilitator.x402mantlesdk.xyz',
319
+
320
+ // Analytics configuration
321
+ telemetry: {
322
+ projectKey: 'pk_xxx', // Get from dashboard
323
+ debug: true // Enable console logging
324
+ },
325
+
326
+ // Callback on each successful payment
327
+ onPaymentSettled: (entry) => {
328
+ console.log('Payment received!');
329
+ console.log('Amount:', entry.valueAtomic);
330
+ console.log('From:', entry.from);
331
+ console.log('To:', entry.to);
332
+ console.log('TxHash:', entry.txHash);
333
+ console.log('Route:', entry.route);
334
+ }
335
+ });
336
+ ```
337
+
338
+ ### PaymentLogEntry Fields
339
+
340
+ | Field | Type | Description |
341
+ |-------|------|-------------|
342
+ | `id` | `string` | Unique payment identifier (nonce) |
343
+ | `from` | `string` | Payer's wallet address |
344
+ | `to` | `string` | Recipient's wallet address |
345
+ | `valueAtomic` | `string` | Amount in atomic units |
346
+ | `network` | `string` | Network ID |
347
+ | `asset` | `string` | Token contract address |
348
+ | `route` | `string` | API route (e.g., `POST /api/generate`) |
349
+ | `txHash` | `string` | Blockchain transaction hash |
350
+ | `timestamp` | `number` | Unix timestamp (ms) |
351
+
352
+ ---
353
+
354
+ ## TypeScript Types
355
+
356
+ ```typescript
357
+ import type {
358
+ // Shared types
359
+ PaymentRequirements,
360
+ Authorization,
361
+ PaymentHeaderObject,
362
+ NetworkId,
363
+
364
+ // Client types
365
+ MantleClient,
366
+ MantleClientConfig,
367
+ PaymentClient,
368
+ PaymentClientConfig,
369
+ CallWithPaymentResult,
370
+
371
+ // Server types
372
+ PaymentLogEntry,
373
+ TelemetryConfig,
374
+ MinimalPaywallOptions,
375
+
376
+ // React types
377
+ UseMantleX402Options,
378
+ UseEthersWalletOptions,
379
+ UseEthersWalletReturn
380
+ } from '@puga-labs/x402-mantle-sdk';
381
+ ```
382
+
383
+ ---
384
+
385
+ ## Import Paths
386
+
387
+ ```typescript
388
+ // Main exports (types + constants)
389
+ import { MANTLE_DEFAULTS } from '@puga-labs/x402-mantle-sdk';
390
+
391
+ // Client
392
+ import { createMantleClient, createPaymentClient } from '@puga-labs/x402-mantle-sdk/client';
393
+
394
+ // React hooks
395
+ import { useMantleX402, useEthersWallet } from '@puga-labs/x402-mantle-sdk/react';
396
+
397
+ // Server - Express
398
+ import { mantlePaywall } from '@puga-labs/x402-mantle-sdk/server/express';
399
+
400
+ // Server - Next.js
401
+ import { mantlePaywall } from '@puga-labs/x402-mantle-sdk/server/nextjs';
402
+
403
+ // Server - Web Standards (Hono, CF Workers, Deno)
404
+ import { mantlePaywall } from '@puga-labs/x402-mantle-sdk/server/web';
405
+ ```
406
+
407
+ ---
408
+
409
+ ## Network Configuration
410
+
411
+ | Network | Chain ID | USDC Address | Decimals |
412
+ |---------|----------|--------------|----------|
413
+ | Mantle Mainnet | 5000 | `0x09Bc4E0D864854c6aFB6eB9A9cdF58aC190D0dF9` | 6 |
414
+
415
+ ### Price Conversion
416
+
417
+ - `priceUsd: 0.01` = 1 cent = 10,000 atomic units
418
+ - Formula: `atomicUnits = priceUsd * 10^6`
419
+
420
+ ---
421
+
422
+ ## Error Handling
423
+
424
+ ### Client-Side Errors
425
+
426
+ ```typescript
427
+ try {
428
+ const { response, txHash } = await postWithPayment('/api/generate', data);
429
+ } catch (error) {
430
+ if (error.code === 4001) {
431
+ // User rejected the transaction
432
+ console.log('User cancelled');
433
+ } else if (error.code === -32603) {
434
+ // Internal error (insufficient funds, etc.)
435
+ console.log('Transaction failed:', error.message);
436
+ } else {
437
+ // Network or facilitator error
438
+ console.log('Error:', error.message);
439
+ }
440
+ }
441
+ ```
442
+
443
+ ### Server-Side Error Responses
444
+
445
+ ```typescript
446
+ // 402 Payment Required
447
+ {
448
+ "error": "Payment Required",
449
+ "paymentRequirements": {
450
+ "scheme": "exact",
451
+ "network": "mantle-mainnet",
452
+ "asset": "0x09Bc4E0D...",
453
+ "maxAmountRequired": "10000",
454
+ "payTo": "0x...",
455
+ "price": "$0.01",
456
+ "currency": "USD"
457
+ }
458
+ }
459
+
460
+ // 400 Invalid Payment
461
+ {
462
+ "error": "Invalid payment",
463
+ "invalidReason": "Payment amount too low"
464
+ }
465
+ ```
466
+
467
+ ---
468
+
469
+ ## Links
470
+
471
+ - [Full Documentation](https://x402mantlesdk.xyz/docs)
472
+ - [Dashboard](https://x402mantlesdk.xyz/dashboard)
473
+ - [GitHub](https://github.com/puga-labs/x402-mantle-sdk)
474
+ - [Facilitator Kit](../create-mantle-facilitator)
475
+
476
+ ## License
477
+
478
+ MIT
@@ -0,0 +1,126 @@
1
+ import {
2
+ buildRouteKey,
3
+ checkPayment,
4
+ validateAddress
5
+ } from "./chunk-UVYA6H32.js";
6
+ import {
7
+ MANTLE_DEFAULTS,
8
+ __export,
9
+ getDefaultAssetForNetwork,
10
+ usdCentsToAtomic
11
+ } from "./chunk-HEZZ74SI.js";
12
+
13
+ // src/server/adapters/express.ts
14
+ var express_exports = {};
15
+ __export(express_exports, {
16
+ createPaymentMiddleware: () => createPaymentMiddleware,
17
+ mantlePaywall: () => mantlePaywall
18
+ });
19
+ function debugLog(config, prefix, message, data) {
20
+ if (config?.debug) {
21
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
22
+ console.log(`[${timestamp}] [x402-debug:${prefix}]`, message, data || "");
23
+ }
24
+ }
25
+ function createPaymentMiddleware(config) {
26
+ const { facilitatorUrl, receiverAddress, routes, apiKey, onPaymentSettled, telemetry } = config;
27
+ if (!facilitatorUrl) {
28
+ throw new Error("facilitatorUrl is required");
29
+ }
30
+ if (!receiverAddress) {
31
+ throw new Error("receiverAddress is required");
32
+ }
33
+ validateAddress(receiverAddress, "receiverAddress");
34
+ if (!routes || Object.keys(routes).length === 0) {
35
+ throw new Error("routes config must not be empty");
36
+ }
37
+ return async function paymentMiddleware(req, res, next) {
38
+ const routeKey = buildRouteKey(req.method, req.path);
39
+ const routeConfig = routes[routeKey];
40
+ if (!routeConfig) {
41
+ next();
42
+ return;
43
+ }
44
+ const { priceUsdCents, network } = routeConfig;
45
+ const assetConfig = getDefaultAssetForNetwork(network);
46
+ const maxAmountRequiredBigInt = usdCentsToAtomic(
47
+ priceUsdCents,
48
+ assetConfig.decimals
49
+ );
50
+ const paymentRequirements = {
51
+ scheme: "exact",
52
+ network,
53
+ asset: assetConfig.address,
54
+ maxAmountRequired: maxAmountRequiredBigInt.toString(),
55
+ payTo: receiverAddress,
56
+ price: `$${(priceUsdCents / 100).toFixed(2)}`,
57
+ currency: "USD"
58
+ };
59
+ const paymentHeader = req.header("X-PAYMENT") || req.header("x-payment") || null;
60
+ const result = await checkPayment({
61
+ paymentHeader,
62
+ paymentRequirements,
63
+ facilitatorUrl,
64
+ apiKey,
65
+ routeKey,
66
+ network,
67
+ asset: assetConfig.address,
68
+ telemetry,
69
+ onPaymentSettled
70
+ });
71
+ if (!result.isValid) {
72
+ res.status(result.statusCode).json(result.responseBody);
73
+ return;
74
+ }
75
+ debugLog(telemetry, "handler", "\u25B6\uFE0F Handler execution started (Express middleware)");
76
+ if (result.sendTelemetryAfterResponse) {
77
+ res.on("finish", () => {
78
+ const statusCode = res.statusCode;
79
+ debugLog(telemetry, "handler", `\u2705 Handler completed: ${statusCode}`);
80
+ const errorMessage = statusCode >= 400 ? `Handler returned ${statusCode}` : void 0;
81
+ debugLog(telemetry, "callback", `\u{1F4E4} Calling telemetry callback with status ${statusCode}`);
82
+ result.sendTelemetryAfterResponse(statusCode, errorMessage);
83
+ });
84
+ res.on("close", () => {
85
+ if (!res.writableEnded) {
86
+ debugLog(telemetry, "handler", "\u274C Response closed without finishing");
87
+ debugLog(telemetry, "callback", "\u{1F4E4} Calling telemetry callback with error");
88
+ result.sendTelemetryAfterResponse(500, "Response closed without finishing");
89
+ }
90
+ });
91
+ } else {
92
+ debugLog(telemetry, "callback", "\u26A0\uFE0F No telemetry callback to call");
93
+ }
94
+ next();
95
+ };
96
+ }
97
+ function mantlePaywall(opts) {
98
+ const { priceUsd, payTo, facilitatorUrl, apiKey, telemetry, onPaymentSettled } = opts;
99
+ validateAddress(payTo, "payTo");
100
+ const priceUsdCents = Math.round(priceUsd * 100);
101
+ return async (req, res, next) => {
102
+ const method = (req.method || "GET").toUpperCase();
103
+ const path = req.path || "/";
104
+ const routeKey = `${method} ${path}`;
105
+ const middleware = createPaymentMiddleware({
106
+ facilitatorUrl: facilitatorUrl || MANTLE_DEFAULTS.FACILITATOR_URL,
107
+ receiverAddress: payTo,
108
+ routes: {
109
+ [routeKey]: {
110
+ priceUsdCents,
111
+ network: MANTLE_DEFAULTS.NETWORK
112
+ }
113
+ },
114
+ apiKey,
115
+ telemetry,
116
+ onPaymentSettled
117
+ });
118
+ return middleware(req, res, next);
119
+ };
120
+ }
121
+
122
+ export {
123
+ createPaymentMiddleware,
124
+ mantlePaywall,
125
+ express_exports
126
+ };
@@ -0,0 +1,96 @@
1
+ import {
2
+ buildRouteKey,
3
+ checkPayment,
4
+ validateAddress
5
+ } from "./chunk-NWWXJFJ4.js";
6
+ import {
7
+ MANTLE_DEFAULTS,
8
+ __export,
9
+ getDefaultAssetForNetwork,
10
+ usdCentsToAtomic
11
+ } from "./chunk-HEZZ74SI.js";
12
+
13
+ // src/server/adapters/web-standards.ts
14
+ var web_standards_exports = {};
15
+ __export(web_standards_exports, {
16
+ mantlePaywall: () => mantlePaywall
17
+ });
18
+ function debugLog(config, prefix, message, data) {
19
+ if (config?.debug) {
20
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
21
+ console.log(`[${timestamp}] [x402-debug:${prefix}]`, message, data || "");
22
+ }
23
+ }
24
+ function mantlePaywall(opts) {
25
+ const { priceUsd, payTo, facilitatorUrl, apiKey, telemetry, onPaymentSettled } = opts;
26
+ validateAddress(payTo, "payTo");
27
+ const priceUsdCents = Math.round(priceUsd * 100);
28
+ return function(handler) {
29
+ return async (request) => {
30
+ const url = new URL(request.url);
31
+ const method = request.method;
32
+ const path = url.pathname;
33
+ const routeKey = buildRouteKey(method, path);
34
+ const network = MANTLE_DEFAULTS.NETWORK;
35
+ const assetConfig = getDefaultAssetForNetwork(network);
36
+ const maxAmountRequiredBigInt = usdCentsToAtomic(
37
+ priceUsdCents,
38
+ assetConfig.decimals
39
+ );
40
+ const paymentRequirements = {
41
+ scheme: "exact",
42
+ network,
43
+ asset: assetConfig.address,
44
+ maxAmountRequired: maxAmountRequiredBigInt.toString(),
45
+ payTo,
46
+ price: `$${(priceUsdCents / 100).toFixed(2)}`,
47
+ currency: "USD"
48
+ };
49
+ const paymentHeader = request.headers.get("X-PAYMENT") || request.headers.get("x-payment") || null;
50
+ const result = await checkPayment({
51
+ paymentHeader,
52
+ paymentRequirements,
53
+ facilitatorUrl: facilitatorUrl || MANTLE_DEFAULTS.FACILITATOR_URL,
54
+ apiKey,
55
+ routeKey,
56
+ network,
57
+ asset: assetConfig.address,
58
+ telemetry,
59
+ onPaymentSettled
60
+ });
61
+ if (!result.isValid) {
62
+ return new Response(JSON.stringify(result.responseBody), {
63
+ status: result.statusCode,
64
+ headers: {
65
+ "Content-Type": "application/json"
66
+ }
67
+ });
68
+ }
69
+ try {
70
+ debugLog(telemetry, "handler", "Handler execution started");
71
+ const response = await handler(request);
72
+ debugLog(telemetry, "handler", `Handler completed: ${response.status}`);
73
+ if (result.sendTelemetryAfterResponse) {
74
+ debugLog(telemetry, "callback", `Calling telemetry callback with status ${response.status}`);
75
+ result.sendTelemetryAfterResponse(response.status);
76
+ } else {
77
+ debugLog(telemetry, "callback", "WARNING: No telemetry callback to call");
78
+ }
79
+ return response;
80
+ } catch (err) {
81
+ const errorMessage = err instanceof Error ? err.message : "Unknown error";
82
+ debugLog(telemetry, "handler", `ERROR: Handler error: ${errorMessage}`);
83
+ if (result.sendTelemetryAfterResponse) {
84
+ debugLog(telemetry, "callback", "Calling telemetry callback with error");
85
+ result.sendTelemetryAfterResponse(500, errorMessage);
86
+ }
87
+ throw err;
88
+ }
89
+ };
90
+ };
91
+ }
92
+
93
+ export {
94
+ mantlePaywall,
95
+ web_standards_exports
96
+ };