toobit-trade-cli 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +28 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -168,7 +168,7 @@ var TOOBIT_CODE_BEHAVIORS = {
|
|
|
168
168
|
"-2014": { retry: false, suggestion: "Bad API key format." },
|
|
169
169
|
"-2015": { retry: false, suggestion: "Invalid API key, IP, or permission." },
|
|
170
170
|
"-2017": { retry: false, suggestion: "API key expired. Generate a new one." },
|
|
171
|
-
"-1130": { retry: false, suggestion: "
|
|
171
|
+
"-1130": { retry: false, suggestion: "A parameter value is invalid. Check the error message for the specific parameter." },
|
|
172
172
|
"-1107": { retry: false, suggestion: "API key is missing or malformed. Check X-BB-APIKEY header." }
|
|
173
173
|
};
|
|
174
174
|
function isDefined(value) {
|
|
@@ -305,10 +305,22 @@ var ToobitRestClient = class {
|
|
|
305
305
|
if (codeStr === "-1003") {
|
|
306
306
|
throw new RateLimitError(message, "Too many requests. Back off.", endpoint);
|
|
307
307
|
}
|
|
308
|
+
let suggestion = behavior?.suggestion;
|
|
309
|
+
if (codeStr === "-1130" && responseMsg) {
|
|
310
|
+
if (/symbol/i.test(responseMsg)) {
|
|
311
|
+
const isFuturesPath = /futures|fundingRate|openInterest|markPrice|contract|longShort|insurance|riskLimit/i.test(config.path);
|
|
312
|
+
suggestion = isFuturesPath ? "Invalid symbol format. Futures endpoints require BTC-SWAP-USDT format; spot endpoints use BTCUSDT." : "Invalid symbol format. Spot endpoints require symbol format like BTCUSDT.";
|
|
313
|
+
} else {
|
|
314
|
+
const paramMatch = responseMsg.match(/paramter\s+'([^']+)'|parameter\s+'([^']+)'/i);
|
|
315
|
+
if (paramMatch) {
|
|
316
|
+
suggestion = `Parameter '${paramMatch[1] || paramMatch[2]}' has an invalid value. Check the allowed range and format.`;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
308
320
|
throw new ToobitApiError(message, {
|
|
309
321
|
code: codeStr,
|
|
310
322
|
endpoint,
|
|
311
|
-
suggestion
|
|
323
|
+
suggestion
|
|
312
324
|
});
|
|
313
325
|
}
|
|
314
326
|
if (!response.ok) {
|
|
@@ -523,7 +535,7 @@ function registerAccountTools() {
|
|
|
523
535
|
addressExt: { type: "string", description: "Memo/tag if required" },
|
|
524
536
|
chainType: { type: "string" },
|
|
525
537
|
withdrawQuantity: { type: "string" },
|
|
526
|
-
clientOrderId: { type: "string" }
|
|
538
|
+
clientOrderId: { type: "string", description: "Only [a-zA-Z0-9_\\-.] allowed; other characters are stripped." }
|
|
527
539
|
},
|
|
528
540
|
required: ["tokenId", "address", "chainType", "withdrawQuantity"]
|
|
529
541
|
},
|
|
@@ -537,7 +549,7 @@ function registerAccountTools() {
|
|
|
537
549
|
addressExt: readString(args, "addressExt"),
|
|
538
550
|
chainType: requireString(args, "chainType"),
|
|
539
551
|
withdrawQuantity: requireString(args, "withdrawQuantity"),
|
|
540
|
-
clientOrderId: readString(args, "clientOrderId")
|
|
552
|
+
clientOrderId: readString(args, "clientOrderId")?.replace(/[^a-zA-Z0-9_\-\.]/g, "")
|
|
541
553
|
}),
|
|
542
554
|
privateRateLimit("account_withdraw", 5)
|
|
543
555
|
);
|
|
@@ -651,8 +663,15 @@ function registerAuditTools() {
|
|
|
651
663
|
handler: async (rawArgs) => {
|
|
652
664
|
const args = asRecord(rawArgs);
|
|
653
665
|
const dateStr = readString(args, "date") ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
666
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(dateStr)) {
|
|
667
|
+
throw new Error('Invalid date format. Must be YYYY-MM-DD (e.g. "2026-03-15").');
|
|
668
|
+
}
|
|
654
669
|
const limit = readNumber(args, "limit") ?? 50;
|
|
655
|
-
const
|
|
670
|
+
const logDir = path.join(os.homedir(), ".toobit", "logs");
|
|
671
|
+
const logPath = path.join(logDir, `trade-${dateStr}.log`);
|
|
672
|
+
if (!logPath.startsWith(logDir)) {
|
|
673
|
+
throw new Error("Invalid date value.");
|
|
674
|
+
}
|
|
656
675
|
if (!fs.existsSync(logPath)) {
|
|
657
676
|
return { endpoint: "local", requestTime: (/* @__PURE__ */ new Date()).toISOString(), data: [] };
|
|
658
677
|
}
|
|
@@ -702,6 +721,10 @@ function registerFuturesTools() {
|
|
|
702
721
|
if (orderType === "MARKET") {
|
|
703
722
|
orderType = "LIMIT";
|
|
704
723
|
priceType = "MARKET";
|
|
724
|
+
} else if (orderType === "LIMIT" && priceType === "MARKET") {
|
|
725
|
+
throw new Error(
|
|
726
|
+
'Conflicting parameters: orderType="LIMIT" with priceType="MARKET" would execute at market price, ignoring your limit price. Use orderType="MARKET" for market orders, or remove priceType for limit orders.'
|
|
727
|
+
);
|
|
705
728
|
}
|
|
706
729
|
const rawClientId = readString(args, "newClientOrderId");
|
|
707
730
|
const clientId = rawClientId ? rawClientId.replace(/[^a-zA-Z0-9_\-\.]/g, "") : `mcp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|