@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
@@ -8,12 +8,13 @@ var ui = require('@rango-dev/ui');
8
8
  var React = require('react');
9
9
  var React__default = _interopDefault(React);
10
10
  var reactRouter = require('react-router');
11
+ var queueManagerRangoPreset = require('@rango-dev/queue-manager-rango-preset');
12
+ var rangoTypes = require('rango-types');
11
13
  var reactRouterDom = require('react-router-dom');
12
14
  var zustand = require('zustand');
13
15
  var BigNumber = require('bignumber.js');
14
16
  var BigNumber__default = _interopDefault(BigNumber);
15
17
  var walletsShared = require('@rango-dev/wallets-shared');
16
- var rangoTypes = require('rango-types');
17
18
  var walletsCore = require('@rango-dev/wallets-core');
18
19
  var middleware = require('zustand/middleware');
19
20
  var rangoSdk = require('rango-sdk');
@@ -21,11 +22,10 @@ var shallow = require('zustand/shallow');
21
22
  var reactI18next = require('react-i18next');
22
23
  var theme = require('@rango-dev/ui/src/theme');
23
24
  var providerAll = require('@rango-dev/provider-all');
24
- var queueManagerReact = require('@rango-dev/queue-manager-react');
25
25
  var i18n = require('i18next');
26
26
  var i18n__default = _interopDefault(i18n);
27
+ var queueManagerReact = require('@rango-dev/queue-manager-react');
27
28
  var copy = _interopDefault(require('copy-to-clipboard'));
28
- var queueManagerRangoPreset = require('@rango-dev/queue-manager-rango-preset');
29
29
  var Backend = _interopDefault(require('i18next-http-backend'));
30
30
  var LanguageDetector = _interopDefault(require('i18next-browser-languagedetector'));
31
31
 
@@ -40,7 +40,6 @@ const navigationRoutes = {
40
40
  swaps: '/swaps',
41
41
  wallets: '/wallets',
42
42
  confirmSwap: '/confirm-swap',
43
- confirmWallets: '/confirm-wallets',
44
43
  swapDetails: '/swaps/:requestId'
45
44
  };
46
45
 
@@ -70,6 +69,22 @@ function shadeColor(color, percent) {
70
69
  var BB = B.toString(16).length == 1 ? '0' + B.toString(16) : B.toString(16);
71
70
  return '#' + RR + GG + BB;
72
71
  }
72
+ function debounce(fn, time) {
73
+ let timeoutId;
74
+ return wrapper;
75
+ function wrapper() {
76
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
77
+ args[_key] = arguments[_key];
78
+ }
79
+ if (timeoutId) {
80
+ clearTimeout(timeoutId);
81
+ }
82
+ timeoutId = setTimeout(() => {
83
+ timeoutId = null;
84
+ fn(...args);
85
+ }, time);
86
+ }
87
+ }
73
88
 
74
89
  const secondsToString = s => {
75
90
  const seconds = (s % 60).toString().padStart(2, '0');
@@ -336,7 +351,7 @@ function getSortedTokens(chain, tokens, balances, otherChainTokens) {
336
351
  return sortTokens(getTokensWithBalance(filteredTokens, balances));
337
352
  }
338
353
  function tokensAreEqual(tokenA, tokenB) {
339
- return tokenA?.blockchain === tokenB?.blockchain && tokenA?.name === tokenB?.name && tokenA?.address === tokenB?.address;
354
+ return tokenA?.blockchain === tokenB?.blockchain && tokenA?.symbol === tokenB?.symbol && tokenA?.address === tokenB?.address;
340
355
  }
341
356
  function getDefaultToken(sortedTokens, otherToken) {
342
357
  let selectedToken;
@@ -462,6 +477,7 @@ function calculatePendingSwap(inputAmount, bestRoute, wallets, settings, validat
462
477
  finishTime: null,
463
478
  requestId: bestRoute.requestId || '',
464
479
  inputAmount: inputAmount,
480
+ //@ts-ignore
465
481
  wallets,
466
482
  status: 'running',
467
483
  isPaused: false,
@@ -476,6 +492,7 @@ function calculatePendingSwap(inputAmount, bestRoute, wallets, settings, validat
476
492
  settings: settings,
477
493
  simulationResult: simulationResult,
478
494
  validateBalanceOrFee,
495
+ //@ts-ignore
479
496
  steps: bestRoute.result?.swaps?.map((swap, index) => {
480
497
  const swapper = meta.swappers.find(swapper => swapper.id === swap.swapperId);
481
498
  const swapperType = swapper?.types[0];
@@ -561,11 +578,10 @@ function hasHighFee(totalFeeInUsd) {
561
578
  }
562
579
  function getMinRequiredSlippage(route) {
563
580
  const slippages = route.result?.swaps.map(slippage => slippage.recommendedSlippage);
564
- return slippages?.map(s => parseFloat(s?.slippage || '0'))?.filter(s => s > 0)?.sort((a, b) => b - a)?.find(() => true) || null;
581
+ return slippages?.map(s => s?.slippage || '0')?.filter(s => parseFloat(s) > 0)?.sort((a, b) => parseFloat(b) - parseFloat(a))?.find(() => true) || null;
565
582
  }
566
583
  function hasProperSlippage(userSlippage, minRequiredSlippage) {
567
584
  if (!minRequiredSlippage) return true;
568
- //@ts-ignore
569
585
  return parseFloat(userSlippage) >= parseFloat(minRequiredSlippage);
570
586
  }
571
587
  function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, selectedWallets, disabledLiquiditySources, slippage, checkPrerequisites) {
@@ -642,6 +658,61 @@ function calcOutputUsdValue(outputAmount, tokenPrice) {
642
658
  const amount = !!outputAmount ? new BigNumber__default(outputAmount) : ZERO;
643
659
  return amount.multipliedBy(tokenPrice || 0);
644
660
  }
661
+ function isNetworkStatusInWarningState(pendingSwapStep) {
662
+ return !!pendingSwapStep && pendingSwapStep.networkStatus !== null && pendingSwapStep.networkStatus !== queueManagerRangoPreset.PendingSwapNetworkStatus.NetworkChanged;
663
+ }
664
+ function getSwapMessages(pendingSwap, currentStep) {
665
+ const textForRemove = 'bellow button or';
666
+ let message = pendingSwap.extraMessage;
667
+ let detailedMessage = pendingSwap.extraMessageDetail;
668
+ if (pendingSwap.networkStatusExtraMessageDetail?.includes(textForRemove)) {
669
+ pendingSwap.networkStatusExtraMessageDetail = pendingSwap.networkStatusExtraMessageDetail.replace(textForRemove, '');
670
+ }
671
+ const networkWarningState = isNetworkStatusInWarningState(currentStep);
672
+ if (networkWarningState) {
673
+ message = pendingSwap.networkStatusExtraMessage || '';
674
+ detailedMessage = pendingSwap.networkStatusExtraMessageDetail || '';
675
+ switch (currentStep?.networkStatus) {
676
+ case queueManagerRangoPreset.PendingSwapNetworkStatus.WaitingForConnectingWallet:
677
+ message = message || 'Waiting for connecting wallet';
678
+ break;
679
+ case queueManagerRangoPreset.PendingSwapNetworkStatus.WaitingForQueue:
680
+ message = message || 'Waiting for other running tasks to be finished';
681
+ break;
682
+ case queueManagerRangoPreset.PendingSwapNetworkStatus.WaitingForNetworkChange:
683
+ message = message || 'Waiting for changing wallet network';
684
+ break;
685
+ }
686
+ }
687
+ detailedMessage = detailedMessage || '';
688
+ message = message || '';
689
+ const isRpc = message?.indexOf('code') !== -1 && message?.indexOf('reason') !== -1;
690
+ return {
691
+ shortMessage: message,
692
+ detailedMessage: {
693
+ content: detailedMessage,
694
+ long: isRpc
695
+ }
696
+ };
697
+ }
698
+ function getLastConvertedTokenInFailedSwap(pendingSwap) {
699
+ let resultToken = null;
700
+ if (pendingSwap.status === 'failed') {
701
+ const lastSuccessStep = pendingSwap.steps.slice().reverse().filter(step => step.status === 'success')[0];
702
+ if (lastSuccessStep) {
703
+ resultToken = {
704
+ blockchain: lastSuccessStep.toBlockchain,
705
+ symbol: lastSuccessStep.toSymbol,
706
+ outputAmount: lastSuccessStep.outputAmount,
707
+ address: lastSuccessStep.toSymbolAddress
708
+ };
709
+ }
710
+ }
711
+ return resultToken;
712
+ }
713
+ function shouldRetrySwap(pendingSwap) {
714
+ return pendingSwap.status === 'failed' && !!pendingSwap.finishTime && new Date().getTime() - parseInt(pendingSwap.finishTime) < 4 * 3600 * 1000;
715
+ }
645
716
 
646
717
  function searchParamsToToken(tokens, searchParams, chain) {
647
718
  if (!chain) return null;
@@ -681,20 +752,6 @@ function getRequiredBalanceOfWallet(selectedWallet, fee) {
681
752
  function isRouteParametersChanged(prevParams, currentParams) {
682
753
  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;
683
754
  }
684
- function getBestRouteWithCalculatedFees(bestRoute, tokens) {
685
- if (!bestRoute || !bestRoute.result) return null;
686
- const swapsWithFee = (bestRoute?.result?.swaps || []).map(swap => ({
687
- ...swap,
688
- feeInUsd: numberToString(getUsdFeeOfStep(swap, tokens), 0, 2)
689
- }));
690
- return {
691
- ...bestRoute,
692
- result: {
693
- ...bestRoute.result,
694
- swaps: swapsWithFee
695
- }
696
- };
697
- }
698
755
 
699
756
  const createSelectors = _store => {
700
757
  let store = _store;
@@ -963,11 +1020,52 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.cre
963
1020
  inputUsdValue: getUsdValue(state.fromToken, amount)
964
1021
  })
965
1022
  }));
1023
+ },
1024
+ retry: pendingSwap => {
1025
+ const {
1026
+ tokens,
1027
+ blockchains
1028
+ } = useMetaStore.getState().meta;
1029
+ const balances = useWalletsStore.getState().balances;
1030
+ const failedIndex = pendingSwap.status === 'failed' ? pendingSwap.steps.findIndex(s => s.status === 'failed') : null;
1031
+ if (failedIndex === null || failedIndex < 0) return;
1032
+ const firstStep = pendingSwap.steps[0];
1033
+ const lastStep = pendingSwap.steps[pendingSwap.steps.length - 1];
1034
+ const fromChain = blockchains.find(blockchain => blockchain.name === firstStep.fromBlockchain) || null;
1035
+ const toChain = blockchains.find(blockchain => blockchain.name === lastStep.toBlockchain) || null;
1036
+ const fromToken = tokens.find(token => tokensAreEqual(token, {
1037
+ blockchain: firstStep.fromBlockchain,
1038
+ symbol: firstStep.fromSymbol,
1039
+ address: firstStep.fromSymbolAddress
1040
+ }));
1041
+ const toToken = tokens.find(token => tokensAreEqual(token, {
1042
+ blockchain: lastStep.toBlockchain,
1043
+ symbol: lastStep.toSymbol,
1044
+ address: lastStep.toSymbolAddress
1045
+ }));
1046
+ const sortedSourceTokens = getSortedTokens(fromChain, tokens, balances, []);
1047
+ const sortedDestinationTokens = getSortedTokens(toChain, tokens, balances, []);
1048
+ const inputAmount = pendingSwap.inputAmount;
1049
+ set({
1050
+ fromChain,
1051
+ fromToken,
1052
+ inputAmount,
1053
+ outputAmount: null,
1054
+ inputUsdValue: new BigNumber__default(0),
1055
+ outputUsdValue: new BigNumber__default(0),
1056
+ toChain,
1057
+ toToken,
1058
+ bestRoute: null,
1059
+ loading: false,
1060
+ error: '',
1061
+ sourceTokens: sortedSourceTokens,
1062
+ destinationTokens: sortedDestinationTokens
1063
+ });
966
1064
  }
967
1065
  }))));
968
1066
  const bestRoute = (bestRouteStore, settingsStore) => {
969
1067
  let abortController = null;
970
- const fetchBestRoute = () => {
1068
+ const fetchBestRoute = debounce(() => {
971
1069
  const {
972
1070
  fromToken,
973
1071
  toToken,
@@ -1007,7 +1105,7 @@ const bestRoute = (bestRouteStore, settingsStore) => {
1007
1105
  loading: false
1008
1106
  });
1009
1107
  });
1010
- };
1108
+ }, 600);
1011
1109
  useBestRouteStore.subscribe(state => ({
1012
1110
  fromChain: state.fromChain,
1013
1111
  fromToken: state.fromToken,
@@ -1093,7 +1191,7 @@ function UpdateUrl() {
1093
1191
  toChainString = '',
1094
1192
  toTokenString = '',
1095
1193
  fromAmount = '';
1096
- if (loadingStatus !== 'success' && ![navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname)) {
1194
+ if (loadingStatus !== 'success' && location.pathname != navigationRoutes.confirmSwap) {
1097
1195
  fromChainString = searchParamsRef.current[SearchParams.FROM_CHAIN];
1098
1196
  fromTokenString = searchParamsRef.current[SearchParams.FROM_TOKEN];
1099
1197
  toChainString = searchParamsRef.current[SearchParams.TO_CHAIN];
@@ -1656,7 +1754,7 @@ function Home(props) {
1656
1754
  disabled: swapButtonState.disabled,
1657
1755
  onClick: () => {
1658
1756
  if (swapButtonState.title === 'Connect Wallet') navigate(navigationRoutes.wallets);else {
1659
- navigate(navigationRoutes.confirmWallets, {
1757
+ navigate(navigationRoutes.confirmSwap, {
1660
1758
  replace: true
1661
1759
  });
1662
1760
  }
@@ -1673,12 +1771,12 @@ const Route = _ref => {
1673
1771
  const navigate = reactRouter.useNavigate();
1674
1772
  const ref = React.useRef(true);
1675
1773
  React.useEffect(() => {
1676
- if ([navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname) && ref.current) navigate(navigationRoutes.home + location.search, {
1774
+ if (location.pathname === navigationRoutes.confirmSwap && ref.current) navigate(navigationRoutes.home + location.search, {
1677
1775
  state: 'redirect'
1678
1776
  });
1679
1777
  ref.current = false;
1680
1778
  }, []);
1681
- if ([navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname) && ref.current) return React__default.createElement(Home, Object.assign({}, props));
1779
+ if (location.pathname === navigationRoutes.confirmSwap && ref.current) return React__default.createElement(Home, Object.assign({}, props));
1682
1780
  return React__default.createElement(React__default.Fragment, null, " ", children);
1683
1781
  };
1684
1782
  function AppRouter(_ref2) {
@@ -1688,52 +1786,34 @@ function AppRouter(_ref2) {
1688
1786
  } = _ref2;
1689
1787
  const isRouterInContext = reactRouter.useInRouterContext();
1690
1788
  const Router = isRouterInContext ? Route : reactRouter.MemoryRouter;
1691
- return React__default.createElement(React__default.Fragment, null, React__default.createElement(Router, Object.assign({}, props), children), isRouterInContext && React__default.createElement(UpdateUrl, null));
1692
- }
1693
-
1694
- function ChangeSlippageButton() {
1695
- const navigate = reactRouterDom.useNavigate();
1696
- return React__default.createElement(ui.Button, {
1697
- type: "primary",
1698
- variant: "outlined",
1699
- size: "small",
1700
- onClick: () => navigate(navigationRoutes.settings)
1701
- }, "Change Slippage");
1702
- }
1703
-
1704
- function HighSlippageWarning(props) {
1705
- const {
1706
- selectedSlippage
1707
- } = props;
1708
- return React__default.createElement(ui.Alert, {
1709
- type: "warning",
1710
- footer: React__default.createElement(ChangeSlippageButton, null)
1711
- }, "Caution, your slippage is high (=", selectedSlippage, "). Your trade may be front run.");
1712
- }
1713
-
1714
- function ConfirmSwapExtraMessages(props) {
1715
1789
  const {
1716
- selectedSlippage
1717
- } = props;
1718
- const highSlippage = selectedSlippage >= HIGH_SLIPPAGE;
1719
- return React__default.createElement(React__default.Fragment, null, highSlippage && React__default.createElement(HighSlippageWarning, {
1720
- selectedSlippage: selectedSlippage
1721
- }));
1790
+ blockchains
1791
+ } = useMetaStore.use.meta();
1792
+ const evmChains = blockchains.filter(rangoTypes.isEvmBlockchain);
1793
+ queueManagerRangoPreset.useQueueManager({
1794
+ lastConnectedWallet: props.lastConnectedWallet,
1795
+ clearDisconnectedWallet: props.clearDisconnectedWallet,
1796
+ disconnectedWallet: props.disconnectedWallet,
1797
+ evmChains,
1798
+ notifier: () => {}
1799
+ });
1800
+ return React__default.createElement(React__default.Fragment, null, React__default.createElement(Router, Object.assign({}, props), children), isRouterInContext && React__default.createElement(UpdateUrl, null));
1722
1801
  }
1723
1802
 
1724
1803
  function useNavigateBack() {
1725
1804
  const isRouterInContext = reactRouterDom.useInRouterContext();
1726
1805
  const navigate = reactRouterDom.useNavigate();
1727
1806
  const navigateBackFrom = currentRoute => {
1807
+ if (currentRoute === navigationRoutes.swapDetails) return navigate(navigationRoutes.swaps, {
1808
+ replace: true
1809
+ });
1728
1810
  if (!isRouterInContext || window.history.state && window.history.state.idx > 0) navigate(-1);else {
1729
- if ([navigationRoutes.fromChain, navigationRoutes.fromToken, navigationRoutes.toChain, navigationRoutes.toToken, navigationRoutes.settings, navigationRoutes.wallets, navigationRoutes.swaps, navigationRoutes.confirmWallets].includes(currentRoute)) navigate(navigationRoutes.home, {
1811
+ if ([navigationRoutes.fromChain, navigationRoutes.fromToken, navigationRoutes.toChain, navigationRoutes.toToken, navigationRoutes.settings, navigationRoutes.wallets, navigationRoutes.swaps, navigationRoutes.confirmSwap].includes(currentRoute)) navigate(navigationRoutes.home, {
1730
1812
  replace: true
1731
1813
  });else if (currentRoute === navigationRoutes.liquiditySources) navigate(navigationRoutes.settings, {
1732
1814
  replace: true
1733
1815
  });else if (currentRoute === navigationRoutes.swapDetails) navigate(navigationRoutes.swaps, {
1734
1816
  replace: true
1735
- });else if (currentRoute === navigationRoutes.confirmSwap) navigate(navigationRoutes.confirmWallets, {
1736
- replace: true
1737
1817
  });
1738
1818
  }
1739
1819
  };
@@ -1742,6 +1822,176 @@ function useNavigateBack() {
1742
1822
  };
1743
1823
  }
1744
1824
 
1825
+ const Box$1 = /*#__PURE__*/ui.styled('div', {
1826
+ display: 'flex',
1827
+ flexDirection: 'column',
1828
+ width: '100%'
1829
+ });
1830
+ const Container$3 = /*#__PURE__*/ui.styled('div', {
1831
+ boxSizing: 'border-box',
1832
+ borderRadius: '$5',
1833
+ padding: '$8 $16 $16 $16',
1834
+ variants: {
1835
+ type: {
1836
+ filled: {
1837
+ backgroundColor: '$neutrals300'
1838
+ },
1839
+ outlined: {
1840
+ border: '1px solid $neutrals300'
1841
+ }
1842
+ }
1843
+ },
1844
+ defaultVariants: {
1845
+ type: 'filled'
1846
+ },
1847
+ '.head': {
1848
+ display: 'flex',
1849
+ justifyContent: 'space-between',
1850
+ alignItems: 'center',
1851
+ minHeight: '32px'
1852
+ },
1853
+ '.form': {
1854
+ display: 'flex',
1855
+ width: '100%',
1856
+ padding: '$2 0',
1857
+ '.selectors': {
1858
+ width: '35%',
1859
+ '._text': {
1860
+ whiteSpace: 'nowrap',
1861
+ overflow: 'hidden',
1862
+ textOverflow: 'ellipsis'
1863
+ }
1864
+ },
1865
+ '.amount': {
1866
+ width: '30%'
1867
+ }
1868
+ }
1869
+ });
1870
+ const StyledImage$1 = /*#__PURE__*/ui.styled('img', {
1871
+ width: '$24',
1872
+ maxHeight: '$24'
1873
+ });
1874
+ const ImagePlaceholder$1 = /*#__PURE__*/ui.styled('span', {
1875
+ width: '24px',
1876
+ height: '24px',
1877
+ backgroundColor: '$neutrals300',
1878
+ borderRadius: '99999px'
1879
+ });
1880
+ const OutputContainer$1 = /*#__PURE__*/ui.styled('div', {
1881
+ windth: '100%',
1882
+ height: '$48',
1883
+ borderRadius: '$5',
1884
+ backgroundColor: '$background',
1885
+ border: '1px solid transparent',
1886
+ position: 'relative',
1887
+ display: 'flex',
1888
+ alignItems: 'center',
1889
+ paddingLeft: '$8',
1890
+ paddingRight: '$8'
1891
+ });
1892
+ function TokenPreview(props) {
1893
+ const {
1894
+ chain,
1895
+ token,
1896
+ loadingStatus
1897
+ } = props;
1898
+ const {
1899
+ t
1900
+ } = reactI18next.useTranslation();
1901
+ const ItemSuffix = React__default.createElement("div", {
1902
+ style: {
1903
+ display: 'flex',
1904
+ justifyContent: 'center',
1905
+ alignItems: 'center'
1906
+ }
1907
+ }, loadingStatus === 'failed' && React__default.createElement(ui.InfoCircleIcon, {
1908
+ color: "error",
1909
+ size: 24
1910
+ }));
1911
+ return React__default.createElement(Box$1, null, React__default.createElement(Container$3, {
1912
+ type: 'outlined'
1913
+ }, React__default.createElement("div", {
1914
+ className: "head"
1915
+ }, React__default.createElement(ui.Typography, {
1916
+ variant: "body2",
1917
+ color: "neutrals800"
1918
+ }, props.label), React__default.createElement(ui.Typography, {
1919
+ variant: "caption",
1920
+ color: "neutrals600"
1921
+ }, `$${numberToString(props.usdValue)}`)), React__default.createElement("div", {
1922
+ className: "form"
1923
+ }, React__default.createElement(ui.Button, {
1924
+ className: "selectors",
1925
+ variant: "outlined",
1926
+ loading: loadingStatus === 'loading',
1927
+ prefix: loadingStatus === 'success' && chain ? React__default.createElement(StyledImage$1, {
1928
+ src: chain.logo
1929
+ }) : React__default.createElement(ImagePlaceholder$1, null),
1930
+ suffix: ItemSuffix,
1931
+ align: "start",
1932
+ size: "large"
1933
+ }, loadingStatus === 'success' && chain ? chain.displayName : t('Chain')), React__default.createElement(ui.Spacer, {
1934
+ size: 12
1935
+ }), React__default.createElement(ui.Button, {
1936
+ className: "selectors",
1937
+ variant: "outlined",
1938
+ loading: loadingStatus === 'loading',
1939
+ prefix: loadingStatus === 'success' && token ? React__default.createElement(StyledImage$1, {
1940
+ src: token.image
1941
+ }) : React__default.createElement(ImagePlaceholder$1, null),
1942
+ suffix: ItemSuffix,
1943
+ size: "large",
1944
+ align: "start"
1945
+ }, loadingStatus === 'success' && token ? token.symbol : t('Token')), React__default.createElement(ui.Spacer, {
1946
+ size: 12
1947
+ }), React__default.createElement("div", {
1948
+ className: "amount"
1949
+ }, React__default.createElement(OutputContainer$1, null, React__default.createElement(ui.Typography, {
1950
+ variant: "h4"
1951
+ }, props.amount))))));
1952
+ }
1953
+
1954
+ const Container$4 = /*#__PURE__*/ui.styled('div', {
1955
+ display: 'flex',
1956
+ alignItems: 'center',
1957
+ justifyContent: 'space-between',
1958
+ padding: '$8',
1959
+ borderRadius: '$5',
1960
+ backgroundColor: '$neutrals300',
1961
+ color: '$neutrals800',
1962
+ fontSize: '$12',
1963
+ '.routes': {
1964
+ display: 'flex',
1965
+ alignItems: 'center'
1966
+ },
1967
+ '.fee': {
1968
+ display: 'flex',
1969
+ alignItems: 'center'
1970
+ }
1971
+ });
1972
+ function RoutesOverview(props) {
1973
+ if (!props.routes) return null;
1974
+ const swaps = props.routes.result?.swaps;
1975
+ return React__default.createElement(Container$4, null, React__default.createElement("div", {
1976
+ className: "routes"
1977
+ }, swaps?.map((swap, idx) => {
1978
+ const isLast = idx + 1 == swaps.length;
1979
+ return React__default.createElement(React__default.Fragment, null, React__default.createElement("div", {
1980
+ className: "route"
1981
+ }, swap.from.symbol), React__default.createElement(ui.ChevronRightIcon, {
1982
+ size: 12
1983
+ }), isLast ? React__default.createElement("div", {
1984
+ className: "route"
1985
+ }, swap.to.symbol) : null);
1986
+ })), props.totalFee ? React__default.createElement("div", {
1987
+ className: "fee"
1988
+ }, React__default.createElement(ui.GasIcon, {
1989
+ size: 12
1990
+ }), React__default.createElement(ui.Spacer, {
1991
+ size: 4
1992
+ }), "$", props.totalFee) : null);
1993
+ }
1994
+
1745
1995
  var ConfirmSwapErrorTypes;
1746
1996
  (function (ConfirmSwapErrorTypes) {
1747
1997
  ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["NO_ROUTE"] = 0] = "NO_ROUTE";
@@ -1758,106 +2008,6 @@ var ConfirmSwapWarningTypes;
1758
2008
  ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["INSUFFICIENT_BALANCE"] = 4] = "INSUFFICIENT_BALANCE";
1759
2009
  })(ConfirmSwapWarningTypes || (ConfirmSwapWarningTypes = {}));
1760
2010
 
1761
- function MinRequiredSlippage(_ref) {
1762
- let {
1763
- minRequiredSlippage
1764
- } = _ref;
1765
- return React__default.createElement(ui.Typography, {
1766
- variant: "body2"
1767
- }, "We recommend you to increase slippage to at least \u00A0", minRequiredSlippage, "\u00A0 for this route.", React__default.createElement(ChangeSlippageButton, null));
1768
- }
1769
-
1770
- function ConfirmSwapErrors(errors) {
1771
- return errors.flatMap(error => {
1772
- switch (error.type) {
1773
- case ConfirmSwapErrorTypes.NO_ROUTE:
1774
- return React__default.createElement(ui.Typography, {
1775
- variant: "body2"
1776
- }, "No routes found. Please try again later.");
1777
- case ConfirmSwapErrorTypes.REQUEST_FAILED:
1778
- return React__default.createElement(ui.Typography, {
1779
- variant: "body2"
1780
- }, `Failed to confirm swap ${error.status ? `'status': ${error.status})` : ''}, please try again.`);
1781
- case ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS:
1782
- return React__default.createElement(ui.Typography, {
1783
- variant: "body2"
1784
- }, "Route updated and price impact is too high, try again later!");
1785
- case ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE:
1786
- return React__default.createElement(MinRequiredSlippage, {
1787
- minRequiredSlippage: error.minRequiredSlippage
1788
- });
1789
- default:
1790
- return [];
1791
- }
1792
- });
1793
- }
1794
-
1795
- const List = /*#__PURE__*/ui.styled('ul', {
1796
- variants: {
1797
- showListStyle: {
1798
- true: {
1799
- paddingLeft: '$24'
1800
- }
1801
- }
1802
- }
1803
- });
1804
- const ListItem = /*#__PURE__*/ui.styled('li', {
1805
- variants: {
1806
- showListStyle: {
1807
- true: {
1808
- listStyleType: 'disc',
1809
- listStylePosition: 'outside'
1810
- }
1811
- }
1812
- }
1813
- });
1814
- const Message = /*#__PURE__*/ui.styled(ui.Typography, {
1815
- display: 'block'
1816
- });
1817
- function BalanceWarnings(_ref) {
1818
- let {
1819
- messages
1820
- } = _ref;
1821
- const showListStyle = messages.length > 1;
1822
- return React__default.createElement(List, {
1823
- showListStyle: showListStyle
1824
- }, messages.map(warning => React__default.createElement(ListItem, {
1825
- showListStyle: showListStyle
1826
- }, React__default.createElement(Message, {
1827
- variant: "body2"
1828
- }, warning))));
1829
- }
1830
-
1831
- function ConfirmSwapWarnings(warnings) {
1832
- return warnings.flatMap(warning => {
1833
- switch (warning.type) {
1834
- case ConfirmSwapWarningTypes.ROUTE_UPDATED:
1835
- return React__default.createElement(ui.Typography, {
1836
- variant: "body2"
1837
- }, "Route has been updated.");
1838
- case ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED:
1839
- return React__default.createElement(ui.Typography, {
1840
- variant: "body2"
1841
- }, `Output amount changed to ${warning.newOutputAmount}
1842
- (${warning.percentageChange}% change).`);
1843
- case ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED:
1844
- return React__default.createElement(ui.Typography, {
1845
- variant: "body2"
1846
- }, "Route swappers has been updated.");
1847
- case ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED:
1848
- return React__default.createElement(ui.Typography, {
1849
- variant: "body2"
1850
- }, "Route internal coins has been updated.");
1851
- case ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE:
1852
- return React__default.createElement(BalanceWarnings, {
1853
- messages: warning.messages
1854
- });
1855
- default:
1856
- return [];
1857
- }
1858
- });
1859
- }
1860
-
1861
2011
  function useConfirmSwap() {
1862
2012
  const fromToken = useBestRouteStore.use.fromToken();
1863
2013
  const toToken = useBestRouteStore.use.toToken();
@@ -1898,6 +2048,7 @@ function useConfirmSwap() {
1898
2048
  proceedAnywayRef.current = false;
1899
2049
  if (confiremedRouteRef.current) {
1900
2050
  const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRouteRef.current, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
2051
+ //@ts-ignore
1901
2052
  return newSwap;
1902
2053
  }
1903
2054
  return;
@@ -1960,6 +2111,7 @@ function useConfirmSwap() {
1960
2111
  disabledSwappersGroups: disabledLiquiditySources
1961
2112
  };
1962
2113
  const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRoute, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
2114
+ //@ts-ignore
1963
2115
  return newSwap;
1964
2116
  } else if (!proceedAnywayRef.current) {
1965
2117
  proceedAnywayRef.current = true;
@@ -1989,31 +2141,194 @@ function useConfirmSwap() {
1989
2141
  };
1990
2142
  }
1991
2143
 
2144
+ function ChangeSlippageButton() {
2145
+ const navigate = reactRouterDom.useNavigate();
2146
+ return React__default.createElement(ui.Button, {
2147
+ type: "primary",
2148
+ variant: "outlined",
2149
+ size: "small",
2150
+ onClick: () => navigate(navigationRoutes.settings)
2151
+ }, "Change Slippage");
2152
+ }
2153
+
2154
+ const StyledMessage = /*#__PURE__*/ui.styled(ui.Typography, {
2155
+ color: '$error500 !important'
2156
+ });
2157
+ function MinRequiredSlippage(_ref) {
2158
+ let {
2159
+ minRequiredSlippage
2160
+ } = _ref;
2161
+ return React__default.createElement(StyledMessage, {
2162
+ variant: "body2"
2163
+ }, "We recommend you to increase slippage to at least \u00A0", minRequiredSlippage, "\u00A0 for this route.", React__default.createElement(ui.Spacer, {
2164
+ size: 8,
2165
+ direction: "vertical"
2166
+ }), React__default.createElement(ChangeSlippageButton, null));
2167
+ }
2168
+
2169
+ function ConfirmSwapErrors(errors) {
2170
+ return errors.flatMap(error => {
2171
+ switch (error.type) {
2172
+ case ConfirmSwapErrorTypes.NO_ROUTE:
2173
+ return React__default.createElement(ui.Typography, {
2174
+ variant: "body2"
2175
+ }, "No routes found. Please try again later.");
2176
+ case ConfirmSwapErrorTypes.REQUEST_FAILED:
2177
+ return React__default.createElement(ui.Typography, {
2178
+ variant: "body2"
2179
+ }, `Failed to confirm swap ${error.status ? `'status': ${error.status})` : ''}, please try again.`);
2180
+ case ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS:
2181
+ return React__default.createElement(ui.Typography, {
2182
+ variant: "body2"
2183
+ }, "Route updated and price impact is too high, try again later!");
2184
+ case ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE:
2185
+ return React__default.createElement(MinRequiredSlippage, {
2186
+ minRequiredSlippage: error.minRequiredSlippage
2187
+ });
2188
+ default:
2189
+ return [];
2190
+ }
2191
+ });
2192
+ }
2193
+
2194
+ const List = /*#__PURE__*/ui.styled('ul', {
2195
+ variants: {
2196
+ showListStyle: {
2197
+ true: {
2198
+ paddingLeft: '$24'
2199
+ }
2200
+ }
2201
+ }
2202
+ });
2203
+ const ListItem = /*#__PURE__*/ui.styled('li', {
2204
+ variants: {
2205
+ showListStyle: {
2206
+ true: {
2207
+ listStyleType: 'disc',
2208
+ listStylePosition: 'outside'
2209
+ }
2210
+ }
2211
+ }
2212
+ });
2213
+ const Message = /*#__PURE__*/ui.styled(ui.Typography, {
2214
+ display: 'block',
2215
+ color: '$warning500 !important'
2216
+ });
2217
+ function BalanceWarnings(_ref) {
2218
+ let {
2219
+ messages
2220
+ } = _ref;
2221
+ const showListStyle = messages.length > 1;
2222
+ return React__default.createElement(List, {
2223
+ showListStyle: showListStyle
2224
+ }, messages.map(warning => React__default.createElement(ListItem, {
2225
+ showListStyle: showListStyle
2226
+ }, React__default.createElement(Message, {
2227
+ variant: "body2"
2228
+ }, warning))));
2229
+ }
2230
+
2231
+ function ConfirmSwapWarnings(warnings) {
2232
+ return warnings.flatMap(warning => {
2233
+ switch (warning.type) {
2234
+ case ConfirmSwapWarningTypes.ROUTE_UPDATED:
2235
+ return React__default.createElement(ui.Typography, {
2236
+ variant: "body2"
2237
+ }, "Route has been updated.");
2238
+ case ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED:
2239
+ return React__default.createElement(ui.Typography, {
2240
+ variant: "body2"
2241
+ }, `Output amount changed to ${warning.newOutputAmount}
2242
+ (${warning.percentageChange}% change).`);
2243
+ case ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED:
2244
+ return React__default.createElement(ui.Typography, {
2245
+ variant: "body2"
2246
+ }, "Route swappers has been updated.");
2247
+ case ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED:
2248
+ return React__default.createElement(ui.Typography, {
2249
+ variant: "body2"
2250
+ }, "Route internal coins has been updated.");
2251
+ case ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE:
2252
+ return React__default.createElement(BalanceWarnings, {
2253
+ messages: warning.messages
2254
+ });
2255
+ default:
2256
+ return [];
2257
+ }
2258
+ });
2259
+ }
2260
+
2261
+ function HighSlippageWarning(props) {
2262
+ const {
2263
+ selectedSlippage
2264
+ } = props;
2265
+ return React__default.createElement(ui.Alert, {
2266
+ type: "warning",
2267
+ footer: React__default.createElement(ChangeSlippageButton, null)
2268
+ }, "Caution, your slippage is high (=", selectedSlippage, "). Your trade may be front run.");
2269
+ }
2270
+
2271
+ function ConfirmSwapExtraMessages(props) {
2272
+ const {
2273
+ selectedSlippage
2274
+ } = props;
2275
+ const highSlippage = selectedSlippage >= HIGH_SLIPPAGE;
2276
+ return React__default.createElement(React__default.Fragment, null, highSlippage && React__default.createElement(HighSlippageWarning, {
2277
+ selectedSlippage: selectedSlippage
2278
+ }));
2279
+ }
2280
+
1992
2281
  function ConfirmSwapPage() {
1993
- const setSelectedSwap = useUiStore.use.setSelectedSwap();
2282
+ const navigate = reactRouterDom.useNavigate();
1994
2283
  const {
1995
2284
  navigateBackFrom
1996
2285
  } = useNavigateBack();
1997
- const {
1998
- manager
1999
- } = queueManagerReact.useManager();
2000
- const navigate = reactRouterDom.useNavigate();
2001
2286
  const bestRoute = useBestRouteStore.use.bestRoute();
2002
2287
  const fetchingBestRoute = useBestRouteStore.use.loading();
2288
+ const setSelectedSwap = useUiStore.use.setSelectedSwap();
2003
2289
  const {
2290
+ blockchains,
2004
2291
  tokens
2005
2292
  } = useMetaStore.use.meta();
2293
+ const accounts = useWalletsStore.use.accounts();
2294
+ const selectedWallets = useWalletsStore.use.selectedWallets();
2295
+ const initSelectedWallets = useWalletsStore.use.initSelectedWallets();
2296
+ const setSelectedWallet = useWalletsStore.use.setSelectedWallet();
2006
2297
  const slippage = useSettingsStore.use.slippage();
2007
2298
  const customSlippage = useSettingsStore.use.customSlippage();
2008
- const selectedSlippage = customSlippage || slippage;
2299
+ const {
2300
+ manager
2301
+ } = queueManagerReact.useManager();
2009
2302
  const {
2010
2303
  loading,
2011
2304
  errors,
2012
2305
  warnings,
2013
2306
  confirmSwap
2014
2307
  } = useConfirmSwap();
2308
+ const selectedSlippage = customSlippage || slippage;
2015
2309
  const showHighSlippageWarning = !errors.find(error => error.type === ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE);
2310
+ const {
2311
+ getWalletInfo,
2312
+ connect
2313
+ } = walletsCore.useWallets();
2314
+ const confirmDisabled = fetchingBestRoute || !requiredWallets(bestRoute).every(chain => selectedWallets.map(wallet => wallet.chain).includes(chain));
2315
+ const firstStep = bestRoute?.result?.swaps[0];
2316
+ const lastStep = bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1];
2317
+ const fromAmount = decimalNumber(firstStep?.fromAmount, 3);
2318
+ const toAmount = decimalNumber(lastStep?.toAmount, 3);
2319
+ React.useEffect(() => {
2320
+ initSelectedWallets();
2321
+ }, []);
2322
+ const selectableWallets = getSelectableWallets(accounts, selectedWallets, getWalletInfo);
2323
+ const handleConnectChain = wallet => {
2324
+ const network = wallet;
2325
+ getKeplrCompatibleConnectedWallets(selectableWallets).forEach(compatibleWallet => connect?.(compatibleWallet, network));
2326
+ };
2327
+ const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
2016
2328
  return React__default.createElement(ui.ConfirmSwap, {
2329
+ requiredWallets: getRequiredChains(bestRoute),
2330
+ selectableWallets: selectableWallets,
2331
+ onBack: navigateBackFrom.bind(null, navigationRoutes.confirmSwap),
2017
2332
  onConfirm: () => {
2018
2333
  confirmSwap?.().then(swap => {
2019
2334
  if (swap) {
@@ -2029,16 +2344,51 @@ function ConfirmSwapPage() {
2029
2344
  }
2030
2345
  });
2031
2346
  },
2032
- onBack: navigateBackFrom.bind(null, navigationRoutes.confirmSwap),
2033
- bestRoute: getBestRouteWithCalculatedFees(bestRoute, tokens),
2347
+ onChange: wallet => setSelectedWallet(wallet),
2348
+ confirmDisabled: confirmDisabled,
2349
+ handleConnectChain: wallet => handleConnectChain(wallet),
2350
+ isExperimentalChain: wallet => getKeplrCompatibleConnectedWallets(selectableWallets).length > 0 ? isExperimentalChain(blockchains, wallet) : false,
2351
+ previewInputs: React__default.createElement(React__default.Fragment, null, React__default.createElement(TokenPreview, {
2352
+ chain: {
2353
+ displayName: firstStep?.from.blockchain || '',
2354
+ logo: firstStep?.from.blockchainLogo || ''
2355
+ },
2356
+ token: {
2357
+ symbol: firstStep?.from.symbol || '',
2358
+ image: firstStep?.from.logo || ''
2359
+ },
2360
+ usdValue: calcOutputUsdValue(fromAmount, firstStep?.from.usdPrice),
2361
+ amount: fromAmount,
2362
+ label: i18n.t('From'),
2363
+ loadingStatus: 'success'
2364
+ }), React__default.createElement(ui.Spacer, {
2365
+ size: 12,
2366
+ direction: "vertical"
2367
+ }), React__default.createElement(TokenPreview, {
2368
+ chain: {
2369
+ displayName: lastStep?.to.blockchain || '',
2370
+ logo: lastStep?.to.blockchainLogo || ''
2371
+ },
2372
+ token: {
2373
+ symbol: lastStep?.to.symbol || '',
2374
+ image: lastStep?.to.logo || ''
2375
+ },
2376
+ usdValue: calcOutputUsdValue(toAmount, lastStep?.to.usdPrice),
2377
+ amount: toAmount,
2378
+ label: i18n.t('To'),
2379
+ loadingStatus: 'success'
2380
+ })),
2381
+ previewRoutes: React__default.createElement(RoutesOverview, {
2382
+ routes: bestRoute,
2383
+ totalFee: numberToString(totalFeeInUsd, 0, 2)
2384
+ }),
2034
2385
  loading: loading,
2035
2386
  errors: ConfirmSwapErrors(errors),
2036
2387
  warnings: ConfirmSwapWarnings(warnings),
2037
2388
  extraMessages: showHighSlippageWarning && React__default.createElement(ConfirmSwapExtraMessages, {
2038
2389
  selectedSlippage: selectedSlippage
2039
2390
  }),
2040
- confirmButtonTitle: warnings.length > 0 || errors.length > 0 ? 'Proceed anyway!' : 'Confirm swap!',
2041
- confirmButtonDisabled: fetchingBestRoute
2391
+ confirmButtonTitle: warnings.length > 0 || errors.length > 0 ? 'Proceed anyway!' : 'Confirm swap!'
2042
2392
  });
2043
2393
  }
2044
2394
 
@@ -2126,436 +2476,185 @@ function SelectChainPage(props) {
2126
2476
  supportedChains
2127
2477
  } = props;
2128
2478
  const blockchains = supportedChains === 'all' ? useMetaStore.use.meta().blockchains : supportedChains;
2129
- const loadingStatus = useMetaStore.use.loadingStatus();
2130
- const fromChain = useBestRouteStore.use.fromChain();
2131
- const toChain = useBestRouteStore.use.toChain();
2132
- const setFromChain = useBestRouteStore.use.setFromChain();
2133
- const setToChain = useBestRouteStore.use.setToChain();
2134
- const {
2135
- navigateBackFrom
2136
- } = useNavigateBack();
2137
- return React__default.createElement(ui.BlockchainSelector, {
2138
- type: type === 'from' ? 'Source' : 'Destination',
2139
- list: blockchains,
2140
- selected: type === 'from' ? fromChain : toChain,
2141
- loadingStatus: loadingStatus,
2142
- onChange: chain => {
2143
- if (type === 'from') setFromChain(chain, true);else setToChain(chain, true);
2144
- navigateBackFrom(navigationRoutes.fromChain);
2145
- },
2146
- onBack: navigateBackFrom.bind(null, navigationRoutes.fromChain)
2147
- });
2148
- }
2149
-
2150
- function SelectTokenPage(props) {
2151
- const {
2152
- navigateBackFrom
2153
- } = useNavigateBack();
2154
- const {
2155
- type,
2156
- supportedTokens
2157
- } = props;
2158
- const sourceTokens = useBestRouteStore.use.sourceTokens();
2159
- const destinationTokens = useBestRouteStore.use.destinationTokens();
2160
- const supportedSourceTokens = supportedTokens === 'all' ? sourceTokens : sourceTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2161
- const supportedDestinationTokens = supportedTokens === 'all' ? destinationTokens : destinationTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2162
- console.log(supportedSourceTokens);
2163
- const fromToken = useBestRouteStore.use.fromToken();
2164
- const toToken = useBestRouteStore.use.toToken();
2165
- const setFromToken = useBestRouteStore.use.setFromToken();
2166
- const setToToken = useBestRouteStore.use.setToToken();
2167
- return React__default.createElement(ui.TokenSelector, {
2168
- type: type === 'from' ? 'Source' : 'Destination',
2169
- list: type == 'from' ? supportedSourceTokens : supportedDestinationTokens,
2170
- selected: type === 'from' ? fromToken : toToken,
2171
- onChange: token => {
2172
- if (type === 'from') setFromToken(token);else setToToken(token);
2173
- navigateBackFrom(navigationRoutes.fromToken);
2174
- },
2175
- onBack: navigateBackFrom.bind(null, navigationRoutes.fromToken)
2176
- });
2177
- }
2178
-
2179
- function SettingsPage(_ref) {
2180
- let {
2181
- supportedSwappers
2182
- } = _ref;
2183
- const slippage = useSettingsStore.use.slippage();
2184
- const setSlippage = useSettingsStore.use.setSlippage();
2185
- const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
2186
- const customSlippage = useSettingsStore.use.customSlippage();
2187
- const setCustomSlippage = useSettingsStore.use.setCustomSlippage();
2188
- const theme = useSettingsStore.use.theme();
2189
- const setTheme = useSettingsStore.use.setTheme();
2190
- const swappers = useMetaStore.use.meta().swappers;
2191
- const navigate = reactRouterDom.useNavigate();
2192
- const {
2193
- navigateBackFrom
2194
- } = useNavigateBack();
2195
- const infiniteApprove = useSettingsStore.use.infiniteApprove();
2196
- const toggleInfiniteApprove = useSettingsStore.use.toggleInfiniteApprove();
2197
- const uniqueSwappersGroups = [];
2198
- removeDuplicateFrom(swappers.map(s => s.swapperGroup)).map(swapperGroup => {
2199
- return swappers.find(s => s.swapperGroup === swapperGroup);
2200
- }).find(s => {
2201
- if (s) {
2202
- for (const type of s.types) {
2203
- uniqueSwappersGroups.push({
2204
- title: s.swapperGroup,
2205
- logo: s.logo,
2206
- type,
2207
- selected: !disabledLiquiditySources.includes(s.swapperGroup)
2208
- });
2209
- }
2210
- }
2211
- });
2212
- supportedSwappers !== 'all' && uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0);
2213
- const supportedUniqueSwappersGroups = supportedSwappers !== 'all' ? uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0) : uniqueSwappersGroups;
2214
- return React__default.createElement(ui.Settings, {
2215
- slippages: SLIPPAGES,
2216
- selectedSlippage: slippage,
2217
- onSlippageChange: slippage => setSlippage(slippage),
2218
- onLiquiditySourcesClick: () => navigate(navigationRoutes.liquiditySources),
2219
- onBack: navigateBackFrom.bind(null, navigationRoutes.settings),
2220
- liquiditySources: supportedUniqueSwappersGroups,
2221
- selectedLiquiditySources: supportedUniqueSwappersGroups.filter(s => s.selected),
2222
- customSlippage: customSlippage || NaN,
2223
- onCustomSlippageChange: setCustomSlippage,
2224
- minSlippage: MIN_SLIPPGAE,
2225
- maxSlippage: MAX_SLIPPAGE,
2226
- selectedTheme: theme,
2227
- onThemeChange: setTheme,
2228
- infiniteApprove: infiniteApprove,
2229
- toggleInfiniteApprove: toggleInfiniteApprove
2230
- });
2231
- }
2232
-
2233
- const ListContainer = /*#__PURE__*/ui.styled('div', {
2234
- display: 'grid',
2235
- gap: '.5rem',
2236
- gridTemplateColumns: ' repeat(2, minmax(0, 1fr))',
2237
- height: '450px',
2238
- alignContent: 'baseline',
2239
- padding: '0.5rem'
2240
- });
2241
- const AlertContainer = /*#__PURE__*/ui.styled('div', {
2242
- paddingBottom: '$16'
2243
- });
2244
- function WalletsPage(_ref) {
2245
- let {
2246
- supportedWallets,
2247
- multiWallets
2248
- } = _ref;
2249
- const {
2250
- navigateBackFrom
2251
- } = useNavigateBack();
2252
- const {
2253
- state,
2254
- disconnect,
2255
- getWalletInfo,
2256
- connect
2257
- } = walletsCore.useWallets();
2258
- const wallets = getlistWallet(state, getWalletInfo, supportedWallets === 'all' ? Object.values(walletsShared.WalletType) : supportedWallets);
2259
- const walletsRef = React.useRef();
2260
- let sortedWallets = walletsShared.detectMobileScreens() ? wallets.filter(wallet => wallet.showOnMobile) : wallets;
2261
- sortedWallets = sortWalletsBasedOnState(sortedWallets);
2262
- const [walletErrorMessage, setWalletErrorMessage] = React.useState('');
2263
- const toggleConnectWalletsButton = useUiStore.use.toggleConnectWalletsButton();
2264
- const {
2265
- t
2266
- } = reactI18next.useTranslation();
2267
- const onSelectWallet = async type => {
2268
- const wallet = state(type);
2269
- try {
2270
- if (walletErrorMessage) setWalletErrorMessage('');
2271
- if (wallet.connected) {
2272
- await disconnect(type);
2273
- } else {
2274
- if (!multiWallets && !!wallets.find(w => w.state === ui.WalletState.CONNECTED)) {
2275
- return;
2276
- }
2277
- await connect(type);
2278
- }
2279
- } catch (e) {
2280
- setWalletErrorMessage('Error: ' + e?.message);
2281
- }
2282
- };
2283
- const disconnectConnectingWallets = () => {
2284
- const connectingWallets = walletsRef.current?.filter(wallet => wallet.state === ui.WalletState.CONNECTING) || [];
2285
- for (const wallet of connectingWallets) {
2286
- disconnect(wallet.type);
2287
- }
2288
- };
2289
- React.useEffect(() => {
2290
- toggleConnectWalletsButton();
2291
- return () => {
2292
- disconnectConnectingWallets();
2293
- toggleConnectWalletsButton();
2294
- };
2295
- }, []);
2296
- React.useEffect(() => {
2297
- walletsRef.current = wallets;
2298
- }, [wallets]);
2299
- return React__default.createElement(ui.SecondaryPage, {
2300
- title: t('Select Wallet') || '',
2301
- textField: false,
2302
- onBack: navigateBackFrom.bind(null, navigationRoutes.wallets)
2303
- }, React__default.createElement(React__default.Fragment, null, walletErrorMessage && React__default.createElement(AlertContainer, null, React__default.createElement(ui.Alert, {
2304
- type: "error"
2305
- }, walletErrorMessage)), React__default.createElement(ListContainer, null, sortedWallets.map((wallet, index) => React__default.createElement(ui.Wallet, Object.assign({}, wallet, {
2306
- key: `${index}-${wallet.type}`,
2307
- onClick: onSelectWallet
2308
- }))))));
2309
- }
2310
-
2311
- const Box$1 = /*#__PURE__*/ui.styled('div', {
2312
- display: 'flex',
2313
- flexDirection: 'column',
2314
- width: '100%'
2315
- });
2316
- const Container$3 = /*#__PURE__*/ui.styled('div', {
2317
- boxSizing: 'border-box',
2318
- borderRadius: '$5',
2319
- padding: '$8 $16 $16 $16',
2320
- variants: {
2321
- type: {
2322
- filled: {
2323
- backgroundColor: '$neutrals300'
2324
- },
2325
- outlined: {
2326
- border: '1px solid $neutrals300'
2327
- }
2328
- }
2329
- },
2330
- defaultVariants: {
2331
- type: 'filled'
2332
- },
2333
- '.head': {
2334
- display: 'flex',
2335
- justifyContent: 'space-between',
2336
- alignItems: 'center',
2337
- minHeight: '32px'
2338
- },
2339
- '.form': {
2340
- display: 'flex',
2341
- width: '100%',
2342
- padding: '$2 0',
2343
- '.selectors': {
2344
- width: '35%',
2345
- '._text': {
2346
- whiteSpace: 'nowrap',
2347
- overflow: 'hidden',
2348
- textOverflow: 'ellipsis'
2349
- }
2350
- },
2351
- '.amount': {
2352
- width: '30%'
2353
- }
2354
- }
2355
- });
2356
- const StyledImage$1 = /*#__PURE__*/ui.styled('img', {
2357
- width: '$24',
2358
- maxHeight: '$24'
2359
- });
2360
- const ImagePlaceholder$1 = /*#__PURE__*/ui.styled('span', {
2361
- width: '24px',
2362
- height: '24px',
2363
- backgroundColor: '$neutrals300',
2364
- borderRadius: '99999px'
2365
- });
2366
- const OutputContainer$1 = /*#__PURE__*/ui.styled('div', {
2367
- windth: '100%',
2368
- height: '$48',
2369
- borderRadius: '$5',
2370
- backgroundColor: '$background',
2371
- border: '1px solid transparent',
2372
- position: 'relative',
2373
- display: 'flex',
2374
- alignItems: 'center',
2375
- paddingLeft: '$8',
2376
- paddingRight: '$8'
2377
- });
2378
- function TokenPreview(props) {
2379
- const {
2380
- chain,
2381
- token,
2382
- loadingStatus
2383
- } = props;
2384
- const {
2385
- t
2386
- } = reactI18next.useTranslation();
2387
- const ItemSuffix = React__default.createElement("div", {
2388
- style: {
2389
- display: 'flex',
2390
- justifyContent: 'center',
2391
- alignItems: 'center'
2392
- }
2393
- }, loadingStatus === 'failed' && React__default.createElement(ui.InfoCircleIcon, {
2394
- color: "error",
2395
- size: 24
2396
- }));
2397
- return React__default.createElement(Box$1, null, React__default.createElement(Container$3, {
2398
- type: 'outlined'
2399
- }, React__default.createElement("div", {
2400
- className: "head"
2401
- }, React__default.createElement(ui.Typography, {
2402
- variant: "body2",
2403
- color: "neutrals800"
2404
- }, props.label), React__default.createElement(ui.Typography, {
2405
- variant: "caption",
2406
- color: "neutrals600"
2407
- }, `$${numberToString(props.usdValue)}`)), React__default.createElement("div", {
2408
- className: "form"
2409
- }, React__default.createElement(ui.Button, {
2410
- className: "selectors",
2411
- variant: "outlined",
2412
- loading: loadingStatus === 'loading',
2413
- prefix: loadingStatus === 'success' && chain ? React__default.createElement(StyledImage$1, {
2414
- src: chain.logo
2415
- }) : React__default.createElement(ImagePlaceholder$1, null),
2416
- suffix: ItemSuffix,
2417
- align: "start",
2418
- size: "large"
2419
- }, loadingStatus === 'success' && chain ? chain.displayName : t('Chain')), React__default.createElement(ui.Spacer, {
2420
- size: 12
2421
- }), React__default.createElement(ui.Button, {
2422
- className: "selectors",
2423
- variant: "outlined",
2424
- loading: loadingStatus === 'loading',
2425
- prefix: loadingStatus === 'success' && token ? React__default.createElement(StyledImage$1, {
2426
- src: token.image
2427
- }) : React__default.createElement(ImagePlaceholder$1, null),
2428
- suffix: ItemSuffix,
2429
- size: "large",
2430
- align: "start"
2431
- }, loadingStatus === 'success' && token ? token.symbol : t('Token')), React__default.createElement(ui.Spacer, {
2432
- size: 12
2433
- }), React__default.createElement("div", {
2434
- className: "amount"
2435
- }, React__default.createElement(OutputContainer$1, null, React__default.createElement(ui.Typography, {
2436
- variant: "h4"
2437
- }, props.amount))))));
2438
- }
2439
-
2440
- const Container$4 = /*#__PURE__*/ui.styled('div', {
2441
- display: 'flex',
2442
- alignItems: 'center',
2443
- justifyContent: 'space-between',
2444
- padding: '$8',
2445
- borderRadius: '$5',
2446
- backgroundColor: '$neutrals300',
2447
- color: '$neutrals800',
2448
- fontSize: '$12',
2449
- '.routes': {
2450
- display: 'flex',
2451
- alignItems: 'center'
2452
- },
2453
- '.fee': {
2454
- display: 'flex',
2455
- alignItems: 'center'
2456
- }
2457
- });
2458
- function RoutesOverview(props) {
2459
- if (!props.routes) return null;
2460
- const swaps = props.routes.result?.swaps;
2461
- return React__default.createElement(Container$4, null, React__default.createElement("div", {
2462
- className: "routes"
2463
- }, swaps?.map((swap, idx) => {
2464
- const isLast = idx + 1 == swaps.length;
2465
- return React__default.createElement(React__default.Fragment, null, React__default.createElement("div", {
2466
- className: "route"
2467
- }, swap.from.symbol), React__default.createElement(ui.ChevronRightIcon, {
2468
- size: 12
2469
- }), isLast ? React__default.createElement("div", {
2470
- className: "route"
2471
- }, swap.to.symbol) : null);
2472
- })), props.totalFee ? React__default.createElement("div", {
2473
- className: "fee"
2474
- }, React__default.createElement(ui.GasIcon, {
2475
- size: 12
2476
- }), React__default.createElement(ui.Spacer, {
2477
- size: 4
2478
- }), "$", props.totalFee) : null);
2479
+ const loadingStatus = useMetaStore.use.loadingStatus();
2480
+ const fromChain = useBestRouteStore.use.fromChain();
2481
+ const toChain = useBestRouteStore.use.toChain();
2482
+ const setFromChain = useBestRouteStore.use.setFromChain();
2483
+ const setToChain = useBestRouteStore.use.setToChain();
2484
+ const {
2485
+ navigateBackFrom
2486
+ } = useNavigateBack();
2487
+ return React__default.createElement(ui.BlockchainSelector, {
2488
+ type: type === 'from' ? 'Source' : 'Destination',
2489
+ list: blockchains,
2490
+ selected: type === 'from' ? fromChain : toChain,
2491
+ loadingStatus: loadingStatus,
2492
+ onChange: chain => {
2493
+ if (type === 'from') setFromChain(chain, true);else setToChain(chain, true);
2494
+ navigateBackFrom(navigationRoutes.fromChain);
2495
+ },
2496
+ onBack: navigateBackFrom.bind(null, navigationRoutes.fromChain)
2497
+ });
2498
+ }
2499
+
2500
+ function SelectTokenPage(props) {
2501
+ const {
2502
+ navigateBackFrom
2503
+ } = useNavigateBack();
2504
+ const {
2505
+ type,
2506
+ supportedTokens
2507
+ } = props;
2508
+ const sourceTokens = useBestRouteStore.use.sourceTokens();
2509
+ const destinationTokens = useBestRouteStore.use.destinationTokens();
2510
+ const supportedSourceTokens = supportedTokens === 'all' ? sourceTokens : sourceTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2511
+ const supportedDestinationTokens = supportedTokens === 'all' ? destinationTokens : destinationTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2512
+ const fromToken = useBestRouteStore.use.fromToken();
2513
+ const toToken = useBestRouteStore.use.toToken();
2514
+ const setFromToken = useBestRouteStore.use.setFromToken();
2515
+ const setToToken = useBestRouteStore.use.setToToken();
2516
+ return React__default.createElement(ui.TokenSelector, {
2517
+ type: type === 'from' ? 'Source' : 'Destination',
2518
+ list: type == 'from' ? supportedSourceTokens : supportedDestinationTokens,
2519
+ selected: type === 'from' ? fromToken : toToken,
2520
+ onChange: token => {
2521
+ if (type === 'from') setFromToken(token);else setToToken(token);
2522
+ navigateBackFrom(navigationRoutes.fromToken);
2523
+ },
2524
+ onBack: navigateBackFrom.bind(null, navigationRoutes.fromToken)
2525
+ });
2479
2526
  }
2480
2527
 
2481
- function ConfirmWalletsPage() {
2528
+ function SettingsPage(_ref) {
2529
+ let {
2530
+ supportedSwappers
2531
+ } = _ref;
2532
+ const slippage = useSettingsStore.use.slippage();
2533
+ const setSlippage = useSettingsStore.use.setSlippage();
2534
+ const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
2535
+ const customSlippage = useSettingsStore.use.customSlippage();
2536
+ const setCustomSlippage = useSettingsStore.use.setCustomSlippage();
2537
+ const theme = useSettingsStore.use.theme();
2538
+ const setTheme = useSettingsStore.use.setTheme();
2539
+ const swappers = useMetaStore.use.meta().swappers;
2482
2540
  const navigate = reactRouterDom.useNavigate();
2483
2541
  const {
2484
2542
  navigateBackFrom
2485
2543
  } = useNavigateBack();
2486
- const bestRoute = useBestRouteStore.use.bestRoute();
2544
+ const infiniteApprove = useSettingsStore.use.infiniteApprove();
2545
+ const toggleInfiniteApprove = useSettingsStore.use.toggleInfiniteApprove();
2546
+ const uniqueSwappersGroups = [];
2547
+ removeDuplicateFrom(swappers.map(s => s.swapperGroup)).map(swapperGroup => {
2548
+ return swappers.find(s => s.swapperGroup === swapperGroup);
2549
+ }).find(s => {
2550
+ if (s) {
2551
+ for (const type of s.types) {
2552
+ uniqueSwappersGroups.push({
2553
+ title: s.swapperGroup,
2554
+ logo: s.logo,
2555
+ type,
2556
+ selected: !disabledLiquiditySources.includes(s.swapperGroup)
2557
+ });
2558
+ }
2559
+ }
2560
+ });
2561
+ supportedSwappers !== 'all' && uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0);
2562
+ const supportedUniqueSwappersGroups = supportedSwappers !== 'all' ? uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0) : uniqueSwappersGroups;
2563
+ return React__default.createElement(ui.Settings, {
2564
+ slippages: SLIPPAGES,
2565
+ selectedSlippage: slippage,
2566
+ onSlippageChange: slippage => setSlippage(slippage),
2567
+ onLiquiditySourcesClick: () => navigate(navigationRoutes.liquiditySources),
2568
+ onBack: navigateBackFrom.bind(null, navigationRoutes.settings),
2569
+ liquiditySources: supportedUniqueSwappersGroups,
2570
+ selectedLiquiditySources: supportedUniqueSwappersGroups.filter(s => s.selected),
2571
+ customSlippage: customSlippage || NaN,
2572
+ onCustomSlippageChange: setCustomSlippage,
2573
+ minSlippage: MIN_SLIPPGAE,
2574
+ maxSlippage: MAX_SLIPPAGE,
2575
+ selectedTheme: theme,
2576
+ onThemeChange: setTheme,
2577
+ infiniteApprove: infiniteApprove,
2578
+ toggleInfiniteApprove: toggleInfiniteApprove
2579
+ });
2580
+ }
2581
+
2582
+ const ListContainer = /*#__PURE__*/ui.styled('div', {
2583
+ display: 'grid',
2584
+ gap: '.5rem',
2585
+ gridTemplateColumns: ' repeat(2, minmax(0, 1fr))',
2586
+ height: '450px',
2587
+ alignContent: 'baseline',
2588
+ padding: '0.5rem'
2589
+ });
2590
+ const AlertContainer = /*#__PURE__*/ui.styled('div', {
2591
+ paddingBottom: '$16'
2592
+ });
2593
+ function WalletsPage(_ref) {
2594
+ let {
2595
+ supportedWallets,
2596
+ multiWallets
2597
+ } = _ref;
2487
2598
  const {
2488
- blockchains,
2489
- tokens
2490
- } = useMetaStore.use.meta();
2491
- const accounts = useWalletsStore.use.accounts();
2492
- const selectedWallets = useWalletsStore.use.selectedWallets();
2493
- const initSelectedWallets = useWalletsStore.use.initSelectedWallets();
2494
- const setSelectedWallet = useWalletsStore.use.setSelectedWallet();
2599
+ navigateBackFrom
2600
+ } = useNavigateBack();
2495
2601
  const {
2602
+ state,
2603
+ disconnect,
2496
2604
  getWalletInfo,
2497
2605
  connect
2498
2606
  } = walletsCore.useWallets();
2499
- const confirmDisabled = !requiredWallets(bestRoute).every(chain => selectedWallets.map(wallet => wallet.chain).includes(chain));
2500
- const firstStep = bestRoute?.result?.swaps[0];
2501
- const lastStep = bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1];
2502
- const fromAmount = decimalNumber(firstStep?.fromAmount, 3);
2503
- const toAmount = decimalNumber(lastStep?.toAmount, 3);
2607
+ const wallets = getlistWallet(state, getWalletInfo, supportedWallets === 'all' ? Object.values(walletsShared.WalletType) : supportedWallets);
2608
+ const walletsRef = React.useRef();
2609
+ let sortedWallets = walletsShared.detectMobileScreens() ? wallets.filter(wallet => wallet.showOnMobile) : wallets;
2610
+ sortedWallets = sortWalletsBasedOnState(sortedWallets);
2611
+ const [walletErrorMessage, setWalletErrorMessage] = React.useState('');
2612
+ const toggleConnectWalletsButton = useUiStore.use.toggleConnectWalletsButton();
2613
+ const {
2614
+ t
2615
+ } = reactI18next.useTranslation();
2616
+ const onSelectWallet = async type => {
2617
+ const wallet = state(type);
2618
+ try {
2619
+ if (walletErrorMessage) setWalletErrorMessage('');
2620
+ if (wallet.connected) {
2621
+ await disconnect(type);
2622
+ } else {
2623
+ if (!multiWallets && !!wallets.find(w => w.state === ui.WalletState.CONNECTED)) {
2624
+ return;
2625
+ }
2626
+ await connect(type);
2627
+ }
2628
+ } catch (e) {
2629
+ setWalletErrorMessage('Error: ' + e?.message);
2630
+ }
2631
+ };
2632
+ const disconnectConnectingWallets = () => {
2633
+ const connectingWallets = walletsRef.current?.filter(wallet => wallet.state === ui.WalletState.CONNECTING) || [];
2634
+ for (const wallet of connectingWallets) {
2635
+ disconnect(wallet.type);
2636
+ }
2637
+ };
2504
2638
  React.useEffect(() => {
2505
- initSelectedWallets();
2639
+ toggleConnectWalletsButton();
2640
+ return () => {
2641
+ disconnectConnectingWallets();
2642
+ toggleConnectWalletsButton();
2643
+ };
2506
2644
  }, []);
2507
- const selectableWallets = getSelectableWallets(accounts, selectedWallets, getWalletInfo);
2508
- const handleConnectChain = wallet => {
2509
- const network = wallet;
2510
- getKeplrCompatibleConnectedWallets(selectableWallets).forEach(compatibleWallet => connect?.(compatibleWallet, network));
2511
- };
2512
- const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
2513
- return React__default.createElement(ui.ConfirmWallets, {
2514
- requiredWallets: getRequiredChains(bestRoute),
2515
- selectableWallets: selectableWallets,
2516
- onBack: navigateBackFrom.bind(null, navigationRoutes.confirmWallets),
2517
- onConfirm: () => navigate(navigationRoutes.confirmSwap, {
2518
- replace: true
2519
- }),
2520
- onChange: wallet => setSelectedWallet(wallet),
2521
- confirmDisabled: confirmDisabled,
2522
- handleConnectChain: wallet => handleConnectChain(wallet),
2523
- isExperimentalChain: wallet => getKeplrCompatibleConnectedWallets(selectableWallets).length > 0 ? isExperimentalChain(blockchains, wallet) : false,
2524
- previewInputs: React__default.createElement(React__default.Fragment, null, React__default.createElement(TokenPreview, {
2525
- chain: {
2526
- displayName: firstStep?.from.blockchain || '',
2527
- logo: firstStep?.from.blockchainLogo || ''
2528
- },
2529
- token: {
2530
- symbol: firstStep?.from.symbol || '',
2531
- image: firstStep?.from.logo || ''
2532
- },
2533
- usdValue: calcOutputUsdValue(fromAmount, firstStep?.from.usdPrice),
2534
- amount: fromAmount,
2535
- label: i18n.t('From'),
2536
- loadingStatus: 'success'
2537
- }), React__default.createElement(ui.Spacer, {
2538
- size: 12,
2539
- direction: "vertical"
2540
- }), React__default.createElement(TokenPreview, {
2541
- chain: {
2542
- displayName: lastStep?.to.blockchain || '',
2543
- logo: lastStep?.to.blockchainLogo || ''
2544
- },
2545
- token: {
2546
- symbol: lastStep?.to.symbol || '',
2547
- image: lastStep?.to.logo || ''
2548
- },
2549
- usdValue: calcOutputUsdValue(toAmount, lastStep?.to.usdPrice),
2550
- amount: toAmount,
2551
- label: i18n.t('To'),
2552
- loadingStatus: 'success'
2553
- })),
2554
- previewRoutes: React__default.createElement(RoutesOverview, {
2555
- routes: bestRoute,
2556
- totalFee: numberToString(totalFeeInUsd, 0, 2)
2557
- })
2558
- });
2645
+ React.useEffect(() => {
2646
+ walletsRef.current = wallets;
2647
+ }, [wallets]);
2648
+ return React__default.createElement(ui.SecondaryPage, {
2649
+ title: t('Select Wallet') || '',
2650
+ textField: false,
2651
+ onBack: navigateBackFrom.bind(null, navigationRoutes.wallets)
2652
+ }, React__default.createElement(React__default.Fragment, null, walletErrorMessage && React__default.createElement(AlertContainer, null, React__default.createElement(ui.Alert, {
2653
+ type: "error"
2654
+ }, walletErrorMessage)), React__default.createElement(ListContainer, null, sortedWallets.map((wallet, index) => React__default.createElement(ui.Wallet, Object.assign({}, wallet, {
2655
+ key: `${index}-${wallet.type}`,
2656
+ onClick: onSelectWallet
2657
+ }))))));
2559
2658
  }
2560
2659
 
2561
2660
  function useCopyToClipboard(resetInterval) {
@@ -2576,15 +2675,60 @@ function useCopyToClipboard(resetInterval) {
2576
2675
  return [isCopied, handleCopy];
2577
2676
  }
2578
2677
 
2678
+ function timeSince(timeMillis) {
2679
+ const seconds = Math.floor((new Date().getTime() - timeMillis) / 1000);
2680
+ let intervalType;
2681
+ let interval = Math.floor(seconds / 31536000);
2682
+ if (interval >= 1) {
2683
+ intervalType = 'year';
2684
+ } else {
2685
+ interval = Math.floor(seconds / 2592000);
2686
+ if (interval >= 1) {
2687
+ intervalType = 'month';
2688
+ } else {
2689
+ interval = Math.floor(seconds / 86400);
2690
+ if (interval >= 1) {
2691
+ intervalType = 'day';
2692
+ } else {
2693
+ interval = Math.floor(seconds / 3600);
2694
+ if (interval >= 1) {
2695
+ intervalType = 'hour';
2696
+ } else {
2697
+ interval = Math.floor(seconds / 60);
2698
+ if (interval >= 1) {
2699
+ intervalType = 'minute';
2700
+ } else {
2701
+ interval = seconds;
2702
+ intervalType = 'second';
2703
+ }
2704
+ }
2705
+ }
2706
+ }
2707
+ }
2708
+ if (interval > 1 || interval === 0) {
2709
+ intervalType += 's';
2710
+ }
2711
+ return interval + ' ' + intervalType;
2712
+ }
2713
+ function getSwapDate(pendingSwap) {
2714
+ 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()}`;
2715
+ }
2716
+
2579
2717
  function SwapDetailsPage() {
2580
2718
  const selectedSwapRequestId = useUiStore.use.selectedSwapRequestId();
2719
+ const {
2720
+ canSwitchNetworkTo,
2721
+ connect
2722
+ } = walletsCore.useWallets();
2723
+ const retry = useBestRouteStore.use.retry();
2724
+ const navigate = reactRouterDom.useNavigate();
2581
2725
  const {
2582
2726
  navigateBackFrom
2583
2727
  } = useNavigateBack();
2728
+ const [isCopied, handleCopy] = useCopyToClipboard(2000);
2584
2729
  const {
2585
2730
  manager
2586
2731
  } = queueManagerReact.useManager();
2587
- const [isCopied, handleCopy] = useCopyToClipboard(2000);
2588
2732
  const pendingSwaps = getPendingSwaps(manager);
2589
2733
  const selectedSwap = pendingSwaps.find(_ref => {
2590
2734
  let {
@@ -2592,20 +2736,50 @@ function SwapDetailsPage() {
2592
2736
  } = _ref;
2593
2737
  return swap.requestId === selectedSwapRequestId;
2594
2738
  });
2595
- //TODO: implement swap cancellation (move queueManager logic to queueManager/rango-preset)
2596
2739
  const onCancel = () => {
2597
- const swap = selectedSwap ? manager?.get(selectedSwap.id) : undefined;
2740
+ const swap = manager?.get(selectedSwap?.id);
2598
2741
  if (swap) queueManagerRangoPreset.cancelSwap(swap);
2599
2742
  };
2600
- return React__default.createElement(ui.SwapHistory, {
2743
+ const swap = selectedSwap?.swap;
2744
+ if (!swap) return null;
2745
+ const currentStep = queueManagerRangoPreset.getCurrentStep(swap);
2746
+ const currentStepBlockchain = currentStep ? queueManagerRangoPreset.getCurrentBlockchainOfOrNull(swap, currentStep) : null;
2747
+ const currentStepWallet = currentStep ? queueManagerRangoPreset.getRelatedWalletOrNull(swap, currentStep) : null;
2748
+ const currentStepNetworkStatus = currentStep?.networkStatus;
2749
+ const swapMessages = getSwapMessages(swap, currentStep);
2750
+ const networkWarningState = isNetworkStatusInWarningState(currentStep);
2751
+ const swapDate = getSwapDate(swap);
2752
+ const shouldRetry = shouldRetrySwap(swap);
2753
+ const switchNetwork = !!currentStepBlockchain && !!currentStepWallet?.walletType && currentStepNetworkStatus === queueManagerRangoPreset.PendingSwapNetworkStatus.WaitingForNetworkChange && canSwitchNetworkTo(currentStepWallet?.walletType, currentStepBlockchain) ? connect.bind(null, currentStepWallet.walletType, currentStepBlockchain) : undefined;
2754
+ const lastConvertedTokenInFailedSwap = getLastConvertedTokenInFailedSwap(swap);
2755
+ return React__default.createElement(ui.SwapHistory, Object.assign({
2601
2756
  onBack: navigateBackFrom.bind(null, navigationRoutes.swapDetails),
2602
2757
  //todo: move PendingSwap type to rango-types
2603
2758
  //@ts-ignore
2604
- pendingSwap: selectedSwap?.swap,
2759
+ pendingSwap: swap,
2605
2760
  onCopy: handleCopy,
2606
2761
  isCopied: isCopied,
2607
- onCancel: onCancel
2608
- });
2762
+ onCancel: onCancel,
2763
+ shortMessage: swapMessages.shortMessage,
2764
+ detailedMessage: swapMessages.detailedMessage,
2765
+ currentStepBlockchain: currentStepBlockchain || '',
2766
+ switchNetwork: switchNetwork,
2767
+ type: networkWarningState ? 'warning' : swap.extraMessageSeverity || undefined,
2768
+ date: swapDate
2769
+ }, shouldRetry && {
2770
+ onRetry: () => {
2771
+ retry(swap);
2772
+ setTimeout(() => {
2773
+ navigate(navigationRoutes.home);
2774
+ }, 0);
2775
+ }
2776
+ }, lastConvertedTokenInFailedSwap && {
2777
+ lastConvertedTokenInFailedSwap: {
2778
+ blockchain: lastConvertedTokenInFailedSwap.blockchain,
2779
+ outputAmount: lastConvertedTokenInFailedSwap.outputAmount,
2780
+ symbol: lastConvertedTokenInFailedSwap.symbol
2781
+ }
2782
+ }));
2609
2783
  }
2610
2784
 
2611
2785
  function AppRoutes(props) {
@@ -2668,9 +2842,6 @@ function AppRoutes(props) {
2668
2842
  }, {
2669
2843
  path: navigationRoutes.confirmSwap,
2670
2844
  element: React__default.createElement(ConfirmSwapPage, null)
2671
- }, {
2672
- path: navigationRoutes.confirmWallets,
2673
- element: React__default.createElement(ConfirmWalletsPage, null)
2674
2845
  }]);
2675
2846
  }
2676
2847
 
@@ -2721,6 +2892,12 @@ function Layout(_ref) {
2721
2892
  setFromToken(configs?.fromToken || null);
2722
2893
  setFromChain(configs?.fromChain || null);
2723
2894
  }, [configs?.fromToken, configs?.fromChain]);
2895
+ React.useEffect(() => {
2896
+ setToChain(null);
2897
+ setFromChain(null);
2898
+ setFromToken(null);
2899
+ setToToken(null);
2900
+ }, [configs?.fromChains, configs?.toChains, configs?.fromTokens, configs?.toTokens]);
2724
2901
  return React__default.createElement(React__default.Fragment, null, React__default.createElement(Header$1, null, React__default.createElement(ui.Button, {
2725
2902
  size: "small",
2726
2903
  suffix: React__default.createElement(ui.AddWalletIcon, {
@@ -3021,7 +3198,9 @@ function QueueManager(props) {
3021
3198
  //@ts-ignore
3022
3199
  queuesDefs: [queueManagerRangoPreset.swapQueueDef],
3023
3200
  context: context,
3024
- onPersistedDataLoaded: _manager => {},
3201
+ onPersistedDataLoaded: manager => {
3202
+ queueManagerRangoPreset.checkWaitingForNetworkChange(manager);
3203
+ },
3025
3204
  isPaused: false
3026
3205
  }, props.children);
3027
3206
  }
@@ -3049,8 +3228,10 @@ const SwapBox = _ref => {
3049
3228
  changeLanguage
3050
3229
  } = useSelectLanguage();
3051
3230
  const clearConnectedWallet = useWalletsStore.use.clearConnectedWallet();
3231
+ const [lastConnectedWalletWithNetwork, setLastConnectedWalletWithNetwork] = React.useState('');
3232
+ const [disconnectedWallet, setDisconnectedWallet] = React.useState();
3052
3233
  const evmBasedChainNames = blockchains.filter(rangoSdk.isEvmBlockchain).map(chain => chain.name);
3053
- const onUpdateState = (type, event, value, _, supportedChains) => {
3234
+ const onUpdateState = (type, event, value, state, supportedChains) => {
3054
3235
  if (event === walletsCore.Events.ACCOUNTS) {
3055
3236
  if (value) {
3056
3237
  const supportedChainNames = walletAndSupportedChainsNames(supportedChains);
@@ -3060,6 +3241,16 @@ const SwapBox = _ref => {
3060
3241
  disconnectWallet(type);
3061
3242
  }
3062
3243
  }
3244
+ if (event === walletsCore.Events.ACCOUNTS && state.connected) {
3245
+ const key = `${type}-${state.network}-${value}`;
3246
+ if (state.connected) {
3247
+ setLastConnectedWalletWithNetwork(key);
3248
+ }
3249
+ }
3250
+ if (event === walletsCore.Events.NETWORK && state.network) {
3251
+ const key = `${type}-${state.network}`;
3252
+ setLastConnectedWalletWithNetwork(key);
3253
+ }
3063
3254
  };
3064
3255
  let providers = providerAll.allProviders();
3065
3256
  React.useEffect(() => {
@@ -3091,7 +3282,12 @@ const SwapBox = _ref => {
3091
3282
  }, React__default.createElement(AppRouter, {
3092
3283
  title: configs.title,
3093
3284
  titleSize: configs.titleSize,
3094
- titleWeight: configs.titleWeight
3285
+ titleWeight: configs.titleWeight,
3286
+ lastConnectedWallet: lastConnectedWalletWithNetwork,
3287
+ disconnectedWallet: disconnectedWallet,
3288
+ clearDisconnectedWallet: () => {
3289
+ setDisconnectedWallet(undefined);
3290
+ }
3095
3291
  }, React__default.createElement(Layout, {
3096
3292
  configs: configs
3097
3293
  }))))));