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