@bankofai/x402-cli 1.0.1-beta.1 → 1.0.1-beta.3

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/README.md CHANGED
@@ -3,9 +3,9 @@
3
3
  TypeScript command-line client for BankofAI x402 payments. This version uses
4
4
  the npm TypeScript SDK packages only:
5
5
 
6
- - `@bankofai/x402-core@1.0.1-beta.2`
7
- - `@bankofai/x402-evm@1.0.1-beta.2`
8
- - `@bankofai/x402-tron@1.0.1-beta.2`
6
+ - `@bankofai/x402-core@1.0.1-beta.4`
7
+ - `@bankofai/x402-evm@1.0.1-beta.4`
8
+ - `@bankofai/x402-tron@1.0.1-beta.4`
9
9
 
10
10
  Stablecoin payments support `scheme=exact` and TRON `scheme=exact_gasfree`.
11
11
  The GasFree flow lets the relayer pay network energy while deducting its fee
@@ -21,7 +21,7 @@ npm run build
21
21
  Run from source during development:
22
22
 
23
23
  ```bash
24
- npm run dev -- serve --pay-to <recipient> --amount 0.0001 --network tron:nile --token USDT
24
+ npm run dev -- serve --pay-to <recipient> --amount 0.0001 --network tron:0xcd8690dc --token USDT
25
25
  ```
26
26
 
27
27
  Run the compiled CLI:
@@ -52,7 +52,7 @@ Start a local x402 paywall endpoint:
52
52
  node dist/cli.js serve \
53
53
  --pay-to <recipient> \
54
54
  --amount 0.0001 \
55
- --network tron:nile \
55
+ --network tron:0xcd8690dc \
56
56
  --token USDT \
57
57
  --port 4020
58
58
  ```
@@ -71,7 +71,7 @@ Pay an x402-protected URL:
71
71
  ```bash
72
72
  TRON_PRIVATE_KEY=<hex> \
73
73
  node dist/cli.js pay http://127.0.0.1:4020/pay \
74
- --network tron:nile \
74
+ --network tron:0xcd8690dc \
75
75
  --token USDT
76
76
  ```
77
77
 
@@ -81,7 +81,7 @@ the server challenge):
81
81
  ```bash
82
82
  TRON_PRIVATE_KEY=<hex> \
83
83
  node dist/cli.js pay https://api.example.com/pay \
84
- --network tron:nile \
84
+ --network tron:0xcd8690dc \
85
85
  --token USDT \
86
86
  --scheme exact_gasfree
87
87
  ```
@@ -100,7 +100,7 @@ TRON_PRIVATE_KEY=<hex> \
100
100
  node dist/cli.js roundtrip \
101
101
  --pay-to <recipient> \
102
102
  --amount 0.0001 \
103
- --network tron:nile \
103
+ --network tron:0xcd8690dc \
104
104
  --token USDT
105
105
  ```
106
106
 
@@ -108,16 +108,17 @@ node dist/cli.js roundtrip \
108
108
 
109
109
  Supported built-in token registry:
110
110
 
111
- - `tron:mainnet` USDT, USDD
112
- - `tron:nile` USDT, USDD
113
- - `tron:shasta` USDT
111
+ - `tron:0x2b6653dc` USDT, USDD
112
+ - `tron:0xcd8690dc` USDT, USDD
113
+ - `tron:0x94a9059e` USDT
114
114
  - `eip155:56` USDT
115
115
  - `eip155:97` USDT, USDC
116
116
 
117
- Aliases accepted:
117
+ Legacy aliases remain accepted for backward compatibility, but new commands and
118
+ configuration should use the canonical IDs above:
118
119
 
119
- - `tron-mainnet` -> `tron:mainnet`
120
- - `tron-nile` -> `tron:nile`
120
+ - `tron-mainnet` -> `tron:0x2b6653dc`
121
+ - `tron-nile` -> `tron:0xcd8690dc`
121
122
  - `bsc-mainnet` -> `eip155:56`
122
123
  - `bsc-testnet` -> `eip155:97`
123
124
 
package/dist/cli.js CHANGED
@@ -335,7 +335,7 @@ Options:
335
335
  --pay-to <address> Recipient wallet address
336
336
  --amount <amount> Human-readable token amount (default: 0.0001)
337
337
  --raw-amount <amount> Smallest-unit amount
338
- --network <caip2> Payment network (default: tron:nile)
338
+ --network <caip2> Payment network (default: tron:0xcd8690dc)
339
339
  --scheme <scheme> Payment scheme: exact or exact_gasfree (default: exact)
340
340
  --token <symbol> Token symbol (default: USDT)
341
341
  --asset <address> Explicit token address
@@ -349,7 +349,7 @@ Options:
349
349
  --json Print JSON envelope
350
350
 
351
351
  Examples:
352
- x402-cli serve --pay-to T... --network tron:nile --token USDT
352
+ x402-cli serve --pay-to T... --network tron:0xcd8690dc --token USDT
353
353
  x402-cli serve --pay-to 0x... --network eip155:97 --token USDT --amount 0.0001
354
354
  `,
355
355
  roundtrip: `Usage:
@@ -968,7 +968,7 @@ async function catalogExportGateway(gatewayUrl, options) {
968
968
  emit({ command: "catalog export-gateway", mode: outputMode(options), result: { provider: providerFqn, catalog: catalogPath, payMd: payMdPath } });
969
969
  }
970
970
  function buildRequirement(options) {
971
- const network = normalizeNetwork(opt(options, "network", "tron:nile"));
971
+ const network = normalizeNetwork(opt(options, "network", "tron:0xcd8690dc"));
972
972
  const scheme = opt(options, "scheme", "exact");
973
973
  if (!["exact", "exact_gasfree"].includes(scheme))
974
974
  throw new Error(`unsupported scheme ${scheme}`);
@@ -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",
@@ -1366,7 +1372,7 @@ routing:
1366
1372
  type: proxy
1367
1373
 
1368
1374
  operator:
1369
- network: tron-nile
1375
+ network: tron:0xcd8690dc
1370
1376
  currencies:
1371
1377
  usd: ["USDT"]
1372
1378
  recipient: <provider-recipient-address>
@@ -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.3",
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.3",
26
26
  "@bankofai/x402-tron": "1.0.1-beta.4",
27
27
  "tronweb": "6.4.0",
28
28
  "viem": "^2.55.0",