@rango-dev/widget-embedded 0.1.10-next.100 → 0.1.10-next.106

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 (64) hide show
  1. package/dist/App.d.ts.map +1 -1
  2. package/dist/QueueManager.d.ts.map +1 -1
  3. package/dist/components/AppRouter.d.ts +6 -1
  4. package/dist/components/AppRouter.d.ts.map +1 -1
  5. package/dist/components/AppRoutes.d.ts.map +1 -1
  6. package/dist/components/Layout.d.ts.map +1 -1
  7. package/dist/components/UpdateUrl.d.ts.map +1 -1
  8. package/dist/components/warnings/BalanceWarnings.d.ts.map +1 -1
  9. package/dist/components/warnings/MinRequiredSlippage.d.ts +1 -1
  10. package/dist/components/warnings/MinRequiredSlippage.d.ts.map +1 -1
  11. package/dist/constants/navigationRoutes.d.ts +0 -1
  12. package/dist/constants/navigationRoutes.d.ts.map +1 -1
  13. package/dist/hooks/useConfirmSwap.d.ts.map +1 -1
  14. package/dist/lib.d.ts.map +1 -1
  15. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  16. package/dist/pages/SelectTokenPage.d.ts.map +1 -1
  17. package/dist/pages/SwapDetailsPage.d.ts +1 -1
  18. package/dist/pages/SwapDetailsPage.d.ts.map +1 -1
  19. package/dist/store/bestRoute.d.ts +3 -1
  20. package/dist/store/bestRoute.d.ts.map +1 -1
  21. package/dist/types/routing.d.ts +1 -1
  22. package/dist/types/swap.d.ts +6 -0
  23. package/dist/types/swap.d.ts.map +1 -1
  24. package/dist/utils/common.d.ts +1 -0
  25. package/dist/utils/common.d.ts.map +1 -1
  26. package/dist/utils/swap.d.ts +16 -5
  27. package/dist/utils/swap.d.ts.map +1 -1
  28. package/dist/utils/time.d.ts +4 -0
  29. package/dist/utils/time.d.ts.map +1 -0
  30. package/dist/utils/wallets.d.ts +1 -1
  31. package/dist/utils/wallets.d.ts.map +1 -1
  32. package/dist/widget-embedded.cjs.development.js +796 -600
  33. package/dist/widget-embedded.cjs.development.js.map +1 -1
  34. package/dist/widget-embedded.cjs.production.min.js +796 -600
  35. package/dist/widget-embedded.cjs.production.min.js.map +1 -1
  36. package/dist/widget-embedded.esm.js +805 -609
  37. package/dist/widget-embedded.esm.js.map +1 -1
  38. package/package.json +9 -9
  39. package/src/App.tsx +26 -4
  40. package/src/QueueManager.tsx +5 -2
  41. package/src/components/AppRouter.tsx +24 -13
  42. package/src/components/AppRoutes.tsx +0 -2
  43. package/src/components/Layout.tsx +13 -0
  44. package/src/components/UpdateUrl.tsx +1 -3
  45. package/src/components/warnings/BalanceWarnings.tsx +1 -0
  46. package/src/components/warnings/MinRequiredSlippage.tsx +9 -4
  47. package/src/constants/navigationRoutes.ts +0 -1
  48. package/src/hooks/useConfirmSwap.ts +2 -1
  49. package/src/hooks/useNavigateBack.ts +3 -3
  50. package/src/lib.tsx +25 -3
  51. package/src/pages/ConfirmSwapPage.tsx +121 -20
  52. package/src/pages/Home.tsx +1 -1
  53. package/src/pages/SelectTokenPage.tsx +0 -1
  54. package/src/pages/SwapDetailsPage.tsx +82 -5
  55. package/src/store/bestRoute.ts +75 -4
  56. package/src/types/routing.ts +1 -1
  57. package/src/types/swap.ts +7 -0
  58. package/src/utils/common.ts +14 -0
  59. package/src/utils/swap.ts +98 -9
  60. package/src/utils/time.ts +52 -0
  61. package/src/utils/wallets.ts +5 -2
  62. package/dist/pages/ConfirmWalletsPage.d.ts +0 -3
  63. package/dist/pages/ConfirmWalletsPage.d.ts.map +0 -1
  64. package/src/pages/ConfirmWalletsPage.tsx +0 -127
@@ -1,22 +1,22 @@
1
- import { WalletState, Tooltip, Button, RetryIcon, HistoryIcon, SettingsIcon, styled, css, Typography, InfoCircleIcon, AngleDownIcon, Spacer, TextField, VerticalSwapIcon, BestRoute, Alert, ConfirmSwap, History, LiquiditySourcesSelector, BlockchainSelector, TokenSelector, Settings, SecondaryPage, Wallet, ChevronRightIcon, GasIcon, ConfirmWallets, SwapHistory, AddWalletIcon, globalCss, createTheme, SwapContainer } from '@rango-dev/ui';
1
+ import { WalletState, Tooltip, Button, RetryIcon, HistoryIcon, SettingsIcon, styled, css, Typography, InfoCircleIcon, AngleDownIcon, Spacer, TextField, VerticalSwapIcon, BestRoute, Alert, ChevronRightIcon, GasIcon, ConfirmSwap, History, LiquiditySourcesSelector, BlockchainSelector, TokenSelector, Settings, SecondaryPage, Wallet, SwapHistory, AddWalletIcon, globalCss, createTheme, SwapContainer } from '@rango-dev/ui';
2
2
  import React, { useRef, useEffect, useState, useLayoutEffect } from 'react';
3
3
  import { useInRouterContext as useInRouterContext$1, MemoryRouter, useLocation as useLocation$1, useNavigate as useNavigate$1 } from 'react-router';
4
+ import { PendingSwapNetworkStatus, useQueueManager, getCurrentStep, getCurrentBlockchainOfOrNull, getRelatedWalletOrNull, cancelSwap, swapQueueDef, checkWaitingForNetworkChange } from '@rango-dev/queue-manager-rango-preset';
5
+ import { isCosmosBlockchain, isEvmBlockchain } from 'rango-types';
4
6
  import { useSearchParams, useLocation, createSearchParams, useNavigate, useInRouterContext, useRoutes } from 'react-router-dom';
5
7
  import { create } from 'zustand';
6
8
  import BigNumber, { BigNumber as BigNumber$1 } from 'bignumber.js';
7
- import { Network, isEvmAddress, detectInstallLink, KEPLR_COMPATIBLE_WALLETS, WalletType, getCosmosExperimentalChainInfo, detectMobileScreens, convertEvmBlockchainMetaToEvmChainInfo } from '@rango-dev/wallets-shared';
8
- import { isCosmosBlockchain } from 'rango-types';
9
+ import { Network, isEvmAddress, KEPLR_COMPATIBLE_WALLETS, detectInstallLink, WalletType, getCosmosExperimentalChainInfo, detectMobileScreens, convertEvmBlockchainMetaToEvmChainInfo } from '@rango-dev/wallets-shared';
9
10
  import { readAccountAddress, useWallets, Provider as Provider$1, Events } from '@rango-dev/wallets-core';
10
11
  import { persist, subscribeWithSelector } from 'zustand/middleware';
11
- import { RangoClient, isEvmBlockchain } from 'rango-sdk';
12
+ import { RangoClient, isEvmBlockchain as isEvmBlockchain$1 } from 'rango-sdk';
12
13
  import { shallow } from 'zustand/shallow';
13
14
  import { useTranslation, initReactI18next } from 'react-i18next';
14
15
  import { styled as styled$1 } from '@rango-dev/ui/src/theme';
15
16
  import { allProviders } from '@rango-dev/provider-all';
16
- import { useManager, Provider } from '@rango-dev/queue-manager-react';
17
17
  import i18n, { t } from 'i18next';
18
+ import { useManager, Provider } from '@rango-dev/queue-manager-react';
18
19
  import copy from 'copy-to-clipboard';
19
- import { cancelSwap, swapQueueDef } from '@rango-dev/queue-manager-rango-preset';
20
20
  import Backend from 'i18next-http-backend';
21
21
  import LanguageDetector from 'i18next-browser-languagedetector';
22
22
 
@@ -31,7 +31,6 @@ const navigationRoutes = {
31
31
  swaps: '/swaps',
32
32
  wallets: '/wallets',
33
33
  confirmSwap: '/confirm-swap',
34
- confirmWallets: '/confirm-wallets',
35
34
  swapDetails: '/swaps/:requestId'
36
35
  };
37
36
 
@@ -61,6 +60,22 @@ function shadeColor(color, percent) {
61
60
  var BB = B.toString(16).length == 1 ? '0' + B.toString(16) : B.toString(16);
62
61
  return '#' + RR + GG + BB;
63
62
  }
63
+ function debounce(fn, time) {
64
+ let timeoutId;
65
+ return wrapper;
66
+ function wrapper() {
67
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
68
+ args[_key] = arguments[_key];
69
+ }
70
+ if (timeoutId) {
71
+ clearTimeout(timeoutId);
72
+ }
73
+ timeoutId = setTimeout(() => {
74
+ timeoutId = null;
75
+ fn(...args);
76
+ }, time);
77
+ }
78
+ }
64
79
 
65
80
  const secondsToString = s => {
66
81
  const seconds = (s % 60).toString().padStart(2, '0');
@@ -327,7 +342,7 @@ function getSortedTokens(chain, tokens, balances, otherChainTokens) {
327
342
  return sortTokens(getTokensWithBalance(filteredTokens, balances));
328
343
  }
329
344
  function tokensAreEqual(tokenA, tokenB) {
330
- return tokenA?.blockchain === tokenB?.blockchain && tokenA?.name === tokenB?.name && tokenA?.address === tokenB?.address;
345
+ return tokenA?.blockchain === tokenB?.blockchain && tokenA?.symbol === tokenB?.symbol && tokenA?.address === tokenB?.address;
331
346
  }
332
347
  function getDefaultToken(sortedTokens, otherToken) {
333
348
  let selectedToken;
@@ -453,6 +468,7 @@ function calculatePendingSwap(inputAmount, bestRoute, wallets, settings, validat
453
468
  finishTime: null,
454
469
  requestId: bestRoute.requestId || '',
455
470
  inputAmount: inputAmount,
471
+ //@ts-ignore
456
472
  wallets,
457
473
  status: 'running',
458
474
  isPaused: false,
@@ -467,6 +483,7 @@ function calculatePendingSwap(inputAmount, bestRoute, wallets, settings, validat
467
483
  settings: settings,
468
484
  simulationResult: simulationResult,
469
485
  validateBalanceOrFee,
486
+ //@ts-ignore
470
487
  steps: bestRoute.result?.swaps?.map((swap, index) => {
471
488
  const swapper = meta.swappers.find(swapper => swapper.id === swap.swapperId);
472
489
  const swapperType = swapper?.types[0];
@@ -552,11 +569,10 @@ function hasHighFee(totalFeeInUsd) {
552
569
  }
553
570
  function getMinRequiredSlippage(route) {
554
571
  const slippages = route.result?.swaps.map(slippage => slippage.recommendedSlippage);
555
- return slippages?.map(s => parseFloat(s?.slippage || '0'))?.filter(s => s > 0)?.sort((a, b) => b - a)?.find(() => true) || null;
572
+ return slippages?.map(s => s?.slippage || '0')?.filter(s => parseFloat(s) > 0)?.sort((a, b) => parseFloat(b) - parseFloat(a))?.find(() => true) || null;
556
573
  }
557
574
  function hasProperSlippage(userSlippage, minRequiredSlippage) {
558
575
  if (!minRequiredSlippage) return true;
559
- //@ts-ignore
560
576
  return parseFloat(userSlippage) >= parseFloat(minRequiredSlippage);
561
577
  }
562
578
  function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, selectedWallets, disabledLiquiditySources, slippage, checkPrerequisites) {
@@ -633,6 +649,61 @@ function calcOutputUsdValue(outputAmount, tokenPrice) {
633
649
  const amount = !!outputAmount ? new BigNumber(outputAmount) : ZERO;
634
650
  return amount.multipliedBy(tokenPrice || 0);
635
651
  }
652
+ function isNetworkStatusInWarningState(pendingSwapStep) {
653
+ return !!pendingSwapStep && pendingSwapStep.networkStatus !== null && pendingSwapStep.networkStatus !== PendingSwapNetworkStatus.NetworkChanged;
654
+ }
655
+ function getSwapMessages(pendingSwap, currentStep) {
656
+ const textForRemove = 'bellow button or';
657
+ let message = pendingSwap.extraMessage;
658
+ let detailedMessage = pendingSwap.extraMessageDetail;
659
+ if (pendingSwap.networkStatusExtraMessageDetail?.includes(textForRemove)) {
660
+ pendingSwap.networkStatusExtraMessageDetail = pendingSwap.networkStatusExtraMessageDetail.replace(textForRemove, '');
661
+ }
662
+ const networkWarningState = isNetworkStatusInWarningState(currentStep);
663
+ if (networkWarningState) {
664
+ message = pendingSwap.networkStatusExtraMessage || '';
665
+ detailedMessage = pendingSwap.networkStatusExtraMessageDetail || '';
666
+ switch (currentStep?.networkStatus) {
667
+ case PendingSwapNetworkStatus.WaitingForConnectingWallet:
668
+ message = message || 'Waiting for connecting wallet';
669
+ break;
670
+ case PendingSwapNetworkStatus.WaitingForQueue:
671
+ message = message || 'Waiting for other running tasks to be finished';
672
+ break;
673
+ case PendingSwapNetworkStatus.WaitingForNetworkChange:
674
+ message = message || 'Waiting for changing wallet network';
675
+ break;
676
+ }
677
+ }
678
+ detailedMessage = detailedMessage || '';
679
+ message = message || '';
680
+ const isRpc = message?.indexOf('code') !== -1 && message?.indexOf('reason') !== -1;
681
+ return {
682
+ shortMessage: message,
683
+ detailedMessage: {
684
+ content: detailedMessage,
685
+ long: isRpc
686
+ }
687
+ };
688
+ }
689
+ function getLastConvertedTokenInFailedSwap(pendingSwap) {
690
+ let resultToken = null;
691
+ if (pendingSwap.status === 'failed') {
692
+ const lastSuccessStep = pendingSwap.steps.slice().reverse().filter(step => step.status === 'success')[0];
693
+ if (lastSuccessStep) {
694
+ resultToken = {
695
+ blockchain: lastSuccessStep.toBlockchain,
696
+ symbol: lastSuccessStep.toSymbol,
697
+ outputAmount: lastSuccessStep.outputAmount,
698
+ address: lastSuccessStep.toSymbolAddress
699
+ };
700
+ }
701
+ }
702
+ return resultToken;
703
+ }
704
+ function shouldRetrySwap(pendingSwap) {
705
+ return pendingSwap.status === 'failed' && !!pendingSwap.finishTime && new Date().getTime() - parseInt(pendingSwap.finishTime) < 4 * 3600 * 1000;
706
+ }
636
707
 
637
708
  function searchParamsToToken(tokens, searchParams, chain) {
638
709
  if (!chain) return null;
@@ -672,20 +743,6 @@ function getRequiredBalanceOfWallet(selectedWallet, fee) {
672
743
  function isRouteParametersChanged(prevParams, currentParams) {
673
744
  return prevParams.fromChain?.name !== currentParams.fromChain?.name || prevParams.toChain?.name !== currentParams.toChain?.name || prevParams.fromToken?.symbol !== currentParams.fromToken?.symbol || prevParams.toToken?.symbol !== currentParams.toToken?.symbol || prevParams.fromToken?.blockchain !== currentParams.fromToken?.blockchain || prevParams.toToken?.blockchain !== currentParams.toToken?.blockchain || prevParams.fromToken?.address !== currentParams.fromToken?.address || prevParams.toToken?.address !== currentParams.toToken?.address || prevParams.inputAmount !== currentParams.inputAmount || prevParams.slippage !== currentParams.slippage || prevParams.customSlippage !== currentParams.customSlippage || prevParams.disabledLiquiditySources?.length !== currentParams.disabledLiquiditySources?.length;
674
745
  }
675
- function getBestRouteWithCalculatedFees(bestRoute, tokens) {
676
- if (!bestRoute || !bestRoute.result) return null;
677
- const swapsWithFee = (bestRoute?.result?.swaps || []).map(swap => ({
678
- ...swap,
679
- feeInUsd: numberToString(getUsdFeeOfStep(swap, tokens), 0, 2)
680
- }));
681
- return {
682
- ...bestRoute,
683
- result: {
684
- ...bestRoute.result,
685
- swaps: swapsWithFee
686
- }
687
- };
688
- }
689
746
 
690
747
  const createSelectors = _store => {
691
748
  let store = _store;
@@ -954,11 +1011,52 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/create()( /
954
1011
  inputUsdValue: getUsdValue(state.fromToken, amount)
955
1012
  })
956
1013
  }));
1014
+ },
1015
+ retry: pendingSwap => {
1016
+ const {
1017
+ tokens,
1018
+ blockchains
1019
+ } = useMetaStore.getState().meta;
1020
+ const balances = useWalletsStore.getState().balances;
1021
+ const failedIndex = pendingSwap.status === 'failed' ? pendingSwap.steps.findIndex(s => s.status === 'failed') : null;
1022
+ if (failedIndex === null || failedIndex < 0) return;
1023
+ const firstStep = pendingSwap.steps[0];
1024
+ const lastStep = pendingSwap.steps[pendingSwap.steps.length - 1];
1025
+ const fromChain = blockchains.find(blockchain => blockchain.name === firstStep.fromBlockchain) || null;
1026
+ const toChain = blockchains.find(blockchain => blockchain.name === lastStep.toBlockchain) || null;
1027
+ const fromToken = tokens.find(token => tokensAreEqual(token, {
1028
+ blockchain: firstStep.fromBlockchain,
1029
+ symbol: firstStep.fromSymbol,
1030
+ address: firstStep.fromSymbolAddress
1031
+ }));
1032
+ const toToken = tokens.find(token => tokensAreEqual(token, {
1033
+ blockchain: lastStep.toBlockchain,
1034
+ symbol: lastStep.toSymbol,
1035
+ address: lastStep.toSymbolAddress
1036
+ }));
1037
+ const sortedSourceTokens = getSortedTokens(fromChain, tokens, balances, []);
1038
+ const sortedDestinationTokens = getSortedTokens(toChain, tokens, balances, []);
1039
+ const inputAmount = pendingSwap.inputAmount;
1040
+ set({
1041
+ fromChain,
1042
+ fromToken,
1043
+ inputAmount,
1044
+ outputAmount: null,
1045
+ inputUsdValue: new BigNumber(0),
1046
+ outputUsdValue: new BigNumber(0),
1047
+ toChain,
1048
+ toToken,
1049
+ bestRoute: null,
1050
+ loading: false,
1051
+ error: '',
1052
+ sourceTokens: sortedSourceTokens,
1053
+ destinationTokens: sortedDestinationTokens
1054
+ });
957
1055
  }
958
1056
  }))));
959
1057
  const bestRoute = (bestRouteStore, settingsStore) => {
960
1058
  let abortController = null;
961
- const fetchBestRoute = () => {
1059
+ const fetchBestRoute = debounce(() => {
962
1060
  const {
963
1061
  fromToken,
964
1062
  toToken,
@@ -998,7 +1096,7 @@ const bestRoute = (bestRouteStore, settingsStore) => {
998
1096
  loading: false
999
1097
  });
1000
1098
  });
1001
- };
1099
+ }, 600);
1002
1100
  useBestRouteStore.subscribe(state => ({
1003
1101
  fromChain: state.fromChain,
1004
1102
  fromToken: state.fromToken,
@@ -1084,7 +1182,7 @@ function UpdateUrl() {
1084
1182
  toChainString = '',
1085
1183
  toTokenString = '',
1086
1184
  fromAmount = '';
1087
- if (loadingStatus !== 'success' && ![navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname)) {
1185
+ if (loadingStatus !== 'success' && location.pathname != navigationRoutes.confirmSwap) {
1088
1186
  fromChainString = searchParamsRef.current[SearchParams.FROM_CHAIN];
1089
1187
  fromTokenString = searchParamsRef.current[SearchParams.FROM_TOKEN];
1090
1188
  toChainString = searchParamsRef.current[SearchParams.TO_CHAIN];
@@ -1647,7 +1745,7 @@ function Home(props) {
1647
1745
  disabled: swapButtonState.disabled,
1648
1746
  onClick: () => {
1649
1747
  if (swapButtonState.title === 'Connect Wallet') navigate(navigationRoutes.wallets);else {
1650
- navigate(navigationRoutes.confirmWallets, {
1748
+ navigate(navigationRoutes.confirmSwap, {
1651
1749
  replace: true
1652
1750
  });
1653
1751
  }
@@ -1664,12 +1762,12 @@ const Route = _ref => {
1664
1762
  const navigate = useNavigate$1();
1665
1763
  const ref = useRef(true);
1666
1764
  useEffect(() => {
1667
- if ([navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname) && ref.current) navigate(navigationRoutes.home + location.search, {
1765
+ if (location.pathname === navigationRoutes.confirmSwap && ref.current) navigate(navigationRoutes.home + location.search, {
1668
1766
  state: 'redirect'
1669
1767
  });
1670
1768
  ref.current = false;
1671
1769
  }, []);
1672
- if ([navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname) && ref.current) return React.createElement(Home, Object.assign({}, props));
1770
+ if (location.pathname === navigationRoutes.confirmSwap && ref.current) return React.createElement(Home, Object.assign({}, props));
1673
1771
  return React.createElement(React.Fragment, null, " ", children);
1674
1772
  };
1675
1773
  function AppRouter(_ref2) {
@@ -1679,52 +1777,34 @@ function AppRouter(_ref2) {
1679
1777
  } = _ref2;
1680
1778
  const isRouterInContext = useInRouterContext$1();
1681
1779
  const Router = isRouterInContext ? Route : MemoryRouter;
1682
- return React.createElement(React.Fragment, null, React.createElement(Router, Object.assign({}, props), children), isRouterInContext && React.createElement(UpdateUrl, null));
1683
- }
1684
-
1685
- function ChangeSlippageButton() {
1686
- const navigate = useNavigate();
1687
- return React.createElement(Button, {
1688
- type: "primary",
1689
- variant: "outlined",
1690
- size: "small",
1691
- onClick: () => navigate(navigationRoutes.settings)
1692
- }, "Change Slippage");
1693
- }
1694
-
1695
- function HighSlippageWarning(props) {
1696
- const {
1697
- selectedSlippage
1698
- } = props;
1699
- return React.createElement(Alert, {
1700
- type: "warning",
1701
- footer: React.createElement(ChangeSlippageButton, null)
1702
- }, "Caution, your slippage is high (=", selectedSlippage, "). Your trade may be front run.");
1703
- }
1704
-
1705
- function ConfirmSwapExtraMessages(props) {
1706
1780
  const {
1707
- selectedSlippage
1708
- } = props;
1709
- const highSlippage = selectedSlippage >= HIGH_SLIPPAGE;
1710
- return React.createElement(React.Fragment, null, highSlippage && React.createElement(HighSlippageWarning, {
1711
- selectedSlippage: selectedSlippage
1712
- }));
1781
+ blockchains
1782
+ } = useMetaStore.use.meta();
1783
+ const evmChains = blockchains.filter(isEvmBlockchain);
1784
+ useQueueManager({
1785
+ lastConnectedWallet: props.lastConnectedWallet,
1786
+ clearDisconnectedWallet: props.clearDisconnectedWallet,
1787
+ disconnectedWallet: props.disconnectedWallet,
1788
+ evmChains,
1789
+ notifier: () => {}
1790
+ });
1791
+ return React.createElement(React.Fragment, null, React.createElement(Router, Object.assign({}, props), children), isRouterInContext && React.createElement(UpdateUrl, null));
1713
1792
  }
1714
1793
 
1715
1794
  function useNavigateBack() {
1716
1795
  const isRouterInContext = useInRouterContext();
1717
1796
  const navigate = useNavigate();
1718
1797
  const navigateBackFrom = currentRoute => {
1798
+ if (currentRoute === navigationRoutes.swapDetails) return navigate(navigationRoutes.swaps, {
1799
+ replace: true
1800
+ });
1719
1801
  if (!isRouterInContext || window.history.state && window.history.state.idx > 0) navigate(-1);else {
1720
- if ([navigationRoutes.fromChain, navigationRoutes.fromToken, navigationRoutes.toChain, navigationRoutes.toToken, navigationRoutes.settings, navigationRoutes.wallets, navigationRoutes.swaps, navigationRoutes.confirmWallets].includes(currentRoute)) navigate(navigationRoutes.home, {
1802
+ if ([navigationRoutes.fromChain, navigationRoutes.fromToken, navigationRoutes.toChain, navigationRoutes.toToken, navigationRoutes.settings, navigationRoutes.wallets, navigationRoutes.swaps, navigationRoutes.confirmSwap].includes(currentRoute)) navigate(navigationRoutes.home, {
1721
1803
  replace: true
1722
1804
  });else if (currentRoute === navigationRoutes.liquiditySources) navigate(navigationRoutes.settings, {
1723
1805
  replace: true
1724
1806
  });else if (currentRoute === navigationRoutes.swapDetails) navigate(navigationRoutes.swaps, {
1725
1807
  replace: true
1726
- });else if (currentRoute === navigationRoutes.confirmSwap) navigate(navigationRoutes.confirmWallets, {
1727
- replace: true
1728
1808
  });
1729
1809
  }
1730
1810
  };
@@ -1733,6 +1813,176 @@ function useNavigateBack() {
1733
1813
  };
1734
1814
  }
1735
1815
 
1816
+ const Box$1 = /*#__PURE__*/styled('div', {
1817
+ display: 'flex',
1818
+ flexDirection: 'column',
1819
+ width: '100%'
1820
+ });
1821
+ const Container$3 = /*#__PURE__*/styled('div', {
1822
+ boxSizing: 'border-box',
1823
+ borderRadius: '$5',
1824
+ padding: '$8 $16 $16 $16',
1825
+ variants: {
1826
+ type: {
1827
+ filled: {
1828
+ backgroundColor: '$neutrals300'
1829
+ },
1830
+ outlined: {
1831
+ border: '1px solid $neutrals300'
1832
+ }
1833
+ }
1834
+ },
1835
+ defaultVariants: {
1836
+ type: 'filled'
1837
+ },
1838
+ '.head': {
1839
+ display: 'flex',
1840
+ justifyContent: 'space-between',
1841
+ alignItems: 'center',
1842
+ minHeight: '32px'
1843
+ },
1844
+ '.form': {
1845
+ display: 'flex',
1846
+ width: '100%',
1847
+ padding: '$2 0',
1848
+ '.selectors': {
1849
+ width: '35%',
1850
+ '._text': {
1851
+ whiteSpace: 'nowrap',
1852
+ overflow: 'hidden',
1853
+ textOverflow: 'ellipsis'
1854
+ }
1855
+ },
1856
+ '.amount': {
1857
+ width: '30%'
1858
+ }
1859
+ }
1860
+ });
1861
+ const StyledImage$1 = /*#__PURE__*/styled('img', {
1862
+ width: '$24',
1863
+ maxHeight: '$24'
1864
+ });
1865
+ const ImagePlaceholder$1 = /*#__PURE__*/styled('span', {
1866
+ width: '24px',
1867
+ height: '24px',
1868
+ backgroundColor: '$neutrals300',
1869
+ borderRadius: '99999px'
1870
+ });
1871
+ const OutputContainer$1 = /*#__PURE__*/styled('div', {
1872
+ windth: '100%',
1873
+ height: '$48',
1874
+ borderRadius: '$5',
1875
+ backgroundColor: '$background',
1876
+ border: '1px solid transparent',
1877
+ position: 'relative',
1878
+ display: 'flex',
1879
+ alignItems: 'center',
1880
+ paddingLeft: '$8',
1881
+ paddingRight: '$8'
1882
+ });
1883
+ function TokenPreview(props) {
1884
+ const {
1885
+ chain,
1886
+ token,
1887
+ loadingStatus
1888
+ } = props;
1889
+ const {
1890
+ t
1891
+ } = useTranslation();
1892
+ const ItemSuffix = React.createElement("div", {
1893
+ style: {
1894
+ display: 'flex',
1895
+ justifyContent: 'center',
1896
+ alignItems: 'center'
1897
+ }
1898
+ }, loadingStatus === 'failed' && React.createElement(InfoCircleIcon, {
1899
+ color: "error",
1900
+ size: 24
1901
+ }));
1902
+ return React.createElement(Box$1, null, React.createElement(Container$3, {
1903
+ type: 'outlined'
1904
+ }, React.createElement("div", {
1905
+ className: "head"
1906
+ }, React.createElement(Typography, {
1907
+ variant: "body2",
1908
+ color: "neutrals800"
1909
+ }, props.label), React.createElement(Typography, {
1910
+ variant: "caption",
1911
+ color: "neutrals600"
1912
+ }, `$${numberToString(props.usdValue)}`)), React.createElement("div", {
1913
+ className: "form"
1914
+ }, React.createElement(Button, {
1915
+ className: "selectors",
1916
+ variant: "outlined",
1917
+ loading: loadingStatus === 'loading',
1918
+ prefix: loadingStatus === 'success' && chain ? React.createElement(StyledImage$1, {
1919
+ src: chain.logo
1920
+ }) : React.createElement(ImagePlaceholder$1, null),
1921
+ suffix: ItemSuffix,
1922
+ align: "start",
1923
+ size: "large"
1924
+ }, loadingStatus === 'success' && chain ? chain.displayName : t('Chain')), React.createElement(Spacer, {
1925
+ size: 12
1926
+ }), React.createElement(Button, {
1927
+ className: "selectors",
1928
+ variant: "outlined",
1929
+ loading: loadingStatus === 'loading',
1930
+ prefix: loadingStatus === 'success' && token ? React.createElement(StyledImage$1, {
1931
+ src: token.image
1932
+ }) : React.createElement(ImagePlaceholder$1, null),
1933
+ suffix: ItemSuffix,
1934
+ size: "large",
1935
+ align: "start"
1936
+ }, loadingStatus === 'success' && token ? token.symbol : t('Token')), React.createElement(Spacer, {
1937
+ size: 12
1938
+ }), React.createElement("div", {
1939
+ className: "amount"
1940
+ }, React.createElement(OutputContainer$1, null, React.createElement(Typography, {
1941
+ variant: "h4"
1942
+ }, props.amount))))));
1943
+ }
1944
+
1945
+ const Container$4 = /*#__PURE__*/styled('div', {
1946
+ display: 'flex',
1947
+ alignItems: 'center',
1948
+ justifyContent: 'space-between',
1949
+ padding: '$8',
1950
+ borderRadius: '$5',
1951
+ backgroundColor: '$neutrals300',
1952
+ color: '$neutrals800',
1953
+ fontSize: '$12',
1954
+ '.routes': {
1955
+ display: 'flex',
1956
+ alignItems: 'center'
1957
+ },
1958
+ '.fee': {
1959
+ display: 'flex',
1960
+ alignItems: 'center'
1961
+ }
1962
+ });
1963
+ function RoutesOverview(props) {
1964
+ if (!props.routes) return null;
1965
+ const swaps = props.routes.result?.swaps;
1966
+ return React.createElement(Container$4, null, React.createElement("div", {
1967
+ className: "routes"
1968
+ }, swaps?.map((swap, idx) => {
1969
+ const isLast = idx + 1 == swaps.length;
1970
+ return React.createElement(React.Fragment, null, React.createElement("div", {
1971
+ className: "route"
1972
+ }, swap.from.symbol), React.createElement(ChevronRightIcon, {
1973
+ size: 12
1974
+ }), isLast ? React.createElement("div", {
1975
+ className: "route"
1976
+ }, swap.to.symbol) : null);
1977
+ })), props.totalFee ? React.createElement("div", {
1978
+ className: "fee"
1979
+ }, React.createElement(GasIcon, {
1980
+ size: 12
1981
+ }), React.createElement(Spacer, {
1982
+ size: 4
1983
+ }), "$", props.totalFee) : null);
1984
+ }
1985
+
1736
1986
  var ConfirmSwapErrorTypes;
1737
1987
  (function (ConfirmSwapErrorTypes) {
1738
1988
  ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["NO_ROUTE"] = 0] = "NO_ROUTE";
@@ -1749,106 +1999,6 @@ var ConfirmSwapWarningTypes;
1749
1999
  ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["INSUFFICIENT_BALANCE"] = 4] = "INSUFFICIENT_BALANCE";
1750
2000
  })(ConfirmSwapWarningTypes || (ConfirmSwapWarningTypes = {}));
1751
2001
 
1752
- function MinRequiredSlippage(_ref) {
1753
- let {
1754
- minRequiredSlippage
1755
- } = _ref;
1756
- return React.createElement(Typography, {
1757
- variant: "body2"
1758
- }, "We recommend you to increase slippage to at least \u00A0", minRequiredSlippage, "\u00A0 for this route.", React.createElement(ChangeSlippageButton, null));
1759
- }
1760
-
1761
- function ConfirmSwapErrors(errors) {
1762
- return errors.flatMap(error => {
1763
- switch (error.type) {
1764
- case ConfirmSwapErrorTypes.NO_ROUTE:
1765
- return React.createElement(Typography, {
1766
- variant: "body2"
1767
- }, "No routes found. Please try again later.");
1768
- case ConfirmSwapErrorTypes.REQUEST_FAILED:
1769
- return React.createElement(Typography, {
1770
- variant: "body2"
1771
- }, `Failed to confirm swap ${error.status ? `'status': ${error.status})` : ''}, please try again.`);
1772
- case ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS:
1773
- return React.createElement(Typography, {
1774
- variant: "body2"
1775
- }, "Route updated and price impact is too high, try again later!");
1776
- case ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE:
1777
- return React.createElement(MinRequiredSlippage, {
1778
- minRequiredSlippage: error.minRequiredSlippage
1779
- });
1780
- default:
1781
- return [];
1782
- }
1783
- });
1784
- }
1785
-
1786
- const List = /*#__PURE__*/styled('ul', {
1787
- variants: {
1788
- showListStyle: {
1789
- true: {
1790
- paddingLeft: '$24'
1791
- }
1792
- }
1793
- }
1794
- });
1795
- const ListItem = /*#__PURE__*/styled('li', {
1796
- variants: {
1797
- showListStyle: {
1798
- true: {
1799
- listStyleType: 'disc',
1800
- listStylePosition: 'outside'
1801
- }
1802
- }
1803
- }
1804
- });
1805
- const Message = /*#__PURE__*/styled(Typography, {
1806
- display: 'block'
1807
- });
1808
- function BalanceWarnings(_ref) {
1809
- let {
1810
- messages
1811
- } = _ref;
1812
- const showListStyle = messages.length > 1;
1813
- return React.createElement(List, {
1814
- showListStyle: showListStyle
1815
- }, messages.map(warning => React.createElement(ListItem, {
1816
- showListStyle: showListStyle
1817
- }, React.createElement(Message, {
1818
- variant: "body2"
1819
- }, warning))));
1820
- }
1821
-
1822
- function ConfirmSwapWarnings(warnings) {
1823
- return warnings.flatMap(warning => {
1824
- switch (warning.type) {
1825
- case ConfirmSwapWarningTypes.ROUTE_UPDATED:
1826
- return React.createElement(Typography, {
1827
- variant: "body2"
1828
- }, "Route has been updated.");
1829
- case ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED:
1830
- return React.createElement(Typography, {
1831
- variant: "body2"
1832
- }, `Output amount changed to ${warning.newOutputAmount}
1833
- (${warning.percentageChange}% change).`);
1834
- case ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED:
1835
- return React.createElement(Typography, {
1836
- variant: "body2"
1837
- }, "Route swappers has been updated.");
1838
- case ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED:
1839
- return React.createElement(Typography, {
1840
- variant: "body2"
1841
- }, "Route internal coins has been updated.");
1842
- case ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE:
1843
- return React.createElement(BalanceWarnings, {
1844
- messages: warning.messages
1845
- });
1846
- default:
1847
- return [];
1848
- }
1849
- });
1850
- }
1851
-
1852
2002
  function useConfirmSwap() {
1853
2003
  const fromToken = useBestRouteStore.use.fromToken();
1854
2004
  const toToken = useBestRouteStore.use.toToken();
@@ -1889,6 +2039,7 @@ function useConfirmSwap() {
1889
2039
  proceedAnywayRef.current = false;
1890
2040
  if (confiremedRouteRef.current) {
1891
2041
  const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRouteRef.current, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
2042
+ //@ts-ignore
1892
2043
  return newSwap;
1893
2044
  }
1894
2045
  return;
@@ -1951,6 +2102,7 @@ function useConfirmSwap() {
1951
2102
  disabledSwappersGroups: disabledLiquiditySources
1952
2103
  };
1953
2104
  const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRoute, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
2105
+ //@ts-ignore
1954
2106
  return newSwap;
1955
2107
  } else if (!proceedAnywayRef.current) {
1956
2108
  proceedAnywayRef.current = true;
@@ -1980,31 +2132,194 @@ function useConfirmSwap() {
1980
2132
  };
1981
2133
  }
1982
2134
 
2135
+ function ChangeSlippageButton() {
2136
+ const navigate = useNavigate();
2137
+ return React.createElement(Button, {
2138
+ type: "primary",
2139
+ variant: "outlined",
2140
+ size: "small",
2141
+ onClick: () => navigate(navigationRoutes.settings)
2142
+ }, "Change Slippage");
2143
+ }
2144
+
2145
+ const StyledMessage = /*#__PURE__*/styled(Typography, {
2146
+ color: '$error500 !important'
2147
+ });
2148
+ function MinRequiredSlippage(_ref) {
2149
+ let {
2150
+ minRequiredSlippage
2151
+ } = _ref;
2152
+ return React.createElement(StyledMessage, {
2153
+ variant: "body2"
2154
+ }, "We recommend you to increase slippage to at least \u00A0", minRequiredSlippage, "\u00A0 for this route.", React.createElement(Spacer, {
2155
+ size: 8,
2156
+ direction: "vertical"
2157
+ }), React.createElement(ChangeSlippageButton, null));
2158
+ }
2159
+
2160
+ function ConfirmSwapErrors(errors) {
2161
+ return errors.flatMap(error => {
2162
+ switch (error.type) {
2163
+ case ConfirmSwapErrorTypes.NO_ROUTE:
2164
+ return React.createElement(Typography, {
2165
+ variant: "body2"
2166
+ }, "No routes found. Please try again later.");
2167
+ case ConfirmSwapErrorTypes.REQUEST_FAILED:
2168
+ return React.createElement(Typography, {
2169
+ variant: "body2"
2170
+ }, `Failed to confirm swap ${error.status ? `'status': ${error.status})` : ''}, please try again.`);
2171
+ case ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS:
2172
+ return React.createElement(Typography, {
2173
+ variant: "body2"
2174
+ }, "Route updated and price impact is too high, try again later!");
2175
+ case ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE:
2176
+ return React.createElement(MinRequiredSlippage, {
2177
+ minRequiredSlippage: error.minRequiredSlippage
2178
+ });
2179
+ default:
2180
+ return [];
2181
+ }
2182
+ });
2183
+ }
2184
+
2185
+ const List = /*#__PURE__*/styled('ul', {
2186
+ variants: {
2187
+ showListStyle: {
2188
+ true: {
2189
+ paddingLeft: '$24'
2190
+ }
2191
+ }
2192
+ }
2193
+ });
2194
+ const ListItem = /*#__PURE__*/styled('li', {
2195
+ variants: {
2196
+ showListStyle: {
2197
+ true: {
2198
+ listStyleType: 'disc',
2199
+ listStylePosition: 'outside'
2200
+ }
2201
+ }
2202
+ }
2203
+ });
2204
+ const Message = /*#__PURE__*/styled(Typography, {
2205
+ display: 'block',
2206
+ color: '$warning500 !important'
2207
+ });
2208
+ function BalanceWarnings(_ref) {
2209
+ let {
2210
+ messages
2211
+ } = _ref;
2212
+ const showListStyle = messages.length > 1;
2213
+ return React.createElement(List, {
2214
+ showListStyle: showListStyle
2215
+ }, messages.map(warning => React.createElement(ListItem, {
2216
+ showListStyle: showListStyle
2217
+ }, React.createElement(Message, {
2218
+ variant: "body2"
2219
+ }, warning))));
2220
+ }
2221
+
2222
+ function ConfirmSwapWarnings(warnings) {
2223
+ return warnings.flatMap(warning => {
2224
+ switch (warning.type) {
2225
+ case ConfirmSwapWarningTypes.ROUTE_UPDATED:
2226
+ return React.createElement(Typography, {
2227
+ variant: "body2"
2228
+ }, "Route has been updated.");
2229
+ case ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED:
2230
+ return React.createElement(Typography, {
2231
+ variant: "body2"
2232
+ }, `Output amount changed to ${warning.newOutputAmount}
2233
+ (${warning.percentageChange}% change).`);
2234
+ case ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED:
2235
+ return React.createElement(Typography, {
2236
+ variant: "body2"
2237
+ }, "Route swappers has been updated.");
2238
+ case ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED:
2239
+ return React.createElement(Typography, {
2240
+ variant: "body2"
2241
+ }, "Route internal coins has been updated.");
2242
+ case ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE:
2243
+ return React.createElement(BalanceWarnings, {
2244
+ messages: warning.messages
2245
+ });
2246
+ default:
2247
+ return [];
2248
+ }
2249
+ });
2250
+ }
2251
+
2252
+ function HighSlippageWarning(props) {
2253
+ const {
2254
+ selectedSlippage
2255
+ } = props;
2256
+ return React.createElement(Alert, {
2257
+ type: "warning",
2258
+ footer: React.createElement(ChangeSlippageButton, null)
2259
+ }, "Caution, your slippage is high (=", selectedSlippage, "). Your trade may be front run.");
2260
+ }
2261
+
2262
+ function ConfirmSwapExtraMessages(props) {
2263
+ const {
2264
+ selectedSlippage
2265
+ } = props;
2266
+ const highSlippage = selectedSlippage >= HIGH_SLIPPAGE;
2267
+ return React.createElement(React.Fragment, null, highSlippage && React.createElement(HighSlippageWarning, {
2268
+ selectedSlippage: selectedSlippage
2269
+ }));
2270
+ }
2271
+
1983
2272
  function ConfirmSwapPage() {
1984
- const setSelectedSwap = useUiStore.use.setSelectedSwap();
2273
+ const navigate = useNavigate();
1985
2274
  const {
1986
2275
  navigateBackFrom
1987
2276
  } = useNavigateBack();
1988
- const {
1989
- manager
1990
- } = useManager();
1991
- const navigate = useNavigate();
1992
2277
  const bestRoute = useBestRouteStore.use.bestRoute();
1993
2278
  const fetchingBestRoute = useBestRouteStore.use.loading();
2279
+ const setSelectedSwap = useUiStore.use.setSelectedSwap();
1994
2280
  const {
2281
+ blockchains,
1995
2282
  tokens
1996
2283
  } = useMetaStore.use.meta();
2284
+ const accounts = useWalletsStore.use.accounts();
2285
+ const selectedWallets = useWalletsStore.use.selectedWallets();
2286
+ const initSelectedWallets = useWalletsStore.use.initSelectedWallets();
2287
+ const setSelectedWallet = useWalletsStore.use.setSelectedWallet();
1997
2288
  const slippage = useSettingsStore.use.slippage();
1998
2289
  const customSlippage = useSettingsStore.use.customSlippage();
1999
- const selectedSlippage = customSlippage || slippage;
2290
+ const {
2291
+ manager
2292
+ } = useManager();
2000
2293
  const {
2001
2294
  loading,
2002
2295
  errors,
2003
2296
  warnings,
2004
2297
  confirmSwap
2005
2298
  } = useConfirmSwap();
2299
+ const selectedSlippage = customSlippage || slippage;
2006
2300
  const showHighSlippageWarning = !errors.find(error => error.type === ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE);
2301
+ const {
2302
+ getWalletInfo,
2303
+ connect
2304
+ } = useWallets();
2305
+ const confirmDisabled = fetchingBestRoute || !requiredWallets(bestRoute).every(chain => selectedWallets.map(wallet => wallet.chain).includes(chain));
2306
+ const firstStep = bestRoute?.result?.swaps[0];
2307
+ const lastStep = bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1];
2308
+ const fromAmount = decimalNumber(firstStep?.fromAmount, 3);
2309
+ const toAmount = decimalNumber(lastStep?.toAmount, 3);
2310
+ useEffect(() => {
2311
+ initSelectedWallets();
2312
+ }, []);
2313
+ const selectableWallets = getSelectableWallets(accounts, selectedWallets, getWalletInfo);
2314
+ const handleConnectChain = wallet => {
2315
+ const network = wallet;
2316
+ getKeplrCompatibleConnectedWallets(selectableWallets).forEach(compatibleWallet => connect?.(compatibleWallet, network));
2317
+ };
2318
+ const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
2007
2319
  return React.createElement(ConfirmSwap, {
2320
+ requiredWallets: getRequiredChains(bestRoute),
2321
+ selectableWallets: selectableWallets,
2322
+ onBack: navigateBackFrom.bind(null, navigationRoutes.confirmSwap),
2008
2323
  onConfirm: () => {
2009
2324
  confirmSwap?.().then(swap => {
2010
2325
  if (swap) {
@@ -2020,16 +2335,51 @@ function ConfirmSwapPage() {
2020
2335
  }
2021
2336
  });
2022
2337
  },
2023
- onBack: navigateBackFrom.bind(null, navigationRoutes.confirmSwap),
2024
- bestRoute: getBestRouteWithCalculatedFees(bestRoute, tokens),
2025
- loading: loading,
2026
- errors: ConfirmSwapErrors(errors),
2027
- warnings: ConfirmSwapWarnings(warnings),
2028
- extraMessages: showHighSlippageWarning && React.createElement(ConfirmSwapExtraMessages, {
2338
+ onChange: wallet => setSelectedWallet(wallet),
2339
+ confirmDisabled: confirmDisabled,
2340
+ handleConnectChain: wallet => handleConnectChain(wallet),
2341
+ isExperimentalChain: wallet => getKeplrCompatibleConnectedWallets(selectableWallets).length > 0 ? isExperimentalChain(blockchains, wallet) : false,
2342
+ previewInputs: React.createElement(React.Fragment, null, React.createElement(TokenPreview, {
2343
+ chain: {
2344
+ displayName: firstStep?.from.blockchain || '',
2345
+ logo: firstStep?.from.blockchainLogo || ''
2346
+ },
2347
+ token: {
2348
+ symbol: firstStep?.from.symbol || '',
2349
+ image: firstStep?.from.logo || ''
2350
+ },
2351
+ usdValue: calcOutputUsdValue(fromAmount, firstStep?.from.usdPrice),
2352
+ amount: fromAmount,
2353
+ label: t('From'),
2354
+ loadingStatus: 'success'
2355
+ }), React.createElement(Spacer, {
2356
+ size: 12,
2357
+ direction: "vertical"
2358
+ }), React.createElement(TokenPreview, {
2359
+ chain: {
2360
+ displayName: lastStep?.to.blockchain || '',
2361
+ logo: lastStep?.to.blockchainLogo || ''
2362
+ },
2363
+ token: {
2364
+ symbol: lastStep?.to.symbol || '',
2365
+ image: lastStep?.to.logo || ''
2366
+ },
2367
+ usdValue: calcOutputUsdValue(toAmount, lastStep?.to.usdPrice),
2368
+ amount: toAmount,
2369
+ label: t('To'),
2370
+ loadingStatus: 'success'
2371
+ })),
2372
+ previewRoutes: React.createElement(RoutesOverview, {
2373
+ routes: bestRoute,
2374
+ totalFee: numberToString(totalFeeInUsd, 0, 2)
2375
+ }),
2376
+ loading: loading,
2377
+ errors: ConfirmSwapErrors(errors),
2378
+ warnings: ConfirmSwapWarnings(warnings),
2379
+ extraMessages: showHighSlippageWarning && React.createElement(ConfirmSwapExtraMessages, {
2029
2380
  selectedSlippage: selectedSlippage
2030
2381
  }),
2031
- confirmButtonTitle: warnings.length > 0 || errors.length > 0 ? 'Proceed anyway!' : 'Confirm swap!',
2032
- confirmButtonDisabled: fetchingBestRoute
2382
+ confirmButtonTitle: warnings.length > 0 || errors.length > 0 ? 'Proceed anyway!' : 'Confirm swap!'
2033
2383
  });
2034
2384
  }
2035
2385
 
@@ -2117,436 +2467,185 @@ function SelectChainPage(props) {
2117
2467
  supportedChains
2118
2468
  } = props;
2119
2469
  const blockchains = supportedChains === 'all' ? useMetaStore.use.meta().blockchains : supportedChains;
2120
- const loadingStatus = useMetaStore.use.loadingStatus();
2121
- const fromChain = useBestRouteStore.use.fromChain();
2122
- const toChain = useBestRouteStore.use.toChain();
2123
- const setFromChain = useBestRouteStore.use.setFromChain();
2124
- const setToChain = useBestRouteStore.use.setToChain();
2125
- const {
2126
- navigateBackFrom
2127
- } = useNavigateBack();
2128
- return React.createElement(BlockchainSelector, {
2129
- type: type === 'from' ? 'Source' : 'Destination',
2130
- list: blockchains,
2131
- selected: type === 'from' ? fromChain : toChain,
2132
- loadingStatus: loadingStatus,
2133
- onChange: chain => {
2134
- if (type === 'from') setFromChain(chain, true);else setToChain(chain, true);
2135
- navigateBackFrom(navigationRoutes.fromChain);
2136
- },
2137
- onBack: navigateBackFrom.bind(null, navigationRoutes.fromChain)
2138
- });
2139
- }
2140
-
2141
- function SelectTokenPage(props) {
2142
- const {
2143
- navigateBackFrom
2144
- } = useNavigateBack();
2145
- const {
2146
- type,
2147
- supportedTokens
2148
- } = props;
2149
- const sourceTokens = useBestRouteStore.use.sourceTokens();
2150
- const destinationTokens = useBestRouteStore.use.destinationTokens();
2151
- const supportedSourceTokens = supportedTokens === 'all' ? sourceTokens : sourceTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2152
- const supportedDestinationTokens = supportedTokens === 'all' ? destinationTokens : destinationTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2153
- console.log(supportedSourceTokens);
2154
- const fromToken = useBestRouteStore.use.fromToken();
2155
- const toToken = useBestRouteStore.use.toToken();
2156
- const setFromToken = useBestRouteStore.use.setFromToken();
2157
- const setToToken = useBestRouteStore.use.setToToken();
2158
- return React.createElement(TokenSelector, {
2159
- type: type === 'from' ? 'Source' : 'Destination',
2160
- list: type == 'from' ? supportedSourceTokens : supportedDestinationTokens,
2161
- selected: type === 'from' ? fromToken : toToken,
2162
- onChange: token => {
2163
- if (type === 'from') setFromToken(token);else setToToken(token);
2164
- navigateBackFrom(navigationRoutes.fromToken);
2165
- },
2166
- onBack: navigateBackFrom.bind(null, navigationRoutes.fromToken)
2167
- });
2168
- }
2169
-
2170
- function SettingsPage(_ref) {
2171
- let {
2172
- supportedSwappers
2173
- } = _ref;
2174
- const slippage = useSettingsStore.use.slippage();
2175
- const setSlippage = useSettingsStore.use.setSlippage();
2176
- const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
2177
- const customSlippage = useSettingsStore.use.customSlippage();
2178
- const setCustomSlippage = useSettingsStore.use.setCustomSlippage();
2179
- const theme = useSettingsStore.use.theme();
2180
- const setTheme = useSettingsStore.use.setTheme();
2181
- const swappers = useMetaStore.use.meta().swappers;
2182
- const navigate = useNavigate();
2183
- const {
2184
- navigateBackFrom
2185
- } = useNavigateBack();
2186
- const infiniteApprove = useSettingsStore.use.infiniteApprove();
2187
- const toggleInfiniteApprove = useSettingsStore.use.toggleInfiniteApprove();
2188
- const uniqueSwappersGroups = [];
2189
- removeDuplicateFrom(swappers.map(s => s.swapperGroup)).map(swapperGroup => {
2190
- return swappers.find(s => s.swapperGroup === swapperGroup);
2191
- }).find(s => {
2192
- if (s) {
2193
- for (const type of s.types) {
2194
- uniqueSwappersGroups.push({
2195
- title: s.swapperGroup,
2196
- logo: s.logo,
2197
- type,
2198
- selected: !disabledLiquiditySources.includes(s.swapperGroup)
2199
- });
2200
- }
2201
- }
2202
- });
2203
- supportedSwappers !== 'all' && uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0);
2204
- const supportedUniqueSwappersGroups = supportedSwappers !== 'all' ? uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0) : uniqueSwappersGroups;
2205
- return React.createElement(Settings, {
2206
- slippages: SLIPPAGES,
2207
- selectedSlippage: slippage,
2208
- onSlippageChange: slippage => setSlippage(slippage),
2209
- onLiquiditySourcesClick: () => navigate(navigationRoutes.liquiditySources),
2210
- onBack: navigateBackFrom.bind(null, navigationRoutes.settings),
2211
- liquiditySources: supportedUniqueSwappersGroups,
2212
- selectedLiquiditySources: supportedUniqueSwappersGroups.filter(s => s.selected),
2213
- customSlippage: customSlippage || NaN,
2214
- onCustomSlippageChange: setCustomSlippage,
2215
- minSlippage: MIN_SLIPPGAE,
2216
- maxSlippage: MAX_SLIPPAGE,
2217
- selectedTheme: theme,
2218
- onThemeChange: setTheme,
2219
- infiniteApprove: infiniteApprove,
2220
- toggleInfiniteApprove: toggleInfiniteApprove
2221
- });
2222
- }
2223
-
2224
- const ListContainer = /*#__PURE__*/styled('div', {
2225
- display: 'grid',
2226
- gap: '.5rem',
2227
- gridTemplateColumns: ' repeat(2, minmax(0, 1fr))',
2228
- height: '450px',
2229
- alignContent: 'baseline',
2230
- padding: '0.5rem'
2231
- });
2232
- const AlertContainer = /*#__PURE__*/styled('div', {
2233
- paddingBottom: '$16'
2234
- });
2235
- function WalletsPage(_ref) {
2236
- let {
2237
- supportedWallets,
2238
- multiWallets
2239
- } = _ref;
2240
- const {
2241
- navigateBackFrom
2242
- } = useNavigateBack();
2243
- const {
2244
- state,
2245
- disconnect,
2246
- getWalletInfo,
2247
- connect
2248
- } = useWallets();
2249
- const wallets = getlistWallet(state, getWalletInfo, supportedWallets === 'all' ? Object.values(WalletType) : supportedWallets);
2250
- const walletsRef = useRef();
2251
- let sortedWallets = detectMobileScreens() ? wallets.filter(wallet => wallet.showOnMobile) : wallets;
2252
- sortedWallets = sortWalletsBasedOnState(sortedWallets);
2253
- const [walletErrorMessage, setWalletErrorMessage] = useState('');
2254
- const toggleConnectWalletsButton = useUiStore.use.toggleConnectWalletsButton();
2255
- const {
2256
- t
2257
- } = useTranslation();
2258
- const onSelectWallet = async type => {
2259
- const wallet = state(type);
2260
- try {
2261
- if (walletErrorMessage) setWalletErrorMessage('');
2262
- if (wallet.connected) {
2263
- await disconnect(type);
2264
- } else {
2265
- if (!multiWallets && !!wallets.find(w => w.state === WalletState.CONNECTED)) {
2266
- return;
2267
- }
2268
- await connect(type);
2269
- }
2270
- } catch (e) {
2271
- setWalletErrorMessage('Error: ' + e?.message);
2272
- }
2273
- };
2274
- const disconnectConnectingWallets = () => {
2275
- const connectingWallets = walletsRef.current?.filter(wallet => wallet.state === WalletState.CONNECTING) || [];
2276
- for (const wallet of connectingWallets) {
2277
- disconnect(wallet.type);
2278
- }
2279
- };
2280
- useEffect(() => {
2281
- toggleConnectWalletsButton();
2282
- return () => {
2283
- disconnectConnectingWallets();
2284
- toggleConnectWalletsButton();
2285
- };
2286
- }, []);
2287
- useEffect(() => {
2288
- walletsRef.current = wallets;
2289
- }, [wallets]);
2290
- return React.createElement(SecondaryPage, {
2291
- title: t('Select Wallet') || '',
2292
- textField: false,
2293
- onBack: navigateBackFrom.bind(null, navigationRoutes.wallets)
2294
- }, React.createElement(React.Fragment, null, walletErrorMessage && React.createElement(AlertContainer, null, React.createElement(Alert, {
2295
- type: "error"
2296
- }, walletErrorMessage)), React.createElement(ListContainer, null, sortedWallets.map((wallet, index) => React.createElement(Wallet, Object.assign({}, wallet, {
2297
- key: `${index}-${wallet.type}`,
2298
- onClick: onSelectWallet
2299
- }))))));
2300
- }
2301
-
2302
- const Box$1 = /*#__PURE__*/styled('div', {
2303
- display: 'flex',
2304
- flexDirection: 'column',
2305
- width: '100%'
2306
- });
2307
- const Container$3 = /*#__PURE__*/styled('div', {
2308
- boxSizing: 'border-box',
2309
- borderRadius: '$5',
2310
- padding: '$8 $16 $16 $16',
2311
- variants: {
2312
- type: {
2313
- filled: {
2314
- backgroundColor: '$neutrals300'
2315
- },
2316
- outlined: {
2317
- border: '1px solid $neutrals300'
2318
- }
2319
- }
2320
- },
2321
- defaultVariants: {
2322
- type: 'filled'
2323
- },
2324
- '.head': {
2325
- display: 'flex',
2326
- justifyContent: 'space-between',
2327
- alignItems: 'center',
2328
- minHeight: '32px'
2329
- },
2330
- '.form': {
2331
- display: 'flex',
2332
- width: '100%',
2333
- padding: '$2 0',
2334
- '.selectors': {
2335
- width: '35%',
2336
- '._text': {
2337
- whiteSpace: 'nowrap',
2338
- overflow: 'hidden',
2339
- textOverflow: 'ellipsis'
2340
- }
2341
- },
2342
- '.amount': {
2343
- width: '30%'
2344
- }
2345
- }
2346
- });
2347
- const StyledImage$1 = /*#__PURE__*/styled('img', {
2348
- width: '$24',
2349
- maxHeight: '$24'
2350
- });
2351
- const ImagePlaceholder$1 = /*#__PURE__*/styled('span', {
2352
- width: '24px',
2353
- height: '24px',
2354
- backgroundColor: '$neutrals300',
2355
- borderRadius: '99999px'
2356
- });
2357
- const OutputContainer$1 = /*#__PURE__*/styled('div', {
2358
- windth: '100%',
2359
- height: '$48',
2360
- borderRadius: '$5',
2361
- backgroundColor: '$background',
2362
- border: '1px solid transparent',
2363
- position: 'relative',
2364
- display: 'flex',
2365
- alignItems: 'center',
2366
- paddingLeft: '$8',
2367
- paddingRight: '$8'
2368
- });
2369
- function TokenPreview(props) {
2370
- const {
2371
- chain,
2372
- token,
2373
- loadingStatus
2374
- } = props;
2375
- const {
2376
- t
2377
- } = useTranslation();
2378
- const ItemSuffix = React.createElement("div", {
2379
- style: {
2380
- display: 'flex',
2381
- justifyContent: 'center',
2382
- alignItems: 'center'
2383
- }
2384
- }, loadingStatus === 'failed' && React.createElement(InfoCircleIcon, {
2385
- color: "error",
2386
- size: 24
2387
- }));
2388
- return React.createElement(Box$1, null, React.createElement(Container$3, {
2389
- type: 'outlined'
2390
- }, React.createElement("div", {
2391
- className: "head"
2392
- }, React.createElement(Typography, {
2393
- variant: "body2",
2394
- color: "neutrals800"
2395
- }, props.label), React.createElement(Typography, {
2396
- variant: "caption",
2397
- color: "neutrals600"
2398
- }, `$${numberToString(props.usdValue)}`)), React.createElement("div", {
2399
- className: "form"
2400
- }, React.createElement(Button, {
2401
- className: "selectors",
2402
- variant: "outlined",
2403
- loading: loadingStatus === 'loading',
2404
- prefix: loadingStatus === 'success' && chain ? React.createElement(StyledImage$1, {
2405
- src: chain.logo
2406
- }) : React.createElement(ImagePlaceholder$1, null),
2407
- suffix: ItemSuffix,
2408
- align: "start",
2409
- size: "large"
2410
- }, loadingStatus === 'success' && chain ? chain.displayName : t('Chain')), React.createElement(Spacer, {
2411
- size: 12
2412
- }), React.createElement(Button, {
2413
- className: "selectors",
2414
- variant: "outlined",
2415
- loading: loadingStatus === 'loading',
2416
- prefix: loadingStatus === 'success' && token ? React.createElement(StyledImage$1, {
2417
- src: token.image
2418
- }) : React.createElement(ImagePlaceholder$1, null),
2419
- suffix: ItemSuffix,
2420
- size: "large",
2421
- align: "start"
2422
- }, loadingStatus === 'success' && token ? token.symbol : t('Token')), React.createElement(Spacer, {
2423
- size: 12
2424
- }), React.createElement("div", {
2425
- className: "amount"
2426
- }, React.createElement(OutputContainer$1, null, React.createElement(Typography, {
2427
- variant: "h4"
2428
- }, props.amount))))));
2429
- }
2430
-
2431
- const Container$4 = /*#__PURE__*/styled('div', {
2432
- display: 'flex',
2433
- alignItems: 'center',
2434
- justifyContent: 'space-between',
2435
- padding: '$8',
2436
- borderRadius: '$5',
2437
- backgroundColor: '$neutrals300',
2438
- color: '$neutrals800',
2439
- fontSize: '$12',
2440
- '.routes': {
2441
- display: 'flex',
2442
- alignItems: 'center'
2443
- },
2444
- '.fee': {
2445
- display: 'flex',
2446
- alignItems: 'center'
2447
- }
2448
- });
2449
- function RoutesOverview(props) {
2450
- if (!props.routes) return null;
2451
- const swaps = props.routes.result?.swaps;
2452
- return React.createElement(Container$4, null, React.createElement("div", {
2453
- className: "routes"
2454
- }, swaps?.map((swap, idx) => {
2455
- const isLast = idx + 1 == swaps.length;
2456
- return React.createElement(React.Fragment, null, React.createElement("div", {
2457
- className: "route"
2458
- }, swap.from.symbol), React.createElement(ChevronRightIcon, {
2459
- size: 12
2460
- }), isLast ? React.createElement("div", {
2461
- className: "route"
2462
- }, swap.to.symbol) : null);
2463
- })), props.totalFee ? React.createElement("div", {
2464
- className: "fee"
2465
- }, React.createElement(GasIcon, {
2466
- size: 12
2467
- }), React.createElement(Spacer, {
2468
- size: 4
2469
- }), "$", props.totalFee) : null);
2470
+ const loadingStatus = useMetaStore.use.loadingStatus();
2471
+ const fromChain = useBestRouteStore.use.fromChain();
2472
+ const toChain = useBestRouteStore.use.toChain();
2473
+ const setFromChain = useBestRouteStore.use.setFromChain();
2474
+ const setToChain = useBestRouteStore.use.setToChain();
2475
+ const {
2476
+ navigateBackFrom
2477
+ } = useNavigateBack();
2478
+ return React.createElement(BlockchainSelector, {
2479
+ type: type === 'from' ? 'Source' : 'Destination',
2480
+ list: blockchains,
2481
+ selected: type === 'from' ? fromChain : toChain,
2482
+ loadingStatus: loadingStatus,
2483
+ onChange: chain => {
2484
+ if (type === 'from') setFromChain(chain, true);else setToChain(chain, true);
2485
+ navigateBackFrom(navigationRoutes.fromChain);
2486
+ },
2487
+ onBack: navigateBackFrom.bind(null, navigationRoutes.fromChain)
2488
+ });
2489
+ }
2490
+
2491
+ function SelectTokenPage(props) {
2492
+ const {
2493
+ navigateBackFrom
2494
+ } = useNavigateBack();
2495
+ const {
2496
+ type,
2497
+ supportedTokens
2498
+ } = props;
2499
+ const sourceTokens = useBestRouteStore.use.sourceTokens();
2500
+ const destinationTokens = useBestRouteStore.use.destinationTokens();
2501
+ const supportedSourceTokens = supportedTokens === 'all' ? sourceTokens : sourceTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2502
+ const supportedDestinationTokens = supportedTokens === 'all' ? destinationTokens : destinationTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2503
+ const fromToken = useBestRouteStore.use.fromToken();
2504
+ const toToken = useBestRouteStore.use.toToken();
2505
+ const setFromToken = useBestRouteStore.use.setFromToken();
2506
+ const setToToken = useBestRouteStore.use.setToToken();
2507
+ return React.createElement(TokenSelector, {
2508
+ type: type === 'from' ? 'Source' : 'Destination',
2509
+ list: type == 'from' ? supportedSourceTokens : supportedDestinationTokens,
2510
+ selected: type === 'from' ? fromToken : toToken,
2511
+ onChange: token => {
2512
+ if (type === 'from') setFromToken(token);else setToToken(token);
2513
+ navigateBackFrom(navigationRoutes.fromToken);
2514
+ },
2515
+ onBack: navigateBackFrom.bind(null, navigationRoutes.fromToken)
2516
+ });
2470
2517
  }
2471
2518
 
2472
- function ConfirmWalletsPage() {
2519
+ function SettingsPage(_ref) {
2520
+ let {
2521
+ supportedSwappers
2522
+ } = _ref;
2523
+ const slippage = useSettingsStore.use.slippage();
2524
+ const setSlippage = useSettingsStore.use.setSlippage();
2525
+ const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
2526
+ const customSlippage = useSettingsStore.use.customSlippage();
2527
+ const setCustomSlippage = useSettingsStore.use.setCustomSlippage();
2528
+ const theme = useSettingsStore.use.theme();
2529
+ const setTheme = useSettingsStore.use.setTheme();
2530
+ const swappers = useMetaStore.use.meta().swappers;
2473
2531
  const navigate = useNavigate();
2474
2532
  const {
2475
2533
  navigateBackFrom
2476
2534
  } = useNavigateBack();
2477
- const bestRoute = useBestRouteStore.use.bestRoute();
2535
+ const infiniteApprove = useSettingsStore.use.infiniteApprove();
2536
+ const toggleInfiniteApprove = useSettingsStore.use.toggleInfiniteApprove();
2537
+ const uniqueSwappersGroups = [];
2538
+ removeDuplicateFrom(swappers.map(s => s.swapperGroup)).map(swapperGroup => {
2539
+ return swappers.find(s => s.swapperGroup === swapperGroup);
2540
+ }).find(s => {
2541
+ if (s) {
2542
+ for (const type of s.types) {
2543
+ uniqueSwappersGroups.push({
2544
+ title: s.swapperGroup,
2545
+ logo: s.logo,
2546
+ type,
2547
+ selected: !disabledLiquiditySources.includes(s.swapperGroup)
2548
+ });
2549
+ }
2550
+ }
2551
+ });
2552
+ supportedSwappers !== 'all' && uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0);
2553
+ const supportedUniqueSwappersGroups = supportedSwappers !== 'all' ? uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0) : uniqueSwappersGroups;
2554
+ return React.createElement(Settings, {
2555
+ slippages: SLIPPAGES,
2556
+ selectedSlippage: slippage,
2557
+ onSlippageChange: slippage => setSlippage(slippage),
2558
+ onLiquiditySourcesClick: () => navigate(navigationRoutes.liquiditySources),
2559
+ onBack: navigateBackFrom.bind(null, navigationRoutes.settings),
2560
+ liquiditySources: supportedUniqueSwappersGroups,
2561
+ selectedLiquiditySources: supportedUniqueSwappersGroups.filter(s => s.selected),
2562
+ customSlippage: customSlippage || NaN,
2563
+ onCustomSlippageChange: setCustomSlippage,
2564
+ minSlippage: MIN_SLIPPGAE,
2565
+ maxSlippage: MAX_SLIPPAGE,
2566
+ selectedTheme: theme,
2567
+ onThemeChange: setTheme,
2568
+ infiniteApprove: infiniteApprove,
2569
+ toggleInfiniteApprove: toggleInfiniteApprove
2570
+ });
2571
+ }
2572
+
2573
+ const ListContainer = /*#__PURE__*/styled('div', {
2574
+ display: 'grid',
2575
+ gap: '.5rem',
2576
+ gridTemplateColumns: ' repeat(2, minmax(0, 1fr))',
2577
+ height: '450px',
2578
+ alignContent: 'baseline',
2579
+ padding: '0.5rem'
2580
+ });
2581
+ const AlertContainer = /*#__PURE__*/styled('div', {
2582
+ paddingBottom: '$16'
2583
+ });
2584
+ function WalletsPage(_ref) {
2585
+ let {
2586
+ supportedWallets,
2587
+ multiWallets
2588
+ } = _ref;
2478
2589
  const {
2479
- blockchains,
2480
- tokens
2481
- } = useMetaStore.use.meta();
2482
- const accounts = useWalletsStore.use.accounts();
2483
- const selectedWallets = useWalletsStore.use.selectedWallets();
2484
- const initSelectedWallets = useWalletsStore.use.initSelectedWallets();
2485
- const setSelectedWallet = useWalletsStore.use.setSelectedWallet();
2590
+ navigateBackFrom
2591
+ } = useNavigateBack();
2486
2592
  const {
2593
+ state,
2594
+ disconnect,
2487
2595
  getWalletInfo,
2488
2596
  connect
2489
2597
  } = useWallets();
2490
- const confirmDisabled = !requiredWallets(bestRoute).every(chain => selectedWallets.map(wallet => wallet.chain).includes(chain));
2491
- const firstStep = bestRoute?.result?.swaps[0];
2492
- const lastStep = bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1];
2493
- const fromAmount = decimalNumber(firstStep?.fromAmount, 3);
2494
- const toAmount = decimalNumber(lastStep?.toAmount, 3);
2598
+ const wallets = getlistWallet(state, getWalletInfo, supportedWallets === 'all' ? Object.values(WalletType) : supportedWallets);
2599
+ const walletsRef = useRef();
2600
+ let sortedWallets = detectMobileScreens() ? wallets.filter(wallet => wallet.showOnMobile) : wallets;
2601
+ sortedWallets = sortWalletsBasedOnState(sortedWallets);
2602
+ const [walletErrorMessage, setWalletErrorMessage] = useState('');
2603
+ const toggleConnectWalletsButton = useUiStore.use.toggleConnectWalletsButton();
2604
+ const {
2605
+ t
2606
+ } = useTranslation();
2607
+ const onSelectWallet = async type => {
2608
+ const wallet = state(type);
2609
+ try {
2610
+ if (walletErrorMessage) setWalletErrorMessage('');
2611
+ if (wallet.connected) {
2612
+ await disconnect(type);
2613
+ } else {
2614
+ if (!multiWallets && !!wallets.find(w => w.state === WalletState.CONNECTED)) {
2615
+ return;
2616
+ }
2617
+ await connect(type);
2618
+ }
2619
+ } catch (e) {
2620
+ setWalletErrorMessage('Error: ' + e?.message);
2621
+ }
2622
+ };
2623
+ const disconnectConnectingWallets = () => {
2624
+ const connectingWallets = walletsRef.current?.filter(wallet => wallet.state === WalletState.CONNECTING) || [];
2625
+ for (const wallet of connectingWallets) {
2626
+ disconnect(wallet.type);
2627
+ }
2628
+ };
2495
2629
  useEffect(() => {
2496
- initSelectedWallets();
2630
+ toggleConnectWalletsButton();
2631
+ return () => {
2632
+ disconnectConnectingWallets();
2633
+ toggleConnectWalletsButton();
2634
+ };
2497
2635
  }, []);
2498
- const selectableWallets = getSelectableWallets(accounts, selectedWallets, getWalletInfo);
2499
- const handleConnectChain = wallet => {
2500
- const network = wallet;
2501
- getKeplrCompatibleConnectedWallets(selectableWallets).forEach(compatibleWallet => connect?.(compatibleWallet, network));
2502
- };
2503
- const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
2504
- return React.createElement(ConfirmWallets, {
2505
- requiredWallets: getRequiredChains(bestRoute),
2506
- selectableWallets: selectableWallets,
2507
- onBack: navigateBackFrom.bind(null, navigationRoutes.confirmWallets),
2508
- onConfirm: () => navigate(navigationRoutes.confirmSwap, {
2509
- replace: true
2510
- }),
2511
- onChange: wallet => setSelectedWallet(wallet),
2512
- confirmDisabled: confirmDisabled,
2513
- handleConnectChain: wallet => handleConnectChain(wallet),
2514
- isExperimentalChain: wallet => getKeplrCompatibleConnectedWallets(selectableWallets).length > 0 ? isExperimentalChain(blockchains, wallet) : false,
2515
- previewInputs: React.createElement(React.Fragment, null, React.createElement(TokenPreview, {
2516
- chain: {
2517
- displayName: firstStep?.from.blockchain || '',
2518
- logo: firstStep?.from.blockchainLogo || ''
2519
- },
2520
- token: {
2521
- symbol: firstStep?.from.symbol || '',
2522
- image: firstStep?.from.logo || ''
2523
- },
2524
- usdValue: calcOutputUsdValue(fromAmount, firstStep?.from.usdPrice),
2525
- amount: fromAmount,
2526
- label: t('From'),
2527
- loadingStatus: 'success'
2528
- }), React.createElement(Spacer, {
2529
- size: 12,
2530
- direction: "vertical"
2531
- }), React.createElement(TokenPreview, {
2532
- chain: {
2533
- displayName: lastStep?.to.blockchain || '',
2534
- logo: lastStep?.to.blockchainLogo || ''
2535
- },
2536
- token: {
2537
- symbol: lastStep?.to.symbol || '',
2538
- image: lastStep?.to.logo || ''
2539
- },
2540
- usdValue: calcOutputUsdValue(toAmount, lastStep?.to.usdPrice),
2541
- amount: toAmount,
2542
- label: t('To'),
2543
- loadingStatus: 'success'
2544
- })),
2545
- previewRoutes: React.createElement(RoutesOverview, {
2546
- routes: bestRoute,
2547
- totalFee: numberToString(totalFeeInUsd, 0, 2)
2548
- })
2549
- });
2636
+ useEffect(() => {
2637
+ walletsRef.current = wallets;
2638
+ }, [wallets]);
2639
+ return React.createElement(SecondaryPage, {
2640
+ title: t('Select Wallet') || '',
2641
+ textField: false,
2642
+ onBack: navigateBackFrom.bind(null, navigationRoutes.wallets)
2643
+ }, React.createElement(React.Fragment, null, walletErrorMessage && React.createElement(AlertContainer, null, React.createElement(Alert, {
2644
+ type: "error"
2645
+ }, walletErrorMessage)), React.createElement(ListContainer, null, sortedWallets.map((wallet, index) => React.createElement(Wallet, Object.assign({}, wallet, {
2646
+ key: `${index}-${wallet.type}`,
2647
+ onClick: onSelectWallet
2648
+ }))))));
2550
2649
  }
2551
2650
 
2552
2651
  function useCopyToClipboard(resetInterval) {
@@ -2567,15 +2666,60 @@ function useCopyToClipboard(resetInterval) {
2567
2666
  return [isCopied, handleCopy];
2568
2667
  }
2569
2668
 
2669
+ function timeSince(timeMillis) {
2670
+ const seconds = Math.floor((new Date().getTime() - timeMillis) / 1000);
2671
+ let intervalType;
2672
+ let interval = Math.floor(seconds / 31536000);
2673
+ if (interval >= 1) {
2674
+ intervalType = 'year';
2675
+ } else {
2676
+ interval = Math.floor(seconds / 2592000);
2677
+ if (interval >= 1) {
2678
+ intervalType = 'month';
2679
+ } else {
2680
+ interval = Math.floor(seconds / 86400);
2681
+ if (interval >= 1) {
2682
+ intervalType = 'day';
2683
+ } else {
2684
+ interval = Math.floor(seconds / 3600);
2685
+ if (interval >= 1) {
2686
+ intervalType = 'hour';
2687
+ } else {
2688
+ interval = Math.floor(seconds / 60);
2689
+ if (interval >= 1) {
2690
+ intervalType = 'minute';
2691
+ } else {
2692
+ interval = seconds;
2693
+ intervalType = 'second';
2694
+ }
2695
+ }
2696
+ }
2697
+ }
2698
+ }
2699
+ if (interval > 1 || interval === 0) {
2700
+ intervalType += 's';
2701
+ }
2702
+ return interval + ' ' + intervalType;
2703
+ }
2704
+ function getSwapDate(pendingSwap) {
2705
+ return pendingSwap.finishTime ? `Finished ${timeSince(parseInt(pendingSwap.finishTime))} ago @ ${new Date(parseInt(pendingSwap.finishTime)).toLocaleString()}` : `Started ${timeSince(parseInt(pendingSwap.creationTime))} ago @ ${new Date(parseInt(pendingSwap.creationTime)).toLocaleString()}`;
2706
+ }
2707
+
2570
2708
  function SwapDetailsPage() {
2571
2709
  const selectedSwapRequestId = useUiStore.use.selectedSwapRequestId();
2710
+ const {
2711
+ canSwitchNetworkTo,
2712
+ connect
2713
+ } = useWallets();
2714
+ const retry = useBestRouteStore.use.retry();
2715
+ const navigate = useNavigate();
2572
2716
  const {
2573
2717
  navigateBackFrom
2574
2718
  } = useNavigateBack();
2719
+ const [isCopied, handleCopy] = useCopyToClipboard(2000);
2575
2720
  const {
2576
2721
  manager
2577
2722
  } = useManager();
2578
- const [isCopied, handleCopy] = useCopyToClipboard(2000);
2579
2723
  const pendingSwaps = getPendingSwaps(manager);
2580
2724
  const selectedSwap = pendingSwaps.find(_ref => {
2581
2725
  let {
@@ -2583,20 +2727,50 @@ function SwapDetailsPage() {
2583
2727
  } = _ref;
2584
2728
  return swap.requestId === selectedSwapRequestId;
2585
2729
  });
2586
- //TODO: implement swap cancellation (move queueManager logic to queueManager/rango-preset)
2587
2730
  const onCancel = () => {
2588
- const swap = selectedSwap ? manager?.get(selectedSwap.id) : undefined;
2731
+ const swap = manager?.get(selectedSwap?.id);
2589
2732
  if (swap) cancelSwap(swap);
2590
2733
  };
2591
- return React.createElement(SwapHistory, {
2734
+ const swap = selectedSwap?.swap;
2735
+ if (!swap) return null;
2736
+ const currentStep = getCurrentStep(swap);
2737
+ const currentStepBlockchain = currentStep ? getCurrentBlockchainOfOrNull(swap, currentStep) : null;
2738
+ const currentStepWallet = currentStep ? getRelatedWalletOrNull(swap, currentStep) : null;
2739
+ const currentStepNetworkStatus = currentStep?.networkStatus;
2740
+ const swapMessages = getSwapMessages(swap, currentStep);
2741
+ const networkWarningState = isNetworkStatusInWarningState(currentStep);
2742
+ const swapDate = getSwapDate(swap);
2743
+ const shouldRetry = shouldRetrySwap(swap);
2744
+ const switchNetwork = !!currentStepBlockchain && !!currentStepWallet?.walletType && currentStepNetworkStatus === PendingSwapNetworkStatus.WaitingForNetworkChange && canSwitchNetworkTo(currentStepWallet?.walletType, currentStepBlockchain) ? connect.bind(null, currentStepWallet.walletType, currentStepBlockchain) : undefined;
2745
+ const lastConvertedTokenInFailedSwap = getLastConvertedTokenInFailedSwap(swap);
2746
+ return React.createElement(SwapHistory, Object.assign({
2592
2747
  onBack: navigateBackFrom.bind(null, navigationRoutes.swapDetails),
2593
2748
  //todo: move PendingSwap type to rango-types
2594
2749
  //@ts-ignore
2595
- pendingSwap: selectedSwap?.swap,
2750
+ pendingSwap: swap,
2596
2751
  onCopy: handleCopy,
2597
2752
  isCopied: isCopied,
2598
- onCancel: onCancel
2599
- });
2753
+ onCancel: onCancel,
2754
+ shortMessage: swapMessages.shortMessage,
2755
+ detailedMessage: swapMessages.detailedMessage,
2756
+ currentStepBlockchain: currentStepBlockchain || '',
2757
+ switchNetwork: switchNetwork,
2758
+ type: networkWarningState ? 'warning' : swap.extraMessageSeverity || undefined,
2759
+ date: swapDate
2760
+ }, shouldRetry && {
2761
+ onRetry: () => {
2762
+ retry(swap);
2763
+ setTimeout(() => {
2764
+ navigate(navigationRoutes.home);
2765
+ }, 0);
2766
+ }
2767
+ }, lastConvertedTokenInFailedSwap && {
2768
+ lastConvertedTokenInFailedSwap: {
2769
+ blockchain: lastConvertedTokenInFailedSwap.blockchain,
2770
+ outputAmount: lastConvertedTokenInFailedSwap.outputAmount,
2771
+ symbol: lastConvertedTokenInFailedSwap.symbol
2772
+ }
2773
+ }));
2600
2774
  }
2601
2775
 
2602
2776
  function AppRoutes(props) {
@@ -2659,9 +2833,6 @@ function AppRoutes(props) {
2659
2833
  }, {
2660
2834
  path: navigationRoutes.confirmSwap,
2661
2835
  element: React.createElement(ConfirmSwapPage, null)
2662
- }, {
2663
- path: navigationRoutes.confirmWallets,
2664
- element: React.createElement(ConfirmWalletsPage, null)
2665
2836
  }]);
2666
2837
  }
2667
2838
 
@@ -2712,6 +2883,12 @@ function Layout(_ref) {
2712
2883
  setFromToken(configs?.fromToken || null);
2713
2884
  setFromChain(configs?.fromChain || null);
2714
2885
  }, [configs?.fromToken, configs?.fromChain]);
2886
+ useEffect(() => {
2887
+ setToChain(null);
2888
+ setFromChain(null);
2889
+ setFromToken(null);
2890
+ setToToken(null);
2891
+ }, [configs?.fromChains, configs?.toChains, configs?.fromTokens, configs?.toTokens]);
2715
2892
  return React.createElement(React.Fragment, null, React.createElement(Header$1, null, React.createElement(Button, {
2716
2893
  size: "small",
2717
2894
  suffix: React.createElement(AddWalletIcon, {
@@ -2979,7 +3156,7 @@ function QueueManager(props) {
2979
3156
  };
2980
3157
  // TODO: this code copy & pasted from rango, should be refactored.
2981
3158
  const allBlockchains = blockchains.filter(blockchain => blockchain.enabled).reduce((blockchainsObj, blockchain) => (blockchainsObj[blockchain.name] = blockchain, blockchainsObj), {});
2982
- const evmBasedChains = blockchains.filter(isEvmBlockchain);
3159
+ const evmBasedChains = blockchains.filter(isEvmBlockchain$1);
2983
3160
  const getSupportedChainNames = type => {
2984
3161
  const {
2985
3162
  supportedChains
@@ -3012,7 +3189,9 @@ function QueueManager(props) {
3012
3189
  //@ts-ignore
3013
3190
  queuesDefs: [swapQueueDef],
3014
3191
  context: context,
3015
- onPersistedDataLoaded: _manager => {},
3192
+ onPersistedDataLoaded: manager => {
3193
+ checkWaitingForNetworkChange(manager);
3194
+ },
3016
3195
  isPaused: false
3017
3196
  }, props.children);
3018
3197
  }
@@ -3040,8 +3219,10 @@ const SwapBox = _ref => {
3040
3219
  changeLanguage
3041
3220
  } = useSelectLanguage();
3042
3221
  const clearConnectedWallet = useWalletsStore.use.clearConnectedWallet();
3043
- const evmBasedChainNames = blockchains.filter(isEvmBlockchain).map(chain => chain.name);
3044
- const onUpdateState = (type, event, value, _, supportedChains) => {
3222
+ const [lastConnectedWalletWithNetwork, setLastConnectedWalletWithNetwork] = useState('');
3223
+ const [disconnectedWallet, setDisconnectedWallet] = useState();
3224
+ const evmBasedChainNames = blockchains.filter(isEvmBlockchain$1).map(chain => chain.name);
3225
+ const onUpdateState = (type, event, value, state, supportedChains) => {
3045
3226
  if (event === Events.ACCOUNTS) {
3046
3227
  if (value) {
3047
3228
  const supportedChainNames = walletAndSupportedChainsNames(supportedChains);
@@ -3051,6 +3232,16 @@ const SwapBox = _ref => {
3051
3232
  disconnectWallet(type);
3052
3233
  }
3053
3234
  }
3235
+ if (event === Events.ACCOUNTS && state.connected) {
3236
+ const key = `${type}-${state.network}-${value}`;
3237
+ if (state.connected) {
3238
+ setLastConnectedWalletWithNetwork(key);
3239
+ }
3240
+ }
3241
+ if (event === Events.NETWORK && state.network) {
3242
+ const key = `${type}-${state.network}`;
3243
+ setLastConnectedWalletWithNetwork(key);
3244
+ }
3054
3245
  };
3055
3246
  let providers = allProviders();
3056
3247
  useEffect(() => {
@@ -3082,7 +3273,12 @@ const SwapBox = _ref => {
3082
3273
  }, React.createElement(AppRouter, {
3083
3274
  title: configs.title,
3084
3275
  titleSize: configs.titleSize,
3085
- titleWeight: configs.titleWeight
3276
+ titleWeight: configs.titleWeight,
3277
+ lastConnectedWallet: lastConnectedWalletWithNetwork,
3278
+ disconnectedWallet: disconnectedWallet,
3279
+ clearDisconnectedWallet: () => {
3280
+ setDisconnectedWallet(undefined);
3281
+ }
3086
3282
  }, React.createElement(Layout, {
3087
3283
  configs: configs
3088
3284
  }))))));