@bankofai/x402-gateway 1.0.1-beta.1 → 1.0.1-beta.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.
Files changed (2) hide show
  1. package/dist/server.js +16 -3
  2. package/package.json +1 -1
package/dist/server.js CHANGED
@@ -5,10 +5,12 @@ import { decodeSignature, encodeRequired, encodeResponse, headers, matchRequirem
5
5
  class HttpError extends Error {
6
6
  status;
7
7
  publicMessage;
8
- constructor(status, publicMessage, message = publicMessage) {
8
+ responseHeaders;
9
+ constructor(status, publicMessage, message = publicMessage, responseHeaders = {}) {
9
10
  super(message);
10
11
  this.status = status;
11
12
  this.publicMessage = publicMessage;
13
+ this.responseHeaders = responseHeaders;
12
14
  }
13
15
  }
14
16
  class RequestTooLargeError extends HttpError {
@@ -102,10 +104,21 @@ async function facilitatorPost(entry, path, body) {
102
104
  }
103
105
  if (!response.ok) {
104
106
  logFacilitatorFailure(entry, path, response, body, data);
107
+ if (response.status === 429) {
108
+ const retryAfter = response.headers.get("retry-after");
109
+ throw new HttpError(429, "facilitator rate limited", `facilitator ${path} rate limited`, retryAfter ? { "retry-after": retryAfter } : {});
110
+ }
105
111
  throw new HttpError(502, "facilitator request failed", `facilitator ${path} failed: ${response.status}`);
106
112
  }
107
113
  return data;
108
114
  }
115
+ function resourceUrl(url) {
116
+ const path = `${url.pathname}${url.search}`;
117
+ const publicBaseUrl = process.env.X402_GATEWAY_PUBLIC_BASE_URL?.trim();
118
+ if (!publicBaseUrl)
119
+ return path;
120
+ return new URL(path, `${publicBaseUrl.replace(/\/+$/, "")}/`).toString();
121
+ }
109
122
  function logFacilitatorFailure(entry, path, response, body, data) {
110
123
  const requirement = body?.paymentRequirements;
111
124
  const nestedError = data?.error && typeof data.error === "object" ? data.error : undefined;
@@ -298,7 +311,7 @@ export function createGatewayServer(providers) {
298
311
  const challenge = {
299
312
  x402Version: 2,
300
313
  error: "Payment required",
301
- resource: { url: url.pathname },
314
+ resource: { url: resourceUrl(url) },
302
315
  accepts,
303
316
  };
304
317
  json(response, 402, challenge, { [headers.required]: encodeRequired(challenge) });
@@ -347,7 +360,7 @@ export function createGatewayServer(providers) {
347
360
  }
348
361
  catch (error) {
349
362
  if (error instanceof HttpError) {
350
- json(response, error.status, { error: error.publicMessage });
363
+ json(response, error.status, { error: error.publicMessage }, error.responseHeaders);
351
364
  return;
352
365
  }
353
366
  console.error(error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bankofai/x402-gateway",
3
- "version": "1.0.1-beta.1",
3
+ "version": "1.0.1-beta.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "files": [