ccxt 4.2.94 → 4.2.95

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.
@@ -13427,74 +13427,37 @@ __webpack_require__.r(__webpack_exports__);
13427
13427
  /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
13428
13428
  /* harmony export */ });
13429
13429
  /* eslint-disable max-classes-per-file */
13430
- // import { errorHierarchy } from './errorHierarchy.js';
13431
- // Commented out since I'm not sure this is mandatory anymore
13432
- // and does not work out of the box with esm
13433
- // /* ------------------------------------------------------------------------ */
13434
- // function subclass (BaseClass, classes, namespace = {}) {
13435
- // for (const [className, subclasses] of Object.entries (classes)) {
13436
- // const Class = Object.assign (namespace, {
13437
- // /* By creating a named property, we trick compiler to assign our class constructor function a name.
13438
- // Otherwise, all our error constructors would be shown as [Function: Error] in the debugger! And
13439
- // the super-useful `e.constructor.name` magic wouldn't work — we then would have no chance to
13440
- // obtain a error type string from an error instance programmatically! */
13441
- // [className]: class extends BaseClass {
13442
- // constructor (message) {
13443
- // super (message)
13444
- // /* A workaround to make `instanceof` work on custom Error classes in transpiled ES5.
13445
- // See my blog post for the explanation of this hack:
13446
- // https://medium.com/@xpl/javascript-deriving-from-error-properly-8d2f8f315801 */
13447
- // this.constructor = Class
13448
- // this.__proto__ = Class.prototype
13449
- // this.name = className
13450
- // this.message = message
13451
- // // https://github.com/Microsoft/TypeScript/wiki/FAQ#why-doesnt-extending-built-ins-like-error-array-and-map-work
13452
- // Object.setPrototypeOf (this, Class.prototype)
13453
- // }
13454
- // }
13455
- // })[className]
13456
- // subclass (Class, subclasses, namespace)
13457
- // }
13458
- // return namespace
13459
- // }
13460
13430
  class BaseError extends Error {
13461
13431
  constructor(message) {
13462
13432
  super(message);
13463
13433
  this.name = 'BaseError';
13464
13434
  }
13465
13435
  }
13466
- // Exchange Error errors
13467
- class ExchangeError extends Error {
13436
+ class ExchangeError extends BaseError {
13468
13437
  constructor(message) {
13469
13438
  super(message);
13470
13439
  this.name = 'ExchangeError';
13471
13440
  }
13472
13441
  }
13473
- class ExchangeClosedByUser extends Error {
13474
- constructor(message) {
13475
- super(message);
13476
- this.name = 'ExchangeClosedByUser';
13477
- }
13478
- }
13479
13442
  class AuthenticationError extends ExchangeError {
13480
13443
  constructor(message) {
13481
13444
  super(message);
13482
13445
  this.name = 'AuthenticationError';
13483
13446
  }
13484
13447
  }
13485
- class PermissionDenied extends ExchangeError {
13448
+ class PermissionDenied extends AuthenticationError {
13486
13449
  constructor(message) {
13487
13450
  super(message);
13488
13451
  this.name = 'PermissionDenied';
13489
13452
  }
13490
13453
  }
13491
- class AccountNotEnabled extends ExchangeError {
13454
+ class AccountNotEnabled extends PermissionDenied {
13492
13455
  constructor(message) {
13493
13456
  super(message);
13494
13457
  this.name = 'AccountNotEnabled';
13495
13458
  }
13496
13459
  }
13497
- class AccountSuspended extends ExchangeError {
13460
+ class AccountSuspended extends AuthenticationError {
13498
13461
  constructor(message) {
13499
13462
  super(message);
13500
13463
  this.name = 'AccountSuspended';
@@ -13512,16 +13475,16 @@ class BadRequest extends ExchangeError {
13512
13475
  this.name = 'BadRequest';
13513
13476
  }
13514
13477
  }
13515
- class OperationRejected extends ExchangeError {
13478
+ class BadSymbol extends BadRequest {
13516
13479
  constructor(message) {
13517
13480
  super(message);
13518
- this.name = 'OperationRejected';
13481
+ this.name = 'BadSymbol';
13519
13482
  }
13520
13483
  }
13521
- class BadSymbol extends BadRequest {
13484
+ class OperationRejected extends ExchangeError {
13522
13485
  constructor(message) {
13523
13486
  super(message);
13524
- this.name = 'BadSymbol';
13487
+ this.name = 'OperationRejected';
13525
13488
  }
13526
13489
  }
13527
13490
  class NoChange extends OperationRejected {
@@ -13542,7 +13505,7 @@ class BadResponse extends ExchangeError {
13542
13505
  this.name = 'BadResponse';
13543
13506
  }
13544
13507
  }
13545
- class NullResponse extends ExchangeError {
13508
+ class NullResponse extends BadResponse {
13546
13509
  constructor(message) {
13547
13510
  super(message);
13548
13511
  this.name = 'NullResponse';
@@ -13572,12 +13535,6 @@ class InvalidOrder extends ExchangeError {
13572
13535
  this.name = 'InvalidOrder';
13573
13536
  }
13574
13537
  }
13575
- class ContractUnavailable extends InvalidOrder {
13576
- constructor(message) {
13577
- super(message);
13578
- this.name = 'ContractUnavailable';
13579
- }
13580
- }
13581
13538
  class OrderNotFound extends InvalidOrder {
13582
13539
  constructor(message) {
13583
13540
  super(message);
@@ -13614,25 +13571,36 @@ class DuplicateOrderId extends InvalidOrder {
13614
13571
  this.name = 'DuplicateOrderId';
13615
13572
  }
13616
13573
  }
13574
+ class ContractUnavailable extends InvalidOrder {
13575
+ constructor(message) {
13576
+ super(message);
13577
+ this.name = 'ContractUnavailable';
13578
+ }
13579
+ }
13617
13580
  class NotSupported extends ExchangeError {
13618
13581
  constructor(message) {
13619
13582
  super(message);
13620
13583
  this.name = 'NotSupported';
13621
13584
  }
13622
13585
  }
13623
- class OperationFailed extends BaseError {
13586
+ class ProxyError extends ExchangeError {
13624
13587
  constructor(message) {
13625
13588
  super(message);
13626
- this.name = 'OperationFailed';
13589
+ this.name = 'ProxyError';
13627
13590
  }
13628
13591
  }
13629
- class ProxyError extends ExchangeError {
13592
+ class ExchangeClosedByUser extends ExchangeError {
13593
+ constructor(message) {
13594
+ super(message);
13595
+ this.name = 'ExchangeClosedByUser';
13596
+ }
13597
+ }
13598
+ class OperationFailed extends BaseError {
13630
13599
  constructor(message) {
13631
13600
  super(message);
13632
13601
  this.name = 'OperationFailed';
13633
13602
  }
13634
13603
  }
13635
- // Network error
13636
13604
  class NetworkError extends OperationFailed {
13637
13605
  constructor(message) {
13638
13606
  super(message);
@@ -13675,16 +13643,8 @@ class RequestTimeout extends NetworkError {
13675
13643
  this.name = 'RequestTimeout';
13676
13644
  }
13677
13645
  }
13678
- /* ------------------------------------------------------------------------ */
13679
- // export default subclass (
13680
- // // Root class
13681
- // Error,
13682
- // // Derived class hierarchy
13683
- // errorHierarchy
13684
- // )
13685
- const errors = { BaseError, ExchangeClosedByUser, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending, ContractUnavailable, NoChange, OperationRejected, OperationFailed, ProxyError };
13686
13646
 
13687
- /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (errors);
13647
+ /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, ProxyError, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout });
13688
13648
 
13689
13649
 
13690
13650
  /***/ }),
@@ -16047,6 +16007,11 @@ class IndexedOrderBook extends OrderBook {
16047
16007
  // Author: github.com/frosty00
16048
16008
  // Email: carlo.revelli@berkeley.edu
16049
16009
  //
16010
+ /**
16011
+ *
16012
+ * @param array
16013
+ * @param x
16014
+ */
16050
16015
  function bisectLeft(array, x) {
16051
16016
  let low = 0;
16052
16017
  let high = array.length - 1;
@@ -70343,6 +70308,12 @@ class bitstamp extends _abstract_bitstamp_js__WEBPACK_IMPORTED_MODULE_0__/* ["de
70343
70308
  'blur_address/': 1,
70344
70309
  'vext_withdrawal/': 1,
70345
70310
  'vext_address/': 1,
70311
+ 'cspr_withdrawal/': 1,
70312
+ 'cspr_address/': 1,
70313
+ 'vchf_withdrawal/': 1,
70314
+ 'vchf_address/': 1,
70315
+ 'veur_withdrawal/': 1,
70316
+ 'veur_address/': 1,
70346
70317
  },
70347
70318
  },
70348
70319
  },
@@ -104462,8 +104433,8 @@ class coinex extends _abstract_coinex_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
104462
104433
  * @method
104463
104434
  * @name coinex#fetchOrderBook
104464
104435
  * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
104465
- * @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot001_market004_market_depth
104466
- * @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http010_market_depth
104436
+ * @see https://docs.coinex.com/api/v2/spot/market/http/list-market-depth
104437
+ * @see https://docs.coinex.com/api/v2/futures/market/http/list-market-depth
104467
104438
  * @param {string} symbol unified symbol of the market to fetch the order book for
104468
104439
  * @param {int} [limit] the maximum amount of order book entries to return
104469
104440
  * @param {object} [params] extra parameters specific to the exchange API endpoint
@@ -104475,65 +104446,71 @@ class coinex extends _abstract_coinex_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
104475
104446
  limit = 20; // default
104476
104447
  }
104477
104448
  const request = {
104478
- 'market': this.marketId(symbol),
104479
- 'merge': '0',
104480
- 'limit': limit.toString(),
104449
+ 'market': market['id'],
104450
+ 'limit': limit,
104451
+ 'interval': '0',
104481
104452
  };
104482
104453
  let response = undefined;
104483
104454
  if (market['swap']) {
104484
- response = await this.v1PerpetualPublicGetMarketDepth(this.extend(request, params));
104455
+ response = await this.v2PublicGetFuturesDepth(this.extend(request, params));
104456
+ //
104457
+ // {
104458
+ // "code": 0,
104459
+ // "data": {
104460
+ // "depth": {
104461
+ // "asks": [
104462
+ // ["70851.94", "0.2119"],
104463
+ // ["70851.95", "0.0004"],
104464
+ // ["70851.96", "0.0004"]
104465
+ // ],
104466
+ // "bids": [
104467
+ // ["70851.93", "1.0314"],
104468
+ // ["70850.93", "0.0021"],
104469
+ // ["70850.42", "0.0306"]
104470
+ // ],
104471
+ // "checksum": 2956436260,
104472
+ // "last": "70851.94",
104473
+ // "updated_at": 1712824003252
104474
+ // },
104475
+ // "is_full": true,
104476
+ // "market": "BTCUSDT"
104477
+ // },
104478
+ // "message": "OK"
104479
+ // }
104480
+ //
104485
104481
  }
104486
104482
  else {
104487
- response = await this.v1PublicGetMarketDepth(this.extend(request, params));
104483
+ response = await this.v2PublicGetSpotDepth(this.extend(request, params));
104484
+ //
104485
+ // {
104486
+ // "code": 0,
104487
+ // "data": {
104488
+ // "depth": {
104489
+ // "asks": [
104490
+ // ["70875.31", "0.28670282"],
104491
+ // ["70875.32", "0.31008114"],
104492
+ // ["70875.42", "0.05876653"]
104493
+ // ],
104494
+ // "bids": [
104495
+ // ["70855.3", "0.00632222"],
104496
+ // ["70855.29", "0.36216834"],
104497
+ // ["70855.17", "0.10166802"]
104498
+ // ],
104499
+ // "checksum": 2313816665,
104500
+ // "last": "70857.19",
104501
+ // "updated_at": 1712823790987
104502
+ // },
104503
+ // "is_full": true,
104504
+ // "market": "BTCUSDT"
104505
+ // },
104506
+ // "message": "OK"
104507
+ // }
104508
+ //
104488
104509
  }
104489
- //
104490
- // Spot
104491
- //
104492
- // {
104493
- // "code": 0,
104494
- // "data": {
104495
- // "asks": [
104496
- // ["41056.33", "0.31727613"],
104497
- // ["41056.34", "1.05657294"],
104498
- // ["41056.35", "0.02346648"]
104499
- // ],
104500
- // "bids": [
104501
- // ["41050.61", "0.40618608"],
104502
- // ["41046.98", "0.13800000"],
104503
- // ["41046.56", "0.22579234"]
104504
- // ],
104505
- // "last": "41050.61",
104506
- // "time": 1650573220346
104507
- // },
104508
- // "message": "OK"
104509
- // }
104510
- //
104511
- // Swap
104512
- //
104513
- // {
104514
- // "code": 0,
104515
- // "data": {
104516
- // "asks": [
104517
- // ["40620.90", "0.0384"],
104518
- // ["40625.50", "0.0219"],
104519
- // ["40625.90", "0.3506"]
104520
- // ],
104521
- // "bids": [
104522
- // ["40620.89", "19.6861"],
104523
- // ["40620.80", "0.0012"],
104524
- // ["40619.87", "0.0365"]
104525
- // ],
104526
- // "last": "40620.89",
104527
- // "time": 1650587672406,
104528
- // "sign_price": "40619.32",
104529
- // "index_price": "40609.93"
104530
- // },
104531
- // "message": "OK"
104532
- // }
104533
- //
104534
- const result = this.safeValue(response, 'data', {});
104535
- const timestamp = this.safeInteger(result, 'time');
104536
- return this.parseOrderBook(result, symbol, timestamp);
104510
+ const data = this.safeDict(response, 'data', {});
104511
+ const depth = this.safeDict(data, 'depth', {});
104512
+ const timestamp = this.safeInteger(depth, 'updated_at');
104513
+ return this.parseOrderBook(depth, symbol, timestamp);
104537
104514
  }
104538
104515
  parseTrade(trade, market = undefined) {
104539
104516
  //
@@ -145749,7 +145726,8 @@ class gemini extends _abstract_gemini_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
145749
145726
  for (let i = 0; i < quoteQurrencies.length; i++) {
145750
145727
  const quoteCurrency = quoteQurrencies[i];
145751
145728
  if (marketIdWithoutPerp.endsWith(quoteCurrency)) {
145752
- baseId = marketIdWithoutPerp.replace(quoteCurrency, '');
145729
+ const quoteLength = this.parseToInt(-1 * quoteCurrency.length);
145730
+ baseId = marketIdWithoutPerp.slice(0, quoteLength);
145753
145731
  quoteId = quoteCurrency;
145754
145732
  if (isPerp) {
145755
145733
  settleId = quoteCurrency; // always same
@@ -153585,14 +153563,8 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
153585
153563
  'fetchMarkets': {
153586
153564
  'types': {
153587
153565
  'spot': true,
153588
- 'future': {
153589
- 'linear': true,
153590
- 'inverse': true,
153591
- },
153592
- 'swap': {
153593
- 'linear': true,
153594
- 'inverse': true,
153595
- },
153566
+ 'linear': true,
153567
+ 'inverse': true,
153596
153568
  },
153597
153569
  },
153598
153570
  'fetchOHLCV': {
@@ -154259,25 +154231,23 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
154259
154231
  * @param {object} [params] extra parameters specific to the exchange API endpoint
154260
154232
  * @returns {object[]} an array of objects representing market data
154261
154233
  */
154262
- const options = this.safeValue(this.options, 'fetchMarkets', {});
154263
- const types = this.safeValue(options, 'types', {});
154234
+ let types = undefined;
154235
+ [types, params] = this.handleOptionAndParams(params, 'fetchMarkets', 'types', {});
154264
154236
  let allMarkets = [];
154265
154237
  let promises = [];
154266
154238
  const keys = Object.keys(types);
154267
154239
  for (let i = 0; i < keys.length; i++) {
154268
- const type = keys[i];
154269
- const value = this.safeValue(types, type);
154270
- if (value === true) {
154271
- promises.push(this.fetchMarketsByTypeAndSubType(type, undefined, params));
154272
- }
154273
- else if (value) {
154274
- const subKeys = Object.keys(value);
154275
- for (let j = 0; j < subKeys.length; j++) {
154276
- const subType = subKeys[j];
154277
- const subValue = this.safeValue(value, subType);
154278
- if (subValue) {
154279
- promises.push(this.fetchMarketsByTypeAndSubType(type, subType, params));
154280
- }
154240
+ const key = keys[i];
154241
+ if (this.safeBool(types, key)) {
154242
+ if (key === 'spot') {
154243
+ promises.push(this.fetchMarketsByTypeAndSubType('spot', undefined, params));
154244
+ }
154245
+ else if (key === 'linear') {
154246
+ promises.push(this.fetchMarketsByTypeAndSubType(undefined, 'linear', params));
154247
+ }
154248
+ else if (key === 'inverse') {
154249
+ promises.push(this.fetchMarketsByTypeAndSubType('swap', 'inverse', params));
154250
+ promises.push(this.fetchMarketsByTypeAndSubType('future', 'inverse', params));
154281
154251
  }
154282
154252
  }
154283
154253
  }
@@ -154288,35 +154258,25 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
154288
154258
  return allMarkets;
154289
154259
  }
154290
154260
  async fetchMarketsByTypeAndSubType(type, subType, params = {}) {
154291
- const query = this.omit(params, ['type', 'subType']);
154292
- const spot = (type === 'spot');
154293
- const contract = (type !== 'spot');
154294
- const future = (type === 'future');
154295
- const swap = (type === 'swap');
154296
- let linear = undefined;
154297
- let inverse = undefined;
154261
+ const isSpot = (type === 'spot');
154298
154262
  const request = {};
154299
154263
  let response = undefined;
154300
- if (contract) {
154301
- linear = (subType === 'linear');
154302
- inverse = (subType === 'inverse');
154303
- if (linear) {
154304
- if (future) {
154305
- request['business_type'] = 'futures';
154306
- }
154307
- response = await this.contractPublicGetLinearSwapApiV1SwapContractInfo(this.extend(request, query));
154264
+ if (!isSpot) {
154265
+ if (subType === 'linear') {
154266
+ request['business_type'] = 'all'; // override default to fetch all linear markets
154267
+ response = await this.contractPublicGetLinearSwapApiV1SwapContractInfo(this.extend(request, params));
154308
154268
  }
154309
- else if (inverse) {
154310
- if (future) {
154311
- response = await this.contractPublicGetApiV1ContractContractInfo(this.extend(request, query));
154269
+ else if (subType === 'inverse') {
154270
+ if (type === 'future') {
154271
+ response = await this.contractPublicGetApiV1ContractContractInfo(this.extend(request, params));
154312
154272
  }
154313
- else if (swap) {
154314
- response = await this.contractPublicGetSwapApiV1SwapContractInfo(this.extend(request, query));
154273
+ else if (type === 'swap') {
154274
+ response = await this.contractPublicGetSwapApiV1SwapContractInfo(this.extend(request, params));
154315
154275
  }
154316
154276
  }
154317
154277
  }
154318
154278
  else {
154319
- response = await this.spotPublicGetV1CommonSymbols(this.extend(request, query));
154279
+ response = await this.spotPublicGetV1CommonSymbols(this.extend(request, params));
154320
154280
  }
154321
154281
  //
154322
154282
  // spot
@@ -154356,75 +154316,58 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
154356
154316
  // ]
154357
154317
  // }
154358
154318
  //
154359
- // inverse future
154319
+ // inverse (swap & future)
154360
154320
  //
154361
154321
  // {
154362
154322
  // "status":"ok",
154363
154323
  // "data":[
154364
154324
  // {
154365
154325
  // "symbol":"BTC",
154366
- // "contract_code":"BTC211126",
154367
- // "contract_type":"this_week",
154368
- // "contract_size":100.000000000000000000,
154369
- // "price_tick":0.010000000000000000,
154370
- // "delivery_date":"20211126",
154371
- // "delivery_time":"1637913600000",
154326
+ // "contract_code":"BTC211126", /// BTC-USD in swap
154327
+ // "contract_type":"this_week", // only in future
154328
+ // "contract_size":100,
154329
+ // "price_tick":0.1,
154330
+ // "delivery_date":"20211126", // only in future
154331
+ // "delivery_time":"1637913600000", // empty in swap
154372
154332
  // "create_date":"20211112",
154373
154333
  // "contract_status":1,
154374
- // "settlement_time":"1637481600000"
154334
+ // "settlement_time":"1637481600000" // only in future
154335
+ // "settlement_date":"16xxxxxxxxxxx" // only in swap
154375
154336
  // },
154337
+ // ...
154376
154338
  // ],
154377
154339
  // "ts":1637474595140
154378
154340
  // }
154379
154341
  //
154380
- // linear futures
154342
+ // linear (swap & future)
154381
154343
  //
154382
154344
  // {
154383
154345
  // "status":"ok",
154384
154346
  // "data":[
154385
154347
  // {
154386
154348
  // "symbol":"BTC",
154387
- // "contract_code":"BTC-USDT-211231",
154388
- // "contract_size":0.001000000000000000,
154389
- // "price_tick":0.100000000000000000,
154390
- // "delivery_date":"20211231",
154391
- // "delivery_time":"1640937600000",
154349
+ // "contract_code":"BTC-USDT-211231", // or "BTC-USDT" in swap
154350
+ // "contract_size":0.001,
154351
+ // "price_tick":0.1,
154352
+ // "delivery_date":"20211231", // empty in swap
154353
+ // "delivery_time":"1640937600000", // empty in swap
154392
154354
  // "create_date":"20211228",
154393
154355
  // "contract_status":1,
154394
154356
  // "settlement_date":"1640764800000",
154395
- // "support_margin_mode":"cross",
154396
- // "business_type":"futures",
154357
+ // "support_margin_mode":"cross", // "all" or "cross"
154358
+ // "business_type":"futures", // "swap" or "futures"
154397
154359
  // "pair":"BTC-USDT",
154398
- // "contract_type":"this_week" // next_week, quarter
154399
- // },
154360
+ // "contract_type":"this_week", // "swap", "this_week", "next_week", "quarter"
154361
+ // "trade_partition":"USDT",
154362
+ // }
154400
154363
  // ],
154401
154364
  // "ts":1640736207263
154402
154365
  // }
154403
154366
  //
154404
- // swaps
154405
- //
154406
- // {
154407
- // "status":"ok",
154408
- // "data":[
154409
- // {
154410
- // "symbol":"BTC",
154411
- // "contract_code":"BTC-USDT",
154412
- // "contract_size":0.001000000000000000,
154413
- // "price_tick":0.100000000000000000,
154414
- // "delivery_time":"",
154415
- // "create_date":"20201021",
154416
- // "contract_status":1,
154417
- // "settlement_date":"1637481600000",
154418
- // "support_margin_mode":"all", // isolated
154419
- // },
154420
- // ],
154421
- // "ts":1637474774467
154422
- // }
154423
- //
154424
- const markets = this.safeValue(response, 'data', []);
154367
+ const markets = this.safeList(response, 'data', []);
154425
154368
  const numMarkets = markets.length;
154426
154369
  if (numMarkets < 1) {
154427
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.NetworkError(this.id + ' fetchMarkets() returned an empty response: ' + this.json(markets));
154370
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.OperationFailed(this.id + ' fetchMarkets() returned an empty response: ' + this.json(response));
154428
154371
  }
154429
154372
  const result = [];
154430
154373
  for (let i = 0; i < markets.length; i++) {
@@ -154434,16 +154377,31 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
154434
154377
  let settleId = undefined;
154435
154378
  let id = undefined;
154436
154379
  let lowercaseId = undefined;
154380
+ const contract = ('contract_code' in market);
154381
+ const spot = !contract;
154382
+ let swap = false;
154383
+ let future = false;
154384
+ let linear = undefined;
154385
+ let inverse = undefined;
154386
+ // check if parsed market is contract
154437
154387
  if (contract) {
154438
154388
  id = this.safeString(market, 'contract_code');
154439
154389
  lowercaseId = id.toLowerCase();
154390
+ const delivery_date = this.safeString(market, 'delivery_date');
154391
+ const business_type = this.safeString(market, 'business_type');
154392
+ future = delivery_date !== undefined;
154393
+ swap = !future;
154394
+ linear = business_type !== undefined;
154395
+ inverse = !linear;
154440
154396
  if (swap) {
154397
+ type = 'swap';
154441
154398
  const parts = id.split('-');
154442
154399
  baseId = this.safeStringLower(market, 'symbol');
154443
154400
  quoteId = this.safeStringLower(parts, 1);
154444
154401
  settleId = inverse ? baseId : quoteId;
154445
154402
  }
154446
154403
  else if (future) {
154404
+ type = 'future';
154447
154405
  baseId = this.safeStringLower(market, 'symbol');
154448
154406
  if (inverse) {
154449
154407
  quoteId = 'USD';
@@ -154458,6 +154416,7 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
154458
154416
  }
154459
154417
  }
154460
154418
  else {
154419
+ type = 'spot';
154461
154420
  baseId = this.safeString(market, 'base-currency');
154462
154421
  quoteId = this.safeString(market, 'quote-currency');
154463
154422
  id = baseId + quoteId;
@@ -154592,6 +154551,45 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
154592
154551
  }
154593
154552
  return result;
154594
154553
  }
154554
+ tryGetSymbolFromFutureMarkets(symbolOrMarketId) {
154555
+ if (symbolOrMarketId in this.markets) {
154556
+ return symbolOrMarketId;
154557
+ }
154558
+ // only on "future" market type (inverse & linear), market-id differs between "fetchMarkets" and "fetchTicker"
154559
+ // so we have to create a mapping
154560
+ // - market-id from fetchMarkts: `BTC-USDT-240419` (linear future) or `BTC240412` (inverse future)
154561
+ // - market-id from fetchTciker[s]: `BTC-USDT-CW` (linear future) or `BTC_CW` (inverse future)
154562
+ if (!('futureMarketIdsForSymbols' in this.options)) {
154563
+ this.options['futureMarketIdsForSymbols'] = {};
154564
+ }
154565
+ const futureMarketIdsForSymbols = this.safeDict(this.options, 'futureMarketIdsForSymbols', {});
154566
+ if (symbolOrMarketId in futureMarketIdsForSymbols) {
154567
+ return futureMarketIdsForSymbols[symbolOrMarketId];
154568
+ }
154569
+ const futureMarkets = this.filterBy(this.markets, 'future', true);
154570
+ const futuresCharsMaps = {
154571
+ 'this_week': 'CW',
154572
+ 'next_week': 'NW',
154573
+ 'quarter': 'CQ',
154574
+ 'next_quarter': 'NQ',
154575
+ };
154576
+ for (let i = 0; i < futureMarkets.length; i++) {
154577
+ const market = futureMarkets[i];
154578
+ const info = this.safeValue(market, 'info', {});
154579
+ const contractType = this.safeString(info, 'contract_type');
154580
+ const contractSuffix = futuresCharsMaps[contractType];
154581
+ // see comment on formats a bit above
154582
+ const constructedId = market['linear'] ? market['base'] + '-' + market['quote'] + '-' + contractSuffix : market['base'] + '_' + contractSuffix;
154583
+ if (constructedId === symbolOrMarketId) {
154584
+ const symbol = market['symbol'];
154585
+ this.options['futureMarketIdsForSymbols'][symbolOrMarketId] = symbol;
154586
+ return symbol;
154587
+ }
154588
+ }
154589
+ // if not found, just save it to avoid unnecessary future iterations
154590
+ this.options['futureMarketIdsForSymbols'][symbolOrMarketId] = symbolOrMarketId;
154591
+ return symbolOrMarketId;
154592
+ }
154595
154593
  parseTicker(ticker, market = undefined) {
154596
154594
  //
154597
154595
  // fetchTicker
@@ -154639,7 +154637,8 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
154639
154637
  // }
154640
154638
  //
154641
154639
  const marketId = this.safeString2(ticker, 'symbol', 'contract_code');
154642
- const symbol = this.safeSymbol(marketId, market);
154640
+ let symbol = this.safeSymbol(marketId, market);
154641
+ symbol = this.tryGetSymbolFromFutureMarkets(symbol);
154643
154642
  const timestamp = this.safeInteger2(ticker, 'ts', 'quoteTime');
154644
154643
  let bid = undefined;
154645
154644
  let bidVolume = undefined;
@@ -154782,7 +154781,7 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
154782
154781
  * @see https://huobiapi.github.io/docs/usdt_swap/v1/en/#general-get-a-batch-of-market-data-overview
154783
154782
  * @see https://huobiapi.github.io/docs/dm/v1/en/#get-a-batch-of-market-data-overview
154784
154783
  * @see https://huobiapi.github.io/docs/coin_margined_swap/v1/en/#get-a-batch-of-market-data-overview-v2
154785
- * @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
154784
+ * @param {string[]} [symbols] unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
154786
154785
  * @param {object} [params] extra parameters specific to the exchange API endpoint
154787
154786
  * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
154788
154787
  */
@@ -154793,22 +154792,30 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
154793
154792
  if (first !== undefined) {
154794
154793
  market = this.market(first);
154795
154794
  }
154795
+ const isSubTypeRequested = ('subType' in params) || ('business_type' in params);
154796
154796
  let type = undefined;
154797
154797
  let subType = undefined;
154798
154798
  [type, params] = this.handleMarketTypeAndParams('fetchTickers', market, params);
154799
154799
  [subType, params] = this.handleSubTypeAndParams('fetchTickers', market, params);
154800
154800
  const request = {};
154801
+ const isSpot = (type === 'spot');
154801
154802
  const future = (type === 'future');
154802
154803
  const swap = (type === 'swap');
154803
154804
  const linear = (subType === 'linear');
154804
154805
  const inverse = (subType === 'inverse');
154805
- params = this.omit(params, ['type', 'subType']);
154806
154806
  let response = undefined;
154807
- if (future || swap) {
154807
+ if (!isSpot || isSubTypeRequested) {
154808
154808
  if (linear) {
154809
+ // independently of type, supports calling all linear symbols i.e. fetchTickers(undefined, {subType:'linear'})
154809
154810
  if (future) {
154810
154811
  request['business_type'] = 'futures';
154811
154812
  }
154813
+ else if (swap) {
154814
+ request['business_type'] = 'swap';
154815
+ }
154816
+ else {
154817
+ request['business_type'] = 'all';
154818
+ }
154812
154819
  response = await this.contractPublicGetLinearSwapExMarketDetailBatchMerged(this.extend(request, params));
154813
154820
  }
154814
154821
  else if (inverse) {
@@ -154818,6 +154825,12 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
154818
154825
  else if (swap) {
154819
154826
  response = await this.contractPublicGetSwapExMarketDetailBatchMerged(this.extend(request, params));
154820
154827
  }
154828
+ else {
154829
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.NotSupported(this.id + ' fetchTickers() you have to set params["type"] to either "swap" or "future" for inverse contracts');
154830
+ }
154831
+ }
154832
+ else {
154833
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.NotSupported(this.id + ' fetchTickers() you have to set params["subType"] to either "linear" or "inverse" for contracts');
154821
154834
  }
154822
154835
  }
154823
154836
  else {
@@ -154873,42 +154886,9 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
154873
154886
  // "ts":1637504679376
154874
154887
  // }
154875
154888
  //
154876
- const tickers = this.safeValue2(response, 'data', 'ticks', []);
154877
- const timestamp = this.safeInteger(response, 'ts');
154878
- const result = {};
154879
- for (let i = 0; i < tickers.length; i++) {
154880
- const ticker = this.parseTicker(tickers[i]);
154881
- // the market ids for linear futures are non-standard and differ from all the other endpoints
154882
- // we are doing a linear-matching here
154883
- if (future && linear) {
154884
- for (let j = 0; j < this.symbols.length; j++) {
154885
- const symbolInner = this.symbols[j];
154886
- const marketInner = this.market(symbolInner);
154887
- const contractType = this.safeString(marketInner['info'], 'contract_type');
154888
- if ((contractType === 'this_week') && (ticker['symbol'] === (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-CW'))) {
154889
- ticker['symbol'] = marketInner['symbol'];
154890
- break;
154891
- }
154892
- else if ((contractType === 'next_week') && (ticker['symbol'] === (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-NW'))) {
154893
- ticker['symbol'] = marketInner['symbol'];
154894
- break;
154895
- }
154896
- else if ((contractType === 'this_quarter') && (ticker['symbol'] === (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-CQ'))) {
154897
- ticker['symbol'] = marketInner['symbol'];
154898
- break;
154899
- }
154900
- else if ((contractType === 'next_quarter') && (ticker['symbol'] === (marketInner['baseId'] + '-' + marketInner['quoteId'] + '-NQ'))) {
154901
- ticker['symbol'] = marketInner['symbol'];
154902
- break;
154903
- }
154904
- }
154905
- }
154906
- const symbol = ticker['symbol'];
154907
- ticker['timestamp'] = timestamp;
154908
- ticker['datetime'] = this.iso8601(timestamp);
154909
- result[symbol] = ticker;
154910
- }
154911
- return this.filterByArrayTickers(result, 'symbol', symbols);
154889
+ const rawTickers = this.safeList2(response, 'data', 'ticks', []);
154890
+ const tickers = this.parseTickers(rawTickers, symbols, params);
154891
+ return this.filterByArrayTickers(tickers, 'symbol', symbols);
154912
154892
  }
154913
154893
  async fetchLastPrices(symbols = undefined, params = {}) {
154914
154894
  /**
@@ -154918,7 +154898,7 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
154918
154898
  * @see https://www.htx.com/en-us/opend/newApiPages/?id=8cb81024-77b5-11ed-9966-0242ac110003 linear swap & linear future
154919
154899
  * @see https://www.htx.com/en-us/opend/newApiPages/?id=28c2e8fc-77ae-11ed-9966-0242ac110003 inverse future
154920
154900
  * @see https://www.htx.com/en-us/opend/newApiPages/?id=5d517ef5-77b6-11ed-9966-0242ac110003 inverse swap
154921
- * @param {string[]|undefined} symbols unified symbols of the markets to fetch the last prices
154901
+ * @param {string[]} [symbols] unified symbols of the markets to fetch the last prices
154922
154902
  * @param {object} [params] extra parameters specific to the exchange API endpoint
154923
154903
  * @returns {object} a dictionary of lastprices structures
154924
154904
  */
@@ -208251,7 +208231,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
208251
208231
  return super.handleMarketTypeAndParams(methodName, market, params);
208252
208232
  }
208253
208233
  convertToInstrumentType(type) {
208254
- const exchangeTypes = this.safeValue(this.options, 'exchangeType', {});
208234
+ const exchangeTypes = this.safeDict(this.options, 'exchangeType', {});
208255
208235
  return this.safeString(exchangeTypes, type, type);
208256
208236
  }
208257
208237
  createExpiredOptionMarket(symbol) {
@@ -210055,7 +210035,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
210055
210035
  const side = this.safeString(rawOrder, 'side');
210056
210036
  const amount = this.safeValue(rawOrder, 'amount');
210057
210037
  const price = this.safeValue(rawOrder, 'price');
210058
- const orderParams = this.safeValue(rawOrder, 'params', {});
210038
+ const orderParams = this.safeDict(rawOrder, 'params', {});
210059
210039
  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
210060
210040
  const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, extendedParams);
210061
210041
  ordersRequests.push(orderRequest);
@@ -210244,8 +210224,8 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
210244
210224
  // "msg": ""
210245
210225
  // }
210246
210226
  //
210247
- const data = this.safeValue(response, 'data', []);
210248
- const first = this.safeValue(data, 0);
210227
+ const data = this.safeList(response, 'data', []);
210228
+ const first = this.safeDict(data, 0, {});
210249
210229
  const order = this.parseOrder(first, market);
210250
210230
  order['type'] = type;
210251
210231
  order['side'] = side;
@@ -211444,7 +211424,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
211444
211424
  if (paginate) {
211445
211425
  return await this.fetchPaginatedCallDynamic('fetchLedger', code, since, limit, params);
211446
211426
  }
211447
- const options = this.safeValue(this.options, 'fetchLedger', {});
211427
+ const options = this.safeDict(this.options, 'fetchLedger', {});
211448
211428
  let method = this.safeString(options, 'method');
211449
211429
  method = this.safeString(params, 'method', method);
211450
211430
  params = this.omit(params, 'method');
@@ -211773,7 +211753,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
211773
211753
  // ]
211774
211754
  // }
211775
211755
  //
211776
- const data = this.safeValue(response, 'data', []);
211756
+ const data = this.safeList(response, 'data', []);
211777
211757
  const filtered = this.filterBy(data, 'selected', true);
211778
211758
  const parsed = this.parseDepositAddresses(filtered, [currency['code']], false);
211779
211759
  return this.indexBy(parsed, 'network');
@@ -211847,7 +211827,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
211847
211827
  };
211848
211828
  let network = this.safeString(params, 'network'); // this line allows the user to specify either ERC20 or ETH
211849
211829
  if (network !== undefined) {
211850
- const networks = this.safeValue(this.options, 'networks', {});
211830
+ const networks = this.safeDict(this.options, 'networks', {});
211851
211831
  network = this.safeString(networks, network.toUpperCase(), network); // handle ETH>ERC20 alias
211852
211832
  request['chain'] = currency['id'] + '-' + network;
211853
211833
  params = this.omit(params, 'network');
@@ -211856,7 +211836,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
211856
211836
  if (fee === undefined) {
211857
211837
  const currencies = await this.fetchCurrencies();
211858
211838
  this.currencies = this.deepExtend(this.currencies, currencies);
211859
- const targetNetwork = this.safeValue(currency['networks'], this.networkIdToCode(network), {});
211839
+ const targetNetwork = this.safeDict(currency['networks'], this.networkIdToCode(network), {});
211860
211840
  fee = this.safeString(targetNetwork, 'fee');
211861
211841
  if (fee === undefined) {
211862
211842
  throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.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.');
@@ -211878,7 +211858,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
211878
211858
  // ]
211879
211859
  // }
211880
211860
  //
211881
- const data = this.safeValue(response, 'data', []);
211861
+ const data = this.safeList(response, 'data', []);
211882
211862
  const transaction = this.safeDict(data, 0);
211883
211863
  return this.parseTransaction(transaction, currency);
211884
211864
  }
@@ -212103,7 +212083,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
212103
212083
  // "msg": ''
212104
212084
  // }
212105
212085
  //
212106
- const data = this.safeValue(response, 'data');
212086
+ const data = this.safeList(response, 'data', []);
212107
212087
  const withdrawal = this.safeDict(data, 0, {});
212108
212088
  return this.parseTransaction(withdrawal);
212109
212089
  }
@@ -212390,8 +212370,8 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
212390
212370
  // ]
212391
212371
  // }
212392
212372
  //
212393
- const data = this.safeValue(response, 'data', []);
212394
- const position = this.safeValue(data, 0);
212373
+ const data = this.safeList(response, 'data', []);
212374
+ const position = this.safeDict(data, 0);
212395
212375
  if (position === undefined) {
212396
212376
  return undefined;
212397
212377
  }
@@ -212427,7 +212407,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
212427
212407
  request['instId'] = marketIds.join(',');
212428
212408
  }
212429
212409
  }
212430
- const fetchPositionsOptions = this.safeValue(this.options, 'fetchPositions', {});
212410
+ const fetchPositionsOptions = this.safeDict(this.options, 'fetchPositions', {});
212431
212411
  const method = this.safeString(fetchPositionsOptions, 'method', 'privateGetAccountPositions');
212432
212412
  let response = undefined;
212433
212413
  if (method === 'privateGetAccountPositionsHistory') {
@@ -212482,7 +212462,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
212482
212462
  // ]
212483
212463
  // }
212484
212464
  //
212485
- const positions = this.safeValue(response, 'data', []);
212465
+ const positions = this.safeList(response, 'data', []);
212486
212466
  const result = [];
212487
212467
  for (let i = 0; i < positions.length; i++) {
212488
212468
  result.push(this.parsePosition(positions[i]));
@@ -212690,7 +212670,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
212690
212670
  */
212691
212671
  await this.loadMarkets();
212692
212672
  const currency = this.currency(code);
212693
- const accountsByType = this.safeValue(this.options, 'accountsByType', {});
212673
+ const accountsByType = this.safeDict(this.options, 'accountsByType', {});
212694
212674
  const fromId = this.safeString(accountsByType, fromAccount, fromAccount);
212695
212675
  const toId = this.safeString(accountsByType, toAccount, toAccount);
212696
212676
  const request = {
@@ -212732,7 +212712,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
212732
212712
  // ]
212733
212713
  // }
212734
212714
  //
212735
- const data = this.safeValue(response, 'data', []);
212715
+ const data = this.safeList(response, 'data', []);
212736
212716
  const rawTransfer = this.safeDict(data, 0, {});
212737
212717
  return this.parseTransfer(rawTransfer, currency);
212738
212718
  }
@@ -212795,7 +212775,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
212795
212775
  let amount = this.safeNumber(transfer, 'amt');
212796
212776
  const fromAccountId = this.safeString(transfer, 'from');
212797
212777
  const toAccountId = this.safeString(transfer, 'to');
212798
- const accountsById = this.safeValue(this.options, 'accountsById', {});
212778
+ const accountsById = this.safeDict(this.options, 'accountsById', {});
212799
212779
  const timestamp = this.safeInteger(transfer, 'ts');
212800
212780
  const balanceChange = this.safeString(transfer, 'sz');
212801
212781
  if (balanceChange !== undefined) {
@@ -212846,7 +212826,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
212846
212826
  // "msg": ""
212847
212827
  // }
212848
212828
  //
212849
- const data = this.safeValue(response, 'data', []);
212829
+ const data = this.safeList(response, 'data', []);
212850
212830
  const transfer = this.safeDict(data, 0);
212851
212831
  return this.parseTransfer(transfer);
212852
212832
  }
@@ -213052,8 +213032,8 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213052
213032
  // "msg": ""
213053
213033
  // }
213054
213034
  //
213055
- const data = this.safeValue(response, 'data', []);
213056
- const entry = this.safeValue(data, 0, {});
213035
+ const data = this.safeList(response, 'data', []);
213036
+ const entry = this.safeDict(data, 0, {});
213057
213037
  return this.parseFundingRate(entry, market);
213058
213038
  }
213059
213039
  async fetchFundingHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
@@ -213193,7 +213173,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213193
213173
  // "type": "8"
213194
213174
  // }
213195
213175
  //
213196
- const data = this.safeValue(response, 'data', []);
213176
+ const data = this.safeList(response, 'data', []);
213197
213177
  const result = [];
213198
213178
  for (let i = 0; i < data.length; i++) {
213199
213179
  const entry = data[i];
@@ -213385,7 +213365,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213385
213365
  // ],
213386
213366
  // }
213387
213367
  //
213388
- const data = this.safeValue(response, 'data', []);
213368
+ const data = this.safeList(response, 'data', []);
213389
213369
  const rates = [];
213390
213370
  for (let i = 0; i < data.length; i++) {
213391
213371
  rates.push(this.parseBorrowRate(data[i]));
@@ -213421,8 +213401,8 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213421
213401
  // "msg": ""
213422
213402
  // }
213423
213403
  //
213424
- const data = this.safeValue(response, 'data');
213425
- const rate = this.safeValue(data, 0);
213404
+ const data = this.safeList(response, 'data', []);
213405
+ const rate = this.safeDict(data, 0, {});
213426
213406
  return this.parseBorrowRate(rate);
213427
213407
  }
213428
213408
  parseBorrowRate(info, currency = undefined) {
@@ -213526,7 +213506,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213526
213506
  // "msg": ""
213527
213507
  // }
213528
213508
  //
213529
- const data = this.safeValue(response, 'data');
213509
+ const data = this.safeList(response, 'data', []);
213530
213510
  return this.parseBorrowRateHistories(data, codes, since, limit);
213531
213511
  }
213532
213512
  async fetchBorrowRateHistory(code, since = undefined, limit = undefined, params = {}) {
@@ -213570,7 +213550,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213570
213550
  // "msg": ""
213571
213551
  // }
213572
213552
  //
213573
- const data = this.safeValue(response, 'data');
213553
+ const data = this.safeList(response, 'data', []);
213574
213554
  return this.parseBorrowRateHistory(data, code, since, limit);
213575
213555
  }
213576
213556
  async modifyMarginHelper(symbol, amount, type, params = {}) {
@@ -213762,7 +213742,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213762
213742
  // ]
213763
213743
  // }
213764
213744
  //
213765
- const data = this.safeValue(response, 'data');
213745
+ const data = this.safeList(response, 'data', []);
213766
213746
  return this.parseMarketLeverageTiers(data, market);
213767
213747
  }
213768
213748
  parseMarketLeverageTiers(info, market = undefined) {
@@ -213864,7 +213844,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213864
213844
  // "msg": ""
213865
213845
  // }
213866
213846
  //
213867
- const data = this.safeValue(response, 'data');
213847
+ const data = this.safeList(response, 'data', []);
213868
213848
  const interest = this.parseBorrowInterests(data);
213869
213849
  return this.filterByCurrencySinceLimit(interest, code, since, limit);
213870
213850
  }
@@ -213920,8 +213900,8 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213920
213900
  // "msg": ""
213921
213901
  // }
213922
213902
  //
213923
- const data = this.safeValue(response, 'data', []);
213924
- const loan = this.safeValue(data, 0);
213903
+ const data = this.safeList(response, 'data', []);
213904
+ const loan = this.safeDict(data, 0, {});
213925
213905
  return this.parseMarginLoan(loan, currency);
213926
213906
  }
213927
213907
  async repayCrossMargin(code, amount, params = {}) {
@@ -213965,8 +213945,8 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
213965
213945
  // "msg": ""
213966
213946
  // }
213967
213947
  //
213968
- const data = this.safeValue(response, 'data', []);
213969
- const loan = this.safeValue(data, 0);
213948
+ const data = this.safeList(response, 'data', []);
213949
+ const loan = this.safeDict(data, 0, {});
213970
213950
  return this.parseMarginLoan(loan, currency);
213971
213951
  }
213972
213952
  parseMarginLoan(info, currency = undefined) {
@@ -214048,8 +214028,8 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
214048
214028
  * @param {int} [params.until] The time in ms of the latest record to retrieve as a unix timestamp
214049
214029
  * @returns An array of [open interest structures]{@link https://docs.ccxt.com/#/?id=open-interest-structure}
214050
214030
  */
214051
- const options = this.safeValue(this.options, 'fetchOpenInterestHistory', {});
214052
- const timeframes = this.safeValue(options, 'timeframes', {});
214031
+ const options = this.safeDict(this.options, 'fetchOpenInterestHistory', {});
214032
+ const timeframes = this.safeDict(options, 'timeframes', {});
214053
214033
  timeframe = this.safeString(timeframes, timeframe, timeframe);
214054
214034
  if (timeframe !== '5m' && timeframe !== '1H' && timeframe !== '1D') {
214055
214035
  throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadRequest(this.id + ' fetchOpenInterestHistory cannot only use the 5m, 1h, and 1d timeframe');
@@ -214339,7 +214319,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
214339
214319
  // "msg": ""
214340
214320
  // }
214341
214321
  //
214342
- const data = this.safeValue(response, 'data', []);
214322
+ const data = this.safeList(response, 'data', []);
214343
214323
  const settlements = this.parseSettlements(data, market);
214344
214324
  const sorted = this.sortBy(settlements, 'timestamp');
214345
214325
  return this.filterBySymbolSinceLimit(sorted, market['symbol'], since, limit);
@@ -214378,7 +214358,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
214378
214358
  for (let i = 0; i < settlements.length; i++) {
214379
214359
  const entry = settlements[i];
214380
214360
  const timestamp = this.safeInteger(entry, 'ts');
214381
- const details = this.safeValue(entry, 'details', []);
214361
+ const details = this.safeList(entry, 'details', []);
214382
214362
  for (let j = 0; j < details.length; j++) {
214383
214363
  const settlement = this.parseSettlement(details[j], market);
214384
214364
  result.push(this.extend(settlement, {
@@ -214424,7 +214404,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
214424
214404
  // "msg": ""
214425
214405
  // }
214426
214406
  //
214427
- const underlyings = this.safeValue(response, 'data', []);
214407
+ const underlyings = this.safeList(response, 'data', []);
214428
214408
  return underlyings[0];
214429
214409
  }
214430
214410
  async fetchGreeks(symbol, params = {}) {
@@ -214476,7 +214456,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
214476
214456
  // "msg": ""
214477
214457
  // }
214478
214458
  //
214479
- const data = this.safeValue(response, 'data', []);
214459
+ const data = this.safeList(response, 'data', []);
214480
214460
  for (let i = 0; i < data.length; i++) {
214481
214461
  const entry = data[i];
214482
214462
  const entryMarketId = this.safeString(entry, 'instId');
@@ -214599,7 +214579,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
214599
214579
  // "outTime": "1701877077102579"
214600
214580
  // }
214601
214581
  //
214602
- const data = this.safeValue(response, 'data');
214582
+ const data = this.safeList(response, 'data', []);
214603
214583
  const order = this.safeDict(data, 0);
214604
214584
  return this.parseOrder(order, market);
214605
214585
  }
@@ -214918,7 +214898,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
214918
214898
  const code = this.safeString(response, 'code');
214919
214899
  if ((code !== '0') && (code !== '2')) { // 2 means that bulk operation partially succeeded
214920
214900
  const feedback = this.id + ' ' + body;
214921
- const data = this.safeValue(response, 'data', []);
214901
+ const data = this.safeList(response, 'data', []);
214922
214902
  for (let i = 0; i < data.length; i++) {
214923
214903
  const error = data[i];
214924
214904
  const errorCode = this.safeString(error, 'sCode');
@@ -248542,6 +248522,9 @@ class coinbase extends _coinbase_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] *
248542
248522
  const messageHash = channel + '::' + wsMarketId;
248543
248523
  newTickers.push(result);
248544
248524
  client.resolve(result, messageHash);
248525
+ if (messageHash.endsWith('USD')) {
248526
+ client.resolve(result, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
248527
+ }
248545
248528
  }
248546
248529
  }
248547
248530
  const messageHashes = this.findMessageHashes(client, 'ticker_batch::');
@@ -248553,6 +248536,9 @@ class coinbase extends _coinbase_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] *
248553
248536
  const tickers = this.filterByArray(newTickers, 'symbol', symbols);
248554
248537
  if (!this.isEmpty(tickers)) {
248555
248538
  client.resolve(tickers, messageHash);
248539
+ if (messageHash.endsWith('USD')) {
248540
+ client.resolve(tickers, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
248541
+ }
248556
248542
  }
248557
248543
  }
248558
248544
  return message;
@@ -248702,6 +248688,9 @@ class coinbase extends _coinbase_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] *
248702
248688
  }
248703
248689
  }
248704
248690
  client.resolve(tradesArray, messageHash);
248691
+ if (marketId.endsWith('USD')) {
248692
+ client.resolve(tradesArray, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
248693
+ }
248705
248694
  return message;
248706
248695
  }
248707
248696
  handleOrder(client, message) {
@@ -248757,6 +248746,9 @@ class coinbase extends _coinbase_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] *
248757
248746
  const marketId = marketIds[i];
248758
248747
  const messageHash = 'user::' + marketId;
248759
248748
  client.resolve(this.orders, messageHash);
248749
+ if (messageHash.endsWith('USD')) {
248750
+ client.resolve(this.orders, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
248751
+ }
248760
248752
  }
248761
248753
  client.resolve(this.orders, 'user');
248762
248754
  return message;
@@ -248869,6 +248861,9 @@ class coinbase extends _coinbase_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] *
248869
248861
  orderbook['datetime'] = undefined;
248870
248862
  orderbook['symbol'] = symbol;
248871
248863
  client.resolve(orderbook, messageHash);
248864
+ if (messageHash.endsWith('USD')) {
248865
+ client.resolve(orderbook, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
248866
+ }
248872
248867
  }
248873
248868
  else if (type === 'update') {
248874
248869
  const orderbook = this.orderbooks[symbol];
@@ -248877,6 +248872,9 @@ class coinbase extends _coinbase_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] *
248877
248872
  orderbook['timestamp'] = this.parse8601(datetime);
248878
248873
  orderbook['symbol'] = symbol;
248879
248874
  client.resolve(orderbook, messageHash);
248875
+ if (messageHash.endsWith('USD')) {
248876
+ client.resolve(orderbook, messageHash + 'C'); // sometimes we subscribe to BTC/USDC and coinbase returns BTC/USD
248877
+ }
248880
248878
  }
248881
248879
  }
248882
248880
  return message;
@@ -326244,7 +326242,7 @@ SOFTWARE.
326244
326242
 
326245
326243
  //-----------------------------------------------------------------------------
326246
326244
  // this is updated by vss.js when building
326247
- const version = '4.2.94';
326245
+ const version = '4.2.95';
326248
326246
  _src_base_Exchange_js__WEBPACK_IMPORTED_MODULE_0__/* .Exchange */ .e.ccxtVersion = version;
326249
326247
  //-----------------------------------------------------------------------------
326250
326248