ccxt 4.4.90 → 4.4.91

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 (55) hide show
  1. package/README.md +5 -6
  2. package/dist/ccxt.browser.min.js +2 -2
  3. package/dist/cjs/ccxt.js +1 -4
  4. package/dist/cjs/src/base/Exchange.js +9 -11
  5. package/dist/cjs/src/base/ws/Client.js +4 -34
  6. package/dist/cjs/src/binance.js +1 -1
  7. package/dist/cjs/src/bitmex.js +2 -1
  8. package/dist/cjs/src/cex.js +61 -0
  9. package/dist/cjs/src/cryptocom.js +21 -2
  10. package/dist/cjs/src/cryptomus.js +1 -1
  11. package/dist/cjs/src/exmo.js +14 -7
  12. package/dist/cjs/src/fmfwio.js +1 -1
  13. package/dist/cjs/src/gate.js +2 -2
  14. package/dist/cjs/src/hyperliquid.js +115 -59
  15. package/dist/cjs/src/kraken.js +29 -1
  16. package/dist/cjs/src/mexc.js +1 -0
  17. package/dist/cjs/src/modetrade.js +2 -2
  18. package/dist/cjs/src/paradex.js +1 -1
  19. package/dist/cjs/src/pro/bitstamp.js +1 -1
  20. package/dist/cjs/src/pro/bybit.js +6 -143
  21. package/dist/cjs/src/pro/kraken.js +251 -264
  22. package/dist/cjs/src/pro/mexc.js +0 -1
  23. package/js/ccxt.d.ts +2 -5
  24. package/js/ccxt.js +2 -4
  25. package/js/src/base/Exchange.d.ts +2 -1
  26. package/js/src/base/Exchange.js +10 -12
  27. package/js/src/base/ws/Client.d.ts +0 -2
  28. package/js/src/base/ws/Client.js +4 -34
  29. package/js/src/binance.js +1 -1
  30. package/js/src/bitmex.js +2 -1
  31. package/js/src/cex.js +61 -0
  32. package/js/src/cryptocom.js +21 -2
  33. package/js/src/cryptomus.js +1 -1
  34. package/js/src/exmo.js +14 -7
  35. package/js/src/fmfwio.js +2 -2
  36. package/js/src/gate.js +2 -2
  37. package/js/src/hyperliquid.d.ts +1 -0
  38. package/js/src/hyperliquid.js +115 -59
  39. package/js/src/kraken.js +29 -1
  40. package/js/src/mexc.js +1 -0
  41. package/js/src/modetrade.js +2 -2
  42. package/js/src/p2b.d.ts +1 -2
  43. package/js/src/paradex.js +1 -1
  44. package/js/src/pro/bitstamp.js +1 -1
  45. package/js/src/pro/bybit.d.ts +0 -1
  46. package/js/src/pro/bybit.js +6 -143
  47. package/js/src/pro/kraken.d.ts +17 -17
  48. package/js/src/pro/kraken.js +251 -264
  49. package/js/src/pro/mexc.js +0 -1
  50. package/js/src/tradeogre.d.ts +1 -2
  51. package/package.json +1 -1
  52. package/js/src/abstract/coinlist.d.ts +0 -60
  53. package/js/src/abstract/coinlist.js +0 -11
  54. package/js/src/coinlist.d.ts +0 -384
  55. package/js/src/coinlist.js +0 -2610
@@ -37,6 +37,7 @@ class kraken extends kraken$1 {
37
37
  'public': 'wss://ws.kraken.com',
38
38
  'private': 'wss://ws-auth.kraken.com',
39
39
  'privateV2': 'wss://ws-auth.kraken.com/v2',
40
+ 'publicV2': 'wss://ws.kraken.com/v2',
40
41
  'beta': 'wss://beta-ws.kraken.com',
41
42
  'beta-private': 'wss://beta-ws-auth.kraken.com',
42
43
  },
@@ -51,9 +52,13 @@ class kraken extends kraken$1 {
51
52
  'ordersLimit': 1000,
52
53
  'symbolsByOrderId': {},
53
54
  'watchOrderBook': {
54
- 'checksum': true,
55
+ 'checksum': false,
55
56
  },
56
57
  },
58
+ 'streaming': {
59
+ 'ping': this.ping,
60
+ 'keepAlive': 6000,
61
+ },
57
62
  'exceptions': {
58
63
  'ws': {
59
64
  'exact': {
@@ -104,6 +109,7 @@ class kraken extends kraken$1 {
104
109
  'EService:Market in post_only mode': errors.NotSupported,
105
110
  'EService:Unavailable': errors.ExchangeNotAvailable,
106
111
  'ETrade:Invalid request': errors.BadRequest,
112
+ 'ESession:Invalid session': errors.AuthenticationError,
107
113
  },
108
114
  },
109
115
  },
@@ -371,8 +377,8 @@ class kraken extends kraken$1 {
371
377
  /**
372
378
  * @method
373
379
  * @name kraken#cancelOrdersWs
374
- * @see https://docs.kraken.com/api/docs/websocket-v1/cancelorder
375
380
  * @description cancel multiple orders
381
+ * @see https://docs.kraken.com/api/docs/websocket-v2/cancel_order
376
382
  * @param {string[]} ids order ids
377
383
  * @param {string} [symbol] unified market symbol, default is undefined
378
384
  * @param {object} [params] extra parameters specific to the exchange API endpoint
@@ -400,8 +406,8 @@ class kraken extends kraken$1 {
400
406
  /**
401
407
  * @method
402
408
  * @name kraken#cancelOrderWs
403
- * @see https://docs.kraken.com/api/docs/websocket-v1/cancelorder
404
409
  * @description cancels an open order
410
+ * @see https://docs.kraken.com/api/docs/websocket-v2/cancel_order
405
411
  * @param {string} id order id
406
412
  * @param {string} [symbol] unified symbol of the market the order was made in
407
413
  * @param {object} [params] extra parameters specific to the exchange API endpoint
@@ -445,8 +451,8 @@ class kraken extends kraken$1 {
445
451
  /**
446
452
  * @method
447
453
  * @name kraken#cancelAllOrdersWs
448
- * @see https://docs.kraken.com/api/docs/websocket-v1/cancelall
449
454
  * @description cancel all open orders
455
+ * @see https://docs.kraken.com/api/docs/websocket-v2/cancel_all
450
456
  * @param {string} [symbol] unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
451
457
  * @param {object} [params] extra parameters specific to the exchange API endpoint
452
458
  * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
@@ -485,54 +491,57 @@ class kraken extends kraken$1 {
485
491
  const reqId = this.safeValue(message, 'req_id');
486
492
  client.resolve(message, reqId);
487
493
  }
488
- handleTicker(client, message, subscription) {
494
+ handleTicker(client, message) {
489
495
  //
490
- // [
491
- // 0, // channelID
492
- // {
493
- // "a": [ "5525.40000", 1, "1.000" ], // ask, wholeAskVolume, askVolume
494
- // "b": [ "5525.10000", 1, "1.000" ], // bid, wholeBidVolume, bidVolume
495
- // "c": [ "5525.10000", "0.00398963" ], // closing price, volume
496
- // "h": [ "5783.00000", "5783.00000" ], // high price today, high price 24h ago
497
- // "l": [ "5505.00000", "5505.00000" ], // low price today, low price 24h ago
498
- // "o": [ "5760.70000", "5763.40000" ], // open price today, open price 24h ago
499
- // "p": [ "5631.44067", "5653.78939" ], // vwap today, vwap 24h ago
500
- // "t": [ 11493, 16267 ], // number of trades today, 24 hours ago
501
- // "v": [ "2634.11501494", "3591.17907851" ], // volume today, volume 24 hours ago
502
- // },
503
- // "ticker",
504
- // "XBT/USD"
505
- // ]
496
+ // {
497
+ // "channel": "ticker",
498
+ // "type": "snapshot",
499
+ // "data": [
500
+ // {
501
+ // "symbol": "BTC/USD",
502
+ // "bid": 108359.8,
503
+ // "bid_qty": 0.01362603,
504
+ // "ask": 108359.9,
505
+ // "ask_qty": 17.17988863,
506
+ // "last": 108359.8,
507
+ // "volume": 2158.32346723,
508
+ // "vwap": 108894.5,
509
+ // "low": 106824,
510
+ // "high": 111300,
511
+ // "change": -2679.9,
512
+ // "change_pct": -2.41
513
+ // }
514
+ // ]
515
+ // }
506
516
  //
507
- const wsName = message[3];
508
- const market = this.safeValue(this.options['marketsByWsName'], wsName);
509
- const symbol = market['symbol'];
517
+ const data = this.safeList(message, 'data', []);
518
+ const ticker = data[0];
519
+ const symbol = this.safeString(ticker, 'symbol');
510
520
  const messageHash = this.getMessageHash('ticker', undefined, symbol);
511
- const ticker = message[1];
512
- const vwap = this.safeString(ticker['p'], 0);
521
+ const vwap = this.safeString(ticker, 'vwap');
513
522
  let quoteVolume = undefined;
514
- const baseVolume = this.safeString(ticker['v'], 0);
523
+ const baseVolume = this.safeString(ticker, 'volume');
515
524
  if (baseVolume !== undefined && vwap !== undefined) {
516
525
  quoteVolume = Precise["default"].stringMul(baseVolume, vwap);
517
526
  }
518
- const last = this.safeString(ticker['c'], 0);
527
+ const last = this.safeString(ticker, 'last');
519
528
  const result = this.safeTicker({
520
529
  'symbol': symbol,
521
530
  'timestamp': undefined,
522
531
  'datetime': undefined,
523
- 'high': this.safeString(ticker['h'], 0),
524
- 'low': this.safeString(ticker['l'], 0),
525
- 'bid': this.safeString(ticker['b'], 0),
526
- 'bidVolume': this.safeString(ticker['b'], 2),
527
- 'ask': this.safeString(ticker['a'], 0),
528
- 'askVolume': this.safeString(ticker['a'], 2),
532
+ 'high': this.safeString(ticker, 'high'),
533
+ 'low': this.safeString(ticker, 'low'),
534
+ 'bid': this.safeString(ticker, 'bid'),
535
+ 'bidVolume': this.safeString(ticker, 'bid_qty'),
536
+ 'ask': this.safeString(ticker, 'ask'),
537
+ 'askVolume': this.safeString(ticker, 'ask_qty'),
529
538
  'vwap': vwap,
530
- 'open': this.safeString(ticker['o'], 0),
539
+ 'open': undefined,
531
540
  'close': last,
532
541
  'last': last,
533
542
  'previousClose': undefined,
534
- 'change': undefined,
535
- 'percentage': undefined,
543
+ 'change': this.safeString(ticker, 'change'),
544
+ 'percentage': this.safeString(ticker, 'change_pct'),
536
545
  'average': undefined,
537
546
  'baseVolume': baseVolume,
538
547
  'quoteVolume': quoteVolume,
@@ -541,31 +550,36 @@ class kraken extends kraken$1 {
541
550
  this.tickers[symbol] = result;
542
551
  client.resolve(result, messageHash);
543
552
  }
544
- handleTrades(client, message, subscription) {
553
+ handleTrades(client, message) {
545
554
  //
546
- // [
547
- // 0, // channelID
548
- // [ // price volume time side type misc
549
- // [ "5541.20000", "0.15850568", "1534614057.321596", "s", "l", "" ],
550
- // [ "6060.00000", "0.02455000", "1534614057.324998", "b", "l", "" ],
551
- // ],
552
- // "trade",
553
- // "XBT/USD"
554
- // ]
555
+ // {
556
+ // "channel": "trade",
557
+ // "type": "update",
558
+ // "data": [
559
+ // {
560
+ // "symbol": "MATIC/USD",
561
+ // "side": "sell",
562
+ // "price": 0.5117,
563
+ // "qty": 40.0,
564
+ // "ord_type": "market",
565
+ // "trade_id": 4665906,
566
+ // "timestamp": "2023-09-25T07:49:37.708706Z"
567
+ // }
568
+ // ]
569
+ // }
555
570
  //
556
- const wsName = this.safeString(message, 3);
557
- const name = this.safeString(message, 2);
558
- const market = this.safeValue(this.options['marketsByWsName'], wsName);
559
- const symbol = market['symbol'];
560
- const messageHash = this.getMessageHash(name, undefined, symbol);
571
+ const data = this.safeList(message, 'data', []);
572
+ const trade = data[0];
573
+ const symbol = this.safeString(trade, 'symbol');
574
+ const messageHash = this.getMessageHash('trade', undefined, symbol);
561
575
  let stored = this.safeValue(this.trades, symbol);
562
576
  if (stored === undefined) {
563
577
  const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
564
578
  stored = new Cache.ArrayCache(limit);
565
579
  this.trades[symbol] = stored;
566
580
  }
567
- const trades = this.safeValue(message, 1, []);
568
- const parsed = this.parseTrades(trades, market);
581
+ const market = this.market(symbol);
582
+ const parsed = this.parseTrades(data, market);
569
583
  for (let i = 0; i < parsed.length; i++) {
570
584
  stored.append(parsed[i]);
571
585
  }
@@ -653,7 +667,7 @@ class kraken extends kraken$1 {
653
667
  * @method
654
668
  * @name kraken#watchTicker
655
669
  * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
656
- * @see https://docs.kraken.com/api/docs/websocket-v1/ticker
670
+ * @see https://docs.kraken.com/api/docs/websocket-v2/ticker
657
671
  * @param {string} symbol unified symbol of the market to fetch the ticker for
658
672
  * @param {object} [params] extra parameters specific to the exchange API endpoint
659
673
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
@@ -668,7 +682,7 @@ class kraken extends kraken$1 {
668
682
  * @method
669
683
  * @name kraken#watchTickers
670
684
  * @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
671
- * @see https://docs.kraken.com/api/docs/websocket-v1/ticker
685
+ * @see https://docs.kraken.com/api/docs/websocket-v2/ticker
672
686
  * @param {string[]} symbols
673
687
  * @param {object} [params] extra parameters specific to the exchange API endpoint
674
688
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
@@ -687,8 +701,8 @@ class kraken extends kraken$1 {
687
701
  /**
688
702
  * @method
689
703
  * @name kraken#watchBidsAsks
690
- * @see https://docs.kraken.com/api/docs/websocket-v1/spread
691
704
  * @description watches best bid & ask for symbols
705
+ * @see https://docs.kraken.com/api/docs/websocket-v2/ticker
692
706
  * @param {string[]} symbols unified symbol of the market to fetch the ticker for
693
707
  * @param {object} [params] extra parameters specific to the exchange API endpoint
694
708
  * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
@@ -696,7 +710,8 @@ class kraken extends kraken$1 {
696
710
  async watchBidsAsks(symbols = undefined, params = {}) {
697
711
  await this.loadMarkets();
698
712
  symbols = this.marketSymbols(symbols, undefined, false);
699
- const ticker = await this.watchMultiHelper('bidask', 'spread', symbols, undefined, params);
713
+ params['event_trigger'] = 'bbo';
714
+ const ticker = await this.watchMultiHelper('bidask', 'ticker', symbols, undefined, params);
700
715
  if (this.newUpdates) {
701
716
  const result = {};
702
717
  result[ticker['symbol']] = ticker;
@@ -704,49 +719,11 @@ class kraken extends kraken$1 {
704
719
  }
705
720
  return this.filterByArray(this.bidsasks, 'symbol', symbols);
706
721
  }
707
- handleBidAsk(client, message, subscription) {
708
- //
709
- // [
710
- // 7208974, // channelID
711
- // [
712
- // "63758.60000", // bid
713
- // "63759.10000", // ask
714
- // "1726814731.089778", // timestamp
715
- // "0.00057917", // bid_volume
716
- // "0.15681688" // ask_volume
717
- // ],
718
- // "spread",
719
- // "XBT/USDT"
720
- // ]
721
- //
722
- const parsedTicker = this.parseWsBidAsk(message);
723
- const symbol = parsedTicker['symbol'];
724
- this.bidsasks[symbol] = parsedTicker;
725
- const messageHash = this.getMessageHash('bidask', undefined, symbol);
726
- client.resolve(parsedTicker, messageHash);
727
- }
728
- parseWsBidAsk(ticker, market = undefined) {
729
- const data = this.safeList(ticker, 1, []);
730
- const marketId = this.safeString(ticker, 3);
731
- market = this.safeValue(this.options['marketsByWsName'], marketId);
732
- const symbol = this.safeString(market, 'symbol');
733
- const timestamp = this.parseToInt(this.safeInteger(data, 2)) * 1000;
734
- return this.safeTicker({
735
- 'symbol': symbol,
736
- 'timestamp': timestamp,
737
- 'datetime': this.iso8601(timestamp),
738
- 'ask': this.safeString(data, 1),
739
- 'askVolume': this.safeString(data, 4),
740
- 'bid': this.safeString(data, 0),
741
- 'bidVolume': this.safeString(data, 3),
742
- 'info': ticker,
743
- }, market);
744
- }
745
722
  /**
746
723
  * @method
747
724
  * @name kraken#watchTrades
748
725
  * @description get the list of most recent trades for a particular symbol
749
- * @see https://docs.kraken.com/api/docs/websocket-v1/trade
726
+ * @see https://docs.kraken.com/api/docs/websocket-v2/trade
750
727
  * @param {string} symbol unified symbol of the market to fetch trades for
751
728
  * @param {int} [since] timestamp in ms of the earliest trade to fetch
752
729
  * @param {int} [limit] the maximum amount of trades to fetch
@@ -759,8 +736,8 @@ class kraken extends kraken$1 {
759
736
  /**
760
737
  * @method
761
738
  * @name kraken#watchTradesForSymbols
762
- * @see https://docs.kraken.com/api/docs/websocket-v1/trade
763
739
  * @description get the list of most recent trades for a list of symbols
740
+ * @see https://docs.kraken.com/api/docs/websocket-v2/trade
764
741
  * @param {string[]} symbols unified symbol of the market to fetch trades for
765
742
  * @param {int} [since] timestamp in ms of the earliest trade to fetch
766
743
  * @param {int} [limit] the maximum amount of trades to fetch
@@ -780,7 +757,7 @@ class kraken extends kraken$1 {
780
757
  * @method
781
758
  * @name kraken#watchOrderBook
782
759
  * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
783
- * @see https://docs.kraken.com/api/docs/websocket-v1/book
760
+ * @see https://docs.kraken.com/api/docs/websocket-v2/book
784
761
  * @param {string} symbol unified symbol of the market to fetch the order book for
785
762
  * @param {int} [limit] the maximum amount of order book entries to return
786
763
  * @param {object} [params] extra parameters specific to the exchange API endpoint
@@ -793,7 +770,7 @@ class kraken extends kraken$1 {
793
770
  * @method
794
771
  * @name kraken#watchOrderBookForSymbols
795
772
  * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
796
- * @see https://docs.kraken.com/api/docs/websocket-v1/book
773
+ * @see https://docs.kraken.com/api/docs/websocket-v2/book
797
774
  * @param {string[]} symbols unified array of symbols
798
775
  * @param {int} [limit] the maximum amount of order book entries to return
799
776
  * @param {object} [params] extra parameters specific to the exchange API endpoint
@@ -803,7 +780,7 @@ class kraken extends kraken$1 {
803
780
  const request = {};
804
781
  if (limit !== undefined) {
805
782
  if (this.inArray(limit, [10, 25, 100, 500, 1000])) {
806
- request['subscription'] = {
783
+ request['params'] = {
807
784
  'depth': limit, // default 10, valid options 10, 25, 100, 500, 1000
808
785
  };
809
786
  }
@@ -869,6 +846,21 @@ class kraken extends kraken$1 {
869
846
  }
870
847
  return markets;
871
848
  }
849
+ ping(client) {
850
+ const url = client.url;
851
+ const request = {};
852
+ if (url.indexOf('v2') >= 0) {
853
+ request['method'] = 'ping';
854
+ }
855
+ else {
856
+ request['event'] = 'ping';
857
+ }
858
+ return request;
859
+ }
860
+ handlePong(client, message) {
861
+ client.lastPong = this.milliseconds();
862
+ return message;
863
+ }
872
864
  async watchHeartbeat(params = {}) {
873
865
  await this.loadMarkets();
874
866
  const event = 'heartbeat';
@@ -884,175 +876,165 @@ class kraken extends kraken$1 {
884
876
  const event = this.safeString(message, 'event');
885
877
  client.resolve(message, event);
886
878
  }
887
- handleOrderBook(client, message, subscription) {
879
+ handleOrderBook(client, message) {
888
880
  //
889
881
  // first message (snapshot)
890
882
  //
891
- // [
892
- // 1234, // channelID
893
- // {
894
- // "as": [
895
- // [ "5541.30000", "2.50700000", "1534614248.123678" ],
896
- // [ "5541.80000", "0.33000000", "1534614098.345543" ],
897
- // [ "5542.70000", "0.64700000", "1534614244.654432" ]
898
- // ],
899
- // "bs": [
900
- // [ "5541.20000", "1.52900000", "1534614248.765567" ],
901
- // [ "5539.90000", "0.30000000", "1534614241.769870" ],
902
- // [ "5539.50000", "5.00000000", "1534613831.243486" ]
903
- // ]
904
- // },
905
- // "book-10",
906
- // "XBT/USD"
907
- // ]
883
+ // {
884
+ // "channel": "book",
885
+ // "type": "snapshot",
886
+ // "data": [
887
+ // {
888
+ // "symbol": "MATIC/USD",
889
+ // "bids": [
890
+ // {
891
+ // "price": 0.5666,
892
+ // "qty": 4831.75496356
893
+ // },
894
+ // {
895
+ // "price": 0.5665,
896
+ // "qty": 6658.22734739
897
+ // }
898
+ // ],
899
+ // "asks": [
900
+ // {
901
+ // "price": 0.5668,
902
+ // "qty": 4410.79769741
903
+ // },
904
+ // {
905
+ // "price": 0.5669,
906
+ // "qty": 4655.40412487
907
+ // }
908
+ // ],
909
+ // "checksum": 2439117997
910
+ // }
911
+ // ]
912
+ // }
908
913
  //
909
914
  // subsequent updates
910
915
  //
911
- // [
912
- // 1234,
913
- // { // optional
914
- // "a": [
915
- // [ "5541.30000", "2.50700000", "1534614248.456738" ],
916
- // [ "5542.50000", "0.40100000", "1534614248.456738" ]
917
- // ]
918
- // },
919
- // { // optional
920
- // "b": [
921
- // [ "5541.30000", "0.00000000", "1534614335.345903" ]
922
- // ]
923
- // },
924
- // "book-10",
925
- // "XBT/USD"
926
- // ]
916
+ // {
917
+ // "channel": "book",
918
+ // "type": "update",
919
+ // "data": [
920
+ // {
921
+ // "symbol": "MATIC/USD",
922
+ // "bids": [
923
+ // {
924
+ // "price": 0.5657,
925
+ // "qty": 1098.3947558
926
+ // }
927
+ // ],
928
+ // "asks": [],
929
+ // "checksum": 2114181697,
930
+ // "timestamp": "2023-10-06T17:35:55.440295Z"
931
+ // }
932
+ // ]
933
+ // }
927
934
  //
928
- const messageLength = message.length;
929
- const wsName = message[messageLength - 1];
930
- const bookDepthString = message[messageLength - 2];
931
- const parts = bookDepthString.split('-');
932
- const depth = this.safeInteger(parts, 1, 10);
933
- const market = this.safeValue(this.options['marketsByWsName'], wsName);
934
- const symbol = market['symbol'];
935
- let timestamp = undefined;
935
+ const type = this.safeString(message, 'type');
936
+ const data = this.safeList(message, 'data', []);
937
+ const first = this.safeDict(data, 0, {});
938
+ const symbol = this.safeString(first, 'symbol');
939
+ const a = this.safeValue(first, 'asks', []);
940
+ const b = this.safeValue(first, 'bids', []);
941
+ const c = this.safeInteger(first, 'checksum');
936
942
  const messageHash = this.getMessageHash('orderbook', undefined, symbol);
937
- // if this is a snapshot
938
- if ('as' in message[1]) {
939
- // todo get depth from marketsByWsName
943
+ let orderbook = undefined;
944
+ if (type === 'update') {
945
+ orderbook = this.orderbooks[symbol];
946
+ const storedAsks = orderbook['asks'];
947
+ const storedBids = orderbook['bids'];
948
+ if (a !== undefined) {
949
+ this.customHandleDeltas(storedAsks, a);
950
+ }
951
+ if (b !== undefined) {
952
+ this.customHandleDeltas(storedBids, b);
953
+ }
954
+ const datetime = this.safeString(first, 'timestamp');
955
+ orderbook['symbol'] = symbol;
956
+ orderbook['timestamp'] = this.parse8601(datetime);
957
+ orderbook['datetime'] = datetime;
958
+ }
959
+ else {
960
+ // snapshot
961
+ const depth = a.length;
940
962
  this.orderbooks[symbol] = this.orderBook({}, depth);
941
- const orderbook = this.orderbooks[symbol];
942
- const sides = {
943
- 'as': 'asks',
944
- 'bs': 'bids',
945
- };
946
- const keys = Object.keys(sides);
963
+ orderbook = this.orderbooks[symbol];
964
+ const keys = ['asks', 'bids'];
947
965
  for (let i = 0; i < keys.length; i++) {
948
966
  const key = keys[i];
949
- const side = sides[key];
950
- const bookside = orderbook[side];
951
- const deltas = this.safeValue(message[1], key, []);
952
- timestamp = this.customHandleDeltas(bookside, deltas, timestamp);
967
+ const bookside = orderbook[key];
968
+ const deltas = this.safeValue(first, key, []);
969
+ if (deltas.length > 0) {
970
+ this.customHandleDeltas(bookside, deltas);
971
+ }
953
972
  }
954
973
  orderbook['symbol'] = symbol;
955
- orderbook['timestamp'] = timestamp;
956
- orderbook['datetime'] = this.iso8601(timestamp);
957
- client.resolve(orderbook, messageHash);
958
974
  }
959
- else {
960
- const orderbook = this.orderbooks[symbol];
961
- // else, if this is an orderbook update
962
- let a = undefined;
963
- let b = undefined;
964
- let c = undefined;
965
- if (messageLength === 5) {
966
- a = this.safeValue(message[1], 'a', []);
967
- b = this.safeValue(message[2], 'b', []);
968
- c = this.safeInteger(message[1], 'c');
969
- c = this.safeInteger(message[2], 'c', c);
970
- }
971
- else {
972
- c = this.safeInteger(message[1], 'c');
973
- if ('a' in message[1]) {
974
- a = this.safeValue(message[1], 'a', []);
975
+ orderbook.limit();
976
+ // checksum temporarily disabled because the exchange checksum was not reliable
977
+ const checksum = this.handleOption('watchOrderBook', 'checksum', false);
978
+ if (checksum) {
979
+ const payloadArray = [];
980
+ if (c !== undefined) {
981
+ const checkAsks = orderbook['asks'];
982
+ const checkBids = orderbook['bids'];
983
+ // const checkAsks = asks.map ((elem) => [ elem['price'], elem['qty'] ]);
984
+ // const checkBids = bids.map ((elem) => [ elem['price'], elem['qty'] ]);
985
+ for (let i = 0; i < 10; i++) {
986
+ const currentAsk = this.safeValue(checkAsks, i, {});
987
+ const formattedAsk = this.formatNumber(currentAsk[0]) + this.formatNumber(currentAsk[1]);
988
+ payloadArray.push(formattedAsk);
975
989
  }
976
- else {
977
- b = this.safeValue(message[1], 'b', []);
990
+ for (let i = 0; i < 10; i++) {
991
+ const currentBid = this.safeValue(checkBids, i, {});
992
+ const formattedBid = this.formatNumber(currentBid[0]) + this.formatNumber(currentBid[1]);
993
+ payloadArray.push(formattedBid);
978
994
  }
979
995
  }
980
- const storedAsks = orderbook['asks'];
981
- const storedBids = orderbook['bids'];
982
- let example = undefined;
983
- if (a !== undefined) {
984
- timestamp = this.customHandleDeltas(storedAsks, a, timestamp);
985
- example = this.safeValue(a, 0);
986
- }
987
- if (b !== undefined) {
988
- timestamp = this.customHandleDeltas(storedBids, b, timestamp);
989
- example = this.safeValue(b, 0);
990
- }
991
- // don't remove this line or I will poop on your face
992
- orderbook.limit();
993
- const checksum = this.handleOption('watchOrderBook', 'checksum', true);
994
- if (checksum) {
995
- const priceString = this.safeString(example, 0);
996
- const amountString = this.safeString(example, 1);
997
- const priceParts = priceString.split('.');
998
- const amountParts = amountString.split('.');
999
- const priceLength = priceParts[1].length - 0;
1000
- const amountLength = amountParts[1].length - 0;
1001
- const payloadArray = [];
1002
- if (c !== undefined) {
1003
- for (let i = 0; i < 10; i++) {
1004
- const formatted = this.formatNumber(storedAsks[i][0], priceLength) + this.formatNumber(storedAsks[i][1], amountLength);
1005
- payloadArray.push(formatted);
1006
- }
1007
- for (let i = 0; i < 10; i++) {
1008
- const formatted = this.formatNumber(storedBids[i][0], priceLength) + this.formatNumber(storedBids[i][1], amountLength);
1009
- payloadArray.push(formatted);
1010
- }
1011
- }
1012
- const payload = payloadArray.join('');
1013
- const localChecksum = this.crc32(payload, false);
1014
- if (localChecksum !== c) {
1015
- const error = new errors.ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
1016
- delete client.subscriptions[messageHash];
1017
- delete this.orderbooks[symbol];
1018
- client.reject(error, messageHash);
1019
- return;
1020
- }
996
+ const payload = payloadArray.join('');
997
+ const localChecksum = this.crc32(payload, false);
998
+ if (localChecksum !== c) {
999
+ const error = new errors.ChecksumError(this.id + ' ' + this.orderbookChecksumMessage(symbol));
1000
+ delete client.subscriptions[messageHash];
1001
+ delete this.orderbooks[symbol];
1002
+ client.reject(error, messageHash);
1003
+ return;
1021
1004
  }
1022
- orderbook['symbol'] = symbol;
1023
- orderbook['timestamp'] = timestamp;
1024
- orderbook['datetime'] = this.iso8601(timestamp);
1025
- client.resolve(orderbook, messageHash);
1005
+ }
1006
+ client.resolve(orderbook, messageHash);
1007
+ }
1008
+ customHandleDeltas(bookside, deltas) {
1009
+ // const sortOrder = (key === 'bids') ? true : false;
1010
+ for (let j = 0; j < deltas.length; j++) {
1011
+ const delta = deltas[j];
1012
+ const price = this.safeNumber(delta, 'price');
1013
+ const amount = this.safeNumber(delta, 'qty');
1014
+ bookside.store(price, amount);
1015
+ // if (amount === 0) {
1016
+ // const index = bookside.findIndex ((x: Int) => x[0] === price);
1017
+ // bookside.splice (index, 1);
1018
+ // } else {
1019
+ // bookside.store (price, amount);
1020
+ // }
1021
+ // bookside = this.sortBy (bookside, 0, sortOrder);
1022
+ // bookside.slice (0, 9);
1026
1023
  }
1027
1024
  }
1028
- formatNumber(n, length) {
1029
- const stringNumber = this.numberToString(n);
1030
- const parts = stringNumber.split('.');
1025
+ formatNumber(data) {
1026
+ const parts = data.split('.');
1031
1027
  const integer = this.safeString(parts, 0);
1032
1028
  const decimals = this.safeString(parts, 1, '');
1033
- const paddedDecimals = decimals.padEnd(length, '0');
1034
- const joined = integer + paddedDecimals;
1029
+ let joinedResult = integer + decimals;
1035
1030
  let i = 0;
1036
- while (joined[i] === '0') {
1031
+ while (joinedResult[i] === '0') {
1037
1032
  i += 1;
1038
1033
  }
1039
1034
  if (i > 0) {
1040
- return joined.slice(i);
1035
+ joinedResult = joinedResult.slice(i);
1041
1036
  }
1042
- else {
1043
- return joined;
1044
- }
1045
- }
1046
- customHandleDeltas(bookside, deltas, timestamp = undefined) {
1047
- for (let j = 0; j < deltas.length; j++) {
1048
- const delta = deltas[j];
1049
- const price = this.parseNumber(delta[0]);
1050
- const amount = this.parseNumber(delta[1]);
1051
- const oldTimestamp = timestamp ? timestamp : 0;
1052
- timestamp = Math.max(oldTimestamp, this.parseToInt(parseFloat(delta[2]) * 1000));
1053
- bookside.store(price, amount);
1054
- }
1055
- return timestamp;
1037
+ return joinedResult;
1056
1038
  }
1057
1039
  handleSystemStatus(client, message) {
1058
1040
  //
@@ -1088,7 +1070,11 @@ class kraken extends kraken$1 {
1088
1070
  const client = this.client(url);
1089
1071
  const authenticated = 'authenticated';
1090
1072
  let subscription = this.safeValue(client.subscriptions, authenticated);
1091
- if (subscription === undefined) {
1073
+ const now = this.seconds();
1074
+ const start = this.safeInteger(subscription, 'start');
1075
+ const expires = this.safeInteger(subscription, 'expires');
1076
+ if ((subscription === undefined) || ((subscription !== undefined) && (start + expires) <= now)) {
1077
+ // https://docs.kraken.com/api/docs/rest-api/get-websockets-token
1092
1078
  const response = await this.privatePostGetWebSocketsToken(params);
1093
1079
  //
1094
1080
  // {
@@ -1099,7 +1085,8 @@ class kraken extends kraken$1 {
1099
1085
  // }
1100
1086
  // }
1101
1087
  //
1102
- subscription = this.safeValue(response, 'result');
1088
+ subscription = this.safeDict(response, 'result');
1089
+ subscription['start'] = now;
1103
1090
  client.subscriptions[authenticated] = subscription;
1104
1091
  }
1105
1092
  return this.safeString(subscription, 'token');
@@ -1565,25 +1552,25 @@ class kraken extends kraken$1 {
1565
1552
  symbols = this.marketSymbols(symbols, undefined, false, true, false);
1566
1553
  const messageHashes = [];
1567
1554
  for (let i = 0; i < symbols.length; i++) {
1568
- messageHashes.push(this.getMessageHash(unifiedName, undefined, this.symbol(symbols[i])));
1569
- }
1570
- // for WS subscriptions, we can't use .marketIds (symbols), instead a custom is field needed
1571
- const markets = this.marketsForSymbols(symbols);
1572
- const wsMarketIds = [];
1573
- for (let i = 0; i < markets.length; i++) {
1574
- const wsMarketId = this.safeString(markets[i]['info'], 'wsname');
1575
- wsMarketIds.push(wsMarketId);
1555
+ const eventTrigger = this.safeString(params, 'event_trigger');
1556
+ if (eventTrigger !== undefined) {
1557
+ messageHashes.push(this.getMessageHash(channelName, undefined, this.symbol(symbols[i])));
1558
+ }
1559
+ else {
1560
+ messageHashes.push(this.getMessageHash(unifiedName, undefined, this.symbol(symbols[i])));
1561
+ }
1576
1562
  }
1577
1563
  const request = {
1578
- 'event': 'subscribe',
1579
- 'reqid': this.requestId(),
1580
- 'pair': wsMarketIds,
1581
- 'subscription': {
1582
- 'name': channelName,
1564
+ 'method': 'subscribe',
1565
+ 'params': {
1566
+ 'channel': channelName,
1567
+ 'symbol': symbols,
1583
1568
  },
1569
+ 'req_id': this.requestId(),
1584
1570
  };
1585
- const url = this.urls['api']['ws']['public'];
1586
- return await this.watchMultiple(url, messageHashes, this.deepExtend(request, params), messageHashes, subscriptionArgs);
1571
+ request['params'] = this.deepExtend(request['params'], params);
1572
+ const url = this.urls['api']['ws']['publicV2'];
1573
+ return await this.watchMultiple(url, messageHashes, request, messageHashes, subscriptionArgs);
1587
1574
  }
1588
1575
  /**
1589
1576
  * @method
@@ -1748,11 +1735,7 @@ class kraken extends kraken$1 {
1748
1735
  const name = this.safeString(info, 'name');
1749
1736
  const methods = {
1750
1737
  // public
1751
- 'book': this.handleOrderBook,
1752
1738
  'ohlc': this.handleOHLCV,
1753
- 'ticker': this.handleTicker,
1754
- 'spread': this.handleBidAsk,
1755
- 'trade': this.handleTrades,
1756
1739
  // private
1757
1740
  'openOrders': this.handleOrders,
1758
1741
  'ownTrades': this.handleMyTrades,
@@ -1767,6 +1750,9 @@ class kraken extends kraken$1 {
1767
1750
  if (channel !== undefined) {
1768
1751
  const methods = {
1769
1752
  'balances': this.handleBalance,
1753
+ 'book': this.handleOrderBook,
1754
+ 'ticker': this.handleTicker,
1755
+ 'trade': this.handleTrades,
1770
1756
  };
1771
1757
  const method = this.safeValue(methods, channel);
1772
1758
  if (method !== undefined) {
@@ -1783,6 +1769,7 @@ class kraken extends kraken$1 {
1783
1769
  'amend_order': this.handleCreateEditOrder,
1784
1770
  'cancel_order': this.handleCancelOrder,
1785
1771
  'cancel_all': this.handleCancelAllOrders,
1772
+ 'pong': this.handlePong,
1786
1773
  };
1787
1774
  const method = this.safeValue(methods, event);
1788
1775
  if (method !== undefined) {