@okx_ai/okx-trade-cli 1.3.1-beta.4 → 1.3.1-beta.5
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 +909 -47
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/scripts/postinstall.js +3 -1
package/dist/index.js
CHANGED
|
@@ -876,6 +876,20 @@ import * as fs3 from "fs";
|
|
|
876
876
|
import * as path3 from "path";
|
|
877
877
|
import * as os3 from "os";
|
|
878
878
|
import { execFileSync } from "child_process";
|
|
879
|
+
import {
|
|
880
|
+
readFileSync as readFileSync7,
|
|
881
|
+
createWriteStream as createWriteStream2,
|
|
882
|
+
mkdirSync as mkdirSync8,
|
|
883
|
+
chmodSync,
|
|
884
|
+
existsSync as existsSync6,
|
|
885
|
+
unlinkSync as unlinkSync3,
|
|
886
|
+
renameSync as renameSync3
|
|
887
|
+
} from "fs";
|
|
888
|
+
import { createHash } from "crypto";
|
|
889
|
+
import { homedir as homedir7, platform, arch } from "os";
|
|
890
|
+
import { join as join9, dirname as dirname6 } from "path";
|
|
891
|
+
import { get as httpsGet } from "https";
|
|
892
|
+
import { get as httpGet } from "http";
|
|
879
893
|
var EXEC_TIMEOUT_MS = 3e4;
|
|
880
894
|
var ALLOWED_DOMAIN_RE = /^[\w.-]+\.okx\.com$/;
|
|
881
895
|
var DOH_BIN_DIR = join(homedir(), ".okx", "bin");
|
|
@@ -2116,6 +2130,30 @@ var MODULES = [
|
|
|
2116
2130
|
"skills"
|
|
2117
2131
|
];
|
|
2118
2132
|
var DEFAULT_MODULES = ["spot", "swap", "option", "account", ...BOT_DEFAULT_SUB_MODULES, "skills"];
|
|
2133
|
+
var SKILLS_MARKETPLACE_DESC = "OKX Skills Marketplace \u2014 search, install, and manage agent skills";
|
|
2134
|
+
var MODULE_DESCRIPTIONS = {
|
|
2135
|
+
market: "Market data (ticker, orderbook, candles, trades)",
|
|
2136
|
+
spot: "Spot trading (orders, algo orders)",
|
|
2137
|
+
swap: "Perpetual swap trading (orders, algo orders)",
|
|
2138
|
+
futures: "Futures trading (orders, positions, algo orders, leverage)",
|
|
2139
|
+
option: "Options trading (orders, positions, greeks)",
|
|
2140
|
+
account: "Account balance, positions, bills, and configuration",
|
|
2141
|
+
"earn.savings": "Simple Earn \u2014 flexible savings, fixed-term, and lending",
|
|
2142
|
+
"earn.onchain": "On-chain Earn \u2014 staking and DeFi products",
|
|
2143
|
+
"earn.dcd": "DCD (Dual Currency Deposit) \u2014 structured products with fixed yield",
|
|
2144
|
+
"earn.autoearn": "Auto-earn \u2014 automatically lend, stake, or earn on idle assets",
|
|
2145
|
+
"bot.grid": "Grid trading bot \u2014 create, monitor, and stop grid orders",
|
|
2146
|
+
"bot.dca": "DCA (Martingale) bot \u2014 spot or contract recurring buys",
|
|
2147
|
+
skills: SKILLS_MARKETPLACE_DESC,
|
|
2148
|
+
earn: "Earn products \u2014 Simple Earn, On-chain Earn, and DCD (Dual Currency Deposit)",
|
|
2149
|
+
bot: "Trading bot strategies (grid, dca)",
|
|
2150
|
+
config: "Manage CLI configuration profiles",
|
|
2151
|
+
setup: "Set up client integrations (Cursor, Windsurf, Claude, etc.)",
|
|
2152
|
+
doh: "Manage DoH (DNS-over-HTTPS) resolver binary",
|
|
2153
|
+
diagnose: "Run network / MCP server diagnostics",
|
|
2154
|
+
upgrade: "Upgrade okx CLI and MCP server to the latest stable version",
|
|
2155
|
+
skill: SKILLS_MARKETPLACE_DESC
|
|
2156
|
+
};
|
|
2119
2157
|
function registerAccountTools() {
|
|
2120
2158
|
return [
|
|
2121
2159
|
{
|
|
@@ -8449,13 +8487,13 @@ function findMsStoreClaudePath() {
|
|
|
8449
8487
|
}
|
|
8450
8488
|
function getConfigPath(client) {
|
|
8451
8489
|
const home = os3.homedir();
|
|
8452
|
-
const
|
|
8490
|
+
const platform2 = process.platform;
|
|
8453
8491
|
switch (client) {
|
|
8454
8492
|
case "claude-desktop":
|
|
8455
|
-
if (
|
|
8493
|
+
if (platform2 === "win32") {
|
|
8456
8494
|
return findMsStoreClaudePath() ?? path3.join(appData(), "Claude", CLAUDE_CONFIG_FILE);
|
|
8457
8495
|
}
|
|
8458
|
-
if (
|
|
8496
|
+
if (platform2 === "darwin") {
|
|
8459
8497
|
return path3.join(home, "Library", "Application Support", "Claude", CLAUDE_CONFIG_FILE);
|
|
8460
8498
|
}
|
|
8461
8499
|
return path3.join(process.env.XDG_CONFIG_HOME ?? path3.join(home, ".config"), "Claude", CLAUDE_CONFIG_FILE);
|
|
@@ -8557,6 +8595,269 @@ function runSetup(options) {
|
|
|
8557
8595
|
`);
|
|
8558
8596
|
}
|
|
8559
8597
|
}
|
|
8598
|
+
var CDN_SOURCES = [
|
|
8599
|
+
{ host: "static.jingyunyilian.com", protocol: "https" },
|
|
8600
|
+
{ host: "static.okx.com", protocol: "https" },
|
|
8601
|
+
{ host: "static.coinall.ltd", protocol: "https" }
|
|
8602
|
+
];
|
|
8603
|
+
var CDN_PATH_PREFIX = "/upgradeapp/doh";
|
|
8604
|
+
var DOWNLOAD_TIMEOUT_MS = 3e4;
|
|
8605
|
+
function getPlatformDir() {
|
|
8606
|
+
const p = platform();
|
|
8607
|
+
const a = arch();
|
|
8608
|
+
const map = {
|
|
8609
|
+
"darwin-arm64": "darwin-arm64",
|
|
8610
|
+
"darwin-x64": "darwin-x64",
|
|
8611
|
+
"linux-x64": "linux-x64",
|
|
8612
|
+
"win32-x64": "win32-x64"
|
|
8613
|
+
};
|
|
8614
|
+
return map[`${p}-${a}`] ?? null;
|
|
8615
|
+
}
|
|
8616
|
+
function getBinaryName() {
|
|
8617
|
+
return platform() === "win32" ? "okx-doh-resolver.exe" : "okx-doh-resolver";
|
|
8618
|
+
}
|
|
8619
|
+
function hashFile(filePath) {
|
|
8620
|
+
const buf = readFileSync7(filePath);
|
|
8621
|
+
return {
|
|
8622
|
+
size: buf.byteLength,
|
|
8623
|
+
sha256: createHash("sha256").update(buf).digest("hex")
|
|
8624
|
+
};
|
|
8625
|
+
}
|
|
8626
|
+
function getDohStatus(binaryPath, opts) {
|
|
8627
|
+
const resolvedPath = binaryPath ?? getDohBinaryPath();
|
|
8628
|
+
const platformDir = getPlatformDir();
|
|
8629
|
+
if (!existsSync6(resolvedPath)) {
|
|
8630
|
+
return {
|
|
8631
|
+
binaryPath: resolvedPath,
|
|
8632
|
+
exists: false,
|
|
8633
|
+
platform: platformDir
|
|
8634
|
+
};
|
|
8635
|
+
}
|
|
8636
|
+
if (opts?.skipHash) {
|
|
8637
|
+
return {
|
|
8638
|
+
binaryPath: resolvedPath,
|
|
8639
|
+
exists: true,
|
|
8640
|
+
platform: platformDir
|
|
8641
|
+
};
|
|
8642
|
+
}
|
|
8643
|
+
const { size, sha256 } = hashFile(resolvedPath);
|
|
8644
|
+
return {
|
|
8645
|
+
binaryPath: resolvedPath,
|
|
8646
|
+
exists: true,
|
|
8647
|
+
platform: platformDir,
|
|
8648
|
+
fileSize: size,
|
|
8649
|
+
sha256
|
|
8650
|
+
};
|
|
8651
|
+
}
|
|
8652
|
+
async function fetchCdnChecksum(sources = CDN_SOURCES, timeoutMs = DOWNLOAD_TIMEOUT_MS) {
|
|
8653
|
+
const platformDir = getPlatformDir();
|
|
8654
|
+
if (!platformDir) return null;
|
|
8655
|
+
const checksumPath = `${CDN_PATH_PREFIX}/${platformDir}/checksum.json`;
|
|
8656
|
+
for (const { host, protocol } of sources) {
|
|
8657
|
+
try {
|
|
8658
|
+
const url = `${protocol}://${host}${checksumPath}`;
|
|
8659
|
+
const raw = await downloadText(url, timeoutMs);
|
|
8660
|
+
const data = JSON.parse(raw);
|
|
8661
|
+
if (typeof data.sha256 !== "string" || typeof data.size !== "number" || typeof data.target !== "string") {
|
|
8662
|
+
continue;
|
|
8663
|
+
}
|
|
8664
|
+
return {
|
|
8665
|
+
sha256: data.sha256,
|
|
8666
|
+
size: data.size,
|
|
8667
|
+
target: data.target,
|
|
8668
|
+
source: host
|
|
8669
|
+
};
|
|
8670
|
+
} catch {
|
|
8671
|
+
}
|
|
8672
|
+
}
|
|
8673
|
+
return null;
|
|
8674
|
+
}
|
|
8675
|
+
async function fetchAndValidateChecksum(host, protocol, checksumPath, platformDir, timeoutMs, onProgress) {
|
|
8676
|
+
const checksumUrl = `${protocol}://${host}${checksumPath}`;
|
|
8677
|
+
onProgress?.(`Fetching checksum from ${host}...`);
|
|
8678
|
+
const raw = await downloadText(checksumUrl, timeoutMs);
|
|
8679
|
+
const checksum = JSON.parse(raw);
|
|
8680
|
+
if (typeof checksum.sha256 !== "string" || typeof checksum.size !== "number" || typeof checksum.target !== "string") {
|
|
8681
|
+
throw new Error("Invalid checksum.json: missing sha256, size, or target");
|
|
8682
|
+
}
|
|
8683
|
+
if (checksum.target !== platformDir) {
|
|
8684
|
+
throw new Error(
|
|
8685
|
+
`Target mismatch: expected ${platformDir}, got ${checksum.target}`
|
|
8686
|
+
);
|
|
8687
|
+
}
|
|
8688
|
+
return { sha256: checksum.sha256, size: checksum.size, target: checksum.target };
|
|
8689
|
+
}
|
|
8690
|
+
async function downloadAndVerify(host, protocol, binaryPath, tmpPath, checksum, timeoutMs, onProgress) {
|
|
8691
|
+
const binaryUrl = `${protocol}://${host}${binaryPath}`;
|
|
8692
|
+
onProgress?.(`Downloading binary from ${host}...`);
|
|
8693
|
+
await download(binaryUrl, tmpPath, timeoutMs);
|
|
8694
|
+
const actual = hashFile(tmpPath);
|
|
8695
|
+
if (actual.size !== checksum.size) {
|
|
8696
|
+
throw new Error(
|
|
8697
|
+
`Size mismatch: expected ${checksum.size}, got ${actual.size}`
|
|
8698
|
+
);
|
|
8699
|
+
}
|
|
8700
|
+
if (actual.sha256 !== checksum.sha256) {
|
|
8701
|
+
throw new Error(
|
|
8702
|
+
`SHA-256 mismatch: expected ${checksum.sha256}, got ${actual.sha256}`
|
|
8703
|
+
);
|
|
8704
|
+
}
|
|
8705
|
+
}
|
|
8706
|
+
function atomicReplace(tmpPath, resolvedDest) {
|
|
8707
|
+
if (platform() === "win32") {
|
|
8708
|
+
try {
|
|
8709
|
+
unlinkSync3(resolvedDest);
|
|
8710
|
+
} catch {
|
|
8711
|
+
}
|
|
8712
|
+
}
|
|
8713
|
+
renameSync3(tmpPath, resolvedDest);
|
|
8714
|
+
if (platform() !== "win32") {
|
|
8715
|
+
chmodSync(resolvedDest, 493);
|
|
8716
|
+
}
|
|
8717
|
+
}
|
|
8718
|
+
function installPreChecks(destPath, sources) {
|
|
8719
|
+
if (!destPath && process.env.OKX_DOH_BINARY_PATH) {
|
|
8720
|
+
return { status: "up-to-date", source: "(env override)" };
|
|
8721
|
+
}
|
|
8722
|
+
if (!getPlatformDir()) {
|
|
8723
|
+
return { status: "failed", error: "Unsupported platform" };
|
|
8724
|
+
}
|
|
8725
|
+
if (sources.length === 0) {
|
|
8726
|
+
return { status: "failed", error: "No CDN sources available" };
|
|
8727
|
+
}
|
|
8728
|
+
return null;
|
|
8729
|
+
}
|
|
8730
|
+
function isLocalUpToDate(localHash, checksum) {
|
|
8731
|
+
return localHash !== null && localHash.size === checksum.size && localHash.sha256 === checksum.sha256;
|
|
8732
|
+
}
|
|
8733
|
+
async function installDohBinary(destPath, sources = CDN_SOURCES, onProgress) {
|
|
8734
|
+
const earlyResult = installPreChecks(destPath, sources);
|
|
8735
|
+
if (earlyResult) return earlyResult;
|
|
8736
|
+
const platformDir = getPlatformDir();
|
|
8737
|
+
const binaryName = getBinaryName();
|
|
8738
|
+
const resolvedDest = destPath ?? join9(homedir7(), ".okx", "bin", binaryName);
|
|
8739
|
+
const tmpPath = resolvedDest + ".tmp";
|
|
8740
|
+
mkdirSync8(dirname6(resolvedDest), { recursive: true });
|
|
8741
|
+
const localHash = existsSync6(resolvedDest) ? hashFile(resolvedDest) : null;
|
|
8742
|
+
const checksumPath = `${CDN_PATH_PREFIX}/${platformDir}/checksum.json`;
|
|
8743
|
+
const binaryPath = `${CDN_PATH_PREFIX}/${platformDir}/${binaryName}`;
|
|
8744
|
+
const errors = [];
|
|
8745
|
+
for (const { host, protocol } of sources) {
|
|
8746
|
+
try {
|
|
8747
|
+
const checksum = await fetchAndValidateChecksum(
|
|
8748
|
+
host,
|
|
8749
|
+
protocol,
|
|
8750
|
+
checksumPath,
|
|
8751
|
+
platformDir,
|
|
8752
|
+
DOWNLOAD_TIMEOUT_MS,
|
|
8753
|
+
onProgress
|
|
8754
|
+
);
|
|
8755
|
+
if (isLocalUpToDate(localHash, checksum)) {
|
|
8756
|
+
onProgress?.("Already up to date (checksum match)");
|
|
8757
|
+
return { status: "up-to-date", source: host };
|
|
8758
|
+
}
|
|
8759
|
+
await downloadAndVerify(host, protocol, binaryPath, tmpPath, checksum, DOWNLOAD_TIMEOUT_MS, onProgress);
|
|
8760
|
+
atomicReplace(tmpPath, resolvedDest);
|
|
8761
|
+
onProgress?.(`Downloaded and verified from ${host}`);
|
|
8762
|
+
return { status: "installed", source: host };
|
|
8763
|
+
} catch (err) {
|
|
8764
|
+
try {
|
|
8765
|
+
unlinkSync3(tmpPath);
|
|
8766
|
+
} catch {
|
|
8767
|
+
}
|
|
8768
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
8769
|
+
errors.push(`${host}: ${msg}`);
|
|
8770
|
+
onProgress?.(`${host} failed: ${msg}`);
|
|
8771
|
+
}
|
|
8772
|
+
}
|
|
8773
|
+
return { status: "failed", error: `All CDN sources failed:
|
|
8774
|
+
${errors.join("\n")}` };
|
|
8775
|
+
}
|
|
8776
|
+
function removeDohBinary(binaryPath) {
|
|
8777
|
+
const resolvedPath = binaryPath ?? getDohBinaryPath();
|
|
8778
|
+
try {
|
|
8779
|
+
unlinkSync3(resolvedPath);
|
|
8780
|
+
return { status: "removed" };
|
|
8781
|
+
} catch (err) {
|
|
8782
|
+
if (err.code === "ENOENT") {
|
|
8783
|
+
return { status: "not-found" };
|
|
8784
|
+
}
|
|
8785
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
8786
|
+
throw new Error(`Failed to remove ${resolvedPath}: ${msg}`);
|
|
8787
|
+
}
|
|
8788
|
+
}
|
|
8789
|
+
function isRedirect(statusCode) {
|
|
8790
|
+
return statusCode !== void 0 && statusCode >= 300 && statusCode < 400;
|
|
8791
|
+
}
|
|
8792
|
+
function validateRedirect(res, requestUrl, redirectCount, maxRedirects) {
|
|
8793
|
+
if (redirectCount > maxRedirects) {
|
|
8794
|
+
throw new Error(`Too many redirects (${maxRedirects})`);
|
|
8795
|
+
}
|
|
8796
|
+
const location = res.headers.location;
|
|
8797
|
+
if (requestUrl.startsWith("https") && !location.startsWith("https")) {
|
|
8798
|
+
throw new Error("Refused HTTPS \u2192 HTTP redirect downgrade");
|
|
8799
|
+
}
|
|
8800
|
+
return location;
|
|
8801
|
+
}
|
|
8802
|
+
function fetchResponse(url, timeoutMs) {
|
|
8803
|
+
return new Promise((resolve3, reject) => {
|
|
8804
|
+
let redirects = 0;
|
|
8805
|
+
const maxRedirects = 5;
|
|
8806
|
+
function doRequest(requestUrl) {
|
|
8807
|
+
const reqFn = requestUrl.startsWith("https") ? httpsGet : httpGet;
|
|
8808
|
+
const req = reqFn(requestUrl, { timeout: timeoutMs }, (res) => {
|
|
8809
|
+
if (isRedirect(res.statusCode) && res.headers.location) {
|
|
8810
|
+
redirects++;
|
|
8811
|
+
try {
|
|
8812
|
+
const location = validateRedirect(res, requestUrl, redirects, maxRedirects);
|
|
8813
|
+
res.resume();
|
|
8814
|
+
doRequest(location);
|
|
8815
|
+
} catch (err) {
|
|
8816
|
+
reject(err);
|
|
8817
|
+
}
|
|
8818
|
+
return;
|
|
8819
|
+
}
|
|
8820
|
+
if (res.statusCode !== 200) {
|
|
8821
|
+
reject(new Error(`HTTP ${res.statusCode ?? "unknown"}`));
|
|
8822
|
+
return;
|
|
8823
|
+
}
|
|
8824
|
+
resolve3(res);
|
|
8825
|
+
});
|
|
8826
|
+
req.on("error", reject);
|
|
8827
|
+
req.on("timeout", () => {
|
|
8828
|
+
req.destroy();
|
|
8829
|
+
reject(new Error("Download timed out"));
|
|
8830
|
+
});
|
|
8831
|
+
}
|
|
8832
|
+
doRequest(url);
|
|
8833
|
+
});
|
|
8834
|
+
}
|
|
8835
|
+
function download(url, destPath, timeoutMs) {
|
|
8836
|
+
return fetchResponse(url, timeoutMs).then(
|
|
8837
|
+
(res) => new Promise((resolve3, reject) => {
|
|
8838
|
+
const file = createWriteStream2(destPath);
|
|
8839
|
+
res.pipe(file);
|
|
8840
|
+
file.on("finish", () => file.close(() => resolve3()));
|
|
8841
|
+
file.on("error", (err) => {
|
|
8842
|
+
try {
|
|
8843
|
+
unlinkSync3(destPath);
|
|
8844
|
+
} catch {
|
|
8845
|
+
}
|
|
8846
|
+
reject(err);
|
|
8847
|
+
});
|
|
8848
|
+
})
|
|
8849
|
+
);
|
|
8850
|
+
}
|
|
8851
|
+
function downloadText(url, timeoutMs) {
|
|
8852
|
+
return fetchResponse(url, timeoutMs).then(
|
|
8853
|
+
(res) => new Promise((resolve3, reject) => {
|
|
8854
|
+
const chunks = [];
|
|
8855
|
+
res.on("data", (chunk) => chunks.push(chunk));
|
|
8856
|
+
res.on("end", () => resolve3(Buffer.concat(chunks).toString("utf8")));
|
|
8857
|
+
res.on("error", reject);
|
|
8858
|
+
})
|
|
8859
|
+
);
|
|
8860
|
+
}
|
|
8560
8861
|
|
|
8561
8862
|
// src/commands/diagnose.ts
|
|
8562
8863
|
import dns from "dns/promises";
|
|
@@ -9189,7 +9490,7 @@ async function cmdDiagnoseMcp(options = {}) {
|
|
|
9189
9490
|
|
|
9190
9491
|
// src/commands/diagnose.ts
|
|
9191
9492
|
var CLI_VERSION = readCliVersion();
|
|
9192
|
-
var GIT_HASH = true ? "
|
|
9493
|
+
var GIT_HASH = true ? "63a5613" : "dev";
|
|
9193
9494
|
function maskKey2(key) {
|
|
9194
9495
|
if (!key) return "(not set)";
|
|
9195
9496
|
if (key.length <= 8) return "****";
|
|
@@ -9431,6 +9732,44 @@ async function cmdDiagnose(config, profile, options = {}) {
|
|
|
9431
9732
|
}
|
|
9432
9733
|
return runCliChecks(config, profile, options.output);
|
|
9433
9734
|
}
|
|
9735
|
+
async function checkDoh(report) {
|
|
9736
|
+
section("DoH Resolver");
|
|
9737
|
+
const local = getDohStatus();
|
|
9738
|
+
if (!local.exists) {
|
|
9739
|
+
fail("DoH binary", "not installed", [
|
|
9740
|
+
"Run: okx doh install",
|
|
9741
|
+
"Or wait for the next npm install to auto-download"
|
|
9742
|
+
]);
|
|
9743
|
+
report.add("doh_binary", "not installed");
|
|
9744
|
+
return;
|
|
9745
|
+
}
|
|
9746
|
+
ok("DoH binary", local.binaryPath);
|
|
9747
|
+
report.add("doh_binary", `installed (${local.platform ?? "unknown"})`);
|
|
9748
|
+
const cdnChecksum = await fetchCdnChecksum(void 0, 5e3);
|
|
9749
|
+
if (!cdnChecksum) {
|
|
9750
|
+
warn("DoH checksum", "CDN unreachable \u2014 cannot verify");
|
|
9751
|
+
report.add("doh_checksum", "CDN unreachable");
|
|
9752
|
+
} else if (cdnChecksum.sha256 === local.sha256) {
|
|
9753
|
+
ok("DoH checksum", `match (${cdnChecksum.source})`);
|
|
9754
|
+
report.add("doh_checksum", `match (${cdnChecksum.source})`);
|
|
9755
|
+
} else {
|
|
9756
|
+
warn("DoH checksum", "mismatch \u2014 update available", ["Run: okx doh install"]);
|
|
9757
|
+
report.add("doh_checksum", "mismatch");
|
|
9758
|
+
}
|
|
9759
|
+
try {
|
|
9760
|
+
const cacheEntry = readCache("www.okx.com");
|
|
9761
|
+
if (cacheEntry) {
|
|
9762
|
+
ok("DoH mode", cacheEntry.mode);
|
|
9763
|
+
report.add("doh_mode", cacheEntry.mode);
|
|
9764
|
+
} else {
|
|
9765
|
+
ok("DoH mode", "no cache (will auto-detect on next request)");
|
|
9766
|
+
report.add("doh_mode", "no cache");
|
|
9767
|
+
}
|
|
9768
|
+
} catch {
|
|
9769
|
+
ok("DoH mode", "no cache");
|
|
9770
|
+
report.add("doh_mode", "no cache");
|
|
9771
|
+
}
|
|
9772
|
+
}
|
|
9434
9773
|
function checkConfigFile(report) {
|
|
9435
9774
|
section("Config File");
|
|
9436
9775
|
const path6 = configFilePath();
|
|
@@ -9459,6 +9798,7 @@ async function runCliChecks(config, profile, outputPath) {
|
|
|
9459
9798
|
report.add("ts", (/* @__PURE__ */ new Date()).toISOString());
|
|
9460
9799
|
const configFilePassed = checkConfigFile(report);
|
|
9461
9800
|
const envPassed = checkEnvironment(report);
|
|
9801
|
+
await checkDoh(report);
|
|
9462
9802
|
if (!config) {
|
|
9463
9803
|
fail("Config", "Could not load config (see Config File check above)", []);
|
|
9464
9804
|
report.add("result", "FAIL");
|
|
@@ -9486,23 +9826,23 @@ async function runCliChecks(config, profile, outputPath) {
|
|
|
9486
9826
|
|
|
9487
9827
|
// src/commands/upgrade.ts
|
|
9488
9828
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
9489
|
-
import { readFileSync as
|
|
9490
|
-
import { dirname as
|
|
9491
|
-
import { homedir as
|
|
9829
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync7, mkdirSync as mkdirSync9 } from "fs";
|
|
9830
|
+
import { dirname as dirname7, join as join10 } from "path";
|
|
9831
|
+
import { homedir as homedir8 } from "os";
|
|
9492
9832
|
var PACKAGES = ["@okx_ai/okx-trade-mcp", "@okx_ai/okx-trade-cli"];
|
|
9493
|
-
var CACHE_FILE2 =
|
|
9833
|
+
var CACHE_FILE2 = join10(homedir8(), ".okx", "last_check");
|
|
9494
9834
|
var THROTTLE_MS = 12 * 60 * 60 * 1e3;
|
|
9495
|
-
var NPM_BIN =
|
|
9835
|
+
var NPM_BIN = join10(dirname7(process.execPath), process.platform === "win32" ? "npm.cmd" : "npm");
|
|
9496
9836
|
function readLastCheck() {
|
|
9497
9837
|
try {
|
|
9498
|
-
return parseInt(
|
|
9838
|
+
return parseInt(readFileSync8(CACHE_FILE2, "utf-8").trim(), 10) || 0;
|
|
9499
9839
|
} catch {
|
|
9500
9840
|
return 0;
|
|
9501
9841
|
}
|
|
9502
9842
|
}
|
|
9503
9843
|
function writeLastCheck() {
|
|
9504
9844
|
try {
|
|
9505
|
-
|
|
9845
|
+
mkdirSync9(join10(homedir8(), ".okx"), { recursive: true });
|
|
9506
9846
|
writeFileSync7(CACHE_FILE2, String(Math.floor(Date.now() / 1e3)), "utf-8");
|
|
9507
9847
|
} catch {
|
|
9508
9848
|
}
|
|
@@ -9587,24 +9927,6 @@ async function cmdUpgrade(currentVersion, options, json) {
|
|
|
9587
9927
|
}
|
|
9588
9928
|
}
|
|
9589
9929
|
|
|
9590
|
-
// src/config/loader.ts
|
|
9591
|
-
function loadProfileConfig(opts) {
|
|
9592
|
-
return loadConfig({
|
|
9593
|
-
profile: opts.profile,
|
|
9594
|
-
modules: opts.modules,
|
|
9595
|
-
readOnly: opts.readOnly ?? false,
|
|
9596
|
-
demo: opts.demo,
|
|
9597
|
-
live: opts.live,
|
|
9598
|
-
site: opts.site,
|
|
9599
|
-
userAgent: opts.userAgent,
|
|
9600
|
-
sourceTag: opts.sourceTag,
|
|
9601
|
-
verbose: opts.verbose
|
|
9602
|
-
});
|
|
9603
|
-
}
|
|
9604
|
-
|
|
9605
|
-
// src/help.ts
|
|
9606
|
-
import { EOL as EOL2 } from "os";
|
|
9607
|
-
|
|
9608
9930
|
// src/commands/client-setup.ts
|
|
9609
9931
|
import * as fs6 from "fs";
|
|
9610
9932
|
var DETECTABLE_CLIENTS = ["claude-desktop", "cursor", "windsurf"];
|
|
@@ -9629,154 +9951,213 @@ function cmdSetupClients() {
|
|
|
9629
9951
|
printSetupUsage();
|
|
9630
9952
|
}
|
|
9631
9953
|
|
|
9632
|
-
// src/
|
|
9633
|
-
var
|
|
9954
|
+
// src/cli-registry.ts
|
|
9955
|
+
var CLI_REGISTRY = {
|
|
9956
|
+
// ── market ─────────────────────────────────────────────────────────────────
|
|
9634
9957
|
market: {
|
|
9635
9958
|
description: "Market data (ticker, orderbook, candles, trades)",
|
|
9636
9959
|
commands: {
|
|
9637
9960
|
ticker: {
|
|
9961
|
+
toolName: "market_get_ticker",
|
|
9638
9962
|
usage: "okx market ticker <instId>",
|
|
9639
9963
|
description: "Get latest ticker data for an instrument"
|
|
9640
9964
|
},
|
|
9641
9965
|
tickers: {
|
|
9966
|
+
toolName: "market_get_tickers",
|
|
9642
9967
|
usage: "okx market tickers <instType>",
|
|
9643
9968
|
description: "Get all tickers for an instrument type (SPOT|SWAP|FUTURES|OPTION)"
|
|
9644
9969
|
},
|
|
9645
9970
|
orderbook: {
|
|
9971
|
+
toolName: "market_get_orderbook",
|
|
9646
9972
|
usage: "okx market orderbook <instId> [--sz <n>]",
|
|
9647
9973
|
description: "Get order book depth for an instrument"
|
|
9648
9974
|
},
|
|
9649
9975
|
candles: {
|
|
9976
|
+
toolName: "market_get_candles",
|
|
9650
9977
|
usage: "okx market candles <instId> [--bar <bar>] [--limit <n>]",
|
|
9651
9978
|
description: "Get candlestick (OHLCV) data"
|
|
9652
9979
|
},
|
|
9653
9980
|
instruments: {
|
|
9981
|
+
toolName: "market_get_instruments",
|
|
9654
9982
|
usage: "okx market instruments --instType <type> [--instId <id>]",
|
|
9655
9983
|
description: "List tradable instruments of a given type"
|
|
9656
9984
|
},
|
|
9657
9985
|
"funding-rate": {
|
|
9986
|
+
toolName: "market_get_funding_rate",
|
|
9658
9987
|
usage: "okx market funding-rate <instId> [--history] [--limit <n>]",
|
|
9659
9988
|
description: "Get current or historical funding rate for perpetual swaps"
|
|
9660
9989
|
},
|
|
9661
9990
|
"mark-price": {
|
|
9991
|
+
toolName: "market_get_mark_price",
|
|
9662
9992
|
usage: "okx market mark-price --instType <MARGIN|SWAP|FUTURES|OPTION> [--instId <id>]",
|
|
9663
9993
|
description: "Get mark price for instruments"
|
|
9664
9994
|
},
|
|
9665
9995
|
trades: {
|
|
9996
|
+
toolName: "market_get_trades",
|
|
9666
9997
|
usage: "okx market trades <instId> [--limit <n>]",
|
|
9667
9998
|
description: "Get recent trades for an instrument"
|
|
9668
9999
|
},
|
|
9669
10000
|
"index-ticker": {
|
|
10001
|
+
toolName: "market_get_index_ticker",
|
|
9670
10002
|
usage: "okx market index-ticker [--instId <id>] [--quoteCcy <ccy>]",
|
|
9671
10003
|
description: "Get index ticker data"
|
|
9672
10004
|
},
|
|
9673
10005
|
"index-candles": {
|
|
10006
|
+
toolName: "market_get_index_candles",
|
|
9674
10007
|
usage: "okx market index-candles <instId> [--bar <bar>] [--limit <n>] [--history]",
|
|
9675
10008
|
description: "Get index candlestick data"
|
|
9676
10009
|
},
|
|
9677
10010
|
"price-limit": {
|
|
10011
|
+
toolName: "market_get_price_limit",
|
|
9678
10012
|
usage: "okx market price-limit <instId>",
|
|
9679
10013
|
description: "Get price limit for an instrument"
|
|
9680
10014
|
},
|
|
9681
10015
|
"open-interest": {
|
|
10016
|
+
toolName: "market_get_open_interest",
|
|
9682
10017
|
usage: "okx market open-interest --instType <SWAP|FUTURES|OPTION> [--instId <id>]",
|
|
9683
10018
|
description: "Get open interest for instruments"
|
|
9684
10019
|
},
|
|
9685
10020
|
"stock-tokens": {
|
|
10021
|
+
toolName: "market_get_stock_tokens",
|
|
9686
10022
|
usage: "okx market stock-tokens [--instType <SPOT|SWAP>] [--instId <id>]",
|
|
9687
10023
|
description: "[Deprecated: use instruments-by-category --instCategory 3] List all stock token instruments (instCategory=3, e.g. AAPL-USDT-SWAP)"
|
|
9688
10024
|
},
|
|
9689
10025
|
"instruments-by-category": {
|
|
10026
|
+
toolName: "market_get_instruments_by_category",
|
|
9690
10027
|
usage: "okx market instruments-by-category --instCategory <4|5|6|7> [--instType <SPOT|SWAP>] [--instId <id>]",
|
|
9691
10028
|
description: "List instruments by asset category: 4=Metals (gold/silver), 5=Commodities (oil/gas), 6=Forex (EUR/USD), 7=Bonds"
|
|
9692
10029
|
}
|
|
10030
|
+
},
|
|
10031
|
+
subgroups: {
|
|
10032
|
+
indicator: {
|
|
10033
|
+
description: "Technical indicators and chart patterns",
|
|
10034
|
+
commands: {
|
|
10035
|
+
list: {
|
|
10036
|
+
toolName: "market_list_indicators",
|
|
10037
|
+
usage: "okx market indicator list",
|
|
10038
|
+
description: "List all supported technical indicators"
|
|
10039
|
+
},
|
|
10040
|
+
"<instId> <indicator>": {
|
|
10041
|
+
toolName: "market_get_indicator",
|
|
10042
|
+
usage: "okx market indicator <instId> <indicator> [--bar <bar>] [--limit <n>] [--backtest-time <ts>] [--params <json>]",
|
|
10043
|
+
description: "Get indicator values for an instrument (e.g. okx market indicator BTC-USDT-SWAP rsi)"
|
|
10044
|
+
}
|
|
10045
|
+
}
|
|
10046
|
+
}
|
|
9693
10047
|
}
|
|
9694
10048
|
},
|
|
10049
|
+
// ── account ────────────────────────────────────────────────────────────────
|
|
9695
10050
|
account: {
|
|
9696
10051
|
description: "Account balance, positions, bills, and configuration",
|
|
9697
10052
|
commands: {
|
|
9698
10053
|
balance: {
|
|
10054
|
+
toolName: "account_get_balance",
|
|
9699
10055
|
usage: "okx account balance [<ccy>]",
|
|
9700
10056
|
description: "Get trading account balance"
|
|
9701
10057
|
},
|
|
9702
10058
|
"asset-balance": {
|
|
10059
|
+
toolName: "account_get_asset_balance",
|
|
9703
10060
|
usage: "okx account asset-balance [--ccy <ccy>]",
|
|
9704
10061
|
description: "Get funding account asset balance"
|
|
9705
10062
|
},
|
|
9706
10063
|
positions: {
|
|
10064
|
+
toolName: "account_get_positions",
|
|
9707
10065
|
usage: "okx account positions [--instType <type>] [--instId <id>]",
|
|
9708
10066
|
description: "Get current open positions"
|
|
9709
10067
|
},
|
|
9710
10068
|
"positions-history": {
|
|
10069
|
+
toolName: "account_get_positions_history",
|
|
9711
10070
|
usage: "okx account positions-history [--instType <type>] [--instId <id>] [--limit <n>]",
|
|
9712
10071
|
description: "Get historical positions"
|
|
9713
10072
|
},
|
|
9714
10073
|
bills: {
|
|
10074
|
+
toolName: "account_get_bills",
|
|
10075
|
+
alternateTools: ["account_get_bills_archive"],
|
|
9715
10076
|
usage: "okx account bills [--instType <type>] [--ccy <ccy>] [--limit <n>] [--archive]",
|
|
9716
10077
|
description: "Get account bill history"
|
|
9717
10078
|
},
|
|
9718
10079
|
fees: {
|
|
10080
|
+
toolName: "account_get_trade_fee",
|
|
9719
10081
|
usage: "okx account fees --instType <type> [--instId <id>]",
|
|
9720
10082
|
description: "Get trading fee rates"
|
|
9721
10083
|
},
|
|
9722
10084
|
config: {
|
|
10085
|
+
toolName: "account_get_config",
|
|
9723
10086
|
usage: "okx account config",
|
|
9724
10087
|
description: "Get account configuration"
|
|
9725
10088
|
},
|
|
9726
10089
|
"set-position-mode": {
|
|
10090
|
+
toolName: "account_set_position_mode",
|
|
9727
10091
|
usage: "okx account set-position-mode --posMode <long_short_mode|net_mode>",
|
|
9728
10092
|
description: "Set position mode (long/short or net)"
|
|
9729
10093
|
},
|
|
9730
10094
|
"max-size": {
|
|
10095
|
+
toolName: "account_get_max_size",
|
|
9731
10096
|
usage: "okx account max-size --instId <id> --tdMode <cross|isolated> [--px <price>]",
|
|
9732
10097
|
description: "Get maximum order size for an instrument"
|
|
9733
10098
|
},
|
|
9734
10099
|
"max-avail-size": {
|
|
10100
|
+
toolName: "account_get_max_avail_size",
|
|
9735
10101
|
usage: "okx account max-avail-size --instId <id> --tdMode <cross|isolated|cash>",
|
|
9736
10102
|
description: "Get maximum available tradable amount"
|
|
9737
10103
|
},
|
|
9738
10104
|
"max-withdrawal": {
|
|
10105
|
+
toolName: "account_get_max_withdrawal",
|
|
9739
10106
|
usage: "okx account max-withdrawal [--ccy <ccy>]",
|
|
9740
10107
|
description: "Get maximum withdrawable amount"
|
|
9741
10108
|
},
|
|
9742
10109
|
transfer: {
|
|
10110
|
+
toolName: "account_transfer",
|
|
9743
10111
|
usage: "okx account transfer --ccy <ccy> --amt <n> --from <acct> --to <acct> [--transferType <0|1|2|3>]",
|
|
9744
10112
|
description: "Transfer funds between accounts"
|
|
9745
10113
|
},
|
|
9746
10114
|
audit: {
|
|
10115
|
+
// trade_get_history ToolSpec reads the same local log files as cmdAccountAudit.
|
|
10116
|
+
// CLI reads files directly without routing through ToolRunner for performance,
|
|
10117
|
+
// but conceptually this command is the CLI representation of the ToolSpec.
|
|
10118
|
+
toolName: "trade_get_history",
|
|
9747
10119
|
usage: "okx account audit [--tool <name>] [--since <ISO-date>] [--limit <n>]",
|
|
9748
10120
|
description: "Audit account activity and tool call history"
|
|
9749
10121
|
}
|
|
9750
10122
|
}
|
|
9751
10123
|
},
|
|
10124
|
+
// ── spot ───────────────────────────────────────────────────────────────────
|
|
9752
10125
|
spot: {
|
|
9753
10126
|
description: "Spot trading (orders, algo orders)",
|
|
9754
10127
|
commands: {
|
|
9755
10128
|
orders: {
|
|
10129
|
+
toolName: "spot_get_orders",
|
|
9756
10130
|
usage: "okx spot orders [--instId <id>] [--history]",
|
|
9757
10131
|
description: "List open or historical spot orders"
|
|
9758
10132
|
},
|
|
9759
10133
|
get: {
|
|
10134
|
+
toolName: "spot_get_order",
|
|
9760
10135
|
usage: "okx spot get --instId <id> --ordId <id>",
|
|
9761
10136
|
description: "Get details of a specific spot order"
|
|
9762
10137
|
},
|
|
9763
10138
|
fills: {
|
|
10139
|
+
toolName: "spot_get_fills",
|
|
9764
10140
|
usage: "okx spot fills [--instId <id>] [--ordId <id>]",
|
|
9765
10141
|
description: "Get trade fill history for spot orders"
|
|
9766
10142
|
},
|
|
9767
10143
|
place: {
|
|
10144
|
+
toolName: "spot_place_order",
|
|
9768
10145
|
usage: "okx spot place --instId <id> --side <buy|sell> --ordType <type> --sz <n> [--px <price>] [--tdMode <cash|cross|isolated>] [--tpTriggerPx <price>] [--tpOrdPx <price|-1>] [--slTriggerPx <price>] [--slOrdPx <price|-1>]",
|
|
9769
10146
|
description: "Place a new spot order (supports attached TP/SL)"
|
|
9770
10147
|
},
|
|
9771
10148
|
amend: {
|
|
10149
|
+
toolName: "spot_amend_order",
|
|
9772
10150
|
usage: "okx spot amend --instId <id> --ordId <id> [--newSz <n>] [--newPx <price>]",
|
|
9773
10151
|
description: "Amend a pending spot order"
|
|
9774
10152
|
},
|
|
9775
10153
|
cancel: {
|
|
10154
|
+
toolName: "spot_cancel_order",
|
|
9776
10155
|
usage: "okx spot cancel <instId> --ordId <id>",
|
|
9777
10156
|
description: "Cancel a pending spot order"
|
|
9778
10157
|
},
|
|
9779
10158
|
batch: {
|
|
10159
|
+
toolName: "spot_batch_orders",
|
|
10160
|
+
alternateTools: ["spot_batch_amend", "spot_batch_cancel"],
|
|
9780
10161
|
usage: "okx spot batch --action <place|amend|cancel> --orders '<json>'",
|
|
9781
10162
|
description: "Batch place, amend, or cancel spot orders"
|
|
9782
10163
|
}
|
|
@@ -9786,18 +10167,27 @@ var HELP_TREE = {
|
|
|
9786
10167
|
description: "Spot algo orders (conditional, OCO, take-profit/stop-loss)",
|
|
9787
10168
|
commands: {
|
|
9788
10169
|
orders: {
|
|
10170
|
+
toolName: "spot_get_algo_orders",
|
|
9789
10171
|
usage: "okx spot algo orders [--instId <id>] [--history] [--ordType <conditional|oco>]",
|
|
9790
10172
|
description: "List spot algo orders"
|
|
9791
10173
|
},
|
|
9792
10174
|
place: {
|
|
10175
|
+
toolName: "spot_place_algo_order",
|
|
9793
10176
|
usage: "okx spot algo place --instId <id> --side <buy|sell> --sz <n> [--ordType <conditional|oco>]\n [--tpTriggerPx <price>] [--tpOrdPx <price|-1>]\n [--slTriggerPx <price>] [--slOrdPx <price|-1>] [--tdMode <cash|cross|isolated>]",
|
|
9794
10177
|
description: "Place a spot algo order (take-profit/stop-loss)"
|
|
9795
10178
|
},
|
|
10179
|
+
trail: {
|
|
10180
|
+
toolName: "spot_place_algo_order",
|
|
10181
|
+
usage: "okx spot algo trail --instId <id> --side <buy|sell> --sz <n> --callbackRatio <ratio>\n [--activePx <price>] [--tdMode <cash|cross|isolated>]",
|
|
10182
|
+
description: "Place a trailing stop algo order for spot"
|
|
10183
|
+
},
|
|
9796
10184
|
amend: {
|
|
10185
|
+
toolName: "spot_amend_algo_order",
|
|
9797
10186
|
usage: "okx spot algo amend --instId <id> --algoId <id> [--newSz <n>]\n [--newTpTriggerPx <price>] [--newTpOrdPx <price|-1>]\n [--newSlTriggerPx <price>] [--newSlOrdPx <price|-1>]",
|
|
9798
10187
|
description: "Amend a pending spot algo order"
|
|
9799
10188
|
},
|
|
9800
10189
|
cancel: {
|
|
10190
|
+
toolName: "spot_cancel_algo_order",
|
|
9801
10191
|
usage: "okx spot algo cancel --instId <id> --algoId <id>",
|
|
9802
10192
|
description: "Cancel a pending spot algo order"
|
|
9803
10193
|
}
|
|
@@ -9805,50 +10195,64 @@ var HELP_TREE = {
|
|
|
9805
10195
|
}
|
|
9806
10196
|
}
|
|
9807
10197
|
},
|
|
10198
|
+
// ── swap ───────────────────────────────────────────────────────────────────
|
|
9808
10199
|
swap: {
|
|
9809
10200
|
description: "Perpetual swap trading (orders, algo orders)",
|
|
9810
10201
|
commands: {
|
|
9811
10202
|
positions: {
|
|
10203
|
+
toolName: "swap_get_positions",
|
|
9812
10204
|
usage: "okx swap positions [<instId>]",
|
|
9813
10205
|
description: "Get current perpetual swap positions"
|
|
9814
10206
|
},
|
|
9815
10207
|
orders: {
|
|
10208
|
+
toolName: "swap_get_orders",
|
|
9816
10209
|
usage: "okx swap orders [--instId <id>] [--history] [--archive]",
|
|
9817
10210
|
description: "List open or historical swap orders"
|
|
9818
10211
|
},
|
|
9819
10212
|
get: {
|
|
10213
|
+
toolName: "swap_get_order",
|
|
9820
10214
|
usage: "okx swap get --instId <id> --ordId <id>",
|
|
9821
10215
|
description: "Get details of a specific swap order"
|
|
9822
10216
|
},
|
|
9823
10217
|
fills: {
|
|
10218
|
+
toolName: "swap_get_fills",
|
|
9824
10219
|
usage: "okx swap fills [--instId <id>] [--ordId <id>] [--archive]",
|
|
9825
10220
|
description: "Get trade fill history for swap orders"
|
|
9826
10221
|
},
|
|
9827
10222
|
place: {
|
|
10223
|
+
toolName: "swap_place_order",
|
|
9828
10224
|
usage: "okx swap place --instId <id> --side <buy|sell> --ordType <type> --sz <n> [--posSide <side>] [--px <price>] [--tdMode <cross|isolated>] [--tpTriggerPx <price>] [--tpOrdPx <price|-1>] [--slTriggerPx <price>] [--slOrdPx <price|-1>]",
|
|
9829
10225
|
description: "Place a new perpetual swap order (supports attached TP/SL)"
|
|
9830
10226
|
},
|
|
9831
10227
|
cancel: {
|
|
10228
|
+
toolName: "swap_cancel_order",
|
|
9832
10229
|
usage: "okx swap cancel <instId> --ordId <id>",
|
|
9833
10230
|
description: "Cancel a pending swap order"
|
|
9834
10231
|
},
|
|
9835
10232
|
amend: {
|
|
10233
|
+
// swap amend uses spot_amend_order (same OKX /trade/amend-order endpoint works for all types)
|
|
10234
|
+
toolName: "spot_amend_order",
|
|
9836
10235
|
usage: "okx swap amend --instId <id> --ordId <id> [--newSz <n>] [--newPx <price>]",
|
|
9837
10236
|
description: "Amend a pending swap order"
|
|
9838
10237
|
},
|
|
9839
10238
|
close: {
|
|
10239
|
+
toolName: "swap_close_position",
|
|
9840
10240
|
usage: "okx swap close --instId <id> --mgnMode <cross|isolated> [--posSide <net|long|short>] [--autoCxl]",
|
|
9841
10241
|
description: "Close a swap position"
|
|
9842
10242
|
},
|
|
9843
10243
|
leverage: {
|
|
10244
|
+
toolName: "swap_set_leverage",
|
|
9844
10245
|
usage: "okx swap leverage --instId <id> --lever <n> --mgnMode <cross|isolated> [--posSide <side>]",
|
|
9845
10246
|
description: "Set leverage for a swap instrument"
|
|
9846
10247
|
},
|
|
9847
10248
|
"get-leverage": {
|
|
10249
|
+
toolName: "swap_get_leverage",
|
|
9848
10250
|
usage: "okx swap get-leverage --instId <id> --mgnMode <cross|isolated>",
|
|
9849
10251
|
description: "Get current leverage setting for a swap instrument"
|
|
9850
10252
|
},
|
|
9851
10253
|
batch: {
|
|
10254
|
+
toolName: "swap_batch_orders",
|
|
10255
|
+
alternateTools: ["swap_batch_amend", "swap_batch_cancel"],
|
|
9852
10256
|
usage: "okx swap batch --action <place|amend|cancel> --orders '<json>'",
|
|
9853
10257
|
description: "Batch place, amend, or cancel swap orders"
|
|
9854
10258
|
}
|
|
@@ -9858,22 +10262,27 @@ var HELP_TREE = {
|
|
|
9858
10262
|
description: "Perpetual swap algo orders (trailing stop, conditional, OCO)",
|
|
9859
10263
|
commands: {
|
|
9860
10264
|
orders: {
|
|
10265
|
+
toolName: "swap_get_algo_orders",
|
|
9861
10266
|
usage: "okx swap algo orders [--instId <id>] [--history] [--ordType <conditional|oco>]",
|
|
9862
10267
|
description: "List swap algo orders"
|
|
9863
10268
|
},
|
|
9864
10269
|
trail: {
|
|
10270
|
+
toolName: "swap_place_move_stop_order",
|
|
9865
10271
|
usage: "okx swap algo trail --instId <id> --side <buy|sell> --sz <n> --callbackRatio <ratio>\n [--activePx <price>] [--posSide <net|long|short>] [--tdMode <cross|isolated>] [--reduceOnly]",
|
|
9866
10272
|
description: "Place a trailing stop algo order for perpetual swap"
|
|
9867
10273
|
},
|
|
9868
10274
|
place: {
|
|
10275
|
+
toolName: "swap_place_algo_order",
|
|
9869
10276
|
usage: "okx swap algo place --instId <id> --side <buy|sell> --sz <n> [--ordType <conditional|oco>]\n [--tpTriggerPx <price>] [--tpOrdPx <price|-1>]\n [--slTriggerPx <price>] [--slOrdPx <price|-1>]\n [--posSide <net|long|short>] [--tdMode <cross|isolated>] [--reduceOnly]",
|
|
9870
10277
|
description: "Place a swap algo order (take-profit/stop-loss)"
|
|
9871
10278
|
},
|
|
9872
10279
|
amend: {
|
|
10280
|
+
toolName: "swap_amend_algo_order",
|
|
9873
10281
|
usage: "okx swap algo amend --instId <id> --algoId <id> [--newSz <n>]\n [--newTpTriggerPx <price>] [--newTpOrdPx <price|-1>]\n [--newSlTriggerPx <price>] [--newSlOrdPx <price|-1>]",
|
|
9874
10282
|
description: "Amend a pending swap algo order"
|
|
9875
10283
|
},
|
|
9876
10284
|
cancel: {
|
|
10285
|
+
toolName: "swap_cancel_algo_orders",
|
|
9877
10286
|
usage: "okx swap algo cancel --instId <id> --algoId <id>",
|
|
9878
10287
|
description: "Cancel a pending swap algo order"
|
|
9879
10288
|
}
|
|
@@ -9881,50 +10290,63 @@ var HELP_TREE = {
|
|
|
9881
10290
|
}
|
|
9882
10291
|
}
|
|
9883
10292
|
},
|
|
10293
|
+
// ── futures ────────────────────────────────────────────────────────────────
|
|
9884
10294
|
futures: {
|
|
9885
10295
|
description: "Futures trading (orders, positions, algo orders, leverage)",
|
|
9886
10296
|
commands: {
|
|
9887
10297
|
orders: {
|
|
10298
|
+
toolName: "futures_get_orders",
|
|
9888
10299
|
usage: "okx futures orders [--instId <id>] [--history] [--archive]",
|
|
9889
10300
|
description: "List open or historical futures orders"
|
|
9890
10301
|
},
|
|
9891
10302
|
positions: {
|
|
10303
|
+
toolName: "futures_get_positions",
|
|
9892
10304
|
usage: "okx futures positions [--instId <id>]",
|
|
9893
10305
|
description: "Get current futures positions"
|
|
9894
10306
|
},
|
|
9895
10307
|
fills: {
|
|
10308
|
+
toolName: "futures_get_fills",
|
|
9896
10309
|
usage: "okx futures fills [--instId <id>] [--ordId <id>] [--archive]",
|
|
9897
10310
|
description: "Get trade fill history for futures orders"
|
|
9898
10311
|
},
|
|
9899
10312
|
place: {
|
|
10313
|
+
toolName: "futures_place_order",
|
|
9900
10314
|
usage: "okx futures place --instId <id> --side <buy|sell> --ordType <type> --sz <n>\n [--tdMode <cross|isolated>] [--posSide <net|long|short>] [--px <price>] [--reduceOnly]\n [--tpTriggerPx <price>] [--tpOrdPx <price|-1>] [--slTriggerPx <price>] [--slOrdPx <price|-1>]",
|
|
9901
10315
|
description: "Place a new futures order (supports attached TP/SL)"
|
|
9902
10316
|
},
|
|
9903
10317
|
cancel: {
|
|
10318
|
+
toolName: "futures_cancel_order",
|
|
9904
10319
|
usage: "okx futures cancel <instId> --ordId <id>",
|
|
9905
10320
|
description: "Cancel a pending futures order"
|
|
9906
10321
|
},
|
|
9907
10322
|
amend: {
|
|
10323
|
+
toolName: "futures_amend_order",
|
|
9908
10324
|
usage: "okx futures amend --instId <id> [--ordId <id>] [--clOrdId <id>] [--newSz <n>] [--newPx <price>]",
|
|
9909
10325
|
description: "Amend a pending futures order"
|
|
9910
10326
|
},
|
|
9911
10327
|
get: {
|
|
10328
|
+
toolName: "futures_get_order",
|
|
9912
10329
|
usage: "okx futures get --instId <id> --ordId <id>",
|
|
9913
10330
|
description: "Get details of a specific futures order"
|
|
9914
10331
|
},
|
|
9915
10332
|
close: {
|
|
10333
|
+
toolName: "futures_close_position",
|
|
9916
10334
|
usage: "okx futures close --instId <id> --mgnMode <cross|isolated> [--posSide <net|long|short>] [--autoCxl]",
|
|
9917
10335
|
description: "Close a futures position"
|
|
9918
10336
|
},
|
|
9919
10337
|
"get-leverage": {
|
|
10338
|
+
toolName: "futures_get_leverage",
|
|
9920
10339
|
usage: "okx futures get-leverage --instId <id> --mgnMode <cross|isolated>",
|
|
9921
10340
|
description: "Get current leverage for a futures instrument"
|
|
9922
10341
|
},
|
|
9923
10342
|
leverage: {
|
|
10343
|
+
toolName: "futures_set_leverage",
|
|
9924
10344
|
usage: "okx futures leverage --instId <id> --lever <n> --mgnMode <cross|isolated> [--posSide <net|long|short>]",
|
|
9925
10345
|
description: "Set leverage for a futures instrument"
|
|
9926
10346
|
},
|
|
9927
10347
|
batch: {
|
|
10348
|
+
toolName: "futures_batch_orders",
|
|
10349
|
+
alternateTools: ["futures_batch_amend", "futures_batch_cancel"],
|
|
9928
10350
|
usage: "okx futures batch --action <place|amend|cancel> --orders '<json>'",
|
|
9929
10351
|
description: "Batch place, amend, or cancel futures orders"
|
|
9930
10352
|
}
|
|
@@ -9934,22 +10356,27 @@ var HELP_TREE = {
|
|
|
9934
10356
|
description: "Futures algo orders (trailing stop, conditional, OCO)",
|
|
9935
10357
|
commands: {
|
|
9936
10358
|
orders: {
|
|
10359
|
+
toolName: "futures_get_algo_orders",
|
|
9937
10360
|
usage: "okx futures algo orders [--instId <id>] [--history] [--ordType <conditional|oco>]",
|
|
9938
10361
|
description: "List futures algo orders"
|
|
9939
10362
|
},
|
|
9940
10363
|
trail: {
|
|
10364
|
+
toolName: "futures_place_move_stop_order",
|
|
9941
10365
|
usage: "okx futures algo trail --instId <id> --side <buy|sell> --sz <n> --callbackRatio <ratio>\n [--activePx <price>] [--posSide <net|long|short>] [--tdMode <cross|isolated>] [--reduceOnly]",
|
|
9942
10366
|
description: "Place a trailing stop algo order for futures"
|
|
9943
10367
|
},
|
|
9944
10368
|
place: {
|
|
10369
|
+
toolName: "futures_place_algo_order",
|
|
9945
10370
|
usage: "okx futures algo place --instId <id> --side <buy|sell> --sz <n> [--ordType <conditional|oco>]\n [--tpTriggerPx <price>] [--tpOrdPx <price|-1>]\n [--slTriggerPx <price>] [--slOrdPx <price|-1>]\n [--posSide <net|long|short>] [--tdMode <cross|isolated>] [--reduceOnly]",
|
|
9946
10371
|
description: "Place a futures algo order (take-profit/stop-loss)"
|
|
9947
10372
|
},
|
|
9948
10373
|
amend: {
|
|
10374
|
+
toolName: "futures_amend_algo_order",
|
|
9949
10375
|
usage: "okx futures algo amend --instId <id> --algoId <id> [--newSz <n>]\n [--newTpTriggerPx <price>] [--newTpOrdPx <price|-1>]\n [--newSlTriggerPx <price>] [--newSlOrdPx <price|-1>]",
|
|
9950
10376
|
description: "Amend a pending futures algo order"
|
|
9951
10377
|
},
|
|
9952
10378
|
cancel: {
|
|
10379
|
+
toolName: "futures_cancel_algo_orders",
|
|
9953
10380
|
usage: "okx futures algo cancel --instId <id> --algoId <id>",
|
|
9954
10381
|
description: "Cancel a pending futures algo order"
|
|
9955
10382
|
}
|
|
@@ -9957,51 +10384,90 @@ var HELP_TREE = {
|
|
|
9957
10384
|
}
|
|
9958
10385
|
}
|
|
9959
10386
|
},
|
|
10387
|
+
// ── option ─────────────────────────────────────────────────────────────────
|
|
9960
10388
|
option: {
|
|
9961
10389
|
description: "Options trading (orders, positions, greeks)",
|
|
9962
10390
|
commands: {
|
|
9963
10391
|
orders: {
|
|
10392
|
+
toolName: "option_get_orders",
|
|
9964
10393
|
usage: "okx option orders [--instId <id>] [--uly <uly>] [--history] [--archive]",
|
|
9965
10394
|
description: "List open or historical option orders"
|
|
9966
10395
|
},
|
|
9967
10396
|
get: {
|
|
10397
|
+
toolName: "option_get_order",
|
|
9968
10398
|
usage: "okx option get --instId <id> [--ordId <id>] [--clOrdId <id>]",
|
|
9969
10399
|
description: "Get details of a specific option order"
|
|
9970
10400
|
},
|
|
9971
10401
|
positions: {
|
|
10402
|
+
toolName: "option_get_positions",
|
|
9972
10403
|
usage: "okx option positions [--instId <id>] [--uly <uly>]",
|
|
9973
10404
|
description: "Get current option positions"
|
|
9974
10405
|
},
|
|
9975
10406
|
fills: {
|
|
10407
|
+
toolName: "option_get_fills",
|
|
9976
10408
|
usage: "okx option fills [--instId <id>] [--ordId <id>] [--archive]",
|
|
9977
10409
|
description: "Get trade fill history for option orders"
|
|
9978
10410
|
},
|
|
9979
10411
|
instruments: {
|
|
10412
|
+
toolName: "option_get_instruments",
|
|
9980
10413
|
usage: "okx option instruments --uly <uly> [--expTime <date>]",
|
|
9981
10414
|
description: "List tradable option instruments for an underlying"
|
|
9982
10415
|
},
|
|
9983
10416
|
greeks: {
|
|
10417
|
+
toolName: "option_get_greeks",
|
|
9984
10418
|
usage: "okx option greeks --uly <uly> [--expTime <date>]",
|
|
9985
10419
|
description: "Get option greeks (delta, gamma, theta, vega)"
|
|
9986
10420
|
},
|
|
9987
10421
|
place: {
|
|
10422
|
+
toolName: "option_place_order",
|
|
9988
10423
|
usage: "okx option place --instId <id> --tdMode <cash|cross|isolated> --side <buy|sell> --ordType <type> --sz <n>\n [--px <price>] [--reduceOnly] [--clOrdId <id>]",
|
|
9989
10424
|
description: "Place a new option order"
|
|
9990
10425
|
},
|
|
9991
10426
|
cancel: {
|
|
10427
|
+
toolName: "option_cancel_order",
|
|
9992
10428
|
usage: "okx option cancel --instId <id> [--ordId <id>] [--clOrdId <id>]",
|
|
9993
10429
|
description: "Cancel a pending option order"
|
|
9994
10430
|
},
|
|
9995
10431
|
amend: {
|
|
10432
|
+
toolName: "option_amend_order",
|
|
9996
10433
|
usage: "okx option amend --instId <id> [--ordId <id>] [--clOrdId <id>] [--newSz <n>] [--newPx <price>]",
|
|
9997
10434
|
description: "Amend a pending option order"
|
|
9998
10435
|
},
|
|
9999
10436
|
"batch-cancel": {
|
|
10437
|
+
toolName: "option_batch_cancel",
|
|
10000
10438
|
usage: "okx option batch-cancel --orders '<json>'",
|
|
10001
10439
|
description: "Batch cancel option orders"
|
|
10002
10440
|
}
|
|
10441
|
+
},
|
|
10442
|
+
subgroups: {
|
|
10443
|
+
algo: {
|
|
10444
|
+
description: "Option algo orders (conditional, TP/SL)",
|
|
10445
|
+
commands: {
|
|
10446
|
+
orders: {
|
|
10447
|
+
toolName: "option_get_algo_orders",
|
|
10448
|
+
usage: "okx option algo orders [--instId <id>] [--history] [--ordType <conditional|oco>]",
|
|
10449
|
+
description: "List option algo orders"
|
|
10450
|
+
},
|
|
10451
|
+
place: {
|
|
10452
|
+
toolName: "option_place_algo_order",
|
|
10453
|
+
usage: "okx option algo place --instId <id> --tdMode <cash|cross|isolated> --side <buy|sell> --sz <n>\n [--ordType <conditional|oco>] [--tpTriggerPx <price>] [--tpOrdPx <price|-1>]\n [--slTriggerPx <price>] [--slOrdPx <price|-1>] [--reduceOnly] [--clOrdId <id>]",
|
|
10454
|
+
description: "Place an option algo order (take-profit/stop-loss)"
|
|
10455
|
+
},
|
|
10456
|
+
amend: {
|
|
10457
|
+
toolName: "option_amend_algo_order",
|
|
10458
|
+
usage: "okx option algo amend --instId <id> --algoId <id> [--newSz <n>]\n [--newTpTriggerPx <price>] [--newTpOrdPx <price|-1>]\n [--newSlTriggerPx <price>] [--newSlOrdPx <price|-1>]",
|
|
10459
|
+
description: "Amend a pending option algo order"
|
|
10460
|
+
},
|
|
10461
|
+
cancel: {
|
|
10462
|
+
toolName: "option_cancel_algo_orders",
|
|
10463
|
+
usage: "okx option algo cancel --instId <id> --algoId <id>",
|
|
10464
|
+
description: "Cancel a pending option algo order"
|
|
10465
|
+
}
|
|
10466
|
+
}
|
|
10467
|
+
}
|
|
10003
10468
|
}
|
|
10004
10469
|
},
|
|
10470
|
+
// ── earn ───────────────────────────────────────────────────────────────────
|
|
10005
10471
|
earn: {
|
|
10006
10472
|
description: "Earn products \u2014 Simple Earn, On-chain Earn, and DCD (Dual Currency Deposit)",
|
|
10007
10473
|
subgroups: {
|
|
@@ -10009,38 +10475,47 @@ var HELP_TREE = {
|
|
|
10009
10475
|
description: "Simple Earn \u2014 flexible savings, fixed-term, and lending",
|
|
10010
10476
|
commands: {
|
|
10011
10477
|
balance: {
|
|
10478
|
+
toolName: "earn_get_savings_balance",
|
|
10012
10479
|
usage: "okx earn savings balance [<ccy>]",
|
|
10013
10480
|
description: "Get savings balance (optionally filter by currency)"
|
|
10014
10481
|
},
|
|
10015
10482
|
purchase: {
|
|
10483
|
+
toolName: "earn_savings_purchase",
|
|
10016
10484
|
usage: "okx earn savings purchase --ccy <ccy> --amt <n> [--rate <rate>]",
|
|
10017
10485
|
description: "Purchase Simple Earn (flexible savings). Rate defaults to 0.01 (1%)"
|
|
10018
10486
|
},
|
|
10019
10487
|
redeem: {
|
|
10488
|
+
toolName: "earn_savings_redeem",
|
|
10020
10489
|
usage: "okx earn savings redeem --ccy <ccy> --amt <n>",
|
|
10021
10490
|
description: "Redeem Simple Earn (flexible savings)"
|
|
10022
10491
|
},
|
|
10023
10492
|
"set-rate": {
|
|
10493
|
+
toolName: "earn_set_lending_rate",
|
|
10024
10494
|
usage: "okx earn savings set-rate --ccy <ccy> --rate <rate>",
|
|
10025
10495
|
description: "Set lending rate for a currency"
|
|
10026
10496
|
},
|
|
10027
10497
|
"lending-history": {
|
|
10498
|
+
toolName: "earn_get_lending_history",
|
|
10028
10499
|
usage: "okx earn savings lending-history [--ccy <ccy>] [--limit <n>]",
|
|
10029
10500
|
description: "Get personal lending records (requires auth)"
|
|
10030
10501
|
},
|
|
10031
10502
|
"rate-history": {
|
|
10503
|
+
toolName: "earn_get_lending_rate_history",
|
|
10032
10504
|
usage: "okx earn savings rate-history [--ccy <ccy>] [--limit <n>]",
|
|
10033
10505
|
description: "Query Simple Earn lending rates and fixed-term offers (requires auth)"
|
|
10034
10506
|
},
|
|
10035
10507
|
"fixed-orders": {
|
|
10508
|
+
toolName: "earn_get_fixed_order_list",
|
|
10036
10509
|
usage: "okx earn savings fixed-orders [--ccy <ccy>] [--state <pending|earning|expired|settled|cancelled>]",
|
|
10037
10510
|
description: "List fixed-term earn orders"
|
|
10038
10511
|
},
|
|
10039
10512
|
"fixed-purchase": {
|
|
10513
|
+
toolName: "earn_fixed_purchase",
|
|
10040
10514
|
usage: "okx earn savings fixed-purchase --ccy <ccy> --amt <n> --term <term> [--confirm]",
|
|
10041
10515
|
description: "Purchase Simple Earn Fixed (\u5B9A\u671F). Preview by default; add --confirm to execute. Funds locked until maturity"
|
|
10042
10516
|
},
|
|
10043
10517
|
"fixed-redeem": {
|
|
10518
|
+
toolName: "earn_fixed_redeem",
|
|
10044
10519
|
usage: "okx earn savings fixed-redeem <reqId>",
|
|
10045
10520
|
description: "Redeem a fixed-term earn order (full amount)"
|
|
10046
10521
|
}
|
|
@@ -10050,26 +10525,32 @@ var HELP_TREE = {
|
|
|
10050
10525
|
description: "On-chain Earn \u2014 staking and DeFi products",
|
|
10051
10526
|
commands: {
|
|
10052
10527
|
offers: {
|
|
10528
|
+
toolName: "onchain_earn_get_offers",
|
|
10053
10529
|
usage: "okx earn onchain offers [--productId <id>] [--protocolType <type>] [--ccy <ccy>]",
|
|
10054
10530
|
description: "Browse available on-chain earn products (staking, DeFi)"
|
|
10055
10531
|
},
|
|
10056
10532
|
purchase: {
|
|
10533
|
+
toolName: "onchain_earn_purchase",
|
|
10057
10534
|
usage: "okx earn onchain purchase --productId <id> --ccy <ccy> --amt <n> [--term <term>] [--tag <tag>]",
|
|
10058
10535
|
description: "Purchase an on-chain earn product (stake/deposit)"
|
|
10059
10536
|
},
|
|
10060
10537
|
redeem: {
|
|
10538
|
+
toolName: "onchain_earn_redeem",
|
|
10061
10539
|
usage: "okx earn onchain redeem --ordId <id> --protocolType <type> [--allowEarlyRedeem]",
|
|
10062
10540
|
description: "Redeem an on-chain earn position"
|
|
10063
10541
|
},
|
|
10064
10542
|
cancel: {
|
|
10543
|
+
toolName: "onchain_earn_cancel",
|
|
10065
10544
|
usage: "okx earn onchain cancel --ordId <id> --protocolType <type>",
|
|
10066
10545
|
description: "Cancel a pending on-chain earn order"
|
|
10067
10546
|
},
|
|
10068
10547
|
orders: {
|
|
10548
|
+
toolName: "onchain_earn_get_active_orders",
|
|
10069
10549
|
usage: "okx earn onchain orders [--productId <id>] [--protocolType <type>] [--ccy <ccy>] [--state <state>]",
|
|
10070
10550
|
description: "List active on-chain earn orders"
|
|
10071
10551
|
},
|
|
10072
10552
|
history: {
|
|
10553
|
+
toolName: "onchain_earn_get_order_history",
|
|
10073
10554
|
usage: "okx earn onchain history [--productId <id>] [--protocolType <type>] [--ccy <ccy>]",
|
|
10074
10555
|
description: "Get on-chain earn order history"
|
|
10075
10556
|
}
|
|
@@ -10079,14 +10560,19 @@ var HELP_TREE = {
|
|
|
10079
10560
|
description: "Auto-earn \u2014 automatically lend, stake, or earn on idle assets",
|
|
10080
10561
|
commands: {
|
|
10081
10562
|
status: {
|
|
10563
|
+
// CLI reads from account_get_balance; earn_auto_set is covered by 'on' command below
|
|
10564
|
+
toolName: null,
|
|
10082
10565
|
usage: "okx earn auto-earn status [<ccy>]",
|
|
10083
10566
|
description: "Query auto-earn status for all or a specific currency"
|
|
10084
10567
|
},
|
|
10085
10568
|
on: {
|
|
10569
|
+
toolName: "earn_auto_set",
|
|
10086
10570
|
usage: "okx earn auto-earn on <ccy>",
|
|
10087
10571
|
description: "Enable auto-earn for a currency (auto-detects lend/stake vs USDG earn)"
|
|
10088
10572
|
},
|
|
10089
10573
|
off: {
|
|
10574
|
+
// same tool as 'on'; earn_auto_set already registered above
|
|
10575
|
+
toolName: "earn_auto_set",
|
|
10090
10576
|
usage: "okx earn auto-earn off <ccy>",
|
|
10091
10577
|
description: "Disable auto-earn for a currency"
|
|
10092
10578
|
}
|
|
@@ -10096,26 +10582,32 @@ var HELP_TREE = {
|
|
|
10096
10582
|
description: "DCD (Dual Currency Deposit) \u2014 structured products with fixed yield",
|
|
10097
10583
|
commands: {
|
|
10098
10584
|
pairs: {
|
|
10585
|
+
toolName: "dcd_get_currency_pairs",
|
|
10099
10586
|
usage: "okx earn dcd pairs",
|
|
10100
10587
|
description: "List available DCD currency pairs"
|
|
10101
10588
|
},
|
|
10102
10589
|
products: {
|
|
10590
|
+
toolName: "dcd_get_products",
|
|
10103
10591
|
usage: "okx earn dcd products --baseCcy <ccy> --quoteCcy <ccy> --optType <C|P>\n [--minYield <n>] [--strikeNear <price>]\n [--termDays <n>] [--minTermDays <n>] [--maxTermDays <n>]\n [--expDate <YYYY-MM-DD|YYYY-MM-DDTHH:mm>]",
|
|
10104
10592
|
description: "List active DCD products (baseCcy, quoteCcy, optType required). Client-side filters: minYield (e.g. 0.05=5%), strikeNear (\xB110%), term range, expDate"
|
|
10105
10593
|
},
|
|
10106
10594
|
"quote-and-buy": {
|
|
10595
|
+
toolName: "dcd_subscribe",
|
|
10107
10596
|
usage: "okx earn dcd quote-and-buy --productId <id> --sz <n> --notionalCcy <ccy> [--clOrdId <id>] [--minAnnualizedYield <pct>]",
|
|
10108
10597
|
description: "[CAUTION] Subscribe to a DCD product atomically (quote + execute in one step)"
|
|
10109
10598
|
},
|
|
10110
10599
|
"redeem-execute": {
|
|
10600
|
+
toolName: "dcd_redeem",
|
|
10111
10601
|
usage: "okx earn dcd redeem-execute --ordId <id>",
|
|
10112
10602
|
description: "[CAUTION] Re-quote and execute early redemption in one step (recommended for AI agent use)"
|
|
10113
10603
|
},
|
|
10114
10604
|
order: {
|
|
10605
|
+
toolName: "dcd_get_order_state",
|
|
10115
10606
|
usage: "okx earn dcd order --ordId <id>",
|
|
10116
10607
|
description: "Query current state of a DCD order"
|
|
10117
10608
|
},
|
|
10118
10609
|
orders: {
|
|
10610
|
+
toolName: "dcd_get_orders",
|
|
10119
10611
|
usage: "okx earn dcd orders [--ordId <id>] [--productId <id>] [--uly <uly>] [--state <state>] [--limit <n>]",
|
|
10120
10612
|
description: "Get DCD order history. State: initial|live|pending_settle|settled|pending_redeem|redeemed|rejected"
|
|
10121
10613
|
}
|
|
@@ -10123,6 +10615,7 @@ var HELP_TREE = {
|
|
|
10123
10615
|
}
|
|
10124
10616
|
}
|
|
10125
10617
|
},
|
|
10618
|
+
// ── bot ────────────────────────────────────────────────────────────────────
|
|
10126
10619
|
bot: {
|
|
10127
10620
|
description: "Trading bot strategies (grid, dca)",
|
|
10128
10621
|
subgroups: {
|
|
@@ -10130,22 +10623,27 @@ var HELP_TREE = {
|
|
|
10130
10623
|
description: "Grid trading bot \u2014 create, monitor, and stop grid orders",
|
|
10131
10624
|
commands: {
|
|
10132
10625
|
orders: {
|
|
10626
|
+
toolName: "grid_get_orders",
|
|
10133
10627
|
usage: "okx bot grid orders --algoOrdType <grid|contract_grid|moon_grid> [--instId <id>] [--algoId <id>] [--history]",
|
|
10134
10628
|
description: "List active or historical grid bot orders"
|
|
10135
10629
|
},
|
|
10136
10630
|
details: {
|
|
10631
|
+
toolName: "grid_get_order_details",
|
|
10137
10632
|
usage: "okx bot grid details --algoOrdType <type> --algoId <id>",
|
|
10138
10633
|
description: "Get details of a specific grid bot order"
|
|
10139
10634
|
},
|
|
10140
10635
|
"sub-orders": {
|
|
10636
|
+
toolName: "grid_get_sub_orders",
|
|
10141
10637
|
usage: "okx bot grid sub-orders --algoOrdType <type> --algoId <id> [--live]",
|
|
10142
10638
|
description: "List sub-orders of a grid bot (filled or live)"
|
|
10143
10639
|
},
|
|
10144
10640
|
create: {
|
|
10641
|
+
toolName: "grid_create_order",
|
|
10145
10642
|
usage: "okx bot grid create --instId <id> --algoOrdType <grid|contract_grid> --maxPx <px> --minPx <px> --gridNum <n>\n [--runType <1|2>] [--quoteSz <n>] [--baseSz <n>]\n [--direction <long|short|neutral>] [--lever <n>] [--sz <n>] [--basePos] [--no-basePos]\n [--tpTriggerPx <px>] [--slTriggerPx <px>] [--tpRatio <n>] [--slRatio <n>] [--algoClOrdId <id>]",
|
|
10146
10643
|
description: "Create a new grid bot order (contract grid opens base position by default)"
|
|
10147
10644
|
},
|
|
10148
10645
|
stop: {
|
|
10646
|
+
toolName: "grid_stop_order",
|
|
10149
10647
|
usage: "okx bot grid stop --algoId <id> --algoOrdType <type> --instId <id> [--stopType <1|2|3|5|6>]",
|
|
10150
10648
|
description: "Stop a running grid bot order"
|
|
10151
10649
|
}
|
|
@@ -10155,22 +10653,27 @@ var HELP_TREE = {
|
|
|
10155
10653
|
description: "DCA (Martingale) bot \u2014 spot or contract recurring buys",
|
|
10156
10654
|
commands: {
|
|
10157
10655
|
orders: {
|
|
10656
|
+
toolName: "dca_get_orders",
|
|
10158
10657
|
usage: "okx bot dca orders [--algoOrdType <spot_dca|contract_dca>] [--algoId <id>] [--instId <id>] [--history]",
|
|
10159
10658
|
description: "List DCA bots (spot and/or contract)"
|
|
10160
10659
|
},
|
|
10161
10660
|
details: {
|
|
10661
|
+
toolName: "dca_get_order_details",
|
|
10162
10662
|
usage: "okx bot dca details --algoOrdType <spot_dca|contract_dca> --algoId <id>",
|
|
10163
10663
|
description: "Get DCA bot details (spot or contract)"
|
|
10164
10664
|
},
|
|
10165
10665
|
"sub-orders": {
|
|
10666
|
+
toolName: "dca_get_sub_orders",
|
|
10166
10667
|
usage: "okx bot dca sub-orders --algoOrdType <spot_dca|contract_dca> --algoId <id> [--cycleId <id>]",
|
|
10167
10668
|
description: "Get DCA cycles/orders (spot or contract)"
|
|
10168
10669
|
},
|
|
10169
10670
|
create: {
|
|
10671
|
+
toolName: "dca_create_order",
|
|
10170
10672
|
usage: "okx bot dca create --algoOrdType <spot_dca|contract_dca> --instId <id> --direction <long|short>\n --initOrdAmt <n> --maxSafetyOrds <n> --tpPct <n>\n [--lever <n>] [--safetyOrdAmt <n>] [--pxSteps <n>] [--pxStepsMult <n>] [--volMult <n>]\n [--slPct <n>] [--slMode <limit|market>] [--allowReinvest <true|false>]\n [--triggerStrategy <instant|price|rsi>] [--triggerPx <price>]\n [--triggerCond <cross_up|cross_down>] [--thold <n>] [--timeframe <tf>] [--timePeriod <n>]\n [--algoClOrdId <id>] [--reserveFunds <true|false>] [--tradeQuoteCcy <ccy>]\n Note: --lever required for contract_dca; safetyOrdAmt, pxSteps, pxStepsMult, volMult required when maxSafetyOrds > 0\n triggerStrategy: contract_dca supports instant|price|rsi; spot_dca supports instant|rsi",
|
|
10171
10673
|
description: "Create a DCA (Martingale) bot (spot or contract)"
|
|
10172
10674
|
},
|
|
10173
10675
|
stop: {
|
|
10676
|
+
toolName: "dca_stop_order",
|
|
10174
10677
|
usage: "okx bot dca stop --algoOrdType <spot_dca|contract_dca> --algoId <id> [--stopType <1|2>]\n Note: --stopType required for spot_dca (1=sell all, 2=keep tokens)",
|
|
10175
10678
|
description: "Stop a DCA bot (spot or contract)"
|
|
10176
10679
|
}
|
|
@@ -10178,73 +10681,254 @@ var HELP_TREE = {
|
|
|
10178
10681
|
}
|
|
10179
10682
|
}
|
|
10180
10683
|
},
|
|
10684
|
+
// ── config ─────────────────────────────────────────────────────────────────
|
|
10181
10685
|
config: {
|
|
10182
10686
|
description: "Manage CLI configuration profiles",
|
|
10183
10687
|
commands: {
|
|
10184
10688
|
init: {
|
|
10689
|
+
toolName: null,
|
|
10185
10690
|
usage: "okx config init [--lang zh]",
|
|
10186
10691
|
description: "Initialize a new configuration profile interactively"
|
|
10187
10692
|
},
|
|
10188
10693
|
show: {
|
|
10694
|
+
toolName: null,
|
|
10189
10695
|
usage: "okx config show",
|
|
10190
10696
|
description: `Show current configuration (file: ${configFilePath()})`
|
|
10191
10697
|
},
|
|
10192
10698
|
set: {
|
|
10699
|
+
toolName: null,
|
|
10193
10700
|
usage: "okx config set <key> <value>",
|
|
10194
10701
|
description: "Set a configuration value"
|
|
10195
10702
|
},
|
|
10196
10703
|
"setup-clients": {
|
|
10704
|
+
toolName: null,
|
|
10197
10705
|
usage: "okx config setup-clients",
|
|
10198
10706
|
description: "Set up MCP client integrations (Cursor, Windsurf, etc.)"
|
|
10199
10707
|
}
|
|
10200
10708
|
}
|
|
10201
10709
|
},
|
|
10710
|
+
// ── setup ──────────────────────────────────────────────────────────────────
|
|
10202
10711
|
setup: {
|
|
10203
10712
|
description: "Set up client integrations (Cursor, Windsurf, Claude, etc.)",
|
|
10204
10713
|
usage: `okx setup --client <${SUPPORTED_CLIENTS.join("|")}> [--profile <name>] [--modules <list>]`
|
|
10205
10714
|
},
|
|
10715
|
+
// ── doh ────────────────────────────────────────────────────────────────────
|
|
10716
|
+
doh: {
|
|
10717
|
+
description: "Manage DoH (DNS-over-HTTPS) resolver binary",
|
|
10718
|
+
commands: {
|
|
10719
|
+
status: {
|
|
10720
|
+
toolName: null,
|
|
10721
|
+
usage: "okx doh status [--json]",
|
|
10722
|
+
description: "Show DoH binary info, checksum, and CDN match status"
|
|
10723
|
+
},
|
|
10724
|
+
install: {
|
|
10725
|
+
toolName: null,
|
|
10726
|
+
usage: "okx doh install [--json]",
|
|
10727
|
+
description: "Download or update the DoH resolver binary"
|
|
10728
|
+
},
|
|
10729
|
+
remove: {
|
|
10730
|
+
toolName: null,
|
|
10731
|
+
usage: "okx doh remove [--force] [--json]",
|
|
10732
|
+
description: "Remove the DoH resolver binary (prompts for confirmation without --force)"
|
|
10733
|
+
}
|
|
10734
|
+
}
|
|
10735
|
+
},
|
|
10736
|
+
// ── diagnose ───────────────────────────────────────────────────────────────
|
|
10206
10737
|
diagnose: {
|
|
10207
10738
|
description: "Run network / MCP server diagnostics",
|
|
10208
10739
|
usage: "okx diagnose [--cli | --mcp | --all] [--profile <name>] [--demo | --live] [--output <file>]"
|
|
10209
10740
|
},
|
|
10741
|
+
// ── skill ──────────────────────────────────────────────────────────────────
|
|
10210
10742
|
skill: {
|
|
10211
10743
|
description: "OKX Skills Marketplace \u2014 search, install, and manage agent skills",
|
|
10212
10744
|
commands: {
|
|
10213
10745
|
search: {
|
|
10746
|
+
toolName: "skills_search",
|
|
10214
10747
|
usage: "okx skill search [--keyword <kw>] [--categories <id>] [--page <n>] [--limit <n>]",
|
|
10215
10748
|
description: "Search for skills in the marketplace"
|
|
10216
10749
|
},
|
|
10217
10750
|
categories: {
|
|
10751
|
+
toolName: "skills_get_categories",
|
|
10218
10752
|
usage: "okx skill categories",
|
|
10219
10753
|
description: "List available skill categories"
|
|
10220
10754
|
},
|
|
10221
10755
|
add: {
|
|
10756
|
+
// Composite: downloads + installs via npx; no single ToolSpec
|
|
10757
|
+
toolName: null,
|
|
10222
10758
|
usage: "okx skill add <name>",
|
|
10223
10759
|
description: "Download and install a skill to detected agents"
|
|
10224
10760
|
},
|
|
10225
10761
|
download: {
|
|
10762
|
+
// CLI calls downloadSkillZip directly (same capability as skills_download ToolSpec)
|
|
10763
|
+
toolName: "skills_download",
|
|
10226
10764
|
usage: "okx skill download <name> [--dir <path>] [--format zip|skill]",
|
|
10227
10765
|
description: "Download a skill package without installing"
|
|
10228
10766
|
},
|
|
10229
10767
|
remove: {
|
|
10768
|
+
toolName: null,
|
|
10230
10769
|
usage: "okx skill remove <name>",
|
|
10231
10770
|
description: "Remove an installed skill"
|
|
10232
10771
|
},
|
|
10233
10772
|
check: {
|
|
10773
|
+
// Uses skills_search internally; skills_search already registered above
|
|
10774
|
+
toolName: null,
|
|
10234
10775
|
usage: "okx skill check <name>",
|
|
10235
10776
|
description: "Check if an installed skill has a newer version"
|
|
10236
10777
|
},
|
|
10237
10778
|
list: {
|
|
10779
|
+
toolName: null,
|
|
10238
10780
|
usage: "okx skill list",
|
|
10239
10781
|
description: "List all locally installed skills"
|
|
10240
10782
|
}
|
|
10241
10783
|
}
|
|
10242
10784
|
},
|
|
10785
|
+
// ── upgrade ────────────────────────────────────────────────────────────────
|
|
10243
10786
|
upgrade: {
|
|
10244
10787
|
description: "Upgrade okx CLI and MCP server to the latest stable version",
|
|
10245
10788
|
usage: "okx upgrade [--check] [--beta] [--force] [--json]"
|
|
10246
10789
|
}
|
|
10247
10790
|
};
|
|
10791
|
+
|
|
10792
|
+
// src/help-generator.ts
|
|
10793
|
+
function buildSpecMap() {
|
|
10794
|
+
return new Map(allToolSpecs().map((s) => [s.name, s]));
|
|
10795
|
+
}
|
|
10796
|
+
function resolveCommandDescription(entry, specMap, fallback = "(no description)") {
|
|
10797
|
+
if (entry.description) return entry.description;
|
|
10798
|
+
if (entry.toolName != null) {
|
|
10799
|
+
const spec = specMap.get(entry.toolName);
|
|
10800
|
+
if (spec?.description) return spec.description.split(/\.\s/)[0] + ".";
|
|
10801
|
+
}
|
|
10802
|
+
return fallback;
|
|
10803
|
+
}
|
|
10804
|
+
function buildCommands(commands, specMap) {
|
|
10805
|
+
const result = {};
|
|
10806
|
+
for (const [name, entry] of Object.entries(commands)) {
|
|
10807
|
+
result[name] = {
|
|
10808
|
+
usage: entry.usage,
|
|
10809
|
+
description: resolveCommandDescription(entry, specMap)
|
|
10810
|
+
};
|
|
10811
|
+
}
|
|
10812
|
+
return result;
|
|
10813
|
+
}
|
|
10814
|
+
function buildGroupInfo(key, mod, specMap) {
|
|
10815
|
+
const description = mod.description ?? MODULE_DESCRIPTIONS[key] ?? key;
|
|
10816
|
+
return {
|
|
10817
|
+
description,
|
|
10818
|
+
usage: mod.usage,
|
|
10819
|
+
commands: mod.commands ? buildCommands(mod.commands, specMap) : void 0,
|
|
10820
|
+
subgroups: mod.subgroups ? buildSubgroups(mod.subgroups, specMap) : void 0
|
|
10821
|
+
};
|
|
10822
|
+
}
|
|
10823
|
+
function buildSubgroups(subgroups, specMap) {
|
|
10824
|
+
const result = {};
|
|
10825
|
+
for (const [name, entry] of Object.entries(subgroups)) {
|
|
10826
|
+
result[name] = buildGroupInfo(name, entry, specMap);
|
|
10827
|
+
}
|
|
10828
|
+
return result;
|
|
10829
|
+
}
|
|
10830
|
+
var _cached = null;
|
|
10831
|
+
function generateHelpTree() {
|
|
10832
|
+
if (_cached) return _cached;
|
|
10833
|
+
const specMap = buildSpecMap();
|
|
10834
|
+
const tree = {};
|
|
10835
|
+
for (const [key, mod] of Object.entries(CLI_REGISTRY)) {
|
|
10836
|
+
tree[key] = buildGroupInfo(key, mod, specMap);
|
|
10837
|
+
}
|
|
10838
|
+
_cached = tree;
|
|
10839
|
+
return tree;
|
|
10840
|
+
}
|
|
10841
|
+
|
|
10842
|
+
// src/commands/discovery.ts
|
|
10843
|
+
function extractParameters(toolName, specMap) {
|
|
10844
|
+
if (toolName == null) return [];
|
|
10845
|
+
const spec = specMap.get(toolName);
|
|
10846
|
+
if (!spec?.inputSchema) return [];
|
|
10847
|
+
const schema = spec.inputSchema;
|
|
10848
|
+
if (!schema.properties) return [];
|
|
10849
|
+
const required = new Set(schema.required ?? []);
|
|
10850
|
+
return Object.entries(schema.properties).map(([name, prop]) => ({
|
|
10851
|
+
name,
|
|
10852
|
+
type: prop.type ?? "string",
|
|
10853
|
+
required: required.has(name),
|
|
10854
|
+
description: prop.description
|
|
10855
|
+
}));
|
|
10856
|
+
}
|
|
10857
|
+
function collectCommands(modulePath, mod, specMap, commands) {
|
|
10858
|
+
for (const [cmdName, entry] of Object.entries(mod.commands ?? {})) {
|
|
10859
|
+
commands.push({
|
|
10860
|
+
path: `${modulePath} ${cmdName}`,
|
|
10861
|
+
toolName: entry.toolName,
|
|
10862
|
+
description: resolveCommandDescription(entry, specMap, ""),
|
|
10863
|
+
parameters: extractParameters(entry.toolName, specMap)
|
|
10864
|
+
});
|
|
10865
|
+
}
|
|
10866
|
+
for (const [sgName, sg] of Object.entries(mod.subgroups ?? {})) {
|
|
10867
|
+
collectCommands(`${modulePath} ${sgName}`, sg, specMap, commands);
|
|
10868
|
+
}
|
|
10869
|
+
}
|
|
10870
|
+
function getDiscoveryOutput() {
|
|
10871
|
+
const specs = allToolSpecs();
|
|
10872
|
+
const specMap = new Map(specs.map((s) => [s.name, s]));
|
|
10873
|
+
const moduleDescMap = new Map(specs.map((s) => [s.module, s.description]));
|
|
10874
|
+
const version = readCliVersion();
|
|
10875
|
+
const modules = [];
|
|
10876
|
+
for (const [moduleKey, moduleEntry] of Object.entries(CLI_REGISTRY)) {
|
|
10877
|
+
const commands = [];
|
|
10878
|
+
collectCommands(`okx ${moduleKey}`, moduleEntry, specMap, commands);
|
|
10879
|
+
const description = moduleEntry.description ?? MODULE_DESCRIPTIONS[moduleKey] ?? moduleDescMap.get(moduleKey) ?? moduleKey;
|
|
10880
|
+
modules.push({
|
|
10881
|
+
name: moduleKey,
|
|
10882
|
+
description,
|
|
10883
|
+
commands
|
|
10884
|
+
});
|
|
10885
|
+
}
|
|
10886
|
+
const totalTools = modules.reduce(
|
|
10887
|
+
(sum, m) => sum + m.commands.filter((c) => c.toolName !== null).length,
|
|
10888
|
+
0
|
|
10889
|
+
);
|
|
10890
|
+
return { version, totalTools, modules };
|
|
10891
|
+
}
|
|
10892
|
+
function cmdListTools(json) {
|
|
10893
|
+
const data = getDiscoveryOutput();
|
|
10894
|
+
if (json) {
|
|
10895
|
+
output(JSON.stringify(data, null, 2) + "\n");
|
|
10896
|
+
return;
|
|
10897
|
+
}
|
|
10898
|
+
const lines = [
|
|
10899
|
+
"",
|
|
10900
|
+
`OKX CLI v${data.version} \u2014 ${data.totalTools} tool-backed commands across ${data.modules.length} modules`,
|
|
10901
|
+
"",
|
|
10902
|
+
"Modules:"
|
|
10903
|
+
];
|
|
10904
|
+
for (const mod of data.modules) {
|
|
10905
|
+
const toolCmds = mod.commands.filter((c) => c.toolName !== null).length;
|
|
10906
|
+
if (toolCmds > 0) {
|
|
10907
|
+
lines.push(` ${mod.name.padEnd(14)}${toolCmds} commands`);
|
|
10908
|
+
}
|
|
10909
|
+
}
|
|
10910
|
+
lines.push("", 'Use "okx list-tools --json" for machine-readable output.', "");
|
|
10911
|
+
output(lines.join("\n"));
|
|
10912
|
+
}
|
|
10913
|
+
|
|
10914
|
+
// src/config/loader.ts
|
|
10915
|
+
function loadProfileConfig(opts) {
|
|
10916
|
+
return loadConfig({
|
|
10917
|
+
profile: opts.profile,
|
|
10918
|
+
modules: opts.modules,
|
|
10919
|
+
readOnly: opts.readOnly ?? false,
|
|
10920
|
+
demo: opts.demo,
|
|
10921
|
+
live: opts.live,
|
|
10922
|
+
site: opts.site,
|
|
10923
|
+
userAgent: opts.userAgent,
|
|
10924
|
+
sourceTag: opts.sourceTag,
|
|
10925
|
+
verbose: opts.verbose
|
|
10926
|
+
});
|
|
10927
|
+
}
|
|
10928
|
+
|
|
10929
|
+
// src/help.ts
|
|
10930
|
+
import { EOL as EOL2 } from "os";
|
|
10931
|
+
var HELP_TREE = generateHelpTree();
|
|
10248
10932
|
function printGlobalHelp() {
|
|
10249
10933
|
const lines = [
|
|
10250
10934
|
"",
|
|
@@ -13366,14 +14050,14 @@ async function cmdDcdQuoteAndBuy(run, opts) {
|
|
|
13366
14050
|
}
|
|
13367
14051
|
|
|
13368
14052
|
// src/commands/skill.ts
|
|
13369
|
-
import { tmpdir, homedir as
|
|
13370
|
-
import { join as
|
|
13371
|
-
import { mkdirSync as
|
|
14053
|
+
import { tmpdir, homedir as homedir10 } from "os";
|
|
14054
|
+
import { join as join12, dirname as dirname8 } from "path";
|
|
14055
|
+
import { mkdirSync as mkdirSync10, rmSync, existsSync as existsSync8, copyFileSync as copyFileSync2 } from "fs";
|
|
13372
14056
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
13373
14057
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
13374
14058
|
function resolveNpx() {
|
|
13375
|
-
const sibling =
|
|
13376
|
-
if (
|
|
14059
|
+
const sibling = join12(dirname8(process.execPath), "npx");
|
|
14060
|
+
if (existsSync8(sibling)) return sibling;
|
|
13377
14061
|
return "npx";
|
|
13378
14062
|
}
|
|
13379
14063
|
var THIRD_PARTY_INSTALL_NOTICE = "Note: This skill was created by a third-party developer, not by OKX. Review SKILL.md before use.";
|
|
@@ -13426,13 +14110,13 @@ async function cmdSkillCategories(run, json) {
|
|
|
13426
14110
|
outputLine("");
|
|
13427
14111
|
}
|
|
13428
14112
|
async function cmdSkillAdd(name, config, json) {
|
|
13429
|
-
const tmpBase =
|
|
13430
|
-
|
|
14113
|
+
const tmpBase = join12(tmpdir(), `okx-skill-${randomUUID2()}`);
|
|
14114
|
+
mkdirSync10(tmpBase, { recursive: true });
|
|
13431
14115
|
try {
|
|
13432
14116
|
outputLine(`Downloading ${name}...`);
|
|
13433
14117
|
const client = new OkxRestClient(config);
|
|
13434
14118
|
const zipPath = await downloadSkillZip(client, name, tmpBase);
|
|
13435
|
-
const contentDir = await extractSkillZip(zipPath,
|
|
14119
|
+
const contentDir = await extractSkillZip(zipPath, join12(tmpBase, "content"));
|
|
13436
14120
|
const meta = readMetaJson(contentDir);
|
|
13437
14121
|
validateSkillMdExists(contentDir);
|
|
13438
14122
|
outputLine("Installing to detected agents...");
|
|
@@ -13442,7 +14126,7 @@ async function cmdSkillAdd(name, config, json) {
|
|
|
13442
14126
|
timeout: 6e4
|
|
13443
14127
|
});
|
|
13444
14128
|
} catch (e) {
|
|
13445
|
-
const savedZip =
|
|
14129
|
+
const savedZip = join12(process.cwd(), `${name}.zip`);
|
|
13446
14130
|
try {
|
|
13447
14131
|
copyFileSync2(zipPath, savedZip);
|
|
13448
14132
|
} catch {
|
|
@@ -13481,7 +14165,7 @@ function cmdSkillRemove(name, json) {
|
|
|
13481
14165
|
timeout: 6e4
|
|
13482
14166
|
});
|
|
13483
14167
|
} catch {
|
|
13484
|
-
const agentsPath =
|
|
14168
|
+
const agentsPath = join12(homedir10(), ".agents", "skills", name);
|
|
13485
14169
|
try {
|
|
13486
14170
|
rmSync(agentsPath, { recursive: true, force: true });
|
|
13487
14171
|
} catch {
|
|
@@ -13554,10 +14238,171 @@ function printSkillInstallResult(meta, json) {
|
|
|
13554
14238
|
}
|
|
13555
14239
|
}
|
|
13556
14240
|
|
|
14241
|
+
// src/commands/doh.ts
|
|
14242
|
+
import readline from "readline";
|
|
14243
|
+
function resolveChecksumMatch(local, cdnChecksum, cdnError) {
|
|
14244
|
+
if (!local.exists) return "not-installed";
|
|
14245
|
+
if (cdnError || !cdnChecksum) return "unavailable";
|
|
14246
|
+
if (cdnChecksum.sha256 === local.sha256) return "match";
|
|
14247
|
+
return "mismatch";
|
|
14248
|
+
}
|
|
14249
|
+
function checksumMatchLabel(match) {
|
|
14250
|
+
if (match === "match") return "\u2713 match";
|
|
14251
|
+
if (match === "mismatch") return "\u2717 mismatch (update available)";
|
|
14252
|
+
return "CDN unreachable";
|
|
14253
|
+
}
|
|
14254
|
+
function formatStatusText(local, checksumMatch, cdnChecksum, runtimeMode) {
|
|
14255
|
+
outputLine("");
|
|
14256
|
+
outputLine(" DoH Resolver Status");
|
|
14257
|
+
outputLine(" " + "\u2500".repeat(40));
|
|
14258
|
+
outputLine(` Binary path : ${local.binaryPath}`);
|
|
14259
|
+
outputLine(` Installed : ${local.exists ? "yes" : "no"}`);
|
|
14260
|
+
outputLine(` Platform : ${local.platform ?? "(unsupported)"}`);
|
|
14261
|
+
if (local.exists) {
|
|
14262
|
+
outputLine(` File size : ${formatBytes(local.fileSize)}`);
|
|
14263
|
+
outputLine(` SHA-256 : ${local.sha256 ?? "(unknown)"}`);
|
|
14264
|
+
outputLine(` CDN check : ${checksumMatchLabel(checksumMatch)}`);
|
|
14265
|
+
if (cdnChecksum) {
|
|
14266
|
+
outputLine(` CDN source : ${cdnChecksum.source}`);
|
|
14267
|
+
}
|
|
14268
|
+
}
|
|
14269
|
+
outputLine(` Runtime mode: ${runtimeMode}`);
|
|
14270
|
+
outputLine("");
|
|
14271
|
+
}
|
|
14272
|
+
async function cmdDohStatus(json, binaryPath) {
|
|
14273
|
+
const local = getDohStatus(binaryPath);
|
|
14274
|
+
let runtimeMode = "no cache";
|
|
14275
|
+
try {
|
|
14276
|
+
const cacheEntry = readCache("www.okx.com");
|
|
14277
|
+
if (cacheEntry) {
|
|
14278
|
+
runtimeMode = cacheEntry.mode;
|
|
14279
|
+
}
|
|
14280
|
+
} catch {
|
|
14281
|
+
}
|
|
14282
|
+
let cdnChecksum = null;
|
|
14283
|
+
let cdnError = null;
|
|
14284
|
+
if (local.exists) {
|
|
14285
|
+
try {
|
|
14286
|
+
cdnChecksum = await fetchCdnChecksum(void 0, 5e3);
|
|
14287
|
+
} catch (err) {
|
|
14288
|
+
cdnError = err instanceof Error ? err.message : String(err);
|
|
14289
|
+
}
|
|
14290
|
+
}
|
|
14291
|
+
const checksumMatch = resolveChecksumMatch(local, cdnChecksum, cdnError);
|
|
14292
|
+
if (json) {
|
|
14293
|
+
outputLine(
|
|
14294
|
+
JSON.stringify({
|
|
14295
|
+
binaryPath: local.binaryPath,
|
|
14296
|
+
exists: local.exists,
|
|
14297
|
+
platform: local.platform,
|
|
14298
|
+
fileSize: local.fileSize ?? null,
|
|
14299
|
+
sha256: local.sha256 ?? null,
|
|
14300
|
+
cdnMatch: checksumMatch,
|
|
14301
|
+
cdnSha256: cdnChecksum?.sha256 ?? null,
|
|
14302
|
+
cdnSource: cdnChecksum?.source ?? null,
|
|
14303
|
+
runtimeMode
|
|
14304
|
+
})
|
|
14305
|
+
);
|
|
14306
|
+
return;
|
|
14307
|
+
}
|
|
14308
|
+
formatStatusText(local, checksumMatch, cdnChecksum, runtimeMode);
|
|
14309
|
+
}
|
|
14310
|
+
async function cmdDohInstall(json, binaryPath) {
|
|
14311
|
+
const messages2 = [];
|
|
14312
|
+
const onProgress = (msg) => {
|
|
14313
|
+
if (!json) {
|
|
14314
|
+
outputLine(` ${msg}`);
|
|
14315
|
+
}
|
|
14316
|
+
messages2.push(msg);
|
|
14317
|
+
};
|
|
14318
|
+
if (!json) {
|
|
14319
|
+
outputLine("");
|
|
14320
|
+
outputLine(" Installing DoH resolver...");
|
|
14321
|
+
}
|
|
14322
|
+
const result = await installDohBinary(binaryPath, void 0, onProgress);
|
|
14323
|
+
if (json) {
|
|
14324
|
+
outputLine(JSON.stringify({ status: result.status, source: result.source ?? null, error: result.error ?? null, messages: messages2 }));
|
|
14325
|
+
if (result.status === "failed") {
|
|
14326
|
+
process.exitCode = 1;
|
|
14327
|
+
}
|
|
14328
|
+
return;
|
|
14329
|
+
}
|
|
14330
|
+
if (result.status === "installed") {
|
|
14331
|
+
outputLine(` \u2713 DoH resolver installed successfully (${result.source ?? ""})`);
|
|
14332
|
+
} else if (result.status === "up-to-date") {
|
|
14333
|
+
outputLine(" \u2713 DoH resolver is already up to date");
|
|
14334
|
+
} else {
|
|
14335
|
+
errorLine(` \u2717 Installation failed: ${result.error ?? "unknown error"}`);
|
|
14336
|
+
errorLine(" Hint: check network connectivity or try again later");
|
|
14337
|
+
process.exitCode = 1;
|
|
14338
|
+
}
|
|
14339
|
+
outputLine("");
|
|
14340
|
+
}
|
|
14341
|
+
async function cmdDohRemove(force, json, binaryPath) {
|
|
14342
|
+
const local = getDohStatus(binaryPath);
|
|
14343
|
+
if (!local.exists) {
|
|
14344
|
+
if (json) {
|
|
14345
|
+
outputLine(JSON.stringify({ status: "not-installed" }));
|
|
14346
|
+
} else {
|
|
14347
|
+
outputLine(" DoH resolver is not installed.");
|
|
14348
|
+
}
|
|
14349
|
+
return;
|
|
14350
|
+
}
|
|
14351
|
+
if (!force) {
|
|
14352
|
+
if (!process.stdin.isTTY) {
|
|
14353
|
+
errorLine(" Error: stdin is not a TTY. Use --force to skip confirmation.");
|
|
14354
|
+
process.exitCode = 1;
|
|
14355
|
+
return;
|
|
14356
|
+
}
|
|
14357
|
+
const confirmed = await askConfirmation(
|
|
14358
|
+
` Remove DoH resolver at ${local.binaryPath}? [y/N] `
|
|
14359
|
+
);
|
|
14360
|
+
if (!confirmed) {
|
|
14361
|
+
outputLine(" Cancelled.");
|
|
14362
|
+
return;
|
|
14363
|
+
}
|
|
14364
|
+
}
|
|
14365
|
+
const result = removeDohBinary(binaryPath);
|
|
14366
|
+
if (json) {
|
|
14367
|
+
outputLine(JSON.stringify({ status: result.status, path: local.binaryPath }));
|
|
14368
|
+
return;
|
|
14369
|
+
}
|
|
14370
|
+
if (result.status === "removed") {
|
|
14371
|
+
outputLine(` \u2713 Removed: ${local.binaryPath}`);
|
|
14372
|
+
} else {
|
|
14373
|
+
outputLine(" DoH resolver is not installed.");
|
|
14374
|
+
}
|
|
14375
|
+
}
|
|
14376
|
+
function formatBytes(bytes) {
|
|
14377
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
14378
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
14379
|
+
return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
|
|
14380
|
+
}
|
|
14381
|
+
function askConfirmation(prompt2) {
|
|
14382
|
+
return new Promise((resolve3) => {
|
|
14383
|
+
const rl = readline.createInterface({
|
|
14384
|
+
input: process.stdin,
|
|
14385
|
+
output: process.stdout
|
|
14386
|
+
});
|
|
14387
|
+
rl.question(prompt2, (answer) => {
|
|
14388
|
+
rl.close();
|
|
14389
|
+
resolve3(answer.trim().toLowerCase() === "y");
|
|
14390
|
+
});
|
|
14391
|
+
});
|
|
14392
|
+
}
|
|
14393
|
+
|
|
13557
14394
|
// src/index.ts
|
|
13558
14395
|
var _require3 = createRequire3(import.meta.url);
|
|
13559
14396
|
var CLI_VERSION2 = _require3("../package.json").version;
|
|
13560
|
-
var GIT_HASH2 = true ? "
|
|
14397
|
+
var GIT_HASH2 = true ? "63a5613" : "dev";
|
|
14398
|
+
function handleDohCommand(action, json, force, binaryPath) {
|
|
14399
|
+
if (action === "status") return cmdDohStatus(json, binaryPath);
|
|
14400
|
+
if (action === "install") return cmdDohInstall(json, binaryPath);
|
|
14401
|
+
if (action === "remove") return cmdDohRemove(force, json, binaryPath);
|
|
14402
|
+
errorLine(`Unknown doh command: ${action}`);
|
|
14403
|
+
errorLine("Usage: okx doh <status|install|remove>");
|
|
14404
|
+
process.exitCode = 1;
|
|
14405
|
+
}
|
|
13561
14406
|
function handleConfigCommand(action, rest, json, lang, force) {
|
|
13562
14407
|
if (action === "init") return cmdConfigInit(lang === "zh" ? "zh" : "en");
|
|
13563
14408
|
if (action === "show") return cmdConfigShow(json);
|
|
@@ -14409,6 +15254,24 @@ async function runDiagnose(v) {
|
|
|
14409
15254
|
}
|
|
14410
15255
|
return cmdDiagnose(config, v.profile ?? "default", { mcp: v.mcp, cli: v.cli, all: v.all, output: v.output });
|
|
14411
15256
|
}
|
|
15257
|
+
function printVersion() {
|
|
15258
|
+
outputLine(`${CLI_VERSION2} (${GIT_HASH2})`);
|
|
15259
|
+
const dohStatus = getDohStatus(void 0, { skipHash: true });
|
|
15260
|
+
if (dohStatus.exists) {
|
|
15261
|
+
outputLine(`DoH resolver: installed (${dohStatus.platform ?? "unknown"})`);
|
|
15262
|
+
} else {
|
|
15263
|
+
outputLine("DoH resolver: not installed");
|
|
15264
|
+
}
|
|
15265
|
+
}
|
|
15266
|
+
function routeManagementCommand(module, action, rest, json, v) {
|
|
15267
|
+
if (module === "config") return handleConfigCommand(action, rest, json, v.lang, v.force);
|
|
15268
|
+
if (module === "setup") return handleSetupCommand(v);
|
|
15269
|
+
if (module === "upgrade") return cmdUpgrade(CLI_VERSION2, { beta: v.beta, check: v.check, force: v.force }, json);
|
|
15270
|
+
if (module === "doh") return handleDohCommand(action, json, v.force ?? false);
|
|
15271
|
+
if (module === "diagnose") return runDiagnose(v);
|
|
15272
|
+
if (module === "list-tools") return cmdListTools(json);
|
|
15273
|
+
return void 0;
|
|
15274
|
+
}
|
|
14412
15275
|
async function main() {
|
|
14413
15276
|
setOutput({
|
|
14414
15277
|
out: (m) => process.stdout.write(m),
|
|
@@ -14417,7 +15280,7 @@ async function main() {
|
|
|
14417
15280
|
checkForUpdates("@okx_ai/okx-trade-cli", CLI_VERSION2);
|
|
14418
15281
|
const { values, positionals } = parseCli(process.argv.slice(2));
|
|
14419
15282
|
if (values.version) {
|
|
14420
|
-
|
|
15283
|
+
printVersion();
|
|
14421
15284
|
return;
|
|
14422
15285
|
}
|
|
14423
15286
|
if (values.help || positionals.length === 0) {
|
|
@@ -14427,10 +15290,8 @@ async function main() {
|
|
|
14427
15290
|
const [module, action, ...rest] = positionals;
|
|
14428
15291
|
const v = values;
|
|
14429
15292
|
const json = v.json ?? false;
|
|
14430
|
-
|
|
14431
|
-
if (
|
|
14432
|
-
if (module === "upgrade") return cmdUpgrade(CLI_VERSION2, { beta: v.beta, check: v.check, force: v.force }, json);
|
|
14433
|
-
if (module === "diagnose") return runDiagnose(v);
|
|
15293
|
+
const mgmt = routeManagementCommand(module, action, rest, json, v);
|
|
15294
|
+
if (mgmt) return mgmt;
|
|
14434
15295
|
const config = loadProfileConfig({ profile: v.profile, demo: v.demo, live: v.live, verbose: v.verbose, userAgent: `okx-trade-cli/${CLI_VERSION2}`, sourceTag: "CLI" });
|
|
14435
15296
|
setEnvContext({ demo: config.demo, profile: v.profile ?? "default" });
|
|
14436
15297
|
setJsonEnvEnabled(v.env ?? false);
|
|
@@ -14468,6 +15329,7 @@ export {
|
|
|
14468
15329
|
handleBotDcaCommand,
|
|
14469
15330
|
handleBotGridCommand,
|
|
14470
15331
|
handleConfigCommand,
|
|
15332
|
+
handleDohCommand,
|
|
14471
15333
|
handleEarnCommand,
|
|
14472
15334
|
handleFuturesAlgoCommand,
|
|
14473
15335
|
handleFuturesCommand,
|