ccxt 4.5.22 → 4.5.23

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 (68) hide show
  1. package/README.md +6 -5
  2. package/dist/ccxt.browser.min.js +2 -2
  3. package/dist/cjs/ccxt.js +6 -1
  4. package/dist/cjs/src/abstract/bullish.js +11 -0
  5. package/dist/cjs/src/base/Exchange.js +3 -2
  6. package/dist/cjs/src/base/ws/WsClient.js +15 -0
  7. package/dist/cjs/src/binance.js +159 -36
  8. package/dist/cjs/src/bingx.js +2 -1
  9. package/dist/cjs/src/bitmart.js +1 -0
  10. package/dist/cjs/src/bullish.js +2919 -0
  11. package/dist/cjs/src/bybit.js +34 -37
  12. package/dist/cjs/src/gate.js +2 -2
  13. package/dist/cjs/src/htx.js +4 -1
  14. package/dist/cjs/src/hyperliquid.js +115 -12
  15. package/dist/cjs/src/kucoin.js +22 -3
  16. package/dist/cjs/src/mexc.js +7 -0
  17. package/dist/cjs/src/okx.js +117 -63
  18. package/dist/cjs/src/paradex.js +78 -3
  19. package/dist/cjs/src/pro/binance.js +131 -29
  20. package/dist/cjs/src/pro/bullish.js +781 -0
  21. package/dist/cjs/src/pro/coinbase.js +2 -2
  22. package/dist/cjs/src/pro/hyperliquid.js +75 -15
  23. package/dist/cjs/src/pro/upbit.js +28 -82
  24. package/js/ccxt.d.ts +8 -2
  25. package/js/ccxt.js +6 -2
  26. package/js/src/abstract/binance.d.ts +1 -0
  27. package/js/src/abstract/binancecoinm.d.ts +1 -0
  28. package/js/src/abstract/binanceus.d.ts +1 -0
  29. package/js/src/abstract/binanceusdm.d.ts +1 -0
  30. package/js/src/abstract/bingx.d.ts +1 -0
  31. package/js/src/abstract/bullish.d.ts +65 -0
  32. package/js/src/abstract/bullish.js +5 -0
  33. package/js/src/abstract/kucoin.d.ts +15 -0
  34. package/js/src/abstract/kucoinfutures.d.ts +15 -0
  35. package/js/src/abstract/mexc.d.ts +7 -0
  36. package/js/src/abstract/myokx.d.ts +90 -39
  37. package/js/src/abstract/okx.d.ts +90 -39
  38. package/js/src/abstract/okxus.d.ts +90 -39
  39. package/js/src/base/Exchange.d.ts +1 -1
  40. package/js/src/base/Exchange.js +3 -2
  41. package/js/src/base/ws/Client.d.ts +1 -0
  42. package/js/src/base/ws/WsClient.js +15 -0
  43. package/js/src/binance.d.ts +14 -5
  44. package/js/src/binance.js +159 -36
  45. package/js/src/bingx.js +2 -1
  46. package/js/src/bitmart.js +1 -0
  47. package/js/src/bullish.d.ts +446 -0
  48. package/js/src/bullish.js +2912 -0
  49. package/js/src/bybit.js +34 -37
  50. package/js/src/gate.js +2 -2
  51. package/js/src/htx.js +4 -1
  52. package/js/src/hyperliquid.d.ts +24 -0
  53. package/js/src/hyperliquid.js +115 -12
  54. package/js/src/kucoin.js +22 -3
  55. package/js/src/mexc.js +7 -0
  56. package/js/src/okx.js +117 -63
  57. package/js/src/paradex.d.ts +15 -1
  58. package/js/src/paradex.js +78 -3
  59. package/js/src/pro/binance.d.ts +7 -0
  60. package/js/src/pro/binance.js +131 -29
  61. package/js/src/pro/bullish.d.ts +108 -0
  62. package/js/src/pro/bullish.js +774 -0
  63. package/js/src/pro/coinbase.js +2 -2
  64. package/js/src/pro/hyperliquid.d.ts +13 -1
  65. package/js/src/pro/hyperliquid.js +75 -15
  66. package/js/src/pro/upbit.d.ts +0 -1
  67. package/js/src/pro/upbit.js +28 -82
  68. package/package.json +2 -2
@@ -3971,15 +3971,12 @@ class bybit extends bybit$1["default"] {
3971
3971
  const market = this.market(symbol);
3972
3972
  const parts = await this.isUnifiedEnabled();
3973
3973
  const enableUnifiedAccount = parts[1];
3974
- const trailingAmount = this.safeString2(params, 'trailingAmount', 'trailingStop');
3975
- const stopLossPrice = this.safeString(params, 'stopLossPrice');
3976
- const takeProfitPrice = this.safeString(params, 'takeProfitPrice');
3977
- const isTrailingAmountOrder = trailingAmount !== undefined;
3978
- const isStopLoss = stopLossPrice !== undefined;
3979
- const isTakeProfit = takeProfitPrice !== undefined;
3974
+ const isTrailingOrder = this.safeString2(params, 'trailingAmount', 'trailingStop') !== undefined;
3975
+ const isStopLossOrder = this.safeString(params, 'stopLossPrice') !== undefined;
3976
+ const isTakeProfitOrder = this.safeString(params, 'takeProfitPrice') !== undefined;
3980
3977
  const orderRequest = this.createOrderRequest(symbol, type, side, amount, price, params, enableUnifiedAccount);
3981
3978
  let defaultMethod = undefined;
3982
- if ((isTrailingAmountOrder || isStopLoss || isTakeProfit) && !market['spot']) {
3979
+ if ((isTrailingOrder || isStopLossOrder || isTakeProfitOrder) && !market['spot']) {
3983
3980
  defaultMethod = 'privatePostV5PositionTradingStop';
3984
3981
  }
3985
3982
  else {
@@ -4050,17 +4047,17 @@ class bybit extends bybit$1["default"] {
4050
4047
  const takeProfit = this.safeValue(params, 'takeProfit');
4051
4048
  const trailingTriggerPrice = this.safeString2(params, 'trailingTriggerPrice', 'activePrice', this.numberToString(price));
4052
4049
  const trailingAmount = this.safeString2(params, 'trailingAmount', 'trailingStop');
4053
- const isTrailingAmountOrder = trailingAmount !== undefined;
4050
+ const isTrailingOrder = trailingAmount !== undefined;
4054
4051
  const isTriggerOrder = triggerPrice !== undefined;
4055
- const isStopLossTriggerOrder = stopLossTriggerPrice !== undefined;
4056
- const isTakeProfitTriggerOrder = takeProfitTriggerPrice !== undefined;
4057
- const isStopLoss = stopLoss !== undefined;
4052
+ const isStopLossOrder = stopLossTriggerPrice !== undefined;
4053
+ const isTakeProfitOrder = takeProfitTriggerPrice !== undefined;
4054
+ const hasStopLoss = stopLoss !== undefined;
4058
4055
  const isTakeProfit = takeProfit !== undefined;
4059
4056
  const isMarket = lowerCaseType === 'market';
4060
4057
  const isLimit = lowerCaseType === 'limit';
4061
4058
  const isBuy = side === 'buy';
4062
4059
  let defaultMethod = undefined;
4063
- if ((isTrailingAmountOrder || isStopLossTriggerOrder || isTakeProfitTriggerOrder) && !market['spot']) {
4060
+ if ((isTrailingOrder || isStopLossOrder || isTakeProfitOrder) && !market['spot']) {
4064
4061
  defaultMethod = 'privatePostV5PositionTradingStop';
4065
4062
  }
4066
4063
  else {
@@ -4068,14 +4065,14 @@ class bybit extends bybit$1["default"] {
4068
4065
  }
4069
4066
  let method = undefined;
4070
4067
  [method, params] = this.handleOptionAndParams(params, 'createOrder', 'method', defaultMethod);
4071
- const isAlternativeEndpoint = method === 'privatePostV5PositionTradingStop';
4068
+ const endpointIsTradingStop = method === 'privatePostV5PositionTradingStop';
4072
4069
  const amountString = this.getAmount(symbol, amount);
4073
4070
  const priceString = (price !== undefined) ? this.getPrice(symbol, this.numberToString(price)) : undefined;
4074
- if (isTrailingAmountOrder || isAlternativeEndpoint) {
4075
- if (isStopLoss || isTakeProfit || isTriggerOrder || market['spot']) {
4071
+ if (isTrailingOrder || endpointIsTradingStop) {
4072
+ if (hasStopLoss || isTakeProfit || isTriggerOrder || market['spot']) {
4076
4073
  throw new errors.InvalidOrder(this.id + ' the API endpoint used only supports contract trailingAmount, stopLossPrice and takeProfitPrice orders');
4077
4074
  }
4078
- if (isStopLossTriggerOrder || isTakeProfitTriggerOrder) {
4075
+ if (isStopLossOrder || isTakeProfitOrder) {
4079
4076
  const tpslMode = this.safeString(params, 'tpslMode', 'Partial');
4080
4077
  const isFullTpsl = tpslMode === 'Full';
4081
4078
  const isPartialTpsl = tpslMode === 'Partial';
@@ -4083,7 +4080,7 @@ class bybit extends bybit$1["default"] {
4083
4080
  throw new errors.InvalidOrder(this.id + ' tpsl orders with "full" tpslMode only support "market" type');
4084
4081
  }
4085
4082
  request['tpslMode'] = tpslMode;
4086
- if (isStopLossTriggerOrder) {
4083
+ if (isStopLossOrder) {
4087
4084
  request['stopLoss'] = this.getPrice(symbol, stopLossTriggerPrice);
4088
4085
  if (isPartialTpsl) {
4089
4086
  request['slSize'] = amountString;
@@ -4093,7 +4090,7 @@ class bybit extends bybit$1["default"] {
4093
4090
  request['slLimitPrice'] = priceString;
4094
4091
  }
4095
4092
  }
4096
- else if (isTakeProfitTriggerOrder) {
4093
+ else if (isTakeProfitOrder) {
4097
4094
  request['takeProfit'] = this.getPrice(symbol, takeProfitTriggerPrice);
4098
4095
  if (isPartialTpsl) {
4099
4096
  request['tpSize'] = amountString;
@@ -4128,7 +4125,7 @@ class bybit extends bybit$1["default"] {
4128
4125
  if (triggerPrice !== undefined) {
4129
4126
  request['orderFilter'] = 'StopOrder';
4130
4127
  }
4131
- else if (isStopLossTriggerOrder || isTakeProfitTriggerOrder) {
4128
+ else if (isStopLossOrder || isTakeProfitOrder) {
4132
4129
  request['orderFilter'] = 'tpslOrder';
4133
4130
  }
4134
4131
  }
@@ -4199,17 +4196,17 @@ class bybit extends bybit$1["default"] {
4199
4196
  }
4200
4197
  }
4201
4198
  else {
4202
- if (!isTrailingAmountOrder && !isAlternativeEndpoint) {
4199
+ if (!isTrailingOrder && !endpointIsTradingStop) {
4203
4200
  request['qty'] = amountString;
4204
4201
  }
4205
4202
  }
4206
- if (isTrailingAmountOrder) {
4203
+ if (isTrailingOrder) {
4207
4204
  if (trailingTriggerPrice !== undefined) {
4208
4205
  request['activePrice'] = this.getPrice(symbol, trailingTriggerPrice);
4209
4206
  }
4210
4207
  request['trailingStop'] = trailingAmount;
4211
4208
  }
4212
- else if (isTriggerOrder && !isAlternativeEndpoint) {
4209
+ else if (isTriggerOrder && !endpointIsTradingStop) {
4213
4210
  const triggerDirection = this.safeString(params, 'triggerDirection');
4214
4211
  params = this.omit(params, ['triggerPrice', 'stopPrice', 'triggerDirection']);
4215
4212
  if (market['spot']) {
@@ -4226,19 +4223,19 @@ class bybit extends bybit$1["default"] {
4226
4223
  }
4227
4224
  request['triggerPrice'] = this.getPrice(symbol, triggerPrice);
4228
4225
  }
4229
- else if ((isStopLossTriggerOrder || isTakeProfitTriggerOrder) && !isAlternativeEndpoint) {
4226
+ else if ((isStopLossOrder || isTakeProfitOrder) && !endpointIsTradingStop) {
4230
4227
  if (isBuy) {
4231
- request['triggerDirection'] = isStopLossTriggerOrder ? 1 : 2;
4228
+ request['triggerDirection'] = isStopLossOrder ? 1 : 2;
4232
4229
  }
4233
4230
  else {
4234
- request['triggerDirection'] = isStopLossTriggerOrder ? 2 : 1;
4231
+ request['triggerDirection'] = isStopLossOrder ? 2 : 1;
4235
4232
  }
4236
- triggerPrice = isStopLossTriggerOrder ? stopLossTriggerPrice : takeProfitTriggerPrice;
4233
+ triggerPrice = isStopLossOrder ? stopLossTriggerPrice : takeProfitTriggerPrice;
4237
4234
  request['triggerPrice'] = this.getPrice(symbol, triggerPrice);
4238
4235
  request['reduceOnly'] = true;
4239
4236
  }
4240
- if ((isStopLoss || isTakeProfit) && !isAlternativeEndpoint) {
4241
- if (isStopLoss) {
4237
+ if ((hasStopLoss || isTakeProfit) && !endpointIsTradingStop) {
4238
+ if (hasStopLoss) {
4242
4239
  const slTriggerPrice = this.safeValue2(stopLoss, 'triggerPrice', 'stopPrice', stopLoss);
4243
4240
  request['stopLoss'] = this.getPrice(symbol, slTriggerPrice);
4244
4241
  const slLimitPrice = this.safeValue(stopLoss, 'price');
@@ -4417,12 +4414,12 @@ class bybit extends bybit$1["default"] {
4417
4414
  const takeProfitTriggerPrice = this.safeString(params, 'takeProfitPrice');
4418
4415
  const stopLoss = this.safeValue(params, 'stopLoss');
4419
4416
  const takeProfit = this.safeValue(params, 'takeProfit');
4420
- const isStopLossTriggerOrder = stopLossTriggerPrice !== undefined;
4421
- const isTakeProfitTriggerOrder = takeProfitTriggerPrice !== undefined;
4422
- const isStopLoss = stopLoss !== undefined;
4423
- const isTakeProfit = takeProfit !== undefined;
4424
- if (isStopLossTriggerOrder || isTakeProfitTriggerOrder) {
4425
- triggerPrice = isStopLossTriggerOrder ? stopLossTriggerPrice : takeProfitTriggerPrice;
4417
+ const isStopLossOrder = stopLossTriggerPrice !== undefined;
4418
+ const isTakeProfitOrder = takeProfitTriggerPrice !== undefined;
4419
+ const hasStopLoss = stopLoss !== undefined;
4420
+ const hasTakeProfit = takeProfit !== undefined;
4421
+ if (isStopLossOrder || isTakeProfitOrder) {
4422
+ triggerPrice = isStopLossOrder ? stopLossTriggerPrice : takeProfitTriggerPrice;
4426
4423
  }
4427
4424
  if (triggerPrice !== undefined) {
4428
4425
  const triggerPriceRequest = (triggerPrice === '0') ? triggerPrice : this.getPrice(symbol, triggerPrice);
@@ -4430,15 +4427,15 @@ class bybit extends bybit$1["default"] {
4430
4427
  const triggerBy = this.safeString(params, 'triggerBy', 'LastPrice');
4431
4428
  request['triggerBy'] = triggerBy;
4432
4429
  }
4433
- if (isStopLoss || isTakeProfit) {
4434
- if (isStopLoss) {
4430
+ if (hasStopLoss || hasTakeProfit) {
4431
+ if (hasStopLoss) {
4435
4432
  const slTriggerPrice = this.safeString2(stopLoss, 'triggerPrice', 'stopPrice', stopLoss);
4436
4433
  const stopLossRequest = (slTriggerPrice === '0') ? slTriggerPrice : this.getPrice(symbol, slTriggerPrice);
4437
4434
  request['stopLoss'] = stopLossRequest;
4438
4435
  const slTriggerBy = this.safeString(params, 'slTriggerBy', 'LastPrice');
4439
4436
  request['slTriggerBy'] = slTriggerBy;
4440
4437
  }
4441
- if (isTakeProfit) {
4438
+ if (hasTakeProfit) {
4442
4439
  const tpTriggerPrice = this.safeString2(takeProfit, 'triggerPrice', 'stopPrice', takeProfit);
4443
4440
  const takeProfitRequest = (tpTriggerPrice === '0') ? tpTriggerPrice : this.getPrice(symbol, tpTriggerPrice);
4444
4441
  request['takeProfit'] = takeProfitRequest;
@@ -1091,7 +1091,6 @@ class gate extends gate$1["default"] {
1091
1091
  'LOAN_RECORD_NOT_FOUND': errors.OrderNotFound,
1092
1092
  'NO_MATCHED_LOAN': errors.ExchangeError,
1093
1093
  'NOT_MERGEABLE': errors.ExchangeError,
1094
- 'NO_CHANGE': errors.ExchangeError,
1095
1094
  'REPAY_TOO_MUCH': errors.ExchangeError,
1096
1095
  'TOO_MANY_CURRENCY_PAIRS': errors.InvalidOrder,
1097
1096
  'TOO_MANY_ORDERS': errors.InvalidOrder,
@@ -1133,7 +1132,8 @@ class gate extends gate$1["default"] {
1133
1132
  'AUTO_TRIGGER_PRICE_LESS_LAST': errors.InvalidOrder,
1134
1133
  'AUTO_TRIGGER_PRICE_GREATE_LAST': errors.InvalidOrder,
1135
1134
  'POSITION_HOLDING': errors.BadRequest,
1136
- 'USER_LOAN_EXCEEDED': errors.BadRequest, // {"label":"USER_LOAN_EXCEEDED","message":"Max loan amount per user would be exceeded"}
1135
+ 'USER_LOAN_EXCEEDED': errors.BadRequest,
1136
+ 'NO_CHANGE': errors.InvalidOrder, // {"label":"NO_CHANGE","message":"No change is made"}
1137
1137
  },
1138
1138
  'broad': {},
1139
1139
  },
@@ -932,6 +932,7 @@ class htx extends htx$1["default"] {
932
932
  'base-symbol-error': errors.BadSymbol,
933
933
  'system-maintenance': errors.OnMaintenance,
934
934
  'base-request-exceed-frequency-limit': errors.RateLimitExceeded,
935
+ 'rate-too-many-requests': errors.RateLimitExceeded,
935
936
  // err-msg
936
937
  'invalid symbol': errors.BadSymbol,
937
938
  'symbol trade not open now': errors.BadSymbol,
@@ -5557,7 +5558,9 @@ class htx extends htx$1["default"] {
5557
5558
  params = this.omit(params, ['clientOrderId']);
5558
5559
  }
5559
5560
  if (type === 'limit' || type === 'ioc' || type === 'fok' || type === 'post_only') {
5560
- request['price'] = this.priceToPrecision(symbol, price);
5561
+ if (price !== undefined) {
5562
+ request['price'] = this.priceToPrecision(symbol, price);
5563
+ }
5561
5564
  }
5562
5565
  }
5563
5566
  const reduceOnly = this.safeBool2(params, 'reduceOnly', 'reduce_only', false);
@@ -102,9 +102,10 @@ class hyperliquid extends hyperliquid$1["default"] {
102
102
  'fetchPositions': true,
103
103
  'fetchPositionsRisk': false,
104
104
  'fetchPremiumIndexOHLCV': false,
105
+ 'fetchStatus': true,
105
106
  'fetchTicker': 'emulated',
106
107
  'fetchTickers': true,
107
- 'fetchTime': false,
108
+ 'fetchTime': true,
108
109
  'fetchTrades': true,
109
110
  'fetchTradingFee': true,
110
111
  'fetchTradingFees': false,
@@ -220,6 +221,7 @@ class hyperliquid extends hyperliquid$1["default"] {
220
221
  'defaultType': 'swap',
221
222
  'sandboxMode': false,
222
223
  'defaultSlippage': 0.05,
224
+ 'marketHelperProps': ['hip3TokensByName', 'cachedCurrenciesById'],
223
225
  'zeroAddress': '0x0000000000000000000000000000000000000000',
224
226
  'spotCurrencyMapping': {
225
227
  'UDZ': '2Z',
@@ -407,6 +409,49 @@ class hyperliquid extends hyperliquid$1["default"] {
407
409
  }
408
410
  return super.safeMarket(marketId, market, delimiter, marketType);
409
411
  }
412
+ /**
413
+ * @method
414
+ * @name hyperliquid#fetchStatus
415
+ * @description the latest known information on the availability of the exchange API
416
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
417
+ * @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure}
418
+ */
419
+ async fetchStatus(params = {}) {
420
+ const request = {
421
+ 'type': 'exchangeStatus',
422
+ };
423
+ const response = await this.publicPostInfo(this.extend(request, params));
424
+ //
425
+ // {
426
+ // "status": "ok"
427
+ // }
428
+ //
429
+ const status = this.safeString(response, 'specialStatuses');
430
+ return {
431
+ 'status': (status === undefined) ? 'ok' : 'maintenance',
432
+ 'updated': this.safeInteger(response, 'time'),
433
+ 'eta': undefined,
434
+ 'url': undefined,
435
+ 'info': response,
436
+ };
437
+ }
438
+ /**
439
+ * @method
440
+ * @name hyperliquid#fetchTime
441
+ * @description fetches the current integer timestamp in milliseconds from the exchange server
442
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
443
+ * @returns {int} the current integer timestamp in milliseconds from the exchange server
444
+ */
445
+ async fetchTime(params = {}) {
446
+ const request = {
447
+ 'type': 'exchangeStatus',
448
+ };
449
+ const response = await this.publicPostInfo(this.extend(request, params));
450
+ //
451
+ // { specialStatuses: null, time: '1764617438643' }
452
+ //
453
+ return this.safeInteger(response, 'time');
454
+ }
410
455
  /**
411
456
  * @method
412
457
  * @name hyperliquid#fetchCurrencies
@@ -420,7 +465,8 @@ class hyperliquid extends hyperliquid$1["default"] {
420
465
  await this.initializeClient();
421
466
  }
422
467
  const request = {
423
- 'type': 'meta',
468
+ // 'type': 'meta',
469
+ 'type': 'spotMeta',
424
470
  };
425
471
  const response = await this.publicPostInfo(this.extend(request, params));
426
472
  //
@@ -437,18 +483,23 @@ class hyperliquid extends hyperliquid$1["default"] {
437
483
  // }
438
484
  // ]
439
485
  //
440
- const meta = this.safeList(response, 'universe', []);
486
+ // const spotMeta = await this.publicPostInfo ({ 'type': 'spotMeta' });
487
+ const tokens = this.safeList(response, 'tokens', []);
488
+ // const meta = this.safeList (response, 'universe', []);
489
+ this.options['cachedCurrenciesById'] = {}; // used to map hip3 markets
441
490
  const result = {};
442
- for (let i = 0; i < meta.length; i++) {
443
- const data = this.safeDict(meta, i, {});
444
- const id = i;
491
+ for (let i = 0; i < tokens.length; i++) {
492
+ const data = this.safeDict(tokens, i, {});
493
+ // const id = i;
494
+ const id = this.safeString(data, 'index');
445
495
  const name = this.safeString(data, 'name');
446
496
  const code = this.safeCurrencyCode(name);
497
+ this.options['cachedCurrenciesById'][id] = name;
447
498
  result[code] = this.safeCurrencyStructure({
448
499
  'id': id,
449
500
  'name': name,
450
501
  'code': code,
451
- 'precision': undefined,
502
+ 'precision': this.parsePrecision(this.safeString(data, 'weiDecimals')),
452
503
  'info': data,
453
504
  'active': undefined,
454
505
  'deposit': undefined,
@@ -570,18 +621,38 @@ class hyperliquid extends hyperliquid$1["default"] {
570
621
  rawPromises.push(this.publicPostInfo(this.extend(request, params)));
571
622
  }
572
623
  const promises = await Promise.all(rawPromises);
624
+ this.options['hip3TokensByName'] = {};
573
625
  let markets = [];
574
626
  for (let i = 0; i < promises.length; i++) {
575
627
  const dexName = fetchDexesList[i];
576
628
  const offset = perpDexesOffset[dexName];
577
629
  const response = promises[i];
578
630
  const meta = this.safeDict(response, 0, {});
631
+ const collateralToken = this.safeString(meta, 'collateralToken');
579
632
  const universe = this.safeList(meta, 'universe', []);
580
633
  const assetCtxs = this.safeList(response, 1, []);
581
634
  const result = [];
635
+ // helper because some endpoints return just the coin name like: flx:crcl
636
+ // and we don't have the base/settle information and we can't assume it's USDC for hip3 markets
582
637
  for (let j = 0; j < universe.length; j++) {
583
638
  const data = this.extend(this.safeDict(universe, j, {}), this.safeDict(assetCtxs, j, {}));
584
639
  data['baseId'] = j + offset;
640
+ data['collateralToken'] = collateralToken;
641
+ data['hip3'] = true;
642
+ data['dex'] = dexName;
643
+ const cachedCurrencies = this.safeDict(this.options, 'cachedCurrenciesById', {});
644
+ // injecting collateral token name for further usage in parseMarket, already converted from like '0' to 'USDC', etc
645
+ if (collateralToken in cachedCurrencies) {
646
+ const name = this.safeString(data, 'name');
647
+ const collateralTokenCode = this.safeString(cachedCurrencies, collateralToken);
648
+ data['collateralTokenName'] = collateralTokenCode;
649
+ // eg: 'flx:crcl' => {'quote': 'USDC', 'code': 'FLX-CRCL'}
650
+ const safeCode = this.safeCurrencyCode(name);
651
+ this.options['hip3TokensByName'][name] = {
652
+ 'quote': collateralTokenCode,
653
+ 'code': safeCode.replace(':', '-'),
654
+ };
655
+ }
585
656
  result.push(data);
586
657
  }
587
658
  markets = this.arrayConcat(markets, this.parseMarkets(result));
@@ -914,16 +985,19 @@ class hyperliquid extends hyperliquid$1["default"] {
914
985
  // "oraclePx": "2367.3",
915
986
  // "premium": "0.00090821",
916
987
  // "prevDayPx": "2381.5"
988
+ // "collateralToken": "0" hip3 tokens only
917
989
  // }
918
990
  //
919
- const quoteId = 'USDC';
991
+ const collateralTokenCode = this.safeString(market, 'collateralTokenName');
992
+ const quoteId = (collateralTokenCode === undefined) ? 'USDC' : collateralTokenCode;
993
+ const settleId = (collateralTokenCode === undefined) ? 'USDC' : collateralTokenCode;
920
994
  const baseName = this.safeString(market, 'name');
921
- const base = this.safeCurrencyCode(baseName);
995
+ let base = this.safeCurrencyCode(baseName);
996
+ base = base.replace(':', '-'); // handle hip3 tokens and converts from like flx:crcl to FLX-CRCL
922
997
  const quote = this.safeCurrencyCode(quoteId);
923
998
  const baseId = this.safeString(market, 'baseId');
924
- const settleId = 'USDC';
925
999
  const settle = this.safeCurrencyCode(settleId);
926
- let symbol = base.replace(':', '-') + '/' + quote;
1000
+ let symbol = base + '/' + quote;
927
1001
  const contract = true;
928
1002
  const swap = true;
929
1003
  {
@@ -1010,6 +1084,7 @@ class hyperliquid extends hyperliquid$1["default"] {
1010
1084
  * @param {string} [params.user] user address, will default to this.walletAddress if not provided
1011
1085
  * @param {string} [params.type] wallet type, ['spot', 'swap'], defaults to swap
1012
1086
  * @param {string} [params.marginMode] 'cross' or 'isolated', for margin trading, uses this.options.defaultMarginMode if not passed, defaults to undefined/None/null
1087
+ * @param {string} [params.dex] for hip3 markets, the dex name, eg: 'xyz'
1013
1088
  * @param {string} [params.subAccountAddress] sub account user address
1014
1089
  * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
1015
1090
  */
@@ -1152,6 +1227,7 @@ class hyperliquid extends hyperliquid$1["default"] {
1152
1227
  * @param {string[]} [symbols] unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1153
1228
  * @param {object} [params] extra parameters specific to the exchange API endpoint
1154
1229
  * @param {string} [params.type] 'spot' or 'swap', by default fetches both
1230
+ * @param {boolean} [params.hip3] set to true to fetch hip3 markets only
1155
1231
  * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1156
1232
  */
1157
1233
  async fetchTickers(symbols = undefined, params = {}) {
@@ -1161,7 +1237,21 @@ class hyperliquid extends hyperliquid$1["default"] {
1161
1237
  let response = [];
1162
1238
  const type = this.safeString(params, 'type');
1163
1239
  params = this.omit(params, 'type');
1164
- if (type === 'spot') {
1240
+ let hip3 = false;
1241
+ [hip3, params] = this.handleOptionAndParams(params, 'fetchTickers', 'hip3', false);
1242
+ if (symbols !== undefined) {
1243
+ // infer from first symbol
1244
+ const firstSymbol = this.safeString(symbols, 0);
1245
+ const market = this.market(firstSymbol);
1246
+ if (this.safeBool(this.safeDict(market, 'info'), 'hip3')) {
1247
+ hip3 = true;
1248
+ }
1249
+ }
1250
+ if (hip3) {
1251
+ params = this.omit(params, 'hip3');
1252
+ response = await this.fetchHip3Markets(params);
1253
+ }
1254
+ else if (type === 'spot') {
1165
1255
  response = await this.fetchSpotMarkets(params);
1166
1256
  }
1167
1257
  else if (type === 'swap') {
@@ -1301,6 +1391,9 @@ class hyperliquid extends hyperliquid$1["default"] {
1301
1391
  // "circulatingSupply": "998949190.03400207", // only in spot
1302
1392
  // },
1303
1393
  //
1394
+ const name = this.safeString(ticker, 'name');
1395
+ const marketId = this.coinToMarketId(name);
1396
+ market = this.safeMarket(marketId, market);
1304
1397
  const bidAsk = this.safeList(ticker, 'impactPxs');
1305
1398
  return this.safeTicker({
1306
1399
  'symbol': market['symbol'],
@@ -4232,6 +4325,16 @@ class hyperliquid extends hyperliquid$1["default"] {
4232
4325
  throw new errors.ArgumentsRequired(this.id + ' ' + methodName + '() requires a user parameter inside \'params\' or the wallet address set');
4233
4326
  }
4234
4327
  coinToMarketId(coin) {
4328
+ // handle also hip3 tokens like flx:CRCL
4329
+ if (coin === undefined) {
4330
+ return undefined;
4331
+ }
4332
+ if (this.safeDict(this.options['hip3TokensByName'], coin)) {
4333
+ const hip3Dict = this.options['hip3TokensByName'][coin];
4334
+ const quote = this.safeString(hip3Dict, 'quote', 'USDC');
4335
+ const code = this.safeString(hip3Dict, 'code', coin);
4336
+ return code + '/' + quote + ':' + quote;
4337
+ }
4235
4338
  if (coin.indexOf('/') > -1 || coin.indexOf('@') > -1) {
4236
4339
  return coin; // spot
4237
4340
  }
@@ -169,6 +169,9 @@ class kucoin extends kucoin$1["default"] {
169
169
  'margin/config': 25,
170
170
  'announcements': 20,
171
171
  'margin/collateralRatio': 10,
172
+ // convert
173
+ 'convert/symbol': 5,
174
+ 'convert/currencies': 5,
172
175
  },
173
176
  'post': {
174
177
  // ws
@@ -254,6 +257,13 @@ class kucoin extends kucoin$1["default"] {
254
257
  'broker/queryUser': 3,
255
258
  'broker/queryDetailByUid': 3,
256
259
  'migrate/user/account/status': 3,
260
+ // convert
261
+ 'convert/quote': 20,
262
+ 'convert/order/detail': 5,
263
+ 'convert/order/history': 5,
264
+ 'convert/limit/quote': 20,
265
+ 'convert/limit/order/detail': 5,
266
+ 'convert/limit/orders': 5,
257
267
  // affiliate
258
268
  'affiliate/inviter/statistics': 30,
259
269
  },
@@ -293,6 +303,9 @@ class kucoin extends kucoin$1["default"] {
293
303
  'purchase': 15,
294
304
  'redeem': 15,
295
305
  'lend/purchase/update': 10,
306
+ // convert
307
+ 'convert/order': 20,
308
+ 'convert/limit/order': 20,
296
309
  // ws
297
310
  'bullet-private': 10,
298
311
  'position/update-user-leverage': 5,
@@ -323,7 +336,9 @@ class kucoin extends kucoin$1["default"] {
323
336
  // margin trading
324
337
  'hf/margin/orders/{orderId}': 5,
325
338
  'hf/margin/orders/client-order/{clientOid}': 5,
326
- 'hf/margin/orders': 10, // 10SW
339
+ 'hf/margin/orders': 10,
340
+ // convert
341
+ 'convert/limit/order/cancel': 5,
327
342
  },
328
343
  },
329
344
  'futuresPublic': {
@@ -441,6 +456,7 @@ class kucoin extends kucoin$1["default"] {
441
456
  },
442
457
  'earn': {
443
458
  'get': {
459
+ 'otc-loan/discount-rate-configs': 10,
444
460
  'otc-loan/loan': 1,
445
461
  'otc-loan/accounts': 1,
446
462
  'earn/redeem-preview': 7.5,
@@ -449,10 +465,13 @@ class kucoin extends kucoin$1["default"] {
449
465
  'earn/promotion/products': 7.5,
450
466
  'earn/kcs-staking/products': 7.5,
451
467
  'earn/staking/products': 7.5,
452
- 'earn/eth-staking/products': 7.5, // 5EW
468
+ 'earn/eth-staking/products': 7.5,
469
+ 'struct-earn/dual/products': 4.5,
470
+ 'struct-earn/orders': 7.5,
453
471
  },
454
472
  'post': {
455
- 'earn/orders': 7.5, // 5EW
473
+ 'earn/orders': 7.5,
474
+ 'struct-earn/orders': 7.5,
456
475
  },
457
476
  'delete': {
458
477
  'earn/orders': 7.5, // 5EW
@@ -174,6 +174,7 @@ class mexc extends mexc$1["default"] {
174
174
  'get': {
175
175
  'ping': 1,
176
176
  'time': 1,
177
+ 'defaultSymbols': 1,
177
178
  'exchangeInfo': 10,
178
179
  'depth': 1,
179
180
  'trades': 5,
@@ -189,14 +190,19 @@ class mexc extends mexc$1["default"] {
189
190
  },
190
191
  'private': {
191
192
  'get': {
193
+ 'kyc/status': 1,
194
+ 'uid': 1,
192
195
  'order': 2,
193
196
  'openOrders': 3,
194
197
  'allOrders': 10,
195
198
  'account': 10,
196
199
  'myTrades': 10,
200
+ 'strategy/group': 20,
201
+ 'strategy/group/uid': 20,
197
202
  'tradeFee': 10,
198
203
  'sub-account/list': 1,
199
204
  'sub-account/apiKey': 1,
205
+ 'sub-account/asset': 1,
200
206
  'capital/config/getall': 10,
201
207
  'capital/deposit/hisrec': 1,
202
208
  'capital/withdraw/history': 1,
@@ -242,6 +248,7 @@ class mexc extends mexc$1["default"] {
242
248
  'sub-account/futures': 1,
243
249
  'sub-account/margin': 1,
244
250
  'batchOrders': 10,
251
+ 'strategy/group': 20,
245
252
  'capital/withdraw/apply': 1,
246
253
  'capital/withdraw': 1,
247
254
  'capital/transfer': 1,