@bankofai/x402-cli 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.
package/dist/cli.js CHANGED
@@ -1202,6 +1202,11 @@ async function pay(url, options) {
1202
1202
  body: ["GET", "HEAD"].includes(method.toUpperCase()) ? undefined : opt(options, "body"),
1203
1203
  }, timeoutMs(options), `fetch ${url}`);
1204
1204
  if (probe.status !== 402) {
1205
+ const body = await responsePayload(probe);
1206
+ if (!probe.ok) {
1207
+ const retryAfter = probe.headers.get("retry-after");
1208
+ throw new Error(`HTTP ${probe.status} from ${url}${retryAfter ? ` (retry after ${retryAfter}s)` : ""}: ${typeof body === "string" ? body.slice(0, 500) : JSON.stringify(body).slice(0, 500)}`);
1209
+ }
1205
1210
  emit({
1206
1211
  command: "client",
1207
1212
  mode: outputMode(options),
@@ -1209,7 +1214,7 @@ async function pay(url, options) {
1209
1214
  url,
1210
1215
  status: probe.status,
1211
1216
  message: "Not a payment-required endpoint",
1212
- response: await responsePayload(probe),
1217
+ response: body,
1213
1218
  },
1214
1219
  });
1215
1220
  return;
@@ -1260,7 +1265,8 @@ async function pay(url, options) {
1260
1265
  ...(paymentResponse ? { paymentResponse: decodeResponse(paymentResponse) } : {}),
1261
1266
  };
1262
1267
  if (!paid.ok) {
1263
- throw new Error(`HTTP ${paid.status} from ${url}: ${typeof body === "string" ? body.slice(0, 500) : JSON.stringify(body).slice(0, 500)}`);
1268
+ const retryAfter = paid.headers.get("retry-after");
1269
+ throw new Error(`HTTP ${paid.status} from ${url}${retryAfter ? ` (retry after ${retryAfter}s)` : ""}: ${typeof body === "string" ? body.slice(0, 500) : JSON.stringify(body).slice(0, 500)}`);
1264
1270
  }
1265
1271
  emit({
1266
1272
  command: "client",
@@ -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-cli",
3
- "version": "1.0.1-beta.1",
3
+ "version": "1.0.1-beta.2",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
@@ -22,7 +22,7 @@
22
22
  "dependencies": {
23
23
  "@bankofai/x402-core": "1.0.1-beta.4",
24
24
  "@bankofai/x402-evm": "1.0.1-beta.4",
25
- "@bankofai/x402-gateway": "1.0.1-beta.1",
25
+ "@bankofai/x402-gateway": "1.0.1-beta.2",
26
26
  "@bankofai/x402-tron": "1.0.1-beta.4",
27
27
  "tronweb": "6.4.0",
28
28
  "viem": "^2.55.0",