@medievalrain/binance-ts 0.1.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.
Files changed (3) hide show
  1. package/dist/index.d.ts +1548 -0
  2. package/dist/index.js +1145 -0
  3. package/package.json +42 -0
package/dist/index.js ADDED
@@ -0,0 +1,1145 @@
1
+ import z$1, { z } from "zod";
2
+ import { Client, WebSocket } from "undici";
3
+ import * as z4 from "zod/v4/core";
4
+ import { createHmac } from "node:crypto";
5
+
6
+ //#region src/rest/futures/schema.ts
7
+ const FuturesTestConnectivitySchema = z.object({});
8
+ const FuturesCheckServerTimeSchema = z.object({ serverTime: z.number() });
9
+ const FuturesExchangeInfoRateLimitSchema = z.object({
10
+ interval: z.enum(["MINUTE", "SECOND"]),
11
+ intervalNum: z.number(),
12
+ limit: z.number(),
13
+ rateLimitType: z.enum(["REQUEST_WEIGHT", "ORDERS"])
14
+ });
15
+ const FuturesExchangeInfoAssetSchema = z.object({
16
+ asset: z.string(),
17
+ marginAvailable: z.boolean(),
18
+ autoAssetExchange: z.string().nullable()
19
+ });
20
+ const FuturesExchangeInfoFilterSchema = z.discriminatedUnion("filterType", [
21
+ z.object({
22
+ filterType: z.literal("PRICE_FILTER"),
23
+ maxPrice: z.coerce.number(),
24
+ minPrice: z.coerce.number(),
25
+ tickSize: z.coerce.number()
26
+ }),
27
+ z.object({
28
+ filterType: z.literal("LOT_SIZE"),
29
+ maxQty: z.coerce.number(),
30
+ minQty: z.coerce.number(),
31
+ stepSize: z.coerce.number()
32
+ }),
33
+ z.object({
34
+ filterType: z.literal("MARKET_LOT_SIZE"),
35
+ maxQty: z.coerce.number(),
36
+ minQty: z.coerce.number(),
37
+ stepSize: z.coerce.number()
38
+ }),
39
+ z.object({
40
+ filterType: z.literal("MAX_NUM_ORDERS"),
41
+ limit: z.number()
42
+ }),
43
+ z.object({
44
+ filterType: z.literal("MAX_NUM_ALGO_ORDERS"),
45
+ limit: z.number()
46
+ }),
47
+ z.object({
48
+ filterType: z.literal("MIN_NOTIONAL"),
49
+ notional: z.string()
50
+ }),
51
+ z.object({
52
+ filterType: z.literal("PERCENT_PRICE"),
53
+ multiplierUp: z.coerce.number(),
54
+ multiplierDown: z.coerce.number().optional(),
55
+ multiplierDecimal: z.coerce.number().optional()
56
+ }),
57
+ z.object({
58
+ filterType: z.literal("POSITION_RISK_CONTROL"),
59
+ positionControlSide: z.literal("NONE"),
60
+ multiplierDown: z.coerce.number().optional(),
61
+ multiplierDecimal: z.coerce.number().optional()
62
+ })
63
+ ]);
64
+ const FuturesContractTypeSchema = z.enum([
65
+ "PERPETUAL",
66
+ "CURRENT_QUARTER",
67
+ "NEXT_QUARTER"
68
+ ]);
69
+ const FuturesUnderlyingTypeSchema = z.enum([
70
+ "COIN",
71
+ "INDEX",
72
+ "PREMARKET"
73
+ ]);
74
+ const FuturesOrderTypeSchema = z.enum([
75
+ "LIMIT",
76
+ "MARKET",
77
+ "STOP",
78
+ "TAKE_PROFIT",
79
+ "STOP_MARKET",
80
+ "TAKE_PROFIT_MARKET",
81
+ "TRAILING_STOP_MARKET"
82
+ ]);
83
+ const FuturesExchangeInfoSymbolSchema = z.object({
84
+ symbol: z.string(),
85
+ pair: z.string(),
86
+ contractType: FuturesContractTypeSchema,
87
+ deliveryDate: z.number(),
88
+ onboardDate: z.number(),
89
+ status: z.enum([
90
+ "TRADING",
91
+ "SETTLING",
92
+ "PENDING_TRADING"
93
+ ]),
94
+ maintMarginPercent: z.string(),
95
+ requiredMarginPercent: z.string(),
96
+ baseAsset: z.string(),
97
+ quoteAsset: z.string(),
98
+ marginAsset: z.string(),
99
+ pricePrecision: z.number(),
100
+ quantityPrecision: z.number(),
101
+ baseAssetPrecision: z.number(),
102
+ quotePrecision: z.number(),
103
+ underlyingType: FuturesUnderlyingTypeSchema,
104
+ underlyingSubType: z.array(z.string()),
105
+ permissionSets: z.array(z.enum(["COPY", "GRID"])),
106
+ settlePlan: z.number().optional(),
107
+ triggerProtect: z.string(),
108
+ filters: z.array(FuturesExchangeInfoFilterSchema),
109
+ OrderType: z.array(FuturesOrderTypeSchema).optional(),
110
+ timeInForce: z.array(z.string()),
111
+ liquidationFee: z.coerce.number(),
112
+ marketTakeBound: z.coerce.number()
113
+ });
114
+ const FuturesExchangeInfoSchema = z.object({
115
+ exchangeFilters: z.array(z.unknown()),
116
+ rateLimits: z.array(FuturesExchangeInfoRateLimitSchema),
117
+ serverTime: z.number(),
118
+ assets: z.array(FuturesExchangeInfoAssetSchema),
119
+ symbols: z.array(FuturesExchangeInfoSymbolSchema),
120
+ timezone: z.string()
121
+ });
122
+ const FuturesOrderBookSchema = z.object({
123
+ lastUpdateId: z.number(),
124
+ E: z.number(),
125
+ T: z.number(),
126
+ bids: z.array(z.tuple([z.coerce.number(), z.coerce.number()])),
127
+ asks: z.array(z.tuple([z.coerce.number(), z.coerce.number()]))
128
+ });
129
+ const FuturesRecentTradesSchema = z.array(z.object({
130
+ id: z.number(),
131
+ price: z.coerce.number(),
132
+ qty: z.coerce.number(),
133
+ quoteQty: z.coerce.number(),
134
+ time: z.number(),
135
+ isBuyerMaker: z.boolean()
136
+ }));
137
+ const FuturesOldTradesLookupSchema = z.array(z.object({
138
+ id: z.number(),
139
+ price: z.coerce.number(),
140
+ qty: z.coerce.number(),
141
+ quoteQty: z.coerce.number(),
142
+ time: z.number(),
143
+ isBuyerMaker: z.boolean()
144
+ }));
145
+ const FuturesAggregateTradesSchema = z.array(z.object({
146
+ a: z.number(),
147
+ p: z.coerce.number(),
148
+ q: z.coerce.number(),
149
+ f: z.number(),
150
+ l: z.number(),
151
+ T: z.number(),
152
+ m: z.boolean()
153
+ }));
154
+ const FuturesKlineDataSchema = z.array(z.tuple([
155
+ z.number(),
156
+ z.coerce.number(),
157
+ z.coerce.number(),
158
+ z.coerce.number(),
159
+ z.coerce.number(),
160
+ z.coerce.number(),
161
+ z.number(),
162
+ z.coerce.number(),
163
+ z.number(),
164
+ z.coerce.number(),
165
+ z.coerce.number(),
166
+ z.coerce.number()
167
+ ]));
168
+ const FuturesMarkPriceSchema = z.object({
169
+ symbol: z.string(),
170
+ markPrice: z.coerce.number(),
171
+ indexPrice: z.coerce.number(),
172
+ estimatedSettlePrice: z.coerce.number(),
173
+ lastFundingRate: z.coerce.number(),
174
+ interestRate: z.coerce.number(),
175
+ nextFundingTime: z.number(),
176
+ time: z.number()
177
+ });
178
+ const FuturesFundingRateEntrySchema = z.object({
179
+ symbol: z.string(),
180
+ fundingRate: z.coerce.number(),
181
+ fundingTime: z.number(),
182
+ markPrice: z.coerce.number()
183
+ });
184
+ const FuturesFundingRateSchema = z.array(FuturesFundingRateEntrySchema);
185
+ const FuturesFundingInfoEntrySchema = z.object({
186
+ symbol: z.string(),
187
+ adjustedFundingRateCap: z.coerce.number(),
188
+ adjustedFundingRateFloor: z.coerce.number(),
189
+ fundingIntervalHours: z.number()
190
+ });
191
+ const FuturesFundingInfoSchema = z.array(FuturesFundingInfoEntrySchema);
192
+ const FuturesTicker24hSchema = z.object({
193
+ symbol: z.string(),
194
+ priceChange: z.coerce.number(),
195
+ priceChangePercent: z.coerce.number(),
196
+ weightedAvgPrice: z.coerce.number(),
197
+ lastPrice: z.coerce.number(),
198
+ lastQty: z.coerce.number(),
199
+ openPrice: z.coerce.number(),
200
+ highPrice: z.coerce.number(),
201
+ lowPrice: z.coerce.number(),
202
+ volume: z.coerce.number(),
203
+ quoteVolume: z.coerce.number(),
204
+ openTime: z.number(),
205
+ closeTime: z.number(),
206
+ firstId: z.number(),
207
+ lastId: z.number(),
208
+ count: z.number()
209
+ });
210
+ const FuturesSymbolPriceSchema = z.object({
211
+ symbol: z.string(),
212
+ price: z.coerce.number(),
213
+ time: z.number()
214
+ });
215
+ const FuturesBookTickerSchema = z.object({
216
+ symbol: z.string(),
217
+ bidPrice: z.coerce.number(),
218
+ bidQty: z.coerce.number(),
219
+ askPrice: z.coerce.number(),
220
+ askQty: z.coerce.number(),
221
+ time: z.coerce.number()
222
+ });
223
+ const FuturesDeliveryPriceSchema = z.array(z.object({
224
+ deliveryTime: z.coerce.number(),
225
+ deliveryPrice: z.coerce.number()
226
+ }));
227
+ const FuturesOpenInterestSchema = z.object({
228
+ openInterest: z.coerce.number(),
229
+ symbol: z.string(),
230
+ time: z.coerce.number()
231
+ });
232
+ const FuturesOpenInterestStatsSchema = z.array(z.object({
233
+ symbol: z.string(),
234
+ sumOpenInterest: z.coerce.number(),
235
+ sumOpenInterestValue: z.coerce.number(),
236
+ timestamp: z.coerce.number()
237
+ }));
238
+ const FuturesLongShortRatioSchema = z.array(z.object({
239
+ symbol: z.string(),
240
+ longShortRatio: z.coerce.number(),
241
+ longAccount: z.coerce.number(),
242
+ shortAccount: z.coerce.number(),
243
+ timestamp: z.coerce.number()
244
+ }));
245
+ const FuturesTakerBuySellRatioItemSchema = z.object({
246
+ buySellRatio: z.coerce.number(),
247
+ buyVol: z.coerce.number(),
248
+ sellVol: z.coerce.number(),
249
+ timestamp: z.coerce.number()
250
+ });
251
+ const FuturesTakerBuySellRatioSchema = z.array(FuturesTakerBuySellRatioItemSchema);
252
+ const FuturesBasisSchema = z.array(z.object({
253
+ indexPrice: z.coerce.number(),
254
+ contractType: FuturesContractTypeSchema,
255
+ basisRate: z.coerce.number(),
256
+ futuresPrice: z.coerce.number(),
257
+ annualizedBasisRate: z.string().optional(),
258
+ basis: z.coerce.number(),
259
+ pair: z.string(),
260
+ timestamp: z.number()
261
+ }));
262
+ const FuturesCompositeIndexAssetSchema = z.object({
263
+ baseAsset: z.string(),
264
+ quoteAsset: z.string(),
265
+ weightInQuantity: z.coerce.number(),
266
+ weightInPercentage: z.coerce.number()
267
+ });
268
+ const FuturesCompositeIndexSchema = z.object({
269
+ symbol: z.string(),
270
+ time: z.coerce.number(),
271
+ component: z.string(),
272
+ baseAssetList: z.array(FuturesCompositeIndexAssetSchema)
273
+ });
274
+ const FuturesAssetIndexSchema = z.object({
275
+ symbol: z.string(),
276
+ time: z.coerce.number(),
277
+ index: z.coerce.number(),
278
+ bidBuffer: z.coerce.number(),
279
+ askBuffer: z.coerce.number(),
280
+ bidRate: z.coerce.number(),
281
+ askRate: z.coerce.number(),
282
+ autoExchangeBidBuffer: z.coerce.number(),
283
+ autoExchangeAskBuffer: z.coerce.number(),
284
+ autoExchangeBidRate: z.coerce.number(),
285
+ autoExchangeAskRate: z.coerce.number()
286
+ });
287
+ const FuturesIndexPriceConstituentItemSchema = z.object({
288
+ exchange: z.string(),
289
+ symbol: z.string(),
290
+ price: z.coerce.number(),
291
+ weight: z.coerce.number()
292
+ });
293
+ const FuturesIndexPriceConstituentsSchema = z.object({
294
+ symbol: z.string(),
295
+ time: z.coerce.number(),
296
+ constituents: z.array(FuturesIndexPriceConstituentItemSchema)
297
+ });
298
+ const FuturesInsuranceBalanceAssetSchema = z.object({
299
+ asset: z.string(),
300
+ marginBalance: z.coerce.number(),
301
+ updateTime: z.coerce.number()
302
+ });
303
+ const FuturesInsuranceBalanceEntrySchema = z.object({
304
+ symbols: z.array(z.string()),
305
+ assets: z.array(FuturesInsuranceBalanceAssetSchema)
306
+ });
307
+ const FuturesAccountBalanceSchema = z.array(z.object({
308
+ accountAlias: z.string(),
309
+ asset: z.string(),
310
+ balance: z.coerce.number(),
311
+ crossWalletBalance: z.coerce.number(),
312
+ crossUnPnl: z.coerce.number(),
313
+ availableBalance: z.coerce.number(),
314
+ maxWithdrawAmount: z.coerce.number(),
315
+ marginAvailable: z.boolean(),
316
+ updateTime: z.number()
317
+ }));
318
+ const FuturesAccountAssetSchema = z.object({
319
+ asset: z.string(),
320
+ walletBalance: z.coerce.number(),
321
+ unrealizedProfit: z.coerce.number(),
322
+ marginBalance: z.coerce.number(),
323
+ maintMargin: z.coerce.number(),
324
+ initialMargin: z.coerce.number(),
325
+ positionInitialMargin: z.coerce.number(),
326
+ openOrderInitialMargin: z.coerce.number(),
327
+ crossWalletBalance: z.coerce.number(),
328
+ crossUnPnl: z.coerce.number(),
329
+ availableBalance: z.coerce.number(),
330
+ maxWithdrawAmount: z.coerce.number(),
331
+ updateTime: z.number(),
332
+ marginAvailable: z.boolean().optional()
333
+ });
334
+ const FuturesAccountPositionSchema = z.object({
335
+ symbol: z.string(),
336
+ positionSide: z.string(),
337
+ positionAmt: z.coerce.number(),
338
+ unrealizedProfit: z.coerce.number(),
339
+ isolatedMargin: z.coerce.number(),
340
+ notional: z.coerce.number(),
341
+ isolatedWallet: z.coerce.number(),
342
+ initialMargin: z.coerce.number(),
343
+ maintMargin: z.coerce.number(),
344
+ updateTime: z.number()
345
+ });
346
+ const FuturesAccountInfoSchema = z.object({
347
+ totalInitialMargin: z.coerce.number(),
348
+ totalMaintMargin: z.coerce.number(),
349
+ totalWalletBalance: z.coerce.number(),
350
+ totalUnrealizedProfit: z.coerce.number(),
351
+ totalMarginBalance: z.coerce.number(),
352
+ totalPositionInitialMargin: z.coerce.number(),
353
+ totalOpenOrderInitialMargin: z.coerce.number(),
354
+ totalCrossWalletBalance: z.coerce.number(),
355
+ totalCrossUnPnl: z.coerce.number(),
356
+ availableBalance: z.coerce.number(),
357
+ maxWithdrawAmount: z.coerce.number(),
358
+ assets: z.array(FuturesAccountAssetSchema),
359
+ positions: z.array(FuturesAccountPositionSchema)
360
+ });
361
+ const FuturesCommissionRateSchema = z.object({
362
+ symbol: z.string(),
363
+ makerCommissionRate: z.coerce.number(),
364
+ takerCommissionRate: z.coerce.number()
365
+ });
366
+ const FuturesAccountConfigSchema = z.object({
367
+ feeTier: z.number(),
368
+ canTrade: z.boolean(),
369
+ canDeposit: z.boolean(),
370
+ canWithdraw: z.boolean(),
371
+ dualSidePosition: z.boolean(),
372
+ multiAssetsMargin: z.boolean(),
373
+ tradeGroupId: z.number()
374
+ });
375
+ const FuturesSymbolConfigSchema = z.array(z.object({
376
+ symbol: z.string(),
377
+ marginType: z.enum(["ISOLATED", "CROSSED"]),
378
+ isAutoAddMargin: z.boolean(),
379
+ leverage: z.coerce.number(),
380
+ maxNotionalValue: z.coerce.number().or(z.literal("INF")).transform((v) => v === "INF" ? Infinity : Number(v))
381
+ }));
382
+ const FuturesUserRateLimitSchema = z.array(z.object({
383
+ rateLimitType: z.literal("ORDERS"),
384
+ interval: z.enum([
385
+ "SECOND",
386
+ "MINUTE",
387
+ "DAY"
388
+ ]),
389
+ intervalNum: z.number(),
390
+ limit: z.number()
391
+ }));
392
+ const FuturesLeverageBracketEntrySchema = z.object({
393
+ bracket: z.number(),
394
+ initialLeverage: z.number(),
395
+ notionalCap: z.number(),
396
+ notionalFloor: z.number(),
397
+ maintMarginRatio: z.number(),
398
+ cum: z.number()
399
+ });
400
+ const FuturesLeverageBracketSchema = z.array(z.object({
401
+ symbol: z.string(),
402
+ notionalCoef: z.number().optional(),
403
+ brackets: z.array(FuturesLeverageBracketEntrySchema)
404
+ }));
405
+ const FuturesPositionModeSchema = z.object({ dualSidePosition: z.boolean() });
406
+ const FuturesIncomeTypeSchema = z.enum([
407
+ "TRANSFER",
408
+ "WELCOME_BONUS",
409
+ "REALIZED_PNL",
410
+ "FUNDING_FEE",
411
+ "COMMISSION",
412
+ "INSURANCE_CLEAR",
413
+ "REFERRAL_KICKBACK",
414
+ "COMMISSION_REBATE",
415
+ "API_REBATE",
416
+ "CONTEST_REWARD",
417
+ "CROSS_COLLATERAL_TRANSFER",
418
+ "OPTIONS_PREMIUM_FEE",
419
+ "OPTIONS_SETTLE_PROFIT",
420
+ "INTERNAL_TRANSFER",
421
+ "AUTO_EXCHANGE",
422
+ "DELIVERED_SETTELMENT",
423
+ "COIN_SWAP_DEPOSIT",
424
+ "COIN_SWAP_WITHDRAW",
425
+ "POSITION_LIMIT_INCREASE_FEE",
426
+ "STRATEGY_UMFUTURES_TRANSFER",
427
+ "FEE_RETURN",
428
+ "BFUSD_REWARD"
429
+ ]);
430
+ const FuturesIncomeHistorySchema = z.array(z.object({
431
+ symbol: z.string().optional(),
432
+ incomeType: FuturesIncomeTypeSchema,
433
+ income: z.coerce.number(),
434
+ asset: z.string(),
435
+ info: z.string(),
436
+ time: z.number(),
437
+ tranId: z.number(),
438
+ tradeId: z.string().optional()
439
+ }));
440
+ const FuturesOrderSideSchema = z.enum(["BUY", "SELL"]);
441
+ const FuturesPositionSideSchema = z.enum([
442
+ "BOTH",
443
+ "LONG",
444
+ "SHORT"
445
+ ]);
446
+ const FuturesTimeInForceSchema = z.enum([
447
+ "GTC",
448
+ "IOC",
449
+ "FOK",
450
+ "GTX",
451
+ "GTD"
452
+ ]);
453
+ const FuturesWorkingTypeSchema = z.enum(["MARK_PRICE", "CONTRACT_PRICE"]);
454
+ const FuturesNewOrderRespTypeSchema = z.enum(["ACK", "RESULT"]);
455
+ const FuturesPriceMatchSchema = z.enum([
456
+ "OPPONENT",
457
+ "OPPONENT_5",
458
+ "OPPONENT_10",
459
+ "OPPONENT_20",
460
+ "QUEUE",
461
+ "QUEUE_5",
462
+ "QUEUE_10",
463
+ "QUEUE_20",
464
+ "NONE"
465
+ ]);
466
+ const FuturesSelfTradePreventionSchema = z.enum([
467
+ "NONE",
468
+ "EXPIRE_TAKER",
469
+ "EXPIRE_MAKER",
470
+ "EXPIRE_BOTH"
471
+ ]);
472
+ const FuturesNewOrderSchema = z.object({
473
+ clientOrderId: z.string(),
474
+ cumQty: z.coerce.number(),
475
+ cumQuote: z.coerce.number(),
476
+ executedQty: z.coerce.number(),
477
+ orderId: z.number(),
478
+ avgPrice: z.coerce.number(),
479
+ origQty: z.coerce.number(),
480
+ price: z.coerce.number(),
481
+ reduceOnly: z.boolean(),
482
+ side: FuturesOrderSideSchema,
483
+ positionSide: FuturesPositionSideSchema,
484
+ status: z.string(),
485
+ stopPrice: z.coerce.number().optional(),
486
+ closePosition: z.boolean().optional(),
487
+ symbol: z.string(),
488
+ timeInForce: FuturesTimeInForceSchema,
489
+ type: FuturesOrderTypeSchema,
490
+ origType: FuturesOrderTypeSchema,
491
+ activatePrice: z.coerce.number().optional(),
492
+ priceRate: z.coerce.number().optional(),
493
+ updateTime: z.number(),
494
+ workingType: FuturesWorkingTypeSchema,
495
+ priceProtect: z.boolean(),
496
+ priceMatch: FuturesPriceMatchSchema.optional(),
497
+ selfTradePreventionMode: FuturesSelfTradePreventionSchema.optional(),
498
+ goodTillDate: z.number().optional()
499
+ });
500
+
501
+ //#endregion
502
+ //#region src/shared/api-error.ts
503
+ var ApiError = class extends Error {
504
+ endpoint;
505
+ constructor({ endpoint, metadata }) {
506
+ super(JSON.stringify({
507
+ endpoint,
508
+ ...metadata
509
+ }, null, 2));
510
+ this.endpoint = endpoint;
511
+ }
512
+ };
513
+ var ValidationError = class extends ApiError {
514
+ error;
515
+ input;
516
+ constructor({ error, input, endpoint }) {
517
+ super({
518
+ endpoint,
519
+ metadata: {
520
+ error,
521
+ input
522
+ }
523
+ });
524
+ this.error = error;
525
+ this.input = input;
526
+ }
527
+ };
528
+ var ResponseError = class extends ApiError {
529
+ code;
530
+ status;
531
+ constructor({ metadata, code, status, endpoint }) {
532
+ super({
533
+ endpoint,
534
+ metadata: {
535
+ ...metadata,
536
+ code,
537
+ status
538
+ }
539
+ });
540
+ this.code = code;
541
+ this.status = status;
542
+ }
543
+ };
544
+ var ErrorMessageParsingError = class extends Error {
545
+ constructor(message) {
546
+ super(message);
547
+ }
548
+ };
549
+ var WeightError = class extends ResponseError {
550
+ ip;
551
+ bannedUntil;
552
+ constructor({ message, endpoint }) {
553
+ super({
554
+ endpoint,
555
+ code: -1003,
556
+ status: 418
557
+ });
558
+ const { ip, timestamp } = this.parseWeightResponse(message);
559
+ this.ip = ip;
560
+ this.bannedUntil = timestamp;
561
+ }
562
+ parseWeightResponse(message) {
563
+ const match = message.match(/IP\(([^)]+)\).*?until (\d+)/);
564
+ if (!match) throw new ErrorMessageParsingError("Can't parse weight data");
565
+ const ip = String(match[1]);
566
+ const timestamp = Number(match[2]);
567
+ return {
568
+ ip,
569
+ timestamp
570
+ };
571
+ }
572
+ };
573
+ var MalformedParamError = class extends ResponseError {
574
+ param;
575
+ constructor({ message, endpoint }) {
576
+ super({
577
+ endpoint,
578
+ code: -1102,
579
+ status: 400
580
+ });
581
+ this.param = this.parseParam(message);
582
+ }
583
+ parseParam(message) {
584
+ const match = message.match(/'([^']+)'/);
585
+ if (match) console.log(match[1]);
586
+ if (!match) throw new ErrorMessageParsingError("Can't parse param data");
587
+ return String(match[1]);
588
+ }
589
+ };
590
+
591
+ //#endregion
592
+ //#region src/shared/schema.ts
593
+ const ErrorResponseSchema = z.object({
594
+ code: z.number(),
595
+ msg: z.string()
596
+ });
597
+
598
+ //#endregion
599
+ //#region src/shared/base-rest-client.ts
600
+ var BaseRestClient = class {
601
+ credentials;
602
+ httpCleint;
603
+ constructor({ baseUrl, credentials, httpOptions }) {
604
+ this.credentials = credentials;
605
+ this.httpCleint = new Client(baseUrl, {
606
+ allowH2: true,
607
+ ...httpOptions
608
+ });
609
+ }
610
+ toSearchParams(rawParams) {
611
+ if (!rawParams) return {};
612
+ return Object.entries(rawParams).reduce((acc, [key, value]) => {
613
+ if (Array.isArray(value)) {
614
+ acc[key] = JSON.stringify(value);
615
+ return acc;
616
+ }
617
+ if (value !== void 0 && value !== null) acc[key] = String(value);
618
+ return acc;
619
+ }, {});
620
+ }
621
+ parseErrorResponse(endpoint, statusCode, json) {
622
+ const result = ErrorResponseSchema.safeParse(json);
623
+ if (result.error) throw new ApiError({
624
+ endpoint,
625
+ metadata: {
626
+ error: result.error,
627
+ json
628
+ }
629
+ });
630
+ switch (statusCode) {
631
+ case 418: throw new WeightError({
632
+ message: result.data.msg,
633
+ endpoint
634
+ });
635
+ case 400: throw new MalformedParamError({
636
+ endpoint,
637
+ message: result.data.msg
638
+ });
639
+ default: throw new ApiError({
640
+ endpoint,
641
+ metadata: { json }
642
+ });
643
+ }
644
+ }
645
+ async parseResponse(schema, response, endpoint) {
646
+ const json = await response.body.json();
647
+ if (response.statusCode === 200) {
648
+ const result = z4.safeParse(schema, json);
649
+ if (result.error) throw new ValidationError({
650
+ endpoint,
651
+ input: json,
652
+ error: result.error
653
+ });
654
+ return result.data;
655
+ }
656
+ throw this.parseErrorResponse(endpoint, response.statusCode, json);
657
+ }
658
+ async publicRequest({ endpoint, params, schema }) {
659
+ const searchParams = this.toSearchParams(params);
660
+ const response = await this.httpCleint.request({
661
+ method: "GET",
662
+ path: endpoint,
663
+ query: searchParams,
664
+ headers: { "X-MBX-APIKEY": this.credentials?.secret }
665
+ });
666
+ return this.parseResponse(schema, response, endpoint);
667
+ }
668
+ async privateRequest({ endpoint, params, schema, method }) {
669
+ if (!this.credentials) throw new ApiError({
670
+ endpoint,
671
+ metadata: { cause: "Empty credentials" }
672
+ });
673
+ const searchParams = this.toSearchParams(params);
674
+ if (this.credentials) {
675
+ searchParams["timestamp"] = (/* @__PURE__ */ new Date()).getTime().toString();
676
+ searchParams["signature"] = this.sign(new URLSearchParams(searchParams).toString(), this.credentials.secret);
677
+ }
678
+ const response = await this.httpCleint.request({
679
+ method,
680
+ path: endpoint,
681
+ query: method !== "POST" ? searchParams : void 0,
682
+ body: method === "POST" ? new URLSearchParams(searchParams).toString() : void 0,
683
+ headers: { "X-MBX-APIKEY": this.credentials?.key }
684
+ });
685
+ return this.parseResponse(schema, response, endpoint);
686
+ }
687
+ sign(message, secret) {
688
+ return createHmac("sha256", secret).update(message).digest("hex");
689
+ }
690
+ };
691
+
692
+ //#endregion
693
+ //#region src/rest/futures/client.ts
694
+ var FuturesRestClient = class extends BaseRestClient {
695
+ constructor({ baseUrl = "https://fapi.binance.com", credentials, httpOptions }) {
696
+ super({
697
+ baseUrl,
698
+ credentials,
699
+ httpOptions
700
+ });
701
+ }
702
+ async testConnectivity() {
703
+ return this.publicRequest({
704
+ endpoint: "/fapi/v1/ping",
705
+ schema: FuturesTestConnectivitySchema
706
+ });
707
+ }
708
+ async checkServerTime() {
709
+ return this.publicRequest({
710
+ endpoint: "/fapi/v1/time",
711
+ schema: FuturesCheckServerTimeSchema
712
+ });
713
+ }
714
+ async exchangeInformation() {
715
+ return this.publicRequest({
716
+ endpoint: "/fapi/v1/exchangeInfo",
717
+ schema: FuturesExchangeInfoSchema
718
+ });
719
+ }
720
+ async orderBook(params) {
721
+ return this.publicRequest({
722
+ params,
723
+ endpoint: "/fapi/v1/depth",
724
+ schema: FuturesOrderBookSchema
725
+ });
726
+ }
727
+ async recentTrades(params) {
728
+ return this.publicRequest({
729
+ params,
730
+ endpoint: "/fapi/v1/trades",
731
+ schema: FuturesRecentTradesSchema
732
+ });
733
+ }
734
+ async oldTradesLookup(params) {
735
+ return this.privateRequest({
736
+ method: "GET",
737
+ params,
738
+ endpoint: "/fapi/v1/historicalTrades",
739
+ schema: FuturesOldTradesLookupSchema
740
+ });
741
+ }
742
+ async aggregateTrades(params) {
743
+ return this.publicRequest({
744
+ params,
745
+ endpoint: "/fapi/v1/aggTrades",
746
+ schema: FuturesAggregateTradesSchema
747
+ });
748
+ }
749
+ async klineData(params) {
750
+ return this.publicRequest({
751
+ params,
752
+ endpoint: "/fapi/v1/klines",
753
+ schema: FuturesKlineDataSchema
754
+ });
755
+ }
756
+ async continuousContractKlineData(params) {
757
+ return this.publicRequest({
758
+ params,
759
+ endpoint: "/fapi/v1/continuousKlines",
760
+ schema: FuturesKlineDataSchema
761
+ });
762
+ }
763
+ async indexPriceKlineData(params) {
764
+ return this.publicRequest({
765
+ params,
766
+ endpoint: "/fapi/v1/indexPriceKlines",
767
+ schema: FuturesKlineDataSchema
768
+ });
769
+ }
770
+ async markPriceKlineData(params) {
771
+ return this.publicRequest({
772
+ params,
773
+ endpoint: "/fapi/v1/markPriceKlines",
774
+ schema: FuturesKlineDataSchema
775
+ });
776
+ }
777
+ async premiumIndexKlineData(params) {
778
+ return this.publicRequest({
779
+ params,
780
+ endpoint: "/fapi/v1/premiumIndexKlines",
781
+ schema: FuturesKlineDataSchema
782
+ });
783
+ }
784
+ async markPrice(params) {
785
+ const isSingle = !!params?.symbol;
786
+ return this.publicRequest({
787
+ params,
788
+ endpoint: "/fapi/v1/premiumIndex",
789
+ schema: isSingle ? FuturesMarkPriceSchema : z$1.array(FuturesMarkPriceSchema)
790
+ });
791
+ }
792
+ async fundingRateHistory(params) {
793
+ return this.publicRequest({
794
+ params,
795
+ endpoint: "/fapi/v1/fundingRate",
796
+ schema: FuturesFundingRateSchema
797
+ });
798
+ }
799
+ async fundingRateInfo() {
800
+ return this.publicRequest({
801
+ endpoint: "/fapi/v1/fundingInfo",
802
+ schema: FuturesFundingInfoSchema
803
+ });
804
+ }
805
+ async ticker24h(params) {
806
+ return this.publicRequest({
807
+ params,
808
+ endpoint: "/fapi/v1/ticker/24hr",
809
+ schema: params?.symbol ? FuturesTicker24hSchema : z$1.array(FuturesTicker24hSchema)
810
+ });
811
+ }
812
+ async symbolPriceTicker(params) {
813
+ return this.publicRequest({
814
+ params,
815
+ endpoint: "/fapi/v2/ticker/price",
816
+ schema: params?.symbol ? FuturesSymbolPriceSchema : z$1.array(FuturesSymbolPriceSchema)
817
+ });
818
+ }
819
+ async bookTicker(params) {
820
+ return this.publicRequest({
821
+ params,
822
+ endpoint: "/fapi/v1/ticker/bookTicker",
823
+ schema: params?.symbol ? FuturesBookTickerSchema : z$1.array(FuturesBookTickerSchema)
824
+ });
825
+ }
826
+ async quarterlySettlementPrices(params) {
827
+ return this.publicRequest({
828
+ params,
829
+ endpoint: "/futures/data/delivery-price",
830
+ schema: FuturesDeliveryPriceSchema
831
+ });
832
+ }
833
+ async openInterest(params) {
834
+ return this.publicRequest({
835
+ params,
836
+ endpoint: "/fapi/v1/openInterest",
837
+ schema: FuturesOpenInterestSchema
838
+ });
839
+ }
840
+ async openInterestStats(params) {
841
+ return this.publicRequest({
842
+ params,
843
+ endpoint: "/futures/data/openInterestHist",
844
+ schema: FuturesOpenInterestStatsSchema
845
+ });
846
+ }
847
+ async topLongShortPositionRatio(params) {
848
+ return this.publicRequest({
849
+ params,
850
+ endpoint: "/futures/data/topLongShortPositionRatio",
851
+ schema: FuturesLongShortRatioSchema
852
+ });
853
+ }
854
+ async topLongShortAccountRatio(params) {
855
+ return this.publicRequest({
856
+ params,
857
+ endpoint: "/futures/data/topLongShortAccountRatio",
858
+ schema: FuturesLongShortRatioSchema
859
+ });
860
+ }
861
+ async globalLongShortAccountRatio(params) {
862
+ return this.publicRequest({
863
+ params,
864
+ endpoint: "/futures/data/globalLongShortAccountRatio",
865
+ schema: FuturesLongShortRatioSchema
866
+ });
867
+ }
868
+ async takerBuySellRatio(params) {
869
+ return this.publicRequest({
870
+ params,
871
+ endpoint: "/futures/data/takerlongshortRatio",
872
+ schema: FuturesTakerBuySellRatioSchema
873
+ });
874
+ }
875
+ async basisData(params) {
876
+ return this.publicRequest({
877
+ params,
878
+ endpoint: "/futures/data/basis",
879
+ schema: FuturesBasisSchema
880
+ });
881
+ }
882
+ async compositeIndexInfo(params) {
883
+ const isSingle = !!params?.symbol;
884
+ return await this.publicRequest({
885
+ params,
886
+ endpoint: "/fapi/v1/indexInfo",
887
+ schema: isSingle ? FuturesCompositeIndexSchema : z$1.array(FuturesCompositeIndexSchema)
888
+ });
889
+ }
890
+ async assetIndex(params) {
891
+ return await this.publicRequest({
892
+ params,
893
+ endpoint: "/fapi/v1/assetIndex",
894
+ schema: params?.symbol ? FuturesAssetIndexSchema : z$1.array(FuturesAssetIndexSchema)
895
+ });
896
+ }
897
+ async indexPriceConstituents(params) {
898
+ return this.publicRequest({
899
+ params,
900
+ endpoint: "/fapi/v1/constituents",
901
+ schema: FuturesIndexPriceConstituentsSchema
902
+ });
903
+ }
904
+ async insuranceBalance(params) {
905
+ const isSingle = !!params?.symbol;
906
+ return this.publicRequest({
907
+ params,
908
+ endpoint: "/fapi/v1/insuranceBalance",
909
+ schema: isSingle ? FuturesInsuranceBalanceEntrySchema : z$1.array(FuturesInsuranceBalanceEntrySchema)
910
+ });
911
+ }
912
+ async accountBalance() {
913
+ return this.privateRequest({
914
+ method: "GET",
915
+ endpoint: "/fapi/v3/balance",
916
+ schema: FuturesAccountBalanceSchema
917
+ });
918
+ }
919
+ async accountInformation() {
920
+ return this.privateRequest({
921
+ method: "GET",
922
+ endpoint: "/fapi/v3/account",
923
+ schema: FuturesAccountInfoSchema
924
+ });
925
+ }
926
+ async userCommissionRate(params) {
927
+ return this.privateRequest({
928
+ method: "GET",
929
+ endpoint: "/fapi/v1/commissionRate",
930
+ params,
931
+ schema: FuturesCommissionRateSchema
932
+ });
933
+ }
934
+ async accountConfig() {
935
+ return this.privateRequest({
936
+ method: "GET",
937
+ endpoint: "/fapi/v1/accountConfig",
938
+ schema: FuturesAccountConfigSchema
939
+ });
940
+ }
941
+ async symbolConfig(params) {
942
+ return this.privateRequest({
943
+ method: "GET",
944
+ endpoint: "/fapi/v1/symbolConfig",
945
+ params,
946
+ schema: FuturesSymbolConfigSchema
947
+ });
948
+ }
949
+ async userRateLimit() {
950
+ return this.privateRequest({
951
+ method: "GET",
952
+ endpoint: "/fapi/v1/rateLimit/order",
953
+ schema: FuturesUserRateLimitSchema
954
+ });
955
+ }
956
+ async leverageBrackets(params) {
957
+ return this.privateRequest({
958
+ method: "GET",
959
+ endpoint: "/fapi/v1/leverageBracket",
960
+ params,
961
+ schema: FuturesLeverageBracketSchema
962
+ });
963
+ }
964
+ async positionMode() {
965
+ return this.privateRequest({
966
+ method: "GET",
967
+ endpoint: "/fapi/v1/positionSide/dual",
968
+ schema: FuturesPositionModeSchema
969
+ });
970
+ }
971
+ async incomeHistory(params) {
972
+ return this.privateRequest({
973
+ method: "GET",
974
+ endpoint: "/fapi/v1/income",
975
+ params,
976
+ schema: FuturesIncomeHistorySchema
977
+ });
978
+ }
979
+ async newOrder(params) {
980
+ return this.privateRequest({
981
+ method: "POST",
982
+ endpoint: "/fapi/v1/order",
983
+ params,
984
+ schema: FuturesNewOrderSchema
985
+ });
986
+ }
987
+ };
988
+
989
+ //#endregion
990
+ //#region src/rest/spot/schema.ts
991
+ const SpotTestConnectivitySchema = z.object({});
992
+ const SpotCheckServerTimeSchema = z.object({ serverTime: z.number() });
993
+
994
+ //#endregion
995
+ //#region src/rest/spot/client.ts
996
+ var SpotRestClient = class extends BaseRestClient {
997
+ constructor({ baseUrl = "https://api.binance.com", credentials, httpOptions }) {
998
+ super({
999
+ baseUrl,
1000
+ credentials,
1001
+ httpOptions
1002
+ });
1003
+ }
1004
+ async testConnectivity() {
1005
+ return this.publicRequest({
1006
+ endpoint: "/api/v3/ping",
1007
+ schema: SpotTestConnectivitySchema
1008
+ });
1009
+ }
1010
+ async checkServerTime() {
1011
+ return this.publicRequest({
1012
+ endpoint: "/api/v3/time",
1013
+ schema: SpotCheckServerTimeSchema
1014
+ });
1015
+ }
1016
+ };
1017
+
1018
+ //#endregion
1019
+ //#region src/rest/client.ts
1020
+ var BinanceRestClient = class {
1021
+ futures;
1022
+ spot;
1023
+ constructor(options) {
1024
+ this.futures = new FuturesRestClient({
1025
+ credentials: options?.credentials,
1026
+ baseUrl: options?.baseUrls?.futures
1027
+ });
1028
+ this.spot = new SpotRestClient({
1029
+ credentials: options?.credentials,
1030
+ baseUrl: options?.baseUrls?.spot
1031
+ });
1032
+ }
1033
+ };
1034
+
1035
+ //#endregion
1036
+ //#region src/websocket/typed-event-emitter.ts
1037
+ var Emitter = class {
1038
+ eventTarget = new EventTarget();
1039
+ addEventListener(event, callback, options) {
1040
+ this.eventTarget.addEventListener(event, (event$1) => callback(...event$1.detail), options);
1041
+ }
1042
+ emit(event, ...data) {
1043
+ this.eventTarget.dispatchEvent(new CustomEvent(event, { detail: data }));
1044
+ }
1045
+ };
1046
+
1047
+ //#endregion
1048
+ //#region src/websocket/base/client.ts
1049
+ var BinanceWebsocketClient = class {
1050
+ socket;
1051
+ baseUrl;
1052
+ emitter = new Emitter();
1053
+ subscriptionId = 1;
1054
+ subscriptions = /* @__PURE__ */ new Map();
1055
+ constructor(baseUrl) {
1056
+ this.parseEvent = this.parseEvent.bind(this);
1057
+ this.baseUrl = baseUrl;
1058
+ this.socket = this.createSocket();
1059
+ }
1060
+ createSocket() {
1061
+ if (this.socket) {
1062
+ this.socket.removeEventListener("message", this.parseEvent);
1063
+ this.socket.close();
1064
+ }
1065
+ const socket = new WebSocket(this.baseUrl);
1066
+ socket.addEventListener("message", this.parseEvent);
1067
+ return socket;
1068
+ }
1069
+ sendMessage(data) {
1070
+ this.socket.send(JSON.stringify(data));
1071
+ }
1072
+ parseEvent(e) {
1073
+ if (typeof e.data !== "string") {
1074
+ this.emitter.emit("error", new Error("Message event is not a string", { cause: e.data }));
1075
+ return;
1076
+ }
1077
+ const data = JSON.parse(e.data);
1078
+ if ("id" in data) this.emitter.emit("connectionMessage", data);
1079
+ else this.emitter.emit("marketMessage", data);
1080
+ }
1081
+ async subscribe(...channels) {
1082
+ await this.connect();
1083
+ const pendingChannels = [];
1084
+ for (const channel of channels) if (!this.subscriptions.get(channel)) {
1085
+ pendingChannels.push(channel);
1086
+ this.subscriptions.set(channel, "PENDING_SUBSCRIPTION");
1087
+ }
1088
+ const id = this.subscriptionId;
1089
+ const data = {
1090
+ method: "SUBSCRIBE",
1091
+ params: pendingChannels,
1092
+ id
1093
+ };
1094
+ this.subscriptionId += 1;
1095
+ this.sendMessage(data);
1096
+ return new Promise((resolve, reject) => {
1097
+ const controller = new AbortController();
1098
+ const handler = (data$1) => {
1099
+ if (data$1.id !== id) return;
1100
+ controller.abort();
1101
+ if ("error" in data$1) {
1102
+ for (const channel of pendingChannels) if (this.subscriptions.get(channel) === "PENDING_SUBSCRIPTION") this.subscriptions.delete(channel);
1103
+ this.emitter.emit("error", data$1);
1104
+ reject(/* @__PURE__ */ new Error(`Subscription ${id} failed`));
1105
+ } else {
1106
+ pendingChannels.forEach((channel) => this.subscriptions.set(channel, "SUBSCRIBED"));
1107
+ resolve();
1108
+ }
1109
+ };
1110
+ this.emitter.addEventListener("connectionMessage", handler, { signal: controller.signal });
1111
+ });
1112
+ }
1113
+ async unsubscribe(...channels) {
1114
+ await this.connect();
1115
+ }
1116
+ async reconnect() {
1117
+ this.socket = this.createSocket();
1118
+ await this.connect();
1119
+ const toRestore = [];
1120
+ for (const [channel, state] of this.subscriptions) if (state !== "PENDING_UNSUBSCRIPTION") toRestore.push(channel);
1121
+ if (toRestore.length) await this.subscribe(...toRestore);
1122
+ }
1123
+ async connect() {
1124
+ if (this.socket.readyState === WebSocket.OPEN) return;
1125
+ if (this.socket.readyState === WebSocket.CONNECTING) return new Promise((resolve, reject) => {
1126
+ this.socket.addEventListener("open", () => resolve(), { once: true });
1127
+ this.socket.addEventListener("close", () => reject(), { once: true });
1128
+ });
1129
+ return this.reconnect();
1130
+ }
1131
+ addEventListener(event, callback, options) {
1132
+ this.emitter.addEventListener(event, callback, options);
1133
+ }
1134
+ };
1135
+
1136
+ //#endregion
1137
+ //#region src/websocket/futures/client.ts
1138
+ var FuturesWebsocketClient = class extends BinanceWebsocketClient {
1139
+ constructor(baseUrl = "wss://stream.binance.com:9443/ws") {
1140
+ super(baseUrl);
1141
+ }
1142
+ };
1143
+
1144
+ //#endregion
1145
+ export { ApiError, BinanceRestClient, ErrorMessageParsingError, FuturesWebsocketClient, MalformedParamError, ResponseError, ValidationError, WeightError };