ccxt 4.2.94 → 4.2.96

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 (43) hide show
  1. package/README.md +3 -3
  2. package/build.sh +1 -1
  3. package/dist/ccxt.browser.js +964 -406
  4. package/dist/ccxt.browser.min.js +2 -2
  5. package/dist/cjs/ccxt.js +1 -1
  6. package/dist/cjs/src/base/errors.js +25 -64
  7. package/dist/cjs/src/base/functions/crypto.js +15 -2
  8. package/dist/cjs/src/base/functions/rsa.js +2 -2
  9. package/dist/cjs/src/base/ws/OrderBookSide.js +5 -0
  10. package/dist/cjs/src/bitstamp.js +6 -0
  11. package/dist/cjs/src/coinbase.js +615 -102
  12. package/dist/cjs/src/coinex.js +61 -55
  13. package/dist/cjs/src/gemini.js +29 -10
  14. package/dist/cjs/src/htx.js +127 -125
  15. package/dist/cjs/src/okx.js +40 -40
  16. package/dist/cjs/src/pro/coinbase.js +37 -4
  17. package/js/ccxt.d.ts +3 -3
  18. package/js/ccxt.js +3 -3
  19. package/js/src/abstract/bitstamp.d.ts +6 -0
  20. package/js/src/abstract/coinbase.d.ts +1 -0
  21. package/js/src/base/errorHierarchy.d.ts +1 -1
  22. package/js/src/base/errorHierarchy.js +1 -1
  23. package/js/src/base/errors.d.ts +26 -26
  24. package/js/src/base/errors.js +26 -66
  25. package/js/src/base/functions/crypto.d.ts +1 -1
  26. package/js/src/base/functions/crypto.js +15 -2
  27. package/js/src/base/functions/rsa.js +2 -2
  28. package/js/src/base/types.d.ts +1 -0
  29. package/js/src/base/ws/OrderBook.d.ts +8 -0
  30. package/js/src/base/ws/OrderBook.js +1 -6
  31. package/js/src/base/ws/OrderBookSide.d.ts +9 -3
  32. package/js/src/base/ws/OrderBookSide.js +6 -1
  33. package/js/src/bitstamp.js +6 -0
  34. package/js/src/coinbase.d.ts +8 -1
  35. package/js/src/coinbase.js +616 -103
  36. package/js/src/coinex.js +61 -55
  37. package/js/src/gemini.js +29 -10
  38. package/js/src/htx.d.ts +1 -0
  39. package/js/src/htx.js +128 -126
  40. package/js/src/okx.js +40 -40
  41. package/js/src/pro/coinbase.js +37 -4
  42. package/package.json +1 -1
  43. package/skip-tests.json +2 -0
package/js/src/okx.js CHANGED
@@ -1120,7 +1120,7 @@ export default class okx extends Exchange {
1120
1120
  return super.handleMarketTypeAndParams(methodName, market, params);
1121
1121
  }
1122
1122
  convertToInstrumentType(type) {
1123
- const exchangeTypes = this.safeValue(this.options, 'exchangeType', {});
1123
+ const exchangeTypes = this.safeDict(this.options, 'exchangeType', {});
1124
1124
  return this.safeString(exchangeTypes, type, type);
1125
1125
  }
1126
1126
  createExpiredOptionMarket(symbol) {
@@ -2924,7 +2924,7 @@ export default class okx extends Exchange {
2924
2924
  const side = this.safeString(rawOrder, 'side');
2925
2925
  const amount = this.safeValue(rawOrder, 'amount');
2926
2926
  const price = this.safeValue(rawOrder, 'price');
2927
- const orderParams = this.safeValue(rawOrder, 'params', {});
2927
+ const orderParams = this.safeDict(rawOrder, 'params', {});
2928
2928
  const extendedParams = this.extend(orderParams, params); // the request does not accept extra params since it's a list, so we're extending each order with the common params
2929
2929
  const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, extendedParams);
2930
2930
  ordersRequests.push(orderRequest);
@@ -3113,8 +3113,8 @@ export default class okx extends Exchange {
3113
3113
  // "msg": ""
3114
3114
  // }
3115
3115
  //
3116
- const data = this.safeValue(response, 'data', []);
3117
- const first = this.safeValue(data, 0);
3116
+ const data = this.safeList(response, 'data', []);
3117
+ const first = this.safeDict(data, 0, {});
3118
3118
  const order = this.parseOrder(first, market);
3119
3119
  order['type'] = type;
3120
3120
  order['side'] = side;
@@ -4313,7 +4313,7 @@ export default class okx extends Exchange {
4313
4313
  if (paginate) {
4314
4314
  return await this.fetchPaginatedCallDynamic('fetchLedger', code, since, limit, params);
4315
4315
  }
4316
- const options = this.safeValue(this.options, 'fetchLedger', {});
4316
+ const options = this.safeDict(this.options, 'fetchLedger', {});
4317
4317
  let method = this.safeString(options, 'method');
4318
4318
  method = this.safeString(params, 'method', method);
4319
4319
  params = this.omit(params, 'method');
@@ -4642,7 +4642,7 @@ export default class okx extends Exchange {
4642
4642
  // ]
4643
4643
  // }
4644
4644
  //
4645
- const data = this.safeValue(response, 'data', []);
4645
+ const data = this.safeList(response, 'data', []);
4646
4646
  const filtered = this.filterBy(data, 'selected', true);
4647
4647
  const parsed = this.parseDepositAddresses(filtered, [currency['code']], false);
4648
4648
  return this.indexBy(parsed, 'network');
@@ -4716,7 +4716,7 @@ export default class okx extends Exchange {
4716
4716
  };
4717
4717
  let network = this.safeString(params, 'network'); // this line allows the user to specify either ERC20 or ETH
4718
4718
  if (network !== undefined) {
4719
- const networks = this.safeValue(this.options, 'networks', {});
4719
+ const networks = this.safeDict(this.options, 'networks', {});
4720
4720
  network = this.safeString(networks, network.toUpperCase(), network); // handle ETH>ERC20 alias
4721
4721
  request['chain'] = currency['id'] + '-' + network;
4722
4722
  params = this.omit(params, 'network');
@@ -4725,7 +4725,7 @@ export default class okx extends Exchange {
4725
4725
  if (fee === undefined) {
4726
4726
  const currencies = await this.fetchCurrencies();
4727
4727
  this.currencies = this.deepExtend(this.currencies, currencies);
4728
- const targetNetwork = this.safeValue(currency['networks'], this.networkIdToCode(network), {});
4728
+ const targetNetwork = this.safeDict(currency['networks'], this.networkIdToCode(network), {});
4729
4729
  fee = this.safeString(targetNetwork, 'fee');
4730
4730
  if (fee === undefined) {
4731
4731
  throw new ArgumentsRequired(this.id + ' withdraw() requires a "fee" string parameter, network transaction fee must be ≥ 0. Withdrawals to OKCoin or OKX are fee-free, please set "0". Withdrawing to external digital asset address requires network transaction fee.');
@@ -4747,7 +4747,7 @@ export default class okx extends Exchange {
4747
4747
  // ]
4748
4748
  // }
4749
4749
  //
4750
- const data = this.safeValue(response, 'data', []);
4750
+ const data = this.safeList(response, 'data', []);
4751
4751
  const transaction = this.safeDict(data, 0);
4752
4752
  return this.parseTransaction(transaction, currency);
4753
4753
  }
@@ -4972,7 +4972,7 @@ export default class okx extends Exchange {
4972
4972
  // "msg": ''
4973
4973
  // }
4974
4974
  //
4975
- const data = this.safeValue(response, 'data');
4975
+ const data = this.safeList(response, 'data', []);
4976
4976
  const withdrawal = this.safeDict(data, 0, {});
4977
4977
  return this.parseTransaction(withdrawal);
4978
4978
  }
@@ -5259,8 +5259,8 @@ export default class okx extends Exchange {
5259
5259
  // ]
5260
5260
  // }
5261
5261
  //
5262
- const data = this.safeValue(response, 'data', []);
5263
- const position = this.safeValue(data, 0);
5262
+ const data = this.safeList(response, 'data', []);
5263
+ const position = this.safeDict(data, 0);
5264
5264
  if (position === undefined) {
5265
5265
  return undefined;
5266
5266
  }
@@ -5296,7 +5296,7 @@ export default class okx extends Exchange {
5296
5296
  request['instId'] = marketIds.join(',');
5297
5297
  }
5298
5298
  }
5299
- const fetchPositionsOptions = this.safeValue(this.options, 'fetchPositions', {});
5299
+ const fetchPositionsOptions = this.safeDict(this.options, 'fetchPositions', {});
5300
5300
  const method = this.safeString(fetchPositionsOptions, 'method', 'privateGetAccountPositions');
5301
5301
  let response = undefined;
5302
5302
  if (method === 'privateGetAccountPositionsHistory') {
@@ -5351,7 +5351,7 @@ export default class okx extends Exchange {
5351
5351
  // ]
5352
5352
  // }
5353
5353
  //
5354
- const positions = this.safeValue(response, 'data', []);
5354
+ const positions = this.safeList(response, 'data', []);
5355
5355
  const result = [];
5356
5356
  for (let i = 0; i < positions.length; i++) {
5357
5357
  result.push(this.parsePosition(positions[i]));
@@ -5559,7 +5559,7 @@ export default class okx extends Exchange {
5559
5559
  */
5560
5560
  await this.loadMarkets();
5561
5561
  const currency = this.currency(code);
5562
- const accountsByType = this.safeValue(this.options, 'accountsByType', {});
5562
+ const accountsByType = this.safeDict(this.options, 'accountsByType', {});
5563
5563
  const fromId = this.safeString(accountsByType, fromAccount, fromAccount);
5564
5564
  const toId = this.safeString(accountsByType, toAccount, toAccount);
5565
5565
  const request = {
@@ -5601,7 +5601,7 @@ export default class okx extends Exchange {
5601
5601
  // ]
5602
5602
  // }
5603
5603
  //
5604
- const data = this.safeValue(response, 'data', []);
5604
+ const data = this.safeList(response, 'data', []);
5605
5605
  const rawTransfer = this.safeDict(data, 0, {});
5606
5606
  return this.parseTransfer(rawTransfer, currency);
5607
5607
  }
@@ -5664,7 +5664,7 @@ export default class okx extends Exchange {
5664
5664
  let amount = this.safeNumber(transfer, 'amt');
5665
5665
  const fromAccountId = this.safeString(transfer, 'from');
5666
5666
  const toAccountId = this.safeString(transfer, 'to');
5667
- const accountsById = this.safeValue(this.options, 'accountsById', {});
5667
+ const accountsById = this.safeDict(this.options, 'accountsById', {});
5668
5668
  const timestamp = this.safeInteger(transfer, 'ts');
5669
5669
  const balanceChange = this.safeString(transfer, 'sz');
5670
5670
  if (balanceChange !== undefined) {
@@ -5715,7 +5715,7 @@ export default class okx extends Exchange {
5715
5715
  // "msg": ""
5716
5716
  // }
5717
5717
  //
5718
- const data = this.safeValue(response, 'data', []);
5718
+ const data = this.safeList(response, 'data', []);
5719
5719
  const transfer = this.safeDict(data, 0);
5720
5720
  return this.parseTransfer(transfer);
5721
5721
  }
@@ -5921,8 +5921,8 @@ export default class okx extends Exchange {
5921
5921
  // "msg": ""
5922
5922
  // }
5923
5923
  //
5924
- const data = this.safeValue(response, 'data', []);
5925
- const entry = this.safeValue(data, 0, {});
5924
+ const data = this.safeList(response, 'data', []);
5925
+ const entry = this.safeDict(data, 0, {});
5926
5926
  return this.parseFundingRate(entry, market);
5927
5927
  }
5928
5928
  async fetchFundingHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
@@ -6062,7 +6062,7 @@ export default class okx extends Exchange {
6062
6062
  // "type": "8"
6063
6063
  // }
6064
6064
  //
6065
- const data = this.safeValue(response, 'data', []);
6065
+ const data = this.safeList(response, 'data', []);
6066
6066
  const result = [];
6067
6067
  for (let i = 0; i < data.length; i++) {
6068
6068
  const entry = data[i];
@@ -6254,7 +6254,7 @@ export default class okx extends Exchange {
6254
6254
  // ],
6255
6255
  // }
6256
6256
  //
6257
- const data = this.safeValue(response, 'data', []);
6257
+ const data = this.safeList(response, 'data', []);
6258
6258
  const rates = [];
6259
6259
  for (let i = 0; i < data.length; i++) {
6260
6260
  rates.push(this.parseBorrowRate(data[i]));
@@ -6290,8 +6290,8 @@ export default class okx extends Exchange {
6290
6290
  // "msg": ""
6291
6291
  // }
6292
6292
  //
6293
- const data = this.safeValue(response, 'data');
6294
- const rate = this.safeValue(data, 0);
6293
+ const data = this.safeList(response, 'data', []);
6294
+ const rate = this.safeDict(data, 0, {});
6295
6295
  return this.parseBorrowRate(rate);
6296
6296
  }
6297
6297
  parseBorrowRate(info, currency = undefined) {
@@ -6395,7 +6395,7 @@ export default class okx extends Exchange {
6395
6395
  // "msg": ""
6396
6396
  // }
6397
6397
  //
6398
- const data = this.safeValue(response, 'data');
6398
+ const data = this.safeList(response, 'data', []);
6399
6399
  return this.parseBorrowRateHistories(data, codes, since, limit);
6400
6400
  }
6401
6401
  async fetchBorrowRateHistory(code, since = undefined, limit = undefined, params = {}) {
@@ -6439,7 +6439,7 @@ export default class okx extends Exchange {
6439
6439
  // "msg": ""
6440
6440
  // }
6441
6441
  //
6442
- const data = this.safeValue(response, 'data');
6442
+ const data = this.safeList(response, 'data', []);
6443
6443
  return this.parseBorrowRateHistory(data, code, since, limit);
6444
6444
  }
6445
6445
  async modifyMarginHelper(symbol, amount, type, params = {}) {
@@ -6631,7 +6631,7 @@ export default class okx extends Exchange {
6631
6631
  // ]
6632
6632
  // }
6633
6633
  //
6634
- const data = this.safeValue(response, 'data');
6634
+ const data = this.safeList(response, 'data', []);
6635
6635
  return this.parseMarketLeverageTiers(data, market);
6636
6636
  }
6637
6637
  parseMarketLeverageTiers(info, market = undefined) {
@@ -6733,7 +6733,7 @@ export default class okx extends Exchange {
6733
6733
  // "msg": ""
6734
6734
  // }
6735
6735
  //
6736
- const data = this.safeValue(response, 'data');
6736
+ const data = this.safeList(response, 'data', []);
6737
6737
  const interest = this.parseBorrowInterests(data);
6738
6738
  return this.filterByCurrencySinceLimit(interest, code, since, limit);
6739
6739
  }
@@ -6789,8 +6789,8 @@ export default class okx extends Exchange {
6789
6789
  // "msg": ""
6790
6790
  // }
6791
6791
  //
6792
- const data = this.safeValue(response, 'data', []);
6793
- const loan = this.safeValue(data, 0);
6792
+ const data = this.safeList(response, 'data', []);
6793
+ const loan = this.safeDict(data, 0, {});
6794
6794
  return this.parseMarginLoan(loan, currency);
6795
6795
  }
6796
6796
  async repayCrossMargin(code, amount, params = {}) {
@@ -6834,8 +6834,8 @@ export default class okx extends Exchange {
6834
6834
  // "msg": ""
6835
6835
  // }
6836
6836
  //
6837
- const data = this.safeValue(response, 'data', []);
6838
- const loan = this.safeValue(data, 0);
6837
+ const data = this.safeList(response, 'data', []);
6838
+ const loan = this.safeDict(data, 0, {});
6839
6839
  return this.parseMarginLoan(loan, currency);
6840
6840
  }
6841
6841
  parseMarginLoan(info, currency = undefined) {
@@ -6917,8 +6917,8 @@ export default class okx extends Exchange {
6917
6917
  * @param {int} [params.until] The time in ms of the latest record to retrieve as a unix timestamp
6918
6918
  * @returns An array of [open interest structures]{@link https://docs.ccxt.com/#/?id=open-interest-structure}
6919
6919
  */
6920
- const options = this.safeValue(this.options, 'fetchOpenInterestHistory', {});
6921
- const timeframes = this.safeValue(options, 'timeframes', {});
6920
+ const options = this.safeDict(this.options, 'fetchOpenInterestHistory', {});
6921
+ const timeframes = this.safeDict(options, 'timeframes', {});
6922
6922
  timeframe = this.safeString(timeframes, timeframe, timeframe);
6923
6923
  if (timeframe !== '5m' && timeframe !== '1H' && timeframe !== '1D') {
6924
6924
  throw new BadRequest(this.id + ' fetchOpenInterestHistory cannot only use the 5m, 1h, and 1d timeframe');
@@ -7208,7 +7208,7 @@ export default class okx extends Exchange {
7208
7208
  // "msg": ""
7209
7209
  // }
7210
7210
  //
7211
- const data = this.safeValue(response, 'data', []);
7211
+ const data = this.safeList(response, 'data', []);
7212
7212
  const settlements = this.parseSettlements(data, market);
7213
7213
  const sorted = this.sortBy(settlements, 'timestamp');
7214
7214
  return this.filterBySymbolSinceLimit(sorted, market['symbol'], since, limit);
@@ -7247,7 +7247,7 @@ export default class okx extends Exchange {
7247
7247
  for (let i = 0; i < settlements.length; i++) {
7248
7248
  const entry = settlements[i];
7249
7249
  const timestamp = this.safeInteger(entry, 'ts');
7250
- const details = this.safeValue(entry, 'details', []);
7250
+ const details = this.safeList(entry, 'details', []);
7251
7251
  for (let j = 0; j < details.length; j++) {
7252
7252
  const settlement = this.parseSettlement(details[j], market);
7253
7253
  result.push(this.extend(settlement, {
@@ -7293,7 +7293,7 @@ export default class okx extends Exchange {
7293
7293
  // "msg": ""
7294
7294
  // }
7295
7295
  //
7296
- const underlyings = this.safeValue(response, 'data', []);
7296
+ const underlyings = this.safeList(response, 'data', []);
7297
7297
  return underlyings[0];
7298
7298
  }
7299
7299
  async fetchGreeks(symbol, params = {}) {
@@ -7345,7 +7345,7 @@ export default class okx extends Exchange {
7345
7345
  // "msg": ""
7346
7346
  // }
7347
7347
  //
7348
- const data = this.safeValue(response, 'data', []);
7348
+ const data = this.safeList(response, 'data', []);
7349
7349
  for (let i = 0; i < data.length; i++) {
7350
7350
  const entry = data[i];
7351
7351
  const entryMarketId = this.safeString(entry, 'instId');
@@ -7468,7 +7468,7 @@ export default class okx extends Exchange {
7468
7468
  // "outTime": "1701877077102579"
7469
7469
  // }
7470
7470
  //
7471
- const data = this.safeValue(response, 'data');
7471
+ const data = this.safeList(response, 'data', []);
7472
7472
  const order = this.safeDict(data, 0);
7473
7473
  return this.parseOrder(order, market);
7474
7474
  }
@@ -7787,7 +7787,7 @@ export default class okx extends Exchange {
7787
7787
  const code = this.safeString(response, 'code');
7788
7788
  if ((code !== '0') && (code !== '2')) { // 2 means that bulk operation partially succeeded
7789
7789
  const feedback = this.id + ' ' + body;
7790
- const data = this.safeValue(response, 'data', []);
7790
+ const data = this.safeList(response, 'data', []);
7791
7791
  for (let i = 0; i < data.length; i++) {
7792
7792
  const error = data[i];
7793
7793
  const errorCode = this.safeString(error, 'sCode');
@@ -143,6 +143,11 @@ export default class coinbase extends coinbaseRest {
143
143
  // "low_52_w": "15460",
144
144
  // "high_52_w": "48240",
145
145
  // "price_percent_chg_24_h": "-4.15775596190603"
146
+ // new as of 2024-04-12
147
+ // "best_bid":"21835.29",
148
+ // "best_bid_quantity": "0.02000000",
149
+ // "best_ask":"23011.18",
150
+ // "best_ask_quantity": "0.01500000"
146
151
  // }
147
152
  // ]
148
153
  // }
@@ -168,6 +173,11 @@ export default class coinbase extends coinbaseRest {
168
173
  // "low_52_w": "0.04908",
169
174
  // "high_52_w": "0.1801",
170
175
  // "price_percent_chg_24_h": "0.50177456859626"
176
+ // new as of 2024-04-12
177
+ // "best_bid":"0.07989",
178
+ // "best_bid_quantity": "500.0",
179
+ // "best_ask":"0.08308",
180
+ // "best_ask_quantity": "300.0"
171
181
  // }
172
182
  // ]
173
183
  // }
@@ -189,6 +199,9 @@ export default class coinbase extends coinbaseRest {
189
199
  const messageHash = channel + '::' + wsMarketId;
190
200
  newTickers.push(result);
191
201
  client.resolve(result, messageHash);
202
+ if (messageHash.endsWith('USD')) {
203
+ client.resolve(result, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
204
+ }
192
205
  }
193
206
  }
194
207
  const messageHashes = this.findMessageHashes(client, 'ticker_batch::');
@@ -200,6 +213,9 @@ export default class coinbase extends coinbaseRest {
200
213
  const tickers = this.filterByArray(newTickers, 'symbol', symbols);
201
214
  if (!this.isEmpty(tickers)) {
202
215
  client.resolve(tickers, messageHash);
216
+ if (messageHash.endsWith('USD')) {
217
+ client.resolve(tickers, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
218
+ }
203
219
  }
204
220
  }
205
221
  return message;
@@ -216,6 +232,11 @@ export default class coinbase extends coinbaseRest {
216
232
  // "low_52_w": "0.04908",
217
233
  // "high_52_w": "0.1801",
218
234
  // "price_percent_chg_24_h": "0.50177456859626"
235
+ // new as of 2024-04-12
236
+ // "best_bid":"0.07989",
237
+ // "best_bid_quantity": "500.0",
238
+ // "best_ask":"0.08308",
239
+ // "best_ask_quantity": "300.0"
219
240
  // }
220
241
  //
221
242
  const marketId = this.safeString(ticker, 'product_id');
@@ -228,10 +249,10 @@ export default class coinbase extends coinbaseRest {
228
249
  'datetime': this.iso8601(timestamp),
229
250
  'high': this.safeString(ticker, 'high_24_h'),
230
251
  'low': this.safeString(ticker, 'low_24_h'),
231
- 'bid': undefined,
232
- 'bidVolume': undefined,
233
- 'ask': undefined,
234
- 'askVolume': undefined,
252
+ 'bid': this.safeString(ticker, 'best_bid'),
253
+ 'bidVolume': this.safeString(ticker, 'best_bid_quantity'),
254
+ 'ask': this.safeString(ticker, 'best_ask'),
255
+ 'askVolume': this.safeString(ticker, 'best_ask_quantity'),
235
256
  'vwap': undefined,
236
257
  'open': undefined,
237
258
  'close': last,
@@ -349,6 +370,9 @@ export default class coinbase extends coinbaseRest {
349
370
  }
350
371
  }
351
372
  client.resolve(tradesArray, messageHash);
373
+ if (marketId.endsWith('USD')) {
374
+ client.resolve(tradesArray, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
375
+ }
352
376
  return message;
353
377
  }
354
378
  handleOrder(client, message) {
@@ -404,6 +428,9 @@ export default class coinbase extends coinbaseRest {
404
428
  const marketId = marketIds[i];
405
429
  const messageHash = 'user::' + marketId;
406
430
  client.resolve(this.orders, messageHash);
431
+ if (messageHash.endsWith('USD')) {
432
+ client.resolve(this.orders, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
433
+ }
407
434
  }
408
435
  client.resolve(this.orders, 'user');
409
436
  return message;
@@ -516,6 +543,9 @@ export default class coinbase extends coinbaseRest {
516
543
  orderbook['datetime'] = undefined;
517
544
  orderbook['symbol'] = symbol;
518
545
  client.resolve(orderbook, messageHash);
546
+ if (messageHash.endsWith('USD')) {
547
+ client.resolve(orderbook, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
548
+ }
519
549
  }
520
550
  else if (type === 'update') {
521
551
  const orderbook = this.orderbooks[symbol];
@@ -524,6 +554,9 @@ export default class coinbase extends coinbaseRest {
524
554
  orderbook['timestamp'] = this.parse8601(datetime);
525
555
  orderbook['symbol'] = symbol;
526
556
  client.resolve(orderbook, messageHash);
557
+ if (messageHash.endsWith('USD')) {
558
+ client.resolve(orderbook, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
559
+ }
527
560
  }
528
561
  }
529
562
  return message;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccxt",
3
- "version": "4.2.94",
3
+ "version": "4.2.96",
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
@@ -1041,6 +1041,7 @@
1041
1041
  "latoken": {
1042
1042
  "skipMethods":{
1043
1043
  "loadMarkets": {
1044
+ "precision": "messed just for one pair https://app.travis-ci.com/github/ccxt/ccxt/builds/269924468#L4006",
1044
1045
  "currency": "messed",
1045
1046
  "currencyIdAndCode": "messed"
1046
1047
  },
@@ -1247,6 +1248,7 @@
1247
1248
  "currencyIdAndCode": "some currencies does not exist in currencies"
1248
1249
  },
1249
1250
  "fetchCurrencies": {
1251
+ "currencyIdAndCode": "https://app.travis-ci.com/github/ccxt/ccxt/builds/269956260#L4357",
1250
1252
  "withdraw": "undefined",
1251
1253
  "deposit": "undefined",
1252
1254
  "networks": "networks key is missing",