mexc-exchange-api 0.0.80__py3-none-any.whl → 0.0.82__py3-none-any.whl
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.
- mexc/ccxt/__init__.py +1 -1
- mexc/ccxt/async_support/__init__.py +1 -1
- mexc/ccxt/async_support/base/exchange.py +44 -9
- mexc/ccxt/async_support/base/ws/client.py +3 -1
- mexc/ccxt/async_support/mexc.py +9 -2
- mexc/ccxt/base/errors.py +0 -6
- mexc/ccxt/base/exchange.py +11 -9
- mexc/ccxt/base/types.py +1 -0
- mexc/ccxt/mexc.py +9 -2
- mexc/ccxt/pro/__init__.py +1 -1
- mexc/ccxt/pro/mexc.py +328 -139
- {mexc_exchange_api-0.0.80.dist-info → mexc_exchange_api-0.0.82.dist-info}/METADATA +3 -3
- {mexc_exchange_api-0.0.80.dist-info → mexc_exchange_api-0.0.82.dist-info}/RECORD +14 -14
- {mexc_exchange_api-0.0.80.dist-info → mexc_exchange_api-0.0.82.dist-info}/WHEEL +0 -0
mexc/ccxt/pro/mexc.py
CHANGED
@@ -52,13 +52,14 @@ class mexc(mexcAsync):
|
|
52
52
|
'urls': {
|
53
53
|
'api': {
|
54
54
|
'ws': {
|
55
|
-
'spot': 'wss://wbs.mexc.com/ws',
|
55
|
+
'spot': 'wss://wbs-api.mexc.com/ws',
|
56
56
|
'swap': 'wss://contract.mexc.com/edge',
|
57
57
|
},
|
58
58
|
},
|
59
59
|
},
|
60
60
|
'options': {
|
61
61
|
'listenKeyRefreshRate': 1200000,
|
62
|
+
'decompressBinary': False,
|
62
63
|
# TODO add reset connection after #16754 is merged
|
63
64
|
'timeframes': {
|
64
65
|
'1m': 'Min1',
|
@@ -103,13 +104,7 @@ class mexc(mexcAsync):
|
|
103
104
|
market = self.market(symbol)
|
104
105
|
messageHash = 'ticker:' + market['symbol']
|
105
106
|
if market['spot']:
|
106
|
-
|
107
|
-
miniTicker, params = self.handle_option_and_params(params, 'watchTicker', 'miniTicker')
|
108
|
-
channel = None
|
109
|
-
if miniTicker:
|
110
|
-
channel = 'spot@public.miniTicker.v3.api@' + market['id'] + '@UTC+8'
|
111
|
-
else:
|
112
|
-
channel = 'spot@public.bookTicker.v3.api@' + market['id']
|
107
|
+
channel = 'spot@public.aggre.bookTicker.v3.api.pb@100ms@' + market['id']
|
113
108
|
return await self.watch_spot_public(channel, messageHash, params)
|
114
109
|
else:
|
115
110
|
channel = 'sub.ticker'
|
@@ -187,9 +182,9 @@ class mexc(mexcAsync):
|
|
187
182
|
# }
|
188
183
|
#
|
189
184
|
self.handle_bid_ask(client, message)
|
190
|
-
rawTicker = self.
|
185
|
+
rawTicker = self.safe_dict_n(message, ['d', 'data', 'publicAggreBookTicker'])
|
191
186
|
marketId = self.safe_string_2(message, 's', 'symbol')
|
192
|
-
timestamp = self.
|
187
|
+
timestamp = self.safe_integer_2(message, 't', 'sendtime')
|
193
188
|
market = self.safe_market(marketId)
|
194
189
|
symbol = market['symbol']
|
195
190
|
ticker = None
|
@@ -229,27 +224,33 @@ class mexc(mexcAsync):
|
|
229
224
|
url = self.urls['api']['ws']['spot'] if (isSpot) else self.urls['api']['ws']['swap']
|
230
225
|
request: dict = {}
|
231
226
|
if isSpot:
|
232
|
-
|
233
|
-
miniTicker
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
227
|
+
raise NotSupported(self.id + ' watchTickers does not support spot markets')
|
228
|
+
# miniTicker = False
|
229
|
+
# miniTicker, params = self.handle_option_and_params(params, 'watchTickers', 'miniTicker')
|
230
|
+
# topics = []
|
231
|
+
# if not miniTicker:
|
232
|
+
# if symbols is None:
|
233
|
+
# raise ArgumentsRequired(self.id + ' watchTickers required symbols argument for the bookTicker channel')
|
234
|
+
# }
|
235
|
+
# marketIds = self.market_ids(symbols)
|
236
|
+
# for i in range(0, len(marketIds)):
|
237
|
+
# marketId = marketIds[i]
|
238
|
+
# messageHashes.append('ticker:' + symbols[i])
|
239
|
+
# channel = 'spot@public.bookTicker.v3.api@' + marketId
|
240
|
+
# topics.append(channel)
|
241
|
+
# }
|
242
|
+
# else:
|
243
|
+
# topics.append('spot@public.miniTickers.v3.api@UTC+8')
|
244
|
+
# if symbols is None:
|
245
|
+
# messageHashes.append('spot:ticker')
|
246
|
+
# else:
|
247
|
+
# for i in range(0, len(symbols)):
|
248
|
+
# messageHashes.append('ticker:' + symbols[i])
|
249
|
+
# }
|
250
|
+
# }
|
251
|
+
# }
|
252
|
+
# request['method'] = 'SUBSCRIPTION'
|
253
|
+
# request['params'] = topics
|
253
254
|
else:
|
254
255
|
request['method'] = 'sub.tickers'
|
255
256
|
request['params'] = {}
|
@@ -348,6 +349,11 @@ class mexc(mexcAsync):
|
|
348
349
|
client.resolve(result, topic)
|
349
350
|
|
350
351
|
def parse_ws_ticker(self, ticker, market=None):
|
352
|
+
# protobuf ticker
|
353
|
+
# "bidprice": "93387.28", # Best bid price
|
354
|
+
# "bidquantity": "3.73485", # Best bid quantity
|
355
|
+
# "askprice": "93387.29", # Best ask price
|
356
|
+
# "askquantity": "7.669875" # Best ask quantity
|
351
357
|
#
|
352
358
|
# spot
|
353
359
|
#
|
@@ -362,7 +368,7 @@ class mexc(mexcAsync):
|
|
362
368
|
#
|
363
369
|
# {
|
364
370
|
# "s": "BTCUSDT",
|
365
|
-
# "p": "
|
371
|
+
# "p": "76521",
|
366
372
|
# "r": "0.0012",
|
367
373
|
# "tr": "0.0012",
|
368
374
|
# "h": "77196.3",
|
@@ -388,10 +394,10 @@ class mexc(mexcAsync):
|
|
388
394
|
'low': self.safe_number(ticker, 'l'),
|
389
395
|
'close': price,
|
390
396
|
'last': price,
|
391
|
-
'bid': self.
|
392
|
-
'bidVolume': self.
|
393
|
-
'ask': self.
|
394
|
-
'askVolume': self.
|
397
|
+
'bid': self.safe_number_2(ticker, 'b', 'bidPrice'),
|
398
|
+
'bidVolume': self.safe_number_2(ticker, 'B', 'bidQuantity'),
|
399
|
+
'ask': self.safe_number_2(ticker, 'a', 'askPrice'),
|
400
|
+
'askVolume': self.safe_number_2(ticker, 'A', 'askQuantity'),
|
395
401
|
'vwap': None,
|
396
402
|
'previousClose': None,
|
397
403
|
'change': None,
|
@@ -426,7 +432,7 @@ class mexc(mexcAsync):
|
|
426
432
|
for i in range(0, len(symbols)):
|
427
433
|
if isSpot:
|
428
434
|
market = self.market(symbols[i])
|
429
|
-
topics.append('spot@public.bookTicker.v3.api@' + market['id'])
|
435
|
+
topics.append('spot@public.aggre.bookTicker.v3.api.pb@100ms@' + market['id'])
|
430
436
|
messageHashes.append('bidask:' + symbols[i])
|
431
437
|
url = self.urls['api']['ws']['spot']
|
432
438
|
request: dict = {
|
@@ -530,7 +536,7 @@ class mexc(mexcAsync):
|
|
530
536
|
async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
531
537
|
"""
|
532
538
|
|
533
|
-
https://
|
539
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-market-streams#trade-streams
|
534
540
|
|
535
541
|
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
536
542
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
@@ -548,7 +554,7 @@ class mexc(mexcAsync):
|
|
548
554
|
messageHash = 'candles:' + symbol + ':' + timeframe
|
549
555
|
ohlcv = None
|
550
556
|
if market['spot']:
|
551
|
-
channel = 'spot@public.kline.v3.api@' + market['id'] + '@' + timeframeId
|
557
|
+
channel = 'spot@public.kline.v3.api.pb@' + market['id'] + '@' + timeframeId
|
552
558
|
ohlcv = await self.watch_spot_public(channel, messageHash, params)
|
553
559
|
else:
|
554
560
|
channel = 'sub.kline'
|
@@ -607,17 +613,45 @@ class mexc(mexcAsync):
|
|
607
613
|
# "symbol": "BTC_USDT",
|
608
614
|
# "ts": 1651230713067
|
609
615
|
# }
|
616
|
+
# protobuf
|
617
|
+
# {
|
618
|
+
# "channel":"spot@public.kline.v3.api.pb@BTCUSDT@Min1",
|
619
|
+
# "symbol":"BTCUSDT",
|
620
|
+
# "symbolId":"2fb942154ef44a4ab2ef98c8afb6a4a7",
|
621
|
+
# "createTime":"1754737941062",
|
622
|
+
# "publicSpotKline":{
|
623
|
+
# "interval":"Min1",
|
624
|
+
# "windowStart":"1754737920",
|
625
|
+
# "openingPrice":"117317.31",
|
626
|
+
# "closingPrice":"117325.26",
|
627
|
+
# "highestPrice":"117341",
|
628
|
+
# "lowestPrice":"117317.3",
|
629
|
+
# "volume":"3.12599854",
|
630
|
+
# "amount":"366804.43",
|
631
|
+
# "windowEnd":"1754737980"
|
632
|
+
# }
|
633
|
+
# }
|
610
634
|
#
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
635
|
+
parsed: dict = None
|
636
|
+
symbol: Str = None
|
637
|
+
timeframe: Str = None
|
638
|
+
if 'publicSpotKline' in message:
|
639
|
+
symbol = self.symbol(self.safe_string(message, 'symbol'))
|
640
|
+
data = self.safe_dict(message, 'publicSpotKline', {})
|
641
|
+
timeframeId = self.safe_string(data, 'interval')
|
642
|
+
timeframe = self.find_timeframe(timeframeId, self.options['timeframes'])
|
643
|
+
parsed = self.parse_ws_ohlcv(data, self.safe_market(symbol))
|
644
|
+
else:
|
645
|
+
d = self.safe_value_2(message, 'd', 'data', {})
|
646
|
+
rawOhlcv = self.safe_value(d, 'k', d)
|
647
|
+
timeframeId = self.safe_string_2(rawOhlcv, 'i', 'interval')
|
648
|
+
timeframes = self.safe_value(self.options, 'timeframes', {})
|
649
|
+
timeframe = self.find_timeframe(timeframeId, timeframes)
|
650
|
+
marketId = self.safe_string_2(message, 's', 'symbol')
|
651
|
+
market = self.safe_market(marketId)
|
652
|
+
symbol = market['symbol']
|
653
|
+
parsed = self.parse_ws_ohlcv(rawOhlcv, market)
|
619
654
|
messageHash = 'candles:' + symbol + ':' + timeframe
|
620
|
-
parsed = self.parse_ws_ohlcv(rawOhlcv, market)
|
621
655
|
self.ohlcvs[symbol] = self.safe_value(self.ohlcvs, symbol, {})
|
622
656
|
stored = self.safe_value(self.ohlcvs[symbol], timeframe)
|
623
657
|
if stored is None:
|
@@ -659,26 +693,38 @@ class mexc(mexcAsync):
|
|
659
693
|
# "rh": 27301.8,
|
660
694
|
# "rl": 27301.8
|
661
695
|
# }
|
696
|
+
# protobuf
|
697
|
+
#
|
698
|
+
# "interval":"Min1",
|
699
|
+
# "windowStart":"1754737920",
|
700
|
+
# "openingPrice":"117317.31",
|
701
|
+
# "closingPrice":"117325.26",
|
702
|
+
# "highestPrice":"117341",
|
703
|
+
# "lowestPrice":"117317.3",
|
704
|
+
# "volume":"3.12599854",
|
705
|
+
# "amount":"366804.43",
|
706
|
+
# "windowEnd":"1754737980"
|
662
707
|
#
|
663
708
|
return [
|
664
|
-
self.
|
665
|
-
self.
|
666
|
-
self.
|
667
|
-
self.
|
668
|
-
self.
|
669
|
-
self.safe_number_2(ohlcv, 'v', '
|
709
|
+
self.safe_timestamp_2(ohlcv, 't', 'windowStart'),
|
710
|
+
self.safe_number_2(ohlcv, 'o', 'openingPrice'),
|
711
|
+
self.safe_number_2(ohlcv, 'h', 'highestPrice'),
|
712
|
+
self.safe_number_2(ohlcv, 'l', 'lowestPrice'),
|
713
|
+
self.safe_number_2(ohlcv, 'c', 'closingPrice'),
|
714
|
+
self.safe_number_2(ohlcv, 'v', 'volume'),
|
670
715
|
]
|
671
716
|
|
672
717
|
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
673
718
|
"""
|
674
719
|
|
675
|
-
https://
|
720
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-market-streams#trade-streams
|
676
721
|
https://mexcdevelop.github.io/apidocs/contract_v1_en/#public-channels
|
677
722
|
|
678
723
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
679
724
|
:param str symbol: unified symbol of the market to fetch the order book for
|
680
725
|
:param int [limit]: the maximum amount of order book entries to return
|
681
726
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
727
|
+
:param str [params.frequency]: the frequency of the order book updates, default is '10ms', can be '100ms' or '10ms
|
682
728
|
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
683
729
|
"""
|
684
730
|
await self.load_markets()
|
@@ -687,7 +733,9 @@ class mexc(mexcAsync):
|
|
687
733
|
messageHash = 'orderbook:' + symbol
|
688
734
|
orderbook = None
|
689
735
|
if market['spot']:
|
690
|
-
|
736
|
+
frequency = None
|
737
|
+
frequency, params = self.handle_option_and_params(params, 'watchOrderBook', 'frequency', '100ms')
|
738
|
+
channel = 'spot@public.aggre.depth.v3.api.pb@' + frequency + '@' + market['id']
|
691
739
|
orderbook = await self.watch_spot_public(channel, messageHash, params)
|
692
740
|
else:
|
693
741
|
channel = 'sub.depth'
|
@@ -711,12 +759,12 @@ class mexc(mexcAsync):
|
|
711
759
|
# return the first index of the cache that can be applied to the orderbook or -1 if not possible
|
712
760
|
nonce = self.safe_integer(orderbook, 'nonce')
|
713
761
|
firstDelta = self.safe_value(cache, 0)
|
714
|
-
firstDeltaNonce = self.
|
762
|
+
firstDeltaNonce = self.safe_integer_n(firstDelta, ['r', 'version', 'fromVersion'])
|
715
763
|
if nonce < firstDeltaNonce - 1:
|
716
764
|
return -1
|
717
765
|
for i in range(0, len(cache)):
|
718
766
|
delta = cache[i]
|
719
|
-
deltaNonce = self.
|
767
|
+
deltaNonce = self.safe_integer_n(delta, ['r', 'version', 'fromVersion'])
|
720
768
|
if deltaNonce >= nonce:
|
721
769
|
return i
|
722
770
|
return len(cache)
|
@@ -764,8 +812,31 @@ class mexc(mexcAsync):
|
|
764
812
|
# "symbol":"BTC_USDT",
|
765
813
|
# "ts":1651239652372
|
766
814
|
# }
|
815
|
+
# protofbuf
|
816
|
+
# {
|
817
|
+
# "channel":"spot@public.aggre.depth.v3.api.pb@100ms@BTCUSDT",
|
818
|
+
# "symbol":"BTCUSDT",
|
819
|
+
# "sendTime":"1754741322152",
|
820
|
+
# "publicAggreDepths":{
|
821
|
+
# "asks":[
|
822
|
+
# {
|
823
|
+
# "price":"117145.49",
|
824
|
+
# "quantity":"0"
|
825
|
+
# }
|
826
|
+
# ],
|
827
|
+
# "bids":[
|
828
|
+
# {
|
829
|
+
# "price":"117053.41",
|
830
|
+
# "quantity":"1.86837271"
|
831
|
+
# }
|
832
|
+
# ],
|
833
|
+
# "eventType":"spot@public.aggre.depth.v3.api.pb@100ms",
|
834
|
+
# "fromVersion":"43296363236",
|
835
|
+
# "toVersion":"43296363255"
|
836
|
+
# }
|
837
|
+
# }
|
767
838
|
#
|
768
|
-
data = self.
|
839
|
+
data = self.safe_dict_n(message, ['d', 'data', 'publicAggreDepths'])
|
769
840
|
marketId = self.safe_string_2(message, 's', 'symbol')
|
770
841
|
symbol = self.safe_symbol(marketId)
|
771
842
|
messageHash = 'orderbook:' + symbol
|
@@ -784,9 +855,10 @@ class mexc(mexcAsync):
|
|
784
855
|
return
|
785
856
|
try:
|
786
857
|
self.handle_delta(storedOrderBook, data)
|
787
|
-
timestamp = self.
|
858
|
+
timestamp = self.safe_integer_n(message, ['t', 'ts', 'sendTime'])
|
788
859
|
storedOrderBook['timestamp'] = timestamp
|
789
860
|
storedOrderBook['datetime'] = self.iso8601(timestamp)
|
861
|
+
storedOrderBook['nonce'] = self.safe_integer(data, 'fromVersion')
|
790
862
|
except Exception as e:
|
791
863
|
del client.subscriptions[messageHash]
|
792
864
|
client.reject(e, messageHash)
|
@@ -804,13 +876,13 @@ class mexc(mexcAsync):
|
|
804
876
|
if isinstance(bidask, list):
|
805
877
|
bookside.storeArray(bidask)
|
806
878
|
else:
|
807
|
-
price = self.
|
808
|
-
amount = self.
|
879
|
+
price = self.safe_float_2(bidask, 'p', 'price')
|
880
|
+
amount = self.safe_float_2(bidask, 'v', 'quantity')
|
809
881
|
bookside.store(price, amount)
|
810
882
|
|
811
883
|
def handle_delta(self, orderbook, delta):
|
812
884
|
existingNonce = self.safe_integer(orderbook, 'nonce')
|
813
|
-
deltaNonce = self.
|
885
|
+
deltaNonce = self.safe_integer_n(delta, ['r', 'version', 'fromVersion'])
|
814
886
|
if deltaNonce < existingNonce:
|
815
887
|
# even when doing < comparison, self happens: https://app.travis-ci.com/github/ccxt/ccxt/builds/269234741#L1809
|
816
888
|
# so, we just skip old updates
|
@@ -826,7 +898,7 @@ class mexc(mexcAsync):
|
|
826
898
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
827
899
|
"""
|
828
900
|
|
829
|
-
https://
|
901
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-market-streams#trade-streams
|
830
902
|
https://mexcdevelop.github.io/apidocs/contract_v1_en/#public-channels
|
831
903
|
|
832
904
|
get the list of most recent trades for a particular symbol
|
@@ -842,7 +914,7 @@ class mexc(mexcAsync):
|
|
842
914
|
messageHash = 'trades:' + symbol
|
843
915
|
trades = None
|
844
916
|
if market['spot']:
|
845
|
-
channel = 'spot@public.deals.v3.api@' + market['id']
|
917
|
+
channel = 'spot@public.aggre.deals.v3.api.pb@100ms@' + market['id']
|
846
918
|
trades = await self.watch_spot_public(channel, messageHash, params)
|
847
919
|
else:
|
848
920
|
channel = 'sub.deal'
|
@@ -855,6 +927,23 @@ class mexc(mexcAsync):
|
|
855
927
|
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
856
928
|
|
857
929
|
def handle_trades(self, client: Client, message):
|
930
|
+
# protobuf
|
931
|
+
# {
|
932
|
+
# "channel": "spot@public.aggre.deals.v3.api.pb@100ms@BTCUSDT",
|
933
|
+
# "publicdeals": {
|
934
|
+
# "dealsList": [
|
935
|
+
# {
|
936
|
+
# "price": "93220.00", # Trade price
|
937
|
+
# "quantity": "0.04438243", # Trade quantity
|
938
|
+
# "tradetype": 2, # Trade type(1: Buy, 2: Sell)
|
939
|
+
# "time": 1736409765051 # Trade time
|
940
|
+
# }
|
941
|
+
# ],
|
942
|
+
# "eventtype": "spot@public.aggre.deals.v3.api.pb@100ms" # Event type
|
943
|
+
# },
|
944
|
+
# "symbol": "BTCUSDT", # Trading pair
|
945
|
+
# "sendtime": 1736409765052 # Event time
|
946
|
+
# }
|
858
947
|
#
|
859
948
|
# {
|
860
949
|
# "c": "spot@public.deals.v3.api@BTCUSDT",
|
@@ -895,8 +984,8 @@ class mexc(mexcAsync):
|
|
895
984
|
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
896
985
|
stored = ArrayCache(limit)
|
897
986
|
self.trades[symbol] = stored
|
898
|
-
d = self.
|
899
|
-
trades = self.
|
987
|
+
d = self.safe_dict_n(message, ['d', 'data', 'publicAggreDeals'])
|
988
|
+
trades = self.safe_list_2(d, 'deals', 'dealsList', [d])
|
900
989
|
for j in range(0, len(trades)):
|
901
990
|
parsedTrade = None
|
902
991
|
if market['spot']:
|
@@ -909,7 +998,7 @@ class mexc(mexcAsync):
|
|
909
998
|
async def watch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
910
999
|
"""
|
911
1000
|
|
912
|
-
https://
|
1001
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-user-data-streams#spot-account-deals
|
913
1002
|
https://mexcdevelop.github.io/apidocs/contract_v1_en/#private-channels
|
914
1003
|
|
915
1004
|
watches information on multiple trades made by the user
|
@@ -930,7 +1019,7 @@ class mexc(mexcAsync):
|
|
930
1019
|
type, params = self.handle_market_type_and_params('watchMyTrades', market, params)
|
931
1020
|
trades = None
|
932
1021
|
if type == 'spot':
|
933
|
-
channel = 'spot@private.deals.v3.api'
|
1022
|
+
channel = 'spot@private.deals.v3.api.pb'
|
934
1023
|
trades = await self.watch_spot_private(channel, messageHash, params)
|
935
1024
|
else:
|
936
1025
|
trades = await self.watch_swap_private(messageHash, params)
|
@@ -956,11 +1045,27 @@ class mexc(mexcAsync):
|
|
956
1045
|
# "s": "BTCUSDT",
|
957
1046
|
# "t": 1678670940700
|
958
1047
|
# }
|
1048
|
+
# {
|
1049
|
+
# channel: "spot@private.deals.v3.api.pb",
|
1050
|
+
# symbol: "MXUSDT",
|
1051
|
+
# sendTime: 1736417034332,
|
1052
|
+
# privateDeals {
|
1053
|
+
# price: "3.6962",
|
1054
|
+
# quantity: "1",
|
1055
|
+
# amount: "3.6962",
|
1056
|
+
# tradeType: 2,
|
1057
|
+
# tradeId: "505979017439002624X1",
|
1058
|
+
# orderId: "C02__505979017439002624115",
|
1059
|
+
# feeAmount: "0.0003998377369698171",
|
1060
|
+
# feeCurrency: "MX",
|
1061
|
+
# time: 1736417034280
|
1062
|
+
# }
|
1063
|
+
# }
|
959
1064
|
#
|
960
1065
|
messageHash = 'myTrades'
|
961
|
-
data = self.
|
1066
|
+
data = self.safe_dict_n(message, ['d', 'data', 'privateDeals'])
|
962
1067
|
futuresMarketId = self.safe_string(data, 'symbol')
|
963
|
-
marketId = self.
|
1068
|
+
marketId = self.safe_string_2(message, 's', 'symbol', futuresMarketId)
|
964
1069
|
market = self.safe_market(marketId)
|
965
1070
|
symbol = market['symbol']
|
966
1071
|
trade = None
|
@@ -980,7 +1085,7 @@ class mexc(mexcAsync):
|
|
980
1085
|
|
981
1086
|
def parse_ws_trade(self, trade, market=None):
|
982
1087
|
#
|
983
|
-
# public trade
|
1088
|
+
# public trade(protobuf)
|
984
1089
|
# {
|
985
1090
|
# "p": "20382.70",
|
986
1091
|
# "v": "0.043800",
|
@@ -1000,7 +1105,6 @@ class mexc(mexcAsync):
|
|
1000
1105
|
# "v": "5"
|
1001
1106
|
# }
|
1002
1107
|
#
|
1003
|
-
#
|
1004
1108
|
# d: {
|
1005
1109
|
# p: '1.0005',
|
1006
1110
|
# v: '5.71',
|
@@ -1015,22 +1119,36 @@ class mexc(mexcAsync):
|
|
1015
1119
|
# n: '0.005712855',
|
1016
1120
|
# N: 'USDT'
|
1017
1121
|
# }
|
1018
|
-
|
1019
|
-
|
1122
|
+
# protobuf
|
1123
|
+
#
|
1124
|
+
# {
|
1125
|
+
# price: "3.6962",
|
1126
|
+
# quantity: "1",
|
1127
|
+
# amount: "3.6962",
|
1128
|
+
# tradeType: 2,
|
1129
|
+
# tradeId: "505979017439002624X1",
|
1130
|
+
# orderId: "C02__505979017439002624115",
|
1131
|
+
# feeAmount: "0.0003998377369698171",
|
1132
|
+
# feeCurrency: "MX",
|
1133
|
+
# time: 1736417034280
|
1134
|
+
# }
|
1135
|
+
#
|
1136
|
+
timestamp = self.safe_integer_2(trade, 'T', 'time')
|
1137
|
+
tradeId = self.safe_string_2(trade, 't', 'tradeId')
|
1020
1138
|
if timestamp is None:
|
1021
1139
|
timestamp = self.safe_integer(trade, 't')
|
1022
1140
|
tradeId = None
|
1023
|
-
priceString = self.
|
1024
|
-
amountString = self.
|
1025
|
-
rawSide = self.
|
1141
|
+
priceString = self.safe_string_2(trade, 'p', 'price')
|
1142
|
+
amountString = self.safe_string_2(trade, 'v', 'quantity')
|
1143
|
+
rawSide = self.safe_string_2(trade, 'S', 'tradeType')
|
1026
1144
|
side = 'buy' if (rawSide == '1') else 'sell'
|
1027
1145
|
isMaker = self.safe_integer(trade, 'm')
|
1028
|
-
feeAmount = self.
|
1029
|
-
feeCurrencyId = self.
|
1146
|
+
feeAmount = self.safe_string_2(trade, 'n', 'feeAmount')
|
1147
|
+
feeCurrencyId = self.safe_string_2(trade, 'N', 'feeCurrency')
|
1030
1148
|
return self.safe_trade({
|
1031
1149
|
'info': trade,
|
1032
1150
|
'id': tradeId,
|
1033
|
-
'order': self.
|
1151
|
+
'order': self.safe_string_2(trade, 'i', 'orderId'),
|
1034
1152
|
'timestamp': timestamp,
|
1035
1153
|
'datetime': self.iso8601(timestamp),
|
1036
1154
|
'symbol': self.safe_symbol(None, market),
|
@@ -1039,7 +1157,7 @@ class mexc(mexcAsync):
|
|
1039
1157
|
'takerOrMaker': 'maker' if (isMaker) else 'taker',
|
1040
1158
|
'price': priceString,
|
1041
1159
|
'amount': amountString,
|
1042
|
-
'cost':
|
1160
|
+
'cost': self.safe_string(trade, 'amount'),
|
1043
1161
|
'fee': {
|
1044
1162
|
'cost': feeAmount,
|
1045
1163
|
'currency': self.safe_currency_code(feeCurrencyId),
|
@@ -1049,7 +1167,7 @@ class mexc(mexcAsync):
|
|
1049
1167
|
async def watch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
1050
1168
|
"""
|
1051
1169
|
|
1052
|
-
https://
|
1170
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-user-data-streams#spot-account-orders
|
1053
1171
|
https://mexcdevelop.github.io/apidocs/spot_v3_en/#margin-account-orders
|
1054
1172
|
|
1055
1173
|
watches information on multiple orders made by the user
|
@@ -1071,7 +1189,7 @@ class mexc(mexcAsync):
|
|
1071
1189
|
type, params = self.handle_market_type_and_params('watchOrders', market, params)
|
1072
1190
|
orders = None
|
1073
1191
|
if type == 'spot':
|
1074
|
-
channel =
|
1192
|
+
channel = 'spot@private.orders.v3.api.pb'
|
1075
1193
|
orders = await self.watch_spot_private(channel, messageHash, params)
|
1076
1194
|
else:
|
1077
1195
|
orders = await self.watch_swap_private(messageHash, params)
|
@@ -1144,11 +1262,18 @@ class mexc(mexcAsync):
|
|
1144
1262
|
# "s": "MXUSDT",
|
1145
1263
|
# "t":1661938138193
|
1146
1264
|
# }
|
1265
|
+
# protobuf
|
1266
|
+
# {
|
1267
|
+
# channel: "spot@private.orders.v3.api.pb",
|
1268
|
+
# symbol: "MXUSDT",
|
1269
|
+
# sendTime: 1736417034281,
|
1270
|
+
# privateOrders {}
|
1271
|
+
# }
|
1147
1272
|
#
|
1148
1273
|
messageHash = 'orders'
|
1149
|
-
data = self.
|
1274
|
+
data = self.safe_dict_n(message, ['d', 'data', 'privateOrders'])
|
1150
1275
|
futuresMarketId = self.safe_string(data, 'symbol')
|
1151
|
-
marketId = self.
|
1276
|
+
marketId = self.safe_string_2(message, 's', 'symbol', futuresMarketId)
|
1152
1277
|
market = self.safe_market(marketId)
|
1153
1278
|
symbol = market['symbol']
|
1154
1279
|
parsed = None
|
@@ -1216,11 +1341,28 @@ class mexc(mexcAsync):
|
|
1216
1341
|
# "s":1,
|
1217
1342
|
# "i":"e03a5c7441e44ed899466a7140b71391",
|
1218
1343
|
# }
|
1344
|
+
# protofbuf spot order
|
1345
|
+
# {
|
1346
|
+
# "id":"C02__583905164440776704043",
|
1347
|
+
# "price":"0.001053",
|
1348
|
+
# "quantity":"2000",
|
1349
|
+
# "amount":"0",
|
1350
|
+
# "avgPrice":"0.001007",
|
1351
|
+
# "orderType":5,
|
1352
|
+
# "tradeType":1,
|
1353
|
+
# "remainAmount":"0.092",
|
1354
|
+
# "remainQuantity":"0",
|
1355
|
+
# "lastDealQuantity":"2000",
|
1356
|
+
# "cumulativeQuantity":"2000",
|
1357
|
+
# "cumulativeAmount":"2.014",
|
1358
|
+
# "status":2,
|
1359
|
+
# "createTime":"1754996075502"
|
1360
|
+
# }
|
1219
1361
|
#
|
1220
|
-
timestamp = self.safe_integer(order, '
|
1221
|
-
side = self.safe_string(order, '
|
1222
|
-
status = self.safe_string(order, '
|
1223
|
-
type = self.safe_string(order, '
|
1362
|
+
timestamp = self.safe_integer(order, 'createTime')
|
1363
|
+
side = self.safe_string(order, 'tradeType')
|
1364
|
+
status = self.safe_string(order, 'status')
|
1365
|
+
type = self.safe_string(order, 'orderType')
|
1224
1366
|
fee = None
|
1225
1367
|
feeCurrency = self.safe_string(order, 'N')
|
1226
1368
|
if feeCurrency is not None:
|
@@ -1229,8 +1371,8 @@ class mexc(mexcAsync):
|
|
1229
1371
|
'cost': None,
|
1230
1372
|
}
|
1231
1373
|
return self.safe_order({
|
1232
|
-
'id': self.safe_string(order, '
|
1233
|
-
'clientOrderId': self.safe_string(order, '
|
1374
|
+
'id': self.safe_string(order, 'id'),
|
1375
|
+
'clientOrderId': self.safe_string(order, 'clientOrderId'),
|
1234
1376
|
'timestamp': timestamp,
|
1235
1377
|
'datetime': self.iso8601(timestamp),
|
1236
1378
|
'lastTradeTimestamp': None,
|
@@ -1239,14 +1381,14 @@ class mexc(mexcAsync):
|
|
1239
1381
|
'type': self.parse_ws_order_type(type),
|
1240
1382
|
'timeInForce': self.parse_ws_time_in_force(type),
|
1241
1383
|
'side': 'buy' if (side == '1') else 'sell',
|
1242
|
-
'price': self.safe_string(order, '
|
1384
|
+
'price': self.safe_string(order, 'price'),
|
1243
1385
|
'stopPrice': None,
|
1244
|
-
'triggerPrice':
|
1245
|
-
'average': self.safe_string(order, '
|
1246
|
-
'amount': self.safe_string(order, '
|
1247
|
-
'cost': self.safe_string(order, '
|
1248
|
-
'filled': self.safe_string(order, '
|
1249
|
-
'remaining': self.safe_string(order, '
|
1386
|
+
'triggerPrice': None,
|
1387
|
+
'average': self.safe_string(order, 'avgPrice'),
|
1388
|
+
'amount': self.safe_string(order, 'quantity'),
|
1389
|
+
'cost': self.safe_string(order, 'amount'),
|
1390
|
+
'filled': self.safe_string(order, 'cumulativeQuantity'),
|
1391
|
+
'remaining': self.safe_string(order, 'remainQuantity'),
|
1250
1392
|
'fee': fee,
|
1251
1393
|
'trades': None,
|
1252
1394
|
'info': order,
|
@@ -1269,7 +1411,7 @@ class mexc(mexcAsync):
|
|
1269
1411
|
def parse_ws_order_type(self, type):
|
1270
1412
|
types: dict = {
|
1271
1413
|
'1': 'limit', # LIMIT_ORDER
|
1272
|
-
'2':
|
1414
|
+
'2': 'limit', # POST_ONLY
|
1273
1415
|
'3': None, # IMMEDIATE_OR_CANCEL
|
1274
1416
|
'4': None, # FILL_OR_KILL
|
1275
1417
|
'5': 'market', # MARKET_ORDER
|
@@ -1291,7 +1433,7 @@ class mexc(mexcAsync):
|
|
1291
1433
|
async def watch_balance(self, params={}) -> Balances:
|
1292
1434
|
"""
|
1293
1435
|
|
1294
|
-
https://
|
1436
|
+
https://www.mexc.com/api-docs/spot-v3/websocket-user-data-streams#spot-account-update
|
1295
1437
|
|
1296
1438
|
watch balance and get the amount of funds available for trading or funds locked in orders
|
1297
1439
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1302,7 +1444,7 @@ class mexc(mexcAsync):
|
|
1302
1444
|
type, params = self.handle_market_type_and_params('watchBalance', None, params)
|
1303
1445
|
messageHash = 'balance:' + type
|
1304
1446
|
if type == 'spot':
|
1305
|
-
channel = 'spot@private.account.v3.api'
|
1447
|
+
channel = 'spot@private.account.v3.api.pb'
|
1306
1448
|
return await self.watch_spot_private(channel, messageHash, params)
|
1307
1449
|
else:
|
1308
1450
|
return await self.watch_swap_private(messageHash, params)
|
@@ -1339,22 +1481,22 @@ class mexc(mexcAsync):
|
|
1339
1481
|
# "ts": 1680059188190
|
1340
1482
|
# }
|
1341
1483
|
#
|
1342
|
-
c = self.
|
1484
|
+
c = self.safe_string_2(message, 'c', 'channel')
|
1343
1485
|
type = 'swap' if (c is None) else 'spot'
|
1344
1486
|
messageHash = 'balance:' + type
|
1345
|
-
data = self.
|
1487
|
+
data = self.safe_dict_n(message, ['d', 'data', 'privateAccount'])
|
1346
1488
|
futuresTimestamp = self.safe_integer(message, 'ts')
|
1347
|
-
timestamp = self.
|
1489
|
+
timestamp = self.safe_integer_2(data, 'c', 'time', futuresTimestamp)
|
1348
1490
|
if not (type in self.balance):
|
1349
1491
|
self.balance[type] = {}
|
1350
1492
|
self.balance[type]['info'] = data
|
1351
1493
|
self.balance[type]['timestamp'] = timestamp
|
1352
1494
|
self.balance[type]['datetime'] = self.iso8601(timestamp)
|
1353
|
-
currencyId = self.
|
1495
|
+
currencyId = self.safe_string_n(data, ['a', 'currency', 'vcoinName'])
|
1354
1496
|
code = self.safe_currency_code(currencyId)
|
1355
1497
|
account = self.account()
|
1356
|
-
account['
|
1357
|
-
account['used'] = self.
|
1498
|
+
account['total'] = self.safe_string_n(data, ['f', 'availableBalance', 'balanceAmount'])
|
1499
|
+
account['used'] = self.safe_string_n(data, ['l', 'frozenBalance', 'frozenAmount'])
|
1358
1500
|
self.balance[type][code] = account
|
1359
1501
|
self.balance[type] = self.safe_balance(self.balance[type])
|
1360
1502
|
client.resolve(self.balance[type], messageHash)
|
@@ -1372,12 +1514,7 @@ class mexc(mexcAsync):
|
|
1372
1514
|
url = None
|
1373
1515
|
channel = None
|
1374
1516
|
if market['spot']:
|
1375
|
-
|
1376
|
-
miniTicker, params = self.handle_option_and_params(params, 'watchTicker', 'miniTicker')
|
1377
|
-
if miniTicker:
|
1378
|
-
channel = 'spot@public.miniTicker.v3.api@' + market['id'] + '@UTC+8'
|
1379
|
-
else:
|
1380
|
-
channel = 'spot@public.bookTicker.v3.api@' + market['id']
|
1517
|
+
channel = 'spot@public.aggre.bookTicker.v3.api.pb@100ms@' + market['id']
|
1381
1518
|
url = self.urls['api']['ws']['spot']
|
1382
1519
|
params['unsubscribed'] = True
|
1383
1520
|
await self.watch_spot_public(channel, messageHash, params)
|
@@ -1412,27 +1549,33 @@ class mexc(mexcAsync):
|
|
1412
1549
|
url = self.urls['api']['ws']['spot'] if (isSpot) else self.urls['api']['ws']['swap']
|
1413
1550
|
request: dict = {}
|
1414
1551
|
if isSpot:
|
1415
|
-
|
1416
|
-
miniTicker
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1552
|
+
raise NotSupported(self.id + ' watchTickers does not support spot markets')
|
1553
|
+
# miniTicker = False
|
1554
|
+
# miniTicker, params = self.handle_option_and_params(params, 'watchTickers', 'miniTicker')
|
1555
|
+
# topics = []
|
1556
|
+
# if not miniTicker:
|
1557
|
+
# if symbols is None:
|
1558
|
+
# raise ArgumentsRequired(self.id + ' watchTickers required symbols argument for the bookTicker channel')
|
1559
|
+
# }
|
1560
|
+
# marketIds = self.market_ids(symbols)
|
1561
|
+
# for i in range(0, len(marketIds)):
|
1562
|
+
# marketId = marketIds[i]
|
1563
|
+
# messageHashes.append('unsubscribe:ticker:' + symbols[i])
|
1564
|
+
# channel = 'spot@public.bookTicker.v3.api@' + marketId
|
1565
|
+
# topics.append(channel)
|
1566
|
+
# }
|
1567
|
+
# else:
|
1568
|
+
# topics.append('spot@public.miniTickers.v3.api@UTC+8')
|
1569
|
+
# if symbols is None:
|
1570
|
+
# messageHashes.append('unsubscribe:spot:ticker')
|
1571
|
+
# else:
|
1572
|
+
# for i in range(0, len(symbols)):
|
1573
|
+
# messageHashes.append('unsubscribe:ticker:' + symbols[i])
|
1574
|
+
# }
|
1575
|
+
# }
|
1576
|
+
# }
|
1577
|
+
# request['method'] = 'UNSUBSCRIPTION'
|
1578
|
+
# request['params'] = topics
|
1436
1579
|
else:
|
1437
1580
|
request['method'] = 'unsub.tickers'
|
1438
1581
|
request['params'] = {}
|
@@ -1464,7 +1607,7 @@ class mexc(mexcAsync):
|
|
1464
1607
|
for i in range(0, len(symbols)):
|
1465
1608
|
if isSpot:
|
1466
1609
|
market = self.market(symbols[i])
|
1467
|
-
topics.append('spot@public.bookTicker.v3.api@' + market['id'])
|
1610
|
+
topics.append('spot@public.aggre.bookTicker.v3.api.pb@100ms@' + market['id'])
|
1468
1611
|
messageHashes.append('unsubscribe:bidask:' + symbols[i])
|
1469
1612
|
url = self.urls['api']['ws']['spot']
|
1470
1613
|
request: dict = {
|
@@ -1494,7 +1637,7 @@ class mexc(mexcAsync):
|
|
1494
1637
|
url = None
|
1495
1638
|
if market['spot']:
|
1496
1639
|
url = self.urls['api']['ws']['spot']
|
1497
|
-
channel = 'spot@public.kline.v3.api@' + market['id'] + '@' + timeframeId
|
1640
|
+
channel = 'spot@public.kline.v3.api.pb@' + market['id'] + '@' + timeframeId
|
1498
1641
|
params['unsubscribed'] = True
|
1499
1642
|
await self.watch_spot_public(channel, messageHash, params)
|
1500
1643
|
else:
|
@@ -1514,6 +1657,7 @@ class mexc(mexcAsync):
|
|
1514
1657
|
unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
1515
1658
|
:param str symbol: unified array of symbols
|
1516
1659
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1660
|
+
:param str [params.frequency]: the frequency of the order book updates, default is '10ms', can be '100ms' or '10ms
|
1517
1661
|
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
1518
1662
|
"""
|
1519
1663
|
await self.load_markets()
|
@@ -1523,7 +1667,9 @@ class mexc(mexcAsync):
|
|
1523
1667
|
url = None
|
1524
1668
|
if market['spot']:
|
1525
1669
|
url = self.urls['api']['ws']['spot']
|
1526
|
-
|
1670
|
+
frequency = None
|
1671
|
+
frequency, params = self.handle_option_and_params(params, 'watchOrderBook', 'frequency', '100ms')
|
1672
|
+
channel = 'spot@public.aggre.depth.v3.api.pb@' + frequency + '@' + market['id']
|
1527
1673
|
params['unsubscribed'] = True
|
1528
1674
|
await self.watch_spot_public(channel, messageHash, params)
|
1529
1675
|
else:
|
@@ -1552,7 +1698,7 @@ class mexc(mexcAsync):
|
|
1552
1698
|
url = None
|
1553
1699
|
if market['spot']:
|
1554
1700
|
url = self.urls['api']['ws']['spot']
|
1555
|
-
channel = 'spot@public.deals.v3.api@' + market['id']
|
1701
|
+
channel = 'spot@public.aggre.deals.v3.api.pb@100ms@' + market['id']
|
1556
1702
|
params['unsubscribed'] = True
|
1557
1703
|
await self.watch_spot_public(channel, messageHash, params)
|
1558
1704
|
else:
|
@@ -1654,16 +1800,59 @@ class mexc(mexcAsync):
|
|
1654
1800
|
channel = self.safe_string(parts, 1)
|
1655
1801
|
methods: dict = {
|
1656
1802
|
'public.increase.depth.v3.api': self.handle_order_book_subscription,
|
1803
|
+
'public.aggre.depth.v3.api.pb': self.handle_order_book_subscription,
|
1657
1804
|
}
|
1658
1805
|
method = self.safe_value(methods, channel)
|
1659
1806
|
if method is not None:
|
1660
1807
|
method(client, message)
|
1661
1808
|
|
1809
|
+
def handle_protobuf_message(self, client: Client, message):
|
1810
|
+
# protobuf message decoded
|
1811
|
+
# {
|
1812
|
+
# "channel":"spot@public.kline.v3.api.pb@BTCUSDT@Min1",
|
1813
|
+
# "symbol":"BTCUSDT",
|
1814
|
+
# "symbolId":"2fb942154ef44a4ab2ef98c8afb6a4a7",
|
1815
|
+
# "createTime":"1754737941062",
|
1816
|
+
# "publicSpotKline":{
|
1817
|
+
# "interval":"Min1",
|
1818
|
+
# "windowStart":"1754737920",
|
1819
|
+
# "openingPrice":"117317.31",
|
1820
|
+
# "closingPrice":"117325.26",
|
1821
|
+
# "highestPrice":"117341",
|
1822
|
+
# "lowestPrice":"117317.3",
|
1823
|
+
# "volume":"3.12599854",
|
1824
|
+
# "amount":"366804.43",
|
1825
|
+
# "windowEnd":"1754737980"
|
1826
|
+
# }
|
1827
|
+
# }
|
1828
|
+
channel = self.safe_string(message, 'channel')
|
1829
|
+
channelParts = channel.split('@')
|
1830
|
+
channelId = self.safe_string(channelParts, 1)
|
1831
|
+
if channelId == 'public.kline.v3.api.pb':
|
1832
|
+
self.handle_ohlcv(client, message)
|
1833
|
+
elif channelId == 'public.aggre.deals.v3.api.pb':
|
1834
|
+
self.handle_trades(client, message)
|
1835
|
+
elif channelId == 'public.aggre.bookTicker.v3.api.pb':
|
1836
|
+
self.handle_ticker(client, message)
|
1837
|
+
elif channelId == 'public.aggre.depth.v3.api.pb':
|
1838
|
+
self.handle_order_book(client, message)
|
1839
|
+
elif channelId == 'private.account.v3.api.pb':
|
1840
|
+
self.handle_balance(client, message)
|
1841
|
+
elif channelId == 'private.deals.v3.api.pb':
|
1842
|
+
self.handle_my_trade(client, message)
|
1843
|
+
elif channelId == 'private.orders.v3.api.pb':
|
1844
|
+
self.handle_order(client, message)
|
1845
|
+
return True
|
1846
|
+
|
1662
1847
|
def handle_message(self, client: Client, message):
|
1663
1848
|
if isinstance(message, str):
|
1664
1849
|
if message == 'Invalid listen key':
|
1665
1850
|
error = AuthenticationError(self.id + ' invalid listen key')
|
1666
1851
|
client.reject(error)
|
1852
|
+
return
|
1853
|
+
if self.is_binary_message(message):
|
1854
|
+
message = self.decode_proto_msg(message)
|
1855
|
+
self.handle_protobuf_message(client, message)
|
1667
1856
|
return
|
1668
1857
|
if 'msg' in message:
|
1669
1858
|
self.handle_subscription_status(client, message)
|