ccxt 4.0.79 → 4.0.81

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 (67) hide show
  1. package/CHANGELOG.md +169 -0
  2. package/README.md +3 -3
  3. package/dist/ccxt.browser.js +257 -139
  4. package/dist/ccxt.browser.min.js +3 -3
  5. package/dist/cjs/ccxt.js +1 -1
  6. package/dist/cjs/src/binance.js +9 -0
  7. package/dist/cjs/src/bitget.js +9 -4
  8. package/dist/cjs/src/bitmex.js +5 -3
  9. package/dist/cjs/src/bybit.js +4 -11
  10. package/dist/cjs/src/coinsph.js +2 -2
  11. package/dist/cjs/src/delta.js +3 -0
  12. package/dist/cjs/src/exmo.js +64 -25
  13. package/dist/cjs/src/gate.js +2 -0
  14. package/dist/cjs/src/hitbtc.js +3 -1
  15. package/dist/cjs/src/huobi.js +2 -0
  16. package/dist/cjs/src/krakenfutures.js +2 -2
  17. package/dist/cjs/src/kucoin.js +96 -69
  18. package/dist/cjs/src/okcoin.js +2 -2
  19. package/dist/cjs/src/okx.js +1 -1
  20. package/dist/cjs/src/pro/bitget.js +18 -2
  21. package/dist/cjs/src/pro/gate.js +5 -3
  22. package/dist/cjs/src/pro/kraken.js +2 -2
  23. package/dist/cjs/src/pro/krakenfutures.js +1 -1
  24. package/dist/cjs/src/pro/okx.js +8 -3
  25. package/dist/cjs/src/pro/probit.js +2 -2
  26. package/dist/cjs/src/probit.js +2 -2
  27. package/dist/cjs/src/upbit.js +9 -1
  28. package/dist/cjs/src/wavesexchange.js +4 -2
  29. package/dist/cjs/src/wazirx.js +1 -0
  30. package/js/ccxt.d.ts +1 -1
  31. package/js/ccxt.js +1 -1
  32. package/js/src/abstract/binance.d.ts +9 -0
  33. package/js/src/abstract/binancecoinm.d.ts +9 -0
  34. package/js/src/abstract/binanceus.d.ts +9 -0
  35. package/js/src/abstract/binanceusdm.d.ts +9 -0
  36. package/js/src/abstract/bybit.d.ts +1 -0
  37. package/js/src/abstract/gate.d.ts +2 -0
  38. package/js/src/abstract/gateio.d.ts +2 -0
  39. package/js/src/abstract/huobi.d.ts +2 -0
  40. package/js/src/abstract/huobipro.d.ts +2 -0
  41. package/js/src/binance.js +9 -0
  42. package/js/src/bitget.js +9 -4
  43. package/js/src/bitmex.d.ts +1 -1
  44. package/js/src/bitmex.js +5 -3
  45. package/js/src/bybit.js +4 -11
  46. package/js/src/coinsph.js +2 -2
  47. package/js/src/delta.js +3 -0
  48. package/js/src/exmo.js +64 -25
  49. package/js/src/gate.js +2 -0
  50. package/js/src/hitbtc.js +3 -1
  51. package/js/src/huobi.js +2 -0
  52. package/js/src/krakenfutures.js +2 -2
  53. package/js/src/kucoin.js +96 -69
  54. package/js/src/okcoin.js +2 -2
  55. package/js/src/okx.js +1 -1
  56. package/js/src/pro/bitget.js +19 -3
  57. package/js/src/pro/gate.js +5 -3
  58. package/js/src/pro/kraken.js +2 -2
  59. package/js/src/pro/krakenfutures.js +1 -1
  60. package/js/src/pro/okx.js +8 -3
  61. package/js/src/pro/probit.js +2 -2
  62. package/js/src/probit.js +2 -2
  63. package/js/src/upbit.js +10 -2
  64. package/js/src/wavesexchange.js +4 -2
  65. package/js/src/wazirx.js +1 -0
  66. package/package.json +1 -1
  67. package/skip-tests.json +7 -2
@@ -15795,6 +15795,12 @@ class binance extends _abstract_binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
15795
15795
  'loan/loanable/data': 40,
15796
15796
  'loan/collateral/data': 40,
15797
15797
  'loan/repay/collateral/rate': 600,
15798
+ 'loan/flexible/ongoing/orders': 30,
15799
+ 'loan/flexible/borrow/history': 40,
15800
+ 'loan/flexible/repay/history': 40,
15801
+ 'loan/flexible/ltv/adjustment/history': 40,
15802
+ 'loan/flexible/loanable/data': 40,
15803
+ 'loan/flexible/collateral/data': 40,
15798
15804
  'loan/vip/ongoing/orders': 40,
15799
15805
  'loan/vip/repay/history': 40,
15800
15806
  'loan/vip/collateral/account': 600,
@@ -16060,6 +16066,9 @@ class binance extends _abstract_binance_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
16060
16066
  'loan/repay': 40.002,
16061
16067
  'loan/adjust/ltv': 40.002,
16062
16068
  'loan/customize/margin_call': 40.002,
16069
+ 'loan/flexible/borrow': 40.002,
16070
+ 'loan/flexible/repay': 40.002,
16071
+ 'loan/flexible/adjust/ltv': 40.002,
16063
16072
  'loan/vip/repay': 40.002,
16064
16073
  'convert/getQuote': 1.3334,
16065
16074
  'convert/acceptQuote': 3.3335,
@@ -40924,6 +40933,8 @@ class bitget extends _abstract_bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
40924
40933
  * @method
40925
40934
  * @name bitget#fetchMyTrades
40926
40935
  * @description fetch all trades made by the user
40936
+ * @see https://bitgetlimited.github.io/apidoc/en/spot/#get-transaction-details
40937
+ * @see https://bitgetlimited.github.io/apidoc/en/mix/#get-order-fill-detail
40927
40938
  * @param {string} symbol unified market symbol
40928
40939
  * @param {int} [since] the earliest time in ms to fetch trades for
40929
40940
  * @param {int} [limit] the maximum number of trades structures to retrieve
@@ -40933,16 +40944,19 @@ class bitget extends _abstract_bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
40933
40944
  this.checkRequiredSymbol('fetchMyTrades', symbol);
40934
40945
  await this.loadMarkets();
40935
40946
  const market = this.market(symbol);
40936
- if (market['swap']) {
40937
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadSymbol(this.id + ' fetchMyTrades() only supports spot markets');
40938
- }
40939
40947
  const request = {
40940
40948
  'symbol': market['id'],
40941
40949
  };
40942
40950
  if (limit !== undefined) {
40943
40951
  request['limit'] = limit;
40944
40952
  }
40945
- const response = await this.privateSpotPostTradeFills(this.extend(request, params));
40953
+ let response = undefined;
40954
+ if (market['spot']) {
40955
+ response = await this.privateSpotPostTradeFills(this.extend(request, params));
40956
+ }
40957
+ else {
40958
+ response = await this.privateMixGetOrderFills(this.extend(request, params));
40959
+ }
40946
40960
  //
40947
40961
  // {
40948
40962
  // code: '00000',
@@ -47848,8 +47862,8 @@ class bitmex extends _abstract_bitmex_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
47848
47862
  'change': undefined,
47849
47863
  'percentage': undefined,
47850
47864
  'average': undefined,
47851
- 'baseVolume': this.convertFromRawQuantity(symbol, this.safeString(ticker, 'homeNotional24h')),
47852
- 'quoteVolume': this.convertFromRawQuantity(symbol, this.safeString(ticker, 'foreignNotional24h')),
47865
+ 'baseVolume': this.safeString(ticker, 'homeNotional24h'),
47866
+ 'quoteVolume': this.safeString(ticker, 'foreignNotional24h'),
47853
47867
  'info': ticker,
47854
47868
  }, market);
47855
47869
  }
@@ -48771,7 +48785,9 @@ class bitmex extends _abstract_bitmex_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
48771
48785
  filteredResponse.push(item);
48772
48786
  }
48773
48787
  }
48774
- return this.parseFundingRates(filteredResponse, symbols);
48788
+ symbols = this.marketSymbols(symbols);
48789
+ const result = this.parseFundingRates(filteredResponse);
48790
+ return this.filterByArray(result, 'symbol', symbols);
48775
48791
  }
48776
48792
  parseFundingRate(contract, market = undefined) {
48777
48793
  // see response sample under "fetchMarkets" because same endpoint is being used here
@@ -71536,6 +71552,7 @@ class bybit extends _abstract_bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
71536
71552
  'v5/spot-lever-token/info': 2.5,
71537
71553
  'v5/spot-lever-token/reference': 2.5,
71538
71554
  // spot margin trade
71555
+ 'v5/spot-margin-trade/data': 2.5,
71539
71556
  'v5/spot-cross-margin-trade/data': 2.5,
71540
71557
  'v5/spot-cross-margin-trade/pledge-token': 2.5,
71541
71558
  'v5/spot-cross-margin-trade/borrow-token': 2.5,
@@ -73815,7 +73832,8 @@ class bybit extends _abstract_bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
73815
73832
  if (symbols !== undefined) {
73816
73833
  symbols = this.marketSymbols(symbols);
73817
73834
  market = this.market(symbols[0]);
73818
- if (symbols.length === 1) {
73835
+ const symbolsLength = symbols.length;
73836
+ if (symbolsLength === 1) {
73819
73837
  request['symbol'] = market['id'];
73820
73838
  }
73821
73839
  }
@@ -75199,7 +75217,7 @@ class bybit extends _abstract_bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
75199
75217
  const cost = this.safeNumber(params, 'cost');
75200
75218
  params = this.omit(params, 'cost');
75201
75219
  if (price === undefined && cost === undefined) {
75202
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder(this.id + " createOrder() requires the price argument with market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = false to supply the cost in the amount argument (the exchange-specific behaviour)");
75220
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder(this.id + ' createOrder() requires the price argument with market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options["createMarketBuyOrderRequiresPrice"] = false to supply the cost in the amount argument (the exchange-specific behaviour)');
75203
75221
  }
75204
75222
  else {
75205
75223
  const amountString = this.numberToString(amount);
@@ -75730,9 +75748,6 @@ class bybit extends _abstract_bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
75730
75748
  return this.parseOrder(order);
75731
75749
  }
75732
75750
  async editUnifiedAccountOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
75733
- if (amount === undefined && price === undefined) {
75734
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder(this.id + ' editOrder requires either a price argument or an amount argument');
75735
- }
75736
75751
  await this.loadMarkets();
75737
75752
  const market = this.market(symbol);
75738
75753
  if (!market['linear'] && !market['option']) {
@@ -75811,9 +75826,6 @@ class bybit extends _abstract_bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
75811
75826
  });
75812
75827
  }
75813
75828
  async editUnifiedMarginOrder(id, symbol, type, side, amount, price = undefined, params = {}) {
75814
- if (amount === undefined && price === undefined) {
75815
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder(this.id + ' editOrder requires either a price argument or an amount argument');
75816
- }
75817
75829
  await this.loadMarkets();
75818
75830
  const market = this.market(symbol);
75819
75831
  if (!market['linear'] && !market['option']) {
@@ -75910,9 +75922,6 @@ class bybit extends _abstract_bybit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
75910
75922
  return this.parseOrder(order);
75911
75923
  }
75912
75924
  async editContractV3Order(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
75913
- if (amount === undefined && price === undefined) {
75914
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder(this.id + ' editOrder requires either a price argument or an amount argument');
75915
- }
75916
75925
  await this.loadMarkets();
75917
75926
  const market = this.market(symbol);
75918
75927
  const request = {
@@ -97589,9 +97598,9 @@ class coinsph extends _abstract_coinsph_js__WEBPACK_IMPORTED_MODULE_0__/* ["defa
97589
97598
  if (i !== 0) {
97590
97599
  encodedArrayParams += '&';
97591
97600
  }
97592
- const array = query[key];
97601
+ const innerArray = query[key];
97593
97602
  query = this.omit(query, key);
97594
- const encodedArrayParam = this.parseArrayParam(array, key);
97603
+ const encodedArrayParam = this.parseArrayParam(innerArray, key);
97595
97604
  encodedArrayParams += encodedArrayParam;
97596
97605
  }
97597
97606
  }
@@ -103884,6 +103893,9 @@ class delta extends _abstract_delta_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
103884
103893
  for (let i = 0; i < markets.length; i++) {
103885
103894
  const market = markets[i];
103886
103895
  let type = this.safeString(market, 'contract_type');
103896
+ if (type === 'options_combos') {
103897
+ continue;
103898
+ }
103887
103899
  // const settlingAsset = this.safeValue (market, 'settling_asset', {});
103888
103900
  const quotingAsset = this.safeValue(market, 'quoting_asset', {});
103889
103901
  const underlyingAsset = this.safeValue(market, 'underlying_asset', {});
@@ -114007,20 +114019,36 @@ class exmo extends _abstract_exmo_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
114007
114019
  }
114008
114020
  parseBalance(response) {
114009
114021
  const result = { 'info': response };
114010
- const free = this.safeValue(response, 'balances', {});
114011
- const used = this.safeValue(response, 'reserved', {});
114012
- const currencyIds = Object.keys(free);
114013
- for (let i = 0; i < currencyIds.length; i++) {
114014
- const currencyId = currencyIds[i];
114015
- const code = this.safeCurrencyCode(currencyId);
114016
- const account = this.account();
114017
- if (currencyId in free) {
114018
- account['free'] = this.safeString(free, currencyId);
114022
+ const wallets = this.safeValue(response, 'wallets');
114023
+ if (wallets !== undefined) {
114024
+ const currencyIds = Object.keys(wallets);
114025
+ for (let i = 0; i < currencyIds.length; i++) {
114026
+ const currencyId = currencyIds[i];
114027
+ const item = wallets[currencyId];
114028
+ const currency = this.safeCurrencyCode(currencyId);
114029
+ const account = this.account();
114030
+ account['used'] = this.safeString(item, 'used');
114031
+ account['free'] = this.safeString(item, 'free');
114032
+ account['total'] = this.safeString(item, 'balance');
114033
+ result[currency] = account;
114019
114034
  }
114020
- if (currencyId in used) {
114021
- account['used'] = this.safeString(used, currencyId);
114035
+ }
114036
+ else {
114037
+ const free = this.safeValue(response, 'balances', {});
114038
+ const used = this.safeValue(response, 'reserved', {});
114039
+ const currencyIds = Object.keys(free);
114040
+ for (let i = 0; i < currencyIds.length; i++) {
114041
+ const currencyId = currencyIds[i];
114042
+ const code = this.safeCurrencyCode(currencyId);
114043
+ const account = this.account();
114044
+ if (currencyId in free) {
114045
+ account['free'] = this.safeString(free, currencyId);
114046
+ }
114047
+ if (currencyId in used) {
114048
+ account['used'] = this.safeString(used, currencyId);
114049
+ }
114050
+ result[code] = account;
114022
114051
  }
114023
- result[code] = account;
114024
114052
  }
114025
114053
  return this.safeBalance(result);
114026
114054
  }
@@ -114030,22 +114058,45 @@ class exmo extends _abstract_exmo_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
114030
114058
  * @name exmo#fetchBalance
114031
114059
  * @description query for balance and get the amount of funds available for trading or funds locked in orders
114032
114060
  * @param {object} [params] extra parameters specific to the exmo api endpoint
114061
+ * @param {string} [params.marginMode] *isolated* fetches the isolated margin balance
114033
114062
  * @returns {object} a [balance structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#balance-structure}
114034
114063
  */
114035
114064
  await this.loadMarkets();
114036
- const response = await this.privatePostUserInfo(params);
114037
- //
114038
- // {
114039
- // "uid":131685,
114040
- // "server_date":1628999600,
114041
- // "balances":{
114042
- // "EXM":"0",
114043
- // "USD":"0",
114044
- // "EUR":"0",
114045
- // "GBP":"0",
114046
- // },
114047
- // }
114048
- //
114065
+ let marginMode = undefined;
114066
+ [marginMode, params] = this.handleMarginModeAndParams('fetchBalance', params);
114067
+ if (marginMode === 'cross') {
114068
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest(this.id + ' does not support cross margin');
114069
+ }
114070
+ let response = undefined;
114071
+ if (marginMode === 'isolated') {
114072
+ response = await this.privatePostMarginUserWalletList(params);
114073
+ //
114074
+ // {
114075
+ // "wallets": {
114076
+ // "USD": {
114077
+ // "balance": "1000",
114078
+ // "free": "600",
114079
+ // "used": "400"
114080
+ // }
114081
+ // }
114082
+ // }
114083
+ //
114084
+ }
114085
+ else {
114086
+ response = await this.privatePostUserInfo(params);
114087
+ //
114088
+ // {
114089
+ // "uid":131685,
114090
+ // "server_date":1628999600,
114091
+ // "balances":{
114092
+ // "EXM":"0",
114093
+ // "USD":"0",
114094
+ // "EUR":"0",
114095
+ // "GBP":"0",
114096
+ // },
114097
+ // }
114098
+ //
114099
+ }
114049
114100
  return this.parseBalance(response);
114050
114101
  }
114051
114102
  async fetchOrderBook(symbol, limit = undefined, params = {}) {
@@ -115565,6 +115616,8 @@ class gate extends _abstract_gate_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
115565
115616
  },
115566
115617
  'portfolio': {
115567
115618
  'get': {
115619
+ 'spot/currency_pairs': 1.5,
115620
+ 'spot/currency_pairs/{currency_pair}': 1.5,
115568
115621
  'accounts': 1.5,
115569
115622
  'account_mode': 1.5,
115570
115623
  'borrowable': 1.5,
@@ -123950,7 +124003,6 @@ class hitbtc extends _abstract_hitbtc_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
123950
124003
  'STEPN': 'GMT',
123951
124004
  'STX': 'STOX',
123952
124005
  'TV': 'Tokenville',
123953
- 'USD': 'USDT',
123954
124006
  'XMT': 'MTL',
123955
124007
  'XPNT': 'PNT',
123956
124008
  },
@@ -124002,6 +124054,9 @@ class hitbtc extends _abstract_hitbtc_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
124002
124054
  const ids = Object.keys(response);
124003
124055
  for (let i = 0; i < ids.length; i++) {
124004
124056
  const id = ids[i];
124057
+ if (id.endsWith('_BQX')) {
124058
+ continue; // seems like an invalid symbol and if we try to access it individually we get: {"timestamp":"2023-09-02T14:38:20.351Z","error":{"description":"Try get /public/symbol, to get list of all available symbols.","code":2001,"message":"No such symbol: EOSUSD_BQX"},"path":"/api/3/public/symbol/EOSUSD_BQX","requestId":"e1e9fce6-16374591"}
124059
+ }
124005
124060
  const market = this.safeValue(response, id);
124006
124061
  const marketType = this.safeString(market, 'type');
124007
124062
  const expiry = this.safeInteger(market, 'expiry');
@@ -128986,6 +129041,7 @@ class huobi extends _abstract_huobi_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
128986
129041
  'linear-swap-api/v3/unified_account_info': 1,
128987
129042
  'linear-swap-api/v3/fix_position_margin_change_record': 1,
128988
129043
  'linear-swap-api/v3/swap_unified_account_type': 1,
129044
+ 'linear-swap-api/v3/linear_swap_overview_account_info': 1,
128989
129045
  },
128990
129046
  'post': {
128991
129047
  // Future Account Interface
@@ -129180,6 +129236,7 @@ class huobi extends _abstract_huobi_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
129180
129236
  'linear-swap-api/v3/swap_cross_hisorders_exact': 1,
129181
129237
  'linear-swap-api/v3/fix_position_margin_change': 1,
129182
129238
  'linear-swap-api/v3/swap_switch_account_type': 1,
129239
+ 'linear-swap-api/v3/linear_swap_fee_switch': 1,
129183
129240
  // Swap Strategy Order Interface
129184
129241
  'linear-swap-api/v1/swap_trigger_order': 1,
129185
129242
  'linear-swap-api/v1/swap_cross_trigger_order': 1,
@@ -145952,7 +146009,7 @@ class krakenfutures extends _abstract_krakenfutures_js__WEBPACK_IMPORTED_MODULE_
145952
146009
  let statusId = undefined;
145953
146010
  let price = undefined;
145954
146011
  let trades = [];
145955
- if (orderEvents.length > 0) {
146012
+ if (orderEvents.length) {
145956
146013
  const executions = [];
145957
146014
  for (let i = 0; i < orderEvents.length; i++) {
145958
146015
  const item = orderEvents[i];
@@ -146000,7 +146057,7 @@ class krakenfutures extends _abstract_krakenfutures_js__WEBPACK_IMPORTED_MODULE_
146000
146057
  let remaining = this.safeString(details, 'unfilledSize');
146001
146058
  let average = undefined;
146002
146059
  let filled2 = '0.0';
146003
- if (trades.length > 0) {
146060
+ if (trades.length) {
146004
146061
  let vwapSum = '0.0';
146005
146062
  for (let i = 0; i < trades.length; i++) {
146006
146063
  const trade = trades[i];
@@ -147385,6 +147442,7 @@ class kucoin extends _abstract_kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
147385
147442
  'versions': {
147386
147443
  'public': {
147387
147444
  'GET': {
147445
+ 'currencies': 'v3',
147388
147446
  'currencies/{currency}': 'v2',
147389
147447
  'status': 'v1',
147390
147448
  'market/orderbook/level2_20': 'v1',
@@ -147890,19 +147948,34 @@ class kucoin extends _abstract_kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
147890
147948
  const promises = [];
147891
147949
  promises.push(this.publicGetCurrencies(params));
147892
147950
  //
147893
- // {
147894
- // "currency": "OMG",
147895
- // "name": "OMG",
147896
- // "fullName": "OmiseGO",
147897
- // "precision": 8,
147898
- // "confirms": 12,
147899
- // "withdrawalMinSize": "4",
147900
- // "withdrawalMinFee": "1.25",
147901
- // "isWithdrawEnabled": false,
147902
- // "isDepositEnabled": false,
147903
- // "isMarginEnabled": false,
147904
- // "isDebitEnabled": false
147905
- // }
147951
+ // {
147952
+ // "code":"200000",
147953
+ // "data":[
147954
+ // {
147955
+ // "currency":"CSP",
147956
+ // "name":"CSP",
147957
+ // "fullName":"Caspian",
147958
+ // "precision":8,
147959
+ // "confirms":null,
147960
+ // "contractAddress":null,
147961
+ // "isMarginEnabled":false,
147962
+ // "isDebitEnabled":false,
147963
+ // "chains":[
147964
+ // {
147965
+ // "chainName":"ERC20",
147966
+ // "chain":"eth",
147967
+ // "withdrawalMinSize":"2999",
147968
+ // "withdrawalMinFee":"2999",
147969
+ // "isWithdrawEnabled":false,
147970
+ // "isDepositEnabled":false,
147971
+ // "confirms":12,
147972
+ // "preConfirms":12,
147973
+ // "contractAddress":"0xa6446d655a0c34bc4f05042ee88170d056cbaf45",
147974
+ // "depositFeeRate": "0.001", // present for some currencies/networks
147975
+ // }
147976
+ // ]
147977
+ // },
147978
+ // }
147906
147979
  //
147907
147980
  promises.push(this.fetchWebEndpoint('fetchCurrencies', 'webExchangeGetCurrencyCurrencyChainInfo', true));
147908
147981
  //
@@ -147913,90 +147986,101 @@ class kucoin extends _abstract_kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
147913
147986
  // "retry": false,
147914
147987
  // "data": [
147915
147988
  // {
147916
- // "withdrawMinFee": "0.0005",
147917
- // "chainName": "BTC",
147918
- // "preDepositTipEnabled": "false",
147919
- // "chain": "btc",
147989
+ // "status": "enabled",
147990
+ // "currency": "BTC",
147920
147991
  // "isChainEnabled": "true",
147921
- // "withdrawDisabledTip": "",
147922
- // "walletPrecision": "8",
147992
+ // "chain": "btc",
147993
+ // "chainName": "BTC",
147923
147994
  // "chainFullName": "Bitcoin",
147924
- // "orgAddress": "",
147995
+ // "walletPrecision": "8",
147925
147996
  // "isDepositEnabled": "true",
147926
- // "withdrawMinSize": "0.001",
147927
- // "depositDisabledTip": "",
147928
- // "userAddressName": "",
147929
- // "txUrl": "https://blockchain.info/tx/{txId}",
147930
- // "preWithdrawTipEnabled": "false",
147931
- // "withdrawFeeRate": "0",
147932
- // "confirmationCount": "2",
147933
- // "currency": "BTC",
147934
147997
  // "depositMinSize": "0.00005",
147998
+ // "confirmationCount": "2",
147935
147999
  // "isWithdrawEnabled": "true",
147936
- // "preDepositTip": "",
148000
+ // "withdrawMinSize": "0.001",
148001
+ // "withdrawMinFee": "0.0005",
148002
+ // "withdrawFeeRate": "0",
148003
+ // "depositDisabledTip": "Wallet Maintenance",
148004
+ // "preDepositTipEnabled": "true",
148005
+ // "preDepositTip": "Do not transfer from ETH network directly",
148006
+ // "withdrawDisabledTip": "",
148007
+ // "preWithdrawTipEnabled": "false",
147937
148008
  // "preWithdrawTip": "",
147938
- // "status": "enabled"
148009
+ // "orgAddress": "",
148010
+ // "userAddressName": "Memo",
147939
148011
  // },
147940
148012
  // ]
147941
148013
  // }
147942
148014
  //
147943
148015
  const responses = await Promise.all(promises);
147944
- const responseCurrencies = responses[0];
147945
- const responseChains = responses[1];
147946
- const data = this.safeValue(responseCurrencies, 'data', []);
147947
- const chainsData = this.safeValue(responseChains, 'data', []);
147948
- const currencyChains = this.groupBy(chainsData, 'currency');
148016
+ const currenciesResponse = this.safeValue(responses, 0, {});
148017
+ const currenciesData = this.safeValue(currenciesResponse, 'data', []);
148018
+ const additionalResponse = this.safeValue(responses, 1, {});
148019
+ const additionalData = this.safeValue(additionalResponse, 'data', []);
148020
+ const additionalDataGrouped = this.groupBy(additionalData, 'currency');
147949
148021
  const result = {};
147950
- for (let i = 0; i < data.length; i++) {
147951
- const entry = data[i];
148022
+ for (let i = 0; i < currenciesData.length; i++) {
148023
+ const entry = currenciesData[i];
147952
148024
  const id = this.safeString(entry, 'currency');
147953
148025
  const name = this.safeString(entry, 'fullName');
147954
148026
  const code = this.safeCurrencyCode(id);
147955
- const isWithdrawEnabled = this.safeValue(entry, 'isWithdrawEnabled', false);
147956
- const isDepositEnabled = this.safeValue(entry, 'isDepositEnabled', false);
147957
- const fee = this.safeNumber(entry, 'withdrawalMinFee');
147958
- const active = (isWithdrawEnabled && isDepositEnabled);
148027
+ let isWithdrawEnabled = undefined;
148028
+ let isDepositEnabled = undefined;
147959
148029
  const networks = {};
147960
- const chains = this.safeValue(currencyChains, id, []);
148030
+ const chains = this.safeValue(entry, 'chains', []);
148031
+ const extraChainsData = this.indexBy(this.safeValue(additionalDataGrouped, id, []), 'chain');
148032
+ const precision = this.parseNumber(this.parsePrecision(this.safeString(entry, 'precision')));
147961
148033
  for (let j = 0; j < chains.length; j++) {
147962
148034
  const chain = chains[j];
147963
148035
  const chainId = this.safeString(chain, 'chain');
147964
- const isChainEnabled = this.safeString(chain, 'isChainEnabled'); // better than 'status'
147965
- if (isChainEnabled === 'true') {
147966
- const networkCode = this.networkIdToCode(chainId);
147967
- const chainWithdrawEnabled = this.safeValue(chain, 'isWithdrawEnabled', false);
147968
- const chainDepositEnabled = this.safeValue(chain, 'isDepositEnabled', false);
147969
- networks[networkCode] = {
147970
- 'info': chain,
147971
- 'id': chainId,
147972
- 'name': this.safeString2(chain, 'chainFullName', 'chainName'),
147973
- 'code': networkCode,
147974
- 'active': chainWithdrawEnabled && chainDepositEnabled,
147975
- 'fee': this.safeNumber(chain, 'withdrawMinFee'),
147976
- 'precision': this.parseNumber(this.parsePrecision(this.safeString(chain, 'walletPrecision'))),
147977
- 'limits': {
147978
- 'withdraw': {
147979
- 'min': this.safeNumber(chain, 'withdrawMinSize'),
147980
- 'max': undefined,
147981
- },
147982
- 'deposit': {
147983
- 'min': this.safeNumber(chain, 'depositMinSize'),
147984
- 'max': undefined,
147985
- },
147986
- },
147987
- };
148036
+ const networkCode = this.networkIdToCode(chainId);
148037
+ const chainWithdrawEnabled = this.safeValue(chain, 'isWithdrawEnabled', false);
148038
+ if (isWithdrawEnabled === undefined) {
148039
+ isWithdrawEnabled = chainWithdrawEnabled;
147988
148040
  }
148041
+ else {
148042
+ isWithdrawEnabled = isWithdrawEnabled || chainWithdrawEnabled;
148043
+ }
148044
+ const chainDepositEnabled = this.safeValue(chain, 'isDepositEnabled', false);
148045
+ if (isDepositEnabled === undefined) {
148046
+ isDepositEnabled = chainDepositEnabled;
148047
+ }
148048
+ else {
148049
+ isDepositEnabled = isDepositEnabled || chainDepositEnabled;
148050
+ }
148051
+ const chainExtraData = this.safeValue(extraChainsData, chainId, {});
148052
+ networks[networkCode] = {
148053
+ 'info': chain,
148054
+ 'id': chainId,
148055
+ 'name': this.safeString(chain, 'chainName'),
148056
+ 'code': networkCode,
148057
+ 'active': chainWithdrawEnabled && chainDepositEnabled,
148058
+ 'fee': this.safeNumber(chain, 'withdrawalMinFee'),
148059
+ 'deposit': chainDepositEnabled,
148060
+ 'withdraw': chainWithdrawEnabled,
148061
+ 'precision': this.parseNumber(this.parsePrecision(this.safeString(chainExtraData, 'walletPrecision'))),
148062
+ 'limits': {
148063
+ 'withdraw': {
148064
+ 'min': this.safeNumber(chain, 'withdrawalMinSize'),
148065
+ 'max': undefined,
148066
+ },
148067
+ 'deposit': {
148068
+ 'min': this.safeNumber(chainExtraData, 'depositMinSize'),
148069
+ 'max': undefined,
148070
+ },
148071
+ },
148072
+ };
147989
148073
  }
147990
148074
  result[code] = {
147991
148075
  'id': id,
147992
148076
  'name': name,
147993
148077
  'code': code,
147994
- 'precision': this.parseNumber(this.parsePrecision(this.safeString(entry, 'precision'))),
148078
+ 'precision': precision,
147995
148079
  'info': entry,
147996
- 'active': active,
148080
+ 'active': (isDepositEnabled || isWithdrawEnabled),
147997
148081
  'deposit': isDepositEnabled,
147998
148082
  'withdraw': isWithdrawEnabled,
147999
- 'fee': fee,
148083
+ 'fee': undefined,
148000
148084
  'limits': this.limits,
148001
148085
  'networks': networks,
148002
148086
  };
@@ -175163,7 +175247,7 @@ class okcoin extends _abstract_okcoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
175163
175247
  }
175164
175248
  }
175165
175249
  else if (notional === undefined) {
175166
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder(this.id + " createOrder() requires the price argument with market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = false and supply the total cost value in the 'amount' argument or in the 'notional' extra parameter (the exchange-specific behaviour)");
175250
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder(this.id + ' createOrder() requires the price argument with market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options["createMarketBuyOrderRequiresPrice"] = false and supply the total cost value in the "amount" argument or in the "notional" extra parameter (the exchange-specific behaviour)');
175167
175251
  }
175168
175252
  }
175169
175253
  else {
@@ -176640,7 +176724,7 @@ class okcoin extends _abstract_okcoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
176640
176724
  let currency = undefined;
176641
176725
  if (type === 'spot') {
176642
176726
  if (code === undefined) {
176643
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + " fetchLedger() requires a currency code argument for '" + type + "' markets");
176727
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ArgumentsRequired(this.id + ' fetchLedger() requires a currency code argument for "' + type + '" markets');
176644
176728
  }
176645
176729
  argument = 'Currency';
176646
176730
  currency = this.currency(code);
@@ -181378,7 +181462,7 @@ class okx extends _abstract_okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
181378
181462
  const targetNetwork = this.safeValue(currency['networks'], this.networkIdToCode(network), {});
181379
181463
  fee = this.safeString(targetNetwork, 'fee');
181380
181464
  if (fee === undefined) {
181381
- 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.");
181465
+ 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.');
181382
181466
  }
181383
181467
  }
181384
181468
  request['fee'] = this.numberToString(fee); // withdrawals to OKCoin or OKX are fee-free, please set 0
@@ -199156,9 +199240,18 @@ class bitget extends _bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
199156
199240
  'ws': {
199157
199241
  'exact': {
199158
199242
  '30001': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadRequest,
199243
+ '30002': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError,
199244
+ '30003': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadRequest,
199245
+ '30004': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError,
199246
+ '30005': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError,
199247
+ '30006': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.RateLimitExceeded,
199248
+ '30007': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.RateLimitExceeded,
199249
+ '30011': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError,
199250
+ '30012': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError,
199251
+ '30013': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError,
199252
+ '30014': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadRequest,
199159
199253
  '30015': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError,
199160
- '30016': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadRequest,
199161
- '30011': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.AuthenticationError, // { event: 'error', code: 30011, msg: 'Invalid ACCESS_KEY' }
199254
+ '30016': _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.BadRequest, // { event: 'error', code: 30016, msg: 'Param error' }
199162
199255
  },
199163
199256
  },
199164
199257
  },
@@ -200248,6 +200341,9 @@ class bitget extends _bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
200248
200341
  const code = this.safeString(message, 'code');
200249
200342
  const feedback = this.id + ' ' + this.json(message);
200250
200343
  this.throwExactlyMatchedException(this.exceptions['ws']['exact'], code, feedback);
200344
+ const msg = this.safeString(message, 'msg', '');
200345
+ this.throwBroadlyMatchedException(this.exceptions['ws']['broad'], msg, feedback);
200346
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.ExchangeError(feedback);
200251
200347
  }
200252
200348
  return false;
200253
200349
  }
@@ -200259,6 +200355,10 @@ class bitget extends _bitget_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
200259
200355
  delete client.subscriptions[messageHash];
200260
200356
  }
200261
200357
  }
200358
+ else {
200359
+ // Note: if error happens on a subscribe event, user will have to close exchange to resubscribe. Issue #19041
200360
+ client.reject(e);
200361
+ }
200262
200362
  return true;
200263
200363
  }
200264
200364
  }
@@ -216211,15 +216311,17 @@ class gate extends _gate_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
216211
216311
  const subscription = this.safeString(ohlcv, 'n', '');
216212
216312
  const parts = subscription.split('_');
216213
216313
  const timeframe = this.safeString(parts, 0);
216314
+ const timeframeId = this.findTimeframe(timeframe);
216214
216315
  const prefix = timeframe + '_';
216215
216316
  const marketId = subscription.replace(prefix, '');
216216
216317
  const symbol = this.safeSymbol(marketId, undefined, '_', marketType);
216217
216318
  const parsed = this.parseOHLCV(ohlcv);
216218
- let stored = this.safeValue(this.ohlcvs, symbol);
216319
+ this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
216320
+ let stored = this.safeValue(this.ohlcvs[symbol], timeframe);
216219
216321
  if (stored === undefined) {
216220
216322
  const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
216221
216323
  stored = new _base_ws_Cache_js__WEBPACK_IMPORTED_MODULE_2__/* .ArrayCacheByTimestamp */ .Py(limit);
216222
- this.ohlcvs[symbol] = stored;
216324
+ this.ohlcvs[symbol][timeframeId] = stored;
216223
216325
  }
216224
216326
  stored.append(parsed);
216225
216327
  marketIds[symbol] = timeframe;
@@ -216230,7 +216332,7 @@ class gate extends _gate_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
216230
216332
  const timeframe = marketIds[symbol];
216231
216333
  const interval = this.findTimeframe(timeframe);
216232
216334
  const hash = 'candles' + ':' + interval + ':' + symbol;
216233
- const stored = this.safeValue(this.ohlcvs, symbol);
216335
+ const stored = this.safeValue(this.ohlcvs[symbol], interval);
216234
216336
  client.resolve(stored, hash);
216235
216337
  }
216236
216338
  }
@@ -223091,8 +223193,8 @@ class kraken extends _kraken_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
223091
223193
  }
223092
223194
  }
223093
223195
  formatNumber(n, length) {
223094
- const string = this.numberToString(n);
223095
- const parts = string.split('.');
223196
+ const stringNumber = this.numberToString(n);
223197
+ const parts = stringNumber.split('.');
223096
223198
  const integer = this.safeString(parts, 0);
223097
223199
  const decimals = this.safeString(parts, 1, '');
223098
223200
  const paddedDecimals = decimals.padEnd(length, '0');
@@ -224357,7 +224459,7 @@ class krakenfutures extends _krakenfutures_js__WEBPACK_IMPORTED_MODULE_0__/* ["d
224357
224459
  symbols[symbol] = true;
224358
224460
  cachedOrders.append(parsed);
224359
224461
  }
224360
- if (this.orders.length > 0) {
224462
+ if (this.orders.length) {
224361
224463
  client.resolve(this.orders, 'orders');
224362
224464
  const keys = Object.keys(symbols);
224363
224465
  for (let i = 0; i < keys.length; i++) {
@@ -229592,15 +229694,17 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
229592
229694
  }
229593
229695
  getUrl(channel, access = 'public') {
229594
229696
  // for context: https://www.okx.com/help-center/changes-to-v5-api-websocket-subscription-parameter-and-url
229697
+ const isSandbox = this.options['sandboxMode'];
229698
+ const sandboxSuffix = isSandbox ? '?brokerId=9999' : '';
229595
229699
  const isPublic = (access === 'public');
229596
229700
  const url = this.urls['api']['ws'];
229597
229701
  if ((channel.indexOf('candle') > -1) || (channel === 'orders-algo')) {
229598
- return url + '/business';
229702
+ return url + '/business' + sandboxSuffix;
229599
229703
  }
229600
229704
  else if (isPublic) {
229601
- return url + '/public';
229705
+ return url + '/public' + sandboxSuffix;
229602
229706
  }
229603
- return url + '/private';
229707
+ return url + '/private' + sandboxSuffix;
229604
229708
  }
229605
229709
  async subscribeMultiple(access, channel, symbols = undefined, params = {}) {
229606
229710
  await this.loadMarkets();
@@ -230747,6 +230851,9 @@ class okx extends _okx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
230747
230851
  }
230748
230852
  return false;
230749
230853
  }
230854
+ else {
230855
+ client.reject(e);
230856
+ }
230750
230857
  }
230751
230858
  return message;
230752
230859
  }
@@ -234970,11 +235077,11 @@ class probit extends _probit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z
234970
235077
  this.handleTicker(client, message);
234971
235078
  }
234972
235079
  const trades = this.safeValue(message, 'recent_trades', []);
234973
- if (trades.length > 0) {
235080
+ if (trades.length) {
234974
235081
  this.handleTrades(client, message);
234975
235082
  }
234976
235083
  const orderBook = this.safeValueN(message, ['order_books', 'order_books_l1', 'order_books_l2', 'order_books_l3', 'order_books_l4'], []);
234977
- if (orderBook.length > 0) {
235084
+ if (orderBook.length) {
234978
235085
  this.handleOrderBook(client, message, orderBook);
234979
235086
  }
234980
235087
  }
@@ -238944,7 +239051,7 @@ class probit extends _abstract_probit_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
238944
239051
  }
238945
239052
  }
238946
239053
  else if (cost === undefined) {
238947
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder(this.id + " createOrder() requires the price argument for market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = false and supply the total cost value in the 'amount' argument or in the 'cost' extra parameter (the exchange-specific behaviour)");
239054
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_1__.InvalidOrder(this.id + ' createOrder() requires the price argument for market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options["createMarketBuyOrderRequiresPrice"] = false and supply the total cost value in the "amount" argument or in the "cost" extra parameter (the exchange-specific behaviour)');
238948
239055
  }
238949
239056
  }
238950
239057
  else {
@@ -239414,7 +239521,7 @@ class probit extends _abstract_probit_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
239414
239521
  const networkCode = this.networkIdToCode(networkId, currency['code']);
239415
239522
  const withdrawalFees = this.safeValue(network, 'withdrawal_fee', {});
239416
239523
  const withdrawFee = this.safeNumber(withdrawalFees[0], 'amount');
239417
- if (withdrawalFees.length > 0) {
239524
+ if (withdrawalFees.length) {
239418
239525
  const withdrawResult = {
239419
239526
  'fee': withdrawFee,
239420
239527
  'percentage': (withdrawFee !== undefined) ? false : undefined,
@@ -254690,7 +254797,7 @@ class upbit extends _abstract_upbit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
254690
254797
  if (side === 'buy') {
254691
254798
  if (this.options['createMarketBuyOrderRequiresPrice']) {
254692
254799
  if (price === undefined) {
254693
- throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.InvalidOrder(this.id + " createOrder() requires the price argument with market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = false to supply the cost in the amount argument (the exchange-specific behaviour)");
254800
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.InvalidOrder(this.id + ' createOrder() requires the price argument with market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options["createMarketBuyOrderRequiresPrice"] = false to supply the cost in the amount argument (the exchange-specific behaviour)');
254694
254801
  }
254695
254802
  else {
254696
254803
  amount = amount * price;
@@ -255381,12 +255488,20 @@ class upbit extends _abstract_upbit_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"
255381
255488
  };
255382
255489
  let method = 'privatePostWithdraws';
255383
255490
  if (code !== 'KRW') {
255491
+ // 2023-05-23 Change to required parameters for digital assets
255492
+ const network = this.safeStringUpper2(params, 'network', 'net_type');
255493
+ if (network === undefined) {
255494
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ArgumentsRequired(this.id + ' withdraw() requires a network argument');
255495
+ }
255496
+ params = this.omit(params, ['network']);
255497
+ request['net_type'] = network;
255384
255498
  method += 'Coin';
255385
255499
  request['currency'] = currency['id'];
255386
255500
  request['address'] = address;
255387
255501
  if (tag !== undefined) {
255388
255502
  request['secondary_address'] = tag;
255389
255503
  }
255504
+ params = this.omit(params, 'network');
255390
255505
  }
255391
255506
  else {
255392
255507
  method += 'Krw';
@@ -257808,7 +257923,8 @@ class wavesexchange extends _abstract_wavesexchange_js__WEBPACK_IMPORTED_MODULE_
257808
257923
  const entry = depositWithdrawFees[code];
257809
257924
  const networks = this.safeValue(entry, 'networks');
257810
257925
  const networkKeys = Object.keys(networks);
257811
- if (networkKeys.length === 1) {
257926
+ const networkKeysLength = networkKeys.length;
257927
+ if (networkKeysLength === 1) {
257812
257928
  const network = this.safeValue(networks, networkKeys[0]);
257813
257929
  depositWithdrawFees[code]['withdraw'] = this.safeValue(network, 'withdraw');
257814
257930
  depositWithdrawFees[code]['deposit'] = this.safeValue(network, 'deposit');
@@ -257950,7 +258066,8 @@ class wavesexchange extends _abstract_wavesexchange_js__WEBPACK_IMPORTED_MODULE_
257950
258066
  let isErc20 = true;
257951
258067
  const noPrefix = this.remove0xPrefix(address);
257952
258068
  const lower = noPrefix.toLowerCase();
257953
- for (let i = 0; i < lower.length; i++) {
258069
+ const stringLength = lower.length * 1;
258070
+ for (let i = 0; i < stringLength; i++) {
257954
258071
  const character = lower[i];
257955
258072
  if (!(character in set)) {
257956
258073
  isErc20 = false;
@@ -258909,6 +259026,7 @@ class wazirx extends _abstract_wazirx_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
258909
259026
  const stopPrice = this.safeString(params, 'stopPrice');
258910
259027
  if (stopPrice !== undefined) {
258911
259028
  request['type'] = 'stop_limit';
259029
+ request['stopPrice'] = this.priceToPrecision(symbol, stopPrice);
258912
259030
  }
258913
259031
  const response = await this.privatePostOrder(this.extend(request, params));
258914
259032
  // {
@@ -273441,7 +273559,7 @@ SOFTWARE.
273441
273559
 
273442
273560
  //-----------------------------------------------------------------------------
273443
273561
  // this is updated by vss.js when building
273444
- const version = '4.0.79';
273562
+ const version = '4.0.81';
273445
273563
  _src_base_Exchange_js__WEBPACK_IMPORTED_MODULE_0__/* .Exchange.ccxtVersion */ .e.ccxtVersion = version;
273446
273564
  //-----------------------------------------------------------------------------
273447
273565