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

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 (49) hide show
  1. package/dist/chunk-33WHNZDS.js +74 -0
  2. package/dist/chunk-B4GST723.js +101 -0
  3. package/dist/chunk-CKBTOS7X.js +86 -0
  4. package/dist/chunk-IEJB5W26.js +113 -0
  5. package/dist/chunk-IXIFGPJ2.js +250 -0
  6. package/dist/chunk-OW2BDRGZ.js +239 -0
  7. package/dist/chunk-T4DIHTBP.js +83 -0
  8. package/dist/chunk-T63MVWX3.js +71 -0
  9. package/dist/express-D8L5Dg1D.d.ts +68 -0
  10. package/dist/express-DqyVgO5n.d.cts +68 -0
  11. package/dist/express-DxxlKmmF.d.ts +68 -0
  12. package/dist/express-Pukmnwuu.d.cts +68 -0
  13. package/dist/index.cjs +39 -12
  14. package/dist/index.d.cts +3 -3
  15. package/dist/index.d.ts +3 -3
  16. package/dist/index.js +2 -2
  17. package/dist/nextjs-CSUWjcxv.d.cts +89 -0
  18. package/dist/nextjs-DGcN_MGa.d.ts +89 -0
  19. package/dist/nextjs-DUdgN0d_.d.ts +89 -0
  20. package/dist/nextjs-EoISXVEo.d.cts +89 -0
  21. package/dist/server-express.cjs +39 -12
  22. package/dist/server-express.d.cts +2 -2
  23. package/dist/server-express.d.ts +2 -2
  24. package/dist/server-express.js +2 -2
  25. package/dist/server-nextjs.cjs +38 -12
  26. package/dist/server-nextjs.d.cts +2 -2
  27. package/dist/server-nextjs.d.ts +2 -2
  28. package/dist/server-nextjs.js +2 -2
  29. package/dist/server-web.cjs +38 -12
  30. package/dist/server-web.d.cts +2 -2
  31. package/dist/server-web.d.ts +2 -2
  32. package/dist/server-web.js +2 -2
  33. package/dist/server.cjs +69 -16
  34. package/dist/server.d.cts +6 -6
  35. package/dist/server.d.ts +6 -6
  36. package/dist/server.js +4 -4
  37. package/dist/types-B87bD2yo.d.cts +102 -0
  38. package/dist/types-BWfKovFm.d.cts +103 -0
  39. package/dist/types-BmK0G74m.d.cts +93 -0
  40. package/dist/types-CXdNC0Ra.d.ts +93 -0
  41. package/dist/types-DgfVPQFb.d.ts +103 -0
  42. package/dist/types-DvKDSdL6.d.ts +106 -0
  43. package/dist/types-X6DeBEgb.d.cts +106 -0
  44. package/dist/types-vicT7qsY.d.ts +102 -0
  45. package/dist/web-standards-BJcdcxD6.d.ts +77 -0
  46. package/dist/web-standards-BvMLEKlU.d.cts +77 -0
  47. package/dist/web-standards-C6JwCDmd.d.cts +77 -0
  48. package/dist/web-standards-g2rYUpgc.d.ts +77 -0
  49. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -189,6 +189,7 @@ async function checkPayment(input) {
189
189
  paymentHeader,
190
190
  paymentRequirements,
191
191
  facilitatorUrl,
192
+ apiKey,
192
193
  routeKey,
193
194
  network,
194
195
  asset,
@@ -212,7 +213,8 @@ async function checkPayment(input) {
212
213
  const verifyRes = await fetch(verifyUrl, {
213
214
  method: "POST",
214
215
  headers: {
215
- "Content-Type": "application/json"
216
+ "Content-Type": "application/json",
217
+ ...apiKey && { "Authorization": `Bearer ${apiKey}` }
216
218
  },
217
219
  body: JSON.stringify({
218
220
  x402Version: 1,
@@ -251,12 +253,13 @@ async function checkPayment(input) {
251
253
  isValid: false
252
254
  };
253
255
  }
254
- if (onPaymentSettled) {
256
+ let baseLogEntry = null;
257
+ if (onPaymentSettled || telemetry) {
255
258
  try {
256
259
  const headerObj = decodePaymentHeader(paymentHeader);
257
260
  const { authorization } = headerObj.payload;
258
261
  const assetConfig = getDefaultAssetForNetwork(network);
259
- const logEntry = {
262
+ baseLogEntry = {
260
263
  id: authorization.nonce,
261
264
  from: authorization.from,
262
265
  to: authorization.to,
@@ -268,12 +271,8 @@ async function checkPayment(input) {
268
271
  facilitatorUrl,
269
272
  paymentRequirements
270
273
  };
271
- onPaymentSettled(logEntry);
272
- if (telemetry) {
273
- const event = createTelemetryEvent(logEntry, telemetry);
274
- sendTelemetry(event, telemetry.endpoint).catch(
275
- (err) => console.error("[x402-telemetry] Async send failed:", err)
276
- );
274
+ if (onPaymentSettled) {
275
+ onPaymentSettled(baseLogEntry);
277
276
  }
278
277
  } catch (err) {
279
278
  console.error(
@@ -282,11 +281,25 @@ async function checkPayment(input) {
282
281
  );
283
282
  }
284
283
  }
284
+ const sendTelemetryAfterResponse = telemetry && baseLogEntry ? (responseStatus, error) => {
285
+ try {
286
+ const event = createTelemetryEvent(baseLogEntry, telemetry);
287
+ event.responseStatus = responseStatus;
288
+ event.errorMessage = error;
289
+ event.serviceDelivered = responseStatus >= 200 && responseStatus < 300;
290
+ sendTelemetry(event, telemetry.endpoint).catch(
291
+ (err) => console.error("[x402-telemetry] Async send failed:", err)
292
+ );
293
+ } catch (err) {
294
+ console.error("[x402-telemetry] Error creating telemetry event:", err);
295
+ }
296
+ } : void 0;
285
297
  return {
286
298
  status: "verified",
287
299
  statusCode: 200,
288
300
  responseBody: null,
289
- isValid: true
301
+ isValid: true,
302
+ sendTelemetryAfterResponse
290
303
  };
291
304
  } catch (err) {
292
305
  console.error(
@@ -308,7 +321,7 @@ async function checkPayment(input) {
308
321
 
309
322
  // src/server/adapters/express.ts
310
323
  function createPaymentMiddleware(config) {
311
- const { facilitatorUrl, receiverAddress, routes, onPaymentSettled, telemetry } = config;
324
+ const { facilitatorUrl, receiverAddress, routes, apiKey, onPaymentSettled, telemetry } = config;
312
325
  if (!facilitatorUrl) {
313
326
  throw new Error("facilitatorUrl is required");
314
327
  }
@@ -346,6 +359,7 @@ function createPaymentMiddleware(config) {
346
359
  paymentHeader,
347
360
  paymentRequirements,
348
361
  facilitatorUrl,
362
+ apiKey,
349
363
  routeKey,
350
364
  network,
351
365
  asset: assetConfig.address,
@@ -356,11 +370,23 @@ function createPaymentMiddleware(config) {
356
370
  res.status(result.statusCode).json(result.responseBody);
357
371
  return;
358
372
  }
373
+ if (result.sendTelemetryAfterResponse) {
374
+ res.on("finish", () => {
375
+ const statusCode = res.statusCode;
376
+ const errorMessage = statusCode >= 400 ? `Handler returned ${statusCode}` : void 0;
377
+ result.sendTelemetryAfterResponse(statusCode, errorMessage);
378
+ });
379
+ res.on("close", () => {
380
+ if (!res.writableEnded) {
381
+ result.sendTelemetryAfterResponse(500, "Response closed without finishing");
382
+ }
383
+ });
384
+ }
359
385
  next();
360
386
  };
361
387
  }
362
388
  function mantlePaywall(opts) {
363
- const { priceUsd, payTo, facilitatorUrl, telemetry, onPaymentSettled } = opts;
389
+ const { priceUsd, payTo, facilitatorUrl, apiKey, telemetry, onPaymentSettled } = opts;
364
390
  validateAddress(payTo, "payTo");
365
391
  const priceUsdCents = Math.round(priceUsd * 100);
366
392
  return async (req, res, next) => {
@@ -376,6 +402,7 @@ function mantlePaywall(opts) {
376
402
  network: MANTLE_DEFAULTS.NETWORK
377
403
  }
378
404
  },
405
+ apiKey,
379
406
  telemetry,
380
407
  onPaymentSettled
381
408
  });
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-CoOdbZSp.cjs';
4
- export { c as createPaymentMiddleware, m as mantlePaywall } from './express-eQOPxfnI.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';
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-CrOsOHcX.cjs';
9
+ import './types-B87bD2yo.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-DTzov_EE.js';
4
- export { c as createPaymentMiddleware, m as mantlePaywall } from './express-D8EwEcOL.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';
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-CqQ6OgRi.js';
9
+ import './types-vicT7qsY.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-MBJTUNDL.js";
14
- import "./chunk-EKEVUVF3.js";
13
+ } from "./chunk-IEJB5W26.js";
14
+ import "./chunk-IXIFGPJ2.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-BmK0G74m.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-vicT7qsY.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 };
@@ -0,0 +1,89 @@
1
+ import { NextRequest } from 'next/server';
2
+ import { M as MinimalPaywallOptions } from './types-CXdNC0Ra.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 };
@@ -0,0 +1,89 @@
1
+ import { NextRequest } from 'next/server';
2
+ import { M as MinimalPaywallOptions } from './types-B87bD2yo.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 };
@@ -167,6 +167,7 @@ async function checkPayment(input) {
167
167
  paymentHeader,
168
168
  paymentRequirements,
169
169
  facilitatorUrl,
170
+ apiKey,
170
171
  routeKey,
171
172
  network,
172
173
  asset,
@@ -190,7 +191,8 @@ async function checkPayment(input) {
190
191
  const verifyRes = await fetch(verifyUrl, {
191
192
  method: "POST",
192
193
  headers: {
193
- "Content-Type": "application/json"
194
+ "Content-Type": "application/json",
195
+ ...apiKey && { "Authorization": `Bearer ${apiKey}` }
194
196
  },
195
197
  body: JSON.stringify({
196
198
  x402Version: 1,
@@ -229,12 +231,13 @@ async function checkPayment(input) {
229
231
  isValid: false
230
232
  };
231
233
  }
232
- if (onPaymentSettled) {
234
+ let baseLogEntry = null;
235
+ if (onPaymentSettled || telemetry) {
233
236
  try {
234
237
  const headerObj = decodePaymentHeader(paymentHeader);
235
238
  const { authorization } = headerObj.payload;
236
239
  const assetConfig = getDefaultAssetForNetwork(network);
237
- const logEntry = {
240
+ baseLogEntry = {
238
241
  id: authorization.nonce,
239
242
  from: authorization.from,
240
243
  to: authorization.to,
@@ -246,12 +249,8 @@ async function checkPayment(input) {
246
249
  facilitatorUrl,
247
250
  paymentRequirements
248
251
  };
249
- onPaymentSettled(logEntry);
250
- if (telemetry) {
251
- const event = createTelemetryEvent(logEntry, telemetry);
252
- sendTelemetry(event, telemetry.endpoint).catch(
253
- (err) => console.error("[x402-telemetry] Async send failed:", err)
254
- );
252
+ if (onPaymentSettled) {
253
+ onPaymentSettled(baseLogEntry);
255
254
  }
256
255
  } catch (err) {
257
256
  console.error(
@@ -260,11 +259,25 @@ async function checkPayment(input) {
260
259
  );
261
260
  }
262
261
  }
262
+ const sendTelemetryAfterResponse = telemetry && baseLogEntry ? (responseStatus, error) => {
263
+ try {
264
+ const event = createTelemetryEvent(baseLogEntry, telemetry);
265
+ event.responseStatus = responseStatus;
266
+ event.errorMessage = error;
267
+ event.serviceDelivered = responseStatus >= 200 && responseStatus < 300;
268
+ sendTelemetry(event, telemetry.endpoint).catch(
269
+ (err) => console.error("[x402-telemetry] Async send failed:", err)
270
+ );
271
+ } catch (err) {
272
+ console.error("[x402-telemetry] Error creating telemetry event:", err);
273
+ }
274
+ } : void 0;
263
275
  return {
264
276
  status: "verified",
265
277
  statusCode: 200,
266
278
  responseBody: null,
267
- isValid: true
279
+ isValid: true,
280
+ sendTelemetryAfterResponse
268
281
  };
269
282
  } catch (err) {
270
283
  console.error(
@@ -286,7 +299,7 @@ async function checkPayment(input) {
286
299
 
287
300
  // src/server/adapters/express.ts
288
301
  function createPaymentMiddleware(config) {
289
- const { facilitatorUrl, receiverAddress, routes, onPaymentSettled, telemetry } = config;
302
+ const { facilitatorUrl, receiverAddress, routes, apiKey, onPaymentSettled, telemetry } = config;
290
303
  if (!facilitatorUrl) {
291
304
  throw new Error("facilitatorUrl is required");
292
305
  }
@@ -324,6 +337,7 @@ function createPaymentMiddleware(config) {
324
337
  paymentHeader,
325
338
  paymentRequirements,
326
339
  facilitatorUrl,
340
+ apiKey,
327
341
  routeKey,
328
342
  network,
329
343
  asset: assetConfig.address,
@@ -334,11 +348,23 @@ function createPaymentMiddleware(config) {
334
348
  res.status(result.statusCode).json(result.responseBody);
335
349
  return;
336
350
  }
351
+ if (result.sendTelemetryAfterResponse) {
352
+ res.on("finish", () => {
353
+ const statusCode = res.statusCode;
354
+ const errorMessage = statusCode >= 400 ? `Handler returned ${statusCode}` : void 0;
355
+ result.sendTelemetryAfterResponse(statusCode, errorMessage);
356
+ });
357
+ res.on("close", () => {
358
+ if (!res.writableEnded) {
359
+ result.sendTelemetryAfterResponse(500, "Response closed without finishing");
360
+ }
361
+ });
362
+ }
337
363
  next();
338
364
  };
339
365
  }
340
366
  function mantlePaywall(opts) {
341
- const { priceUsd, payTo, facilitatorUrl, telemetry, onPaymentSettled } = opts;
367
+ const { priceUsd, payTo, facilitatorUrl, apiKey, telemetry, onPaymentSettled } = opts;
342
368
  validateAddress(payTo, "payTo");
343
369
  const priceUsdCents = Math.round(priceUsd * 100);
344
370
  return async (req, res, next) => {
@@ -354,6 +380,7 @@ function mantlePaywall(opts) {
354
380
  network: MANTLE_DEFAULTS.NETWORK
355
381
  }
356
382
  },
383
+ apiKey,
357
384
  telemetry,
358
385
  onPaymentSettled
359
386
  });
@@ -1,5 +1,5 @@
1
- export { M as MantleMiddleware, P as PaymentMiddlewareConfig, c as createPaymentMiddleware, m as mantlePaywall } from './express-eQOPxfnI.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-CrOsOHcX.cjs';
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';
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-D8EwEcOL.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-CqQ6OgRi.js';
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';
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';