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.
@@ -27,7 +27,7 @@ class gemini extends gemini$1 {
27
27
  'CORS': undefined,
28
28
  'spot': true,
29
29
  'margin': false,
30
- 'swap': false,
30
+ 'swap': true,
31
31
  'future': false,
32
32
  'option': false,
33
33
  'addMargin': false,
@@ -252,11 +252,11 @@ class gemini extends gemini$1 {
252
252
  },
253
253
  },
254
254
  'options': {
255
- 'fetchMarketsMethod': 'fetch_markets_from_web',
255
+ 'fetchMarketsMethod': 'fetch_markets_from_api',
256
256
  'fetchMarketFromWebRetries': 10,
257
257
  'fetchMarketsFromAPI': {
258
258
  'fetchDetailsForAllSymbols': false,
259
- 'fetchDetailsForMarketIds': [],
259
+ 'quoteCurrencies': ['USDT', 'GUSD', 'USD', 'DAI', 'EUR', 'GBP', 'SGD', 'BTC', 'ETH', 'LTC', 'BCH'],
260
260
  },
261
261
  'fetchMarkets': {
262
262
  'webApiEnable': true,
@@ -312,10 +312,7 @@ class gemini extends gemini$1 {
312
312
  }
313
313
  //
314
314
  // {
315
- // "tradingPairs": [
316
- // [ "BTCAUD", 2, 8, "0.00001", 10, true ],
317
- // ...
318
- // ],
315
+ // "tradingPairs": [ [ 'BTCUSD', 2, 8, '0.00001', 10, true ], ... ],
319
316
  // "currencies": [
320
317
  // [ "ORCA", "Orca", 204, 6, 0, 6, 8, false, null, "solana" ], // as confirmed, precisions seem to be the 5th index
321
318
  // [ "ATOM", "Cosmos", 44, 6, 0, 6, 8, false, null, "cosmos" ],
@@ -334,6 +331,7 @@ class gemini extends gemini$1 {
334
331
  // }
335
332
  //
336
333
  const result = {};
334
+ this.options['tradingPairs'] = this.safeList(data, 'tradingPairs');
337
335
  const currenciesArray = this.safeValue(data, 'currencies', []);
338
336
  for (let i = 0; i < currenciesArray.length; i++) {
339
337
  const currency = currenciesArray[i];
@@ -543,7 +541,7 @@ class gemini extends gemini$1 {
543
541
  return result;
544
542
  }
545
543
  async fetchMarketsFromAPI(params = {}) {
546
- const response = await this.publicGetV1Symbols(params);
544
+ const marketIdsRaw = await this.publicGetV1Symbols(params);
547
545
  //
548
546
  // [
549
547
  // "btcusd",
@@ -551,93 +549,185 @@ class gemini extends gemini$1 {
551
549
  // ...
552
550
  // ]
553
551
  //
554
- const result = {};
555
- for (let i = 0; i < response.length; i++) {
556
- const marketId = response[i];
557
- const market = {
558
- 'symbol': marketId,
559
- };
560
- result[marketId] = this.parseMarket(market);
552
+ const result = [];
553
+ const options = this.safeDict(this.options, 'fetchMarketsFromAPI', {});
554
+ const bugSymbol = 'efilfil'; // we skip this inexistent test symbol, which bugs other functions
555
+ const marketIds = [];
556
+ for (let i = 0; i < marketIdsRaw.length; i++) {
557
+ if (marketIdsRaw[i] !== bugSymbol) {
558
+ marketIds.push(marketIdsRaw[i]);
559
+ }
561
560
  }
562
- const options = this.safeValue(this.options, 'fetchMarketsFromAPI', {});
563
- const fetchDetailsForAllSymbols = this.safeBool(options, 'fetchDetailsForAllSymbols', false);
564
- const fetchDetailsForMarketIds = this.safeValue(options, 'fetchDetailsForMarketIds', []);
565
- let promises = [];
566
- let marketIds = [];
567
- if (fetchDetailsForAllSymbols) {
568
- marketIds = response;
561
+ if (this.safeBool(options, 'fetchDetailsForAllSymbols', false)) {
562
+ const promises = [];
563
+ for (let i = 0; i < marketIds.length; i++) {
564
+ const marketId = marketIds[i];
565
+ const request = {
566
+ 'symbol': marketId,
567
+ };
568
+ promises.push(this.publicGetV1SymbolsDetailsSymbol(this.extend(request, params)));
569
+ //
570
+ // {
571
+ // "symbol": "BTCUSD",
572
+ // "base_currency": "BTC",
573
+ // "quote_currency": "USD",
574
+ // "tick_size": 1E-8,
575
+ // "quote_increment": 0.01,
576
+ // "min_order_size": "0.00001",
577
+ // "status": "open",
578
+ // "wrap_enabled": false
579
+ // }
580
+ //
581
+ }
582
+ const responses = await Promise.all(promises);
583
+ for (let i = 0; i < responses.length; i++) {
584
+ result.push(this.parseMarket(responses[i]));
585
+ }
569
586
  }
570
587
  else {
571
- marketIds = fetchDetailsForMarketIds;
572
- }
573
- for (let i = 0; i < marketIds.length; i++) {
574
- const marketId = marketIds[i];
575
- const request = {
576
- 'symbol': marketId,
577
- };
578
- promises.push(this.publicGetV1SymbolsDetailsSymbol(this.extend(request, params)));
579
- //
580
- // {
581
- // "symbol": "BTCUSD",
582
- // "base_currency": "BTC",
583
- // "quote_currency": "USD",
584
- // "tick_size": 1E-8,
585
- // "quote_increment": 0.01,
586
- // "min_order_size": "0.00001",
587
- // "status": "open",
588
- // "wrap_enabled": false
589
- // }
590
- //
591
- }
592
- promises = await Promise.all(promises);
593
- for (let i = 0; i < promises.length; i++) {
594
- const responseInner = promises[i];
595
- const marketId = this.safeStringLower(responseInner, 'symbol');
596
- result[marketId] = this.parseMarket(responseInner);
588
+ // use trading-pairs info, if it was fetched
589
+ const tradingPairs = this.safeList(this.options, 'tradingPairs');
590
+ if (tradingPairs !== undefined) {
591
+ const indexedTradingPairs = this.indexBy(tradingPairs, 0);
592
+ for (let i = 0; i < marketIds.length; i++) {
593
+ const marketId = marketIds[i];
594
+ const tradingPair = this.safeList(indexedTradingPairs, marketId.toUpperCase());
595
+ if (tradingPair !== undefined) {
596
+ result.push(this.parseMarket(tradingPair));
597
+ }
598
+ }
599
+ }
600
+ else {
601
+ for (let i = 0; i < marketIds.length; i++) {
602
+ result.push(this.parseMarket(marketIds[i]));
603
+ }
604
+ }
597
605
  }
598
- return this.toArray(result);
606
+ return result;
599
607
  }
600
608
  parseMarket(response) {
601
- const marketId = this.safeStringLower(response, 'symbol');
602
- let baseId = this.safeString(response, 'base_currency');
603
- let quoteId = this.safeString(response, 'quote_currency');
604
- if (baseId === undefined) {
605
- const idLength = marketId.length - 0;
606
- const isUSDT = marketId.indexOf('usdt') >= 0;
607
- const quoteSize = isUSDT ? 4 : 3;
608
- baseId = marketId.slice(0, idLength - quoteSize); // Not true for all markets
609
- quoteId = marketId.slice(idLength - quoteSize, idLength);
609
+ //
610
+ // response might be:
611
+ //
612
+ // btcusd
613
+ //
614
+ // or
615
+ //
616
+ // [
617
+ // 'BTCUSD', // symbol
618
+ // 2, // priceTickDecimalPlaces
619
+ // 8, // quantityTickDecimalPlaces
620
+ // '0.00001', // quantityMinimum
621
+ // 10, // quantityRoundDecimalPlaces
622
+ // true // minimumsAreInclusive
623
+ // ],
624
+ //
625
+ // or
626
+ //
627
+ // {
628
+ // "symbol": "BTCUSD", // perpetuals have 'PERP' suffix, i.e. DOGEUSDPERP
629
+ // "base_currency": "BTC",
630
+ // "quote_currency": "USD",
631
+ // "tick_size": 1E-8,
632
+ // "quote_increment": 0.01,
633
+ // "min_order_size": "0.00001",
634
+ // "status": "open",
635
+ // "wrap_enabled": false
636
+ // "product_type": "swap", // only in perps
637
+ // "contract_type": "linear", // only in perps
638
+ // "contract_price_currency": "GUSD" // only in perps
639
+ // }
640
+ //
641
+ let marketId = undefined;
642
+ let baseId = undefined;
643
+ let quoteId = undefined;
644
+ let settleId = undefined;
645
+ let tickSize = undefined;
646
+ let increment = undefined;
647
+ let minSize = undefined;
648
+ let status = undefined;
649
+ let swap = false;
650
+ let contractSize = undefined;
651
+ let linear = undefined;
652
+ let inverse = undefined;
653
+ const isString = (typeof response === 'string');
654
+ const isArray = (Array.isArray(response));
655
+ if (!isString && !isArray) {
656
+ marketId = this.safeStringLower(response, 'symbol');
657
+ minSize = this.safeNumber(response, 'min_order_size');
658
+ tickSize = this.safeNumber(response, 'tick_size');
659
+ increment = this.safeNumber(response, 'quote_increment');
660
+ status = this.parseMarketActive(this.safeString(response, 'status'));
661
+ baseId = this.safeString(response, 'base_currency');
662
+ quoteId = this.safeString(response, 'quote_currency');
663
+ settleId = this.safeString(response, 'contract_price_currency');
664
+ }
665
+ else {
666
+ // if no detailed API was called, then parse either string or array
667
+ if (isString) {
668
+ marketId = response;
669
+ }
670
+ else {
671
+ marketId = this.safeStringLower(response, 0);
672
+ minSize = this.safeNumber(response, 3);
673
+ tickSize = this.parseNumber(this.parsePrecision(this.safeString(response, 1)));
674
+ increment = this.parseNumber(this.parsePrecision(this.safeString(response, 2)));
675
+ }
676
+ const marketIdUpper = marketId.toUpperCase();
677
+ const isPerp = (marketIdUpper.indexOf('PERP') >= 0);
678
+ const marketIdWithoutPerp = marketIdUpper.replace('PERP', '');
679
+ const quoteQurrencies = this.handleOption('fetchMarketsFromAPI', 'quoteCurrencies', []);
680
+ for (let i = 0; i < quoteQurrencies.length; i++) {
681
+ const quoteCurrency = quoteQurrencies[i];
682
+ if (marketIdWithoutPerp.endsWith(quoteCurrency)) {
683
+ baseId = marketIdWithoutPerp.replace(quoteCurrency, '');
684
+ quoteId = quoteCurrency;
685
+ if (isPerp) {
686
+ settleId = quoteCurrency; // always same
687
+ }
688
+ break;
689
+ }
690
+ }
610
691
  }
611
692
  const base = this.safeCurrencyCode(baseId);
612
693
  const quote = this.safeCurrencyCode(quoteId);
613
- const status = this.safeString(response, 'status');
694
+ const settle = this.safeCurrencyCode(settleId);
695
+ let symbol = base + '/' + quote;
696
+ if (settleId !== undefined) {
697
+ symbol = symbol + ':' + settle;
698
+ swap = true;
699
+ contractSize = tickSize; // always same
700
+ linear = true; // always linear
701
+ inverse = false;
702
+ }
703
+ const type = swap ? 'swap' : 'spot';
614
704
  return {
615
705
  'id': marketId,
616
- 'symbol': base + '/' + quote,
706
+ 'symbol': symbol,
617
707
  'base': base,
618
708
  'quote': quote,
619
- 'settle': undefined,
709
+ 'settle': settle,
620
710
  'baseId': baseId,
621
711
  'quoteId': quoteId,
622
- 'settleId': undefined,
623
- 'type': 'spot',
624
- 'spot': true,
712
+ 'settleId': settleId,
713
+ 'type': type,
714
+ 'spot': !swap,
625
715
  'margin': false,
626
- 'swap': false,
716
+ 'swap': swap,
627
717
  'future': false,
628
718
  'option': false,
629
- 'active': this.parseMarketActive(status),
630
- 'contract': false,
631
- 'linear': undefined,
632
- 'inverse': undefined,
633
- 'contractSize': undefined,
719
+ 'active': status,
720
+ 'contract': swap,
721
+ 'linear': linear,
722
+ 'inverse': inverse,
723
+ 'contractSize': contractSize,
634
724
  'expiry': undefined,
635
725
  'expiryDatetime': undefined,
636
726
  'strike': undefined,
637
727
  'optionType': undefined,
638
728
  'precision': {
639
- 'price': this.safeNumber(response, 'quote_increment'),
640
- 'amount': this.safeNumber(response, 'tick_size'),
729
+ 'price': increment,
730
+ 'amount': tickSize,
641
731
  },
642
732
  'limits': {
643
733
  'leverage': {
@@ -645,7 +735,7 @@ class gemini extends gemini$1 {
645
735
  'max': undefined,
646
736
  },
647
737
  'amount': {
648
- 'min': this.safeNumber(response, 'min_order_size'),
738
+ 'min': minSize,
649
739
  'max': undefined,
650
740
  },
651
741
  'price': {
@@ -315,6 +315,7 @@ class hitbtc extends hitbtc$1 {
315
315
  '2012': errors.BadRequest,
316
316
  '2020': errors.BadRequest,
317
317
  '2022': errors.BadRequest,
318
+ '2024': errors.InvalidOrder,
318
319
  '10001': errors.BadRequest,
319
320
  '10021': errors.AccountSuspended,
320
321
  '10022': errors.BadRequest,
@@ -332,6 +333,7 @@ class hitbtc extends hitbtc$1 {
332
333
  '20012': errors.ExchangeError,
333
334
  '20014': errors.ExchangeError,
334
335
  '20016': errors.ExchangeError,
336
+ '20018': errors.ExchangeError,
335
337
  '20031': errors.ExchangeError,
336
338
  '20032': errors.ExchangeError,
337
339
  '20033': errors.ExchangeError,
@@ -342,10 +344,15 @@ class hitbtc extends hitbtc$1 {
342
344
  '20043': errors.ExchangeError,
343
345
  '20044': errors.PermissionDenied,
344
346
  '20045': errors.InvalidOrder,
347
+ '20047': errors.InvalidOrder,
348
+ '20048': errors.InvalidOrder,
349
+ '20049': errors.InvalidOrder,
345
350
  '20080': errors.ExchangeError,
346
351
  '21001': errors.ExchangeError,
347
352
  '21003': errors.AccountSuspended,
348
353
  '21004': errors.AccountSuspended,
354
+ '22004': errors.ExchangeError,
355
+ '22008': errors.ExchangeError, // Gateway timeout exceeded.
349
356
  },
350
357
  'broad': {},
351
358
  },
@@ -467,6 +467,7 @@ class htx extends htx$1 {
467
467
  'v2/sub-user/api-key-modification': 1,
468
468
  'v2/sub-user/api-key-deletion': 1,
469
469
  'v1/subuser/transfer': 10,
470
+ 'v1/trust/user/active/credit': 10,
470
471
  // Trading
471
472
  'v1/order/orders/place': 0.2,
472
473
  'v1/order/batch-orders': 0.4,
@@ -410,6 +410,7 @@ class kucoin extends kucoin$1 {
410
410
  '12h': '12hour',
411
411
  '1d': '1day',
412
412
  '1w': '1week',
413
+ '1M': '1month',
413
414
  },
414
415
  'precisionMode': number.TICK_SIZE,
415
416
  'exceptions': {
@@ -4459,7 +4460,7 @@ class kucoin extends kucoin$1 {
4459
4460
  url = url + endpoint;
4460
4461
  const isFuturePrivate = (api === 'futuresPrivate');
4461
4462
  const isPrivate = (api === 'private');
4462
- const isBroker = (api === 'private');
4463
+ const isBroker = (api === 'broker');
4463
4464
  if (isPrivate || isFuturePrivate || isBroker) {
4464
4465
  this.checkRequiredCredentials();
4465
4466
  const timestamp = this.nonce().toString();
@@ -4491,7 +4492,9 @@ class kucoin extends kucoin$1 {
4491
4492
  }
4492
4493
  if (isBroker) {
4493
4494
  const brokerName = this.safeString(partner, 'name');
4494
- headers['KC-BROKER-NAME'] = brokerName;
4495
+ if (brokerName !== undefined) {
4496
+ headers['KC-BROKER-NAME'] = brokerName;
4497
+ }
4495
4498
  }
4496
4499
  }
4497
4500
  return { 'url': url, 'method': method, 'body': body, 'headers': headers };
@@ -426,7 +426,7 @@ class lbank extends lbank$1 {
426
426
  // "volume":6.3607,
427
427
  // "amount":77148.9303,
428
428
  // "price":12129,
429
- // "direction":"sell",
429
+ // "direction":"sell", // or "sell_market"
430
430
  // "TS":"2019-06-28T19:55:49.460"
431
431
  // },
432
432
  // "type":"trade",
@@ -466,7 +466,7 @@ class lbank extends lbank$1 {
466
466
  // "volume":6.3607,
467
467
  // "amount":77148.9303,
468
468
  // "price":12129,
469
- // "direction":"sell",
469
+ // "direction":"sell", // or "sell_market"
470
470
  // "TS":"2019-06-28T19:55:49.460"
471
471
  // }
472
472
  //
@@ -475,6 +475,8 @@ class lbank extends lbank$1 {
475
475
  if (timestamp === undefined) {
476
476
  timestamp = this.parse8601(datetime);
477
477
  }
478
+ let side = this.safeString2(trade, 'direction', 3);
479
+ side = side.replace('_market', '');
478
480
  return this.safeTrade({
479
481
  'timestamp': timestamp,
480
482
  'datetime': datetime,
@@ -483,7 +485,7 @@ class lbank extends lbank$1 {
483
485
  'order': undefined,
484
486
  'type': undefined,
485
487
  'takerOrMaker': undefined,
486
- 'side': this.safeString2(trade, 'direction', 3),
488
+ 'side': side,
487
489
  'price': this.safeString2(trade, 'price', 1),
488
490
  'amount': this.safeString2(trade, 'volume', 2),
489
491
  'cost': this.safeString(trade, 'amount'),
@@ -3,4 +3,4 @@ m2r2==0.2.7
3
3
  # https://github.com/CrossNox/m2r2/issues/47
4
4
  mistune==0.8.4
5
5
  sphinx-rtd-theme==0.5.2
6
- readthedocs-sphinx-search==0.1.0
6
+ readthedocs-sphinx-search==0.3.2
package/js/ccxt.d.ts CHANGED
@@ -4,7 +4,7 @@ import * as functions from './src/base/functions.js';
4
4
  import * as errors from './src/base/errors.js';
5
5
  import type { Market, Trade, Fee, Ticker, OrderBook, Order, Transaction, Tickers, Currency, Balance, DepositAddress, WithdrawalResponse, DepositAddressResponse, OHLCV, Balances, PartialBalances, Dictionary, MinMax, Position, FundingRateHistory, Liquidation, FundingHistory, MarginMode, Greeks, Leverage, Leverages } 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, NoChange } from './src/base/errors.js';
7
- declare const version = "4.2.67";
7
+ declare const version = "4.2.69";
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, NoChange } from './src/base/errors.js';
39
39
  //-----------------------------------------------------------------------------
40
40
  // this is updated by vss.js when building
41
- const version = '4.2.68';
41
+ const version = '4.2.70';
42
42
  Exchange.ccxtVersion = version;
43
43
  //-----------------------------------------------------------------------------
44
44
  import ace from './src/ace.js';
@@ -192,6 +192,7 @@ interface Exchange {
192
192
  spotPrivatePostV2SubUserApiKeyModification(params?: {}): Promise<implicitReturnType>;
193
193
  spotPrivatePostV2SubUserApiKeyDeletion(params?: {}): Promise<implicitReturnType>;
194
194
  spotPrivatePostV1SubuserTransfer(params?: {}): Promise<implicitReturnType>;
195
+ spotPrivatePostV1TrustUserActiveCredit(params?: {}): Promise<implicitReturnType>;
195
196
  spotPrivatePostV1OrderOrdersPlace(params?: {}): Promise<implicitReturnType>;
196
197
  spotPrivatePostV1OrderBatchOrders(params?: {}): Promise<implicitReturnType>;
197
198
  spotPrivatePostV1OrderAutoPlace(params?: {}): Promise<implicitReturnType>;
@@ -192,6 +192,7 @@ interface htx {
192
192
  spotPrivatePostV2SubUserApiKeyModification(params?: {}): Promise<implicitReturnType>;
193
193
  spotPrivatePostV2SubUserApiKeyDeletion(params?: {}): Promise<implicitReturnType>;
194
194
  spotPrivatePostV1SubuserTransfer(params?: {}): Promise<implicitReturnType>;
195
+ spotPrivatePostV1TrustUserActiveCredit(params?: {}): Promise<implicitReturnType>;
195
196
  spotPrivatePostV1OrderOrdersPlace(params?: {}): Promise<implicitReturnType>;
196
197
  spotPrivatePostV1OrderBatchOrders(params?: {}): Promise<implicitReturnType>;
197
198
  spotPrivatePostV1OrderAutoPlace(params?: {}): Promise<implicitReturnType>;
@@ -573,8 +573,8 @@ export default class Exchange {
573
573
  socksProxyAgentModule: any;
574
574
  socksProxyAgentModuleChecked: boolean;
575
575
  proxyDictionaries: any;
576
- proxyModulesLoaded: boolean;
577
- loadProxyModules(): Promise<void>;
576
+ proxiesModulesLoading: Promise<any>;
577
+ loadProxyModules(): Promise<any>;
578
578
  setProxyAgents(httpProxy: any, httpsProxy: any, socksProxy: any): any;
579
579
  loadHttpProxyAgent(): Promise<any>;
580
580
  getHttpAgentIfNeeded(url: any): any;
@@ -215,7 +215,7 @@ export default class Exchange {
215
215
  this.socksProxyAgentModule = undefined;
216
216
  this.socksProxyAgentModuleChecked = false;
217
217
  this.proxyDictionaries = {};
218
- this.proxyModulesLoaded = false;
218
+ this.proxiesModulesLoading = undefined;
219
219
  Object.assign(this, functions);
220
220
  //
221
221
  // if (isNode) {
@@ -716,36 +716,38 @@ export default class Exchange {
716
716
  console.log(...args);
717
717
  }
718
718
  async loadProxyModules() {
719
- if (this.proxyModulesLoaded) {
720
- return;
721
- }
722
- this.proxyModulesLoaded = true;
723
- // we have to handle it with below nested way, because of dynamic
724
- // import issues (https://github.com/ccxt/ccxt/pull/20687)
725
- try {
726
- // todo: possible sync alternatives: https://stackoverflow.com/questions/51069002/convert-import-to-synchronous
727
- this.httpProxyAgentModule = await import(/* webpackIgnore: true */ '../static_dependencies/proxies/http-proxy-agent/index.js');
728
- this.httpsProxyAgentModule = await import(/* webpackIgnore: true */ '../static_dependencies/proxies/https-proxy-agent/index.js');
729
- }
730
- catch (e) {
731
- // if several users are using those frameworks which cause exceptions,
732
- // let them to be able to load modules still, by installing them
733
- try {
734
- // @ts-ignore
735
- this.httpProxyAgentModule = await import(/* webpackIgnore: true */ 'http-proxy-agent');
736
- // @ts-ignore
737
- this.httpProxyAgentModule = await import(/* webpackIgnore: true */ 'https-proxy-agent');
738
- }
739
- catch (e) { }
740
- }
741
- if (this.socksProxyAgentModuleChecked === false) {
742
- this.socksProxyAgentModuleChecked = true;
743
- try {
744
- // @ts-ignore
745
- this.socksProxyAgentModule = await import(/* webpackIgnore: true */ 'socks-proxy-agent');
746
- }
747
- catch (e) { }
719
+ // when loading markets, multiple parallel calls are made, so need one promise
720
+ if (this.proxiesModulesLoading === undefined) {
721
+ this.proxiesModulesLoading = (async () => {
722
+ // we have to handle it with below nested way, because of dynamic
723
+ // import issues (https://github.com/ccxt/ccxt/pull/20687)
724
+ try {
725
+ // todo: possible sync alternatives: https://stackoverflow.com/questions/51069002/convert-import-to-synchronous
726
+ this.httpProxyAgentModule = await import(/* webpackIgnore: true */ '../static_dependencies/proxies/http-proxy-agent/index.js');
727
+ this.httpsProxyAgentModule = await import(/* webpackIgnore: true */ '../static_dependencies/proxies/https-proxy-agent/index.js');
728
+ }
729
+ catch (e) {
730
+ // if several users are using those frameworks which cause exceptions,
731
+ // let them to be able to load modules still, by installing them
732
+ try {
733
+ // @ts-ignore
734
+ this.httpProxyAgentModule = await import(/* webpackIgnore: true */ 'http-proxy-agent');
735
+ // @ts-ignore
736
+ this.httpProxyAgentModule = await import(/* webpackIgnore: true */ 'https-proxy-agent');
737
+ }
738
+ catch (e) { }
739
+ }
740
+ if (this.socksProxyAgentModuleChecked === false) {
741
+ try {
742
+ // @ts-ignore
743
+ this.socksProxyAgentModule = await import(/* webpackIgnore: true */ 'socks-proxy-agent');
744
+ }
745
+ catch (e) { }
746
+ this.socksProxyAgentModuleChecked = true;
747
+ }
748
+ })();
748
749
  }
750
+ return await this.proxiesModulesLoading;
749
751
  }
750
752
  setProxyAgents(httpProxy, httpsProxy, socksProxy) {
751
753
  let chosenAgent = undefined;
@@ -1,5 +1,5 @@
1
1
  import Exchange from './abstract/bitstamp.js';
2
- import type { Balances, Currency, Int, Market, OHLCV, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction } from './base/types.js';
2
+ import type { Balances, Currency, Int, Market, OHLCV, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry } from './base/types.js';
3
3
  /**
4
4
  * @class bitstamp
5
5
  * @augments Exchange
@@ -132,6 +132,19 @@ export default class bitstamp extends Exchange {
132
132
  info: any;
133
133
  }>;
134
134
  withdraw(code: string, amount: number, address: any, tag?: any, params?: {}): Promise<Transaction>;
135
+ transfer(code: string, amount: number, fromAccount: string, toAccount: string, params?: {}): Promise<TransferEntry>;
136
+ parseTransfer(transfer: any, currency?: any): {
137
+ info: any;
138
+ id: any;
139
+ timestamp: any;
140
+ datetime: any;
141
+ currency: any;
142
+ amount: any;
143
+ fromAccount: any;
144
+ toAccount: any;
145
+ status: string;
146
+ };
147
+ parseTransferStatus(status: any): string;
135
148
  nonce(): number;
136
149
  sign(path: any, api?: string, method?: string, params?: {}, headers?: any, body?: any): {
137
150
  url: string;