@parallel-protocol/x402 0.7.1 → 0.8.0

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/next.js CHANGED
@@ -1,5 +1,5 @@
1
- import { isJsonContentType, createPaymentGate, raceTimeout, HANDLER_TIMEOUT, SETTLE_AMOUNT_HEADER, resolveCharge, jsonFromResponse, invalidSettleAmountResponse, encodeBase64 } from './chunk-AENXD4OC.js';
2
- import './chunk-AFRDHGDT.js';
1
+ import { isJsonContentType, createPaymentGate, raceTimeout, HANDLER_TIMEOUT, SETTLE_AMOUNT_HEADER, resolveCharge, jsonFromResponse, invalidSettleAmountResponse, settleVerified, encodeBase64, settlementFailureResponse } from './chunk-SA5ULSG2.js';
2
+ import './chunk-QAECRSWF.js';
3
3
  import { NextResponse } from 'next/server';
4
4
 
5
5
  // src/next/adapter.ts
@@ -34,6 +34,12 @@ var NextAdapter = class {
34
34
  };
35
35
 
36
36
  // src/next/index.ts
37
+ function fromResult(result) {
38
+ return new NextResponse(JSON.stringify(result.body), {
39
+ status: result.status,
40
+ headers: { "Content-Type": "application/json", ...result.headers }
41
+ });
42
+ }
37
43
  function withPayment(config, handler) {
38
44
  const gate = createPaymentGate(config);
39
45
  return async (req) => {
@@ -41,15 +47,7 @@ function withPayment(config, handler) {
41
47
  if (gateResult.type === "pass") {
42
48
  return handler(req);
43
49
  }
44
- if (gateResult.type === "error") {
45
- return new NextResponse(JSON.stringify(gateResult.result.body), {
46
- status: gateResult.result.status,
47
- headers: {
48
- ...gateResult.result.headers,
49
- "Content-Type": "application/json"
50
- }
51
- });
52
- }
50
+ if (gateResult.type === "error") return fromResult(gateResult.result);
53
51
  let response;
54
52
  try {
55
53
  const outcome = await raceTimeout(
@@ -88,38 +86,24 @@ function withPayment(config, handler) {
88
86
  if (resolved.kind === "invalid") {
89
87
  handled.body?.cancel().catch(() => {
90
88
  });
91
- return NextResponse.json(
92
- invalidSettleAmountResponse(resolved.reason),
93
- {
94
- status: 402
95
- }
96
- );
89
+ return fromResult(invalidSettleAmountResponse(resolved.reason));
97
90
  }
98
91
  if (resolved.kind === "skip") return response;
99
92
  settleOptions = { amount: resolved.amount };
100
93
  }
101
- try {
102
- const settleResponse = settleOptions ? await gateResult.settle(settleOptions) : await gateResult.settle();
103
- if (settleResponse.success) {
104
- const headers = new Headers(response.headers);
105
- headers.set("payment-response", encodeBase64(settleResponse));
106
- headers.set("access-control-expose-headers", "payment-response");
107
- return new NextResponse(response.body, {
108
- status: response.status,
109
- headers
110
- });
111
- }
112
- } catch {
94
+ const outcome = await settleVerified(gateResult, settleOptions);
95
+ if (outcome.settled) {
96
+ const headers = new Headers(response.headers);
97
+ headers.set("payment-response", encodeBase64(outcome.confirmation));
98
+ headers.set("access-control-expose-headers", "payment-response");
99
+ return new NextResponse(response.body, {
100
+ status: response.status,
101
+ headers
102
+ });
113
103
  }
114
104
  response.body?.cancel().catch(() => {
115
105
  });
116
- return NextResponse.json(
117
- {
118
- error: "PAYMENT_SETTLEMENT_FAILED",
119
- message: "Payment could not be confirmed after multiple attempts. Please retry."
120
- },
121
- { status: 402 }
122
- );
106
+ return fromResult(settlementFailureResponse(outcome));
123
107
  }
124
108
  return response;
125
109
  };
@@ -117,6 +117,8 @@ interface PaymentRequirements {
117
117
  interface PaymentRequired {
118
118
  x402Version: number;
119
119
  error?: string;
120
+ /** The facilitator's message for `error`, when it answered with one. */
121
+ message?: string;
120
122
  resource: ResourceInfo;
121
123
  accepts: PaymentRequirements[];
122
124
  extensions?: Record<string, unknown>;
@@ -134,6 +136,24 @@ interface SettleOptions {
134
136
  /** Amount actually charged, in the asset's smallest unit. */
135
137
  amount?: string;
136
138
  }
139
+ /**
140
+ * What `FacilitatorClient.settle` sends besides the payment: the metered
141
+ * amount, and the settle token the facilitator issued at verify. The payment
142
+ * gate fills the token in itself; a direct caller of the client passes the one
143
+ * `verify` returned.
144
+ */
145
+ interface FacilitatorSettleOptions extends SettleOptions {
146
+ settleToken?: string;
147
+ }
148
+ /**
149
+ * What a successful `FacilitatorClient.verify` returns: the settle token the
150
+ * facilitator issued for this payment, to present back at settle. It is a
151
+ * secret for the life of the request: keep it in memory, never log it, never
152
+ * send it to the payer.
153
+ */
154
+ interface VerifyResult {
155
+ settleToken: string;
156
+ }
137
157
  interface PaymentConfirmation {
138
158
  success: true;
139
159
  txHash: Address;
@@ -143,6 +163,11 @@ interface PaymentConfirmation {
143
163
  networkId: string;
144
164
  /** Amount actually charged (smallest unit) — metered routes only. */
145
165
  amountSettled?: string;
166
+ /**
167
+ * Present when the facilitator answered from the outcome an earlier settle
168
+ * of the same payment recorded: this call broadcast nothing.
169
+ */
170
+ alreadySettled?: true;
146
171
  }
147
172
  interface PaymentFailure {
148
173
  success: false;
@@ -150,6 +175,10 @@ interface PaymentFailure {
150
175
  code: string;
151
176
  message: string;
152
177
  hint?: string;
178
+ /** The facilitator's HTTP status, when the refusal is its answer. */
179
+ status?: number;
180
+ /** The facilitator's `Retry-After` header, when it sent one. */
181
+ retryAfter?: string;
153
182
  };
154
183
  }
155
184
  type FacilitatorResponse = PaymentConfirmation | PaymentFailure;
@@ -182,4 +211,4 @@ type PaymentGateResult = {
182
211
  result: MiddlewareResult;
183
212
  } | VerifiedPayment;
184
213
 
185
- export type { FacilitatorConfig as F, HTTPAdapter as H, MiddlewareResult as M, PaymentMiddlewareConfig as P, RunHandlerOptions as R, SettleOptions as S, VerifiedPayment as V, RunHandlerResult as a, FacilitatorPaymentRequirements as b, FacilitatorResponse as c, PaymentGateResult as d, PassResult as e, MeterContext as f, MeterFunction as g, PaymentConfirmation as h, PaymentFailure as i, PaymentRequired as j, PaymentRequirements as k, PriceContext as l, PriceFunction as m, ResourceInfo as n, RouteConfig as o };
214
+ export type { FacilitatorConfig as F, HTTPAdapter as H, MiddlewareResult as M, PaymentMiddlewareConfig as P, RunHandlerOptions as R, SettleOptions as S, VerifyResult as V, RunHandlerResult as a, FacilitatorPaymentRequirements as b, FacilitatorSettleOptions as c, FacilitatorResponse as d, PaymentConfirmation as e, PaymentGateResult as f, PassResult as g, VerifiedPayment as h, MeterContext as i, MeterFunction as j, PaymentFailure as k, PaymentRequired as l, PaymentRequirements as m, PriceContext as n, PriceFunction as o, ResourceInfo as p, RouteConfig as q };
@@ -117,6 +117,8 @@ interface PaymentRequirements {
117
117
  interface PaymentRequired {
118
118
  x402Version: number;
119
119
  error?: string;
120
+ /** The facilitator's message for `error`, when it answered with one. */
121
+ message?: string;
120
122
  resource: ResourceInfo;
121
123
  accepts: PaymentRequirements[];
122
124
  extensions?: Record<string, unknown>;
@@ -134,6 +136,24 @@ interface SettleOptions {
134
136
  /** Amount actually charged, in the asset's smallest unit. */
135
137
  amount?: string;
136
138
  }
139
+ /**
140
+ * What `FacilitatorClient.settle` sends besides the payment: the metered
141
+ * amount, and the settle token the facilitator issued at verify. The payment
142
+ * gate fills the token in itself; a direct caller of the client passes the one
143
+ * `verify` returned.
144
+ */
145
+ interface FacilitatorSettleOptions extends SettleOptions {
146
+ settleToken?: string;
147
+ }
148
+ /**
149
+ * What a successful `FacilitatorClient.verify` returns: the settle token the
150
+ * facilitator issued for this payment, to present back at settle. It is a
151
+ * secret for the life of the request: keep it in memory, never log it, never
152
+ * send it to the payer.
153
+ */
154
+ interface VerifyResult {
155
+ settleToken: string;
156
+ }
137
157
  interface PaymentConfirmation {
138
158
  success: true;
139
159
  txHash: Address;
@@ -143,6 +163,11 @@ interface PaymentConfirmation {
143
163
  networkId: string;
144
164
  /** Amount actually charged (smallest unit) — metered routes only. */
145
165
  amountSettled?: string;
166
+ /**
167
+ * Present when the facilitator answered from the outcome an earlier settle
168
+ * of the same payment recorded: this call broadcast nothing.
169
+ */
170
+ alreadySettled?: true;
146
171
  }
147
172
  interface PaymentFailure {
148
173
  success: false;
@@ -150,6 +175,10 @@ interface PaymentFailure {
150
175
  code: string;
151
176
  message: string;
152
177
  hint?: string;
178
+ /** The facilitator's HTTP status, when the refusal is its answer. */
179
+ status?: number;
180
+ /** The facilitator's `Retry-After` header, when it sent one. */
181
+ retryAfter?: string;
153
182
  };
154
183
  }
155
184
  type FacilitatorResponse = PaymentConfirmation | PaymentFailure;
@@ -182,4 +211,4 @@ type PaymentGateResult = {
182
211
  result: MiddlewareResult;
183
212
  } | VerifiedPayment;
184
213
 
185
- export type { FacilitatorConfig as F, HTTPAdapter as H, MiddlewareResult as M, PaymentMiddlewareConfig as P, RunHandlerOptions as R, SettleOptions as S, VerifiedPayment as V, RunHandlerResult as a, FacilitatorPaymentRequirements as b, FacilitatorResponse as c, PaymentGateResult as d, PassResult as e, MeterContext as f, MeterFunction as g, PaymentConfirmation as h, PaymentFailure as i, PaymentRequired as j, PaymentRequirements as k, PriceContext as l, PriceFunction as m, ResourceInfo as n, RouteConfig as o };
214
+ export type { FacilitatorConfig as F, HTTPAdapter as H, MiddlewareResult as M, PaymentMiddlewareConfig as P, RunHandlerOptions as R, SettleOptions as S, VerifyResult as V, RunHandlerResult as a, FacilitatorPaymentRequirements as b, FacilitatorSettleOptions as c, FacilitatorResponse as d, PaymentConfirmation as e, PaymentGateResult as f, PassResult as g, VerifiedPayment as h, MeterContext as i, MeterFunction as j, PaymentFailure as k, PaymentRequired as l, PaymentRequirements as m, PriceContext as n, PriceFunction as o, ResourceInfo as p, RouteConfig as q };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parallel-protocol/x402",
3
- "version": "0.7.1",
3
+ "version": "0.8.0",
4
4
  "description": "Parallel Protocol x402 payment middleware — Express, Next.js, Fastify, Hono",
5
5
  "author": "Parallel Protocol <contact@parallel.best>",
6
6
  "repository": {