@rabbitio/ui-kit 1.0.0-beta.11 → 1.0.0-beta.12

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.
@@ -1,5 +1,6 @@
1
1
  import React, { useState, useRef, useEffect } from 'react';
2
2
  import { BigNumber } from 'bignumber.js';
3
+ import axios from 'axios';
3
4
 
4
5
  function createCommonjsModule(fn) {
5
6
  var module = { exports: {} };
@@ -2525,5 +2526,477 @@ SwapProvider.SWAP_STATUSES = {
2525
2526
  FAILED: "failed" // public +
2526
2527
  };
2527
2528
 
2528
- export { AmountUtils, AssetIcon, Blockchain, Button, Cache, Coin, ExistingSwap, FiatCurrenciesService, LoadingDots, Logger, LogsStorage, Protocol, SupportChat, SwapProvider, improveAndRethrow, safeStringify };
2529
+ const BANNED_PARTNERS = ["stealthex", "changee", "coincraddle"];
2530
+ const FALLBACK_ICON_URL = "https://rabbit.io/asset-icons/fallback.svg";
2531
+ class SwapspaceSwapProvider extends SwapProvider {
2532
+ constructor(apiKeysProxyUrl, cache, customCoinBuilder = (coin, network) => null, useRestrictedCoinsSet = true) {
2533
+ super();
2534
+ this._supportedCoins = [];
2535
+ this._URL = `${apiKeysProxyUrl}/swapspace`;
2536
+ this._maxRateDigits = 20;
2537
+ this.useRestrictedCoinsSet = useRestrictedCoinsSet;
2538
+ this._customCoinBuilder = customCoinBuilder;
2539
+ this._cache = cache;
2540
+ }
2541
+ getSwapCreationInfoTtlMs() {
2542
+ /* Actually 2 minutes and only relevant for some partners, but we use it
2543
+ * (and even a bit smaller value) for better consistency */
2544
+ return 110000;
2545
+ }
2546
+ async getDepositCurrencies() {
2547
+ const loggerSource = "getDepositCurrencies";
2548
+ try {
2549
+ var _this$_supportedCoins;
2550
+ await this._fetchSupportedCurrenciesIfNeeded();
2551
+ Logger.log(`We have ${(_this$_supportedCoins = this._supportedCoins) == null ? void 0 : _this$_supportedCoins.length} supported coins, getting depositable`, loggerSource);
2552
+ return {
2553
+ result: true,
2554
+ coins: this._supportedCoins.filter(item => item.deposit).map(item => item.coin)
2555
+ };
2556
+ } catch (e) {
2557
+ var _e$response;
2558
+ if ((e == null || (_e$response = e.response) == null ? void 0 : _e$response.status) === 429) {
2559
+ return {
2560
+ result: false,
2561
+ reason: SwapProvider.COMMON_ERRORS.REQUESTS_LIMIT_EXCEEDED
2562
+ };
2563
+ }
2564
+ improveAndRethrow(e, loggerSource);
2565
+ }
2566
+ }
2567
+ async getWithdrawalCurrencies(exceptCurrency = null) {
2568
+ const loggerSource = "getWithdrawalCurrencies";
2569
+ try {
2570
+ var _this$_supportedCoins2;
2571
+ await this._fetchSupportedCurrenciesIfNeeded();
2572
+ Logger.log(`We have ${(_this$_supportedCoins2 = this._supportedCoins) == null ? void 0 : _this$_supportedCoins2.length} supported coins, getting withdrawable`, loggerSource);
2573
+ return {
2574
+ result: true,
2575
+ coins: this._supportedCoins.filter(item => item.withdrawal && (!exceptCurrency || item.coin !== exceptCurrency)).map(item => item.coin)
2576
+ };
2577
+ } catch (e) {
2578
+ var _e$response2;
2579
+ if ((e == null || (_e$response2 = e.response) == null ? void 0 : _e$response2.status) === 429) {
2580
+ return {
2581
+ result: false,
2582
+ reason: SwapProvider.COMMON_ERRORS.REQUESTS_LIMIT_EXCEEDED
2583
+ };
2584
+ }
2585
+ improveAndRethrow(e, loggerSource);
2586
+ }
2587
+ }
2588
+ async initialize() {
2589
+ await this._fetchSupportedCurrenciesIfNeeded();
2590
+ }
2591
+ getIconUrl(coinOrTicker) {
2592
+ const loggerSource = "getIconUrl";
2593
+ try {
2594
+ var _this$_supportedCoins4, _this$_supportedCoins5;
2595
+ let coin = coinOrTicker;
2596
+ if (!(coinOrTicker instanceof Coin)) {
2597
+ var _this$_supportedCoins3;
2598
+ coin = (_this$_supportedCoins3 = this._supportedCoins.find(i => i.coin.ticker === coinOrTicker)) == null ? void 0 : _this$_supportedCoins3.coin;
2599
+ }
2600
+ return (_this$_supportedCoins4 = (_this$_supportedCoins5 = this._supportedCoins.find(item => item.coin === coin)) == null ? void 0 : _this$_supportedCoins5.iconURL) != null ? _this$_supportedCoins4 : FALLBACK_ICON_URL;
2601
+ } catch (e) {
2602
+ improveAndRethrow(e, loggerSource);
2603
+ }
2604
+ }
2605
+ async _fetchSupportedCurrenciesIfNeeded() {
2606
+ const loggerSource = "_fetchSupportedCurrenciesIfNeeded";
2607
+ try {
2608
+ var _this$_supportedCoins6;
2609
+ if (!((_this$_supportedCoins6 = this._supportedCoins) != null && _this$_supportedCoins6.length)) {
2610
+ var _rawResponse$data, _rawResponse$data2;
2611
+ const rawResponse = await axios.get(`${this._URL}/api/v2/currencies`);
2612
+ Logger.log(`Retrieved ${rawResponse == null || (_rawResponse$data = rawResponse.data) == null ? void 0 : _rawResponse$data.length} currencies`, loggerSource);
2613
+ this._supportedCoins = ((_rawResponse$data2 = rawResponse == null ? void 0 : rawResponse.data) != null ? _rawResponse$data2 : []).map(item => {
2614
+ let coin = this._customCoinBuilder(item.code, item.network);
2615
+ if (!coin && !this.useRestrictedCoinsSet) {
2616
+ /** Building coin object for coin that isn't supported OOB in Rabbit.
2617
+ * We are doing this way to be able to use extended coins set for swaps.
2618
+ * These temporary built coins are only for in-swap use, and we omit some usual
2619
+ * coin details here.
2620
+ * Ideally we should add some new abstractions e.g. BaseCoin:
2621
+ * Coin will extend BaseCoin, SwapCoin will extend BaseCoin etc.
2622
+ * But for now it is reasonable to use this simpler approach.
2623
+ */
2624
+ const code = item.code.toUpperCase();
2625
+ const network = item.network.toUpperCase();
2626
+ const ticker = `${code}${code === network ? "" : network}`;
2627
+ const defaultDecimalPlacesForCoinNotSupportedOOB = 8;
2628
+ const defaultMinConfirmationsForCoinNotSupportedOOB = 1;
2629
+ coin = new Coin(item.name, ticker, code, defaultDecimalPlacesForCoinNotSupportedOOB, null, "", null, null, defaultMinConfirmationsForCoinNotSupportedOOB, null, [], 60000, null,
2630
+ // We cannot recognize blockchain from swapspace data
2631
+ new Protocol(network),
2632
+ // TODO: [dev] maybe we should recognize standard protocols?
2633
+ item.contractAddress || null, false);
2634
+ }
2635
+ if (coin) {
2636
+ var _item$deposit, _item$withdrawal, _item$validationRegex;
2637
+ return {
2638
+ coin: coin,
2639
+ code: item.code,
2640
+ network: item.network,
2641
+ extraId: item.extraIdName,
2642
+ isPopular: !!(item != null && item.popular),
2643
+ iconURL: item.icon ? `https://storage.swapspace.co${item.icon}` : FALLBACK_ICON_URL,
2644
+ deposit: (_item$deposit = item.deposit) != null ? _item$deposit : false,
2645
+ withdrawal: (_item$withdrawal = item.withdrawal) != null ? _item$withdrawal : false,
2646
+ validationRegexp: (_item$validationRegex = item.validationRegexp) != null ? _item$validationRegex : null
2647
+ };
2648
+ }
2649
+ return [];
2650
+ }).flat();
2651
+ this._putPopularCoinsFirst();
2652
+ }
2653
+ } catch (e) {
2654
+ improveAndRethrow(e, loggerSource);
2655
+ }
2656
+ }
2657
+
2658
+ /**
2659
+ * This method sort internal list putting popular (as swapspace thinks) coins to the top.
2660
+ * This is just for users of this API if they don't care about the sorting - we just improve a list a bit this way.
2661
+ * @private
2662
+ */
2663
+ _putPopularCoinsFirst() {
2664
+ this._supportedCoins.sort((i1, i2) => {
2665
+ if (i1.isPopular && !i2.isPopular) return -1;
2666
+ if (i2.isPopular && !i1.isPopular) return 1;
2667
+ return i1.coin.ticker > i2.coin.ticker ? 1 : i1.coin.ticker < i2.coin.ticker ? -1 : 0;
2668
+ });
2669
+ }
2670
+ async getCoinToUSDTRate(coin) {
2671
+ const loggerSource = "getCoinToUSDTRate";
2672
+ try {
2673
+ var _this$_supportedCoins7;
2674
+ await this._fetchSupportedCurrenciesIfNeeded();
2675
+
2676
+ // Using USDT TRC20 as usually fee in this network is smaller than ERC20 and this network is widely used for USDT
2677
+ const usdtTrc20 = (_this$_supportedCoins7 = this._supportedCoins.find(i => i.code === "usdt" && i.network === "trc20")) == null ? void 0 : _this$_supportedCoins7.coin;
2678
+ if (!usdtTrc20) {
2679
+ return {
2680
+ result: false
2681
+ };
2682
+ }
2683
+ const cached = this._cache.get("swapspace_usdt_rate_" + coin.ticker);
2684
+ if (cached != null) {
2685
+ return {
2686
+ result: true,
2687
+ rate: cached
2688
+ };
2689
+ }
2690
+ Logger.log("Loading USDT -> coin rate as not found in cache:", coin == null ? void 0 : coin.ticker);
2691
+ const result = await this.getSwapInfo(usdtTrc20, coin, "5000");
2692
+ if (!result.result) {
2693
+ return {
2694
+ result: false
2695
+ };
2696
+ }
2697
+
2698
+ // This calculation is not precise as we cannot recognize the actual fee and network fee. Just approximate.
2699
+ const standardSwapspaceFeeMultiplier = 1.002; // usually 0.2%
2700
+ const rate = BigNumber(1).div(BigNumber(result.rate).times(standardSwapspaceFeeMultiplier)).toString();
2701
+ this._cache.put("swapspace_usdt_rate_" + coin.ticker, rate, 15 * 60000);
2702
+ return {
2703
+ result: true,
2704
+ rate: rate
2705
+ };
2706
+ } catch (e) {
2707
+ improveAndRethrow(e, loggerSource);
2708
+ }
2709
+ }
2710
+ getCoinByTickerIfPresent(ticker) {
2711
+ try {
2712
+ var _item$coin;
2713
+ const item = this._supportedCoins.find(i => i.coin.ticker === ticker);
2714
+ return (_item$coin = item == null ? void 0 : item.coin) != null ? _item$coin : null;
2715
+ } catch (e) {
2716
+ improveAndRethrow(e, "getCoinByTickerIfPresent");
2717
+ }
2718
+ }
2719
+ async getSwapInfo(fromCoin, toCoin, amountCoins, fromCoinToUsdRate = null) {
2720
+ const loggerSource = "getSwapInfo";
2721
+ try {
2722
+ var _response$data;
2723
+ if (!(fromCoin instanceof Coin) || !(toCoin instanceof Coin) || typeof amountCoins !== "string" || BigNumber(amountCoins).lt("0")) {
2724
+ throw new Error(`Wrong input params: ${amountCoins} ${fromCoin.ticker} -> ${toCoin.ticker}` + (fromCoin instanceof Coin) + (toCoin instanceof Coin));
2725
+ }
2726
+ const fromCoinSwapspaceDetails = this._supportedCoins.find(i => i.coin === fromCoin);
2727
+ const toCoinSwapspaceDetails = this._supportedCoins.find(i => i.coin === toCoin);
2728
+ if (!fromCoinSwapspaceDetails || !toCoinSwapspaceDetails) {
2729
+ throw new Error("Failed to find swapspace coin details for: " + fromCoin.ticker + " -> " + toCoin.ticker);
2730
+ }
2731
+ /* Here we use not documented parameter 'estimated=false'. This parameter controls whether we want to use
2732
+ * cached rate values stored in swapspace cache. Their support says they store at most for 30 sec.
2733
+ * But we are better off using the most actual rates.
2734
+ */
2735
+ const response = await axios.get(`${this._URL}/api/v2/amounts?fromCurrency=${fromCoinSwapspaceDetails.code}&fromNetwork=${fromCoinSwapspaceDetails.network}&toNetwork=${toCoinSwapspaceDetails.network}&toCurrency=${toCoinSwapspaceDetails.code}&amount=${amountCoins}&float=true&estimated=false`);
2736
+ Logger.log(`Retrieved ${response == null || (_response$data = response.data) == null ? void 0 : _response$data.length} options`, loggerSource);
2737
+ const options = Array.isArray(response.data) ? response.data : [];
2738
+ const exchangesSupportingThePair = options.filter(exchange => (exchange == null ? void 0 : exchange.exists) && !BANNED_PARTNERS.find(bannedPartner => bannedPartner === (exchange == null ? void 0 : exchange.partner)) && (exchange == null ? void 0 : exchange.fixed) === false && (exchange.min === 0 || exchange.max === 0 || exchange.max > exchange.min || (typeof exchange.min !== "number" || typeof exchange.max !== "number") && exchange.toAmount > 0));
2739
+ Logger.log(`${exchangesSupportingThePair == null ? void 0 : exchangesSupportingThePair.length} of them have exist=true`, loggerSource);
2740
+ if (!exchangesSupportingThePair.length) {
2741
+ return {
2742
+ result: false,
2743
+ reason: SwapProvider.NO_SWAPS_REASONS.NOT_SUPPORTED
2744
+ };
2745
+ }
2746
+ const availableExchanges = exchangesSupportingThePair.filter(exchange => typeof (exchange == null ? void 0 : exchange.toAmount) === "number" && exchange.toAmount > 0);
2747
+ Logger.log(`Available (having amountTo): ${safeStringify(availableExchanges)}`, loggerSource);
2748
+ // min=0 or max=0 means there is no limit for the partner
2749
+ let smallestMin = null;
2750
+ if (exchangesSupportingThePair.find(ex => BigNumber(ex.min).isZero()) == null) {
2751
+ smallestMin = exchangesSupportingThePair.reduce((prev, cur) => {
2752
+ if (typeof cur.min === "number" && (prev === null || BigNumber(cur.min).lt(prev))) return BigNumber(cur.min);
2753
+ return prev;
2754
+ }, null);
2755
+ }
2756
+ let greatestMax = null;
2757
+ if (exchangesSupportingThePair.find(ex => BigNumber(ex.max).isZero()) == null) {
2758
+ greatestMax = exchangesSupportingThePair.reduce((prev, cur) => {
2759
+ if (typeof cur.max === "number" && (prev === null || BigNumber(cur.max).gt(prev))) return BigNumber(cur.max);
2760
+ return prev;
2761
+ }, null);
2762
+ }
2763
+ let extraCoinsToFitMinMax = "0";
2764
+ if (typeof fromCoinToUsdRate === "string" && BigNumber(fromCoinToUsdRate).gt("0")) {
2765
+ const extraUsdToFitMinMax = BigNumber("1"); // We correct the limits as the exact limit can fluctuate and cause failed swap creation
2766
+ extraCoinsToFitMinMax = AmountUtils.trim(extraUsdToFitMinMax.div(fromCoinToUsdRate), fromCoin.digits);
2767
+ }
2768
+ if (smallestMin instanceof BigNumber) {
2769
+ smallestMin = AmountUtils.trim(smallestMin.plus(extraCoinsToFitMinMax), fromCoin.digits);
2770
+ }
2771
+ if (greatestMax instanceof BigNumber) {
2772
+ if (greatestMax > extraCoinsToFitMinMax) {
2773
+ greatestMax = AmountUtils.trim(greatestMax.minus(extraCoinsToFitMinMax), fromCoin.digits);
2774
+ } else {
2775
+ greatestMax = "0";
2776
+ }
2777
+ }
2778
+ if (availableExchanges.length) {
2779
+ var _bestOpt$duration;
2780
+ const sorted = availableExchanges.sort((op1, op2) => op2.toAmount - op1.toAmount);
2781
+ const bestOpt = sorted[0];
2782
+ Logger.log(`Returning first option after sorting: ${safeStringify(bestOpt)}`, loggerSource);
2783
+ let max = null;
2784
+ let min = null;
2785
+ if (extraCoinsToFitMinMax != null) {
2786
+ if (typeof bestOpt.max === "number" && bestOpt.max !== 0) {
2787
+ max = BigNumber(bestOpt.max).minus(extraCoinsToFitMinMax);
2788
+ max = AmountUtils.trim(max.lt(0) ? "0" : max, fromCoin.digits);
2789
+ }
2790
+ if (typeof bestOpt.min === "number" && bestOpt.min !== 0) {
2791
+ min = AmountUtils.trim(BigNumber(bestOpt.min).plus(extraCoinsToFitMinMax), fromCoin.digits);
2792
+ }
2793
+ }
2794
+ const rate = bestOpt.toAmount && bestOpt.fromAmount ? BigNumber(bestOpt.toAmount).div(bestOpt.fromAmount) : null;
2795
+ return {
2796
+ result: true,
2797
+ min: min,
2798
+ max: max,
2799
+ smallestMin: smallestMin,
2800
+ greatestMax: greatestMax,
2801
+ rate: rate != null ? AmountUtils.trim(rate, this._maxRateDigits) : null,
2802
+ durationMinutesRange: (_bestOpt$duration = bestOpt.duration) != null ? _bestOpt$duration : null,
2803
+ rawSwapData: bestOpt
2804
+ };
2805
+ }
2806
+ const result = {
2807
+ result: false,
2808
+ reason: smallestMin && BigNumber(amountCoins).lt(smallestMin) ? SwapProvider.NO_SWAPS_REASONS.TOO_LOW : greatestMax && BigNumber(amountCoins).gt(greatestMax) ? SwapProvider.NO_SWAPS_REASONS.TOO_HIGH : SwapProvider.NO_SWAPS_REASONS.NOT_SUPPORTED,
2809
+ smallestMin: smallestMin,
2810
+ greatestMax: greatestMax
2811
+ };
2812
+ Logger.log(`Returning result ${safeStringify(result)}`, loggerSource);
2813
+ return result;
2814
+ } catch (e) {
2815
+ var _e$response3;
2816
+ if ((e == null || (_e$response3 = e.response) == null ? void 0 : _e$response3.status) === 429) {
2817
+ return {
2818
+ result: false,
2819
+ reason: SwapProvider.COMMON_ERRORS.REQUESTS_LIMIT_EXCEEDED
2820
+ };
2821
+ }
2822
+ Logger.log(`Internal swapspace/rabbit error when getting swap options ${safeStringify(e)}`, loggerSource);
2823
+ improveAndRethrow(e, loggerSource);
2824
+ }
2825
+ }
2826
+ async createSwap(fromCoin, toCoin, amount, toAddress, refundAddress, rawSwapData, clientIpAddress) {
2827
+ const loggerSource = "createSwap";
2828
+ const partner = rawSwapData == null ? void 0 : rawSwapData.partner;
2829
+ try {
2830
+ var _this$_supportedCoins8, _this$_supportedCoins9;
2831
+ if (!(fromCoin instanceof Coin) || !(toCoin instanceof Coin) || typeof amount !== "string" || typeof toAddress !== "string" || typeof refundAddress !== "string") {
2832
+ throw new Error(`Invalid input: ${fromCoin} ${toCoin} ${amount} ${toAddress} ${refundAddress}`);
2833
+ }
2834
+ if (typeof partner !== "string" || typeof (rawSwapData == null ? void 0 : rawSwapData.fromCurrency) !== "string" || typeof (rawSwapData == null ? void 0 : rawSwapData.fromNetwork) !== "string" || typeof (rawSwapData == null ? void 0 : rawSwapData.toCurrency) !== "string" || typeof (rawSwapData == null ? void 0 : rawSwapData.toNetwork) !== "string" || typeof (rawSwapData == null ? void 0 : rawSwapData.id) !== "string" // can be just empty
2835
+ ) {
2836
+ throw new Error(`Invalid raw swap data: ${safeStringify(rawSwapData)}`);
2837
+ }
2838
+ await this._fetchSupportedCurrenciesIfNeeded();
2839
+ const toCurrencyExtraId = (_this$_supportedCoins8 = (_this$_supportedCoins9 = this._supportedCoins.find(item => item.coin === toCoin)) == null ? void 0 : _this$_supportedCoins9.extraId) != null ? _this$_supportedCoins8 : "";
2840
+ const requestData = {
2841
+ partner: partner,
2842
+ fromCurrency: rawSwapData == null ? void 0 : rawSwapData.fromCurrency,
2843
+ fromNetwork: rawSwapData == null ? void 0 : rawSwapData.fromNetwork,
2844
+ toCurrency: rawSwapData == null ? void 0 : rawSwapData.toCurrency,
2845
+ toNetwork: rawSwapData == null ? void 0 : rawSwapData.toNetwork,
2846
+ address: toAddress,
2847
+ amount: amount,
2848
+ fixed: false,
2849
+ extraId: toCurrencyExtraId != null ? toCurrencyExtraId : "",
2850
+ rateId: rawSwapData == null ? void 0 : rawSwapData.id,
2851
+ userIp: clientIpAddress,
2852
+ refund: refundAddress
2853
+ };
2854
+ Logger.log(`Sending create request: ${safeStringify(requestData)}`, loggerSource);
2855
+ const response = await axios.post(`${this._URL}/api/v2/exchange`, requestData);
2856
+ const result = response.data;
2857
+ Logger.log(`Creation result ${safeStringify(result)}`, loggerSource);
2858
+ if (result != null && result.id) {
2859
+ var _result$from, _result$from2, _result$to, _result$to2, _result$from4, _result$from5, _result$to4, _result$to5;
2860
+ if (typeof (result == null || (_result$from = result.from) == null ? void 0 : _result$from.amount) !== "number" || typeof (result == null || (_result$from2 = result.from) == null ? void 0 : _result$from2.address) !== "string" || typeof (result == null || (_result$to = result.to) == null ? void 0 : _result$to.amount) !== "number" || typeof (result == null || (_result$to2 = result.to) == null ? void 0 : _result$to2.address) !== "string") throw new Error(`Wrong swap creation result ${result}`);
2861
+ /* We use the returned rate preferably but if the retrieved
2862
+ * rate 0/null/undefined we calculate it manually */
2863
+ let rate = result.rate;
2864
+ if (typeof rate !== "number" || BigNumber(rate).isZero()) {
2865
+ var _result$to3, _result$from3;
2866
+ rate = BigNumber(result == null || (_result$to3 = result.to) == null ? void 0 : _result$to3.amount).div(result == null || (_result$from3 = result.from) == null ? void 0 : _result$from3.amount);
2867
+ } else {
2868
+ rate = BigNumber(rate);
2869
+ }
2870
+ return {
2871
+ result: true,
2872
+ swapId: result == null ? void 0 : result.id,
2873
+ fromCoin: fromCoin,
2874
+ fromAmount: AmountUtils.trim(result == null || (_result$from4 = result.from) == null ? void 0 : _result$from4.amount, fromCoin.digits),
2875
+ fromAddress: result == null || (_result$from5 = result.from) == null ? void 0 : _result$from5.address,
2876
+ toCoin: toCoin,
2877
+ toAmount: AmountUtils.trim(result == null || (_result$to4 = result.to) == null ? void 0 : _result$to4.amount, toCoin.digits),
2878
+ toAddress: result == null || (_result$to5 = result.to) == null ? void 0 : _result$to5.address,
2879
+ rate: AmountUtils.trim(rate, this._maxRateDigits)
2880
+ };
2881
+ }
2882
+ const errorMessage = `Swap creation succeeded but the response is wrong: ${safeStringify(response)}`;
2883
+ Logger.log(errorMessage, loggerSource);
2884
+ throw new Error(errorMessage);
2885
+ } catch (e) {
2886
+ var _e$response4, _e$response5;
2887
+ Logger.log(`Failed to create swap. Error is: ${safeStringify(e)}`, loggerSource);
2888
+ const composeFailResult = reason => ({
2889
+ result: false,
2890
+ reason: reason,
2891
+ partner: partner
2892
+ });
2893
+ const status = e == null || (_e$response4 = e.response) == null ? void 0 : _e$response4.status;
2894
+ const data = e == null || (_e$response5 = e.response) == null ? void 0 : _e$response5.data;
2895
+ if (status === 429) {
2896
+ Logger.log(`Returning fail - RPS limit exceeded ${data}`, loggerSource);
2897
+ return composeFailResult(SwapProvider.COMMON_ERRORS.REQUESTS_LIMIT_EXCEEDED);
2898
+ }
2899
+ const texts422 = ["Pair cannot be processed by", "Currency not found", "Amount maximum is", "Amount minimum is"];
2900
+ const text403 = "IP address is forbidden";
2901
+ if (typeof data === "string" && (status === 403 && data.includes(text403) || status === 422 && texts422.find(text => data.includes(text)))) {
2902
+ Logger.log(`Returning retriable fail: ${status} - ${data}, ${partner}`, loggerSource);
2903
+ return composeFailResult(SwapProvider.CREATION_FAIL_REASONS.RETRIABLE_FAIL);
2904
+ }
2905
+ Logger.log(`Internal swapspace/rabbit error for ${partner}: ${safeStringify(e)}`, loggerSource);
2906
+ improveAndRethrow(e, loggerSource);
2907
+ }
2908
+ }
2909
+ _mapSwapspaceStatusToRabbitStatus(status) {
2910
+ switch (status) {
2911
+ case "waiting":
2912
+ return SwapProvider.SWAP_STATUSES.WAITING_FOR_PAYMENT;
2913
+ case "confirming":
2914
+ return SwapProvider.SWAP_STATUSES.CONFIRMING;
2915
+ case "exchanging":
2916
+ return SwapProvider.SWAP_STATUSES.EXCHANGING;
2917
+ case "sending":
2918
+ return SwapProvider.SWAP_STATUSES.PAYMENT_RECEIVED;
2919
+ case "finished":
2920
+ return SwapProvider.SWAP_STATUSES.COMPLETED;
2921
+ case "verifying":
2922
+ return SwapProvider.SWAP_STATUSES.EXCHANGING;
2923
+ case "refunded":
2924
+ return SwapProvider.SWAP_STATUSES.REFUNDED;
2925
+ case "expired":
2926
+ return SwapProvider.SWAP_STATUSES.EXPIRED;
2927
+ case "failed":
2928
+ return SwapProvider.SWAP_STATUSES.FAILED;
2929
+ default:
2930
+ throw new Error(`Unknown swapspace status: ${status}`);
2931
+ }
2932
+ }
2933
+ async getExistingSwapsDetailsAndStatus(swapIds) {
2934
+ var _this = this;
2935
+ const loggerSource = "getExistingSwapsDetailsAndStatus";
2936
+ try {
2937
+ if (swapIds.find(id => typeof id !== "string")) {
2938
+ throw new Error("Swap id is not string: " + safeStringify(swapIds));
2939
+ }
2940
+ const getNotFailingOn404 = async function getNotFailingOn404(swapId) {
2941
+ try {
2942
+ return await axios.get(`${_this._URL}/api/v2/exchange/${swapId}`);
2943
+ } catch (error) {
2944
+ var _error$response;
2945
+ if ((error == null || (_error$response = error.response) == null ? void 0 : _error$response.status) === 404) return [];
2946
+ throw error;
2947
+ }
2948
+ };
2949
+ const responses = await Promise.all(swapIds.map(swapId => getNotFailingOn404(swapId)));
2950
+ const wo404 = responses.flat();
2951
+ const swaps = wo404.map(r => r.data).map((swap, index) => {
2952
+ var _this$_supportedCoins10, _this$_supportedCoins11;
2953
+ const fromCoin = (_this$_supportedCoins10 = this._supportedCoins.find(i => i.code === swap.from.code && i.network === swap.from.network)) == null ? void 0 : _this$_supportedCoins10.coin;
2954
+ const toCoin = (_this$_supportedCoins11 = this._supportedCoins.find(i => i.code === swap.to.code && i.network === swap.to.network)) == null ? void 0 : _this$_supportedCoins11.coin;
2955
+ if (!fromCoin || !toCoin) {
2956
+ return []; // We skip swaps with not supported coins for now
2957
+ }
2958
+ const status = this._mapSwapspaceStatusToRabbitStatus(swap.status);
2959
+ const toDigits = status === SwapProvider.SWAP_STATUSES.REFUNDED ? fromCoin.digits : toCoin.digits;
2960
+ const addressToSendCoinsToSwapspace = swap.from.address;
2961
+ const toUtcTimestamp = timeStr => Date.parse(timeStr.match(/.+[Zz]$/) ? timeStr : `${timeStr}Z`);
2962
+ return new ExistingSwap(swapIds[index], status, toUtcTimestamp(swap.timestamps.createdAt), toUtcTimestamp(swap.timestamps.expiresAt), swap.confirmations, AmountUtils.trim(swap.rate, this._maxRateDigits), swap.refundAddress, addressToSendCoinsToSwapspace, fromCoin, AmountUtils.trim(swap.from.amount, fromCoin.digits), swap.from.transactionHash, swap.blockExplorerTransactionUrl.from, toCoin, AmountUtils.trim(swap.to.amount, toDigits), swap.to.transactionHash, swap.blockExplorerTransactionUrl.to, swap.to.address, swap.partner);
2963
+ }).flat();
2964
+ Logger.log(`Swap details result ${safeStringify(swaps)}`, loggerSource);
2965
+ return {
2966
+ result: true,
2967
+ swaps: swaps
2968
+ };
2969
+ } catch (e) {
2970
+ var _e$response6, _e$response7;
2971
+ Logger.log(`Failed to get swap details. Error is: ${safeStringify(e)}`, loggerSource);
2972
+ const composeFailResult = reason => ({
2973
+ result: false,
2974
+ reason: reason
2975
+ });
2976
+ const status = e == null || (_e$response6 = e.response) == null ? void 0 : _e$response6.status;
2977
+ const data = e == null || (_e$response7 = e.response) == null ? void 0 : _e$response7.data;
2978
+ if (status === 429) {
2979
+ Logger.log(`Returning fail - RPS limit exceeded ${data}`, loggerSource);
2980
+ return composeFailResult(SwapProvider.COMMON_ERRORS.REQUESTS_LIMIT_EXCEEDED);
2981
+ }
2982
+ improveAndRethrow(e, loggerSource);
2983
+ }
2984
+ }
2985
+ isAddressValidForAsset(asset, address) {
2986
+ try {
2987
+ const assetData = this._supportedCoins.find(i => i.coin === asset);
2988
+ if (assetData) {
2989
+ let corrected = assetData.validationRegexp.trim();
2990
+ corrected = corrected[0] === "/" ? corrected.slice(1) : corrected;
2991
+ corrected = corrected[corrected.length - 1] === "/" ? corrected.slice(0, corrected.length - 1) : corrected;
2992
+ return address.match(corrected) != null;
2993
+ }
2994
+ } catch (e) {
2995
+ Logger.logError(e, "isAddressValidForAsset");
2996
+ }
2997
+ return false;
2998
+ }
2999
+ }
3000
+
3001
+ export { AmountUtils, AssetIcon, Blockchain, Button, Cache, Coin, ExistingSwap, FiatCurrenciesService, LoadingDots, Logger, LogsStorage, Protocol, SupportChat, SwapProvider, SwapspaceSwapProvider, improveAndRethrow, safeStringify };
2529
3002
  //# sourceMappingURL=index.modern.js.map