@nemesis-oss/binance-sdk 1.0.0 → 2.0.0
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/README.md +136 -8
- package/dist/index-BO27qOb5.d.cts +3887 -0
- package/dist/index-BO27qOb5.d.ts +3887 -0
- package/dist/index.cjs +2640 -629
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -8
- package/dist/index.d.ts +62 -8
- package/dist/index.js +2536 -632
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.cjs +2429 -632
- package/dist/mcp/index.cjs.map +1 -1
- package/dist/mcp/index.js +2430 -633
- package/dist/mcp/index.js.map +1 -1
- package/dist/tools/index.d.cts +2 -1
- package/dist/tools/index.d.ts +2 -1
- package/package.json +8 -3
- package/dist/index-D2T_Rhwj.d.cts +0 -2055
- package/dist/index-D2T_Rhwj.d.ts +0 -2055
package/dist/mcp/index.js
CHANGED
|
@@ -5,7 +5,6 @@ import http from "http";
|
|
|
5
5
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
6
|
|
|
7
7
|
// src/client/HttpClient.ts
|
|
8
|
-
import { createHmac } from "crypto";
|
|
9
8
|
import axios from "axios";
|
|
10
9
|
import Bottleneck from "bottleneck";
|
|
11
10
|
|
|
@@ -28,18 +27,33 @@ var BinanceAuthError = class extends BinanceError {
|
|
|
28
27
|
|
|
29
28
|
// src/errors/BinanceApiError.ts
|
|
30
29
|
var BinanceApiError = class extends BinanceError {
|
|
31
|
-
constructor(message, code, status) {
|
|
30
|
+
constructor(message, code, status, context) {
|
|
32
31
|
super(message);
|
|
33
32
|
this.name = "BinanceApiError";
|
|
34
33
|
this.code = code;
|
|
35
34
|
this.status = status;
|
|
35
|
+
this.endpoint = context?.endpoint;
|
|
36
|
+
this.method = context?.method;
|
|
37
|
+
this.headers = context?.headers;
|
|
38
|
+
}
|
|
39
|
+
/** -1003 (way too many requests) or HTTP 429/418. */
|
|
40
|
+
isRateLimitError() {
|
|
41
|
+
return this.code === -1003 || this.status === 429 || this.status === 418;
|
|
42
|
+
}
|
|
43
|
+
/** -1021: request timestamp outside recvWindow, usually caused by local clock drift. */
|
|
44
|
+
isTimestampError() {
|
|
45
|
+
return this.code === -1021;
|
|
46
|
+
}
|
|
47
|
+
/** -2010: account has insufficient balance for the requested action. */
|
|
48
|
+
isInsufficientBalance() {
|
|
49
|
+
return this.code === -2010;
|
|
36
50
|
}
|
|
37
51
|
};
|
|
38
52
|
|
|
39
53
|
// src/errors/RateLimitError.ts
|
|
40
54
|
var RateLimitError = class extends BinanceApiError {
|
|
41
|
-
constructor(message, code, status, retryAfterMs) {
|
|
42
|
-
super(message, code, status);
|
|
55
|
+
constructor(message, code, status, retryAfterMs, context) {
|
|
56
|
+
super(message, code, status, context);
|
|
43
57
|
this.name = "RateLimitError";
|
|
44
58
|
this.retryAfterMs = retryAfterMs;
|
|
45
59
|
}
|
|
@@ -54,16 +68,144 @@ var NetworkError = class extends BinanceError {
|
|
|
54
68
|
}
|
|
55
69
|
};
|
|
56
70
|
|
|
71
|
+
// src/errors/PolicyViolationError.ts
|
|
72
|
+
var PolicyViolationError = class extends BinanceError {
|
|
73
|
+
constructor(rule, message, method, endpoint, details) {
|
|
74
|
+
super(`Blocked by trading policy (${rule}): ${message} [${method} ${endpoint}]`);
|
|
75
|
+
this.name = "PolicyViolationError";
|
|
76
|
+
this.rule = rule;
|
|
77
|
+
this.method = method;
|
|
78
|
+
this.endpoint = endpoint;
|
|
79
|
+
this.details = details;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// src/errors/DryRunError.ts
|
|
84
|
+
var DryRunError = class extends BinanceError {
|
|
85
|
+
constructor(method, endpoint, params = {}) {
|
|
86
|
+
super(`DRY RUN \u2014 request not sent: ${method} ${endpoint} ${JSON.stringify(params)}`);
|
|
87
|
+
this.name = "DryRunError";
|
|
88
|
+
this.method = method;
|
|
89
|
+
this.endpoint = endpoint;
|
|
90
|
+
this.params = params;
|
|
91
|
+
}
|
|
92
|
+
/** Human/LLM-readable description of the suppressed request. */
|
|
93
|
+
describe() {
|
|
94
|
+
return `Would have sent ${this.method} ${this.endpoint} with ${JSON.stringify(this.params)}`;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// src/client/RateLimitTracker.ts
|
|
99
|
+
var WEIGHT_HEADER = /^x-mbx-used-weight-(.+)$/i;
|
|
100
|
+
var ORDER_COUNT_HEADER = /^x-mbx-order-count-(.+)$/i;
|
|
101
|
+
var RateLimitTracker = class {
|
|
102
|
+
constructor(options = {}) {
|
|
103
|
+
this.usage = {
|
|
104
|
+
usedWeight: 0,
|
|
105
|
+
usedWeightByInterval: {},
|
|
106
|
+
orderCountByInterval: {},
|
|
107
|
+
lastUpdated: 0
|
|
108
|
+
};
|
|
109
|
+
this.weightLimitPerMinute = options.weightLimitPerMinute ?? 6e3;
|
|
110
|
+
this.safetyMargin = options.safetyMargin ?? 0.8;
|
|
111
|
+
}
|
|
112
|
+
update(headers) {
|
|
113
|
+
if (!headers) return;
|
|
114
|
+
const usedWeightByInterval = {};
|
|
115
|
+
const orderCountByInterval = {};
|
|
116
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
117
|
+
const weightMatch = key.match(WEIGHT_HEADER);
|
|
118
|
+
if (weightMatch?.[1]) {
|
|
119
|
+
usedWeightByInterval[weightMatch[1]] = Number(value);
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
const orderMatch = key.match(ORDER_COUNT_HEADER);
|
|
123
|
+
if (orderMatch?.[1]) {
|
|
124
|
+
orderCountByInterval[orderMatch[1]] = Number(value);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (Object.keys(usedWeightByInterval).length === 0 && Object.keys(orderCountByInterval).length === 0) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
this.usage = {
|
|
131
|
+
usedWeight: Math.max(0, ...Object.values(usedWeightByInterval)),
|
|
132
|
+
usedWeightByInterval,
|
|
133
|
+
orderCountByInterval,
|
|
134
|
+
lastUpdated: Date.now()
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
getUsage() {
|
|
138
|
+
return this.usage;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Milliseconds a caller should wait before its next request, based on the most recently
|
|
142
|
+
* observed 1-minute weight usage. Returns 0 when usage is stale or under the safety margin.
|
|
143
|
+
*/
|
|
144
|
+
getThrottleDelayMs() {
|
|
145
|
+
if (this.safetyMargin >= 1) return 0;
|
|
146
|
+
const oneMinuteWeight = this.usage.usedWeightByInterval["1m"] ?? this.usage.usedWeight;
|
|
147
|
+
if (!oneMinuteWeight) return 0;
|
|
148
|
+
if (Date.now() - this.usage.lastUpdated > 6e4) return 0;
|
|
149
|
+
const threshold = this.weightLimitPerMinute * this.safetyMargin;
|
|
150
|
+
if (oneMinuteWeight < threshold) return 0;
|
|
151
|
+
const msIntoMinute = Date.now() % 6e4;
|
|
152
|
+
return 6e4 - msIntoMinute;
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// src/client/Signer.ts
|
|
157
|
+
import { createHmac, createPrivateKey, createSign, sign as cryptoSign } from "crypto";
|
|
158
|
+
var Signer = class {
|
|
159
|
+
constructor(options) {
|
|
160
|
+
this.algorithm = options.algorithm ?? (options.privateKey ? "ED25519" : "HMAC");
|
|
161
|
+
this.apiSecret = options.apiSecret;
|
|
162
|
+
if (options.privateKey) {
|
|
163
|
+
this.privateKey = createPrivateKey(options.privateKey);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
canSign() {
|
|
167
|
+
return this.algorithm === "HMAC" ? Boolean(this.apiSecret) : Boolean(this.privateKey);
|
|
168
|
+
}
|
|
169
|
+
sign(payload) {
|
|
170
|
+
switch (this.algorithm) {
|
|
171
|
+
case "HMAC": {
|
|
172
|
+
if (!this.apiSecret) throw new Error("apiSecret is required for HMAC signing");
|
|
173
|
+
return createHmac("sha256", this.apiSecret).update(payload).digest("hex");
|
|
174
|
+
}
|
|
175
|
+
case "ED25519": {
|
|
176
|
+
if (!this.privateKey) throw new Error("privateKey is required for ED25519 signing");
|
|
177
|
+
return cryptoSign(null, Buffer.from(payload), this.privateKey).toString("base64");
|
|
178
|
+
}
|
|
179
|
+
case "RSA": {
|
|
180
|
+
if (!this.privateKey) throw new Error("privateKey is required for RSA signing");
|
|
181
|
+
return createSign("RSA-SHA256").update(payload).sign(this.privateKey, "base64");
|
|
182
|
+
}
|
|
183
|
+
default: {
|
|
184
|
+
const exhaustive = this.algorithm;
|
|
185
|
+
throw new Error(`Unsupported signature algorithm: ${String(exhaustive)}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
57
191
|
// src/client/HttpClient.ts
|
|
58
192
|
var RETRYABLE_STATUS = /* @__PURE__ */ new Set([429, 418, 500, 502, 503, 504]);
|
|
59
193
|
function sleep(ms) {
|
|
60
194
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
61
195
|
}
|
|
196
|
+
function normalizeHeaders(headers) {
|
|
197
|
+
const result = {};
|
|
198
|
+
if (!headers || typeof headers !== "object") return result;
|
|
199
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
200
|
+
if (value !== void 0 && value !== null) result[key.toLowerCase()] = String(value);
|
|
201
|
+
}
|
|
202
|
+
return result;
|
|
203
|
+
}
|
|
62
204
|
var HttpClient = class {
|
|
63
205
|
constructor(options) {
|
|
64
206
|
this.pendingRequests = 0;
|
|
207
|
+
this.timeOffsetMs = 0;
|
|
65
208
|
this.apiKey = options.apiKey;
|
|
66
|
-
this.apiSecret = options.apiSecret;
|
|
67
209
|
this.recvWindow = options.recvWindow ?? 5e3;
|
|
68
210
|
this.timeoutMs = options.timeoutMs ?? 15e3;
|
|
69
211
|
this.maxRetries = options.maxRetries ?? 3;
|
|
@@ -71,7 +213,22 @@ var HttpClient = class {
|
|
|
71
213
|
this.retryBaseDelayMs = options.retryBaseDelayMs ?? 1e3;
|
|
72
214
|
this.retryMaxDelayMs = options.retryMaxDelayMs ?? 3e4;
|
|
73
215
|
this.retryFactor = options.retryFactor ?? 2;
|
|
74
|
-
this.
|
|
216
|
+
this.signer = new Signer({
|
|
217
|
+
algorithm: options.signatureAlgorithm,
|
|
218
|
+
apiSecret: options.apiSecret,
|
|
219
|
+
privateKey: options.privateKey
|
|
220
|
+
});
|
|
221
|
+
this.rateLimitTracker = new RateLimitTracker({
|
|
222
|
+
weightLimitPerMinute: options.rateLimitWeightPerMinute,
|
|
223
|
+
safetyMargin: options.rateLimitSafetyMargin
|
|
224
|
+
});
|
|
225
|
+
this.policy = options.policy;
|
|
226
|
+
this.axios = axios.create({
|
|
227
|
+
baseURL: options.baseURL,
|
|
228
|
+
timeout: this.timeoutMs,
|
|
229
|
+
httpsAgent: options.httpsAgent,
|
|
230
|
+
proxy: options.proxy
|
|
231
|
+
});
|
|
75
232
|
this.limiter = new Bottleneck({ minTime: this.minTimeMs });
|
|
76
233
|
}
|
|
77
234
|
async get(path, params, mode = "public") {
|
|
@@ -89,6 +246,10 @@ var HttpClient = class {
|
|
|
89
246
|
getRateLimiterStatus() {
|
|
90
247
|
return { minTimeMs: this.minTimeMs, queueLength: this.pendingRequests };
|
|
91
248
|
}
|
|
249
|
+
/** Snapshot of the most recently observed `X-MBX-USED-WEIGHT-*` / `X-MBX-ORDER-COUNT-*` response headers. */
|
|
250
|
+
getRateLimitUsage() {
|
|
251
|
+
return this.rateLimitTracker.getUsage();
|
|
252
|
+
}
|
|
92
253
|
configureRateLimiter(options) {
|
|
93
254
|
if (options.minTimeMs !== void 0) {
|
|
94
255
|
this.minTimeMs = options.minTimeMs;
|
|
@@ -109,10 +270,28 @@ var HttpClient = class {
|
|
|
109
270
|
if (options.maxDelayMs !== void 0) this.retryMaxDelayMs = options.maxDelayMs;
|
|
110
271
|
if (options.factor !== void 0) this.retryFactor = options.factor;
|
|
111
272
|
}
|
|
273
|
+
/**
|
|
274
|
+
* Fetches server time from `timePath` (e.g. '/time', '/fapi/v1/time', '/dapi/v1/time') and
|
|
275
|
+
* stores the offset from local time, applied to every signed request's `timestamp` param.
|
|
276
|
+
* Mitigates `-1021` (timestamp outside recvWindow) errors caused by local clock drift.
|
|
277
|
+
*/
|
|
278
|
+
async syncTime(timePath = "/time") {
|
|
279
|
+
const res = await this.axios.request({ method: "GET", url: timePath });
|
|
280
|
+
this.timeOffsetMs = res.data.serverTime - Date.now();
|
|
281
|
+
return this.timeOffsetMs;
|
|
282
|
+
}
|
|
283
|
+
getTimeOffsetMs() {
|
|
284
|
+
return this.timeOffsetMs;
|
|
285
|
+
}
|
|
112
286
|
async request(method, path, params, mode) {
|
|
287
|
+
this.policy?.check(method, path, params ?? {});
|
|
113
288
|
const url = this.buildUrl(path, params, mode);
|
|
114
289
|
const config = { method, url, headers: this.buildHeaders(mode) };
|
|
115
|
-
return this.limiter.schedule(() =>
|
|
290
|
+
return this.limiter.schedule(async () => {
|
|
291
|
+
const throttleMs = this.rateLimitTracker.getThrottleDelayMs();
|
|
292
|
+
if (throttleMs > 0) await sleep(throttleMs);
|
|
293
|
+
return this.requestWithRetry(config, 0, method, path);
|
|
294
|
+
});
|
|
116
295
|
}
|
|
117
296
|
buildHeaders(mode) {
|
|
118
297
|
const headers = {
|
|
@@ -124,7 +303,7 @@ var HttpClient = class {
|
|
|
124
303
|
}
|
|
125
304
|
buildUrl(path, params, mode) {
|
|
126
305
|
if (mode !== "signed") return this.appendQuery(path, params);
|
|
127
|
-
const requestData = { ...params, timestamp: Date.now(), recvWindow: this.recvWindow };
|
|
306
|
+
const requestData = { ...params, timestamp: Date.now() + this.timeOffsetMs, recvWindow: this.recvWindow };
|
|
128
307
|
const queryString = this.buildQueryString(requestData);
|
|
129
308
|
const signature = this.sign(queryString);
|
|
130
309
|
return `${path}?${queryString}&signature=${signature}`;
|
|
@@ -135,20 +314,25 @@ var HttpClient = class {
|
|
|
135
314
|
}
|
|
136
315
|
buildQueryString(params) {
|
|
137
316
|
if (!params) return "";
|
|
138
|
-
return Object.entries(params).filter(([, val]) => val !== void 0 && val !== null).
|
|
317
|
+
return Object.entries(params).filter(([, val]) => val !== void 0 && val !== null).flatMap(
|
|
318
|
+
([key, val]) => Array.isArray(val) ? val.map((item) => `${key}=${encodeURIComponent(String(item))}`) : [`${key}=${encodeURIComponent(String(val))}`]
|
|
319
|
+
).join("&");
|
|
139
320
|
}
|
|
140
321
|
sign(queryString) {
|
|
141
|
-
if (!this.
|
|
142
|
-
|
|
322
|
+
if (!this.signer.canSign()) {
|
|
323
|
+
throw new BinanceAuthError(this.signer.algorithm === "HMAC" ? "apiSecret" : "privateKey");
|
|
324
|
+
}
|
|
325
|
+
return this.signer.sign(queryString);
|
|
143
326
|
}
|
|
144
327
|
requireApiKey() {
|
|
145
328
|
if (!this.apiKey) throw new BinanceAuthError("apiKey");
|
|
146
329
|
return this.apiKey;
|
|
147
330
|
}
|
|
148
|
-
async requestWithRetry(config, attempt) {
|
|
331
|
+
async requestWithRetry(config, attempt, method, endpoint) {
|
|
149
332
|
this.pendingRequests += 1;
|
|
150
333
|
try {
|
|
151
334
|
const res = await this.axios.request(config);
|
|
335
|
+
this.rateLimitTracker.update(normalizeHeaders(res.headers));
|
|
152
336
|
return res.data;
|
|
153
337
|
} catch (err) {
|
|
154
338
|
if (!axios.isAxiosError(err)) {
|
|
@@ -156,21 +340,36 @@ var HttpClient = class {
|
|
|
156
340
|
}
|
|
157
341
|
const status = err.response?.status;
|
|
158
342
|
const body = err.response?.data;
|
|
343
|
+
const headers = normalizeHeaders(err.response?.headers);
|
|
344
|
+
this.rateLimitTracker.update(headers);
|
|
159
345
|
if (attempt < this.maxRetries && this.shouldRetry(err)) {
|
|
160
346
|
await sleep(this.calculateDelay(attempt));
|
|
161
|
-
return this.requestWithRetry(config, attempt + 1);
|
|
347
|
+
return this.requestWithRetry(config, attempt + 1, method, endpoint);
|
|
162
348
|
}
|
|
349
|
+
const context = { endpoint, method, headers };
|
|
163
350
|
if (status === 429 || status === 418) {
|
|
164
|
-
throw new RateLimitError(
|
|
351
|
+
throw new RateLimitError(
|
|
352
|
+
body?.msg ?? "Binance rate limit exceeded",
|
|
353
|
+
body?.code ?? -1,
|
|
354
|
+
status,
|
|
355
|
+
this.parseRetryAfterMs(headers),
|
|
356
|
+
context
|
|
357
|
+
);
|
|
165
358
|
}
|
|
166
359
|
if (status && body) {
|
|
167
|
-
throw new BinanceApiError(body.msg ?? "Binance API error", body.code ?? -1, status);
|
|
360
|
+
throw new BinanceApiError(body.msg ?? "Binance API error", body.code ?? -1, status, context);
|
|
168
361
|
}
|
|
169
362
|
throw new NetworkError(err.message, err);
|
|
170
363
|
} finally {
|
|
171
364
|
this.pendingRequests -= 1;
|
|
172
365
|
}
|
|
173
366
|
}
|
|
367
|
+
parseRetryAfterMs(headers) {
|
|
368
|
+
const raw = headers["retry-after"];
|
|
369
|
+
if (!raw) return void 0;
|
|
370
|
+
const seconds = Number(raw);
|
|
371
|
+
return Number.isFinite(seconds) ? seconds * 1e3 : void 0;
|
|
372
|
+
}
|
|
174
373
|
shouldRetry(err) {
|
|
175
374
|
if (err.response?.status !== void 0) return RETRYABLE_STATUS.has(err.response.status);
|
|
176
375
|
return true;
|
|
@@ -182,6 +381,92 @@ var HttpClient = class {
|
|
|
182
381
|
}
|
|
183
382
|
};
|
|
184
383
|
|
|
384
|
+
// src/client/TradingPolicy.ts
|
|
385
|
+
var WITHDRAW_FRAGMENTS = ["/capital/withdraw/apply"];
|
|
386
|
+
var TRANSFER_FRAGMENTS = [
|
|
387
|
+
"/asset/transfer",
|
|
388
|
+
"/margin/transfer",
|
|
389
|
+
"/margin/isolated/transfer",
|
|
390
|
+
"/universaltransfer",
|
|
391
|
+
"/futures/transfer"
|
|
392
|
+
];
|
|
393
|
+
var MUTATING_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "DELETE"]);
|
|
394
|
+
function toNumber(value) {
|
|
395
|
+
if (value === void 0 || value === null || value === "") return void 0;
|
|
396
|
+
const num2 = Number(value);
|
|
397
|
+
return Number.isFinite(num2) ? num2 : void 0;
|
|
398
|
+
}
|
|
399
|
+
function includesFragment(path, fragments) {
|
|
400
|
+
const lower = path.toLowerCase();
|
|
401
|
+
return fragments.some((fragment) => lower.includes(fragment.toLowerCase()));
|
|
402
|
+
}
|
|
403
|
+
var TradingPolicy = class {
|
|
404
|
+
constructor(options = {}) {
|
|
405
|
+
this.options = options;
|
|
406
|
+
if (options.allowedSymbols?.length) {
|
|
407
|
+
this.allowedSymbols = new Set(options.allowedSymbols.map((s) => s.toUpperCase()));
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
/** Throws {@link PolicyViolationError} or {@link DryRunError} if the request is not permitted. */
|
|
411
|
+
check(method, path, params = {}) {
|
|
412
|
+
if (!MUTATING_METHODS.has(method)) return;
|
|
413
|
+
const deny = (rule, message, details) => {
|
|
414
|
+
throw new PolicyViolationError(rule, message, method, path, details);
|
|
415
|
+
};
|
|
416
|
+
if (this.options.blockedPaths?.length && includesFragment(path, this.options.blockedPaths)) {
|
|
417
|
+
deny("blockedPath", "endpoint is on the blocked-path list");
|
|
418
|
+
}
|
|
419
|
+
if (this.options.readOnly) {
|
|
420
|
+
deny("readOnly", "client is in read-only mode; mutating requests are refused");
|
|
421
|
+
}
|
|
422
|
+
if (includesFragment(path, WITHDRAW_FRAGMENTS) && this.options.allowWithdrawals !== true) {
|
|
423
|
+
deny("withdrawalsBlocked", "withdrawals are disabled; set safety.allowWithdrawals to permit them");
|
|
424
|
+
}
|
|
425
|
+
if (includesFragment(path, TRANSFER_FRAGMENTS) && this.options.allowTransfers === false) {
|
|
426
|
+
deny("transfersBlocked", "account transfers are disabled by policy");
|
|
427
|
+
}
|
|
428
|
+
this.checkSymbol(path, params, deny);
|
|
429
|
+
this.checkNotional(path, params, deny);
|
|
430
|
+
if (this.options.dryRun) {
|
|
431
|
+
throw new DryRunError(method, path, params);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
checkSymbol(path, params, deny) {
|
|
435
|
+
if (!this.allowedSymbols) return;
|
|
436
|
+
const symbol3 = params.symbol;
|
|
437
|
+
if (typeof symbol3 !== "string" || symbol3 === "") return;
|
|
438
|
+
if (!this.allowedSymbols.has(symbol3.toUpperCase())) {
|
|
439
|
+
deny("symbolNotAllowed", `symbol ${symbol3} is not in the allowed list`, {
|
|
440
|
+
symbol: symbol3,
|
|
441
|
+
allowed: [...this.allowedSymbols]
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
checkNotional(path, params, deny) {
|
|
446
|
+
const max = this.options.maxNotionalPerOrder;
|
|
447
|
+
if (max === void 0) return;
|
|
448
|
+
if (!path.toLowerCase().includes("order")) return;
|
|
449
|
+
const quantity = toNumber(params.quantity);
|
|
450
|
+
const quoteOrderQty = toNumber(params.quoteOrderQty);
|
|
451
|
+
if (quantity === void 0 && quoteOrderQty === void 0) return;
|
|
452
|
+
const price = toNumber(params.price);
|
|
453
|
+
const notional = quoteOrderQty ?? (price !== void 0 && quantity !== void 0 ? price * quantity : void 0);
|
|
454
|
+
if (notional === void 0) {
|
|
455
|
+
deny(
|
|
456
|
+
"notionalUndeterminable",
|
|
457
|
+
`cannot verify notional against the ${max} cap (no price on this order); supply a price or raise/remove maxNotionalPerOrder`,
|
|
458
|
+
{ quantity, maxNotionalPerOrder: max }
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
if (notional > max) {
|
|
462
|
+
deny("maxNotionalPerOrder", `order notional ${notional} exceeds the ${max} cap`, {
|
|
463
|
+
notional,
|
|
464
|
+
maxNotionalPerOrder: max
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
|
|
185
470
|
// src/client/endpoints.ts
|
|
186
471
|
function resolveEnvironment(options) {
|
|
187
472
|
const env = options?.demo ? "demo" : options?.testnet ? "testnet" : "live";
|
|
@@ -192,6 +477,9 @@ function resolveEnvironment(options) {
|
|
|
192
477
|
const restSpotHost = options?.apiBase ?? (env === "testnet" ? "https://testnet.binance.vision" : "https://api.binance.com");
|
|
193
478
|
const wsSpotMarketHost = options?.wsBase ?? (env === "testnet" ? "wss://testnet.binance.vision/stream" : "wss://stream.binance.com:9443/stream");
|
|
194
479
|
const wsSpotUserHost = options?.wsUserBase ?? (env === "testnet" ? "wss://testnet.binance.vision/ws" : "wss://stream.binance.com:9443/ws");
|
|
480
|
+
const restDapiHost = options?.dapiBase ?? (env === "testnet" || env === "demo" ? "https://testnet.binancefuture.com" : "https://dapi.binance.com");
|
|
481
|
+
const wsSpotApiHost = options?.wsSpotApiBase ?? (env === "testnet" ? "wss://testnet.binance.vision/ws-api/v3" : "wss://ws-api.binance.com:443/ws-api/v3");
|
|
482
|
+
const wsDapiHost = options?.wsDapiBase ?? (env === "testnet" || env === "demo" ? "wss://dstream.binancefuture.com" : "wss://dstream.binance.com");
|
|
195
483
|
return {
|
|
196
484
|
env,
|
|
197
485
|
endpoints: {
|
|
@@ -199,11 +487,17 @@ function resolveEnvironment(options) {
|
|
|
199
487
|
restFapi: `${restHost}/fapi/v1`,
|
|
200
488
|
restFuturesData: `${restHost}/futures/data`,
|
|
201
489
|
restSpot: `${restSpotHost}/api/v3`,
|
|
490
|
+
restApiRoot: restSpotHost,
|
|
491
|
+
restDapiRoot: restDapiHost,
|
|
492
|
+
restDapi: `${restDapiHost}/dapi/v1`,
|
|
202
493
|
wsMarket: wsMarketHost,
|
|
203
494
|
wsUser: wsUserHost,
|
|
204
495
|
wsApi: wsApiHost,
|
|
205
496
|
wsSpotMarket: wsSpotMarketHost,
|
|
206
|
-
wsSpotUser: wsSpotUserHost
|
|
497
|
+
wsSpotUser: wsSpotUserHost,
|
|
498
|
+
wsSpotApi: wsSpotApiHost,
|
|
499
|
+
wsDapiMarket: `${wsDapiHost}/stream`,
|
|
500
|
+
wsDapiUser: `${wsDapiHost}/ws`
|
|
207
501
|
}
|
|
208
502
|
};
|
|
209
503
|
}
|
|
@@ -1852,301 +2146,1404 @@ var UserDataStream = class {
|
|
|
1852
2146
|
}
|
|
1853
2147
|
};
|
|
1854
2148
|
|
|
1855
|
-
// src/
|
|
1856
|
-
import { EventEmitter } from "events";
|
|
1857
|
-
import WebSocket from "ws";
|
|
1858
|
-
|
|
1859
|
-
// src/types/ws.types.ts
|
|
2149
|
+
// src/types/coinm.types.ts
|
|
1860
2150
|
import { z as z7 } from "zod";
|
|
1861
|
-
var
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
o: z7.string().transform(Number),
|
|
1871
|
-
c: z7.string().transform(Number),
|
|
1872
|
-
h: z7.string().transform(Number),
|
|
1873
|
-
l: z7.string().transform(Number),
|
|
1874
|
-
v: z7.string().transform(Number),
|
|
1875
|
-
n: z7.number(),
|
|
1876
|
-
x: z7.boolean(),
|
|
1877
|
-
q: z7.string().transform(Number),
|
|
1878
|
-
V: z7.string().transform(Number),
|
|
1879
|
-
Q: z7.string().transform(Number)
|
|
1880
|
-
})
|
|
2151
|
+
var CoinMBalanceSchema = z7.object({
|
|
2152
|
+
accountAlias: z7.string(),
|
|
2153
|
+
asset: z7.string(),
|
|
2154
|
+
balance: z7.string().transform(Number),
|
|
2155
|
+
withdrawAvailable: z7.string().transform(Number),
|
|
2156
|
+
crossWalletBalance: z7.string().transform(Number),
|
|
2157
|
+
crossUnPnl: z7.string().transform(Number),
|
|
2158
|
+
availableBalance: z7.string().transform(Number),
|
|
2159
|
+
updateTime: z7.number()
|
|
1881
2160
|
});
|
|
1882
|
-
var
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
2161
|
+
var CoinMBalanceResponseSchema = z7.array(CoinMBalanceSchema);
|
|
2162
|
+
var CoinMPositionRiskSchema = z7.object({
|
|
2163
|
+
symbol: z7.string(),
|
|
2164
|
+
pair: z7.string().optional(),
|
|
2165
|
+
positionAmt: z7.string().transform(Number),
|
|
2166
|
+
entryPrice: z7.string().transform(Number),
|
|
2167
|
+
markPrice: z7.string().transform(Number),
|
|
2168
|
+
unRealizedProfit: z7.string().transform(Number),
|
|
2169
|
+
liquidationPrice: z7.string().transform(Number),
|
|
2170
|
+
leverage: z7.string().transform(Number),
|
|
2171
|
+
maxQty: z7.string().transform(Number).optional(),
|
|
2172
|
+
marginType: z7.enum(["isolated", "cross"]),
|
|
2173
|
+
isolatedMargin: z7.string().transform(Number).optional(),
|
|
2174
|
+
isAutoAddMargin: z7.union([z7.string(), z7.boolean()]).optional(),
|
|
2175
|
+
positionSide: z7.string(),
|
|
2176
|
+
notionalValue: z7.string().transform(Number).optional(),
|
|
2177
|
+
breakEvenPrice: z7.string().transform(Number).optional(),
|
|
2178
|
+
updateTime: z7.number().optional()
|
|
2179
|
+
}).loose();
|
|
2180
|
+
var CoinMPositionRiskResponseSchema = z7.array(CoinMPositionRiskSchema);
|
|
2181
|
+
var CoinMAccountAssetSchema = z7.object({
|
|
2182
|
+
asset: z7.string(),
|
|
2183
|
+
walletBalance: z7.string().transform(Number),
|
|
2184
|
+
unrealizedProfit: z7.string().transform(Number),
|
|
2185
|
+
marginBalance: z7.string().transform(Number),
|
|
2186
|
+
maintMargin: z7.string().transform(Number),
|
|
2187
|
+
initialMargin: z7.string().transform(Number),
|
|
2188
|
+
positionInitialMargin: z7.string().transform(Number),
|
|
2189
|
+
openOrderInitialMargin: z7.string().transform(Number),
|
|
2190
|
+
maxWithdrawAmount: z7.string().transform(Number),
|
|
2191
|
+
crossWalletBalance: z7.string().transform(Number),
|
|
2192
|
+
crossUnPnl: z7.string().transform(Number),
|
|
2193
|
+
availableBalance: z7.string().transform(Number),
|
|
2194
|
+
updateTime: z7.number()
|
|
2195
|
+
}).loose();
|
|
2196
|
+
var CoinMAccountPositionSchema = z7.object({
|
|
2197
|
+
symbol: z7.string(),
|
|
2198
|
+
positionAmt: z7.string().transform(Number),
|
|
2199
|
+
initialMargin: z7.string().transform(Number),
|
|
2200
|
+
maintMargin: z7.string().transform(Number),
|
|
2201
|
+
unrealizedProfit: z7.string().transform(Number),
|
|
2202
|
+
positionInitialMargin: z7.string().transform(Number),
|
|
2203
|
+
openOrderInitialMargin: z7.string().transform(Number),
|
|
2204
|
+
leverage: z7.string().transform(Number),
|
|
2205
|
+
isolated: z7.boolean(),
|
|
2206
|
+
positionSide: z7.string(),
|
|
2207
|
+
entryPrice: z7.string().transform(Number),
|
|
2208
|
+
maxQty: z7.string().transform(Number).optional(),
|
|
2209
|
+
updateTime: z7.number().optional()
|
|
2210
|
+
}).loose();
|
|
2211
|
+
var CoinMAccountSchema = z7.object({
|
|
2212
|
+
canDeposit: z7.boolean(),
|
|
2213
|
+
canTrade: z7.boolean(),
|
|
2214
|
+
canWithdraw: z7.boolean(),
|
|
2215
|
+
feeTier: z7.number(),
|
|
2216
|
+
updateTime: z7.number(),
|
|
2217
|
+
assets: z7.array(CoinMAccountAssetSchema),
|
|
2218
|
+
positions: z7.array(CoinMAccountPositionSchema)
|
|
2219
|
+
}).loose();
|
|
2220
|
+
var CoinMOrderSchema = z7.object({
|
|
2221
|
+
orderId: z7.number(),
|
|
2222
|
+
symbol: z7.string(),
|
|
2223
|
+
pair: z7.string().optional(),
|
|
2224
|
+
status: z7.string(),
|
|
2225
|
+
clientOrderId: z7.string(),
|
|
2226
|
+
price: z7.string().transform(Number),
|
|
2227
|
+
avgPrice: z7.string().transform(Number),
|
|
2228
|
+
origQty: z7.string().transform(Number),
|
|
2229
|
+
executedQty: z7.string().transform(Number),
|
|
2230
|
+
cumBase: z7.string().transform(Number).optional(),
|
|
2231
|
+
type: z7.string(),
|
|
2232
|
+
reduceOnly: z7.boolean(),
|
|
2233
|
+
closePosition: z7.boolean().optional(),
|
|
2234
|
+
side: z7.string(),
|
|
2235
|
+
positionSide: z7.string(),
|
|
2236
|
+
stopPrice: z7.string().transform(Number).optional(),
|
|
2237
|
+
workingType: z7.string().optional(),
|
|
2238
|
+
priceProtect: z7.boolean().optional(),
|
|
2239
|
+
origType: z7.string().optional(),
|
|
2240
|
+
timeInForce: z7.string().optional(),
|
|
2241
|
+
activatePrice: z7.string().transform(Number).optional(),
|
|
2242
|
+
priceRate: z7.string().transform(Number).optional(),
|
|
2243
|
+
time: z7.number(),
|
|
2244
|
+
updateTime: z7.number()
|
|
2245
|
+
}).loose();
|
|
2246
|
+
var CoinMOrderResponseSchema = CoinMOrderSchema;
|
|
2247
|
+
var CoinMOrdersResponseSchema = z7.array(CoinMOrderSchema);
|
|
2248
|
+
var CoinMCreateOrderParamsSchema = z7.object({
|
|
2249
|
+
symbol: z7.string(),
|
|
2250
|
+
side: z7.enum(["BUY", "SELL"]),
|
|
2251
|
+
positionSide: z7.enum(["BOTH", "LONG", "SHORT"]).optional(),
|
|
2252
|
+
type: z7.string(),
|
|
2253
|
+
timeInForce: z7.enum(["GTC", "IOC", "FOK", "GTX"]).optional(),
|
|
2254
|
+
quantity: z7.union([z7.string(), z7.number()]).optional(),
|
|
2255
|
+
reduceOnly: z7.boolean().optional(),
|
|
2256
|
+
price: z7.union([z7.string(), z7.number()]).optional(),
|
|
2257
|
+
newClientOrderId: z7.string().optional(),
|
|
2258
|
+
stopPrice: z7.union([z7.string(), z7.number()]).optional(),
|
|
2259
|
+
closePosition: z7.boolean().optional(),
|
|
2260
|
+
activationPrice: z7.union([z7.string(), z7.number()]).optional(),
|
|
2261
|
+
callbackRate: z7.union([z7.string(), z7.number()]).optional(),
|
|
2262
|
+
workingType: z7.enum(["MARK_PRICE", "CONTRACT_PRICE"]).optional(),
|
|
2263
|
+
priceProtect: z7.boolean().optional(),
|
|
2264
|
+
newOrderRespType: z7.enum(["ACK", "RESULT"]).optional()
|
|
1973
2265
|
});
|
|
1974
|
-
var
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
p: z7.string().transform(Number),
|
|
1979
|
-
c: z7.array(
|
|
1980
|
-
z7.object({
|
|
1981
|
-
b: z7.string(),
|
|
1982
|
-
q: z7.string(),
|
|
1983
|
-
w: z7.string().transform(Number),
|
|
1984
|
-
p: z7.string().transform(Number)
|
|
1985
|
-
})
|
|
1986
|
-
)
|
|
2266
|
+
var CoinMLeverageChangeSchema = z7.object({
|
|
2267
|
+
leverage: z7.number(),
|
|
2268
|
+
maxQty: z7.string().transform(Number),
|
|
2269
|
+
symbol: z7.string()
|
|
1987
2270
|
});
|
|
1988
|
-
var
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2271
|
+
var CoinMMarginTypeChangeSchema = z7.object({ code: z7.number(), msg: z7.string() });
|
|
2272
|
+
var CoinMPositionMarginChangeSchema = z7.object({
|
|
2273
|
+
amount: z7.number(),
|
|
2274
|
+
code: z7.number(),
|
|
2275
|
+
msg: z7.string(),
|
|
2276
|
+
type: z7.number()
|
|
2277
|
+
});
|
|
2278
|
+
var CoinMIncomeSchema = z7.object({
|
|
2279
|
+
symbol: z7.string().optional(),
|
|
2280
|
+
incomeType: z7.string(),
|
|
2281
|
+
income: z7.string().transform(Number),
|
|
2282
|
+
asset: z7.string(),
|
|
2283
|
+
info: z7.string().optional(),
|
|
2284
|
+
time: z7.number(),
|
|
2285
|
+
tranId: z7.number(),
|
|
2286
|
+
tradeId: z7.string().optional()
|
|
2287
|
+
}).loose();
|
|
2288
|
+
var CoinMIncomeHistoryResponseSchema = z7.array(CoinMIncomeSchema);
|
|
2289
|
+
var CoinMUserTradeSchema = z7.object({
|
|
2290
|
+
symbol: z7.string(),
|
|
2291
|
+
id: z7.number(),
|
|
2292
|
+
orderId: z7.number(),
|
|
2293
|
+
pair: z7.string().optional(),
|
|
2294
|
+
side: z7.string(),
|
|
2295
|
+
price: z7.string().transform(Number),
|
|
2296
|
+
qty: z7.string().transform(Number),
|
|
2297
|
+
realizedPnl: z7.string().transform(Number),
|
|
2298
|
+
marginAsset: z7.string().optional(),
|
|
2299
|
+
baseQty: z7.string().transform(Number).optional(),
|
|
2300
|
+
commission: z7.string().transform(Number),
|
|
2301
|
+
commissionAsset: z7.string(),
|
|
2302
|
+
time: z7.number(),
|
|
2303
|
+
positionSide: z7.string(),
|
|
2304
|
+
buyer: z7.boolean(),
|
|
2305
|
+
maker: z7.boolean()
|
|
2306
|
+
}).loose();
|
|
2307
|
+
var CoinMUserTradesResponseSchema = z7.array(CoinMUserTradeSchema);
|
|
2308
|
+
var CoinMOpenInterestHistEntrySchema = z7.object({
|
|
2309
|
+
pair: z7.string(),
|
|
2310
|
+
contractType: z7.string(),
|
|
2311
|
+
sumOpenInterest: z7.string().transform(Number),
|
|
2312
|
+
sumOpenInterestValue: z7.string().transform(Number),
|
|
2313
|
+
timestamp: z7.number()
|
|
2314
|
+
});
|
|
2315
|
+
var CoinMOpenInterestHistSchema = z7.array(CoinMOpenInterestHistEntrySchema);
|
|
2316
|
+
var CoinMPositionModeSchema = z7.object({ dualSidePosition: z7.boolean() });
|
|
2317
|
+
var CoinMLeverageBracketSchema = z7.object({
|
|
2318
|
+
bracket: z7.number(),
|
|
2319
|
+
initialLeverage: z7.number(),
|
|
2320
|
+
qtyCap: z7.number(),
|
|
2321
|
+
qtyFloor: z7.number(),
|
|
2322
|
+
maintMarginRatio: z7.number(),
|
|
2323
|
+
cum: z7.number().optional()
|
|
2324
|
+
});
|
|
2325
|
+
var CoinMLeverageBracketResponseSchema = z7.array(
|
|
2326
|
+
z7.object({
|
|
2327
|
+
symbol: z7.string().optional(),
|
|
2328
|
+
pair: z7.string().optional(),
|
|
2329
|
+
brackets: z7.array(CoinMLeverageBracketSchema)
|
|
2330
|
+
})
|
|
2331
|
+
);
|
|
2332
|
+
var CoinMCommissionRateSchema = z7.object({
|
|
2333
|
+
symbol: z7.string(),
|
|
2334
|
+
makerCommissionRate: z7.string().transform(Number),
|
|
2335
|
+
takerCommissionRate: z7.string().transform(Number)
|
|
2018
2336
|
});
|
|
2019
|
-
function parseWsPayload(streamName, raw) {
|
|
2020
|
-
if (streamName.includes("@kline_")) return WsKlinePayloadSchema.parse(raw);
|
|
2021
|
-
if (streamName.includes("@continuousKline_") || streamName.includes("@indexPriceKline_") || streamName.includes("@markPriceKline_")) {
|
|
2022
|
-
return WsKlinePayloadSchema.parse(raw);
|
|
2023
|
-
}
|
|
2024
|
-
if (streamName.includes("@aggTrade")) return WsAggTradePayloadSchema.parse(raw);
|
|
2025
|
-
if (streamName.includes("@trade")) return WsTradePayloadSchema.parse(raw);
|
|
2026
|
-
if (streamName.includes("@depth")) return WsDepthUpdatePayloadSchema.parse(raw);
|
|
2027
|
-
if (streamName.includes("@bookTicker")) return WsBookTickerPayloadSchema.parse(raw);
|
|
2028
|
-
if (streamName.includes("@markPrice")) return WsMarkPricePayloadSchema.parse(raw);
|
|
2029
|
-
if (streamName.includes("@miniTicker")) return WsMiniTickerPayloadSchema.parse(raw);
|
|
2030
|
-
if (streamName.includes("@forceOrder")) return WsForceOrderPayloadSchema.parse(raw);
|
|
2031
|
-
if (streamName.includes("@compositeIndex")) return WsCompositeIndexPayloadSchema.parse(raw);
|
|
2032
|
-
if (streamName.includes("@assetIndex")) return WsAssetIndexPayloadSchema.parse(raw);
|
|
2033
|
-
if (streamName.includes("@avgPrice")) return WsSpotAvgPricePayloadSchema.parse(raw);
|
|
2034
|
-
if (streamName.includes("@ticker_")) return WsRollingWindowTickerPayloadSchema.parse(raw);
|
|
2035
|
-
if (streamName.includes("@ticker")) return WsTicker24hrPayloadSchema.parse(raw);
|
|
2036
|
-
throw new Error(`Unknown WS stream type: ${streamName}`);
|
|
2037
|
-
}
|
|
2038
2337
|
|
|
2039
|
-
// src/
|
|
2040
|
-
var
|
|
2041
|
-
constructor(
|
|
2042
|
-
super();
|
|
2043
|
-
this.options = options;
|
|
2044
|
-
this.ws = null;
|
|
2045
|
-
this.streams = /* @__PURE__ */ new Set();
|
|
2046
|
-
this.reconnectAttempt = 0;
|
|
2047
|
-
this.closedByUser = false;
|
|
2048
|
-
}
|
|
2049
|
-
subscribe(streams) {
|
|
2050
|
-
streams.forEach((s) => this.streams.add(s));
|
|
2051
|
-
if (this.isOpen()) {
|
|
2052
|
-
this.send({ method: "SUBSCRIBE", params: streams, id: Date.now() });
|
|
2053
|
-
} else {
|
|
2054
|
-
this.connect();
|
|
2055
|
-
}
|
|
2056
|
-
}
|
|
2057
|
-
unsubscribe(streams) {
|
|
2058
|
-
streams.forEach((s) => this.streams.delete(s));
|
|
2059
|
-
if (this.isOpen()) {
|
|
2060
|
-
this.send({ method: "UNSUBSCRIBE", params: streams, id: Date.now() });
|
|
2061
|
-
}
|
|
2062
|
-
}
|
|
2063
|
-
close() {
|
|
2064
|
-
this.closedByUser = true;
|
|
2065
|
-
this.ws?.close();
|
|
2338
|
+
// src/resources/CoinMMarket.ts
|
|
2339
|
+
var CoinMMarket = class extends MarketDataBase {
|
|
2340
|
+
constructor(http2) {
|
|
2341
|
+
super(http2 ?? new HttpClient({ baseURL: "https://dapi.binance.com/dapi/v1" }));
|
|
2066
2342
|
}
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2343
|
+
async continuousKlines(pair, contractType2, interval, options) {
|
|
2344
|
+
const data = await this.http.get("/continuousKlines", {
|
|
2345
|
+
pair,
|
|
2346
|
+
contractType: contractType2,
|
|
2347
|
+
interval,
|
|
2348
|
+
startTime: options?.startTime,
|
|
2349
|
+
endTime: options?.endTime,
|
|
2350
|
+
limit: options?.limit ?? 500
|
|
2351
|
+
});
|
|
2352
|
+
return KlinesResponseSchema.parse(data);
|
|
2071
2353
|
}
|
|
2072
|
-
|
|
2073
|
-
this.
|
|
2354
|
+
async indexPriceKlines(pair, interval, options) {
|
|
2355
|
+
const data = await this.http.get("/indexPriceKlines", {
|
|
2356
|
+
pair,
|
|
2357
|
+
interval,
|
|
2358
|
+
startTime: options?.startTime,
|
|
2359
|
+
endTime: options?.endTime,
|
|
2360
|
+
limit: options?.limit ?? 500
|
|
2361
|
+
});
|
|
2362
|
+
return KlinesResponseSchema.parse(data);
|
|
2074
2363
|
}
|
|
2075
|
-
|
|
2076
|
-
|
|
2364
|
+
async markPriceKlines(symbol3, interval, options) {
|
|
2365
|
+
const data = await this.http.get("/markPriceKlines", {
|
|
2366
|
+
symbol: symbol3,
|
|
2367
|
+
interval,
|
|
2368
|
+
startTime: options?.startTime,
|
|
2369
|
+
endTime: options?.endTime,
|
|
2370
|
+
limit: options?.limit ?? 500
|
|
2371
|
+
});
|
|
2372
|
+
return KlinesResponseSchema.parse(data);
|
|
2077
2373
|
}
|
|
2078
|
-
|
|
2079
|
-
|
|
2374
|
+
async premiumIndex(options) {
|
|
2375
|
+
return PremiumIndexSchema.or(PremiumIndexSchema.array()).parse(
|
|
2376
|
+
await this.http.get("/premiumIndex", options)
|
|
2377
|
+
);
|
|
2080
2378
|
}
|
|
2081
|
-
|
|
2082
|
-
this.
|
|
2083
|
-
const url = `${this.options.baseStreamUrl}?streams=${[...this.streams].join("/")}`;
|
|
2084
|
-
this.ws = new WebSocket(url);
|
|
2085
|
-
this.ws.on("open", () => {
|
|
2086
|
-
this.reconnectAttempt = 0;
|
|
2087
|
-
this.emit("open");
|
|
2088
|
-
});
|
|
2089
|
-
this.ws.on("message", (raw) => {
|
|
2090
|
-
this.handleMessage(raw.toString());
|
|
2091
|
-
});
|
|
2092
|
-
this.ws.on("close", () => {
|
|
2093
|
-
this.emit("close");
|
|
2094
|
-
if (!this.closedByUser) this.scheduleReconnect();
|
|
2095
|
-
});
|
|
2096
|
-
this.ws.on("error", (err) => {
|
|
2097
|
-
if (this.closedByUser) return;
|
|
2098
|
-
this.emit("error", err);
|
|
2099
|
-
});
|
|
2379
|
+
async fundingRateHistory(symbol3, options) {
|
|
2380
|
+
return FundingRateHistorySchema.parse(await this.http.get("/fundingRate", { symbol: symbol3, ...options }));
|
|
2100
2381
|
}
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
try {
|
|
2104
|
-
parsed = JSON.parse(raw);
|
|
2105
|
-
} catch {
|
|
2106
|
-
return;
|
|
2107
|
-
}
|
|
2108
|
-
if (!parsed.stream || parsed.data === void 0) return;
|
|
2109
|
-
try {
|
|
2110
|
-
const payload = parseWsPayload(parsed.stream, parsed.data);
|
|
2111
|
-
this.emit("message", parsed.stream, payload);
|
|
2112
|
-
this.emit(parsed.stream, payload);
|
|
2113
|
-
} catch (err) {
|
|
2114
|
-
this.emit("error", err);
|
|
2115
|
-
}
|
|
2382
|
+
async openInterest(symbol3) {
|
|
2383
|
+
return OpenInterestSchema.parse(await this.http.get("/openInterest", { symbol: symbol3 }));
|
|
2116
2384
|
}
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
this.reconnectAttempt += 1;
|
|
2122
|
-
setTimeout(() => {
|
|
2123
|
-
if (!this.closedByUser) this.connect();
|
|
2124
|
-
}, delay);
|
|
2385
|
+
async openInterestHist(pair, contractType2, period2, options) {
|
|
2386
|
+
return CoinMOpenInterestHistSchema.parse(
|
|
2387
|
+
await this.http.get("/openInterestHist", { pair, contractType: contractType2, period: period2, ...options })
|
|
2388
|
+
);
|
|
2125
2389
|
}
|
|
2126
2390
|
};
|
|
2127
2391
|
|
|
2128
|
-
// src/
|
|
2129
|
-
var
|
|
2130
|
-
constructor(
|
|
2131
|
-
|
|
2392
|
+
// src/resources/CoinMAccount.ts
|
|
2393
|
+
var CoinMAccount = class {
|
|
2394
|
+
constructor(http2) {
|
|
2395
|
+
this.http = http2;
|
|
2132
2396
|
}
|
|
2133
|
-
|
|
2134
|
-
return
|
|
2397
|
+
async balance() {
|
|
2398
|
+
return CoinMBalanceResponseSchema.parse(await this.http.get("/dapi/v1/balance", void 0, "signed"));
|
|
2135
2399
|
}
|
|
2136
|
-
|
|
2137
|
-
return
|
|
2400
|
+
async account() {
|
|
2401
|
+
return CoinMAccountSchema.parse(await this.http.get("/dapi/v1/account", void 0, "signed"));
|
|
2138
2402
|
}
|
|
2139
|
-
|
|
2140
|
-
return
|
|
2403
|
+
async positionRisk(options) {
|
|
2404
|
+
return CoinMPositionRiskResponseSchema.parse(
|
|
2405
|
+
await this.http.get("/dapi/v1/positionRisk", options, "signed")
|
|
2406
|
+
);
|
|
2141
2407
|
}
|
|
2142
|
-
|
|
2143
|
-
return
|
|
2408
|
+
async incomeHistory(options) {
|
|
2409
|
+
return CoinMIncomeHistoryResponseSchema.parse(await this.http.get("/dapi/v1/income", options, "signed"));
|
|
2144
2410
|
}
|
|
2145
|
-
|
|
2146
|
-
return
|
|
2411
|
+
async userTrades(options) {
|
|
2412
|
+
return CoinMUserTradesResponseSchema.parse(
|
|
2413
|
+
await this.http.get("/dapi/v1/userTrades", options, "signed")
|
|
2414
|
+
);
|
|
2147
2415
|
}
|
|
2148
|
-
|
|
2149
|
-
|
|
2416
|
+
async leverageBrackets(symbol3) {
|
|
2417
|
+
const params = symbol3 ? { symbol: symbol3 } : void 0;
|
|
2418
|
+
return CoinMLeverageBracketResponseSchema.parse(
|
|
2419
|
+
await this.http.get("/dapi/v1/leverageBracket", params, "signed")
|
|
2420
|
+
);
|
|
2421
|
+
}
|
|
2422
|
+
async commissionRate(symbol3) {
|
|
2423
|
+
return CoinMCommissionRateSchema.parse(
|
|
2424
|
+
await this.http.get("/dapi/v1/commissionRate", { symbol: symbol3 }, "signed")
|
|
2425
|
+
);
|
|
2426
|
+
}
|
|
2427
|
+
async positionMode() {
|
|
2428
|
+
return CoinMPositionModeSchema.parse(
|
|
2429
|
+
await this.http.get("/dapi/v1/positionSide/dual", void 0, "signed")
|
|
2430
|
+
);
|
|
2431
|
+
}
|
|
2432
|
+
async setPositionMode(dualSidePosition) {
|
|
2433
|
+
return this.http.post("/dapi/v1/positionSide/dual", { dualSidePosition }, "signed");
|
|
2434
|
+
}
|
|
2435
|
+
};
|
|
2436
|
+
|
|
2437
|
+
// src/resources/CoinMTrading.ts
|
|
2438
|
+
var CoinMTrading = class {
|
|
2439
|
+
constructor(http2) {
|
|
2440
|
+
this.http = http2;
|
|
2441
|
+
}
|
|
2442
|
+
async setLeverage(symbol3, leverage) {
|
|
2443
|
+
return CoinMLeverageChangeSchema.parse(
|
|
2444
|
+
await this.http.post("/dapi/v1/leverage", { symbol: symbol3, leverage }, "signed")
|
|
2445
|
+
);
|
|
2446
|
+
}
|
|
2447
|
+
async setMarginType(symbol3, marginType) {
|
|
2448
|
+
return CoinMMarginTypeChangeSchema.parse(
|
|
2449
|
+
await this.http.post("/dapi/v1/marginType", { symbol: symbol3, marginType }, "signed")
|
|
2450
|
+
);
|
|
2451
|
+
}
|
|
2452
|
+
async createOrder(params) {
|
|
2453
|
+
return CoinMOrderResponseSchema.parse(await this.http.post("/dapi/v1/order", params, "signed"));
|
|
2454
|
+
}
|
|
2455
|
+
async createTestOrder(params) {
|
|
2456
|
+
return this.http.post("/dapi/v1/order/test", params, "signed");
|
|
2457
|
+
}
|
|
2458
|
+
async getOrder(symbol3, options) {
|
|
2459
|
+
return CoinMOrderResponseSchema.parse(
|
|
2460
|
+
await this.http.get("/dapi/v1/order", { symbol: symbol3, ...options }, "signed")
|
|
2461
|
+
);
|
|
2462
|
+
}
|
|
2463
|
+
async cancelOrder(symbol3, options) {
|
|
2464
|
+
return CoinMOrderResponseSchema.parse(
|
|
2465
|
+
await this.http.delete("/dapi/v1/order", { symbol: symbol3, ...options }, "signed")
|
|
2466
|
+
);
|
|
2467
|
+
}
|
|
2468
|
+
async cancelAllOpenOrders(symbol3) {
|
|
2469
|
+
return this.http.delete("/dapi/v1/allOpenOrders", { symbol: symbol3 }, "signed");
|
|
2470
|
+
}
|
|
2471
|
+
async getOpenOrders(symbol3) {
|
|
2472
|
+
const params = symbol3 ? { symbol: symbol3 } : void 0;
|
|
2473
|
+
return CoinMOrdersResponseSchema.parse(await this.http.get("/dapi/v1/openOrders", params, "signed"));
|
|
2474
|
+
}
|
|
2475
|
+
async getAllOrders(symbol3, options) {
|
|
2476
|
+
return CoinMOrdersResponseSchema.parse(
|
|
2477
|
+
await this.http.get("/dapi/v1/allOrders", { symbol: symbol3, ...options }, "signed")
|
|
2478
|
+
);
|
|
2479
|
+
}
|
|
2480
|
+
async modifyPositionMargin(symbol3, amount, type) {
|
|
2481
|
+
return CoinMPositionMarginChangeSchema.parse(
|
|
2482
|
+
await this.http.post("/dapi/v1/positionMargin", { symbol: symbol3, amount, type }, "signed")
|
|
2483
|
+
);
|
|
2484
|
+
}
|
|
2485
|
+
};
|
|
2486
|
+
|
|
2487
|
+
// src/resources/CoinMUserDataStream.ts
|
|
2488
|
+
var CoinMUserDataStream = class {
|
|
2489
|
+
constructor(http2) {
|
|
2490
|
+
this.http = http2;
|
|
2491
|
+
}
|
|
2492
|
+
async createListenKey() {
|
|
2493
|
+
return ListenKeySchema.parse(await this.http.post("/dapi/v1/listenKey", void 0, "apiKey"));
|
|
2494
|
+
}
|
|
2495
|
+
async keepAliveListenKey() {
|
|
2496
|
+
return this.http.put("/dapi/v1/listenKey", void 0, "apiKey");
|
|
2497
|
+
}
|
|
2498
|
+
async closeListenKey() {
|
|
2499
|
+
return this.http.delete("/dapi/v1/listenKey", void 0, "apiKey");
|
|
2500
|
+
}
|
|
2501
|
+
};
|
|
2502
|
+
|
|
2503
|
+
// src/types/margin.types.ts
|
|
2504
|
+
import { z as z8 } from "zod";
|
|
2505
|
+
var MarginAssetBalanceSchema = z8.object({
|
|
2506
|
+
asset: z8.string(),
|
|
2507
|
+
borrowed: z8.string().transform(Number),
|
|
2508
|
+
free: z8.string().transform(Number),
|
|
2509
|
+
interest: z8.string().transform(Number),
|
|
2510
|
+
locked: z8.string().transform(Number),
|
|
2511
|
+
netAsset: z8.string().transform(Number)
|
|
2512
|
+
});
|
|
2513
|
+
var CrossMarginAccountSchema = z8.object({
|
|
2514
|
+
borrowEnabled: z8.boolean(),
|
|
2515
|
+
marginLevel: z8.string().transform(Number),
|
|
2516
|
+
totalAssetOfBtc: z8.string().transform(Number),
|
|
2517
|
+
totalLiabilityOfBtc: z8.string().transform(Number),
|
|
2518
|
+
totalNetAssetOfBtc: z8.string().transform(Number),
|
|
2519
|
+
tradeEnabled: z8.boolean(),
|
|
2520
|
+
transferEnabled: z8.boolean(),
|
|
2521
|
+
accountType: z8.string().optional(),
|
|
2522
|
+
userAssets: z8.array(MarginAssetBalanceSchema)
|
|
2523
|
+
}).loose();
|
|
2524
|
+
var IsolatedMarginAssetSchema = z8.object({
|
|
2525
|
+
asset: z8.string(),
|
|
2526
|
+
borrowEnabled: z8.boolean(),
|
|
2527
|
+
borrowed: z8.string().transform(Number),
|
|
2528
|
+
free: z8.string().transform(Number),
|
|
2529
|
+
interest: z8.string().transform(Number),
|
|
2530
|
+
locked: z8.string().transform(Number),
|
|
2531
|
+
netAsset: z8.string().transform(Number),
|
|
2532
|
+
netAssetOfBtc: z8.string().transform(Number),
|
|
2533
|
+
repayEnabled: z8.boolean(),
|
|
2534
|
+
totalAsset: z8.string().transform(Number)
|
|
2535
|
+
}).loose();
|
|
2536
|
+
var IsolatedMarginSymbolSchema = z8.object({
|
|
2537
|
+
baseAsset: IsolatedMarginAssetSchema,
|
|
2538
|
+
quoteAsset: IsolatedMarginAssetSchema,
|
|
2539
|
+
symbol: z8.string(),
|
|
2540
|
+
isolatedCreated: z8.boolean().optional(),
|
|
2541
|
+
enabled: z8.boolean(),
|
|
2542
|
+
marginLevel: z8.string().transform(Number),
|
|
2543
|
+
marginLevelStatus: z8.string().optional(),
|
|
2544
|
+
marginRatio: z8.string().transform(Number).optional(),
|
|
2545
|
+
indexPrice: z8.string().transform(Number).optional(),
|
|
2546
|
+
liquidatePrice: z8.string().transform(Number).optional(),
|
|
2547
|
+
liquidateRate: z8.string().transform(Number).optional(),
|
|
2548
|
+
tradeEnabled: z8.boolean()
|
|
2549
|
+
}).loose();
|
|
2550
|
+
var IsolatedMarginAccountSchema = z8.object({
|
|
2551
|
+
assets: z8.array(IsolatedMarginSymbolSchema),
|
|
2552
|
+
totalAssetOfBtc: z8.string().transform(Number).optional(),
|
|
2553
|
+
totalLiabilityOfBtc: z8.string().transform(Number).optional(),
|
|
2554
|
+
totalNetAssetOfBtc: z8.string().transform(Number).optional()
|
|
2555
|
+
});
|
|
2556
|
+
var MaxBorrowableSchema = z8.object({
|
|
2557
|
+
amount: z8.string().transform(Number),
|
|
2558
|
+
borrowLimit: z8.string().transform(Number)
|
|
2559
|
+
});
|
|
2560
|
+
var MaxTransferableSchema = z8.object({
|
|
2561
|
+
amount: z8.string().transform(Number),
|
|
2562
|
+
fullAmount: z8.string().transform(Number).optional()
|
|
2563
|
+
});
|
|
2564
|
+
var BorrowRepayParamsSchema = z8.object({
|
|
2565
|
+
asset: z8.string(),
|
|
2566
|
+
isIsolated: z8.enum(["TRUE", "FALSE"]).optional(),
|
|
2567
|
+
symbol: z8.string().optional(),
|
|
2568
|
+
amount: z8.union([z8.string(), z8.number()]),
|
|
2569
|
+
type: z8.enum(["BORROW", "REPAY"])
|
|
2570
|
+
});
|
|
2571
|
+
var BorrowRepayResultSchema = z8.object({ tranId: z8.number() });
|
|
2572
|
+
var BorrowRepayRecordEntrySchema = z8.object({
|
|
2573
|
+
isolatedSymbol: z8.string().optional(),
|
|
2574
|
+
txId: z8.number(),
|
|
2575
|
+
asset: z8.string(),
|
|
2576
|
+
principal: z8.string().transform(Number),
|
|
2577
|
+
timestamp: z8.number(),
|
|
2578
|
+
status: z8.string()
|
|
2579
|
+
}).loose();
|
|
2580
|
+
var BorrowRepayRecordResponseSchema = z8.object({
|
|
2581
|
+
rows: z8.array(BorrowRepayRecordEntrySchema),
|
|
2582
|
+
total: z8.number()
|
|
2583
|
+
});
|
|
2584
|
+
var MarginTransferResultSchema = z8.object({ tranId: z8.number() });
|
|
2585
|
+
var IsolatedTransferParamsSchema = z8.object({
|
|
2586
|
+
asset: z8.string(),
|
|
2587
|
+
symbol: z8.string(),
|
|
2588
|
+
transFrom: z8.enum(["SPOT", "ISOLATED_MARGIN"]),
|
|
2589
|
+
transTo: z8.enum(["SPOT", "ISOLATED_MARGIN"]),
|
|
2590
|
+
amount: z8.union([z8.string(), z8.number()])
|
|
2591
|
+
});
|
|
2592
|
+
var MarginInterestHistoryEntrySchema = z8.object({
|
|
2593
|
+
txId: z8.number(),
|
|
2594
|
+
interestAccuredTime: z8.number(),
|
|
2595
|
+
asset: z8.string(),
|
|
2596
|
+
rawAsset: z8.string().optional(),
|
|
2597
|
+
principal: z8.string().transform(Number),
|
|
2598
|
+
interest: z8.string().transform(Number),
|
|
2599
|
+
interestRate: z8.string().transform(Number),
|
|
2600
|
+
type: z8.string(),
|
|
2601
|
+
isolatedSymbol: z8.string().optional()
|
|
2602
|
+
}).loose();
|
|
2603
|
+
var MarginInterestHistoryResponseSchema = z8.object({
|
|
2604
|
+
rows: z8.array(MarginInterestHistoryEntrySchema),
|
|
2605
|
+
total: z8.number()
|
|
2606
|
+
});
|
|
2607
|
+
var MarginForceLiquidationEntrySchema = z8.object({
|
|
2608
|
+
avgPrice: z8.string().transform(Number),
|
|
2609
|
+
executedQty: z8.string().transform(Number),
|
|
2610
|
+
orderId: z8.number(),
|
|
2611
|
+
price: z8.string().transform(Number),
|
|
2612
|
+
qty: z8.string().transform(Number),
|
|
2613
|
+
side: z8.string(),
|
|
2614
|
+
symbol: z8.string(),
|
|
2615
|
+
timeInForce: z8.string(),
|
|
2616
|
+
isIsolated: z8.boolean().optional(),
|
|
2617
|
+
updatedTime: z8.number()
|
|
2618
|
+
}).loose();
|
|
2619
|
+
var MarginForceLiquidationResponseSchema = z8.object({
|
|
2620
|
+
rows: z8.array(MarginForceLiquidationEntrySchema),
|
|
2621
|
+
total: z8.number()
|
|
2622
|
+
});
|
|
2623
|
+
var MarginPriceIndexSchema = z8.object({
|
|
2624
|
+
calcTime: z8.number(),
|
|
2625
|
+
price: z8.string().transform(Number),
|
|
2626
|
+
symbol: z8.string()
|
|
2627
|
+
});
|
|
2628
|
+
var MarginOrderSchema = z8.object({
|
|
2629
|
+
symbol: z8.string(),
|
|
2630
|
+
orderId: z8.number(),
|
|
2631
|
+
clientOrderId: z8.string(),
|
|
2632
|
+
isIsolated: z8.boolean().optional(),
|
|
2633
|
+
price: z8.string().transform(Number),
|
|
2634
|
+
origQty: z8.string().transform(Number),
|
|
2635
|
+
executedQty: z8.string().transform(Number),
|
|
2636
|
+
cummulativeQuoteQty: z8.string().transform(Number),
|
|
2637
|
+
status: z8.string(),
|
|
2638
|
+
timeInForce: z8.string().optional(),
|
|
2639
|
+
type: z8.string(),
|
|
2640
|
+
side: z8.string(),
|
|
2641
|
+
transactTime: z8.number().optional(),
|
|
2642
|
+
time: z8.number().optional(),
|
|
2643
|
+
updateTime: z8.number().optional(),
|
|
2644
|
+
fills: z8.array(z8.unknown()).optional()
|
|
2645
|
+
}).loose();
|
|
2646
|
+
var MarginOrderResponseSchema = MarginOrderSchema;
|
|
2647
|
+
var MarginOrdersResponseSchema = z8.array(MarginOrderSchema);
|
|
2648
|
+
var MarginCreateOrderParamsSchema = z8.object({
|
|
2649
|
+
symbol: z8.string(),
|
|
2650
|
+
isIsolated: z8.enum(["TRUE", "FALSE"]).optional(),
|
|
2651
|
+
side: z8.enum(["BUY", "SELL"]),
|
|
2652
|
+
type: z8.string(),
|
|
2653
|
+
quantity: z8.union([z8.string(), z8.number()]).optional(),
|
|
2654
|
+
quoteOrderQty: z8.union([z8.string(), z8.number()]).optional(),
|
|
2655
|
+
price: z8.union([z8.string(), z8.number()]).optional(),
|
|
2656
|
+
stopPrice: z8.union([z8.string(), z8.number()]).optional(),
|
|
2657
|
+
newClientOrderId: z8.string().optional(),
|
|
2658
|
+
icebergQty: z8.union([z8.string(), z8.number()]).optional(),
|
|
2659
|
+
timeInForce: z8.enum(["GTC", "IOC", "FOK"]).optional(),
|
|
2660
|
+
sideEffectType: z8.enum(["NO_SIDE_EFFECT", "MARGIN_BUY", "AUTO_REPAY", "AUTO_BORROW_REPAY"]).optional(),
|
|
2661
|
+
newOrderRespType: z8.enum(["ACK", "RESULT", "FULL"]).optional(),
|
|
2662
|
+
autoRepayAtCancel: z8.boolean().optional()
|
|
2663
|
+
});
|
|
2664
|
+
var MarginTradeSchema = z8.object({
|
|
2665
|
+
symbol: z8.string(),
|
|
2666
|
+
id: z8.number(),
|
|
2667
|
+
orderId: z8.number(),
|
|
2668
|
+
price: z8.string().transform(Number),
|
|
2669
|
+
qty: z8.string().transform(Number),
|
|
2670
|
+
quoteQty: z8.string().transform(Number),
|
|
2671
|
+
commission: z8.string().transform(Number),
|
|
2672
|
+
commissionAsset: z8.string(),
|
|
2673
|
+
time: z8.number(),
|
|
2674
|
+
isBuyer: z8.boolean(),
|
|
2675
|
+
isMaker: z8.boolean(),
|
|
2676
|
+
isBestMatch: z8.boolean().optional(),
|
|
2677
|
+
isIsolated: z8.boolean().optional()
|
|
2678
|
+
}).loose();
|
|
2679
|
+
var MarginTradesResponseSchema = z8.array(MarginTradeSchema);
|
|
2680
|
+
|
|
2681
|
+
// src/resources/Margin.ts
|
|
2682
|
+
var MarginAccount = class {
|
|
2683
|
+
constructor(http2) {
|
|
2684
|
+
this.http = http2;
|
|
2685
|
+
}
|
|
2686
|
+
async crossAccount() {
|
|
2687
|
+
return CrossMarginAccountSchema.parse(await this.http.get("/sapi/v1/margin/account", void 0, "signed"));
|
|
2688
|
+
}
|
|
2689
|
+
async isolatedAccount(symbols) {
|
|
2690
|
+
const params = symbols?.length ? { symbols: symbols.join(",") } : void 0;
|
|
2691
|
+
return IsolatedMarginAccountSchema.parse(
|
|
2692
|
+
await this.http.get("/sapi/v1/margin/isolated/account", params, "signed")
|
|
2693
|
+
);
|
|
2694
|
+
}
|
|
2695
|
+
async maxBorrowable(asset, isolatedSymbol) {
|
|
2696
|
+
return MaxBorrowableSchema.parse(
|
|
2697
|
+
await this.http.get("/sapi/v1/margin/maxBorrowable", { asset, isolatedSymbol }, "signed")
|
|
2698
|
+
);
|
|
2699
|
+
}
|
|
2700
|
+
async maxTransferable(asset, isolatedSymbol) {
|
|
2701
|
+
return MaxTransferableSchema.parse(
|
|
2702
|
+
await this.http.get("/sapi/v1/margin/maxTransferable", { asset, isolatedSymbol }, "signed")
|
|
2703
|
+
);
|
|
2704
|
+
}
|
|
2705
|
+
async borrowRepay(params) {
|
|
2706
|
+
return BorrowRepayResultSchema.parse(
|
|
2707
|
+
await this.http.post("/sapi/v1/margin/borrow-repay", params, "signed")
|
|
2708
|
+
);
|
|
2709
|
+
}
|
|
2710
|
+
async borrow(asset, amount, options) {
|
|
2711
|
+
return this.borrowRepay({
|
|
2712
|
+
asset,
|
|
2713
|
+
amount,
|
|
2714
|
+
type: "BORROW",
|
|
2715
|
+
isIsolated: options?.isIsolated ? "TRUE" : void 0,
|
|
2716
|
+
symbol: options?.symbol
|
|
2717
|
+
});
|
|
2718
|
+
}
|
|
2719
|
+
async repay(asset, amount, options) {
|
|
2720
|
+
return this.borrowRepay({
|
|
2721
|
+
asset,
|
|
2722
|
+
amount,
|
|
2723
|
+
type: "REPAY",
|
|
2724
|
+
isIsolated: options?.isIsolated ? "TRUE" : void 0,
|
|
2725
|
+
symbol: options?.symbol
|
|
2726
|
+
});
|
|
2727
|
+
}
|
|
2728
|
+
async borrowRepayRecord(type, options) {
|
|
2729
|
+
return BorrowRepayRecordResponseSchema.parse(
|
|
2730
|
+
await this.http.get("/sapi/v1/margin/borrow-repay", { type, ...options }, "signed")
|
|
2731
|
+
);
|
|
2732
|
+
}
|
|
2733
|
+
async transfer(asset, amount, type) {
|
|
2734
|
+
return MarginTransferResultSchema.parse(
|
|
2735
|
+
await this.http.post("/sapi/v1/margin/transfer", { asset, amount, type }, "signed")
|
|
2736
|
+
);
|
|
2737
|
+
}
|
|
2738
|
+
async isolatedTransfer(params) {
|
|
2739
|
+
return MarginTransferResultSchema.parse(
|
|
2740
|
+
await this.http.post("/sapi/v1/margin/isolated/transfer", params, "signed")
|
|
2741
|
+
);
|
|
2742
|
+
}
|
|
2743
|
+
async interestHistory(options) {
|
|
2744
|
+
return MarginInterestHistoryResponseSchema.parse(
|
|
2745
|
+
await this.http.get("/sapi/v1/margin/interestHistory", options, "signed")
|
|
2746
|
+
);
|
|
2747
|
+
}
|
|
2748
|
+
async forceLiquidationRecord(options) {
|
|
2749
|
+
return MarginForceLiquidationResponseSchema.parse(
|
|
2750
|
+
await this.http.get("/sapi/v1/margin/forceLiquidationRec", options, "signed")
|
|
2751
|
+
);
|
|
2752
|
+
}
|
|
2753
|
+
async priceIndex(symbol3) {
|
|
2754
|
+
return MarginPriceIndexSchema.parse(await this.http.get("/sapi/v1/margin/priceIndex", { symbol: symbol3 }));
|
|
2755
|
+
}
|
|
2756
|
+
};
|
|
2757
|
+
var MarginTrading = class {
|
|
2758
|
+
constructor(http2) {
|
|
2759
|
+
this.http = http2;
|
|
2760
|
+
}
|
|
2761
|
+
async createOrder(params) {
|
|
2762
|
+
return MarginOrderResponseSchema.parse(await this.http.post("/sapi/v1/margin/order", params, "signed"));
|
|
2763
|
+
}
|
|
2764
|
+
async cancelOrder(symbol3, options) {
|
|
2765
|
+
return MarginOrderResponseSchema.parse(
|
|
2766
|
+
await this.http.delete("/sapi/v1/margin/order", { symbol: symbol3, ...options }, "signed")
|
|
2767
|
+
);
|
|
2768
|
+
}
|
|
2769
|
+
async cancelAllOpenOrders(symbol3, isIsolated) {
|
|
2770
|
+
return MarginOrdersResponseSchema.parse(
|
|
2771
|
+
await this.http.delete("/sapi/v1/margin/openOrders", { symbol: symbol3, isIsolated }, "signed")
|
|
2772
|
+
);
|
|
2773
|
+
}
|
|
2774
|
+
async getOrder(symbol3, options) {
|
|
2775
|
+
return MarginOrderResponseSchema.parse(
|
|
2776
|
+
await this.http.get("/sapi/v1/margin/order", { symbol: symbol3, ...options }, "signed")
|
|
2777
|
+
);
|
|
2778
|
+
}
|
|
2779
|
+
async getOpenOrders(options) {
|
|
2780
|
+
return MarginOrdersResponseSchema.parse(await this.http.get("/sapi/v1/margin/openOrders", options, "signed"));
|
|
2781
|
+
}
|
|
2782
|
+
async getAllOrders(symbol3, options) {
|
|
2783
|
+
return MarginOrdersResponseSchema.parse(
|
|
2784
|
+
await this.http.get("/sapi/v1/margin/allOrders", { symbol: symbol3, ...options }, "signed")
|
|
2785
|
+
);
|
|
2786
|
+
}
|
|
2787
|
+
async myTrades(symbol3, options) {
|
|
2788
|
+
return MarginTradesResponseSchema.parse(
|
|
2789
|
+
await this.http.get("/sapi/v1/margin/myTrades", { symbol: symbol3, ...options }, "signed")
|
|
2790
|
+
);
|
|
2791
|
+
}
|
|
2792
|
+
};
|
|
2793
|
+
|
|
2794
|
+
// src/types/wallet.types.ts
|
|
2795
|
+
import { z as z9 } from "zod";
|
|
2796
|
+
var TransferTypeSchema = z9.enum([
|
|
2797
|
+
"MAIN_UMFUTURE",
|
|
2798
|
+
"MAIN_CMFUTURE",
|
|
2799
|
+
"MAIN_MARGIN",
|
|
2800
|
+
"MAIN_MINING",
|
|
2801
|
+
"MAIN_FUNDING",
|
|
2802
|
+
"MAIN_OPTION",
|
|
2803
|
+
"UMFUTURE_MAIN",
|
|
2804
|
+
"UMFUTURE_MARGIN",
|
|
2805
|
+
"UMFUTURE_FUNDING",
|
|
2806
|
+
"CMFUTURE_MAIN",
|
|
2807
|
+
"CMFUTURE_MARGIN",
|
|
2808
|
+
"MARGIN_MAIN",
|
|
2809
|
+
"MARGIN_UMFUTURE",
|
|
2810
|
+
"MARGIN_CMFUTURE",
|
|
2811
|
+
"MARGIN_MINING",
|
|
2812
|
+
"MARGIN_FUNDING",
|
|
2813
|
+
"MINING_MAIN",
|
|
2814
|
+
"MINING_UMFUTURE",
|
|
2815
|
+
"MINING_MARGIN",
|
|
2816
|
+
"FUNDING_MAIN",
|
|
2817
|
+
"FUNDING_UMFUTURE",
|
|
2818
|
+
"FUNDING_MARGIN",
|
|
2819
|
+
"FUNDING_CMFUTURE",
|
|
2820
|
+
"OPTION_MAIN",
|
|
2821
|
+
"MAIN_OPTION_MARGIN",
|
|
2822
|
+
"MAIN_PORTFOLIO_MARGIN",
|
|
2823
|
+
"PORTFOLIO_MARGIN_MAIN",
|
|
2824
|
+
"ISOLATEDMARGIN_MARGIN",
|
|
2825
|
+
"MARGIN_ISOLATEDMARGIN",
|
|
2826
|
+
"ISOLATEDMARGIN_ISOLATEDMARGIN"
|
|
2827
|
+
]);
|
|
2828
|
+
var UniversalTransferParamsSchema = z9.object({
|
|
2829
|
+
type: TransferTypeSchema,
|
|
2830
|
+
asset: z9.string(),
|
|
2831
|
+
amount: z9.union([z9.string(), z9.number()]),
|
|
2832
|
+
fromSymbol: z9.string().optional(),
|
|
2833
|
+
toSymbol: z9.string().optional()
|
|
2834
|
+
});
|
|
2835
|
+
var UniversalTransferResultSchema = z9.object({ tranId: z9.number() });
|
|
2836
|
+
var UniversalTransferHistoryEntrySchema = z9.object({
|
|
2837
|
+
asset: z9.string(),
|
|
2838
|
+
amount: z9.string().transform(Number),
|
|
2839
|
+
type: z9.string(),
|
|
2840
|
+
status: z9.string(),
|
|
2841
|
+
tranId: z9.number(),
|
|
2842
|
+
timestamp: z9.number(),
|
|
2843
|
+
fromSymbol: z9.string().nullable().optional(),
|
|
2844
|
+
toSymbol: z9.string().nullable().optional()
|
|
2845
|
+
}).loose();
|
|
2846
|
+
var UniversalTransferHistoryResponseSchema = z9.object({
|
|
2847
|
+
total: z9.number(),
|
|
2848
|
+
rows: z9.array(UniversalTransferHistoryEntrySchema)
|
|
2849
|
+
});
|
|
2850
|
+
var FundingAssetSchema = z9.object({
|
|
2851
|
+
asset: z9.string(),
|
|
2852
|
+
free: z9.string().transform(Number),
|
|
2853
|
+
locked: z9.string().transform(Number),
|
|
2854
|
+
freeze: z9.string().transform(Number),
|
|
2855
|
+
withdrawing: z9.string().transform(Number),
|
|
2856
|
+
btcValuation: z9.string().transform(Number)
|
|
2857
|
+
});
|
|
2858
|
+
var FundingAssetsResponseSchema = z9.array(FundingAssetSchema);
|
|
2859
|
+
var UserAssetSchema = z9.object({
|
|
2860
|
+
asset: z9.string(),
|
|
2861
|
+
free: z9.string().transform(Number),
|
|
2862
|
+
locked: z9.string().transform(Number),
|
|
2863
|
+
freeze: z9.string().transform(Number),
|
|
2864
|
+
withdrawing: z9.string().transform(Number),
|
|
2865
|
+
ipoable: z9.string().transform(Number),
|
|
2866
|
+
btcValuation: z9.string().transform(Number)
|
|
2867
|
+
});
|
|
2868
|
+
var UserAssetsResponseSchema = z9.array(UserAssetSchema);
|
|
2869
|
+
var DepositHistoryEntrySchema = z9.object({
|
|
2870
|
+
id: z9.string(),
|
|
2871
|
+
amount: z9.string().transform(Number),
|
|
2872
|
+
coin: z9.string(),
|
|
2873
|
+
network: z9.string(),
|
|
2874
|
+
status: z9.number(),
|
|
2875
|
+
address: z9.string(),
|
|
2876
|
+
addressTag: z9.string().optional(),
|
|
2877
|
+
txId: z9.string(),
|
|
2878
|
+
insertTime: z9.number(),
|
|
2879
|
+
transferType: z9.number(),
|
|
2880
|
+
confirmTimes: z9.string().optional(),
|
|
2881
|
+
unlockConfirm: z9.union([z9.string(), z9.number()]).optional(),
|
|
2882
|
+
walletType: z9.number().optional()
|
|
2883
|
+
}).loose();
|
|
2884
|
+
var DepositHistoryResponseSchema = z9.array(DepositHistoryEntrySchema);
|
|
2885
|
+
var WithdrawHistoryEntrySchema = z9.object({
|
|
2886
|
+
id: z9.string(),
|
|
2887
|
+
amount: z9.string().transform(Number),
|
|
2888
|
+
transactionFee: z9.string().transform(Number),
|
|
2889
|
+
coin: z9.string(),
|
|
2890
|
+
status: z9.number(),
|
|
2891
|
+
address: z9.string(),
|
|
2892
|
+
txId: z9.string().optional(),
|
|
2893
|
+
applyTime: z9.string(),
|
|
2894
|
+
network: z9.string(),
|
|
2895
|
+
transferType: z9.number(),
|
|
2896
|
+
withdrawOrderId: z9.string().nullable().optional(),
|
|
2897
|
+
info: z9.string().optional(),
|
|
2898
|
+
confirmNo: z9.number().optional(),
|
|
2899
|
+
walletType: z9.number().optional()
|
|
2900
|
+
}).loose();
|
|
2901
|
+
var WithdrawHistoryResponseSchema = z9.array(WithdrawHistoryEntrySchema);
|
|
2902
|
+
var WithdrawParamsSchema = z9.object({
|
|
2903
|
+
coin: z9.string(),
|
|
2904
|
+
address: z9.string(),
|
|
2905
|
+
amount: z9.union([z9.string(), z9.number()]),
|
|
2906
|
+
withdrawOrderId: z9.string().optional(),
|
|
2907
|
+
network: z9.string().optional(),
|
|
2908
|
+
addressTag: z9.string().optional(),
|
|
2909
|
+
transactionFeeFlag: z9.boolean().optional(),
|
|
2910
|
+
name: z9.string().optional(),
|
|
2911
|
+
walletType: z9.number().optional()
|
|
2912
|
+
});
|
|
2913
|
+
var WithdrawResultSchema = z9.object({ id: z9.string() });
|
|
2914
|
+
var DepositAddressSchema = z9.object({
|
|
2915
|
+
address: z9.string(),
|
|
2916
|
+
coin: z9.string(),
|
|
2917
|
+
tag: z9.string(),
|
|
2918
|
+
url: z9.string().optional()
|
|
2919
|
+
});
|
|
2920
|
+
var ApiKeyPermissionsSchema = z9.object({
|
|
2921
|
+
ipRestrict: z9.boolean(),
|
|
2922
|
+
createTime: z9.number(),
|
|
2923
|
+
enableWithdrawals: z9.boolean(),
|
|
2924
|
+
enableInternalTransfer: z9.boolean(),
|
|
2925
|
+
enableFutures: z9.boolean(),
|
|
2926
|
+
enableMargin: z9.boolean(),
|
|
2927
|
+
enableSpotAndMarginTrading: z9.boolean(),
|
|
2928
|
+
permitsUniversalTransfer: z9.boolean().optional(),
|
|
2929
|
+
enableReading: z9.boolean().optional(),
|
|
2930
|
+
tradingAuthorityExpirationTime: z9.number().optional()
|
|
2931
|
+
}).loose();
|
|
2932
|
+
var AssetDetailSchema = z9.record(
|
|
2933
|
+
z9.string(),
|
|
2934
|
+
z9.object({
|
|
2935
|
+
minWithdrawAmount: z9.string().transform(Number),
|
|
2936
|
+
depositStatus: z9.boolean(),
|
|
2937
|
+
withdrawFee: z9.number(),
|
|
2938
|
+
withdrawStatus: z9.boolean(),
|
|
2939
|
+
depositTip: z9.string().optional()
|
|
2940
|
+
}).loose()
|
|
2941
|
+
);
|
|
2942
|
+
var DustLogEntrySchema = z9.object({
|
|
2943
|
+
transId: z9.number(),
|
|
2944
|
+
serviceChargeAmount: z9.string().transform(Number),
|
|
2945
|
+
amount: z9.string().transform(Number),
|
|
2946
|
+
operateTime: z9.string(),
|
|
2947
|
+
transferedAmount: z9.string().transform(Number),
|
|
2948
|
+
fromAsset: z9.string()
|
|
2949
|
+
}).loose();
|
|
2950
|
+
var DustLogResponseSchema = z9.object({
|
|
2951
|
+
total: z9.number(),
|
|
2952
|
+
userAssetDribblets: z9.array(
|
|
2953
|
+
z9.object({
|
|
2954
|
+
operateTime: z9.number(),
|
|
2955
|
+
totalTransferedAmount: z9.string().transform(Number),
|
|
2956
|
+
totalServiceChargeAmount: z9.string().transform(Number),
|
|
2957
|
+
transId: z9.number(),
|
|
2958
|
+
userAssetDribbletDetails: z9.array(DustLogEntrySchema)
|
|
2959
|
+
})
|
|
2960
|
+
)
|
|
2961
|
+
});
|
|
2962
|
+
var DustConversionResultSchema = z9.object({
|
|
2963
|
+
totalServiceCharge: z9.string().transform(Number),
|
|
2964
|
+
totalTransfered: z9.string().transform(Number),
|
|
2965
|
+
transferResult: z9.array(
|
|
2966
|
+
z9.object({
|
|
2967
|
+
amount: z9.string().transform(Number),
|
|
2968
|
+
fromAsset: z9.string(),
|
|
2969
|
+
operateTime: z9.number(),
|
|
2970
|
+
serviceChargeAmount: z9.string().transform(Number),
|
|
2971
|
+
tranId: z9.number(),
|
|
2972
|
+
transferedAmount: z9.string().transform(Number)
|
|
2973
|
+
}).loose()
|
|
2974
|
+
)
|
|
2975
|
+
}).loose();
|
|
2976
|
+
var TradeFeeEntrySchema = z9.object({
|
|
2977
|
+
symbol: z9.string(),
|
|
2978
|
+
makerCommission: z9.string().transform(Number),
|
|
2979
|
+
takerCommission: z9.string().transform(Number)
|
|
2980
|
+
});
|
|
2981
|
+
var TradeFeeResponseSchema = z9.array(TradeFeeEntrySchema);
|
|
2982
|
+
var AccountSnapshotSchema = z9.object({
|
|
2983
|
+
code: z9.number(),
|
|
2984
|
+
msg: z9.string(),
|
|
2985
|
+
snapshotVos: z9.array(
|
|
2986
|
+
z9.object({
|
|
2987
|
+
type: z9.string(),
|
|
2988
|
+
updateTime: z9.number(),
|
|
2989
|
+
data: z9.record(z9.string(), z9.unknown())
|
|
2990
|
+
}).loose()
|
|
2991
|
+
)
|
|
2992
|
+
}).loose();
|
|
2993
|
+
|
|
2994
|
+
// src/resources/Wallet.ts
|
|
2995
|
+
var Wallet = class {
|
|
2996
|
+
constructor(http2) {
|
|
2997
|
+
this.http = http2;
|
|
2998
|
+
}
|
|
2999
|
+
async universalTransfer(params) {
|
|
3000
|
+
return UniversalTransferResultSchema.parse(
|
|
3001
|
+
await this.http.post("/sapi/v1/asset/transfer", params, "signed")
|
|
3002
|
+
);
|
|
3003
|
+
}
|
|
3004
|
+
async universalTransferHistory(options) {
|
|
3005
|
+
return UniversalTransferHistoryResponseSchema.parse(
|
|
3006
|
+
await this.http.get("/sapi/v1/asset/transfer", options, "signed")
|
|
3007
|
+
);
|
|
3008
|
+
}
|
|
3009
|
+
async fundingWallet(options) {
|
|
3010
|
+
return FundingAssetsResponseSchema.parse(
|
|
3011
|
+
await this.http.post("/sapi/v1/asset/get-funding-asset", options, "signed")
|
|
3012
|
+
);
|
|
3013
|
+
}
|
|
3014
|
+
async userAsset(options) {
|
|
3015
|
+
return UserAssetsResponseSchema.parse(
|
|
3016
|
+
await this.http.post("/sapi/v3/asset/getUserAsset", options, "signed")
|
|
3017
|
+
);
|
|
3018
|
+
}
|
|
3019
|
+
async depositHistory(options) {
|
|
3020
|
+
return DepositHistoryResponseSchema.parse(
|
|
3021
|
+
await this.http.get("/sapi/v1/capital/deposit/hisrec", options, "signed")
|
|
3022
|
+
);
|
|
3023
|
+
}
|
|
3024
|
+
async withdrawHistory(options) {
|
|
3025
|
+
return WithdrawHistoryResponseSchema.parse(
|
|
3026
|
+
await this.http.get("/sapi/v1/capital/withdraw/history", options, "signed")
|
|
3027
|
+
);
|
|
3028
|
+
}
|
|
3029
|
+
async withdraw(params) {
|
|
3030
|
+
return WithdrawResultSchema.parse(
|
|
3031
|
+
await this.http.post("/sapi/v1/capital/withdraw/apply", params, "signed")
|
|
3032
|
+
);
|
|
3033
|
+
}
|
|
3034
|
+
async depositAddress(coin, network) {
|
|
3035
|
+
return DepositAddressSchema.parse(
|
|
3036
|
+
await this.http.get("/sapi/v1/capital/deposit/address", { coin, network }, "signed")
|
|
3037
|
+
);
|
|
3038
|
+
}
|
|
3039
|
+
async accountSnapshot(type, options) {
|
|
3040
|
+
return AccountSnapshotSchema.parse(
|
|
3041
|
+
await this.http.get("/sapi/v1/accountSnapshot", { type, ...options }, "signed")
|
|
3042
|
+
);
|
|
3043
|
+
}
|
|
3044
|
+
async apiKeyPermissions() {
|
|
3045
|
+
return ApiKeyPermissionsSchema.parse(
|
|
3046
|
+
await this.http.get("/sapi/v1/account/apiRestrictions", void 0, "signed")
|
|
3047
|
+
);
|
|
3048
|
+
}
|
|
3049
|
+
async assetDetail(asset) {
|
|
3050
|
+
const params = asset ? { asset } : void 0;
|
|
3051
|
+
return AssetDetailSchema.parse(await this.http.get("/sapi/v1/asset/assetDetail", params, "signed"));
|
|
3052
|
+
}
|
|
3053
|
+
async dustLog(options) {
|
|
3054
|
+
return DustLogResponseSchema.parse(
|
|
3055
|
+
await this.http.get("/sapi/v1/asset/dribblet", options, "signed")
|
|
3056
|
+
);
|
|
3057
|
+
}
|
|
3058
|
+
async convertDustToBnb(assets, accountType) {
|
|
3059
|
+
return DustConversionResultSchema.parse(
|
|
3060
|
+
await this.http.post("/sapi/v1/asset/dust", { asset: assets, accountType }, "signed")
|
|
3061
|
+
);
|
|
3062
|
+
}
|
|
3063
|
+
async tradeFee(symbol3) {
|
|
3064
|
+
const params = symbol3 ? { symbol: symbol3 } : void 0;
|
|
3065
|
+
return TradeFeeResponseSchema.parse(await this.http.get("/sapi/v1/asset/tradeFee", params, "signed"));
|
|
3066
|
+
}
|
|
3067
|
+
};
|
|
3068
|
+
|
|
3069
|
+
// src/types/subaccount.types.ts
|
|
3070
|
+
import { z as z10 } from "zod";
|
|
3071
|
+
var SubAccountEntrySchema = z10.object({
|
|
3072
|
+
email: z10.string(),
|
|
3073
|
+
isFreeze: z10.boolean(),
|
|
3074
|
+
createTime: z10.number(),
|
|
3075
|
+
isManagedSubAccount: z10.boolean().optional(),
|
|
3076
|
+
isAssetManagementSubAccount: z10.boolean().optional(),
|
|
3077
|
+
type: z10.string().optional()
|
|
3078
|
+
}).loose();
|
|
3079
|
+
var SubAccountListResponseSchema = z10.object({
|
|
3080
|
+
subAccounts: z10.array(SubAccountEntrySchema)
|
|
3081
|
+
});
|
|
3082
|
+
var SubAccountStatusSchema = z10.object({
|
|
3083
|
+
email: z10.string(),
|
|
3084
|
+
isSubUserEnabled: z10.boolean(),
|
|
3085
|
+
isUserActive: z10.boolean(),
|
|
3086
|
+
insertTime: z10.number(),
|
|
3087
|
+
isMarginEnabled: z10.boolean(),
|
|
3088
|
+
isFutureEnabled: z10.boolean(),
|
|
3089
|
+
mobile: z10.number().optional()
|
|
3090
|
+
}).loose();
|
|
3091
|
+
var SubAccountStatusResponseSchema = z10.array(SubAccountStatusSchema);
|
|
3092
|
+
var SubAccountSpotAssetSchema = z10.object({
|
|
3093
|
+
asset: z10.string(),
|
|
3094
|
+
free: z10.string().transform(Number),
|
|
3095
|
+
locked: z10.string().transform(Number)
|
|
3096
|
+
});
|
|
3097
|
+
var SubAccountSpotAssetsResponseSchema = z10.object({
|
|
3098
|
+
balances: z10.array(SubAccountSpotAssetSchema)
|
|
3099
|
+
});
|
|
3100
|
+
var SubAccountSpotSummaryEntrySchema = z10.object({
|
|
3101
|
+
email: z10.string(),
|
|
3102
|
+
totalAsset: z10.string().transform(Number)
|
|
3103
|
+
}).loose();
|
|
3104
|
+
var SubAccountSpotSummarySchema = z10.object({
|
|
3105
|
+
totalCount: z10.number(),
|
|
3106
|
+
masterAccountTotalAsset: z10.string().transform(Number),
|
|
3107
|
+
spotSubUserAssetBtcVoList: z10.array(SubAccountSpotSummaryEntrySchema)
|
|
3108
|
+
});
|
|
3109
|
+
var SubAccountFuturesSummarySchema = z10.object({
|
|
3110
|
+
totalCount: z10.number().optional(),
|
|
3111
|
+
totalMarginBalanceOfBTC: z10.string().transform(Number).optional(),
|
|
3112
|
+
totalUnrealizedProfitOfBTC: z10.string().transform(Number).optional(),
|
|
3113
|
+
totalWalletBalanceOfBTC: z10.string().transform(Number).optional(),
|
|
3114
|
+
subAccountList: z10.array(z10.record(z10.string(), z10.unknown())).optional()
|
|
3115
|
+
}).loose();
|
|
3116
|
+
var SubAccountMarginAccountSchema = z10.object({
|
|
3117
|
+
email: z10.string(),
|
|
3118
|
+
marginLevel: z10.string().transform(Number),
|
|
3119
|
+
totalAssetOfBtc: z10.string().transform(Number),
|
|
3120
|
+
totalLiabilityOfBtc: z10.string().transform(Number),
|
|
3121
|
+
totalNetAssetOfBtc: z10.string().transform(Number),
|
|
3122
|
+
marginTradeCoeffVo: z10.record(z10.string(), z10.unknown()).optional(),
|
|
3123
|
+
marginUserAssetVoList: z10.array(z10.record(z10.string(), z10.unknown())).optional()
|
|
3124
|
+
}).loose();
|
|
3125
|
+
var SubAccountUniversalTransferParamsSchema = z10.object({
|
|
3126
|
+
fromEmail: z10.string().optional(),
|
|
3127
|
+
toEmail: z10.string().optional(),
|
|
3128
|
+
fromAccountType: z10.enum(["SPOT", "USDT_FUTURE", "COIN_FUTURE", "MARGIN", "ISOLATED_MARGIN"]),
|
|
3129
|
+
toAccountType: z10.enum(["SPOT", "USDT_FUTURE", "COIN_FUTURE", "MARGIN", "ISOLATED_MARGIN"]),
|
|
3130
|
+
symbol: z10.string().optional(),
|
|
3131
|
+
asset: z10.string(),
|
|
3132
|
+
amount: z10.union([z10.string(), z10.number()]),
|
|
3133
|
+
clientTranId: z10.string().optional()
|
|
3134
|
+
});
|
|
3135
|
+
var SubAccountUniversalTransferResultSchema = z10.object({
|
|
3136
|
+
tranId: z10.number(),
|
|
3137
|
+
clientTranId: z10.string().optional()
|
|
3138
|
+
});
|
|
3139
|
+
var SubAccountUniversalTransferEntrySchema = z10.object({
|
|
3140
|
+
tranId: z10.number(),
|
|
3141
|
+
fromEmail: z10.string(),
|
|
3142
|
+
toEmail: z10.string(),
|
|
3143
|
+
asset: z10.string(),
|
|
3144
|
+
amount: z10.string().transform(Number),
|
|
3145
|
+
fromAccountType: z10.string(),
|
|
3146
|
+
toAccountType: z10.string(),
|
|
3147
|
+
status: z10.string(),
|
|
3148
|
+
createTimeStamp: z10.number(),
|
|
3149
|
+
clientTranId: z10.string().optional()
|
|
3150
|
+
}).loose();
|
|
3151
|
+
var SubAccountUniversalTransferHistoryResponseSchema = z10.object({
|
|
3152
|
+
result: z10.array(SubAccountUniversalTransferEntrySchema),
|
|
3153
|
+
totalCount: z10.number()
|
|
3154
|
+
});
|
|
3155
|
+
var VirtualSubAccountResultSchema = z10.object({ email: z10.string() });
|
|
3156
|
+
var SubAccountDepositAddressSchema = z10.object({
|
|
3157
|
+
address: z10.string(),
|
|
3158
|
+
coin: z10.string(),
|
|
3159
|
+
tag: z10.string(),
|
|
3160
|
+
url: z10.string().optional()
|
|
3161
|
+
});
|
|
3162
|
+
var SubAccountDepositHistoryEntrySchema = z10.object({
|
|
3163
|
+
id: z10.string(),
|
|
3164
|
+
amount: z10.string().transform(Number),
|
|
3165
|
+
coin: z10.string(),
|
|
3166
|
+
network: z10.string(),
|
|
3167
|
+
status: z10.number(),
|
|
3168
|
+
address: z10.string(),
|
|
3169
|
+
txId: z10.string(),
|
|
3170
|
+
insertTime: z10.number(),
|
|
3171
|
+
transferType: z10.number()
|
|
3172
|
+
}).loose();
|
|
3173
|
+
var SubAccountDepositHistoryResponseSchema = z10.array(SubAccountDepositHistoryEntrySchema);
|
|
3174
|
+
var SubAccountEnableResultSchema = z10.object({
|
|
3175
|
+
email: z10.string(),
|
|
3176
|
+
isFuturesEnabled: z10.boolean().optional(),
|
|
3177
|
+
isMarginEnabled: z10.boolean().optional()
|
|
3178
|
+
}).loose();
|
|
3179
|
+
|
|
3180
|
+
// src/resources/SubAccount.ts
|
|
3181
|
+
var SubAccount = class {
|
|
3182
|
+
constructor(http2) {
|
|
3183
|
+
this.http = http2;
|
|
3184
|
+
}
|
|
3185
|
+
async list(options) {
|
|
3186
|
+
const res = await this.http.get("/sapi/v1/sub-account/list", options, "signed");
|
|
3187
|
+
return SubAccountListResponseSchema.parse(res).subAccounts;
|
|
3188
|
+
}
|
|
3189
|
+
async status(email) {
|
|
3190
|
+
const params = email ? { email } : void 0;
|
|
3191
|
+
return SubAccountStatusResponseSchema.parse(
|
|
3192
|
+
await this.http.get("/sapi/v1/sub-account/status", params, "signed")
|
|
3193
|
+
);
|
|
3194
|
+
}
|
|
3195
|
+
async spotAssets(email) {
|
|
3196
|
+
return SubAccountSpotAssetsResponseSchema.parse(
|
|
3197
|
+
await this.http.get("/sapi/v3/sub-account/assets", { email }, "signed")
|
|
3198
|
+
);
|
|
3199
|
+
}
|
|
3200
|
+
async spotSummary(options) {
|
|
3201
|
+
return SubAccountSpotSummarySchema.parse(
|
|
3202
|
+
await this.http.get("/sapi/v1/sub-account/spotSummary", options, "signed")
|
|
3203
|
+
);
|
|
3204
|
+
}
|
|
3205
|
+
async futuresAccountSummary(futuresType) {
|
|
3206
|
+
return SubAccountFuturesSummarySchema.parse(
|
|
3207
|
+
await this.http.get("/sapi/v2/sub-account/futures/accountSummary", { futuresType }, "signed")
|
|
3208
|
+
);
|
|
3209
|
+
}
|
|
3210
|
+
async marginAccount(email) {
|
|
3211
|
+
return SubAccountMarginAccountSchema.parse(
|
|
3212
|
+
await this.http.get("/sapi/v1/sub-account/margin/account", { email }, "signed")
|
|
3213
|
+
);
|
|
3214
|
+
}
|
|
3215
|
+
async universalTransfer(params) {
|
|
3216
|
+
return SubAccountUniversalTransferResultSchema.parse(
|
|
3217
|
+
await this.http.post("/sapi/v1/sub-account/universalTransfer", params, "signed")
|
|
3218
|
+
);
|
|
3219
|
+
}
|
|
3220
|
+
async universalTransferHistory(options) {
|
|
3221
|
+
return SubAccountUniversalTransferHistoryResponseSchema.parse(
|
|
3222
|
+
await this.http.get("/sapi/v1/sub-account/universalTransfer", options, "signed")
|
|
3223
|
+
);
|
|
3224
|
+
}
|
|
3225
|
+
async createVirtualSubAccount(subAccountString) {
|
|
3226
|
+
return VirtualSubAccountResultSchema.parse(
|
|
3227
|
+
await this.http.post("/sapi/v1/sub-account/virtualSubAccount", { subAccountString }, "signed")
|
|
3228
|
+
);
|
|
3229
|
+
}
|
|
3230
|
+
async enableFutures(email) {
|
|
3231
|
+
return SubAccountEnableResultSchema.parse(
|
|
3232
|
+
await this.http.post("/sapi/v1/sub-account/futures/enable", { email }, "signed")
|
|
3233
|
+
);
|
|
3234
|
+
}
|
|
3235
|
+
async enableMargin(email) {
|
|
3236
|
+
return SubAccountEnableResultSchema.parse(
|
|
3237
|
+
await this.http.post("/sapi/v1/sub-account/margin/enable", { email }, "signed")
|
|
3238
|
+
);
|
|
3239
|
+
}
|
|
3240
|
+
async depositAddress(email, coin, network) {
|
|
3241
|
+
return SubAccountDepositAddressSchema.parse(
|
|
3242
|
+
await this.http.get("/sapi/v1/capital/deposit/subAddress", { email, coin, network }, "signed")
|
|
3243
|
+
);
|
|
3244
|
+
}
|
|
3245
|
+
async depositHistory(options) {
|
|
3246
|
+
return SubAccountDepositHistoryResponseSchema.parse(
|
|
3247
|
+
await this.http.get("/sapi/v1/capital/deposit/subHisrec", options, "signed")
|
|
3248
|
+
);
|
|
3249
|
+
}
|
|
3250
|
+
};
|
|
3251
|
+
|
|
3252
|
+
// src/ws/BaseWS.ts
|
|
3253
|
+
import { EventEmitter } from "events";
|
|
3254
|
+
import WebSocket from "ws";
|
|
3255
|
+
|
|
3256
|
+
// src/types/ws.types.ts
|
|
3257
|
+
import { z as z11 } from "zod";
|
|
3258
|
+
var WsKlinePayloadSchema = z11.object({
|
|
3259
|
+
e: z11.literal("kline"),
|
|
3260
|
+
E: z11.number(),
|
|
3261
|
+
s: z11.string(),
|
|
3262
|
+
k: z11.object({
|
|
3263
|
+
t: z11.number(),
|
|
3264
|
+
T: z11.number(),
|
|
3265
|
+
s: z11.string(),
|
|
3266
|
+
i: z11.string(),
|
|
3267
|
+
o: z11.string().transform(Number),
|
|
3268
|
+
c: z11.string().transform(Number),
|
|
3269
|
+
h: z11.string().transform(Number),
|
|
3270
|
+
l: z11.string().transform(Number),
|
|
3271
|
+
v: z11.string().transform(Number),
|
|
3272
|
+
n: z11.number(),
|
|
3273
|
+
x: z11.boolean(),
|
|
3274
|
+
q: z11.string().transform(Number),
|
|
3275
|
+
V: z11.string().transform(Number),
|
|
3276
|
+
Q: z11.string().transform(Number)
|
|
3277
|
+
})
|
|
3278
|
+
});
|
|
3279
|
+
var WsAggTradePayloadSchema = z11.object({
|
|
3280
|
+
e: z11.literal("aggTrade"),
|
|
3281
|
+
E: z11.number(),
|
|
3282
|
+
s: z11.string(),
|
|
3283
|
+
a: z11.number(),
|
|
3284
|
+
p: z11.string().transform(Number),
|
|
3285
|
+
q: z11.string().transform(Number),
|
|
3286
|
+
f: z11.number(),
|
|
3287
|
+
l: z11.number(),
|
|
3288
|
+
T: z11.number(),
|
|
3289
|
+
m: z11.boolean()
|
|
3290
|
+
});
|
|
3291
|
+
var WsTradePayloadSchema = z11.object({
|
|
3292
|
+
e: z11.literal("trade"),
|
|
3293
|
+
E: z11.number(),
|
|
3294
|
+
s: z11.string(),
|
|
3295
|
+
t: z11.number(),
|
|
3296
|
+
p: z11.string().transform(Number),
|
|
3297
|
+
q: z11.string().transform(Number),
|
|
3298
|
+
T: z11.number(),
|
|
3299
|
+
m: z11.boolean()
|
|
3300
|
+
});
|
|
3301
|
+
var WsDepthUpdatePayloadSchema = z11.object({
|
|
3302
|
+
e: z11.literal("depthUpdate"),
|
|
3303
|
+
E: z11.number(),
|
|
3304
|
+
s: z11.string(),
|
|
3305
|
+
U: z11.number(),
|
|
3306
|
+
u: z11.number(),
|
|
3307
|
+
T: z11.number().optional(),
|
|
3308
|
+
pu: z11.number().optional(),
|
|
3309
|
+
b: z11.array(z11.tuple([z11.string(), z11.string()])),
|
|
3310
|
+
a: z11.array(z11.tuple([z11.string(), z11.string()]))
|
|
3311
|
+
});
|
|
3312
|
+
var WsTicker24hrPayloadSchema = z11.object({
|
|
3313
|
+
e: z11.literal("24hrTicker"),
|
|
3314
|
+
E: z11.number(),
|
|
3315
|
+
s: z11.string(),
|
|
3316
|
+
p: z11.string().transform(Number),
|
|
3317
|
+
P: z11.string().transform(Number),
|
|
3318
|
+
c: z11.string().transform(Number),
|
|
3319
|
+
o: z11.string().transform(Number),
|
|
3320
|
+
h: z11.string().transform(Number),
|
|
3321
|
+
l: z11.string().transform(Number),
|
|
3322
|
+
v: z11.string().transform(Number),
|
|
3323
|
+
q: z11.string().transform(Number)
|
|
3324
|
+
});
|
|
3325
|
+
var WsBookTickerPayloadSchema = z11.object({
|
|
3326
|
+
u: z11.number(),
|
|
3327
|
+
s: z11.string(),
|
|
3328
|
+
b: z11.string().transform(Number),
|
|
3329
|
+
B: z11.string().transform(Number),
|
|
3330
|
+
a: z11.string().transform(Number),
|
|
3331
|
+
A: z11.string().transform(Number)
|
|
3332
|
+
});
|
|
3333
|
+
var WsMarkPricePayloadSchema = z11.object({
|
|
3334
|
+
e: z11.literal("markPriceUpdate"),
|
|
3335
|
+
E: z11.number(),
|
|
3336
|
+
s: z11.string(),
|
|
3337
|
+
p: z11.string().transform(Number),
|
|
3338
|
+
i: z11.string().transform(Number),
|
|
3339
|
+
P: z11.string().transform(Number),
|
|
3340
|
+
r: z11.string().transform(Number),
|
|
3341
|
+
T: z11.number()
|
|
3342
|
+
});
|
|
3343
|
+
var WsMiniTickerPayloadSchema = z11.object({
|
|
3344
|
+
e: z11.literal("24hrMiniTicker"),
|
|
3345
|
+
E: z11.number(),
|
|
3346
|
+
s: z11.string(),
|
|
3347
|
+
c: z11.string().transform(Number),
|
|
3348
|
+
o: z11.string().transform(Number),
|
|
3349
|
+
h: z11.string().transform(Number),
|
|
3350
|
+
l: z11.string().transform(Number),
|
|
3351
|
+
v: z11.string().transform(Number),
|
|
3352
|
+
q: z11.string().transform(Number)
|
|
3353
|
+
});
|
|
3354
|
+
var WsForceOrderPayloadSchema = z11.object({
|
|
3355
|
+
e: z11.literal("forceOrder"),
|
|
3356
|
+
E: z11.number(),
|
|
3357
|
+
o: z11.object({
|
|
3358
|
+
s: z11.string(),
|
|
3359
|
+
S: z11.string(),
|
|
3360
|
+
o: z11.string(),
|
|
3361
|
+
f: z11.string(),
|
|
3362
|
+
q: z11.string().transform(Number),
|
|
3363
|
+
p: z11.string().transform(Number),
|
|
3364
|
+
ap: z11.string().transform(Number),
|
|
3365
|
+
X: z11.string(),
|
|
3366
|
+
l: z11.string().transform(Number),
|
|
3367
|
+
z: z11.string().transform(Number),
|
|
3368
|
+
T: z11.number()
|
|
3369
|
+
})
|
|
3370
|
+
});
|
|
3371
|
+
var WsCompositeIndexPayloadSchema = z11.object({
|
|
3372
|
+
e: z11.literal("compositeIndex"),
|
|
3373
|
+
E: z11.number(),
|
|
3374
|
+
s: z11.string(),
|
|
3375
|
+
p: z11.string().transform(Number),
|
|
3376
|
+
c: z11.array(
|
|
3377
|
+
z11.object({
|
|
3378
|
+
b: z11.string(),
|
|
3379
|
+
q: z11.string(),
|
|
3380
|
+
w: z11.string().transform(Number),
|
|
3381
|
+
p: z11.string().transform(Number)
|
|
3382
|
+
})
|
|
3383
|
+
)
|
|
3384
|
+
});
|
|
3385
|
+
var WsAssetIndexPayloadSchema = z11.object({
|
|
3386
|
+
e: z11.literal("assetIndex"),
|
|
3387
|
+
E: z11.number(),
|
|
3388
|
+
s: z11.string(),
|
|
3389
|
+
i: z11.string().transform(Number),
|
|
3390
|
+
b: z11.string().transform(Number),
|
|
3391
|
+
a: z11.string().transform(Number)
|
|
3392
|
+
});
|
|
3393
|
+
var WsRollingWindowTickerPayloadSchema = z11.object({
|
|
3394
|
+
e: z11.enum(["1hTicker", "4hTicker", "1dTicker", "7dTicker", "30dTicker"]),
|
|
3395
|
+
E: z11.number(),
|
|
3396
|
+
s: z11.string(),
|
|
3397
|
+
p: z11.string().transform(Number),
|
|
3398
|
+
P: z11.string().transform(Number),
|
|
3399
|
+
o: z11.string().transform(Number),
|
|
3400
|
+
h: z11.string().transform(Number),
|
|
3401
|
+
l: z11.string().transform(Number),
|
|
3402
|
+
c: z11.string().transform(Number),
|
|
3403
|
+
v: z11.string().transform(Number),
|
|
3404
|
+
q: z11.string().transform(Number),
|
|
3405
|
+
O: z11.number(),
|
|
3406
|
+
C: z11.number()
|
|
3407
|
+
});
|
|
3408
|
+
var WsSpotAvgPricePayloadSchema = z11.object({
|
|
3409
|
+
e: z11.literal("avgPrice"),
|
|
3410
|
+
E: z11.number(),
|
|
3411
|
+
s: z11.string(),
|
|
3412
|
+
i: z11.string(),
|
|
3413
|
+
w: z11.string().transform(Number),
|
|
3414
|
+
T: z11.number()
|
|
3415
|
+
});
|
|
3416
|
+
function parseWsPayload(streamName, raw) {
|
|
3417
|
+
if (streamName.includes("@kline_")) return WsKlinePayloadSchema.parse(raw);
|
|
3418
|
+
if (streamName.includes("@continuousKline_") || streamName.includes("@indexPriceKline_") || streamName.includes("@markPriceKline_")) {
|
|
3419
|
+
return WsKlinePayloadSchema.parse(raw);
|
|
3420
|
+
}
|
|
3421
|
+
if (streamName.includes("@aggTrade")) return WsAggTradePayloadSchema.parse(raw);
|
|
3422
|
+
if (streamName.includes("@trade")) return WsTradePayloadSchema.parse(raw);
|
|
3423
|
+
if (streamName.includes("@depth")) return WsDepthUpdatePayloadSchema.parse(raw);
|
|
3424
|
+
if (streamName.includes("@bookTicker")) return WsBookTickerPayloadSchema.parse(raw);
|
|
3425
|
+
if (streamName.includes("@markPrice")) return WsMarkPricePayloadSchema.parse(raw);
|
|
3426
|
+
if (streamName.includes("@miniTicker")) return WsMiniTickerPayloadSchema.parse(raw);
|
|
3427
|
+
if (streamName.includes("@forceOrder")) return WsForceOrderPayloadSchema.parse(raw);
|
|
3428
|
+
if (streamName.includes("@compositeIndex")) return WsCompositeIndexPayloadSchema.parse(raw);
|
|
3429
|
+
if (streamName.includes("@assetIndex")) return WsAssetIndexPayloadSchema.parse(raw);
|
|
3430
|
+
if (streamName.includes("@avgPrice")) return WsSpotAvgPricePayloadSchema.parse(raw);
|
|
3431
|
+
if (streamName.includes("@ticker_")) return WsRollingWindowTickerPayloadSchema.parse(raw);
|
|
3432
|
+
if (streamName.includes("@ticker")) return WsTicker24hrPayloadSchema.parse(raw);
|
|
3433
|
+
throw new Error(`Unknown WS stream type: ${streamName}`);
|
|
3434
|
+
}
|
|
3435
|
+
|
|
3436
|
+
// src/ws/BaseWS.ts
|
|
3437
|
+
var BaseWS = class extends EventEmitter {
|
|
3438
|
+
constructor(options) {
|
|
3439
|
+
super();
|
|
3440
|
+
this.options = options;
|
|
3441
|
+
this.ws = null;
|
|
3442
|
+
this.streams = /* @__PURE__ */ new Set();
|
|
3443
|
+
this.reconnectAttempt = 0;
|
|
3444
|
+
this.closedByUser = false;
|
|
3445
|
+
}
|
|
3446
|
+
subscribe(streams) {
|
|
3447
|
+
streams.forEach((s) => this.streams.add(s));
|
|
3448
|
+
if (this.isOpen()) {
|
|
3449
|
+
this.send({ method: "SUBSCRIBE", params: streams, id: Date.now() });
|
|
3450
|
+
} else {
|
|
3451
|
+
this.connect();
|
|
3452
|
+
}
|
|
3453
|
+
}
|
|
3454
|
+
unsubscribe(streams) {
|
|
3455
|
+
streams.forEach((s) => this.streams.delete(s));
|
|
3456
|
+
if (this.isOpen()) {
|
|
3457
|
+
this.send({ method: "UNSUBSCRIBE", params: streams, id: Date.now() });
|
|
3458
|
+
}
|
|
3459
|
+
}
|
|
3460
|
+
close() {
|
|
3461
|
+
this.closedByUser = true;
|
|
3462
|
+
this.ws?.close();
|
|
3463
|
+
}
|
|
3464
|
+
reconnect() {
|
|
3465
|
+
if (this.ws?.readyState === WebSocket.OPEN) this.ws.close();
|
|
3466
|
+
this.reconnectAttempt = 0;
|
|
3467
|
+
if (!this.closedByUser) this.connect();
|
|
3468
|
+
}
|
|
3469
|
+
resetReconnectAttempts() {
|
|
3470
|
+
this.reconnectAttempt = 0;
|
|
3471
|
+
}
|
|
3472
|
+
isOpen() {
|
|
3473
|
+
return this.ws?.readyState === WebSocket.OPEN;
|
|
3474
|
+
}
|
|
3475
|
+
send(payload) {
|
|
3476
|
+
this.ws?.send(JSON.stringify(payload));
|
|
3477
|
+
}
|
|
3478
|
+
connect() {
|
|
3479
|
+
this.closedByUser = false;
|
|
3480
|
+
const url = `${this.options.baseStreamUrl}?streams=${[...this.streams].join("/")}`;
|
|
3481
|
+
this.ws = new WebSocket(url);
|
|
3482
|
+
this.ws.on("open", () => {
|
|
3483
|
+
this.reconnectAttempt = 0;
|
|
3484
|
+
this.emit("open");
|
|
3485
|
+
});
|
|
3486
|
+
this.ws.on("message", (raw) => {
|
|
3487
|
+
this.handleMessage(raw.toString());
|
|
3488
|
+
});
|
|
3489
|
+
this.ws.on("close", () => {
|
|
3490
|
+
this.emit("close");
|
|
3491
|
+
if (!this.closedByUser) this.scheduleReconnect();
|
|
3492
|
+
});
|
|
3493
|
+
this.ws.on("error", (err) => {
|
|
3494
|
+
if (this.closedByUser) return;
|
|
3495
|
+
this.emit("error", err);
|
|
3496
|
+
});
|
|
3497
|
+
}
|
|
3498
|
+
handleMessage(raw) {
|
|
3499
|
+
let parsed;
|
|
3500
|
+
try {
|
|
3501
|
+
parsed = JSON.parse(raw);
|
|
3502
|
+
} catch {
|
|
3503
|
+
return;
|
|
3504
|
+
}
|
|
3505
|
+
if (!parsed.stream || parsed.data === void 0) return;
|
|
3506
|
+
try {
|
|
3507
|
+
const payload = parseWsPayload(parsed.stream, parsed.data);
|
|
3508
|
+
this.emit("message", parsed.stream, payload);
|
|
3509
|
+
this.emit(parsed.stream, payload);
|
|
3510
|
+
} catch (err) {
|
|
3511
|
+
this.emit("error", err);
|
|
3512
|
+
}
|
|
3513
|
+
}
|
|
3514
|
+
scheduleReconnect() {
|
|
3515
|
+
const base = this.options.reconnectDelayMs ?? 1e3;
|
|
3516
|
+
const max = this.options.maxReconnectDelayMs ?? 3e4;
|
|
3517
|
+
const delay = Math.min(base * 2 ** this.reconnectAttempt, max);
|
|
3518
|
+
this.reconnectAttempt += 1;
|
|
3519
|
+
setTimeout(() => {
|
|
3520
|
+
if (!this.closedByUser) this.connect();
|
|
3521
|
+
}, delay);
|
|
3522
|
+
}
|
|
3523
|
+
};
|
|
3524
|
+
|
|
3525
|
+
// src/ws/FuturesMarketWS.ts
|
|
3526
|
+
var FuturesMarketWS = class extends BaseWS {
|
|
3527
|
+
constructor(baseStreamUrl = "wss://fstream.binance.com/stream") {
|
|
3528
|
+
super({ baseStreamUrl });
|
|
3529
|
+
}
|
|
3530
|
+
kline(symbol3, interval) {
|
|
3531
|
+
return `${symbol3.toLowerCase()}@kline_${interval}`;
|
|
3532
|
+
}
|
|
3533
|
+
continuousKline(symbol3, contractType2, interval) {
|
|
3534
|
+
return `${symbol3.toLowerCase()}@continuousKline_${contractType2}_${interval}`;
|
|
3535
|
+
}
|
|
3536
|
+
indexPriceKline(symbol3, interval) {
|
|
3537
|
+
return `${symbol3.toLowerCase()}@indexPriceKline_${interval}`;
|
|
3538
|
+
}
|
|
3539
|
+
markPriceKline(symbol3, interval) {
|
|
3540
|
+
return `${symbol3.toLowerCase()}@markPriceKline_${interval}`;
|
|
3541
|
+
}
|
|
3542
|
+
aggTrade(symbol3) {
|
|
3543
|
+
return `${symbol3.toLowerCase()}@aggTrade`;
|
|
3544
|
+
}
|
|
3545
|
+
trade(symbol3) {
|
|
3546
|
+
return `${symbol3.toLowerCase()}@trade`;
|
|
2150
3547
|
}
|
|
2151
3548
|
depth(symbol3, level = 20) {
|
|
2152
3549
|
return `${symbol3.toLowerCase()}@depth${level}`;
|
|
@@ -2291,48 +3688,185 @@ var SpotUserWS = class extends EventEmitter2 {
|
|
|
2291
3688
|
this.emit("error", err);
|
|
2292
3689
|
});
|
|
2293
3690
|
}
|
|
2294
|
-
close() {
|
|
2295
|
-
this.closedByUser = true;
|
|
2296
|
-
this.ws?.close();
|
|
3691
|
+
close() {
|
|
3692
|
+
this.closedByUser = true;
|
|
3693
|
+
this.ws?.close();
|
|
3694
|
+
}
|
|
3695
|
+
reconnect() {
|
|
3696
|
+
if (this.ws?.readyState === WebSocket2.OPEN) this.ws.close();
|
|
3697
|
+
this.reconnectAttempt = 0;
|
|
3698
|
+
if (!this.closedByUser) this.connect();
|
|
3699
|
+
}
|
|
3700
|
+
resetReconnectAttempts() {
|
|
3701
|
+
this.reconnectAttempt = 0;
|
|
3702
|
+
}
|
|
3703
|
+
handleMessage(raw) {
|
|
3704
|
+
let parsed;
|
|
3705
|
+
try {
|
|
3706
|
+
parsed = JSON.parse(raw);
|
|
3707
|
+
} catch {
|
|
3708
|
+
return;
|
|
3709
|
+
}
|
|
3710
|
+
try {
|
|
3711
|
+
const event = parseSpotUserDataEvent(parsed);
|
|
3712
|
+
this.emit(event.e, event);
|
|
3713
|
+
this.emit("userData", event);
|
|
3714
|
+
} catch (err) {
|
|
3715
|
+
this.emit("error", err);
|
|
3716
|
+
}
|
|
3717
|
+
}
|
|
3718
|
+
scheduleReconnect() {
|
|
3719
|
+
const base = this.options.reconnectDelayMs ?? 1e3;
|
|
3720
|
+
const max = this.options.maxReconnectDelayMs ?? 3e4;
|
|
3721
|
+
const delay = Math.min(base * 2 ** this.reconnectAttempt, max);
|
|
3722
|
+
this.reconnectAttempt += 1;
|
|
3723
|
+
setTimeout(() => {
|
|
3724
|
+
if (!this.closedByUser) this.connect();
|
|
3725
|
+
}, delay);
|
|
3726
|
+
}
|
|
3727
|
+
};
|
|
3728
|
+
|
|
3729
|
+
// src/ws/FuturesUserWS.ts
|
|
3730
|
+
import { EventEmitter as EventEmitter3 } from "events";
|
|
3731
|
+
import WebSocket3 from "ws";
|
|
3732
|
+
var FuturesUserWS = class extends EventEmitter3 {
|
|
3733
|
+
constructor(options) {
|
|
3734
|
+
super();
|
|
3735
|
+
this.options = options;
|
|
3736
|
+
this.ws = null;
|
|
3737
|
+
this.reconnectAttempt = 0;
|
|
3738
|
+
this.closedByUser = false;
|
|
3739
|
+
}
|
|
3740
|
+
connect() {
|
|
3741
|
+
const listenKey = this.options.getListenKey();
|
|
3742
|
+
if (!listenKey) {
|
|
3743
|
+
this.emit("error", new Error("No listenKey available for user data stream"));
|
|
3744
|
+
return;
|
|
3745
|
+
}
|
|
3746
|
+
this.closedByUser = false;
|
|
3747
|
+
const url = `${this.options.baseUserUrl}/${listenKey}`;
|
|
3748
|
+
this.ws = new WebSocket3(url);
|
|
3749
|
+
this.ws.on("open", () => {
|
|
3750
|
+
this.reconnectAttempt = 0;
|
|
3751
|
+
this.emit("open");
|
|
3752
|
+
});
|
|
3753
|
+
this.ws.on("message", (raw) => {
|
|
3754
|
+
this.handleMessage(raw.toString());
|
|
3755
|
+
});
|
|
3756
|
+
this.ws.on("close", () => {
|
|
3757
|
+
this.emit("close");
|
|
3758
|
+
if (!this.closedByUser) this.scheduleReconnect();
|
|
3759
|
+
});
|
|
3760
|
+
this.ws.on("error", (err) => {
|
|
3761
|
+
this.emit("error", err);
|
|
3762
|
+
});
|
|
3763
|
+
}
|
|
3764
|
+
close() {
|
|
3765
|
+
this.closedByUser = true;
|
|
3766
|
+
this.ws?.close();
|
|
3767
|
+
}
|
|
3768
|
+
reconnect() {
|
|
3769
|
+
if (this.ws?.readyState === WebSocket3.OPEN) this.ws.close();
|
|
3770
|
+
this.reconnectAttempt = 0;
|
|
3771
|
+
if (!this.closedByUser) this.connect();
|
|
3772
|
+
}
|
|
3773
|
+
resetReconnectAttempts() {
|
|
3774
|
+
this.reconnectAttempt = 0;
|
|
3775
|
+
}
|
|
3776
|
+
handleMessage(raw) {
|
|
3777
|
+
let parsed;
|
|
3778
|
+
try {
|
|
3779
|
+
parsed = JSON.parse(raw);
|
|
3780
|
+
} catch {
|
|
3781
|
+
return;
|
|
3782
|
+
}
|
|
3783
|
+
try {
|
|
3784
|
+
const event = parseUserDataEvent(parsed);
|
|
3785
|
+
this.emit(event.e, event);
|
|
3786
|
+
this.emit("userData", event);
|
|
3787
|
+
} catch (err) {
|
|
3788
|
+
this.emit("error", err);
|
|
3789
|
+
}
|
|
3790
|
+
}
|
|
3791
|
+
scheduleReconnect() {
|
|
3792
|
+
const base = this.options.reconnectDelayMs ?? 1e3;
|
|
3793
|
+
const max = this.options.maxReconnectDelayMs ?? 3e4;
|
|
3794
|
+
const delay = Math.min(base * 2 ** this.reconnectAttempt, max);
|
|
3795
|
+
this.reconnectAttempt += 1;
|
|
3796
|
+
setTimeout(() => {
|
|
3797
|
+
if (!this.closedByUser) this.connect();
|
|
3798
|
+
}, delay);
|
|
3799
|
+
}
|
|
3800
|
+
};
|
|
3801
|
+
|
|
3802
|
+
// src/ws/CoinMMarketWS.ts
|
|
3803
|
+
var CoinMMarketWS = class extends BaseWS {
|
|
3804
|
+
constructor(baseStreamUrl = "wss://dstream.binance.com/stream") {
|
|
3805
|
+
super({ baseStreamUrl });
|
|
3806
|
+
}
|
|
3807
|
+
kline(symbol3, interval) {
|
|
3808
|
+
return `${symbol3.toLowerCase()}@kline_${interval}`;
|
|
3809
|
+
}
|
|
3810
|
+
continuousKline(pair, contractType2, interval) {
|
|
3811
|
+
return `${pair.toLowerCase()}_${contractType2}@continuousKline_${interval}`;
|
|
3812
|
+
}
|
|
3813
|
+
indexPriceKline(pair, interval) {
|
|
3814
|
+
return `${pair.toLowerCase()}@indexPriceKline_${interval}`;
|
|
3815
|
+
}
|
|
3816
|
+
markPriceKline(symbol3, interval) {
|
|
3817
|
+
return `${symbol3.toLowerCase()}@markPriceKline_${interval}`;
|
|
3818
|
+
}
|
|
3819
|
+
aggTrade(symbol3) {
|
|
3820
|
+
return `${symbol3.toLowerCase()}@aggTrade`;
|
|
3821
|
+
}
|
|
3822
|
+
trade(symbol3) {
|
|
3823
|
+
return `${symbol3.toLowerCase()}@trade`;
|
|
3824
|
+
}
|
|
3825
|
+
depth(symbol3, level = 20) {
|
|
3826
|
+
return `${symbol3.toLowerCase()}@depth${level}`;
|
|
3827
|
+
}
|
|
3828
|
+
depthDiff(symbol3) {
|
|
3829
|
+
return `${symbol3.toLowerCase()}@depth`;
|
|
3830
|
+
}
|
|
3831
|
+
depthDiffSpeed(symbol3, updateSpeed) {
|
|
3832
|
+
return `${symbol3.toLowerCase()}@depth@${updateSpeed}`;
|
|
3833
|
+
}
|
|
3834
|
+
ticker(symbol3) {
|
|
3835
|
+
return `${symbol3.toLowerCase()}@ticker`;
|
|
3836
|
+
}
|
|
3837
|
+
allMarketTickers() {
|
|
3838
|
+
return "!ticker@arr";
|
|
3839
|
+
}
|
|
3840
|
+
miniTicker(symbol3) {
|
|
3841
|
+
return `${symbol3.toLowerCase()}@miniTicker`;
|
|
3842
|
+
}
|
|
3843
|
+
allMiniTickers() {
|
|
3844
|
+
return "!miniTicker@arr";
|
|
3845
|
+
}
|
|
3846
|
+
bookTicker(symbol3) {
|
|
3847
|
+
return `${symbol3.toLowerCase()}@bookTicker`;
|
|
2297
3848
|
}
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
this.reconnectAttempt = 0;
|
|
2301
|
-
if (!this.closedByUser) this.connect();
|
|
3849
|
+
allBookTickers() {
|
|
3850
|
+
return "!bookTicker";
|
|
2302
3851
|
}
|
|
2303
|
-
|
|
2304
|
-
|
|
3852
|
+
markPrice(symbol3, updateSpeed = "3s") {
|
|
3853
|
+
return `${symbol3.toLowerCase()}@markPrice@${updateSpeed}`;
|
|
2305
3854
|
}
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
try {
|
|
2309
|
-
parsed = JSON.parse(raw);
|
|
2310
|
-
} catch {
|
|
2311
|
-
return;
|
|
2312
|
-
}
|
|
2313
|
-
try {
|
|
2314
|
-
const event = parseSpotUserDataEvent(parsed);
|
|
2315
|
-
this.emit(event.e, event);
|
|
2316
|
-
this.emit("userData", event);
|
|
2317
|
-
} catch (err) {
|
|
2318
|
-
this.emit("error", err);
|
|
2319
|
-
}
|
|
3855
|
+
markPriceForPair(pair, updateSpeed = "3s") {
|
|
3856
|
+
return `${pair.toLowerCase()}@markPrice@${updateSpeed}`;
|
|
2320
3857
|
}
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
setTimeout(() => {
|
|
2327
|
-
if (!this.closedByUser) this.connect();
|
|
2328
|
-
}, delay);
|
|
3858
|
+
liquidationOrder(symbol3) {
|
|
3859
|
+
return `${symbol3.toLowerCase()}@forceOrder`;
|
|
3860
|
+
}
|
|
3861
|
+
allLiquidationOrders() {
|
|
3862
|
+
return "!forceOrder@arr";
|
|
2329
3863
|
}
|
|
2330
3864
|
};
|
|
2331
3865
|
|
|
2332
|
-
// src/ws/
|
|
2333
|
-
import { EventEmitter as
|
|
2334
|
-
import
|
|
2335
|
-
var
|
|
3866
|
+
// src/ws/CoinMUserWS.ts
|
|
3867
|
+
import { EventEmitter as EventEmitter4 } from "events";
|
|
3868
|
+
import WebSocket4 from "ws";
|
|
3869
|
+
var CoinMUserWS = class extends EventEmitter4 {
|
|
2336
3870
|
constructor(options) {
|
|
2337
3871
|
super();
|
|
2338
3872
|
this.options = options;
|
|
@@ -2343,12 +3877,12 @@ var FuturesUserWS = class extends EventEmitter3 {
|
|
|
2343
3877
|
connect() {
|
|
2344
3878
|
const listenKey = this.options.getListenKey();
|
|
2345
3879
|
if (!listenKey) {
|
|
2346
|
-
this.emit("error", new Error("No listenKey available for user data stream"));
|
|
3880
|
+
this.emit("error", new Error("No listenKey available for COIN-M user data stream"));
|
|
2347
3881
|
return;
|
|
2348
3882
|
}
|
|
2349
3883
|
this.closedByUser = false;
|
|
2350
3884
|
const url = `${this.options.baseUserUrl}/${listenKey}`;
|
|
2351
|
-
this.ws = new
|
|
3885
|
+
this.ws = new WebSocket4(url);
|
|
2352
3886
|
this.ws.on("open", () => {
|
|
2353
3887
|
this.reconnectAttempt = 0;
|
|
2354
3888
|
this.emit("open");
|
|
@@ -2369,7 +3903,7 @@ var FuturesUserWS = class extends EventEmitter3 {
|
|
|
2369
3903
|
this.ws?.close();
|
|
2370
3904
|
}
|
|
2371
3905
|
reconnect() {
|
|
2372
|
-
if (this.ws?.readyState ===
|
|
3906
|
+
if (this.ws?.readyState === WebSocket4.OPEN) this.ws.close();
|
|
2373
3907
|
this.reconnectAttempt = 0;
|
|
2374
3908
|
if (!this.closedByUser) this.connect();
|
|
2375
3909
|
}
|
|
@@ -2403,32 +3937,37 @@ var FuturesUserWS = class extends EventEmitter3 {
|
|
|
2403
3937
|
};
|
|
2404
3938
|
|
|
2405
3939
|
// src/ws/WsApi.ts
|
|
2406
|
-
import {
|
|
2407
|
-
import
|
|
3940
|
+
import { randomUUID } from "crypto";
|
|
3941
|
+
import WebSocket5 from "ws";
|
|
2408
3942
|
function buildQueryString(data) {
|
|
2409
3943
|
return Object.entries(data).filter(([, val]) => val !== void 0 && val !== null).map(([key, val]) => `${key}=${encodeURIComponent(String(val))}`).join("&");
|
|
2410
3944
|
}
|
|
2411
3945
|
var WsApi = class {
|
|
2412
3946
|
constructor(options) {
|
|
2413
3947
|
this.options = options;
|
|
3948
|
+
this.signer = new Signer({
|
|
3949
|
+
algorithm: options.signatureAlgorithm,
|
|
3950
|
+
apiSecret: options.apiSecret,
|
|
3951
|
+
privateKey: options.privateKey
|
|
3952
|
+
});
|
|
2414
3953
|
}
|
|
2415
3954
|
async request(method, params = {}, options) {
|
|
2416
|
-
const { apiKey
|
|
3955
|
+
const { apiKey } = this.options;
|
|
2417
3956
|
const signed = options?.signed ?? true;
|
|
2418
3957
|
const { id = randomUUID(), ...methodParams } = params;
|
|
2419
3958
|
const requestParams = { ...methodParams };
|
|
2420
3959
|
if (signed) {
|
|
2421
|
-
if (!apiKey || !
|
|
2422
|
-
throw new Error("API key and secret required for signed WebSocket API requests");
|
|
3960
|
+
if (!apiKey || !this.signer.canSign()) {
|
|
3961
|
+
throw new Error("API key and secret (or privateKey) required for signed WebSocket API requests");
|
|
2423
3962
|
}
|
|
2424
3963
|
requestParams.apiKey = apiKey;
|
|
2425
3964
|
requestParams.timestamp = Date.now();
|
|
2426
3965
|
requestParams.recvWindow = this.options.recvWindow ?? 5e3;
|
|
2427
3966
|
const queryString = buildQueryString(requestParams);
|
|
2428
|
-
requestParams.signature =
|
|
3967
|
+
requestParams.signature = this.signer.sign(queryString);
|
|
2429
3968
|
}
|
|
2430
3969
|
return new Promise((resolve, reject) => {
|
|
2431
|
-
const ws = new
|
|
3970
|
+
const ws = new WebSocket5(this.options.baseUrl);
|
|
2432
3971
|
const timeout = setTimeout(() => {
|
|
2433
3972
|
ws.close();
|
|
2434
3973
|
reject(new NetworkError(`WebSocket API request timed out: ${method}`));
|
|
@@ -2529,6 +4068,174 @@ var WsApi = class {
|
|
|
2529
4068
|
}
|
|
2530
4069
|
};
|
|
2531
4070
|
|
|
4071
|
+
// src/ws/SpotWsApi.ts
|
|
4072
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
4073
|
+
import WebSocket6 from "ws";
|
|
4074
|
+
function buildQueryString2(data) {
|
|
4075
|
+
return Object.entries(data).filter(([, val]) => val !== void 0 && val !== null).map(([key, val]) => `${key}=${encodeURIComponent(String(val))}`).join("&");
|
|
4076
|
+
}
|
|
4077
|
+
var SpotWsApi = class {
|
|
4078
|
+
constructor(options) {
|
|
4079
|
+
this.options = options;
|
|
4080
|
+
this.signer = new Signer({
|
|
4081
|
+
algorithm: options.signatureAlgorithm,
|
|
4082
|
+
apiSecret: options.apiSecret,
|
|
4083
|
+
privateKey: options.privateKey
|
|
4084
|
+
});
|
|
4085
|
+
}
|
|
4086
|
+
async request(method, params = {}, options) {
|
|
4087
|
+
const { apiKey } = this.options;
|
|
4088
|
+
const signed = options?.signed ?? true;
|
|
4089
|
+
const { id = randomUUID2(), ...methodParams } = params;
|
|
4090
|
+
const requestParams = { ...methodParams };
|
|
4091
|
+
if (signed) {
|
|
4092
|
+
if (!apiKey || !this.signer.canSign()) {
|
|
4093
|
+
throw new Error("API key and secret (or privateKey) required for signed WebSocket API requests");
|
|
4094
|
+
}
|
|
4095
|
+
requestParams.apiKey = apiKey;
|
|
4096
|
+
requestParams.timestamp = Date.now();
|
|
4097
|
+
requestParams.recvWindow = this.options.recvWindow ?? 5e3;
|
|
4098
|
+
const queryString = buildQueryString2(requestParams);
|
|
4099
|
+
requestParams.signature = this.signer.sign(queryString);
|
|
4100
|
+
}
|
|
4101
|
+
return new Promise((resolve, reject) => {
|
|
4102
|
+
const ws = new WebSocket6(this.options.baseUrl);
|
|
4103
|
+
const timeout = setTimeout(() => {
|
|
4104
|
+
ws.close();
|
|
4105
|
+
reject(new NetworkError(`WebSocket API request timed out: ${method}`));
|
|
4106
|
+
}, this.options.timeoutMs ?? 15e3);
|
|
4107
|
+
ws.on("open", () => ws.send(JSON.stringify({ id, method, params: requestParams })));
|
|
4108
|
+
ws.on("message", (raw) => {
|
|
4109
|
+
clearTimeout(timeout);
|
|
4110
|
+
ws.close();
|
|
4111
|
+
try {
|
|
4112
|
+
const parsed = JSON.parse(raw.toString());
|
|
4113
|
+
if (parsed.status >= 400) {
|
|
4114
|
+
reject(new Error(parsed.error?.msg ?? `WebSocket API error: ${method}`));
|
|
4115
|
+
} else {
|
|
4116
|
+
resolve(parsed);
|
|
4117
|
+
}
|
|
4118
|
+
} catch (err) {
|
|
4119
|
+
reject(new NetworkError("Invalid WebSocket API JSON payload", err));
|
|
4120
|
+
}
|
|
4121
|
+
});
|
|
4122
|
+
ws.on("error", (err) => {
|
|
4123
|
+
clearTimeout(timeout);
|
|
4124
|
+
reject(new NetworkError(err.message, err));
|
|
4125
|
+
});
|
|
4126
|
+
});
|
|
4127
|
+
}
|
|
4128
|
+
// ---- Trading (signed) ----
|
|
4129
|
+
placeOrder(params) {
|
|
4130
|
+
return this.request("order.place", params);
|
|
4131
|
+
}
|
|
4132
|
+
testOrder(params) {
|
|
4133
|
+
return this.request("order.test", params);
|
|
4134
|
+
}
|
|
4135
|
+
cancelOrder(params) {
|
|
4136
|
+
return this.request("order.cancel", params);
|
|
4137
|
+
}
|
|
4138
|
+
cancelReplaceOrder(params) {
|
|
4139
|
+
return this.request("order.cancelReplace", params);
|
|
4140
|
+
}
|
|
4141
|
+
orderStatus(params) {
|
|
4142
|
+
return this.request("order.status", params);
|
|
4143
|
+
}
|
|
4144
|
+
openOrdersStatus(params = {}) {
|
|
4145
|
+
return this.request("openOrders.status", params);
|
|
4146
|
+
}
|
|
4147
|
+
cancelOpenOrders(params) {
|
|
4148
|
+
return this.request("openOrders.cancelAll", params);
|
|
4149
|
+
}
|
|
4150
|
+
placeOrderList(params) {
|
|
4151
|
+
return this.request("orderList.place", params);
|
|
4152
|
+
}
|
|
4153
|
+
cancelOrderList(params) {
|
|
4154
|
+
return this.request("orderList.cancel", params);
|
|
4155
|
+
}
|
|
4156
|
+
orderListStatus(params) {
|
|
4157
|
+
return this.request("orderList.status", params);
|
|
4158
|
+
}
|
|
4159
|
+
openOrderListsStatus() {
|
|
4160
|
+
return this.request("openOrderLists.status", {});
|
|
4161
|
+
}
|
|
4162
|
+
// ---- Account (signed) ----
|
|
4163
|
+
accountStatus() {
|
|
4164
|
+
return this.request("account.status", {});
|
|
4165
|
+
}
|
|
4166
|
+
accountCommission(params) {
|
|
4167
|
+
return this.request("account.commission", params);
|
|
4168
|
+
}
|
|
4169
|
+
accountRateLimitsOrders() {
|
|
4170
|
+
return this.request("account.rateLimits.orders", {});
|
|
4171
|
+
}
|
|
4172
|
+
allOrders(params) {
|
|
4173
|
+
return this.request("allOrders", params);
|
|
4174
|
+
}
|
|
4175
|
+
allOrderLists(params = {}) {
|
|
4176
|
+
return this.request("allOrderLists", params);
|
|
4177
|
+
}
|
|
4178
|
+
myTrades(params) {
|
|
4179
|
+
return this.request("myTrades", params);
|
|
4180
|
+
}
|
|
4181
|
+
// ---- User data stream (managed listen keys) ----
|
|
4182
|
+
userDataStreamStart() {
|
|
4183
|
+
return this.request("userDataStream.start", {});
|
|
4184
|
+
}
|
|
4185
|
+
userDataStreamPing(listenKey) {
|
|
4186
|
+
return this.request("userDataStream.ping", { listenKey });
|
|
4187
|
+
}
|
|
4188
|
+
userDataStreamStop(listenKey) {
|
|
4189
|
+
return this.request("userDataStream.stop", { listenKey });
|
|
4190
|
+
}
|
|
4191
|
+
// ---- Public market data (no signature required) ----
|
|
4192
|
+
ping() {
|
|
4193
|
+
return this.request("ping", {}, { signed: false });
|
|
4194
|
+
}
|
|
4195
|
+
time() {
|
|
4196
|
+
return this.request("time", {}, { signed: false });
|
|
4197
|
+
}
|
|
4198
|
+
exchangeInfo(params = {}) {
|
|
4199
|
+
return this.request("exchangeInfo", params, { signed: false });
|
|
4200
|
+
}
|
|
4201
|
+
depth(params) {
|
|
4202
|
+
return this.request("depth", params, { signed: false });
|
|
4203
|
+
}
|
|
4204
|
+
recentTrades(params) {
|
|
4205
|
+
return this.request("trades.recent", params, { signed: false });
|
|
4206
|
+
}
|
|
4207
|
+
historicalTrades(params) {
|
|
4208
|
+
return this.request("trades.historical", params, { signed: false });
|
|
4209
|
+
}
|
|
4210
|
+
aggTrades(params) {
|
|
4211
|
+
return this.request("trades.aggregate", params, { signed: false });
|
|
4212
|
+
}
|
|
4213
|
+
klines(params) {
|
|
4214
|
+
return this.request("klines", params, { signed: false });
|
|
4215
|
+
}
|
|
4216
|
+
uiKlines(params) {
|
|
4217
|
+
return this.request("uiKlines", params, { signed: false });
|
|
4218
|
+
}
|
|
4219
|
+
avgPrice(params) {
|
|
4220
|
+
return this.request("avgPrice", params, { signed: false });
|
|
4221
|
+
}
|
|
4222
|
+
ticker24hr(params = {}) {
|
|
4223
|
+
return this.request("ticker.24hr", params, { signed: false });
|
|
4224
|
+
}
|
|
4225
|
+
tickerTradingDay(params) {
|
|
4226
|
+
return this.request("ticker.tradingDay", params, { signed: false });
|
|
4227
|
+
}
|
|
4228
|
+
tickerPrice(params = {}) {
|
|
4229
|
+
return this.request("ticker.price", params, { signed: false });
|
|
4230
|
+
}
|
|
4231
|
+
tickerBook(params = {}) {
|
|
4232
|
+
return this.request("ticker.book", params, { signed: false });
|
|
4233
|
+
}
|
|
4234
|
+
ticker(params) {
|
|
4235
|
+
return this.request("ticker", params, { signed: false });
|
|
4236
|
+
}
|
|
4237
|
+
};
|
|
4238
|
+
|
|
2532
4239
|
// src/client/BinanceClient.ts
|
|
2533
4240
|
var BinanceClient = class {
|
|
2534
4241
|
constructor(options = {}) {
|
|
@@ -2536,18 +4243,29 @@ var BinanceClient = class {
|
|
|
2536
4243
|
this.keepAliveInterval = null;
|
|
2537
4244
|
this.spotListenKeyValue = null;
|
|
2538
4245
|
this.spotKeepAliveInterval = null;
|
|
4246
|
+
this.coinmListenKeyValue = null;
|
|
4247
|
+
this.coinmKeepAliveInterval = null;
|
|
2539
4248
|
const { endpoints } = resolveEnvironment(options);
|
|
4249
|
+
this.policy = options.safety ? new TradingPolicy(options.safety) : void 0;
|
|
2540
4250
|
const httpOptions = {
|
|
4251
|
+
policy: this.policy,
|
|
2541
4252
|
apiKey: options.apiKey,
|
|
2542
4253
|
apiSecret: options.apiSecret,
|
|
4254
|
+
privateKey: options.privateKey,
|
|
4255
|
+
signatureAlgorithm: options.signatureAlgorithm,
|
|
2543
4256
|
recvWindow: options.recvWindow ?? 5e3,
|
|
2544
4257
|
timeoutMs: options.timeoutMs ?? 15e3,
|
|
2545
4258
|
maxRetries: options.maxRetries ?? 3,
|
|
2546
4259
|
retryBaseDelayMs: options.retryBaseDelayMs,
|
|
2547
|
-
retryMaxDelayMs: options.retryMaxDelayMs
|
|
4260
|
+
retryMaxDelayMs: options.retryMaxDelayMs,
|
|
4261
|
+
rateLimitWeightPerMinute: options.rateLimitWeightPerMinute,
|
|
4262
|
+
rateLimitSafetyMargin: options.rateLimitSafetyMargin,
|
|
4263
|
+
httpsAgent: options.httpsAgent,
|
|
4264
|
+
proxy: options.proxy
|
|
2548
4265
|
};
|
|
2549
4266
|
this.authHttp = new HttpClient({ baseURL: endpoints.restRoot, ...httpOptions });
|
|
2550
|
-
|
|
4267
|
+
this.spotHttp = new HttpClient({ baseURL: endpoints.restSpot, ...httpOptions });
|
|
4268
|
+
const spotHttp = this.spotHttp;
|
|
2551
4269
|
this.spot = {
|
|
2552
4270
|
market: new SpotMarket(spotHttp),
|
|
2553
4271
|
account: new SpotAccount(spotHttp),
|
|
@@ -2557,6 +4275,14 @@ var BinanceClient = class {
|
|
|
2557
4275
|
wsUser: new SpotUserWS({
|
|
2558
4276
|
baseUserUrl: endpoints.wsSpotUser,
|
|
2559
4277
|
getListenKey: () => this.spotListenKeyValue
|
|
4278
|
+
}),
|
|
4279
|
+
wsApi: new SpotWsApi({
|
|
4280
|
+
baseUrl: endpoints.wsSpotApi,
|
|
4281
|
+
apiKey: options.apiKey,
|
|
4282
|
+
apiSecret: options.apiSecret,
|
|
4283
|
+
privateKey: options.privateKey,
|
|
4284
|
+
signatureAlgorithm: options.signatureAlgorithm,
|
|
4285
|
+
recvWindow: options.recvWindow
|
|
2560
4286
|
})
|
|
2561
4287
|
};
|
|
2562
4288
|
const futuresMarket = new FuturesMarket(
|
|
@@ -2586,9 +4312,30 @@ var BinanceClient = class {
|
|
|
2586
4312
|
baseUrl: endpoints.wsApi,
|
|
2587
4313
|
apiKey: options.apiKey,
|
|
2588
4314
|
apiSecret: options.apiSecret,
|
|
4315
|
+
privateKey: options.privateKey,
|
|
4316
|
+
signatureAlgorithm: options.signatureAlgorithm,
|
|
2589
4317
|
recvWindow: options.recvWindow
|
|
2590
4318
|
})
|
|
2591
4319
|
};
|
|
4320
|
+
this.dapiHttp = new HttpClient({ baseURL: endpoints.restDapiRoot, ...httpOptions });
|
|
4321
|
+
this.coinm = {
|
|
4322
|
+
market: new CoinMMarket(new HttpClient({ baseURL: endpoints.restDapi, ...httpOptions })),
|
|
4323
|
+
account: new CoinMAccount(this.dapiHttp),
|
|
4324
|
+
trading: new CoinMTrading(this.dapiHttp),
|
|
4325
|
+
userStream: new CoinMUserDataStream(this.dapiHttp),
|
|
4326
|
+
ws: new CoinMMarketWS(endpoints.wsDapiMarket),
|
|
4327
|
+
wsUser: new CoinMUserWS({
|
|
4328
|
+
baseUserUrl: endpoints.wsDapiUser,
|
|
4329
|
+
getListenKey: () => this.coinmListenKeyValue
|
|
4330
|
+
})
|
|
4331
|
+
};
|
|
4332
|
+
this.sapiHttp = new HttpClient({ baseURL: endpoints.restApiRoot, ...httpOptions });
|
|
4333
|
+
this.margin = {
|
|
4334
|
+
account: new MarginAccount(this.sapiHttp),
|
|
4335
|
+
trading: new MarginTrading(this.sapiHttp)
|
|
4336
|
+
};
|
|
4337
|
+
this.wallet = new Wallet(this.sapiHttp);
|
|
4338
|
+
this.subaccount = new SubAccount(this.sapiHttp);
|
|
2592
4339
|
}
|
|
2593
4340
|
static nowSeconds() {
|
|
2594
4341
|
return Math.floor(Date.now() / 1e3);
|
|
@@ -2605,6 +4352,31 @@ var BinanceClient = class {
|
|
|
2605
4352
|
const dir = side3 === "buy" ? 1 : -1;
|
|
2606
4353
|
return dir === 1 ? entryPrice * (1 - 1 / leverage + mm) : entryPrice * (1 + 1 / leverage - mm);
|
|
2607
4354
|
}
|
|
4355
|
+
/**
|
|
4356
|
+
* Syncs local time against each REST host's server clock and stores the offset, applied to
|
|
4357
|
+
* every subsequent signed request's `timestamp` param. Call this once after construction to
|
|
4358
|
+
* mitigate `-1021` errors caused by local clock drift.
|
|
4359
|
+
*/
|
|
4360
|
+
async syncTime() {
|
|
4361
|
+
await Promise.all([
|
|
4362
|
+
this.authHttp.syncTime("/fapi/v1/time"),
|
|
4363
|
+
this.spotHttp.syncTime("/time"),
|
|
4364
|
+
this.dapiHttp.syncTime("/dapi/v1/time"),
|
|
4365
|
+
this.sapiHttp.syncTime("/api/v3/time")
|
|
4366
|
+
]);
|
|
4367
|
+
}
|
|
4368
|
+
/**
|
|
4369
|
+
* Snapshot of the most recently observed `X-MBX-USED-WEIGHT-*` / `X-MBX-ORDER-COUNT-*`
|
|
4370
|
+
* response headers, per REST host. Each host tracks its own weight budget independently.
|
|
4371
|
+
*/
|
|
4372
|
+
getRateLimitUsage() {
|
|
4373
|
+
return {
|
|
4374
|
+
spot: this.spotHttp.getRateLimitUsage(),
|
|
4375
|
+
futures: this.authHttp.getRateLimitUsage(),
|
|
4376
|
+
coinm: this.dapiHttp.getRateLimitUsage(),
|
|
4377
|
+
sapi: this.sapiHttp.getRateLimitUsage()
|
|
4378
|
+
};
|
|
4379
|
+
}
|
|
2608
4380
|
async startUserStream() {
|
|
2609
4381
|
const { listenKey } = await this.futures.userStream.createListenKey();
|
|
2610
4382
|
this.listenKeyValue = listenKey;
|
|
@@ -2641,25 +4413,50 @@ var BinanceClient = class {
|
|
|
2641
4413
|
});
|
|
2642
4414
|
this.spotListenKeyValue = null;
|
|
2643
4415
|
}
|
|
4416
|
+
async startCoinMUserStream() {
|
|
4417
|
+
const { listenKey } = await this.coinm.userStream.createListenKey();
|
|
4418
|
+
this.coinmListenKeyValue = listenKey;
|
|
4419
|
+
this.coinmKeepAliveInterval = setInterval(() => {
|
|
4420
|
+
this.coinm.userStream.keepAliveListenKey().catch(() => {
|
|
4421
|
+
});
|
|
4422
|
+
}, 30 * 60 * 1e3);
|
|
4423
|
+
this.coinm.wsUser.connect();
|
|
4424
|
+
return listenKey;
|
|
4425
|
+
}
|
|
4426
|
+
closeCoinMUserStream() {
|
|
4427
|
+
if (this.coinmKeepAliveInterval) clearInterval(this.coinmKeepAliveInterval);
|
|
4428
|
+
this.coinmKeepAliveInterval = null;
|
|
4429
|
+
this.coinm.wsUser.close();
|
|
4430
|
+
this.coinm.userStream.closeListenKey().catch(() => {
|
|
4431
|
+
});
|
|
4432
|
+
this.coinmListenKeyValue = null;
|
|
4433
|
+
}
|
|
2644
4434
|
closeAllWebSockets() {
|
|
2645
4435
|
this.futures.ws.close();
|
|
2646
4436
|
this.futures.wsUser.close();
|
|
2647
4437
|
this.spot.ws.close();
|
|
2648
4438
|
this.spot.wsUser.close();
|
|
4439
|
+
this.coinm.ws.close();
|
|
4440
|
+
this.coinm.wsUser.close();
|
|
2649
4441
|
this.closeUserStream();
|
|
2650
4442
|
this.closeSpotUserStream();
|
|
4443
|
+
this.closeCoinMUserStream();
|
|
2651
4444
|
}
|
|
2652
4445
|
reconnectWebSocket(target) {
|
|
2653
4446
|
if (target === "ws") this.futures.ws.reconnect();
|
|
2654
4447
|
else if (target === "wsUser") this.futures.wsUser.reconnect();
|
|
2655
4448
|
else if (target === "spot") this.spot.ws.reconnect();
|
|
2656
|
-
else this.spot.wsUser.reconnect();
|
|
4449
|
+
else if (target === "spotUser") this.spot.wsUser.reconnect();
|
|
4450
|
+
else if (target === "coinm") this.coinm.ws.reconnect();
|
|
4451
|
+
else this.coinm.wsUser.reconnect();
|
|
2657
4452
|
}
|
|
2658
4453
|
resetReconnectAttempts() {
|
|
2659
4454
|
this.futures.ws.resetReconnectAttempts();
|
|
2660
4455
|
this.futures.wsUser.resetReconnectAttempts();
|
|
2661
4456
|
this.spot.ws.resetReconnectAttempts();
|
|
2662
4457
|
this.spot.wsUser.resetReconnectAttempts();
|
|
4458
|
+
this.coinm.ws.resetReconnectAttempts();
|
|
4459
|
+
this.coinm.wsUser.resetReconnectAttempts();
|
|
2663
4460
|
}
|
|
2664
4461
|
};
|
|
2665
4462
|
|
|
@@ -2667,10 +4464,10 @@ var BinanceClient = class {
|
|
|
2667
4464
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2668
4465
|
|
|
2669
4466
|
// src/tools/account.tools.ts
|
|
2670
|
-
import { z as
|
|
4467
|
+
import { z as z13 } from "zod";
|
|
2671
4468
|
|
|
2672
4469
|
// src/tools/types.ts
|
|
2673
|
-
import { z as
|
|
4470
|
+
import { z as z12 } from "zod";
|
|
2674
4471
|
function normalizeSymbol(value) {
|
|
2675
4472
|
return String(value ?? "").trim().toUpperCase();
|
|
2676
4473
|
}
|
|
@@ -2679,248 +4476,248 @@ function textResult(data) {
|
|
|
2679
4476
|
}
|
|
2680
4477
|
|
|
2681
4478
|
// src/tools/account.tools.ts
|
|
2682
|
-
var optionalSymbol =
|
|
2683
|
-
var limit =
|
|
2684
|
-
var startTime =
|
|
2685
|
-
var endTime =
|
|
4479
|
+
var optionalSymbol = z13.string().min(1).describe("USD-M pair, e.g. BTCUSDT").optional();
|
|
4480
|
+
var limit = z13.number().int().positive().max(1e3).default(100);
|
|
4481
|
+
var startTime = z13.number().int().positive().optional();
|
|
4482
|
+
var endTime = z13.number().int().positive().optional();
|
|
2686
4483
|
function accountTools(client) {
|
|
2687
4484
|
const a = client.futures.account;
|
|
2688
4485
|
return [
|
|
2689
4486
|
{
|
|
2690
4487
|
name: "futures_balance",
|
|
2691
4488
|
description: "Get futures account balances (v3): asset, wallet balance, unrealized profit, margin balance, available balance (signed).",
|
|
2692
|
-
inputSchema:
|
|
4489
|
+
inputSchema: z13.object({}),
|
|
2693
4490
|
handler: async () => textResult(await a.balanceV3())
|
|
2694
4491
|
},
|
|
2695
4492
|
{
|
|
2696
4493
|
name: "futures_account",
|
|
2697
4494
|
description: "Get full account information (v3): total wallet/margin balance, unrealized profit, available balance, assets & positions (signed).",
|
|
2698
|
-
inputSchema:
|
|
4495
|
+
inputSchema: z13.object({}),
|
|
2699
4496
|
handler: async () => textResult(await a.accountV3())
|
|
2700
4497
|
},
|
|
2701
4498
|
{
|
|
2702
4499
|
name: "futures_balance_v2",
|
|
2703
4500
|
description: "Get futures account balance (v2 legacy) per asset (signed).",
|
|
2704
|
-
inputSchema:
|
|
4501
|
+
inputSchema: z13.object({}),
|
|
2705
4502
|
handler: async () => textResult(await a.balance())
|
|
2706
4503
|
},
|
|
2707
4504
|
{
|
|
2708
4505
|
name: "futures_account_v2",
|
|
2709
4506
|
description: "Get futures account information (v2 legacy) (signed).",
|
|
2710
|
-
inputSchema:
|
|
4507
|
+
inputSchema: z13.object({}),
|
|
2711
4508
|
handler: async () => textResult(await a.account())
|
|
2712
4509
|
},
|
|
2713
4510
|
{
|
|
2714
4511
|
name: "futures_position_risk",
|
|
2715
4512
|
description: "Get current open positions (v3): symbol, side, size, entry price, mark price, liquidation price, leverage, unrealized PnL, margin (signed).",
|
|
2716
|
-
inputSchema:
|
|
4513
|
+
inputSchema: z13.object({ symbol: optionalSymbol }),
|
|
2717
4514
|
handler: async ({ symbol: symbol3 }) => textResult(await a.positionRiskV3(symbol3 ? normalizeSymbol(symbol3) : void 0))
|
|
2718
4515
|
},
|
|
2719
4516
|
{
|
|
2720
4517
|
name: "futures_income_history",
|
|
2721
4518
|
description: "Get futures income history (realized PnL, funding fees, commissions, transfers, insurance clearing). incomeType examples: TRANSFER, REALIZED_PNL, FUNDING_FEE, COMMISSION, INSURANCE_CLEAR, REFERRAL_KICKBACK (signed).",
|
|
2722
|
-
inputSchema:
|
|
4519
|
+
inputSchema: z13.object({ symbol: optionalSymbol, incomeType: z13.string().optional().describe("e.g. TRANSFER, REALIZED_PNL, FUNDING_FEE, COMMISSION"), startTime, endTime, limit: limit.default(100) }),
|
|
2723
4520
|
handler: async ({ symbol: symbol3, incomeType, startTime: startTime5, endTime: endTime5, limit: limit4 }) => textResult(await a.incomeHistory({ symbol: symbol3 ? normalizeSymbol(symbol3) : void 0, incomeType, startTime: startTime5, endTime: endTime5, limit: Number(limit4) }))
|
|
2724
4521
|
},
|
|
2725
4522
|
{
|
|
2726
4523
|
name: "futures_user_trades",
|
|
2727
4524
|
description: "Get account trade list (filled trades) for a symbol with optional time range (signed).",
|
|
2728
|
-
inputSchema:
|
|
4525
|
+
inputSchema: z13.object({ symbol: z13.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), startTime, endTime, limit: limit.default(100), fromId: z13.number().int().positive().optional() }),
|
|
2729
4526
|
handler: async ({ symbol: symbol3, startTime: startTime5, endTime: endTime5, limit: limit4, fromId }) => textResult(await a.userTrades({ symbol: normalizeSymbol(symbol3), startTime: startTime5, endTime: endTime5, limit: Number(limit4), fromId }))
|
|
2730
4527
|
},
|
|
2731
4528
|
{
|
|
2732
4529
|
name: "futures_leverage_brackets",
|
|
2733
4530
|
description: "Get notional and leverage brackets for one symbol or all: tier caps, maintenance margin rate, max leverage (signed).",
|
|
2734
|
-
inputSchema:
|
|
4531
|
+
inputSchema: z13.object({ symbol: optionalSymbol }),
|
|
2735
4532
|
handler: async ({ symbol: symbol3 }) => textResult(await a.leverageBrackets(symbol3 ? normalizeSymbol(symbol3) : void 0))
|
|
2736
4533
|
},
|
|
2737
4534
|
{
|
|
2738
4535
|
name: "futures_commission_rate",
|
|
2739
4536
|
description: "Get user commission rate (taker & maker fee) for a symbol (signed).",
|
|
2740
|
-
inputSchema:
|
|
4537
|
+
inputSchema: z13.object({ symbol: z13.string().min(1).describe("USD-M pair, e.g. ETHUSDT") }),
|
|
2741
4538
|
handler: async ({ symbol: symbol3 }) => textResult(await a.commissionRate(normalizeSymbol(symbol3)))
|
|
2742
4539
|
},
|
|
2743
4540
|
{
|
|
2744
4541
|
name: "futures_multi_assets_mode",
|
|
2745
4542
|
description: "Get current multi-assets margin mode status (signed).",
|
|
2746
|
-
inputSchema:
|
|
4543
|
+
inputSchema: z13.object({}),
|
|
2747
4544
|
handler: async () => textResult(await a.multiAssetsMargin())
|
|
2748
4545
|
},
|
|
2749
4546
|
{
|
|
2750
4547
|
name: "futures_set_multi_assets_mode",
|
|
2751
4548
|
description: "Enable or disable multi-assets mode (signed; 7-day cooldown between toggles).",
|
|
2752
|
-
inputSchema:
|
|
4549
|
+
inputSchema: z13.object({ enabled: z13.boolean().describe("true to enable, false to disable") }),
|
|
2753
4550
|
handler: async ({ enabled }) => textResult(await a.setMultiAssetsMargin(enabled))
|
|
2754
4551
|
},
|
|
2755
4552
|
{
|
|
2756
4553
|
name: "futures_fee_burn_status",
|
|
2757
4554
|
description: "Get BNB fee burn status for futures trades (signed).",
|
|
2758
|
-
inputSchema:
|
|
4555
|
+
inputSchema: z13.object({}),
|
|
2759
4556
|
handler: async () => textResult(await a.feeBurnStatus())
|
|
2760
4557
|
},
|
|
2761
4558
|
{
|
|
2762
4559
|
name: "futures_set_fee_burn",
|
|
2763
4560
|
description: "Toggle BNB fee burn on futures trades (signed).",
|
|
2764
|
-
inputSchema:
|
|
4561
|
+
inputSchema: z13.object({ enabled: z13.boolean().describe("true to enable fee burn") }),
|
|
2765
4562
|
handler: async ({ enabled }) => textResult(await a.setFeeBurnStatus(enabled))
|
|
2766
4563
|
},
|
|
2767
4564
|
{
|
|
2768
4565
|
name: "futures_position_mode",
|
|
2769
4566
|
description: "Get current position mode: one-way (BOTH) or hedge mode (LONG/SHORT) (signed).",
|
|
2770
|
-
inputSchema:
|
|
4567
|
+
inputSchema: z13.object({}),
|
|
2771
4568
|
handler: async () => textResult(await a.positionMode())
|
|
2772
4569
|
},
|
|
2773
4570
|
{
|
|
2774
4571
|
name: "futures_set_position_mode",
|
|
2775
4572
|
description: "Change position mode: hedgeMode true = dual side (hedge), false = one-way (signed; 30-day cooldown).",
|
|
2776
|
-
inputSchema:
|
|
4573
|
+
inputSchema: z13.object({ hedgeMode: z13.boolean().describe("true = hedge mode, false = one-way") }),
|
|
2777
4574
|
handler: async ({ hedgeMode }) => textResult(await a.setPositionMode(hedgeMode))
|
|
2778
4575
|
},
|
|
2779
4576
|
{
|
|
2780
4577
|
name: "futures_api_trading_status",
|
|
2781
4578
|
description: "Get futures trading quantitative rules indicators and disable intervals (signed).",
|
|
2782
|
-
inputSchema:
|
|
4579
|
+
inputSchema: z13.object({}),
|
|
2783
4580
|
handler: async () => textResult(await a.apiTradingStatus())
|
|
2784
4581
|
},
|
|
2785
4582
|
{
|
|
2786
4583
|
name: "futures_position_margin_history",
|
|
2787
4584
|
description: "Get isolated position margin change history. type: 1 = add margin, 2 = reduce margin (signed).",
|
|
2788
|
-
inputSchema:
|
|
4585
|
+
inputSchema: z13.object({ symbol: z13.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), type: z13.enum(["1", "2"]).describe("1 = add margin, 2 = reduce margin"), startTime, endTime, limit: limit.default(50) }),
|
|
2789
4586
|
handler: async ({ symbol: symbol3, type, startTime: startTime5, endTime: endTime5, limit: limit4 }) => textResult(await a.positionMarginHistory({ symbol: normalizeSymbol(symbol3), type: Number(type), startTime: startTime5, endTime: endTime5, limit: Number(limit4) }))
|
|
2790
4587
|
},
|
|
2791
4588
|
{
|
|
2792
4589
|
name: "futures_rate_limit_order",
|
|
2793
4590
|
description: "Query the current user order rate limit usage (signed).",
|
|
2794
|
-
inputSchema:
|
|
4591
|
+
inputSchema: z13.object({}),
|
|
2795
4592
|
handler: async () => textResult(await a.rateLimitOrder())
|
|
2796
4593
|
},
|
|
2797
4594
|
{
|
|
2798
4595
|
name: "futures_request_order_download",
|
|
2799
4596
|
description: "Request a futures order-history download (async, 7-day window). Returns a downloadId (signed).",
|
|
2800
|
-
inputSchema:
|
|
4597
|
+
inputSchema: z13.object({ symbol: optionalSymbol, startTime, endTime }),
|
|
2801
4598
|
handler: async ({ symbol: symbol3, startTime: startTime5, endTime: endTime5 }) => textResult(await a.requestOrderDownload({ symbol: symbol3 ? normalizeSymbol(symbol3) : void 0, startTime: startTime5, endTime: endTime5 }))
|
|
2802
4599
|
},
|
|
2803
4600
|
{
|
|
2804
4601
|
name: "futures_order_download_status",
|
|
2805
4602
|
description: "Get the futures order-history download link by downloadId (signed).",
|
|
2806
|
-
inputSchema:
|
|
4603
|
+
inputSchema: z13.object({ downloadId: z13.string().min(1) }),
|
|
2807
4604
|
handler: async ({ downloadId }) => textResult(await a.getOrderDownloadStatus(downloadId))
|
|
2808
4605
|
},
|
|
2809
4606
|
{
|
|
2810
4607
|
name: "futures_request_trade_download",
|
|
2811
4608
|
description: "Request a futures trade-history download (async, 7-day window). Returns a downloadId (signed).",
|
|
2812
|
-
inputSchema:
|
|
4609
|
+
inputSchema: z13.object({ symbol: optionalSymbol, startTime, endTime }),
|
|
2813
4610
|
handler: async ({ symbol: symbol3, startTime: startTime5, endTime: endTime5 }) => textResult(await a.requestTradeDownload({ symbol: symbol3 ? normalizeSymbol(symbol3) : void 0, startTime: startTime5, endTime: endTime5 }))
|
|
2814
4611
|
},
|
|
2815
4612
|
{
|
|
2816
4613
|
name: "futures_trade_download_status",
|
|
2817
4614
|
description: "Get the futures trade-history download link by downloadId (signed).",
|
|
2818
|
-
inputSchema:
|
|
4615
|
+
inputSchema: z13.object({ downloadId: z13.string().min(1) }),
|
|
2819
4616
|
handler: async ({ downloadId }) => textResult(await a.getTradeDownloadStatus(downloadId))
|
|
2820
4617
|
},
|
|
2821
4618
|
{
|
|
2822
4619
|
name: "futures_account_config",
|
|
2823
4620
|
description: "Get futures account configuration: fee tier, trading permissions, dual-side position setting (signed).",
|
|
2824
|
-
inputSchema:
|
|
4621
|
+
inputSchema: z13.object({}),
|
|
2825
4622
|
handler: async () => textResult(await a.accountConfig())
|
|
2826
4623
|
},
|
|
2827
4624
|
{
|
|
2828
4625
|
name: "futures_portfolio_margin_account_info",
|
|
2829
4626
|
description: "Get Portfolio Margin account info for an asset: cross margin balance and liability (signed).",
|
|
2830
|
-
inputSchema:
|
|
4627
|
+
inputSchema: z13.object({ asset: z13.string().min(1).describe("Asset, e.g. USDT") }),
|
|
2831
4628
|
handler: async ({ asset }) => textResult(await a.pmAccountInfo(asset))
|
|
2832
4629
|
},
|
|
2833
4630
|
{
|
|
2834
4631
|
name: "futures_request_income_download",
|
|
2835
4632
|
description: "Request a futures income/transaction-history download (async). Returns a downloadId (signed).",
|
|
2836
|
-
inputSchema:
|
|
4633
|
+
inputSchema: z13.object({ startTime: startTime.unwrap(), endTime: endTime.unwrap() }),
|
|
2837
4634
|
handler: async ({ startTime: startTime5, endTime: endTime5 }) => textResult(await a.requestIncomeDownload({ startTime: startTime5, endTime: endTime5 }))
|
|
2838
4635
|
},
|
|
2839
4636
|
{
|
|
2840
4637
|
name: "futures_income_download_status",
|
|
2841
4638
|
description: "Get the futures income/transaction-history download link by downloadId (signed).",
|
|
2842
|
-
inputSchema:
|
|
4639
|
+
inputSchema: z13.object({ downloadId: z13.string().min(1) }),
|
|
2843
4640
|
handler: async ({ downloadId }) => textResult(await a.getIncomeDownloadStatus(downloadId))
|
|
2844
4641
|
}
|
|
2845
4642
|
];
|
|
2846
4643
|
}
|
|
2847
4644
|
|
|
2848
4645
|
// src/tools/derived.tools.ts
|
|
2849
|
-
import { z as
|
|
2850
|
-
var symbol =
|
|
4646
|
+
import { z as z14 } from "zod";
|
|
4647
|
+
var symbol = z14.string().min(1).describe("USD-M pair, e.g. BTCUSDT");
|
|
2851
4648
|
function derivedTools(client) {
|
|
2852
4649
|
const ops = client.futures.ops;
|
|
2853
4650
|
return [
|
|
2854
4651
|
{
|
|
2855
4652
|
name: "futures_symbol_rules",
|
|
2856
4653
|
description: "Get the tradeable rules for a symbol in one call: tick size, step size, min/max quantity, market-order lot bounds and minimum notional, flattened out of exchangeInfo filters. Call this before sizing or pricing any order.",
|
|
2857
|
-
inputSchema:
|
|
4654
|
+
inputSchema: z14.object({ symbol, refresh: z14.boolean().default(false).describe("Bypass the 60s cache") }),
|
|
2858
4655
|
handler: async ({ symbol: s, refresh }) => textResult(await ops.symbolRules(normalizeSymbol(s), { refresh }))
|
|
2859
4656
|
},
|
|
2860
4657
|
{
|
|
2861
4658
|
name: "futures_quantize",
|
|
2862
4659
|
description: "Round a price to the symbol's tick size and a quantity to its step size, returning exchange-ready strings. Use this instead of rounding numbers yourself \u2014 Binance rejects off-tick prices (-1111).",
|
|
2863
|
-
inputSchema:
|
|
4660
|
+
inputSchema: z14.object({
|
|
2864
4661
|
symbol,
|
|
2865
|
-
price:
|
|
2866
|
-
quantity:
|
|
2867
|
-
marketOrder:
|
|
4662
|
+
price: z14.number().positive().optional(),
|
|
4663
|
+
quantity: z14.number().positive().optional(),
|
|
4664
|
+
marketOrder: z14.boolean().default(false).describe("Use MARKET_LOT_SIZE bounds instead of LOT_SIZE")
|
|
2868
4665
|
}),
|
|
2869
4666
|
handler: async ({ symbol: s, price, quantity, marketOrder }) => textResult(await ops.quantize(normalizeSymbol(s), { price, quantity, marketOrder }))
|
|
2870
4667
|
},
|
|
2871
4668
|
{
|
|
2872
4669
|
name: "futures_size_position",
|
|
2873
4670
|
description: "Convert a risk budget into an exchange-ready order quantity. Given a stop price and either riskAmount (quote currency) or riskPct (percent of available balance), returns the quantity rounded down to the symbol step size, plus the notional, required margin and every constraint that failed (min notional, lot bounds, wrong-side stop). Never increases risk to satisfy a minimum \u2014 it reports instead.",
|
|
2874
|
-
inputSchema:
|
|
4671
|
+
inputSchema: z14.object({
|
|
2875
4672
|
symbol,
|
|
2876
|
-
side:
|
|
2877
|
-
stopPrice:
|
|
2878
|
-
entryPrice:
|
|
2879
|
-
riskAmount:
|
|
2880
|
-
riskPct:
|
|
2881
|
-
leverage:
|
|
2882
|
-
marketOrder:
|
|
4673
|
+
side: z14.enum(["BUY", "SELL"]),
|
|
4674
|
+
stopPrice: z14.number().positive().describe("Protective stop price"),
|
|
4675
|
+
entryPrice: z14.number().positive().optional().describe("Defaults to current mark price"),
|
|
4676
|
+
riskAmount: z14.number().positive().optional().describe("Quote-currency amount to risk, e.g. 50 USDT"),
|
|
4677
|
+
riskPct: z14.number().positive().max(100).optional().describe("Percent of available balance to risk (signed call)"),
|
|
4678
|
+
leverage: z14.number().int().min(1).max(125).optional().describe("Used to report required margin"),
|
|
4679
|
+
marketOrder: z14.boolean().default(false)
|
|
2883
4680
|
}),
|
|
2884
4681
|
handler: async (args) => textResult(await ops.sizePosition({ ...args, symbol: normalizeSymbol(args.symbol) }))
|
|
2885
4682
|
},
|
|
2886
4683
|
{
|
|
2887
4684
|
name: "futures_close_position",
|
|
2888
4685
|
description: "Flatten an open position with a reduce-only market order. Reads the current position, derives the closing side from its sign, and automatically uses reduceOnly in one-way mode vs positionSide in hedge mode (Binance rejects the wrong one). Set dryRun to preview the order without sending it. Signed, destructive.",
|
|
2889
|
-
inputSchema:
|
|
4686
|
+
inputSchema: z14.object({
|
|
2890
4687
|
symbol,
|
|
2891
|
-
positionSide:
|
|
2892
|
-
portion:
|
|
2893
|
-
dryRun:
|
|
4688
|
+
positionSide: z14.enum(["BOTH", "LONG", "SHORT"]).optional().describe("Required when hedge mode has both sides open"),
|
|
4689
|
+
portion: z14.number().positive().max(1).default(1).describe("Fraction of the position to close, e.g. 0.5 for half"),
|
|
4690
|
+
dryRun: z14.boolean().default(false)
|
|
2894
4691
|
}),
|
|
2895
4692
|
handler: async (args) => textResult(await ops.closePosition({ ...args, symbol: normalizeSymbol(args.symbol) }))
|
|
2896
4693
|
},
|
|
2897
4694
|
{
|
|
2898
4695
|
name: "futures_market_snapshot",
|
|
2899
4696
|
description: "One-call market picture for a symbol: 24h stats, mark/index price with funding, open interest and long/short positioning. Replaces four separate primitive calls; individual feeds degrade to an error field rather than failing the whole snapshot.",
|
|
2900
|
-
inputSchema:
|
|
4697
|
+
inputSchema: z14.object({
|
|
2901
4698
|
symbol,
|
|
2902
|
-
period:
|
|
4699
|
+
period: z14.enum(["5m", "15m", "30m", "1h", "2h", "4h", "6h", "12h", "1d"]).default("1h")
|
|
2903
4700
|
}),
|
|
2904
4701
|
handler: async ({ symbol: s, period: period2 }) => textResult(await ops.marketSnapshot(normalizeSymbol(s), { period: period2 }))
|
|
2905
4702
|
},
|
|
2906
4703
|
{
|
|
2907
4704
|
name: "futures_account_overview",
|
|
2908
4705
|
description: "One-call account picture: funded balances, open positions only (zero-size entries filtered out), working orders, and totals for unrealized PnL and gross notional. Signed.",
|
|
2909
|
-
inputSchema:
|
|
4706
|
+
inputSchema: z14.object({}),
|
|
2910
4707
|
handler: async () => textResult(await ops.accountOverview())
|
|
2911
4708
|
},
|
|
2912
4709
|
{
|
|
2913
4710
|
name: "futures_place_bracket_order",
|
|
2914
4711
|
description: "Place an entry order together with its protective stop-loss and optional take-profit, with all prices quantized to the symbol tick. Returns each leg separately; if a protective leg fails the response is flagged protectionComplete=false and the entry is NOT auto-cancelled (it may already have filled). Signed, destructive.",
|
|
2915
|
-
inputSchema:
|
|
4712
|
+
inputSchema: z14.object({
|
|
2916
4713
|
symbol,
|
|
2917
|
-
side:
|
|
2918
|
-
quantity:
|
|
2919
|
-
entryPrice:
|
|
2920
|
-
stopLossPrice:
|
|
2921
|
-
takeProfitPrice:
|
|
2922
|
-
positionSide:
|
|
2923
|
-
workingType:
|
|
4714
|
+
side: z14.enum(["BUY", "SELL"]),
|
|
4715
|
+
quantity: z14.union([z14.string(), z14.number()]),
|
|
4716
|
+
entryPrice: z14.number().positive().optional().describe("Omit for a MARKET entry"),
|
|
4717
|
+
stopLossPrice: z14.number().positive(),
|
|
4718
|
+
takeProfitPrice: z14.number().positive().optional(),
|
|
4719
|
+
positionSide: z14.enum(["BOTH", "LONG", "SHORT"]).optional(),
|
|
4720
|
+
workingType: z14.enum(["MARK_PRICE", "CONTRACT_PRICE"]).default("MARK_PRICE")
|
|
2924
4721
|
}),
|
|
2925
4722
|
handler: async (args) => textResult(await ops.placeBracketOrder({ ...args, symbol: normalizeSymbol(args.symbol) }))
|
|
2926
4723
|
}
|
|
@@ -2928,14 +4725,14 @@ function derivedTools(client) {
|
|
|
2928
4725
|
}
|
|
2929
4726
|
|
|
2930
4727
|
// src/tools/market-data.tools.ts
|
|
2931
|
-
import { z as
|
|
4728
|
+
import { z as z15 } from "zod";
|
|
2932
4729
|
var u = (s) => s.optional();
|
|
2933
|
-
var optSymbol = u(
|
|
2934
|
-
var limitDefault =
|
|
2935
|
-
var startTime2 =
|
|
2936
|
-
var endTime2 =
|
|
2937
|
-
var period =
|
|
2938
|
-
var contractType =
|
|
4730
|
+
var optSymbol = u(z15.string().min(1)).describe("USD-M pair, e.g. BTCUSDT");
|
|
4731
|
+
var limitDefault = z15.number().int().positive().max(1500).default(100);
|
|
4732
|
+
var startTime2 = z15.number().int().positive().optional();
|
|
4733
|
+
var endTime2 = z15.number().int().positive().optional();
|
|
4734
|
+
var period = z15.enum(["5m", "15m", "30m", "1h", "2h", "4h", "6h", "12h", "1d"]).default("1h");
|
|
4735
|
+
var contractType = z15.enum(["perpetual", "current_quarter", "next_quarter"]).default("perpetual");
|
|
2939
4736
|
function marketDataTools(client) {
|
|
2940
4737
|
const m = client.futures.market;
|
|
2941
4738
|
const d = client.futures.data;
|
|
@@ -2943,65 +4740,65 @@ function marketDataTools(client) {
|
|
|
2943
4740
|
{
|
|
2944
4741
|
name: "futures_ping",
|
|
2945
4742
|
description: "Test connectivity to the Binance USD-M futures REST API. Returns empty object {} on success.",
|
|
2946
|
-
inputSchema:
|
|
4743
|
+
inputSchema: z15.object({}),
|
|
2947
4744
|
handler: async () => textResult(await m.ping())
|
|
2948
4745
|
},
|
|
2949
4746
|
{
|
|
2950
4747
|
name: "futures_server_time",
|
|
2951
4748
|
description: "Get the current Binance USD-M futures server time in milliseconds since epoch.",
|
|
2952
|
-
inputSchema:
|
|
4749
|
+
inputSchema: z15.object({}),
|
|
2953
4750
|
handler: async () => textResult(await m.serverTime())
|
|
2954
4751
|
},
|
|
2955
4752
|
{
|
|
2956
4753
|
name: "futures_exchange_info",
|
|
2957
4754
|
description: "Get exchange trading rules and symbol metadata: contract type, status, base/quote assets, price/quantity filters, tick size, step size, notional and leverage brackets, delivery dates.",
|
|
2958
|
-
inputSchema:
|
|
4755
|
+
inputSchema: z15.object({}),
|
|
2959
4756
|
handler: async () => textResult(await m.exchangeInfo())
|
|
2960
4757
|
},
|
|
2961
4758
|
{
|
|
2962
4759
|
name: "futures_ticker_price",
|
|
2963
4760
|
description: "Get latest price for one symbol (v1).",
|
|
2964
|
-
inputSchema:
|
|
4761
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT") }),
|
|
2965
4762
|
handler: async ({ symbol: symbol3 }) => textResult(await m.tickerPrice(normalizeSymbol(symbol3)))
|
|
2966
4763
|
},
|
|
2967
4764
|
{
|
|
2968
4765
|
name: "futures_ticker_price_v2",
|
|
2969
4766
|
description: "Get latest price for one symbol, or for all symbols when symbol is omitted (v2 endpoint). Use all-symbols mode for market overviews.",
|
|
2970
|
-
inputSchema:
|
|
4767
|
+
inputSchema: z15.object({ symbol: optSymbol }),
|
|
2971
4768
|
handler: async ({ symbol: symbol3 }) => textResult(await m.tickerPriceV2(symbol3 ? normalizeSymbol(symbol3) : void 0))
|
|
2972
4769
|
},
|
|
2973
4770
|
{
|
|
2974
4771
|
name: "futures_ticker_24hr",
|
|
2975
4772
|
description: "Get 24-hour rolling price change statistics for a symbol: price change %, high, low, volume, quote volume, open interest.",
|
|
2976
|
-
inputSchema:
|
|
4773
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT") }),
|
|
2977
4774
|
handler: async ({ symbol: symbol3 }) => textResult(await m.ticker24hr(normalizeSymbol(symbol3)))
|
|
2978
4775
|
},
|
|
2979
4776
|
{
|
|
2980
4777
|
name: "futures_book_ticker",
|
|
2981
4778
|
description: "Get best bid/ask (top of book) for a single symbol (v1).",
|
|
2982
|
-
inputSchema:
|
|
4779
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT") }),
|
|
2983
4780
|
handler: async ({ symbol: symbol3 }) => textResult(await m.bookTicker(normalizeSymbol(symbol3)))
|
|
2984
4781
|
},
|
|
2985
4782
|
{
|
|
2986
4783
|
name: "futures_book_ticker_v2",
|
|
2987
4784
|
description: "Get best bid/ask (top of book) for one symbol, or all symbols when omitted (v2 endpoint).",
|
|
2988
|
-
inputSchema:
|
|
4785
|
+
inputSchema: z15.object({ symbol: optSymbol }),
|
|
2989
4786
|
handler: async ({ symbol: symbol3 }) => textResult(await m.bookTickerV2(symbol3 ? normalizeSymbol(symbol3) : void 0))
|
|
2990
4787
|
},
|
|
2991
4788
|
{
|
|
2992
4789
|
name: "futures_order_book",
|
|
2993
4790
|
description: "Get order book depth for a symbol. Limits: 5, 10, 20, 50, 100, 500, 1000.",
|
|
2994
|
-
inputSchema:
|
|
2995
|
-
symbol:
|
|
2996
|
-
limit:
|
|
4791
|
+
inputSchema: z15.object({
|
|
4792
|
+
symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT"),
|
|
4793
|
+
limit: z15.enum(["5", "10", "20", "50", "100", "500", "1000"]).default("100")
|
|
2997
4794
|
}),
|
|
2998
4795
|
handler: async ({ symbol: symbol3, limit: limit4 }) => textResult(await m.depth(normalizeSymbol(symbol3), Number(limit4)))
|
|
2999
4796
|
},
|
|
3000
4797
|
{
|
|
3001
4798
|
name: "futures_recent_trades",
|
|
3002
4799
|
description: "Get the most recent executed trades for a symbol (public endpoint).",
|
|
3003
|
-
inputSchema:
|
|
3004
|
-
symbol:
|
|
4800
|
+
inputSchema: z15.object({
|
|
4801
|
+
symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT"),
|
|
3005
4802
|
limit: limitDefault.default(500)
|
|
3006
4803
|
}),
|
|
3007
4804
|
handler: async ({ symbol: symbol3, limit: limit4 }) => textResult(await m.trades(normalizeSymbol(symbol3), Number(limit4)))
|
|
@@ -3009,30 +4806,30 @@ function marketDataTools(client) {
|
|
|
3009
4806
|
{
|
|
3010
4807
|
name: "futures_historical_trades",
|
|
3011
4808
|
description: "Get older trades for a symbol by fromId (older than recent).",
|
|
3012
|
-
inputSchema:
|
|
3013
|
-
symbol:
|
|
4809
|
+
inputSchema: z15.object({
|
|
4810
|
+
symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT"),
|
|
3014
4811
|
limit: limitDefault.default(500),
|
|
3015
|
-
fromId:
|
|
4812
|
+
fromId: z15.number().int().positive().optional()
|
|
3016
4813
|
}),
|
|
3017
4814
|
handler: async ({ symbol: symbol3, limit: limit4, fromId }) => textResult(await m.historicalTrades(normalizeSymbol(symbol3), { limit: Number(limit4), fromId }))
|
|
3018
4815
|
},
|
|
3019
4816
|
{
|
|
3020
4817
|
name: "futures_agg_trades",
|
|
3021
4818
|
description: "Get compressed/aggregate trades for a symbol within an optional time window. Each entry aggregates trades with the same price and side.",
|
|
3022
|
-
inputSchema:
|
|
4819
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), limit: limitDefault.default(500), startTime: startTime2, endTime: endTime2 }),
|
|
3023
4820
|
handler: async ({ symbol: symbol3, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await m.aggTrades(normalizeSymbol(symbol3), { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
|
|
3024
4821
|
},
|
|
3025
4822
|
{
|
|
3026
4823
|
name: "futures_klines",
|
|
3027
4824
|
description: "Get candlestick (OHLCV) data for a symbol. Intervals: 1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,1M. Max 1500 per request.",
|
|
3028
|
-
inputSchema:
|
|
4825
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), interval: KlineIntervalSchema, limit: limitDefault.default(500), startTime: startTime2, endTime: endTime2 }),
|
|
3029
4826
|
handler: async ({ symbol: symbol3, interval, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await m.klines(normalizeSymbol(symbol3), interval, { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
|
|
3030
4827
|
},
|
|
3031
4828
|
{
|
|
3032
4829
|
name: "futures_continuous_klines",
|
|
3033
4830
|
description: "Get klines for a continuous contract (perpetual, current_quarter, next_quarter) identified by base pair (e.g. BTCUSDT).",
|
|
3034
|
-
inputSchema:
|
|
3035
|
-
symbol:
|
|
4831
|
+
inputSchema: z15.object({
|
|
4832
|
+
symbol: z15.string().min(1).describe("Base pair, e.g. BTCUSDT"),
|
|
3036
4833
|
contractType,
|
|
3037
4834
|
interval: KlineIntervalSchema,
|
|
3038
4835
|
limit: limitDefault.default(500),
|
|
@@ -3044,80 +4841,80 @@ function marketDataTools(client) {
|
|
|
3044
4841
|
{
|
|
3045
4842
|
name: "futures_index_price_klines",
|
|
3046
4843
|
description: "Get index price candlesticks for a pair (e.g. BTCUSDT index).",
|
|
3047
|
-
inputSchema:
|
|
4844
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("Base pair, e.g. BTCUSDT"), interval: KlineIntervalSchema, limit: limitDefault.default(500), startTime: startTime2, endTime: endTime2 }),
|
|
3048
4845
|
handler: async ({ symbol: symbol3, interval, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await m.indexPriceKlines(normalizeSymbol(symbol3), interval, { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
|
|
3049
4846
|
},
|
|
3050
4847
|
{
|
|
3051
4848
|
name: "futures_mark_price_klines",
|
|
3052
4849
|
description: "Get mark price candlesticks for a symbol.",
|
|
3053
|
-
inputSchema:
|
|
4850
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), interval: KlineIntervalSchema, limit: limitDefault.default(500), startTime: startTime2, endTime: endTime2 }),
|
|
3054
4851
|
handler: async ({ symbol: symbol3, interval, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await m.markPriceKlines(normalizeSymbol(symbol3), interval, { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
|
|
3055
4852
|
},
|
|
3056
4853
|
{
|
|
3057
4854
|
name: "futures_trading_day_ticker",
|
|
3058
4855
|
description: "Get the trading-day ticker (v1: rolling window stats by symbol, including open, close, high, low, volume, closeTime).",
|
|
3059
|
-
inputSchema:
|
|
4856
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT") }),
|
|
3060
4857
|
handler: async ({ symbol: symbol3 }) => textResult(await m.tradingDayTicker(normalizeSymbol(symbol3)))
|
|
3061
4858
|
},
|
|
3062
4859
|
{
|
|
3063
4860
|
name: "futures_mark_price",
|
|
3064
4861
|
description: "Get mark price, index price, estimated settle price, last funding rate, next funding time and interest rate for a symbol.",
|
|
3065
|
-
inputSchema:
|
|
4862
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT") }),
|
|
3066
4863
|
handler: async ({ symbol: symbol3 }) => textResult(await d.premiumIndex(normalizeSymbol(symbol3)))
|
|
3067
4864
|
},
|
|
3068
4865
|
{
|
|
3069
4866
|
name: "futures_funding_rate_history",
|
|
3070
4867
|
description: "Get historical funding rates for a symbol.",
|
|
3071
|
-
inputSchema:
|
|
4868
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), limit: limitDefault.default(100), startTime: startTime2, endTime: endTime2 }),
|
|
3072
4869
|
handler: async ({ symbol: symbol3, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await d.fundingRateHistory(normalizeSymbol(symbol3), { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
|
|
3073
4870
|
},
|
|
3074
4871
|
{
|
|
3075
4872
|
name: "futures_funding_info",
|
|
3076
4873
|
description: "Get funding rate configuration for all symbols with adjusted funding cap/floor or interval (e.g. under extreme volatility).",
|
|
3077
|
-
inputSchema:
|
|
4874
|
+
inputSchema: z15.object({}),
|
|
3078
4875
|
handler: async () => textResult(await d.fundingInfo())
|
|
3079
4876
|
},
|
|
3080
4877
|
{
|
|
3081
4878
|
name: "futures_open_interest",
|
|
3082
4879
|
description: "Get the current total open interest for a symbol.",
|
|
3083
|
-
inputSchema:
|
|
4880
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT") }),
|
|
3084
4881
|
handler: async ({ symbol: symbol3 }) => textResult(await d.openInterest(normalizeSymbol(symbol3)))
|
|
3085
4882
|
},
|
|
3086
4883
|
{
|
|
3087
4884
|
name: "futures_open_interest_hist",
|
|
3088
4885
|
description: "Get historical open interest statistics per period.",
|
|
3089
|
-
inputSchema:
|
|
4886
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), period, limit: limitDefault.default(30) }),
|
|
3090
4887
|
handler: async ({ symbol: symbol3, period: period2, limit: limit4 }) => textResult(await d.openInterestHist(normalizeSymbol(symbol3), period2, Number(limit4)))
|
|
3091
4888
|
},
|
|
3092
4889
|
{
|
|
3093
4890
|
name: "futures_top_long_short_account_ratio",
|
|
3094
4891
|
description: "Get top trader long/short account ratio (number of accounts) for a symbol.",
|
|
3095
|
-
inputSchema:
|
|
4892
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), period, limit: limitDefault.default(30) }),
|
|
3096
4893
|
handler: async ({ symbol: symbol3, period: period2, limit: limit4 }) => textResult(await d.topLongShortAccountRatio(normalizeSymbol(symbol3), period2, Number(limit4)))
|
|
3097
4894
|
},
|
|
3098
4895
|
{
|
|
3099
4896
|
name: "futures_top_long_short_position_ratio",
|
|
3100
4897
|
description: "Get top trader long/short position ratio (accounts with net positions) for a symbol.",
|
|
3101
|
-
inputSchema:
|
|
4898
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), period, limit: limitDefault.default(30) }),
|
|
3102
4899
|
handler: async ({ symbol: symbol3, period: period2, limit: limit4 }) => textResult(await d.topLongShortPositionRatio(normalizeSymbol(symbol3), period2, Number(limit4)))
|
|
3103
4900
|
},
|
|
3104
4901
|
{
|
|
3105
4902
|
name: "futures_global_long_short_ratio",
|
|
3106
4903
|
description: "Get global long/short account ratio for a symbol (all accounts).",
|
|
3107
|
-
inputSchema:
|
|
4904
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), period, limit: limitDefault.default(30) }),
|
|
3108
4905
|
handler: async ({ symbol: symbol3, period: period2, limit: limit4 }) => textResult(await d.globalLongShortAccountRatio(normalizeSymbol(symbol3), period2, Number(limit4)))
|
|
3109
4906
|
},
|
|
3110
4907
|
{
|
|
3111
4908
|
name: "futures_taker_long_short_ratio",
|
|
3112
4909
|
description: "Get taker buy/sell volume ratio for a symbol.",
|
|
3113
|
-
inputSchema:
|
|
4910
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), period, limit: limitDefault.default(30) }),
|
|
3114
4911
|
handler: async ({ symbol: symbol3, period: period2, limit: limit4 }) => textResult(await d.takerLongShortRatio(normalizeSymbol(symbol3), period2, Number(limit4)))
|
|
3115
4912
|
},
|
|
3116
4913
|
{
|
|
3117
4914
|
name: "futures_basis",
|
|
3118
4915
|
description: "Get basis data (spot-futures spread, mark price - index price) for a pair and contract type.",
|
|
3119
|
-
inputSchema:
|
|
3120
|
-
symbol:
|
|
4916
|
+
inputSchema: z15.object({
|
|
4917
|
+
symbol: z15.string().min(1).describe("Base pair, e.g. BTCUSDT"),
|
|
3121
4918
|
period,
|
|
3122
4919
|
limit: limitDefault.default(30),
|
|
3123
4920
|
startTime: startTime2,
|
|
@@ -3128,63 +4925,63 @@ function marketDataTools(client) {
|
|
|
3128
4925
|
{
|
|
3129
4926
|
name: "futures_asset_index",
|
|
3130
4927
|
description: "Get multi-assets mode asset index (collateral price) for one asset or all assets.",
|
|
3131
|
-
inputSchema:
|
|
4928
|
+
inputSchema: z15.object({ symbol: optSymbol.describe("Asset index symbol, e.g. ADAUSD") }),
|
|
3132
4929
|
handler: async ({ symbol: symbol3 }) => textResult(await d.assetIndex(symbol3 ? normalizeSymbol(symbol3) : void 0))
|
|
3133
4930
|
},
|
|
3134
4931
|
{
|
|
3135
4932
|
name: "futures_composite_index_info",
|
|
3136
4933
|
description: "Get composite index symbol information (e.g. DEFIUSDT) with constituent weights.",
|
|
3137
|
-
inputSchema:
|
|
4934
|
+
inputSchema: z15.object({ symbol: optSymbol }),
|
|
3138
4935
|
handler: async ({ symbol: symbol3 }) => textResult(await d.compositeIndexInfo(symbol3 ? normalizeSymbol(symbol3) : void 0))
|
|
3139
4936
|
},
|
|
3140
4937
|
{
|
|
3141
4938
|
name: "futures_insurance_balance",
|
|
3142
4939
|
description: "Get insurance fund balance snapshots for a symbol.",
|
|
3143
|
-
inputSchema:
|
|
4940
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BNBUSDT"), limit: limitDefault.default(100), startTime: startTime2, endTime: endTime2 }),
|
|
3144
4941
|
handler: async ({ symbol: symbol3, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await d.insuranceFundBalance({ symbol: normalizeSymbol(symbol3), limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
|
|
3145
4942
|
},
|
|
3146
4943
|
{
|
|
3147
4944
|
name: "futures_index_price_constituents",
|
|
3148
4945
|
description: "Get the index price constituents (exchange weights) for a symbol.",
|
|
3149
|
-
inputSchema:
|
|
4946
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT") }),
|
|
3150
4947
|
handler: async ({ symbol: symbol3 }) => textResult(await d.indexPriceConstituents(normalizeSymbol(symbol3)))
|
|
3151
4948
|
},
|
|
3152
4949
|
{
|
|
3153
4950
|
name: "futures_premium_index_klines",
|
|
3154
4951
|
description: "Get premium index candlesticks for a symbol (mark price premium over index price).",
|
|
3155
|
-
inputSchema:
|
|
4952
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), interval: KlineIntervalSchema, limit: limitDefault.default(500), startTime: startTime2, endTime: endTime2 }),
|
|
3156
4953
|
handler: async ({ symbol: symbol3, interval, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await m.premiumIndexKlines(normalizeSymbol(symbol3), interval, { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
|
|
3157
4954
|
},
|
|
3158
4955
|
{
|
|
3159
4956
|
name: "futures_rpi_depth",
|
|
3160
4957
|
description: "Get the RPI (Retail Price Improvement) order book depth for a symbol.",
|
|
3161
|
-
inputSchema:
|
|
4958
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), limit: z15.number().int().positive().default(1e3) }),
|
|
3162
4959
|
handler: async ({ symbol: symbol3, limit: limit4 }) => textResult(await m.rpiDepth(normalizeSymbol(symbol3), Number(limit4)))
|
|
3163
4960
|
},
|
|
3164
4961
|
{
|
|
3165
4962
|
name: "futures_delivery_price",
|
|
3166
4963
|
description: "Get historical quarterly contract settlement/delivery prices for a pair.",
|
|
3167
|
-
inputSchema:
|
|
4964
|
+
inputSchema: z15.object({ symbol: z15.string().min(1).describe("Base pair, e.g. BTCUSDT") }),
|
|
3168
4965
|
handler: async ({ symbol: symbol3 }) => textResult(await d.deliveryPrice(normalizeSymbol(symbol3)))
|
|
3169
4966
|
},
|
|
3170
4967
|
{
|
|
3171
4968
|
name: "futures_symbol_adl_risk",
|
|
3172
4969
|
description: "Get the auto-deleveraging (ADL) risk level for one symbol or all symbols on the account (signed).",
|
|
3173
|
-
inputSchema:
|
|
4970
|
+
inputSchema: z15.object({ symbol: optSymbol }),
|
|
3174
4971
|
handler: async ({ symbol: symbol3 }) => textResult(await d.symbolAdlRisk(symbol3 ? normalizeSymbol(symbol3) : void 0))
|
|
3175
4972
|
},
|
|
3176
4973
|
{
|
|
3177
4974
|
name: "futures_adl_quantile",
|
|
3178
4975
|
description: "Get the position ADL (auto-deleveraging) quantile estimation for one symbol or all symbols (signed).",
|
|
3179
|
-
inputSchema:
|
|
4976
|
+
inputSchema: z15.object({ symbol: optSymbol }),
|
|
3180
4977
|
handler: async ({ symbol: symbol3 }) => textResult(await d.adlQuantile(symbol3 ? normalizeSymbol(symbol3) : void 0))
|
|
3181
4978
|
},
|
|
3182
4979
|
{
|
|
3183
4980
|
name: "futures_force_orders",
|
|
3184
4981
|
description: "Get the user's force-liquidation orders (LIQUIDATION) and ADL orders for a symbol or all symbols (signed).",
|
|
3185
|
-
inputSchema:
|
|
4982
|
+
inputSchema: z15.object({
|
|
3186
4983
|
symbol: optSymbol,
|
|
3187
|
-
autoCloseType:
|
|
4984
|
+
autoCloseType: z15.enum(["LIQUIDATION", "ADL"]).optional(),
|
|
3188
4985
|
startTime: startTime2,
|
|
3189
4986
|
endTime: endTime2,
|
|
3190
4987
|
limit: limitDefault.default(50)
|
|
@@ -3204,7 +5001,7 @@ function marketDataTools(client) {
|
|
|
3204
5001
|
}
|
|
3205
5002
|
|
|
3206
5003
|
// src/tools/paper.tools.ts
|
|
3207
|
-
import { z as
|
|
5004
|
+
import { z as z16 } from "zod";
|
|
3208
5005
|
function createPaperContext(client, initialState = {}) {
|
|
3209
5006
|
return {
|
|
3210
5007
|
client,
|
|
@@ -3222,7 +5019,7 @@ function paperTools(ctx) {
|
|
|
3222
5019
|
{
|
|
3223
5020
|
name: "paper_init",
|
|
3224
5021
|
description: "Initialize paper-trading state (reset balances, positions, history). No API keys required.",
|
|
3225
|
-
inputSchema:
|
|
5022
|
+
inputSchema: z16.object({ balance: z16.number().positive().default(1e4).describe("Starting USDT balance") }),
|
|
3226
5023
|
handler: async ({ balance }) => {
|
|
3227
5024
|
s.balance = balance;
|
|
3228
5025
|
s.positions = [];
|
|
@@ -3233,17 +5030,17 @@ function paperTools(ctx) {
|
|
|
3233
5030
|
{
|
|
3234
5031
|
name: "paper_balance",
|
|
3235
5032
|
description: "Get current paper-trading balance and open-position equity (uses live market prices if an open position exists). No API keys required.",
|
|
3236
|
-
inputSchema:
|
|
5033
|
+
inputSchema: z16.object({}),
|
|
3237
5034
|
handler: async () => textResult(s)
|
|
3238
5035
|
},
|
|
3239
5036
|
{
|
|
3240
5037
|
name: "paper_open_position",
|
|
3241
5038
|
description: "Open an in-memory paper position at the live ticker price (or a fixed price). No API keys required.",
|
|
3242
|
-
inputSchema:
|
|
3243
|
-
symbol:
|
|
3244
|
-
side:
|
|
3245
|
-
quantity:
|
|
3246
|
-
price:
|
|
5039
|
+
inputSchema: z16.object({
|
|
5040
|
+
symbol: z16.string().min(1).describe("USD-M pair, e.g. BTCUSDT"),
|
|
5041
|
+
side: z16.enum(["LONG", "SHORT"]),
|
|
5042
|
+
quantity: z16.number().positive(),
|
|
5043
|
+
price: z16.number().positive().optional().describe("If omitted, uses live ticker price")
|
|
3247
5044
|
}),
|
|
3248
5045
|
handler: async ({ symbol: symbol3, side: side3, quantity, price }) => {
|
|
3249
5046
|
const sym = normalizeSymbol(symbol3);
|
|
@@ -3257,10 +5054,10 @@ function paperTools(ctx) {
|
|
|
3257
5054
|
{
|
|
3258
5055
|
name: "paper_close_position",
|
|
3259
5056
|
description: "Close a paper position by id (or symbol) and realize PnL at the live/last price.",
|
|
3260
|
-
inputSchema:
|
|
3261
|
-
id:
|
|
3262
|
-
symbol:
|
|
3263
|
-
price:
|
|
5057
|
+
inputSchema: z16.object({
|
|
5058
|
+
id: z16.string().optional().describe("Position id from paper_open_position"),
|
|
5059
|
+
symbol: z16.string().min(1).optional().describe("Close the position for this symbol"),
|
|
5060
|
+
price: z16.number().positive().optional().describe("If omitted, uses live ticker price")
|
|
3264
5061
|
}),
|
|
3265
5062
|
handler: async ({ id, symbol: symbol3, price }) => {
|
|
3266
5063
|
const idx = s.positions.findIndex((p) => id ? p.id === id : normalizeSymbol(p.symbol) === normalizeSymbol(symbol3 ?? ""));
|
|
@@ -3278,7 +5075,7 @@ function paperTools(ctx) {
|
|
|
3278
5075
|
{
|
|
3279
5076
|
name: "paper_positions",
|
|
3280
5077
|
description: "List open paper positions with live unrealized PnL (marked to market).",
|
|
3281
|
-
inputSchema:
|
|
5078
|
+
inputSchema: z16.object({}),
|
|
3282
5079
|
handler: async () => {
|
|
3283
5080
|
const out = await Promise.all(
|
|
3284
5081
|
s.positions.map(async (p) => {
|
|
@@ -3292,39 +5089,39 @@ function paperTools(ctx) {
|
|
|
3292
5089
|
{
|
|
3293
5090
|
name: "paper_history",
|
|
3294
5091
|
description: "List paper-trading history of open/close events with realized PnL.",
|
|
3295
|
-
inputSchema:
|
|
5092
|
+
inputSchema: z16.object({}),
|
|
3296
5093
|
handler: async () => textResult(s.history)
|
|
3297
5094
|
},
|
|
3298
5095
|
{
|
|
3299
5096
|
name: "paper_summary",
|
|
3300
5097
|
description: "Summarize paper-trading state: balance, open positions, trade count.",
|
|
3301
|
-
inputSchema:
|
|
5098
|
+
inputSchema: z16.object({}),
|
|
3302
5099
|
handler: async () => textResult({ balance: s.balance, openPositions: s.positions.length, trades: s.history.length })
|
|
3303
5100
|
}
|
|
3304
5101
|
];
|
|
3305
5102
|
}
|
|
3306
5103
|
|
|
3307
5104
|
// src/tools/spot.tools.ts
|
|
3308
|
-
import { z as
|
|
3309
|
-
var spotSymbol =
|
|
3310
|
-
var optionalSymbol2 =
|
|
3311
|
-
var limit2 =
|
|
3312
|
-
var startTime3 =
|
|
3313
|
-
var endTime3 =
|
|
3314
|
-
var side =
|
|
3315
|
-
var spotOrderParamsSchema =
|
|
5105
|
+
import { z as z17 } from "zod";
|
|
5106
|
+
var spotSymbol = z17.string().min(1).describe("Spot pair, e.g. BTCUSDT");
|
|
5107
|
+
var optionalSymbol2 = z17.string().min(1).describe("Spot pair, e.g. BTCUSDT").optional();
|
|
5108
|
+
var limit2 = z17.number().int().positive().max(1e3).default(100);
|
|
5109
|
+
var startTime3 = z17.number().int().positive().optional();
|
|
5110
|
+
var endTime3 = z17.number().int().positive().optional();
|
|
5111
|
+
var side = z17.enum(["BUY", "SELL"]);
|
|
5112
|
+
var spotOrderParamsSchema = z17.object({
|
|
3316
5113
|
symbol: spotSymbol,
|
|
3317
5114
|
side,
|
|
3318
|
-
type:
|
|
3319
|
-
quantity:
|
|
3320
|
-
quoteOrderQty:
|
|
3321
|
-
price:
|
|
3322
|
-
stopPrice:
|
|
3323
|
-
timeInForce:
|
|
3324
|
-
newClientOrderId:
|
|
3325
|
-
newOrderRespType:
|
|
3326
|
-
icebergQty:
|
|
3327
|
-
selfTradePreventionMode:
|
|
5115
|
+
type: z17.enum(["LIMIT", "MARKET", "LIMIT_MAKER", "STOP_LOSS", "STOP_LOSS_LIMIT", "TAKE_PROFIT", "TAKE_PROFIT_LIMIT"]),
|
|
5116
|
+
quantity: z17.union([z17.string(), z17.number()]).optional().describe("Base-asset quantity; omit if using quoteOrderQty"),
|
|
5117
|
+
quoteOrderQty: z17.union([z17.string(), z17.number()]).optional().describe("Quote-asset quantity (e.g. spend 100 USDT on a MARKET order)"),
|
|
5118
|
+
price: z17.union([z17.string(), z17.number()]).optional().describe("Required for LIMIT / STOP_LOSS_LIMIT / TAKE_PROFIT_LIMIT"),
|
|
5119
|
+
stopPrice: z17.union([z17.string(), z17.number()]).optional().describe("Trigger price for STOP_LOSS / TAKE_PROFIT variants"),
|
|
5120
|
+
timeInForce: z17.enum(["GTC", "IOC", "FOK"]).optional().describe("Required for LIMIT"),
|
|
5121
|
+
newClientOrderId: z17.string().optional(),
|
|
5122
|
+
newOrderRespType: z17.enum(["ACK", "RESULT", "FULL"]).optional(),
|
|
5123
|
+
icebergQty: z17.union([z17.string(), z17.number()]).optional(),
|
|
5124
|
+
selfTradePreventionMode: z17.enum(["NONE", "EXPIRE_TAKER", "EXPIRE_MAKER", "EXPIRE_BOTH"]).optional()
|
|
3328
5125
|
});
|
|
3329
5126
|
function spotTools(client) {
|
|
3330
5127
|
const m = client.spot.market;
|
|
@@ -3335,128 +5132,128 @@ function spotTools(client) {
|
|
|
3335
5132
|
{
|
|
3336
5133
|
name: "spot_ping",
|
|
3337
5134
|
description: "Test connectivity to the Binance Spot REST API.",
|
|
3338
|
-
inputSchema:
|
|
5135
|
+
inputSchema: z17.object({}),
|
|
3339
5136
|
handler: async () => textResult(await m.ping())
|
|
3340
5137
|
},
|
|
3341
5138
|
{
|
|
3342
5139
|
name: "spot_server_time",
|
|
3343
5140
|
description: "Get the current Binance Spot server time in ms since epoch.",
|
|
3344
|
-
inputSchema:
|
|
5141
|
+
inputSchema: z17.object({}),
|
|
3345
5142
|
handler: async () => textResult(await m.serverTime())
|
|
3346
5143
|
},
|
|
3347
5144
|
{
|
|
3348
5145
|
name: "spot_exchange_info",
|
|
3349
5146
|
description: "Get Spot exchange trading rules and symbol metadata (status, base/quote assets, filters, permissions).",
|
|
3350
|
-
inputSchema:
|
|
5147
|
+
inputSchema: z17.object({}),
|
|
3351
5148
|
handler: async () => textResult(await m.exchangeInfo())
|
|
3352
5149
|
},
|
|
3353
5150
|
{
|
|
3354
5151
|
name: "spot_ticker_price",
|
|
3355
5152
|
description: "Get the latest price for a Spot symbol.",
|
|
3356
|
-
inputSchema:
|
|
5153
|
+
inputSchema: z17.object({ symbol: spotSymbol }),
|
|
3357
5154
|
handler: async ({ symbol: symbol3 }) => textResult(await m.tickerPrice(normalizeSymbol(symbol3)))
|
|
3358
5155
|
},
|
|
3359
5156
|
{
|
|
3360
5157
|
name: "spot_ticker_24hr",
|
|
3361
5158
|
description: "Get 24-hour rolling price change statistics for a Spot symbol.",
|
|
3362
|
-
inputSchema:
|
|
5159
|
+
inputSchema: z17.object({ symbol: spotSymbol }),
|
|
3363
5160
|
handler: async ({ symbol: symbol3 }) => textResult(await m.ticker24hr(normalizeSymbol(symbol3)))
|
|
3364
5161
|
},
|
|
3365
5162
|
{
|
|
3366
5163
|
name: "spot_book_ticker",
|
|
3367
5164
|
description: "Get the best bid/ask (top of book) for a Spot symbol.",
|
|
3368
|
-
inputSchema:
|
|
5165
|
+
inputSchema: z17.object({ symbol: spotSymbol }),
|
|
3369
5166
|
handler: async ({ symbol: symbol3 }) => textResult(await m.bookTicker(normalizeSymbol(symbol3)))
|
|
3370
5167
|
},
|
|
3371
5168
|
{
|
|
3372
5169
|
name: "spot_order_book",
|
|
3373
5170
|
description: "Get the Spot order book depth for a symbol (limits 5/10/20/50/100/500/1000/5000).",
|
|
3374
|
-
inputSchema:
|
|
5171
|
+
inputSchema: z17.object({
|
|
3375
5172
|
symbol: spotSymbol,
|
|
3376
|
-
limit:
|
|
5173
|
+
limit: z17.enum(["5", "10", "20", "50", "100", "500", "1000", "5000"]).default("100")
|
|
3377
5174
|
}),
|
|
3378
5175
|
handler: async ({ symbol: symbol3, limit: limit4 }) => textResult(await m.depth(normalizeSymbol(symbol3), Number(limit4)))
|
|
3379
5176
|
},
|
|
3380
5177
|
{
|
|
3381
5178
|
name: "spot_recent_trades",
|
|
3382
5179
|
description: "Get the most recent executed trades for a Spot symbol.",
|
|
3383
|
-
inputSchema:
|
|
5180
|
+
inputSchema: z17.object({ symbol: spotSymbol, limit: limit2.default(500) }),
|
|
3384
5181
|
handler: async ({ symbol: symbol3, limit: limit4 }) => textResult(await m.trades(normalizeSymbol(symbol3), Number(limit4)))
|
|
3385
5182
|
},
|
|
3386
5183
|
{
|
|
3387
5184
|
name: "spot_historical_trades",
|
|
3388
5185
|
description: "Get older Spot trades for a symbol by fromId.",
|
|
3389
|
-
inputSchema:
|
|
5186
|
+
inputSchema: z17.object({ symbol: spotSymbol, limit: limit2.default(500), fromId: z17.number().int().positive().optional() }),
|
|
3390
5187
|
handler: async ({ symbol: symbol3, limit: limit4, fromId }) => textResult(await m.historicalTrades(normalizeSymbol(symbol3), { limit: Number(limit4), fromId }))
|
|
3391
5188
|
},
|
|
3392
5189
|
{
|
|
3393
5190
|
name: "spot_agg_trades",
|
|
3394
5191
|
description: "Get compressed/aggregate Spot trades for a symbol within an optional time window.",
|
|
3395
|
-
inputSchema:
|
|
5192
|
+
inputSchema: z17.object({ symbol: spotSymbol, limit: limit2.default(500), startTime: startTime3, endTime: endTime3 }),
|
|
3396
5193
|
handler: async ({ symbol: symbol3, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await m.aggTrades(normalizeSymbol(symbol3), { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
|
|
3397
5194
|
},
|
|
3398
5195
|
{
|
|
3399
5196
|
name: "spot_klines",
|
|
3400
5197
|
description: "Get Spot candlesticks (OHLCV). Intervals 1m\u20261M; max 1000 per request.",
|
|
3401
|
-
inputSchema:
|
|
5198
|
+
inputSchema: z17.object({ symbol: spotSymbol, interval: KlineIntervalSchema, limit: limit2.default(500), startTime: startTime3, endTime: endTime3 }),
|
|
3402
5199
|
handler: async ({ symbol: symbol3, interval, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await m.klines(normalizeSymbol(symbol3), interval, { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
|
|
3403
5200
|
},
|
|
3404
5201
|
{
|
|
3405
5202
|
name: "spot_ui_klines",
|
|
3406
5203
|
description: "Get Spot candlesticks via the optimized uiKlines endpoint (same shape as spot_klines).",
|
|
3407
|
-
inputSchema:
|
|
5204
|
+
inputSchema: z17.object({ symbol: spotSymbol, interval: KlineIntervalSchema, limit: limit2.default(500), startTime: startTime3, endTime: endTime3 }),
|
|
3408
5205
|
handler: async ({ symbol: symbol3, interval, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await m.uiKlines(normalizeSymbol(symbol3), interval, { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
|
|
3409
5206
|
},
|
|
3410
5207
|
{
|
|
3411
5208
|
name: "spot_avg_price",
|
|
3412
5209
|
description: "Get the current average price (5-minute rolling average) for a Spot symbol.",
|
|
3413
|
-
inputSchema:
|
|
5210
|
+
inputSchema: z17.object({ symbol: spotSymbol }),
|
|
3414
5211
|
handler: async ({ symbol: symbol3 }) => textResult(await m.avgPrice(normalizeSymbol(symbol3)))
|
|
3415
5212
|
},
|
|
3416
5213
|
{
|
|
3417
5214
|
name: "spot_rolling_window_ticker",
|
|
3418
5215
|
description: "Get rolling-window price change statistics (1d/7d/30d). Omit symbol for all symbols.",
|
|
3419
|
-
inputSchema:
|
|
5216
|
+
inputSchema: z17.object({
|
|
3420
5217
|
symbol: optionalSymbol2,
|
|
3421
|
-
windowSize:
|
|
5218
|
+
windowSize: z17.enum(["1d", "7d", "30d"]).optional()
|
|
3422
5219
|
}),
|
|
3423
5220
|
handler: async ({ symbol: symbol3, windowSize }) => textResult(await m.rollingWindowTicker(symbol3 ? normalizeSymbol(symbol3) : void 0, windowSize))
|
|
3424
5221
|
},
|
|
3425
5222
|
{
|
|
3426
5223
|
name: "spot_trading_day_ticker",
|
|
3427
5224
|
description: "Get the Spot trading-day ticker (open/close/high/low/volume by UTC day). Omit symbol for all symbols.",
|
|
3428
|
-
inputSchema:
|
|
5225
|
+
inputSchema: z17.object({ symbol: optionalSymbol2, timeZone: z17.string().optional(), type: z17.enum(["FULL", "MINI"]).optional() }),
|
|
3429
5226
|
handler: async ({ symbol: symbol3, timeZone, type }) => textResult(await m.tradingDayTicker(symbol3 ? normalizeSymbol(symbol3) : void 0, { timeZone, type }))
|
|
3430
5227
|
},
|
|
3431
5228
|
// ---- Account (signed) ----
|
|
3432
5229
|
{
|
|
3433
5230
|
name: "spot_account",
|
|
3434
5231
|
description: "Get the Spot account: balances (free/locked), commissions, permissions (signed).",
|
|
3435
|
-
inputSchema:
|
|
5232
|
+
inputSchema: z17.object({}),
|
|
3436
5233
|
handler: async () => textResult(await a.account())
|
|
3437
5234
|
},
|
|
3438
5235
|
{
|
|
3439
5236
|
name: "spot_my_trades",
|
|
3440
5237
|
description: "Get the Spot account trade list (filled trades) for a symbol with optional time range (signed).",
|
|
3441
|
-
inputSchema:
|
|
5238
|
+
inputSchema: z17.object({ symbol: spotSymbol, orderId: z17.number().int().positive().optional(), startTime: startTime3, endTime: endTime3, fromId: z17.number().int().positive().optional(), limit: limit2.default(500) }),
|
|
3442
5239
|
handler: async ({ symbol: symbol3, orderId, startTime: startTime5, endTime: endTime5, fromId, limit: limit4 }) => textResult(await a.myTrades(normalizeSymbol(symbol3), { orderId, startTime: startTime5, endTime: endTime5, fromId, limit: Number(limit4) }))
|
|
3443
5240
|
},
|
|
3444
5241
|
{
|
|
3445
5242
|
name: "spot_my_prevented_matches",
|
|
3446
5243
|
description: "Get Spot orders that were expired by the self-trade-prevention (STP) mechanism (signed).",
|
|
3447
|
-
inputSchema:
|
|
5244
|
+
inputSchema: z17.object({ symbol: spotSymbol, preventedMatchId: z17.number().int().positive().optional(), orderId: z17.number().int().positive().optional(), limit: limit2.default(500) }),
|
|
3448
5245
|
handler: async ({ symbol: symbol3, preventedMatchId, orderId, limit: limit4 }) => textResult(await a.myPreventedMatches(normalizeSymbol(symbol3), { preventedMatchId, orderId, limit: Number(limit4) }))
|
|
3449
5246
|
},
|
|
3450
5247
|
{
|
|
3451
5248
|
name: "spot_account_commission",
|
|
3452
5249
|
description: "Get the Spot account commission rates for a symbol (signed).",
|
|
3453
|
-
inputSchema:
|
|
5250
|
+
inputSchema: z17.object({ symbol: spotSymbol }),
|
|
3454
5251
|
handler: async ({ symbol: symbol3 }) => textResult(await a.accountCommission(normalizeSymbol(symbol3)))
|
|
3455
5252
|
},
|
|
3456
5253
|
{
|
|
3457
5254
|
name: "spot_rate_limit_order",
|
|
3458
5255
|
description: "Query the current Spot order rate limit usage (signed).",
|
|
3459
|
-
inputSchema:
|
|
5256
|
+
inputSchema: z17.object({}),
|
|
3460
5257
|
handler: async () => textResult(await a.rateLimitOrder())
|
|
3461
5258
|
},
|
|
3462
5259
|
// ---- Trading (signed) ----
|
|
@@ -3475,109 +5272,109 @@ function spotTools(client) {
|
|
|
3475
5272
|
{
|
|
3476
5273
|
name: "spot_get_order",
|
|
3477
5274
|
description: "Query a specific Spot order by orderId or client order id. Signed.",
|
|
3478
|
-
inputSchema:
|
|
5275
|
+
inputSchema: z17.object({ symbol: spotSymbol, orderId: z17.number().int().positive().optional(), origClientOrderId: z17.string().optional() }),
|
|
3479
5276
|
handler: async ({ symbol: symbol3, orderId, origClientOrderId }) => textResult(await t.getOrder(normalizeSymbol(symbol3), { orderId, origClientOrderId }))
|
|
3480
5277
|
},
|
|
3481
5278
|
{
|
|
3482
5279
|
name: "spot_cancel_order",
|
|
3483
5280
|
description: "Cancel a specific open Spot order by orderId or client order id. Signed.",
|
|
3484
|
-
inputSchema:
|
|
5281
|
+
inputSchema: z17.object({ symbol: spotSymbol, orderId: z17.number().int().positive().optional(), origClientOrderId: z17.string().optional(), newClientOrderId: z17.string().optional() }),
|
|
3485
5282
|
handler: async ({ symbol: symbol3, orderId, origClientOrderId, newClientOrderId }) => textResult(await t.cancelOrder(normalizeSymbol(symbol3), { orderId, origClientOrderId, newClientOrderId }))
|
|
3486
5283
|
},
|
|
3487
5284
|
{
|
|
3488
5285
|
name: "spot_open_orders",
|
|
3489
5286
|
description: "Get all current open Spot orders, for one symbol or all symbols. Signed.",
|
|
3490
|
-
inputSchema:
|
|
5287
|
+
inputSchema: z17.object({ symbol: optionalSymbol2 }),
|
|
3491
5288
|
handler: async ({ symbol: symbol3 }) => textResult(await t.getOpenOrders(symbol3 ? normalizeSymbol(symbol3) : void 0))
|
|
3492
5289
|
},
|
|
3493
5290
|
{
|
|
3494
5291
|
name: "spot_all_orders",
|
|
3495
5292
|
description: "Get historical Spot orders for a symbol with optional time range. Signed.",
|
|
3496
|
-
inputSchema:
|
|
5293
|
+
inputSchema: z17.object({ symbol: spotSymbol, orderId: z17.number().int().positive().optional(), startTime: startTime3, endTime: endTime3, limit: limit2 }),
|
|
3497
5294
|
handler: async ({ symbol: symbol3, orderId, startTime: startTime5, endTime: endTime5, limit: limit4 }) => textResult(await t.getAllOrders(normalizeSymbol(symbol3), { orderId, startTime: startTime5, endTime: endTime5, limit: limit4 }))
|
|
3498
5295
|
},
|
|
3499
5296
|
{
|
|
3500
5297
|
name: "spot_cancel_open_orders",
|
|
3501
5298
|
description: "Cancel all open Spot orders for a symbol. Signed.",
|
|
3502
|
-
inputSchema:
|
|
5299
|
+
inputSchema: z17.object({ symbol: spotSymbol }),
|
|
3503
5300
|
handler: async ({ symbol: symbol3 }) => textResult(await t.cancelOpenOrders(normalizeSymbol(symbol3)))
|
|
3504
5301
|
},
|
|
3505
5302
|
{
|
|
3506
5303
|
name: "spot_cancel_replace_order",
|
|
3507
5304
|
description: "Cancel an existing Spot order and place a new one on the same symbol (cancel-replace). Signed.",
|
|
3508
|
-
inputSchema:
|
|
5305
|
+
inputSchema: z17.object({
|
|
3509
5306
|
symbol: spotSymbol,
|
|
3510
5307
|
side,
|
|
3511
|
-
type:
|
|
3512
|
-
cancelReplaceMode:
|
|
3513
|
-
cancelOrderId:
|
|
3514
|
-
cancelOrigClientOrderId:
|
|
3515
|
-
cancelNewClientOrderId:
|
|
3516
|
-
quantity:
|
|
3517
|
-
price:
|
|
3518
|
-
timeInForce:
|
|
3519
|
-
newClientOrderId:
|
|
5308
|
+
type: z17.enum(["LIMIT", "MARKET", "STOP_LOSS", "STOP_LOSS_LIMIT", "TAKE_PROFIT", "TAKE_PROFIT_LIMIT"]),
|
|
5309
|
+
cancelReplaceMode: z17.enum(["STOP_ON_FAILURE", "ALLOW_FAILURE"]).default("STOP_ON_FAILURE"),
|
|
5310
|
+
cancelOrderId: z17.number().int().positive().optional(),
|
|
5311
|
+
cancelOrigClientOrderId: z17.string().optional(),
|
|
5312
|
+
cancelNewClientOrderId: z17.string().optional(),
|
|
5313
|
+
quantity: z17.union([z17.string(), z17.number()]).optional(),
|
|
5314
|
+
price: z17.union([z17.string(), z17.number()]).optional(),
|
|
5315
|
+
timeInForce: z17.enum(["GTC", "IOC", "FOK"]).optional(),
|
|
5316
|
+
newClientOrderId: z17.string().optional()
|
|
3520
5317
|
}),
|
|
3521
5318
|
handler: async (args) => textResult(await t.cancelReplaceOrder({ ...args, symbol: normalizeSymbol(args.symbol) }))
|
|
3522
5319
|
},
|
|
3523
5320
|
{
|
|
3524
5321
|
name: "spot_new_oco_order",
|
|
3525
5322
|
description: "Place a new Spot OCO (one-cancels-other) order: a stop-loss limit + a limit-maker take-profit. Signed.",
|
|
3526
|
-
inputSchema:
|
|
5323
|
+
inputSchema: z17.object({
|
|
3527
5324
|
symbol: spotSymbol,
|
|
3528
5325
|
side,
|
|
3529
|
-
quantity:
|
|
3530
|
-
price:
|
|
3531
|
-
stopPrice:
|
|
3532
|
-
stopLimitPrice:
|
|
3533
|
-
stopLimitTimeInForce:
|
|
3534
|
-
listClientOrderId:
|
|
3535
|
-
limitClientOrderId:
|
|
3536
|
-
stopClientOrderId:
|
|
5326
|
+
quantity: z17.union([z17.string(), z17.number()]).describe("Total base-asset quantity for both legs"),
|
|
5327
|
+
price: z17.union([z17.string(), z17.number()]).describe("Limit (take-profit) price"),
|
|
5328
|
+
stopPrice: z17.union([z17.string(), z17.number()]).describe("Stop-loss trigger price"),
|
|
5329
|
+
stopLimitPrice: z17.union([z17.string(), z17.number()]).optional().describe("Stop-loss limit price (defaults to stopPrice)"),
|
|
5330
|
+
stopLimitTimeInForce: z17.enum(["GTC", "IOC", "FOK"]).optional(),
|
|
5331
|
+
listClientOrderId: z17.string().optional(),
|
|
5332
|
+
limitClientOrderId: z17.string().optional(),
|
|
5333
|
+
stopClientOrderId: z17.string().optional()
|
|
3537
5334
|
}),
|
|
3538
5335
|
handler: async (args) => textResult(await t.createOCOOrder({ ...args, symbol: normalizeSymbol(args.symbol) }))
|
|
3539
5336
|
},
|
|
3540
5337
|
{
|
|
3541
5338
|
name: "spot_cancel_oco_order",
|
|
3542
5339
|
description: "Cancel an entire Spot OCO order list by orderListId or listClientOrderId. Signed.",
|
|
3543
|
-
inputSchema:
|
|
5340
|
+
inputSchema: z17.object({ symbol: spotSymbol, orderListId: z17.number().int().positive().optional(), listClientOrderId: z17.string().optional(), newClientOrderId: z17.string().optional() }),
|
|
3544
5341
|
handler: async ({ symbol: symbol3, orderListId, listClientOrderId, newClientOrderId }) => textResult(await t.cancelOCOOrder(normalizeSymbol(symbol3), { orderListId, listClientOrderId, newClientOrderId }))
|
|
3545
5342
|
},
|
|
3546
5343
|
{
|
|
3547
5344
|
name: "spot_get_oco_order",
|
|
3548
5345
|
description: "Query a Spot OCO order list by orderListId or listClientOrderId. Signed.",
|
|
3549
|
-
inputSchema:
|
|
5346
|
+
inputSchema: z17.object({ symbol: spotSymbol, orderListId: z17.number().int().positive().optional(), origClientOrderId: z17.string().optional() }),
|
|
3550
5347
|
handler: async ({ symbol: symbol3, orderListId, origClientOrderId }) => textResult(await t.getOCOOrder(normalizeSymbol(symbol3), { orderListId, origClientOrderId }))
|
|
3551
5348
|
},
|
|
3552
5349
|
{
|
|
3553
5350
|
name: "spot_open_oco_orders",
|
|
3554
5351
|
description: "Get all current open Spot OCO order lists. Signed.",
|
|
3555
|
-
inputSchema:
|
|
5352
|
+
inputSchema: z17.object({}),
|
|
3556
5353
|
handler: async () => textResult(await t.getOpenOCOOrders())
|
|
3557
5354
|
},
|
|
3558
5355
|
{
|
|
3559
5356
|
name: "spot_all_oco_orders",
|
|
3560
5357
|
description: "Get historical Spot OCO order lists for a symbol with optional time range. Signed.",
|
|
3561
|
-
inputSchema:
|
|
5358
|
+
inputSchema: z17.object({ symbol: spotSymbol, fromId: z17.number().int().positive().optional(), startTime: startTime3, endTime: endTime3, limit: limit2 }),
|
|
3562
5359
|
handler: async ({ symbol: symbol3, fromId, startTime: startTime5, endTime: endTime5, limit: limit4 }) => textResult(await t.getAllOCOOrders(normalizeSymbol(symbol3), { fromId, startTime: startTime5, endTime: endTime5, limit: limit4 }))
|
|
3563
5360
|
},
|
|
3564
5361
|
{
|
|
3565
5362
|
name: "spot_cancel_open_oco_orders",
|
|
3566
5363
|
description: "Cancel all open Spot OCO order lists for a symbol. Signed.",
|
|
3567
|
-
inputSchema:
|
|
5364
|
+
inputSchema: z17.object({ symbol: spotSymbol }),
|
|
3568
5365
|
handler: async ({ symbol: symbol3 }) => textResult(await t.cancelOpenOCOOrders(normalizeSymbol(symbol3)))
|
|
3569
5366
|
},
|
|
3570
5367
|
// ---- User data stream (signed) ----
|
|
3571
5368
|
{
|
|
3572
5369
|
name: "spot_ws_start_user_stream",
|
|
3573
5370
|
description: "Start the Spot user data stream: creates a listenKey, connects the private WebSocket, and begins keep-alive. Emits executionReport, outboundAccountPosition, balanceUpdate, listStatus.",
|
|
3574
|
-
inputSchema:
|
|
5371
|
+
inputSchema: z17.object({}),
|
|
3575
5372
|
handler: async () => textResult({ listenKey: await client.startSpotUserStream() })
|
|
3576
5373
|
},
|
|
3577
5374
|
{
|
|
3578
5375
|
name: "spot_ws_stop_user_stream",
|
|
3579
5376
|
description: "Stop the Spot user data stream: closes the private WebSocket and invalidates the listenKey.",
|
|
3580
|
-
inputSchema:
|
|
5377
|
+
inputSchema: z17.object({}),
|
|
3581
5378
|
handler: async () => {
|
|
3582
5379
|
client.closeSpotUserStream();
|
|
3583
5380
|
return textResult({ stopped: true });
|
|
@@ -3588,33 +5385,33 @@ function spotTools(client) {
|
|
|
3588
5385
|
}
|
|
3589
5386
|
|
|
3590
5387
|
// src/tools/trading.tools.ts
|
|
3591
|
-
import { z as
|
|
3592
|
-
var symbol2 =
|
|
3593
|
-
var optionalSymbol3 =
|
|
3594
|
-
var limit3 =
|
|
3595
|
-
var startTime4 =
|
|
3596
|
-
var endTime4 =
|
|
3597
|
-
var side2 =
|
|
3598
|
-
var positionSide =
|
|
3599
|
-
var orderParamsSchema =
|
|
5388
|
+
import { z as z18 } from "zod";
|
|
5389
|
+
var symbol2 = z18.string().min(1).describe("USD-M pair, e.g. BTCUSDT");
|
|
5390
|
+
var optionalSymbol3 = z18.string().min(1).describe("USD-M pair, e.g. BTCUSDT").optional();
|
|
5391
|
+
var limit3 = z18.number().int().positive().max(1e3).default(100);
|
|
5392
|
+
var startTime4 = z18.number().int().positive().optional();
|
|
5393
|
+
var endTime4 = z18.number().int().positive().optional();
|
|
5394
|
+
var side2 = z18.enum(["BUY", "SELL"]);
|
|
5395
|
+
var positionSide = z18.enum(["BOTH", "LONG", "SHORT"]).optional();
|
|
5396
|
+
var orderParamsSchema = z18.object({
|
|
3600
5397
|
symbol: symbol2,
|
|
3601
5398
|
side: side2,
|
|
3602
|
-
type:
|
|
3603
|
-
quantity:
|
|
3604
|
-
price:
|
|
3605
|
-
timeInForce:
|
|
3606
|
-
stopPrice:
|
|
3607
|
-
reduceOnly:
|
|
5399
|
+
type: z18.enum(["LIMIT", "MARKET", "STOP", "STOP_MARKET", "TAKE_PROFIT", "TAKE_PROFIT_MARKET", "TRAILING_STOP_MARKET"]),
|
|
5400
|
+
quantity: z18.union([z18.string(), z18.number()]).describe("Order quantity in base asset"),
|
|
5401
|
+
price: z18.union([z18.string(), z18.number()]).optional().describe("Required for LIMIT and STOP/TAKE_PROFIT (limit-triggered) types"),
|
|
5402
|
+
timeInForce: z18.enum(["GTC", "IOC", "FOK", "GTX"]).optional(),
|
|
5403
|
+
stopPrice: z18.union([z18.string(), z18.number()]).optional().describe("Trigger price for STOP/STOP_MARKET/TAKE_PROFIT/TAKE_PROFIT_MARKET"),
|
|
5404
|
+
reduceOnly: z18.boolean().optional().describe("true = only reduces the position, never opens"),
|
|
3608
5405
|
positionSide,
|
|
3609
|
-
newClientOrderId:
|
|
3610
|
-
closePosition:
|
|
3611
|
-
newOrderRespType:
|
|
3612
|
-
priceProtect:
|
|
3613
|
-
workingType:
|
|
3614
|
-
callbackRate:
|
|
3615
|
-
activationPrice:
|
|
3616
|
-
selfTradePreventionMode:
|
|
3617
|
-
goodTillDate:
|
|
5406
|
+
newClientOrderId: z18.string().optional(),
|
|
5407
|
+
closePosition: z18.boolean().optional().describe("Close the full position on trigger (mutually exclusive with quantity)"),
|
|
5408
|
+
newOrderRespType: z18.enum(["ACK", "RESULT"]).optional(),
|
|
5409
|
+
priceProtect: z18.boolean().optional(),
|
|
5410
|
+
workingType: z18.enum(["MARK_PRICE", "CONTRACT_PRICE"]).optional().describe("Trigger price basis; default CONTRACT_PRICE"),
|
|
5411
|
+
callbackRate: z18.union([z18.string(), z18.number()]).optional().describe("Percent callback for TRAILING_STOP_MARKET, e.g. 0.5"),
|
|
5412
|
+
activationPrice: z18.union([z18.string(), z18.number()]).optional().describe("Activation price for TRAILING_STOP_MARKET"),
|
|
5413
|
+
selfTradePreventionMode: z18.enum(["NONE", "EXPIRE_TAKER", "EXPIRE_MAKER", "EXPIRE_BOTH"]).optional(),
|
|
5414
|
+
goodTillDate: z18.number().int().optional().describe("Timestamp when a GTD order expires")
|
|
3618
5415
|
});
|
|
3619
5416
|
function tradingTools(client) {
|
|
3620
5417
|
const t = client.futures.trading;
|
|
@@ -3634,66 +5431,66 @@ function tradingTools(client) {
|
|
|
3634
5431
|
{
|
|
3635
5432
|
name: "futures_get_order",
|
|
3636
5433
|
description: "Query a specific order by orderId or client order id. Signed.",
|
|
3637
|
-
inputSchema:
|
|
5434
|
+
inputSchema: z18.object({ symbol: symbol2, orderId: z18.number().int().positive().optional(), origClientOrderId: z18.string().optional() }),
|
|
3638
5435
|
handler: async ({ symbol: symbol3, orderId, origClientOrderId }) => textResult(await t.getOrder(normalizeSymbol(symbol3), { orderId, origClientOrderId }))
|
|
3639
5436
|
},
|
|
3640
5437
|
{
|
|
3641
5438
|
name: "futures_cancel_order",
|
|
3642
5439
|
description: "Cancel a specific open order by orderId or client order id. Signed.",
|
|
3643
|
-
inputSchema:
|
|
5440
|
+
inputSchema: z18.object({ symbol: symbol2, orderId: z18.number().int().positive().optional(), origClientOrderId: z18.string().optional() }),
|
|
3644
5441
|
handler: async ({ symbol: symbol3, orderId, origClientOrderId }) => textResult(await t.cancelOrder(normalizeSymbol(symbol3), { orderId, origClientOrderId }))
|
|
3645
5442
|
},
|
|
3646
5443
|
{
|
|
3647
5444
|
name: "futures_get_open_order",
|
|
3648
5445
|
description: "Query a current open order (must exist in the open order book). Signed.",
|
|
3649
|
-
inputSchema:
|
|
5446
|
+
inputSchema: z18.object({ symbol: symbol2, orderId: z18.number().int().positive().optional(), origClientOrderId: z18.string().optional() }),
|
|
3650
5447
|
handler: async ({ symbol: symbol3, orderId, origClientOrderId }) => textResult(await t.getCurrentOrder(normalizeSymbol(symbol3), { orderId, origClientOrderId }))
|
|
3651
5448
|
},
|
|
3652
5449
|
{
|
|
3653
5450
|
name: "futures_open_orders",
|
|
3654
5451
|
description: "Get all current open orders, for one symbol or all symbols. Signed.",
|
|
3655
|
-
inputSchema:
|
|
5452
|
+
inputSchema: z18.object({ symbol: optionalSymbol3 }),
|
|
3656
5453
|
handler: async ({ symbol: symbol3 }) => textResult(await t.getOpenOrders(symbol3 ? normalizeSymbol(symbol3) : void 0))
|
|
3657
5454
|
},
|
|
3658
5455
|
{
|
|
3659
5456
|
name: "futures_all_orders",
|
|
3660
5457
|
description: "Get historical orders for a symbol with optional time range (last 7 days by default). Signed.",
|
|
3661
|
-
inputSchema:
|
|
5458
|
+
inputSchema: z18.object({ symbol: symbol2, orderId: z18.number().int().positive().optional(), startTime: startTime4, endTime: endTime4, limit: limit3 }),
|
|
3662
5459
|
handler: async ({ symbol: symbol3, orderId, startTime: startTime5, endTime: endTime5, limit: limit4 }) => textResult(await t.getAllOrders(normalizeSymbol(symbol3), { orderId, startTime: startTime5, endTime: endTime5, limit: limit4 }))
|
|
3663
5460
|
},
|
|
3664
5461
|
{
|
|
3665
5462
|
name: "futures_cancel_all_orders",
|
|
3666
5463
|
description: "Cancel all open orders for a symbol. Signed.",
|
|
3667
|
-
inputSchema:
|
|
5464
|
+
inputSchema: z18.object({ symbol: symbol2 }),
|
|
3668
5465
|
handler: async ({ symbol: symbol3 }) => textResult(await t.cancelAllOpenOrders(normalizeSymbol(symbol3)))
|
|
3669
5466
|
},
|
|
3670
5467
|
{
|
|
3671
5468
|
name: "futures_modify_order",
|
|
3672
5469
|
description: "Modify an open order (price/quantity/stopPrice). Cannot modify when position side is BOTH and closePosition is true. Signed.",
|
|
3673
|
-
inputSchema:
|
|
5470
|
+
inputSchema: z18.object({
|
|
3674
5471
|
symbol: symbol2,
|
|
3675
5472
|
side: side2,
|
|
3676
|
-
quantity:
|
|
3677
|
-
price:
|
|
3678
|
-
orderId:
|
|
3679
|
-
origClientOrderId:
|
|
3680
|
-
stopPrice:
|
|
3681
|
-
timeInForce:
|
|
5473
|
+
quantity: z18.union([z18.string(), z18.number()]),
|
|
5474
|
+
price: z18.union([z18.string(), z18.number()]).optional(),
|
|
5475
|
+
orderId: z18.number().int().positive().optional(),
|
|
5476
|
+
origClientOrderId: z18.string().optional(),
|
|
5477
|
+
stopPrice: z18.union([z18.string(), z18.number()]).optional(),
|
|
5478
|
+
timeInForce: z18.enum(["GTC", "IOC", "FOK", "GTX"]).optional(),
|
|
3682
5479
|
positionSide,
|
|
3683
|
-
newClientOrderId:
|
|
5480
|
+
newClientOrderId: z18.string().optional()
|
|
3684
5481
|
}),
|
|
3685
5482
|
handler: async (args) => textResult(await t.modifyOrder({ ...args, symbol: normalizeSymbol(args.symbol) }))
|
|
3686
5483
|
},
|
|
3687
5484
|
{
|
|
3688
5485
|
name: "futures_order_modify_history",
|
|
3689
5486
|
description: "Get order modification history for a symbol. Signed.",
|
|
3690
|
-
inputSchema:
|
|
5487
|
+
inputSchema: z18.object({ symbol: symbol2, startTime: startTime4, endTime: endTime4, limit: limit3 }),
|
|
3691
5488
|
handler: async ({ symbol: symbol3, startTime: startTime5, endTime: endTime5, limit: limit4 }) => textResult(await t.getOrderModifyHistory(normalizeSymbol(symbol3), { startTime: startTime5, endTime: endTime5, limit: limit4 }))
|
|
3692
5489
|
},
|
|
3693
5490
|
{
|
|
3694
5491
|
name: "futures_batch_orders",
|
|
3695
5492
|
description: "Place up to 5 orders in one request (array of order objects, max 30 per minute per symbol). Signed.",
|
|
3696
|
-
inputSchema:
|
|
5493
|
+
inputSchema: z18.object({ orders: z18.array(orderParamsSchema).min(1).max(5) }),
|
|
3697
5494
|
handler: async (args) => {
|
|
3698
5495
|
const mapped = args.orders.map((o) => ({ ...o, symbol: normalizeSymbol(o.symbol) }));
|
|
3699
5496
|
return textResult(await t.createBatchOrders(mapped));
|
|
@@ -3702,124 +5499,124 @@ function tradingTools(client) {
|
|
|
3702
5499
|
{
|
|
3703
5500
|
name: "futures_cancel_batch_orders",
|
|
3704
5501
|
description: "Cancel multiple orders at once (up to 10 by orderId list or client order id list). Signed.",
|
|
3705
|
-
inputSchema:
|
|
5502
|
+
inputSchema: z18.object({
|
|
3706
5503
|
symbol: symbol2,
|
|
3707
|
-
orderIdList:
|
|
3708
|
-
origClientOrderIdList:
|
|
5504
|
+
orderIdList: z18.array(z18.number().int().positive()).max(10).optional(),
|
|
5505
|
+
origClientOrderIdList: z18.array(z18.string()).max(10).optional()
|
|
3709
5506
|
}),
|
|
3710
5507
|
handler: async ({ symbol: symbol3, orderIdList, origClientOrderIdList }) => textResult(await t.cancelBatchOrders(normalizeSymbol(symbol3), { orderIdList, origClientOrderIdList }))
|
|
3711
5508
|
},
|
|
3712
5509
|
{
|
|
3713
5510
|
name: "futures_set_leverage",
|
|
3714
5511
|
description: "Change initial leverage for a symbol (1-125, within bracket). Signed.",
|
|
3715
|
-
inputSchema:
|
|
5512
|
+
inputSchema: z18.object({ symbol: symbol2, leverage: z18.number().int().min(1).max(125) }),
|
|
3716
5513
|
handler: async ({ symbol: symbol3, leverage }) => textResult(await t.setLeverage(normalizeSymbol(symbol3), leverage))
|
|
3717
5514
|
},
|
|
3718
5515
|
{
|
|
3719
5516
|
name: "futures_set_margin_type",
|
|
3720
5517
|
description: "Change margin type for a symbol: isolated or cross. Only allowed when no open position for the symbol. Signed.",
|
|
3721
|
-
inputSchema:
|
|
5518
|
+
inputSchema: z18.object({ symbol: symbol2, marginType: z18.enum(["isolated", "cross"]) }),
|
|
3722
5519
|
handler: async ({ symbol: symbol3, marginType }) => textResult(await t.setMarginType(normalizeSymbol(symbol3), marginType))
|
|
3723
5520
|
},
|
|
3724
5521
|
{
|
|
3725
5522
|
name: "futures_modify_position_margin",
|
|
3726
5523
|
description: "Add or reduce isolated position margin. marginType: 1 = add margin, 2 = reduce margin. Signed.",
|
|
3727
|
-
inputSchema:
|
|
5524
|
+
inputSchema: z18.object({ symbol: symbol2, amount: z18.number().positive(), marginType: z18.enum(["1", "2"]).describe("1 = add margin, 2 = reduce margin") }),
|
|
3728
5525
|
handler: async ({ symbol: symbol3, amount, marginType }) => textResult(await t.modifyPositionMargin(normalizeSymbol(symbol3), amount, Number(marginType)))
|
|
3729
5526
|
},
|
|
3730
5527
|
{
|
|
3731
5528
|
name: "futures_countdown_cancel_all",
|
|
3732
5529
|
description: "Auto-cancel all open orders for a symbol after countdownTime ms (0 = cancel the countdown). Emergency circuit breaker. Signed.",
|
|
3733
|
-
inputSchema:
|
|
5530
|
+
inputSchema: z18.object({ symbol: symbol2, countdownTime: z18.number().int().min(100).max(6e4) }),
|
|
3734
5531
|
handler: async ({ symbol: symbol3, countdownTime }) => textResult(await t.setCountdownCancelAll(normalizeSymbol(symbol3), countdownTime))
|
|
3735
5532
|
},
|
|
3736
5533
|
{
|
|
3737
5534
|
name: "futures_new_algo_order",
|
|
3738
5535
|
description: "Place a conditional algo order (CONDITIONAL or VP). CONDITIONAL supports STOP_MARKET/TAKE_PROFIT_MARKET types with triggerPrice; VP is a volume-participation order with urgency and quantity. Signed.",
|
|
3739
|
-
inputSchema:
|
|
3740
|
-
algoType:
|
|
5536
|
+
inputSchema: z18.object({
|
|
5537
|
+
algoType: z18.enum(["CONDITIONAL", "VP"]),
|
|
3741
5538
|
symbol: symbol2,
|
|
3742
5539
|
side: side2,
|
|
3743
5540
|
positionSide,
|
|
3744
|
-
type:
|
|
3745
|
-
quantity:
|
|
3746
|
-
triggerPrice:
|
|
3747
|
-
price:
|
|
3748
|
-
timeInForce:
|
|
3749
|
-
workingType:
|
|
3750
|
-
priceProtect:
|
|
3751
|
-
reduceOnly:
|
|
3752
|
-
closePosition:
|
|
3753
|
-
urgency:
|
|
3754
|
-
clientAlgoId:
|
|
5541
|
+
type: z18.enum(["STOP_MARKET", "TAKE_PROFIT_MARKET", "LIMIT"]).describe("For CONDITIONAL: STOP_MARKET/TAKE_PROFIT_MARKET. For VP: LIMIT"),
|
|
5542
|
+
quantity: z18.union([z18.string(), z18.number()]),
|
|
5543
|
+
triggerPrice: z18.union([z18.string(), z18.number()]).optional().describe("Required for CONDITIONAL"),
|
|
5544
|
+
price: z18.union([z18.string(), z18.number()]).optional(),
|
|
5545
|
+
timeInForce: z18.enum(["GTC", "IOC", "FOK", "GTX"]).optional(),
|
|
5546
|
+
workingType: z18.enum(["MARK_PRICE", "CONTRACT_PRICE"]).optional(),
|
|
5547
|
+
priceProtect: z18.boolean().optional(),
|
|
5548
|
+
reduceOnly: z18.boolean().optional(),
|
|
5549
|
+
closePosition: z18.boolean().optional(),
|
|
5550
|
+
urgency: z18.enum(["LOW", "MEDIUM", "HIGH"]).optional().describe("Required for VP"),
|
|
5551
|
+
clientAlgoId: z18.string().optional()
|
|
3755
5552
|
}),
|
|
3756
5553
|
handler: async (args) => textResult(await t.createAlgoOrder({ ...args, symbol: normalizeSymbol(args.symbol) }))
|
|
3757
5554
|
},
|
|
3758
5555
|
{
|
|
3759
5556
|
name: "futures_cancel_algo_order",
|
|
3760
5557
|
description: "Cancel an open algo order by algoId or clientAlgoId. Signed.",
|
|
3761
|
-
inputSchema:
|
|
5558
|
+
inputSchema: z18.object({ symbol: symbol2, algoId: z18.number().int().positive().optional(), clientAlgoId: z18.string().optional() }),
|
|
3762
5559
|
handler: async ({ symbol: symbol3, algoId, clientAlgoId }) => textResult(await t.cancelAlgoOrder(normalizeSymbol(symbol3), { algoId, clientAlgoId }))
|
|
3763
5560
|
},
|
|
3764
5561
|
{
|
|
3765
5562
|
name: "futures_cancel_all_algo_orders",
|
|
3766
5563
|
description: "Cancel all open algo orders for a symbol. Signed.",
|
|
3767
|
-
inputSchema:
|
|
5564
|
+
inputSchema: z18.object({ symbol: symbol2 }),
|
|
3768
5565
|
handler: async ({ symbol: symbol3 }) => textResult(await t.cancelAllOpenAlgoOrders(normalizeSymbol(symbol3)))
|
|
3769
5566
|
},
|
|
3770
5567
|
{
|
|
3771
5568
|
name: "futures_get_algo_order",
|
|
3772
5569
|
description: "Query an algo order by algoId or clientAlgoId. Signed.",
|
|
3773
|
-
inputSchema:
|
|
5570
|
+
inputSchema: z18.object({ symbol: symbol2, algoId: z18.number().int().positive().optional(), clientAlgoId: z18.string().optional() }),
|
|
3774
5571
|
handler: async ({ symbol: symbol3, algoId, clientAlgoId }) => textResult(await t.getAlgoOrder(normalizeSymbol(symbol3), { algoId, clientAlgoId }))
|
|
3775
5572
|
},
|
|
3776
5573
|
{
|
|
3777
5574
|
name: "futures_open_algo_orders",
|
|
3778
5575
|
description: "Get all current open algo orders, optionally filtered by symbol. Signed.",
|
|
3779
|
-
inputSchema:
|
|
5576
|
+
inputSchema: z18.object({ symbol: optionalSymbol3 }),
|
|
3780
5577
|
handler: async ({ symbol: symbol3 }) => textResult(await t.getOpenAlgoOrders(symbol3 ? normalizeSymbol(symbol3) : void 0))
|
|
3781
5578
|
},
|
|
3782
5579
|
{
|
|
3783
5580
|
name: "futures_all_algo_orders",
|
|
3784
5581
|
description: "Get historical algo orders for a symbol with optional time range. Signed.",
|
|
3785
|
-
inputSchema:
|
|
5582
|
+
inputSchema: z18.object({ symbol: symbol2, startTime: startTime4, endTime: endTime4, limit: limit3 }),
|
|
3786
5583
|
handler: async ({ symbol: symbol3, startTime: startTime5, endTime: endTime5, limit: limit4 }) => textResult(await t.getAllAlgoOrders(normalizeSymbol(symbol3), { startTime: startTime5, endTime: endTime5, limit: limit4 }))
|
|
3787
5584
|
},
|
|
3788
5585
|
{
|
|
3789
5586
|
name: "futures_convert_exchange_info",
|
|
3790
5587
|
description: "List asset pairs eligible for futures Convert, optionally filtered by fromAsset/toAsset.",
|
|
3791
|
-
inputSchema:
|
|
5588
|
+
inputSchema: z18.object({ fromAsset: z18.string().optional(), toAsset: z18.string().optional() }),
|
|
3792
5589
|
handler: async ({ fromAsset, toAsset }) => textResult(await t.convertExchangeInfo({ fromAsset, toAsset }))
|
|
3793
5590
|
},
|
|
3794
5591
|
{
|
|
3795
5592
|
name: "futures_convert_get_quote",
|
|
3796
5593
|
description: "Request a Convert quote between two assets (quote expires quickly; accept with futures_convert_accept_quote). Signed.",
|
|
3797
|
-
inputSchema:
|
|
3798
|
-
fromAsset:
|
|
3799
|
-
toAsset:
|
|
3800
|
-
fromAmount:
|
|
3801
|
-
toAmount:
|
|
3802
|
-
validTime:
|
|
5594
|
+
inputSchema: z18.object({
|
|
5595
|
+
fromAsset: z18.string().min(1),
|
|
5596
|
+
toAsset: z18.string().min(1),
|
|
5597
|
+
fromAmount: z18.number().positive().optional(),
|
|
5598
|
+
toAmount: z18.number().positive().optional(),
|
|
5599
|
+
validTime: z18.enum(["10s", "30s", "1m", "2m"]).optional()
|
|
3803
5600
|
}),
|
|
3804
5601
|
handler: async (args) => textResult(await t.convertGetQuote(args))
|
|
3805
5602
|
},
|
|
3806
5603
|
{
|
|
3807
5604
|
name: "futures_convert_accept_quote",
|
|
3808
5605
|
description: "Accept a previously requested Convert quote by quoteId. Signed.",
|
|
3809
|
-
inputSchema:
|
|
5606
|
+
inputSchema: z18.object({ quoteId: z18.string().min(1) }),
|
|
3810
5607
|
handler: async ({ quoteId }) => textResult(await t.convertAcceptQuote(quoteId))
|
|
3811
5608
|
},
|
|
3812
5609
|
{
|
|
3813
5610
|
name: "futures_convert_order_status",
|
|
3814
5611
|
description: "Query the status of a Convert order by orderId or quoteId. Signed.",
|
|
3815
|
-
inputSchema:
|
|
5612
|
+
inputSchema: z18.object({ orderId: z18.string().optional(), quoteId: z18.string().optional() }),
|
|
3816
5613
|
handler: async ({ orderId, quoteId }) => textResult(await t.convertOrderStatus({ orderId, quoteId }))
|
|
3817
5614
|
}
|
|
3818
5615
|
];
|
|
3819
5616
|
}
|
|
3820
5617
|
|
|
3821
5618
|
// src/tools/ws.tools.ts
|
|
3822
|
-
import { z as
|
|
5619
|
+
import { z as z19 } from "zod";
|
|
3823
5620
|
var buffers = /* @__PURE__ */ new Map();
|
|
3824
5621
|
var MAX_BUFFER = 500;
|
|
3825
5622
|
function bufferFor(client) {
|
|
@@ -3846,8 +5643,8 @@ function wsTools(client) {
|
|
|
3846
5643
|
{
|
|
3847
5644
|
name: "futures_ws_subscribe",
|
|
3848
5645
|
description: "Subscribe to real-time market data streams. Topic format: <symbol>@<stream>, e.g. btcusdt@aggTrade, btcusdt@kline_1m, btcusdt@depth20, btcusdt@markPrice@1s, btcusdt@bookTicker, btcusdt@ticker, btcusdt@miniTicker, btcusdt@forceOrder, or all-market topics !ticker@arr, !bookTicker, !markPrice@arr, !forceOrder@arr, !miniTicker@arr. Multiple topics can be passed at once.",
|
|
3849
|
-
inputSchema:
|
|
3850
|
-
topics:
|
|
5646
|
+
inputSchema: z19.object({
|
|
5647
|
+
topics: z19.array(z19.string().min(1)).min(1).describe('Stream topics, e.g. ["btcusdt@aggTrade", "btcusdt@kline_1m"]')
|
|
3851
5648
|
}),
|
|
3852
5649
|
handler: async ({ topics }) => {
|
|
3853
5650
|
const normalized = topics.map((t) => t.trim().toLowerCase());
|
|
@@ -3859,7 +5656,7 @@ function wsTools(client) {
|
|
|
3859
5656
|
{
|
|
3860
5657
|
name: "futures_ws_unsubscribe",
|
|
3861
5658
|
description: "Unsubscribe from previously subscribed market data streams.",
|
|
3862
|
-
inputSchema:
|
|
5659
|
+
inputSchema: z19.object({ topics: z19.array(z19.string().min(1)).min(1) }),
|
|
3863
5660
|
handler: async ({ topics }) => {
|
|
3864
5661
|
const normalized = topics.map((t) => t.trim().toLowerCase());
|
|
3865
5662
|
client.futures.ws.unsubscribe(normalized);
|
|
@@ -3870,19 +5667,19 @@ function wsTools(client) {
|
|
|
3870
5667
|
{
|
|
3871
5668
|
name: "futures_ws_subscriptions",
|
|
3872
5669
|
description: "List the currently subscribed WebSocket market streams for this client.",
|
|
3873
|
-
inputSchema:
|
|
5670
|
+
inputSchema: z19.object({}),
|
|
3874
5671
|
handler: async () => textResult({ active: [...buffer.subscriptions] })
|
|
3875
5672
|
},
|
|
3876
5673
|
{
|
|
3877
5674
|
name: "futures_ws_events",
|
|
3878
5675
|
description: "Read the buffered real-time payloads received since the last read for the subscribed streams (aggregate trades, klines, depth deltas, mark price, book tickers, tickers, force orders). Payloads are parsed; depth deltas must be applied to a snapshot from futures_order_book.",
|
|
3879
|
-
inputSchema:
|
|
5676
|
+
inputSchema: z19.object({ limit: z19.number().int().min(1).max(200).default(50) }),
|
|
3880
5677
|
handler: async ({ limit: limit4 }) => textResult(getBufferedWsEvents(client, limit4))
|
|
3881
5678
|
},
|
|
3882
5679
|
{
|
|
3883
5680
|
name: "futures_ws_clear_events",
|
|
3884
5681
|
description: "Clear the buffered WebSocket events so the next read only returns new payloads.",
|
|
3885
|
-
inputSchema:
|
|
5682
|
+
inputSchema: z19.object({}),
|
|
3886
5683
|
handler: async () => {
|
|
3887
5684
|
clearBufferedWsEvents(client);
|
|
3888
5685
|
return textResult({ cleared: true });
|
|
@@ -3891,13 +5688,13 @@ function wsTools(client) {
|
|
|
3891
5688
|
{
|
|
3892
5689
|
name: "futures_ws_start_user_stream",
|
|
3893
5690
|
description: "Start the user data stream: creates a listenKey, connects the private WebSocket, and begins a 30-minute keep-alive. Emits private events (ACCOUNT_UPDATE, ORDER_TRADE_UPDATE, MARGIN_CALL, ACCOUNT_CONFIG_UPDATE, listenKeyExpired) that the application can consume from the client.",
|
|
3894
|
-
inputSchema:
|
|
5691
|
+
inputSchema: z19.object({}),
|
|
3895
5692
|
handler: async () => textResult({ listenKey: await client.startUserStream() })
|
|
3896
5693
|
},
|
|
3897
5694
|
{
|
|
3898
5695
|
name: "futures_ws_stop_user_stream",
|
|
3899
5696
|
description: "Stop the user data stream: closes the private WebSocket and invalidates the listenKey.",
|
|
3900
|
-
inputSchema:
|
|
5697
|
+
inputSchema: z19.object({}),
|
|
3901
5698
|
handler: async () => {
|
|
3902
5699
|
client.closeUserStream();
|
|
3903
5700
|
return textResult({ stopped: true });
|
|
@@ -3906,49 +5703,49 @@ function wsTools(client) {
|
|
|
3906
5703
|
{
|
|
3907
5704
|
name: "futures_ws_api_order_status",
|
|
3908
5705
|
description: "Query an order via the signed WebSocket API (order.status) \u2014 lower-latency alternative to futures_get_order.",
|
|
3909
|
-
inputSchema:
|
|
3910
|
-
symbol:
|
|
3911
|
-
orderId:
|
|
3912
|
-
origClientOrderId:
|
|
5706
|
+
inputSchema: z19.object({
|
|
5707
|
+
symbol: z19.string().min(1).describe("USD-M pair, e.g. BTCUSDT"),
|
|
5708
|
+
orderId: z19.number().int().positive().optional(),
|
|
5709
|
+
origClientOrderId: z19.string().optional()
|
|
3913
5710
|
}),
|
|
3914
5711
|
handler: async ({ symbol: symbol3, orderId, origClientOrderId }) => textResult(await client.futures.wsApi.orderStatus({ symbol: normalizeSymbol(symbol3), orderId, origClientOrderId }))
|
|
3915
5712
|
},
|
|
3916
5713
|
{
|
|
3917
5714
|
name: "futures_ws_api_account_status",
|
|
3918
5715
|
description: "Get account info via the signed WebSocket API (account.status).",
|
|
3919
|
-
inputSchema:
|
|
5716
|
+
inputSchema: z19.object({}),
|
|
3920
5717
|
handler: async () => textResult(await client.futures.wsApi.accountStatus())
|
|
3921
5718
|
},
|
|
3922
5719
|
{
|
|
3923
5720
|
name: "futures_ws_api_account_position",
|
|
3924
5721
|
description: "Get current positions via the signed WebSocket API (account.position).",
|
|
3925
|
-
inputSchema:
|
|
5722
|
+
inputSchema: z19.object({ symbol: z19.string().min(1).describe("USD-M pair, e.g. BTCUSDT").optional() }),
|
|
3926
5723
|
handler: async ({ symbol: symbol3 }) => textResult(await client.futures.wsApi.accountPosition(symbol3 ? { symbol: normalizeSymbol(symbol3) } : {}))
|
|
3927
5724
|
},
|
|
3928
5725
|
{
|
|
3929
5726
|
name: "futures_ws_api_user_data_stream_start",
|
|
3930
5727
|
description: "Create a listenKey via the signed WebSocket API (userDataStream.start) \u2014 no REST call required.",
|
|
3931
|
-
inputSchema:
|
|
5728
|
+
inputSchema: z19.object({}),
|
|
3932
5729
|
handler: async () => textResult(await client.futures.wsApi.userDataStreamStart())
|
|
3933
5730
|
},
|
|
3934
5731
|
{
|
|
3935
5732
|
name: "futures_ws_api_user_data_stream_stop",
|
|
3936
5733
|
description: "Invalidate a listenKey via the signed WebSocket API (userDataStream.stop).",
|
|
3937
|
-
inputSchema:
|
|
5734
|
+
inputSchema: z19.object({ listenKey: z19.string().min(1) }),
|
|
3938
5735
|
handler: async ({ listenKey }) => textResult(await client.futures.wsApi.userDataStreamStop(listenKey))
|
|
3939
5736
|
},
|
|
3940
5737
|
{
|
|
3941
5738
|
name: "futures_ws_api_ticker_price",
|
|
3942
5739
|
description: "Get latest price via the unsigned WebSocket API (ticker.price); omit symbol for all symbols.",
|
|
3943
|
-
inputSchema:
|
|
5740
|
+
inputSchema: z19.object({ symbol: z19.string().min(1).describe("USD-M pair, e.g. BTCUSDT").optional() }),
|
|
3944
5741
|
handler: async ({ symbol: symbol3 }) => textResult(await client.futures.wsApi.tickerPrice(symbol3 ? { symbol: normalizeSymbol(symbol3) } : {}))
|
|
3945
5742
|
},
|
|
3946
5743
|
{
|
|
3947
5744
|
name: "futures_ws_api_order_book",
|
|
3948
5745
|
description: "Get order-book depth via the unsigned WebSocket API (depth).",
|
|
3949
|
-
inputSchema:
|
|
3950
|
-
symbol:
|
|
3951
|
-
limit:
|
|
5746
|
+
inputSchema: z19.object({
|
|
5747
|
+
symbol: z19.string().min(1).describe("USD-M pair, e.g. BTCUSDT"),
|
|
5748
|
+
limit: z19.enum(["5", "10", "20", "50", "100", "500", "1000"]).optional()
|
|
3952
5749
|
}),
|
|
3953
5750
|
handler: async ({ symbol: symbol3, limit: limit4 }) => textResult(await client.futures.wsApi.depth({ symbol: normalizeSymbol(symbol3), limit: limit4 }))
|
|
3954
5751
|
}
|
|
@@ -3981,7 +5778,7 @@ function createFuturesToolkit(client) {
|
|
|
3981
5778
|
|
|
3982
5779
|
// src/mcp/server.ts
|
|
3983
5780
|
function createBinanceMcpServer(client) {
|
|
3984
|
-
const server = new McpServer({ name: "binance-sdk", version: "
|
|
5781
|
+
const server = new McpServer({ name: "binance-sdk", version: "2.0.0" });
|
|
3985
5782
|
const toolkit = createFuturesToolkit(client);
|
|
3986
5783
|
toolkit.tools.forEach((tool) => {
|
|
3987
5784
|
server.registerTool(tool.name, { description: tool.description, inputSchema: tool.inputSchema }, async (args) => ({
|