@parallel-protocol/x402 0.9.0 → 0.10.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/dist/hono.js CHANGED
@@ -1,5 +1,5 @@
1
- import { isJsonContentType, raceTimeout, HANDLER_TIMEOUT, jsonFromResponse, createPaymentMiddleware } from './chunk-G7HSURPM.js';
2
- import './chunk-QAECRSWF.js';
1
+ import { isJsonContentType, raceTimeout, HANDLER_TIMEOUT, jsonFromResponse, createPaymentMiddleware, preflightInit } from './chunk-CNASNROQ.js';
2
+ import './chunk-MZCHBBUN.js';
3
3
 
4
4
  // src/hono/adapter.ts
5
5
  var TIMEOUT_BODY = JSON.stringify({
@@ -36,6 +36,13 @@ var HonoAdapter = class {
36
36
  }
37
37
  }
38
38
  async runHandler(options) {
39
+ const headersBefore = new Headers(this.c.res.headers);
40
+ const replace = (body, status) => {
41
+ const headers = new Headers(headersBefore);
42
+ if (body !== null) headers.set("Content-Type", "application/json");
43
+ this.c.res = void 0;
44
+ this.c.res = new Response(body, { status, headers });
45
+ };
39
46
  const outcome = await raceTimeout(this.next(), options?.timeoutMs);
40
47
  if (outcome === HANDLER_TIMEOUT) {
41
48
  return {
@@ -45,12 +52,7 @@ var HonoAdapter = class {
45
52
  getResponseHeader: () => void 0,
46
53
  removeResponseHeader: () => {
47
54
  },
48
- sendResponse: () => {
49
- this.c.res = new Response(TIMEOUT_BODY, {
50
- status: 504,
51
- headers: { "Content-Type": "application/json" }
52
- });
53
- },
55
+ sendResponse: () => replace(TIMEOUT_BODY, 504),
54
56
  discardResponse: () => {
55
57
  }
56
58
  };
@@ -70,6 +72,7 @@ var HonoAdapter = class {
70
72
  discardResponse: () => {
71
73
  res.body?.cancel().catch(() => {
72
74
  });
75
+ replace(null);
73
76
  }
74
77
  };
75
78
  }
@@ -83,9 +86,14 @@ function paymentMiddleware(config) {
83
86
  if ("pass" in result) {
84
87
  if (result.handlerRan) return;
85
88
  await next();
89
+ if (result.preflight) {
90
+ const init = preflightInit(c.res);
91
+ c.res = void 0;
92
+ c.res = new Response(null, init);
93
+ }
86
94
  return;
87
95
  }
88
- return new Response(JSON.stringify(result.body), {
96
+ c.res = new Response(JSON.stringify(result.body), {
89
97
  status: result.status,
90
98
  headers: { ...result.headers, "Content-Type": "application/json" }
91
99
  });
package/dist/index.cjs CHANGED
@@ -1,83 +1,87 @@
1
1
  'use strict';
2
2
 
3
- var chunkTH77IB3T_cjs = require('./chunk-TH77IB3T.cjs');
4
- var chunkKZZY5LS6_cjs = require('./chunk-KZZY5LS6.cjs');
3
+ var chunkAYMDIX7A_cjs = require('./chunk-AYMDIX7A.cjs');
4
+ var chunk4CEMNRCZ_cjs = require('./chunk-4CEMNRCZ.cjs');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "FacilitatorClient", {
9
9
  enumerable: true,
10
- get: function () { return chunkTH77IB3T_cjs.FacilitatorClient; }
10
+ get: function () { return chunkAYMDIX7A_cjs.FacilitatorClient; }
11
11
  });
12
12
  Object.defineProperty(exports, "PARALLEL_TOKENS", {
13
13
  enumerable: true,
14
- get: function () { return chunkTH77IB3T_cjs.PARALLEL_TOKENS; }
14
+ get: function () { return chunkAYMDIX7A_cjs.PARALLEL_TOKENS; }
15
15
  });
16
16
  Object.defineProperty(exports, "SETTLE_AMOUNT_HEADER", {
17
17
  enumerable: true,
18
- get: function () { return chunkTH77IB3T_cjs.SETTLE_AMOUNT_HEADER; }
18
+ get: function () { return chunkAYMDIX7A_cjs.SETTLE_AMOUNT_HEADER; }
19
19
  });
20
20
  Object.defineProperty(exports, "createPaymentGate", {
21
21
  enumerable: true,
22
- get: function () { return chunkTH77IB3T_cjs.createPaymentGate; }
22
+ get: function () { return chunkAYMDIX7A_cjs.createPaymentGate; }
23
23
  });
24
24
  Object.defineProperty(exports, "createPaymentMiddleware", {
25
25
  enumerable: true,
26
- get: function () { return chunkTH77IB3T_cjs.createPaymentMiddleware; }
26
+ get: function () { return chunkAYMDIX7A_cjs.createPaymentMiddleware; }
27
27
  });
28
28
  Object.defineProperty(exports, "encodeBase64", {
29
29
  enumerable: true,
30
- get: function () { return chunkTH77IB3T_cjs.encodeBase64; }
30
+ get: function () { return chunkAYMDIX7A_cjs.encodeBase64; }
31
31
  });
32
32
  Object.defineProperty(exports, "getDefaultAcceptedTokens", {
33
33
  enumerable: true,
34
- get: function () { return chunkTH77IB3T_cjs.getDefaultAcceptedTokens; }
34
+ get: function () { return chunkAYMDIX7A_cjs.getDefaultAcceptedTokens; }
35
+ });
36
+ Object.defineProperty(exports, "normalizeRoutePath", {
37
+ enumerable: true,
38
+ get: function () { return chunkAYMDIX7A_cjs.normalizeRoutePath; }
35
39
  });
36
40
  Object.defineProperty(exports, "parsePrice", {
37
41
  enumerable: true,
38
- get: function () { return chunkTH77IB3T_cjs.parsePrice; }
42
+ get: function () { return chunkAYMDIX7A_cjs.parsePrice; }
39
43
  });
40
44
  Object.defineProperty(exports, "resolveCharge", {
41
45
  enumerable: true,
42
- get: function () { return chunkTH77IB3T_cjs.resolveCharge; }
46
+ get: function () { return chunkAYMDIX7A_cjs.resolveCharge; }
43
47
  });
44
48
  Object.defineProperty(exports, "resolveSettleAmount", {
45
49
  enumerable: true,
46
- get: function () { return chunkTH77IB3T_cjs.resolveSettleAmount; }
50
+ get: function () { return chunkAYMDIX7A_cjs.resolveSettleAmount; }
47
51
  });
48
52
  Object.defineProperty(exports, "settleVerified", {
49
53
  enumerable: true,
50
- get: function () { return chunkTH77IB3T_cjs.settleVerified; }
54
+ get: function () { return chunkAYMDIX7A_cjs.settleVerified; }
51
55
  });
52
56
  Object.defineProperty(exports, "settlementFailureResponse", {
53
57
  enumerable: true,
54
- get: function () { return chunkTH77IB3T_cjs.settlementFailureResponse; }
58
+ get: function () { return chunkAYMDIX7A_cjs.settlementFailureResponse; }
55
59
  });
56
60
  Object.defineProperty(exports, "toEip155Network", {
57
61
  enumerable: true,
58
- get: function () { return chunkTH77IB3T_cjs.toEip155Network; }
62
+ get: function () { return chunkAYMDIX7A_cjs.toEip155Network; }
59
63
  });
60
64
  Object.defineProperty(exports, "validateAddress", {
61
65
  enumerable: true,
62
- get: function () { return chunkTH77IB3T_cjs.validateAddress; }
66
+ get: function () { return chunkAYMDIX7A_cjs.validateAddress; }
63
67
  });
64
68
  Object.defineProperty(exports, "X402ConfigError", {
65
69
  enumerable: true,
66
- get: function () { return chunkKZZY5LS6_cjs.X402ConfigError; }
70
+ get: function () { return chunk4CEMNRCZ_cjs.X402ConfigError; }
67
71
  });
68
72
  Object.defineProperty(exports, "X402PriceRejectedError", {
69
73
  enumerable: true,
70
- get: function () { return chunkKZZY5LS6_cjs.X402PriceRejectedError; }
74
+ get: function () { return chunk4CEMNRCZ_cjs.X402PriceRejectedError; }
71
75
  });
72
76
  Object.defineProperty(exports, "X402RuntimeError", {
73
77
  enumerable: true,
74
- get: function () { return chunkKZZY5LS6_cjs.X402RuntimeError; }
78
+ get: function () { return chunk4CEMNRCZ_cjs.X402RuntimeError; }
75
79
  });
76
80
  Object.defineProperty(exports, "X402_ERROR_CODES", {
77
81
  enumerable: true,
78
- get: function () { return chunkKZZY5LS6_cjs.X402_ERROR_CODES; }
82
+ get: function () { return chunk4CEMNRCZ_cjs.X402_ERROR_CODES; }
79
83
  });
80
84
  Object.defineProperty(exports, "isPriceRejection", {
81
85
  enumerable: true,
82
- get: function () { return chunkKZZY5LS6_cjs.isPriceRejection; }
86
+ get: function () { return chunk4CEMNRCZ_cjs.isPriceRejection; }
83
87
  });
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FacilitatorConfig, b as FacilitatorPaymentRequirements, V as VerifyResult, c as FacilitatorSettleOptions, d as FacilitatorResponse, e as PaymentConfirmation, P as PaymentMiddlewareConfig, H as HTTPAdapter, f as PaymentGateResult, M as MiddlewareResult, g as PassResult, h as VerifiedPayment, S as SettleOptions } from './types-BkGQ2lPA.cjs';
2
- export { i as MeterContext, j as MeterFunction, k as PaymentFailure, l as PaymentRequired, m as PaymentRequirements, n as PriceContext, o as PriceFunction, p as ResourceInfo, q as RouteConfig, R as RunHandlerOptions, a as RunHandlerResult } from './types-BkGQ2lPA.cjs';
1
+ import { F as FacilitatorConfig, b as FacilitatorPaymentRequirements, V as VerifyResult, c as FacilitatorSettleOptions, d as FacilitatorResponse, e as PaymentConfirmation, P as PaymentMiddlewareConfig, H as HTTPAdapter, f as PaymentGateResult, M as MiddlewareResult, g as PassResult, h as VerifiedPayment, S as SettleOptions } from './types-CRBMTQaq.cjs';
2
+ export { i as MeterContext, j as MeterFunction, k as PaymentFailure, l as PaymentRequired, m as PaymentRequirements, n as PriceContext, o as PriceFunction, p as ResourceInfo, q as RouteConfig, R as RunHandlerOptions, a as RunHandlerResult } from './types-CRBMTQaq.cjs';
3
3
  import { Address } from 'viem';
4
4
 
5
5
  declare class FacilitatorClient {
@@ -20,6 +20,8 @@ declare const X402_ERROR_CODES: {
20
20
  readonly FACILITATOR_UNAVAILABLE: "FACILITATOR_UNAVAILABLE";
21
21
  readonly FACILITATOR_INVALID_RESPONSE: "FACILITATOR_INVALID_RESPONSE";
22
22
  readonly INVALID_PAYMENT: "INVALID_PAYMENT";
23
+ /** A path with `.` or `..` segments on a paid route, refused with 400. */
24
+ readonly INVALID_PATH: "INVALID_PATH";
23
25
  /** The facilitator did not answer a settle within the client's timeout: the payment may still settle. */
24
26
  readonly SETTLE_TIMEOUT: "SETTLE_TIMEOUT";
25
27
  };
@@ -59,7 +61,7 @@ declare class X402PriceRejectedError extends Error {
59
61
  */
60
62
  declare function isPriceRejection(error: unknown): error is X402PriceRejectedError;
61
63
 
62
- type GateAdapter = Pick<HTTPAdapter, "getHeader" | "getPath" | "getUrl" | "getMethod" | "getBody">;
64
+ type GateAdapter = Pick<HTTPAdapter, "getHeader" | "getPath" | "getFullPath" | "getUrl" | "getMethod" | "getBody">;
63
65
  /**
64
66
  * Response header a handler on a metered (`upto`) route sets to the amount it
65
67
  * actually charges, in whole token units like `price` ("0.75"). Read and
@@ -156,5 +158,7 @@ declare function parsePrice(price: string | bigint, decimals?: number): bigint;
156
158
  declare function validateAddress(address: string): address is Address;
157
159
  declare function toEip155Network(network: string): string;
158
160
  declare function encodeBase64(obj: unknown): string;
161
+ /** The form routes are matched on: `"/API//Data/"` becomes `"/api/data"`. */
162
+ declare function normalizeRoutePath(path: string): string;
159
163
 
160
- export { type ChargeResponse, FacilitatorClient, FacilitatorConfig, FacilitatorPaymentRequirements, FacilitatorResponse, FacilitatorSettleOptions, HTTPAdapter, MiddlewareResult, PARALLEL_TOKENS, type ParallelNetwork, PassResult, PaymentConfirmation, PaymentGateResult, PaymentMiddlewareConfig, SETTLE_AMOUNT_HEADER, type SettleAmountResolution, SettleOptions, type SettlementFailure, type SettlementFailureBody, type SettlementOutcome, VerifiedPayment, VerifyResult, X402ConfigError, type X402ErrorCode, X402PriceRejectedError, X402RuntimeError, X402_ERROR_CODES, createPaymentGate, createPaymentMiddleware, encodeBase64, getDefaultAcceptedTokens, isPriceRejection, parsePrice, resolveCharge, resolveSettleAmount, settleVerified, settlementFailureResponse, toEip155Network, validateAddress };
164
+ export { type ChargeResponse, FacilitatorClient, FacilitatorConfig, FacilitatorPaymentRequirements, FacilitatorResponse, FacilitatorSettleOptions, HTTPAdapter, MiddlewareResult, PARALLEL_TOKENS, type ParallelNetwork, PassResult, PaymentConfirmation, PaymentGateResult, PaymentMiddlewareConfig, SETTLE_AMOUNT_HEADER, type SettleAmountResolution, SettleOptions, type SettlementFailure, type SettlementFailureBody, type SettlementOutcome, VerifiedPayment, VerifyResult, X402ConfigError, type X402ErrorCode, X402PriceRejectedError, X402RuntimeError, X402_ERROR_CODES, createPaymentGate, createPaymentMiddleware, encodeBase64, getDefaultAcceptedTokens, isPriceRejection, normalizeRoutePath, parsePrice, resolveCharge, resolveSettleAmount, settleVerified, settlementFailureResponse, toEip155Network, validateAddress };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FacilitatorConfig, b as FacilitatorPaymentRequirements, V as VerifyResult, c as FacilitatorSettleOptions, d as FacilitatorResponse, e as PaymentConfirmation, P as PaymentMiddlewareConfig, H as HTTPAdapter, f as PaymentGateResult, M as MiddlewareResult, g as PassResult, h as VerifiedPayment, S as SettleOptions } from './types-BkGQ2lPA.js';
2
- export { i as MeterContext, j as MeterFunction, k as PaymentFailure, l as PaymentRequired, m as PaymentRequirements, n as PriceContext, o as PriceFunction, p as ResourceInfo, q as RouteConfig, R as RunHandlerOptions, a as RunHandlerResult } from './types-BkGQ2lPA.js';
1
+ import { F as FacilitatorConfig, b as FacilitatorPaymentRequirements, V as VerifyResult, c as FacilitatorSettleOptions, d as FacilitatorResponse, e as PaymentConfirmation, P as PaymentMiddlewareConfig, H as HTTPAdapter, f as PaymentGateResult, M as MiddlewareResult, g as PassResult, h as VerifiedPayment, S as SettleOptions } from './types-CRBMTQaq.js';
2
+ export { i as MeterContext, j as MeterFunction, k as PaymentFailure, l as PaymentRequired, m as PaymentRequirements, n as PriceContext, o as PriceFunction, p as ResourceInfo, q as RouteConfig, R as RunHandlerOptions, a as RunHandlerResult } from './types-CRBMTQaq.js';
3
3
  import { Address } from 'viem';
4
4
 
5
5
  declare class FacilitatorClient {
@@ -20,6 +20,8 @@ declare const X402_ERROR_CODES: {
20
20
  readonly FACILITATOR_UNAVAILABLE: "FACILITATOR_UNAVAILABLE";
21
21
  readonly FACILITATOR_INVALID_RESPONSE: "FACILITATOR_INVALID_RESPONSE";
22
22
  readonly INVALID_PAYMENT: "INVALID_PAYMENT";
23
+ /** A path with `.` or `..` segments on a paid route, refused with 400. */
24
+ readonly INVALID_PATH: "INVALID_PATH";
23
25
  /** The facilitator did not answer a settle within the client's timeout: the payment may still settle. */
24
26
  readonly SETTLE_TIMEOUT: "SETTLE_TIMEOUT";
25
27
  };
@@ -59,7 +61,7 @@ declare class X402PriceRejectedError extends Error {
59
61
  */
60
62
  declare function isPriceRejection(error: unknown): error is X402PriceRejectedError;
61
63
 
62
- type GateAdapter = Pick<HTTPAdapter, "getHeader" | "getPath" | "getUrl" | "getMethod" | "getBody">;
64
+ type GateAdapter = Pick<HTTPAdapter, "getHeader" | "getPath" | "getFullPath" | "getUrl" | "getMethod" | "getBody">;
63
65
  /**
64
66
  * Response header a handler on a metered (`upto`) route sets to the amount it
65
67
  * actually charges, in whole token units like `price` ("0.75"). Read and
@@ -156,5 +158,7 @@ declare function parsePrice(price: string | bigint, decimals?: number): bigint;
156
158
  declare function validateAddress(address: string): address is Address;
157
159
  declare function toEip155Network(network: string): string;
158
160
  declare function encodeBase64(obj: unknown): string;
161
+ /** The form routes are matched on: `"/API//Data/"` becomes `"/api/data"`. */
162
+ declare function normalizeRoutePath(path: string): string;
159
163
 
160
- export { type ChargeResponse, FacilitatorClient, FacilitatorConfig, FacilitatorPaymentRequirements, FacilitatorResponse, FacilitatorSettleOptions, HTTPAdapter, MiddlewareResult, PARALLEL_TOKENS, type ParallelNetwork, PassResult, PaymentConfirmation, PaymentGateResult, PaymentMiddlewareConfig, SETTLE_AMOUNT_HEADER, type SettleAmountResolution, SettleOptions, type SettlementFailure, type SettlementFailureBody, type SettlementOutcome, VerifiedPayment, VerifyResult, X402ConfigError, type X402ErrorCode, X402PriceRejectedError, X402RuntimeError, X402_ERROR_CODES, createPaymentGate, createPaymentMiddleware, encodeBase64, getDefaultAcceptedTokens, isPriceRejection, parsePrice, resolveCharge, resolveSettleAmount, settleVerified, settlementFailureResponse, toEip155Network, validateAddress };
164
+ export { type ChargeResponse, FacilitatorClient, FacilitatorConfig, FacilitatorPaymentRequirements, FacilitatorResponse, FacilitatorSettleOptions, HTTPAdapter, MiddlewareResult, PARALLEL_TOKENS, type ParallelNetwork, PassResult, PaymentConfirmation, PaymentGateResult, PaymentMiddlewareConfig, SETTLE_AMOUNT_HEADER, type SettleAmountResolution, SettleOptions, type SettlementFailure, type SettlementFailureBody, type SettlementOutcome, VerifiedPayment, VerifyResult, X402ConfigError, type X402ErrorCode, X402PriceRejectedError, X402RuntimeError, X402_ERROR_CODES, createPaymentGate, createPaymentMiddleware, encodeBase64, getDefaultAcceptedTokens, isPriceRejection, normalizeRoutePath, parsePrice, resolveCharge, resolveSettleAmount, settleVerified, settlementFailureResponse, toEip155Network, validateAddress };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { FacilitatorClient, PARALLEL_TOKENS, SETTLE_AMOUNT_HEADER, createPaymentGate, createPaymentMiddleware, encodeBase64, getDefaultAcceptedTokens, parsePrice, resolveCharge, resolveSettleAmount, settleVerified, settlementFailureResponse, toEip155Network, validateAddress } from './chunk-G7HSURPM.js';
2
- export { X402ConfigError, X402PriceRejectedError, X402RuntimeError, X402_ERROR_CODES, isPriceRejection } from './chunk-QAECRSWF.js';
1
+ export { FacilitatorClient, PARALLEL_TOKENS, SETTLE_AMOUNT_HEADER, createPaymentGate, createPaymentMiddleware, encodeBase64, getDefaultAcceptedTokens, normalizeRoutePath, parsePrice, resolveCharge, resolveSettleAmount, settleVerified, settlementFailureResponse, toEip155Network, validateAddress } from './chunk-CNASNROQ.js';
2
+ export { X402ConfigError, X402PriceRejectedError, X402RuntimeError, X402_ERROR_CODES, isPriceRejection } from './chunk-MZCHBBUN.js';
package/dist/llm.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkKZZY5LS6_cjs = require('./chunk-KZZY5LS6.cjs');
3
+ var chunk4CEMNRCZ_cjs = require('./chunk-4CEMNRCZ.cjs');
4
4
 
5
5
  // src/llm/estimate.ts
6
6
  function estimateTokens(text) {
@@ -71,7 +71,7 @@ function lookup(table, model) {
71
71
  function staticPrices(table) {
72
72
  for (const [model, price] of Object.entries(table)) {
73
73
  if (!isValidPrice(price)) {
74
- throw new chunkKZZY5LS6_cjs.X402ConfigError(
74
+ throw new chunk4CEMNRCZ_cjs.X402ConfigError(
75
75
  `Invalid price for model "${model}": expected { input, output } in USD per million tokens`
76
76
  );
77
77
  }
@@ -106,13 +106,13 @@ function shortName(value) {
106
106
  function parseDuration(value) {
107
107
  if (typeof value === "number") {
108
108
  if (!Number.isFinite(value) || value < 0) {
109
- throw new chunkKZZY5LS6_cjs.X402ConfigError(`Invalid duration: ${value}`);
109
+ throw new chunk4CEMNRCZ_cjs.X402ConfigError(`Invalid duration: ${value}`);
110
110
  }
111
111
  return value;
112
112
  }
113
113
  const match = value.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);
114
114
  if (!match) {
115
- throw new chunkKZZY5LS6_cjs.X402ConfigError(
115
+ throw new chunk4CEMNRCZ_cjs.X402ConfigError(
116
116
  `Invalid duration "${value}": expected a number of milliseconds or a value like "24h", "30m", "10s"`
117
117
  );
118
118
  }
@@ -180,7 +180,7 @@ function openRouterPrices(options = {}) {
180
180
  if (canRetry()) await load().catch(() => {
181
181
  });
182
182
  if (!table) {
183
- throw new chunkKZZY5LS6_cjs.X402PriceRejectedError(
183
+ throw new chunk4CEMNRCZ_cjs.X402PriceRejectedError(
184
184
  "PRICING_UNAVAILABLE",
185
185
  "Model prices are not available right now, retry shortly",
186
186
  503
@@ -197,7 +197,7 @@ function openRouterPrices(options = {}) {
197
197
  });
198
198
  }
199
199
  if (inflight) {
200
- throw new chunkKZZY5LS6_cjs.X402PriceRejectedError(
200
+ throw new chunk4CEMNRCZ_cjs.X402PriceRejectedError(
201
201
  "UNKNOWN_MODEL",
202
202
  `No price known for model "${shortName(model)}" yet. The price list is being refreshed, retry in a few seconds.`
203
203
  );
@@ -210,7 +210,7 @@ function openRouterPrices(options = {}) {
210
210
  // src/llm/cap.ts
211
211
  var DEFAULT_MARGIN = 0;
212
212
  function reject(code, message) {
213
- throw new chunkKZZY5LS6_cjs.X402PriceRejectedError(code, message);
213
+ throw new chunk4CEMNRCZ_cjs.X402PriceRejectedError(code, message);
214
214
  }
215
215
  function isTextOnly(modalities) {
216
216
  return Array.isArray(modalities) && modalities.every((modality) => modality === "text");
@@ -222,17 +222,17 @@ function chatCompletionCap(options) {
222
222
  const allowed = options.models ? new Set(options.models) : void 0;
223
223
  const estimate = options.estimateInputTokens ?? estimateInputTokens;
224
224
  if (positiveInteger(maxOutputTokens) === void 0) {
225
- throw new chunkKZZY5LS6_cjs.X402ConfigError(
225
+ throw new chunk4CEMNRCZ_cjs.X402ConfigError(
226
226
  `chatCompletionCap: maxOutputTokens must be a positive integer, got ${maxOutputTokens}`
227
227
  );
228
228
  }
229
229
  if (!Number.isFinite(margin) || margin < 0) {
230
- throw new chunkKZZY5LS6_cjs.X402ConfigError(
230
+ throw new chunk4CEMNRCZ_cjs.X402ConfigError(
231
231
  `chatCompletionCap: margin must be a non-negative number, got ${margin}`
232
232
  );
233
233
  }
234
234
  if (allowed?.size === 0) {
235
- throw new chunkKZZY5LS6_cjs.X402ConfigError("chatCompletionCap: models must not be empty");
235
+ throw new chunk4CEMNRCZ_cjs.X402ConfigError("chatCompletionCap: models must not be empty");
236
236
  }
237
237
  return async (ctx) => {
238
238
  const raw = ctx.body;
@@ -295,7 +295,7 @@ function chatCompletionCap(options) {
295
295
  reject("UNKNOWN_MODEL", `No price known for model "${shortName(model)}"`);
296
296
  }
297
297
  if (!isValidPrice(price)) {
298
- throw new chunkKZZY5LS6_cjs.X402ConfigError(
298
+ throw new chunk4CEMNRCZ_cjs.X402ConfigError(
299
299
  `chatCompletionCap: the price source returned an invalid price for model "${shortName(model)}"`
300
300
  );
301
301
  }
@@ -343,13 +343,13 @@ var failure = (status, error, message) => ({
343
343
  });
344
344
  async function forwardChatCompletion(body, options) {
345
345
  if (typeof options.baseUrl !== "string" || !URL.canParse(options.baseUrl)) {
346
- throw new chunkKZZY5LS6_cjs.X402ConfigError(
346
+ throw new chunk4CEMNRCZ_cjs.X402ConfigError(
347
347
  `forwardChatCompletion: baseUrl must be a URL, got ${JSON.stringify(options.baseUrl)}`
348
348
  );
349
349
  }
350
350
  const maxOutputTokens = options.maxOutputTokens ?? DEFAULT_MAX_OUTPUT_TOKENS;
351
351
  if (positiveInteger(maxOutputTokens) === void 0) {
352
- throw new chunkKZZY5LS6_cjs.X402ConfigError(
352
+ throw new chunk4CEMNRCZ_cjs.X402ConfigError(
353
353
  `forwardChatCompletion: maxOutputTokens must be a positive integer, got ${maxOutputTokens}`
354
354
  );
355
355
  }
package/dist/llm.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { o as PriceFunction, j as MeterFunction } from './types-BkGQ2lPA.cjs';
1
+ import { o as PriceFunction, j as MeterFunction } from './types-CRBMTQaq.cjs';
2
2
  import 'viem';
3
3
 
4
4
  /**
package/dist/llm.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { o as PriceFunction, j as MeterFunction } from './types-BkGQ2lPA.js';
1
+ import { o as PriceFunction, j as MeterFunction } from './types-CRBMTQaq.js';
2
2
  import 'viem';
3
3
 
4
4
  /**
package/dist/llm.js CHANGED
@@ -1,4 +1,4 @@
1
- import { X402ConfigError, X402PriceRejectedError } from './chunk-QAECRSWF.js';
1
+ import { X402ConfigError, X402PriceRejectedError } from './chunk-MZCHBBUN.js';
2
2
 
3
3
  // src/llm/estimate.ts
4
4
  function estimateTokens(text) {
package/dist/next.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkTH77IB3T_cjs = require('./chunk-TH77IB3T.cjs');
4
- require('./chunk-KZZY5LS6.cjs');
3
+ var chunkAYMDIX7A_cjs = require('./chunk-AYMDIX7A.cjs');
4
+ require('./chunk-4CEMNRCZ.cjs');
5
5
  var server = require('next/server');
6
6
 
7
7
  // src/next/adapter.ts
@@ -25,7 +25,7 @@ var NextAdapter = class {
25
25
  // Read from a clone: a request body is a stream that can be consumed once,
26
26
  // and the handler still needs the original.
27
27
  async getBody() {
28
- if (!chunkTH77IB3T_cjs.isJsonContentType(this.req.headers.get("content-type") ?? void 0))
28
+ if (!chunkAYMDIX7A_cjs.isJsonContentType(this.req.headers.get("content-type") ?? void 0))
29
29
  return void 0;
30
30
  try {
31
31
  return await this.req.clone().json();
@@ -43,20 +43,21 @@ function fromResult(result) {
43
43
  });
44
44
  }
45
45
  function withPayment(config, handler) {
46
- const gate = chunkTH77IB3T_cjs.createPaymentGate(config);
46
+ const gate = chunkAYMDIX7A_cjs.createPaymentGate(config);
47
47
  return async (req) => {
48
48
  const gateResult = await gate(new NextAdapter(req));
49
49
  if (gateResult.type === "pass") {
50
- return handler(req);
50
+ if (!gateResult.preflight) return handler(req);
51
+ return new server.NextResponse(null, { status: 204 });
51
52
  }
52
53
  if (gateResult.type === "error") return fromResult(gateResult.result);
53
54
  let response;
54
55
  try {
55
- const outcome = await chunkTH77IB3T_cjs.raceTimeout(
56
+ const outcome = await chunkAYMDIX7A_cjs.raceTimeout(
56
57
  handler(req),
57
58
  gateResult.handlerTimeoutMs
58
59
  );
59
- if (outcome === chunkTH77IB3T_cjs.HANDLER_TIMEOUT) {
60
+ if (outcome === chunkAYMDIX7A_cjs.HANDLER_TIMEOUT) {
60
61
  return new server.NextResponse(null, { status: 504 });
61
62
  }
62
63
  response = outcome;
@@ -65,10 +66,10 @@ function withPayment(config, handler) {
65
66
  }
66
67
  let raw;
67
68
  if (gateResult.scheme === "upto") {
68
- raw = response.headers.get(chunkTH77IB3T_cjs.SETTLE_AMOUNT_HEADER) ?? void 0;
69
+ raw = response.headers.get(chunkAYMDIX7A_cjs.SETTLE_AMOUNT_HEADER) ?? void 0;
69
70
  if (raw !== void 0) {
70
71
  const headers = new Headers(response.headers);
71
- headers.delete(chunkTH77IB3T_cjs.SETTLE_AMOUNT_HEADER);
72
+ headers.delete(chunkAYMDIX7A_cjs.SETTLE_AMOUNT_HEADER);
72
73
  response = new server.NextResponse(response.body, {
73
74
  status: response.status,
74
75
  headers
@@ -79,24 +80,24 @@ function withPayment(config, handler) {
79
80
  let settleOptions;
80
81
  if (gateResult.scheme === "upto") {
81
82
  const handled = response;
82
- const resolved = await chunkTH77IB3T_cjs.resolveCharge(gateResult, raw, {
83
+ const resolved = await chunkAYMDIX7A_cjs.resolveCharge(gateResult, raw, {
83
84
  status: handled.status,
84
85
  header: (name) => handled.headers.get(name) ?? void 0,
85
86
  // Read from a clone: the body streams once, to the client.
86
- body: () => chunkTH77IB3T_cjs.jsonFromResponse(handled)
87
+ body: () => chunkAYMDIX7A_cjs.jsonFromResponse(handled)
87
88
  });
88
89
  if (resolved.kind === "invalid") {
89
90
  handled.body?.cancel().catch(() => {
90
91
  });
91
- return fromResult(chunkTH77IB3T_cjs.invalidSettleAmountResponse(resolved.reason));
92
+ return fromResult(chunkAYMDIX7A_cjs.invalidSettleAmountResponse(resolved.reason));
92
93
  }
93
94
  if (resolved.kind === "skip") return response;
94
95
  settleOptions = { amount: resolved.amount };
95
96
  }
96
- const outcome = await chunkTH77IB3T_cjs.settleVerified(gateResult, settleOptions);
97
+ const outcome = await chunkAYMDIX7A_cjs.settleVerified(gateResult, settleOptions);
97
98
  if (outcome.settled) {
98
99
  const headers = new Headers(response.headers);
99
- headers.set("payment-response", chunkTH77IB3T_cjs.encodeBase64(outcome.confirmation));
100
+ headers.set("payment-response", chunkAYMDIX7A_cjs.encodeBase64(outcome.confirmation));
100
101
  headers.set("access-control-expose-headers", "payment-response");
101
102
  return new server.NextResponse(response.body, {
102
103
  status: response.status,
@@ -105,7 +106,7 @@ function withPayment(config, handler) {
105
106
  }
106
107
  response.body?.cancel().catch(() => {
107
108
  });
108
- return fromResult(chunkTH77IB3T_cjs.settlementFailureResponse(outcome));
109
+ return fromResult(chunkAYMDIX7A_cjs.settlementFailureResponse(outcome));
109
110
  }
110
111
  return response;
111
112
  };
package/dist/next.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
- import { H as HTTPAdapter, P as PaymentMiddlewareConfig } from './types-BkGQ2lPA.cjs';
2
+ import { H as HTTPAdapter, P as PaymentMiddlewareConfig } from './types-CRBMTQaq.cjs';
3
3
  import 'viem';
4
4
 
5
5
  declare class NextAdapter implements HTTPAdapter {
package/dist/next.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
- import { H as HTTPAdapter, P as PaymentMiddlewareConfig } from './types-BkGQ2lPA.js';
2
+ import { H as HTTPAdapter, P as PaymentMiddlewareConfig } from './types-CRBMTQaq.js';
3
3
  import 'viem';
4
4
 
5
5
  declare class NextAdapter implements HTTPAdapter {
package/dist/next.js CHANGED
@@ -1,5 +1,5 @@
1
- import { isJsonContentType, createPaymentGate, raceTimeout, HANDLER_TIMEOUT, SETTLE_AMOUNT_HEADER, resolveCharge, jsonFromResponse, invalidSettleAmountResponse, settleVerified, encodeBase64, settlementFailureResponse } from './chunk-G7HSURPM.js';
2
- import './chunk-QAECRSWF.js';
1
+ import { isJsonContentType, createPaymentGate, raceTimeout, HANDLER_TIMEOUT, SETTLE_AMOUNT_HEADER, resolveCharge, jsonFromResponse, invalidSettleAmountResponse, settleVerified, encodeBase64, settlementFailureResponse } from './chunk-CNASNROQ.js';
2
+ import './chunk-MZCHBBUN.js';
3
3
  import { NextResponse } from 'next/server';
4
4
 
5
5
  // src/next/adapter.ts
@@ -45,7 +45,8 @@ function withPayment(config, handler) {
45
45
  return async (req) => {
46
46
  const gateResult = await gate(new NextAdapter(req));
47
47
  if (gateResult.type === "pass") {
48
- return handler(req);
48
+ if (!gateResult.preflight) return handler(req);
49
+ return new NextResponse(null, { status: 204 });
49
50
  }
50
51
  if (gateResult.type === "error") return fromResult(gateResult.result);
51
52
  let response;
@@ -10,7 +10,14 @@ interface FacilitatorConfig {
10
10
  */
11
11
  interface PriceContext {
12
12
  method: string;
13
+ /** As the framework gives it, not normalized: compare `routePath` instead. */
13
14
  path: string;
15
+ /**
16
+ * The path the route matched, in the form routes are matched on: under an
17
+ * Express mount, the full path when the key is written with it. Set by the
18
+ * middleware.
19
+ */
20
+ routePath?: string;
14
21
  url: string;
15
22
  header(name: string): string | undefined;
16
23
  body: unknown;
@@ -95,6 +102,8 @@ interface HTTPAdapter {
95
102
  getHeader(name: string): string | undefined;
96
103
  getMethod(): string;
97
104
  getPath(): string;
105
+ /** The path with the prefix a mount stripped from `getPath()`. */
106
+ getFullPath?(): string;
98
107
  getUrl(): string;
99
108
  /** The parsed request body, for routes priced per request. */
100
109
  getBody?(): Promise<unknown>;
@@ -163,11 +172,22 @@ interface PaymentConfirmation {
163
172
  networkId: string;
164
173
  /** Amount actually charged (smallest unit) — metered routes only. */
165
174
  amountSettled?: string;
175
+ /**
176
+ * A standard x402 Permit2 payment: the USDp the merchant received for
177
+ * `amountSettled` (smallest unit), when the facilitator read it from the
178
+ * settlement.
179
+ */
180
+ amountDelivered?: string;
166
181
  /**
167
182
  * Present when the facilitator answered from the outcome an earlier settle
168
183
  * of the same payment recorded: this call broadcast nothing.
169
184
  */
170
185
  alreadySettled?: true;
186
+ transaction?: Address;
187
+ network?: string;
188
+ /** The amount charged, in the smallest unit of the paid token. */
189
+ amount?: string;
190
+ payer?: Address;
171
191
  }
172
192
  interface PaymentFailure {
173
193
  success: false;
@@ -190,6 +210,8 @@ interface MiddlewareResult {
190
210
  interface PassResult {
191
211
  pass: true;
192
212
  handlerRan?: true;
213
+ /** An OPTIONS on a paid route: send only the handler's status and CORS headers. */
214
+ preflight?: true;
193
215
  }
194
216
  type VerifiedPayment = {
195
217
  type: "verified";
@@ -206,6 +228,7 @@ type VerifiedPayment = {
206
228
  };
207
229
  type PaymentGateResult = {
208
230
  type: "pass";
231
+ preflight?: true;
209
232
  } | {
210
233
  type: "error";
211
234
  result: MiddlewareResult;
@@ -10,7 +10,14 @@ interface FacilitatorConfig {
10
10
  */
11
11
  interface PriceContext {
12
12
  method: string;
13
+ /** As the framework gives it, not normalized: compare `routePath` instead. */
13
14
  path: string;
15
+ /**
16
+ * The path the route matched, in the form routes are matched on: under an
17
+ * Express mount, the full path when the key is written with it. Set by the
18
+ * middleware.
19
+ */
20
+ routePath?: string;
14
21
  url: string;
15
22
  header(name: string): string | undefined;
16
23
  body: unknown;
@@ -95,6 +102,8 @@ interface HTTPAdapter {
95
102
  getHeader(name: string): string | undefined;
96
103
  getMethod(): string;
97
104
  getPath(): string;
105
+ /** The path with the prefix a mount stripped from `getPath()`. */
106
+ getFullPath?(): string;
98
107
  getUrl(): string;
99
108
  /** The parsed request body, for routes priced per request. */
100
109
  getBody?(): Promise<unknown>;
@@ -163,11 +172,22 @@ interface PaymentConfirmation {
163
172
  networkId: string;
164
173
  /** Amount actually charged (smallest unit) — metered routes only. */
165
174
  amountSettled?: string;
175
+ /**
176
+ * A standard x402 Permit2 payment: the USDp the merchant received for
177
+ * `amountSettled` (smallest unit), when the facilitator read it from the
178
+ * settlement.
179
+ */
180
+ amountDelivered?: string;
166
181
  /**
167
182
  * Present when the facilitator answered from the outcome an earlier settle
168
183
  * of the same payment recorded: this call broadcast nothing.
169
184
  */
170
185
  alreadySettled?: true;
186
+ transaction?: Address;
187
+ network?: string;
188
+ /** The amount charged, in the smallest unit of the paid token. */
189
+ amount?: string;
190
+ payer?: Address;
171
191
  }
172
192
  interface PaymentFailure {
173
193
  success: false;
@@ -190,6 +210,8 @@ interface MiddlewareResult {
190
210
  interface PassResult {
191
211
  pass: true;
192
212
  handlerRan?: true;
213
+ /** An OPTIONS on a paid route: send only the handler's status and CORS headers. */
214
+ preflight?: true;
193
215
  }
194
216
  type VerifiedPayment = {
195
217
  type: "verified";
@@ -206,6 +228,7 @@ type VerifiedPayment = {
206
228
  };
207
229
  type PaymentGateResult = {
208
230
  type: "pass";
231
+ preflight?: true;
209
232
  } | {
210
233
  type: "error";
211
234
  result: MiddlewareResult;