@okx_ai/okx-trade-cli 1.2.8-beta.1 → 1.2.8-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/dist/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  import { createRequire as createRequire3 } from "module";
5
5
 
6
6
  // ../core/dist/index.js
7
- import { Agent, ProxyAgent } from "undici";
7
+ import { ProxyAgent } from "undici";
8
8
  import { createHmac } from "crypto";
9
9
  import fs from "fs";
10
10
  import path from "path";
@@ -847,13 +847,6 @@ import * as fs3 from "fs";
847
847
  import * as path3 from "path";
848
848
  import * as os3 from "os";
849
849
  import { execFileSync } from "child_process";
850
- async function resolveDoh(_domain) {
851
- return {
852
- ip: "47.242.161.22",
853
- host: "okexweb.qqhrss.com",
854
- ttl: 120
855
- };
856
- }
857
850
  function getNow() {
858
851
  return (/* @__PURE__ */ new Date()).toISOString();
859
852
  }
@@ -1072,61 +1065,12 @@ var OkxRestClient = class {
1072
1065
  config;
1073
1066
  rateLimiter;
1074
1067
  dispatcher;
1075
- // DoH proxy state (lazy-resolved on first request)
1076
- dohResolverFn;
1077
- dohResolved = false;
1078
- dohNode = null;
1079
- dohAgent = null;
1080
- dohBaseUrl = null;
1081
- /**
1082
- * @param config - OKX API client configuration
1083
- * @param options - Optional overrides (e.g. custom DoH resolver for testing).
1084
- * Pass `{ resolveDoh: null }` to disable DoH entirely.
1085
- */
1086
- constructor(config, options) {
1068
+ constructor(config) {
1087
1069
  this.config = config;
1088
1070
  this.rateLimiter = new RateLimiter(3e4, config.verbose);
1089
1071
  if (config.proxyUrl) {
1090
1072
  this.dispatcher = new ProxyAgent(config.proxyUrl);
1091
1073
  }
1092
- this.dohResolverFn = options?.resolveDoh !== void 0 ? options.resolveDoh : resolveDoh;
1093
- }
1094
- /**
1095
- * Lazily resolve the DoH proxy node on the first request.
1096
- * Skipped entirely when the user has configured proxy_url or DoH is disabled.
1097
- * On failure, silently falls back to direct connection.
1098
- */
1099
- async ensureDoh() {
1100
- if (this.dohResolved || this.dispatcher || !this.dohResolverFn) return;
1101
- this.dohResolved = true;
1102
- try {
1103
- const { hostname, protocol } = new URL(this.config.baseUrl);
1104
- const node = await this.dohResolverFn(hostname);
1105
- if (node) {
1106
- this.dohNode = node;
1107
- this.dohBaseUrl = `${protocol}//${node.host}`;
1108
- this.dohAgent = new Agent({
1109
- connect: {
1110
- lookup: (_hostname, options, callback) => {
1111
- if (options?.all) {
1112
- callback(null, [{ address: node.ip, family: 4 }]);
1113
- } else {
1114
- callback(null, node.ip, 4);
1115
- }
1116
- }
1117
- }
1118
- });
1119
- if (this.config.verbose) {
1120
- vlog(`DoH proxy active: ${hostname} \u2192 ${node.host} (${node.ip}), ttl=${node.ttl}s`);
1121
- }
1122
- }
1123
- } catch (err) {
1124
- if (this.config.verbose) {
1125
- const cause = err instanceof Error ? err.message : String(err);
1126
- vlog(`DoH resolution failed, falling back to direct: ${cause}`);
1127
- }
1128
- this.dohNode = null;
1129
- }
1130
1074
  }
1131
1075
  logRequest(method, url, auth) {
1132
1076
  if (!this.config.verbose) return;
@@ -1270,11 +1214,9 @@ var OkxRestClient = class {
1270
1214
  };
1271
1215
  }
1272
1216
  async request(reqConfig) {
1273
- await this.ensureDoh();
1274
1217
  const queryString = buildQueryString(reqConfig.query);
1275
1218
  const requestPath = queryString.length > 0 ? `${reqConfig.path}?${queryString}` : reqConfig.path;
1276
- const baseUrl = this.dohNode ? this.dohBaseUrl : this.config.baseUrl;
1277
- const url = `${baseUrl}${requestPath}`;
1219
+ const url = `${this.config.baseUrl}${requestPath}`;
1278
1220
  const bodyJson = reqConfig.body ? JSON.stringify(reqConfig.body) : "";
1279
1221
  const timestamp = getNow();
1280
1222
  this.logRequest(reqConfig.method, url, reqConfig.auth);
@@ -1285,9 +1227,7 @@ var OkxRestClient = class {
1285
1227
  "Content-Type": "application/json",
1286
1228
  Accept: "application/json"
1287
1229
  });
1288
- if (this.dohNode) {
1289
- headers.set("User-Agent", "OKX/2.7.2");
1290
- } else if (this.config.userAgent) {
1230
+ if (this.config.userAgent) {
1291
1231
  headers.set("User-Agent", this.config.userAgent);
1292
1232
  }
1293
1233
  if (reqConfig.auth === "private") {
@@ -1307,8 +1247,6 @@ var OkxRestClient = class {
1307
1247
  };
1308
1248
  if (this.dispatcher) {
1309
1249
  fetchOptions.dispatcher = this.dispatcher;
1310
- } else if (this.dohAgent) {
1311
- fetchOptions.dispatcher = this.dohAgent;
1312
1250
  }
1313
1251
  response = await fetch(url, fetchOptions);
1314
1252
  } catch (error) {
@@ -7037,6 +6975,22 @@ function isNewerVersion(current, latest) {
7037
6975
  if (lMin !== cMin) return lMin > cMin;
7038
6976
  return lPat > cPat;
7039
6977
  }
6978
+ async function fetchDistTags(packageName) {
6979
+ try {
6980
+ const controller = new AbortController();
6981
+ const timeout = setTimeout(() => controller.abort(), 3e3);
6982
+ const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}`, {
6983
+ signal: controller.signal,
6984
+ headers: { accept: "application/json" }
6985
+ });
6986
+ clearTimeout(timeout);
6987
+ if (!res.ok) return null;
6988
+ const data = await res.json();
6989
+ return data["dist-tags"] ?? null;
6990
+ } catch {
6991
+ return null;
6992
+ }
6993
+ }
7040
6994
  async function fetchLatestVersion(packageName) {
7041
6995
  try {
7042
6996
  const controller = new AbortController();
@@ -7838,7 +7792,7 @@ async function cmdDiagnoseMcp(options = {}) {
7838
7792
 
7839
7793
  // src/commands/diagnose.ts
7840
7794
  var CLI_VERSION = readCliVersion();
7841
- var GIT_HASH = true ? "b691d23" : "dev";
7795
+ var GIT_HASH = true ? "43f321d" : "dev";
7842
7796
  function maskKey2(key) {
7843
7797
  if (!key) return "(not set)";
7844
7798
  if (key.length <= 8) return "****";
@@ -8133,6 +8087,109 @@ async function runCliChecks(config, profile, outputPath) {
8133
8087
  writeReportIfRequested(report, outputPath);
8134
8088
  }
8135
8089
 
8090
+ // src/commands/upgrade.ts
8091
+ import { spawnSync as spawnSync2 } from "child_process";
8092
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4 } from "fs";
8093
+ import { dirname as dirname3, join as join4 } from "path";
8094
+ import { homedir as homedir4 } from "os";
8095
+ var PACKAGES = ["@okx_ai/okx-trade-mcp", "@okx_ai/okx-trade-cli"];
8096
+ var CACHE_FILE2 = join4(homedir4(), ".okx", "last_check");
8097
+ var THROTTLE_MS = 12 * 60 * 60 * 1e3;
8098
+ var NPM_BIN = join4(dirname3(process.execPath), process.platform === "win32" ? "npm.cmd" : "npm");
8099
+ function readLastCheck() {
8100
+ try {
8101
+ return parseInt(readFileSync4(CACHE_FILE2, "utf-8").trim(), 10) || 0;
8102
+ } catch {
8103
+ return 0;
8104
+ }
8105
+ }
8106
+ function writeLastCheck() {
8107
+ try {
8108
+ mkdirSync4(join4(homedir4(), ".okx"), { recursive: true });
8109
+ writeFileSync4(CACHE_FILE2, String(Math.floor(Date.now() / 1e3)), "utf-8");
8110
+ } catch {
8111
+ }
8112
+ }
8113
+ function printResult(result, json) {
8114
+ if (json) {
8115
+ process.stdout.write(JSON.stringify(result) + "\n");
8116
+ } else {
8117
+ switch (result.status) {
8118
+ case "up-to-date":
8119
+ process.stderr.write(`[ok] Already up to date: ${result.currentVersion}
8120
+ `);
8121
+ break;
8122
+ case "update-available":
8123
+ process.stderr.write(
8124
+ `[info] Update available: ${result.currentVersion} \u2192 ${result.latestVersion}
8125
+ Run: okx upgrade
8126
+ `
8127
+ );
8128
+ break;
8129
+ case "updated":
8130
+ process.stderr.write(`[ok] Upgraded: ${result.currentVersion} \u2192 ${result.latestVersion}
8131
+ `);
8132
+ break;
8133
+ case "error":
8134
+ process.stderr.write(`[error] Failed to fetch latest version from npm registry
8135
+ `);
8136
+ break;
8137
+ }
8138
+ }
8139
+ }
8140
+ function isThrottled(options) {
8141
+ if (options.force || options.check) return false;
8142
+ return Date.now() - readLastCheck() * 1e3 < THROTTLE_MS;
8143
+ }
8144
+ async function resolveLatestVersion(beta) {
8145
+ if (beta) {
8146
+ const tags = await fetchDistTags("@okx_ai/okx-trade-cli");
8147
+ return tags?.["next"] ?? tags?.["latest"] ?? null;
8148
+ }
8149
+ return fetchLatestVersion("@okx_ai/okx-trade-cli");
8150
+ }
8151
+ function runNpmInstall(json) {
8152
+ const result = spawnSync2(NPM_BIN, ["install", "-g", ...PACKAGES], {
8153
+ stdio: json ? ["inherit", "ignore", process.stderr] : "inherit",
8154
+ shell: false
8155
+ });
8156
+ return result.status === 0;
8157
+ }
8158
+ async function cmdUpgrade(currentVersion, options, json) {
8159
+ if (isThrottled(options)) {
8160
+ if (json) {
8161
+ process.stdout.write(
8162
+ JSON.stringify({ currentVersion, latestVersion: currentVersion, status: "up-to-date", updated: false }) + "\n"
8163
+ );
8164
+ }
8165
+ return;
8166
+ }
8167
+ const latestVersion = await resolveLatestVersion(options.beta ?? false);
8168
+ if (!latestVersion) {
8169
+ printResult({ currentVersion, latestVersion: "unknown", status: "error", updated: false }, json);
8170
+ process.exitCode = 1;
8171
+ return;
8172
+ }
8173
+ const stableCurrentVersion = currentVersion.split(/[-+]/)[0] ?? currentVersion;
8174
+ const needsUpdate = options.force || isNewerVersion(stableCurrentVersion, latestVersion);
8175
+ if (!needsUpdate) {
8176
+ if (!options.check) writeLastCheck();
8177
+ printResult({ currentVersion, latestVersion, status: "up-to-date", updated: false }, json);
8178
+ return;
8179
+ }
8180
+ if (options.check) {
8181
+ printResult({ currentVersion, latestVersion, status: "update-available", updated: false }, json);
8182
+ return;
8183
+ }
8184
+ if (runNpmInstall(json)) {
8185
+ writeLastCheck();
8186
+ printResult({ currentVersion, latestVersion, status: "updated", updated: true }, json);
8187
+ } else {
8188
+ printResult({ currentVersion, latestVersion, status: "error", updated: false }, json);
8189
+ process.exitCode = 1;
8190
+ }
8191
+ }
8192
+
8136
8193
  // src/config/loader.ts
8137
8194
  function loadProfileConfig(opts) {
8138
8195
  return loadConfig({
@@ -8735,6 +8792,10 @@ var HELP_TREE = {
8735
8792
  diagnose: {
8736
8793
  description: "Run network / MCP server diagnostics",
8737
8794
  usage: "okx diagnose [--cli | --mcp | --all] [--profile <name>] [--demo] [--output <file>]"
8795
+ },
8796
+ upgrade: {
8797
+ description: "Upgrade okx CLI and MCP server to the latest stable version",
8798
+ usage: "okx upgrade [--check] [--beta] [--force] [--json]"
8738
8799
  }
8739
8800
  };
8740
8801
  function printGlobalHelp() {
@@ -8984,6 +9045,9 @@ var CLI_OPTIONS = {
8984
9045
  // audit
8985
9046
  since: { type: "string" },
8986
9047
  tool: { type: "string" },
9048
+ // upgrade
9049
+ beta: { type: "boolean", default: false },
9050
+ check: { type: "boolean", default: false },
8987
9051
  // config profile
8988
9052
  force: { type: "boolean", default: false },
8989
9053
  // onchain-earn
@@ -9325,14 +9389,17 @@ async function cmdAccountBalance(run, ccy, json) {
9325
9389
  const data = getData2(result);
9326
9390
  if (json) return printJson(data);
9327
9391
  const details = data?.[0]?.["details"] ?? [];
9328
- printTable(
9329
- details.filter((d) => Number(d["eq"]) > 0).map((d) => ({
9330
- currency: d["ccy"],
9331
- equity: d["eq"],
9332
- available: d["availEq"],
9333
- frozen: d["frozenBal"]
9334
- }))
9335
- );
9392
+ const rows = details.filter((d) => Number(d["eq"]) > 0).map((d) => ({
9393
+ currency: d["ccy"],
9394
+ equity: d["eq"],
9395
+ available: d["availEq"],
9396
+ frozen: d["frozenBal"]
9397
+ }));
9398
+ if (rows.length === 0 && data?.[0]) {
9399
+ printTable([{ currency: "Total", equity: data[0]["totalEq"] ?? "0", available: data[0]["adjEq"] ?? "0", frozen: "-" }]);
9400
+ return;
9401
+ }
9402
+ printTable(rows);
9336
9403
  }
9337
9404
  async function cmdAccountAssetBalance(run, ccy, json, showValuation) {
9338
9405
  const result = await run("account_get_asset_balance", {
@@ -9341,14 +9408,17 @@ async function cmdAccountAssetBalance(run, ccy, json, showValuation) {
9341
9408
  });
9342
9409
  const data = result.data ?? [];
9343
9410
  if (json) return printJson(showValuation ? { data, valuation: result.valuation } : data);
9344
- printTable(
9345
- data.filter((r) => Number(r["bal"]) > 0).map((r) => ({
9346
- ccy: r["ccy"],
9347
- bal: r["bal"],
9348
- availBal: r["availBal"],
9349
- frozenBal: r["frozenBal"]
9350
- }))
9351
- );
9411
+ const assetRows = data.filter((r) => Number(r["bal"]) > 0).map((r) => ({
9412
+ ccy: r["ccy"],
9413
+ bal: r["bal"],
9414
+ availBal: r["availBal"],
9415
+ frozenBal: r["frozenBal"]
9416
+ }));
9417
+ if (assetRows.length === 0 && data.length > 0) {
9418
+ outputLine("Total balance: 0");
9419
+ } else {
9420
+ printTable(assetRows);
9421
+ }
9352
9422
  if (showValuation && result.valuation) {
9353
9423
  const valuationData = result.valuation ?? [];
9354
9424
  outputLine("");
@@ -10653,7 +10723,7 @@ function writeCliConfig(config) {
10653
10723
 
10654
10724
  // src/commands/config.ts
10655
10725
  import { createInterface } from "readline";
10656
- import { spawnSync as spawnSync2 } from "child_process";
10726
+ import { spawnSync as spawnSync3 } from "child_process";
10657
10727
  var messages = {
10658
10728
  en: {
10659
10729
  title: "OKX Trade CLI \u2014 Configuration Wizard",
@@ -10795,7 +10865,7 @@ function tryOpenUrl(url) {
10795
10865
  } else {
10796
10866
  opener = "xdg-open";
10797
10867
  }
10798
- spawnSync2(opener, [url], { stdio: "ignore", shell: process.platform === "win32" });
10868
+ spawnSync3(opener, [url], { stdio: "ignore", shell: process.platform === "win32" });
10799
10869
  } catch {
10800
10870
  }
10801
10871
  }
@@ -11693,7 +11763,7 @@ async function cmdDcdQuoteAndBuy(run, opts) {
11693
11763
  // src/index.ts
11694
11764
  var _require3 = createRequire3(import.meta.url);
11695
11765
  var CLI_VERSION2 = _require3("../package.json").version;
11696
- var GIT_HASH2 = true ? "b691d23" : "dev";
11766
+ var GIT_HASH2 = true ? "43f321d" : "dev";
11697
11767
  function handleConfigCommand(action, rest, json, lang, force) {
11698
11768
  if (action === "init") return cmdConfigInit(lang === "zh" ? "zh" : "en");
11699
11769
  if (action === "show") return cmdConfigShow(json);
@@ -12485,6 +12555,7 @@ async function main() {
12485
12555
  const json = v.json ?? false;
12486
12556
  if (module === "config") return handleConfigCommand(action, rest, json, v.lang, v.force);
12487
12557
  if (module === "setup") return handleSetupCommand(v);
12558
+ if (module === "upgrade") return cmdUpgrade(CLI_VERSION2, { beta: v.beta, check: v.check, force: v.force }, json);
12488
12559
  if (module === "diagnose") {
12489
12560
  let config2;
12490
12561
  try {