@okx_ai/okx-trade-cli 1.3.2-beta.1 → 1.3.2-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 +310 -186
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/scripts/postinstall.js +9 -9
package/dist/index.js
CHANGED
|
@@ -892,19 +892,19 @@ import { get as httpsGet } from "https";
|
|
|
892
892
|
import { get as httpGet } from "http";
|
|
893
893
|
var EXEC_TIMEOUT_MS = 3e4;
|
|
894
894
|
var ALLOWED_DOMAIN_RE = /^[\w.-]+\.okx\.com$/;
|
|
895
|
-
var
|
|
896
|
-
function
|
|
897
|
-
if (process.env.
|
|
898
|
-
return process.env.
|
|
895
|
+
var PILOT_BIN_DIR = join(homedir(), ".okx", "bin");
|
|
896
|
+
function getPilotBinaryPath() {
|
|
897
|
+
if (process.env.OKX_PILOT_BINARY_PATH) {
|
|
898
|
+
return process.env.OKX_PILOT_BINARY_PATH;
|
|
899
899
|
}
|
|
900
900
|
const ext = process.platform === "win32" ? ".exe" : "";
|
|
901
|
-
return join(
|
|
901
|
+
return join(PILOT_BIN_DIR, `okx-pilot${ext}`);
|
|
902
902
|
}
|
|
903
|
-
function
|
|
903
|
+
function execPilotBinary(domain, exclude = [], userAgent) {
|
|
904
904
|
if (!ALLOWED_DOMAIN_RE.test(domain)) {
|
|
905
905
|
return Promise.resolve(null);
|
|
906
906
|
}
|
|
907
|
-
const binPath =
|
|
907
|
+
const binPath = getPilotBinaryPath();
|
|
908
908
|
const args = ["--domain", domain];
|
|
909
909
|
if (exclude.length > 0) {
|
|
910
910
|
args.push("--exclude", exclude.join(","));
|
|
@@ -937,7 +937,7 @@ function execDohBinary(domain, exclude = [], userAgent) {
|
|
|
937
937
|
});
|
|
938
938
|
}
|
|
939
939
|
function getDefaultCachePath() {
|
|
940
|
-
return process.env.
|
|
940
|
+
return process.env.OKX_PILOT_CACHE_PATH || join2(homedir2(), ".okx", "pilot-cache.json");
|
|
941
941
|
}
|
|
942
942
|
function readCache(hostname, cachePath = getDefaultCachePath()) {
|
|
943
943
|
try {
|
|
@@ -991,7 +991,7 @@ function getActiveFailedNodes(nodes) {
|
|
|
991
991
|
const now = Date.now();
|
|
992
992
|
return nodes.filter((n) => now - n.failedAt < FAILED_NODE_TTL_MS);
|
|
993
993
|
}
|
|
994
|
-
function
|
|
994
|
+
function resolvePilot(hostname, cachePath) {
|
|
995
995
|
const entry = readCache(hostname, cachePath);
|
|
996
996
|
if (entry) {
|
|
997
997
|
if (entry.mode === "direct") {
|
|
@@ -1003,53 +1003,53 @@ function resolveDoh(hostname, cachePath) {
|
|
|
1003
1003
|
}
|
|
1004
1004
|
return { mode: null, node: null };
|
|
1005
1005
|
}
|
|
1006
|
-
async function
|
|
1006
|
+
async function reResolvePilot(hostname, failedIp, userAgent, cachePath) {
|
|
1007
1007
|
const entry = readCache(hostname, cachePath);
|
|
1008
1008
|
const active = getActiveFailedNodes(entry?.failedNodes);
|
|
1009
1009
|
const now = Date.now();
|
|
1010
1010
|
const alreadyFailed = failedIp && active.some((n) => n.ip === failedIp);
|
|
1011
1011
|
const failedNodes = failedIp && !alreadyFailed ? [...active, { ip: failedIp, failedAt: now }] : active;
|
|
1012
1012
|
const excludeIps = failedNodes.map((n) => n.ip);
|
|
1013
|
-
const node = await
|
|
1013
|
+
const node = await execPilotBinary(hostname, excludeIps, userAgent);
|
|
1014
1014
|
return classifyAndCache(node, hostname, failedNodes, cachePath);
|
|
1015
1015
|
}
|
|
1016
1016
|
function vlog(message) {
|
|
1017
1017
|
process.stderr.write(`[verbose] ${message}
|
|
1018
1018
|
`);
|
|
1019
1019
|
}
|
|
1020
|
-
var
|
|
1020
|
+
var PilotManager = class {
|
|
1021
1021
|
opts;
|
|
1022
|
-
//
|
|
1023
|
-
|
|
1024
|
-
|
|
1022
|
+
// Pilot proxy state (lazy-resolved on first request)
|
|
1023
|
+
pilotResolved = false;
|
|
1024
|
+
pilotRetried = false;
|
|
1025
1025
|
directUnverified = false;
|
|
1026
1026
|
// The first direct connection has not yet been verified
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1027
|
+
pilotNode = null;
|
|
1028
|
+
pilotAgent = null;
|
|
1029
|
+
pilotBaseUrl = null;
|
|
1030
1030
|
constructor(opts) {
|
|
1031
1031
|
this.opts = opts;
|
|
1032
1032
|
}
|
|
1033
1033
|
/**
|
|
1034
|
-
* Lazily resolve the
|
|
1034
|
+
* Lazily resolve the Pilot proxy node on the first request.
|
|
1035
1035
|
* Uses cache-first strategy via the resolver.
|
|
1036
1036
|
*/
|
|
1037
|
-
|
|
1038
|
-
if (this.
|
|
1039
|
-
this.
|
|
1037
|
+
preparePilot() {
|
|
1038
|
+
if (this.pilotResolved || this.opts.hasCustomProxy) return;
|
|
1039
|
+
this.pilotResolved = true;
|
|
1040
1040
|
try {
|
|
1041
1041
|
const { hostname, protocol } = new URL(this.opts.baseUrl);
|
|
1042
|
-
const result =
|
|
1042
|
+
const result = resolvePilot(hostname);
|
|
1043
1043
|
if (!result.mode) {
|
|
1044
1044
|
this.directUnverified = true;
|
|
1045
1045
|
if (this.opts.verbose) {
|
|
1046
|
-
vlog("
|
|
1046
|
+
vlog("Pilot: no cache, trying direct connection first");
|
|
1047
1047
|
}
|
|
1048
1048
|
return;
|
|
1049
1049
|
}
|
|
1050
1050
|
if (result.mode === "direct") {
|
|
1051
1051
|
if (this.opts.verbose) {
|
|
1052
|
-
vlog("
|
|
1052
|
+
vlog("Pilot: mode=direct (overseas or cached), using direct connection");
|
|
1053
1053
|
}
|
|
1054
1054
|
return;
|
|
1055
1055
|
}
|
|
@@ -1059,57 +1059,57 @@ var DohManager = class {
|
|
|
1059
1059
|
} catch (err) {
|
|
1060
1060
|
if (this.opts.verbose) {
|
|
1061
1061
|
const cause = err instanceof Error ? err.message : String(err);
|
|
1062
|
-
vlog(`
|
|
1062
|
+
vlog(`Pilot resolution failed, falling back to direct: ${cause}`);
|
|
1063
1063
|
}
|
|
1064
1064
|
}
|
|
1065
1065
|
}
|
|
1066
1066
|
/** Get connection parameters for the current request. */
|
|
1067
1067
|
getConnectionParams() {
|
|
1068
|
-
const baseUrl = this.
|
|
1068
|
+
const baseUrl = this.pilotNode ? this.pilotBaseUrl : this.opts.baseUrl;
|
|
1069
1069
|
const result = { baseUrl };
|
|
1070
|
-
if (this.
|
|
1071
|
-
result.dispatcher = this.
|
|
1070
|
+
if (this.pilotAgent) {
|
|
1071
|
+
result.dispatcher = this.pilotAgent;
|
|
1072
1072
|
}
|
|
1073
|
-
if (this.
|
|
1074
|
-
result.userAgent = this.
|
|
1073
|
+
if (this.pilotNode) {
|
|
1074
|
+
result.userAgent = this.pilotUserAgent;
|
|
1075
1075
|
}
|
|
1076
1076
|
return result;
|
|
1077
1077
|
}
|
|
1078
|
-
/** Whether a
|
|
1078
|
+
/** Whether a Pilot proxy node is currently active. */
|
|
1079
1079
|
get isProxyActive() {
|
|
1080
|
-
return this.
|
|
1080
|
+
return this.pilotNode !== null;
|
|
1081
1081
|
}
|
|
1082
1082
|
/** Whether we have already retried after network failure. */
|
|
1083
1083
|
get hasRetried() {
|
|
1084
|
-
return this.
|
|
1084
|
+
return this.pilotRetried;
|
|
1085
1085
|
}
|
|
1086
1086
|
/**
|
|
1087
1087
|
* Handle network failure: re-resolve with --exclude and retry once.
|
|
1088
1088
|
* Returns true if retry should proceed, false if already retried.
|
|
1089
1089
|
*/
|
|
1090
1090
|
async handleNetworkFailure() {
|
|
1091
|
-
if (this.
|
|
1092
|
-
this.
|
|
1093
|
-
const failedIp = this.
|
|
1091
|
+
if (this.pilotRetried) return false;
|
|
1092
|
+
this.pilotRetried = true;
|
|
1093
|
+
const failedIp = this.pilotNode?.ip ?? "";
|
|
1094
1094
|
const { hostname, protocol } = new URL(this.opts.baseUrl);
|
|
1095
|
-
this.
|
|
1096
|
-
this.
|
|
1097
|
-
this.
|
|
1095
|
+
this.pilotNode = null;
|
|
1096
|
+
this.pilotAgent = null;
|
|
1097
|
+
this.pilotBaseUrl = null;
|
|
1098
1098
|
if (!failedIp) this.directUnverified = false;
|
|
1099
1099
|
if (this.opts.verbose) {
|
|
1100
|
-
vlog(failedIp ? `
|
|
1100
|
+
vlog(failedIp ? `Pilot: proxy node ${failedIp} failed, re-resolving with --exclude` : "Pilot: direct connection failed, calling binary for Pilot resolution");
|
|
1101
1101
|
}
|
|
1102
1102
|
try {
|
|
1103
|
-
const result = await
|
|
1103
|
+
const result = await reResolvePilot(hostname, failedIp, this.pilotUserAgent);
|
|
1104
1104
|
if (result.mode === "proxy" && result.node) {
|
|
1105
1105
|
this.applyNode(result.node, protocol);
|
|
1106
|
-
this.
|
|
1106
|
+
this.pilotRetried = false;
|
|
1107
1107
|
return true;
|
|
1108
1108
|
}
|
|
1109
1109
|
} catch {
|
|
1110
1110
|
}
|
|
1111
1111
|
if (this.opts.verbose) {
|
|
1112
|
-
vlog("
|
|
1112
|
+
vlog("Pilot: re-resolution failed or switched to direct, retrying with direct connection");
|
|
1113
1113
|
}
|
|
1114
1114
|
return true;
|
|
1115
1115
|
}
|
|
@@ -1118,7 +1118,7 @@ var DohManager = class {
|
|
|
1118
1118
|
* (Even if the business response is an error, the network path is valid.)
|
|
1119
1119
|
*/
|
|
1120
1120
|
cacheDirectIfNeeded() {
|
|
1121
|
-
if (!this.directUnverified || this.
|
|
1121
|
+
if (!this.directUnverified || this.pilotNode) return;
|
|
1122
1122
|
this.directUnverified = false;
|
|
1123
1123
|
const { hostname } = new URL(this.opts.baseUrl);
|
|
1124
1124
|
writeCache(hostname, {
|
|
@@ -1128,25 +1128,25 @@ var DohManager = class {
|
|
|
1128
1128
|
updatedAt: Date.now()
|
|
1129
1129
|
});
|
|
1130
1130
|
if (this.opts.verbose) {
|
|
1131
|
-
vlog("
|
|
1131
|
+
vlog("Pilot: direct connection succeeded, cached mode=direct");
|
|
1132
1132
|
}
|
|
1133
1133
|
}
|
|
1134
|
-
/** User-Agent for
|
|
1135
|
-
get
|
|
1134
|
+
/** User-Agent for Pilot proxy requests: OKX/@okx_ai/{packageName}/{version} */
|
|
1135
|
+
get pilotUserAgent() {
|
|
1136
1136
|
return `OKX/@okx_ai/${this.opts.packageUserAgent ?? "unknown"}`;
|
|
1137
1137
|
}
|
|
1138
1138
|
/**
|
|
1139
|
-
* Apply a
|
|
1139
|
+
* Apply a Pilot node: set up the custom Agent + base URL.
|
|
1140
1140
|
*
|
|
1141
1141
|
* node.ip may be a real IP or a domain (CNAME like *.aliyunddos1021.com).
|
|
1142
1142
|
* - Real IP → use directly in lookup callback
|
|
1143
1143
|
* - Domain → dns.lookup on every connection to get a fresh IP
|
|
1144
1144
|
*/
|
|
1145
1145
|
applyNode(node, protocol) {
|
|
1146
|
-
this.
|
|
1147
|
-
this.
|
|
1146
|
+
this.pilotNode = node;
|
|
1147
|
+
this.pilotBaseUrl = `${protocol}//${node.host}`;
|
|
1148
1148
|
const nodeIpIsRealIp = !!isIP(node.ip);
|
|
1149
|
-
this.
|
|
1149
|
+
this.pilotAgent = new Agent({
|
|
1150
1150
|
connect: {
|
|
1151
1151
|
lookup: (_hostname, options, callback) => {
|
|
1152
1152
|
if (nodeIpIsRealIp) {
|
|
@@ -1170,7 +1170,7 @@ var DohManager = class {
|
|
|
1170
1170
|
}
|
|
1171
1171
|
});
|
|
1172
1172
|
if (this.opts.verbose) {
|
|
1173
|
-
vlog(`
|
|
1173
|
+
vlog(`Pilot proxy active: \u2192 ${node.host} (${node.ip}), ttl=${node.ttl}s`);
|
|
1174
1174
|
}
|
|
1175
1175
|
}
|
|
1176
1176
|
};
|
|
@@ -1392,14 +1392,14 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1392
1392
|
config;
|
|
1393
1393
|
rateLimiter;
|
|
1394
1394
|
dispatcher;
|
|
1395
|
-
|
|
1395
|
+
pilot;
|
|
1396
1396
|
constructor(config) {
|
|
1397
1397
|
this.config = config;
|
|
1398
1398
|
this.rateLimiter = new RateLimiter(3e4, config.verbose);
|
|
1399
1399
|
if (config.proxyUrl) {
|
|
1400
1400
|
this.dispatcher = new ProxyAgent(config.proxyUrl);
|
|
1401
1401
|
}
|
|
1402
|
-
this.
|
|
1402
|
+
this.pilot = new PilotManager({
|
|
1403
1403
|
baseUrl: config.baseUrl,
|
|
1404
1404
|
packageUserAgent: config.userAgent,
|
|
1405
1405
|
verbose: config.verbose,
|
|
@@ -1582,12 +1582,12 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1582
1582
|
* Security: validates Content-Type and enforces maxBytes limit.
|
|
1583
1583
|
*/
|
|
1584
1584
|
async privatePostBinary(path42, body, opts) {
|
|
1585
|
-
this.
|
|
1585
|
+
this.pilot.preparePilot();
|
|
1586
1586
|
const maxBytes = opts?.maxBytes ?? _OkxRestClient.DEFAULT_MAX_BYTES;
|
|
1587
1587
|
const expectedCT = opts?.expectedContentType ?? "application/octet-stream";
|
|
1588
1588
|
const bodyJson = body ? JSON.stringify(body) : "";
|
|
1589
1589
|
const endpoint = `POST ${path42}`;
|
|
1590
|
-
const conn = this.
|
|
1590
|
+
const conn = this.pilot.getConnectionParams();
|
|
1591
1591
|
this.logRequest("POST", `${conn.baseUrl}${path42}`, "private");
|
|
1592
1592
|
const reqConfig = { method: "POST", path: path42, auth: "private" };
|
|
1593
1593
|
const headers = this.buildHeaders(reqConfig, path42, bodyJson, getNow());
|
|
@@ -1599,13 +1599,15 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1599
1599
|
try {
|
|
1600
1600
|
response = await this.fetchBinary(path42, endpoint, headers, bodyJson, t0);
|
|
1601
1601
|
} catch (error) {
|
|
1602
|
-
|
|
1603
|
-
|
|
1602
|
+
try {
|
|
1603
|
+
await this.pilot.handleNetworkFailure();
|
|
1604
|
+
} catch {
|
|
1605
|
+
}
|
|
1604
1606
|
throw error;
|
|
1605
1607
|
}
|
|
1606
1608
|
const elapsed = Date.now() - t0;
|
|
1607
1609
|
const traceId = extractTraceId(response.headers);
|
|
1608
|
-
this.
|
|
1610
|
+
this.pilot.cacheDirectIfNeeded();
|
|
1609
1611
|
if (!response.ok) {
|
|
1610
1612
|
const text = await response.text();
|
|
1611
1613
|
this.logResponse(response.status, text.length, elapsed, traceId, String(response.status));
|
|
@@ -1631,15 +1633,15 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1631
1633
|
/**
|
|
1632
1634
|
* Send an unauthenticated GET request and return the raw binary response.
|
|
1633
1635
|
* Used for pre-signed download URLs where auth is embedded in the token.
|
|
1634
|
-
* Inherits proxy, timeout,
|
|
1636
|
+
* Inherits proxy, timeout, Pilot, and verbose capabilities from the client.
|
|
1635
1637
|
*/
|
|
1636
1638
|
async publicGetBinary(path42, query, opts) {
|
|
1637
|
-
this.
|
|
1639
|
+
this.pilot.preparePilot();
|
|
1638
1640
|
const maxBytes = opts?.maxBytes ?? _OkxRestClient.DEFAULT_MAX_BYTES;
|
|
1639
1641
|
const expectedCT = opts?.expectedContentType ?? "application/octet-stream";
|
|
1640
1642
|
const queryString = buildQueryString(query);
|
|
1641
1643
|
const requestPath = queryString ? `${path42}?${queryString}` : path42;
|
|
1642
|
-
const conn = this.
|
|
1644
|
+
const conn = this.pilot.getConnectionParams();
|
|
1643
1645
|
const url = `${conn.baseUrl}${requestPath}`;
|
|
1644
1646
|
this.logRequest("GET", url, "public");
|
|
1645
1647
|
const headers = new Headers({ Accept: "application/octet-stream" });
|
|
@@ -1655,13 +1657,15 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1655
1657
|
dispatcher: this.dispatcher ?? conn.dispatcher
|
|
1656
1658
|
});
|
|
1657
1659
|
} catch (error) {
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
+
try {
|
|
1661
|
+
await this.pilot.handleNetworkFailure();
|
|
1662
|
+
} catch {
|
|
1663
|
+
}
|
|
1660
1664
|
throw new NetworkError(`Failed to call OKX endpoint GET ${path42}.`, `GET ${path42}`, error);
|
|
1661
1665
|
}
|
|
1662
1666
|
const elapsed = Date.now() - t0;
|
|
1663
1667
|
const traceId = extractTraceId(response.headers);
|
|
1664
|
-
this.
|
|
1668
|
+
this.pilot.cacheDirectIfNeeded();
|
|
1665
1669
|
if (!response.ok) {
|
|
1666
1670
|
const text = await response.text();
|
|
1667
1671
|
this.logResponse(response.status, text.length, elapsed, traceId, String(response.status));
|
|
@@ -1686,7 +1690,7 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1686
1690
|
}
|
|
1687
1691
|
/** Execute fetch for binary endpoint, wrapping network errors. */
|
|
1688
1692
|
async fetchBinary(path42, endpoint, headers, bodyJson, t0) {
|
|
1689
|
-
const conn = this.
|
|
1693
|
+
const conn = this.pilot.getConnectionParams();
|
|
1690
1694
|
try {
|
|
1691
1695
|
const fetchOptions = {
|
|
1692
1696
|
method: "POST",
|
|
@@ -1733,16 +1737,16 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1733
1737
|
// JSON request
|
|
1734
1738
|
// ---------------------------------------------------------------------------
|
|
1735
1739
|
/**
|
|
1736
|
-
* Handle network error during a JSON request: refresh
|
|
1740
|
+
* Handle network error during a JSON request: refresh Pilot and maybe retry.
|
|
1737
1741
|
* Always either returns a retry result or throws NetworkError.
|
|
1738
1742
|
*/
|
|
1739
1743
|
async handleRequestNetworkError(error, reqConfig, requestPath, t0) {
|
|
1740
|
-
if (!this.
|
|
1744
|
+
if (!this.pilot.hasRetried) {
|
|
1741
1745
|
if (this.config.verbose) {
|
|
1742
1746
|
const cause = error instanceof Error ? error.message : String(error);
|
|
1743
|
-
vlog2(`Network failure, refreshing
|
|
1747
|
+
vlog2(`Network failure, refreshing Pilot: ${cause}`);
|
|
1744
1748
|
}
|
|
1745
|
-
const shouldRetry = await this.
|
|
1749
|
+
const shouldRetry = await this.pilot.handleNetworkFailure();
|
|
1746
1750
|
if (shouldRetry && (reqConfig.method === "GET" || reqConfig.retryOnNetworkError)) {
|
|
1747
1751
|
return this.request(reqConfig);
|
|
1748
1752
|
}
|
|
@@ -1759,10 +1763,10 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1759
1763
|
);
|
|
1760
1764
|
}
|
|
1761
1765
|
async request(reqConfig) {
|
|
1762
|
-
this.
|
|
1766
|
+
this.pilot.preparePilot();
|
|
1763
1767
|
const queryString = buildQueryString(reqConfig.query);
|
|
1764
1768
|
const requestPath = queryString.length > 0 ? `${reqConfig.path}?${queryString}` : reqConfig.path;
|
|
1765
|
-
const conn = this.
|
|
1769
|
+
const conn = this.pilot.getConnectionParams();
|
|
1766
1770
|
const url = `${conn.baseUrl}${requestPath}`;
|
|
1767
1771
|
const bodyJson = reqConfig.body ? JSON.stringify(reqConfig.body) : "";
|
|
1768
1772
|
const timestamp = getNow();
|
|
@@ -1791,7 +1795,7 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1791
1795
|
const rawText = await response.text();
|
|
1792
1796
|
const elapsed = Date.now() - t0;
|
|
1793
1797
|
const traceId = extractTraceId(response.headers);
|
|
1794
|
-
this.
|
|
1798
|
+
this.pilot.cacheDirectIfNeeded();
|
|
1795
1799
|
return this.processResponse(rawText, response, elapsed, traceId, reqConfig, requestPath);
|
|
1796
1800
|
}
|
|
1797
1801
|
};
|
|
@@ -2248,7 +2252,7 @@ var MODULE_DESCRIPTIONS = {
|
|
|
2248
2252
|
bot: "Trading bot strategies (grid, dca)",
|
|
2249
2253
|
config: "Manage CLI configuration profiles",
|
|
2250
2254
|
setup: "Set up client integrations (Cursor, Windsurf, Claude, etc.)",
|
|
2251
|
-
|
|
2255
|
+
pilot: "Manage Pilot proxy resolver binary",
|
|
2252
2256
|
diagnose: "Run network / MCP server diagnostics",
|
|
2253
2257
|
upgrade: "Upgrade okx CLI and MCP server to the latest stable version",
|
|
2254
2258
|
skill: SKILLS_MARKETPLACE_DESC
|
|
@@ -2398,6 +2402,10 @@ function registerAccountTools() {
|
|
|
2398
2402
|
showValuation: {
|
|
2399
2403
|
type: "boolean",
|
|
2400
2404
|
description: "Include total asset valuation breakdown by account type (trading/funding/earn). Default false."
|
|
2405
|
+
},
|
|
2406
|
+
valuationCcy: {
|
|
2407
|
+
type: "string",
|
|
2408
|
+
description: "Currency used to denominate the total asset valuation (e.g. USDT, BTC). Default USDT. Only applies when showValuation=true."
|
|
2401
2409
|
}
|
|
2402
2410
|
}
|
|
2403
2411
|
},
|
|
@@ -2405,6 +2413,7 @@ function registerAccountTools() {
|
|
|
2405
2413
|
const args = asRecord(rawArgs);
|
|
2406
2414
|
const ccy = readString(args, "ccy");
|
|
2407
2415
|
const showValuation = readBoolean(args, "showValuation");
|
|
2416
|
+
const valuationCcy = readString(args, "valuationCcy") ?? "USDT";
|
|
2408
2417
|
if (showValuation) {
|
|
2409
2418
|
const balanceResp2 = await context.client.privateGet(
|
|
2410
2419
|
"/api/v5/asset/balances",
|
|
@@ -2412,16 +2421,26 @@ function registerAccountTools() {
|
|
|
2412
2421
|
privateRateLimit("account_get_asset_balance", 6)
|
|
2413
2422
|
);
|
|
2414
2423
|
let valuationData = null;
|
|
2424
|
+
let valuationError;
|
|
2415
2425
|
try {
|
|
2416
2426
|
const valuationResp = await context.client.privateGet(
|
|
2417
2427
|
"/api/v5/asset/asset-valuation",
|
|
2418
|
-
{},
|
|
2428
|
+
{ ccy: valuationCcy },
|
|
2419
2429
|
privateRateLimit("account_get_asset_valuation", 1)
|
|
2420
2430
|
);
|
|
2421
2431
|
valuationData = valuationResp.data;
|
|
2422
|
-
} catch {
|
|
2432
|
+
} catch (err) {
|
|
2433
|
+
valuationError = err instanceof Error ? err.message : String(err);
|
|
2423
2434
|
}
|
|
2424
|
-
|
|
2435
|
+
const valuationResult = {
|
|
2436
|
+
...normalizeResponse(balanceResp2),
|
|
2437
|
+
valuation: valuationData,
|
|
2438
|
+
valuationCcy
|
|
2439
|
+
};
|
|
2440
|
+
if (valuationError !== void 0) {
|
|
2441
|
+
valuationResult["valuationError"] = valuationError;
|
|
2442
|
+
}
|
|
2443
|
+
return valuationResult;
|
|
2425
2444
|
}
|
|
2426
2445
|
const balanceResp = await context.client.privateGet(
|
|
2427
2446
|
"/api/v5/asset/balances",
|
|
@@ -6557,9 +6576,9 @@ function registerEventContractTools() {
|
|
|
6557
6576
|
var PATH_LEADERBOARD = "/api/v5/orbit/public/leaderboard";
|
|
6558
6577
|
var PATH_POSITION_CURRENT = "/api/v5/orbit/public/position-current";
|
|
6559
6578
|
var PATH_TRADE_RECORDS = "/api/v5/orbit/public/trade-records";
|
|
6560
|
-
var PATH_OVERVIEW = "/api/v5/journal/
|
|
6561
|
-
var PATH_SIGNAL = "/api/v5/journal/
|
|
6562
|
-
var PATH_SIGNAL_HISTORY = "/api/v5/journal/
|
|
6579
|
+
var PATH_OVERVIEW = "/api/v5/journal/smartmoney/overview";
|
|
6580
|
+
var PATH_SIGNAL = "/api/v5/journal/smartmoney/signal";
|
|
6581
|
+
var PATH_SIGNAL_HISTORY = "/api/v5/journal/smartmoney/signal-history";
|
|
6563
6582
|
var SIGNAL_POOL_FILTER_PROPS = {
|
|
6564
6583
|
sortType: {
|
|
6565
6584
|
type: "string",
|
|
@@ -6629,23 +6648,6 @@ function extractLeaderboardData(data) {
|
|
|
6629
6648
|
}
|
|
6630
6649
|
return [];
|
|
6631
6650
|
}
|
|
6632
|
-
var SMARTMONEY_DEMO_MESSAGE = "Smart Money features are not available in demo/simulated trading mode.";
|
|
6633
|
-
var SMARTMONEY_DEMO_SUGGESTION = "Switch to a live profile to use Smart Money features.";
|
|
6634
|
-
function withSmartmoneyDemoGuard(tool) {
|
|
6635
|
-
const originalHandler = tool.handler;
|
|
6636
|
-
return {
|
|
6637
|
-
...tool,
|
|
6638
|
-
handler: async (args, context) => {
|
|
6639
|
-
if (context.config.demo) {
|
|
6640
|
-
throw new ConfigError(
|
|
6641
|
-
SMARTMONEY_DEMO_MESSAGE,
|
|
6642
|
-
SMARTMONEY_DEMO_SUGGESTION
|
|
6643
|
-
);
|
|
6644
|
-
}
|
|
6645
|
-
return originalHandler(args, context);
|
|
6646
|
-
}
|
|
6647
|
-
};
|
|
6648
|
-
}
|
|
6649
6651
|
function registerSmartmoneyTools() {
|
|
6650
6652
|
const tools = [
|
|
6651
6653
|
/* ---------- 1. Overview ---------- */
|
|
@@ -6799,11 +6801,11 @@ function registerSmartmoneyTools() {
|
|
|
6799
6801
|
},
|
|
6800
6802
|
granularity: {
|
|
6801
6803
|
type: "string",
|
|
6802
|
-
description: "1h or 1d"
|
|
6804
|
+
description: "1h or 1d (default 1h)"
|
|
6803
6805
|
},
|
|
6804
6806
|
limit: {
|
|
6805
6807
|
type: "string",
|
|
6806
|
-
description: "Data points 1-500"
|
|
6808
|
+
description: "Data points 1-500 (default 24)"
|
|
6807
6809
|
},
|
|
6808
6810
|
...SIGNAL_POOL_FILTER_PROPS
|
|
6809
6811
|
},
|
|
@@ -6947,7 +6949,7 @@ function registerSmartmoneyTools() {
|
|
|
6947
6949
|
}
|
|
6948
6950
|
}
|
|
6949
6951
|
];
|
|
6950
|
-
return tools
|
|
6952
|
+
return tools;
|
|
6951
6953
|
}
|
|
6952
6954
|
function buildContractTradeTools(cfg) {
|
|
6953
6955
|
const { prefix, module, label, instTypes, instIdExample } = cfg;
|
|
@@ -10745,18 +10747,20 @@ var CDN_SOURCES = [
|
|
|
10745
10747
|
{ host: "static.okx.com", protocol: "https" },
|
|
10746
10748
|
{ host: "static.coinall.ltd", protocol: "https" }
|
|
10747
10749
|
];
|
|
10748
|
-
var CDN_PATH_PREFIX = "/upgradeapp/
|
|
10750
|
+
var CDN_PATH_PREFIX = "/upgradeapp/tools/pilot";
|
|
10749
10751
|
var DOWNLOAD_TIMEOUT_MS = 3e4;
|
|
10752
|
+
var PLATFORM_MAP = {
|
|
10753
|
+
"darwin-arm64": "darwin-arm64",
|
|
10754
|
+
"darwin-x64": "darwin-x64",
|
|
10755
|
+
"linux-arm64": "linux-arm64",
|
|
10756
|
+
"linux-x64": "linux-x64",
|
|
10757
|
+
"win32-arm64": "win32-arm64",
|
|
10758
|
+
"win32-x64": "win32-x64"
|
|
10759
|
+
};
|
|
10750
10760
|
function getPlatformDir() {
|
|
10751
10761
|
const p = platform();
|
|
10752
10762
|
const a = arch();
|
|
10753
|
-
|
|
10754
|
-
"darwin-arm64": "darwin-arm64",
|
|
10755
|
-
"darwin-x64": "darwin-x64",
|
|
10756
|
-
"linux-x64": "linux-x64",
|
|
10757
|
-
"win32-x64": "win32-x64"
|
|
10758
|
-
};
|
|
10759
|
-
return map[`${p}-${a}`] ?? null;
|
|
10763
|
+
return PLATFORM_MAP[`${p}-${a}`] ?? null;
|
|
10760
10764
|
}
|
|
10761
10765
|
function getBinaryName() {
|
|
10762
10766
|
return platform() === "win32" ? "okx-pilot.exe" : "okx-pilot";
|
|
@@ -10768,8 +10772,8 @@ function hashFile(filePath) {
|
|
|
10768
10772
|
sha256: createHash("sha256").update(buf).digest("hex")
|
|
10769
10773
|
};
|
|
10770
10774
|
}
|
|
10771
|
-
function
|
|
10772
|
-
const resolvedPath = binaryPath ??
|
|
10775
|
+
function getPilotStatus(binaryPath, opts) {
|
|
10776
|
+
const resolvedPath = binaryPath ?? getPilotBinaryPath();
|
|
10773
10777
|
const platformDir = getPlatformDir();
|
|
10774
10778
|
if (!existsSync6(resolvedPath)) {
|
|
10775
10779
|
return {
|
|
@@ -10861,7 +10865,7 @@ function atomicReplace(tmpPath, resolvedDest) {
|
|
|
10861
10865
|
}
|
|
10862
10866
|
}
|
|
10863
10867
|
function installPreChecks(destPath, sources) {
|
|
10864
|
-
if (!destPath && process.env.
|
|
10868
|
+
if (!destPath && process.env.OKX_PILOT_BINARY_PATH) {
|
|
10865
10869
|
return { status: "up-to-date", source: "(env override)" };
|
|
10866
10870
|
}
|
|
10867
10871
|
if (!getPlatformDir()) {
|
|
@@ -10875,7 +10879,7 @@ function installPreChecks(destPath, sources) {
|
|
|
10875
10879
|
function isLocalUpToDate(localHash, checksum) {
|
|
10876
10880
|
return localHash !== null && localHash.size === checksum.size && localHash.sha256 === checksum.sha256;
|
|
10877
10881
|
}
|
|
10878
|
-
async function
|
|
10882
|
+
async function installPilotBinary(destPath, sources = CDN_SOURCES, onProgress) {
|
|
10879
10883
|
const earlyResult = installPreChecks(destPath, sources);
|
|
10880
10884
|
if (earlyResult) return earlyResult;
|
|
10881
10885
|
const platformDir = getPlatformDir();
|
|
@@ -10918,8 +10922,8 @@ async function installDohBinary(destPath, sources = CDN_SOURCES, onProgress) {
|
|
|
10918
10922
|
return { status: "failed", error: `All CDN sources failed:
|
|
10919
10923
|
${errors.join("\n")}` };
|
|
10920
10924
|
}
|
|
10921
|
-
function
|
|
10922
|
-
const resolvedPath = binaryPath ??
|
|
10925
|
+
function removePilotBinary(binaryPath) {
|
|
10926
|
+
const resolvedPath = binaryPath ?? getPilotBinaryPath();
|
|
10923
10927
|
try {
|
|
10924
10928
|
unlinkSync3(resolvedPath);
|
|
10925
10929
|
return { status: "removed" };
|
|
@@ -11642,7 +11646,7 @@ async function cmdDiagnoseMcp(options = {}) {
|
|
|
11642
11646
|
|
|
11643
11647
|
// src/commands/diagnose.ts
|
|
11644
11648
|
var CLI_VERSION = readCliVersion();
|
|
11645
|
-
var GIT_HASH = true ? "
|
|
11649
|
+
var GIT_HASH = true ? "330e727a" : "dev";
|
|
11646
11650
|
function maskKey2(key) {
|
|
11647
11651
|
if (!key) return "(not set)";
|
|
11648
11652
|
if (key.length <= 8) return "****";
|
|
@@ -11884,42 +11888,42 @@ async function cmdDiagnose(config, profile, options = {}) {
|
|
|
11884
11888
|
}
|
|
11885
11889
|
return runCliChecks(config, profile, options.output);
|
|
11886
11890
|
}
|
|
11887
|
-
async function
|
|
11888
|
-
section("
|
|
11889
|
-
const local =
|
|
11891
|
+
async function checkPilot(report) {
|
|
11892
|
+
section("Pilot");
|
|
11893
|
+
const local = getPilotStatus();
|
|
11890
11894
|
if (!local.exists) {
|
|
11891
|
-
fail("
|
|
11892
|
-
"Run: okx
|
|
11895
|
+
fail("Pilot binary", "not installed", [
|
|
11896
|
+
"Run: okx pilot install",
|
|
11893
11897
|
"Or wait for the next npm install to auto-download"
|
|
11894
11898
|
]);
|
|
11895
|
-
report.add("
|
|
11899
|
+
report.add("pilot_binary", "not installed");
|
|
11896
11900
|
return;
|
|
11897
11901
|
}
|
|
11898
|
-
ok("
|
|
11899
|
-
report.add("
|
|
11902
|
+
ok("Pilot binary", local.binaryPath);
|
|
11903
|
+
report.add("pilot_binary", `installed (${local.platform ?? "unknown"})`);
|
|
11900
11904
|
const cdnChecksum = await fetchCdnChecksum(void 0, 5e3);
|
|
11901
11905
|
if (!cdnChecksum) {
|
|
11902
|
-
warn("
|
|
11903
|
-
report.add("
|
|
11906
|
+
warn("Pilot checksum", "CDN unreachable \u2014 cannot verify");
|
|
11907
|
+
report.add("pilot_checksum", "CDN unreachable");
|
|
11904
11908
|
} else if (cdnChecksum.sha256 === local.sha256) {
|
|
11905
|
-
ok("
|
|
11906
|
-
report.add("
|
|
11909
|
+
ok("Pilot checksum", `match (${cdnChecksum.source})`);
|
|
11910
|
+
report.add("pilot_checksum", `match (${cdnChecksum.source})`);
|
|
11907
11911
|
} else {
|
|
11908
|
-
warn("
|
|
11909
|
-
report.add("
|
|
11912
|
+
warn("Pilot checksum", "mismatch \u2014 update available", ["Run: okx pilot install"]);
|
|
11913
|
+
report.add("pilot_checksum", "mismatch");
|
|
11910
11914
|
}
|
|
11911
11915
|
try {
|
|
11912
11916
|
const cacheEntry = readCache("www.okx.com");
|
|
11913
11917
|
if (cacheEntry) {
|
|
11914
|
-
ok("
|
|
11915
|
-
report.add("
|
|
11918
|
+
ok("Pilot mode", cacheEntry.mode);
|
|
11919
|
+
report.add("pilot_mode", cacheEntry.mode);
|
|
11916
11920
|
} else {
|
|
11917
|
-
ok("
|
|
11918
|
-
report.add("
|
|
11921
|
+
ok("Pilot mode", "no cache (will auto-detect on next request)");
|
|
11922
|
+
report.add("pilot_mode", "no cache");
|
|
11919
11923
|
}
|
|
11920
11924
|
} catch {
|
|
11921
|
-
ok("
|
|
11922
|
-
report.add("
|
|
11925
|
+
ok("Pilot mode", "no cache");
|
|
11926
|
+
report.add("pilot_mode", "no cache");
|
|
11923
11927
|
}
|
|
11924
11928
|
}
|
|
11925
11929
|
function checkConfigFile(report) {
|
|
@@ -11950,7 +11954,7 @@ async function runCliChecks(config, profile, outputPath) {
|
|
|
11950
11954
|
report.add("ts", (/* @__PURE__ */ new Date()).toISOString());
|
|
11951
11955
|
const configFilePassed = checkConfigFile(report);
|
|
11952
11956
|
const envPassed = checkEnvironment(report);
|
|
11953
|
-
await
|
|
11957
|
+
await checkPilot(report);
|
|
11954
11958
|
if (!config) {
|
|
11955
11959
|
fail("Config", "Could not load config (see Config File check above)", []);
|
|
11956
11960
|
report.add("result", "FAIL");
|
|
@@ -11976,6 +11980,31 @@ async function runCliChecks(config, profile, outputPath) {
|
|
|
11976
11980
|
writeReportIfRequested(report, outputPath);
|
|
11977
11981
|
}
|
|
11978
11982
|
|
|
11983
|
+
// src/unknown-command.ts
|
|
11984
|
+
function unknownSubcommand(module, action, knownActions) {
|
|
11985
|
+
const actionStr = action ?? "(missing)";
|
|
11986
|
+
errorLine(`Unknown command: okx ${module} ${actionStr}`);
|
|
11987
|
+
const hint = suggestSubcommand(action, knownActions);
|
|
11988
|
+
if (hint) {
|
|
11989
|
+
errorLine(` Did you mean: okx ${module} ${hint} ?`);
|
|
11990
|
+
}
|
|
11991
|
+
if (knownActions.length > 0) {
|
|
11992
|
+
errorLine(` Available subcommands: ${knownActions.join(", ")}`);
|
|
11993
|
+
}
|
|
11994
|
+
errorLine(` Run 'okx ${module} --help' for full usage.`);
|
|
11995
|
+
process.exitCode = 1;
|
|
11996
|
+
}
|
|
11997
|
+
function suggestSubcommand(action, knownActions) {
|
|
11998
|
+
if (!action || !action.includes("-")) return void 0;
|
|
11999
|
+
const parts = action.split("-");
|
|
12000
|
+
if (parts.length !== 2) return void 0;
|
|
12001
|
+
const [a, b] = parts;
|
|
12002
|
+
if (knownActions.includes(b)) {
|
|
12003
|
+
return `${b} ${a}`;
|
|
12004
|
+
}
|
|
12005
|
+
return void 0;
|
|
12006
|
+
}
|
|
12007
|
+
|
|
11979
12008
|
// src/commands/upgrade.ts
|
|
11980
12009
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
11981
12010
|
import { readFileSync as readFileSync8, writeFileSync as writeFileSync7, mkdirSync as mkdirSync9 } from "fs";
|
|
@@ -12981,24 +13010,24 @@ var CLI_REGISTRY = {
|
|
|
12981
13010
|
description: "Set up client integrations (Cursor, Windsurf, Claude, etc.)",
|
|
12982
13011
|
usage: `okx setup --client <${SUPPORTED_CLIENTS.join("|")}> [--profile <name>] [--modules <list>]`
|
|
12983
13012
|
},
|
|
12984
|
-
// ──
|
|
12985
|
-
|
|
12986
|
-
description: "Manage
|
|
13013
|
+
// ── pilot ──────────────────────────────────────────────────────────────────
|
|
13014
|
+
pilot: {
|
|
13015
|
+
description: "Manage Pilot proxy resolver binary",
|
|
12987
13016
|
commands: {
|
|
12988
13017
|
status: {
|
|
12989
13018
|
toolName: null,
|
|
12990
|
-
usage: "okx
|
|
12991
|
-
description: "Show
|
|
13019
|
+
usage: "okx pilot status [--json]",
|
|
13020
|
+
description: "Show Pilot binary info, checksum, and CDN match status"
|
|
12992
13021
|
},
|
|
12993
13022
|
install: {
|
|
12994
13023
|
toolName: null,
|
|
12995
|
-
usage: "okx
|
|
12996
|
-
description: "Download or update the
|
|
13024
|
+
usage: "okx pilot install [--json]",
|
|
13025
|
+
description: "Download or update the Pilot binary"
|
|
12997
13026
|
},
|
|
12998
13027
|
remove: {
|
|
12999
13028
|
toolName: null,
|
|
13000
|
-
usage: "okx
|
|
13001
|
-
description: "Remove the
|
|
13029
|
+
usage: "okx pilot remove [--force] [--json]",
|
|
13030
|
+
description: "Remove the Pilot binary (prompts for confirmation without --force)"
|
|
13002
13031
|
}
|
|
13003
13032
|
}
|
|
13004
13033
|
},
|
|
@@ -13685,6 +13714,7 @@ var CLI_OPTIONS = {
|
|
|
13685
13714
|
// account extras
|
|
13686
13715
|
archive: { type: "boolean", default: false },
|
|
13687
13716
|
valuation: { type: "boolean", default: false },
|
|
13717
|
+
valuationCcy: { type: "string" },
|
|
13688
13718
|
posMode: { type: "string" },
|
|
13689
13719
|
ccy: { type: "string" },
|
|
13690
13720
|
from: { type: "string" },
|
|
@@ -14217,12 +14247,13 @@ async function cmdMarketOiHistory(run, instId, opts) {
|
|
|
14217
14247
|
});
|
|
14218
14248
|
const data = getData2(result);
|
|
14219
14249
|
if (opts.json) return printJson(data);
|
|
14220
|
-
const
|
|
14250
|
+
const entry = Array.isArray(data) ? data[0] : data;
|
|
14251
|
+
const rows = entry?.["rows"] ?? [];
|
|
14221
14252
|
if (!rows.length) {
|
|
14222
14253
|
outputLine("No OI data");
|
|
14223
14254
|
return;
|
|
14224
14255
|
}
|
|
14225
|
-
outputLine(`${
|
|
14256
|
+
outputLine(`${entry?.["instId"] ?? instId} bar=${entry?.["bar"] ?? opts.bar ?? "1H"}`);
|
|
14226
14257
|
printTable(
|
|
14227
14258
|
rows.map((r) => ({
|
|
14228
14259
|
ts: new Date(Number(r["ts"])).toLocaleString(),
|
|
@@ -14288,13 +14319,14 @@ async function cmdAccountBalance(run, ccy, json) {
|
|
|
14288
14319
|
}
|
|
14289
14320
|
printTable(rows);
|
|
14290
14321
|
}
|
|
14291
|
-
async function cmdAccountAssetBalance(run, ccy, json, showValuation) {
|
|
14322
|
+
async function cmdAccountAssetBalance(run, ccy, json, showValuation, valuationCcy) {
|
|
14292
14323
|
const result = await run("account_get_asset_balance", {
|
|
14293
14324
|
ccy,
|
|
14294
|
-
...showValuation ? { showValuation: true } : {}
|
|
14325
|
+
...showValuation ? { showValuation: true } : {},
|
|
14326
|
+
...valuationCcy !== void 0 ? { valuationCcy } : {}
|
|
14295
14327
|
});
|
|
14296
14328
|
const data = result.data ?? [];
|
|
14297
|
-
if (json) return printJson(showValuation ? { data, valuation: result.valuation } : data);
|
|
14329
|
+
if (json) return printJson(showValuation ? { data, valuation: result.valuation, valuationCcy: result.valuationCcy } : data);
|
|
14298
14330
|
const assetRows = data.filter((r) => Number(r["bal"]) > 0).map((r) => ({
|
|
14299
14331
|
ccy: r["ccy"],
|
|
14300
14332
|
bal: r["bal"],
|
|
@@ -14309,7 +14341,7 @@ async function cmdAccountAssetBalance(run, ccy, json, showValuation) {
|
|
|
14309
14341
|
if (showValuation && result.valuation) {
|
|
14310
14342
|
const valuationData = result.valuation ?? [];
|
|
14311
14343
|
outputLine("");
|
|
14312
|
-
outputLine(
|
|
14344
|
+
outputLine(`Asset Valuation by Account Type (${String(result.valuationCcy ?? "USDT")}):`);
|
|
14313
14345
|
printTable(
|
|
14314
14346
|
valuationData.map((v) => {
|
|
14315
14347
|
const details = v["details"] ?? {};
|
|
@@ -17205,7 +17237,7 @@ function printSkillInstallResult(meta, json) {
|
|
|
17205
17237
|
}
|
|
17206
17238
|
}
|
|
17207
17239
|
|
|
17208
|
-
// src/commands/
|
|
17240
|
+
// src/commands/pilot.ts
|
|
17209
17241
|
import readline from "readline";
|
|
17210
17242
|
function resolveChecksumMatch(local, cdnChecksum, cdnError) {
|
|
17211
17243
|
if (!local.exists) return "not-installed";
|
|
@@ -17220,7 +17252,7 @@ function checksumMatchLabel(match) {
|
|
|
17220
17252
|
}
|
|
17221
17253
|
function formatStatusText(local, checksumMatch, cdnChecksum, runtimeMode) {
|
|
17222
17254
|
outputLine("");
|
|
17223
|
-
outputLine("
|
|
17255
|
+
outputLine(" Pilot Status");
|
|
17224
17256
|
outputLine(" " + "\u2500".repeat(40));
|
|
17225
17257
|
outputLine(` Binary path : ${local.binaryPath}`);
|
|
17226
17258
|
outputLine(` Installed : ${local.exists ? "yes" : "no"}`);
|
|
@@ -17236,8 +17268,8 @@ function formatStatusText(local, checksumMatch, cdnChecksum, runtimeMode) {
|
|
|
17236
17268
|
outputLine(` Runtime mode: ${runtimeMode}`);
|
|
17237
17269
|
outputLine("");
|
|
17238
17270
|
}
|
|
17239
|
-
async function
|
|
17240
|
-
const local =
|
|
17271
|
+
async function cmdPilotStatus(json, binaryPath) {
|
|
17272
|
+
const local = getPilotStatus(binaryPath);
|
|
17241
17273
|
let runtimeMode = "no cache";
|
|
17242
17274
|
try {
|
|
17243
17275
|
const cacheEntry = readCache("www.okx.com");
|
|
@@ -17274,7 +17306,7 @@ async function cmdDohStatus(json, binaryPath) {
|
|
|
17274
17306
|
}
|
|
17275
17307
|
formatStatusText(local, checksumMatch, cdnChecksum, runtimeMode);
|
|
17276
17308
|
}
|
|
17277
|
-
async function
|
|
17309
|
+
async function cmdPilotInstall(json, binaryPath) {
|
|
17278
17310
|
const messages2 = [];
|
|
17279
17311
|
const onProgress = (msg) => {
|
|
17280
17312
|
if (!json) {
|
|
@@ -17284,9 +17316,9 @@ async function cmdDohInstall(json, binaryPath) {
|
|
|
17284
17316
|
};
|
|
17285
17317
|
if (!json) {
|
|
17286
17318
|
outputLine("");
|
|
17287
|
-
outputLine(" Installing
|
|
17319
|
+
outputLine(" Installing Pilot...");
|
|
17288
17320
|
}
|
|
17289
|
-
const result = await
|
|
17321
|
+
const result = await installPilotBinary(binaryPath, void 0, onProgress);
|
|
17290
17322
|
if (json) {
|
|
17291
17323
|
outputLine(JSON.stringify({ status: result.status, source: result.source ?? null, error: result.error ?? null, messages: messages2 }));
|
|
17292
17324
|
if (result.status === "failed") {
|
|
@@ -17295,9 +17327,9 @@ async function cmdDohInstall(json, binaryPath) {
|
|
|
17295
17327
|
return;
|
|
17296
17328
|
}
|
|
17297
17329
|
if (result.status === "installed") {
|
|
17298
|
-
outputLine(` \u2713
|
|
17330
|
+
outputLine(` \u2713 Pilot installed successfully (${result.source ?? ""})`);
|
|
17299
17331
|
} else if (result.status === "up-to-date") {
|
|
17300
|
-
outputLine(" \u2713
|
|
17332
|
+
outputLine(" \u2713 Pilot is already up to date");
|
|
17301
17333
|
} else {
|
|
17302
17334
|
errorLine(` \u2717 Installation failed: ${result.error ?? "unknown error"}`);
|
|
17303
17335
|
errorLine(" Hint: check network connectivity or try again later");
|
|
@@ -17305,13 +17337,13 @@ async function cmdDohInstall(json, binaryPath) {
|
|
|
17305
17337
|
}
|
|
17306
17338
|
outputLine("");
|
|
17307
17339
|
}
|
|
17308
|
-
async function
|
|
17309
|
-
const local =
|
|
17340
|
+
async function cmdPilotRemove(force, json, binaryPath) {
|
|
17341
|
+
const local = getPilotStatus(binaryPath);
|
|
17310
17342
|
if (!local.exists) {
|
|
17311
17343
|
if (json) {
|
|
17312
17344
|
outputLine(JSON.stringify({ status: "not-installed" }));
|
|
17313
17345
|
} else {
|
|
17314
|
-
outputLine("
|
|
17346
|
+
outputLine(" Pilot is not installed.");
|
|
17315
17347
|
}
|
|
17316
17348
|
return;
|
|
17317
17349
|
}
|
|
@@ -17322,14 +17354,14 @@ async function cmdDohRemove(force, json, binaryPath) {
|
|
|
17322
17354
|
return;
|
|
17323
17355
|
}
|
|
17324
17356
|
const confirmed = await askConfirmation(
|
|
17325
|
-
` Remove
|
|
17357
|
+
` Remove Pilot at ${local.binaryPath}? [y/N] `
|
|
17326
17358
|
);
|
|
17327
17359
|
if (!confirmed) {
|
|
17328
17360
|
outputLine(" Cancelled.");
|
|
17329
17361
|
return;
|
|
17330
17362
|
}
|
|
17331
17363
|
}
|
|
17332
|
-
const result =
|
|
17364
|
+
const result = removePilotBinary(binaryPath);
|
|
17333
17365
|
if (json) {
|
|
17334
17366
|
outputLine(JSON.stringify({ status: result.status, path: local.binaryPath }));
|
|
17335
17367
|
return;
|
|
@@ -17337,7 +17369,7 @@ async function cmdDohRemove(force, json, binaryPath) {
|
|
|
17337
17369
|
if (result.status === "removed") {
|
|
17338
17370
|
outputLine(` \u2713 Removed: ${local.binaryPath}`);
|
|
17339
17371
|
} else {
|
|
17340
|
-
outputLine("
|
|
17372
|
+
outputLine(" Pilot is not installed.");
|
|
17341
17373
|
}
|
|
17342
17374
|
}
|
|
17343
17375
|
function formatBytes(bytes) {
|
|
@@ -17804,13 +17836,13 @@ async function cmdEventCancel(run, opts) {
|
|
|
17804
17836
|
// src/index.ts
|
|
17805
17837
|
var _require3 = createRequire3(import.meta.url);
|
|
17806
17838
|
var CLI_VERSION2 = _require3("../package.json").version;
|
|
17807
|
-
var GIT_HASH2 = true ? "
|
|
17808
|
-
function
|
|
17809
|
-
if (action === "status") return
|
|
17810
|
-
if (action === "install") return
|
|
17811
|
-
if (action === "remove") return
|
|
17812
|
-
errorLine(`Unknown
|
|
17813
|
-
errorLine("Usage: okx
|
|
17839
|
+
var GIT_HASH2 = true ? "330e727a" : "dev";
|
|
17840
|
+
function handlePilotCommand(action, json, force, binaryPath) {
|
|
17841
|
+
if (action === "status") return cmdPilotStatus(json, binaryPath);
|
|
17842
|
+
if (action === "install") return cmdPilotInstall(json, binaryPath);
|
|
17843
|
+
if (action === "remove") return cmdPilotRemove(force, json, binaryPath);
|
|
17844
|
+
errorLine(`Unknown pilot command: ${action}`);
|
|
17845
|
+
errorLine("Usage: okx pilot <status|install|remove>");
|
|
17814
17846
|
process.exitCode = 1;
|
|
17815
17847
|
}
|
|
17816
17848
|
function handleConfigCommand(action, rest, json, lang, force) {
|
|
@@ -17909,9 +17941,6 @@ function handleMarketFilterCommand(run, action, rest, v, json) {
|
|
|
17909
17941
|
limit,
|
|
17910
17942
|
json
|
|
17911
17943
|
});
|
|
17912
|
-
errorLine(`Unknown market command: ${action}`);
|
|
17913
|
-
errorLine("Valid: ticker, tickers, orderbook, candles, trades, instruments, mark-price, funding-rate, open-interest, index-ticker, price-limit, stock-tokens, instruments-by-category, indicator, filter, oi-history, oi-change");
|
|
17914
|
-
process.exitCode = 1;
|
|
17915
17944
|
}
|
|
17916
17945
|
function handleIndicatorAction(run, rest, v, json) {
|
|
17917
17946
|
if (rest[0] === "list") return cmdMarketIndicatorList(json);
|
|
@@ -17940,7 +17969,28 @@ function handleMarketDataCommand(run, action, rest, v, json) {
|
|
|
17940
17969
|
return cmdMarketIndexCandles(run, rest[0], { bar: v.bar, limit, history: v.history ?? false, json, demo: v.demo });
|
|
17941
17970
|
}
|
|
17942
17971
|
function handleMarketCommand(run, action, rest, v, json) {
|
|
17943
|
-
|
|
17972
|
+
const result = handleMarketPublicCommand(run, action, rest, v, json) ?? handleMarketDataCommand(run, action, rest, v, json);
|
|
17973
|
+
if (result !== void 0) return result;
|
|
17974
|
+
unknownSubcommand("market", action, [
|
|
17975
|
+
"ticker",
|
|
17976
|
+
"tickers",
|
|
17977
|
+
"orderbook",
|
|
17978
|
+
"candles",
|
|
17979
|
+
"trades",
|
|
17980
|
+
"instruments",
|
|
17981
|
+
"mark-price",
|
|
17982
|
+
"funding-rate",
|
|
17983
|
+
"open-interest",
|
|
17984
|
+
"index-ticker",
|
|
17985
|
+
"price-limit",
|
|
17986
|
+
"stock-tokens",
|
|
17987
|
+
"instruments-by-category",
|
|
17988
|
+
"indicator",
|
|
17989
|
+
"filter",
|
|
17990
|
+
"oi-history",
|
|
17991
|
+
"oi-change",
|
|
17992
|
+
"index-candles"
|
|
17993
|
+
]);
|
|
17944
17994
|
}
|
|
17945
17995
|
function handleAccountWriteCommand(run, action, v, json) {
|
|
17946
17996
|
if (action === "set-position-mode")
|
|
@@ -17960,13 +18010,28 @@ function handleAccountWriteCommand(run, action, v, json) {
|
|
|
17960
18010
|
subAcct: v.subAcct,
|
|
17961
18011
|
json
|
|
17962
18012
|
});
|
|
18013
|
+
unknownSubcommand("account", action, [
|
|
18014
|
+
"audit",
|
|
18015
|
+
"balance",
|
|
18016
|
+
"asset-balance",
|
|
18017
|
+
"positions",
|
|
18018
|
+
"positions-history",
|
|
18019
|
+
"bills",
|
|
18020
|
+
"fees",
|
|
18021
|
+
"config",
|
|
18022
|
+
"set-position-mode",
|
|
18023
|
+
"max-size",
|
|
18024
|
+
"max-avail-size",
|
|
18025
|
+
"max-withdrawal",
|
|
18026
|
+
"transfer"
|
|
18027
|
+
]);
|
|
17963
18028
|
}
|
|
17964
18029
|
function handleAccountCommand(run, action, rest, v, json) {
|
|
17965
18030
|
if (action === "audit")
|
|
17966
18031
|
return cmdAccountAudit({ limit: v.limit, tool: v.tool, since: v.since, json });
|
|
17967
18032
|
const limit = v.limit !== void 0 ? Number(v.limit) : void 0;
|
|
17968
18033
|
if (action === "balance") return cmdAccountBalance(run, rest[0], json);
|
|
17969
|
-
if (action === "asset-balance") return cmdAccountAssetBalance(run, v.ccy, json, v.valuation);
|
|
18034
|
+
if (action === "asset-balance") return cmdAccountAssetBalance(run, v.ccy, json, v.valuation, v.valuationCcy);
|
|
17970
18035
|
if (action === "positions")
|
|
17971
18036
|
return cmdAccountPositions(run, { instType: v.instType, instId: v.instId, json });
|
|
17972
18037
|
if (action === "positions-history")
|
|
@@ -18039,6 +18104,7 @@ function handleSpotAlgoCommand(run, subAction, v, json) {
|
|
|
18039
18104
|
ordType: v.ordType,
|
|
18040
18105
|
json
|
|
18041
18106
|
});
|
|
18107
|
+
unknownSubcommand("spot algo", subAction, ["trail", "place", "amend", "cancel", "orders"]);
|
|
18042
18108
|
}
|
|
18043
18109
|
function handleSpotCommand(run, action, rest, v, json) {
|
|
18044
18110
|
if (action === "orders")
|
|
@@ -18090,6 +18156,17 @@ function handleSpotCommand(run, action, rest, v, json) {
|
|
|
18090
18156
|
mgnMode: v.mgnMode,
|
|
18091
18157
|
json
|
|
18092
18158
|
});
|
|
18159
|
+
unknownSubcommand("spot", action, [
|
|
18160
|
+
"orders",
|
|
18161
|
+
"get",
|
|
18162
|
+
"fills",
|
|
18163
|
+
"place",
|
|
18164
|
+
"cancel",
|
|
18165
|
+
"amend",
|
|
18166
|
+
"algo",
|
|
18167
|
+
"batch",
|
|
18168
|
+
"leverage"
|
|
18169
|
+
]);
|
|
18093
18170
|
}
|
|
18094
18171
|
function handleSwapAlgoCommand(run, subAction, v, json) {
|
|
18095
18172
|
if (subAction === "trail")
|
|
@@ -18145,6 +18222,7 @@ function handleSwapAlgoCommand(run, subAction, v, json) {
|
|
|
18145
18222
|
ordType: v.ordType,
|
|
18146
18223
|
json
|
|
18147
18224
|
});
|
|
18225
|
+
unknownSubcommand("swap algo", subAction, ["trail", "place", "amend", "cancel", "orders"]);
|
|
18148
18226
|
}
|
|
18149
18227
|
function handleSwapQuery(run, action, rest, v, json) {
|
|
18150
18228
|
if (action === "positions")
|
|
@@ -18220,6 +18298,20 @@ function handleSwapCommand(run, action, rest, v, json) {
|
|
|
18220
18298
|
return handleSwapAlgoCommand(run, rest[0], v, json);
|
|
18221
18299
|
if (action === "batch")
|
|
18222
18300
|
return cmdSwapBatch(run, { action: v.action, orders: v.orders, json });
|
|
18301
|
+
unknownSubcommand("swap", action, [
|
|
18302
|
+
"positions",
|
|
18303
|
+
"orders",
|
|
18304
|
+
"get",
|
|
18305
|
+
"fills",
|
|
18306
|
+
"get-leverage",
|
|
18307
|
+
"place",
|
|
18308
|
+
"cancel",
|
|
18309
|
+
"amend",
|
|
18310
|
+
"close",
|
|
18311
|
+
"leverage",
|
|
18312
|
+
"algo",
|
|
18313
|
+
"batch"
|
|
18314
|
+
]);
|
|
18223
18315
|
}
|
|
18224
18316
|
function handleOptionAlgoCommand(run, subAction, v, json) {
|
|
18225
18317
|
if (subAction === "place")
|
|
@@ -18258,6 +18350,7 @@ function handleOptionAlgoCommand(run, subAction, v, json) {
|
|
|
18258
18350
|
ordType: v.ordType,
|
|
18259
18351
|
json
|
|
18260
18352
|
});
|
|
18353
|
+
unknownSubcommand("option algo", subAction, ["place", "amend", "cancel", "orders"]);
|
|
18261
18354
|
}
|
|
18262
18355
|
function handleOptionCommand(run, action, rest, v, json) {
|
|
18263
18356
|
if (action === "orders") {
|
|
@@ -18308,6 +18401,19 @@ function handleOptionCommand(run, action, rest, v, json) {
|
|
|
18308
18401
|
return cmdOptionBatchCancel(run, { orders: v.orders, json });
|
|
18309
18402
|
if (action === "algo")
|
|
18310
18403
|
return handleOptionAlgoCommand(run, rest[0], v, json);
|
|
18404
|
+
unknownSubcommand("option", action, [
|
|
18405
|
+
"orders",
|
|
18406
|
+
"get",
|
|
18407
|
+
"positions",
|
|
18408
|
+
"fills",
|
|
18409
|
+
"instruments",
|
|
18410
|
+
"greeks",
|
|
18411
|
+
"place",
|
|
18412
|
+
"cancel",
|
|
18413
|
+
"amend",
|
|
18414
|
+
"batch-cancel",
|
|
18415
|
+
"algo"
|
|
18416
|
+
]);
|
|
18311
18417
|
}
|
|
18312
18418
|
function handleFuturesAlgoCommand(run, subAction, v, json) {
|
|
18313
18419
|
if (subAction === "trail")
|
|
@@ -18363,6 +18469,7 @@ function handleFuturesAlgoCommand(run, subAction, v, json) {
|
|
|
18363
18469
|
ordType: v.ordType,
|
|
18364
18470
|
json
|
|
18365
18471
|
});
|
|
18472
|
+
unknownSubcommand("futures algo", subAction, ["trail", "place", "amend", "cancel", "orders"]);
|
|
18366
18473
|
}
|
|
18367
18474
|
function resolveFuturesOrdersStatus(v) {
|
|
18368
18475
|
if (v.archive) return "archive";
|
|
@@ -18438,6 +18545,20 @@ function handleFuturesCommand(run, action, rest, v, json) {
|
|
|
18438
18545
|
return cmdFuturesBatch(run, { action: v.action, orders: v.orders, json });
|
|
18439
18546
|
if (action === "algo")
|
|
18440
18547
|
return handleFuturesAlgoCommand(run, rest[0], v, json);
|
|
18548
|
+
unknownSubcommand("futures", action, [
|
|
18549
|
+
"orders",
|
|
18550
|
+
"positions",
|
|
18551
|
+
"fills",
|
|
18552
|
+
"get",
|
|
18553
|
+
"get-leverage",
|
|
18554
|
+
"place",
|
|
18555
|
+
"cancel",
|
|
18556
|
+
"amend",
|
|
18557
|
+
"close",
|
|
18558
|
+
"leverage",
|
|
18559
|
+
"batch",
|
|
18560
|
+
"algo"
|
|
18561
|
+
]);
|
|
18441
18562
|
}
|
|
18442
18563
|
function handleBotGridCommand(run, v, rest, json) {
|
|
18443
18564
|
const subAction = rest[0];
|
|
@@ -18505,6 +18626,7 @@ function handleBotGridCommand(run, v, rest, json) {
|
|
|
18505
18626
|
stopType: v.stopType,
|
|
18506
18627
|
json
|
|
18507
18628
|
});
|
|
18629
|
+
unknownSubcommand("bot grid", subAction, ["orders", "details", "sub-orders", "create", "amend", "stop"]);
|
|
18508
18630
|
}
|
|
18509
18631
|
function handleBotDcaCommand(run, subAction, v, json) {
|
|
18510
18632
|
const algoOrdType = v.algoOrdType ?? "contract_dca";
|
|
@@ -18543,10 +18665,12 @@ function handleBotDcaCommand(run, subAction, v, json) {
|
|
|
18543
18665
|
});
|
|
18544
18666
|
if (subAction === "stop")
|
|
18545
18667
|
return cmdDcaStop(run, { algoId: v.algoId, algoOrdType, stopType: v.stopType, json });
|
|
18668
|
+
unknownSubcommand("bot dca", subAction, ["orders", "details", "sub-orders", "create", "stop"]);
|
|
18546
18669
|
}
|
|
18547
18670
|
function handleBotCommand(run, action, rest, v, json) {
|
|
18548
18671
|
if (action === "grid") return handleBotGridCommand(run, v, rest, json);
|
|
18549
18672
|
if (action === "dca") return handleBotDcaCommand(run, rest[0], v, json);
|
|
18673
|
+
unknownSubcommand("bot", action, ["grid", "dca"]);
|
|
18550
18674
|
}
|
|
18551
18675
|
function handleEarnCommand(run, submodule, rest, v, json) {
|
|
18552
18676
|
const action = rest[0];
|
|
@@ -18888,11 +19012,11 @@ async function runDiagnose(v) {
|
|
|
18888
19012
|
}
|
|
18889
19013
|
function printVersion() {
|
|
18890
19014
|
outputLine(`${CLI_VERSION2} (${GIT_HASH2})`);
|
|
18891
|
-
const
|
|
18892
|
-
if (
|
|
18893
|
-
outputLine(`
|
|
19015
|
+
const pilotStatus = getPilotStatus(void 0, { skipHash: true });
|
|
19016
|
+
if (pilotStatus.exists) {
|
|
19017
|
+
outputLine(`Pilot: installed (${pilotStatus.platform ?? "unknown"})`);
|
|
18894
19018
|
} else {
|
|
18895
|
-
outputLine("
|
|
19019
|
+
outputLine("Pilot: not installed");
|
|
18896
19020
|
}
|
|
18897
19021
|
}
|
|
18898
19022
|
function routeManagementCommand(module, action, rest, json, v) {
|
|
@@ -18905,8 +19029,8 @@ function routeManagementCommand(module, action, rest, json, v) {
|
|
|
18905
19029
|
return true;
|
|
18906
19030
|
}
|
|
18907
19031
|
if (module === "upgrade") return cmdUpgrade(CLI_VERSION2, { beta: v.beta, check: v.check, force: v.force }, json);
|
|
18908
|
-
if (module === "
|
|
18909
|
-
const r =
|
|
19032
|
+
if (module === "pilot") {
|
|
19033
|
+
const r = handlePilotCommand(action, json, v.force ?? false);
|
|
18910
19034
|
return r ?? true;
|
|
18911
19035
|
}
|
|
18912
19036
|
if (module === "diagnose") return runDiagnose(v);
|
|
@@ -18976,7 +19100,6 @@ export {
|
|
|
18976
19100
|
handleBotDcaCommand,
|
|
18977
19101
|
handleBotGridCommand,
|
|
18978
19102
|
handleConfigCommand,
|
|
18979
|
-
handleDohCommand,
|
|
18980
19103
|
handleEarnCommand,
|
|
18981
19104
|
handleEventCommand,
|
|
18982
19105
|
handleFuturesAlgoCommand,
|
|
@@ -18987,6 +19110,7 @@ export {
|
|
|
18987
19110
|
handleNewsCommand,
|
|
18988
19111
|
handleOptionAlgoCommand,
|
|
18989
19112
|
handleOptionCommand,
|
|
19113
|
+
handlePilotCommand,
|
|
18990
19114
|
handleSetupCommand,
|
|
18991
19115
|
handleSkillCommand,
|
|
18992
19116
|
handleSmartmoneyCommand,
|