ccxt 4.0.80 → 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 (46) hide show
  1. package/CHANGELOG.md +169 -0
  2. package/README.md +3 -3
  3. package/dist/ccxt.browser.js +211 -116
  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 +3 -1
  9. package/dist/cjs/src/bybit.js +0 -9
  10. package/dist/cjs/src/delta.js +3 -0
  11. package/dist/cjs/src/exmo.js +64 -25
  12. package/dist/cjs/src/gate.js +2 -0
  13. package/dist/cjs/src/hitbtc.js +3 -1
  14. package/dist/cjs/src/huobi.js +2 -0
  15. package/dist/cjs/src/kucoin.js +96 -69
  16. package/dist/cjs/src/pro/krakenfutures.js +1 -1
  17. package/dist/cjs/src/pro/okx.js +8 -3
  18. package/dist/cjs/src/pro/probit.js +2 -2
  19. package/dist/cjs/src/upbit.js +8 -0
  20. package/js/ccxt.d.ts +1 -1
  21. package/js/ccxt.js +1 -1
  22. package/js/src/abstract/binance.d.ts +9 -0
  23. package/js/src/abstract/binancecoinm.d.ts +9 -0
  24. package/js/src/abstract/binanceus.d.ts +9 -0
  25. package/js/src/abstract/binanceusdm.d.ts +9 -0
  26. package/js/src/abstract/gate.d.ts +2 -0
  27. package/js/src/abstract/gateio.d.ts +2 -0
  28. package/js/src/abstract/huobi.d.ts +2 -0
  29. package/js/src/abstract/huobipro.d.ts +2 -0
  30. package/js/src/binance.js +9 -0
  31. package/js/src/bitget.js +9 -4
  32. package/js/src/bitmex.d.ts +1 -1
  33. package/js/src/bitmex.js +3 -1
  34. package/js/src/bybit.js +0 -9
  35. package/js/src/delta.js +3 -0
  36. package/js/src/exmo.js +64 -25
  37. package/js/src/gate.js +2 -0
  38. package/js/src/hitbtc.js +3 -1
  39. package/js/src/huobi.js +2 -0
  40. package/js/src/kucoin.js +96 -69
  41. package/js/src/pro/krakenfutures.js +1 -1
  42. package/js/src/pro/okx.js +8 -3
  43. package/js/src/pro/probit.js +2 -2
  44. package/js/src/upbit.js +9 -1
  45. package/package.json +1 -1
  46. package/skip-tests.json +7 -2
package/dist/cjs/ccxt.js CHANGED
@@ -180,7 +180,7 @@ var woo$1 = require('./src/pro/woo.js');
180
180
 
181
181
  //-----------------------------------------------------------------------------
182
182
  // this is updated by vss.js when building
183
- const version = '4.0.80';
183
+ const version = '4.0.81';
184
184
  Exchange["default"].ccxtVersion = version;
185
185
  const exchanges = {
186
186
  'ace': ace,
@@ -252,6 +252,12 @@ class binance extends binance$1 {
252
252
  'loan/loanable/data': 40,
253
253
  'loan/collateral/data': 40,
254
254
  'loan/repay/collateral/rate': 600,
255
+ 'loan/flexible/ongoing/orders': 30,
256
+ 'loan/flexible/borrow/history': 40,
257
+ 'loan/flexible/repay/history': 40,
258
+ 'loan/flexible/ltv/adjustment/history': 40,
259
+ 'loan/flexible/loanable/data': 40,
260
+ 'loan/flexible/collateral/data': 40,
255
261
  'loan/vip/ongoing/orders': 40,
256
262
  'loan/vip/repay/history': 40,
257
263
  'loan/vip/collateral/account': 600,
@@ -517,6 +523,9 @@ class binance extends binance$1 {
517
523
  'loan/repay': 40.002,
518
524
  'loan/adjust/ltv': 40.002,
519
525
  'loan/customize/margin_call': 40.002,
526
+ 'loan/flexible/borrow': 40.002,
527
+ 'loan/flexible/repay': 40.002,
528
+ 'loan/flexible/adjust/ltv': 40.002,
520
529
  'loan/vip/repay': 40.002,
521
530
  'convert/getQuote': 1.3334,
522
531
  'convert/acceptQuote': 3.3335,
@@ -3838,6 +3838,8 @@ class bitget extends bitget$1 {
3838
3838
  * @method
3839
3839
  * @name bitget#fetchMyTrades
3840
3840
  * @description fetch all trades made by the user
3841
+ * @see https://bitgetlimited.github.io/apidoc/en/spot/#get-transaction-details
3842
+ * @see https://bitgetlimited.github.io/apidoc/en/mix/#get-order-fill-detail
3841
3843
  * @param {string} symbol unified market symbol
3842
3844
  * @param {int} [since] the earliest time in ms to fetch trades for
3843
3845
  * @param {int} [limit] the maximum number of trades structures to retrieve
@@ -3847,16 +3849,19 @@ class bitget extends bitget$1 {
3847
3849
  this.checkRequiredSymbol('fetchMyTrades', symbol);
3848
3850
  await this.loadMarkets();
3849
3851
  const market = this.market(symbol);
3850
- if (market['swap']) {
3851
- throw new errors.BadSymbol(this.id + ' fetchMyTrades() only supports spot markets');
3852
- }
3853
3852
  const request = {
3854
3853
  'symbol': market['id'],
3855
3854
  };
3856
3855
  if (limit !== undefined) {
3857
3856
  request['limit'] = limit;
3858
3857
  }
3859
- const response = await this.privateSpotPostTradeFills(this.extend(request, params));
3858
+ let response = undefined;
3859
+ if (market['spot']) {
3860
+ response = await this.privateSpotPostTradeFills(this.extend(request, params));
3861
+ }
3862
+ else {
3863
+ response = await this.privateMixGetOrderFills(this.extend(request, params));
3864
+ }
3860
3865
  //
3861
3866
  // {
3862
3867
  // code: '00000',
@@ -2274,7 +2274,9 @@ class bitmex extends bitmex$1 {
2274
2274
  filteredResponse.push(item);
2275
2275
  }
2276
2276
  }
2277
- return this.parseFundingRates(filteredResponse, symbols);
2277
+ symbols = this.marketSymbols(symbols);
2278
+ const result = this.parseFundingRates(filteredResponse);
2279
+ return this.filterByArray(result, 'symbol', symbols);
2278
2280
  }
2279
2281
  parseFundingRate(contract, market = undefined) {
2280
2282
  // see response sample under "fetchMarkets" because same endpoint is being used here
@@ -4444,9 +4444,6 @@ class bybit extends bybit$1 {
4444
4444
  return this.parseOrder(order);
4445
4445
  }
4446
4446
  async editUnifiedAccountOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
4447
- if (amount === undefined && price === undefined) {
4448
- throw new errors.InvalidOrder(this.id + ' editOrder requires either a price argument or an amount argument');
4449
- }
4450
4447
  await this.loadMarkets();
4451
4448
  const market = this.market(symbol);
4452
4449
  if (!market['linear'] && !market['option']) {
@@ -4525,9 +4522,6 @@ class bybit extends bybit$1 {
4525
4522
  });
4526
4523
  }
4527
4524
  async editUnifiedMarginOrder(id, symbol, type, side, amount, price = undefined, params = {}) {
4528
- if (amount === undefined && price === undefined) {
4529
- throw new errors.InvalidOrder(this.id + ' editOrder requires either a price argument or an amount argument');
4530
- }
4531
4525
  await this.loadMarkets();
4532
4526
  const market = this.market(symbol);
4533
4527
  if (!market['linear'] && !market['option']) {
@@ -4624,9 +4618,6 @@ class bybit extends bybit$1 {
4624
4618
  return this.parseOrder(order);
4625
4619
  }
4626
4620
  async editContractV3Order(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
4627
- if (amount === undefined && price === undefined) {
4628
- throw new errors.InvalidOrder(this.id + ' editOrder requires either a price argument or an amount argument');
4629
- }
4630
4621
  await this.loadMarkets();
4631
4622
  const market = this.market(symbol);
4632
4623
  const request = {
@@ -704,6 +704,9 @@ class delta extends delta$1 {
704
704
  for (let i = 0; i < markets.length; i++) {
705
705
  const market = markets[i];
706
706
  let type = this.safeString(market, 'contract_type');
707
+ if (type === 'options_combos') {
708
+ continue;
709
+ }
707
710
  // const settlingAsset = this.safeValue (market, 'settling_asset', {});
708
711
  const quotingAsset = this.safeValue(market, 'quoting_asset', {});
709
712
  const underlyingAsset = this.safeValue(market, 'underlying_asset', {});
@@ -871,20 +871,36 @@ class exmo extends exmo$1 {
871
871
  }
872
872
  parseBalance(response) {
873
873
  const result = { 'info': response };
874
- const free = this.safeValue(response, 'balances', {});
875
- const used = this.safeValue(response, 'reserved', {});
876
- const currencyIds = Object.keys(free);
877
- for (let i = 0; i < currencyIds.length; i++) {
878
- const currencyId = currencyIds[i];
879
- const code = this.safeCurrencyCode(currencyId);
880
- const account = this.account();
881
- if (currencyId in free) {
882
- account['free'] = this.safeString(free, currencyId);
874
+ const wallets = this.safeValue(response, 'wallets');
875
+ if (wallets !== undefined) {
876
+ const currencyIds = Object.keys(wallets);
877
+ for (let i = 0; i < currencyIds.length; i++) {
878
+ const currencyId = currencyIds[i];
879
+ const item = wallets[currencyId];
880
+ const currency = this.safeCurrencyCode(currencyId);
881
+ const account = this.account();
882
+ account['used'] = this.safeString(item, 'used');
883
+ account['free'] = this.safeString(item, 'free');
884
+ account['total'] = this.safeString(item, 'balance');
885
+ result[currency] = account;
883
886
  }
884
- if (currencyId in used) {
885
- account['used'] = this.safeString(used, currencyId);
887
+ }
888
+ else {
889
+ const free = this.safeValue(response, 'balances', {});
890
+ const used = this.safeValue(response, 'reserved', {});
891
+ const currencyIds = Object.keys(free);
892
+ for (let i = 0; i < currencyIds.length; i++) {
893
+ const currencyId = currencyIds[i];
894
+ const code = this.safeCurrencyCode(currencyId);
895
+ const account = this.account();
896
+ if (currencyId in free) {
897
+ account['free'] = this.safeString(free, currencyId);
898
+ }
899
+ if (currencyId in used) {
900
+ account['used'] = this.safeString(used, currencyId);
901
+ }
902
+ result[code] = account;
886
903
  }
887
- result[code] = account;
888
904
  }
889
905
  return this.safeBalance(result);
890
906
  }
@@ -894,22 +910,45 @@ class exmo extends exmo$1 {
894
910
  * @name exmo#fetchBalance
895
911
  * @description query for balance and get the amount of funds available for trading or funds locked in orders
896
912
  * @param {object} [params] extra parameters specific to the exmo api endpoint
913
+ * @param {string} [params.marginMode] *isolated* fetches the isolated margin balance
897
914
  * @returns {object} a [balance structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#balance-structure}
898
915
  */
899
916
  await this.loadMarkets();
900
- const response = await this.privatePostUserInfo(params);
901
- //
902
- // {
903
- // "uid":131685,
904
- // "server_date":1628999600,
905
- // "balances":{
906
- // "EXM":"0",
907
- // "USD":"0",
908
- // "EUR":"0",
909
- // "GBP":"0",
910
- // },
911
- // }
912
- //
917
+ let marginMode = undefined;
918
+ [marginMode, params] = this.handleMarginModeAndParams('fetchBalance', params);
919
+ if (marginMode === 'cross') {
920
+ throw new errors.BadRequest(this.id + ' does not support cross margin');
921
+ }
922
+ let response = undefined;
923
+ if (marginMode === 'isolated') {
924
+ response = await this.privatePostMarginUserWalletList(params);
925
+ //
926
+ // {
927
+ // "wallets": {
928
+ // "USD": {
929
+ // "balance": "1000",
930
+ // "free": "600",
931
+ // "used": "400"
932
+ // }
933
+ // }
934
+ // }
935
+ //
936
+ }
937
+ else {
938
+ response = await this.privatePostUserInfo(params);
939
+ //
940
+ // {
941
+ // "uid":131685,
942
+ // "server_date":1628999600,
943
+ // "balances":{
944
+ // "EXM":"0",
945
+ // "USD":"0",
946
+ // "EUR":"0",
947
+ // "GBP":"0",
948
+ // },
949
+ // }
950
+ //
951
+ }
913
952
  return this.parseBalance(response);
914
953
  }
915
954
  async fetchOrderBook(symbol, limit = undefined, params = {}) {
@@ -279,6 +279,8 @@ class gate extends gate$1 {
279
279
  },
280
280
  'portfolio': {
281
281
  'get': {
282
+ 'spot/currency_pairs': 1.5,
283
+ 'spot/currency_pairs/{currency_pair}': 1.5,
282
284
  'accounts': 1.5,
283
285
  'account_mode': 1.5,
284
286
  'borrowable': 1.5,
@@ -589,7 +589,6 @@ class hitbtc extends hitbtc$1 {
589
589
  'STEPN': 'GMT',
590
590
  'STX': 'STOX',
591
591
  'TV': 'Tokenville',
592
- 'USD': 'USDT',
593
592
  'XMT': 'MTL',
594
593
  'XPNT': 'PNT',
595
594
  },
@@ -641,6 +640,9 @@ class hitbtc extends hitbtc$1 {
641
640
  const ids = Object.keys(response);
642
641
  for (let i = 0; i < ids.length; i++) {
643
642
  const id = ids[i];
643
+ if (id.endsWith('_BQX')) {
644
+ 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"}
645
+ }
644
646
  const market = this.safeValue(response, id);
645
647
  const marketType = this.safeString(market, 'type');
646
648
  const expiry = this.safeInteger(market, 'expiry');
@@ -602,6 +602,7 @@ class huobi extends huobi$1 {
602
602
  'linear-swap-api/v3/unified_account_info': 1,
603
603
  'linear-swap-api/v3/fix_position_margin_change_record': 1,
604
604
  'linear-swap-api/v3/swap_unified_account_type': 1,
605
+ 'linear-swap-api/v3/linear_swap_overview_account_info': 1,
605
606
  },
606
607
  'post': {
607
608
  // Future Account Interface
@@ -796,6 +797,7 @@ class huobi extends huobi$1 {
796
797
  'linear-swap-api/v3/swap_cross_hisorders_exact': 1,
797
798
  'linear-swap-api/v3/fix_position_margin_change': 1,
798
799
  'linear-swap-api/v3/swap_switch_account_type': 1,
800
+ 'linear-swap-api/v3/linear_swap_fee_switch': 1,
799
801
  // Swap Strategy Order Interface
800
802
  'linear-swap-api/v1/swap_trigger_order': 1,
801
803
  'linear-swap-api/v1/swap_cross_trigger_order': 1,
@@ -492,6 +492,7 @@ class kucoin extends kucoin$1 {
492
492
  'versions': {
493
493
  'public': {
494
494
  'GET': {
495
+ 'currencies': 'v3',
495
496
  'currencies/{currency}': 'v2',
496
497
  'status': 'v1',
497
498
  'market/orderbook/level2_20': 'v1',
@@ -997,19 +998,34 @@ class kucoin extends kucoin$1 {
997
998
  const promises = [];
998
999
  promises.push(this.publicGetCurrencies(params));
999
1000
  //
1000
- // {
1001
- // "currency": "OMG",
1002
- // "name": "OMG",
1003
- // "fullName": "OmiseGO",
1004
- // "precision": 8,
1005
- // "confirms": 12,
1006
- // "withdrawalMinSize": "4",
1007
- // "withdrawalMinFee": "1.25",
1008
- // "isWithdrawEnabled": false,
1009
- // "isDepositEnabled": false,
1010
- // "isMarginEnabled": false,
1011
- // "isDebitEnabled": false
1012
- // }
1001
+ // {
1002
+ // "code":"200000",
1003
+ // "data":[
1004
+ // {
1005
+ // "currency":"CSP",
1006
+ // "name":"CSP",
1007
+ // "fullName":"Caspian",
1008
+ // "precision":8,
1009
+ // "confirms":null,
1010
+ // "contractAddress":null,
1011
+ // "isMarginEnabled":false,
1012
+ // "isDebitEnabled":false,
1013
+ // "chains":[
1014
+ // {
1015
+ // "chainName":"ERC20",
1016
+ // "chain":"eth",
1017
+ // "withdrawalMinSize":"2999",
1018
+ // "withdrawalMinFee":"2999",
1019
+ // "isWithdrawEnabled":false,
1020
+ // "isDepositEnabled":false,
1021
+ // "confirms":12,
1022
+ // "preConfirms":12,
1023
+ // "contractAddress":"0xa6446d655a0c34bc4f05042ee88170d056cbaf45",
1024
+ // "depositFeeRate": "0.001", // present for some currencies/networks
1025
+ // }
1026
+ // ]
1027
+ // },
1028
+ // }
1013
1029
  //
1014
1030
  promises.push(this.fetchWebEndpoint('fetchCurrencies', 'webExchangeGetCurrencyCurrencyChainInfo', true));
1015
1031
  //
@@ -1020,90 +1036,101 @@ class kucoin extends kucoin$1 {
1020
1036
  // "retry": false,
1021
1037
  // "data": [
1022
1038
  // {
1023
- // "withdrawMinFee": "0.0005",
1024
- // "chainName": "BTC",
1025
- // "preDepositTipEnabled": "false",
1026
- // "chain": "btc",
1039
+ // "status": "enabled",
1040
+ // "currency": "BTC",
1027
1041
  // "isChainEnabled": "true",
1028
- // "withdrawDisabledTip": "",
1029
- // "walletPrecision": "8",
1042
+ // "chain": "btc",
1043
+ // "chainName": "BTC",
1030
1044
  // "chainFullName": "Bitcoin",
1031
- // "orgAddress": "",
1045
+ // "walletPrecision": "8",
1032
1046
  // "isDepositEnabled": "true",
1033
- // "withdrawMinSize": "0.001",
1034
- // "depositDisabledTip": "",
1035
- // "userAddressName": "",
1036
- // "txUrl": "https://blockchain.info/tx/{txId}",
1037
- // "preWithdrawTipEnabled": "false",
1038
- // "withdrawFeeRate": "0",
1039
- // "confirmationCount": "2",
1040
- // "currency": "BTC",
1041
1047
  // "depositMinSize": "0.00005",
1048
+ // "confirmationCount": "2",
1042
1049
  // "isWithdrawEnabled": "true",
1043
- // "preDepositTip": "",
1050
+ // "withdrawMinSize": "0.001",
1051
+ // "withdrawMinFee": "0.0005",
1052
+ // "withdrawFeeRate": "0",
1053
+ // "depositDisabledTip": "Wallet Maintenance",
1054
+ // "preDepositTipEnabled": "true",
1055
+ // "preDepositTip": "Do not transfer from ETH network directly",
1056
+ // "withdrawDisabledTip": "",
1057
+ // "preWithdrawTipEnabled": "false",
1044
1058
  // "preWithdrawTip": "",
1045
- // "status": "enabled"
1059
+ // "orgAddress": "",
1060
+ // "userAddressName": "Memo",
1046
1061
  // },
1047
1062
  // ]
1048
1063
  // }
1049
1064
  //
1050
1065
  const responses = await Promise.all(promises);
1051
- const responseCurrencies = responses[0];
1052
- const responseChains = responses[1];
1053
- const data = this.safeValue(responseCurrencies, 'data', []);
1054
- const chainsData = this.safeValue(responseChains, 'data', []);
1055
- const currencyChains = this.groupBy(chainsData, 'currency');
1066
+ const currenciesResponse = this.safeValue(responses, 0, {});
1067
+ const currenciesData = this.safeValue(currenciesResponse, 'data', []);
1068
+ const additionalResponse = this.safeValue(responses, 1, {});
1069
+ const additionalData = this.safeValue(additionalResponse, 'data', []);
1070
+ const additionalDataGrouped = this.groupBy(additionalData, 'currency');
1056
1071
  const result = {};
1057
- for (let i = 0; i < data.length; i++) {
1058
- const entry = data[i];
1072
+ for (let i = 0; i < currenciesData.length; i++) {
1073
+ const entry = currenciesData[i];
1059
1074
  const id = this.safeString(entry, 'currency');
1060
1075
  const name = this.safeString(entry, 'fullName');
1061
1076
  const code = this.safeCurrencyCode(id);
1062
- const isWithdrawEnabled = this.safeValue(entry, 'isWithdrawEnabled', false);
1063
- const isDepositEnabled = this.safeValue(entry, 'isDepositEnabled', false);
1064
- const fee = this.safeNumber(entry, 'withdrawalMinFee');
1065
- const active = (isWithdrawEnabled && isDepositEnabled);
1077
+ let isWithdrawEnabled = undefined;
1078
+ let isDepositEnabled = undefined;
1066
1079
  const networks = {};
1067
- const chains = this.safeValue(currencyChains, id, []);
1080
+ const chains = this.safeValue(entry, 'chains', []);
1081
+ const extraChainsData = this.indexBy(this.safeValue(additionalDataGrouped, id, []), 'chain');
1082
+ const precision = this.parseNumber(this.parsePrecision(this.safeString(entry, 'precision')));
1068
1083
  for (let j = 0; j < chains.length; j++) {
1069
1084
  const chain = chains[j];
1070
1085
  const chainId = this.safeString(chain, 'chain');
1071
- const isChainEnabled = this.safeString(chain, 'isChainEnabled'); // better than 'status'
1072
- if (isChainEnabled === 'true') {
1073
- const networkCode = this.networkIdToCode(chainId);
1074
- const chainWithdrawEnabled = this.safeValue(chain, 'isWithdrawEnabled', false);
1075
- const chainDepositEnabled = this.safeValue(chain, 'isDepositEnabled', false);
1076
- networks[networkCode] = {
1077
- 'info': chain,
1078
- 'id': chainId,
1079
- 'name': this.safeString2(chain, 'chainFullName', 'chainName'),
1080
- 'code': networkCode,
1081
- 'active': chainWithdrawEnabled && chainDepositEnabled,
1082
- 'fee': this.safeNumber(chain, 'withdrawMinFee'),
1083
- 'precision': this.parseNumber(this.parsePrecision(this.safeString(chain, 'walletPrecision'))),
1084
- 'limits': {
1085
- 'withdraw': {
1086
- 'min': this.safeNumber(chain, 'withdrawMinSize'),
1087
- 'max': undefined,
1088
- },
1089
- 'deposit': {
1090
- 'min': this.safeNumber(chain, 'depositMinSize'),
1091
- 'max': undefined,
1092
- },
1093
- },
1094
- };
1086
+ const networkCode = this.networkIdToCode(chainId);
1087
+ const chainWithdrawEnabled = this.safeValue(chain, 'isWithdrawEnabled', false);
1088
+ if (isWithdrawEnabled === undefined) {
1089
+ isWithdrawEnabled = chainWithdrawEnabled;
1095
1090
  }
1091
+ else {
1092
+ isWithdrawEnabled = isWithdrawEnabled || chainWithdrawEnabled;
1093
+ }
1094
+ const chainDepositEnabled = this.safeValue(chain, 'isDepositEnabled', false);
1095
+ if (isDepositEnabled === undefined) {
1096
+ isDepositEnabled = chainDepositEnabled;
1097
+ }
1098
+ else {
1099
+ isDepositEnabled = isDepositEnabled || chainDepositEnabled;
1100
+ }
1101
+ const chainExtraData = this.safeValue(extraChainsData, chainId, {});
1102
+ networks[networkCode] = {
1103
+ 'info': chain,
1104
+ 'id': chainId,
1105
+ 'name': this.safeString(chain, 'chainName'),
1106
+ 'code': networkCode,
1107
+ 'active': chainWithdrawEnabled && chainDepositEnabled,
1108
+ 'fee': this.safeNumber(chain, 'withdrawalMinFee'),
1109
+ 'deposit': chainDepositEnabled,
1110
+ 'withdraw': chainWithdrawEnabled,
1111
+ 'precision': this.parseNumber(this.parsePrecision(this.safeString(chainExtraData, 'walletPrecision'))),
1112
+ 'limits': {
1113
+ 'withdraw': {
1114
+ 'min': this.safeNumber(chain, 'withdrawalMinSize'),
1115
+ 'max': undefined,
1116
+ },
1117
+ 'deposit': {
1118
+ 'min': this.safeNumber(chainExtraData, 'depositMinSize'),
1119
+ 'max': undefined,
1120
+ },
1121
+ },
1122
+ };
1096
1123
  }
1097
1124
  result[code] = {
1098
1125
  'id': id,
1099
1126
  'name': name,
1100
1127
  'code': code,
1101
- 'precision': this.parseNumber(this.parsePrecision(this.safeString(entry, 'precision'))),
1128
+ 'precision': precision,
1102
1129
  'info': entry,
1103
- 'active': active,
1130
+ 'active': (isDepositEnabled || isWithdrawEnabled),
1104
1131
  'deposit': isDepositEnabled,
1105
1132
  'withdraw': isWithdrawEnabled,
1106
- 'fee': fee,
1133
+ 'fee': undefined,
1107
1134
  'limits': this.limits,
1108
1135
  'networks': networks,
1109
1136
  };
@@ -621,7 +621,7 @@ class krakenfutures extends krakenfutures$1 {
621
621
  symbols[symbol] = true;
622
622
  cachedOrders.append(parsed);
623
623
  }
624
- if (this.orders.length > 0) {
624
+ if (this.orders.length) {
625
625
  client.resolve(this.orders, 'orders');
626
626
  const keys = Object.keys(symbols);
627
627
  for (let i = 0; i < keys.length; i++) {
@@ -95,15 +95,17 @@ class okx extends okx$1 {
95
95
  }
96
96
  getUrl(channel, access = 'public') {
97
97
  // for context: https://www.okx.com/help-center/changes-to-v5-api-websocket-subscription-parameter-and-url
98
+ const isSandbox = this.options['sandboxMode'];
99
+ const sandboxSuffix = isSandbox ? '?brokerId=9999' : '';
98
100
  const isPublic = (access === 'public');
99
101
  const url = this.urls['api']['ws'];
100
102
  if ((channel.indexOf('candle') > -1) || (channel === 'orders-algo')) {
101
- return url + '/business';
103
+ return url + '/business' + sandboxSuffix;
102
104
  }
103
105
  else if (isPublic) {
104
- return url + '/public';
106
+ return url + '/public' + sandboxSuffix;
105
107
  }
106
- return url + '/private';
108
+ return url + '/private' + sandboxSuffix;
107
109
  }
108
110
  async subscribeMultiple(access, channel, symbols = undefined, params = {}) {
109
111
  await this.loadMarkets();
@@ -1250,6 +1252,9 @@ class okx extends okx$1 {
1250
1252
  }
1251
1253
  return false;
1252
1254
  }
1255
+ else {
1256
+ client.reject(e);
1257
+ }
1253
1258
  }
1254
1259
  return message;
1255
1260
  }
@@ -513,11 +513,11 @@ class probit extends probit$1 {
513
513
  this.handleTicker(client, message);
514
514
  }
515
515
  const trades = this.safeValue(message, 'recent_trades', []);
516
- if (trades.length > 0) {
516
+ if (trades.length) {
517
517
  this.handleTrades(client, message);
518
518
  }
519
519
  const orderBook = this.safeValueN(message, ['order_books', 'order_books_l1', 'order_books_l2', 'order_books_l3', 'order_books_l4'], []);
520
- if (orderBook.length > 0) {
520
+ if (orderBook.length) {
521
521
  this.handleOrderBook(client, message, orderBook);
522
522
  }
523
523
  }
@@ -1725,12 +1725,20 @@ class upbit extends upbit$1 {
1725
1725
  };
1726
1726
  let method = 'privatePostWithdraws';
1727
1727
  if (code !== 'KRW') {
1728
+ // 2023-05-23 Change to required parameters for digital assets
1729
+ const network = this.safeStringUpper2(params, 'network', 'net_type');
1730
+ if (network === undefined) {
1731
+ throw new errors.ArgumentsRequired(this.id + ' withdraw() requires a network argument');
1732
+ }
1733
+ params = this.omit(params, ['network']);
1734
+ request['net_type'] = network;
1728
1735
  method += 'Coin';
1729
1736
  request['currency'] = currency['id'];
1730
1737
  request['address'] = address;
1731
1738
  if (tag !== undefined) {
1732
1739
  request['secondary_address'] = tag;
1733
1740
  }
1741
+ params = this.omit(params, 'network');
1734
1742
  }
1735
1743
  else {
1736
1744
  method += 'Krw';
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 { Market, Trade, Fee, Ticker, OrderBook, Order, Transaction, Tickers, Currency, Balance, DepositAddress, WithdrawalResponse, DepositAddressResponse, OHLCV, Balances, PartialBalances, Dictionary, MinMax } from './src/base/types.js';
6
6
  import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending } from './src/base/errors.js';
7
- declare const version = "4.0.79";
7
+ declare const version = "4.0.80";
8
8
  import ace from './src/ace.js';
9
9
  import alpaca from './src/alpaca.js';
10
10
  import ascendex from './src/ascendex.js';
package/js/ccxt.js CHANGED
@@ -38,7 +38,7 @@ import * as errors from './src/base/errors.js';
38
38
  import { BaseError, ExchangeError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, MarginModeAlreadySet, BadResponse, NullResponse, InsufficientFunds, InvalidAddress, InvalidOrder, OrderNotFound, OrderNotCached, CancelPending, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, NotSupported, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, RequestTimeout, AuthenticationError, AddressPending } from './src/base/errors.js';
39
39
  //-----------------------------------------------------------------------------
40
40
  // this is updated by vss.js when building
41
- const version = '4.0.80';
41
+ const version = '4.0.81';
42
42
  Exchange.ccxtVersion = version;
43
43
  //-----------------------------------------------------------------------------
44
44
  import ace from './src/ace.js';
@@ -59,6 +59,12 @@ interface Exchange {
59
59
  sapiGetLoanLoanableData(params?: {}): Promise<implicitReturnType>;
60
60
  sapiGetLoanCollateralData(params?: {}): Promise<implicitReturnType>;
61
61
  sapiGetLoanRepayCollateralRate(params?: {}): Promise<implicitReturnType>;
62
+ sapiGetLoanFlexibleOngoingOrders(params?: {}): Promise<implicitReturnType>;
63
+ sapiGetLoanFlexibleBorrowHistory(params?: {}): Promise<implicitReturnType>;
64
+ sapiGetLoanFlexibleRepayHistory(params?: {}): Promise<implicitReturnType>;
65
+ sapiGetLoanFlexibleLtvAdjustmentHistory(params?: {}): Promise<implicitReturnType>;
66
+ sapiGetLoanFlexibleLoanableData(params?: {}): Promise<implicitReturnType>;
67
+ sapiGetLoanFlexibleCollateralData(params?: {}): Promise<implicitReturnType>;
62
68
  sapiGetLoanVipOngoingOrders(params?: {}): Promise<implicitReturnType>;
63
69
  sapiGetLoanVipRepayHistory(params?: {}): Promise<implicitReturnType>;
64
70
  sapiGetLoanVipCollateralAccount(params?: {}): Promise<implicitReturnType>;
@@ -300,6 +306,9 @@ interface Exchange {
300
306
  sapiPostLoanRepay(params?: {}): Promise<implicitReturnType>;
301
307
  sapiPostLoanAdjustLtv(params?: {}): Promise<implicitReturnType>;
302
308
  sapiPostLoanCustomizeMarginCall(params?: {}): Promise<implicitReturnType>;
309
+ sapiPostLoanFlexibleBorrow(params?: {}): Promise<implicitReturnType>;
310
+ sapiPostLoanFlexibleRepay(params?: {}): Promise<implicitReturnType>;
311
+ sapiPostLoanFlexibleAdjustLtv(params?: {}): Promise<implicitReturnType>;
303
312
  sapiPostLoanVipRepay(params?: {}): Promise<implicitReturnType>;
304
313
  sapiPostConvertGetQuote(params?: {}): Promise<implicitReturnType>;
305
314
  sapiPostConvertAcceptQuote(params?: {}): Promise<implicitReturnType>;