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

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.
@@ -0,0 +1,68 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+ import { b as RoutesConfig, M as MinimalPaywallOptions } from './types-Ba0v9XsC.js';
3
+
4
+ /**
5
+ * Express middleware function type for Mantle paywall.
6
+ */
7
+ type MantleMiddleware = (req: Request, res: Response, next: NextFunction) => Promise<void>;
8
+ /** Config for createPaymentMiddleware. */
9
+ interface PaymentMiddlewareConfig {
10
+ /** Base URL of facilitator, e.g. https://facilitator.nosubs.ai */
11
+ facilitatorUrl: string;
12
+ /** Recipient address (developer). Validated at runtime. */
13
+ receiverAddress: string;
14
+ /** Map of protected routes and their pricing. */
15
+ routes: RoutesConfig;
16
+ /** Optional API key for hosted facilitator billing. */
17
+ apiKey?: string;
18
+ /**
19
+ * Optional hook called whenever a payment is successfully settled.
20
+ */
21
+ onPaymentSettled?: MinimalPaywallOptions["onPaymentSettled"];
22
+ /** Optional: Send usage telemetry for billing/analytics. */
23
+ telemetry?: MinimalPaywallOptions["telemetry"];
24
+ }
25
+ /**
26
+ * Create Express middleware for x402 payment verification on multiple routes.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * const middleware = createPaymentMiddleware({
31
+ * facilitatorUrl: 'https://facilitator.nosubs.ai',
32
+ * receiverAddress: '0x...',
33
+ * routes: {
34
+ * 'POST /api/generate': { priceUsdCents: 1, network: 'mantle-mainnet' },
35
+ * 'GET /api/data': { priceUsdCents: 5, network: 'mantle-mainnet' },
36
+ * }
37
+ * });
38
+ *
39
+ * app.use(middleware);
40
+ * ```
41
+ */
42
+ declare function createPaymentMiddleware(config: PaymentMiddlewareConfig): MantleMiddleware;
43
+ /**
44
+ * Simplified wrapper for protecting a single route with x402 payments.
45
+ * Uses Mantle mainnet defaults (USDC, exact scheme, etc.).
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * const pay = mantlePaywall({ priceUsd: 0.01, payTo: "0x..." });
50
+ * app.post('/api/generate', pay, async (req, res) => {
51
+ * // Your handler code here
52
+ * });
53
+ * ```
54
+ *
55
+ * @param opts - Minimal configuration (price, payTo, optional facilitator/telemetry).
56
+ * @returns Express middleware function for single-route protection.
57
+ */
58
+ declare function mantlePaywall(opts: MinimalPaywallOptions): MantleMiddleware;
59
+
60
+ type express_MantleMiddleware = MantleMiddleware;
61
+ type express_PaymentMiddlewareConfig = PaymentMiddlewareConfig;
62
+ declare const express_createPaymentMiddleware: typeof createPaymentMiddleware;
63
+ declare const express_mantlePaywall: typeof mantlePaywall;
64
+ declare namespace express {
65
+ export { type express_MantleMiddleware as MantleMiddleware, type express_PaymentMiddlewareConfig as PaymentMiddlewareConfig, express_createPaymentMiddleware as createPaymentMiddleware, express_mantlePaywall as mantlePaywall };
66
+ }
67
+
68
+ export { type MantleMiddleware as M, type PaymentMiddlewareConfig as P, createPaymentMiddleware as c, express as e, mantlePaywall as m };
package/dist/index.cjs CHANGED
@@ -159,9 +159,20 @@ function createTelemetryEvent(entry, config) {
159
159
  priceUsd: entry.paymentRequirements?.price
160
160
  };
161
161
  }
162
- async function sendTelemetry(event, endpoint) {
162
+ async function sendTelemetry(event, endpoint, debug) {
163
163
  const targetEndpoint = endpoint ?? DEFAULT_TELEMETRY_ENDPOINT;
164
+ if (debug) {
165
+ console.log(`[x402-debug:telemetry] \u{1F4E4} Sending telemetry event:`, {
166
+ event: event.event,
167
+ endpoint: targetEndpoint,
168
+ projectKey: event.projectKey.substring(0, 10) + "...",
169
+ route: event.route,
170
+ responseStatus: event.responseStatus,
171
+ serviceDelivered: event.serviceDelivered
172
+ });
173
+ }
164
174
  if (!targetEndpoint) {
175
+ if (debug) console.log(`[x402-debug:telemetry] \u26A0\uFE0F No endpoint configured, skipping`);
165
176
  return;
166
177
  }
167
178
  try {
@@ -173,17 +184,29 @@ async function sendTelemetry(event, endpoint) {
173
184
  },
174
185
  body: JSON.stringify(event)
175
186
  });
187
+ if (debug) {
188
+ console.log(`[x402-debug:telemetry] ${response.ok ? "\u2705" : "\u274C"} Telemetry sent: HTTP ${response.status}`);
189
+ }
176
190
  if (!response.ok) {
177
191
  console.warn(
178
192
  `[x402-telemetry] Failed to send event: HTTP ${response.status}`
179
193
  );
180
194
  }
181
195
  } catch (err) {
196
+ if (debug) {
197
+ console.error(`[x402-debug:telemetry] \u274C Error sending:`, err);
198
+ }
182
199
  console.error("[x402-telemetry] Error sending telemetry:", err);
183
200
  }
184
201
  }
185
202
 
186
203
  // src/server/core/verifyPayment.ts
204
+ function debugLog(config, prefix, message, data) {
205
+ if (config?.debug) {
206
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
207
+ console.log(`[${timestamp}] [x402-debug:${prefix}]`, message, data || "");
208
+ }
209
+ }
187
210
  async function checkPayment(input) {
188
211
  const {
189
212
  paymentHeader,
@@ -271,6 +294,10 @@ async function checkPayment(input) {
271
294
  facilitatorUrl,
272
295
  paymentRequirements
273
296
  };
297
+ debugLog(telemetry, "verify", "\u2705 Payment verified", {
298
+ nonce: authorization.nonce,
299
+ route: routeKey
300
+ });
274
301
  if (onPaymentSettled) {
275
302
  onPaymentSettled(baseLogEntry);
276
303
  }
@@ -283,17 +310,33 @@ async function checkPayment(input) {
283
310
  }
284
311
  const sendTelemetryAfterResponse = telemetry && baseLogEntry ? (responseStatus, error) => {
285
312
  try {
313
+ debugLog(telemetry, "callback", "\u{1F4E4} Telemetry callback invoked", {
314
+ responseStatus,
315
+ hasError: !!error
316
+ });
286
317
  const event = createTelemetryEvent(baseLogEntry, telemetry);
287
318
  event.responseStatus = responseStatus;
288
319
  event.errorMessage = error;
289
320
  event.serviceDelivered = responseStatus >= 200 && responseStatus < 300;
290
- sendTelemetry(event, telemetry.endpoint).catch(
321
+ sendTelemetry(event, telemetry.endpoint, telemetry.debug).catch(
291
322
  (err) => console.error("[x402-telemetry] Async send failed:", err)
292
323
  );
293
324
  } catch (err) {
294
325
  console.error("[x402-telemetry] Error creating telemetry event:", err);
295
326
  }
296
327
  } : void 0;
328
+ if (telemetry && baseLogEntry) {
329
+ debugLog(telemetry, "callback", "\u2705 Telemetry callback created", {
330
+ route: routeKey,
331
+ hasTelemetryConfig: !!telemetry,
332
+ hasLogEntry: !!baseLogEntry
333
+ });
334
+ } else if (telemetry) {
335
+ debugLog(telemetry, "callback", "\u26A0\uFE0F Telemetry callback NOT created", {
336
+ hasTelemetryConfig: !!telemetry,
337
+ hasLogEntry: !!baseLogEntry
338
+ });
339
+ }
297
340
  return {
298
341
  status: "verified",
299
342
  statusCode: 200,
@@ -320,6 +363,12 @@ async function checkPayment(input) {
320
363
  }
321
364
 
322
365
  // src/server/adapters/express.ts
366
+ function debugLog2(config, prefix, message, data) {
367
+ if (config?.debug) {
368
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
369
+ console.log(`[${timestamp}] [x402-debug:${prefix}]`, message, data || "");
370
+ }
371
+ }
323
372
  function createPaymentMiddleware(config) {
324
373
  const { facilitatorUrl, receiverAddress, routes, apiKey, onPaymentSettled, telemetry } = config;
325
374
  if (!facilitatorUrl) {
@@ -370,17 +419,24 @@ function createPaymentMiddleware(config) {
370
419
  res.status(result.statusCode).json(result.responseBody);
371
420
  return;
372
421
  }
422
+ debugLog2(telemetry, "handler", "\u25B6\uFE0F Handler execution started (Express middleware)");
373
423
  if (result.sendTelemetryAfterResponse) {
374
424
  res.on("finish", () => {
375
425
  const statusCode = res.statusCode;
426
+ debugLog2(telemetry, "handler", `\u2705 Handler completed: ${statusCode}`);
376
427
  const errorMessage = statusCode >= 400 ? `Handler returned ${statusCode}` : void 0;
428
+ debugLog2(telemetry, "callback", `\u{1F4E4} Calling telemetry callback with status ${statusCode}`);
377
429
  result.sendTelemetryAfterResponse(statusCode, errorMessage);
378
430
  });
379
431
  res.on("close", () => {
380
432
  if (!res.writableEnded) {
433
+ debugLog2(telemetry, "handler", "\u274C Response closed without finishing");
434
+ debugLog2(telemetry, "callback", "\u{1F4E4} Calling telemetry callback with error");
381
435
  result.sendTelemetryAfterResponse(500, "Response closed without finishing");
382
436
  }
383
437
  });
438
+ } else {
439
+ debugLog2(telemetry, "callback", "\u26A0\uFE0F No telemetry callback to call");
384
440
  }
385
441
  next();
386
442
  };
package/dist/index.d.cts CHANGED
@@ -1,10 +1,10 @@
1
1
  export { A as AssetConfig, a as Authorization, E as EIP1193Provider, N as NetworkId, d as PaymentHeaderBase64, c as PaymentHeaderObject, b as PaymentHeaderPayload, P as PaymentRequirements } from './types-BFUqKBBO.cjs';
2
2
  export { M as MANTLE_DEFAULTS } from './constants-CsIL25uQ.cjs';
3
- export { M as MantleMiddleware, e as MinimalPaywallOptions, P as PaymentLogEntry, d as PaymentMiddlewareConfig, R as RouteKey, a as RoutePricingConfig, b as RoutesConfig, T as TelemetryConfig, c as TelemetryEvent } from './types-X6DeBEgb.cjs';
4
- export { c as createPaymentMiddleware, m as mantlePaywall } from './express-DqyVgO5n.cjs';
3
+ export { M as MantleMiddleware, e as MinimalPaywallOptions, P as PaymentLogEntry, d as PaymentMiddlewareConfig, R as RouteKey, a as RoutePricingConfig, b as RoutesConfig, T as TelemetryConfig, c as TelemetryEvent } from './types-DrBw0xwj.cjs';
4
+ export { c as createPaymentMiddleware, m as mantlePaywall } from './express-BWE0nQty.cjs';
5
5
  export { C as CallWithPaymentResult, M as MantleClient, a as MantleClientConfig, b as PaymentClient, P as PaymentClientConfig, c as createMantleClient } from './createMantleClient-CO0uWPb-.cjs';
6
6
  export { createPaymentClient } from './client.cjs';
7
7
  export { UseEthersWalletOptions, UseEthersWalletReturn, UseMantleX402Options, useEthersWallet, useMantleX402 } from './react.cjs';
8
8
  import 'express';
9
- import './types-B87bD2yo.cjs';
9
+ import './types-BkGUHT4x.cjs';
10
10
  import 'ethers';
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  export { A as AssetConfig, a as Authorization, E as EIP1193Provider, N as NetworkId, d as PaymentHeaderBase64, c as PaymentHeaderObject, b as PaymentHeaderPayload, P as PaymentRequirements } from './types-BFUqKBBO.js';
2
2
  export { M as MANTLE_DEFAULTS } from './constants-0ncqvV_O.js';
3
- export { M as MantleMiddleware, e as MinimalPaywallOptions, P as PaymentLogEntry, d as PaymentMiddlewareConfig, R as RouteKey, a as RoutePricingConfig, b as RoutesConfig, T as TelemetryConfig, c as TelemetryEvent } from './types-DvKDSdL6.js';
4
- export { c as createPaymentMiddleware, m as mantlePaywall } from './express-DxxlKmmF.js';
3
+ export { M as MantleMiddleware, e as MinimalPaywallOptions, P as PaymentLogEntry, d as PaymentMiddlewareConfig, R as RouteKey, a as RoutePricingConfig, b as RoutesConfig, T as TelemetryConfig, c as TelemetryEvent } from './types-DEpSrXCf.js';
4
+ export { c as createPaymentMiddleware, m as mantlePaywall } from './express-BvuN0Lx1.js';
5
5
  export { C as CallWithPaymentResult, M as MantleClient, a as MantleClientConfig, b as PaymentClient, P as PaymentClientConfig, c as createMantleClient } from './createMantleClient-CuiPsTa6.js';
6
6
  export { createPaymentClient } from './client.js';
7
7
  export { UseEthersWalletOptions, UseEthersWalletReturn, UseMantleX402Options, useEthersWallet, useMantleX402 } from './react.js';
8
8
  import 'express';
9
- import './types-vicT7qsY.js';
9
+ import './types-Ba0v9XsC.js';
10
10
  import 'ethers';
package/dist/index.js CHANGED
@@ -10,8 +10,8 @@ import "./chunk-WO2MYZXT.js";
10
10
  import {
11
11
  createPaymentMiddleware,
12
12
  mantlePaywall
13
- } from "./chunk-IEJB5W26.js";
14
- import "./chunk-IXIFGPJ2.js";
13
+ } from "./chunk-3DGAB7HD.js";
14
+ import "./chunk-UVYA6H32.js";
15
15
  import {
16
16
  MANTLE_DEFAULTS
17
17
  } from "./chunk-HEZZ74SI.js";
@@ -0,0 +1,89 @@
1
+ import { NextRequest } from 'next/server';
2
+ import { M as MinimalPaywallOptions } from './types-BkGUHT4x.cjs';
3
+ import { P as PaymentRequirements } from './types-BFUqKBBO.cjs';
4
+
5
+ /**
6
+ * Error response returned when payment verification fails.
7
+ * This can be due to missing payment, invalid payment, or verification errors.
8
+ */
9
+ interface PaywallErrorResponse {
10
+ error: string;
11
+ paymentRequirements?: PaymentRequirements;
12
+ paymentHeader?: null;
13
+ invalidReason?: string | null;
14
+ details?: string;
15
+ }
16
+ /**
17
+ * Simple promise-or-value helper.
18
+ */
19
+ type Awaitable<T> = T | Promise<T>;
20
+ /**
21
+ * Next.js App Router route handler type.
22
+ *
23
+ * Accepts anything that is a valid `Response` to avoid forcing users
24
+ * to annotate union bodies on every handler.
25
+ */
26
+ type NextJSHandler = (req: NextRequest) => Awaitable<Response>;
27
+ /**
28
+ * Wrapper function that adds x402 payment verification to Next.js route handler.
29
+ * Returns a handler that may return either the original handler's response
30
+ * or a PaywallErrorResponse if payment verification fails.
31
+ */
32
+ type NextJSPaywallWrapper = (handler: NextJSHandler) => NextJSHandler;
33
+ /**
34
+ * Create Next.js App Router middleware for x402 payment verification.
35
+ * Uses Mantle mainnet defaults (USDC, exact scheme, etc.).
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * // app/api/generate-image/route.ts
40
+ * import { mantlePaywall } from '@puga-labs/x402-mantle-sdk/server/nextjs'
41
+ *
42
+ * const pay = mantlePaywall({
43
+ * priceUsd: 0.01,
44
+ * payTo: process.env.PAY_TO!,
45
+ * });
46
+ *
47
+ * // No 'as any' needed! TypeScript correctly infers the union type
48
+ * export const POST = pay(async (req: NextRequest) => {
49
+ * const { prompt } = await req.json();
50
+ * // Your handler code here
51
+ * return NextResponse.json({ success: true, imageUrl: "..." });
52
+ * });
53
+ * // TypeScript knows POST returns: NextResponse<{ success: boolean; imageUrl: string } | PaywallErrorResponse>
54
+ * ```
55
+ *
56
+ * @param opts - Minimal configuration (price, payTo, optional facilitator/telemetry).
57
+ * @returns Function that wraps Next.js route handlers with payment verification.
58
+ */
59
+ declare function mantlePaywall(opts: MinimalPaywallOptions): NextJSPaywallWrapper;
60
+ /**
61
+ * Type guard to check if a response is a paywall error response.
62
+ * Useful for handling the union type returned by the paywall wrapper.
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const response = await fetch('/api/protected');
67
+ * const data = await response.json();
68
+ *
69
+ * if (isPaywallErrorResponse(data)) {
70
+ * // Handle error: data.error, data.paymentRequirements, etc.
71
+ * console.error('Payment required:', data.paymentRequirements);
72
+ * } else {
73
+ * // Handle success: data has type T
74
+ * console.log('Success:', data);
75
+ * }
76
+ * ```
77
+ */
78
+ declare function isPaywallErrorResponse(response: unknown): response is PaywallErrorResponse;
79
+
80
+ type nextjs_NextJSHandler = NextJSHandler;
81
+ type nextjs_NextJSPaywallWrapper = NextJSPaywallWrapper;
82
+ type nextjs_PaywallErrorResponse = PaywallErrorResponse;
83
+ declare const nextjs_isPaywallErrorResponse: typeof isPaywallErrorResponse;
84
+ declare const nextjs_mantlePaywall: typeof mantlePaywall;
85
+ declare namespace nextjs {
86
+ export { type nextjs_NextJSHandler as NextJSHandler, type nextjs_NextJSPaywallWrapper as NextJSPaywallWrapper, type nextjs_PaywallErrorResponse as PaywallErrorResponse, nextjs_isPaywallErrorResponse as isPaywallErrorResponse, nextjs_mantlePaywall as mantlePaywall };
87
+ }
88
+
89
+ export { type NextJSHandler as N, type PaywallErrorResponse as P, type NextJSPaywallWrapper as a, isPaywallErrorResponse as i, mantlePaywall as m, nextjs as n };
@@ -0,0 +1,89 @@
1
+ import { NextRequest } from 'next/server';
2
+ import { M as MinimalPaywallOptions } from './types-Ba0v9XsC.js';
3
+ import { P as PaymentRequirements } from './types-BFUqKBBO.js';
4
+
5
+ /**
6
+ * Error response returned when payment verification fails.
7
+ * This can be due to missing payment, invalid payment, or verification errors.
8
+ */
9
+ interface PaywallErrorResponse {
10
+ error: string;
11
+ paymentRequirements?: PaymentRequirements;
12
+ paymentHeader?: null;
13
+ invalidReason?: string | null;
14
+ details?: string;
15
+ }
16
+ /**
17
+ * Simple promise-or-value helper.
18
+ */
19
+ type Awaitable<T> = T | Promise<T>;
20
+ /**
21
+ * Next.js App Router route handler type.
22
+ *
23
+ * Accepts anything that is a valid `Response` to avoid forcing users
24
+ * to annotate union bodies on every handler.
25
+ */
26
+ type NextJSHandler = (req: NextRequest) => Awaitable<Response>;
27
+ /**
28
+ * Wrapper function that adds x402 payment verification to Next.js route handler.
29
+ * Returns a handler that may return either the original handler's response
30
+ * or a PaywallErrorResponse if payment verification fails.
31
+ */
32
+ type NextJSPaywallWrapper = (handler: NextJSHandler) => NextJSHandler;
33
+ /**
34
+ * Create Next.js App Router middleware for x402 payment verification.
35
+ * Uses Mantle mainnet defaults (USDC, exact scheme, etc.).
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * // app/api/generate-image/route.ts
40
+ * import { mantlePaywall } from '@puga-labs/x402-mantle-sdk/server/nextjs'
41
+ *
42
+ * const pay = mantlePaywall({
43
+ * priceUsd: 0.01,
44
+ * payTo: process.env.PAY_TO!,
45
+ * });
46
+ *
47
+ * // No 'as any' needed! TypeScript correctly infers the union type
48
+ * export const POST = pay(async (req: NextRequest) => {
49
+ * const { prompt } = await req.json();
50
+ * // Your handler code here
51
+ * return NextResponse.json({ success: true, imageUrl: "..." });
52
+ * });
53
+ * // TypeScript knows POST returns: NextResponse<{ success: boolean; imageUrl: string } | PaywallErrorResponse>
54
+ * ```
55
+ *
56
+ * @param opts - Minimal configuration (price, payTo, optional facilitator/telemetry).
57
+ * @returns Function that wraps Next.js route handlers with payment verification.
58
+ */
59
+ declare function mantlePaywall(opts: MinimalPaywallOptions): NextJSPaywallWrapper;
60
+ /**
61
+ * Type guard to check if a response is a paywall error response.
62
+ * Useful for handling the union type returned by the paywall wrapper.
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const response = await fetch('/api/protected');
67
+ * const data = await response.json();
68
+ *
69
+ * if (isPaywallErrorResponse(data)) {
70
+ * // Handle error: data.error, data.paymentRequirements, etc.
71
+ * console.error('Payment required:', data.paymentRequirements);
72
+ * } else {
73
+ * // Handle success: data has type T
74
+ * console.log('Success:', data);
75
+ * }
76
+ * ```
77
+ */
78
+ declare function isPaywallErrorResponse(response: unknown): response is PaywallErrorResponse;
79
+
80
+ type nextjs_NextJSHandler = NextJSHandler;
81
+ type nextjs_NextJSPaywallWrapper = NextJSPaywallWrapper;
82
+ type nextjs_PaywallErrorResponse = PaywallErrorResponse;
83
+ declare const nextjs_isPaywallErrorResponse: typeof isPaywallErrorResponse;
84
+ declare const nextjs_mantlePaywall: typeof mantlePaywall;
85
+ declare namespace nextjs {
86
+ export { type nextjs_NextJSHandler as NextJSHandler, type nextjs_NextJSPaywallWrapper as NextJSPaywallWrapper, type nextjs_PaywallErrorResponse as PaywallErrorResponse, nextjs_isPaywallErrorResponse as isPaywallErrorResponse, nextjs_mantlePaywall as mantlePaywall };
87
+ }
88
+
89
+ export { type NextJSHandler as N, type PaywallErrorResponse as P, type NextJSPaywallWrapper as a, isPaywallErrorResponse as i, mantlePaywall as m, nextjs as n };
@@ -137,9 +137,20 @@ function createTelemetryEvent(entry, config) {
137
137
  priceUsd: entry.paymentRequirements?.price
138
138
  };
139
139
  }
140
- async function sendTelemetry(event, endpoint) {
140
+ async function sendTelemetry(event, endpoint, debug) {
141
141
  const targetEndpoint = endpoint ?? DEFAULT_TELEMETRY_ENDPOINT;
142
+ if (debug) {
143
+ console.log(`[x402-debug:telemetry] \u{1F4E4} Sending telemetry event:`, {
144
+ event: event.event,
145
+ endpoint: targetEndpoint,
146
+ projectKey: event.projectKey.substring(0, 10) + "...",
147
+ route: event.route,
148
+ responseStatus: event.responseStatus,
149
+ serviceDelivered: event.serviceDelivered
150
+ });
151
+ }
142
152
  if (!targetEndpoint) {
153
+ if (debug) console.log(`[x402-debug:telemetry] \u26A0\uFE0F No endpoint configured, skipping`);
143
154
  return;
144
155
  }
145
156
  try {
@@ -151,17 +162,29 @@ async function sendTelemetry(event, endpoint) {
151
162
  },
152
163
  body: JSON.stringify(event)
153
164
  });
165
+ if (debug) {
166
+ console.log(`[x402-debug:telemetry] ${response.ok ? "\u2705" : "\u274C"} Telemetry sent: HTTP ${response.status}`);
167
+ }
154
168
  if (!response.ok) {
155
169
  console.warn(
156
170
  `[x402-telemetry] Failed to send event: HTTP ${response.status}`
157
171
  );
158
172
  }
159
173
  } catch (err) {
174
+ if (debug) {
175
+ console.error(`[x402-debug:telemetry] \u274C Error sending:`, err);
176
+ }
160
177
  console.error("[x402-telemetry] Error sending telemetry:", err);
161
178
  }
162
179
  }
163
180
 
164
181
  // src/server/core/verifyPayment.ts
182
+ function debugLog(config, prefix, message, data) {
183
+ if (config?.debug) {
184
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
185
+ console.log(`[${timestamp}] [x402-debug:${prefix}]`, message, data || "");
186
+ }
187
+ }
165
188
  async function checkPayment(input) {
166
189
  const {
167
190
  paymentHeader,
@@ -249,6 +272,10 @@ async function checkPayment(input) {
249
272
  facilitatorUrl,
250
273
  paymentRequirements
251
274
  };
275
+ debugLog(telemetry, "verify", "\u2705 Payment verified", {
276
+ nonce: authorization.nonce,
277
+ route: routeKey
278
+ });
252
279
  if (onPaymentSettled) {
253
280
  onPaymentSettled(baseLogEntry);
254
281
  }
@@ -261,17 +288,33 @@ async function checkPayment(input) {
261
288
  }
262
289
  const sendTelemetryAfterResponse = telemetry && baseLogEntry ? (responseStatus, error) => {
263
290
  try {
291
+ debugLog(telemetry, "callback", "\u{1F4E4} Telemetry callback invoked", {
292
+ responseStatus,
293
+ hasError: !!error
294
+ });
264
295
  const event = createTelemetryEvent(baseLogEntry, telemetry);
265
296
  event.responseStatus = responseStatus;
266
297
  event.errorMessage = error;
267
298
  event.serviceDelivered = responseStatus >= 200 && responseStatus < 300;
268
- sendTelemetry(event, telemetry.endpoint).catch(
299
+ sendTelemetry(event, telemetry.endpoint, telemetry.debug).catch(
269
300
  (err) => console.error("[x402-telemetry] Async send failed:", err)
270
301
  );
271
302
  } catch (err) {
272
303
  console.error("[x402-telemetry] Error creating telemetry event:", err);
273
304
  }
274
305
  } : void 0;
306
+ if (telemetry && baseLogEntry) {
307
+ debugLog(telemetry, "callback", "\u2705 Telemetry callback created", {
308
+ route: routeKey,
309
+ hasTelemetryConfig: !!telemetry,
310
+ hasLogEntry: !!baseLogEntry
311
+ });
312
+ } else if (telemetry) {
313
+ debugLog(telemetry, "callback", "\u26A0\uFE0F Telemetry callback NOT created", {
314
+ hasTelemetryConfig: !!telemetry,
315
+ hasLogEntry: !!baseLogEntry
316
+ });
317
+ }
275
318
  return {
276
319
  status: "verified",
277
320
  statusCode: 200,
@@ -298,6 +341,12 @@ async function checkPayment(input) {
298
341
  }
299
342
 
300
343
  // src/server/adapters/express.ts
344
+ function debugLog2(config, prefix, message, data) {
345
+ if (config?.debug) {
346
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
347
+ console.log(`[${timestamp}] [x402-debug:${prefix}]`, message, data || "");
348
+ }
349
+ }
301
350
  function createPaymentMiddleware(config) {
302
351
  const { facilitatorUrl, receiverAddress, routes, apiKey, onPaymentSettled, telemetry } = config;
303
352
  if (!facilitatorUrl) {
@@ -348,17 +397,24 @@ function createPaymentMiddleware(config) {
348
397
  res.status(result.statusCode).json(result.responseBody);
349
398
  return;
350
399
  }
400
+ debugLog2(telemetry, "handler", "\u25B6\uFE0F Handler execution started (Express middleware)");
351
401
  if (result.sendTelemetryAfterResponse) {
352
402
  res.on("finish", () => {
353
403
  const statusCode = res.statusCode;
404
+ debugLog2(telemetry, "handler", `\u2705 Handler completed: ${statusCode}`);
354
405
  const errorMessage = statusCode >= 400 ? `Handler returned ${statusCode}` : void 0;
406
+ debugLog2(telemetry, "callback", `\u{1F4E4} Calling telemetry callback with status ${statusCode}`);
355
407
  result.sendTelemetryAfterResponse(statusCode, errorMessage);
356
408
  });
357
409
  res.on("close", () => {
358
410
  if (!res.writableEnded) {
411
+ debugLog2(telemetry, "handler", "\u274C Response closed without finishing");
412
+ debugLog2(telemetry, "callback", "\u{1F4E4} Calling telemetry callback with error");
359
413
  result.sendTelemetryAfterResponse(500, "Response closed without finishing");
360
414
  }
361
415
  });
416
+ } else {
417
+ debugLog2(telemetry, "callback", "\u26A0\uFE0F No telemetry callback to call");
362
418
  }
363
419
  next();
364
420
  };
@@ -1,5 +1,5 @@
1
- export { M as MantleMiddleware, P as PaymentMiddlewareConfig, c as createPaymentMiddleware, m as mantlePaywall } from './express-DqyVgO5n.cjs';
2
- export { M as MinimalPaywallOptions, c as PaymentCheckInput, d as PaymentCheckResult, P as PaymentLogEntry, R as RouteKey, a as RoutePricingConfig, b as RoutesConfig, T as TelemetryConfig } from './types-B87bD2yo.cjs';
1
+ export { M as MantleMiddleware, P as PaymentMiddlewareConfig, c as createPaymentMiddleware, m as mantlePaywall } from './express-BWE0nQty.cjs';
2
+ export { M as MinimalPaywallOptions, c as PaymentCheckInput, d as PaymentCheckResult, P as PaymentLogEntry, R as RouteKey, a as RoutePricingConfig, b as RoutesConfig, T as TelemetryConfig } from './types-BkGUHT4x.cjs';
3
3
  export { A as AssetConfig, a as Authorization, E as EIP1193Provider, N as NetworkId, d as PaymentHeaderBase64, c as PaymentHeaderObject, b as PaymentHeaderPayload, P as PaymentRequirements } from './types-BFUqKBBO.cjs';
4
4
  export { M as MANTLE_DEFAULTS } from './constants-CsIL25uQ.cjs';
5
5
  import 'express';
@@ -1,5 +1,5 @@
1
- export { M as MantleMiddleware, P as PaymentMiddlewareConfig, c as createPaymentMiddleware, m as mantlePaywall } from './express-DxxlKmmF.js';
2
- export { M as MinimalPaywallOptions, c as PaymentCheckInput, d as PaymentCheckResult, P as PaymentLogEntry, R as RouteKey, a as RoutePricingConfig, b as RoutesConfig, T as TelemetryConfig } from './types-vicT7qsY.js';
1
+ export { M as MantleMiddleware, P as PaymentMiddlewareConfig, c as createPaymentMiddleware, m as mantlePaywall } from './express-BvuN0Lx1.js';
2
+ export { M as MinimalPaywallOptions, c as PaymentCheckInput, d as PaymentCheckResult, P as PaymentLogEntry, R as RouteKey, a as RoutePricingConfig, b as RoutesConfig, T as TelemetryConfig } from './types-Ba0v9XsC.js';
3
3
  export { A as AssetConfig, a as Authorization, E as EIP1193Provider, N as NetworkId, d as PaymentHeaderBase64, c as PaymentHeaderObject, b as PaymentHeaderPayload, P as PaymentRequirements } from './types-BFUqKBBO.js';
4
4
  export { M as MANTLE_DEFAULTS } from './constants-0ncqvV_O.js';
5
5
  import 'express';
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  createPaymentMiddleware,
3
3
  mantlePaywall
4
- } from "./chunk-IEJB5W26.js";
5
- import "./chunk-IXIFGPJ2.js";
4
+ } from "./chunk-3DGAB7HD.js";
5
+ import "./chunk-UVYA6H32.js";
6
6
  import {
7
7
  MANTLE_DEFAULTS
8
8
  } from "./chunk-HEZZ74SI.js";