@solncebro/exchange-engine 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 (108) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/LICENSE +21 -0
  3. package/README.md +390 -0
  4. package/dist/auth/binanceAuth.d.ts +9 -0
  5. package/dist/auth/binanceAuth.d.ts.map +1 -0
  6. package/dist/auth/binanceAuth.js +31 -0
  7. package/dist/auth/binanceAuth.js.map +1 -0
  8. package/dist/auth/bybitAuth.d.ts +10 -0
  9. package/dist/auth/bybitAuth.d.ts.map +1 -0
  10. package/dist/auth/bybitAuth.js +23 -0
  11. package/dist/auth/bybitAuth.js.map +1 -0
  12. package/dist/constants/binance.d.ts +9 -0
  13. package/dist/constants/binance.d.ts.map +1 -0
  14. package/dist/constants/binance.js +28 -0
  15. package/dist/constants/binance.js.map +1 -0
  16. package/dist/constants/bybit.d.ts +14 -0
  17. package/dist/constants/bybit.d.ts.map +1 -0
  18. package/dist/constants/bybit.js +33 -0
  19. package/dist/constants/bybit.js.map +1 -0
  20. package/dist/exchanges/BinanceFutures.d.ts +28 -0
  21. package/dist/exchanges/BinanceFutures.d.ts.map +1 -0
  22. package/dist/exchanges/BinanceFutures.js +125 -0
  23. package/dist/exchanges/BinanceFutures.js.map +1 -0
  24. package/dist/exchanges/BinanceSpot.d.ts +28 -0
  25. package/dist/exchanges/BinanceSpot.d.ts.map +1 -0
  26. package/dist/exchanges/BinanceSpot.js +116 -0
  27. package/dist/exchanges/BinanceSpot.js.map +1 -0
  28. package/dist/exchanges/BybitLinear.d.ts +28 -0
  29. package/dist/exchanges/BybitLinear.d.ts.map +1 -0
  30. package/dist/exchanges/BybitLinear.js +131 -0
  31. package/dist/exchanges/BybitLinear.js.map +1 -0
  32. package/dist/exchanges/BybitSpot.d.ts +27 -0
  33. package/dist/exchanges/BybitSpot.d.ts.map +1 -0
  34. package/dist/exchanges/BybitSpot.js +113 -0
  35. package/dist/exchanges/BybitSpot.js.map +1 -0
  36. package/dist/exchanges/Exchange.d.ts +11 -0
  37. package/dist/exchanges/Exchange.d.ts.map +1 -0
  38. package/dist/exchanges/Exchange.js +32 -0
  39. package/dist/exchanges/Exchange.js.map +1 -0
  40. package/dist/http/BaseHttpClient.d.ts +14 -0
  41. package/dist/http/BaseHttpClient.d.ts.map +1 -0
  42. package/dist/http/BaseHttpClient.js +77 -0
  43. package/dist/http/BaseHttpClient.js.map +1 -0
  44. package/dist/http/BinanceFuturesHttpClient.d.ts +53 -0
  45. package/dist/http/BinanceFuturesHttpClient.d.ts.map +1 -0
  46. package/dist/http/BinanceFuturesHttpClient.js +235 -0
  47. package/dist/http/BinanceFuturesHttpClient.js.map +1 -0
  48. package/dist/http/BinanceSpotHttpClient.d.ts +26 -0
  49. package/dist/http/BinanceSpotHttpClient.d.ts.map +1 -0
  50. package/dist/http/BinanceSpotHttpClient.js +98 -0
  51. package/dist/http/BinanceSpotHttpClient.js.map +1 -0
  52. package/dist/http/BybitHttpClient.d.ts +143 -0
  53. package/dist/http/BybitHttpClient.d.ts.map +1 -0
  54. package/dist/http/BybitHttpClient.js +233 -0
  55. package/dist/http/BybitHttpClient.js.map +1 -0
  56. package/dist/index.d.ts +4 -0
  57. package/dist/index.d.ts.map +1 -0
  58. package/dist/index.js +6 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/normalizers/binanceNormalizer.d.ts +79 -0
  61. package/dist/normalizers/binanceNormalizer.d.ts.map +1 -0
  62. package/dist/normalizers/binanceNormalizer.js +133 -0
  63. package/dist/normalizers/binanceNormalizer.js.map +1 -0
  64. package/dist/normalizers/bybitNormalizer.d.ts +79 -0
  65. package/dist/normalizers/bybitNormalizer.d.ts.map +1 -0
  66. package/dist/normalizers/bybitNormalizer.js +150 -0
  67. package/dist/normalizers/bybitNormalizer.js.map +1 -0
  68. package/dist/precision/precision.d.ts +6 -0
  69. package/dist/precision/precision.d.ts.map +1 -0
  70. package/dist/precision/precision.js +29 -0
  71. package/dist/precision/precision.js.map +1 -0
  72. package/dist/types/common.d.ts +86 -0
  73. package/dist/types/common.d.ts.map +1 -0
  74. package/dist/types/common.js +3 -0
  75. package/dist/types/common.js.map +1 -0
  76. package/dist/types/exchange.d.ts +43 -0
  77. package/dist/types/exchange.d.ts.map +1 -0
  78. package/dist/types/exchange.js +3 -0
  79. package/dist/types/exchange.js.map +1 -0
  80. package/dist/types/index.d.ts +3 -0
  81. package/dist/types/index.d.ts.map +1 -0
  82. package/dist/types/index.js +3 -0
  83. package/dist/types/index.js.map +1 -0
  84. package/dist/ws/BinanceFuturesPublicStream.d.ts +30 -0
  85. package/dist/ws/BinanceFuturesPublicStream.d.ts.map +1 -0
  86. package/dist/ws/BinanceFuturesPublicStream.js +216 -0
  87. package/dist/ws/BinanceFuturesPublicStream.js.map +1 -0
  88. package/dist/ws/BinanceSpotPublicStream.d.ts +24 -0
  89. package/dist/ws/BinanceSpotPublicStream.d.ts.map +1 -0
  90. package/dist/ws/BinanceSpotPublicStream.js +186 -0
  91. package/dist/ws/BinanceSpotPublicStream.js.map +1 -0
  92. package/dist/ws/BinanceUserDataStream.d.ts +23 -0
  93. package/dist/ws/BinanceUserDataStream.d.ts.map +1 -0
  94. package/dist/ws/BinanceUserDataStream.js +48 -0
  95. package/dist/ws/BinanceUserDataStream.js.map +1 -0
  96. package/dist/ws/BybitPrivateStream.d.ts +25 -0
  97. package/dist/ws/BybitPrivateStream.d.ts.map +1 -0
  98. package/dist/ws/BybitPrivateStream.js +79 -0
  99. package/dist/ws/BybitPrivateStream.js.map +1 -0
  100. package/dist/ws/BybitPublicStream.d.ts +25 -0
  101. package/dist/ws/BybitPublicStream.d.ts.map +1 -0
  102. package/dist/ws/BybitPublicStream.js +178 -0
  103. package/dist/ws/BybitPublicStream.js.map +1 -0
  104. package/dist/ws/BybitTradeStream.d.ts +27 -0
  105. package/dist/ws/BybitTradeStream.d.ts.map +1 -0
  106. package/dist/ws/BybitTradeStream.js +146 -0
  107. package/dist/ws/BybitTradeStream.js.map +1 -0
  108. package/package.json +58 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,54 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2026-02-25
9
+
10
+ ### Added
11
+ - Initial release of @solncebro/exchange-engine
12
+ - Unified API for Binance and Bybit
13
+ - Support for Binance Spot and Futures markets
14
+ - Support for Bybit Spot and Linear Perpetual markets
15
+ - REST API endpoints:
16
+ - `loadMarkets()` — fetch and cache market information
17
+ - `fetchTickers()` — get current prices for all symbols
18
+ - `fetchKlines()` — historical candlestick data
19
+ - `fetchBalance()` — account balance
20
+ - `fetchPosition()` — futures position info (futures only)
21
+ - `createOrderWs()` — place orders via WebSocket
22
+ - `setLeverage()` — adjust position leverage (futures only)
23
+ - `setMarginMode()` — isolated or cross margin (futures only)
24
+ - WebSocket subscriptions:
25
+ - Real-time kline updates (`subscribeKlines()`)
26
+ - Ticker price updates (Binance Futures)
27
+ - Type-safe unified types:
28
+ - `Kline` — candlestick data
29
+ - `Ticker` — current price and 24h change
30
+ - `Position` — futures position details
31
+ - `Order` — placed order info
32
+ - `Market` — market metadata
33
+ - `Balance` — account balance
34
+ - Automatic WebSocket reconnection with exponential backoff
35
+ - Structured logging via custom logger interface
36
+ - Price and amount precision formatting
37
+ - Error normalization across exchanges
38
+
39
+ ### Internal
40
+ - Separate HTTP clients for each exchange
41
+ - Exchange-specific normalizers (Binance and Bybit)
42
+ - Public and private WebSocket streams
43
+ - Auth utilities (HMAC signing, headers)
44
+ - Four exchange implementations: BinanceFutures, BinanceSpot, BybitLinear, BybitSpot
45
+ - Factory pattern via unified `Exchange` entry point
46
+
47
+ ### Notes
48
+ - Binance spot and futures use separate rate limits
49
+ - Bybit combines spot and linear in single unified API
50
+ - Public endpoints (markets, klines) do not require API keys
51
+ - Private endpoints (balance, position, orders) require valid credentials
52
+ - WebSocket subscriptions are stateless and can be re-established on reconnect
53
+
54
+ [0.1.0]: https://github.com/solncebro/exchange-engine/releases/tag/v0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 solncebro
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,390 @@
1
+ # @solncebro/exchange-engine
2
+
3
+ Universal TypeScript client library for cryptocurrency trading on Binance and Bybit with unified API, WebSocket support, and native type safety.
4
+
5
+ ## Features
6
+
7
+ - 🔀 **Single API for multiple exchanges** — same code works with Binance or Bybit
8
+ - 🎯 **Type-safe unified types** — all responses normalized to consistent types (Kline, Ticker, Position, etc.)
9
+ - 📊 **REST & WebSocket support** — fetch historical data and subscribe to real-time streams
10
+ - 🔄 **Automatic reconnection** — resilient WebSocket connections with exponential backoff
11
+ - 📝 **Comprehensive logging** — built-in structured logging via custom logger interface
12
+ - 🚀 **Zero dependencies** — only axios and websocket-engine
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @solncebro/exchange-engine
18
+ # or
19
+ yarn add @solncebro/exchange-engine
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ```typescript
25
+ import { Exchange } from '@solncebro/exchange-engine';
26
+ import { pinoLogger } from './logger'; // your logger instance
27
+
28
+ // Create exchange instance (works identically for 'binance' or 'bybit')
29
+ const exchange = new Exchange('binance', {
30
+ config: { apiKey: process.env.API_KEY, secret: process.env.API_SECRET },
31
+ logger: pinoLogger,
32
+ onNotify: (msg) => telegramBot.send(msg), // optional notifications
33
+ });
34
+
35
+ // Load markets
36
+ await exchange.futures.loadMarkets();
37
+
38
+ // Fetch historical klines
39
+ const klines = await exchange.futures.fetchKlines('BTCUSDT', '1h', { limit: 100 });
40
+ console.log(klines[0]); // { openTime, open, high, low, close, volume, ... }
41
+
42
+ // Get current tickers
43
+ const tickers = await exchange.futures.fetchTickers();
44
+
45
+ // Subscribe to real-time klines
46
+ exchange.futures.subscribeKlines({
47
+ symbol: 'BTCUSDT',
48
+ interval: '1m',
49
+ handler: (kline) => {
50
+ console.log(`[${kline.openTime}] ${kline.close}`);
51
+ },
52
+ });
53
+
54
+ // Create an order
55
+ const order = await exchange.futures.createOrderWs({
56
+ symbol: 'BTCUSDT',
57
+ type: 'market',
58
+ side: 'buy',
59
+ amount: 0.01,
60
+ price: 0, // ignored for market orders
61
+ params: {}, // exchange-specific params
62
+ });
63
+
64
+ // Fetch position info
65
+ const position = await exchange.futures.fetchPosition('BTCUSDT');
66
+ console.log(`Leverage: ${position.leverage}, Contracts: ${position.contracts}`);
67
+
68
+ // Set leverage
69
+ await exchange.futures.setLeverage(10, 'BTCUSDT');
70
+
71
+ // Close connection
72
+ await exchange.close();
73
+ ```
74
+
75
+ ## API Reference
76
+
77
+ ### Exchange (Main Entry Point)
78
+
79
+ ```typescript
80
+ const exchange = new Exchange('binance' | 'bybit', {
81
+ config: { apiKey: string; secret: string; recvWindow?: number };
82
+ logger: ExchangeLogger;
83
+ onNotify?: (message: string) => void | Promise<void>;
84
+ });
85
+
86
+ // Access exchange clients
87
+ exchange.futures // BinanceFutures | BybitLinear
88
+ exchange.spot // BinanceSpot | BybitSpot
89
+
90
+ // Cleanup
91
+ await exchange.close();
92
+ ```
93
+
94
+ ### ExchangeClient Interface
95
+
96
+ All four classes (BinanceFutures, BinanceSpot, BybitLinear, BybitSpot) implement this interface:
97
+
98
+ #### Market Data (REST)
99
+
100
+ ```typescript
101
+ // Load and cache market information
102
+ await client.loadMarkets(reload?: boolean): Promise<MarketBySymbol>;
103
+
104
+ // Get all markets (already loaded)
105
+ const markets = client.markets; // Record<string, Market>
106
+
107
+ // Fetch current ticker prices
108
+ await client.fetchTickers(): Promise<TickerBySymbol>;
109
+
110
+ // Fetch historical candlestick data
111
+ await client.fetchKlines(
112
+ symbol: string,
113
+ interval: KlineInterval,
114
+ opts?: { limit?: number; startTime?: number; endTime?: number }
115
+ ): Promise<Kline[]>;
116
+
117
+ // Get account balance
118
+ await client.fetchBalance(): Promise<BalanceByAsset>;
119
+ ```
120
+
121
+ #### Trading (REST + WebSocket)
122
+
123
+ ```typescript
124
+ // Create order via WebSocket (recommended for speed)
125
+ await client.createOrderWs({
126
+ symbol: string;
127
+ type: 'market' | 'limit';
128
+ side: 'buy' | 'sell';
129
+ amount: number;
130
+ price: number;
131
+ params?: Record<string, unknown>; // hedgeMode, timeInForce, etc.
132
+ }): Promise<Order>;
133
+ ```
134
+
135
+ #### Futures-Specific
136
+
137
+ ```typescript
138
+ // Fetch position details
139
+ await client.fetchPosition(symbol: string): Promise<Position>;
140
+
141
+ // Set leverage (Binance: 2-125x, Bybit: 1-99.5x)
142
+ await client.setLeverage(leverage: number, symbol: string): Promise<void>;
143
+
144
+ // Set margin mode
145
+ await client.setMarginMode(marginMode: 'isolated' | 'cross', symbol: string): Promise<void>;
146
+ ```
147
+
148
+ #### Real-Time Data (WebSocket)
149
+
150
+ ```typescript
151
+ // Subscribe to kline updates
152
+ client.subscribeKlines({
153
+ symbol: string;
154
+ interval: KlineInterval;
155
+ handler: (kline: Kline) => void;
156
+ }): void;
157
+
158
+ // Unsubscribe
159
+ client.unsubscribeKlines({ symbol, interval, handler }): void;
160
+ ```
161
+
162
+ #### Precision
163
+
164
+ ```typescript
165
+ // Format amount to exchange precision
166
+ const formatted = client.amountToPrecision('BTCUSDT', 0.12345);
167
+
168
+ // Format price to exchange precision
169
+ const formatted = client.priceToPrecision('BTCUSDT', 65432.1);
170
+ ```
171
+
172
+ ### Unified Types
173
+
174
+ All types are normalized across exchanges. No raw exchange formats leak out.
175
+
176
+ ```typescript
177
+ // Candlestick
178
+ interface Kline {
179
+ openTime: number;
180
+ open: number;
181
+ high: number;
182
+ low: number;
183
+ close: number;
184
+ volume: number;
185
+ closeTime: number;
186
+ quoteVolume: number;
187
+ trades: number;
188
+ }
189
+
190
+ // Current price
191
+ interface Ticker {
192
+ symbol: string;
193
+ close: number;
194
+ percentage: number; // 24h change %
195
+ timestamp: number;
196
+ }
197
+
198
+ // Market metadata
199
+ interface Market {
200
+ symbol: string;
201
+ baseAsset: string;
202
+ quoteAsset: string;
203
+ settle: string;
204
+ active: boolean;
205
+ type: 'spot' | 'swap' | 'future';
206
+ linear: boolean;
207
+ contractSize: number;
208
+ filter: MarketFilter;
209
+ }
210
+
211
+ // Open position (futures)
212
+ interface Position {
213
+ symbol: string;
214
+ side: 'long' | 'short' | 'both';
215
+ contracts: number;
216
+ entryPrice: number;
217
+ markPrice: number;
218
+ unrealizedPnl: number;
219
+ leverage: number;
220
+ marginMode: 'isolated' | 'cross';
221
+ liquidationPrice: number;
222
+ info: Record<string, unknown>; // raw exchange data
223
+ }
224
+
225
+ // Placed order
226
+ interface Order {
227
+ id: string;
228
+ symbol: string;
229
+ side: 'buy' | 'sell';
230
+ type: 'market' | 'limit';
231
+ amount: number;
232
+ price: number;
233
+ status: string;
234
+ timestamp: number;
235
+ }
236
+
237
+ // Account balance
238
+ interface Balance {
239
+ asset: string;
240
+ free: number;
241
+ locked: number;
242
+ total: number;
243
+ }
244
+ ```
245
+
246
+ ## Logger Interface
247
+
248
+ Provide any logger that implements this interface:
249
+
250
+ ```typescript
251
+ interface ExchangeLogger {
252
+ debug(message: string): void;
253
+ info(message: string): void;
254
+ warn(message: string): void;
255
+ error(message: string): void;
256
+ fatal(message: string): void;
257
+ }
258
+ ```
259
+
260
+ ### Example with Pino
261
+
262
+ ```typescript
263
+ import pino from 'pino';
264
+
265
+ const logger = pino({
266
+ level: 'info',
267
+ transport: {
268
+ target: 'pino-pretty',
269
+ options: { colorize: true },
270
+ },
271
+ });
272
+
273
+ const exchange = new Exchange('binance', {
274
+ config: { apiKey, secret },
275
+ logger, // pino instance is compatible
276
+ });
277
+ ```
278
+
279
+ ## Exchange Differences
280
+
281
+ ### API Keys & Permissions
282
+
283
+ - **Binance**: Read, Trade, Withdraw permissions (for different features)
284
+ - **Bybit**: Single API key handles all
285
+
286
+ ### Order Placement
287
+
288
+ - **Binance**: `createOrderWs()` uses REST (faster than WS)
289
+ - **Bybit**: `createOrderWs()` uses dedicated trade WebSocket stream
290
+
291
+ ### Position Modes
292
+
293
+ - **Binance**: Supports Hedge Mode (separate long/short) and One-Way Mode
294
+ - **Bybit**: Always supports both buy and sell sides simultaneously
295
+
296
+ ### Funding Rates
297
+
298
+ - **Binance**: 8 times per day at fixed UTC times
299
+ - **Bybit**: Hourly funding
300
+
301
+ These differences are transparent — the same code works for both.
302
+
303
+ ## Performance Tips
304
+
305
+ 1. **Batch requests** — use `Promise.all()` for multiple operations
306
+ ```typescript
307
+ const [tickers, position, balance] = await Promise.all([
308
+ client.fetchTickers(),
309
+ client.fetchPosition('BTCUSDT'),
310
+ client.fetchBalance(),
311
+ ]);
312
+ ```
313
+
314
+ 2. **Reuse markets** — call `loadMarkets()` once at startup
315
+ ```typescript
316
+ await client.loadMarkets();
317
+ const symbols = Object.keys(client.markets);
318
+ ```
319
+
320
+ 3. **Limit historical data** — fetch only needed range
321
+ ```typescript
322
+ const klines = await client.fetchKlines('BTCUSDT', '1h', {
323
+ limit: 100,
324
+ startTime: Date.now() - 100 * 60 * 60 * 1000, // last 100 hours
325
+ });
326
+ ```
327
+
328
+ 4. **Subscribe instead of polling** — WebSocket is more efficient
329
+ ```typescript
330
+ // Instead of:
331
+ setInterval(() => fetchTickers(), 5000);
332
+
333
+ // Use:
334
+ client.subscribeKlines({ symbol, interval, handler });
335
+ ```
336
+
337
+ ## Error Handling
338
+
339
+ All errors are logged and thrown. Wrap calls in try-catch:
340
+
341
+ ```typescript
342
+ try {
343
+ await exchange.futures.setLeverage(100, 'BTCUSDT');
344
+ } catch (error) {
345
+ console.error(`Failed to set leverage: ${error.message}`);
346
+ // error has code, status, response fields for detailed handling
347
+ }
348
+ ```
349
+
350
+ ## Extending the Library
351
+
352
+ Adding new endpoints follows a standard pattern:
353
+
354
+ 1. **HTTP Client** → add method to `BinanceFuturesHttpClient` or `BybitHttpClient`
355
+ 2. **Normalizer** → add raw type + normalization function
356
+ 3. **Interface** → add method to `ExchangeClient`
357
+ 4. **Implementation** → implement in all 4 exchange classes
358
+
359
+ Example: adding `fetchOpenInterest(symbol)`
360
+
361
+ ```typescript
362
+ // 1. In BinanceFuturesHttpClient
363
+ private async fetchOpenInterestRaw(symbol: string): Promise<BinanceRawOpenInterest> {
364
+ return this.get('/fapi/v1/openInterest', { symbol });
365
+ }
366
+
367
+ // 2. In binanceNormalizer.ts
368
+ export function normalizeOpenInterest(raw: BinanceRawOpenInterest): OpenInterest {
369
+ return { symbol: raw.symbol, openInterest: parseFloat(raw.openInterest) };
370
+ }
371
+
372
+ // 3. In ExchangeClient interface
373
+ fetchOpenInterest(symbol: string): Promise<OpenInterest>;
374
+
375
+ // 4. In BinanceFutures
376
+ async fetchOpenInterest(symbol: string): Promise<OpenInterest> {
377
+ const raw = await this.httpClient.fetchOpenInterestRaw(symbol);
378
+ return normalizeOpenInterest(raw);
379
+ }
380
+ ```
381
+
382
+ ## License
383
+
384
+ MIT
385
+
386
+ ## Support
387
+
388
+ - GitHub Issues: [solncebro/exchange-engine](https://github.com/solncebro/exchange-engine/issues)
389
+ - Documentation: See inline JSDoc comments
390
+ - Examples: Check `examples/` directory
@@ -0,0 +1,9 @@
1
+ export declare function buildBinanceSignature(queryString: string, secret: string): string;
2
+ export interface BuildBinanceSignedParamsArgs {
3
+ params: Record<string, string | number | boolean>;
4
+ secret: string;
5
+ recvWindow?: number;
6
+ }
7
+ export declare function buildBinanceSignedParams(args: BuildBinanceSignedParamsArgs): Record<string, string | number>;
8
+ export declare function buildBinanceAuthHeaders(apiKey: string): Record<string, string>;
9
+ //# sourceMappingURL=binanceAuth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binanceAuth.d.ts","sourceRoot":"","sources":["../../src/auth/binanceAuth.ts"],"names":[],"mappings":"AAEA,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjF;AAED,MAAM,WAAW,4BAA4B;IAC3C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,4BAA4B,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAkB5G;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAI9E"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.buildBinanceSignature = buildBinanceSignature;
7
+ exports.buildBinanceSignedParams = buildBinanceSignedParams;
8
+ exports.buildBinanceAuthHeaders = buildBinanceAuthHeaders;
9
+ const crypto_1 = __importDefault(require("crypto"));
10
+ function buildBinanceSignature(queryString, secret) {
11
+ return crypto_1.default.createHmac('sha256', secret).update(queryString).digest('hex');
12
+ }
13
+ function buildBinanceSignedParams(args) {
14
+ const { params, secret, recvWindow = 5000 } = args;
15
+ const timestamp = Date.now();
16
+ const signedParams = {
17
+ ...params,
18
+ timestamp,
19
+ recvWindow,
20
+ };
21
+ const queryString = new URLSearchParams(Object.entries(signedParams).map(([k, v]) => [k, String(v)])).toString();
22
+ const signature = buildBinanceSignature(queryString, secret);
23
+ signedParams.signature = signature;
24
+ return signedParams;
25
+ }
26
+ function buildBinanceAuthHeaders(apiKey) {
27
+ return {
28
+ 'X-MBX-APIKEY': apiKey,
29
+ };
30
+ }
31
+ //# sourceMappingURL=binanceAuth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binanceAuth.js","sourceRoot":"","sources":["../../src/auth/binanceAuth.ts"],"names":[],"mappings":";;;;;AAEA,sDAEC;AAQD,4DAkBC;AAED,0DAIC;AApCD,oDAA4B;AAE5B,SAAgB,qBAAqB,CAAC,WAAmB,EAAE,MAAc;IACvE,OAAO,gBAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC/E,CAAC;AAQD,SAAgB,wBAAwB,CAAC,IAAkC;IACzE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;IACnD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,YAAY,GAAoC;QACpD,GAAG,MAAM;QACT,SAAS;QACT,UAAU;KACX,CAAC;IAEF,MAAM,WAAW,GAAG,IAAI,eAAe,CACrC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAuB,CACnF,CAAC,QAAQ,EAAE,CAAC;IAEb,MAAM,SAAS,GAAG,qBAAqB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAE7D,YAAY,CAAC,SAAS,GAAG,SAAS,CAAC;IAEnC,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,SAAgB,uBAAuB,CAAC,MAAc;IACpD,OAAO;QACL,cAAc,EAAE,MAAM;KACvB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ export interface BuildBybitAuthHeadersArgs {
2
+ apiKey: string;
3
+ secret: string;
4
+ timestamp: number;
5
+ recvWindow?: number;
6
+ payload: string;
7
+ }
8
+ export declare function buildBybitAuthHeaders(args: BuildBybitAuthHeadersArgs): Record<string, string>;
9
+ export declare function getCurrentTimestamp(): number;
10
+ //# sourceMappingURL=bybitAuth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bybitAuth.d.ts","sourceRoot":"","sources":["../../src/auth/bybitAuth.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,yBAAyB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAW7F;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.buildBybitAuthHeaders = buildBybitAuthHeaders;
7
+ exports.getCurrentTimestamp = getCurrentTimestamp;
8
+ const crypto_1 = __importDefault(require("crypto"));
9
+ function buildBybitAuthHeaders(args) {
10
+ const { apiKey, secret, timestamp, recvWindow = 5000, payload } = args;
11
+ const signPayload = `${timestamp}${apiKey}${recvWindow}${payload}`;
12
+ const signature = crypto_1.default.createHmac('sha256', secret).update(signPayload).digest('hex');
13
+ return {
14
+ 'X-BAPI-API-KEY': apiKey,
15
+ 'X-BAPI-TIMESTAMP': String(timestamp),
16
+ 'X-BAPI-SIGN': signature,
17
+ 'X-BAPI-RECV-WINDOW': String(recvWindow),
18
+ };
19
+ }
20
+ function getCurrentTimestamp() {
21
+ return Date.now();
22
+ }
23
+ //# sourceMappingURL=bybitAuth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bybitAuth.js","sourceRoot":"","sources":["../../src/auth/bybitAuth.ts"],"names":[],"mappings":";;;;;AAUA,sDAWC;AAED,kDAEC;AAzBD,oDAA4B;AAU5B,SAAgB,qBAAqB,CAAC,IAA+B;IACnE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACvE,MAAM,WAAW,GAAG,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,EAAE,CAAC;IACnE,MAAM,SAAS,GAAG,gBAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAExF,OAAO;QACL,gBAAgB,EAAE,MAAM;QACxB,kBAAkB,EAAE,MAAM,CAAC,SAAS,CAAC;QACrC,aAAa,EAAE,SAAS;QACxB,oBAAoB,EAAE,MAAM,CAAC,UAAU,CAAC;KACzC,CAAC;AACJ,CAAC;AAED,SAAgB,mBAAmB;IACjC,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC;AACpB,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare const BINANCE_SPOT_BASE_URL = "https://api.binance.com";
2
+ export declare const BINANCE_FUTURES_BASE_URL = "https://fapi.binance.com";
3
+ export declare const BINANCE_FUTURES_TESTNET_BASE_URL = "https://testnet.binancefuture.com";
4
+ export declare const BINANCE_FUTURES_WS_STREAM_URL = "wss://fstream.binance.com/ws";
5
+ export declare const BINANCE_FUTURES_WS_COMBINED_URL = "wss://fstream.binance.com/stream";
6
+ export declare const BINANCE_SPOT_WS_STREAM_URL = "wss://stream.binance.com:9443/ws";
7
+ export declare const BINANCE_REQUEST_TIMEOUT = 30000;
8
+ export declare const BINANCE_KLINE_INTERVAL: Record<string, string>;
9
+ //# sourceMappingURL=binance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binance.d.ts","sourceRoot":"","sources":["../../src/constants/binance.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,4BAA4B,CAAC;AAC/D,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AACnE,eAAO,MAAM,gCAAgC,sCAAsC,CAAC;AAEpF,eAAO,MAAM,6BAA6B,iCAAiC,CAAC;AAC5E,eAAO,MAAM,+BAA+B,qCAAqC,CAAC;AAClF,eAAO,MAAM,0BAA0B,qCAAqC,CAAC;AAE7E,eAAO,MAAM,uBAAuB,QAAQ,CAAC;AAG7C,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAezD,CAAC"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BINANCE_KLINE_INTERVAL = exports.BINANCE_REQUEST_TIMEOUT = exports.BINANCE_SPOT_WS_STREAM_URL = exports.BINANCE_FUTURES_WS_COMBINED_URL = exports.BINANCE_FUTURES_WS_STREAM_URL = exports.BINANCE_FUTURES_TESTNET_BASE_URL = exports.BINANCE_FUTURES_BASE_URL = exports.BINANCE_SPOT_BASE_URL = void 0;
4
+ exports.BINANCE_SPOT_BASE_URL = 'https://api.binance.com';
5
+ exports.BINANCE_FUTURES_BASE_URL = 'https://fapi.binance.com';
6
+ exports.BINANCE_FUTURES_TESTNET_BASE_URL = 'https://testnet.binancefuture.com';
7
+ exports.BINANCE_FUTURES_WS_STREAM_URL = 'wss://fstream.binance.com/ws';
8
+ exports.BINANCE_FUTURES_WS_COMBINED_URL = 'wss://fstream.binance.com/stream';
9
+ exports.BINANCE_SPOT_WS_STREAM_URL = 'wss://stream.binance.com:9443/ws';
10
+ exports.BINANCE_REQUEST_TIMEOUT = 30000; // 30 seconds
11
+ // Маппинг унифицированного KlineInterval -> формат Binance (совпадает 1:1)
12
+ exports.BINANCE_KLINE_INTERVAL = {
13
+ '1m': '1m',
14
+ '3m': '3m',
15
+ '5m': '5m',
16
+ '15m': '15m',
17
+ '30m': '30m',
18
+ '1h': '1h',
19
+ '2h': '2h',
20
+ '4h': '4h',
21
+ '6h': '6h',
22
+ '12h': '12h',
23
+ '1d': '1d',
24
+ '3d': '3d',
25
+ '1w': '1w',
26
+ '1M': '1M',
27
+ };
28
+ //# sourceMappingURL=binance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binance.js","sourceRoot":"","sources":["../../src/constants/binance.ts"],"names":[],"mappings":";;;AAAa,QAAA,qBAAqB,GAAG,yBAAyB,CAAC;AAClD,QAAA,wBAAwB,GAAG,0BAA0B,CAAC;AACtD,QAAA,gCAAgC,GAAG,mCAAmC,CAAC;AAEvE,QAAA,6BAA6B,GAAG,8BAA8B,CAAC;AAC/D,QAAA,+BAA+B,GAAG,kCAAkC,CAAC;AACrE,QAAA,0BAA0B,GAAG,kCAAkC,CAAC;AAEhE,QAAA,uBAAuB,GAAG,KAAK,CAAC,CAAC,aAAa;AAE3D,2EAA2E;AAC9D,QAAA,sBAAsB,GAA2B;IAC5D,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,KAAK;IACZ,KAAK,EAAE,KAAK;IACZ,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,KAAK;IACZ,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;CACX,CAAC"}
@@ -0,0 +1,14 @@
1
+ export declare const BYBIT_BASE_URL = "https://api.bybit.com";
2
+ export declare const BYBIT_TESTNET_BASE_URL = "https://api-testnet.bybit.com";
3
+ export declare const BYBIT_PUBLIC_LINEAR_WS_URL = "wss://stream.bybit.com/v5/public/linear";
4
+ export declare const BYBIT_PUBLIC_SPOT_WS_URL = "wss://stream.bybit.com/v5/public/spot";
5
+ export declare const BYBIT_PRIVATE_WS_URL = "wss://stream.bybit.com/v5/private";
6
+ export declare const BYBIT_TRADE_WS_URL = "wss://stream.bybit.com/v5/trade";
7
+ export declare const BYBIT_PUBLIC_LINEAR_WS_TESTNET_URL = "wss://stream-testnet.bybit.com/v5/public/linear";
8
+ export declare const BYBIT_PUBLIC_SPOT_WS_TESTNET_URL = "wss://stream-testnet.bybit.com/v5/public/spot";
9
+ export declare const BYBIT_PRIVATE_WS_TESTNET_URL = "wss://stream-testnet.bybit.com/v5/private";
10
+ export declare const BYBIT_TRADE_WS_TESTNET_URL = "wss://stream-testnet.bybit.com/v5/trade";
11
+ export declare const BYBIT_RECV_WINDOW = 7000;
12
+ export declare const BYBIT_REQUEST_TIMEOUT = 30000;
13
+ export declare const BYBIT_KLINE_INTERVAL: Record<string, string>;
14
+ //# sourceMappingURL=bybit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bybit.d.ts","sourceRoot":"","sources":["../../src/constants/bybit.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,0BAA0B,CAAC;AACtD,eAAO,MAAM,sBAAsB,kCAAkC,CAAC;AAEtE,eAAO,MAAM,0BAA0B,4CAA4C,CAAC;AACpF,eAAO,MAAM,wBAAwB,0CAA0C,CAAC;AAChF,eAAO,MAAM,oBAAoB,sCAAsC,CAAC;AACxE,eAAO,MAAM,kBAAkB,oCAAoC,CAAC;AAEpE,eAAO,MAAM,kCAAkC,oDAAoD,CAAC;AACpG,eAAO,MAAM,gCAAgC,kDAAkD,CAAC;AAChG,eAAO,MAAM,4BAA4B,8CAA8C,CAAC;AACxF,eAAO,MAAM,0BAA0B,4CAA4C,CAAC;AAEpF,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAG3C,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAevD,CAAC"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BYBIT_KLINE_INTERVAL = exports.BYBIT_REQUEST_TIMEOUT = exports.BYBIT_RECV_WINDOW = exports.BYBIT_TRADE_WS_TESTNET_URL = exports.BYBIT_PRIVATE_WS_TESTNET_URL = exports.BYBIT_PUBLIC_SPOT_WS_TESTNET_URL = exports.BYBIT_PUBLIC_LINEAR_WS_TESTNET_URL = exports.BYBIT_TRADE_WS_URL = exports.BYBIT_PRIVATE_WS_URL = exports.BYBIT_PUBLIC_SPOT_WS_URL = exports.BYBIT_PUBLIC_LINEAR_WS_URL = exports.BYBIT_TESTNET_BASE_URL = exports.BYBIT_BASE_URL = void 0;
4
+ exports.BYBIT_BASE_URL = 'https://api.bybit.com';
5
+ exports.BYBIT_TESTNET_BASE_URL = 'https://api-testnet.bybit.com';
6
+ exports.BYBIT_PUBLIC_LINEAR_WS_URL = 'wss://stream.bybit.com/v5/public/linear';
7
+ exports.BYBIT_PUBLIC_SPOT_WS_URL = 'wss://stream.bybit.com/v5/public/spot';
8
+ exports.BYBIT_PRIVATE_WS_URL = 'wss://stream.bybit.com/v5/private';
9
+ exports.BYBIT_TRADE_WS_URL = 'wss://stream.bybit.com/v5/trade';
10
+ exports.BYBIT_PUBLIC_LINEAR_WS_TESTNET_URL = 'wss://stream-testnet.bybit.com/v5/public/linear';
11
+ exports.BYBIT_PUBLIC_SPOT_WS_TESTNET_URL = 'wss://stream-testnet.bybit.com/v5/public/spot';
12
+ exports.BYBIT_PRIVATE_WS_TESTNET_URL = 'wss://stream-testnet.bybit.com/v5/private';
13
+ exports.BYBIT_TRADE_WS_TESTNET_URL = 'wss://stream-testnet.bybit.com/v5/trade';
14
+ exports.BYBIT_RECV_WINDOW = 7000; // milliseconds
15
+ exports.BYBIT_REQUEST_TIMEOUT = 30000; // 30 seconds
16
+ // Маппинг KlineInterval -> формат Bybit (числа минут или D/W/M)
17
+ exports.BYBIT_KLINE_INTERVAL = {
18
+ '1m': '1',
19
+ '3m': '3',
20
+ '5m': '5',
21
+ '15m': '15',
22
+ '30m': '30',
23
+ '1h': '60',
24
+ '2h': '120',
25
+ '4h': '240',
26
+ '6h': '360',
27
+ '12h': '720',
28
+ '1d': 'D',
29
+ '3d': '3D',
30
+ '1w': 'W',
31
+ '1M': 'M',
32
+ };
33
+ //# sourceMappingURL=bybit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bybit.js","sourceRoot":"","sources":["../../src/constants/bybit.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAG,uBAAuB,CAAC;AACzC,QAAA,sBAAsB,GAAG,+BAA+B,CAAC;AAEzD,QAAA,0BAA0B,GAAG,yCAAyC,CAAC;AACvE,QAAA,wBAAwB,GAAG,uCAAuC,CAAC;AACnE,QAAA,oBAAoB,GAAG,mCAAmC,CAAC;AAC3D,QAAA,kBAAkB,GAAG,iCAAiC,CAAC;AAEvD,QAAA,kCAAkC,GAAG,iDAAiD,CAAC;AACvF,QAAA,gCAAgC,GAAG,+CAA+C,CAAC;AACnF,QAAA,4BAA4B,GAAG,2CAA2C,CAAC;AAC3E,QAAA,0BAA0B,GAAG,yCAAyC,CAAC;AAEvE,QAAA,iBAAiB,GAAG,IAAI,CAAC,CAAC,eAAe;AACzC,QAAA,qBAAqB,GAAG,KAAK,CAAC,CAAC,aAAa;AAEzD,gEAAgE;AACnD,QAAA,oBAAoB,GAA2B;IAC1D,IAAI,EAAE,GAAG;IACT,IAAI,EAAE,GAAG;IACT,IAAI,EAAE,GAAG;IACT,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,KAAK;IACX,IAAI,EAAE,KAAK;IACX,IAAI,EAAE,KAAK;IACX,KAAK,EAAE,KAAK;IACZ,IAAI,EAAE,GAAG;IACT,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,GAAG;IACT,IAAI,EAAE,GAAG;CACV,CAAC"}