ccxt 4.2.68 → 4.2.70

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.
@@ -7254,7 +7254,7 @@ class Exchange {
7254
7254
  this.socksProxyAgentModule = undefined;
7255
7255
  this.socksProxyAgentModuleChecked = false;
7256
7256
  this.proxyDictionaries = {};
7257
- this.proxyModulesLoaded = false;
7257
+ this.proxiesModulesLoading = undefined;
7258
7258
  Object.assign(this, _functions_js__WEBPACK_IMPORTED_MODULE_0__);
7259
7259
  //
7260
7260
  // if (isNode) {
@@ -7755,36 +7755,38 @@ class Exchange {
7755
7755
  console.log(...args);
7756
7756
  }
7757
7757
  async loadProxyModules() {
7758
- if (this.proxyModulesLoaded) {
7759
- return;
7760
- }
7761
- this.proxyModulesLoaded = true;
7762
- // we have to handle it with below nested way, because of dynamic
7763
- // import issues (https://github.com/ccxt/ccxt/pull/20687)
7764
- try {
7765
- // todo: possible sync alternatives: https://stackoverflow.com/questions/51069002/convert-import-to-synchronous
7766
- this.httpProxyAgentModule = await import(/* webpackIgnore: true */ '../static_dependencies/proxies/http-proxy-agent/index.js');
7767
- this.httpsProxyAgentModule = await import(/* webpackIgnore: true */ '../static_dependencies/proxies/https-proxy-agent/index.js');
7768
- }
7769
- catch (e) {
7770
- // if several users are using those frameworks which cause exceptions,
7771
- // let them to be able to load modules still, by installing them
7772
- try {
7773
- // @ts-ignore
7774
- this.httpProxyAgentModule = await import(/* webpackIgnore: true */ 'http-proxy-agent');
7775
- // @ts-ignore
7776
- this.httpProxyAgentModule = await import(/* webpackIgnore: true */ 'https-proxy-agent');
7777
- }
7778
- catch (e) { }
7779
- }
7780
- if (this.socksProxyAgentModuleChecked === false) {
7781
- this.socksProxyAgentModuleChecked = true;
7782
- try {
7783
- // @ts-ignore
7784
- this.socksProxyAgentModule = await import(/* webpackIgnore: true */ 'socks-proxy-agent');
7785
- }
7786
- catch (e) { }
7758
+ // when loading markets, multiple parallel calls are made, so need one promise
7759
+ if (this.proxiesModulesLoading === undefined) {
7760
+ this.proxiesModulesLoading = (async () => {
7761
+ // we have to handle it with below nested way, because of dynamic
7762
+ // import issues (https://github.com/ccxt/ccxt/pull/20687)
7763
+ try {
7764
+ // todo: possible sync alternatives: https://stackoverflow.com/questions/51069002/convert-import-to-synchronous
7765
+ this.httpProxyAgentModule = await import(/* webpackIgnore: true */ '../static_dependencies/proxies/http-proxy-agent/index.js');
7766
+ this.httpsProxyAgentModule = await import(/* webpackIgnore: true */ '../static_dependencies/proxies/https-proxy-agent/index.js');
7767
+ }
7768
+ catch (e) {
7769
+ // if several users are using those frameworks which cause exceptions,
7770
+ // let them to be able to load modules still, by installing them
7771
+ try {
7772
+ // @ts-ignore
7773
+ this.httpProxyAgentModule = await import(/* webpackIgnore: true */ 'http-proxy-agent');
7774
+ // @ts-ignore
7775
+ this.httpProxyAgentModule = await import(/* webpackIgnore: true */ 'https-proxy-agent');
7776
+ }
7777
+ catch (e) { }
7778
+ }
7779
+ if (this.socksProxyAgentModuleChecked === false) {
7780
+ try {
7781
+ // @ts-ignore
7782
+ this.socksProxyAgentModule = await import(/* webpackIgnore: true */ 'socks-proxy-agent');
7783
+ }
7784
+ catch (e) { }
7785
+ this.socksProxyAgentModuleChecked = true;
7786
+ }
7787
+ })();
7787
7788
  }
7789
+ return await this.proxiesModulesLoading;
7788
7790
  }
7789
7791
  setProxyAgents(httpProxy, httpsProxy, socksProxy) {
7790
7792
  let chosenAgent = undefined;
@@ -68854,6 +68856,7 @@ class bitstamp extends _abstract_bitstamp_js__WEBPACK_IMPORTED_MODULE_0__/* ["de
68854
68856
  'setLeverage': false,
68855
68857
  'setMarginMode': false,
68856
68858
  'setPositionMode': false,
68859
+ 'transfer': true,
68857
68860
  'withdraw': true,
68858
68861
  },
68859
68862
  'urls': {
@@ -70888,6 +70891,73 @@ class bitstamp extends _abstract_bitstamp_js__WEBPACK_IMPORTED_MODULE_0__/* ["de
70888
70891
  const response = await this[method](this.extend(request, params));
70889
70892
  return this.parseTransaction(response, currency);
70890
70893
  }
70894
+ async transfer(code, amount, fromAccount, toAccount, params = {}) {
70895
+ /**
70896
+ * @method
70897
+ * @name bitstamp#transfer
70898
+ * @description transfer currency internally between wallets on the same account
70899
+ * @see https://www.bitstamp.net/api/#tag/Sub-account/operation/TransferFromMainToSub
70900
+ * @see https://www.bitstamp.net/api/#tag/Sub-account/operation/TransferFromSubToMain
70901
+ * @param {string} code unified currency code
70902
+ * @param {float} amount amount to transfer
70903
+ * @param {string} fromAccount account to transfer from
70904
+ * @param {string} toAccount account to transfer to
70905
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
70906
+ * @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
70907
+ */
70908
+ await this.loadMarkets();
70909
+ const currency = this.currency(code);
70910
+ amount = this.currencyToPrecision(code, amount);
70911
+ amount = this.parseToNumeric(amount);
70912
+ const request = {
70913
+ 'amount': amount,
70914
+ 'currency': currency['id'].toUpperCase(),
70915
+ };
70916
+ let response = undefined;
70917
+ if (fromAccount === 'main') {
70918
+ request['subAccount'] = toAccount;
70919
+ response = await this.privatePostTransferFromMain(this.extend(request, params));
70920
+ }
70921
+ else if (toAccount === 'main') {
70922
+ request['subAccount'] = fromAccount;
70923
+ response = await this.privatePostTransferToMain(this.extend(request, params));
70924
+ }
70925
+ else {
70926
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest(this.id + ' transfer() only supports from or to main');
70927
+ }
70928
+ //
70929
+ // { status: 'ok' }
70930
+ //
70931
+ const transfer = this.parseTransfer(response, currency);
70932
+ transfer['amount'] = amount;
70933
+ transfer['fromAccount'] = fromAccount;
70934
+ transfer['toAccount'] = toAccount;
70935
+ return transfer;
70936
+ }
70937
+ parseTransfer(transfer, currency = undefined) {
70938
+ //
70939
+ // { status: 'ok' }
70940
+ //
70941
+ const status = this.safeString(transfer, 'status');
70942
+ return {
70943
+ 'info': transfer,
70944
+ 'id': undefined,
70945
+ 'timestamp': undefined,
70946
+ 'datetime': undefined,
70947
+ 'currency': currency['code'],
70948
+ 'amount': undefined,
70949
+ 'fromAccount': undefined,
70950
+ 'toAccount': undefined,
70951
+ 'status': this.parseTransferStatus(status),
70952
+ };
70953
+ }
70954
+ parseTransferStatus(status) {
70955
+ const statuses = {
70956
+ 'ok': 'ok',
70957
+ 'error': 'failed',
70958
+ };
70959
+ return this.safeString(statuses, status, status);
70960
+ }
70891
70961
  nonce() {
70892
70962
  return this.milliseconds();
70893
70963
  }
@@ -133371,7 +133441,8 @@ class gate extends _abstract_gate_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
133371
133441
  'fetchIsolatedBorrowRate': false,
133372
133442
  'fetchIsolatedBorrowRates': false,
133373
133443
  'fetchLedger': true,
133374
- 'fetchLeverage': false,
133444
+ 'fetchLeverage': true,
133445
+ 'fetchLeverages': true,
133375
133446
  'fetchLeverageTiers': true,
133376
133447
  'fetchLiquidations': true,
133377
133448
  'fetchMarginMode': false,
@@ -137736,7 +137807,10 @@ class gate extends _abstract_gate_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
137736
137807
  if (lastTradeTimestamp === undefined) {
137737
137808
  lastTradeTimestamp = this.safeTimestamp2(order, 'update_time', 'finish_time');
137738
137809
  }
137739
- const marketType = ('currency_pair' in order) ? 'spot' : 'contract';
137810
+ let marketType = 'contract';
137811
+ if (('currency_pair' in order) || ('market' in order)) {
137812
+ marketType = 'spot';
137813
+ }
137740
137814
  const exchangeSymbol = this.safeString2(order, 'currency_pair', 'market', contract);
137741
137815
  const symbol = this.safeSymbol(exchangeSymbol, market, '_', marketType);
137742
137816
  // Everything below this(above return) is related to fees
@@ -140268,6 +140342,178 @@ class gate extends _abstract_gate_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"]
140268
140342
  }
140269
140343
  return await this.createOrder(symbol, 'market', side, 0, undefined, params);
140270
140344
  }
140345
+ async fetchLeverage(symbol, params = {}) {
140346
+ /**
140347
+ * @method
140348
+ * @name gate#fetchLeverage
140349
+ * @description fetch the set leverage for a market
140350
+ * @see https://www.gate.io/docs/developers/apiv4/en/#get-unified-account-information
140351
+ * @see https://www.gate.io/docs/developers/apiv4/en/#get-detail-of-lending-market
140352
+ * @see https://www.gate.io/docs/developers/apiv4/en/#query-one-single-margin-currency-pair-deprecated
140353
+ * @param {string} symbol unified market symbol
140354
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
140355
+ * @param {boolean} [params.unified] default false, set to true for fetching the unified accounts leverage
140356
+ * @returns {object} a [leverage structure]{@link https://docs.ccxt.com/#/?id=leverage-structure}
140357
+ */
140358
+ await this.loadMarkets();
140359
+ let market = undefined;
140360
+ if (symbol !== undefined) {
140361
+ // unified account does not require a symbol
140362
+ market = this.market(symbol);
140363
+ }
140364
+ const request = {};
140365
+ let response = undefined;
140366
+ const isUnified = this.safeBool(params, 'unified');
140367
+ params = this.omit(params, 'unified');
140368
+ if (market['spot']) {
140369
+ request['currency_pair'] = market['id'];
140370
+ if (isUnified) {
140371
+ response = await this.publicMarginGetUniCurrencyPairsCurrencyPair(this.extend(request, params));
140372
+ //
140373
+ // {
140374
+ // "currency_pair": "BTC_USDT",
140375
+ // "base_min_borrow_amount": "0.0001",
140376
+ // "quote_min_borrow_amount": "1",
140377
+ // "leverage": "10"
140378
+ // }
140379
+ //
140380
+ }
140381
+ else {
140382
+ response = await this.publicMarginGetCurrencyPairsCurrencyPair(this.extend(request, params));
140383
+ //
140384
+ // {
140385
+ // "id": "BTC_USDT",
140386
+ // "base": "BTC",
140387
+ // "quote": "USDT",
140388
+ // "leverage": 10,
140389
+ // "min_base_amount": "0.0001",
140390
+ // "min_quote_amount": "1",
140391
+ // "max_quote_amount": "40000000",
140392
+ // "status": 1
140393
+ // }
140394
+ //
140395
+ }
140396
+ }
140397
+ else if (isUnified) {
140398
+ response = await this.privateUnifiedGetAccounts(this.extend(request, params));
140399
+ //
140400
+ // {
140401
+ // "user_id": 10001,
140402
+ // "locked": false,
140403
+ // "balances": {
140404
+ // "ETH": {
140405
+ // "available": "0",
140406
+ // "freeze": "0",
140407
+ // "borrowed": "0.075393666654",
140408
+ // "negative_liab": "0",
140409
+ // "futures_pos_liab": "0",
140410
+ // "equity": "1016.1",
140411
+ // "total_freeze": "0",
140412
+ // "total_liab": "0"
140413
+ // },
140414
+ // "POINT": {
140415
+ // "available": "9999999999.017023138734",
140416
+ // "freeze": "0",
140417
+ // "borrowed": "0",
140418
+ // "negative_liab": "0",
140419
+ // "futures_pos_liab": "0",
140420
+ // "equity": "12016.1",
140421
+ // "total_freeze": "0",
140422
+ // "total_liab": "0"
140423
+ // },
140424
+ // "USDT": {
140425
+ // "available": "0.00000062023",
140426
+ // "freeze": "0",
140427
+ // "borrowed": "0",
140428
+ // "negative_liab": "0",
140429
+ // "futures_pos_liab": "0",
140430
+ // "equity": "16.1",
140431
+ // "total_freeze": "0",
140432
+ // "total_liab": "0"
140433
+ // }
140434
+ // },
140435
+ // "total": "230.94621713",
140436
+ // "borrowed": "161.66395521",
140437
+ // "total_initial_margin": "1025.0524665088",
140438
+ // "total_margin_balance": "3382495.944473949183",
140439
+ // "total_maintenance_margin": "205.01049330176",
140440
+ // "total_initial_margin_rate": "3299.827135672679",
140441
+ // "total_maintenance_margin_rate": "16499.135678363399",
140442
+ // "total_available_margin": "3381470.892007440383",
140443
+ // "unified_account_total": "3381470.892007440383",
140444
+ // "unified_account_total_liab": "0",
140445
+ // "unified_account_total_equity": "100016.1",
140446
+ // "leverage": "2"
140447
+ // }
140448
+ //
140449
+ }
140450
+ else {
140451
+ throw new _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.NotSupported(this.id + ' fetchLeverage() does not support ' + market['type'] + ' markets');
140452
+ }
140453
+ return this.parseLeverage(response, market);
140454
+ }
140455
+ async fetchLeverages(symbols = undefined, params = {}) {
140456
+ /**
140457
+ * @method
140458
+ * @name gate#fetchLeverages
140459
+ * @description fetch the set leverage for all leverage markets, only spot margin is supported on gate
140460
+ * @see https://www.gate.io/docs/developers/apiv4/en/#list-lending-markets
140461
+ * @see https://www.gate.io/docs/developers/apiv4/en/#list-all-supported-currency-pairs-supported-in-margin-trading-deprecated
140462
+ * @param {string[]} symbols a list of unified market symbols
140463
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
140464
+ * @param {boolean} [params.unified] default false, set to true for fetching unified account leverages
140465
+ * @returns {object} a list of [leverage structures]{@link https://docs.ccxt.com/#/?id=leverage-structure}
140466
+ */
140467
+ await this.loadMarkets();
140468
+ symbols = this.marketSymbols(symbols);
140469
+ let response = undefined;
140470
+ const isUnified = this.safeBool(params, 'unified');
140471
+ params = this.omit(params, 'unified');
140472
+ let marketIdRequest = 'id';
140473
+ if (isUnified) {
140474
+ marketIdRequest = 'currency_pair';
140475
+ response = await this.publicMarginGetUniCurrencyPairs(params);
140476
+ //
140477
+ // [
140478
+ // {
140479
+ // "currency_pair": "1INCH_USDT",
140480
+ // "base_min_borrow_amount": "8",
140481
+ // "quote_min_borrow_amount": "1",
140482
+ // "leverage": "3"
140483
+ // },
140484
+ // ]
140485
+ //
140486
+ }
140487
+ else {
140488
+ response = await this.publicMarginGetCurrencyPairs(params);
140489
+ //
140490
+ // [
140491
+ // {
140492
+ // "id": "1CAT_USDT",
140493
+ // "base": "1CAT",
140494
+ // "quote": "USDT",
140495
+ // "leverage": 3,
140496
+ // "min_base_amount": "71",
140497
+ // "min_quote_amount": "1",
140498
+ // "max_quote_amount": "10000",
140499
+ // "status": 1
140500
+ // },
140501
+ // ]
140502
+ //
140503
+ }
140504
+ return this.parseLeverages(response, symbols, marketIdRequest, 'spot');
140505
+ }
140506
+ parseLeverage(leverage, market = undefined) {
140507
+ const marketId = this.safeString2(leverage, 'currency_pair', 'id');
140508
+ const leverageValue = this.safeInteger(leverage, 'leverage');
140509
+ return {
140510
+ 'info': leverage,
140511
+ 'symbol': this.safeSymbol(marketId, market, '_', 'spot'),
140512
+ 'marginMode': undefined,
140513
+ 'longLeverage': leverageValue,
140514
+ 'shortLeverage': leverageValue,
140515
+ };
140516
+ }
140271
140517
  handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
140272
140518
  if (response === undefined) {
140273
140519
  return undefined;
@@ -140351,7 +140597,7 @@ class gemini extends _abstract_gemini_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
140351
140597
  'CORS': undefined,
140352
140598
  'spot': true,
140353
140599
  'margin': false,
140354
- 'swap': false,
140600
+ 'swap': true,
140355
140601
  'future': false,
140356
140602
  'option': false,
140357
140603
  'addMargin': false,
@@ -140576,11 +140822,11 @@ class gemini extends _abstract_gemini_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
140576
140822
  },
140577
140823
  },
140578
140824
  'options': {
140579
- 'fetchMarketsMethod': 'fetch_markets_from_web',
140825
+ 'fetchMarketsMethod': 'fetch_markets_from_api',
140580
140826
  'fetchMarketFromWebRetries': 10,
140581
140827
  'fetchMarketsFromAPI': {
140582
140828
  'fetchDetailsForAllSymbols': false,
140583
- 'fetchDetailsForMarketIds': [],
140829
+ 'quoteCurrencies': ['USDT', 'GUSD', 'USD', 'DAI', 'EUR', 'GBP', 'SGD', 'BTC', 'ETH', 'LTC', 'BCH'],
140584
140830
  },
140585
140831
  'fetchMarkets': {
140586
140832
  'webApiEnable': true,
@@ -140636,10 +140882,7 @@ class gemini extends _abstract_gemini_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
140636
140882
  }
140637
140883
  //
140638
140884
  // {
140639
- // "tradingPairs": [
140640
- // [ "BTCAUD", 2, 8, "0.00001", 10, true ],
140641
- // ...
140642
- // ],
140885
+ // "tradingPairs": [ [ 'BTCUSD', 2, 8, '0.00001', 10, true ], ... ],
140643
140886
  // "currencies": [
140644
140887
  // [ "ORCA", "Orca", 204, 6, 0, 6, 8, false, null, "solana" ], // as confirmed, precisions seem to be the 5th index
140645
140888
  // [ "ATOM", "Cosmos", 44, 6, 0, 6, 8, false, null, "cosmos" ],
@@ -140658,6 +140901,7 @@ class gemini extends _abstract_gemini_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
140658
140901
  // }
140659
140902
  //
140660
140903
  const result = {};
140904
+ this.options['tradingPairs'] = this.safeList(data, 'tradingPairs');
140661
140905
  const currenciesArray = this.safeValue(data, 'currencies', []);
140662
140906
  for (let i = 0; i < currenciesArray.length; i++) {
140663
140907
  const currency = currenciesArray[i];
@@ -140867,7 +141111,7 @@ class gemini extends _abstract_gemini_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
140867
141111
  return result;
140868
141112
  }
140869
141113
  async fetchMarketsFromAPI(params = {}) {
140870
- const response = await this.publicGetV1Symbols(params);
141114
+ const marketIdsRaw = await this.publicGetV1Symbols(params);
140871
141115
  //
140872
141116
  // [
140873
141117
  // "btcusd",
@@ -140875,93 +141119,185 @@ class gemini extends _abstract_gemini_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
140875
141119
  // ...
140876
141120
  // ]
140877
141121
  //
140878
- const result = {};
140879
- for (let i = 0; i < response.length; i++) {
140880
- const marketId = response[i];
140881
- const market = {
140882
- 'symbol': marketId,
140883
- };
140884
- result[marketId] = this.parseMarket(market);
141122
+ const result = [];
141123
+ const options = this.safeDict(this.options, 'fetchMarketsFromAPI', {});
141124
+ const bugSymbol = 'efilfil'; // we skip this inexistent test symbol, which bugs other functions
141125
+ const marketIds = [];
141126
+ for (let i = 0; i < marketIdsRaw.length; i++) {
141127
+ if (marketIdsRaw[i] !== bugSymbol) {
141128
+ marketIds.push(marketIdsRaw[i]);
141129
+ }
140885
141130
  }
140886
- const options = this.safeValue(this.options, 'fetchMarketsFromAPI', {});
140887
- const fetchDetailsForAllSymbols = this.safeBool(options, 'fetchDetailsForAllSymbols', false);
140888
- const fetchDetailsForMarketIds = this.safeValue(options, 'fetchDetailsForMarketIds', []);
140889
- let promises = [];
140890
- let marketIds = [];
140891
- if (fetchDetailsForAllSymbols) {
140892
- marketIds = response;
141131
+ if (this.safeBool(options, 'fetchDetailsForAllSymbols', false)) {
141132
+ const promises = [];
141133
+ for (let i = 0; i < marketIds.length; i++) {
141134
+ const marketId = marketIds[i];
141135
+ const request = {
141136
+ 'symbol': marketId,
141137
+ };
141138
+ promises.push(this.publicGetV1SymbolsDetailsSymbol(this.extend(request, params)));
141139
+ //
141140
+ // {
141141
+ // "symbol": "BTCUSD",
141142
+ // "base_currency": "BTC",
141143
+ // "quote_currency": "USD",
141144
+ // "tick_size": 1E-8,
141145
+ // "quote_increment": 0.01,
141146
+ // "min_order_size": "0.00001",
141147
+ // "status": "open",
141148
+ // "wrap_enabled": false
141149
+ // }
141150
+ //
141151
+ }
141152
+ const responses = await Promise.all(promises);
141153
+ for (let i = 0; i < responses.length; i++) {
141154
+ result.push(this.parseMarket(responses[i]));
141155
+ }
140893
141156
  }
140894
141157
  else {
140895
- marketIds = fetchDetailsForMarketIds;
140896
- }
140897
- for (let i = 0; i < marketIds.length; i++) {
140898
- const marketId = marketIds[i];
140899
- const request = {
140900
- 'symbol': marketId,
140901
- };
140902
- promises.push(this.publicGetV1SymbolsDetailsSymbol(this.extend(request, params)));
140903
- //
140904
- // {
140905
- // "symbol": "BTCUSD",
140906
- // "base_currency": "BTC",
140907
- // "quote_currency": "USD",
140908
- // "tick_size": 1E-8,
140909
- // "quote_increment": 0.01,
140910
- // "min_order_size": "0.00001",
140911
- // "status": "open",
140912
- // "wrap_enabled": false
140913
- // }
140914
- //
140915
- }
140916
- promises = await Promise.all(promises);
140917
- for (let i = 0; i < promises.length; i++) {
140918
- const responseInner = promises[i];
140919
- const marketId = this.safeStringLower(responseInner, 'symbol');
140920
- result[marketId] = this.parseMarket(responseInner);
141158
+ // use trading-pairs info, if it was fetched
141159
+ const tradingPairs = this.safeList(this.options, 'tradingPairs');
141160
+ if (tradingPairs !== undefined) {
141161
+ const indexedTradingPairs = this.indexBy(tradingPairs, 0);
141162
+ for (let i = 0; i < marketIds.length; i++) {
141163
+ const marketId = marketIds[i];
141164
+ const tradingPair = this.safeList(indexedTradingPairs, marketId.toUpperCase());
141165
+ if (tradingPair !== undefined) {
141166
+ result.push(this.parseMarket(tradingPair));
141167
+ }
141168
+ }
141169
+ }
141170
+ else {
141171
+ for (let i = 0; i < marketIds.length; i++) {
141172
+ result.push(this.parseMarket(marketIds[i]));
141173
+ }
141174
+ }
140921
141175
  }
140922
- return this.toArray(result);
141176
+ return result;
140923
141177
  }
140924
141178
  parseMarket(response) {
140925
- const marketId = this.safeStringLower(response, 'symbol');
140926
- let baseId = this.safeString(response, 'base_currency');
140927
- let quoteId = this.safeString(response, 'quote_currency');
140928
- if (baseId === undefined) {
140929
- const idLength = marketId.length - 0;
140930
- const isUSDT = marketId.indexOf('usdt') >= 0;
140931
- const quoteSize = isUSDT ? 4 : 3;
140932
- baseId = marketId.slice(0, idLength - quoteSize); // Not true for all markets
140933
- quoteId = marketId.slice(idLength - quoteSize, idLength);
141179
+ //
141180
+ // response might be:
141181
+ //
141182
+ // btcusd
141183
+ //
141184
+ // or
141185
+ //
141186
+ // [
141187
+ // 'BTCUSD', // symbol
141188
+ // 2, // priceTickDecimalPlaces
141189
+ // 8, // quantityTickDecimalPlaces
141190
+ // '0.00001', // quantityMinimum
141191
+ // 10, // quantityRoundDecimalPlaces
141192
+ // true // minimumsAreInclusive
141193
+ // ],
141194
+ //
141195
+ // or
141196
+ //
141197
+ // {
141198
+ // "symbol": "BTCUSD", // perpetuals have 'PERP' suffix, i.e. DOGEUSDPERP
141199
+ // "base_currency": "BTC",
141200
+ // "quote_currency": "USD",
141201
+ // "tick_size": 1E-8,
141202
+ // "quote_increment": 0.01,
141203
+ // "min_order_size": "0.00001",
141204
+ // "status": "open",
141205
+ // "wrap_enabled": false
141206
+ // "product_type": "swap", // only in perps
141207
+ // "contract_type": "linear", // only in perps
141208
+ // "contract_price_currency": "GUSD" // only in perps
141209
+ // }
141210
+ //
141211
+ let marketId = undefined;
141212
+ let baseId = undefined;
141213
+ let quoteId = undefined;
141214
+ let settleId = undefined;
141215
+ let tickSize = undefined;
141216
+ let increment = undefined;
141217
+ let minSize = undefined;
141218
+ let status = undefined;
141219
+ let swap = false;
141220
+ let contractSize = undefined;
141221
+ let linear = undefined;
141222
+ let inverse = undefined;
141223
+ const isString = (typeof response === 'string');
141224
+ const isArray = (Array.isArray(response));
141225
+ if (!isString && !isArray) {
141226
+ marketId = this.safeStringLower(response, 'symbol');
141227
+ minSize = this.safeNumber(response, 'min_order_size');
141228
+ tickSize = this.safeNumber(response, 'tick_size');
141229
+ increment = this.safeNumber(response, 'quote_increment');
141230
+ status = this.parseMarketActive(this.safeString(response, 'status'));
141231
+ baseId = this.safeString(response, 'base_currency');
141232
+ quoteId = this.safeString(response, 'quote_currency');
141233
+ settleId = this.safeString(response, 'contract_price_currency');
141234
+ }
141235
+ else {
141236
+ // if no detailed API was called, then parse either string or array
141237
+ if (isString) {
141238
+ marketId = response;
141239
+ }
141240
+ else {
141241
+ marketId = this.safeStringLower(response, 0);
141242
+ minSize = this.safeNumber(response, 3);
141243
+ tickSize = this.parseNumber(this.parsePrecision(this.safeString(response, 1)));
141244
+ increment = this.parseNumber(this.parsePrecision(this.safeString(response, 2)));
141245
+ }
141246
+ const marketIdUpper = marketId.toUpperCase();
141247
+ const isPerp = (marketIdUpper.indexOf('PERP') >= 0);
141248
+ const marketIdWithoutPerp = marketIdUpper.replace('PERP', '');
141249
+ const quoteQurrencies = this.handleOption('fetchMarketsFromAPI', 'quoteCurrencies', []);
141250
+ for (let i = 0; i < quoteQurrencies.length; i++) {
141251
+ const quoteCurrency = quoteQurrencies[i];
141252
+ if (marketIdWithoutPerp.endsWith(quoteCurrency)) {
141253
+ baseId = marketIdWithoutPerp.replace(quoteCurrency, '');
141254
+ quoteId = quoteCurrency;
141255
+ if (isPerp) {
141256
+ settleId = quoteCurrency; // always same
141257
+ }
141258
+ break;
141259
+ }
141260
+ }
140934
141261
  }
140935
141262
  const base = this.safeCurrencyCode(baseId);
140936
141263
  const quote = this.safeCurrencyCode(quoteId);
140937
- const status = this.safeString(response, 'status');
141264
+ const settle = this.safeCurrencyCode(settleId);
141265
+ let symbol = base + '/' + quote;
141266
+ if (settleId !== undefined) {
141267
+ symbol = symbol + ':' + settle;
141268
+ swap = true;
141269
+ contractSize = tickSize; // always same
141270
+ linear = true; // always linear
141271
+ inverse = false;
141272
+ }
141273
+ const type = swap ? 'swap' : 'spot';
140938
141274
  return {
140939
141275
  'id': marketId,
140940
- 'symbol': base + '/' + quote,
141276
+ 'symbol': symbol,
140941
141277
  'base': base,
140942
141278
  'quote': quote,
140943
- 'settle': undefined,
141279
+ 'settle': settle,
140944
141280
  'baseId': baseId,
140945
141281
  'quoteId': quoteId,
140946
- 'settleId': undefined,
140947
- 'type': 'spot',
140948
- 'spot': true,
141282
+ 'settleId': settleId,
141283
+ 'type': type,
141284
+ 'spot': !swap,
140949
141285
  'margin': false,
140950
- 'swap': false,
141286
+ 'swap': swap,
140951
141287
  'future': false,
140952
141288
  'option': false,
140953
- 'active': this.parseMarketActive(status),
140954
- 'contract': false,
140955
- 'linear': undefined,
140956
- 'inverse': undefined,
140957
- 'contractSize': undefined,
141289
+ 'active': status,
141290
+ 'contract': swap,
141291
+ 'linear': linear,
141292
+ 'inverse': inverse,
141293
+ 'contractSize': contractSize,
140958
141294
  'expiry': undefined,
140959
141295
  'expiryDatetime': undefined,
140960
141296
  'strike': undefined,
140961
141297
  'optionType': undefined,
140962
141298
  'precision': {
140963
- 'price': this.safeNumber(response, 'quote_increment'),
140964
- 'amount': this.safeNumber(response, 'tick_size'),
141299
+ 'price': increment,
141300
+ 'amount': tickSize,
140965
141301
  },
140966
141302
  'limits': {
140967
141303
  'leverage': {
@@ -140969,7 +141305,7 @@ class gemini extends _abstract_gemini_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
140969
141305
  'max': undefined,
140970
141306
  },
140971
141307
  'amount': {
140972
- 'min': this.safeNumber(response, 'min_order_size'),
141308
+ 'min': minSize,
140973
141309
  'max': undefined,
140974
141310
  },
140975
141311
  'price': {
@@ -142473,6 +142809,7 @@ class hitbtc extends _abstract_hitbtc_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
142473
142809
  '2012': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest,
142474
142810
  '2020': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest,
142475
142811
  '2022': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest,
142812
+ '2024': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.InvalidOrder,
142476
142813
  '10001': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest,
142477
142814
  '10021': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.AccountSuspended,
142478
142815
  '10022': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.BadRequest,
@@ -142490,6 +142827,7 @@ class hitbtc extends _abstract_hitbtc_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
142490
142827
  '20012': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ExchangeError,
142491
142828
  '20014': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ExchangeError,
142492
142829
  '20016': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ExchangeError,
142830
+ '20018': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ExchangeError,
142493
142831
  '20031': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ExchangeError,
142494
142832
  '20032': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ExchangeError,
142495
142833
  '20033': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ExchangeError,
@@ -142500,10 +142838,15 @@ class hitbtc extends _abstract_hitbtc_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
142500
142838
  '20043': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ExchangeError,
142501
142839
  '20044': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.PermissionDenied,
142502
142840
  '20045': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.InvalidOrder,
142841
+ '20047': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.InvalidOrder,
142842
+ '20048': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.InvalidOrder,
142843
+ '20049': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.InvalidOrder,
142503
142844
  '20080': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ExchangeError,
142504
142845
  '21001': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ExchangeError,
142505
142846
  '21003': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.AccountSuspended,
142506
142847
  '21004': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.AccountSuspended,
142848
+ '22004': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ExchangeError,
142849
+ '22008': _base_errors_js__WEBPACK_IMPORTED_MODULE_2__.ExchangeError, // Gateway timeout exceeded.
142507
142850
  },
142508
142851
  'broad': {},
142509
142852
  },
@@ -148242,6 +148585,7 @@ class htx extends _abstract_htx_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */
148242
148585
  'v2/sub-user/api-key-modification': 1,
148243
148586
  'v2/sub-user/api-key-deletion': 1,
148244
148587
  'v1/subuser/transfer': 10,
148588
+ 'v1/trust/user/active/credit': 10,
148245
148589
  // Trading
148246
148590
  'v1/order/orders/place': 0.2,
148247
148591
  'v1/order/batch-orders': 0.4,
@@ -171037,6 +171381,7 @@ class kucoin extends _abstract_kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
171037
171381
  '12h': '12hour',
171038
171382
  '1d': '1day',
171039
171383
  '1w': '1week',
171384
+ '1M': '1month',
171040
171385
  },
171041
171386
  'precisionMode': _base_functions_number_js__WEBPACK_IMPORTED_MODULE_1__/* .TICK_SIZE */ .sh,
171042
171387
  'exceptions': {
@@ -175086,7 +175431,7 @@ class kucoin extends _abstract_kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
175086
175431
  url = url + endpoint;
175087
175432
  const isFuturePrivate = (api === 'futuresPrivate');
175088
175433
  const isPrivate = (api === 'private');
175089
- const isBroker = (api === 'private');
175434
+ const isBroker = (api === 'broker');
175090
175435
  if (isPrivate || isFuturePrivate || isBroker) {
175091
175436
  this.checkRequiredCredentials();
175092
175437
  const timestamp = this.nonce().toString();
@@ -175118,7 +175463,9 @@ class kucoin extends _abstract_kucoin_js__WEBPACK_IMPORTED_MODULE_0__/* ["defaul
175118
175463
  }
175119
175464
  if (isBroker) {
175120
175465
  const brokerName = this.safeString(partner, 'name');
175121
- headers['KC-BROKER-NAME'] = brokerName;
175466
+ if (brokerName !== undefined) {
175467
+ headers['KC-BROKER-NAME'] = brokerName;
175468
+ }
175122
175469
  }
175123
175470
  }
175124
175471
  return { 'url': url, 'method': method, 'body': body, 'headers': headers };
@@ -261889,7 +262236,7 @@ class lbank extends _lbank_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
261889
262236
  // "volume":6.3607,
261890
262237
  // "amount":77148.9303,
261891
262238
  // "price":12129,
261892
- // "direction":"sell",
262239
+ // "direction":"sell", // or "sell_market"
261893
262240
  // "TS":"2019-06-28T19:55:49.460"
261894
262241
  // },
261895
262242
  // "type":"trade",
@@ -261929,7 +262276,7 @@ class lbank extends _lbank_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
261929
262276
  // "volume":6.3607,
261930
262277
  // "amount":77148.9303,
261931
262278
  // "price":12129,
261932
- // "direction":"sell",
262279
+ // "direction":"sell", // or "sell_market"
261933
262280
  // "TS":"2019-06-28T19:55:49.460"
261934
262281
  // }
261935
262282
  //
@@ -261938,6 +262285,8 @@ class lbank extends _lbank_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
261938
262285
  if (timestamp === undefined) {
261939
262286
  timestamp = this.parse8601(datetime);
261940
262287
  }
262288
+ let side = this.safeString2(trade, 'direction', 3);
262289
+ side = side.replace('_market', '');
261941
262290
  return this.safeTrade({
261942
262291
  'timestamp': timestamp,
261943
262292
  'datetime': datetime,
@@ -261946,7 +262295,7 @@ class lbank extends _lbank_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z {
261946
262295
  'order': undefined,
261947
262296
  'type': undefined,
261948
262297
  'takerOrMaker': undefined,
261949
- 'side': this.safeString2(trade, 'direction', 3),
262298
+ 'side': side,
261950
262299
  'price': this.safeString2(trade, 'price', 1),
261951
262300
  'amount': this.safeString2(trade, 'volume', 2),
261952
262301
  'cost': this.safeString(trade, 'amount'),
@@ -316927,7 +317276,7 @@ SOFTWARE.
316927
317276
 
316928
317277
  //-----------------------------------------------------------------------------
316929
317278
  // this is updated by vss.js when building
316930
- const version = '4.2.68';
317279
+ const version = '4.2.70';
316931
317280
  _src_base_Exchange_js__WEBPACK_IMPORTED_MODULE_0__/* .Exchange */ .e.ccxtVersion = version;
316932
317281
  //-----------------------------------------------------------------------------
316933
317282