ccxt 4.0.80 → 4.0.82

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 +212 -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 +10 -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 +10 -0
  23. package/js/src/abstract/binancecoinm.d.ts +10 -0
  24. package/js/src/abstract/binanceus.d.ts +10 -0
  25. package/js/src/abstract/binanceusdm.d.ts +10 -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 +10 -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/js/src/kucoin.js CHANGED
@@ -495,6 +495,7 @@ export default class kucoin extends Exchange {
495
495
  'versions': {
496
496
  'public': {
497
497
  'GET': {
498
+ 'currencies': 'v3',
498
499
  'currencies/{currency}': 'v2',
499
500
  'status': 'v1',
500
501
  'market/orderbook/level2_20': 'v1',
@@ -1000,19 +1001,34 @@ export default class kucoin extends Exchange {
1000
1001
  const promises = [];
1001
1002
  promises.push(this.publicGetCurrencies(params));
1002
1003
  //
1003
- // {
1004
- // "currency": "OMG",
1005
- // "name": "OMG",
1006
- // "fullName": "OmiseGO",
1007
- // "precision": 8,
1008
- // "confirms": 12,
1009
- // "withdrawalMinSize": "4",
1010
- // "withdrawalMinFee": "1.25",
1011
- // "isWithdrawEnabled": false,
1012
- // "isDepositEnabled": false,
1013
- // "isMarginEnabled": false,
1014
- // "isDebitEnabled": false
1015
- // }
1004
+ // {
1005
+ // "code":"200000",
1006
+ // "data":[
1007
+ // {
1008
+ // "currency":"CSP",
1009
+ // "name":"CSP",
1010
+ // "fullName":"Caspian",
1011
+ // "precision":8,
1012
+ // "confirms":null,
1013
+ // "contractAddress":null,
1014
+ // "isMarginEnabled":false,
1015
+ // "isDebitEnabled":false,
1016
+ // "chains":[
1017
+ // {
1018
+ // "chainName":"ERC20",
1019
+ // "chain":"eth",
1020
+ // "withdrawalMinSize":"2999",
1021
+ // "withdrawalMinFee":"2999",
1022
+ // "isWithdrawEnabled":false,
1023
+ // "isDepositEnabled":false,
1024
+ // "confirms":12,
1025
+ // "preConfirms":12,
1026
+ // "contractAddress":"0xa6446d655a0c34bc4f05042ee88170d056cbaf45",
1027
+ // "depositFeeRate": "0.001", // present for some currencies/networks
1028
+ // }
1029
+ // ]
1030
+ // },
1031
+ // }
1016
1032
  //
1017
1033
  promises.push(this.fetchWebEndpoint('fetchCurrencies', 'webExchangeGetCurrencyCurrencyChainInfo', true));
1018
1034
  //
@@ -1023,90 +1039,101 @@ export default class kucoin extends Exchange {
1023
1039
  // "retry": false,
1024
1040
  // "data": [
1025
1041
  // {
1026
- // "withdrawMinFee": "0.0005",
1027
- // "chainName": "BTC",
1028
- // "preDepositTipEnabled": "false",
1029
- // "chain": "btc",
1042
+ // "status": "enabled",
1043
+ // "currency": "BTC",
1030
1044
  // "isChainEnabled": "true",
1031
- // "withdrawDisabledTip": "",
1032
- // "walletPrecision": "8",
1045
+ // "chain": "btc",
1046
+ // "chainName": "BTC",
1033
1047
  // "chainFullName": "Bitcoin",
1034
- // "orgAddress": "",
1048
+ // "walletPrecision": "8",
1035
1049
  // "isDepositEnabled": "true",
1036
- // "withdrawMinSize": "0.001",
1037
- // "depositDisabledTip": "",
1038
- // "userAddressName": "",
1039
- // "txUrl": "https://blockchain.info/tx/{txId}",
1040
- // "preWithdrawTipEnabled": "false",
1041
- // "withdrawFeeRate": "0",
1042
- // "confirmationCount": "2",
1043
- // "currency": "BTC",
1044
1050
  // "depositMinSize": "0.00005",
1051
+ // "confirmationCount": "2",
1045
1052
  // "isWithdrawEnabled": "true",
1046
- // "preDepositTip": "",
1053
+ // "withdrawMinSize": "0.001",
1054
+ // "withdrawMinFee": "0.0005",
1055
+ // "withdrawFeeRate": "0",
1056
+ // "depositDisabledTip": "Wallet Maintenance",
1057
+ // "preDepositTipEnabled": "true",
1058
+ // "preDepositTip": "Do not transfer from ETH network directly",
1059
+ // "withdrawDisabledTip": "",
1060
+ // "preWithdrawTipEnabled": "false",
1047
1061
  // "preWithdrawTip": "",
1048
- // "status": "enabled"
1062
+ // "orgAddress": "",
1063
+ // "userAddressName": "Memo",
1049
1064
  // },
1050
1065
  // ]
1051
1066
  // }
1052
1067
  //
1053
1068
  const responses = await Promise.all(promises);
1054
- const responseCurrencies = responses[0];
1055
- const responseChains = responses[1];
1056
- const data = this.safeValue(responseCurrencies, 'data', []);
1057
- const chainsData = this.safeValue(responseChains, 'data', []);
1058
- const currencyChains = this.groupBy(chainsData, 'currency');
1069
+ const currenciesResponse = this.safeValue(responses, 0, {});
1070
+ const currenciesData = this.safeValue(currenciesResponse, 'data', []);
1071
+ const additionalResponse = this.safeValue(responses, 1, {});
1072
+ const additionalData = this.safeValue(additionalResponse, 'data', []);
1073
+ const additionalDataGrouped = this.groupBy(additionalData, 'currency');
1059
1074
  const result = {};
1060
- for (let i = 0; i < data.length; i++) {
1061
- const entry = data[i];
1075
+ for (let i = 0; i < currenciesData.length; i++) {
1076
+ const entry = currenciesData[i];
1062
1077
  const id = this.safeString(entry, 'currency');
1063
1078
  const name = this.safeString(entry, 'fullName');
1064
1079
  const code = this.safeCurrencyCode(id);
1065
- const isWithdrawEnabled = this.safeValue(entry, 'isWithdrawEnabled', false);
1066
- const isDepositEnabled = this.safeValue(entry, 'isDepositEnabled', false);
1067
- const fee = this.safeNumber(entry, 'withdrawalMinFee');
1068
- const active = (isWithdrawEnabled && isDepositEnabled);
1080
+ let isWithdrawEnabled = undefined;
1081
+ let isDepositEnabled = undefined;
1069
1082
  const networks = {};
1070
- const chains = this.safeValue(currencyChains, id, []);
1083
+ const chains = this.safeValue(entry, 'chains', []);
1084
+ const extraChainsData = this.indexBy(this.safeValue(additionalDataGrouped, id, []), 'chain');
1085
+ const precision = this.parseNumber(this.parsePrecision(this.safeString(entry, 'precision')));
1071
1086
  for (let j = 0; j < chains.length; j++) {
1072
1087
  const chain = chains[j];
1073
1088
  const chainId = this.safeString(chain, 'chain');
1074
- const isChainEnabled = this.safeString(chain, 'isChainEnabled'); // better than 'status'
1075
- if (isChainEnabled === 'true') {
1076
- const networkCode = this.networkIdToCode(chainId);
1077
- const chainWithdrawEnabled = this.safeValue(chain, 'isWithdrawEnabled', false);
1078
- const chainDepositEnabled = this.safeValue(chain, 'isDepositEnabled', false);
1079
- networks[networkCode] = {
1080
- 'info': chain,
1081
- 'id': chainId,
1082
- 'name': this.safeString2(chain, 'chainFullName', 'chainName'),
1083
- 'code': networkCode,
1084
- 'active': chainWithdrawEnabled && chainDepositEnabled,
1085
- 'fee': this.safeNumber(chain, 'withdrawMinFee'),
1086
- 'precision': this.parseNumber(this.parsePrecision(this.safeString(chain, 'walletPrecision'))),
1087
- 'limits': {
1088
- 'withdraw': {
1089
- 'min': this.safeNumber(chain, 'withdrawMinSize'),
1090
- 'max': undefined,
1091
- },
1092
- 'deposit': {
1093
- 'min': this.safeNumber(chain, 'depositMinSize'),
1094
- 'max': undefined,
1095
- },
1096
- },
1097
- };
1089
+ const networkCode = this.networkIdToCode(chainId);
1090
+ const chainWithdrawEnabled = this.safeValue(chain, 'isWithdrawEnabled', false);
1091
+ if (isWithdrawEnabled === undefined) {
1092
+ isWithdrawEnabled = chainWithdrawEnabled;
1098
1093
  }
1094
+ else {
1095
+ isWithdrawEnabled = isWithdrawEnabled || chainWithdrawEnabled;
1096
+ }
1097
+ const chainDepositEnabled = this.safeValue(chain, 'isDepositEnabled', false);
1098
+ if (isDepositEnabled === undefined) {
1099
+ isDepositEnabled = chainDepositEnabled;
1100
+ }
1101
+ else {
1102
+ isDepositEnabled = isDepositEnabled || chainDepositEnabled;
1103
+ }
1104
+ const chainExtraData = this.safeValue(extraChainsData, chainId, {});
1105
+ networks[networkCode] = {
1106
+ 'info': chain,
1107
+ 'id': chainId,
1108
+ 'name': this.safeString(chain, 'chainName'),
1109
+ 'code': networkCode,
1110
+ 'active': chainWithdrawEnabled && chainDepositEnabled,
1111
+ 'fee': this.safeNumber(chain, 'withdrawalMinFee'),
1112
+ 'deposit': chainDepositEnabled,
1113
+ 'withdraw': chainWithdrawEnabled,
1114
+ 'precision': this.parseNumber(this.parsePrecision(this.safeString(chainExtraData, 'walletPrecision'))),
1115
+ 'limits': {
1116
+ 'withdraw': {
1117
+ 'min': this.safeNumber(chain, 'withdrawalMinSize'),
1118
+ 'max': undefined,
1119
+ },
1120
+ 'deposit': {
1121
+ 'min': this.safeNumber(chainExtraData, 'depositMinSize'),
1122
+ 'max': undefined,
1123
+ },
1124
+ },
1125
+ };
1099
1126
  }
1100
1127
  result[code] = {
1101
1128
  'id': id,
1102
1129
  'name': name,
1103
1130
  'code': code,
1104
- 'precision': this.parseNumber(this.parsePrecision(this.safeString(entry, 'precision'))),
1131
+ 'precision': precision,
1105
1132
  'info': entry,
1106
- 'active': active,
1133
+ 'active': (isDepositEnabled || isWithdrawEnabled),
1107
1134
  'deposit': isDepositEnabled,
1108
1135
  'withdraw': isWithdrawEnabled,
1109
- 'fee': fee,
1136
+ 'fee': undefined,
1110
1137
  'limits': this.limits,
1111
1138
  'networks': networks,
1112
1139
  };
@@ -624,7 +624,7 @@ export default class krakenfutures extends krakenfuturesRest {
624
624
  symbols[symbol] = true;
625
625
  cachedOrders.append(parsed);
626
626
  }
627
- if (this.orders.length > 0) {
627
+ if (this.orders.length) {
628
628
  client.resolve(this.orders, 'orders');
629
629
  const keys = Object.keys(symbols);
630
630
  for (let i = 0; i < keys.length; i++) {
package/js/src/pro/okx.js CHANGED
@@ -98,15 +98,17 @@ export default class okx extends okxRest {
98
98
  }
99
99
  getUrl(channel, access = 'public') {
100
100
  // for context: https://www.okx.com/help-center/changes-to-v5-api-websocket-subscription-parameter-and-url
101
+ const isSandbox = this.options['sandboxMode'];
102
+ const sandboxSuffix = isSandbox ? '?brokerId=9999' : '';
101
103
  const isPublic = (access === 'public');
102
104
  const url = this.urls['api']['ws'];
103
105
  if ((channel.indexOf('candle') > -1) || (channel === 'orders-algo')) {
104
- return url + '/business';
106
+ return url + '/business' + sandboxSuffix;
105
107
  }
106
108
  else if (isPublic) {
107
- return url + '/public';
109
+ return url + '/public' + sandboxSuffix;
108
110
  }
109
- return url + '/private';
111
+ return url + '/private' + sandboxSuffix;
110
112
  }
111
113
  async subscribeMultiple(access, channel, symbols = undefined, params = {}) {
112
114
  await this.loadMarkets();
@@ -1253,6 +1255,9 @@ export default class okx extends okxRest {
1253
1255
  }
1254
1256
  return false;
1255
1257
  }
1258
+ else {
1259
+ client.reject(e);
1260
+ }
1256
1261
  }
1257
1262
  return message;
1258
1263
  }
@@ -518,11 +518,11 @@ export default class probit extends probitRest {
518
518
  this.handleTicker(client, message);
519
519
  }
520
520
  const trades = this.safeValue(message, 'recent_trades', []);
521
- if (trades.length > 0) {
521
+ if (trades.length) {
522
522
  this.handleTrades(client, message);
523
523
  }
524
524
  const orderBook = this.safeValueN(message, ['order_books', 'order_books_l1', 'order_books_l2', 'order_books_l3', 'order_books_l4'], []);
525
- if (orderBook.length > 0) {
525
+ if (orderBook.length) {
526
526
  this.handleOrderBook(client, message, orderBook);
527
527
  }
528
528
  }
package/js/src/upbit.js CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  // ---------------------------------------------------------------------------
8
8
  import Exchange from './abstract/upbit.js';
9
- import { ExchangeError, BadRequest, AuthenticationError, InvalidOrder, InsufficientFunds, OrderNotFound, PermissionDenied, AddressPending } from './base/errors.js';
9
+ import { ExchangeError, BadRequest, AuthenticationError, InvalidOrder, InsufficientFunds, OrderNotFound, PermissionDenied, AddressPending, ArgumentsRequired } from './base/errors.js';
10
10
  import { Precise } from './base/Precise.js';
11
11
  import { TICK_SIZE } from './base/functions/number.js';
12
12
  import { sha512 } from './static_dependencies/noble-hashes/sha512.js';
@@ -1728,12 +1728,20 @@ export default class upbit extends Exchange {
1728
1728
  };
1729
1729
  let method = 'privatePostWithdraws';
1730
1730
  if (code !== 'KRW') {
1731
+ // 2023-05-23 Change to required parameters for digital assets
1732
+ const network = this.safeStringUpper2(params, 'network', 'net_type');
1733
+ if (network === undefined) {
1734
+ throw new ArgumentsRequired(this.id + ' withdraw() requires a network argument');
1735
+ }
1736
+ params = this.omit(params, ['network']);
1737
+ request['net_type'] = network;
1731
1738
  method += 'Coin';
1732
1739
  request['currency'] = currency['id'];
1733
1740
  request['address'] = address;
1734
1741
  if (tag !== undefined) {
1735
1742
  request['secondary_address'] = tag;
1736
1743
  }
1744
+ params = this.omit(params, 'network');
1737
1745
  }
1738
1746
  else {
1739
1747
  method += 'Krw';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccxt",
3
- "version": "4.0.80",
3
+ "version": "4.0.82",
4
4
  "description": "A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 130+ exchanges",
5
5
  "unpkg": "dist/ccxt.browser.js",
6
6
  "type": "module",
package/skip-tests.json CHANGED
@@ -201,6 +201,8 @@
201
201
  }
202
202
  },
203
203
  "bithumb": {
204
+ "skip": "fetchMarkets returning undefined",
205
+ "until": "2023-09-05",
204
206
  "skipMethods": {
205
207
  "fetchTickers": {
206
208
  "quoteVolume": "quoteVolume >= baseVolume * low is failing",
@@ -511,7 +513,8 @@
511
513
  },
512
514
  "fetchTickers": {
513
515
  "bid": "broken bid-ask",
514
- "ask": "broken bid-ask"
516
+ "ask": "broken bid-ask",
517
+ "baseVolume": "negative value"
515
518
  }
516
519
  }
517
520
  },
@@ -915,7 +918,9 @@
915
918
  "skipWs": true,
916
919
  "skipMethods":{
917
920
  "fetchCurrencies": {
918
- "networks": "not yet implemented"
921
+ "networks": "not yet implemented",
922
+ "withdraw": "not provided for some currencies",
923
+ "deposit": "not provided for some currencies"
919
924
  },
920
925
  "loadMarkets": {
921
926
  "currencyIdAndCode": "messed"