ccxt 4.0.66 → 4.0.68

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 (44) hide show
  1. package/README.md +3 -12
  2. package/dist/ccxt.browser.js +166 -59
  3. package/dist/ccxt.browser.min.js +3 -3
  4. package/dist/cjs/ccxt.js +1 -1
  5. package/dist/cjs/src/base/Exchange.js +1 -1
  6. package/dist/cjs/src/binance.js +1 -0
  7. package/dist/cjs/src/bitget.js +8 -1
  8. package/dist/cjs/src/bybit.js +12 -2
  9. package/dist/cjs/src/lykke.js +1 -1
  10. package/dist/cjs/src/phemex.js +2 -1
  11. package/dist/cjs/src/pro/binance.js +1 -1
  12. package/dist/cjs/src/pro/bitfinex2.js +7 -6
  13. package/dist/cjs/src/pro/bitget.js +10 -7
  14. package/dist/cjs/src/pro/bitmart.js +7 -6
  15. package/dist/cjs/src/pro/bittrex.js +2 -3
  16. package/dist/cjs/src/pro/bybit.js +3 -2
  17. package/dist/cjs/src/pro/coinbasepro.js +71 -9
  18. package/dist/cjs/src/pro/huobi.js +4 -2
  19. package/dist/cjs/src/pro/idex.js +1 -1
  20. package/dist/cjs/src/wavesexchange.js +34 -15
  21. package/js/ccxt.d.ts +1 -1
  22. package/js/ccxt.js +1 -1
  23. package/js/src/base/Exchange.js +1 -1
  24. package/js/src/binance.js +1 -0
  25. package/js/src/bitget.js +8 -1
  26. package/js/src/bybit.js +12 -2
  27. package/js/src/lykke.js +1 -1
  28. package/js/src/phemex.js +2 -1
  29. package/js/src/pro/binance.js +1 -1
  30. package/js/src/pro/bitfinex2.d.ts +1 -1
  31. package/js/src/pro/bitfinex2.js +7 -6
  32. package/js/src/pro/bitget.d.ts +1 -1
  33. package/js/src/pro/bitget.js +10 -7
  34. package/js/src/pro/bitmart.d.ts +1 -1
  35. package/js/src/pro/bitmart.js +7 -6
  36. package/js/src/pro/bittrex.js +2 -3
  37. package/js/src/pro/bybit.js +3 -2
  38. package/js/src/pro/coinbasepro.d.ts +3 -1
  39. package/js/src/pro/coinbasepro.js +71 -9
  40. package/js/src/pro/huobi.js +4 -2
  41. package/js/src/pro/idex.js +1 -1
  42. package/js/src/wavesexchange.d.ts +2 -1
  43. package/js/src/wavesexchange.js +34 -15
  44. package/package.json +1 -1
package/README.md CHANGED
@@ -210,22 +210,13 @@ console.log(version, Object.keys(exchanges));
210
210
 
211
211
  All-in-one browser bundle (dependencies included), served from a CDN of your choice:
212
212
 
213
- <<<<<<< HEAD
214
- * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.0.66/dist/ccxt.browser.js
215
- * unpkg: https://unpkg.com/ccxt@4.0.66/dist/ccxt.browser.js
216
- =======
217
- * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.0.66/dist/ccxt.browser.js
218
- * unpkg: https://unpkg.com/ccxt@4.0.66/dist/ccxt.browser.js
219
- >>>>>>> e74b18a3a8a8cbcfe45ce4c1d32b9c03d4fae41c
213
+ * jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@4.0.68/dist/ccxt.browser.js
214
+ * unpkg: https://unpkg.com/ccxt@4.0.68/dist/ccxt.browser.js
220
215
 
221
216
  CDNs are not updated in real-time and may have delays. Defaulting to the most recent version without specifying the version number is not recommended. Please, keep in mind that we are not responsible for the correct operation of those CDN servers.
222
217
 
223
218
  ```HTML
224
- <<<<<<< HEAD
225
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.0.66/dist/ccxt.browser.js"></script>
226
- =======
227
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.0.66/dist/ccxt.browser.js"></script>
228
- >>>>>>> e74b18a3a8a8cbcfe45ce4c1d32b9c03d4fae41c
219
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@4.0.68/dist/ccxt.browser.js"></script>
229
220
  ```
230
221
 
231
222
  Creates a global `ccxt` object:
@@ -7841,7 +7841,7 @@ class Exchange {
7841
7841
  throw new _errors_js__WEBPACK_IMPORTED_MODULE_1__.NotSupported(this.id + ' fetchOrderBook() is not supported yet');
7842
7842
  }
7843
7843
  async fetchRestOrderBookSafe(symbol, limit = undefined, params = {}) {
7844
- const fetchSnapshotMaxRetries = this.handleOption('watchOrderBook', 'snapshotMaxRetries', 3);
7844
+ const fetchSnapshotMaxRetries = this.handleOption('watchOrderBook', 'maxRetries', 3);
7845
7845
  for (let i = 0; i < fetchSnapshotMaxRetries; i++) {
7846
7846
  try {
7847
7847
  const orderBook = await this.fetchOrderBook(symbol, limit, params);
@@ -17020,6 +17020,7 @@ class binance extends _abstract_binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
17020
17020
  '-4045': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ExchangeError,
17021
17021
  '-4046': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.AuthenticationError,
17022
17022
  '-4047': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest,
17023
+ '-4054': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest,
17023
17024
  '-5001': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest,
17024
17025
  '-5002': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.InsufficientFunds,
17025
17026
  '-5003': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.InsufficientFunds,
@@ -39325,8 +39326,9 @@ class bitget extends _abstract_bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
39325
39326
  'symbol': market['id'],
39326
39327
  };
39327
39328
  const until = this.safeInteger2(params, 'until', 'till');
39329
+ const limitIsUndefined = (limit === undefined);
39328
39330
  if (limit === undefined) {
39329
- limit = 1000;
39331
+ limit = 200;
39330
39332
  }
39331
39333
  request['limit'] = limit;
39332
39334
  const marketType = market['spot'] ? 'spot' : 'swap';
@@ -39372,6 +39374,9 @@ class bitget extends _abstract_bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
39372
39374
  const method = this.safeString(params, 'method', defaultSpotMethod);
39373
39375
  params = this.omit(params, 'method');
39374
39376
  if (method === 'publicSpotGetMarketCandles') {
39377
+ if (limitIsUndefined) {
39378
+ request['limit'] = 1000;
39379
+ }
39375
39380
  response = await this.publicSpotGetMarketCandles(this.extend(request, params));
39376
39381
  }
39377
39382
  else if (method === 'publicSpotGetMarketHistoryCandles') {
@@ -39391,6 +39396,9 @@ class bitget extends _abstract_bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
39391
39396
  response = await this.publicMixGetMarketHistoryIndexCandles(this.extend(request, params));
39392
39397
  }
39393
39398
  else if (swapMethod === 'publicMixGetMarketCandles') {
39399
+ if (limitIsUndefined) {
39400
+ request['limit'] = 1000;
39401
+ }
39394
39402
  response = await this.publicMixGetMarketCandles(this.extend(request, params));
39395
39403
  }
39396
39404
  else if (swapMethod === 'publicMixGetMarketHistoryCandles') {
@@ -72411,6 +72419,16 @@ class bybit extends _abstract_bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
72411
72419
  }
72412
72420
  else if (symbol in this.markets_by_id) {
72413
72421
  const markets = this.markets_by_id[symbol];
72422
+ let defaultType = this.safeString2(this.options, 'defaultType', 'defaultSubType', 'spot');
72423
+ if (defaultType === 'future') {
72424
+ defaultType = 'contract';
72425
+ }
72426
+ for (let i = 0; i < markets.length; i++) {
72427
+ const market = markets[i];
72428
+ if (market[defaultType]) {
72429
+ return market;
72430
+ }
72431
+ }
72414
72432
  return markets[0];
72415
72433
  }
72416
72434
  else if ((symbol.indexOf('-C') > -1) || (symbol.indexOf('-P') > -1)) {
@@ -73107,10 +73125,10 @@ class bybit extends _abstract_bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
73107
73125
  // "change24h": "86"
73108
73126
  // }
73109
73127
  //
73128
+ const isSpot = this.safeString(ticker, 'openInterestValue') === undefined;
73110
73129
  const timestamp = this.safeInteger(ticker, 'time');
73111
73130
  const marketId = this.safeString(ticker, 'symbol');
73112
- const defaultType = this.safeString(this.options, 'defaultType', 'spot');
73113
- const type = this.safeString(market, 'type', defaultType);
73131
+ const type = isSpot ? 'spot' : 'contract';
73114
73132
  market = this.safeMarket(marketId, market, undefined, type);
73115
73133
  const symbol = this.safeSymbol(marketId, market, undefined, type);
73116
73134
  const last = this.safeString(ticker, 'lastPrice');
@@ -159687,7 +159705,7 @@ class lykke extends _abstract_lykke_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
159687
159705
  'fetchMarkets': true,
159688
159706
  'fetchMarkOHLCV': false,
159689
159707
  'fetchMyTrades': true,
159690
- 'fetchOHLCV': 'emulated',
159708
+ 'fetchOHLCV': undefined,
159691
159709
  'fetchOpenInterestHistory': false,
159692
159710
  'fetchOpenOrders': true,
159693
159711
  'fetchOrder': true,
@@ -186951,6 +186969,7 @@ class phemex extends _abstract_phemex_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
186951
186969
  }
186952
186970
  const unrealizedPnl = _base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise.stringMul */ .O.stringMul(_base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise.stringMul */ .O.stringMul(priceDiff, contracts), contractSizeString);
186953
186971
  const marginRatio = _base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise.stringDiv */ .O.stringDiv(maintenanceMarginString, collateral);
186972
+ const isCross = this.safeValue(position, 'crossMargin');
186954
186973
  return this.safePosition({
186955
186974
  'info': position,
186956
186975
  'id': undefined,
@@ -186973,7 +186992,7 @@ class phemex extends _abstract_phemex_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
186973
186992
  'maintenanceMarginPercentage': this.parseNumber(maintenanceMarginPercentageString),
186974
186993
  'marginRatio': this.parseNumber(marginRatio),
186975
186994
  'datetime': undefined,
186976
- 'marginMode': undefined,
186995
+ 'marginMode': isCross ? 'cross' : 'isolated',
186977
186996
  'side': side,
186978
186997
  'hedged': false,
186979
186998
  'percentage': undefined,
@@ -193630,7 +193649,7 @@ class binance extends _binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
193630
193649
  'name': 'kline', // or indexPriceKline or markPriceKline (coin-m futures)
193631
193650
  },
193632
193651
  'watchOrderBook': {
193633
- 'snapshotMaxRetries': 3,
193652
+ 'maxRetries': 3,
193634
193653
  },
193635
193654
  'watchBalance': {
193636
193655
  'fetchBalanceSnapshot': false,
@@ -197662,12 +197681,13 @@ class bitfinex2 extends _bitfinex2_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
197662
197681
  client.subscriptions[channelId] = message;
197663
197682
  return message;
197664
197683
  }
197665
- authenticate(params = {}) {
197684
+ async authenticate(params = {}) {
197666
197685
  const url = this.urls['api']['ws']['private'];
197667
197686
  const client = this.client(url);
197668
197687
  const messageHash = 'authenticated';
197669
- let future = this.safeValue(client.subscriptions, messageHash);
197670
- if (future === undefined) {
197688
+ const future = client.future(messageHash);
197689
+ const authenticated = this.safeValue(client.subscriptions, messageHash);
197690
+ if (authenticated === undefined) {
197671
197691
  const nonce = this.milliseconds();
197672
197692
  const payload = 'AUTH' + nonce.toString();
197673
197693
  const signature = this.hmac(this.encode(payload), this.encode(this.secret), _static_dependencies_noble_hashes_sha512_js__WEBPACK_IMPORTED_MODULE_4__/* .sha384 */ .iC, 'hex');
@@ -197680,8 +197700,7 @@ class bitfinex2 extends _bitfinex2_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
197680
197700
  'event': event,
197681
197701
  };
197682
197702
  const message = this.extend(request, params);
197683
- future = this.watch(url, messageHash, message);
197684
- client.subscriptions[messageHash] = future;
197703
+ this.watch(url, messageHash, message, messageHash);
197685
197704
  }
197686
197705
  return future;
197687
197706
  }
@@ -197690,7 +197709,8 @@ class bitfinex2 extends _bitfinex2_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
197690
197709
  const status = this.safeString(message, 'status');
197691
197710
  if (status === 'OK') {
197692
197711
  // we resolve the future here permanently so authentication only happens once
197693
- client.resolve(message, messageHash);
197712
+ const future = this.safeValue(client.futures, messageHash);
197713
+ future.resolve(true);
197694
197714
  }
197695
197715
  else {
197696
197716
  const error = new _base_errors_js__WEBPACK_IMPORTED_MODULE_3__.AuthenticationError(this.json(message));
@@ -198046,7 +198066,9 @@ class bitget extends _bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
198046
198066
  'ws': {
198047
198067
  'exact': {
198048
198068
  '30001': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadRequest,
198049
- '30015': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError, // { event: 'error', code: 30015, msg: 'Invalid sign' }
198069
+ '30015': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError,
198070
+ '30016': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadRequest,
198071
+ '30011': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError, // { event: 'error', code: 30011, msg: 'Invalid ACCESS_KEY' }
198050
198072
  },
198051
198073
  },
198052
198074
  },
@@ -199080,13 +199102,14 @@ class bitget extends _bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
199080
199102
  const message = this.extend(request, params);
199081
199103
  return await this.watch(url, messageHash, message, messageHash);
199082
199104
  }
199083
- authenticate(params = {}) {
199105
+ async authenticate(params = {}) {
199084
199106
  this.checkRequiredCredentials();
199085
199107
  const url = this.urls['api']['ws'];
199086
199108
  const client = this.client(url);
199087
199109
  const messageHash = 'authenticated';
199088
- let future = this.safeValue(client.subscriptions, messageHash);
199089
- if (future === undefined) {
199110
+ const future = client.future(messageHash);
199111
+ const authenticated = this.safeValue(client.subscriptions, messageHash);
199112
+ if (authenticated === undefined) {
199090
199113
  const timestamp = this.seconds().toString();
199091
199114
  const auth = timestamp + 'GET' + '/user/verify';
199092
199115
  const signature = this.hmac(this.encode(auth), this.encode(this.secret), _static_dependencies_noble_hashes_sha256_js__WEBPACK_IMPORTED_MODULE_4__/* .sha256 */ .J, 'base64');
@@ -199103,8 +199126,7 @@ class bitget extends _bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
199103
199126
  ],
199104
199127
  };
199105
199128
  const message = this.extend(request, params);
199106
- future = this.watch(url, messageHash, message);
199107
- client.subscriptions[messageHash] = future;
199129
+ this.watch(url, messageHash, message, messageHash);
199108
199130
  }
199109
199131
  return future;
199110
199132
  }
@@ -199123,7 +199145,8 @@ class bitget extends _bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
199123
199145
  // { event: 'login', code: 0 }
199124
199146
  //
199125
199147
  const messageHash = 'authenticated';
199126
- client.resolve(message, messageHash);
199148
+ const future = this.safeValue(client.futures, messageHash);
199149
+ future.resolve(true);
199127
199150
  }
199128
199151
  handleErrorMessage(client, message) {
199129
199152
  //
@@ -199737,13 +199760,14 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
199737
199760
  }
199738
199761
  return message;
199739
199762
  }
199740
- authenticate(params = {}) {
199763
+ async authenticate(params = {}) {
199741
199764
  this.checkRequiredCredentials();
199742
199765
  const url = this.implodeHostname(this.urls['api']['ws']['private']);
199743
199766
  const messageHash = 'authenticated';
199744
199767
  const client = this.client(url);
199745
- let future = this.safeValue(client.subscriptions, messageHash);
199746
- if (future === undefined) {
199768
+ const future = client.future(messageHash);
199769
+ const authenticated = this.safeValue(client.subscriptions, messageHash);
199770
+ if (authenticated === undefined) {
199747
199771
  const timestamp = this.milliseconds().toString();
199748
199772
  const memo = this.uid;
199749
199773
  const path = 'bitmart.WebSocket';
@@ -199759,8 +199783,7 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
199759
199783
  ],
199760
199784
  };
199761
199785
  const message = this.extend(request, params);
199762
- future = this.watch(url, messageHash, message);
199763
- client.subscriptions[messageHash] = future;
199786
+ this.watch(url, messageHash, message, messageHash);
199764
199787
  }
199765
199788
  return future;
199766
199789
  }
@@ -199775,7 +199798,8 @@ class bitmart extends _bitmart_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
199775
199798
  // { event: 'login' }
199776
199799
  //
199777
199800
  const messageHash = 'authenticated';
199778
- client.resolve(message, messageHash);
199801
+ const future = this.safeValue(client.futures, messageHash);
199802
+ future.resolve(true);
199779
199803
  }
199780
199804
  handleErrorMessage(client, message) {
199781
199805
  //
@@ -204010,7 +204034,7 @@ class bittrex extends _bittrex_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */
204010
204034
  'hub': 'c3',
204011
204035
  'I': this.milliseconds(),
204012
204036
  'watchOrderBook': {
204013
- 'snapshotMaxRetries': 3,
204037
+ 'maxRetries': 3,
204014
204038
  },
204015
204039
  },
204016
204040
  });
@@ -204596,8 +204620,7 @@ class bittrex extends _bittrex_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */
204596
204620
  // then we cannot align it with the cached deltas and we need to
204597
204621
  // retry synchronizing in maxAttempts
204598
204622
  if ((sequence !== undefined) && (nonce < sequence)) {
204599
- const options = this.safeValue(this.options, 'fetchOrderBookSnapshot', {});
204600
- const maxAttempts = this.safeInteger(options, 'maxAttempts', 3);
204623
+ const maxAttempts = this.handleOption('watchOrderBook', 'maxRetries', 3);
204601
204624
  let numAttempts = this.safeInteger(subscription, 'numAttempts', 0);
204602
204625
  // retry to syncrhonize if we haven't reached maxAttempts yet
204603
204626
  if (numAttempts < maxAttempts) {
@@ -206676,7 +206699,8 @@ class bybit extends _bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
206676
206699
  const topic = this.safeString(message, 'topic', '');
206677
206700
  const updateType = this.safeString(message, 'type', '');
206678
206701
  const data = this.safeValue(message, 'data', {});
206679
- const isSpot = this.safeString(data, 's') !== undefined;
206702
+ const isSpot = this.safeString(data, 'openInterestValue') === undefined;
206703
+ const type = isSpot ? 'spot' : 'contract';
206680
206704
  let symbol = undefined;
206681
206705
  let parsed = undefined;
206682
206706
  if ((updateType === 'snapshot') || isSpot) {
@@ -206687,7 +206711,7 @@ class bybit extends _bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
206687
206711
  const topicParts = topic.split('.');
206688
206712
  const topicLength = topicParts.length;
206689
206713
  const marketId = this.safeString(topicParts, topicLength - 1);
206690
- const market = this.market(marketId);
206714
+ const market = this.safeMarket(marketId, undefined, undefined, type);
206691
206715
  symbol = market['symbol'];
206692
206716
  // update the info in place
206693
206717
  const ticker = this.safeValue(this.tickers, symbol, {});
@@ -209825,7 +209849,7 @@ class coinbasepro extends _coinbasepro_js__WEBPACK_IMPORTED_MODULE_0__/* ["defau
209825
209849
  'watchOHLCV': false,
209826
209850
  'watchOrderBook': true,
209827
209851
  'watchTicker': true,
209828
- 'watchTickers': false,
209852
+ 'watchTickers': true,
209829
209853
  'watchTrades': true,
209830
209854
  'watchBalance': false,
209831
209855
  'watchStatus': false,
@@ -209860,10 +209884,16 @@ class coinbasepro extends _coinbasepro_js__WEBPACK_IMPORTED_MODULE_0__/* ["defau
209860
209884
  'passphrase': this.password,
209861
209885
  };
209862
209886
  }
209863
- async subscribe(name, symbol, messageHashStart, params = {}) {
209887
+ async subscribe(name, symbol = undefined, messageHashStart = undefined, params = {}) {
209864
209888
  await this.loadMarkets();
209865
- const market = this.market(symbol);
209866
- const messageHash = messageHashStart + ':' + market['id'];
209889
+ let market = undefined;
209890
+ let messageHash = messageHashStart;
209891
+ const productIds = [];
209892
+ if (symbol !== undefined) {
209893
+ market = this.market(symbol);
209894
+ messageHash += ':' + market['id'];
209895
+ productIds.push(market['id']);
209896
+ }
209867
209897
  let url = this.urls['api']['ws'];
209868
209898
  if ('signature' in params) {
209869
209899
  // need to distinguish between public trades and user trades
@@ -209871,9 +209901,33 @@ class coinbasepro extends _coinbasepro_js__WEBPACK_IMPORTED_MODULE_0__/* ["defau
209871
209901
  }
209872
209902
  const subscribe = {
209873
209903
  'type': 'subscribe',
209874
- 'product_ids': [
209875
- market['id'],
209904
+ 'product_ids': productIds,
209905
+ 'channels': [
209906
+ name,
209876
209907
  ],
209908
+ };
209909
+ const request = this.extend(subscribe, params);
209910
+ return await this.watch(url, messageHash, request, messageHash);
209911
+ }
209912
+ async subscribeMultiple(name, symbols = [], messageHashStart = undefined, params = {}) {
209913
+ await this.loadMarkets();
209914
+ let market = undefined;
209915
+ symbols = this.marketSymbols(symbols);
209916
+ const messageHash = messageHashStart + symbols.join(',');
209917
+ const productIds = [];
209918
+ for (let i = 0; i < symbols.length; i++) {
209919
+ const symbol = symbols[i];
209920
+ market = this.market(symbol);
209921
+ productIds.push(market['id']);
209922
+ }
209923
+ let url = this.urls['api']['ws'];
209924
+ if ('signature' in params) {
209925
+ // need to distinguish between public trades and user trades
209926
+ url = url + '?';
209927
+ }
209928
+ const subscribe = {
209929
+ 'type': 'subscribe',
209930
+ 'product_ids': productIds,
209877
209931
  'channels': [
209878
209932
  name,
209879
209933
  ],
@@ -209893,6 +209947,30 @@ class coinbasepro extends _coinbasepro_js__WEBPACK_IMPORTED_MODULE_0__/* ["defau
209893
209947
  const name = 'ticker';
209894
209948
  return await this.subscribe(name, symbol, name, params);
209895
209949
  }
209950
+ async watchTickers(symbols = undefined, params = {}) {
209951
+ /**
209952
+ * @method
209953
+ * @name okx#watchTickers
209954
+ * @see https://www.okx.com/docs-v5/en/#order-book-trading-market-data-ws-tickers-channel
209955
+ * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
209956
+ * @param {string[]} [symbols] unified symbol of the market to fetch the ticker for
209957
+ * @param {object} [params] extra parameters specific to the okx api endpoint
209958
+ * @param {string} [params.channel] the channel to subscribe to, tickers by default. Can be tickers, sprd-tickers, index-tickers, block-tickers
209959
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
209960
+ */
209961
+ await this.loadMarkets();
209962
+ const symbolsLength = symbols.length;
209963
+ if (symbolsLength === 0) {
209964
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadSymbol(this.id + ' watchTickers requires a non-empty symbols array');
209965
+ }
209966
+ const channel = 'ticker';
209967
+ const messageHash = 'tickers::';
209968
+ const newTickers = await this.subscribeMultiple(channel, symbols, messageHash, params);
209969
+ if (this.newUpdates) {
209970
+ return newTickers;
209971
+ }
209972
+ return this.filterByArray(this.tickers, 'symbol', symbols);
209973
+ }
209896
209974
  async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
209897
209975
  /**
209898
209976
  * @method
@@ -209924,9 +210002,7 @@ class coinbasepro extends _coinbasepro_js__WEBPACK_IMPORTED_MODULE_0__/* ["defau
209924
210002
  * @param {object} [params] extra parameters specific to the coinbasepro api endpoint
209925
210003
  * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
209926
210004
  */
209927
- if (symbol === undefined) {
209928
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadSymbol(this.id + ' watchMyTrades requires a symbol');
209929
- }
210005
+ this.checkRequiredSymbol('watchMyTrades', symbol);
209930
210006
  await this.loadMarkets();
209931
210007
  symbol = this.symbol(symbol);
209932
210008
  const name = 'user';
@@ -210382,6 +210458,16 @@ class coinbasepro extends _coinbasepro_js__WEBPACK_IMPORTED_MODULE_0__/* ["defau
210382
210458
  const type = this.safeString(message, 'type');
210383
210459
  const messageHash = type + ':' + marketId;
210384
210460
  client.resolve(ticker, messageHash);
210461
+ const messageHashes = this.findMessageHashes(client, 'tickers::');
210462
+ for (let i = 0; i < messageHashes.length; i++) {
210463
+ const messageHash = messageHashes[i];
210464
+ const parts = messageHash.split('::');
210465
+ const symbolsString = parts[1];
210466
+ const symbols = symbolsString.split(',');
210467
+ if (this.inArray(symbol, symbols)) {
210468
+ client.resolve(ticker, messageHash);
210469
+ }
210470
+ }
210385
210471
  }
210386
210472
  return message;
210387
210473
  }
@@ -217420,7 +217506,9 @@ class huobi extends _huobi_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
217420
217506
  'tradesLimit': 1000,
217421
217507
  'OHLCVLimit': 1000,
217422
217508
  'api': 'api',
217423
- 'maxOrderBookSyncAttempts': 3,
217509
+ 'watchOrderBook': {
217510
+ 'maxRetries': 3,
217511
+ },
217424
217512
  'ws': {
217425
217513
  'gunzip': true,
217426
217514
  },
@@ -217718,7 +217806,7 @@ class huobi extends _huobi_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
217718
217806
  const snapshotOrderBook = this.orderBook(snapshot, snapshotLimit);
217719
217807
  client.resolve(snapshotOrderBook, id);
217720
217808
  if ((sequence !== undefined) && (nonce < sequence)) {
217721
- const maxAttempts = this.safeInteger(this.options, 'maxOrderBookSyncAttempts', 3);
217809
+ const maxAttempts = this.handleOption('watchOrderBook', 'maxRetries', 3);
217722
217810
  let numAttempts = this.safeInteger(subscription, 'numAttempts', 0);
217723
217811
  // retry to synchronize if we have not reached maxAttempts yet
217724
217812
  if (numAttempts < maxAttempts) {
@@ -220197,7 +220285,7 @@ class idex extends _idex_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
220197
220285
  'orderBookSubscriptions': {},
220198
220286
  'token': undefined,
220199
220287
  'watchOrderBook': {
220200
- 'snapshotMaxRetries': 3,
220288
+ 'maxRetries': 3,
220201
220289
  },
220202
220290
  'fetchOrderBookSnapshotMaxAttempts': 10,
220203
220291
  'fetchOrderBookSnapshotMaxDelay': 10000, // throw if there are no orders in 10 seconds
@@ -254907,19 +254995,32 @@ class wavesexchange extends _abstract_wavesexchange_js__WEBPACK_IMPORTED_MODULE_
254907
254995
  }
254908
254996
  parseOrderBookSide(bookSide, market = undefined, limit = undefined) {
254909
254997
  const precision = market['precision'];
254910
- const wavesPrecision = this.safeInteger(this.options, 'wavesPrecision', 8);
254911
- const amountPrecision = Math.pow(10, precision['amount']);
254912
- const difference = precision['amount'] - precision['price'];
254913
- const pricePrecision = Math.pow(10, wavesPrecision - difference);
254998
+ const wavesPrecision = this.safeString(this.options, 'wavesPrecision', '8');
254999
+ const amountPrecision = '1e' + this.numberToString(precision['amount']);
255000
+ const amountPrecisionString = this.numberToString(precision['amount']);
255001
+ const pricePrecisionString = this.numberToString(precision['price']);
255002
+ const difference = _base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise.stringSub */ .O.stringSub(amountPrecisionString, pricePrecisionString);
255003
+ const pricePrecision = '1e' + _base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise.stringSub */ .O.stringSub(wavesPrecision, difference);
254914
255004
  const result = [];
254915
255005
  for (let i = 0; i < bookSide.length; i++) {
254916
255006
  const entry = bookSide[i];
254917
- const price = this.safeInteger(entry, 'price', 0) / pricePrecision;
254918
- const amount = this.safeInteger(entry, 'amount', 0) / amountPrecision;
255007
+ const entryPrice = this.safeString(entry, 'price', '0');
255008
+ const entryAmount = this.safeString(entry, 'amount', '0');
255009
+ let price = undefined;
255010
+ let amount = undefined;
255011
+ if ((pricePrecision !== undefined) && (entryPrice !== undefined)) {
255012
+ price = _base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise.stringDiv */ .O.stringDiv(entryPrice, pricePrecision);
255013
+ }
255014
+ if ((amountPrecision !== undefined) && (entryAmount !== undefined)) {
255015
+ amount = _base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise.stringDiv */ .O.stringDiv(entryAmount, amountPrecision);
255016
+ }
254919
255017
  if ((limit !== undefined) && (i > limit)) {
254920
255018
  break;
254921
255019
  }
254922
- result.push([price, amount]);
255020
+ result.push([
255021
+ this.parseNumber(price),
255022
+ this.parseNumber(amount),
255023
+ ]);
254923
255024
  }
254924
255025
  return result;
254925
255026
  }
@@ -255499,15 +255600,21 @@ class wavesexchange extends _abstract_wavesexchange_js__WEBPACK_IMPORTED_MODULE_
255499
255600
  }
255500
255601
  customPriceToPrecision(symbol, price) {
255501
255602
  const market = this.markets[symbol];
255502
- const wavesPrecision = this.safeInteger(this.options, 'wavesPrecision', 8);
255503
- const difference = market['precision']['amount'] - market['precision']['price'];
255504
- return this.parseToInt(parseFloat(this.toPrecision(price, wavesPrecision - difference)));
255603
+ const wavesPrecision = this.safeString(this.options, 'wavesPrecision', '8');
255604
+ const amount = this.numberToString(market['precision']['amount']);
255605
+ const precisionPrice = this.numberToString(market['precision']['price']);
255606
+ const difference = _base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise.stringSub */ .O.stringSub(amount, precisionPrice);
255607
+ const precision = _base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise.stringSub */ .O.stringSub(wavesPrecision, difference);
255608
+ const pricePrecision = this.toPrecision(price, precision).toString();
255609
+ return this.parseToInt(parseFloat(pricePrecision));
255505
255610
  }
255506
255611
  customAmountToPrecision(symbol, amount) {
255507
- return this.parseToInt(parseFloat(this.toPrecision(amount, this.markets[symbol]['precision']['amount'])));
255612
+ const amountPrecision = this.numberToString(this.toPrecision(amount, this.numberToString(this.markets[symbol]['precision']['amount'])));
255613
+ return this.parseToInt(parseFloat(amountPrecision));
255508
255614
  }
255509
255615
  currencyToPrecision(code, amount, networkCode = undefined) {
255510
- return this.parseToInt(parseFloat(this.toPrecision(amount, this.currencies[code]['precision'])));
255616
+ const amountPrecision = this.numberToString(this.toPrecision(amount, this.currencies[code]['precision']));
255617
+ return this.parseToInt(parseFloat(amountPrecision));
255511
255618
  }
255512
255619
  fromPrecision(amount, scale) {
255513
255620
  if (amount === undefined) {
@@ -255519,11 +255626,11 @@ class wavesexchange extends _abstract_wavesexchange_js__WEBPACK_IMPORTED_MODULE_
255519
255626
  return precise.toString();
255520
255627
  }
255521
255628
  toPrecision(amount, scale) {
255522
- const amountString = amount.toString();
255629
+ const amountString = this.numberToString(amount);
255523
255630
  const precise = new _base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise */ .O(amountString);
255524
- precise.decimals = precise.decimals - scale;
255631
+ precise.decimals = _base_Precise_js__WEBPACK_IMPORTED_MODULE_3__/* .Precise.stringSub */ .O.stringSub(precise.decimals, scale);
255525
255632
  precise.reduce();
255526
- return precise.toString();
255633
+ return precise;
255527
255634
  }
255528
255635
  currencyFromPrecision(currency, amount) {
255529
255636
  const scale = this.currencies[currency]['precision'];
@@ -272218,7 +272325,7 @@ SOFTWARE.
272218
272325
 
272219
272326
  //-----------------------------------------------------------------------------
272220
272327
  // this is updated by vss.js when building
272221
- const version = '4.0.66';
272328
+ const version = '4.0.68';
272222
272329
  _src_base_Exchange_js__WEBPACK_IMPORTED_MODULE_0__/* .Exchange.ccxtVersion */ .e.ccxtVersion = version;
272223
272330
  //-----------------------------------------------------------------------------
272224
272331