@rango-dev/widget-embedded 0.1.10-next.99 → 0.1.11-next.0

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 (105) 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/HeaderButtons.d.ts +4 -1
  7. package/dist/components/HeaderButtons.d.ts.map +1 -1
  8. package/dist/components/Layout.d.ts.map +1 -1
  9. package/dist/components/PercentageChange.d.ts +9 -0
  10. package/dist/components/PercentageChange.d.ts.map +1 -0
  11. package/dist/components/SwapDetailsPlaceholder.d.ts +9 -0
  12. package/dist/components/SwapDetailsPlaceholder.d.ts.map +1 -0
  13. package/dist/components/TokenInfo.d.ts.map +1 -1
  14. package/dist/components/TokenPreview.d.ts +3 -2
  15. package/dist/components/TokenPreview.d.ts.map +1 -1
  16. package/dist/components/UpdateUrl.d.ts.map +1 -1
  17. package/dist/components/warnings/BalanceWarnings.d.ts.map +1 -1
  18. package/dist/components/warnings/MinRequiredSlippage.d.ts +1 -1
  19. package/dist/components/warnings/MinRequiredSlippage.d.ts.map +1 -1
  20. package/dist/constants/navigationRoutes.d.ts +0 -1
  21. package/dist/constants/navigationRoutes.d.ts.map +1 -1
  22. package/dist/globalStyles.d.ts.map +1 -1
  23. package/dist/hooks/useConfirmSwap.d.ts.map +1 -1
  24. package/dist/lib.d.ts.map +1 -1
  25. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  26. package/dist/pages/HistoryPage.d.ts.map +1 -1
  27. package/dist/pages/Home.d.ts.map +1 -1
  28. package/dist/pages/LiquiditySourcesPage.d.ts.map +1 -1
  29. package/dist/pages/SelectTokenPage.d.ts.map +1 -1
  30. package/dist/pages/SettingsPage.d.ts.map +1 -1
  31. package/dist/pages/SwapDetailsPage.d.ts.map +1 -1
  32. package/dist/pages/WalletsPage.d.ts +1 -0
  33. package/dist/pages/WalletsPage.d.ts.map +1 -1
  34. package/dist/store/bestRoute.d.ts +3 -0
  35. package/dist/store/bestRoute.d.ts.map +1 -1
  36. package/dist/store/ui.d.ts.map +1 -1
  37. package/dist/store/wallets.d.ts +14 -0
  38. package/dist/store/wallets.d.ts.map +1 -1
  39. package/dist/types/routing.d.ts +15 -2
  40. package/dist/types/routing.d.ts.map +1 -1
  41. package/dist/types/swap.d.ts +6 -0
  42. package/dist/types/swap.d.ts.map +1 -1
  43. package/dist/utils/common.d.ts +1 -0
  44. package/dist/utils/common.d.ts.map +1 -1
  45. package/dist/utils/date.d.ts +3 -0
  46. package/dist/utils/date.d.ts.map +1 -0
  47. package/dist/utils/routing.d.ts +3 -2
  48. package/dist/utils/routing.d.ts.map +1 -1
  49. package/dist/utils/swap.d.ts +16 -5
  50. package/dist/utils/swap.d.ts.map +1 -1
  51. package/dist/utils/time.d.ts +4 -0
  52. package/dist/utils/time.d.ts.map +1 -0
  53. package/dist/utils/wallets.d.ts +1 -1
  54. package/dist/utils/wallets.d.ts.map +1 -1
  55. package/dist/widget-embedded.cjs.development.js +1122 -719
  56. package/dist/widget-embedded.cjs.development.js.map +1 -1
  57. package/dist/widget-embedded.cjs.production.min.js +1122 -719
  58. package/dist/widget-embedded.cjs.production.min.js.map +1 -1
  59. package/dist/widget-embedded.esm.js +1131 -728
  60. package/dist/widget-embedded.esm.js.map +1 -1
  61. package/package.json +12 -11
  62. package/readme.md +1 -2
  63. package/src/App.tsx +30 -5
  64. package/src/QueueManager.tsx +5 -2
  65. package/src/components/AppRouter.tsx +24 -13
  66. package/src/components/AppRoutes.tsx +15 -12
  67. package/src/components/HeaderButtons.tsx +9 -2
  68. package/src/components/Layout.tsx +37 -5
  69. package/src/components/PercentageChange.tsx +33 -0
  70. package/src/components/SwapDetailsPlaceholder.tsx +32 -0
  71. package/src/components/TokenInfo.tsx +20 -4
  72. package/src/components/TokenPreview.tsx +17 -6
  73. package/src/components/UpdateUrl.tsx +1 -3
  74. package/src/components/warnings/BalanceWarnings.tsx +1 -0
  75. package/src/components/warnings/MinRequiredSlippage.tsx +9 -4
  76. package/src/constants/navigationRoutes.ts +0 -1
  77. package/src/globalStyles.ts +2 -1
  78. package/src/hooks/useConfirmSwap.ts +2 -1
  79. package/src/hooks/useNavigateBack.ts +3 -3
  80. package/src/lib.tsx +25 -3
  81. package/src/pages/ConfirmSwapPage.tsx +133 -20
  82. package/src/pages/HistoryPage.tsx +4 -4
  83. package/src/pages/Home.tsx +27 -22
  84. package/src/pages/LiquiditySourcesPage.tsx +2 -0
  85. package/src/pages/SelectTokenPage.tsx +3 -1
  86. package/src/pages/SettingsPage.tsx +3 -0
  87. package/src/pages/SwapDetailsPage.tsx +142 -6
  88. package/src/pages/WalletsPage.tsx +47 -11
  89. package/src/store/bestRoute.ts +143 -16
  90. package/src/store/ui.ts +4 -0
  91. package/src/store/wallets.ts +4 -1
  92. package/src/types/routing.ts +18 -2
  93. package/src/types/swap.ts +7 -0
  94. package/src/utils/common.ts +14 -0
  95. package/src/utils/date.ts +62 -0
  96. package/src/utils/routing.ts +36 -20
  97. package/src/utils/swap.ts +103 -11
  98. package/src/utils/time.ts +52 -0
  99. package/src/utils/wallets.ts +13 -4
  100. package/dist/components/Header.d.ts +0 -10
  101. package/dist/components/Header.d.ts.map +0 -1
  102. package/dist/pages/ConfirmWalletsPage.d.ts +0 -3
  103. package/dist/pages/ConfirmWalletsPage.d.ts.map +0 -1
  104. package/src/components/Header.tsx +0 -37
  105. 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,11 @@ 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');
28
+ var dayjs = _interopDefault(require('dayjs'));
27
29
  var copy = _interopDefault(require('copy-to-clipboard'));
28
- var queueManagerRangoPreset = require('@rango-dev/queue-manager-rango-preset');
29
30
  var Backend = _interopDefault(require('i18next-http-backend'));
30
31
  var LanguageDetector = _interopDefault(require('i18next-browser-languagedetector'));
31
32
 
@@ -40,7 +41,6 @@ const navigationRoutes = {
40
41
  swaps: '/swaps',
41
42
  wallets: '/wallets',
42
43
  confirmSwap: '/confirm-swap',
43
- confirmWallets: '/confirm-wallets',
44
44
  swapDetails: '/swaps/:requestId'
45
45
  };
46
46
 
@@ -70,6 +70,22 @@ function shadeColor(color, percent) {
70
70
  var BB = B.toString(16).length == 1 ? '0' + B.toString(16) : B.toString(16);
71
71
  return '#' + RR + GG + BB;
72
72
  }
73
+ function debounce(fn, time) {
74
+ let timeoutId;
75
+ return wrapper;
76
+ function wrapper() {
77
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
78
+ args[_key] = arguments[_key];
79
+ }
80
+ if (timeoutId) {
81
+ clearTimeout(timeoutId);
82
+ }
83
+ timeoutId = setTimeout(() => {
84
+ timeoutId = null;
85
+ fn(...args);
86
+ }, time);
87
+ }
88
+ }
73
89
 
74
90
  const secondsToString = s => {
75
91
  const seconds = (s % 60).toString().padStart(2, '0');
@@ -336,7 +352,7 @@ function getSortedTokens(chain, tokens, balances, otherChainTokens) {
336
352
  return sortTokens(getTokensWithBalance(filteredTokens, balances));
337
353
  }
338
354
  function tokensAreEqual(tokenA, tokenB) {
339
- return tokenA?.blockchain === tokenB?.blockchain && tokenA?.name === tokenB?.name && tokenA?.address === tokenB?.address;
355
+ return tokenA?.blockchain === tokenB?.blockchain && tokenA?.symbol === tokenB?.symbol && tokenA?.address === tokenB?.address;
340
356
  }
341
357
  function getDefaultToken(sortedTokens, otherToken) {
342
358
  let selectedToken;
@@ -346,7 +362,7 @@ function getDefaultToken(sortedTokens, otherToken) {
346
362
  return selectedToken;
347
363
  }
348
364
  function sortWalletsBasedOnState(wallets) {
349
- return wallets.sort((a, b) => Number(b.state === ui.WalletState.CONNECTED) - Number(a.state === ui.WalletState.CONNECTED) || Number(b.state === ui.WalletState.DISCONNECTED) - Number(a.state === ui.WalletState.DISCONNECTED));
365
+ return wallets.sort((a, b) => Number(b.state === ui.WalletState.CONNECTED) - Number(a.state === ui.WalletState.CONNECTED) || Number(b.state === ui.WalletState.DISCONNECTED || b.state === ui.WalletState.CONNECTING) - Number(a.state === ui.WalletState.DISCONNECTED || a.state === ui.WalletState.CONNECTING));
350
366
  }
351
367
 
352
368
  function getOutputRatio(inputUsdValue, outputUsdValue) {
@@ -429,7 +445,7 @@ function getSwapButtonState(loadingMetaStatus, accounts, loading, bestRoute, has
429
445
  };else if (inputIsZero) return {
430
446
  title: 'Enter an amount',
431
447
  disabled: true
432
- };else if (!bestRoute) return {
448
+ };else if (!bestRoute || !bestRoute.result) return {
433
449
  title: 'Swap',
434
450
  disabled: true
435
451
  };else if (hasLimitError) return {
@@ -462,6 +478,7 @@ function calculatePendingSwap(inputAmount, bestRoute, wallets, settings, validat
462
478
  finishTime: null,
463
479
  requestId: bestRoute.requestId || '',
464
480
  inputAmount: inputAmount,
481
+ //@ts-ignore
465
482
  wallets,
466
483
  status: 'running',
467
484
  isPaused: false,
@@ -476,6 +493,7 @@ function calculatePendingSwap(inputAmount, bestRoute, wallets, settings, validat
476
493
  settings: settings,
477
494
  simulationResult: simulationResult,
478
495
  validateBalanceOrFee,
496
+ //@ts-ignore
479
497
  steps: bestRoute.result?.swaps?.map((swap, index) => {
480
498
  const swapper = meta.swappers.find(swapper => swapper.id === swap.swapperId);
481
499
  const swapperType = swapper?.types[0];
@@ -561,11 +579,10 @@ function hasHighFee(totalFeeInUsd) {
561
579
  }
562
580
  function getMinRequiredSlippage(route) {
563
581
  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;
582
+ return slippages?.map(s => s?.slippage || '0')?.filter(s => parseFloat(s) > 0)?.sort((a, b) => parseFloat(b) - parseFloat(a))?.find(() => true) || null;
565
583
  }
566
584
  function hasProperSlippage(userSlippage, minRequiredSlippage) {
567
585
  if (!minRequiredSlippage) return true;
568
- //@ts-ignore
569
586
  return parseFloat(userSlippage) >= parseFloat(minRequiredSlippage);
570
587
  }
571
588
  function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, selectedWallets, disabledLiquiditySources, slippage, checkPrerequisites) {
@@ -578,6 +595,7 @@ function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, se
578
595
  addresses: [wallet.address]
579
596
  });
580
597
  });
598
+ const filteredBlockchains = selectedWallets.map(wallet => wallet.chain);
581
599
  const requestBody = {
582
600
  amount: inputAmount.toString(),
583
601
  checkPrerequisites,
@@ -595,8 +613,10 @@ function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, se
595
613
  selectedWallets: selectedWalletsMap,
596
614
  swapperGroups: disabledLiquiditySources,
597
615
  swappersGroupsExclude: true,
598
- //@ts-ignore
599
- slippage: slippage.toString()
616
+ slippage: slippage.toString(),
617
+ ...(checkPrerequisites && {
618
+ blockchains: filteredBlockchains
619
+ })
600
620
  };
601
621
  return requestBody;
602
622
  }
@@ -642,6 +662,61 @@ function calcOutputUsdValue(outputAmount, tokenPrice) {
642
662
  const amount = !!outputAmount ? new BigNumber__default(outputAmount) : ZERO;
643
663
  return amount.multipliedBy(tokenPrice || 0);
644
664
  }
665
+ function isNetworkStatusInWarningState(pendingSwapStep) {
666
+ return !!pendingSwapStep && pendingSwapStep.networkStatus !== null && pendingSwapStep.networkStatus !== queueManagerRangoPreset.PendingSwapNetworkStatus.NetworkChanged;
667
+ }
668
+ function getSwapMessages(pendingSwap, currentStep) {
669
+ const textForRemove = 'bellow button or';
670
+ let message = pendingSwap.extraMessage;
671
+ let detailedMessage = pendingSwap.extraMessageDetail;
672
+ if (pendingSwap.networkStatusExtraMessageDetail?.includes(textForRemove)) {
673
+ pendingSwap.networkStatusExtraMessageDetail = pendingSwap.networkStatusExtraMessageDetail.replace(textForRemove, '');
674
+ }
675
+ const networkWarningState = isNetworkStatusInWarningState(currentStep);
676
+ if (networkWarningState) {
677
+ message = pendingSwap.networkStatusExtraMessage || '';
678
+ detailedMessage = pendingSwap.networkStatusExtraMessageDetail || '';
679
+ switch (currentStep?.networkStatus) {
680
+ case queueManagerRangoPreset.PendingSwapNetworkStatus.WaitingForConnectingWallet:
681
+ message = message || 'Waiting for connecting wallet';
682
+ break;
683
+ case queueManagerRangoPreset.PendingSwapNetworkStatus.WaitingForQueue:
684
+ message = message || 'Waiting for other running tasks to be finished';
685
+ break;
686
+ case queueManagerRangoPreset.PendingSwapNetworkStatus.WaitingForNetworkChange:
687
+ message = message || 'Waiting for changing wallet network';
688
+ break;
689
+ }
690
+ }
691
+ detailedMessage = detailedMessage || '';
692
+ message = message || '';
693
+ const isRpc = message?.indexOf('code') !== -1 && message?.indexOf('reason') !== -1;
694
+ return {
695
+ shortMessage: message,
696
+ detailedMessage: {
697
+ content: detailedMessage,
698
+ long: isRpc
699
+ }
700
+ };
701
+ }
702
+ function getLastConvertedTokenInFailedSwap(pendingSwap) {
703
+ let resultToken = null;
704
+ if (pendingSwap.status === 'failed') {
705
+ const lastSuccessStep = pendingSwap.steps.slice().reverse().filter(step => step.status === 'success')[0];
706
+ if (lastSuccessStep) {
707
+ resultToken = {
708
+ blockchain: lastSuccessStep.toBlockchain,
709
+ symbol: lastSuccessStep.toSymbol,
710
+ outputAmount: lastSuccessStep.outputAmount,
711
+ address: lastSuccessStep.toSymbolAddress
712
+ };
713
+ }
714
+ }
715
+ return resultToken;
716
+ }
717
+ function shouldRetrySwap(pendingSwap) {
718
+ return pendingSwap.status === 'failed' && !!pendingSwap.finishTime && new Date().getTime() - parseInt(pendingSwap.finishTime) < 4 * 3600 * 1000;
719
+ }
645
720
 
646
721
  function searchParamsToToken(tokens, searchParams, chain) {
647
722
  if (!chain) return null;
@@ -678,23 +753,27 @@ function getRequiredBalanceOfWallet(selectedWallet, fee) {
678
753
  if (!relatedFeeStatus) return null;
679
754
  return relatedFeeStatus.requiredAssets;
680
755
  }
681
- function isRouteParametersChanged(prevParams, currentParams) {
682
- 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
- }
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
- };
756
+ function isRouteParametersChanged(params) {
757
+ if (params.store === 'bestRoute') {
758
+ const {
759
+ prevState,
760
+ currentState
761
+ } = params;
762
+ return !!currentState.fromToken && !!currentState.toToken && (prevState.fromChain?.name !== currentState.fromChain?.name || prevState.toChain?.name !== currentState.toChain?.name || prevState.fromToken?.symbol !== currentState.fromToken?.symbol || prevState.toToken?.symbol !== currentState.toToken?.symbol || prevState.fromToken?.blockchain !== prevState.fromToken?.blockchain || prevState.toToken?.blockchain !== currentState.toToken?.blockchain || prevState.fromToken?.address !== currentState.fromToken?.address || prevState.toToken?.address !== currentState.toToken?.address || prevState.inputAmount !== currentState.inputAmount);
763
+ } else if (params.store === 'settings') {
764
+ const {
765
+ prevState,
766
+ currentState
767
+ } = params;
768
+ return prevState.slippage !== currentState.slippage || prevState.customSlippage !== currentState.customSlippage || prevState.disabledLiquiditySources?.length !== currentState.disabledLiquiditySources?.length || prevState.infiniteApprove || currentState.infiniteApprove;
769
+ }
770
+ return false;
697
771
  }
772
+ //todo: refactor bestRoute store and add loadingStatus
773
+ const getBestRouteStatus = (loading, error) => {
774
+ if (loading) return 'loading';
775
+ if (error) return 'failed';else return 'success';
776
+ };
698
777
 
699
778
  const createSelectors = _store => {
700
779
  let store = _store;
@@ -845,7 +924,7 @@ const useWalletsStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.creat
845
924
  }
846
925
  });
847
926
  return {
848
- selectedWallets: state.selectedWallets.concat(selectedWallets)
927
+ selectedWallets: selectedWallets
849
928
  };
850
929
  }),
851
930
  setSelectedWallet: wallet => set(state => ({
@@ -877,6 +956,7 @@ useWalletsStore.subscribe(state => state.balances, balances => {
877
956
  }, {
878
957
  equalityFn: shallow.shallow
879
958
  });
959
+ const fetchingBalanceSelector = state => !!state.balances.find(wallet => wallet.loading);
880
960
 
881
961
  const getUsdValue = (token, amount) => new BigNumber__default(amount || ZERO).multipliedBy(token?.usdPrice || 0);
882
962
  const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/middleware.subscribeWithSelector(set => ({
@@ -896,6 +976,7 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.cre
896
976
  setBestRoute: bestRoute => set(state => {
897
977
  let outputAmount = null;
898
978
  let outputUsdValue = ZERO;
979
+ if (!state.inputAmount || state.inputAmount === '0') return {};
899
980
  if (!!bestRoute) {
900
981
  outputAmount = !!bestRoute.result?.outputAmount ? new BigNumber__default(bestRoute.result?.outputAmount) : null;
901
982
  outputUsdValue = calcOutputUsdValue(bestRoute.result?.outputAmount, getBestRouteToTokenUsdPrice(bestRoute) || state.toToken?.usdPrice);
@@ -963,7 +1044,58 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.cre
963
1044
  inputUsdValue: getUsdValue(state.fromToken, amount)
964
1045
  })
965
1046
  }));
966
- }
1047
+ },
1048
+ retry: pendingSwap => {
1049
+ const {
1050
+ tokens,
1051
+ blockchains
1052
+ } = useMetaStore.getState().meta;
1053
+ const balances = useWalletsStore.getState().balances;
1054
+ const failedIndex = pendingSwap.status === 'failed' ? pendingSwap.steps.findIndex(s => s.status === 'failed') : null;
1055
+ if (failedIndex === null || failedIndex < 0) return;
1056
+ const firstStep = pendingSwap.steps[0];
1057
+ const lastStep = pendingSwap.steps[pendingSwap.steps.length - 1];
1058
+ const fromChain = blockchains.find(blockchain => blockchain.name === firstStep.fromBlockchain) || null;
1059
+ const toChain = blockchains.find(blockchain => blockchain.name === lastStep.toBlockchain) || null;
1060
+ const fromToken = tokens.find(token => tokensAreEqual(token, {
1061
+ blockchain: firstStep.fromBlockchain,
1062
+ symbol: firstStep.fromSymbol,
1063
+ address: firstStep.fromSymbolAddress
1064
+ }));
1065
+ const toToken = tokens.find(token => tokensAreEqual(token, {
1066
+ blockchain: lastStep.toBlockchain,
1067
+ symbol: lastStep.toSymbol,
1068
+ address: lastStep.toSymbolAddress
1069
+ }));
1070
+ const sortedSourceTokens = getSortedTokens(fromChain, tokens, balances, []);
1071
+ const sortedDestinationTokens = getSortedTokens(toChain, tokens, balances, []);
1072
+ const inputAmount = pendingSwap.inputAmount;
1073
+ set({
1074
+ fromChain,
1075
+ fromToken,
1076
+ inputAmount,
1077
+ outputAmount: null,
1078
+ inputUsdValue: getUsdValue(fromToken || null, inputAmount),
1079
+ outputUsdValue: new BigNumber__default(0),
1080
+ toChain,
1081
+ toToken,
1082
+ bestRoute: null,
1083
+ loading: false,
1084
+ error: '',
1085
+ sourceTokens: sortedSourceTokens,
1086
+ destinationTokens: sortedDestinationTokens
1087
+ });
1088
+ },
1089
+ switchFromAndTo: () => set(state => ({
1090
+ fromChain: state.toChain,
1091
+ fromToken: state.toToken,
1092
+ toChain: state.fromChain,
1093
+ toToken: state.fromToken,
1094
+ sourceTokens: state.destinationTokens,
1095
+ destinationTokens: state.sourceTokens,
1096
+ inputAmount: state.outputAmount?.toString() || '',
1097
+ inputUsdValue: getUsdValue(state.toToken, state.outputAmount?.toString() || '')
1098
+ }))
967
1099
  }))));
968
1100
  const bestRoute = (bestRouteStore, settingsStore) => {
969
1101
  let abortController = null;
@@ -978,12 +1110,12 @@ const bestRoute = (bestRouteStore, settingsStore) => {
978
1110
  customSlippage,
979
1111
  disabledLiquiditySources
980
1112
  } = settingsStore.getState();
981
- if (!fromToken || !toToken || !inputAmount) return;
1113
+ if (!fromToken || !toToken || !inputAmount || inputAmount === '0') return;
982
1114
  abortController?.abort();
983
1115
  abortController = new AbortController();
984
1116
  const userSlippage = !!customSlippage ? customSlippage : slippage;
985
1117
  const requestBody = createBestRouteRequestBody(fromToken, toToken, inputAmount, [], [], disabledLiquiditySources, userSlippage, false);
986
- bestRouteStore.setState({
1118
+ if (!bestRouteStore.getState().loading) bestRouteStore.setState({
987
1119
  loading: true,
988
1120
  bestRoute: null,
989
1121
  outputAmount: null,
@@ -1008,24 +1140,56 @@ const bestRoute = (bestRouteStore, settingsStore) => {
1008
1140
  });
1009
1141
  });
1010
1142
  };
1143
+ const debouncedFetchBestRoute = debounce(fetchBestRoute, 600);
1144
+ const bestRouteParamsListener = () => {
1145
+ const {
1146
+ fromToken,
1147
+ toToken,
1148
+ inputAmount,
1149
+ inputUsdValue
1150
+ } = useBestRouteStore.getState();
1151
+ if (!inputAmount || inputAmount === '0' || inputUsdValue.eq(0)) return;
1152
+ if (tokensAreEqual(fromToken, toToken)) return bestRouteStore.setState({
1153
+ loading: false,
1154
+ bestRoute: null,
1155
+ outputAmount: new BigNumber__default(inputAmount),
1156
+ outputUsdValue: inputUsdValue
1157
+ });
1158
+ if (!bestRouteStore.getState().loading) bestRouteStore.setState({
1159
+ loading: true,
1160
+ bestRoute: null,
1161
+ outputAmount: null,
1162
+ outputUsdValue: new BigNumber__default(0)
1163
+ });
1164
+ debouncedFetchBestRoute();
1165
+ };
1011
1166
  useBestRouteStore.subscribe(state => ({
1012
1167
  fromChain: state.fromChain,
1013
1168
  fromToken: state.fromToken,
1014
1169
  toChain: state.toChain,
1015
1170
  toToken: state.toToken,
1016
1171
  inputAmount: state.inputAmount
1017
- }), fetchBestRoute.bind(null), {
1018
- equalityFn: (prevState, state) => {
1019
- if (isRouteParametersChanged(prevState, state)) return false;else return true;
1172
+ }), bestRouteParamsListener, {
1173
+ equalityFn: (prevState, currentState) => {
1174
+ if (isRouteParametersChanged({
1175
+ store: 'bestRoute',
1176
+ prevState,
1177
+ currentState
1178
+ })) return false;else return true;
1020
1179
  }
1021
1180
  });
1022
1181
  useSettingsStore.subscribe(state => ({
1023
1182
  slippage: state.slippage,
1024
1183
  customSlippage: state.customSlippage,
1025
- disabledLiquiditySources: state.disabledLiquiditySources
1026
- }), fetchBestRoute.bind(null), {
1027
- equalityFn: (prevState, state) => {
1028
- if (isRouteParametersChanged(prevState, state)) return false;else return true;
1184
+ disabledLiquiditySources: state.disabledLiquiditySources,
1185
+ infiniteApprove: state.infiniteApprove
1186
+ }), bestRouteParamsListener, {
1187
+ equalityFn: (prevState, currentState) => {
1188
+ if (isRouteParametersChanged({
1189
+ store: 'settings',
1190
+ prevState,
1191
+ currentState
1192
+ })) return false;else return true;
1029
1193
  }
1030
1194
  });
1031
1195
  return {
@@ -1048,11 +1212,15 @@ var SearchParams;
1048
1212
  const useUiStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()(set => ({
1049
1213
  connectWalletsButtonDisabled: false,
1050
1214
  selectedSwapRequestId: null,
1215
+ currentPage: '',
1051
1216
  toggleConnectWalletsButton: () => set(state => ({
1052
1217
  connectWalletsButtonDisabled: !state.connectWalletsButtonDisabled
1053
1218
  })),
1054
1219
  setSelectedSwap: requestId => set({
1055
1220
  selectedSwapRequestId: requestId
1221
+ }),
1222
+ setCurrentPage: path => set({
1223
+ currentPage: path
1056
1224
  })
1057
1225
  })));
1058
1226
 
@@ -1093,7 +1261,7 @@ function UpdateUrl() {
1093
1261
  toChainString = '',
1094
1262
  toTokenString = '',
1095
1263
  fromAmount = '';
1096
- if (loadingStatus !== 'success' && ![navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname)) {
1264
+ if (loadingStatus !== 'success' && location.pathname != navigationRoutes.confirmSwap) {
1097
1265
  fromChainString = searchParamsRef.current[SearchParams.FROM_CHAIN];
1098
1266
  fromTokenString = searchParamsRef.current[SearchParams.FROM_TOKEN];
1099
1267
  toChainString = searchParamsRef.current[SearchParams.TO_CHAIN];
@@ -1186,65 +1354,18 @@ function UpdateUrl() {
1186
1354
  return null;
1187
1355
  }
1188
1356
 
1189
- const ButtonsContainer = /*#__PURE__*/ui.styled('div', {
1190
- display: 'flex'
1191
- });
1192
- function HeaderButtons(props) {
1193
- const {
1194
- onClickRefresh
1195
- } = props;
1196
- const navigate = reactRouterDom.useNavigate();
1197
- return React__default.createElement(ButtonsContainer, null, React__default.createElement(ui.Tooltip, {
1198
- content: "Refresh"
1199
- }, React__default.createElement(ui.Button, {
1200
- variant: "ghost",
1201
- onClick: onClickRefresh
1202
- }, React__default.createElement(ui.RetryIcon, {
1203
- size: 24
1204
- }))), React__default.createElement(ui.Tooltip, {
1205
- content: "Transactions History"
1206
- }, React__default.createElement(ui.Button, {
1207
- variant: "ghost",
1208
- onClick: () => navigate(navigationRoutes.swaps)
1209
- }, React__default.createElement(ui.HistoryIcon, {
1210
- size: 24
1211
- }))), React__default.createElement(ui.Tooltip, {
1212
- content: "Settings"
1213
- }, React__default.createElement(ui.Button, {
1214
- variant: "ghost",
1215
- onClick: () => navigate(navigationRoutes.settings)
1216
- }, React__default.createElement(ui.SettingsIcon, {
1217
- size: 24
1218
- }))));
1219
- }
1220
-
1221
- const HeaderContainer = /*#__PURE__*/ui.styled('div', {
1222
- display: 'flex',
1223
- justifyContent: 'space-between',
1224
- alignItems: 'center',
1225
- width: '100%',
1226
- padding: '$16 0'
1227
- });
1228
- function Header(props) {
1357
+ function PercentageChange(props) {
1229
1358
  const {
1230
- onClickRefresh,
1231
- title,
1232
- titleSize,
1233
- titleWeight
1359
+ inputUsdValue,
1360
+ outputUsdValue
1234
1361
  } = props;
1235
- const {
1236
- t
1237
- } = reactI18next.useTranslation();
1238
- const titleStyle = ui.css({
1239
- fontSize: `${titleSize}px !important`,
1240
- fontWeight: `${titleWeight} !important`
1241
- });
1242
- return React__default.createElement(HeaderContainer, null, React__default.createElement(ui.Typography, {
1243
- variant: "h4",
1244
- className: titleStyle()
1245
- }, title ? t(title.toLocaleLowerCase()) : ''), React__default.createElement(HeaderButtons, {
1246
- onClickRefresh: onClickRefresh
1247
- }));
1362
+ if (!inputUsdValue || !outputUsdValue || !outputUsdValue.gt(0)) return null;
1363
+ const percentageChange = getPercentageChange(inputUsdValue.toNumber(), outputUsdValue.toNumber());
1364
+ const showPercentageChange = percentageChange?.lt(0);
1365
+ return React__default.createElement(React__default.Fragment, null, showPercentageChange && React__default.createElement(ui.Typography, {
1366
+ variant: "caption",
1367
+ color: "$error500"
1368
+ }, `(${numberToString(percentageChange, 0, 2)}%)`));
1248
1369
  }
1249
1370
 
1250
1371
  const Box = /*#__PURE__*/ui.styled('div', {
@@ -1290,6 +1411,13 @@ const Container = /*#__PURE__*/ui.styled('div', {
1290
1411
  '.amount': {
1291
1412
  width: '30%'
1292
1413
  }
1414
+ },
1415
+ '.output-usd': {
1416
+ display: 'flex',
1417
+ div: {
1418
+ display: 'flex',
1419
+ paddingLeft: '$8'
1420
+ }
1293
1421
  }
1294
1422
  });
1295
1423
  const StyledImage = /*#__PURE__*/ui.styled('img', {
@@ -1374,10 +1502,15 @@ function TokenInfo(props) {
1374
1502
  type: "primary",
1375
1503
  variant: "ghost",
1376
1504
  size: "compact"
1377
- }, t('Max')))) : React__default.createElement(ui.Typography, {
1505
+ }, t('Max')))) : React__default.createElement("div", {
1506
+ className: "output-usd"
1507
+ }, React__default.createElement(PercentageChange, {
1508
+ inputUsdValue: inputUsdValue,
1509
+ outputUsdValue: props.outputUsdValue
1510
+ }), React__default.createElement("div", null, React__default.createElement(ui.Typography, {
1378
1511
  variant: "caption",
1379
1512
  color: "neutrals600"
1380
- }, `$${numberToString(props.outputUsdValue)}`)), React__default.createElement("div", {
1513
+ }, `$${numberToString(props.outputUsdValue)}`)))), React__default.createElement("div", {
1381
1514
  className: "form"
1382
1515
  }, React__default.createElement(ui.Button, {
1383
1516
  className: "selectors",
@@ -1534,6 +1667,39 @@ const errorMessages = {
1534
1667
  genericServerError: 'Error connecting server, please reload the app and try again'
1535
1668
  };
1536
1669
 
1670
+ const ButtonsContainer = /*#__PURE__*/ui.styled('div', {
1671
+ display: 'flex'
1672
+ });
1673
+ function HeaderButtons(props) {
1674
+ const {
1675
+ onClickRefresh
1676
+ } = props;
1677
+ const navigate = reactRouterDom.useNavigate();
1678
+ return React__default.createElement(ButtonsContainer, null, React__default.createElement(ui.Tooltip, {
1679
+ content: "Refresh"
1680
+ }, React__default.createElement(ui.Button, {
1681
+ variant: "ghost",
1682
+ onClick: onClickRefresh,
1683
+ disabled: !onClickRefresh
1684
+ }, React__default.createElement(ui.RetryIcon, {
1685
+ size: 24
1686
+ }))), React__default.createElement(ui.Tooltip, {
1687
+ content: "Transactions History"
1688
+ }, React__default.createElement(ui.Button, {
1689
+ variant: "ghost",
1690
+ onClick: () => navigate(navigationRoutes.swaps)
1691
+ }, React__default.createElement(ui.HistoryIcon, {
1692
+ size: 24
1693
+ }))), React__default.createElement(ui.Tooltip, {
1694
+ content: "Settings"
1695
+ }, React__default.createElement(ui.Button, {
1696
+ variant: "ghost",
1697
+ onClick: () => navigate(navigationRoutes.settings)
1698
+ }, React__default.createElement(ui.SettingsIcon, {
1699
+ size: 24
1700
+ }))));
1701
+ }
1702
+
1537
1703
  const Container$2 = /*#__PURE__*/ui.styled('div', {
1538
1704
  display: 'flex',
1539
1705
  flexDirection: 'column'
@@ -1558,9 +1724,7 @@ const Alerts = /*#__PURE__*/ui.styled('div', {
1558
1724
  });
1559
1725
  function Home(props) {
1560
1726
  const {
1561
- title = 'SWAP',
1562
- titleSize = 18,
1563
- titleWeight = 600
1727
+ title = 'SWAP'
1564
1728
  } = props;
1565
1729
  const isRouterInContext = reactRouterDom.useInRouterContext();
1566
1730
  const navigate = reactRouterDom.useNavigate();
@@ -1569,10 +1733,6 @@ function Home(props) {
1569
1733
  const fromToken = useBestRouteStore.use.fromToken();
1570
1734
  const toChain = useBestRouteStore.use.toChain();
1571
1735
  const toToken = useBestRouteStore.use.toToken();
1572
- const setFromChain = useBestRouteStore.use.setFromChain();
1573
- const setFromToken = useBestRouteStore.use.setFromToken();
1574
- const setToChain = useBestRouteStore.use.setToChain();
1575
- const setToToken = useBestRouteStore.use.setToToken();
1576
1736
  const setInputAmount = useBestRouteStore.use.setInputAmount();
1577
1737
  const inputUsdValue = useBestRouteStore.use.inputUsdValue();
1578
1738
  const inputAmount = useBestRouteStore.use.inputAmount();
@@ -1584,14 +1744,8 @@ function Home(props) {
1584
1744
  const bestRouteError = useBestRouteStore.use.error();
1585
1745
  const loadingMetaStatus = useMetaStore.use.loadingStatus();
1586
1746
  const accounts = useWalletsStore.use.accounts();
1587
- const swithFromAndTo = () => {
1588
- setFromChain(toChain);
1589
- setFromToken(toToken);
1590
- setToChain(fromChain);
1591
- setToToken(fromToken);
1592
- setInputAmount(outputAmount?.toString() || '');
1593
- setCount(prev => prev + 1);
1594
- };
1747
+ const setCurrentPage = useUiStore.use.setCurrentPage();
1748
+ const switchFromAndTo = useBestRouteStore.use.switchFromAndTo();
1595
1749
  const errorMessage = loadingMetaStatus === 'failed' ? errorMessages.genericServerError : bestRouteError;
1596
1750
  const needsToWarnEthOnPath = false;
1597
1751
  const showBestRoute = inputAmount && (!!bestRoute || fetchingBestRoute || bestRouteError);
@@ -1607,11 +1761,15 @@ function Home(props) {
1607
1761
  const swapButtonState = getSwapButtonState(loadingMetaStatus, accounts, fetchingBestRoute, bestRoute, hasLimitError(bestRoute), highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath, inputIsZero);
1608
1762
  const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
1609
1763
  const highFee = hasHighFee(totalFeeInUsd);
1610
- return React__default.createElement(Container$2, null, React__default.createElement(Header, {
1764
+ React.useEffect(() => {
1765
+ setCurrentPage(navigationRoutes.home);
1766
+ return setCurrentPage.bind(null, '');
1767
+ }, []);
1768
+ return React__default.createElement(Container$2, null, React__default.createElement(ui.Header, {
1611
1769
  title: title,
1612
- titleSize: titleSize,
1613
- titleWeight: titleWeight,
1614
- onClickRefresh: fetchBestRoute
1770
+ suffix: React__default.createElement(HeaderButtons, {
1771
+ onClickRefresh: !!bestRoute ? fetchBestRoute : undefined
1772
+ })
1615
1773
  }), React__default.createElement(FromContainer, null, React__default.createElement(TokenInfo, {
1616
1774
  type: "From",
1617
1775
  chain: fromChain,
@@ -1620,9 +1778,12 @@ function Home(props) {
1620
1778
  inputAmount: inputAmount
1621
1779
  }), React__default.createElement(SwitchButtonContainer, null, React__default.createElement(ui.Button, {
1622
1780
  variant: "ghost",
1623
- onClick: swithFromAndTo
1781
+ onClick: () => {
1782
+ switchFromAndTo();
1783
+ setCount(prev => prev + 1);
1784
+ }
1624
1785
  }, React__default.createElement(ui.VerticalSwapIcon, {
1625
- size: 24
1786
+ size: 32
1626
1787
  }), isRouterInContext && React__default.createElement(SwithFromAndTo, {
1627
1788
  count: count
1628
1789
  })))), React__default.createElement(TokenInfo, {
@@ -1656,7 +1817,7 @@ function Home(props) {
1656
1817
  disabled: swapButtonState.disabled,
1657
1818
  onClick: () => {
1658
1819
  if (swapButtonState.title === 'Connect Wallet') navigate(navigationRoutes.wallets);else {
1659
- navigate(navigationRoutes.confirmWallets, {
1820
+ navigate(navigationRoutes.confirmSwap, {
1660
1821
  replace: true
1661
1822
  });
1662
1823
  }
@@ -1673,12 +1834,12 @@ const Route = _ref => {
1673
1834
  const navigate = reactRouter.useNavigate();
1674
1835
  const ref = React.useRef(true);
1675
1836
  React.useEffect(() => {
1676
- if ([navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname) && ref.current) navigate(navigationRoutes.home + location.search, {
1837
+ if (location.pathname === navigationRoutes.confirmSwap && ref.current) navigate(navigationRoutes.home + location.search, {
1677
1838
  state: 'redirect'
1678
1839
  });
1679
1840
  ref.current = false;
1680
1841
  }, []);
1681
- if ([navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname) && ref.current) return React__default.createElement(Home, Object.assign({}, props));
1842
+ if (location.pathname === navigationRoutes.confirmSwap && ref.current) return React__default.createElement(Home, Object.assign({}, props));
1682
1843
  return React__default.createElement(React__default.Fragment, null, " ", children);
1683
1844
  };
1684
1845
  function AppRouter(_ref2) {
@@ -1688,52 +1849,34 @@ function AppRouter(_ref2) {
1688
1849
  } = _ref2;
1689
1850
  const isRouterInContext = reactRouter.useInRouterContext();
1690
1851
  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
1852
  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
- }));
1853
+ blockchains
1854
+ } = useMetaStore.use.meta();
1855
+ const evmChains = blockchains.filter(rangoTypes.isEvmBlockchain);
1856
+ queueManagerRangoPreset.useQueueManager({
1857
+ lastConnectedWallet: props.lastConnectedWallet,
1858
+ clearDisconnectedWallet: props.clearDisconnectedWallet,
1859
+ disconnectedWallet: props.disconnectedWallet,
1860
+ evmChains,
1861
+ notifier: () => {}
1862
+ });
1863
+ return React__default.createElement(React__default.Fragment, null, React__default.createElement(Router, Object.assign({}, props), children), isRouterInContext && React__default.createElement(UpdateUrl, null));
1722
1864
  }
1723
1865
 
1724
1866
  function useNavigateBack() {
1725
1867
  const isRouterInContext = reactRouterDom.useInRouterContext();
1726
1868
  const navigate = reactRouterDom.useNavigate();
1727
1869
  const navigateBackFrom = currentRoute => {
1870
+ if (currentRoute === navigationRoutes.swapDetails) return navigate(navigationRoutes.swaps, {
1871
+ replace: true
1872
+ });
1728
1873
  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, {
1874
+ if ([navigationRoutes.fromChain, navigationRoutes.fromToken, navigationRoutes.toChain, navigationRoutes.toToken, navigationRoutes.settings, navigationRoutes.wallets, navigationRoutes.swaps, navigationRoutes.confirmSwap].includes(currentRoute)) navigate(navigationRoutes.home, {
1730
1875
  replace: true
1731
1876
  });else if (currentRoute === navigationRoutes.liquiditySources) navigate(navigationRoutes.settings, {
1732
1877
  replace: true
1733
1878
  });else if (currentRoute === navigationRoutes.swapDetails) navigate(navigationRoutes.swaps, {
1734
1879
  replace: true
1735
- });else if (currentRoute === navigationRoutes.confirmSwap) navigate(navigationRoutes.confirmWallets, {
1736
- replace: true
1737
1880
  });
1738
1881
  }
1739
1882
  };
@@ -1742,122 +1885,197 @@ function useNavigateBack() {
1742
1885
  };
1743
1886
  }
1744
1887
 
1745
- var ConfirmSwapErrorTypes;
1746
- (function (ConfirmSwapErrorTypes) {
1747
- ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["NO_ROUTE"] = 0] = "NO_ROUTE";
1748
- ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS"] = 1] = "ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS";
1749
- ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["REQUEST_FAILED"] = 2] = "REQUEST_FAILED";
1750
- ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["INSUFFICIENT_SLIPPAGE"] = 3] = "INSUFFICIENT_SLIPPAGE";
1751
- })(ConfirmSwapErrorTypes || (ConfirmSwapErrorTypes = {}));
1752
- var ConfirmSwapWarningTypes;
1753
- (function (ConfirmSwapWarningTypes) {
1754
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_UPDATED"] = 0] = "ROUTE_UPDATED";
1755
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_SWAPPERS_UPDATED"] = 1] = "ROUTE_SWAPPERS_UPDATED";
1756
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_COINS_UPDATED"] = 2] = "ROUTE_COINS_UPDATED";
1757
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_AND_OUTPUT_AMOUNT_UPDATED"] = 3] = "ROUTE_AND_OUTPUT_AMOUNT_UPDATED";
1758
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["INSUFFICIENT_BALANCE"] = 4] = "INSUFFICIENT_BALANCE";
1759
- })(ConfirmSwapWarningTypes || (ConfirmSwapWarningTypes = {}));
1760
-
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', {
1888
+ const Box$1 = /*#__PURE__*/ui.styled('div', {
1889
+ display: 'flex',
1890
+ flexDirection: 'column',
1891
+ width: '100%'
1892
+ });
1893
+ const Container$3 = /*#__PURE__*/ui.styled('div', {
1894
+ boxSizing: 'border-box',
1895
+ borderRadius: '$5',
1896
+ padding: '$8 $16 $16 $16',
1796
1897
  variants: {
1797
- showListStyle: {
1798
- true: {
1799
- paddingLeft: '$24'
1898
+ type: {
1899
+ filled: {
1900
+ backgroundColor: '$neutrals300'
1901
+ },
1902
+ outlined: {
1903
+ border: '1px solid $neutrals300'
1800
1904
  }
1801
1905
  }
1802
- }
1803
- });
1804
- const ListItem = /*#__PURE__*/ui.styled('li', {
1805
- variants: {
1806
- showListStyle: {
1807
- true: {
1808
- listStyleType: 'disc',
1809
- listStylePosition: 'outside'
1906
+ },
1907
+ defaultVariants: {
1908
+ type: 'filled'
1909
+ },
1910
+ '.head': {
1911
+ display: 'flex',
1912
+ justifyContent: 'space-between',
1913
+ alignItems: 'center',
1914
+ minHeight: '32px',
1915
+ '.usd-value': {
1916
+ paddingLeft: '$8'
1917
+ }
1918
+ },
1919
+ '.form': {
1920
+ display: 'flex',
1921
+ width: '100%',
1922
+ padding: '$2 0',
1923
+ '.selectors': {
1924
+ width: '35%',
1925
+ '._text': {
1926
+ whiteSpace: 'nowrap',
1927
+ overflow: 'hidden',
1928
+ textOverflow: 'ellipsis'
1810
1929
  }
1930
+ },
1931
+ '.amount': {
1932
+ width: '30%'
1811
1933
  }
1812
1934
  }
1813
1935
  });
1814
- const Message = /*#__PURE__*/ui.styled(ui.Typography, {
1815
- display: 'block'
1936
+ const StyledImage$1 = /*#__PURE__*/ui.styled('img', {
1937
+ width: '$24',
1938
+ maxHeight: '$24'
1816
1939
  });
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))));
1940
+ const ImagePlaceholder$1 = /*#__PURE__*/ui.styled('span', {
1941
+ width: '24px',
1942
+ height: '24px',
1943
+ backgroundColor: '$neutrals300',
1944
+ borderRadius: '99999px'
1945
+ });
1946
+ const OutputContainer$1 = /*#__PURE__*/ui.styled('div', {
1947
+ windth: '100%',
1948
+ height: '$48',
1949
+ borderRadius: '$5',
1950
+ backgroundColor: '$background',
1951
+ border: '1px solid transparent',
1952
+ position: 'relative',
1953
+ display: 'flex',
1954
+ alignItems: 'center',
1955
+ paddingLeft: '$8',
1956
+ paddingRight: '$8'
1957
+ });
1958
+ function TokenPreview(props) {
1959
+ const {
1960
+ chain,
1961
+ token,
1962
+ loadingStatus,
1963
+ percentageChange
1964
+ } = props;
1965
+ const {
1966
+ t
1967
+ } = reactI18next.useTranslation();
1968
+ const ItemSuffix = React__default.createElement("div", {
1969
+ style: {
1970
+ display: 'flex',
1971
+ justifyContent: 'center',
1972
+ alignItems: 'center'
1973
+ }
1974
+ }, loadingStatus === 'failed' && React__default.createElement(ui.InfoCircleIcon, {
1975
+ color: "error",
1976
+ size: 24
1977
+ }));
1978
+ return React__default.createElement(Box$1, null, React__default.createElement(Container$3, {
1979
+ type: 'outlined'
1980
+ }, React__default.createElement("div", {
1981
+ className: "head"
1982
+ }, React__default.createElement(ui.Typography, {
1983
+ variant: "body2",
1984
+ color: "neutrals800"
1985
+ }, props.label), React__default.createElement("div", null, percentageChange, props.usdValue && React__default.createElement(ui.Typography, {
1986
+ variant: "caption",
1987
+ color: "neutrals600",
1988
+ className: "usd-value"
1989
+ }, `$${numberToString(props.usdValue)}`))), React__default.createElement("div", {
1990
+ className: "form"
1991
+ }, React__default.createElement(ui.Button, {
1992
+ className: "selectors",
1993
+ variant: "outlined",
1994
+ loading: loadingStatus === 'loading',
1995
+ prefix: loadingStatus === 'success' && chain ? React__default.createElement(StyledImage$1, {
1996
+ src: chain.logo
1997
+ }) : React__default.createElement(ImagePlaceholder$1, null),
1998
+ suffix: ItemSuffix,
1999
+ align: "start",
2000
+ size: "large"
2001
+ }, loadingStatus === 'success' && chain ? chain.displayName : t('Chain')), React__default.createElement(ui.Spacer, {
2002
+ size: 12
2003
+ }), React__default.createElement(ui.Button, {
2004
+ className: "selectors",
2005
+ variant: "outlined",
2006
+ loading: loadingStatus === 'loading',
2007
+ prefix: loadingStatus === 'success' && token ? React__default.createElement(StyledImage$1, {
2008
+ src: token.image
2009
+ }) : React__default.createElement(ImagePlaceholder$1, null),
2010
+ suffix: ItemSuffix,
2011
+ size: "large",
2012
+ align: "start"
2013
+ }, loadingStatus === 'success' && token ? token.symbol : t('Token')), React__default.createElement(ui.Spacer, {
2014
+ size: 12
2015
+ }), React__default.createElement("div", {
2016
+ className: "amount"
2017
+ }, React__default.createElement(OutputContainer$1, null, React__default.createElement(ui.Typography, {
2018
+ variant: "h4"
2019
+ }, props.amount))))));
1829
2020
  }
1830
2021
 
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
- });
2022
+ const Container$4 = /*#__PURE__*/ui.styled('div', {
2023
+ display: 'flex',
2024
+ alignItems: 'center',
2025
+ justifyContent: 'space-between',
2026
+ padding: '$8',
2027
+ borderRadius: '$5',
2028
+ backgroundColor: '$neutrals300',
2029
+ color: '$neutrals800',
2030
+ fontSize: '$12',
2031
+ '.routes': {
2032
+ display: 'flex',
2033
+ alignItems: 'center'
2034
+ },
2035
+ '.fee': {
2036
+ display: 'flex',
2037
+ alignItems: 'center'
2038
+ }
2039
+ });
2040
+ function RoutesOverview(props) {
2041
+ if (!props.routes) return null;
2042
+ const swaps = props.routes.result?.swaps;
2043
+ return React__default.createElement(Container$4, null, React__default.createElement("div", {
2044
+ className: "routes"
2045
+ }, swaps?.map((swap, idx) => {
2046
+ const isLast = idx + 1 == swaps.length;
2047
+ return React__default.createElement(React__default.Fragment, null, React__default.createElement("div", {
2048
+ className: "route"
2049
+ }, swap.from.symbol), React__default.createElement(ui.ChevronRightIcon, {
2050
+ size: 12
2051
+ }), isLast ? React__default.createElement("div", {
2052
+ className: "route"
2053
+ }, swap.to.symbol) : null);
2054
+ })), props.totalFee ? React__default.createElement("div", {
2055
+ className: "fee"
2056
+ }, React__default.createElement(ui.GasIcon, {
2057
+ size: 12
2058
+ }), React__default.createElement(ui.Spacer, {
2059
+ size: 4
2060
+ }), "$", props.totalFee) : null);
1859
2061
  }
1860
2062
 
2063
+ var ConfirmSwapErrorTypes;
2064
+ (function (ConfirmSwapErrorTypes) {
2065
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["NO_ROUTE"] = 0] = "NO_ROUTE";
2066
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS"] = 1] = "ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS";
2067
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["REQUEST_FAILED"] = 2] = "REQUEST_FAILED";
2068
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["INSUFFICIENT_SLIPPAGE"] = 3] = "INSUFFICIENT_SLIPPAGE";
2069
+ })(ConfirmSwapErrorTypes || (ConfirmSwapErrorTypes = {}));
2070
+ var ConfirmSwapWarningTypes;
2071
+ (function (ConfirmSwapWarningTypes) {
2072
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_UPDATED"] = 0] = "ROUTE_UPDATED";
2073
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_SWAPPERS_UPDATED"] = 1] = "ROUTE_SWAPPERS_UPDATED";
2074
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_COINS_UPDATED"] = 2] = "ROUTE_COINS_UPDATED";
2075
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_AND_OUTPUT_AMOUNT_UPDATED"] = 3] = "ROUTE_AND_OUTPUT_AMOUNT_UPDATED";
2076
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["INSUFFICIENT_BALANCE"] = 4] = "INSUFFICIENT_BALANCE";
2077
+ })(ConfirmSwapWarningTypes || (ConfirmSwapWarningTypes = {}));
2078
+
1861
2079
  function useConfirmSwap() {
1862
2080
  const fromToken = useBestRouteStore.use.fromToken();
1863
2081
  const toToken = useBestRouteStore.use.toToken();
@@ -1898,6 +2116,7 @@ function useConfirmSwap() {
1898
2116
  proceedAnywayRef.current = false;
1899
2117
  if (confiremedRouteRef.current) {
1900
2118
  const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRouteRef.current, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
2119
+ //@ts-ignore
1901
2120
  return newSwap;
1902
2121
  }
1903
2122
  return;
@@ -1960,6 +2179,7 @@ function useConfirmSwap() {
1960
2179
  disabledSwappersGroups: disabledLiquiditySources
1961
2180
  };
1962
2181
  const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRoute, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
2182
+ //@ts-ignore
1963
2183
  return newSwap;
1964
2184
  } else if (!proceedAnywayRef.current) {
1965
2185
  proceedAnywayRef.current = true;
@@ -1989,57 +2209,263 @@ function useConfirmSwap() {
1989
2209
  };
1990
2210
  }
1991
2211
 
1992
- function ConfirmSwapPage() {
1993
- const setSelectedSwap = useUiStore.use.setSelectedSwap();
1994
- const {
1995
- navigateBackFrom
1996
- } = useNavigateBack();
1997
- const {
1998
- manager
1999
- } = queueManagerReact.useManager();
2212
+ function ChangeSlippageButton() {
2000
2213
  const navigate = reactRouterDom.useNavigate();
2001
- const bestRoute = useBestRouteStore.use.bestRoute();
2002
- const fetchingBestRoute = useBestRouteStore.use.loading();
2003
- const {
2004
- tokens
2005
- } = useMetaStore.use.meta();
2006
- const slippage = useSettingsStore.use.slippage();
2007
- const customSlippage = useSettingsStore.use.customSlippage();
2008
- const selectedSlippage = customSlippage || slippage;
2009
- const {
2010
- loading,
2011
- errors,
2012
- warnings,
2013
- confirmSwap
2014
- } = useConfirmSwap();
2015
- const showHighSlippageWarning = !errors.find(error => error.type === ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE);
2016
- return React__default.createElement(ui.ConfirmSwap, {
2017
- onConfirm: () => {
2018
- confirmSwap?.().then(swap => {
2019
- if (swap) {
2020
- manager?.create('swap', {
2021
- swapDetails: swap
2022
- }, {
2023
- id: swap.requestId
2024
- });
2025
- setSelectedSwap(swap.requestId);
2026
- navigate(navigationRoutes.swaps + `/${swap.requestId}`, {
2027
- replace: true
2028
- });
2029
- }
2030
- });
2031
- },
2032
- onBack: navigateBackFrom.bind(null, navigationRoutes.confirmSwap),
2033
- bestRoute: getBestRouteWithCalculatedFees(bestRoute, tokens),
2034
- loading: loading,
2035
- errors: ConfirmSwapErrors(errors),
2036
- warnings: ConfirmSwapWarnings(warnings),
2037
- extraMessages: showHighSlippageWarning && React__default.createElement(ConfirmSwapExtraMessages, {
2038
- selectedSlippage: selectedSlippage
2039
- }),
2040
- confirmButtonTitle: warnings.length > 0 || errors.length > 0 ? 'Proceed anyway!' : 'Confirm swap!',
2041
- confirmButtonDisabled: fetchingBestRoute
2042
- });
2214
+ return React__default.createElement(ui.Button, {
2215
+ type: "primary",
2216
+ variant: "outlined",
2217
+ size: "small",
2218
+ onClick: () => navigate(navigationRoutes.settings)
2219
+ }, "Change Slippage");
2220
+ }
2221
+
2222
+ const StyledMessage = /*#__PURE__*/ui.styled(ui.Typography, {
2223
+ color: '$error500 !important'
2224
+ });
2225
+ function MinRequiredSlippage(_ref) {
2226
+ let {
2227
+ minRequiredSlippage
2228
+ } = _ref;
2229
+ return React__default.createElement(StyledMessage, {
2230
+ variant: "body2"
2231
+ }, "We recommend you to increase slippage to at least \u00A0", minRequiredSlippage, "\u00A0 for this route.", React__default.createElement(ui.Spacer, {
2232
+ size: 8,
2233
+ direction: "vertical"
2234
+ }), React__default.createElement(ChangeSlippageButton, null));
2235
+ }
2236
+
2237
+ function ConfirmSwapErrors(errors) {
2238
+ return errors.flatMap(error => {
2239
+ switch (error.type) {
2240
+ case ConfirmSwapErrorTypes.NO_ROUTE:
2241
+ return React__default.createElement(ui.Typography, {
2242
+ variant: "body2"
2243
+ }, "No routes found. Please try again later.");
2244
+ case ConfirmSwapErrorTypes.REQUEST_FAILED:
2245
+ return React__default.createElement(ui.Typography, {
2246
+ variant: "body2"
2247
+ }, `Failed to confirm swap ${error.status ? `'status': ${error.status})` : ''}, please try again.`);
2248
+ case ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS:
2249
+ return React__default.createElement(ui.Typography, {
2250
+ variant: "body2"
2251
+ }, "Route updated and price impact is too high, try again later!");
2252
+ case ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE:
2253
+ return React__default.createElement(MinRequiredSlippage, {
2254
+ minRequiredSlippage: error.minRequiredSlippage
2255
+ });
2256
+ default:
2257
+ return [];
2258
+ }
2259
+ });
2260
+ }
2261
+
2262
+ const List = /*#__PURE__*/ui.styled('ul', {
2263
+ variants: {
2264
+ showListStyle: {
2265
+ true: {
2266
+ paddingLeft: '$24'
2267
+ }
2268
+ }
2269
+ }
2270
+ });
2271
+ const ListItem = /*#__PURE__*/ui.styled('li', {
2272
+ variants: {
2273
+ showListStyle: {
2274
+ true: {
2275
+ listStyleType: 'disc',
2276
+ listStylePosition: 'outside'
2277
+ }
2278
+ }
2279
+ }
2280
+ });
2281
+ const Message = /*#__PURE__*/ui.styled(ui.Typography, {
2282
+ display: 'block',
2283
+ color: '$warning500 !important'
2284
+ });
2285
+ function BalanceWarnings(_ref) {
2286
+ let {
2287
+ messages
2288
+ } = _ref;
2289
+ const showListStyle = messages.length > 1;
2290
+ return React__default.createElement(List, {
2291
+ showListStyle: showListStyle
2292
+ }, messages.map(warning => React__default.createElement(ListItem, {
2293
+ showListStyle: showListStyle
2294
+ }, React__default.createElement(Message, {
2295
+ variant: "body2"
2296
+ }, warning))));
2297
+ }
2298
+
2299
+ function ConfirmSwapWarnings(warnings) {
2300
+ return warnings.flatMap(warning => {
2301
+ switch (warning.type) {
2302
+ case ConfirmSwapWarningTypes.ROUTE_UPDATED:
2303
+ return React__default.createElement(ui.Typography, {
2304
+ variant: "body2"
2305
+ }, "Route has been updated.");
2306
+ case ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED:
2307
+ return React__default.createElement(ui.Typography, {
2308
+ variant: "body2"
2309
+ }, `Output amount changed to ${warning.newOutputAmount}
2310
+ (${warning.percentageChange}% change).`);
2311
+ case ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED:
2312
+ return React__default.createElement(ui.Typography, {
2313
+ variant: "body2"
2314
+ }, "Route swappers has been updated.");
2315
+ case ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED:
2316
+ return React__default.createElement(ui.Typography, {
2317
+ variant: "body2"
2318
+ }, "Route internal coins has been updated.");
2319
+ case ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE:
2320
+ return React__default.createElement(BalanceWarnings, {
2321
+ messages: warning.messages
2322
+ });
2323
+ default:
2324
+ return [];
2325
+ }
2326
+ });
2327
+ }
2328
+
2329
+ function HighSlippageWarning(props) {
2330
+ const {
2331
+ selectedSlippage
2332
+ } = props;
2333
+ return React__default.createElement(ui.Alert, {
2334
+ type: "warning",
2335
+ footer: React__default.createElement(ChangeSlippageButton, null)
2336
+ }, "Caution, your slippage is high (=", selectedSlippage, "). Your trade may be front run.");
2337
+ }
2338
+
2339
+ function ConfirmSwapExtraMessages(props) {
2340
+ const {
2341
+ selectedSlippage
2342
+ } = props;
2343
+ const highSlippage = selectedSlippage >= HIGH_SLIPPAGE;
2344
+ return React__default.createElement(React__default.Fragment, null, highSlippage && React__default.createElement(HighSlippageWarning, {
2345
+ selectedSlippage: selectedSlippage
2346
+ }));
2347
+ }
2348
+
2349
+ function ConfirmSwapPage() {
2350
+ const navigate = reactRouterDom.useNavigate();
2351
+ const {
2352
+ navigateBackFrom
2353
+ } = useNavigateBack();
2354
+ const bestRoute = useBestRouteStore.use.bestRoute();
2355
+ const fetchingBestRoute = useBestRouteStore.use.loading();
2356
+ const fetchingBestRouteError = useBestRouteStore.use.error();
2357
+ const setSelectedSwap = useUiStore.use.setSelectedSwap();
2358
+ const {
2359
+ blockchains,
2360
+ tokens
2361
+ } = useMetaStore.use.meta();
2362
+ const accounts = useWalletsStore.use.accounts();
2363
+ const selectedWallets = useWalletsStore.use.selectedWallets();
2364
+ const initSelectedWallets = useWalletsStore.use.initSelectedWallets();
2365
+ const setSelectedWallet = useWalletsStore.use.setSelectedWallet();
2366
+ const slippage = useSettingsStore.use.slippage();
2367
+ const customSlippage = useSettingsStore.use.customSlippage();
2368
+ const inputUsdValue = useBestRouteStore.use.inputUsdValue();
2369
+ const outputUsdValue = useBestRouteStore.use.outputUsdValue();
2370
+ const bestRouteloadingStatus = getBestRouteStatus(fetchingBestRoute, !!fetchingBestRouteError);
2371
+ const {
2372
+ manager
2373
+ } = queueManagerReact.useManager();
2374
+ const {
2375
+ loading,
2376
+ errors,
2377
+ warnings,
2378
+ confirmSwap
2379
+ } = useConfirmSwap();
2380
+ const selectedSlippage = customSlippage || slippage;
2381
+ const showHighSlippageWarning = !errors.find(error => error.type === ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE);
2382
+ const {
2383
+ getWalletInfo,
2384
+ connect
2385
+ } = walletsCore.useWallets();
2386
+ const confirmDisabled = fetchingBestRoute || !requiredWallets(bestRoute).every(chain => selectedWallets.map(wallet => wallet.chain).includes(chain));
2387
+ const firstStep = bestRoute?.result?.swaps[0];
2388
+ const lastStep = bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1];
2389
+ const fromAmount = decimalNumber(firstStep?.fromAmount, 3);
2390
+ const toAmount = decimalNumber(lastStep?.toAmount, 3);
2391
+ React.useEffect(() => {
2392
+ initSelectedWallets();
2393
+ }, []);
2394
+ const selectableWallets = getSelectableWallets(accounts, selectedWallets, getWalletInfo);
2395
+ const handleConnectChain = wallet => {
2396
+ const network = wallet;
2397
+ getKeplrCompatibleConnectedWallets(selectableWallets).forEach(compatibleWallet => connect?.(compatibleWallet, network));
2398
+ };
2399
+ const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
2400
+ return React__default.createElement(ui.ConfirmSwap, {
2401
+ requiredWallets: getRequiredChains(bestRoute),
2402
+ selectableWallets: selectableWallets,
2403
+ onBack: navigateBackFrom.bind(null, navigationRoutes.confirmSwap),
2404
+ onConfirm: () => {
2405
+ confirmSwap?.().then(swap => {
2406
+ if (swap) {
2407
+ manager?.create('swap', {
2408
+ swapDetails: swap
2409
+ }, {
2410
+ id: swap.requestId
2411
+ });
2412
+ setSelectedSwap(swap.requestId);
2413
+ navigate(navigationRoutes.swaps + `/${swap.requestId}`, {
2414
+ replace: true
2415
+ });
2416
+ }
2417
+ });
2418
+ },
2419
+ onChange: wallet => setSelectedWallet(wallet),
2420
+ confirmDisabled: confirmDisabled,
2421
+ handleConnectChain: wallet => handleConnectChain(wallet),
2422
+ isExperimentalChain: wallet => getKeplrCompatibleConnectedWallets(selectableWallets).length > 0 ? isExperimentalChain(blockchains, wallet) : false,
2423
+ previewInputs: React__default.createElement(React__default.Fragment, null, React__default.createElement(TokenPreview, {
2424
+ chain: {
2425
+ displayName: firstStep?.from.blockchain || '',
2426
+ logo: firstStep?.from.blockchainLogo || ''
2427
+ },
2428
+ token: {
2429
+ symbol: firstStep?.from.symbol || '',
2430
+ image: firstStep?.from.logo || ''
2431
+ },
2432
+ usdValue: inputUsdValue,
2433
+ amount: fromAmount,
2434
+ label: i18n.t('From'),
2435
+ loadingStatus: bestRouteloadingStatus
2436
+ }), React__default.createElement(ui.Spacer, {
2437
+ size: 12,
2438
+ direction: "vertical"
2439
+ }), React__default.createElement(TokenPreview, {
2440
+ chain: {
2441
+ displayName: lastStep?.to.blockchain || '',
2442
+ logo: lastStep?.to.blockchainLogo || ''
2443
+ },
2444
+ token: {
2445
+ symbol: lastStep?.to.symbol || '',
2446
+ image: lastStep?.to.logo || ''
2447
+ },
2448
+ usdValue: outputUsdValue,
2449
+ amount: toAmount,
2450
+ label: i18n.t('To'),
2451
+ loadingStatus: bestRouteloadingStatus,
2452
+ percentageChange: React__default.createElement(PercentageChange, {
2453
+ inputUsdValue: inputUsdValue,
2454
+ outputUsdValue: outputUsdValue
2455
+ })
2456
+ })),
2457
+ previewRoutes: React__default.createElement(RoutesOverview, {
2458
+ routes: bestRoute,
2459
+ totalFee: numberToString(totalFeeInUsd, 0, 2)
2460
+ }),
2461
+ loading: loading,
2462
+ errors: ConfirmSwapErrors(errors),
2463
+ warnings: ConfirmSwapWarnings(warnings),
2464
+ extraMessages: showHighSlippageWarning && React__default.createElement(ConfirmSwapExtraMessages, {
2465
+ selectedSlippage: selectedSlippage
2466
+ }),
2467
+ confirmButtonTitle: warnings.length > 0 || errors.length > 0 ? 'Proceed anyway!' : 'Confirm swap!'
2468
+ });
2043
2469
  }
2044
2470
 
2045
2471
  const getPendingSwaps = manager => {
@@ -2056,6 +2482,31 @@ const getPendingSwaps = manager => {
2056
2482
  return result.sort((a, b) => Number(b.swap.creationTime) - Number(a.swap.creationTime));
2057
2483
  };
2058
2484
 
2485
+ const groupSwapsByDate = swaps => {
2486
+ const output = new Map([['today', {
2487
+ title: 'Today',
2488
+ swaps: []
2489
+ }], ['week', {
2490
+ title: 'This week',
2491
+ swaps: []
2492
+ }], ['month', {
2493
+ title: 'This month',
2494
+ swaps: []
2495
+ }], ['year', {
2496
+ title: 'This year',
2497
+ swaps: []
2498
+ }], ['history', {
2499
+ title: 'History',
2500
+ swaps: []
2501
+ }]]);
2502
+ const now = dayjs();
2503
+ swaps.forEach(swap => {
2504
+ const swapDate = dayjs(Number(swap.creationTime));
2505
+ if (now.isSame(swapDate, 'day')) output.get('today')?.swaps.push(swap);else if (now.isSame(swapDate, 'week')) output.get('week')?.swaps.push(swap);else if (now.isSame(swapDate, 'month')) output.get('month')?.swaps.push(swap);else if (now.isSame(swapDate, 'year')) output.get('year')?.swaps.push(swap);else output.get('history')?.swaps.push(swap);
2506
+ });
2507
+ return Array.from(output.values());
2508
+ };
2509
+
2059
2510
  function HistoryPage() {
2060
2511
  const setSelectedSwap = useUiStore.use.setSelectedSwap();
2061
2512
  const navigate = reactRouterDom.useNavigate();
@@ -2071,16 +2522,14 @@ function HistoryPage() {
2071
2522
  } = _ref;
2072
2523
  return swap;
2073
2524
  });
2074
- return React__default.createElement(ui.History
2075
- //todo: move PendingSwap type to rango-types
2076
- //@ts-ignore
2077
- , {
2078
- //todo: move PendingSwap type to rango-types
2079
- //@ts-ignore
2525
+ return React__default.createElement(ui.History, {
2080
2526
  list: pendingSwaps,
2527
+ groupBy: groupSwapsByDate,
2081
2528
  onSwapClick: requestId => {
2082
2529
  setSelectedSwap(requestId);
2083
- navigate(navigationRoutes.swaps + `/${requestId}`);
2530
+ navigate(navigationRoutes.swaps + `/${requestId}`, {
2531
+ replace: true
2532
+ });
2084
2533
  },
2085
2534
  onBack: navigateBackFrom.bind(null, navigationRoutes.swaps)
2086
2535
  });
@@ -2091,6 +2540,7 @@ function LiquiditySourcePage(_ref) {
2091
2540
  supportedSwappers
2092
2541
  } = _ref;
2093
2542
  const swappers = useMetaStore.use.meta().swappers;
2543
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2094
2544
  const toggleLiquiditySource = useSettingsStore.use.toggleLiquiditySource();
2095
2545
  const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
2096
2546
  const toggleAllLiquiditySources = useSettingsStore.use.toggleAllLiquiditySources();
@@ -2116,7 +2566,8 @@ function LiquiditySourcePage(_ref) {
2116
2566
  toggleAll: toggleAllLiquiditySources,
2117
2567
  list: supportedSwappers !== 'all' ? uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0) : uniqueSwappersGroups,
2118
2568
  onChange: liquiditySource => toggleLiquiditySource(liquiditySource.title),
2119
- onBack: navigateBackFrom.bind(null, navigationRoutes.liquiditySources)
2569
+ onBack: navigateBackFrom.bind(null, navigationRoutes.liquiditySources),
2570
+ loadingStatus: loadingMetaStatus
2120
2571
  });
2121
2572
  }
2122
2573
 
@@ -2158,391 +2609,169 @@ function SelectTokenPage(props) {
2158
2609
  const sourceTokens = useBestRouteStore.use.sourceTokens();
2159
2610
  const destinationTokens = useBestRouteStore.use.destinationTokens();
2160
2611
  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
- let sortedWallets = walletsShared.detectMobileScreens() ? wallets.filter(wallet => wallet.showOnMobile) : wallets;
2260
- sortedWallets = sortWalletsBasedOnState(sortedWallets);
2261
- const [walletErrorMessage, setWalletErrorMessage] = React.useState('');
2262
- const toggleConnectWalletsButton = useUiStore.use.toggleConnectWalletsButton();
2263
- const {
2264
- t
2265
- } = reactI18next.useTranslation();
2266
- const onSelectWallet = async type => {
2267
- const wallet = state(type);
2268
- try {
2269
- if (walletErrorMessage) setWalletErrorMessage('');
2270
- if (wallet.connected) {
2271
- await disconnect(type);
2272
- } else {
2273
- if (!multiWallets && !!wallets.find(w => w.state === ui.WalletState.CONNECTED)) {
2274
- return;
2275
- }
2276
- await connect(type);
2277
- }
2278
- } catch (e) {
2279
- setWalletErrorMessage('Error: ' + e?.message);
2280
- }
2281
- };
2282
- React.useEffect(() => {
2283
- toggleConnectWalletsButton();
2284
- return () => toggleConnectWalletsButton();
2285
- }, []);
2286
- return React__default.createElement(ui.SecondaryPage, {
2287
- title: t('Select Wallet') || '',
2288
- textField: false,
2289
- onBack: navigateBackFrom.bind(null, navigationRoutes.wallets)
2290
- }, React__default.createElement(React__default.Fragment, null, walletErrorMessage && React__default.createElement(AlertContainer, null, React__default.createElement(ui.Alert, {
2291
- type: "error"
2292
- }, walletErrorMessage)), React__default.createElement(ListContainer, null, sortedWallets.map((wallet, index) => React__default.createElement(ui.Wallet, Object.assign({}, wallet, {
2293
- key: `${index}-${wallet.type}`,
2294
- onClick: onSelectWallet
2295
- }))))));
2296
- }
2297
-
2298
- const Box$1 = /*#__PURE__*/ui.styled('div', {
2299
- display: 'flex',
2300
- flexDirection: 'column',
2301
- width: '100%'
2302
- });
2303
- const Container$3 = /*#__PURE__*/ui.styled('div', {
2304
- boxSizing: 'border-box',
2305
- borderRadius: '$5',
2306
- padding: '$8 $16 $16 $16',
2307
- variants: {
2308
- type: {
2309
- filled: {
2310
- backgroundColor: '$neutrals300'
2311
- },
2312
- outlined: {
2313
- border: '1px solid $neutrals300'
2314
- }
2315
- }
2316
- },
2317
- defaultVariants: {
2318
- type: 'filled'
2319
- },
2320
- '.head': {
2321
- display: 'flex',
2322
- justifyContent: 'space-between',
2323
- alignItems: 'center',
2324
- minHeight: '32px'
2325
- },
2326
- '.form': {
2327
- display: 'flex',
2328
- width: '100%',
2329
- padding: '$2 0',
2330
- '.selectors': {
2331
- width: '35%',
2332
- '._text': {
2333
- whiteSpace: 'nowrap',
2334
- overflow: 'hidden',
2335
- textOverflow: 'ellipsis'
2336
- }
2337
- },
2338
- '.amount': {
2339
- width: '30%'
2340
- }
2341
- }
2342
- });
2343
- const StyledImage$1 = /*#__PURE__*/ui.styled('img', {
2344
- width: '$24',
2345
- maxHeight: '$24'
2346
- });
2347
- const ImagePlaceholder$1 = /*#__PURE__*/ui.styled('span', {
2348
- width: '24px',
2349
- height: '24px',
2350
- backgroundColor: '$neutrals300',
2351
- borderRadius: '99999px'
2352
- });
2353
- const OutputContainer$1 = /*#__PURE__*/ui.styled('div', {
2354
- windth: '100%',
2355
- height: '$48',
2356
- borderRadius: '$5',
2357
- backgroundColor: '$background',
2358
- border: '1px solid transparent',
2359
- position: 'relative',
2360
- display: 'flex',
2361
- alignItems: 'center',
2362
- paddingLeft: '$8',
2363
- paddingRight: '$8'
2364
- });
2365
- function TokenPreview(props) {
2366
- const {
2367
- chain,
2368
- token,
2369
- loadingStatus
2370
- } = props;
2371
- const {
2372
- t
2373
- } = reactI18next.useTranslation();
2374
- const ItemSuffix = React__default.createElement("div", {
2375
- style: {
2376
- display: 'flex',
2377
- justifyContent: 'center',
2378
- alignItems: 'center'
2379
- }
2380
- }, loadingStatus === 'failed' && React__default.createElement(ui.InfoCircleIcon, {
2381
- color: "error",
2382
- size: 24
2383
- }));
2384
- return React__default.createElement(Box$1, null, React__default.createElement(Container$3, {
2385
- type: 'outlined'
2386
- }, React__default.createElement("div", {
2387
- className: "head"
2388
- }, React__default.createElement(ui.Typography, {
2389
- variant: "body2",
2390
- color: "neutrals800"
2391
- }, props.label), React__default.createElement(ui.Typography, {
2392
- variant: "caption",
2393
- color: "neutrals600"
2394
- }, `$${numberToString(props.usdValue)}`)), React__default.createElement("div", {
2395
- className: "form"
2396
- }, React__default.createElement(ui.Button, {
2397
- className: "selectors",
2398
- variant: "outlined",
2399
- loading: loadingStatus === 'loading',
2400
- prefix: loadingStatus === 'success' && chain ? React__default.createElement(StyledImage$1, {
2401
- src: chain.logo
2402
- }) : React__default.createElement(ImagePlaceholder$1, null),
2403
- suffix: ItemSuffix,
2404
- align: "start",
2405
- size: "large"
2406
- }, loadingStatus === 'success' && chain ? chain.displayName : t('Chain')), React__default.createElement(ui.Spacer, {
2407
- size: 12
2408
- }), React__default.createElement(ui.Button, {
2409
- className: "selectors",
2410
- variant: "outlined",
2411
- loading: loadingStatus === 'loading',
2412
- prefix: loadingStatus === 'success' && token ? React__default.createElement(StyledImage$1, {
2413
- src: token.image
2414
- }) : React__default.createElement(ImagePlaceholder$1, null),
2415
- suffix: ItemSuffix,
2416
- size: "large",
2417
- align: "start"
2418
- }, loadingStatus === 'success' && token ? token.symbol : t('Token')), React__default.createElement(ui.Spacer, {
2419
- size: 12
2420
- }), React__default.createElement("div", {
2421
- className: "amount"
2422
- }, React__default.createElement(OutputContainer$1, null, React__default.createElement(ui.Typography, {
2423
- variant: "h4"
2424
- }, props.amount))))));
2425
- }
2426
-
2427
- const Container$4 = /*#__PURE__*/ui.styled('div', {
2428
- display: 'flex',
2429
- alignItems: 'center',
2430
- justifyContent: 'space-between',
2431
- padding: '$8',
2432
- borderRadius: '$5',
2433
- backgroundColor: '$neutrals300',
2434
- color: '$neutrals800',
2435
- fontSize: '$12',
2436
- '.routes': {
2437
- display: 'flex',
2438
- alignItems: 'center'
2439
- },
2440
- '.fee': {
2441
- display: 'flex',
2442
- alignItems: 'center'
2443
- }
2444
- });
2445
- function RoutesOverview(props) {
2446
- if (!props.routes) return null;
2447
- const swaps = props.routes.result?.swaps;
2448
- return React__default.createElement(Container$4, null, React__default.createElement("div", {
2449
- className: "routes"
2450
- }, swaps?.map((swap, idx) => {
2451
- const isLast = idx + 1 == swaps.length;
2452
- return React__default.createElement(React__default.Fragment, null, React__default.createElement("div", {
2453
- className: "route"
2454
- }, swap.from.symbol), React__default.createElement(ui.ChevronRightIcon, {
2455
- size: 12
2456
- }), isLast ? React__default.createElement("div", {
2457
- className: "route"
2458
- }, swap.to.symbol) : null);
2459
- })), props.totalFee ? React__default.createElement("div", {
2460
- className: "fee"
2461
- }, React__default.createElement(ui.GasIcon, {
2462
- size: 12
2463
- }), React__default.createElement(ui.Spacer, {
2464
- size: 4
2465
- }), "$", props.totalFee) : null);
2612
+ const supportedDestinationTokens = supportedTokens === 'all' ? destinationTokens : destinationTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2613
+ const fromToken = useBestRouteStore.use.fromToken();
2614
+ const toToken = useBestRouteStore.use.toToken();
2615
+ const setFromToken = useBestRouteStore.use.setFromToken();
2616
+ const setToToken = useBestRouteStore.use.setToToken();
2617
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2618
+ return React__default.createElement(ui.TokenSelector, {
2619
+ type: type === 'from' ? 'Source' : 'Destination',
2620
+ list: type == 'from' ? supportedSourceTokens : supportedDestinationTokens,
2621
+ selected: type === 'from' ? fromToken : toToken,
2622
+ onChange: token => {
2623
+ if (type === 'from') setFromToken(token);else setToToken(token);
2624
+ navigateBackFrom(navigationRoutes.fromToken);
2625
+ },
2626
+ onBack: navigateBackFrom.bind(null, navigationRoutes.fromToken),
2627
+ loadingStatus: loadingMetaStatus
2628
+ });
2466
2629
  }
2467
2630
 
2468
- function ConfirmWalletsPage() {
2631
+ function SettingsPage(_ref) {
2632
+ let {
2633
+ supportedSwappers
2634
+ } = _ref;
2635
+ const slippage = useSettingsStore.use.slippage();
2636
+ const setSlippage = useSettingsStore.use.setSlippage();
2637
+ const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
2638
+ const customSlippage = useSettingsStore.use.customSlippage();
2639
+ const setCustomSlippage = useSettingsStore.use.setCustomSlippage();
2640
+ const theme = useSettingsStore.use.theme();
2641
+ const setTheme = useSettingsStore.use.setTheme();
2642
+ const swappers = useMetaStore.use.meta().swappers;
2469
2643
  const navigate = reactRouterDom.useNavigate();
2470
2644
  const {
2471
2645
  navigateBackFrom
2472
2646
  } = useNavigateBack();
2473
- const bestRoute = useBestRouteStore.use.bestRoute();
2647
+ const infiniteApprove = useSettingsStore.use.infiniteApprove();
2648
+ const toggleInfiniteApprove = useSettingsStore.use.toggleInfiniteApprove();
2649
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2650
+ const uniqueSwappersGroups = [];
2651
+ removeDuplicateFrom(swappers.map(s => s.swapperGroup)).map(swapperGroup => {
2652
+ return swappers.find(s => s.swapperGroup === swapperGroup);
2653
+ }).find(s => {
2654
+ if (s) {
2655
+ for (const type of s.types) {
2656
+ uniqueSwappersGroups.push({
2657
+ title: s.swapperGroup,
2658
+ logo: s.logo,
2659
+ type,
2660
+ selected: !disabledLiquiditySources.includes(s.swapperGroup)
2661
+ });
2662
+ }
2663
+ }
2664
+ });
2665
+ supportedSwappers !== 'all' && uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0);
2666
+ const supportedUniqueSwappersGroups = supportedSwappers !== 'all' ? uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0) : uniqueSwappersGroups;
2667
+ return React__default.createElement(ui.Settings, {
2668
+ slippages: SLIPPAGES,
2669
+ selectedSlippage: slippage,
2670
+ onSlippageChange: slippage => setSlippage(slippage),
2671
+ onLiquiditySourcesClick: () => navigate(navigationRoutes.liquiditySources),
2672
+ onBack: navigateBackFrom.bind(null, navigationRoutes.settings),
2673
+ liquiditySources: supportedUniqueSwappersGroups,
2674
+ selectedLiquiditySources: supportedUniqueSwappersGroups.filter(s => s.selected),
2675
+ customSlippage: customSlippage || NaN,
2676
+ onCustomSlippageChange: setCustomSlippage,
2677
+ minSlippage: MIN_SLIPPGAE,
2678
+ maxSlippage: MAX_SLIPPAGE,
2679
+ selectedTheme: theme,
2680
+ onThemeChange: setTheme,
2681
+ infiniteApprove: infiniteApprove,
2682
+ toggleInfiniteApprove: toggleInfiniteApprove,
2683
+ loadingStatus: loadingMetaStatus
2684
+ });
2685
+ }
2686
+
2687
+ const ListContainer = /*#__PURE__*/ui.styled('div', {
2688
+ display: 'grid',
2689
+ gap: '.5rem',
2690
+ gridTemplateColumns: ' repeat(2, minmax(0, 1fr))',
2691
+ alignContent: 'baseline',
2692
+ padding: '0.5rem',
2693
+ overflowY: 'auto'
2694
+ });
2695
+ const LoaderContainer = /*#__PURE__*/ui.styled('div', {
2696
+ display: 'flex',
2697
+ justifyContent: 'center',
2698
+ width: '100%',
2699
+ position: 'absolute',
2700
+ top: '50%'
2701
+ });
2702
+ const AlertContainer = /*#__PURE__*/ui.styled('div', {
2703
+ paddingBottom: '$16'
2704
+ });
2705
+ function WalletsPage(_ref) {
2706
+ let {
2707
+ supportedWallets,
2708
+ multiWallets
2709
+ } = _ref;
2474
2710
  const {
2475
- blockchains,
2476
- tokens
2477
- } = useMetaStore.use.meta();
2478
- const accounts = useWalletsStore.use.accounts();
2479
- const selectedWallets = useWalletsStore.use.selectedWallets();
2480
- const initSelectedWallets = useWalletsStore.use.initSelectedWallets();
2481
- const setSelectedWallet = useWalletsStore.use.setSelectedWallet();
2711
+ navigateBackFrom
2712
+ } = useNavigateBack();
2482
2713
  const {
2714
+ state,
2715
+ disconnect,
2483
2716
  getWalletInfo,
2484
2717
  connect
2485
2718
  } = walletsCore.useWallets();
2486
- const confirmDisabled = !requiredWallets(bestRoute).every(chain => selectedWallets.map(wallet => wallet.chain).includes(chain));
2487
- const firstStep = bestRoute?.result?.swaps[0];
2488
- const lastStep = bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1];
2489
- const fromAmount = decimalNumber(firstStep?.fromAmount, 3);
2490
- const toAmount = decimalNumber(lastStep?.toAmount, 3);
2719
+ const wallets = getlistWallet(state, getWalletInfo, supportedWallets === 'all' ? Object.values(walletsShared.WalletType) : supportedWallets);
2720
+ const walletsRef = React.useRef();
2721
+ let sortedWallets = walletsShared.detectMobileScreens() ? wallets.filter(wallet => wallet.showOnMobile) : wallets;
2722
+ sortedWallets = sortWalletsBasedOnState(sortedWallets);
2723
+ const [walletErrorMessage, setWalletErrorMessage] = React.useState('');
2724
+ const toggleConnectWalletsButton = useUiStore.use.toggleConnectWalletsButton();
2725
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2726
+ const {
2727
+ t
2728
+ } = reactI18next.useTranslation();
2729
+ const onSelectWallet = async type => {
2730
+ const wallet = state(type);
2731
+ try {
2732
+ if (walletErrorMessage) setWalletErrorMessage('');
2733
+ if (wallet.connected) {
2734
+ await disconnect(type);
2735
+ } else {
2736
+ if (!multiWallets && !!wallets.find(w => w.state === ui.WalletState.CONNECTED)) {
2737
+ return;
2738
+ }
2739
+ await connect(type);
2740
+ }
2741
+ } catch (e) {
2742
+ setWalletErrorMessage('Error: ' + e?.message);
2743
+ }
2744
+ };
2745
+ const disconnectConnectingWallets = () => {
2746
+ const connectingWallets = walletsRef.current?.filter(wallet => wallet.state === ui.WalletState.CONNECTING) || [];
2747
+ for (const wallet of connectingWallets) {
2748
+ disconnect(wallet.type);
2749
+ }
2750
+ };
2491
2751
  React.useEffect(() => {
2492
- initSelectedWallets();
2752
+ toggleConnectWalletsButton();
2753
+ return () => {
2754
+ disconnectConnectingWallets();
2755
+ toggleConnectWalletsButton();
2756
+ };
2493
2757
  }, []);
2494
- const selectableWallets = getSelectableWallets(accounts, selectedWallets, getWalletInfo);
2495
- const handleConnectChain = wallet => {
2496
- const network = wallet;
2497
- getKeplrCompatibleConnectedWallets(selectableWallets).forEach(compatibleWallet => connect?.(compatibleWallet, network));
2498
- };
2499
- const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
2500
- return React__default.createElement(ui.ConfirmWallets, {
2501
- requiredWallets: getRequiredChains(bestRoute),
2502
- selectableWallets: selectableWallets,
2503
- onBack: navigateBackFrom.bind(null, navigationRoutes.confirmWallets),
2504
- onConfirm: () => navigate(navigationRoutes.confirmSwap, {
2505
- replace: true
2506
- }),
2507
- onChange: wallet => setSelectedWallet(wallet),
2508
- confirmDisabled: confirmDisabled,
2509
- handleConnectChain: wallet => handleConnectChain(wallet),
2510
- isExperimentalChain: wallet => getKeplrCompatibleConnectedWallets(selectableWallets).length > 0 ? isExperimentalChain(blockchains, wallet) : false,
2511
- previewInputs: React__default.createElement(React__default.Fragment, null, React__default.createElement(TokenPreview, {
2512
- chain: {
2513
- displayName: firstStep?.from.blockchain || '',
2514
- logo: firstStep?.from.blockchainLogo || ''
2515
- },
2516
- token: {
2517
- symbol: firstStep?.from.symbol || '',
2518
- image: firstStep?.from.logo || ''
2519
- },
2520
- usdValue: calcOutputUsdValue(fromAmount, firstStep?.from.usdPrice),
2521
- amount: fromAmount,
2522
- label: i18n.t('From'),
2523
- loadingStatus: 'success'
2524
- }), React__default.createElement(ui.Spacer, {
2525
- size: 12,
2526
- direction: "vertical"
2527
- }), React__default.createElement(TokenPreview, {
2528
- chain: {
2529
- displayName: lastStep?.to.blockchain || '',
2530
- logo: lastStep?.to.blockchainLogo || ''
2531
- },
2532
- token: {
2533
- symbol: lastStep?.to.symbol || '',
2534
- image: lastStep?.to.logo || ''
2535
- },
2536
- usdValue: calcOutputUsdValue(toAmount, lastStep?.to.usdPrice),
2537
- amount: toAmount,
2538
- label: i18n.t('To'),
2539
- loadingStatus: 'success'
2540
- })),
2541
- previewRoutes: React__default.createElement(RoutesOverview, {
2542
- routes: bestRoute,
2543
- totalFee: numberToString(totalFeeInUsd, 0, 2)
2544
- })
2545
- });
2758
+ React.useEffect(() => {
2759
+ walletsRef.current = wallets;
2760
+ }, [wallets]);
2761
+ return React__default.createElement(ui.SecondaryPage, {
2762
+ title: t('Select Wallet') || '',
2763
+ textField: false,
2764
+ onBack: navigateBackFrom.bind(null, navigationRoutes.wallets)
2765
+ }, React__default.createElement(React__default.Fragment, null, walletErrorMessage && React__default.createElement(AlertContainer, null, React__default.createElement(ui.Alert, {
2766
+ type: "error"
2767
+ }, walletErrorMessage)), loadingMetaStatus === 'loading' && React__default.createElement(LoaderContainer, {
2768
+ className: "loader"
2769
+ }, React__default.createElement(ui.Spinner, {
2770
+ size: 24
2771
+ })), loadingMetaStatus === 'failed' && React__default.createElement(ui.LoadingFailedAlert, null), React__default.createElement(ListContainer, null, loadingMetaStatus === 'success' && sortedWallets.map((wallet, index) => React__default.createElement(ui.Wallet, Object.assign({}, wallet, {
2772
+ key: `${index}-${wallet.type}`,
2773
+ onClick: onSelectWallet
2774
+ }))))));
2546
2775
  }
2547
2776
 
2548
2777
  function useCopyToClipboard(resetInterval) {
@@ -2563,15 +2792,87 @@ function useCopyToClipboard(resetInterval) {
2563
2792
  return [isCopied, handleCopy];
2564
2793
  }
2565
2794
 
2795
+ function timeSince(timeMillis) {
2796
+ const seconds = Math.floor((new Date().getTime() - timeMillis) / 1000);
2797
+ let intervalType;
2798
+ let interval = Math.floor(seconds / 31536000);
2799
+ if (interval >= 1) {
2800
+ intervalType = 'year';
2801
+ } else {
2802
+ interval = Math.floor(seconds / 2592000);
2803
+ if (interval >= 1) {
2804
+ intervalType = 'month';
2805
+ } else {
2806
+ interval = Math.floor(seconds / 86400);
2807
+ if (interval >= 1) {
2808
+ intervalType = 'day';
2809
+ } else {
2810
+ interval = Math.floor(seconds / 3600);
2811
+ if (interval >= 1) {
2812
+ intervalType = 'hour';
2813
+ } else {
2814
+ interval = Math.floor(seconds / 60);
2815
+ if (interval >= 1) {
2816
+ intervalType = 'minute';
2817
+ } else {
2818
+ interval = seconds;
2819
+ intervalType = 'second';
2820
+ }
2821
+ }
2822
+ }
2823
+ }
2824
+ }
2825
+ if (interval > 1 || interval === 0) {
2826
+ intervalType += 's';
2827
+ }
2828
+ return interval + ' ' + intervalType;
2829
+ }
2830
+ function getSwapDate(pendingSwap) {
2831
+ 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()}`;
2832
+ }
2833
+
2834
+ const PlaceholderContainer = /*#__PURE__*/ui.styled('div', {
2835
+ height: '450px'
2836
+ });
2837
+ function SwapDetailsPlaceholder(props) {
2838
+ const {
2839
+ requestId,
2840
+ loading,
2841
+ onBack
2842
+ } = props;
2843
+ return React__default.createElement(ui.SecondaryPage, {
2844
+ title: "Swap Details",
2845
+ textField: false,
2846
+ onBack: onBack
2847
+ }, React__default.createElement(PlaceholderContainer, null, loading ? React__default.createElement(LoaderContainer, null, React__default.createElement(ui.Spinner, {
2848
+ size: 24
2849
+ })) : React__default.createElement(ui.Alert, {
2850
+ type: "secondary",
2851
+ title: `Swap with request ID = ${requestId} not found.`
2852
+ })));
2853
+ }
2854
+
2566
2855
  function SwapDetailsPage() {
2567
2856
  const selectedSwapRequestId = useUiStore.use.selectedSwapRequestId();
2857
+ const {
2858
+ canSwitchNetworkTo,
2859
+ connect
2860
+ } = walletsCore.useWallets();
2861
+ const retry = useBestRouteStore.use.retry();
2862
+ const navigate = reactRouterDom.useNavigate();
2568
2863
  const {
2569
2864
  navigateBackFrom
2570
2865
  } = useNavigateBack();
2866
+ const [isCopied, handleCopy] = useCopyToClipboard(2000);
2571
2867
  const {
2572
2868
  manager
2573
2869
  } = queueManagerReact.useManager();
2574
- const [isCopied, handleCopy] = useCopyToClipboard(2000);
2870
+ const [loading, setLoading] = React.useState(true);
2871
+ React.useEffect(() => {
2872
+ setTimeout(() => {
2873
+ setLoading(false);
2874
+ }, 5000);
2875
+ }, []);
2575
2876
  const pendingSwaps = getPendingSwaps(manager);
2576
2877
  const selectedSwap = pendingSwaps.find(_ref => {
2577
2878
  let {
@@ -2579,92 +2880,161 @@ function SwapDetailsPage() {
2579
2880
  } = _ref;
2580
2881
  return swap.requestId === selectedSwapRequestId;
2581
2882
  });
2582
- //TODO: implement swap cancellation (move queueManager logic to queueManager/rango-preset)
2583
2883
  const onCancel = () => {
2584
- const swap = selectedSwap ? manager?.get(selectedSwap.id) : undefined;
2884
+ const swap = manager?.get(selectedSwap?.id);
2585
2885
  if (swap) queueManagerRangoPreset.cancelSwap(swap);
2586
2886
  };
2587
- return React__default.createElement(ui.SwapHistory, {
2887
+ const swap = selectedSwap?.swap;
2888
+ if (!swap) return React__default.createElement(SwapDetailsPlaceholder, {
2889
+ requestId: selectedSwapRequestId || '',
2890
+ loading: loading,
2891
+ onBack: navigateBackFrom.bind(null, navigationRoutes.swapDetails)
2892
+ });
2893
+ const firstStep = swap.steps[0];
2894
+ const lastStep = swap.steps[swap.steps.length - 1];
2895
+ const fromAmount = numberToString(swap.inputAmount);
2896
+ const toAmount = numberToString(swap.simulationResult.outputAmount);
2897
+ const currentStep = queueManagerRangoPreset.getCurrentStep(swap);
2898
+ const currentStepBlockchain = currentStep ? queueManagerRangoPreset.getCurrentBlockchainOfOrNull(swap, currentStep) : null;
2899
+ const currentStepWallet = currentStep ? queueManagerRangoPreset.getRelatedWalletOrNull(swap, currentStep) : null;
2900
+ const currentStepNetworkStatus = currentStep?.networkStatus;
2901
+ const swapMessages = getSwapMessages(swap, currentStep);
2902
+ const networkWarningState = isNetworkStatusInWarningState(currentStep);
2903
+ const swapDate = getSwapDate(swap);
2904
+ const shouldRetry = shouldRetrySwap(swap);
2905
+ const switchNetwork = !!currentStepBlockchain && !!currentStepWallet?.walletType && currentStepNetworkStatus === queueManagerRangoPreset.PendingSwapNetworkStatus.WaitingForNetworkChange && canSwitchNetworkTo(currentStepWallet?.walletType, currentStepBlockchain) ? connect.bind(null, currentStepWallet.walletType, currentStepBlockchain) : undefined;
2906
+ const lastConvertedTokenInFailedSwap = getLastConvertedTokenInFailedSwap(swap);
2907
+ return React__default.createElement(ui.SwapHistory, Object.assign({
2588
2908
  onBack: navigateBackFrom.bind(null, navigationRoutes.swapDetails),
2909
+ previewInputs: React__default.createElement(React__default.Fragment, null, React__default.createElement(TokenPreview, {
2910
+ chain: {
2911
+ displayName: firstStep?.fromBlockchain || '',
2912
+ // @ts-ignore
2913
+ logo: firstStep?.fromBlockchainLogo || ''
2914
+ },
2915
+ token: {
2916
+ symbol: firstStep?.fromSymbol || '',
2917
+ image: firstStep?.fromLogo || ''
2918
+ },
2919
+ amount: fromAmount,
2920
+ label: i18n.t('From'),
2921
+ loadingStatus: 'success'
2922
+ }), React__default.createElement(ui.Spacer, {
2923
+ size: 12,
2924
+ direction: "vertical"
2925
+ }), React__default.createElement(TokenPreview, {
2926
+ chain: {
2927
+ displayName: lastStep?.toBlockchain || '',
2928
+ // @ts-ignore
2929
+ logo: lastStep?.toBlockchainLogo || ''
2930
+ },
2931
+ token: {
2932
+ symbol: lastStep?.toSymbol || '',
2933
+ image: lastStep?.toLogo || ''
2934
+ },
2935
+ amount: toAmount,
2936
+ label: i18n.t('To'),
2937
+ loadingStatus: 'success'
2938
+ })),
2589
2939
  //todo: move PendingSwap type to rango-types
2590
2940
  //@ts-ignore
2591
- pendingSwap: selectedSwap?.swap,
2941
+ pendingSwap: swap,
2592
2942
  onCopy: handleCopy,
2593
2943
  isCopied: isCopied,
2594
- onCancel: onCancel
2595
- });
2944
+ onCancel: onCancel,
2945
+ shortMessage: swapMessages.shortMessage,
2946
+ detailedMessage: swapMessages.detailedMessage,
2947
+ currentStepBlockchain: currentStepBlockchain || '',
2948
+ switchNetwork: switchNetwork,
2949
+ type: networkWarningState ? 'warning' : swap.extraMessageSeverity || undefined,
2950
+ date: swapDate
2951
+ }, shouldRetry && {
2952
+ onRetry: () => {
2953
+ retry(swap);
2954
+ setTimeout(() => {
2955
+ navigate(navigationRoutes.home);
2956
+ }, 0);
2957
+ }
2958
+ }, lastConvertedTokenInFailedSwap && {
2959
+ lastConvertedTokenInFailedSwap: {
2960
+ blockchain: lastConvertedTokenInFailedSwap.blockchain,
2961
+ outputAmount: lastConvertedTokenInFailedSwap.outputAmount || '',
2962
+ symbol: lastConvertedTokenInFailedSwap.symbol
2963
+ }
2964
+ }));
2596
2965
  }
2597
2966
 
2967
+ const getAbsolutePath = path => path.replace('/', '');
2598
2968
  function AppRoutes(props) {
2599
2969
  const {
2600
2970
  configs
2601
2971
  } = props;
2602
2972
  return reactRouterDom.useRoutes([{
2603
- path: navigationRoutes.home,
2973
+ path: getAbsolutePath(navigationRoutes.home),
2604
2974
  element: React__default.createElement(Home, {
2605
2975
  title: configs?.title,
2606
2976
  titleSize: configs?.titleSize,
2607
2977
  titleWeight: configs?.titleWeight
2608
2978
  })
2609
2979
  }, {
2610
- path: navigationRoutes.fromChain,
2980
+ path: getAbsolutePath(navigationRoutes.fromChain),
2611
2981
  element: React__default.createElement(SelectChainPage, {
2612
2982
  type: "from",
2613
2983
  supportedChains: configs?.fromChains || 'all'
2614
2984
  })
2615
2985
  }, {
2616
- path: navigationRoutes.toChain,
2986
+ path: getAbsolutePath(navigationRoutes.toChain),
2617
2987
  element: React__default.createElement(SelectChainPage, {
2618
2988
  type: "to",
2619
2989
  supportedChains: configs?.toChains || 'all'
2620
2990
  })
2621
2991
  }, {
2622
- path: navigationRoutes.fromToken + '/*',
2992
+ path: getAbsolutePath(navigationRoutes.fromToken),
2623
2993
  element: React__default.createElement(SelectTokenPage, {
2624
2994
  type: "from",
2625
2995
  supportedTokens: configs?.fromTokens || 'all'
2626
2996
  })
2627
2997
  }, {
2628
- path: navigationRoutes.toToken,
2998
+ path: getAbsolutePath(navigationRoutes.toToken),
2629
2999
  element: React__default.createElement(SelectTokenPage, {
2630
3000
  type: "to",
2631
3001
  supportedTokens: configs?.toTokens || 'all'
2632
3002
  })
2633
3003
  }, {
2634
- path: navigationRoutes.settings,
3004
+ path: getAbsolutePath(navigationRoutes.settings),
2635
3005
  element: React__default.createElement(SettingsPage, {
2636
3006
  supportedSwappers: configs?.liquiditySources || 'all'
2637
3007
  })
2638
3008
  }, {
2639
- path: navigationRoutes.liquiditySources,
3009
+ path: getAbsolutePath(navigationRoutes.liquiditySources),
2640
3010
  element: React__default.createElement(LiquiditySourcePage, {
2641
3011
  supportedSwappers: configs?.liquiditySources || 'all'
2642
3012
  })
2643
3013
  }, {
2644
- path: navigationRoutes.swaps,
3014
+ path: getAbsolutePath(navigationRoutes.swaps),
2645
3015
  element: React__default.createElement(HistoryPage, null)
2646
3016
  }, {
2647
3017
  path: navigationRoutes.swapDetails,
2648
3018
  element: React__default.createElement(SwapDetailsPage, null)
2649
3019
  }, {
2650
- path: navigationRoutes.wallets,
3020
+ path: getAbsolutePath(navigationRoutes.wallets),
2651
3021
  element: React__default.createElement(WalletsPage, {
2652
3022
  supportedWallets: configs?.wallets || 'all',
2653
3023
  multiWallets: typeof configs?.multiWallets === 'undefined' ? true : configs.multiWallets
2654
3024
  })
2655
3025
  }, {
2656
- path: navigationRoutes.confirmSwap,
3026
+ path: getAbsolutePath(navigationRoutes.confirmSwap),
2657
3027
  element: React__default.createElement(ConfirmSwapPage, null)
2658
- }, {
2659
- path: navigationRoutes.confirmWallets,
2660
- element: React__default.createElement(ConfirmWalletsPage, null)
2661
3028
  }]);
2662
3029
  }
2663
3030
 
2664
- const Header$1 = /*#__PURE__*/ui.styled('div', {
3031
+ const Header = /*#__PURE__*/ui.styled('div', {
2665
3032
  display: 'flex',
2666
3033
  width: '100%',
2667
- justifyContent: 'end'
3034
+ justifyContent: 'end',
3035
+ '.balance': {
3036
+ display: 'flex'
3037
+ }
2668
3038
  });
2669
3039
  const WalletImage = /*#__PURE__*/ui.styled('img', {
2670
3040
  width: '$24',
@@ -2694,6 +3064,8 @@ function Layout(_ref) {
2694
3064
  const setInputAmount = useBestRouteStore.use.setInputAmount();
2695
3065
  const totalBalance = calculateWalletUsdValue(balances);
2696
3066
  const connectWalletsButtonDisabled = useUiStore.use.connectWalletsButtonDisabled();
3067
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
3068
+ const fetchingBalance = useWalletsStore(fetchingBalanceSelector);
2697
3069
  const {
2698
3070
  t
2699
3071
  } = reactI18next.useTranslation();
@@ -2708,22 +3080,32 @@ function Layout(_ref) {
2708
3080
  setFromToken(configs?.fromToken || null);
2709
3081
  setFromChain(configs?.fromChain || null);
2710
3082
  }, [configs?.fromToken, configs?.fromChain]);
2711
- return React__default.createElement(React__default.Fragment, null, React__default.createElement(Header$1, null, React__default.createElement(ui.Button, {
3083
+ React.useEffect(() => {
3084
+ setToChain(null);
3085
+ setFromChain(null);
3086
+ setFromToken(null);
3087
+ setToToken(null);
3088
+ }, [configs?.fromChains, configs?.toChains, configs?.fromTokens, configs?.toTokens]);
3089
+ return React__default.createElement(React__default.Fragment, null, React__default.createElement(Header, null, React__default.createElement(ui.Button, {
2712
3090
  size: "small",
2713
3091
  suffix: React__default.createElement(ui.AddWalletIcon, {
2714
3092
  size: 20
2715
3093
  }),
2716
3094
  variant: "ghost",
2717
3095
  flexContent: true,
3096
+ loading: loadingMetaStatus === 'loading',
3097
+ disabled: loadingMetaStatus === 'failed',
2718
3098
  onClick: () => {
2719
3099
  if (!connectWalletsButtonDisabled) navigate(navigationRoutes.wallets);
2720
3100
  }
2721
3101
  }, connectedWalletsImages?.length ? connectedWalletsImages.map((walletImage, index) => React__default.createElement(WalletImage, {
2722
3102
  key: index,
2723
3103
  src: walletImage
2724
- })) : React__default.createElement(React__default.Fragment, null), React__default.createElement(ui.Typography, {
3104
+ })) : React__default.createElement(React__default.Fragment, null), React__default.createElement("div", {
3105
+ className: "balance"
3106
+ }, React__default.createElement(ui.Typography, {
2725
3107
  variant: "body2"
2726
- }, !accounts?.length ? t('Connect Wallet') : `$${totalBalance || 0}`))), React__default.createElement(AppRoutes, {
3108
+ }, !accounts?.length ? t('Connect Wallet') : `$${totalBalance || 0}`), fetchingBalance && React__default.createElement(ui.Spinner, null)))), React__default.createElement(AppRoutes, {
2727
3109
  configs: configs
2728
3110
  }));
2729
3111
  }
@@ -2731,10 +3113,12 @@ function Layout(_ref) {
2731
3113
  const globalStyles = /*#__PURE__*/ui.globalCss({
2732
3114
  '*': {
2733
3115
  '&::-webkit-scrollbar': {
2734
- width: '$8'
3116
+ width: '$8',
3117
+ height: '$8'
2735
3118
  },
2736
3119
  '&::-webkit-scrollbar-thumb': {
2737
- backgroundColor: '$neutrals400'
3120
+ backgroundColor: '$neutrals400',
3121
+ borderRadius: '$10'
2738
3122
  },
2739
3123
  '&::-webkit-scrollbar-thumb:hover': {
2740
3124
  backgroundColor: '$neutrals500'
@@ -3008,7 +3392,9 @@ function QueueManager(props) {
3008
3392
  //@ts-ignore
3009
3393
  queuesDefs: [queueManagerRangoPreset.swapQueueDef],
3010
3394
  context: context,
3011
- onPersistedDataLoaded: _manager => {},
3395
+ onPersistedDataLoaded: manager => {
3396
+ queueManagerRangoPreset.checkWaitingForNetworkChange(manager);
3397
+ },
3012
3398
  isPaused: false
3013
3399
  }, props.children);
3014
3400
  }
@@ -3036,8 +3422,10 @@ const SwapBox = _ref => {
3036
3422
  changeLanguage
3037
3423
  } = useSelectLanguage();
3038
3424
  const clearConnectedWallet = useWalletsStore.use.clearConnectedWallet();
3425
+ const [lastConnectedWalletWithNetwork, setLastConnectedWalletWithNetwork] = React.useState('');
3426
+ const [disconnectedWallet, setDisconnectedWallet] = React.useState();
3039
3427
  const evmBasedChainNames = blockchains.filter(rangoSdk.isEvmBlockchain).map(chain => chain.name);
3040
- const onUpdateState = (type, event, value, _, supportedChains) => {
3428
+ const onUpdateState = (type, event, value, state, supportedChains) => {
3041
3429
  if (event === walletsCore.Events.ACCOUNTS) {
3042
3430
  if (value) {
3043
3431
  const supportedChainNames = walletAndSupportedChainsNames(supportedChains);
@@ -3047,6 +3435,16 @@ const SwapBox = _ref => {
3047
3435
  disconnectWallet(type);
3048
3436
  }
3049
3437
  }
3438
+ if (event === walletsCore.Events.ACCOUNTS && state.connected) {
3439
+ const key = `${type}-${state.network}-${value}`;
3440
+ if (state.connected) {
3441
+ setLastConnectedWalletWithNetwork(key);
3442
+ }
3443
+ }
3444
+ if (event === walletsCore.Events.NETWORK && state.network) {
3445
+ const key = `${type}-${state.network}`;
3446
+ setLastConnectedWalletWithNetwork(key);
3447
+ }
3050
3448
  };
3051
3449
  let providers = providerAll.allProviders();
3052
3450
  React.useEffect(() => {
@@ -3078,7 +3476,12 @@ const SwapBox = _ref => {
3078
3476
  }, React__default.createElement(AppRouter, {
3079
3477
  title: configs.title,
3080
3478
  titleSize: configs.titleSize,
3081
- titleWeight: configs.titleWeight
3479
+ titleWeight: configs.titleWeight,
3480
+ lastConnectedWallet: lastConnectedWalletWithNetwork,
3481
+ disconnectedWallet: disconnectedWallet,
3482
+ clearDisconnectedWallet: () => {
3483
+ setDisconnectedWallet(undefined);
3484
+ }
3082
3485
  }, React__default.createElement(Layout, {
3083
3486
  configs: configs
3084
3487
  }))))));