@bankofai/x402-cli 1.0.1-beta.4 → 1.0.1-beta.6

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
@@ -13,6 +13,15 @@ from the payment token, so the payer does not need TRX.
13
13
 
14
14
  ## Install
15
15
 
16
+ Install the CLI package:
17
+
18
+ ```bash
19
+ npm install -g @bankofai/x402-cli
20
+ x402-cli --version
21
+ ```
22
+
23
+ For repository development:
24
+
16
25
  ```bash
17
26
  npm install
18
27
  npm run build
@@ -61,8 +70,8 @@ The server exposes:
61
70
 
62
71
  - `GET /health`
63
72
  - `GET /.well-known/x402`
64
- - `GET /pay` returns `402 Payment Required`
65
- - `POST /pay` verifies and settles with the facilitator
73
+ - `/pay` returns `402 Payment Required` without a payment signature
74
+ - The signed retry uses the same HTTP method, then verifies and settles with the facilitator
66
75
 
67
76
  ### Pay
68
77
 
@@ -75,6 +84,9 @@ node dist/cli.js pay http://127.0.0.1:4020/pay \
75
84
  --token USDT
76
85
  ```
77
86
 
87
+ For automated or unfamiliar endpoints, set `--max-amount` or
88
+ `--max-raw-amount` before allowing the CLI to sign a payment.
89
+
78
90
  Pay a TRON GasFree endpoint (the CLI normally selects this automatically from
79
91
  the server challenge):
80
92
 
@@ -89,7 +101,31 @@ node dist/cli.js pay https://api.example.com/pay \
89
101
  Use `--gasfree-api-url <url>` or `X402_GASFREE_API_URL` to override the SDK's
90
102
  default relayer endpoint.
91
103
 
104
+ GasFree fees are separate from the advertised payment amount. Set a fee limit
105
+ so the CLI estimates the relayer fee and rejects the payment before signing if
106
+ the estimate is too high:
107
+
108
+ ```bash
109
+ x402-cli pay https://api.example.com/pay \
110
+ --scheme exact_gasfree \
111
+ --max-amount 0.01 \
112
+ --max-gasfree-fee 0.5 \
113
+ --json
114
+ ```
115
+
116
+ Use `--max-gasfree-fee-raw` to express the fee limit in the token's smallest
117
+ unit. Successful and failed paid responses distinguish `settled` (payment
118
+ completed) from `delivered` (HTTP business response succeeded). A settled
119
+ upstream failure has `paid=true`, `settled=true`, and `delivered=false` and
120
+ includes its transaction information.
121
+
92
122
  For EVM networks use `EVM_PRIVATE_KEY` or `PRIVATE_KEY`.
123
+ Prefer environment variables over `--private-key` in shared environments,
124
+ because command-line arguments may be visible to other local processes.
125
+
126
+ If the gateway settles a payment but the upstream request fails, JSON error
127
+ output includes `error.details.paymentResponse` for reconciliation. Do not retry
128
+ such a request blindly; inspect the transaction and provider behavior first.
93
129
 
94
130
  ### Roundtrip
95
131
 
package/dist/cli.js CHANGED
@@ -18,11 +18,13 @@ class CliError extends Error {
18
18
  code;
19
19
  hint;
20
20
  exitCode;
21
- constructor(code, message, hint, exitCode = 1) {
21
+ details;
22
+ constructor(code, message, hint, exitCode = 1, details) {
22
23
  super(message);
23
24
  this.code = code;
24
25
  this.hint = hint;
25
26
  this.exitCode = exitCode;
27
+ this.details = details;
26
28
  }
27
29
  }
28
30
  function parseArgs(argv) {
@@ -144,6 +146,8 @@ function emit(args) {
144
146
  process.stderr.write(` ${args.error.message}\n`);
145
147
  if (args.error.hint)
146
148
  process.stderr.write(` hint: ${args.error.hint}\n`);
149
+ if (args.error.details !== undefined)
150
+ process.stderr.write(` details: ${JSON.stringify(args.error.details)}\n`);
147
151
  return;
148
152
  }
149
153
  const suffix = [args.network, args.scheme].filter(Boolean).join(" ");
@@ -171,6 +175,7 @@ function classify(error) {
171
175
  code: error.code,
172
176
  message,
173
177
  hint: error.hint,
178
+ details: error.details,
174
179
  };
175
180
  }
176
181
  const lower = message.toLowerCase();
@@ -316,6 +321,8 @@ Options:
316
321
  --token <symbol> Require a specific token
317
322
  --scheme <scheme> Require a specific x402 scheme
318
323
  --gasfree-api-url <url> Override the TRON GasFree relayer API URL
324
+ --max-gasfree-fee <amt> Maximum GasFree relayer fee in token units
325
+ --max-gasfree-fee-raw <n> Maximum GasFree relayer fee in smallest units
319
326
  --max-amount <amount> Maximum human-readable payment amount
320
327
  --max-raw-amount <amount> Maximum smallest-unit payment amount
321
328
  --dry-run Read requirements but do not sign or pay
@@ -737,7 +744,7 @@ async function fetchWithTimeout(input, init = {}, timeout = DEFAULT_TIMEOUT_MS,
737
744
  return await fetch(input, { ...init, signal: controller.signal });
738
745
  }
739
746
  catch (error) {
740
- if (error?.name === "AbortError")
747
+ if (error instanceof Error && error.name === "AbortError")
741
748
  throw new Error(`${label} timed out after ${timeout}ms`);
742
749
  throw error;
743
750
  }
@@ -1079,6 +1086,31 @@ function validateAmountLimits(selected, options) {
1079
1086
  }
1080
1087
  }
1081
1088
  }
1089
+ function gasfreeFeeLimitRaw(selected, options) {
1090
+ const maxRaw = opt(options, "max-gasfree-fee-raw");
1091
+ const maxHuman = opt(options, "max-gasfree-fee");
1092
+ if (maxRaw && maxHuman) {
1093
+ throw new CliError("INVALID_ARGUMENT", "--max-gasfree-fee and --max-gasfree-fee-raw are mutually exclusive", "Pass one GasFree fee limit.", 2);
1094
+ }
1095
+ if (selected.scheme !== "exact_gasfree") {
1096
+ if (maxRaw || maxHuman)
1097
+ throw new Error("GasFree fee limits require an exact_gasfree payment requirement");
1098
+ return undefined;
1099
+ }
1100
+ if (maxRaw)
1101
+ return assertRawAmount(maxRaw, "--max-gasfree-fee-raw");
1102
+ if (!maxHuman)
1103
+ return undefined;
1104
+ const token = findTokenByAddress(selected.network, selected.asset);
1105
+ const decimalsOption = opt(options, "decimals");
1106
+ if (!token && decimalsOption === undefined) {
1107
+ throw new Error("cannot evaluate --max-gasfree-fee for an unknown asset; pass --max-gasfree-fee-raw or --decimals");
1108
+ }
1109
+ const decimals = decimalsOption !== undefined ? Number(decimalsOption) : token.decimals;
1110
+ if (!Number.isInteger(decimals) || decimals < 0)
1111
+ throw new Error("--decimals must be a non-negative integer");
1112
+ return toSmallestUnit(maxHuman, decimals);
1113
+ }
1082
1114
  async function serve(options) {
1083
1115
  const host = opt(options, "host", "127.0.0.1");
1084
1116
  const port = Number(opt(options, "port", "4020"));
@@ -1182,7 +1214,13 @@ function selectRequirement(accepts, options) {
1182
1214
  if (scheme && scheme !== req.scheme)
1183
1215
  return false;
1184
1216
  if (token) {
1185
- const tokenInfo = getToken(req.network, token);
1217
+ let tokenInfo;
1218
+ try {
1219
+ tokenInfo = getToken(req.network, token);
1220
+ }
1221
+ catch {
1222
+ return false;
1223
+ }
1186
1224
  if (tokenInfo.address.toLowerCase() !== req.asset.toLowerCase())
1187
1225
  return false;
1188
1226
  }
@@ -1225,6 +1263,7 @@ async function pay(url, options) {
1225
1263
  const required = decodeRequired(header);
1226
1264
  const selected = selectRequirement(required.accepts ?? [], options);
1227
1265
  validateAmountLimits(selected, options);
1266
+ const maxGasfreeFeeRaw = gasfreeFeeLimitRaw(selected, options);
1228
1267
  if (options["dry-run"]) {
1229
1268
  emit({
1230
1269
  command: "client",
@@ -1240,16 +1279,17 @@ async function pay(url, options) {
1240
1279
  });
1241
1280
  return;
1242
1281
  }
1243
- const payload = await withSdkStdoutRedirect(outputMode(options) === "json", () => createPaymentPayload({
1282
+ const creation = await withSdkStdoutRedirect(outputMode(options) === "json", () => createPaymentPayload({
1244
1283
  selected,
1245
1284
  resource: required.resource?.url ?? url,
1246
1285
  extensions: required.extensions,
1247
1286
  rpcUrl: opt(options, "rpc-url"),
1248
1287
  privateKey: opt(options, "private-key"),
1249
1288
  gasfreeApiUrl: opt(options, "gasfree-api-url"),
1289
+ maxGasfreeFeeRaw,
1250
1290
  }));
1251
1291
  const retryHeaders = new Headers(baseHeaders);
1252
- retryHeaders.set(headers.signature, encodeSignature(payload));
1292
+ retryHeaders.set(headers.signature, encodeSignature(creation.payload));
1253
1293
  const paid = await fetchWithTimeout(url, {
1254
1294
  method,
1255
1295
  headers: retryHeaders,
@@ -1257,16 +1297,26 @@ async function pay(url, options) {
1257
1297
  }, timeoutMs(options), `fetch ${url}`);
1258
1298
  const body = await responsePayload(paid);
1259
1299
  const paymentResponse = paid.headers.get(headers.response);
1300
+ const settlement = paymentResponse ? decodeResponse(paymentResponse) : undefined;
1301
+ const settled = settlement !== undefined;
1260
1302
  const result = {
1261
1303
  url,
1262
1304
  status: paid.status,
1263
- paid: paid.ok,
1305
+ paid: settled,
1306
+ settled,
1307
+ delivered: paid.ok,
1264
1308
  response: body,
1265
- ...(paymentResponse ? { paymentResponse: decodeResponse(paymentResponse) } : {}),
1309
+ ...(settlement !== undefined ? {
1310
+ paymentResponse: settlement,
1311
+ transaction: settlement?.transaction ?? settlement?.txHash ?? null,
1312
+ } : {}),
1313
+ ...(creation.gasfreeEstimate ? { gasfreeEstimate: creation.gasfreeEstimate } : {}),
1266
1314
  };
1267
1315
  if (!paid.ok) {
1268
1316
  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)}`);
1317
+ throw new CliError(paid.status === 429 ? "RATE_LIMITED" : "HTTP_ERROR", `HTTP ${paid.status} from ${url}${retryAfter ? ` (retry after ${retryAfter}s)` : ""}: ${typeof body === "string" ? body.slice(0, 500) : JSON.stringify(body).slice(0, 500)}`, paymentResponse
1318
+ ? "The gateway reports that payment was settled; retain paymentResponse for support or reconciliation."
1319
+ : "Inspect the HTTP response and retry only when it is safe to do so.", 1, result);
1270
1320
  }
1271
1321
  emit({
1272
1322
  command: "client",
@@ -1278,8 +1328,7 @@ async function pay(url, options) {
1278
1328
  }
1279
1329
  async function roundtrip(options) {
1280
1330
  const port = Number(opt(options, "port", "4020"));
1281
- serve(options);
1282
- await delay(500);
1331
+ await serve(options);
1283
1332
  await pay(`http://127.0.0.1:${port}/pay`, options);
1284
1333
  process.exit(0);
1285
1334
  }
@@ -104,15 +104,21 @@ export function loadProvider(file) {
104
104
  validateProvider(config, file);
105
105
  config.operator.network = normalizeNetwork(config.operator.network);
106
106
  normalizePaymentProtocol(config, file);
107
+ const facilitatorUrl = config.operator.facilitator_url ||
108
+ process.env.X402_FACILITATOR_URL ||
109
+ process.env.FACILITATOR_URL ||
110
+ "https://facilitator.bankofai.io";
111
+ assertHttpUrl(facilitatorUrl, `${file}: facilitator URL`);
112
+ const configuredApiKeyEnv = config.operator.facilitator_api_key_env;
113
+ if (configuredApiKeyEnv && !process.env[configuredApiKeyEnv]) {
114
+ throw new Error(`${file}: environment variable ${configuredApiKeyEnv} is not set`);
115
+ }
107
116
  return {
108
117
  config,
109
- facilitatorUrl: config.operator.facilitator_url ||
110
- process.env.X402_FACILITATOR_URL ||
111
- process.env.FACILITATOR_URL ||
112
- "https://facilitator.bankofai.io",
118
+ facilitatorUrl,
113
119
  facilitatorApiKey: config.operator.facilitator_api_key ||
114
- (config.operator.facilitator_api_key_env
115
- ? process.env[config.operator.facilitator_api_key_env]
120
+ (configuredApiKeyEnv
121
+ ? process.env[configuredApiKeyEnv]
116
122
  : undefined) ||
117
123
  process.env.X402_FACILITATOR_API_KEY ||
118
124
  process.env.FACILITATOR_API_KEY,
@@ -18,9 +18,20 @@ class RequestTooLargeError extends HttpError {
18
18
  super(413, "request body too large");
19
19
  }
20
20
  }
21
- const MAX_BODY_BYTES = Number(process.env.X402_GATEWAY_MAX_BODY_BYTES ?? 1_000_000);
22
- const FACILITATOR_TIMEOUT_MS = Number(process.env.X402_GATEWAY_FACILITATOR_TIMEOUT_MS ?? 10_000);
23
- const UPSTREAM_TIMEOUT_MS = Number(process.env.X402_GATEWAY_UPSTREAM_TIMEOUT_MS ?? 30_000);
21
+ function positiveIntegerEnv(name, fallback) {
22
+ const raw = process.env[name];
23
+ if (raw === undefined || raw === "")
24
+ return fallback;
25
+ if (!/^\d+$/.test(raw))
26
+ throw new Error(`${name} must be a positive integer`);
27
+ const value = Number(raw);
28
+ if (!Number.isSafeInteger(value) || value <= 0)
29
+ throw new Error(`${name} must be a positive integer`);
30
+ return value;
31
+ }
32
+ const MAX_BODY_BYTES = positiveIntegerEnv("X402_GATEWAY_MAX_BODY_BYTES", 1_000_000);
33
+ const FACILITATOR_TIMEOUT_MS = positiveIntegerEnv("X402_GATEWAY_FACILITATOR_TIMEOUT_MS", 10_000);
34
+ const UPSTREAM_TIMEOUT_MS = positiveIntegerEnv("X402_GATEWAY_UPSTREAM_TIMEOUT_MS", 30_000);
24
35
  const STRIP_REQUEST_HEADERS = new Set([
25
36
  "host",
26
37
  "connection",
@@ -48,14 +59,22 @@ const STRIP_RESPONSE_HEADERS = new Set([
48
59
  "authorization",
49
60
  "proxy-authorization",
50
61
  "set-cookie",
62
+ "payment-required",
63
+ "x-payment-required",
64
+ "payment-signature",
65
+ "x-payment",
66
+ "payment-response",
67
+ "x-payment-response",
51
68
  ]);
52
- const metrics = {
53
- requests: 0,
54
- paidRequests: 0,
55
- verifyFailures: 0,
56
- settleFailures: 0,
57
- upstreamFailures: 0,
58
- };
69
+ function createMetrics() {
70
+ return {
71
+ requests: 0,
72
+ paidRequests: 0,
73
+ verifyFailures: 0,
74
+ settleFailures: 0,
75
+ upstreamFailures: 0,
76
+ };
77
+ }
59
78
  async function readBody(request) {
60
79
  const chunks = [];
61
80
  let total = 0;
@@ -79,7 +98,7 @@ async function fetchWithTimeout(url, init, timeoutMs, label = "upstream") {
79
98
  return await fetch(url, { ...init, signal: controller.signal });
80
99
  }
81
100
  catch (error) {
82
- if (error?.name === "AbortError")
101
+ if (error instanceof Error && error.name === "AbortError")
83
102
  throw new HttpError(504, `${label} request timed out`);
84
103
  throw error;
85
104
  }
@@ -112,12 +131,25 @@ async function facilitatorPost(entry, path, body) {
112
131
  }
113
132
  return data;
114
133
  }
115
- function resourceUrl(url) {
134
+ function configuredPublicBaseUrl() {
135
+ const value = process.env.X402_GATEWAY_PUBLIC_BASE_URL?.trim();
136
+ if (!value)
137
+ return undefined;
138
+ try {
139
+ const url = new URL(value);
140
+ if (!["http:", "https:"].includes(url.protocol))
141
+ throw new Error("unsupported protocol");
142
+ return `${value.replace(/\/+$/, "")}/`;
143
+ }
144
+ catch {
145
+ throw new Error("X402_GATEWAY_PUBLIC_BASE_URL must be a valid http(s) URL");
146
+ }
147
+ }
148
+ function resourceUrl(url, publicBaseUrl) {
116
149
  const path = `${url.pathname}${url.search}`;
117
- const publicBaseUrl = process.env.X402_GATEWAY_PUBLIC_BASE_URL?.trim();
118
150
  if (!publicBaseUrl)
119
151
  return path;
120
- return new URL(path, `${publicBaseUrl.replace(/\/+$/, "")}/`).toString();
152
+ return new URL(path, publicBaseUrl).toString();
121
153
  }
122
154
  function logFacilitatorFailure(entry, path, response, body, data) {
123
155
  const requirement = body?.paymentRequirements;
@@ -205,7 +237,7 @@ function upstreamUrl(entry, request, routePath) {
205
237
  }
206
238
  return upstream;
207
239
  }
208
- async function forward(entry, request, response, routePath, body, paymentResponse) {
240
+ async function forward(metrics, entry, request, response, routePath, body, paymentResponse) {
209
241
  const upstream = upstreamUrl(entry, request, routePath);
210
242
  let upstreamResponse;
211
243
  try {
@@ -229,10 +261,13 @@ async function forward(entry, request, response, routePath, body, paymentRespons
229
261
  });
230
262
  if (paymentResponse)
231
263
  responseHeaders[headers.response] = encodeResponse(paymentResponse);
264
+ const responseBody = Buffer.from(await upstreamResponse.arrayBuffer());
232
265
  response.writeHead(upstreamResponse.status, responseHeaders);
233
- response.end(Buffer.from(await upstreamResponse.arrayBuffer()));
266
+ response.end(responseBody);
234
267
  }
235
268
  export function createGatewayServer(providers) {
269
+ const publicBaseUrl = configuredPublicBaseUrl();
270
+ const metrics = createMetrics();
236
271
  return http.createServer(async (request, response) => {
237
272
  try {
238
273
  metrics.requests += 1;
@@ -302,7 +337,7 @@ export function createGatewayServer(providers) {
302
337
  const body = await readBody(request);
303
338
  const requirements = paymentRequirements(entry.config, priceUsd(endpoint, requestParams(url, body, request)));
304
339
  if (!requirements.length) {
305
- await forward(entry, request, response, routePath, body);
340
+ await forward(metrics, entry, request, response, routePath, body);
306
341
  return;
307
342
  }
308
343
  const paymentHeader = request.headers[headers.signature.toLowerCase()];
@@ -311,7 +346,7 @@ export function createGatewayServer(providers) {
311
346
  const challenge = {
312
347
  x402Version: 2,
313
348
  error: "Payment required",
314
- resource: { url: resourceUrl(url) },
349
+ resource: { url: resourceUrl(url, publicBaseUrl) },
315
350
  accepts,
316
351
  };
317
352
  json(response, 402, challenge, { [headers.required]: encodeRequired(challenge) });
@@ -356,7 +391,20 @@ export function createGatewayServer(providers) {
356
391
  return;
357
392
  }
358
393
  metrics.paidRequests += 1;
359
- await forward(entry, request, response, routePath, body, settle);
394
+ try {
395
+ await forward(metrics, entry, request, response, routePath, body, settle);
396
+ }
397
+ catch (error) {
398
+ const status = error instanceof HttpError ? error.status : 502;
399
+ const extraHeaders = error instanceof HttpError ? error.responseHeaders : {};
400
+ json(response, status, {
401
+ error: "upstream failed after payment settlement",
402
+ settled: true,
403
+ }, {
404
+ ...extraHeaders,
405
+ [headers.response]: encodeResponse(settle),
406
+ });
407
+ }
360
408
  }
361
409
  catch (error) {
362
410
  if (error instanceof HttpError) {
package/dist/x402.js CHANGED
@@ -2,7 +2,7 @@ import { decodePaymentRequiredHeader, decodePaymentResponseHeader, decodePayment
2
2
  import { x402Client } from "@bankofai/x402-core/client";
3
3
  import { ExactEvmScheme, toClientEvmSigner } from "@bankofai/x402-evm";
4
4
  import { ExactTronScheme, createClientTronSigner } from "@bankofai/x402-tron";
5
- import { registerExactGasFreeTronScheme } from "@bankofai/x402-tron/gasfree/client";
5
+ import { ExactGasFreeTronScheme, createGasFreeApiClients, getGasFreeApiBaseUrl } from "@bankofai/x402-tron/gasfree";
6
6
  import { createPublicClient, http } from "viem";
7
7
  import { privateKeyToAccount } from "viem/accounts";
8
8
  import { TronWeb } from "tronweb";
@@ -142,9 +142,10 @@ export async function createPaymentPayload(args) {
142
142
  const publicClient = rpcUrl ? createPublicClient({ transport: http(rpcUrl) }) : undefined;
143
143
  const signer = toClientEvmSigner(account, publicClient);
144
144
  const scheme = new ExactEvmScheme(signer, rpcUrl ? { rpcUrl } : undefined);
145
- return new x402Client()
145
+ const payload = await new x402Client()
146
146
  .register(selected.network, scheme)
147
147
  .createPaymentPayload(required);
148
+ return { payload };
148
149
  }
149
150
  if (selected.network.startsWith("tron:")) {
150
151
  const privateKey = privateKeyFrom(["TRON_PRIVATE_KEY", "AGENT_WALLET_PRIVATE_KEY", "PRIVATE_KEY"], args.privateKey, ["tron_client", "payer", "default"]);
@@ -156,14 +157,20 @@ export async function createPaymentPayload(args) {
156
157
  allowanceMode: args.allowanceMode || process.env.X402_TRON_ALLOWANCE_MODE || "auto",
157
158
  });
158
159
  const client = new x402Client();
160
+ let gasfreeEstimate;
159
161
  if (selected.scheme === "exact_gasfree") {
160
- registerExactGasFreeTronScheme(client, {
161
- signer,
162
- networks: [selected.network],
163
- ...(args.gasfreeApiUrl || process.env.X402_GASFREE_API_URL
164
- ? { schemeOptions: { apiBaseUrls: { [selected.network]: args.gasfreeApiUrl || process.env.X402_GASFREE_API_URL } } }
165
- : {}),
162
+ const apiUrl = args.gasfreeApiUrl || process.env.X402_GASFREE_API_URL || getGasFreeApiBaseUrl(selected.network);
163
+ const scheme = new ExactGasFreeTronScheme(signer, {
164
+ apiClients: createGasFreeApiClients({ [selected.network]: apiUrl }),
166
165
  });
166
+ const total = await scheme.estimateCost(selected);
167
+ const amount = BigInt(selected.amount);
168
+ const fee = total - amount;
169
+ if (args.maxGasfreeFeeRaw !== undefined && fee > BigInt(args.maxGasfreeFeeRaw)) {
170
+ throw new Error(`estimated GasFree fee ${fee} exceeds --max-gasfree-fee limit ${args.maxGasfreeFeeRaw}`);
171
+ }
172
+ gasfreeEstimate = { fee: fee.toString(), total: total.toString() };
173
+ client.register(selected.network, scheme);
167
174
  }
168
175
  else if (selected.scheme === "exact") {
169
176
  client.register(selected.network, new ExactTronScheme(signer));
@@ -171,7 +178,8 @@ export async function createPaymentPayload(args) {
171
178
  else {
172
179
  throw new Error(`unsupported scheme ${selected.scheme} on ${selected.network}`);
173
180
  }
174
- return client.createPaymentPayload(required);
181
+ const payload = await client.createPaymentPayload(required);
182
+ return { payload, ...(gasfreeEstimate ? { gasfreeEstimate } : {}) };
175
183
  }
176
184
  throw new Error(`unsupported network ${selected.network}`);
177
185
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bankofai/x402-cli",
3
- "version": "1.0.1-beta.4",
3
+ "version": "1.0.1-beta.6",
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.4",
25
+ "@bankofai/x402-gateway": "1.0.1-beta.5",
26
26
  "@bankofai/x402-tron": "1.0.1-beta.4",
27
27
  "tronweb": "6.4.0",
28
28
  "viem": "^2.55.0",
@@ -32,5 +32,8 @@
32
32
  "@types/node": "^24.10.1",
33
33
  "tsx": "^4.20.6",
34
34
  "typescript": "^5.9.3"
35
+ },
36
+ "overrides": {
37
+ "ws": "8.21.0"
35
38
  }
36
39
  }