ccxt 4.2.23 → 4.2.24

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.
@@ -13,6 +13,7 @@ export default class binanceus extends binance {
13
13
  'id': 'binanceus',
14
14
  'name': 'Binance US',
15
15
  'countries': ['US'],
16
+ 'hostname': 'binance.us',
16
17
  'rateLimit': 50,
17
18
  'certified': false,
18
19
  'pro': true,
@@ -20,10 +21,11 @@ export default class binanceus extends binance {
20
21
  'logo': 'https://user-images.githubusercontent.com/1294454/65177307-217b7c80-da5f-11e9-876e-0b748ba0a358.jpg',
21
22
  'api': {
22
23
  'web': 'https://www.binance.us',
23
- 'sapi': 'https://api.binance.us/sapi/v1',
24
- 'wapi': 'https://api.binance.us/wapi/v3',
25
24
  'public': 'https://api.binance.us/api/v3',
26
25
  'private': 'https://api.binance.us/api/v3',
26
+ 'sapi': 'https://api.binance.us/sapi/v1',
27
+ 'sapiV2': 'https://api.binance.us/sapi/v2',
28
+ 'sapiV3': 'https://api.binance.us/sapi/v3',
27
29
  },
28
30
  'www': 'https://www.binance.us',
29
31
  'referral': 'https://www.binance.us/?ref=35005074',
@@ -84,13 +86,13 @@ export default class binanceus extends binance {
84
86
  'api': {
85
87
  'public': {
86
88
  'get': {
87
- 'exchangeInfo': 10,
88
89
  'ping': 1,
89
90
  'time': 1,
90
- 'depth': { 'cost': 1, 'byLimit': [[100, 1], [500, 5], [1000, 10], [5000, 50]] },
91
+ 'exchangeInfo': 10,
91
92
  'trades': 1,
92
- 'aggTrades': 1,
93
93
  'historicalTrades': 5,
94
+ 'aggTrades': 1,
95
+ 'depth': { 'cost': 1, 'byLimit': [[100, 1], [500, 5], [1000, 10], [5000, 50]] },
94
96
  'klines': 1,
95
97
  'ticker/price': { 'cost': 1, 'noSymbol': 2 },
96
98
  'avgPrice': 1,
@@ -101,7 +103,107 @@ export default class binanceus extends binance {
101
103
  },
102
104
  'private': {
103
105
  'get': {
104
- 'status': 1,
106
+ 'account': 10,
107
+ 'rateLimit/order': 20,
108
+ 'order': 2,
109
+ 'openOrders': { 'cost': 3, 'noSymbol': 40 },
110
+ 'myTrades': 10,
111
+ 'myPreventedMatches': 10,
112
+ 'allOrders': 10,
113
+ 'orderList': 2,
114
+ 'allOrderList': 10,
115
+ 'openOrderList': 3,
116
+ },
117
+ 'post': {
118
+ 'order': 1,
119
+ 'order/test': 1,
120
+ 'order/cancelReplace': 1,
121
+ 'order/oco': 1,
122
+ },
123
+ 'delete': {
124
+ 'order': 1,
125
+ 'openOrders': 1,
126
+ 'orderList': 1,
127
+ },
128
+ },
129
+ 'sapi': {
130
+ 'get': {
131
+ 'system/status': 1,
132
+ 'asset/assetDistributionHistory': 1,
133
+ 'asset/query/trading-fee': 1,
134
+ 'asset/query/trading-volume': 1,
135
+ 'sub-account/spotSummary': 1,
136
+ 'sub-account/status': 1,
137
+ 'otc/coinPairs': 1,
138
+ 'otc/orders/{orderId}': 1,
139
+ 'otc/orders': 1,
140
+ 'ocbs/orders': 1,
141
+ 'capital/config/getall': 1,
142
+ 'capital/withdraw/history': 1,
143
+ 'fiatpayment/query/withdraw/history': 1,
144
+ 'capital/deposit/address': 1,
145
+ 'capital/deposit/hisrec': 1,
146
+ 'fiatpayment/query/deposit/history': 1,
147
+ 'capital/sub-account/deposit/address': 1,
148
+ 'capital/sub-account/deposit/history': 1,
149
+ 'asset/query/dust-logs': 1,
150
+ 'asset/query/dust-assets': 1,
151
+ 'marketing/referral/reward/history': 1,
152
+ 'staking/asset': 1,
153
+ 'staking/stakingBalance': 1,
154
+ 'staking/history': 1,
155
+ 'staking/stakingRewardsHistory': 1,
156
+ 'custodian/balance': 1,
157
+ 'custodian/supportedAssetList': 1,
158
+ 'custodian/walletTransferHistory': 1,
159
+ 'custodian/custodianTransferHistory': 1,
160
+ 'custodian/openOrders': 1,
161
+ 'custodian/order': 1,
162
+ 'custodian/orderHistory': 1,
163
+ 'custodian/tradeHistory': 1,
164
+ 'custodian/settlementSetting': 1,
165
+ 'custodian/settlementHistory': 1,
166
+ 'cl/transferHistory': 1,
167
+ 'apipartner/checkEligibility': 1,
168
+ 'apipartner/rebateHistory': 1,
169
+ },
170
+ 'post': {
171
+ 'otc/quotes': 1,
172
+ 'otc/orders': 1,
173
+ 'fiatpayment/withdraw/apply': 1,
174
+ 'capital/withdraw/apply': 1,
175
+ 'asset/dust': 10,
176
+ 'staking/stake': 1,
177
+ 'staking/unstake': 1,
178
+ 'custodian/walletTransfer': 1,
179
+ 'custodian/custodianTransfer': 1,
180
+ 'custodian/undoTransfer': 1,
181
+ 'custodian/order': 1,
182
+ 'custodian/ocoOrder': 1,
183
+ 'cl/transfer': 1,
184
+ },
185
+ 'delete': {
186
+ 'custodian/cancelOrder': 1,
187
+ 'custodian/cancelOrdersBySymbol': 1,
188
+ 'custodian/cancelOcoOrder': 1,
189
+ },
190
+ },
191
+ 'sapiV2': {
192
+ 'get': {
193
+ 'cl/account': 10,
194
+ 'cl/alertHistory': 1,
195
+ },
196
+ },
197
+ 'sapiV3': {
198
+ 'get': {
199
+ 'accountStatus': 1,
200
+ 'apiTradingStatus': 1,
201
+ 'sub-account/list': 1,
202
+ 'sub-account/transfer/history': 1,
203
+ 'sub-account/assets': 1,
204
+ },
205
+ 'post': {
206
+ 'sub-account/transfer': 1,
105
207
  },
106
208
  },
107
209
  },
package/js/src/bingx.js CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  // ---------------------------------------------------------------------------
8
8
  import Exchange from './abstract/bingx.js';
9
- import { AuthenticationError, ExchangeNotAvailable, PermissionDenied, AccountSuspended, ExchangeError, InsufficientFunds, BadRequest, OrderNotFound, DDoSProtection, BadSymbol, ArgumentsRequired, NotSupported } from './base/errors.js';
9
+ import { AuthenticationError, PermissionDenied, AccountSuspended, ExchangeError, InsufficientFunds, BadRequest, OrderNotFound, DDoSProtection, BadSymbol, ArgumentsRequired, NotSupported } from './base/errors.js';
10
10
  import { Precise } from './base/Precise.js';
11
11
  import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
12
12
  import { DECIMAL_PLACES } from './base/functions/number.js';
@@ -363,7 +363,7 @@ export default class bingx extends Exchange {
363
363
  '100500': ExchangeError,
364
364
  '100503': ExchangeError,
365
365
  '80001': BadRequest,
366
- '80012': ExchangeNotAvailable,
366
+ '80012': InsufficientFunds,
367
367
  '80014': BadRequest,
368
368
  '80016': OrderNotFound,
369
369
  '80017': OrderNotFound,
@@ -1,5 +1,5 @@
1
1
  import Exchange from './abstract/bitfinex2.js';
2
- import type { Int, OrderSide, OrderType, Trade, OHLCV, Order, FundingRateHistory, OrderBook, Str, Transaction, Ticker, Balances, Tickers, Strings, Currency, Market } from './base/types.js';
2
+ import type { Int, OrderSide, OrderType, Trade, OHLCV, Order, FundingRateHistory, OrderBook, Str, Transaction, Ticker, Balances, Tickers, Strings, Currency, Market, OpenInterest } from './base/types.js';
3
3
  /**
4
4
  * @class bitfinex2
5
5
  * @augments Exchange
@@ -156,6 +156,7 @@ export default class bitfinex2 extends Exchange {
156
156
  previousFundingTimestamp: any;
157
157
  previousFundingDatetime: any;
158
158
  };
159
- fetchOpenInterest(symbol: string, params?: {}): Promise<import("./base/types.js").OpenInterest>;
160
- parseOpenInterest(interest: any, market?: Market): import("./base/types.js").OpenInterest;
159
+ fetchOpenInterest(symbol: string, params?: {}): Promise<OpenInterest>;
160
+ fetchOpenInterestHistory(symbol: string, timeframe?: string, since?: Int, limit?: Int, params?: {}): Promise<OpenInterest[]>;
161
+ parseOpenInterest(interest: any, market?: Market): OpenInterest;
161
162
  }
@@ -58,6 +58,7 @@ export default class bitfinex2 extends Exchange {
58
58
  'fetchMyTrades': true,
59
59
  'fetchOHLCV': true,
60
60
  'fetchOpenInterest': true,
61
+ 'fetchOpenInterestHistory': true,
61
62
  'fetchOpenOrder': true,
62
63
  'fetchOpenOrders': true,
63
64
  'fetchOrder': true,
@@ -3037,7 +3038,73 @@ export default class bitfinex2 extends Exchange {
3037
3038
  //
3038
3039
  return this.parseOpenInterest(response[0], market);
3039
3040
  }
3041
+ async fetchOpenInterestHistory(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
3042
+ /**
3043
+ * @method
3044
+ * @name bitfinex2#fetchOpenInterestHistory
3045
+ * @description retrieves the open interest history of a currency
3046
+ * @see https://docs.bitfinex.com/reference/rest-public-derivatives-status-history
3047
+ * @param {string} symbol unified CCXT market symbol
3048
+ * @param {string} timeframe the time period of each row of data, not used by bitfinex2
3049
+ * @param {int} [since] the time in ms of the earliest record to retrieve as a unix timestamp
3050
+ * @param {int} [limit] the number of records in the response
3051
+ * @param {object} [params] exchange specific parameters
3052
+ * @param {int} [params.until] the time in ms of the latest record to retrieve as a unix timestamp
3053
+ * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
3054
+ * @returns An array of [open interest structures]{@link https://docs.ccxt.com/#/?id=open-interest-structure}
3055
+ */
3056
+ await this.loadMarkets();
3057
+ let paginate = false;
3058
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchOpenInterestHistory', 'paginate');
3059
+ if (paginate) {
3060
+ return await this.fetchPaginatedCallDeterministic('fetchOpenInterestHistory', symbol, since, limit, '8h', params, 5000);
3061
+ }
3062
+ const market = this.market(symbol);
3063
+ let request = {
3064
+ 'symbol': market['id'],
3065
+ };
3066
+ if (since !== undefined) {
3067
+ request['start'] = since;
3068
+ }
3069
+ if (limit !== undefined) {
3070
+ request['limit'] = limit;
3071
+ }
3072
+ [request, params] = this.handleUntilOption('end', request, params);
3073
+ const response = await this.publicGetStatusDerivSymbolHist(this.extend(request, params));
3074
+ //
3075
+ // [
3076
+ // [
3077
+ // 1706295191000, // timestamp
3078
+ // null,
3079
+ // 42152.425382, // derivative mid price
3080
+ // 42133, // spot mid price
3081
+ // null,
3082
+ // 37671589.7853521, // insurance fund balance
3083
+ // null,
3084
+ // 1706313600000, // timestamp of next funding
3085
+ // 0.00018734, // accrued funding for next period
3086
+ // 3343, // next funding step
3087
+ // null,
3088
+ // 0.00007587, // current funding
3089
+ // null,
3090
+ // null,
3091
+ // 42134.1, // mark price
3092
+ // null,
3093
+ // null,
3094
+ // 5775.20348804, // open interest number of contracts
3095
+ // null,
3096
+ // null,
3097
+ // null,
3098
+ // 0.0005, // average spread without funding payment
3099
+ // 0.0025 // funding payment cap
3100
+ // ],
3101
+ // ]
3102
+ //
3103
+ return this.parseOpenInterests(response, market, since, limit);
3104
+ }
3040
3105
  parseOpenInterest(interest, market = undefined) {
3106
+ //
3107
+ // fetchOpenInterest:
3041
3108
  //
3042
3109
  // [
3043
3110
  // "tXRPF0:USTF0", // market id
@@ -3066,11 +3133,41 @@ export default class bitfinex2 extends Exchange {
3066
3133
  // 0.0025 // funding payment cap
3067
3134
  // ]
3068
3135
  //
3136
+ // fetchOpenInterestHistory:
3137
+ //
3138
+ // [
3139
+ // 1706295191000, // timestamp
3140
+ // null,
3141
+ // 42152.425382, // derivative mid price
3142
+ // 42133, // spot mid price
3143
+ // null,
3144
+ // 37671589.7853521, // insurance fund balance
3145
+ // null,
3146
+ // 1706313600000, // timestamp of next funding
3147
+ // 0.00018734, // accrued funding for next period
3148
+ // 3343, // next funding step
3149
+ // null,
3150
+ // 0.00007587, // current funding
3151
+ // null,
3152
+ // null,
3153
+ // 42134.1, // mark price
3154
+ // null,
3155
+ // null,
3156
+ // 5775.20348804, // open interest number of contracts
3157
+ // null,
3158
+ // null,
3159
+ // null,
3160
+ // 0.0005, // average spread without funding payment
3161
+ // 0.0025 // funding payment cap
3162
+ // ]
3163
+ //
3164
+ const interestLength = interest.length;
3165
+ const openInterestIndex = (interestLength === 23) ? 17 : 18;
3069
3166
  const timestamp = this.safeInteger(interest, 1);
3070
3167
  const marketId = this.safeString(interest, 0);
3071
3168
  return this.safeOpenInterest({
3072
3169
  'symbol': this.safeSymbol(marketId, market, undefined, 'swap'),
3073
- 'openInterestAmount': this.safeNumber(interest, 18),
3170
+ 'openInterestAmount': this.safeNumber(interest, openInterestIndex),
3074
3171
  'openInterestValue': undefined,
3075
3172
  'timestamp': timestamp,
3076
3173
  'datetime': this.iso8601(timestamp),
package/js/src/phemex.js CHANGED
@@ -3769,7 +3769,7 @@ export default class phemex extends Exchange {
3769
3769
  const contracts = this.safeString(position, 'size');
3770
3770
  const contractSize = this.safeValue(market, 'contractSize');
3771
3771
  const contractSizeString = this.numberToString(contractSize);
3772
- const leverage = this.parseNumber(Precise.stringAbs((this.safeString(position, 'leverage', 'leverageRr'))));
3772
+ const leverage = this.parseNumber(Precise.stringAbs((this.safeString2(position, 'leverage', 'leverageRr'))));
3773
3773
  const entryPriceString = this.safeString2(position, 'avgEntryPrice', 'avgEntryPriceRp');
3774
3774
  const rawSide = this.safeString(position, 'side');
3775
3775
  let side = undefined;
@@ -1,5 +1,5 @@
1
1
  import bitoproRest from '../bitopro.js';
2
- import type { Int, OrderBook, Trade, Ticker, Balances } from '../base/types.js';
2
+ import type { Int, OrderBook, Trade, Ticker, Balances, Market, Str } from '../base/types.js';
3
3
  import Client from '../base/ws/Client.js';
4
4
  export default class bitopro extends bitoproRest {
5
5
  describe(): any;
@@ -8,6 +8,9 @@ export default class bitopro extends bitoproRest {
8
8
  handleOrderBook(client: Client, message: any): void;
9
9
  watchTrades(symbol: string, since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
10
10
  handleTrade(client: Client, message: any): void;
11
+ watchMyTrades(symbol?: Str, since?: Int, limit?: Int, params?: {}): Promise<Trade[]>;
12
+ handleMyTrade(client: Client, message: any): void;
13
+ parseWsTrade(trade: any, market?: Market): Trade;
11
14
  watchTicker(symbol: string, params?: {}): Promise<Ticker>;
12
15
  handleTicker(client: Client, message: any): void;
13
16
  authenticate(url: any): void;
@@ -7,7 +7,7 @@
7
7
  // ----------------------------------------------------------------------------
8
8
  import bitoproRest from '../bitopro.js';
9
9
  import { ExchangeError } from '../base/errors.js';
10
- import { ArrayCache } from '../base/ws/Cache.js';
10
+ import { ArrayCache, ArrayCacheBySymbolById } from '../base/ws/Cache.js';
11
11
  import { sha384 } from '../static_dependencies/noble-hashes/sha512.js';
12
12
  // ----------------------------------------------------------------------------
13
13
  export default class bitopro extends bitoproRest {
@@ -16,7 +16,7 @@ export default class bitopro extends bitoproRest {
16
16
  'has': {
17
17
  'ws': true,
18
18
  'watchBalance': true,
19
- 'watchMyTrades': false,
19
+ 'watchMyTrades': true,
20
20
  'watchOHLCV': false,
21
21
  'watchOrderBook': true,
22
22
  'watchOrders': false,
@@ -177,6 +177,150 @@ export default class bitopro extends bitoproRest {
177
177
  this.trades[symbol] = tradesCache;
178
178
  client.resolve(tradesCache, messageHash);
179
179
  }
180
+ async watchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
181
+ /**
182
+ * @method
183
+ * @name bitopro#watchMyTrades
184
+ * @description watches information on multiple trades made by the user
185
+ * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/ws/private/matches_stream.md
186
+ * @param {string} symbol unified market symbol of the market trades were made in
187
+ * @param {int} [since] the earliest time in ms to fetch trades for
188
+ * @param {int} [limit] the maximum number of trade structures to retrieve
189
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
190
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure
191
+ */
192
+ this.checkRequiredCredentials();
193
+ await this.loadMarkets();
194
+ let messageHash = 'USER_TRADE';
195
+ if (symbol !== undefined) {
196
+ const market = this.market(symbol);
197
+ messageHash = messageHash + ':' + market['symbol'];
198
+ }
199
+ const url = this.urls['ws']['private'] + '/' + 'user-trades';
200
+ this.authenticate(url);
201
+ const trades = await this.watch(url, messageHash, undefined, messageHash);
202
+ if (this.newUpdates) {
203
+ limit = trades.getLimit(symbol, limit);
204
+ }
205
+ return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
206
+ }
207
+ handleMyTrade(client, message) {
208
+ //
209
+ // {
210
+ // "event": "USER_TRADE",
211
+ // "timestamp": 1694667358782,
212
+ // "datetime": "2023-09-14T12:55:58.782Z",
213
+ // "data": {
214
+ // "base": "usdt",
215
+ // "quote": "twd",
216
+ // "side": "ask",
217
+ // "price": "32.039",
218
+ // "volume": "1",
219
+ // "fee": "6407800",
220
+ // "feeCurrency": "twd",
221
+ // "transactionTimestamp": 1694667358,
222
+ // "eventTimestamp": 1694667358,
223
+ // "orderID": 390733918,
224
+ // "orderType": "LIMIT",
225
+ // "matchID": "bd07673a-94b1-419e-b5ee-d7b723261a5d",
226
+ // "isMarket": false,
227
+ // "isMaker": false
228
+ // }
229
+ // }
230
+ //
231
+ const data = this.safeValue(message, 'data', {});
232
+ const baseId = this.safeString(data, 'base');
233
+ const quoteId = this.safeString(data, 'quote');
234
+ const base = this.safeCurrencyCode(baseId);
235
+ const quote = this.safeCurrencyCode(quoteId);
236
+ const symbol = this.symbol(base + '/' + quote);
237
+ const messageHash = this.safeString(message, 'event');
238
+ if (this.myTrades === undefined) {
239
+ const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
240
+ this.myTrades = new ArrayCacheBySymbolById(limit);
241
+ }
242
+ const trades = this.myTrades;
243
+ const parsed = this.parseWsTrade(data);
244
+ trades.append(parsed);
245
+ client.resolve(trades, messageHash);
246
+ client.resolve(trades, messageHash + ':' + symbol);
247
+ }
248
+ parseWsTrade(trade, market = undefined) {
249
+ //
250
+ // {
251
+ // "base": "usdt",
252
+ // "quote": "twd",
253
+ // "side": "ask",
254
+ // "price": "32.039",
255
+ // "volume": "1",
256
+ // "fee": "6407800",
257
+ // "feeCurrency": "twd",
258
+ // "transactionTimestamp": 1694667358,
259
+ // "eventTimestamp": 1694667358,
260
+ // "orderID": 390733918,
261
+ // "orderType": "LIMIT",
262
+ // "matchID": "bd07673a-94b1-419e-b5ee-d7b723261a5d",
263
+ // "isMarket": false,
264
+ // "isMaker": false
265
+ // }
266
+ //
267
+ const id = this.safeString(trade, 'matchID');
268
+ const orderId = this.safeString(trade, 'orderID');
269
+ const timestamp = this.safeTimestamp(trade, 'transactionTimestamp');
270
+ const baseId = this.safeString(trade, 'base');
271
+ const quoteId = this.safeString(trade, 'quote');
272
+ const base = this.safeCurrencyCode(baseId);
273
+ const quote = this.safeCurrencyCode(quoteId);
274
+ const symbol = this.symbol(base + '/' + quote);
275
+ market = this.safeMarket(symbol, market);
276
+ const price = this.safeString(trade, 'price');
277
+ const type = this.safeStringLower(trade, 'orderType');
278
+ let side = this.safeString(trade, 'side');
279
+ if (side !== undefined) {
280
+ if (side === 'ask') {
281
+ side = 'sell';
282
+ }
283
+ else if (side === 'bid') {
284
+ side = 'buy';
285
+ }
286
+ }
287
+ const amount = this.safeString(trade, 'volume');
288
+ let fee = undefined;
289
+ const feeAmount = this.safeString(trade, 'fee');
290
+ const feeSymbol = this.safeCurrencyCode(this.safeString(trade, 'feeCurrency'));
291
+ if (feeAmount !== undefined) {
292
+ fee = {
293
+ 'cost': feeAmount,
294
+ 'currency': feeSymbol,
295
+ 'rate': undefined,
296
+ };
297
+ }
298
+ const isMaker = this.safeValue(trade, 'isMaker');
299
+ let takerOrMaker = undefined;
300
+ if (isMaker !== undefined) {
301
+ if (isMaker) {
302
+ takerOrMaker = 'maker';
303
+ }
304
+ else {
305
+ takerOrMaker = 'taker';
306
+ }
307
+ }
308
+ return this.safeTrade({
309
+ 'id': id,
310
+ 'info': trade,
311
+ 'order': orderId,
312
+ 'timestamp': timestamp,
313
+ 'datetime': this.iso8601(timestamp),
314
+ 'symbol': symbol,
315
+ 'takerOrMaker': takerOrMaker,
316
+ 'type': type,
317
+ 'side': side,
318
+ 'price': price,
319
+ 'amount': amount,
320
+ 'cost': undefined,
321
+ 'fee': fee,
322
+ }, market);
323
+ }
180
324
  async watchTicker(symbol, params = {}) {
181
325
  /**
182
326
  * @method
@@ -319,6 +463,7 @@ export default class bitopro extends bitoproRest {
319
463
  'TICKER': this.handleTicker,
320
464
  'ORDER_BOOK': this.handleOrderBook,
321
465
  'ACCOUNT_BALANCE': this.handleBalance,
466
+ 'USER_TRADE': this.handleMyTrade,
322
467
  };
323
468
  const event = this.safeString(message, 'event');
324
469
  const method = this.safeValue(methods, event);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccxt",
3
- "version": "4.2.23",
3
+ "version": "4.2.24",
4
4
  "description": "A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges",
5
5
  "unpkg": "dist/ccxt.browser.js",
6
6
  "type": "module",
package/skip-tests.json CHANGED
@@ -338,6 +338,7 @@
338
338
  }
339
339
  },
340
340
  "bitopro": {
341
+ "skipWs": true,
341
342
  "skipMethods": {
342
343
  "fetchCurrencies": {
343
344
  "precision": "not provided",