@parallel-protocol/x402 0.7.1 → 0.8.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/fastify.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkPOU7EH3E_cjs = require('./chunk-POU7EH3E.cjs');
4
- require('./chunk-JPMK5YBU.cjs');
3
+ var chunkSNW5Z5HB_cjs = require('./chunk-SNW5Z5HB.cjs');
4
+ require('./chunk-KZZY5LS6.cjs');
5
5
  var fp = require('fastify-plugin');
6
6
 
7
7
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -37,12 +37,14 @@ 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 chunkPOU7EH3E_cjs.parseJsonBody(contentType, text);
40
+ return chunkSNW5Z5HB_cjs.parseJsonBody(contentType, text);
41
41
  }
42
- function refuse(reply, body) {
43
- const json = JSON.stringify(body);
44
- reply.status(402);
45
- reply.header("Content-Type", "application/json");
42
+ function refuse(reply, result) {
43
+ const json = JSON.stringify(result.body);
44
+ reply.status(result.status);
45
+ for (const [name, value] of Object.entries(result.headers)) {
46
+ reply.header(name, value);
47
+ }
46
48
  reply.header("Content-Length", Buffer.byteLength(json));
47
49
  return json;
48
50
  }
@@ -52,11 +54,11 @@ function headerValue(value) {
52
54
  }
53
55
  function paymentMiddleware(config) {
54
56
  return fp__default.default(async (fastify) => {
55
- const gate = chunkPOU7EH3E_cjs.createPaymentGate(config);
57
+ const gate = chunkSNW5Z5HB_cjs.createPaymentGate(config);
56
58
  const verifiedMap = /* @__PURE__ */ new WeakMap();
57
59
  const rawWriters = /* @__PURE__ */ new WeakMap();
58
60
  const needsBody = (req) => {
59
- const route = chunkPOU7EH3E_cjs.matchRoute(
61
+ const route = chunkSNW5Z5HB_cjs.matchRoute(
60
62
  new FastifyAdapter(req).getPath(),
61
63
  config.routes
62
64
  );
@@ -109,41 +111,30 @@ function paymentMiddleware(config) {
109
111
  if (!verified) return payload;
110
112
  let raw;
111
113
  if (verified.scheme === "upto") {
112
- raw = headerValue(reply.getHeader(chunkPOU7EH3E_cjs.SETTLE_AMOUNT_HEADER));
113
- reply.removeHeader(chunkPOU7EH3E_cjs.SETTLE_AMOUNT_HEADER);
114
+ raw = headerValue(reply.getHeader(chunkSNW5Z5HB_cjs.SETTLE_AMOUNT_HEADER));
115
+ reply.removeHeader(chunkSNW5Z5HB_cjs.SETTLE_AMOUNT_HEADER);
114
116
  }
115
117
  if (reply.statusCode < 200 || reply.statusCode >= 300) {
116
118
  return payload;
117
119
  }
118
120
  let settleOptions;
119
121
  if (verified.scheme === "upto") {
120
- const resolved = await chunkPOU7EH3E_cjs.resolveCharge(verified, raw, {
122
+ const resolved = await chunkSNW5Z5HB_cjs.resolveCharge(verified, raw, {
121
123
  status: reply.statusCode,
122
124
  header: (name) => headerValue(reply.getHeader(name)),
123
125
  body: async () => payloadJson(headerValue(reply.getHeader("content-type")), payload)
124
126
  });
125
127
  if (resolved.kind === "invalid") {
126
- return refuse(reply, chunkPOU7EH3E_cjs.invalidSettleAmountResponse(resolved.reason));
128
+ return refuse(reply, chunkSNW5Z5HB_cjs.invalidSettleAmountResponse(resolved.reason));
127
129
  }
128
130
  if (resolved.kind === "skip") return payload;
129
131
  settleOptions = { amount: resolved.amount };
130
132
  }
131
- let settled = false;
132
- try {
133
- const settleResponse = settleOptions ? await verified.settle(settleOptions) : await verified.settle();
134
- if (settleResponse.success) {
135
- reply.header("payment-response", chunkPOU7EH3E_cjs.encodeBase64(settleResponse));
136
- reply.header("access-control-expose-headers", "payment-response");
137
- settled = true;
138
- }
139
- } catch {
140
- }
141
- if (!settled) {
142
- return refuse(reply, {
143
- error: "PAYMENT_SETTLEMENT_FAILED",
144
- message: "Payment could not be confirmed after multiple attempts. Please retry."
145
- });
146
- }
133
+ const outcome = await chunkSNW5Z5HB_cjs.settleVerified(verified, settleOptions);
134
+ if (!outcome.settled)
135
+ return refuse(reply, chunkSNW5Z5HB_cjs.settlementFailureResponse(outcome));
136
+ reply.header("payment-response", chunkSNW5Z5HB_cjs.encodeBase64(outcome.confirmation));
137
+ reply.header("access-control-expose-headers", "payment-response");
147
138
  return payload;
148
139
  });
149
140
  });
@@ -1,5 +1,5 @@
1
1
  import { FastifyRequest, FastifyPluginAsync } from 'fastify';
2
- import { H as HTTPAdapter, P as PaymentMiddlewareConfig } from './types-q_gu5wjz.cjs';
2
+ import { H as HTTPAdapter, P as PaymentMiddlewareConfig } from './types-BkGQ2lPA.cjs';
3
3
  import 'viem';
4
4
 
5
5
  declare class FastifyAdapter implements HTTPAdapter {
package/dist/fastify.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { FastifyRequest, FastifyPluginAsync } from 'fastify';
2
- import { H as HTTPAdapter, P as PaymentMiddlewareConfig } from './types-q_gu5wjz.js';
2
+ import { H as HTTPAdapter, P as PaymentMiddlewareConfig } from './types-BkGQ2lPA.js';
3
3
  import 'viem';
4
4
 
5
5
  declare class FastifyAdapter implements HTTPAdapter {
package/dist/fastify.js CHANGED
@@ -1,5 +1,5 @@
1
- import { createPaymentGate, SETTLE_AMOUNT_HEADER, resolveCharge, invalidSettleAmountResponse, encodeBase64, matchRoute, parseJsonBody } from './chunk-AENXD4OC.js';
2
- import './chunk-AFRDHGDT.js';
1
+ import { createPaymentGate, SETTLE_AMOUNT_HEADER, resolveCharge, invalidSettleAmountResponse, settleVerified, settlementFailureResponse, encodeBase64, matchRoute, parseJsonBody } from './chunk-GXPUE3ES.js';
2
+ import './chunk-QAECRSWF.js';
3
3
  import fp from 'fastify-plugin';
4
4
 
5
5
  // src/fastify/adapter.ts
@@ -33,10 +33,12 @@ function payloadJson(contentType, payload) {
33
33
  const text = typeof payload === "string" ? payload : payload instanceof Uint8Array ? Buffer.from(payload).toString("utf8") : void 0;
34
34
  return parseJsonBody(contentType, text);
35
35
  }
36
- function refuse(reply, body) {
37
- const json = JSON.stringify(body);
38
- reply.status(402);
39
- reply.header("Content-Type", "application/json");
36
+ function refuse(reply, result) {
37
+ const json = JSON.stringify(result.body);
38
+ reply.status(result.status);
39
+ for (const [name, value] of Object.entries(result.headers)) {
40
+ reply.header(name, value);
41
+ }
40
42
  reply.header("Content-Length", Buffer.byteLength(json));
41
43
  return json;
42
44
  }
@@ -122,22 +124,11 @@ function paymentMiddleware(config) {
122
124
  if (resolved.kind === "skip") return payload;
123
125
  settleOptions = { amount: resolved.amount };
124
126
  }
125
- let settled = false;
126
- try {
127
- const settleResponse = settleOptions ? await verified.settle(settleOptions) : await verified.settle();
128
- if (settleResponse.success) {
129
- reply.header("payment-response", encodeBase64(settleResponse));
130
- reply.header("access-control-expose-headers", "payment-response");
131
- settled = true;
132
- }
133
- } catch {
134
- }
135
- if (!settled) {
136
- return refuse(reply, {
137
- error: "PAYMENT_SETTLEMENT_FAILED",
138
- message: "Payment could not be confirmed after multiple attempts. Please retry."
139
- });
140
- }
127
+ const outcome = await settleVerified(verified, settleOptions);
128
+ if (!outcome.settled)
129
+ return refuse(reply, settlementFailureResponse(outcome));
130
+ reply.header("payment-response", encodeBase64(outcome.confirmation));
131
+ reply.header("access-control-expose-headers", "payment-response");
141
132
  return payload;
142
133
  });
143
134
  });
package/dist/hono.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkPOU7EH3E_cjs = require('./chunk-POU7EH3E.cjs');
4
- require('./chunk-JPMK5YBU.cjs');
3
+ var chunkSNW5Z5HB_cjs = require('./chunk-SNW5Z5HB.cjs');
4
+ require('./chunk-KZZY5LS6.cjs');
5
5
 
6
6
  // src/hono/adapter.ts
7
7
  var TIMEOUT_BODY = JSON.stringify({
@@ -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 (!chunkPOU7EH3E_cjs.isJsonContentType(this.c.req.header("content-type"))) return void 0;
33
+ if (!chunkSNW5Z5HB_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 chunkPOU7EH3E_cjs.raceTimeout(this.next(), options?.timeoutMs);
42
- if (outcome === chunkPOU7EH3E_cjs.HANDLER_TIMEOUT) {
41
+ const outcome = await chunkSNW5Z5HB_cjs.raceTimeout(this.next(), options?.timeoutMs);
42
+ if (outcome === chunkSNW5Z5HB_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: () => chunkPOU7EH3E_cjs.jsonFromResponse(res),
67
+ getResponseBody: () => chunkSNW5Z5HB_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 = chunkPOU7EH3E_cjs.createPaymentMiddleware(config);
82
+ const middleware = chunkSNW5Z5HB_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.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Context, Next, MiddlewareHandler } from 'hono';
2
- import { H as HTTPAdapter, R as RunHandlerOptions, a as RunHandlerResult, P as PaymentMiddlewareConfig } from './types-q_gu5wjz.cjs';
2
+ import { H as HTTPAdapter, R as RunHandlerOptions, a as RunHandlerResult, P as PaymentMiddlewareConfig } from './types-BkGQ2lPA.cjs';
3
3
  import 'viem';
4
4
 
5
5
  declare class HonoAdapter implements HTTPAdapter {
package/dist/hono.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Context, Next, MiddlewareHandler } from 'hono';
2
- import { H as HTTPAdapter, R as RunHandlerOptions, a as RunHandlerResult, P as PaymentMiddlewareConfig } from './types-q_gu5wjz.js';
2
+ import { H as HTTPAdapter, R as RunHandlerOptions, a as RunHandlerResult, P as PaymentMiddlewareConfig } from './types-BkGQ2lPA.js';
3
3
  import 'viem';
4
4
 
5
5
  declare class HonoAdapter implements HTTPAdapter {
package/dist/hono.js CHANGED
@@ -1,5 +1,5 @@
1
- import { isJsonContentType, raceTimeout, HANDLER_TIMEOUT, jsonFromResponse, createPaymentMiddleware } from './chunk-AENXD4OC.js';
2
- import './chunk-AFRDHGDT.js';
1
+ import { isJsonContentType, raceTimeout, HANDLER_TIMEOUT, jsonFromResponse, createPaymentMiddleware } from './chunk-GXPUE3ES.js';
2
+ import './chunk-QAECRSWF.js';
3
3
 
4
4
  // src/hono/adapter.ts
5
5
  var TIMEOUT_BODY = JSON.stringify({
package/dist/index.cjs CHANGED
@@ -1,75 +1,83 @@
1
1
  'use strict';
2
2
 
3
- var chunkPOU7EH3E_cjs = require('./chunk-POU7EH3E.cjs');
4
- var chunkJPMK5YBU_cjs = require('./chunk-JPMK5YBU.cjs');
3
+ var chunkSNW5Z5HB_cjs = require('./chunk-SNW5Z5HB.cjs');
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 chunkPOU7EH3E_cjs.FacilitatorClient; }
10
+ get: function () { return chunkSNW5Z5HB_cjs.FacilitatorClient; }
11
11
  });
12
12
  Object.defineProperty(exports, "PARALLEL_TOKENS", {
13
13
  enumerable: true,
14
- get: function () { return chunkPOU7EH3E_cjs.PARALLEL_TOKENS; }
14
+ get: function () { return chunkSNW5Z5HB_cjs.PARALLEL_TOKENS; }
15
15
  });
16
16
  Object.defineProperty(exports, "SETTLE_AMOUNT_HEADER", {
17
17
  enumerable: true,
18
- get: function () { return chunkPOU7EH3E_cjs.SETTLE_AMOUNT_HEADER; }
18
+ get: function () { return chunkSNW5Z5HB_cjs.SETTLE_AMOUNT_HEADER; }
19
19
  });
20
20
  Object.defineProperty(exports, "createPaymentGate", {
21
21
  enumerable: true,
22
- get: function () { return chunkPOU7EH3E_cjs.createPaymentGate; }
22
+ get: function () { return chunkSNW5Z5HB_cjs.createPaymentGate; }
23
23
  });
24
24
  Object.defineProperty(exports, "createPaymentMiddleware", {
25
25
  enumerable: true,
26
- get: function () { return chunkPOU7EH3E_cjs.createPaymentMiddleware; }
26
+ get: function () { return chunkSNW5Z5HB_cjs.createPaymentMiddleware; }
27
27
  });
28
28
  Object.defineProperty(exports, "encodeBase64", {
29
29
  enumerable: true,
30
- get: function () { return chunkPOU7EH3E_cjs.encodeBase64; }
30
+ get: function () { return chunkSNW5Z5HB_cjs.encodeBase64; }
31
31
  });
32
32
  Object.defineProperty(exports, "getDefaultAcceptedTokens", {
33
33
  enumerable: true,
34
- get: function () { return chunkPOU7EH3E_cjs.getDefaultAcceptedTokens; }
34
+ get: function () { return chunkSNW5Z5HB_cjs.getDefaultAcceptedTokens; }
35
35
  });
36
36
  Object.defineProperty(exports, "parsePrice", {
37
37
  enumerable: true,
38
- get: function () { return chunkPOU7EH3E_cjs.parsePrice; }
38
+ get: function () { return chunkSNW5Z5HB_cjs.parsePrice; }
39
39
  });
40
40
  Object.defineProperty(exports, "resolveCharge", {
41
41
  enumerable: true,
42
- get: function () { return chunkPOU7EH3E_cjs.resolveCharge; }
42
+ get: function () { return chunkSNW5Z5HB_cjs.resolveCharge; }
43
43
  });
44
44
  Object.defineProperty(exports, "resolveSettleAmount", {
45
45
  enumerable: true,
46
- get: function () { return chunkPOU7EH3E_cjs.resolveSettleAmount; }
46
+ get: function () { return chunkSNW5Z5HB_cjs.resolveSettleAmount; }
47
+ });
48
+ Object.defineProperty(exports, "settleVerified", {
49
+ enumerable: true,
50
+ get: function () { return chunkSNW5Z5HB_cjs.settleVerified; }
51
+ });
52
+ Object.defineProperty(exports, "settlementFailureResponse", {
53
+ enumerable: true,
54
+ get: function () { return chunkSNW5Z5HB_cjs.settlementFailureResponse; }
47
55
  });
48
56
  Object.defineProperty(exports, "toEip155Network", {
49
57
  enumerable: true,
50
- get: function () { return chunkPOU7EH3E_cjs.toEip155Network; }
58
+ get: function () { return chunkSNW5Z5HB_cjs.toEip155Network; }
51
59
  });
52
60
  Object.defineProperty(exports, "validateAddress", {
53
61
  enumerable: true,
54
- get: function () { return chunkPOU7EH3E_cjs.validateAddress; }
62
+ get: function () { return chunkSNW5Z5HB_cjs.validateAddress; }
55
63
  });
56
64
  Object.defineProperty(exports, "X402ConfigError", {
57
65
  enumerable: true,
58
- get: function () { return chunkJPMK5YBU_cjs.X402ConfigError; }
66
+ get: function () { return chunkKZZY5LS6_cjs.X402ConfigError; }
59
67
  });
60
68
  Object.defineProperty(exports, "X402PriceRejectedError", {
61
69
  enumerable: true,
62
- get: function () { return chunkJPMK5YBU_cjs.X402PriceRejectedError; }
70
+ get: function () { return chunkKZZY5LS6_cjs.X402PriceRejectedError; }
63
71
  });
64
72
  Object.defineProperty(exports, "X402RuntimeError", {
65
73
  enumerable: true,
66
- get: function () { return chunkJPMK5YBU_cjs.X402RuntimeError; }
74
+ get: function () { return chunkKZZY5LS6_cjs.X402RuntimeError; }
67
75
  });
68
76
  Object.defineProperty(exports, "X402_ERROR_CODES", {
69
77
  enumerable: true,
70
- get: function () { return chunkJPMK5YBU_cjs.X402_ERROR_CODES; }
78
+ get: function () { return chunkKZZY5LS6_cjs.X402_ERROR_CODES; }
71
79
  });
72
80
  Object.defineProperty(exports, "isPriceRejection", {
73
81
  enumerable: true,
74
- get: function () { return chunkJPMK5YBU_cjs.isPriceRejection; }
82
+ get: function () { return chunkKZZY5LS6_cjs.isPriceRejection; }
75
83
  });
package/dist/index.d.cts CHANGED
@@ -1,12 +1,17 @@
1
- import { F as FacilitatorConfig, b as FacilitatorPaymentRequirements, S as SettleOptions, c as FacilitatorResponse, P as PaymentMiddlewareConfig, H as HTTPAdapter, d as PaymentGateResult, M as MiddlewareResult, e as PassResult, V as VerifiedPayment } from './types-q_gu5wjz.cjs';
2
- export { f as MeterContext, g as MeterFunction, h as PaymentConfirmation, i as PaymentFailure, j as PaymentRequired, k as PaymentRequirements, l as PriceContext, m as PriceFunction, n as ResourceInfo, o as RouteConfig, R as RunHandlerOptions, a as RunHandlerResult } from './types-q_gu5wjz.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-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';
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
- verify(paymentHeader: string, paymentRequirements: FacilitatorPaymentRequirements): Promise<void>;
9
- settle(paymentHeader: string, paymentRequirements: FacilitatorPaymentRequirements, options?: SettleOptions): Promise<FacilitatorResponse>;
9
+ verify(paymentHeader: string, paymentRequirements: FacilitatorPaymentRequirements): Promise<VerifyResult>;
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
  }
@@ -15,6 +20,8 @@ declare const X402_ERROR_CODES: {
15
20
  readonly FACILITATOR_UNAVAILABLE: "FACILITATOR_UNAVAILABLE";
16
21
  readonly FACILITATOR_INVALID_RESPONSE: "FACILITATOR_INVALID_RESPONSE";
17
22
  readonly INVALID_PAYMENT: "INVALID_PAYMENT";
23
+ /** The facilitator did not answer a settle within the client's timeout: the payment may still settle. */
24
+ readonly SETTLE_TIMEOUT: "SETTLE_TIMEOUT";
18
25
  };
19
26
  type X402ErrorCode = (typeof X402_ERROR_CODES)[keyof typeof X402_ERROR_CODES];
20
27
  declare class X402ConfigError extends Error {
@@ -22,7 +29,17 @@ declare class X402ConfigError extends Error {
22
29
  }
23
30
  declare class X402RuntimeError extends Error {
24
31
  readonly code: string;
25
- constructor(code: string);
32
+ /** The facilitator's message for this code, when it answered with one. */
33
+ readonly detail?: string;
34
+ /** The facilitator's HTTP status, when the error comes from its answer. */
35
+ readonly status?: number;
36
+ /** The facilitator's `Retry-After` header, when it sent one. */
37
+ readonly retryAfter?: string;
38
+ constructor(code: string, extra?: {
39
+ detail?: string;
40
+ status?: number;
41
+ retryAfter?: string;
42
+ });
26
43
  }
27
44
  /**
28
45
  * Thrown by a per-request price function to refuse a request before anything
@@ -85,6 +102,38 @@ interface ChargeResponse {
85
102
  */
86
103
  declare function resolveCharge(verified: VerifiedPayment, settleHeader: string | undefined, response: ChargeResponse): Promise<SettleAmountResolution>;
87
104
  declare function createPaymentGate(config: PaymentMiddlewareConfig): (adapter: GateAdapter) => Promise<PaymentGateResult>;
105
+ /** The 402 body a merchant answers when a verified payment could not be settled. */
106
+ interface SettlementFailureBody {
107
+ /** Kept for the clients that read it: the historical code. */
108
+ error: "PAYMENT_SETTLEMENT_FAILED";
109
+ /**
110
+ * The facilitator's code, or this SDK's: `SETTLE_TIMEOUT`,
111
+ * `FACILITATOR_UNAVAILABLE`, `FACILITATOR_INVALID_RESPONSE`,
112
+ * `AMOUNT_MISMATCH`, `UNKNOWN`.
113
+ */
114
+ reason: string;
115
+ message: string;
116
+ }
117
+ /** A settlement that did not confirm the payment, and what the agent is told. */
118
+ interface SettlementFailure {
119
+ settled: false;
120
+ reason: string;
121
+ message: string;
122
+ /** The facilitator's `Retry-After`, when it sent one. */
123
+ retryAfter?: string;
124
+ }
125
+ type SettlementOutcome = {
126
+ settled: true;
127
+ confirmation: PaymentConfirmation;
128
+ } | SettlementFailure;
129
+ /**
130
+ * Settles a verified payment once the handler answered, and says what the
131
+ * agent must be told when it could not be. A metered settle must settle the
132
+ * amount this request asked for, whatever else the facilitator recorded.
133
+ */
134
+ declare function settleVerified(verified: VerifiedPayment, options?: SettleOptions): Promise<SettlementOutcome>;
135
+ /** The 402 for a settlement that failed, with the facilitator's Retry-After when it gave one. */
136
+ declare function settlementFailureResponse(failure: SettlementFailure): MiddlewareResult;
88
137
  declare function createPaymentMiddleware(config: PaymentMiddlewareConfig): (adapter: HTTPAdapter) => Promise<MiddlewareResult | PassResult>;
89
138
 
90
139
  type ParallelNetwork = "ethereum" | "base" | "avalanche" | "hyperevm";
@@ -108,4 +157,4 @@ declare function validateAddress(address: string): address is Address;
108
157
  declare function toEip155Network(network: string): string;
109
158
  declare function encodeBase64(obj: unknown): string;
110
159
 
111
- export { type ChargeResponse, FacilitatorClient, FacilitatorConfig, FacilitatorPaymentRequirements, FacilitatorResponse, HTTPAdapter, MiddlewareResult, PARALLEL_TOKENS, type ParallelNetwork, PassResult, PaymentGateResult, PaymentMiddlewareConfig, SETTLE_AMOUNT_HEADER, type SettleAmountResolution, SettleOptions, VerifiedPayment, X402ConfigError, type X402ErrorCode, X402PriceRejectedError, X402RuntimeError, X402_ERROR_CODES, createPaymentGate, createPaymentMiddleware, encodeBase64, getDefaultAcceptedTokens, isPriceRejection, parsePrice, resolveCharge, resolveSettleAmount, toEip155Network, validateAddress };
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 };
package/dist/index.d.ts CHANGED
@@ -1,12 +1,17 @@
1
- import { F as FacilitatorConfig, b as FacilitatorPaymentRequirements, S as SettleOptions, c as FacilitatorResponse, P as PaymentMiddlewareConfig, H as HTTPAdapter, d as PaymentGateResult, M as MiddlewareResult, e as PassResult, V as VerifiedPayment } from './types-q_gu5wjz.js';
2
- export { f as MeterContext, g as MeterFunction, h as PaymentConfirmation, i as PaymentFailure, j as PaymentRequired, k as PaymentRequirements, l as PriceContext, m as PriceFunction, n as ResourceInfo, o as RouteConfig, R as RunHandlerOptions, a as RunHandlerResult } from './types-q_gu5wjz.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-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';
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
- verify(paymentHeader: string, paymentRequirements: FacilitatorPaymentRequirements): Promise<void>;
9
- settle(paymentHeader: string, paymentRequirements: FacilitatorPaymentRequirements, options?: SettleOptions): Promise<FacilitatorResponse>;
9
+ verify(paymentHeader: string, paymentRequirements: FacilitatorPaymentRequirements): Promise<VerifyResult>;
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
  }
@@ -15,6 +20,8 @@ declare const X402_ERROR_CODES: {
15
20
  readonly FACILITATOR_UNAVAILABLE: "FACILITATOR_UNAVAILABLE";
16
21
  readonly FACILITATOR_INVALID_RESPONSE: "FACILITATOR_INVALID_RESPONSE";
17
22
  readonly INVALID_PAYMENT: "INVALID_PAYMENT";
23
+ /** The facilitator did not answer a settle within the client's timeout: the payment may still settle. */
24
+ readonly SETTLE_TIMEOUT: "SETTLE_TIMEOUT";
18
25
  };
19
26
  type X402ErrorCode = (typeof X402_ERROR_CODES)[keyof typeof X402_ERROR_CODES];
20
27
  declare class X402ConfigError extends Error {
@@ -22,7 +29,17 @@ declare class X402ConfigError extends Error {
22
29
  }
23
30
  declare class X402RuntimeError extends Error {
24
31
  readonly code: string;
25
- constructor(code: string);
32
+ /** The facilitator's message for this code, when it answered with one. */
33
+ readonly detail?: string;
34
+ /** The facilitator's HTTP status, when the error comes from its answer. */
35
+ readonly status?: number;
36
+ /** The facilitator's `Retry-After` header, when it sent one. */
37
+ readonly retryAfter?: string;
38
+ constructor(code: string, extra?: {
39
+ detail?: string;
40
+ status?: number;
41
+ retryAfter?: string;
42
+ });
26
43
  }
27
44
  /**
28
45
  * Thrown by a per-request price function to refuse a request before anything
@@ -85,6 +102,38 @@ interface ChargeResponse {
85
102
  */
86
103
  declare function resolveCharge(verified: VerifiedPayment, settleHeader: string | undefined, response: ChargeResponse): Promise<SettleAmountResolution>;
87
104
  declare function createPaymentGate(config: PaymentMiddlewareConfig): (adapter: GateAdapter) => Promise<PaymentGateResult>;
105
+ /** The 402 body a merchant answers when a verified payment could not be settled. */
106
+ interface SettlementFailureBody {
107
+ /** Kept for the clients that read it: the historical code. */
108
+ error: "PAYMENT_SETTLEMENT_FAILED";
109
+ /**
110
+ * The facilitator's code, or this SDK's: `SETTLE_TIMEOUT`,
111
+ * `FACILITATOR_UNAVAILABLE`, `FACILITATOR_INVALID_RESPONSE`,
112
+ * `AMOUNT_MISMATCH`, `UNKNOWN`.
113
+ */
114
+ reason: string;
115
+ message: string;
116
+ }
117
+ /** A settlement that did not confirm the payment, and what the agent is told. */
118
+ interface SettlementFailure {
119
+ settled: false;
120
+ reason: string;
121
+ message: string;
122
+ /** The facilitator's `Retry-After`, when it sent one. */
123
+ retryAfter?: string;
124
+ }
125
+ type SettlementOutcome = {
126
+ settled: true;
127
+ confirmation: PaymentConfirmation;
128
+ } | SettlementFailure;
129
+ /**
130
+ * Settles a verified payment once the handler answered, and says what the
131
+ * agent must be told when it could not be. A metered settle must settle the
132
+ * amount this request asked for, whatever else the facilitator recorded.
133
+ */
134
+ declare function settleVerified(verified: VerifiedPayment, options?: SettleOptions): Promise<SettlementOutcome>;
135
+ /** The 402 for a settlement that failed, with the facilitator's Retry-After when it gave one. */
136
+ declare function settlementFailureResponse(failure: SettlementFailure): MiddlewareResult;
88
137
  declare function createPaymentMiddleware(config: PaymentMiddlewareConfig): (adapter: HTTPAdapter) => Promise<MiddlewareResult | PassResult>;
89
138
 
90
139
  type ParallelNetwork = "ethereum" | "base" | "avalanche" | "hyperevm";
@@ -108,4 +157,4 @@ declare function validateAddress(address: string): address is Address;
108
157
  declare function toEip155Network(network: string): string;
109
158
  declare function encodeBase64(obj: unknown): string;
110
159
 
111
- export { type ChargeResponse, FacilitatorClient, FacilitatorConfig, FacilitatorPaymentRequirements, FacilitatorResponse, HTTPAdapter, MiddlewareResult, PARALLEL_TOKENS, type ParallelNetwork, PassResult, PaymentGateResult, PaymentMiddlewareConfig, SETTLE_AMOUNT_HEADER, type SettleAmountResolution, SettleOptions, VerifiedPayment, X402ConfigError, type X402ErrorCode, X402PriceRejectedError, X402RuntimeError, X402_ERROR_CODES, createPaymentGate, createPaymentMiddleware, encodeBase64, getDefaultAcceptedTokens, isPriceRejection, parsePrice, resolveCharge, resolveSettleAmount, toEip155Network, validateAddress };
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 };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { FacilitatorClient, PARALLEL_TOKENS, SETTLE_AMOUNT_HEADER, createPaymentGate, createPaymentMiddleware, encodeBase64, getDefaultAcceptedTokens, parsePrice, resolveCharge, resolveSettleAmount, toEip155Network, validateAddress } from './chunk-AENXD4OC.js';
2
- export { X402ConfigError, X402PriceRejectedError, X402RuntimeError, X402_ERROR_CODES, isPriceRejection } from './chunk-AFRDHGDT.js';
1
+ export { FacilitatorClient, PARALLEL_TOKENS, SETTLE_AMOUNT_HEADER, createPaymentGate, createPaymentMiddleware, encodeBase64, getDefaultAcceptedTokens, parsePrice, resolveCharge, resolveSettleAmount, settleVerified, settlementFailureResponse, toEip155Network, validateAddress } from './chunk-GXPUE3ES.js';
2
+ export { X402ConfigError, X402PriceRejectedError, X402RuntimeError, X402_ERROR_CODES, isPriceRejection } from './chunk-QAECRSWF.js';
package/dist/llm.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkJPMK5YBU_cjs = require('./chunk-JPMK5YBU.cjs');
3
+ var chunkKZZY5LS6_cjs = require('./chunk-KZZY5LS6.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 chunkJPMK5YBU_cjs.X402ConfigError(
74
+ throw new chunkKZZY5LS6_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 chunkJPMK5YBU_cjs.X402ConfigError(`Invalid duration: ${value}`);
109
+ throw new chunkKZZY5LS6_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 chunkJPMK5YBU_cjs.X402ConfigError(
115
+ throw new chunkKZZY5LS6_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 chunkJPMK5YBU_cjs.X402PriceRejectedError(
183
+ throw new chunkKZZY5LS6_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 chunkJPMK5YBU_cjs.X402PriceRejectedError(
200
+ throw new chunkKZZY5LS6_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 chunkJPMK5YBU_cjs.X402PriceRejectedError(code, message);
213
+ throw new chunkKZZY5LS6_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 chunkJPMK5YBU_cjs.X402ConfigError(
225
+ throw new chunkKZZY5LS6_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 chunkJPMK5YBU_cjs.X402ConfigError(
230
+ throw new chunkKZZY5LS6_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 chunkJPMK5YBU_cjs.X402ConfigError("chatCompletionCap: models must not be empty");
235
+ throw new chunkKZZY5LS6_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 chunkJPMK5YBU_cjs.X402ConfigError(
298
+ throw new chunkKZZY5LS6_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 chunkJPMK5YBU_cjs.X402ConfigError(
346
+ throw new chunkKZZY5LS6_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 chunkJPMK5YBU_cjs.X402ConfigError(
352
+ throw new chunkKZZY5LS6_cjs.X402ConfigError(
353
353
  `forwardChatCompletion: maxOutputTokens must be a positive integer, got ${maxOutputTokens}`
354
354
  );
355
355
  }