ccxt 4.4.82 → 4.4.86

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 (145) hide show
  1. package/README.md +6 -9
  2. package/dist/ccxt.browser.min.js +7 -7
  3. package/dist/cjs/ccxt.js +6 -17
  4. package/dist/cjs/src/abstract/bittrade.js +9 -0
  5. package/dist/cjs/src/apex.js +2 -1
  6. package/dist/cjs/src/ascendex.js +189 -155
  7. package/dist/cjs/src/base/Exchange.js +15 -2
  8. package/dist/cjs/src/bequant.js +1 -1
  9. package/dist/cjs/src/bitget.js +6 -7
  10. package/dist/cjs/src/bitmart.js +1 -1
  11. package/dist/cjs/src/bitrue.js +14 -35
  12. package/dist/cjs/src/bitso.js +33 -0
  13. package/dist/cjs/src/bitstamp.js +33 -0
  14. package/dist/cjs/src/bittrade.js +2049 -0
  15. package/dist/cjs/src/blofin.js +154 -13
  16. package/dist/cjs/src/btcbox.js +25 -5
  17. package/dist/cjs/src/bybit.js +16 -40
  18. package/dist/cjs/src/cex.js +2 -4
  19. package/dist/cjs/src/coinbase.js +58 -46
  20. package/dist/cjs/src/coinbaseexchange.js +142 -32
  21. package/dist/cjs/src/coincatch.js +14 -67
  22. package/dist/cjs/src/coinex.js +29 -32
  23. package/dist/cjs/src/coinlist.js +16 -15
  24. package/dist/cjs/src/coinmetro.js +22 -11
  25. package/dist/cjs/src/coinone.js +8 -10
  26. package/dist/cjs/src/coinsph.js +126 -1
  27. package/dist/cjs/src/cryptocom.js +111 -1
  28. package/dist/cjs/src/cryptomus.js +43 -89
  29. package/dist/cjs/src/delta.js +76 -36
  30. package/dist/cjs/src/deribit.js +4 -5
  31. package/dist/cjs/src/derive.js +46 -10
  32. package/dist/cjs/src/ellipx.js +175 -79
  33. package/dist/cjs/src/gate.js +1 -1
  34. package/dist/cjs/src/gemini.js +3 -5
  35. package/dist/cjs/src/hitbtc.js +56 -69
  36. package/dist/cjs/src/hollaex.js +107 -49
  37. package/dist/cjs/src/htx.js +20 -44
  38. package/dist/cjs/src/hyperliquid.js +6 -6
  39. package/dist/cjs/src/kraken.js +29 -24
  40. package/dist/cjs/src/kucoinfutures.js +6 -0
  41. package/dist/cjs/src/lbank.js +1 -1
  42. package/dist/cjs/src/mexc.js +2 -2
  43. package/dist/cjs/src/ndax.js +25 -24
  44. package/dist/cjs/src/okcoin.js +12 -31
  45. package/dist/cjs/src/okx.js +9 -0
  46. package/dist/cjs/src/onetrading.js +9 -6
  47. package/dist/cjs/src/oxfun.js +42 -114
  48. package/dist/cjs/src/paradex.js +124 -4
  49. package/dist/cjs/src/pro/binance.js +32 -33
  50. package/dist/cjs/src/pro/bithumb.js +5 -3
  51. package/dist/cjs/src/pro/bittrade.js +605 -0
  52. package/dist/cjs/src/pro/kraken.js +289 -79
  53. package/dist/cjs/src/pro/luno.js +6 -5
  54. package/dist/cjs/src/pro/mexc.js +304 -7
  55. package/dist/cjs/src/pro/poloniex.js +6 -2
  56. package/examples/js/cli.js +127 -13
  57. package/js/ccxt.d.ts +8 -20
  58. package/js/ccxt.js +6 -14
  59. package/js/src/abstract/blofin.d.ts +8 -0
  60. package/js/src/abstract/btcbox.d.ts +1 -0
  61. package/js/src/abstract/myokx.d.ts +2 -0
  62. package/js/src/abstract/okx.d.ts +2 -0
  63. package/js/src/apex.js +2 -1
  64. package/js/src/ascendex.d.ts +2 -0
  65. package/js/src/ascendex.js +189 -155
  66. package/js/src/base/Exchange.d.ts +15 -1
  67. package/js/src/base/Exchange.js +15 -2
  68. package/js/src/base/types.d.ts +3 -0
  69. package/js/src/bequant.js +1 -1
  70. package/js/src/bitget.js +6 -7
  71. package/js/src/bitmart.js +1 -1
  72. package/js/src/bitrue.js +14 -35
  73. package/js/src/bitso.js +33 -0
  74. package/js/src/bitstamp.js +33 -0
  75. package/js/src/{huobijp.d.ts → bittrade.d.ts} +29 -29
  76. package/js/src/{huobijp.js → bittrade.js} +35 -35
  77. package/js/src/blofin.d.ts +42 -2
  78. package/js/src/blofin.js +154 -13
  79. package/js/src/btcbox.js +25 -5
  80. package/js/src/bybit.js +16 -40
  81. package/js/src/cex.js +2 -4
  82. package/js/src/coinbase.js +58 -46
  83. package/js/src/coinbaseexchange.js +142 -32
  84. package/js/src/coincatch.js +14 -67
  85. package/js/src/coinex.js +28 -29
  86. package/js/src/coinlist.js +16 -15
  87. package/js/src/coinmetro.js +22 -11
  88. package/js/src/coinone.js +8 -10
  89. package/js/src/coinsph.d.ts +10 -1
  90. package/js/src/coinsph.js +126 -1
  91. package/js/src/cryptocom.d.ts +10 -1
  92. package/js/src/cryptocom.js +111 -1
  93. package/js/src/cryptomus.js +43 -89
  94. package/js/src/delta.js +76 -36
  95. package/js/src/deribit.js +4 -5
  96. package/js/src/derive.js +46 -10
  97. package/js/src/ellipx.d.ts +2 -3
  98. package/js/src/ellipx.js +175 -80
  99. package/js/src/gate.js +1 -1
  100. package/js/src/gemini.js +3 -5
  101. package/js/src/hitbtc.js +56 -69
  102. package/js/src/hollaex.js +107 -49
  103. package/js/src/htx.js +20 -44
  104. package/js/src/hyperliquid.js +6 -6
  105. package/js/src/kraken.js +29 -24
  106. package/js/src/kucoinfutures.d.ts +1 -0
  107. package/js/src/kucoinfutures.js +6 -0
  108. package/js/src/lbank.js +1 -1
  109. package/js/src/mexc.js +2 -2
  110. package/js/src/ndax.js +25 -24
  111. package/js/src/okcoin.js +12 -31
  112. package/js/src/okx.js +9 -0
  113. package/js/src/onetrading.js +9 -6
  114. package/js/src/oxfun.js +42 -114
  115. package/js/src/paradex.d.ts +12 -1
  116. package/js/src/paradex.js +124 -4
  117. package/js/src/pro/binance.d.ts +26 -26
  118. package/js/src/pro/binance.js +32 -33
  119. package/js/src/pro/bithumb.js +5 -3
  120. package/js/src/pro/{huobijp.d.ts → bittrade.d.ts} +6 -6
  121. package/js/src/pro/{huobijp.js → bittrade.js} +7 -7
  122. package/js/src/pro/kraken.d.ts +7 -6
  123. package/js/src/pro/kraken.js +290 -80
  124. package/js/src/pro/luno.js +6 -5
  125. package/js/src/pro/mexc.d.ts +58 -0
  126. package/js/src/pro/mexc.js +304 -7
  127. package/js/src/pro/poloniex.d.ts +1 -1
  128. package/js/src/pro/poloniex.js +6 -2
  129. package/package.json +1 -1
  130. package/js/src/abstract/bl3p.d.ts +0 -22
  131. package/js/src/abstract/huobijp.js +0 -11
  132. package/js/src/abstract/idex.d.ts +0 -29
  133. package/js/src/abstract/idex.js +0 -11
  134. package/js/src/abstract/kuna.d.ts +0 -185
  135. package/js/src/abstract/kuna.js +0 -11
  136. package/js/src/bl3p.d.ts +0 -116
  137. package/js/src/bl3p.js +0 -552
  138. package/js/src/idex.d.ts +0 -312
  139. package/js/src/idex.js +0 -1961
  140. package/js/src/kuna.d.ts +0 -335
  141. package/js/src/kuna.js +0 -2006
  142. package/js/src/pro/idex.d.ts +0 -81
  143. package/js/src/pro/idex.js +0 -720
  144. /package/js/src/abstract/{huobijp.d.ts → bittrade.d.ts} +0 -0
  145. /package/js/src/abstract/{bl3p.js → bittrade.js} +0 -0
@@ -1,720 +0,0 @@
1
- // ----------------------------------------------------------------------------
2
-
3
- // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
- // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
- // EDIT THE CORRESPONDENT .ts FILE INSTEAD
6
-
7
- // ---------------------------------------------------------------------------
8
- import idexRest from '../idex.js';
9
- import { InvalidNonce } from '../base/errors.js';
10
- import { ArrayCache, ArrayCacheByTimestamp, ArrayCacheBySymbolById } from '../base/ws/Cache.js';
11
- import { Precise } from '../base/Precise.js';
12
- // ---------------------------------------------------------------------------
13
- export default class idex extends idexRest {
14
- describe() {
15
- return this.deepExtend(super.describe(), {
16
- 'has': {
17
- 'ws': true,
18
- 'watchOrderBook': true,
19
- 'watchTrades': true,
20
- 'watchOHLCV': true,
21
- 'watchTicker': true,
22
- 'watchTickers': false,
23
- 'watchOrders': true,
24
- 'watchTransactions': true,
25
- },
26
- 'urls': {
27
- 'test': {
28
- 'ws': 'wss://websocket-matic.idex.io/v1',
29
- },
30
- 'api': {},
31
- },
32
- 'options': {
33
- 'tradesLimit': 1000,
34
- 'ordersLimit': 1000,
35
- 'OHLCVLimit': 1000,
36
- 'watchOrderBookLimit': 1000,
37
- 'orderBookSubscriptions': {},
38
- 'token': undefined,
39
- 'watchOrderBook': {
40
- 'maxRetries': 3,
41
- },
42
- 'fetchOrderBookSnapshotMaxAttempts': 10,
43
- 'fetchOrderBookSnapshotMaxDelay': 10000, // throw if there are no orders in 10 seconds
44
- },
45
- });
46
- }
47
- async subscribe(subscribeObject, messageHash, subscription = true) {
48
- const url = this.urls['test']['ws'];
49
- const request = {
50
- 'method': 'subscribe',
51
- 'subscriptions': [
52
- subscribeObject,
53
- ],
54
- };
55
- return await this.watch(url, messageHash, request, messageHash, subscription);
56
- }
57
- async subscribePrivate(subscribeObject, messageHash) {
58
- const token = await this.authenticate();
59
- const url = this.urls['test']['ws'];
60
- const request = {
61
- 'method': 'subscribe',
62
- 'token': token,
63
- 'subscriptions': [
64
- subscribeObject,
65
- ],
66
- };
67
- return await this.watch(url, messageHash, request, messageHash);
68
- }
69
- /**
70
- * @method
71
- * @name idex#watchTicker
72
- * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
73
- * @see https://api-docs-v4.idex.io/#tickers
74
- * @param {string} symbol unified symbol of the market to fetch the ticker for
75
- * @param {object} [params] extra parameters specific to the exchange API endpoint
76
- * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
77
- */
78
- async watchTicker(symbol, params = {}) {
79
- await this.loadMarkets();
80
- const market = this.market(symbol);
81
- const name = 'tickers';
82
- const subscribeObject = {
83
- 'name': name,
84
- 'markets': [market['id']],
85
- };
86
- const messageHash = name + ':' + market['id'];
87
- return await this.subscribe(this.extend(subscribeObject, params), messageHash);
88
- }
89
- handleTicker(client, message) {
90
- // { type: "tickers",
91
- // "data":
92
- // { m: "DIL-ETH",
93
- // "t": 1599213946045,
94
- // "o": "0.09699020",
95
- // "h": "0.10301548",
96
- // "l": "0.09577222",
97
- // "c": "0.09907311",
98
- // "Q": "1.32723120",
99
- // "v": "297.80667468",
100
- // "q": "29.52142669",
101
- // "P": "2.14",
102
- // "n": 197,
103
- // "a": "0.09912245",
104
- // "b": "0.09686980",
105
- // "u": 5870 } }
106
- const type = this.safeString(message, 'type');
107
- const data = this.safeValue(message, 'data');
108
- const marketId = this.safeString(data, 'm');
109
- const symbol = this.safeSymbol(marketId);
110
- const messageHash = type + ':' + marketId;
111
- const timestamp = this.safeInteger(data, 't');
112
- const close = this.safeString(data, 'c');
113
- const percentage = this.safeString(data, 'P');
114
- let change = undefined;
115
- if ((percentage !== undefined) && (close !== undefined)) {
116
- change = Precise.stringMul(close, percentage);
117
- }
118
- const ticker = this.safeTicker({
119
- 'symbol': symbol,
120
- 'timestamp': timestamp,
121
- 'datetime': this.iso8601(timestamp),
122
- 'high': this.safeString(data, 'h'),
123
- 'low': this.safeString(data, 'l'),
124
- 'bid': this.safeString(data, 'b'),
125
- 'bidVolume': undefined,
126
- 'ask': this.safeString(data, 'a'),
127
- 'askVolume': undefined,
128
- 'vwap': undefined,
129
- 'open': this.safeString(data, 'o'),
130
- 'close': close,
131
- 'last': close,
132
- 'previousClose': undefined,
133
- 'change': change,
134
- 'percentage': percentage,
135
- 'average': undefined,
136
- 'baseVolume': this.safeString(data, 'v'),
137
- 'quoteVolume': this.safeString(data, 'q'),
138
- 'info': message,
139
- });
140
- client.resolve(ticker, messageHash);
141
- }
142
- /**
143
- * @method
144
- * @name idex#watchTrades
145
- * @description get the list of most recent trades for a particular symbol
146
- * @see https://api-docs-v4.idex.io/#trades
147
- * @param {string} symbol unified symbol of the market to fetch trades for
148
- * @param {int} [since] timestamp in ms of the earliest trade to fetch
149
- * @param {int} [limit] the maximum amount of trades to fetch
150
- * @param {object} [params] extra parameters specific to the exchange API endpoint
151
- * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
152
- */
153
- async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
154
- await this.loadMarkets();
155
- const market = this.market(symbol);
156
- symbol = market['symbol'];
157
- const name = 'trades';
158
- const subscribeObject = {
159
- 'name': name,
160
- 'markets': [market['id']],
161
- };
162
- const messageHash = name + ':' + market['id'];
163
- const trades = await this.subscribe(subscribeObject, messageHash);
164
- if (this.newUpdates) {
165
- limit = trades.getLimit(symbol, limit);
166
- }
167
- return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
168
- }
169
- handleTrade(client, message) {
170
- const type = this.safeString(message, 'type');
171
- const data = this.safeValue(message, 'data');
172
- const marketId = this.safeString(data, 'm');
173
- const messageHash = type + ':' + marketId;
174
- const trade = this.parseWsTrade(data);
175
- const keys = Object.keys(this.trades);
176
- const length = keys.length;
177
- if (length === 0) {
178
- const limit = this.safeInteger(this.options, 'tradesLimit');
179
- this.trades = new ArrayCacheBySymbolById(limit);
180
- }
181
- const trades = this.trades;
182
- trades.append(trade);
183
- client.resolve(trades, messageHash);
184
- }
185
- parseWsTrade(trade, market = undefined) {
186
- // public trades
187
- // { m: "DIL-ETH",
188
- // "i": "897ecae6-4b75-368a-ac00-be555e6ad65f",
189
- // "p": "0.09696995",
190
- // "q": "2.00000000",
191
- // "Q": "0.19393990",
192
- // "t": 1599504616247,
193
- // "s": "buy",
194
- // "u": 6620 }
195
- // private trades
196
- // { i: "ee253d78-88be-37ed-a61c-a36395c2ce48",
197
- // "p": "0.09925382",
198
- // "q": "0.15000000",
199
- // "Q": "0.01488807",
200
- // "t": 1599499129369,
201
- // "s": "sell",
202
- // "u": 6603,
203
- // "f": "0.00030000",
204
- // "a": "DIL",
205
- // "g": "0.00856110",
206
- // "l": "maker",
207
- // "S": "pending" }
208
- const marketId = this.safeString(trade, 'm');
209
- const symbol = this.safeSymbol(marketId);
210
- const id = this.safeString(trade, 'i');
211
- const price = this.safeString(trade, 'p');
212
- const amount = this.safeString(trade, 'q');
213
- const cost = this.safeString(trade, 'Q');
214
- const timestamp = this.safeInteger(trade, 't');
215
- const side = this.safeString(trade, 's');
216
- const fee = {
217
- 'currency': this.safeString(trade, 'a'),
218
- 'cost': this.safeString(trade, 'f'),
219
- };
220
- const takerOrMarker = this.safeString(trade, 'l');
221
- return this.safeTrade({
222
- 'info': trade,
223
- 'timestamp': timestamp,
224
- 'datetime': this.iso8601(timestamp),
225
- 'symbol': symbol,
226
- 'id': id,
227
- 'order': undefined,
228
- 'type': undefined,
229
- 'takerOrMaker': takerOrMarker,
230
- 'side': side,
231
- 'price': price,
232
- 'amount': amount,
233
- 'cost': cost,
234
- 'fee': fee,
235
- });
236
- }
237
- /**
238
- * @method
239
- * @name idex#watchOHLCV
240
- * @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
241
- * @see https://api-docs-v4.idex.io/#candles
242
- * @param {string} symbol unified symbol of the market to fetch OHLCV data for
243
- * @param {string} timeframe the length of time each candle represents
244
- * @param {int} [since] timestamp in ms of the earliest candle to fetch
245
- * @param {int} [limit] the maximum amount of candles to fetch
246
- * @param {object} [params] extra parameters specific to the exchange API endpoint
247
- * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
248
- */
249
- async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
250
- await this.loadMarkets();
251
- const market = this.market(symbol);
252
- symbol = market['symbol'];
253
- const name = 'candles';
254
- const interval = this.safeString(this.timeframes, timeframe, timeframe);
255
- const subscribeObject = {
256
- 'name': name,
257
- 'markets': [market['id']],
258
- 'interval': interval,
259
- };
260
- const messageHash = name + ':' + market['id'];
261
- const ohlcv = await this.subscribe(subscribeObject, messageHash);
262
- if (this.newUpdates) {
263
- limit = ohlcv.getLimit(symbol, limit);
264
- }
265
- return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
266
- }
267
- handleOHLCV(client, message) {
268
- // { type: "candles",
269
- // "data":
270
- // { m: "DIL-ETH",
271
- // "t": 1599477340109,
272
- // "i": "1m",
273
- // "s": 1599477300000,
274
- // "e": 1599477360000,
275
- // "o": "0.09911040",
276
- // "h": "0.09911040",
277
- // "l": "0.09911040",
278
- // "c": "0.09911040",
279
- // "v": "0.15000000",
280
- // "n": 1,
281
- // "u": 6531 } }
282
- const type = this.safeString(message, 'type');
283
- const data = this.safeValue(message, 'data');
284
- const marketId = this.safeString(data, 'm');
285
- const messageHash = type + ':' + marketId;
286
- const parsed = [
287
- this.safeInteger(data, 's'),
288
- this.safeFloat(data, 'o'),
289
- this.safeFloat(data, 'h'),
290
- this.safeFloat(data, 'l'),
291
- this.safeFloat(data, 'c'),
292
- this.safeFloat(data, 'v'),
293
- ];
294
- const symbol = this.safeSymbol(marketId);
295
- const interval = this.safeString(data, 'i');
296
- const timeframe = this.findTimeframe(interval);
297
- // TODO: move to base class
298
- this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
299
- let stored = this.safeValue(this.ohlcvs[symbol], timeframe);
300
- if (stored === undefined) {
301
- const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
302
- stored = new ArrayCacheByTimestamp(limit);
303
- this.ohlcvs[symbol][timeframe] = stored;
304
- }
305
- stored.append(parsed);
306
- client.resolve(stored, messageHash);
307
- }
308
- handleSubscribeMessage(client, message) {
309
- // {
310
- // "type": "subscriptions",
311
- // "subscriptions": [
312
- // {
313
- // "name": "l2orderbook",
314
- // "markets": [
315
- // "DIL-ETH"
316
- // ]
317
- // }
318
- // ]
319
- // }
320
- const subscriptions = this.safeValue(message, 'subscriptions');
321
- for (let i = 0; i < subscriptions.length; i++) {
322
- const subscription = subscriptions[i];
323
- const name = this.safeString(subscription, 'name');
324
- if (name === 'l2orderbook') {
325
- const markets = this.safeValue(subscription, 'markets');
326
- for (let j = 0; j < markets.length; j++) {
327
- const marketId = markets[j];
328
- const orderBookSubscriptions = this.safeValue(this.options, 'orderBookSubscriptions', {});
329
- if (!(marketId in orderBookSubscriptions)) {
330
- const symbol = this.safeSymbol(marketId);
331
- if (!(symbol in this.orderbooks)) {
332
- const orderbook = this.countedOrderBook({});
333
- // orderbook.cache = []; // cache is never used?
334
- this.orderbooks[symbol] = orderbook;
335
- }
336
- this.spawn(this.fetchOrderBookSnapshot, client, symbol);
337
- }
338
- }
339
- break;
340
- }
341
- }
342
- }
343
- async fetchOrderBookSnapshot(client, symbol, params = {}) {
344
- const orderbook = this.orderbooks[symbol];
345
- const market = this.market(symbol);
346
- const messageHash = 'l2orderbook' + ':' + market['id'];
347
- const subscription = client.subscriptions[messageHash];
348
- if (!subscription['fetchingOrderBookSnapshot']) {
349
- subscription['startTime'] = this.milliseconds();
350
- }
351
- subscription['fetchingOrderBookSnapshot'] = true;
352
- const maxAttempts = this.safeInteger(this.options, 'fetchOrderBookSnapshotMaxAttempts', 10);
353
- const maxDelay = this.safeInteger(this.options, 'fetchOrderBookSnapshotMaxDelay', 10000);
354
- try {
355
- const limit = this.safeInteger(subscription, 'limit', 0);
356
- // 3. Request a level-2 order book snapshot for the market from the REST API Order Books endpoint with limit set to 0.
357
- const snapshot = await this.fetchRestOrderBookSafe(symbol, limit);
358
- const firstBuffered = this.safeValue(orderbook.cache, 0);
359
- const firstData = this.safeValue(firstBuffered, 'data');
360
- const firstNonce = this.safeInteger(firstData, 'u');
361
- const length = orderbook.cache.length;
362
- const lastBuffered = this.safeValue(orderbook.cache, length - 1);
363
- const lastData = this.safeValue(lastBuffered, 'data');
364
- const lastNonce = this.safeInteger(lastData, 'u');
365
- const bothExist = (firstNonce !== undefined) && (lastNonce !== undefined);
366
- // ensure the snapshot is inside the range of our cached messages
367
- // for example if the snapshot nonce is 100
368
- // the first nonce must be less than or equal to 101 and the last nonce must be greater than 101
369
- if (bothExist && (firstNonce <= snapshot['nonce'] + 1) && (lastNonce > snapshot['nonce'])) {
370
- orderbook.reset(snapshot);
371
- for (let i = 0; i < orderbook.cache.length; i++) {
372
- const message = orderbook.cache[i];
373
- const data = this.safeValue(message, 'data');
374
- const u = this.safeInteger(data, 'u');
375
- if (u > orderbook['nonce']) {
376
- // 5. Discard all order book update messages with sequence numbers less than or equal to the snapshot sequence number.
377
- // 6. Apply the remaining buffered order book update messages and any incoming order book update messages to the order book snapshot.
378
- this.handleOrderBookMessage(client, message, orderbook);
379
- }
380
- }
381
- subscription['fetchingOrderBookSnapshot'] = false;
382
- client.resolve(orderbook, messageHash);
383
- }
384
- else {
385
- // 4. If the sequence in the order book snapshot is less than the sequence of the
386
- // first buffered order book update message, discard the order book snapshot and retry step 3.
387
- // this will continue to recurse until we have a buffered message
388
- // since updates the order book endpoint depend on order events
389
- // so it will eventually throw if there are no orders on a pair
390
- subscription['numAttempts'] = subscription['numAttempts'] + 1;
391
- const timeElapsed = this.milliseconds() - subscription['startTime'];
392
- const maxAttemptsValid = subscription['numAttempts'] < maxAttempts;
393
- const timeElapsedValid = timeElapsed < maxDelay;
394
- if (maxAttemptsValid && timeElapsedValid) {
395
- this.delay(this.rateLimit, this.fetchOrderBookSnapshot, client, symbol);
396
- }
397
- else {
398
- const endpart = (!maxAttemptsValid) ? ' in ' + maxAttempts.toString() + ' attempts' : ' after ' + maxDelay.toString() + ' milliseconds';
399
- throw new InvalidNonce(this.id + ' failed to synchronize WebSocket feed with the snapshot for symbol ' + symbol + endpart);
400
- }
401
- }
402
- }
403
- catch (e) {
404
- subscription['fetchingOrderBookSnapshot'] = false;
405
- client.reject(e, messageHash);
406
- }
407
- }
408
- /**
409
- * @method
410
- * @name idex#watchOrderBook
411
- * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
412
- * @see https://api-docs-v4.idex.io/#l2-order-book
413
- * @param {string} symbol unified symbol of the market to fetch the order book for
414
- * @param {int} [limit] the maximum amount of order book entries to return
415
- * @param {object} [params] extra parameters specific to the exchange API endpoint
416
- * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
417
- */
418
- async watchOrderBook(symbol, limit = undefined, params = {}) {
419
- await this.loadMarkets();
420
- const market = this.market(symbol);
421
- const name = 'l2orderbook';
422
- const subscribeObject = {
423
- 'name': name,
424
- 'markets': [market['id']],
425
- };
426
- const messageHash = name + ':' + market['id'];
427
- const subscription = {
428
- 'fetchingOrderBookSnapshot': false,
429
- 'numAttempts': 0,
430
- 'startTime': undefined,
431
- };
432
- if (limit === undefined) {
433
- subscription['limit'] = 1000;
434
- }
435
- else {
436
- subscription['limit'] = limit;
437
- }
438
- // 1. Connect to the WebSocket API endpoint and subscribe to the L2 Order Book for the target market.
439
- const orderbook = await this.subscribe(subscribeObject, messageHash, subscription);
440
- return orderbook.limit();
441
- }
442
- handleOrderBook(client, message) {
443
- const data = this.safeValue(message, 'data');
444
- const marketId = this.safeString(data, 'm');
445
- const symbol = this.safeSymbol(marketId);
446
- const orderbook = this.orderbooks[symbol];
447
- if (orderbook['nonce'] === undefined) {
448
- // 2. Buffer the incoming order book update subscription messages.
449
- orderbook.cache.push(message);
450
- }
451
- else {
452
- this.handleOrderBookMessage(client, message, orderbook);
453
- }
454
- }
455
- handleOrderBookMessage(client, message, orderbook) {
456
- // {
457
- // "type": "l2orderbook",
458
- // "data": {
459
- // "m": "DIL-ETH",
460
- // "t": 1600197205037,
461
- // "u": 94116643,
462
- // "b": [
463
- // [
464
- // "0.09662187",
465
- // "0.00000000",
466
- // 0
467
- // ]
468
- // ],
469
- // "a": []
470
- // }
471
- // }
472
- const type = this.safeString(message, 'type');
473
- const data = this.safeValue(message, 'data');
474
- const marketId = this.safeString(data, 'm');
475
- const messageHash = type + ':' + marketId;
476
- const nonce = this.safeInteger(data, 'u');
477
- const timestamp = this.safeInteger(data, 't');
478
- const bids = this.safeValue(data, 'b');
479
- const asks = this.safeValue(data, 'a');
480
- this.handleDeltas(orderbook['bids'], bids);
481
- this.handleDeltas(orderbook['asks'], asks);
482
- orderbook['nonce'] = nonce;
483
- orderbook['timestamp'] = timestamp;
484
- orderbook['datetime'] = this.iso8601(timestamp);
485
- client.resolve(orderbook, messageHash);
486
- }
487
- handleDelta(bookside, delta) {
488
- const price = this.safeFloat(delta, 0);
489
- const amount = this.safeFloat(delta, 1);
490
- const count = this.safeInteger(delta, 2);
491
- bookside.storeArray([price, amount, count]);
492
- }
493
- handleDeltas(bookside, deltas) {
494
- for (let i = 0; i < deltas.length; i++) {
495
- this.handleDelta(bookside, deltas[i]);
496
- }
497
- }
498
- async authenticate(params = {}) {
499
- const time = this.seconds();
500
- const lastAuthenticatedTime = this.safeInteger(this.options, 'lastAuthenticatedTime', 0);
501
- if (time - lastAuthenticatedTime > 900) {
502
- const request = {
503
- 'wallet': this.walletAddress,
504
- 'nonce': this.uuidv1(),
505
- };
506
- const response = await this.privateGetWsToken(this.extend(request, params));
507
- this.options['lastAuthenticatedTime'] = time;
508
- this.options['token'] = this.safeString(response, 'token');
509
- }
510
- return this.options['token'];
511
- }
512
- /**
513
- * @method
514
- * @name idex#watchOrders
515
- * @description watches information on multiple orders made by the user
516
- * @see https://api-docs-v4.idex.io/#orders
517
- * @param {string} symbol unified market symbol of the market orders were made in
518
- * @param {int} [since] the earliest time in ms to fetch orders for
519
- * @param {int} [limit] the maximum number of order structures to retrieve
520
- * @param {object} [params] extra parameters specific to the exchange API endpoint
521
- * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
522
- */
523
- async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
524
- await this.loadMarkets();
525
- const name = 'orders';
526
- const subscribeObject = {
527
- 'name': name,
528
- };
529
- let messageHash = name;
530
- if (symbol !== undefined) {
531
- symbol = this.symbol(symbol);
532
- const marketId = this.marketId(symbol);
533
- subscribeObject['markets'] = [marketId];
534
- messageHash = name + ':' + marketId;
535
- }
536
- const orders = await this.subscribePrivate(subscribeObject, messageHash);
537
- if (this.newUpdates) {
538
- limit = orders.getLimit(symbol, limit);
539
- }
540
- return this.filterBySinceLimit(orders, since, limit, 'timestamp', true);
541
- }
542
- handleOrder(client, message) {
543
- // {
544
- // "type": "orders",
545
- // "data": {
546
- // "m": "DIL-ETH",
547
- // "i": "8f75dd30-f12d-11ea-b63c-df3381b4b5b4",
548
- // "w": "0x0AB991497116f7F5532a4c2f4f7B1784488628e1",
549
- // "t": 1599498857138,
550
- // "T": 1599498857092,
551
- // "x": "fill",
552
- // "X": "filled",
553
- // "u": 67695627,
554
- // "o": "limit",
555
- // "S": "buy",
556
- // "q": "0.15000000",
557
- // "z": "0.15000000",
558
- // "Z": "0.01486286",
559
- // "v": "0.09908573",
560
- // "p": "1.00000000",
561
- // "f": "gtc",
562
- // "V": "2",
563
- // "F": [
564
- // {
565
- // "i": "5cdc6d14-bc35-3279-ab5e-40d654ca1523",
566
- // "p": "0.09908577",
567
- // "q": "0.15000000",
568
- // "Q": "0.01486286",
569
- // "t": 1599498857092,
570
- // "s": "sell",
571
- // "u": 6600,
572
- // "f": "0.00030000",
573
- // "a": "DIL",
574
- // "g": "0.00856977",
575
- // "l": "maker",
576
- // "S": "pending"
577
- // }
578
- // ]
579
- // }
580
- // }
581
- const type = this.safeString(message, 'type');
582
- const order = this.safeValue(message, 'data');
583
- const marketId = this.safeString(order, 'm');
584
- const symbol = this.safeSymbol(marketId);
585
- const timestamp = this.safeInteger(order, 't');
586
- const fills = this.safeValue(order, 'F', []);
587
- const trades = [];
588
- for (let i = 0; i < fills.length; i++) {
589
- trades.push(this.parseWsTrade(fills[i]));
590
- }
591
- const id = this.safeString(order, 'i');
592
- const side = this.safeString(order, 's');
593
- const orderType = this.safeString(order, 'o');
594
- const amount = this.safeString(order, 'q');
595
- const filled = this.safeString(order, 'z');
596
- const average = this.safeString(order, 'v');
597
- const price = this.safeString(order, 'price', average); // for market orders
598
- const rawStatus = this.safeString(order, 'X');
599
- const status = this.parseOrderStatus(rawStatus);
600
- const fee = {
601
- 'currency': undefined,
602
- 'cost': undefined,
603
- };
604
- let lastTrade = undefined;
605
- for (let i = 0; i < trades.length; i++) {
606
- lastTrade = trades[i];
607
- fee['currency'] = lastTrade['fee']['currency'];
608
- const stringLastTradeFee = lastTrade['fee']['cost'];
609
- fee['cost'] = Precise.stringAdd(fee['cost'], stringLastTradeFee);
610
- }
611
- const lastTradeTimestamp = this.safeInteger(lastTrade, 'timestamp');
612
- const parsedOrder = this.safeOrder({
613
- 'info': message,
614
- 'id': id,
615
- 'clientOrderId': undefined,
616
- 'timestamp': timestamp,
617
- 'datetime': this.iso8601(timestamp),
618
- 'lastTradeTimestamp': lastTradeTimestamp,
619
- 'symbol': symbol,
620
- 'type': orderType,
621
- 'side': side,
622
- 'price': this.parseNumber(price),
623
- 'stopPrice': undefined,
624
- 'triggerPrice': undefined,
625
- 'amount': this.parseNumber(amount),
626
- 'cost': undefined,
627
- 'average': this.parseNumber(average),
628
- 'filled': this.parseNumber(filled),
629
- 'remaining': undefined,
630
- 'status': status,
631
- 'fee': fee,
632
- 'trades': trades,
633
- });
634
- if (this.orders === undefined) {
635
- const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
636
- this.orders = new ArrayCacheBySymbolById(limit);
637
- }
638
- const orders = this.orders;
639
- orders.append(parsedOrder);
640
- const symbolSpecificMessageHash = type + ':' + marketId;
641
- client.resolve(orders, symbolSpecificMessageHash);
642
- client.resolve(orders, type);
643
- }
644
- async watchTransactions(code = undefined, since = undefined, limit = undefined, params = {}) {
645
- await this.loadMarkets();
646
- const name = 'balances';
647
- const subscribeObject = {
648
- 'name': name,
649
- };
650
- let messageHash = name;
651
- if (code !== undefined) {
652
- messageHash = name + ':' + code;
653
- }
654
- const transactions = await this.subscribePrivate(subscribeObject, messageHash);
655
- if (this.newUpdates) {
656
- limit = transactions.getLimit(code, limit);
657
- }
658
- return this.filterBySinceLimit(transactions, since, limit, 'timestamp');
659
- }
660
- handleTransaction(client, message) {
661
- // Update Speed: Real time, updates on any deposit or withdrawal of the wallet
662
- // { type: "balances",
663
- // "data":
664
- // { w: "0x0AB991497116f7F5532a4c2f4f7B1784488628e1",
665
- // "a": "ETH",
666
- // "q": "0.11198667",
667
- // "f": "0.11198667",
668
- // "l": "0.00000000",
669
- // "d": "0.00" } }
670
- const type = this.safeString(message, 'type');
671
- const data = this.safeValue(message, 'data');
672
- const currencyId = this.safeString(data, 'a');
673
- const messageHash = type + ':' + currencyId;
674
- const code = this.safeCurrencyCode(currencyId);
675
- const address = this.safeString(data, 'w');
676
- const transaction = {
677
- 'info': message,
678
- 'id': undefined,
679
- 'currency': code,
680
- 'amount': undefined,
681
- 'address': address,
682
- 'addressTo': undefined,
683
- 'addressFrom': undefined,
684
- 'tag': undefined,
685
- 'tagTo': undefined,
686
- 'tagFrom': undefined,
687
- 'status': 'ok',
688
- 'type': undefined,
689
- 'updated': undefined,
690
- 'txid': undefined,
691
- 'timestamp': undefined,
692
- 'datetime': undefined,
693
- 'fee': undefined,
694
- };
695
- if (!(code in this.transactions)) {
696
- const limit = this.safeInteger(this.options, 'transactionsLimit', 1000);
697
- this.transactions[code] = new ArrayCache(limit);
698
- }
699
- const transactions = this.transactions[code];
700
- transactions.append(transaction);
701
- client.resolve(transactions, messageHash);
702
- client.resolve(transactions, type);
703
- }
704
- handleMessage(client, message) {
705
- const type = this.safeString(message, 'type');
706
- const methods = {
707
- 'tickers': this.handleTicker,
708
- 'trades': this.handleTrade,
709
- 'subscriptions': this.handleSubscribeMessage,
710
- 'candles': this.handleOHLCV,
711
- 'l2orderbook': this.handleOrderBook,
712
- 'balances': this.handleTransaction,
713
- 'orders': this.handleOrder,
714
- };
715
- if (type in methods) {
716
- const method = methods[type];
717
- method.call(this, client, message);
718
- }
719
- }
720
- }