@parallel-protocol/x402 0.8.0 → 0.8.2

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.
@@ -1,4 +1,4 @@
1
- import { X402_ERROR_CODES, X402RuntimeError, X402ConfigError, isPriceRejection } from './chunk-QAECRSWF.js';
1
+ import { X402_ERROR_CODES, X402ConfigError, X402RuntimeError, isPriceRejection } from './chunk-QAECRSWF.js';
2
2
  import { getTokenDecimals as getTokenDecimals$1 } from '@parallel-protocol/chains';
3
3
  import { z } from 'zod';
4
4
 
@@ -127,8 +127,18 @@ var priceSchema = z.union([
127
127
  "Price must be a string, a bigint or a function of the request"
128
128
  )
129
129
  ]);
130
+ var LOCAL_HOSTNAMES = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]"]);
131
+ function isFacilitatorUrl(value) {
132
+ if (!URL.canParse(value)) return false;
133
+ const { protocol, hostname } = new URL(value);
134
+ return protocol === "https:" || protocol === "http:" && LOCAL_HOSTNAMES.has(hostname);
135
+ }
136
+ var facilitatorUrlSchema = z.string().refine(
137
+ isFacilitatorUrl,
138
+ "The facilitator URL must use https (plain http only on localhost, 127.0.0.1 or [::1])"
139
+ );
130
140
  var facilitatorConfigSchema = z.object({
131
- url: z.string().refine((v) => URL.canParse(v), "Invalid facilitator URL"),
141
+ url: facilitatorUrlSchema,
132
142
  apiKey: z.string().optional()
133
143
  });
134
144
  var UPTO_MAX_TIMEOUT_SECONDS = 3600;
@@ -223,6 +233,15 @@ function retryAfterOf(response) {
223
233
  const value = response.headers.get("retry-after");
224
234
  return value !== null && RETRY_AFTER_SHAPE.test(value) ? value : void 0;
225
235
  }
236
+ function throwIfRedirect(response) {
237
+ const redirected = response.type === "opaqueredirect" || response.status >= 300 && response.status < 400;
238
+ if (!redirected) return;
239
+ response.body?.cancel().catch(() => {
240
+ });
241
+ throw new X402RuntimeError(X402_ERROR_CODES.FACILITATOR_UNAVAILABLE, {
242
+ status: response.status
243
+ });
244
+ }
226
245
  function decodePaymentHeader(paymentHeader) {
227
246
  try {
228
247
  return decodeBase64(paymentHeader);
@@ -231,20 +250,33 @@ function decodePaymentHeader(paymentHeader) {
231
250
  }
232
251
  }
233
252
  var FacilitatorClient = class {
253
+ // Checked and kept when the client is built: a config changed afterwards
254
+ // does not move the calls elsewhere.
255
+ url;
256
+ apiKey;
234
257
  constructor(config) {
235
- this.config = config;
258
+ const url = facilitatorUrlSchema.safeParse(config.url);
259
+ if (!url.success) {
260
+ throw new X402ConfigError(
261
+ url.error.issues[0]?.message ?? "Invalid facilitator URL",
262
+ url.error
263
+ );
264
+ }
265
+ this.url = new URL(url.data).href.replace(/\/+$/, "");
266
+ this.apiKey = config.apiKey;
236
267
  }
237
- config;
238
268
  async verify(paymentHeader, paymentRequirements) {
239
269
  const paymentPayload = decodePaymentHeader(paymentHeader);
240
270
  let json;
241
271
  try {
242
- const response = await fetch(`${this.config.url}/x402/verify`, {
272
+ const response = await fetch(`${this.url}/x402/verify`, {
243
273
  method: "POST",
244
274
  headers: this.buildHeaders(),
245
275
  body: JSON.stringify({ paymentPayload, paymentRequirements }),
276
+ redirect: "manual",
246
277
  signal: AbortSignal.timeout(FACILITATOR_TIMEOUT_MS)
247
278
  });
279
+ throwIfRedirect(response);
248
280
  if (!response.ok) {
249
281
  const body = await readErrorBody(response);
250
282
  throw new X402RuntimeError(
@@ -272,7 +304,7 @@ var FacilitatorClient = class {
272
304
  const paymentPayload = decodePaymentHeader(paymentHeader);
273
305
  let json;
274
306
  try {
275
- const response = await fetch(`${this.config.url}/x402/settle`, {
307
+ const response = await fetch(`${this.url}/x402/settle`, {
276
308
  method: "POST",
277
309
  headers: this.buildHeaders(),
278
310
  // settleAmount only travels for metered routes; the settle token
@@ -287,18 +319,22 @@ var FacilitatorClient = class {
287
319
  settleToken: options.settleToken
288
320
  }
289
321
  }),
322
+ redirect: "manual",
290
323
  signal: AbortSignal.timeout(SETTLE_TIMEOUT_MS)
291
324
  });
325
+ throwIfRedirect(response);
292
326
  if (!response.ok) {
293
327
  const body = await readErrorBody(response);
294
- if (body.error === void 0 && response.status >= 500) {
295
- throw new X402RuntimeError(X402_ERROR_CODES.FACILITATOR_UNAVAILABLE);
328
+ if (body.error === void 0) {
329
+ throw new X402RuntimeError(X402_ERROR_CODES.FACILITATOR_UNAVAILABLE, {
330
+ status: response.status
331
+ });
296
332
  }
297
333
  const retryAfter = retryAfterOf(response);
298
334
  return {
299
335
  success: false,
300
336
  error: {
301
- code: body.error ?? "SUBMISSION_FAILED",
337
+ code: body.error,
302
338
  message: body.message ?? "Settlement failed",
303
339
  status: response.status,
304
340
  ...retryAfter !== void 0 && { retryAfter }
@@ -337,16 +373,22 @@ var FacilitatorClient = class {
337
373
  throw new X402RuntimeError(X402_ERROR_CODES.FACILITATOR_INVALID_RESPONSE);
338
374
  }
339
375
  }
376
+ /**
377
+ * @deprecated The Parallel facilitator no longer serves `/x402/pay`, so this
378
+ * call fails with `FACILITATOR_UNAVAILABLE`. Use `verify`, then `settle`.
379
+ */
340
380
  async pay(paymentHeader) {
341
381
  const headers = this.buildHeaders();
342
382
  headers["X-PAYMENT"] = paymentHeader;
343
383
  let json;
344
384
  try {
345
- const response = await fetch(`${this.config.url}/x402/pay`, {
385
+ const response = await fetch(`${this.url}/x402/pay`, {
346
386
  method: "POST",
347
387
  headers,
388
+ redirect: "manual",
348
389
  signal: AbortSignal.timeout(FACILITATOR_TIMEOUT_MS)
349
390
  });
391
+ throwIfRedirect(response);
350
392
  if (!response.ok) {
351
393
  throw new X402RuntimeError(X402_ERROR_CODES.FACILITATOR_UNAVAILABLE);
352
394
  }
@@ -365,8 +407,8 @@ var FacilitatorClient = class {
365
407
  const headers = {
366
408
  "Content-Type": "application/json"
367
409
  };
368
- if (this.config.apiKey) {
369
- headers["X-API-Key"] = this.config.apiKey;
410
+ if (this.apiKey) {
411
+ headers["X-API-Key"] = this.apiKey;
370
412
  }
371
413
  return headers;
372
414
  }
@@ -650,12 +692,13 @@ function paymentRequiredResponse(url, config, resolvedTokens, price, refusal) {
650
692
  });
651
693
  }
652
694
  function createPaymentGate(config) {
653
- try {
654
- paymentMiddlewareConfigSchema.parse(config);
655
- } catch (cause) {
695
+ const checked = paymentMiddlewareConfigSchema.safeParse(config);
696
+ if (!checked.success) {
697
+ const issue = checked.error.issues[0];
698
+ const where = issue?.path.length ? ` at ${issue.path.join(".")}` : "";
656
699
  throw new X402ConfigError(
657
- "Invalid paymentMiddleware config \u2014 check your routes, facilitator URL and payTo addresses",
658
- cause
700
+ `Invalid paymentMiddleware config${where}: ${issue?.message ?? "check your routes, facilitator URL and payTo addresses"}`,
701
+ checked.error
659
702
  );
660
703
  }
661
704
  const client = new FacilitatorClient(config.facilitator);
@@ -731,8 +774,9 @@ function createPaymentGate(config) {
731
774
  };
732
775
  };
733
776
  }
734
- var UNKNOWN_SETTLEMENT_MESSAGE = "The payment could not be settled.";
777
+ var DEFAULT_SETTLEMENT_MESSAGE = "The payment could not be settled.";
735
778
  var MERCHANT_SETTLEMENT_MESSAGE = "The merchant could not complete the settlement of this payment. The payment was not taken: do not sign another payment for this request before checking with the merchant.";
779
+ var UNAVAILABLE_SETTLEMENT_MESSAGE = "The facilitator could not settle the payment for now. It may still settle until its authorization expires, or an earlier attempt may already have settled it: do not sign another payment for this request before checking with the merchant.";
736
780
  var AGENT_MESSAGES = {
737
781
  [X402_ERROR_CODES.SETTLE_TIMEOUT]: "The facilitator did not confirm the settlement in time. The payment may still settle: do not sign another payment for this request before checking with the merchant.",
738
782
  [X402_ERROR_CODES.FACILITATOR_UNAVAILABLE]: "The facilitator could not be reached to settle the payment. It may still have settled: do not sign another payment for this request before checking with the merchant.",
@@ -741,15 +785,19 @@ var AGENT_MESSAGES = {
741
785
  RECEIPT_UNAVAILABLE: "The facilitator sent the transaction but could not read its confirmation. The payment may have settled: do not sign another payment for this request before checking with the merchant.",
742
786
  SETTLE_TOKEN_INVALID: MERCHANT_SETTLEMENT_MESSAGE,
743
787
  SETTLE_TOKEN_REQUIRED: MERCHANT_SETTLEMENT_MESSAGE,
788
+ AUTHORIZATION_USED: "The payment's authorization was already consumed or cancelled on-chain. It may have paid the merchant: do not sign another payment for this request before checking with the merchant.",
789
+ PAYMENT_NOT_VERIFIED: "The facilitator holds no payment it can settle for this request. An earlier attempt may have paid the merchant, or may still settle: do not sign another payment for this request before checking with the merchant.",
790
+ PARALLELIZER_PAUSED: UNAVAILABLE_SETTLEMENT_MESSAGE,
791
+ SERVICE_UNAVAILABLE: UNAVAILABLE_SETTLEMENT_MESSAGE,
744
792
  AMOUNT_MISMATCH: "The facilitator settled a different amount than this request asked for. The response was not served: do not sign another payment for this request before checking with the merchant.",
745
- UNKNOWN: UNKNOWN_SETTLEMENT_MESSAGE
793
+ UNKNOWN: "The facilitator gave no reason for this failure, and the payment may have settled: do not sign another payment for this request before checking with the merchant."
746
794
  };
747
795
  function settlementFailure(code, failure) {
748
796
  const reason = shapedCode(code) ?? "UNKNOWN";
749
797
  return {
750
798
  settled: false,
751
799
  reason,
752
- message: AGENT_MESSAGES[reason] ?? boundedMessage(failure?.message) ?? UNKNOWN_SETTLEMENT_MESSAGE,
800
+ message: AGENT_MESSAGES[reason] ?? boundedMessage(failure?.message) ?? DEFAULT_SETTLEMENT_MESSAGE,
753
801
  ...failure?.retryAfter !== void 0 && {
754
802
  retryAfter: failure.retryAfter
755
803
  }
@@ -129,8 +129,18 @@ var priceSchema = zod.z.union([
129
129
  "Price must be a string, a bigint or a function of the request"
130
130
  )
131
131
  ]);
132
+ var LOCAL_HOSTNAMES = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]"]);
133
+ function isFacilitatorUrl(value) {
134
+ if (!URL.canParse(value)) return false;
135
+ const { protocol, hostname } = new URL(value);
136
+ return protocol === "https:" || protocol === "http:" && LOCAL_HOSTNAMES.has(hostname);
137
+ }
138
+ var facilitatorUrlSchema = zod.z.string().refine(
139
+ isFacilitatorUrl,
140
+ "The facilitator URL must use https (plain http only on localhost, 127.0.0.1 or [::1])"
141
+ );
132
142
  var facilitatorConfigSchema = zod.z.object({
133
- url: zod.z.string().refine((v) => URL.canParse(v), "Invalid facilitator URL"),
143
+ url: facilitatorUrlSchema,
134
144
  apiKey: zod.z.string().optional()
135
145
  });
136
146
  var UPTO_MAX_TIMEOUT_SECONDS = 3600;
@@ -225,6 +235,15 @@ function retryAfterOf(response) {
225
235
  const value = response.headers.get("retry-after");
226
236
  return value !== null && RETRY_AFTER_SHAPE.test(value) ? value : void 0;
227
237
  }
238
+ function throwIfRedirect(response) {
239
+ const redirected = response.type === "opaqueredirect" || response.status >= 300 && response.status < 400;
240
+ if (!redirected) return;
241
+ response.body?.cancel().catch(() => {
242
+ });
243
+ throw new chunkKZZY5LS6_cjs.X402RuntimeError(chunkKZZY5LS6_cjs.X402_ERROR_CODES.FACILITATOR_UNAVAILABLE, {
244
+ status: response.status
245
+ });
246
+ }
228
247
  function decodePaymentHeader(paymentHeader) {
229
248
  try {
230
249
  return decodeBase64(paymentHeader);
@@ -233,20 +252,33 @@ function decodePaymentHeader(paymentHeader) {
233
252
  }
234
253
  }
235
254
  var FacilitatorClient = class {
255
+ // Checked and kept when the client is built: a config changed afterwards
256
+ // does not move the calls elsewhere.
257
+ url;
258
+ apiKey;
236
259
  constructor(config) {
237
- this.config = config;
260
+ const url = facilitatorUrlSchema.safeParse(config.url);
261
+ if (!url.success) {
262
+ throw new chunkKZZY5LS6_cjs.X402ConfigError(
263
+ url.error.issues[0]?.message ?? "Invalid facilitator URL",
264
+ url.error
265
+ );
266
+ }
267
+ this.url = new URL(url.data).href.replace(/\/+$/, "");
268
+ this.apiKey = config.apiKey;
238
269
  }
239
- config;
240
270
  async verify(paymentHeader, paymentRequirements) {
241
271
  const paymentPayload = decodePaymentHeader(paymentHeader);
242
272
  let json;
243
273
  try {
244
- const response = await fetch(`${this.config.url}/x402/verify`, {
274
+ const response = await fetch(`${this.url}/x402/verify`, {
245
275
  method: "POST",
246
276
  headers: this.buildHeaders(),
247
277
  body: JSON.stringify({ paymentPayload, paymentRequirements }),
278
+ redirect: "manual",
248
279
  signal: AbortSignal.timeout(FACILITATOR_TIMEOUT_MS)
249
280
  });
281
+ throwIfRedirect(response);
250
282
  if (!response.ok) {
251
283
  const body = await readErrorBody(response);
252
284
  throw new chunkKZZY5LS6_cjs.X402RuntimeError(
@@ -274,7 +306,7 @@ var FacilitatorClient = class {
274
306
  const paymentPayload = decodePaymentHeader(paymentHeader);
275
307
  let json;
276
308
  try {
277
- const response = await fetch(`${this.config.url}/x402/settle`, {
309
+ const response = await fetch(`${this.url}/x402/settle`, {
278
310
  method: "POST",
279
311
  headers: this.buildHeaders(),
280
312
  // settleAmount only travels for metered routes; the settle token
@@ -289,18 +321,22 @@ var FacilitatorClient = class {
289
321
  settleToken: options.settleToken
290
322
  }
291
323
  }),
324
+ redirect: "manual",
292
325
  signal: AbortSignal.timeout(SETTLE_TIMEOUT_MS)
293
326
  });
327
+ throwIfRedirect(response);
294
328
  if (!response.ok) {
295
329
  const body = await readErrorBody(response);
296
- if (body.error === void 0 && response.status >= 500) {
297
- throw new chunkKZZY5LS6_cjs.X402RuntimeError(chunkKZZY5LS6_cjs.X402_ERROR_CODES.FACILITATOR_UNAVAILABLE);
330
+ if (body.error === void 0) {
331
+ throw new chunkKZZY5LS6_cjs.X402RuntimeError(chunkKZZY5LS6_cjs.X402_ERROR_CODES.FACILITATOR_UNAVAILABLE, {
332
+ status: response.status
333
+ });
298
334
  }
299
335
  const retryAfter = retryAfterOf(response);
300
336
  return {
301
337
  success: false,
302
338
  error: {
303
- code: body.error ?? "SUBMISSION_FAILED",
339
+ code: body.error,
304
340
  message: body.message ?? "Settlement failed",
305
341
  status: response.status,
306
342
  ...retryAfter !== void 0 && { retryAfter }
@@ -339,16 +375,22 @@ var FacilitatorClient = class {
339
375
  throw new chunkKZZY5LS6_cjs.X402RuntimeError(chunkKZZY5LS6_cjs.X402_ERROR_CODES.FACILITATOR_INVALID_RESPONSE);
340
376
  }
341
377
  }
378
+ /**
379
+ * @deprecated The Parallel facilitator no longer serves `/x402/pay`, so this
380
+ * call fails with `FACILITATOR_UNAVAILABLE`. Use `verify`, then `settle`.
381
+ */
342
382
  async pay(paymentHeader) {
343
383
  const headers = this.buildHeaders();
344
384
  headers["X-PAYMENT"] = paymentHeader;
345
385
  let json;
346
386
  try {
347
- const response = await fetch(`${this.config.url}/x402/pay`, {
387
+ const response = await fetch(`${this.url}/x402/pay`, {
348
388
  method: "POST",
349
389
  headers,
390
+ redirect: "manual",
350
391
  signal: AbortSignal.timeout(FACILITATOR_TIMEOUT_MS)
351
392
  });
393
+ throwIfRedirect(response);
352
394
  if (!response.ok) {
353
395
  throw new chunkKZZY5LS6_cjs.X402RuntimeError(chunkKZZY5LS6_cjs.X402_ERROR_CODES.FACILITATOR_UNAVAILABLE);
354
396
  }
@@ -367,8 +409,8 @@ var FacilitatorClient = class {
367
409
  const headers = {
368
410
  "Content-Type": "application/json"
369
411
  };
370
- if (this.config.apiKey) {
371
- headers["X-API-Key"] = this.config.apiKey;
412
+ if (this.apiKey) {
413
+ headers["X-API-Key"] = this.apiKey;
372
414
  }
373
415
  return headers;
374
416
  }
@@ -652,12 +694,13 @@ function paymentRequiredResponse(url, config, resolvedTokens, price, refusal) {
652
694
  });
653
695
  }
654
696
  function createPaymentGate(config) {
655
- try {
656
- paymentMiddlewareConfigSchema.parse(config);
657
- } catch (cause) {
697
+ const checked = paymentMiddlewareConfigSchema.safeParse(config);
698
+ if (!checked.success) {
699
+ const issue = checked.error.issues[0];
700
+ const where = issue?.path.length ? ` at ${issue.path.join(".")}` : "";
658
701
  throw new chunkKZZY5LS6_cjs.X402ConfigError(
659
- "Invalid paymentMiddleware config \u2014 check your routes, facilitator URL and payTo addresses",
660
- cause
702
+ `Invalid paymentMiddleware config${where}: ${issue?.message ?? "check your routes, facilitator URL and payTo addresses"}`,
703
+ checked.error
661
704
  );
662
705
  }
663
706
  const client = new FacilitatorClient(config.facilitator);
@@ -733,8 +776,9 @@ function createPaymentGate(config) {
733
776
  };
734
777
  };
735
778
  }
736
- var UNKNOWN_SETTLEMENT_MESSAGE = "The payment could not be settled.";
779
+ var DEFAULT_SETTLEMENT_MESSAGE = "The payment could not be settled.";
737
780
  var MERCHANT_SETTLEMENT_MESSAGE = "The merchant could not complete the settlement of this payment. The payment was not taken: do not sign another payment for this request before checking with the merchant.";
781
+ var UNAVAILABLE_SETTLEMENT_MESSAGE = "The facilitator could not settle the payment for now. It may still settle until its authorization expires, or an earlier attempt may already have settled it: do not sign another payment for this request before checking with the merchant.";
738
782
  var AGENT_MESSAGES = {
739
783
  [chunkKZZY5LS6_cjs.X402_ERROR_CODES.SETTLE_TIMEOUT]: "The facilitator did not confirm the settlement in time. The payment may still settle: do not sign another payment for this request before checking with the merchant.",
740
784
  [chunkKZZY5LS6_cjs.X402_ERROR_CODES.FACILITATOR_UNAVAILABLE]: "The facilitator could not be reached to settle the payment. It may still have settled: do not sign another payment for this request before checking with the merchant.",
@@ -743,15 +787,19 @@ var AGENT_MESSAGES = {
743
787
  RECEIPT_UNAVAILABLE: "The facilitator sent the transaction but could not read its confirmation. The payment may have settled: do not sign another payment for this request before checking with the merchant.",
744
788
  SETTLE_TOKEN_INVALID: MERCHANT_SETTLEMENT_MESSAGE,
745
789
  SETTLE_TOKEN_REQUIRED: MERCHANT_SETTLEMENT_MESSAGE,
790
+ AUTHORIZATION_USED: "The payment's authorization was already consumed or cancelled on-chain. It may have paid the merchant: do not sign another payment for this request before checking with the merchant.",
791
+ PAYMENT_NOT_VERIFIED: "The facilitator holds no payment it can settle for this request. An earlier attempt may have paid the merchant, or may still settle: do not sign another payment for this request before checking with the merchant.",
792
+ PARALLELIZER_PAUSED: UNAVAILABLE_SETTLEMENT_MESSAGE,
793
+ SERVICE_UNAVAILABLE: UNAVAILABLE_SETTLEMENT_MESSAGE,
746
794
  AMOUNT_MISMATCH: "The facilitator settled a different amount than this request asked for. The response was not served: do not sign another payment for this request before checking with the merchant.",
747
- UNKNOWN: UNKNOWN_SETTLEMENT_MESSAGE
795
+ UNKNOWN: "The facilitator gave no reason for this failure, and the payment may have settled: do not sign another payment for this request before checking with the merchant."
748
796
  };
749
797
  function settlementFailure(code, failure) {
750
798
  const reason = shapedCode(code) ?? "UNKNOWN";
751
799
  return {
752
800
  settled: false,
753
801
  reason,
754
- message: AGENT_MESSAGES[reason] ?? boundedMessage(failure?.message) ?? UNKNOWN_SETTLEMENT_MESSAGE,
802
+ message: AGENT_MESSAGES[reason] ?? boundedMessage(failure?.message) ?? DEFAULT_SETTLEMENT_MESSAGE,
755
803
  ...failure?.retryAfter !== void 0 && {
756
804
  retryAfter: failure.retryAfter
757
805
  }
package/dist/express.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkNA7245L5_cjs = require('./chunk-NA7245L5.cjs');
3
+ var chunkMXGS3HMS_cjs = require('./chunk-MXGS3HMS.cjs');
4
4
  require('./chunk-KZZY5LS6.cjs');
5
5
 
6
6
  // src/express/adapter.ts
@@ -108,8 +108,8 @@ var ExpressAdapter = class {
108
108
  return originalEnd(...args);
109
109
  });
110
110
  next();
111
- const outcome = await chunkNA7245L5_cjs.raceTimeout(endPromise, options?.timeoutMs);
112
- if (outcome === chunkNA7245L5_cjs.HANDLER_TIMEOUT) {
111
+ const outcome = await chunkMXGS3HMS_cjs.raceTimeout(endPromise, options?.timeoutMs);
112
+ if (outcome === chunkMXGS3HMS_cjs.HANDLER_TIMEOUT) {
113
113
  discarded = true;
114
114
  return {
115
115
  status: 504,
@@ -146,7 +146,7 @@ var ExpressAdapter = class {
146
146
  const chunk = chunkBytes(args);
147
147
  if (chunk) bytes.push(chunk);
148
148
  }
149
- return chunkNA7245L5_cjs.parseJsonBody(
149
+ return chunkMXGS3HMS_cjs.parseJsonBody(
150
150
  contentType,
151
151
  Buffer.concat(bytes).toString("utf8")
152
152
  );
@@ -170,7 +170,7 @@ var ExpressAdapter = class {
170
170
 
171
171
  // src/express/index.ts
172
172
  function paymentMiddleware(config) {
173
- const middleware = chunkNA7245L5_cjs.createPaymentMiddleware(config);
173
+ const middleware = chunkMXGS3HMS_cjs.createPaymentMiddleware(config);
174
174
  return async (req, res, next) => {
175
175
  const result = await middleware(new ExpressAdapter(req, res, next));
176
176
  if ("pass" in result) {
package/dist/express.js CHANGED
@@ -1,4 +1,4 @@
1
- import { raceTimeout, HANDLER_TIMEOUT, parseJsonBody, createPaymentMiddleware } from './chunk-SA5ULSG2.js';
1
+ import { raceTimeout, HANDLER_TIMEOUT, parseJsonBody, createPaymentMiddleware } from './chunk-KTBFF5HI.js';
2
2
  import './chunk-QAECRSWF.js';
3
3
 
4
4
  // src/express/adapter.ts
package/dist/fastify.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkNA7245L5_cjs = require('./chunk-NA7245L5.cjs');
3
+ var chunkMXGS3HMS_cjs = require('./chunk-MXGS3HMS.cjs');
4
4
  require('./chunk-KZZY5LS6.cjs');
5
5
  var fp = require('fastify-plugin');
6
6
 
@@ -37,7 +37,7 @@ var FastifyAdapter = class {
37
37
  // src/fastify/index.ts
38
38
  function payloadJson(contentType, payload) {
39
39
  const text = typeof payload === "string" ? payload : payload instanceof Uint8Array ? Buffer.from(payload).toString("utf8") : void 0;
40
- return chunkNA7245L5_cjs.parseJsonBody(contentType, text);
40
+ return chunkMXGS3HMS_cjs.parseJsonBody(contentType, text);
41
41
  }
42
42
  function refuse(reply, result) {
43
43
  const json = JSON.stringify(result.body);
@@ -54,11 +54,11 @@ function headerValue(value) {
54
54
  }
55
55
  function paymentMiddleware(config) {
56
56
  return fp__default.default(async (fastify) => {
57
- const gate = chunkNA7245L5_cjs.createPaymentGate(config);
57
+ const gate = chunkMXGS3HMS_cjs.createPaymentGate(config);
58
58
  const verifiedMap = /* @__PURE__ */ new WeakMap();
59
59
  const rawWriters = /* @__PURE__ */ new WeakMap();
60
60
  const needsBody = (req) => {
61
- const route = chunkNA7245L5_cjs.matchRoute(
61
+ const route = chunkMXGS3HMS_cjs.matchRoute(
62
62
  new FastifyAdapter(req).getPath(),
63
63
  config.routes
64
64
  );
@@ -111,29 +111,29 @@ function paymentMiddleware(config) {
111
111
  if (!verified) return payload;
112
112
  let raw;
113
113
  if (verified.scheme === "upto") {
114
- raw = headerValue(reply.getHeader(chunkNA7245L5_cjs.SETTLE_AMOUNT_HEADER));
115
- reply.removeHeader(chunkNA7245L5_cjs.SETTLE_AMOUNT_HEADER);
114
+ raw = headerValue(reply.getHeader(chunkMXGS3HMS_cjs.SETTLE_AMOUNT_HEADER));
115
+ reply.removeHeader(chunkMXGS3HMS_cjs.SETTLE_AMOUNT_HEADER);
116
116
  }
117
117
  if (reply.statusCode < 200 || reply.statusCode >= 300) {
118
118
  return payload;
119
119
  }
120
120
  let settleOptions;
121
121
  if (verified.scheme === "upto") {
122
- const resolved = await chunkNA7245L5_cjs.resolveCharge(verified, raw, {
122
+ const resolved = await chunkMXGS3HMS_cjs.resolveCharge(verified, raw, {
123
123
  status: reply.statusCode,
124
124
  header: (name) => headerValue(reply.getHeader(name)),
125
125
  body: async () => payloadJson(headerValue(reply.getHeader("content-type")), payload)
126
126
  });
127
127
  if (resolved.kind === "invalid") {
128
- return refuse(reply, chunkNA7245L5_cjs.invalidSettleAmountResponse(resolved.reason));
128
+ return refuse(reply, chunkMXGS3HMS_cjs.invalidSettleAmountResponse(resolved.reason));
129
129
  }
130
130
  if (resolved.kind === "skip") return payload;
131
131
  settleOptions = { amount: resolved.amount };
132
132
  }
133
- const outcome = await chunkNA7245L5_cjs.settleVerified(verified, settleOptions);
133
+ const outcome = await chunkMXGS3HMS_cjs.settleVerified(verified, settleOptions);
134
134
  if (!outcome.settled)
135
- return refuse(reply, chunkNA7245L5_cjs.settlementFailureResponse(outcome));
136
- reply.header("payment-response", chunkNA7245L5_cjs.encodeBase64(outcome.confirmation));
135
+ return refuse(reply, chunkMXGS3HMS_cjs.settlementFailureResponse(outcome));
136
+ reply.header("payment-response", chunkMXGS3HMS_cjs.encodeBase64(outcome.confirmation));
137
137
  reply.header("access-control-expose-headers", "payment-response");
138
138
  return payload;
139
139
  });
package/dist/fastify.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createPaymentGate, SETTLE_AMOUNT_HEADER, resolveCharge, invalidSettleAmountResponse, settleVerified, settlementFailureResponse, encodeBase64, matchRoute, parseJsonBody } from './chunk-SA5ULSG2.js';
1
+ import { createPaymentGate, SETTLE_AMOUNT_HEADER, resolveCharge, invalidSettleAmountResponse, settleVerified, settlementFailureResponse, encodeBase64, matchRoute, parseJsonBody } from './chunk-KTBFF5HI.js';
2
2
  import './chunk-QAECRSWF.js';
3
3
  import fp from 'fastify-plugin';
4
4
 
package/dist/hono.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkNA7245L5_cjs = require('./chunk-NA7245L5.cjs');
3
+ var chunkMXGS3HMS_cjs = require('./chunk-MXGS3HMS.cjs');
4
4
  require('./chunk-KZZY5LS6.cjs');
5
5
 
6
6
  // src/hono/adapter.ts
@@ -30,7 +30,7 @@ var HonoAdapter = class {
30
30
  // Hono caches the parsed body on the request, so the handler can still read
31
31
  // it after the price function did.
32
32
  async getBody() {
33
- if (!chunkNA7245L5_cjs.isJsonContentType(this.c.req.header("content-type"))) return void 0;
33
+ if (!chunkMXGS3HMS_cjs.isJsonContentType(this.c.req.header("content-type"))) return void 0;
34
34
  try {
35
35
  return await this.c.req.json();
36
36
  } catch {
@@ -38,8 +38,8 @@ var HonoAdapter = class {
38
38
  }
39
39
  }
40
40
  async runHandler(options) {
41
- const outcome = await chunkNA7245L5_cjs.raceTimeout(this.next(), options?.timeoutMs);
42
- if (outcome === chunkNA7245L5_cjs.HANDLER_TIMEOUT) {
41
+ const outcome = await chunkMXGS3HMS_cjs.raceTimeout(this.next(), options?.timeoutMs);
42
+ if (outcome === chunkMXGS3HMS_cjs.HANDLER_TIMEOUT) {
43
43
  return {
44
44
  status: 504,
45
45
  setResponseHeader: () => {
@@ -64,7 +64,7 @@ var HonoAdapter = class {
64
64
  getResponseHeader: (name) => res.headers.get(name) ?? void 0,
65
65
  removeResponseHeader: (name) => res.headers.delete(name),
66
66
  // Read from a clone: the response body streams once, to the client.
67
- getResponseBody: () => chunkNA7245L5_cjs.jsonFromResponse(res),
67
+ getResponseBody: () => chunkMXGS3HMS_cjs.jsonFromResponse(res),
68
68
  sendResponse: () => {
69
69
  },
70
70
  // The response is replaced: release its body (and whatever upstream
@@ -79,7 +79,7 @@ var HonoAdapter = class {
79
79
 
80
80
  // src/hono/index.ts
81
81
  function paymentMiddleware(config) {
82
- const middleware = chunkNA7245L5_cjs.createPaymentMiddleware(config);
82
+ const middleware = chunkMXGS3HMS_cjs.createPaymentMiddleware(config);
83
83
  return async (c, next) => {
84
84
  const result = await middleware(new HonoAdapter(c, next));
85
85
  if ("pass" in result) {
package/dist/hono.js CHANGED
@@ -1,4 +1,4 @@
1
- import { isJsonContentType, raceTimeout, HANDLER_TIMEOUT, jsonFromResponse, createPaymentMiddleware } from './chunk-SA5ULSG2.js';
1
+ import { isJsonContentType, raceTimeout, HANDLER_TIMEOUT, jsonFromResponse, createPaymentMiddleware } from './chunk-KTBFF5HI.js';
2
2
  import './chunk-QAECRSWF.js';
3
3
 
4
4
  // src/hono/adapter.ts
package/dist/index.cjs CHANGED
@@ -1,65 +1,65 @@
1
1
  'use strict';
2
2
 
3
- var chunkNA7245L5_cjs = require('./chunk-NA7245L5.cjs');
3
+ var chunkMXGS3HMS_cjs = require('./chunk-MXGS3HMS.cjs');
4
4
  var chunkKZZY5LS6_cjs = require('./chunk-KZZY5LS6.cjs');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "FacilitatorClient", {
9
9
  enumerable: true,
10
- get: function () { return chunkNA7245L5_cjs.FacilitatorClient; }
10
+ get: function () { return chunkMXGS3HMS_cjs.FacilitatorClient; }
11
11
  });
12
12
  Object.defineProperty(exports, "PARALLEL_TOKENS", {
13
13
  enumerable: true,
14
- get: function () { return chunkNA7245L5_cjs.PARALLEL_TOKENS; }
14
+ get: function () { return chunkMXGS3HMS_cjs.PARALLEL_TOKENS; }
15
15
  });
16
16
  Object.defineProperty(exports, "SETTLE_AMOUNT_HEADER", {
17
17
  enumerable: true,
18
- get: function () { return chunkNA7245L5_cjs.SETTLE_AMOUNT_HEADER; }
18
+ get: function () { return chunkMXGS3HMS_cjs.SETTLE_AMOUNT_HEADER; }
19
19
  });
20
20
  Object.defineProperty(exports, "createPaymentGate", {
21
21
  enumerable: true,
22
- get: function () { return chunkNA7245L5_cjs.createPaymentGate; }
22
+ get: function () { return chunkMXGS3HMS_cjs.createPaymentGate; }
23
23
  });
24
24
  Object.defineProperty(exports, "createPaymentMiddleware", {
25
25
  enumerable: true,
26
- get: function () { return chunkNA7245L5_cjs.createPaymentMiddleware; }
26
+ get: function () { return chunkMXGS3HMS_cjs.createPaymentMiddleware; }
27
27
  });
28
28
  Object.defineProperty(exports, "encodeBase64", {
29
29
  enumerable: true,
30
- get: function () { return chunkNA7245L5_cjs.encodeBase64; }
30
+ get: function () { return chunkMXGS3HMS_cjs.encodeBase64; }
31
31
  });
32
32
  Object.defineProperty(exports, "getDefaultAcceptedTokens", {
33
33
  enumerable: true,
34
- get: function () { return chunkNA7245L5_cjs.getDefaultAcceptedTokens; }
34
+ get: function () { return chunkMXGS3HMS_cjs.getDefaultAcceptedTokens; }
35
35
  });
36
36
  Object.defineProperty(exports, "parsePrice", {
37
37
  enumerable: true,
38
- get: function () { return chunkNA7245L5_cjs.parsePrice; }
38
+ get: function () { return chunkMXGS3HMS_cjs.parsePrice; }
39
39
  });
40
40
  Object.defineProperty(exports, "resolveCharge", {
41
41
  enumerable: true,
42
- get: function () { return chunkNA7245L5_cjs.resolveCharge; }
42
+ get: function () { return chunkMXGS3HMS_cjs.resolveCharge; }
43
43
  });
44
44
  Object.defineProperty(exports, "resolveSettleAmount", {
45
45
  enumerable: true,
46
- get: function () { return chunkNA7245L5_cjs.resolveSettleAmount; }
46
+ get: function () { return chunkMXGS3HMS_cjs.resolveSettleAmount; }
47
47
  });
48
48
  Object.defineProperty(exports, "settleVerified", {
49
49
  enumerable: true,
50
- get: function () { return chunkNA7245L5_cjs.settleVerified; }
50
+ get: function () { return chunkMXGS3HMS_cjs.settleVerified; }
51
51
  });
52
52
  Object.defineProperty(exports, "settlementFailureResponse", {
53
53
  enumerable: true,
54
- get: function () { return chunkNA7245L5_cjs.settlementFailureResponse; }
54
+ get: function () { return chunkMXGS3HMS_cjs.settlementFailureResponse; }
55
55
  });
56
56
  Object.defineProperty(exports, "toEip155Network", {
57
57
  enumerable: true,
58
- get: function () { return chunkNA7245L5_cjs.toEip155Network; }
58
+ get: function () { return chunkMXGS3HMS_cjs.toEip155Network; }
59
59
  });
60
60
  Object.defineProperty(exports, "validateAddress", {
61
61
  enumerable: true,
62
- get: function () { return chunkNA7245L5_cjs.validateAddress; }
62
+ get: function () { return chunkMXGS3HMS_cjs.validateAddress; }
63
63
  });
64
64
  Object.defineProperty(exports, "X402ConfigError", {
65
65
  enumerable: true,
package/dist/index.d.cts CHANGED
@@ -3,10 +3,15 @@ export { i as MeterContext, j as MeterFunction, k as PaymentFailure, l as Paymen
3
3
  import { Address } from 'viem';
4
4
 
5
5
  declare class FacilitatorClient {
6
- private readonly config;
6
+ private readonly url;
7
+ private readonly apiKey;
7
8
  constructor(config: FacilitatorConfig);
8
9
  verify(paymentHeader: string, paymentRequirements: FacilitatorPaymentRequirements): Promise<VerifyResult>;
9
10
  settle(paymentHeader: string, paymentRequirements: FacilitatorPaymentRequirements, options?: FacilitatorSettleOptions): Promise<FacilitatorResponse>;
11
+ /**
12
+ * @deprecated The Parallel facilitator no longer serves `/x402/pay`, so this
13
+ * call fails with `FACILITATOR_UNAVAILABLE`. Use `verify`, then `settle`.
14
+ */
10
15
  pay(paymentHeader: string): Promise<FacilitatorResponse>;
11
16
  private buildHeaders;
12
17
  }