@okx_ai/okx-trade-cli 1.3.1-beta.6 → 1.3.1-beta.8
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 +696 -91
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/scripts/postinstall.js +77 -0
package/dist/index.js
CHANGED
|
@@ -21,23 +21,26 @@ import {
|
|
|
21
21
|
import { homedir as homedir2 } from "os";
|
|
22
22
|
import { join as join2, dirname } from "path";
|
|
23
23
|
import { createHmac } from "crypto";
|
|
24
|
+
import { spawn, execFile as execFile2 } from "child_process";
|
|
25
|
+
import { homedir as homedir3 } from "os";
|
|
26
|
+
import { join as join3 } from "path";
|
|
24
27
|
import fs from "fs";
|
|
25
28
|
import path from "path";
|
|
26
29
|
import os from "os";
|
|
27
30
|
import { writeFileSync as writeFileSync2, renameSync as renameSync2, unlinkSync as unlinkSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
28
|
-
import { join as
|
|
31
|
+
import { join as join4, resolve, basename, sep } from "path";
|
|
29
32
|
import { randomUUID } from "crypto";
|
|
30
33
|
import yauzl from "yauzl";
|
|
31
34
|
import { createWriteStream, mkdirSync as mkdirSync3 } from "fs";
|
|
32
35
|
import { resolve as resolve2, dirname as dirname2 } from "path";
|
|
33
36
|
import { readFileSync as readFileSync2, existsSync } from "fs";
|
|
34
|
-
import { join as
|
|
37
|
+
import { join as join5 } from "path";
|
|
35
38
|
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, existsSync as existsSync2 } from "fs";
|
|
36
|
-
import { join as
|
|
37
|
-
import { homedir as homedir3 } from "os";
|
|
38
|
-
import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5, existsSync as existsSync3 } from "fs";
|
|
39
|
-
import { join as join6, dirname as dirname4 } from "path";
|
|
39
|
+
import { join as join6, dirname as dirname3 } from "path";
|
|
40
40
|
import { homedir as homedir4 } from "os";
|
|
41
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5, existsSync as existsSync3 } from "fs";
|
|
42
|
+
import { join as join7, dirname as dirname4 } from "path";
|
|
43
|
+
import { homedir as homedir5 } from "os";
|
|
41
44
|
|
|
42
45
|
// ../../node_modules/.pnpm/smol-toml@1.6.0/node_modules/smol-toml/dist/error.js
|
|
43
46
|
function getLineColFromPtr(string, ptr) {
|
|
@@ -867,8 +870,8 @@ function stringify(obj, { maxDepth = 1e3, numbersAsFloat = false } = {}) {
|
|
|
867
870
|
|
|
868
871
|
// ../core/dist/index.js
|
|
869
872
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, existsSync as existsSync4 } from "fs";
|
|
870
|
-
import { join as
|
|
871
|
-
import { homedir as
|
|
873
|
+
import { join as join8 } from "path";
|
|
874
|
+
import { homedir as homedir6 } from "os";
|
|
872
875
|
import fs2 from "fs";
|
|
873
876
|
import path2 from "path";
|
|
874
877
|
import os2 from "os";
|
|
@@ -876,6 +879,18 @@ import * as fs3 from "fs";
|
|
|
876
879
|
import * as path3 from "path";
|
|
877
880
|
import * as os3 from "os";
|
|
878
881
|
import { execFileSync } from "child_process";
|
|
882
|
+
import {
|
|
883
|
+
createWriteStream as createWriteStream3,
|
|
884
|
+
mkdirSync as mkdirSync9,
|
|
885
|
+
chmodSync as chmodSync2,
|
|
886
|
+
existsSync as existsSync7,
|
|
887
|
+
unlinkSync as unlinkSync4,
|
|
888
|
+
renameSync as renameSync4
|
|
889
|
+
} from "fs";
|
|
890
|
+
import { homedir as homedir9, platform as platform2 } from "os";
|
|
891
|
+
import { join as join11, dirname as dirname7 } from "path";
|
|
892
|
+
import { get as httpsGet2 } from "https";
|
|
893
|
+
import { get as httpGet2 } from "http";
|
|
879
894
|
import {
|
|
880
895
|
readFileSync as readFileSync7,
|
|
881
896
|
createWriteStream as createWriteStream2,
|
|
@@ -886,8 +901,8 @@ import {
|
|
|
886
901
|
renameSync as renameSync3
|
|
887
902
|
} from "fs";
|
|
888
903
|
import { createHash } from "crypto";
|
|
889
|
-
import { homedir as
|
|
890
|
-
import { join as
|
|
904
|
+
import { homedir as homedir8, platform, arch } from "os";
|
|
905
|
+
import { join as join10, dirname as dirname6 } from "path";
|
|
891
906
|
import { get as httpsGet } from "https";
|
|
892
907
|
import { get as httpGet } from "http";
|
|
893
908
|
var EXEC_TIMEOUT_MS = 3e4;
|
|
@@ -1201,6 +1216,11 @@ var ConfigError = class extends OkxMcpError {
|
|
|
1201
1216
|
super("ConfigError", message, { suggestion });
|
|
1202
1217
|
}
|
|
1203
1218
|
};
|
|
1219
|
+
var NotLoggedInError = class extends ConfigError {
|
|
1220
|
+
constructor(suggestion = "Run `okx auth login` to authenticate.") {
|
|
1221
|
+
super("Not logged in.", suggestion);
|
|
1222
|
+
}
|
|
1223
|
+
};
|
|
1204
1224
|
var ValidationError = class extends OkxMcpError {
|
|
1205
1225
|
constructor(message, suggestion) {
|
|
1206
1226
|
super("ValidationError", message, { suggestion });
|
|
@@ -1253,6 +1273,97 @@ function toToolErrorPayload(error, fallbackEndpoint) {
|
|
|
1253
1273
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1254
1274
|
};
|
|
1255
1275
|
}
|
|
1276
|
+
var EXIT_CODES = {
|
|
1277
|
+
SUCCESS: 0,
|
|
1278
|
+
UNAUTHORIZED_CALLER: 1,
|
|
1279
|
+
NOT_LOGGED_IN: 2,
|
|
1280
|
+
REFRESH_FAILED: 3
|
|
1281
|
+
};
|
|
1282
|
+
var EXEC_TIMEOUT_MS2 = 5e3;
|
|
1283
|
+
var AUTH_BIN_DIR = join3(homedir3(), ".okx", "bin");
|
|
1284
|
+
function getAuthBinaryPath() {
|
|
1285
|
+
if (process.env.OKX_AUTH_BIN) {
|
|
1286
|
+
return process.env.OKX_AUTH_BIN;
|
|
1287
|
+
}
|
|
1288
|
+
const ext = process.platform === "win32" ? ".exe" : "";
|
|
1289
|
+
return join3(AUTH_BIN_DIR, `okx-auth${ext}`);
|
|
1290
|
+
}
|
|
1291
|
+
function execAuthToken() {
|
|
1292
|
+
const binPath = getAuthBinaryPath();
|
|
1293
|
+
return new Promise((resolve3, reject) => {
|
|
1294
|
+
const child = spawn(binPath, ["token"], {
|
|
1295
|
+
stdio: ["ignore", "ignore", "inherit", "pipe"]
|
|
1296
|
+
// stdin stdout stderr fd3 (pipe)
|
|
1297
|
+
});
|
|
1298
|
+
const chunks = [];
|
|
1299
|
+
const fd3 = child.stdio[3];
|
|
1300
|
+
fd3.on("data", (chunk) => chunks.push(chunk));
|
|
1301
|
+
child.on("error", (err) => {
|
|
1302
|
+
reject(new ConfigError(
|
|
1303
|
+
`Failed to spawn okx-auth: ${err.message}`,
|
|
1304
|
+
"Ensure the okx-auth binary exists and is executable."
|
|
1305
|
+
));
|
|
1306
|
+
});
|
|
1307
|
+
child.on("close", (code) => {
|
|
1308
|
+
if (code === EXIT_CODES.SUCCESS) {
|
|
1309
|
+
const token = Buffer.concat(chunks).toString("utf-8").trim();
|
|
1310
|
+
if (!token) {
|
|
1311
|
+
reject(new AuthenticationError(
|
|
1312
|
+
"okx-auth returned empty token.",
|
|
1313
|
+
"Run `okx auth login` to re-authenticate."
|
|
1314
|
+
));
|
|
1315
|
+
return;
|
|
1316
|
+
}
|
|
1317
|
+
resolve3(token);
|
|
1318
|
+
return;
|
|
1319
|
+
}
|
|
1320
|
+
if (code === EXIT_CODES.NOT_LOGGED_IN) {
|
|
1321
|
+
reject(new NotLoggedInError());
|
|
1322
|
+
return;
|
|
1323
|
+
}
|
|
1324
|
+
if (code === EXIT_CODES.UNAUTHORIZED_CALLER) {
|
|
1325
|
+
reject(new AuthenticationError(
|
|
1326
|
+
"okx-auth rejected the caller (unauthorized).",
|
|
1327
|
+
"Ensure you are running from a trusted OKX tool."
|
|
1328
|
+
));
|
|
1329
|
+
return;
|
|
1330
|
+
}
|
|
1331
|
+
if (code === EXIT_CODES.REFRESH_FAILED) {
|
|
1332
|
+
reject(new AuthenticationError(
|
|
1333
|
+
"Token refresh failed.",
|
|
1334
|
+
"Run `okx auth login` to re-authenticate."
|
|
1335
|
+
));
|
|
1336
|
+
return;
|
|
1337
|
+
}
|
|
1338
|
+
reject(new AuthenticationError(
|
|
1339
|
+
`okx-auth token exited with code ${code}.`,
|
|
1340
|
+
"Run `okx auth login` to re-authenticate."
|
|
1341
|
+
));
|
|
1342
|
+
});
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
function execAuthStatus() {
|
|
1346
|
+
const binPath = getAuthBinaryPath();
|
|
1347
|
+
return new Promise((resolve3) => {
|
|
1348
|
+
execFile2(
|
|
1349
|
+
binPath,
|
|
1350
|
+
["status", "--json"],
|
|
1351
|
+
{ timeout: EXEC_TIMEOUT_MS2, encoding: "utf-8" },
|
|
1352
|
+
(error, stdout) => {
|
|
1353
|
+
if (error) {
|
|
1354
|
+
resolve3(null);
|
|
1355
|
+
return;
|
|
1356
|
+
}
|
|
1357
|
+
try {
|
|
1358
|
+
const result = JSON.parse(stdout);
|
|
1359
|
+
resolve3(result);
|
|
1360
|
+
} catch {
|
|
1361
|
+
resolve3(null);
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
);
|
|
1365
|
+
});
|
|
1366
|
+
}
|
|
1256
1367
|
function sleep(ms) {
|
|
1257
1368
|
return new Promise((resolve3) => {
|
|
1258
1369
|
setTimeout(resolve3, ms);
|
|
@@ -1384,6 +1495,7 @@ function maskKey(key) {
|
|
|
1384
1495
|
if (key.length <= 8) return "***";
|
|
1385
1496
|
return `${key.slice(0, 3)}***${key.slice(-3)}`;
|
|
1386
1497
|
}
|
|
1498
|
+
var TOKEN_CACHE_TTL_MS = 6e4;
|
|
1387
1499
|
function vlog2(message) {
|
|
1388
1500
|
process.stderr.write(`[verbose] ${message}
|
|
1389
1501
|
`);
|
|
@@ -1392,6 +1504,8 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1392
1504
|
config;
|
|
1393
1505
|
rateLimiter;
|
|
1394
1506
|
dispatcher;
|
|
1507
|
+
cachedAccessToken;
|
|
1508
|
+
cachedAccessTokenAt = 0;
|
|
1395
1509
|
doh;
|
|
1396
1510
|
constructor(config) {
|
|
1397
1511
|
this.config = config;
|
|
@@ -1406,6 +1520,51 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1406
1520
|
hasCustomProxy: !!config.proxyUrl
|
|
1407
1521
|
});
|
|
1408
1522
|
}
|
|
1523
|
+
/**
|
|
1524
|
+
* Resolve OAuth access token via the okx-auth binary (fd3 pipe).
|
|
1525
|
+
* Caches the token for 60 s to avoid spawning the binary on every
|
|
1526
|
+
* request. The binary handles refresh internally (300s TTL lead),
|
|
1527
|
+
* so periodic re-calls let it serve a fresh token when needed.
|
|
1528
|
+
* Returns null when not logged in.
|
|
1529
|
+
*/
|
|
1530
|
+
async resolveAccessToken() {
|
|
1531
|
+
if (this.cachedAccessToken && Date.now() - this.cachedAccessTokenAt < TOKEN_CACHE_TTL_MS) {
|
|
1532
|
+
return this.cachedAccessToken;
|
|
1533
|
+
}
|
|
1534
|
+
try {
|
|
1535
|
+
const token = await execAuthToken();
|
|
1536
|
+
this.cachedAccessToken = token;
|
|
1537
|
+
this.cachedAccessTokenAt = Date.now();
|
|
1538
|
+
return token;
|
|
1539
|
+
} catch (e) {
|
|
1540
|
+
if (e instanceof NotLoggedInError) {
|
|
1541
|
+
return null;
|
|
1542
|
+
}
|
|
1543
|
+
throw e;
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
/**
|
|
1547
|
+
* Dynamic auth — determines auth method per request.
|
|
1548
|
+
*
|
|
1549
|
+
* 1. API key in config → HMAC signing (no OAuth fallback)
|
|
1550
|
+
* 2. OAuth token via okx-auth binary → Bearer token
|
|
1551
|
+
* 3. Neither → throw ConfigError
|
|
1552
|
+
*/
|
|
1553
|
+
async applyAuth(headers, method, requestPath, bodyJson, timestamp) {
|
|
1554
|
+
if (this.config.apiKey && this.config.secretKey && this.config.passphrase) {
|
|
1555
|
+
this.setAuthHeaders(headers, method, requestPath, bodyJson, timestamp);
|
|
1556
|
+
return;
|
|
1557
|
+
}
|
|
1558
|
+
const accessToken = await this.resolveAccessToken();
|
|
1559
|
+
if (accessToken) {
|
|
1560
|
+
headers.set("Authorization", `Bearer ${accessToken}`);
|
|
1561
|
+
return;
|
|
1562
|
+
}
|
|
1563
|
+
throw new ConfigError(
|
|
1564
|
+
"No credentials found.",
|
|
1565
|
+
"Run `okx auth login` to authenticate, or configure API key credentials."
|
|
1566
|
+
);
|
|
1567
|
+
}
|
|
1409
1568
|
/** The canonical base URL for this client (e.g. https://www.okx.com). */
|
|
1410
1569
|
get baseUrl() {
|
|
1411
1570
|
return this.config.baseUrl;
|
|
@@ -1463,18 +1622,6 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1463
1622
|
});
|
|
1464
1623
|
}
|
|
1465
1624
|
setAuthHeaders(headers, method, requestPath, bodyJson, timestamp) {
|
|
1466
|
-
if (!this.config.hasAuth) {
|
|
1467
|
-
throw new ConfigError(
|
|
1468
|
-
"Private endpoint requires API credentials.",
|
|
1469
|
-
"Configure OKX_API_KEY, OKX_SECRET_KEY and OKX_PASSPHRASE."
|
|
1470
|
-
);
|
|
1471
|
-
}
|
|
1472
|
-
if (!this.config.apiKey || !this.config.secretKey || !this.config.passphrase) {
|
|
1473
|
-
throw new ConfigError(
|
|
1474
|
-
"Invalid private API credentials state.",
|
|
1475
|
-
"Ensure all OKX credentials are set."
|
|
1476
|
-
);
|
|
1477
|
-
}
|
|
1478
1625
|
const payload = `${timestamp}${method.toUpperCase()}${requestPath}${bodyJson}`;
|
|
1479
1626
|
const signature = signOkxPayload(payload, this.config.secretKey);
|
|
1480
1627
|
headers.set("OK-ACCESS-KEY", this.config.apiKey);
|
|
@@ -1589,7 +1736,7 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1589
1736
|
const conn = this.doh.getConnectionParams();
|
|
1590
1737
|
this.logRequest("POST", `${conn.baseUrl}${path42}`, "private");
|
|
1591
1738
|
const reqConfig = { method: "POST", path: path42, auth: "private" };
|
|
1592
|
-
const headers = this.buildHeaders(reqConfig, path42, bodyJson, getNow());
|
|
1739
|
+
const headers = await this.buildHeaders(reqConfig, path42, bodyJson, getNow());
|
|
1593
1740
|
if (conn.userAgent) {
|
|
1594
1741
|
headers.set("User-Agent", conn.userAgent);
|
|
1595
1742
|
}
|
|
@@ -1706,7 +1853,7 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1706
1853
|
// Header building
|
|
1707
1854
|
// ---------------------------------------------------------------------------
|
|
1708
1855
|
/** Build HTTP headers. reqConfig.extraHeaders must NOT contain auth keys (OK-ACCESS-*). */
|
|
1709
|
-
buildHeaders(reqConfig, requestPath, bodyJson, timestamp) {
|
|
1856
|
+
async buildHeaders(reqConfig, requestPath, bodyJson, timestamp) {
|
|
1710
1857
|
const headers = new Headers({
|
|
1711
1858
|
"Content-Type": "application/json",
|
|
1712
1859
|
Accept: "application/json"
|
|
@@ -1715,7 +1862,7 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1715
1862
|
headers.set("User-Agent", this.config.userAgent);
|
|
1716
1863
|
}
|
|
1717
1864
|
if (reqConfig.auth === "private") {
|
|
1718
|
-
this.
|
|
1865
|
+
await this.applyAuth(headers, reqConfig.method, requestPath, bodyJson, timestamp);
|
|
1719
1866
|
}
|
|
1720
1867
|
const useSimulated = reqConfig.simulatedTrading !== void 0 ? reqConfig.simulatedTrading : this.config.demo;
|
|
1721
1868
|
if (useSimulated) {
|
|
@@ -1769,7 +1916,7 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1769
1916
|
if (reqConfig.rateLimit) {
|
|
1770
1917
|
await this.rateLimiter.consume(reqConfig.rateLimit);
|
|
1771
1918
|
}
|
|
1772
|
-
const headers = this.buildHeaders(reqConfig, requestPath, bodyJson, timestamp);
|
|
1919
|
+
const headers = await this.buildHeaders(reqConfig, requestPath, bodyJson, timestamp);
|
|
1773
1920
|
if (conn.userAgent) {
|
|
1774
1921
|
headers.set("User-Agent", conn.userAgent);
|
|
1775
1922
|
}
|
|
@@ -2192,7 +2339,7 @@ var OKX_SITES = {
|
|
|
2192
2339
|
},
|
|
2193
2340
|
us: {
|
|
2194
2341
|
label: "US",
|
|
2195
|
-
apiBaseUrl: "https://
|
|
2342
|
+
apiBaseUrl: "https://us.okx.com",
|
|
2196
2343
|
webUrl: "https://app.okx.com"
|
|
2197
2344
|
}
|
|
2198
2345
|
};
|
|
@@ -3722,7 +3869,7 @@ function safeWriteFile(targetDir, fileName, data) {
|
|
|
3722
3869
|
throw new Error(`Invalid file name: "${fileName}"`);
|
|
3723
3870
|
}
|
|
3724
3871
|
const resolvedDir = resolve(targetDir);
|
|
3725
|
-
const filePath =
|
|
3872
|
+
const filePath = join4(resolvedDir, safeName);
|
|
3726
3873
|
const resolvedPath = resolve(filePath);
|
|
3727
3874
|
if (!resolvedPath.startsWith(resolvedDir + sep)) {
|
|
3728
3875
|
throw new Error(`Path traversal detected: "${fileName}" resolves outside target directory`);
|
|
@@ -3850,7 +3997,7 @@ async function extractSkillZip(zipPath, targetDir, limits) {
|
|
|
3850
3997
|
});
|
|
3851
3998
|
}
|
|
3852
3999
|
function readMetaJson(contentDir) {
|
|
3853
|
-
const metaPath =
|
|
4000
|
+
const metaPath = join5(contentDir, "_meta.json");
|
|
3854
4001
|
if (!existsSync(metaPath)) {
|
|
3855
4002
|
throw new Error(`_meta.json not found in ${contentDir}. Invalid skill package.`);
|
|
3856
4003
|
}
|
|
@@ -3876,12 +4023,12 @@ function readMetaJson(contentDir) {
|
|
|
3876
4023
|
};
|
|
3877
4024
|
}
|
|
3878
4025
|
function validateSkillMdExists(contentDir) {
|
|
3879
|
-
const skillMdPath =
|
|
4026
|
+
const skillMdPath = join5(contentDir, "SKILL.md");
|
|
3880
4027
|
if (!existsSync(skillMdPath)) {
|
|
3881
4028
|
throw new Error(`SKILL.md not found in ${contentDir}. Invalid skill package.`);
|
|
3882
4029
|
}
|
|
3883
4030
|
}
|
|
3884
|
-
var DEFAULT_REGISTRY_PATH =
|
|
4031
|
+
var DEFAULT_REGISTRY_PATH = join6(homedir4(), ".okx", "skills", "registry.json");
|
|
3885
4032
|
function readRegistry(registryPath = DEFAULT_REGISTRY_PATH) {
|
|
3886
4033
|
if (!existsSync2(registryPath)) {
|
|
3887
4034
|
return { version: 1, skills: {} };
|
|
@@ -9646,7 +9793,7 @@ function createToolRunner(client, config) {
|
|
|
9646
9793
|
};
|
|
9647
9794
|
}
|
|
9648
9795
|
function configFilePath() {
|
|
9649
|
-
return
|
|
9796
|
+
return join7(homedir5(), ".okx", "config.toml");
|
|
9650
9797
|
}
|
|
9651
9798
|
function readFullConfig() {
|
|
9652
9799
|
const path42 = configFilePath();
|
|
@@ -9665,11 +9812,6 @@ Or re-run: okx config init`
|
|
|
9665
9812
|
);
|
|
9666
9813
|
}
|
|
9667
9814
|
}
|
|
9668
|
-
function readTomlProfile(profileName) {
|
|
9669
|
-
const config = readFullConfig();
|
|
9670
|
-
const name = profileName ?? config.default_profile ?? "default";
|
|
9671
|
-
return config.profiles?.[name] ?? {};
|
|
9672
|
-
}
|
|
9673
9815
|
var CONFIG_HEADER = `# OKX Trade Kit Configuration
|
|
9674
9816
|
# If editing manually, wrap values containing special chars in quotes:
|
|
9675
9817
|
# passphrase = 'value' (if value contains # \\ ")
|
|
@@ -9718,18 +9860,24 @@ function parseModuleList(rawModules) {
|
|
|
9718
9860
|
}
|
|
9719
9861
|
return Array.from(deduped);
|
|
9720
9862
|
}
|
|
9721
|
-
function loadCredentials(toml) {
|
|
9863
|
+
async function loadCredentials(toml) {
|
|
9722
9864
|
const apiKey = process.env.OKX_API_KEY?.trim() ?? toml.api_key;
|
|
9723
9865
|
const secretKey = process.env.OKX_SECRET_KEY?.trim() ?? toml.secret_key;
|
|
9724
9866
|
const passphrase = process.env.OKX_PASSPHRASE?.trim() ?? toml.passphrase;
|
|
9725
|
-
const
|
|
9867
|
+
const hasApiKey = Boolean(apiKey && secretKey && passphrase);
|
|
9726
9868
|
const partialAuth = Boolean(apiKey) || Boolean(secretKey) || Boolean(passphrase);
|
|
9727
|
-
if (partialAuth && !
|
|
9869
|
+
if (partialAuth && !hasApiKey) {
|
|
9728
9870
|
throw new ConfigError(
|
|
9729
9871
|
"Partial API credentials detected.",
|
|
9730
9872
|
"Set OKX_API_KEY, OKX_SECRET_KEY and OKX_PASSPHRASE together (env vars or config.toml profile)."
|
|
9731
9873
|
);
|
|
9732
9874
|
}
|
|
9875
|
+
let hasOAuth = false;
|
|
9876
|
+
if (!hasApiKey) {
|
|
9877
|
+
const status = await execAuthStatus();
|
|
9878
|
+
hasOAuth = status?.status === "logged_in";
|
|
9879
|
+
}
|
|
9880
|
+
const hasAuth = hasOAuth || hasApiKey;
|
|
9733
9881
|
return { apiKey, secretKey, passphrase, hasAuth };
|
|
9734
9882
|
}
|
|
9735
9883
|
function resolveSite(cliSite, tomlSite) {
|
|
@@ -9763,9 +9911,11 @@ function resolveDemo(cli, toml) {
|
|
|
9763
9911
|
if (cli.demo === true) return true;
|
|
9764
9912
|
return process.env.OKX_DEMO === "1" || process.env.OKX_DEMO === "true" || (toml.demo ?? false);
|
|
9765
9913
|
}
|
|
9766
|
-
function loadConfig(cli) {
|
|
9767
|
-
const
|
|
9768
|
-
const
|
|
9914
|
+
async function loadConfig(cli) {
|
|
9915
|
+
const config = readFullConfig();
|
|
9916
|
+
const profileName = cli.profile ?? config.default_profile ?? "default";
|
|
9917
|
+
const toml = config.profiles?.[profileName] ?? {};
|
|
9918
|
+
const creds = await loadCredentials(toml);
|
|
9769
9919
|
const demo = resolveDemo(cli, toml);
|
|
9770
9920
|
const site = resolveSite(cli.site, toml.site);
|
|
9771
9921
|
const baseUrl = resolveBaseUrl(site, toml.base_url);
|
|
@@ -9785,6 +9935,7 @@ function loadConfig(cli) {
|
|
|
9785
9935
|
}
|
|
9786
9936
|
return {
|
|
9787
9937
|
...creds,
|
|
9938
|
+
profile: profileName,
|
|
9788
9939
|
baseUrl,
|
|
9789
9940
|
timeoutMs: Math.floor(rawTimeout),
|
|
9790
9941
|
modules: parseModuleList(cli.modules),
|
|
@@ -9797,7 +9948,7 @@ function loadConfig(cli) {
|
|
|
9797
9948
|
verbose: cli.verbose ?? false
|
|
9798
9949
|
};
|
|
9799
9950
|
}
|
|
9800
|
-
var CACHE_FILE =
|
|
9951
|
+
var CACHE_FILE = join8(homedir6(), ".okx", "update-check.json");
|
|
9801
9952
|
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
9802
9953
|
function readCache2() {
|
|
9803
9954
|
try {
|
|
@@ -9810,7 +9961,7 @@ function readCache2() {
|
|
|
9810
9961
|
}
|
|
9811
9962
|
function writeCache2(cache) {
|
|
9812
9963
|
try {
|
|
9813
|
-
mkdirSync6(
|
|
9964
|
+
mkdirSync6(join8(homedir6(), ".okx"), { recursive: true });
|
|
9814
9965
|
writeFileSync5(CACHE_FILE, JSON.stringify(cache, null, 2), "utf-8");
|
|
9815
9966
|
} catch {
|
|
9816
9967
|
}
|
|
@@ -9980,13 +10131,13 @@ function findMsStoreClaudePath() {
|
|
|
9980
10131
|
}
|
|
9981
10132
|
function getConfigPath(client) {
|
|
9982
10133
|
const home = os3.homedir();
|
|
9983
|
-
const
|
|
10134
|
+
const platform3 = process.platform;
|
|
9984
10135
|
switch (client) {
|
|
9985
10136
|
case "claude-desktop":
|
|
9986
|
-
if (
|
|
10137
|
+
if (platform3 === "win32") {
|
|
9987
10138
|
return findMsStoreClaudePath() ?? path3.join(appData(), "Claude", CLAUDE_CONFIG_FILE);
|
|
9988
10139
|
}
|
|
9989
|
-
if (
|
|
10140
|
+
if (platform3 === "darwin") {
|
|
9990
10141
|
return path3.join(home, "Library", "Application Support", "Claude", CLAUDE_CONFIG_FILE);
|
|
9991
10142
|
}
|
|
9992
10143
|
return path3.join(process.env.XDG_CONFIG_HOME ?? path3.join(home, ".config"), "Claude", CLAUDE_CONFIG_FILE);
|
|
@@ -10228,7 +10379,7 @@ async function installDohBinary(destPath, sources = CDN_SOURCES, onProgress) {
|
|
|
10228
10379
|
if (earlyResult) return earlyResult;
|
|
10229
10380
|
const platformDir = getPlatformDir();
|
|
10230
10381
|
const binaryName = getBinaryName();
|
|
10231
|
-
const resolvedDest = destPath ??
|
|
10382
|
+
const resolvedDest = destPath ?? join10(homedir8(), ".okx", "bin", binaryName);
|
|
10232
10383
|
const tmpPath = resolvedDest + ".tmp";
|
|
10233
10384
|
mkdirSync8(dirname6(resolvedDest), { recursive: true });
|
|
10234
10385
|
const localHash = existsSync6(resolvedDest) ? hashFile(resolvedDest) : null;
|
|
@@ -10351,16 +10502,224 @@ function downloadText(url, timeoutMs) {
|
|
|
10351
10502
|
})
|
|
10352
10503
|
);
|
|
10353
10504
|
}
|
|
10505
|
+
var AUTH_CDN_PATH_PREFIX = "/upgradeapp/tools/oauth";
|
|
10506
|
+
function getAuthBinaryName() {
|
|
10507
|
+
return platform2() === "win32" ? "okx-auth.exe" : "okx-auth";
|
|
10508
|
+
}
|
|
10509
|
+
function getAuthStatus(binaryPath, opts) {
|
|
10510
|
+
const resolvedPath = binaryPath ?? getAuthBinaryPath();
|
|
10511
|
+
const platformDir = getPlatformDir();
|
|
10512
|
+
if (!existsSync7(resolvedPath)) {
|
|
10513
|
+
return { binaryPath: resolvedPath, exists: false, platform: platformDir };
|
|
10514
|
+
}
|
|
10515
|
+
if (opts?.skipHash) {
|
|
10516
|
+
return { binaryPath: resolvedPath, exists: true, platform: platformDir };
|
|
10517
|
+
}
|
|
10518
|
+
const { size, sha256 } = hashFile(resolvedPath);
|
|
10519
|
+
return { binaryPath: resolvedPath, exists: true, platform: platformDir, fileSize: size, sha256 };
|
|
10520
|
+
}
|
|
10521
|
+
async function fetchAuthCdnChecksum(sources = CDN_SOURCES, timeoutMs = DOWNLOAD_TIMEOUT_MS) {
|
|
10522
|
+
const platformDir = getPlatformDir();
|
|
10523
|
+
if (!platformDir) return null;
|
|
10524
|
+
const checksumPath = `${AUTH_CDN_PATH_PREFIX}/${platformDir}/checksum.json`;
|
|
10525
|
+
for (const { host, protocol } of sources) {
|
|
10526
|
+
try {
|
|
10527
|
+
const url = `${protocol}://${host}${checksumPath}`;
|
|
10528
|
+
const raw = await downloadText2(url, timeoutMs);
|
|
10529
|
+
const data = JSON.parse(raw);
|
|
10530
|
+
if (typeof data.sha256 !== "string" || typeof data.size !== "number" || typeof data.target !== "string") {
|
|
10531
|
+
continue;
|
|
10532
|
+
}
|
|
10533
|
+
return { sha256: data.sha256, size: data.size, target: data.target, source: host };
|
|
10534
|
+
} catch {
|
|
10535
|
+
}
|
|
10536
|
+
}
|
|
10537
|
+
return null;
|
|
10538
|
+
}
|
|
10539
|
+
async function fetchAndValidateChecksum2(host, protocol, checksumPath, platformDir, timeoutMs, onProgress) {
|
|
10540
|
+
const checksumUrl = `${protocol}://${host}${checksumPath}`;
|
|
10541
|
+
onProgress?.(`Fetching checksum from ${host}...`);
|
|
10542
|
+
const raw = await downloadText2(checksumUrl, timeoutMs);
|
|
10543
|
+
const checksum = JSON.parse(raw);
|
|
10544
|
+
if (typeof checksum.sha256 !== "string" || typeof checksum.size !== "number" || typeof checksum.target !== "string") {
|
|
10545
|
+
throw new Error("Invalid checksum.json: missing sha256, size, or target");
|
|
10546
|
+
}
|
|
10547
|
+
if (checksum.target !== platformDir) {
|
|
10548
|
+
throw new Error(`Target mismatch: expected ${platformDir}, got ${checksum.target}`);
|
|
10549
|
+
}
|
|
10550
|
+
return { sha256: checksum.sha256, size: checksum.size, target: checksum.target };
|
|
10551
|
+
}
|
|
10552
|
+
async function downloadAndVerify2(host, protocol, binaryPath, tmpPath, checksum, timeoutMs, onProgress) {
|
|
10553
|
+
const binaryUrl = `${protocol}://${host}${binaryPath}`;
|
|
10554
|
+
onProgress?.(`Downloading binary from ${host}...`);
|
|
10555
|
+
await download2(binaryUrl, tmpPath, timeoutMs);
|
|
10556
|
+
const actual = hashFile(tmpPath);
|
|
10557
|
+
if (actual.size !== checksum.size) {
|
|
10558
|
+
throw new Error(`Size mismatch: expected ${checksum.size}, got ${actual.size}`);
|
|
10559
|
+
}
|
|
10560
|
+
if (actual.sha256 !== checksum.sha256) {
|
|
10561
|
+
throw new Error(`SHA-256 mismatch: expected ${checksum.sha256}, got ${actual.sha256}`);
|
|
10562
|
+
}
|
|
10563
|
+
}
|
|
10564
|
+
function atomicReplace2(tmpPath, resolvedDest) {
|
|
10565
|
+
if (platform2() === "win32") {
|
|
10566
|
+
try {
|
|
10567
|
+
unlinkSync4(resolvedDest);
|
|
10568
|
+
} catch {
|
|
10569
|
+
}
|
|
10570
|
+
}
|
|
10571
|
+
renameSync4(tmpPath, resolvedDest);
|
|
10572
|
+
if (platform2() !== "win32") {
|
|
10573
|
+
chmodSync2(resolvedDest, 493);
|
|
10574
|
+
}
|
|
10575
|
+
}
|
|
10576
|
+
function installPreChecks2(destPath, sources) {
|
|
10577
|
+
if (!destPath && process.env.OKX_AUTH_BIN) {
|
|
10578
|
+
return { status: "up-to-date", source: "(env override)" };
|
|
10579
|
+
}
|
|
10580
|
+
if (!getPlatformDir()) {
|
|
10581
|
+
return { status: "failed", error: "Unsupported platform" };
|
|
10582
|
+
}
|
|
10583
|
+
if (sources.length === 0) {
|
|
10584
|
+
return { status: "failed", error: "No CDN sources available" };
|
|
10585
|
+
}
|
|
10586
|
+
return null;
|
|
10587
|
+
}
|
|
10588
|
+
function isLocalUpToDate2(localHash, checksum) {
|
|
10589
|
+
return localHash !== null && localHash.size === checksum.size && localHash.sha256 === checksum.sha256;
|
|
10590
|
+
}
|
|
10591
|
+
async function installAuthBinary(destPath, sources = CDN_SOURCES, onProgress) {
|
|
10592
|
+
const earlyResult = installPreChecks2(destPath, sources);
|
|
10593
|
+
if (earlyResult) return earlyResult;
|
|
10594
|
+
const platformDir = getPlatformDir();
|
|
10595
|
+
const binaryName = getAuthBinaryName();
|
|
10596
|
+
const resolvedDest = destPath ?? join11(homedir9(), ".okx", "bin", binaryName);
|
|
10597
|
+
const tmpPath = resolvedDest + ".tmp";
|
|
10598
|
+
mkdirSync9(dirname7(resolvedDest), { recursive: true });
|
|
10599
|
+
const localHash = existsSync7(resolvedDest) ? hashFile(resolvedDest) : null;
|
|
10600
|
+
const checksumPath = `${AUTH_CDN_PATH_PREFIX}/${platformDir}/checksum.json`;
|
|
10601
|
+
const binaryPath = `${AUTH_CDN_PATH_PREFIX}/${platformDir}/${binaryName}`;
|
|
10602
|
+
const errors = [];
|
|
10603
|
+
for (const { host, protocol } of sources) {
|
|
10604
|
+
try {
|
|
10605
|
+
const checksum = await fetchAndValidateChecksum2(
|
|
10606
|
+
host,
|
|
10607
|
+
protocol,
|
|
10608
|
+
checksumPath,
|
|
10609
|
+
platformDir,
|
|
10610
|
+
DOWNLOAD_TIMEOUT_MS,
|
|
10611
|
+
onProgress
|
|
10612
|
+
);
|
|
10613
|
+
if (isLocalUpToDate2(localHash, checksum)) {
|
|
10614
|
+
onProgress?.("Already up to date (checksum match)");
|
|
10615
|
+
return { status: "up-to-date", source: host };
|
|
10616
|
+
}
|
|
10617
|
+
await downloadAndVerify2(host, protocol, binaryPath, tmpPath, checksum, DOWNLOAD_TIMEOUT_MS, onProgress);
|
|
10618
|
+
atomicReplace2(tmpPath, resolvedDest);
|
|
10619
|
+
onProgress?.(`Downloaded and verified from ${host}`);
|
|
10620
|
+
return { status: "installed", source: host };
|
|
10621
|
+
} catch (err) {
|
|
10622
|
+
try {
|
|
10623
|
+
unlinkSync4(tmpPath);
|
|
10624
|
+
} catch {
|
|
10625
|
+
}
|
|
10626
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
10627
|
+
errors.push(`${host}: ${msg}`);
|
|
10628
|
+
onProgress?.(`${host} failed: ${msg}`);
|
|
10629
|
+
}
|
|
10630
|
+
}
|
|
10631
|
+
return { status: "failed", error: `All CDN sources failed:
|
|
10632
|
+
${errors.join("\n")}` };
|
|
10633
|
+
}
|
|
10634
|
+
function removeAuthBinary(binaryPath) {
|
|
10635
|
+
const resolvedPath = binaryPath ?? getAuthBinaryPath();
|
|
10636
|
+
try {
|
|
10637
|
+
unlinkSync4(resolvedPath);
|
|
10638
|
+
return { status: "removed" };
|
|
10639
|
+
} catch (err) {
|
|
10640
|
+
if (err.code === "ENOENT") {
|
|
10641
|
+
return { status: "not-found" };
|
|
10642
|
+
}
|
|
10643
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
10644
|
+
throw new Error(`Failed to remove ${resolvedPath}: ${msg}`);
|
|
10645
|
+
}
|
|
10646
|
+
}
|
|
10647
|
+
function isRedirect2(statusCode) {
|
|
10648
|
+
return statusCode !== void 0 && statusCode >= 300 && statusCode < 400;
|
|
10649
|
+
}
|
|
10650
|
+
function validateRedirect2(res, requestUrl, redirectCount, maxRedirects) {
|
|
10651
|
+
if (redirectCount > maxRedirects) {
|
|
10652
|
+
throw new Error(`Too many redirects (${maxRedirects})`);
|
|
10653
|
+
}
|
|
10654
|
+
const location = res.headers.location;
|
|
10655
|
+
if (requestUrl.startsWith("https") && !location.startsWith("https")) {
|
|
10656
|
+
throw new Error("Refused HTTPS \u2192 HTTP redirect downgrade");
|
|
10657
|
+
}
|
|
10658
|
+
return location;
|
|
10659
|
+
}
|
|
10660
|
+
function fetchResponse2(url, timeoutMs) {
|
|
10661
|
+
return new Promise((resolve3, reject) => {
|
|
10662
|
+
let redirects = 0;
|
|
10663
|
+
const maxRedirects = 5;
|
|
10664
|
+
function doRequest(requestUrl) {
|
|
10665
|
+
const reqFn = requestUrl.startsWith("https") ? httpsGet2 : httpGet2;
|
|
10666
|
+
const req = reqFn(requestUrl, { timeout: timeoutMs }, (res) => {
|
|
10667
|
+
if (isRedirect2(res.statusCode) && res.headers.location) {
|
|
10668
|
+
redirects++;
|
|
10669
|
+
try {
|
|
10670
|
+
const location = validateRedirect2(res, requestUrl, redirects, maxRedirects);
|
|
10671
|
+
res.resume();
|
|
10672
|
+
doRequest(location);
|
|
10673
|
+
} catch (err) {
|
|
10674
|
+
reject(err);
|
|
10675
|
+
}
|
|
10676
|
+
return;
|
|
10677
|
+
}
|
|
10678
|
+
if (res.statusCode !== 200) {
|
|
10679
|
+
reject(new Error(`HTTP ${res.statusCode ?? "unknown"}`));
|
|
10680
|
+
return;
|
|
10681
|
+
}
|
|
10682
|
+
resolve3(res);
|
|
10683
|
+
});
|
|
10684
|
+
req.on("error", reject);
|
|
10685
|
+
req.on("timeout", () => {
|
|
10686
|
+
req.destroy();
|
|
10687
|
+
reject(new Error("Download timed out"));
|
|
10688
|
+
});
|
|
10689
|
+
}
|
|
10690
|
+
doRequest(url);
|
|
10691
|
+
});
|
|
10692
|
+
}
|
|
10693
|
+
function download2(url, destPath, timeoutMs) {
|
|
10694
|
+
return fetchResponse2(url, timeoutMs).then(
|
|
10695
|
+
(res) => new Promise((resolve3, reject) => {
|
|
10696
|
+
const file = createWriteStream3(destPath);
|
|
10697
|
+
res.pipe(file);
|
|
10698
|
+
file.on("finish", () => file.close(() => resolve3()));
|
|
10699
|
+
file.on("error", (err) => {
|
|
10700
|
+
try {
|
|
10701
|
+
unlinkSync4(destPath);
|
|
10702
|
+
} catch {
|
|
10703
|
+
}
|
|
10704
|
+
reject(err);
|
|
10705
|
+
});
|
|
10706
|
+
})
|
|
10707
|
+
);
|
|
10708
|
+
}
|
|
10709
|
+
function downloadText2(url, timeoutMs) {
|
|
10710
|
+
return fetchResponse2(url, timeoutMs).then(
|
|
10711
|
+
(res) => new Promise((resolve3, reject) => {
|
|
10712
|
+
const chunks = [];
|
|
10713
|
+
res.on("data", (chunk) => chunks.push(chunk));
|
|
10714
|
+
res.on("end", () => resolve3(Buffer.concat(chunks).toString("utf8")));
|
|
10715
|
+
res.on("error", reject);
|
|
10716
|
+
})
|
|
10717
|
+
);
|
|
10718
|
+
}
|
|
10354
10719
|
|
|
10355
|
-
// src/commands/
|
|
10356
|
-
import
|
|
10357
|
-
import
|
|
10358
|
-
import os5 from "os";
|
|
10359
|
-
import tls from "tls";
|
|
10360
|
-
|
|
10361
|
-
// src/commands/diagnose-utils.ts
|
|
10362
|
-
import fs4 from "fs";
|
|
10363
|
-
import { createRequire } from "module";
|
|
10720
|
+
// src/commands/auth.ts
|
|
10721
|
+
import { spawn as spawn2 } from "child_process";
|
|
10722
|
+
import readline from "readline";
|
|
10364
10723
|
|
|
10365
10724
|
// src/formatter.ts
|
|
10366
10725
|
import { EOL } from "os";
|
|
@@ -10451,7 +10810,249 @@ function markFailedIfSCodeError(data) {
|
|
|
10451
10810
|
}
|
|
10452
10811
|
}
|
|
10453
10812
|
|
|
10813
|
+
// src/commands/auth.ts
|
|
10814
|
+
function runOkxAuth(args) {
|
|
10815
|
+
const binPath = getAuthBinaryPath();
|
|
10816
|
+
return new Promise((resolve3, reject) => {
|
|
10817
|
+
const child = spawn2(binPath, args, {
|
|
10818
|
+
stdio: "inherit"
|
|
10819
|
+
});
|
|
10820
|
+
child.on("error", (err) => {
|
|
10821
|
+
reject(new Error(`Failed to spawn okx-auth: ${err.message}`));
|
|
10822
|
+
});
|
|
10823
|
+
child.on("close", (code) => {
|
|
10824
|
+
resolve3(code ?? 1);
|
|
10825
|
+
});
|
|
10826
|
+
});
|
|
10827
|
+
}
|
|
10828
|
+
function runOkxAuthCapture(args) {
|
|
10829
|
+
const binPath = getAuthBinaryPath();
|
|
10830
|
+
return new Promise((resolve3, reject) => {
|
|
10831
|
+
const child = spawn2(binPath, args, {
|
|
10832
|
+
stdio: ["inherit", "pipe", "inherit"]
|
|
10833
|
+
});
|
|
10834
|
+
const chunks = [];
|
|
10835
|
+
child.stdout.on("data", (chunk) => chunks.push(chunk));
|
|
10836
|
+
child.on("error", (err) => {
|
|
10837
|
+
reject(new Error(`Failed to spawn okx-auth: ${err.message}`));
|
|
10838
|
+
});
|
|
10839
|
+
child.on("close", (code) => {
|
|
10840
|
+
resolve3({
|
|
10841
|
+
code: code ?? 1,
|
|
10842
|
+
stdout: Buffer.concat(chunks).toString("utf-8")
|
|
10843
|
+
});
|
|
10844
|
+
});
|
|
10845
|
+
});
|
|
10846
|
+
}
|
|
10847
|
+
async function cmdAuthLogin(args) {
|
|
10848
|
+
const cliArgs = ["login"];
|
|
10849
|
+
if (args.site) cliArgs.push("--site", args.site);
|
|
10850
|
+
if (args.manual) cliArgs.push("--manual");
|
|
10851
|
+
const code = await runOkxAuth(cliArgs);
|
|
10852
|
+
if (code !== 0) {
|
|
10853
|
+
process.exitCode = code;
|
|
10854
|
+
}
|
|
10855
|
+
}
|
|
10856
|
+
async function cmdAuthLogout() {
|
|
10857
|
+
const code = await runOkxAuth(["logout"]);
|
|
10858
|
+
if (code !== 0) {
|
|
10859
|
+
process.exitCode = code;
|
|
10860
|
+
}
|
|
10861
|
+
}
|
|
10862
|
+
async function cmdAuthStatus(args) {
|
|
10863
|
+
const cliArgs = ["status"];
|
|
10864
|
+
if (args.json) cliArgs.push("--json");
|
|
10865
|
+
const result = await runOkxAuthCapture(cliArgs);
|
|
10866
|
+
if (result.stdout) {
|
|
10867
|
+
process.stdout.write(result.stdout);
|
|
10868
|
+
}
|
|
10869
|
+
if (result.code !== 0) {
|
|
10870
|
+
process.exitCode = result.code;
|
|
10871
|
+
}
|
|
10872
|
+
}
|
|
10873
|
+
function resolveChecksumMatch(local, cdnChecksum, cdnError) {
|
|
10874
|
+
if (!local.exists) return "not-installed";
|
|
10875
|
+
if (cdnError || !cdnChecksum) return "unavailable";
|
|
10876
|
+
if (cdnChecksum.sha256 === local.sha256) return "match";
|
|
10877
|
+
return "mismatch";
|
|
10878
|
+
}
|
|
10879
|
+
function checksumMatchLabel(match) {
|
|
10880
|
+
if (match === "match") return "\u2713 match";
|
|
10881
|
+
if (match === "mismatch") return "\u2717 mismatch (update available)";
|
|
10882
|
+
return "CDN unreachable";
|
|
10883
|
+
}
|
|
10884
|
+
function formatBytes(bytes) {
|
|
10885
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
10886
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
10887
|
+
return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
|
|
10888
|
+
}
|
|
10889
|
+
async function cmdAuthInstallStatus(json) {
|
|
10890
|
+
const local = getAuthStatus();
|
|
10891
|
+
let cdnChecksum = null;
|
|
10892
|
+
let cdnError = null;
|
|
10893
|
+
if (local.exists) {
|
|
10894
|
+
try {
|
|
10895
|
+
cdnChecksum = await fetchAuthCdnChecksum(void 0, 5e3);
|
|
10896
|
+
} catch (err) {
|
|
10897
|
+
cdnError = err instanceof Error ? err.message : String(err);
|
|
10898
|
+
}
|
|
10899
|
+
}
|
|
10900
|
+
const checksumMatch = resolveChecksumMatch(local, cdnChecksum, cdnError);
|
|
10901
|
+
if (json) {
|
|
10902
|
+
outputLine(
|
|
10903
|
+
JSON.stringify({
|
|
10904
|
+
binaryPath: local.binaryPath,
|
|
10905
|
+
exists: local.exists,
|
|
10906
|
+
platform: local.platform,
|
|
10907
|
+
fileSize: local.fileSize ?? null,
|
|
10908
|
+
sha256: local.sha256 ?? null,
|
|
10909
|
+
cdnMatch: checksumMatch,
|
|
10910
|
+
cdnSha256: cdnChecksum?.sha256 ?? null,
|
|
10911
|
+
cdnSource: cdnChecksum?.source ?? null
|
|
10912
|
+
})
|
|
10913
|
+
);
|
|
10914
|
+
return;
|
|
10915
|
+
}
|
|
10916
|
+
outputLine("");
|
|
10917
|
+
outputLine(" okx-auth Binary Status");
|
|
10918
|
+
outputLine(" " + "\u2500".repeat(40));
|
|
10919
|
+
outputLine(` Binary path : ${local.binaryPath}`);
|
|
10920
|
+
outputLine(` Installed : ${local.exists ? "yes" : "no"}`);
|
|
10921
|
+
outputLine(` Platform : ${local.platform ?? "(unsupported)"}`);
|
|
10922
|
+
if (local.exists) {
|
|
10923
|
+
outputLine(` File size : ${formatBytes(local.fileSize)}`);
|
|
10924
|
+
outputLine(` SHA-256 : ${local.sha256 ?? "(unknown)"}`);
|
|
10925
|
+
outputLine(` CDN check : ${checksumMatchLabel(checksumMatch)}`);
|
|
10926
|
+
if (cdnChecksum) {
|
|
10927
|
+
outputLine(` CDN source : ${cdnChecksum.source}`);
|
|
10928
|
+
}
|
|
10929
|
+
}
|
|
10930
|
+
outputLine("");
|
|
10931
|
+
}
|
|
10932
|
+
async function cmdAuthInstall(json) {
|
|
10933
|
+
const messages2 = [];
|
|
10934
|
+
const onProgress = (msg) => {
|
|
10935
|
+
if (!json) {
|
|
10936
|
+
outputLine(` ${msg}`);
|
|
10937
|
+
}
|
|
10938
|
+
messages2.push(msg);
|
|
10939
|
+
};
|
|
10940
|
+
if (!json) {
|
|
10941
|
+
outputLine("");
|
|
10942
|
+
outputLine(" Installing okx-auth...");
|
|
10943
|
+
}
|
|
10944
|
+
const result = await installAuthBinary(void 0, void 0, onProgress);
|
|
10945
|
+
if (json) {
|
|
10946
|
+
outputLine(JSON.stringify({ status: result.status, source: result.source ?? null, error: result.error ?? null, messages: messages2 }));
|
|
10947
|
+
if (result.status === "failed") {
|
|
10948
|
+
process.exitCode = 1;
|
|
10949
|
+
}
|
|
10950
|
+
return;
|
|
10951
|
+
}
|
|
10952
|
+
if (result.status === "installed") {
|
|
10953
|
+
outputLine(` \u2713 okx-auth installed successfully (${result.source ?? ""})`);
|
|
10954
|
+
} else if (result.status === "up-to-date") {
|
|
10955
|
+
outputLine(" \u2713 okx-auth is already up to date");
|
|
10956
|
+
} else {
|
|
10957
|
+
errorLine(` \u2717 Installation failed: ${result.error ?? "unknown error"}`);
|
|
10958
|
+
errorLine(" Hint: check network connectivity or try again later");
|
|
10959
|
+
process.exitCode = 1;
|
|
10960
|
+
}
|
|
10961
|
+
outputLine("");
|
|
10962
|
+
}
|
|
10963
|
+
async function cmdAuthRemove(force, json) {
|
|
10964
|
+
const local = getAuthStatus(void 0, { skipHash: true });
|
|
10965
|
+
if (!local.exists) {
|
|
10966
|
+
if (json) {
|
|
10967
|
+
outputLine(JSON.stringify({ status: "not-installed" }));
|
|
10968
|
+
} else {
|
|
10969
|
+
outputLine(" okx-auth is not installed.");
|
|
10970
|
+
}
|
|
10971
|
+
return;
|
|
10972
|
+
}
|
|
10973
|
+
if (!force) {
|
|
10974
|
+
if (!process.stdin.isTTY) {
|
|
10975
|
+
errorLine(" Error: stdin is not a TTY. Use --force to skip confirmation.");
|
|
10976
|
+
process.exitCode = 1;
|
|
10977
|
+
return;
|
|
10978
|
+
}
|
|
10979
|
+
const confirmed = await askConfirmation(
|
|
10980
|
+
` Remove okx-auth at ${local.binaryPath}? [y/N] `
|
|
10981
|
+
);
|
|
10982
|
+
if (!confirmed) {
|
|
10983
|
+
outputLine(" Cancelled.");
|
|
10984
|
+
return;
|
|
10985
|
+
}
|
|
10986
|
+
}
|
|
10987
|
+
let result;
|
|
10988
|
+
try {
|
|
10989
|
+
result = removeAuthBinary();
|
|
10990
|
+
} catch (err) {
|
|
10991
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
10992
|
+
if (json) {
|
|
10993
|
+
outputLine(JSON.stringify({ status: "failed", error: msg }));
|
|
10994
|
+
} else {
|
|
10995
|
+
errorLine(` \u2717 Failed to remove: ${msg}`);
|
|
10996
|
+
}
|
|
10997
|
+
process.exitCode = 1;
|
|
10998
|
+
return;
|
|
10999
|
+
}
|
|
11000
|
+
if (json) {
|
|
11001
|
+
outputLine(JSON.stringify({ status: result.status, path: local.binaryPath }));
|
|
11002
|
+
return;
|
|
11003
|
+
}
|
|
11004
|
+
if (result.status === "removed") {
|
|
11005
|
+
outputLine(` \u2713 Removed: ${local.binaryPath}`);
|
|
11006
|
+
} else {
|
|
11007
|
+
outputLine(" okx-auth is not installed.");
|
|
11008
|
+
}
|
|
11009
|
+
}
|
|
11010
|
+
function askConfirmation(prompt2) {
|
|
11011
|
+
return new Promise((resolve3) => {
|
|
11012
|
+
const rl = readline.createInterface({
|
|
11013
|
+
input: process.stdin,
|
|
11014
|
+
output: process.stdout
|
|
11015
|
+
});
|
|
11016
|
+
rl.question(prompt2, (answer) => {
|
|
11017
|
+
rl.close();
|
|
11018
|
+
resolve3(answer.trim().toLowerCase() === "y");
|
|
11019
|
+
});
|
|
11020
|
+
});
|
|
11021
|
+
}
|
|
11022
|
+
function handleAuthCommand(action, _rest, v) {
|
|
11023
|
+
const site = v.site;
|
|
11024
|
+
const json = v.json;
|
|
11025
|
+
const manual = v.manual;
|
|
11026
|
+
const force = v.force;
|
|
11027
|
+
switch (action) {
|
|
11028
|
+
case "login":
|
|
11029
|
+
return cmdAuthLogin({ site, manual });
|
|
11030
|
+
case "logout":
|
|
11031
|
+
return cmdAuthLogout();
|
|
11032
|
+
case "status":
|
|
11033
|
+
return cmdAuthStatus({ json });
|
|
11034
|
+
case "install":
|
|
11035
|
+
return cmdAuthInstall(json ?? false);
|
|
11036
|
+
case "install-status":
|
|
11037
|
+
return cmdAuthInstallStatus(json ?? false);
|
|
11038
|
+
case "remove":
|
|
11039
|
+
return cmdAuthRemove(force ?? false, json ?? false);
|
|
11040
|
+
default:
|
|
11041
|
+
errorLine(`Unknown auth command: ${action}`);
|
|
11042
|
+
errorLine("Available: login, logout, status, install, install-status, remove");
|
|
11043
|
+
process.exitCode = 1;
|
|
11044
|
+
}
|
|
11045
|
+
}
|
|
11046
|
+
|
|
11047
|
+
// src/commands/diagnose.ts
|
|
11048
|
+
import dns from "dns/promises";
|
|
11049
|
+
import net from "net";
|
|
11050
|
+
import os5 from "os";
|
|
11051
|
+
import tls from "tls";
|
|
11052
|
+
|
|
10454
11053
|
// src/commands/diagnose-utils.ts
|
|
11054
|
+
import fs4 from "fs";
|
|
11055
|
+
import { createRequire } from "module";
|
|
10455
11056
|
var _require = createRequire(import.meta.url);
|
|
10456
11057
|
function readCliVersion() {
|
|
10457
11058
|
for (const rel of ["../package.json", "../../package.json"]) {
|
|
@@ -10537,7 +11138,7 @@ function sanitize2(value) {
|
|
|
10537
11138
|
import fs5 from "fs";
|
|
10538
11139
|
import path4 from "path";
|
|
10539
11140
|
import os4 from "os";
|
|
10540
|
-
import { spawnSync, spawn } from "child_process";
|
|
11141
|
+
import { spawnSync, spawn as spawn3 } from "child_process";
|
|
10541
11142
|
import { createRequire as createRequire2 } from "module";
|
|
10542
11143
|
import { fileURLToPath } from "url";
|
|
10543
11144
|
var _require2 = createRequire2(import.meta.url);
|
|
@@ -10871,7 +11472,7 @@ async function checkStdioHandshake(entryPath, report) {
|
|
|
10871
11472
|
clearTimeout(timer);
|
|
10872
11473
|
resolve3(passed);
|
|
10873
11474
|
};
|
|
10874
|
-
const child =
|
|
11475
|
+
const child = spawn3(process.execPath, [entryPath], {
|
|
10875
11476
|
stdio: ["pipe", "pipe", "pipe"],
|
|
10876
11477
|
env: { ...process.env }
|
|
10877
11478
|
});
|
|
@@ -10990,7 +11591,7 @@ async function cmdDiagnoseMcp(options = {}) {
|
|
|
10990
11591
|
|
|
10991
11592
|
// src/commands/diagnose.ts
|
|
10992
11593
|
var CLI_VERSION = readCliVersion();
|
|
10993
|
-
var GIT_HASH = true ? "
|
|
11594
|
+
var GIT_HASH = true ? "1431fd4" : "dev";
|
|
10994
11595
|
function maskKey2(key) {
|
|
10995
11596
|
if (!key) return "(not set)";
|
|
10996
11597
|
if (key.length <= 8) return "****";
|
|
@@ -11326,13 +11927,13 @@ async function runCliChecks(config, profile, outputPath) {
|
|
|
11326
11927
|
|
|
11327
11928
|
// src/commands/upgrade.ts
|
|
11328
11929
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
11329
|
-
import { readFileSync as readFileSync8, writeFileSync as writeFileSync7, mkdirSync as
|
|
11330
|
-
import { dirname as
|
|
11331
|
-
import { homedir as
|
|
11930
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync7, mkdirSync as mkdirSync10 } from "fs";
|
|
11931
|
+
import { dirname as dirname8, join as join12 } from "path";
|
|
11932
|
+
import { homedir as homedir10 } from "os";
|
|
11332
11933
|
var PACKAGES = ["@okx_ai/okx-trade-mcp", "@okx_ai/okx-trade-cli"];
|
|
11333
|
-
var CACHE_FILE2 =
|
|
11934
|
+
var CACHE_FILE2 = join12(homedir10(), ".okx", "last_check");
|
|
11334
11935
|
var THROTTLE_MS = 12 * 60 * 60 * 1e3;
|
|
11335
|
-
var NPM_BIN =
|
|
11936
|
+
var NPM_BIN = join12(dirname8(process.execPath), process.platform === "win32" ? "npm.cmd" : "npm");
|
|
11336
11937
|
function readLastCheck() {
|
|
11337
11938
|
try {
|
|
11338
11939
|
return parseInt(readFileSync8(CACHE_FILE2, "utf-8").trim(), 10) || 0;
|
|
@@ -11342,7 +11943,7 @@ function readLastCheck() {
|
|
|
11342
11943
|
}
|
|
11343
11944
|
function writeLastCheck() {
|
|
11344
11945
|
try {
|
|
11345
|
-
|
|
11946
|
+
mkdirSync10(join12(homedir10(), ".okx"), { recursive: true });
|
|
11346
11947
|
writeFileSync7(CACHE_FILE2, String(Math.floor(Date.now() / 1e3)), "utf-8");
|
|
11347
11948
|
} catch {
|
|
11348
11949
|
}
|
|
@@ -12763,7 +13364,7 @@ async function cmdNewsSentimentRank(run, opts) {
|
|
|
12763
13364
|
}
|
|
12764
13365
|
|
|
12765
13366
|
// src/config/loader.ts
|
|
12766
|
-
function loadProfileConfig(opts) {
|
|
13367
|
+
async function loadProfileConfig(opts) {
|
|
12767
13368
|
return loadConfig({
|
|
12768
13369
|
profile: opts.profile,
|
|
12769
13370
|
modules: opts.modules,
|
|
@@ -13081,6 +13682,9 @@ var CLI_OPTIONS = {
|
|
|
13081
13682
|
dir: { type: "string" },
|
|
13082
13683
|
page: { type: "string" },
|
|
13083
13684
|
format: { type: "string" },
|
|
13685
|
+
// auth
|
|
13686
|
+
site: { type: "string" },
|
|
13687
|
+
manual: { type: "boolean", default: false },
|
|
13084
13688
|
// event contract
|
|
13085
13689
|
underlying: { type: "string" },
|
|
13086
13690
|
seriesId: { type: "string" },
|
|
@@ -16095,14 +16699,14 @@ async function cmdDcdQuoteAndBuy(run, opts) {
|
|
|
16095
16699
|
}
|
|
16096
16700
|
|
|
16097
16701
|
// src/commands/skill.ts
|
|
16098
|
-
import { tmpdir, homedir as
|
|
16099
|
-
import { join as
|
|
16100
|
-
import { mkdirSync as
|
|
16702
|
+
import { tmpdir, homedir as homedir12 } from "os";
|
|
16703
|
+
import { join as join14, dirname as dirname9 } from "path";
|
|
16704
|
+
import { mkdirSync as mkdirSync11, rmSync, existsSync as existsSync9, copyFileSync as copyFileSync2 } from "fs";
|
|
16101
16705
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
16102
16706
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
16103
16707
|
function resolveNpx() {
|
|
16104
|
-
const sibling =
|
|
16105
|
-
if (
|
|
16708
|
+
const sibling = join14(dirname9(process.execPath), "npx");
|
|
16709
|
+
if (existsSync9(sibling)) return sibling;
|
|
16106
16710
|
return "npx";
|
|
16107
16711
|
}
|
|
16108
16712
|
var THIRD_PARTY_INSTALL_NOTICE = "Note: This skill was created by a third-party developer, not by OKX. Review SKILL.md before use.";
|
|
@@ -16155,13 +16759,13 @@ async function cmdSkillCategories(run, json) {
|
|
|
16155
16759
|
outputLine("");
|
|
16156
16760
|
}
|
|
16157
16761
|
async function cmdSkillAdd(name, config, json) {
|
|
16158
|
-
const tmpBase =
|
|
16159
|
-
|
|
16762
|
+
const tmpBase = join14(tmpdir(), `okx-skill-${randomUUID2()}`);
|
|
16763
|
+
mkdirSync11(tmpBase, { recursive: true });
|
|
16160
16764
|
try {
|
|
16161
16765
|
outputLine(`Downloading ${name}...`);
|
|
16162
16766
|
const client = new OkxRestClient(config);
|
|
16163
16767
|
const zipPath = await downloadSkillZip(client, name, tmpBase);
|
|
16164
|
-
const contentDir = await extractSkillZip(zipPath,
|
|
16768
|
+
const contentDir = await extractSkillZip(zipPath, join14(tmpBase, "content"));
|
|
16165
16769
|
const meta = readMetaJson(contentDir);
|
|
16166
16770
|
validateSkillMdExists(contentDir);
|
|
16167
16771
|
outputLine("Installing to detected agents...");
|
|
@@ -16171,7 +16775,7 @@ async function cmdSkillAdd(name, config, json) {
|
|
|
16171
16775
|
timeout: 6e4
|
|
16172
16776
|
});
|
|
16173
16777
|
} catch (e) {
|
|
16174
|
-
const savedZip =
|
|
16778
|
+
const savedZip = join14(process.cwd(), `${name}.zip`);
|
|
16175
16779
|
try {
|
|
16176
16780
|
copyFileSync2(zipPath, savedZip);
|
|
16177
16781
|
} catch {
|
|
@@ -16210,7 +16814,7 @@ function cmdSkillRemove(name, json) {
|
|
|
16210
16814
|
timeout: 6e4
|
|
16211
16815
|
});
|
|
16212
16816
|
} catch {
|
|
16213
|
-
const agentsPath =
|
|
16817
|
+
const agentsPath = join14(homedir12(), ".agents", "skills", name);
|
|
16214
16818
|
try {
|
|
16215
16819
|
rmSync(agentsPath, { recursive: true, force: true });
|
|
16216
16820
|
} catch {
|
|
@@ -16284,14 +16888,14 @@ function printSkillInstallResult(meta, json) {
|
|
|
16284
16888
|
}
|
|
16285
16889
|
|
|
16286
16890
|
// src/commands/doh.ts
|
|
16287
|
-
import
|
|
16288
|
-
function
|
|
16891
|
+
import readline2 from "readline";
|
|
16892
|
+
function resolveChecksumMatch2(local, cdnChecksum, cdnError) {
|
|
16289
16893
|
if (!local.exists) return "not-installed";
|
|
16290
16894
|
if (cdnError || !cdnChecksum) return "unavailable";
|
|
16291
16895
|
if (cdnChecksum.sha256 === local.sha256) return "match";
|
|
16292
16896
|
return "mismatch";
|
|
16293
16897
|
}
|
|
16294
|
-
function
|
|
16898
|
+
function checksumMatchLabel2(match) {
|
|
16295
16899
|
if (match === "match") return "\u2713 match";
|
|
16296
16900
|
if (match === "mismatch") return "\u2717 mismatch (update available)";
|
|
16297
16901
|
return "CDN unreachable";
|
|
@@ -16304,9 +16908,9 @@ function formatStatusText(local, checksumMatch, cdnChecksum, runtimeMode) {
|
|
|
16304
16908
|
outputLine(` Installed : ${local.exists ? "yes" : "no"}`);
|
|
16305
16909
|
outputLine(` Platform : ${local.platform ?? "(unsupported)"}`);
|
|
16306
16910
|
if (local.exists) {
|
|
16307
|
-
outputLine(` File size : ${
|
|
16911
|
+
outputLine(` File size : ${formatBytes2(local.fileSize)}`);
|
|
16308
16912
|
outputLine(` SHA-256 : ${local.sha256 ?? "(unknown)"}`);
|
|
16309
|
-
outputLine(` CDN check : ${
|
|
16913
|
+
outputLine(` CDN check : ${checksumMatchLabel2(checksumMatch)}`);
|
|
16310
16914
|
if (cdnChecksum) {
|
|
16311
16915
|
outputLine(` CDN source : ${cdnChecksum.source}`);
|
|
16312
16916
|
}
|
|
@@ -16333,7 +16937,7 @@ async function cmdDohStatus(json, binaryPath) {
|
|
|
16333
16937
|
cdnError = err instanceof Error ? err.message : String(err);
|
|
16334
16938
|
}
|
|
16335
16939
|
}
|
|
16336
|
-
const checksumMatch =
|
|
16940
|
+
const checksumMatch = resolveChecksumMatch2(local, cdnChecksum, cdnError);
|
|
16337
16941
|
if (json) {
|
|
16338
16942
|
outputLine(
|
|
16339
16943
|
JSON.stringify({
|
|
@@ -16399,7 +17003,7 @@ async function cmdDohRemove(force, json, binaryPath) {
|
|
|
16399
17003
|
process.exitCode = 1;
|
|
16400
17004
|
return;
|
|
16401
17005
|
}
|
|
16402
|
-
const confirmed = await
|
|
17006
|
+
const confirmed = await askConfirmation2(
|
|
16403
17007
|
` Remove DoH resolver at ${local.binaryPath}? [y/N] `
|
|
16404
17008
|
);
|
|
16405
17009
|
if (!confirmed) {
|
|
@@ -16418,14 +17022,14 @@ async function cmdDohRemove(force, json, binaryPath) {
|
|
|
16418
17022
|
outputLine(" DoH resolver is not installed.");
|
|
16419
17023
|
}
|
|
16420
17024
|
}
|
|
16421
|
-
function
|
|
17025
|
+
function formatBytes2(bytes) {
|
|
16422
17026
|
if (bytes < 1024) return `${bytes} B`;
|
|
16423
17027
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
16424
17028
|
return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
|
|
16425
17029
|
}
|
|
16426
|
-
function
|
|
17030
|
+
function askConfirmation2(prompt2) {
|
|
16427
17031
|
return new Promise((resolve3) => {
|
|
16428
|
-
const rl =
|
|
17032
|
+
const rl = readline2.createInterface({
|
|
16429
17033
|
input: process.stdin,
|
|
16430
17034
|
output: process.stdout
|
|
16431
17035
|
});
|
|
@@ -16882,7 +17486,7 @@ async function cmdEventCancel(run, opts) {
|
|
|
16882
17486
|
// src/index.ts
|
|
16883
17487
|
var _require3 = createRequire3(import.meta.url);
|
|
16884
17488
|
var CLI_VERSION2 = _require3("../package.json").version;
|
|
16885
|
-
var GIT_HASH2 = true ? "
|
|
17489
|
+
var GIT_HASH2 = true ? "1431fd4" : "dev";
|
|
16886
17490
|
function handleDohCommand(action, json, force, binaryPath) {
|
|
16887
17491
|
if (action === "status") return cmdDohStatus(json, binaryPath);
|
|
16888
17492
|
if (action === "install") return cmdDohInstall(json, binaryPath);
|
|
@@ -17857,7 +18461,7 @@ function wrapRunnerWithLogger(baseRunner, logger, verbose = false) {
|
|
|
17857
18461
|
async function runDiagnose(v) {
|
|
17858
18462
|
let config;
|
|
17859
18463
|
try {
|
|
17860
|
-
config = loadProfileConfig({ profile: v.profile, demo: v.demo, live: v.live, verbose: v.verbose, userAgent: `okx-trade-cli/${CLI_VERSION2}`, sourceTag: "CLI" });
|
|
18464
|
+
config = await loadProfileConfig({ profile: v.profile, demo: v.demo, live: v.live, verbose: v.verbose, userAgent: `okx-trade-cli/${CLI_VERSION2}`, sourceTag: "CLI" });
|
|
17861
18465
|
} catch {
|
|
17862
18466
|
}
|
|
17863
18467
|
return cmdDiagnose(config, v.profile ?? "default", { mcp: v.mcp, cli: v.cli, all: v.all, output: v.output });
|
|
@@ -17874,6 +18478,7 @@ function printVersion() {
|
|
|
17874
18478
|
function routeManagementCommand(module, action, rest, json, v) {
|
|
17875
18479
|
if (module === "config") return handleConfigCommand(action, rest, json, v.lang, v.force);
|
|
17876
18480
|
if (module === "setup") return handleSetupCommand(v);
|
|
18481
|
+
if (module === "auth") return handleAuthCommand(action, rest, v);
|
|
17877
18482
|
if (module === "upgrade") return cmdUpgrade(CLI_VERSION2, { beta: v.beta, check: v.check, force: v.force }, json);
|
|
17878
18483
|
if (module === "doh") return handleDohCommand(action, json, v.force ?? false);
|
|
17879
18484
|
if (module === "diagnose") return runDiagnose(v);
|
|
@@ -17900,7 +18505,7 @@ async function main() {
|
|
|
17900
18505
|
const json = v.json ?? false;
|
|
17901
18506
|
const mgmt = routeManagementCommand(module, action, rest, json, v);
|
|
17902
18507
|
if (mgmt) return mgmt;
|
|
17903
|
-
const config = loadProfileConfig({ profile: v.profile, demo: v.demo, live: v.live, verbose: v.verbose, userAgent: `okx-trade-cli/${CLI_VERSION2}`, sourceTag: "CLI" });
|
|
18508
|
+
const config = await loadProfileConfig({ profile: v.profile, demo: v.demo, live: v.live, verbose: v.verbose, userAgent: `okx-trade-cli/${CLI_VERSION2}`, sourceTag: "CLI" });
|
|
17904
18509
|
setEnvContext({ demo: config.demo, profile: v.profile ?? "default" });
|
|
17905
18510
|
setJsonEnvEnabled(v.env ?? false);
|
|
17906
18511
|
const client = new OkxRestClient(config);
|