ccxt 4.5.24 → 4.5.26

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.
package/dist/cjs/ccxt.js CHANGED
@@ -196,7 +196,7 @@ var xt$1 = require('./src/pro/xt.js');
196
196
 
197
197
  //-----------------------------------------------------------------------------
198
198
  // this is updated by vss.js when building
199
- const version = '4.5.24';
199
+ const version = '4.5.26';
200
200
  Exchange["default"].ccxtVersion = version;
201
201
  const exchanges = {
202
202
  'alpaca': alpaca["default"],
@@ -525,7 +525,6 @@ class bitmart extends bitmart$1["default"] {
525
525
  },
526
526
  'broad': {
527
527
  'You contract account available balance not enough': errors.InsufficientFunds,
528
- 'you contract account available balance not enough': errors.InsufficientFunds,
529
528
  'This trading pair does not support API trading': errors.BadSymbol, // {"message":"This trading pair does not support API trading","code":51008,"trace":"5d3ebd46-4e7a-4505-b37b-74464f398f01","data":{}}
530
529
  },
531
530
  },
@@ -5629,8 +5628,9 @@ class bitmart extends bitmart$1["default"] {
5629
5628
  //
5630
5629
  // {"errno":"OK","message":"INVALID_PARAMETER","code":49998,"trace":"eb5ebb54-23cd-4de2-9064-e090b6c3b2e3","data":null}
5631
5630
  //
5632
- const message = this.safeStringLower(response, 'message');
5633
- const isErrorMessage = (message !== undefined) && (message !== 'ok') && (message !== 'success');
5631
+ const message = this.safeString(response, 'message');
5632
+ const messageLower = message.toLowerCase();
5633
+ const isErrorMessage = (message !== undefined) && (messageLower !== 'ok') && (messageLower !== 'success');
5634
5634
  const errorCode = this.safeString(response, 'code');
5635
5635
  const isErrorCode = (errorCode !== undefined) && (errorCode !== '1000');
5636
5636
  if (isErrorCode || isErrorMessage) {
@@ -916,6 +916,10 @@ class htx extends htx$1["default"] {
916
916
  'order-marketorder-amount-min-error': errors.InvalidOrder,
917
917
  'order-limitorder-price-min-error': errors.InvalidOrder,
918
918
  'order-limitorder-price-max-error': errors.InvalidOrder,
919
+ 'order-limitorder-price-buy-min-error': errors.InvalidOrder,
920
+ 'order-limitorder-price-buy-max-error': errors.InvalidOrder,
921
+ 'order-limitorder-price-sell-min-error': errors.InvalidOrder,
922
+ 'order-limitorder-price-sell-max-error': errors.InvalidOrder,
919
923
  'order-stop-order-hit-trigger': errors.InvalidOrder,
920
924
  'order-value-min-error': errors.InvalidOrder,
921
925
  'order-invalid-price': errors.InvalidOrder,
@@ -7613,7 +7617,7 @@ class htx extends htx$1["default"] {
7613
7617
  }
7614
7618
  if ('status' in response) {
7615
7619
  //
7616
- // {"status":"error","err-code":"order-limitorder-amount-min-error","err-msg":"limit order amount error, min: `0.001`","data":null}
7620
+ // {"status":"error","err-code":"o-amount-min-error","err-msg":"limit order amount error, min: `0.001`","data":null}
7617
7621
  // {"status":"ok","data":{"errors":[{"order_id":"1349442392365359104","err_code":1061,"err_msg":"The order does not exist."}],"successes":""},"ts":1741773744526}
7618
7622
  //
7619
7623
  const status = this.safeString(response, 'status');
@@ -223,6 +223,7 @@ class hyperliquid extends hyperliquid$1["default"] {
223
223
  'defaultSlippage': 0.05,
224
224
  'marketHelperProps': ['hip3TokensByName', 'cachedCurrenciesById'],
225
225
  'zeroAddress': '0x0000000000000000000000000000000000000000',
226
+ // below will be filled automatically
226
227
  'spotCurrencyMapping': {
227
228
  'UDZ': '2Z',
228
229
  'UBONK': 'BONK',
@@ -363,51 +364,20 @@ class hyperliquid extends hyperliquid$1["default"] {
363
364
  if (this.markets === undefined) {
364
365
  throw new errors.ExchangeError(this.id + ' markets not loaded');
365
366
  }
366
- if (symbol in this.markets) {
367
- const market = this.markets[symbol];
368
- if (market['spot']) {
369
- const baseName = this.safeString(market, 'baseName');
370
- const spotCurrencyMapping = this.safeDict(this.options, 'spotCurrencyMapping', {});
371
- if (baseName in spotCurrencyMapping) {
372
- const unifiedBaseName = this.safeString(spotCurrencyMapping, baseName);
373
- const quote = this.safeString(market, 'quote');
374
- const newSymbol = this.safeCurrencyCode(unifiedBaseName) + '/' + quote;
375
- if (newSymbol in this.markets) {
376
- return this.markets[newSymbol];
377
- }
378
- }
379
- }
380
- }
381
- const res = super.market(symbol);
382
- return res;
383
- }
384
- safeMarket(marketId = undefined, market = undefined, delimiter = undefined, marketType = undefined) {
385
- if (marketId !== undefined) {
386
- if ((this.markets_by_id !== undefined) && (marketId in this.markets_by_id)) {
387
- const markets = this.markets_by_id[marketId];
388
- const numMarkets = markets.length;
389
- if (numMarkets === 1) {
390
- return markets[0];
391
- }
392
- else {
393
- if (numMarkets > 2) {
394
- throw new errors.ExchangeError(this.id + ' safeMarket() found more than two markets with the same market id ' + marketId);
395
- }
396
- const firstMarket = markets[0];
397
- const secondMarket = markets[1];
398
- if (this.safeString(firstMarket, 'type') !== this.safeString(secondMarket, 'type')) {
399
- throw new errors.ExchangeError(this.id + ' safeMarket() found two different market types with the same market id ' + marketId);
400
- }
401
- const baseCurrency = this.safeString(firstMarket, 'base');
402
- const spotCurrencyMapping = this.safeDict(this.options, 'spotCurrencyMapping', {});
403
- if (baseCurrency in spotCurrencyMapping) {
404
- return secondMarket;
405
- }
406
- return firstMarket;
367
+ if ((symbol !== undefined) && !(symbol in this.markets)) {
368
+ const symbolParts = symbol.split('/');
369
+ const baseName = this.safeString(symbolParts, 0);
370
+ const spotCurrencyMapping = this.safeDict(this.options, 'spotCurrencyMapping', {});
371
+ if (baseName in spotCurrencyMapping) {
372
+ const unifiedBaseName = this.safeString(spotCurrencyMapping, baseName);
373
+ const quote = this.safeString(symbolParts, 1);
374
+ const newSymbol = this.safeCurrencyCode(unifiedBaseName) + '/' + quote;
375
+ if (newSymbol in this.markets) {
376
+ return this.markets[newSymbol];
407
377
  }
408
378
  }
409
379
  }
410
- return super.safeMarket(marketId, market, delimiter, marketType);
380
+ return super.market(symbol);
411
381
  }
412
382
  /**
413
383
  * @method
@@ -518,6 +488,20 @@ class hyperliquid extends hyperliquid$1["default"] {
518
488
  },
519
489
  },
520
490
  });
491
+ // add in wrapped map
492
+ const fullName = this.safeString(data, 'fullName');
493
+ if (fullName !== undefined && name !== undefined) {
494
+ const isWrapped = fullName.startsWith('Unit ') && name.startsWith('U');
495
+ if (isWrapped) {
496
+ const parts = name.split('U');
497
+ let nameWithoutU = '';
498
+ for (let j = 0; j < parts.length; j++) {
499
+ nameWithoutU = nameWithoutU + parts[j];
500
+ }
501
+ const baseCode = this.safeCurrencyCode(nameWithoutU);
502
+ this.options['spotCurrencyMapping'][code] = baseCode;
503
+ }
504
+ }
521
505
  }
522
506
  return result;
523
507
  }
@@ -951,18 +935,18 @@ class hyperliquid extends hyperliquid$1["default"] {
951
935
  'info': this.extend(extraData, market),
952
936
  };
953
937
  markets.push(this.safeMarketStructure(entry));
954
- // backward support
955
- const base = this.safeCurrencyCode(baseName);
956
- const quote = this.safeCurrencyCode(quoteId);
957
- const newEntry = this.extend({}, entry);
958
- const symbol = base + '/' + quote;
959
- if (symbol !== mappedSymbol) {
960
- newEntry['symbol'] = symbol;
961
- newEntry['base'] = base;
962
- newEntry['quote'] = quote;
963
- newEntry['baseName'] = baseName;
964
- markets.push(this.safeMarketStructure(newEntry));
965
- }
938
+ // // backward support
939
+ // const base = this.safeCurrencyCode (baseName);
940
+ // const quote = this.safeCurrencyCode (quoteId);
941
+ // const newEntry = this.extend ({}, entry);
942
+ // const symbol = base + '/' + quote;
943
+ // if (symbol !== mappedSymbol) {
944
+ // newEntry['symbol'] = symbol;
945
+ // newEntry['base'] = base;
946
+ // newEntry['quote'] = quote;
947
+ // newEntry['baseName'] = baseName;
948
+ // markets.push (this.safeMarketStructure (newEntry));
949
+ // }
966
950
  }
967
951
  return markets;
968
952
  }
@@ -1242,9 +1226,11 @@ class hyperliquid extends hyperliquid$1["default"] {
1242
1226
  if (symbols !== undefined) {
1243
1227
  // infer from first symbol
1244
1228
  const firstSymbol = this.safeString(symbols, 0);
1245
- const market = this.market(firstSymbol);
1246
- if (this.safeBool(this.safeDict(market, 'info'), 'hip3')) {
1247
- hip3 = true;
1229
+ if (firstSymbol !== undefined) {
1230
+ const market = this.market(firstSymbol);
1231
+ if (this.safeBool(this.safeDict(market, 'info'), 'hip3')) {
1232
+ hip3 = true;
1233
+ }
1248
1234
  }
1249
1235
  }
1250
1236
  if (hip3) {
@@ -1513,7 +1499,10 @@ class hyperliquid extends hyperliquid$1["default"] {
1513
1499
  let userAddress = undefined;
1514
1500
  [userAddress, params] = this.handlePublicAddress('fetchTrades', params);
1515
1501
  await this.loadMarkets();
1516
- const market = this.safeMarket(symbol);
1502
+ let market = undefined;
1503
+ if (symbol !== undefined) {
1504
+ market = this.market(symbol);
1505
+ }
1517
1506
  const request = {
1518
1507
  'user': userAddress,
1519
1508
  };
@@ -2826,7 +2815,10 @@ class hyperliquid extends hyperliquid$1["default"] {
2826
2815
  let userAddress = undefined;
2827
2816
  [userAddress, params] = this.handlePublicAddress('fetchOrder', params);
2828
2817
  await this.loadMarkets();
2829
- const market = this.safeMarket(symbol);
2818
+ let market = undefined;
2819
+ if (symbol !== undefined) {
2820
+ market = this.market(symbol);
2821
+ }
2830
2822
  const clientOrderId = this.safeString(params, 'clientOrderId');
2831
2823
  const request = {
2832
2824
  'type': 'orderStatus',
@@ -3076,7 +3068,10 @@ class hyperliquid extends hyperliquid$1["default"] {
3076
3068
  let userAddress = undefined;
3077
3069
  [userAddress, params] = this.handlePublicAddress('fetchMyTrades', params);
3078
3070
  await this.loadMarkets();
3079
- const market = this.safeMarket(symbol);
3071
+ let market = undefined;
3072
+ if (symbol !== undefined) {
3073
+ market = this.market(symbol);
3074
+ }
3080
3075
  const request = {
3081
3076
  'user': userAddress,
3082
3077
  };
@@ -3187,6 +3182,30 @@ class hyperliquid extends hyperliquid$1["default"] {
3187
3182
  const positions = await this.fetchPositions([symbol], params);
3188
3183
  return this.safeDict(positions, 0, {});
3189
3184
  }
3185
+ getDexFromSymbols(methodName, symbols = undefined) {
3186
+ if (symbols === undefined) {
3187
+ return undefined;
3188
+ }
3189
+ const symbolsLength = symbols.length;
3190
+ if (symbolsLength === 0) {
3191
+ return undefined;
3192
+ }
3193
+ let dexName = undefined;
3194
+ for (let i = 0; i < symbolsLength; i++) {
3195
+ if (dexName === undefined) {
3196
+ const market = this.market(symbols[i]);
3197
+ dexName = this.getDexFromHip3Symbol(market);
3198
+ }
3199
+ else {
3200
+ const market = this.market(symbols[i]);
3201
+ const currentDexName = this.getDexFromHip3Symbol(market);
3202
+ if (currentDexName !== dexName) {
3203
+ throw new errors.NotSupported(this.id + ' ' + methodName + ' only supports fetching positions for one DEX at a time for HIP3 markets');
3204
+ }
3205
+ }
3206
+ }
3207
+ return dexName;
3208
+ }
3190
3209
  /**
3191
3210
  * @method
3192
3211
  * @name hyperliquid#fetchPositions
@@ -3208,12 +3227,9 @@ class hyperliquid extends hyperliquid$1["default"] {
3208
3227
  'type': 'clearinghouseState',
3209
3228
  'user': userAddress,
3210
3229
  };
3211
- if (symbols !== undefined) {
3212
- const market = this.market(symbols[0]);
3213
- const dexName = this.getDexFromHip3Symbol(market);
3214
- if (dexName !== undefined) {
3215
- request['dex'] = dexName;
3216
- }
3230
+ const dexName = this.getDexFromSymbols('fetchPositions', symbols);
3231
+ if (dexName !== undefined) {
3232
+ request['dex'] = dexName;
3217
3233
  }
3218
3234
  const response = await this.publicPostInfo(this.extend(request, params));
3219
3235
  //
@@ -1759,8 +1759,8 @@ class mexc extends mexc$1["default"] {
1759
1759
  /**
1760
1760
  * @method
1761
1761
  * @name mexc#fetchOHLCV
1762
- * @see https://mexcdevelop.github.io/apidocs/spot_v3_en/#kline-candlestick-data
1763
- * @see https://mexcdevelop.github.io/apidocs/contract_v1_en/#k-line-data
1762
+ * @see https://www.mexc.com/api-docs/spot-v3/market-data-endpoints#klinecandlestick-data
1763
+ * @see https://www.mexc.com/api-docs/futures/market-endpoints#get-candlestick-data
1764
1764
  * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1765
1765
  * @param {string} symbol unified symbol of the market to fetch OHLCV data for
1766
1766
  * @param {string} timeframe the length of time each candle represents
@@ -1774,7 +1774,7 @@ class mexc extends mexc$1["default"] {
1774
1774
  async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
1775
1775
  await this.loadMarkets();
1776
1776
  const market = this.market(symbol);
1777
- const maxLimit = (market['spot']) ? 1000 : 2000;
1777
+ const maxLimit = (market['spot']) ? 500 : 2000; // docs say 1000 for spot, but in practice it's 500
1778
1778
  let paginate = false;
1779
1779
  [paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate', false);
1780
1780
  if (paginate) {
@@ -1789,10 +1789,16 @@ class mexc extends mexc$1["default"] {
1789
1789
  'interval': timeframeValue,
1790
1790
  };
1791
1791
  let candles = undefined;
1792
+ const until = this.safeIntegerN(params, ['until', 'endTime']);
1793
+ let start = since;
1794
+ if ((until !== undefined) && (since === undefined)) {
1795
+ params = this.omit(params, ['until']);
1796
+ const usedLimit = limit ? limit : maxLimit;
1797
+ start = until - (usedLimit * duration);
1798
+ }
1792
1799
  if (market['spot']) {
1793
- const until = this.safeIntegerN(params, ['until', 'endTime']);
1794
- if (since !== undefined) {
1795
- request['startTime'] = since;
1800
+ if (start !== undefined) {
1801
+ request['startTime'] = start;
1796
1802
  if (until === undefined) {
1797
1803
  // we have to calculate it assuming we can get at most 2000 entries per request
1798
1804
  const end = this.sum(since, maxLimit * duration);
@@ -1804,8 +1810,7 @@ class mexc extends mexc$1["default"] {
1804
1810
  request['limit'] = limit;
1805
1811
  }
1806
1812
  if (until !== undefined) {
1807
- params = this.omit(params, ['until']);
1808
- request['endTime'] = until;
1813
+ request['endTime'] = until + 1; // mexc's endTime is not inclusive, so we add 1 ms to avoid missing the last candle in the results
1809
1814
  }
1810
1815
  const response = await this.spotPublicGetKlines(this.extend(request, params));
1811
1816
  //
@@ -1825,13 +1830,14 @@ class mexc extends mexc$1["default"] {
1825
1830
  candles = response;
1826
1831
  }
1827
1832
  else if (market['swap']) {
1828
- const until = this.safeIntegerProductN(params, ['until', 'endTime'], 0.001);
1829
1833
  if (since !== undefined) {
1830
1834
  request['start'] = this.parseToInt(since / 1000);
1831
1835
  }
1832
1836
  if (until !== undefined) {
1833
- params = this.omit(params, ['until']);
1834
- request['end'] = until;
1837
+ request['end'] = this.parseToInt(until / 1000);
1838
+ if (since === undefined) {
1839
+ request['start'] = this.parseToInt(start / 1000);
1840
+ }
1835
1841
  }
1836
1842
  const priceType = this.safeString(params, 'price', 'default');
1837
1843
  params = this.omit(params, 'price');
package/js/ccxt.d.ts CHANGED
@@ -4,7 +4,7 @@ import * as functions from './src/base/functions.js';
4
4
  import * as errors from './src/base/errors.js';
5
5
  import type { Int, int, Str, Strings, Num, Bool, IndexType, OrderSide, OrderType, MarketType, SubType, Dict, NullableDict, List, NullableList, Fee, OHLCV, OHLCVC, implicitReturnType, Market, Currency, Dictionary, MinMax, FeeInterface, TradingFeeInterface, MarketInterface, Trade, Order, OrderBook, Ticker, Transaction, Tickers, CurrencyInterface, Balance, BalanceAccount, Account, PartialBalances, Balances, DepositAddress, WithdrawalResponse, FundingRate, FundingRates, Position, BorrowInterest, LeverageTier, LedgerEntry, DepositWithdrawFeeNetwork, DepositWithdrawFee, TransferEntry, CrossBorrowRate, IsolatedBorrowRate, FundingRateHistory, OpenInterest, Liquidation, OrderRequest, CancellationRequest, FundingHistory, MarketMarginModes, MarginMode, Greeks, Conversion, Option, LastPrice, Leverage, MarginModification, Leverages, LastPrices, Currencies, TradingFees, MarginModes, OptionChain, IsolatedBorrowRates, CrossBorrowRates, LeverageTiers, LongShortRatio, OrderBooks, OpenInterests, ConstructorArgs } from './src/base/types.js';
6
6
  import { BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, MarketClosed, ManualInteractionNeeded, RestrictedLocation, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, InvalidProxySettings, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, ChecksumError, RequestTimeout, BadResponse, NullResponse, CancelPending, UnsubscribeError } from './src/base/errors.js';
7
- declare const version = "4.5.23";
7
+ declare const version = "4.5.25";
8
8
  import alpaca from './src/alpaca.js';
9
9
  import apex from './src/apex.js';
10
10
  import arkham from './src/arkham.js';
package/js/ccxt.js CHANGED
@@ -38,7 +38,7 @@ import * as errors from './src/base/errors.js';
38
38
  import { BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, MarketClosed, ManualInteractionNeeded, RestrictedLocation, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, InvalidProxySettings, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, ChecksumError, RequestTimeout, BadResponse, NullResponse, CancelPending, UnsubscribeError } from './src/base/errors.js';
39
39
  //-----------------------------------------------------------------------------
40
40
  // this is updated by vss.js when building
41
- const version = '4.5.23';
41
+ const version = '4.5.25';
42
42
  Exchange.ccxtVersion = version;
43
43
  //-----------------------------------------------------------------------------
44
44
  import alpaca from './src/alpaca.js';
package/js/src/bitmart.js CHANGED
@@ -526,7 +526,6 @@ export default class bitmart extends Exchange {
526
526
  },
527
527
  'broad': {
528
528
  'You contract account available balance not enough': InsufficientFunds,
529
- 'you contract account available balance not enough': InsufficientFunds,
530
529
  'This trading pair does not support API trading': BadSymbol, // {"message":"This trading pair does not support API trading","code":51008,"trace":"5d3ebd46-4e7a-4505-b37b-74464f398f01","data":{}}
531
530
  },
532
531
  },
@@ -5630,8 +5629,9 @@ export default class bitmart extends Exchange {
5630
5629
  //
5631
5630
  // {"errno":"OK","message":"INVALID_PARAMETER","code":49998,"trace":"eb5ebb54-23cd-4de2-9064-e090b6c3b2e3","data":null}
5632
5631
  //
5633
- const message = this.safeStringLower(response, 'message');
5634
- const isErrorMessage = (message !== undefined) && (message !== 'ok') && (message !== 'success');
5632
+ const message = this.safeString(response, 'message');
5633
+ const messageLower = message.toLowerCase();
5634
+ const isErrorMessage = (message !== undefined) && (messageLower !== 'ok') && (messageLower !== 'success');
5635
5635
  const errorCode = this.safeString(response, 'code');
5636
5636
  const isErrorCode = (errorCode !== undefined) && (errorCode !== '1000');
5637
5637
  if (isErrorCode || isErrorMessage) {
package/js/src/htx.js CHANGED
@@ -917,6 +917,10 @@ export default class htx extends Exchange {
917
917
  'order-marketorder-amount-min-error': InvalidOrder,
918
918
  'order-limitorder-price-min-error': InvalidOrder,
919
919
  'order-limitorder-price-max-error': InvalidOrder,
920
+ 'order-limitorder-price-buy-min-error': InvalidOrder,
921
+ 'order-limitorder-price-buy-max-error': InvalidOrder,
922
+ 'order-limitorder-price-sell-min-error': InvalidOrder,
923
+ 'order-limitorder-price-sell-max-error': InvalidOrder,
920
924
  'order-stop-order-hit-trigger': InvalidOrder,
921
925
  'order-value-min-error': InvalidOrder,
922
926
  'order-invalid-price': InvalidOrder,
@@ -7614,7 +7618,7 @@ export default class htx extends Exchange {
7614
7618
  }
7615
7619
  if ('status' in response) {
7616
7620
  //
7617
- // {"status":"error","err-code":"order-limitorder-amount-min-error","err-msg":"limit order amount error, min: `0.001`","data":null}
7621
+ // {"status":"error","err-code":"o-amount-min-error","err-msg":"limit order amount error, min: `0.001`","data":null}
7618
7622
  // {"status":"ok","data":{"errors":[{"order_id":"1349442392365359104","err_code":1061,"err_msg":"The order does not exist."}],"successes":""},"ts":1741773744526}
7619
7623
  //
7620
7624
  const status = this.safeString(response, 'status');
@@ -8,7 +8,6 @@ export default class hyperliquid extends Exchange {
8
8
  describe(): any;
9
9
  setSandboxMode(enabled: any): void;
10
10
  market(symbol: string): MarketInterface;
11
- safeMarket(marketId?: Str, market?: Market, delimiter?: Str, marketType?: Str): MarketInterface;
12
11
  /**
13
12
  * @method
14
13
  * @name hyperliquid#fetchStatus
@@ -483,6 +482,7 @@ export default class hyperliquid extends Exchange {
483
482
  * @returns {object} a [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
484
483
  */
485
484
  fetchPosition(symbol: string, params?: {}): Promise<Position>;
485
+ getDexFromSymbols(methodName: string, symbols?: Strings): any;
486
486
  /**
487
487
  * @method
488
488
  * @name hyperliquid#fetchPositions
@@ -224,6 +224,7 @@ export default class hyperliquid extends Exchange {
224
224
  'defaultSlippage': 0.05,
225
225
  'marketHelperProps': ['hip3TokensByName', 'cachedCurrenciesById'],
226
226
  'zeroAddress': '0x0000000000000000000000000000000000000000',
227
+ // below will be filled automatically
227
228
  'spotCurrencyMapping': {
228
229
  'UDZ': '2Z',
229
230
  'UBONK': 'BONK',
@@ -364,51 +365,20 @@ export default class hyperliquid extends Exchange {
364
365
  if (this.markets === undefined) {
365
366
  throw new ExchangeError(this.id + ' markets not loaded');
366
367
  }
367
- if (symbol in this.markets) {
368
- const market = this.markets[symbol];
369
- if (market['spot']) {
370
- const baseName = this.safeString(market, 'baseName');
371
- const spotCurrencyMapping = this.safeDict(this.options, 'spotCurrencyMapping', {});
372
- if (baseName in spotCurrencyMapping) {
373
- const unifiedBaseName = this.safeString(spotCurrencyMapping, baseName);
374
- const quote = this.safeString(market, 'quote');
375
- const newSymbol = this.safeCurrencyCode(unifiedBaseName) + '/' + quote;
376
- if (newSymbol in this.markets) {
377
- return this.markets[newSymbol];
378
- }
379
- }
380
- }
381
- }
382
- const res = super.market(symbol);
383
- return res;
384
- }
385
- safeMarket(marketId = undefined, market = undefined, delimiter = undefined, marketType = undefined) {
386
- if (marketId !== undefined) {
387
- if ((this.markets_by_id !== undefined) && (marketId in this.markets_by_id)) {
388
- const markets = this.markets_by_id[marketId];
389
- const numMarkets = markets.length;
390
- if (numMarkets === 1) {
391
- return markets[0];
392
- }
393
- else {
394
- if (numMarkets > 2) {
395
- throw new ExchangeError(this.id + ' safeMarket() found more than two markets with the same market id ' + marketId);
396
- }
397
- const firstMarket = markets[0];
398
- const secondMarket = markets[1];
399
- if (this.safeString(firstMarket, 'type') !== this.safeString(secondMarket, 'type')) {
400
- throw new ExchangeError(this.id + ' safeMarket() found two different market types with the same market id ' + marketId);
401
- }
402
- const baseCurrency = this.safeString(firstMarket, 'base');
403
- const spotCurrencyMapping = this.safeDict(this.options, 'spotCurrencyMapping', {});
404
- if (baseCurrency in spotCurrencyMapping) {
405
- return secondMarket;
406
- }
407
- return firstMarket;
368
+ if ((symbol !== undefined) && !(symbol in this.markets)) {
369
+ const symbolParts = symbol.split('/');
370
+ const baseName = this.safeString(symbolParts, 0);
371
+ const spotCurrencyMapping = this.safeDict(this.options, 'spotCurrencyMapping', {});
372
+ if (baseName in spotCurrencyMapping) {
373
+ const unifiedBaseName = this.safeString(spotCurrencyMapping, baseName);
374
+ const quote = this.safeString(symbolParts, 1);
375
+ const newSymbol = this.safeCurrencyCode(unifiedBaseName) + '/' + quote;
376
+ if (newSymbol in this.markets) {
377
+ return this.markets[newSymbol];
408
378
  }
409
379
  }
410
380
  }
411
- return super.safeMarket(marketId, market, delimiter, marketType);
381
+ return super.market(symbol);
412
382
  }
413
383
  /**
414
384
  * @method
@@ -519,6 +489,20 @@ export default class hyperliquid extends Exchange {
519
489
  },
520
490
  },
521
491
  });
492
+ // add in wrapped map
493
+ const fullName = this.safeString(data, 'fullName');
494
+ if (fullName !== undefined && name !== undefined) {
495
+ const isWrapped = fullName.startsWith('Unit ') && name.startsWith('U');
496
+ if (isWrapped) {
497
+ const parts = name.split('U');
498
+ let nameWithoutU = '';
499
+ for (let j = 0; j < parts.length; j++) {
500
+ nameWithoutU = nameWithoutU + parts[j];
501
+ }
502
+ const baseCode = this.safeCurrencyCode(nameWithoutU);
503
+ this.options['spotCurrencyMapping'][code] = baseCode;
504
+ }
505
+ }
522
506
  }
523
507
  return result;
524
508
  }
@@ -952,18 +936,18 @@ export default class hyperliquid extends Exchange {
952
936
  'info': this.extend(extraData, market),
953
937
  };
954
938
  markets.push(this.safeMarketStructure(entry));
955
- // backward support
956
- const base = this.safeCurrencyCode(baseName);
957
- const quote = this.safeCurrencyCode(quoteId);
958
- const newEntry = this.extend({}, entry);
959
- const symbol = base + '/' + quote;
960
- if (symbol !== mappedSymbol) {
961
- newEntry['symbol'] = symbol;
962
- newEntry['base'] = base;
963
- newEntry['quote'] = quote;
964
- newEntry['baseName'] = baseName;
965
- markets.push(this.safeMarketStructure(newEntry));
966
- }
939
+ // // backward support
940
+ // const base = this.safeCurrencyCode (baseName);
941
+ // const quote = this.safeCurrencyCode (quoteId);
942
+ // const newEntry = this.extend ({}, entry);
943
+ // const symbol = base + '/' + quote;
944
+ // if (symbol !== mappedSymbol) {
945
+ // newEntry['symbol'] = symbol;
946
+ // newEntry['base'] = base;
947
+ // newEntry['quote'] = quote;
948
+ // newEntry['baseName'] = baseName;
949
+ // markets.push (this.safeMarketStructure (newEntry));
950
+ // }
967
951
  }
968
952
  return markets;
969
953
  }
@@ -1243,9 +1227,11 @@ export default class hyperliquid extends Exchange {
1243
1227
  if (symbols !== undefined) {
1244
1228
  // infer from first symbol
1245
1229
  const firstSymbol = this.safeString(symbols, 0);
1246
- const market = this.market(firstSymbol);
1247
- if (this.safeBool(this.safeDict(market, 'info'), 'hip3')) {
1248
- hip3 = true;
1230
+ if (firstSymbol !== undefined) {
1231
+ const market = this.market(firstSymbol);
1232
+ if (this.safeBool(this.safeDict(market, 'info'), 'hip3')) {
1233
+ hip3 = true;
1234
+ }
1249
1235
  }
1250
1236
  }
1251
1237
  if (hip3) {
@@ -1514,7 +1500,10 @@ export default class hyperliquid extends Exchange {
1514
1500
  let userAddress = undefined;
1515
1501
  [userAddress, params] = this.handlePublicAddress('fetchTrades', params);
1516
1502
  await this.loadMarkets();
1517
- const market = this.safeMarket(symbol);
1503
+ let market = undefined;
1504
+ if (symbol !== undefined) {
1505
+ market = this.market(symbol);
1506
+ }
1518
1507
  const request = {
1519
1508
  'user': userAddress,
1520
1509
  };
@@ -2827,7 +2816,10 @@ export default class hyperliquid extends Exchange {
2827
2816
  let userAddress = undefined;
2828
2817
  [userAddress, params] = this.handlePublicAddress('fetchOrder', params);
2829
2818
  await this.loadMarkets();
2830
- const market = this.safeMarket(symbol);
2819
+ let market = undefined;
2820
+ if (symbol !== undefined) {
2821
+ market = this.market(symbol);
2822
+ }
2831
2823
  const clientOrderId = this.safeString(params, 'clientOrderId');
2832
2824
  const request = {
2833
2825
  'type': 'orderStatus',
@@ -3077,7 +3069,10 @@ export default class hyperliquid extends Exchange {
3077
3069
  let userAddress = undefined;
3078
3070
  [userAddress, params] = this.handlePublicAddress('fetchMyTrades', params);
3079
3071
  await this.loadMarkets();
3080
- const market = this.safeMarket(symbol);
3072
+ let market = undefined;
3073
+ if (symbol !== undefined) {
3074
+ market = this.market(symbol);
3075
+ }
3081
3076
  const request = {
3082
3077
  'user': userAddress,
3083
3078
  };
@@ -3188,6 +3183,30 @@ export default class hyperliquid extends Exchange {
3188
3183
  const positions = await this.fetchPositions([symbol], params);
3189
3184
  return this.safeDict(positions, 0, {});
3190
3185
  }
3186
+ getDexFromSymbols(methodName, symbols = undefined) {
3187
+ if (symbols === undefined) {
3188
+ return undefined;
3189
+ }
3190
+ const symbolsLength = symbols.length;
3191
+ if (symbolsLength === 0) {
3192
+ return undefined;
3193
+ }
3194
+ let dexName = undefined;
3195
+ for (let i = 0; i < symbolsLength; i++) {
3196
+ if (dexName === undefined) {
3197
+ const market = this.market(symbols[i]);
3198
+ dexName = this.getDexFromHip3Symbol(market);
3199
+ }
3200
+ else {
3201
+ const market = this.market(symbols[i]);
3202
+ const currentDexName = this.getDexFromHip3Symbol(market);
3203
+ if (currentDexName !== dexName) {
3204
+ throw new NotSupported(this.id + ' ' + methodName + ' only supports fetching positions for one DEX at a time for HIP3 markets');
3205
+ }
3206
+ }
3207
+ }
3208
+ return dexName;
3209
+ }
3191
3210
  /**
3192
3211
  * @method
3193
3212
  * @name hyperliquid#fetchPositions
@@ -3209,12 +3228,9 @@ export default class hyperliquid extends Exchange {
3209
3228
  'type': 'clearinghouseState',
3210
3229
  'user': userAddress,
3211
3230
  };
3212
- if (symbols !== undefined) {
3213
- const market = this.market(symbols[0]);
3214
- const dexName = this.getDexFromHip3Symbol(market);
3215
- if (dexName !== undefined) {
3216
- request['dex'] = dexName;
3217
- }
3231
+ const dexName = this.getDexFromSymbols('fetchPositions', symbols);
3232
+ if (dexName !== undefined) {
3233
+ request['dex'] = dexName;
3218
3234
  }
3219
3235
  const response = await this.publicPostInfo(this.extend(request, params));
3220
3236
  //