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

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 (99) 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/SwapDetailsPlaceholder.d.ts +9 -0
  10. package/dist/components/SwapDetailsPlaceholder.d.ts.map +1 -0
  11. package/dist/components/TokenPreview.d.ts +1 -1
  12. package/dist/components/TokenPreview.d.ts.map +1 -1
  13. package/dist/components/UpdateUrl.d.ts.map +1 -1
  14. package/dist/components/warnings/BalanceWarnings.d.ts.map +1 -1
  15. package/dist/components/warnings/MinRequiredSlippage.d.ts +1 -1
  16. package/dist/components/warnings/MinRequiredSlippage.d.ts.map +1 -1
  17. package/dist/constants/navigationRoutes.d.ts +0 -1
  18. package/dist/constants/navigationRoutes.d.ts.map +1 -1
  19. package/dist/globalStyles.d.ts.map +1 -1
  20. package/dist/hooks/useConfirmSwap.d.ts.map +1 -1
  21. package/dist/lib.d.ts.map +1 -1
  22. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  23. package/dist/pages/HistoryPage.d.ts.map +1 -1
  24. package/dist/pages/Home.d.ts.map +1 -1
  25. package/dist/pages/LiquiditySourcesPage.d.ts.map +1 -1
  26. package/dist/pages/SelectTokenPage.d.ts.map +1 -1
  27. package/dist/pages/SettingsPage.d.ts.map +1 -1
  28. package/dist/pages/SwapDetailsPage.d.ts.map +1 -1
  29. package/dist/pages/WalletsPage.d.ts +1 -0
  30. package/dist/pages/WalletsPage.d.ts.map +1 -1
  31. package/dist/store/bestRoute.d.ts +2 -0
  32. package/dist/store/bestRoute.d.ts.map +1 -1
  33. package/dist/store/ui.d.ts.map +1 -1
  34. package/dist/store/wallets.d.ts +14 -0
  35. package/dist/store/wallets.d.ts.map +1 -1
  36. package/dist/types/routing.d.ts +1 -1
  37. package/dist/types/swap.d.ts +6 -0
  38. package/dist/types/swap.d.ts.map +1 -1
  39. package/dist/utils/common.d.ts +1 -0
  40. package/dist/utils/common.d.ts.map +1 -1
  41. package/dist/utils/date.d.ts +3 -0
  42. package/dist/utils/date.d.ts.map +1 -0
  43. package/dist/utils/routing.d.ts +1 -0
  44. package/dist/utils/routing.d.ts.map +1 -1
  45. package/dist/utils/swap.d.ts +16 -5
  46. package/dist/utils/swap.d.ts.map +1 -1
  47. package/dist/utils/time.d.ts +4 -0
  48. package/dist/utils/time.d.ts.map +1 -0
  49. package/dist/utils/wallets.d.ts +1 -1
  50. package/dist/utils/wallets.d.ts.map +1 -1
  51. package/dist/widget-embedded.cjs.development.js +1048 -705
  52. package/dist/widget-embedded.cjs.development.js.map +1 -1
  53. package/dist/widget-embedded.cjs.production.min.js +1048 -705
  54. package/dist/widget-embedded.cjs.production.min.js.map +1 -1
  55. package/dist/widget-embedded.esm.js +1057 -714
  56. package/dist/widget-embedded.esm.js.map +1 -1
  57. package/package.json +12 -11
  58. package/readme.md +1 -2
  59. package/src/App.tsx +30 -5
  60. package/src/QueueManager.tsx +5 -2
  61. package/src/components/AppRouter.tsx +24 -13
  62. package/src/components/AppRoutes.tsx +15 -12
  63. package/src/components/HeaderButtons.tsx +9 -2
  64. package/src/components/Layout.tsx +37 -5
  65. package/src/components/SwapDetailsPlaceholder.tsx +32 -0
  66. package/src/components/TokenPreview.tsx +7 -4
  67. package/src/components/UpdateUrl.tsx +1 -3
  68. package/src/components/warnings/BalanceWarnings.tsx +1 -0
  69. package/src/components/warnings/MinRequiredSlippage.tsx +9 -4
  70. package/src/constants/navigationRoutes.ts +0 -1
  71. package/src/globalStyles.ts +2 -1
  72. package/src/hooks/useConfirmSwap.ts +2 -1
  73. package/src/hooks/useNavigateBack.ts +3 -3
  74. package/src/lib.tsx +25 -3
  75. package/src/pages/ConfirmSwapPage.tsx +128 -20
  76. package/src/pages/HistoryPage.tsx +4 -4
  77. package/src/pages/Home.tsx +19 -8
  78. package/src/pages/LiquiditySourcesPage.tsx +2 -0
  79. package/src/pages/SelectTokenPage.tsx +3 -1
  80. package/src/pages/SettingsPage.tsx +3 -0
  81. package/src/pages/SwapDetailsPage.tsx +142 -6
  82. package/src/pages/WalletsPage.tsx +47 -11
  83. package/src/store/bestRoute.ts +110 -12
  84. package/src/store/ui.ts +4 -0
  85. package/src/store/wallets.ts +4 -1
  86. package/src/types/routing.ts +1 -1
  87. package/src/types/swap.ts +7 -0
  88. package/src/utils/common.ts +14 -0
  89. package/src/utils/date.ts +62 -0
  90. package/src/utils/routing.ts +23 -13
  91. package/src/utils/swap.ts +101 -10
  92. package/src/utils/time.ts +52 -0
  93. package/src/utils/wallets.ts +13 -4
  94. package/dist/components/Header.d.ts +0 -10
  95. package/dist/components/Header.d.ts.map +0 -1
  96. package/dist/pages/ConfirmWalletsPage.d.ts +0 -3
  97. package/dist/pages/ConfirmWalletsPage.d.ts.map +0 -1
  98. package/src/components/Header.tsx +0 -37
  99. 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) {
@@ -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;
@@ -679,22 +754,13 @@ function getRequiredBalanceOfWallet(selectedWallet, fee) {
679
754
  return relatedFeeStatus.requiredAssets;
680
755
  }
681
756
  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
- };
757
+ return !!currentParams.fromToken && !!currentParams.toToken && (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);
697
758
  }
759
+ //todo: refactor bestRoute store and add loadingStatus
760
+ const getBestRouteStatus = (loading, error) => {
761
+ if (loading) return 'loading';
762
+ if (error) return 'failed';else return 'success';
763
+ };
698
764
 
699
765
  const createSelectors = _store => {
700
766
  let store = _store;
@@ -845,7 +911,7 @@ const useWalletsStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.creat
845
911
  }
846
912
  });
847
913
  return {
848
- selectedWallets: state.selectedWallets.concat(selectedWallets)
914
+ selectedWallets: selectedWallets
849
915
  };
850
916
  }),
851
917
  setSelectedWallet: wallet => set(state => ({
@@ -877,6 +943,7 @@ useWalletsStore.subscribe(state => state.balances, balances => {
877
943
  }, {
878
944
  equalityFn: shallow.shallow
879
945
  });
946
+ const fetchingBalanceSelector = state => !!state.balances.find(wallet => wallet.loading);
880
947
 
881
948
  const getUsdValue = (token, amount) => new BigNumber__default(amount || ZERO).multipliedBy(token?.usdPrice || 0);
882
949
  const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/middleware.subscribeWithSelector(set => ({
@@ -896,6 +963,7 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.cre
896
963
  setBestRoute: bestRoute => set(state => {
897
964
  let outputAmount = null;
898
965
  let outputUsdValue = ZERO;
966
+ if (!state.inputAmount || state.inputAmount === '0') return {};
899
967
  if (!!bestRoute) {
900
968
  outputAmount = !!bestRoute.result?.outputAmount ? new BigNumber__default(bestRoute.result?.outputAmount) : null;
901
969
  outputUsdValue = calcOutputUsdValue(bestRoute.result?.outputAmount, getBestRouteToTokenUsdPrice(bestRoute) || state.toToken?.usdPrice);
@@ -952,6 +1020,7 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.cre
952
1020
  toToken: token
953
1021
  })),
954
1022
  setInputAmount: amount => {
1023
+ console.log(amount, typeof amount);
955
1024
  set(state => ({
956
1025
  inputAmount: amount,
957
1026
  ...(!amount && {
@@ -963,6 +1032,47 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.cre
963
1032
  inputUsdValue: getUsdValue(state.fromToken, amount)
964
1033
  })
965
1034
  }));
1035
+ },
1036
+ retry: pendingSwap => {
1037
+ const {
1038
+ tokens,
1039
+ blockchains
1040
+ } = useMetaStore.getState().meta;
1041
+ const balances = useWalletsStore.getState().balances;
1042
+ const failedIndex = pendingSwap.status === 'failed' ? pendingSwap.steps.findIndex(s => s.status === 'failed') : null;
1043
+ if (failedIndex === null || failedIndex < 0) return;
1044
+ const firstStep = pendingSwap.steps[0];
1045
+ const lastStep = pendingSwap.steps[pendingSwap.steps.length - 1];
1046
+ const fromChain = blockchains.find(blockchain => blockchain.name === firstStep.fromBlockchain) || null;
1047
+ const toChain = blockchains.find(blockchain => blockchain.name === lastStep.toBlockchain) || null;
1048
+ const fromToken = tokens.find(token => tokensAreEqual(token, {
1049
+ blockchain: firstStep.fromBlockchain,
1050
+ symbol: firstStep.fromSymbol,
1051
+ address: firstStep.fromSymbolAddress
1052
+ }));
1053
+ const toToken = tokens.find(token => tokensAreEqual(token, {
1054
+ blockchain: lastStep.toBlockchain,
1055
+ symbol: lastStep.toSymbol,
1056
+ address: lastStep.toSymbolAddress
1057
+ }));
1058
+ const sortedSourceTokens = getSortedTokens(fromChain, tokens, balances, []);
1059
+ const sortedDestinationTokens = getSortedTokens(toChain, tokens, balances, []);
1060
+ const inputAmount = pendingSwap.inputAmount;
1061
+ set({
1062
+ fromChain,
1063
+ fromToken,
1064
+ inputAmount,
1065
+ outputAmount: null,
1066
+ inputUsdValue: getUsdValue(fromToken || null, inputAmount),
1067
+ outputUsdValue: new BigNumber__default(0),
1068
+ toChain,
1069
+ toToken,
1070
+ bestRoute: null,
1071
+ loading: false,
1072
+ error: '',
1073
+ sourceTokens: sortedSourceTokens,
1074
+ destinationTokens: sortedDestinationTokens
1075
+ });
966
1076
  }
967
1077
  }))));
968
1078
  const bestRoute = (bestRouteStore, settingsStore) => {
@@ -978,12 +1088,12 @@ const bestRoute = (bestRouteStore, settingsStore) => {
978
1088
  customSlippage,
979
1089
  disabledLiquiditySources
980
1090
  } = settingsStore.getState();
981
- if (!fromToken || !toToken || !inputAmount) return;
1091
+ if (!fromToken || !toToken || !inputAmount || inputAmount === '0') return;
982
1092
  abortController?.abort();
983
1093
  abortController = new AbortController();
984
1094
  const userSlippage = !!customSlippage ? customSlippage : slippage;
985
1095
  const requestBody = createBestRouteRequestBody(fromToken, toToken, inputAmount, [], [], disabledLiquiditySources, userSlippage, false);
986
- bestRouteStore.setState({
1096
+ if (!bestRouteStore.getState().loading) bestRouteStore.setState({
987
1097
  loading: true,
988
1098
  bestRoute: null,
989
1099
  outputAmount: null,
@@ -1008,13 +1118,36 @@ const bestRoute = (bestRouteStore, settingsStore) => {
1008
1118
  });
1009
1119
  });
1010
1120
  };
1121
+ const debouncedFetchBestRoute = debounce(fetchBestRoute, 600);
1122
+ const bestRouteParamsListener = () => {
1123
+ const {
1124
+ fromToken,
1125
+ toToken,
1126
+ inputAmount,
1127
+ inputUsdValue
1128
+ } = useBestRouteStore.getState();
1129
+ if (!inputAmount || inputAmount === '0') return;
1130
+ if (tokensAreEqual(fromToken, toToken)) return bestRouteStore.setState({
1131
+ loading: false,
1132
+ bestRoute: null,
1133
+ outputAmount: new BigNumber__default(inputAmount),
1134
+ outputUsdValue: inputUsdValue
1135
+ });
1136
+ if (!bestRouteStore.getState().loading) bestRouteStore.setState({
1137
+ loading: true,
1138
+ bestRoute: null,
1139
+ outputAmount: null,
1140
+ outputUsdValue: new BigNumber__default(0)
1141
+ });
1142
+ debouncedFetchBestRoute();
1143
+ };
1011
1144
  useBestRouteStore.subscribe(state => ({
1012
1145
  fromChain: state.fromChain,
1013
1146
  fromToken: state.fromToken,
1014
1147
  toChain: state.toChain,
1015
1148
  toToken: state.toToken,
1016
1149
  inputAmount: state.inputAmount
1017
- }), fetchBestRoute.bind(null), {
1150
+ }), bestRouteParamsListener, {
1018
1151
  equalityFn: (prevState, state) => {
1019
1152
  if (isRouteParametersChanged(prevState, state)) return false;else return true;
1020
1153
  }
@@ -1023,7 +1156,7 @@ const bestRoute = (bestRouteStore, settingsStore) => {
1023
1156
  slippage: state.slippage,
1024
1157
  customSlippage: state.customSlippage,
1025
1158
  disabledLiquiditySources: state.disabledLiquiditySources
1026
- }), fetchBestRoute.bind(null), {
1159
+ }), bestRouteParamsListener, {
1027
1160
  equalityFn: (prevState, state) => {
1028
1161
  if (isRouteParametersChanged(prevState, state)) return false;else return true;
1029
1162
  }
@@ -1048,11 +1181,15 @@ var SearchParams;
1048
1181
  const useUiStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()(set => ({
1049
1182
  connectWalletsButtonDisabled: false,
1050
1183
  selectedSwapRequestId: null,
1184
+ currentPage: '',
1051
1185
  toggleConnectWalletsButton: () => set(state => ({
1052
1186
  connectWalletsButtonDisabled: !state.connectWalletsButtonDisabled
1053
1187
  })),
1054
1188
  setSelectedSwap: requestId => set({
1055
1189
  selectedSwapRequestId: requestId
1190
+ }),
1191
+ setCurrentPage: path => set({
1192
+ currentPage: path
1056
1193
  })
1057
1194
  })));
1058
1195
 
@@ -1093,7 +1230,7 @@ function UpdateUrl() {
1093
1230
  toChainString = '',
1094
1231
  toTokenString = '',
1095
1232
  fromAmount = '';
1096
- if (loadingStatus !== 'success' && ![navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname)) {
1233
+ if (loadingStatus !== 'success' && location.pathname != navigationRoutes.confirmSwap) {
1097
1234
  fromChainString = searchParamsRef.current[SearchParams.FROM_CHAIN];
1098
1235
  fromTokenString = searchParamsRef.current[SearchParams.FROM_TOKEN];
1099
1236
  toChainString = searchParamsRef.current[SearchParams.TO_CHAIN];
@@ -1186,67 +1323,6 @@ function UpdateUrl() {
1186
1323
  return null;
1187
1324
  }
1188
1325
 
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) {
1229
- const {
1230
- onClickRefresh,
1231
- title,
1232
- titleSize,
1233
- titleWeight
1234
- } = 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
- }));
1248
- }
1249
-
1250
1326
  const Box = /*#__PURE__*/ui.styled('div', {
1251
1327
  display: 'flex',
1252
1328
  flexDirection: 'column',
@@ -1534,6 +1610,39 @@ const errorMessages = {
1534
1610
  genericServerError: 'Error connecting server, please reload the app and try again'
1535
1611
  };
1536
1612
 
1613
+ const ButtonsContainer = /*#__PURE__*/ui.styled('div', {
1614
+ display: 'flex'
1615
+ });
1616
+ function HeaderButtons(props) {
1617
+ const {
1618
+ onClickRefresh
1619
+ } = props;
1620
+ const navigate = reactRouterDom.useNavigate();
1621
+ return React__default.createElement(ButtonsContainer, null, React__default.createElement(ui.Tooltip, {
1622
+ content: "Refresh"
1623
+ }, React__default.createElement(ui.Button, {
1624
+ variant: "ghost",
1625
+ onClick: onClickRefresh,
1626
+ disabled: !onClickRefresh
1627
+ }, React__default.createElement(ui.RetryIcon, {
1628
+ size: 24
1629
+ }))), React__default.createElement(ui.Tooltip, {
1630
+ content: "Transactions History"
1631
+ }, React__default.createElement(ui.Button, {
1632
+ variant: "ghost",
1633
+ onClick: () => navigate(navigationRoutes.swaps)
1634
+ }, React__default.createElement(ui.HistoryIcon, {
1635
+ size: 24
1636
+ }))), React__default.createElement(ui.Tooltip, {
1637
+ content: "Settings"
1638
+ }, React__default.createElement(ui.Button, {
1639
+ variant: "ghost",
1640
+ onClick: () => navigate(navigationRoutes.settings)
1641
+ }, React__default.createElement(ui.SettingsIcon, {
1642
+ size: 24
1643
+ }))));
1644
+ }
1645
+
1537
1646
  const Container$2 = /*#__PURE__*/ui.styled('div', {
1538
1647
  display: 'flex',
1539
1648
  flexDirection: 'column'
@@ -1558,9 +1667,7 @@ const Alerts = /*#__PURE__*/ui.styled('div', {
1558
1667
  });
1559
1668
  function Home(props) {
1560
1669
  const {
1561
- title = 'SWAP',
1562
- titleSize = 18,
1563
- titleWeight = 600
1670
+ title = 'SWAP'
1564
1671
  } = props;
1565
1672
  const isRouterInContext = reactRouterDom.useInRouterContext();
1566
1673
  const navigate = reactRouterDom.useNavigate();
@@ -1584,6 +1691,7 @@ function Home(props) {
1584
1691
  const bestRouteError = useBestRouteStore.use.error();
1585
1692
  const loadingMetaStatus = useMetaStore.use.loadingStatus();
1586
1693
  const accounts = useWalletsStore.use.accounts();
1694
+ const setCurrentPage = useUiStore.use.setCurrentPage();
1587
1695
  const swithFromAndTo = () => {
1588
1696
  setFromChain(toChain);
1589
1697
  setFromToken(toToken);
@@ -1607,11 +1715,15 @@ function Home(props) {
1607
1715
  const swapButtonState = getSwapButtonState(loadingMetaStatus, accounts, fetchingBestRoute, bestRoute, hasLimitError(bestRoute), highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath, inputIsZero);
1608
1716
  const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
1609
1717
  const highFee = hasHighFee(totalFeeInUsd);
1610
- return React__default.createElement(Container$2, null, React__default.createElement(Header, {
1718
+ React.useEffect(() => {
1719
+ setCurrentPage(navigationRoutes.home);
1720
+ return setCurrentPage.bind(null, '');
1721
+ }, []);
1722
+ return React__default.createElement(Container$2, null, React__default.createElement(ui.Header, {
1611
1723
  title: title,
1612
- titleSize: titleSize,
1613
- titleWeight: titleWeight,
1614
- onClickRefresh: fetchBestRoute
1724
+ suffix: React__default.createElement(HeaderButtons, {
1725
+ onClickRefresh: !!bestRoute ? fetchBestRoute : undefined
1726
+ })
1615
1727
  }), React__default.createElement(FromContainer, null, React__default.createElement(TokenInfo, {
1616
1728
  type: "From",
1617
1729
  chain: fromChain,
@@ -1622,7 +1734,7 @@ function Home(props) {
1622
1734
  variant: "ghost",
1623
1735
  onClick: swithFromAndTo
1624
1736
  }, React__default.createElement(ui.VerticalSwapIcon, {
1625
- size: 24
1737
+ size: 32
1626
1738
  }), isRouterInContext && React__default.createElement(SwithFromAndTo, {
1627
1739
  count: count
1628
1740
  })))), React__default.createElement(TokenInfo, {
@@ -1656,7 +1768,7 @@ function Home(props) {
1656
1768
  disabled: swapButtonState.disabled,
1657
1769
  onClick: () => {
1658
1770
  if (swapButtonState.title === 'Connect Wallet') navigate(navigationRoutes.wallets);else {
1659
- navigate(navigationRoutes.confirmWallets, {
1771
+ navigate(navigationRoutes.confirmSwap, {
1660
1772
  replace: true
1661
1773
  });
1662
1774
  }
@@ -1673,12 +1785,12 @@ const Route = _ref => {
1673
1785
  const navigate = reactRouter.useNavigate();
1674
1786
  const ref = React.useRef(true);
1675
1787
  React.useEffect(() => {
1676
- if ([navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname) && ref.current) navigate(navigationRoutes.home + location.search, {
1788
+ if (location.pathname === navigationRoutes.confirmSwap && ref.current) navigate(navigationRoutes.home + location.search, {
1677
1789
  state: 'redirect'
1678
1790
  });
1679
1791
  ref.current = false;
1680
1792
  }, []);
1681
- if ([navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname) && ref.current) return React__default.createElement(Home, Object.assign({}, props));
1793
+ if (location.pathname === navigationRoutes.confirmSwap && ref.current) return React__default.createElement(Home, Object.assign({}, props));
1682
1794
  return React__default.createElement(React__default.Fragment, null, " ", children);
1683
1795
  };
1684
1796
  function AppRouter(_ref2) {
@@ -1688,52 +1800,34 @@ function AppRouter(_ref2) {
1688
1800
  } = _ref2;
1689
1801
  const isRouterInContext = reactRouter.useInRouterContext();
1690
1802
  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
1803
  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
- }));
1804
+ blockchains
1805
+ } = useMetaStore.use.meta();
1806
+ const evmChains = blockchains.filter(rangoTypes.isEvmBlockchain);
1807
+ queueManagerRangoPreset.useQueueManager({
1808
+ lastConnectedWallet: props.lastConnectedWallet,
1809
+ clearDisconnectedWallet: props.clearDisconnectedWallet,
1810
+ disconnectedWallet: props.disconnectedWallet,
1811
+ evmChains,
1812
+ notifier: () => {}
1813
+ });
1814
+ return React__default.createElement(React__default.Fragment, null, React__default.createElement(Router, Object.assign({}, props), children), isRouterInContext && React__default.createElement(UpdateUrl, null));
1722
1815
  }
1723
1816
 
1724
1817
  function useNavigateBack() {
1725
1818
  const isRouterInContext = reactRouterDom.useInRouterContext();
1726
1819
  const navigate = reactRouterDom.useNavigate();
1727
1820
  const navigateBackFrom = currentRoute => {
1821
+ if (currentRoute === navigationRoutes.swapDetails) return navigate(navigationRoutes.swaps, {
1822
+ replace: true
1823
+ });
1728
1824
  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, {
1825
+ if ([navigationRoutes.fromChain, navigationRoutes.fromToken, navigationRoutes.toChain, navigationRoutes.toToken, navigationRoutes.settings, navigationRoutes.wallets, navigationRoutes.swaps, navigationRoutes.confirmSwap].includes(currentRoute)) navigate(navigationRoutes.home, {
1730
1826
  replace: true
1731
1827
  });else if (currentRoute === navigationRoutes.liquiditySources) navigate(navigationRoutes.settings, {
1732
1828
  replace: true
1733
1829
  });else if (currentRoute === navigationRoutes.swapDetails) navigate(navigationRoutes.swaps, {
1734
1830
  replace: true
1735
- });else if (currentRoute === navigationRoutes.confirmSwap) navigate(navigationRoutes.confirmWallets, {
1736
- replace: true
1737
1831
  });
1738
1832
  }
1739
1833
  };
@@ -1742,122 +1836,192 @@ function useNavigateBack() {
1742
1836
  };
1743
1837
  }
1744
1838
 
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', {
1796
- variants: {
1797
- showListStyle: {
1798
- true: {
1799
- paddingLeft: '$24'
1800
- }
1801
- }
1802
- }
1839
+ const Box$1 = /*#__PURE__*/ui.styled('div', {
1840
+ display: 'flex',
1841
+ flexDirection: 'column',
1842
+ width: '100%'
1803
1843
  });
1804
- const ListItem = /*#__PURE__*/ui.styled('li', {
1844
+ const Container$3 = /*#__PURE__*/ui.styled('div', {
1845
+ boxSizing: 'border-box',
1846
+ borderRadius: '$5',
1847
+ padding: '$8 $16 $16 $16',
1805
1848
  variants: {
1806
- showListStyle: {
1807
- true: {
1808
- listStyleType: 'disc',
1809
- listStylePosition: 'outside'
1849
+ type: {
1850
+ filled: {
1851
+ backgroundColor: '$neutrals300'
1852
+ },
1853
+ outlined: {
1854
+ border: '1px solid $neutrals300'
1810
1855
  }
1811
1856
  }
1812
- }
1813
- });
1814
- const Message = /*#__PURE__*/ui.styled(ui.Typography, {
1815
- display: 'block'
1816
- });
1817
- function BalanceWarnings(_ref) {
1818
- let {
1819
- messages
1820
- } = _ref;
1821
- const showListStyle = messages.length > 1;
1822
- return React__default.createElement(List, {
1823
- showListStyle: showListStyle
1824
- }, messages.map(warning => React__default.createElement(ListItem, {
1825
- showListStyle: showListStyle
1826
- }, React__default.createElement(Message, {
1827
- variant: "body2"
1828
- }, warning))));
1857
+ },
1858
+ defaultVariants: {
1859
+ type: 'filled'
1860
+ },
1861
+ '.head': {
1862
+ display: 'flex',
1863
+ justifyContent: 'space-between',
1864
+ alignItems: 'center',
1865
+ minHeight: '32px'
1866
+ },
1867
+ '.form': {
1868
+ display: 'flex',
1869
+ width: '100%',
1870
+ padding: '$2 0',
1871
+ '.selectors': {
1872
+ width: '35%',
1873
+ '._text': {
1874
+ whiteSpace: 'nowrap',
1875
+ overflow: 'hidden',
1876
+ textOverflow: 'ellipsis'
1877
+ }
1878
+ },
1879
+ '.amount': {
1880
+ width: '30%'
1881
+ }
1882
+ }
1883
+ });
1884
+ const StyledImage$1 = /*#__PURE__*/ui.styled('img', {
1885
+ width: '$24',
1886
+ maxHeight: '$24'
1887
+ });
1888
+ const ImagePlaceholder$1 = /*#__PURE__*/ui.styled('span', {
1889
+ width: '24px',
1890
+ height: '24px',
1891
+ backgroundColor: '$neutrals300',
1892
+ borderRadius: '99999px'
1893
+ });
1894
+ const OutputContainer$1 = /*#__PURE__*/ui.styled('div', {
1895
+ windth: '100%',
1896
+ height: '$48',
1897
+ borderRadius: '$5',
1898
+ backgroundColor: '$background',
1899
+ border: '1px solid transparent',
1900
+ position: 'relative',
1901
+ display: 'flex',
1902
+ alignItems: 'center',
1903
+ paddingLeft: '$8',
1904
+ paddingRight: '$8'
1905
+ });
1906
+ function TokenPreview(props) {
1907
+ const {
1908
+ chain,
1909
+ token,
1910
+ loadingStatus
1911
+ } = props;
1912
+ const {
1913
+ t
1914
+ } = reactI18next.useTranslation();
1915
+ const ItemSuffix = React__default.createElement("div", {
1916
+ style: {
1917
+ display: 'flex',
1918
+ justifyContent: 'center',
1919
+ alignItems: 'center'
1920
+ }
1921
+ }, loadingStatus === 'failed' && React__default.createElement(ui.InfoCircleIcon, {
1922
+ color: "error",
1923
+ size: 24
1924
+ }));
1925
+ return React__default.createElement(Box$1, null, React__default.createElement(Container$3, {
1926
+ type: 'outlined'
1927
+ }, React__default.createElement("div", {
1928
+ className: "head"
1929
+ }, React__default.createElement(ui.Typography, {
1930
+ variant: "body2",
1931
+ color: "neutrals800"
1932
+ }, props.label), props.usdValue && React__default.createElement(ui.Typography, {
1933
+ variant: "caption",
1934
+ color: "neutrals600"
1935
+ }, `$${numberToString(props.usdValue)}`)), React__default.createElement("div", {
1936
+ className: "form"
1937
+ }, React__default.createElement(ui.Button, {
1938
+ className: "selectors",
1939
+ variant: "outlined",
1940
+ loading: loadingStatus === 'loading',
1941
+ prefix: loadingStatus === 'success' && chain ? React__default.createElement(StyledImage$1, {
1942
+ src: chain.logo
1943
+ }) : React__default.createElement(ImagePlaceholder$1, null),
1944
+ suffix: ItemSuffix,
1945
+ align: "start",
1946
+ size: "large"
1947
+ }, loadingStatus === 'success' && chain ? chain.displayName : t('Chain')), React__default.createElement(ui.Spacer, {
1948
+ size: 12
1949
+ }), React__default.createElement(ui.Button, {
1950
+ className: "selectors",
1951
+ variant: "outlined",
1952
+ loading: loadingStatus === 'loading',
1953
+ prefix: loadingStatus === 'success' && token ? React__default.createElement(StyledImage$1, {
1954
+ src: token.image
1955
+ }) : React__default.createElement(ImagePlaceholder$1, null),
1956
+ suffix: ItemSuffix,
1957
+ size: "large",
1958
+ align: "start"
1959
+ }, loadingStatus === 'success' && token ? token.symbol : t('Token')), React__default.createElement(ui.Spacer, {
1960
+ size: 12
1961
+ }), React__default.createElement("div", {
1962
+ className: "amount"
1963
+ }, React__default.createElement(OutputContainer$1, null, React__default.createElement(ui.Typography, {
1964
+ variant: "h4"
1965
+ }, props.amount))))));
1829
1966
  }
1830
1967
 
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
- });
1968
+ const Container$4 = /*#__PURE__*/ui.styled('div', {
1969
+ display: 'flex',
1970
+ alignItems: 'center',
1971
+ justifyContent: 'space-between',
1972
+ padding: '$8',
1973
+ borderRadius: '$5',
1974
+ backgroundColor: '$neutrals300',
1975
+ color: '$neutrals800',
1976
+ fontSize: '$12',
1977
+ '.routes': {
1978
+ display: 'flex',
1979
+ alignItems: 'center'
1980
+ },
1981
+ '.fee': {
1982
+ display: 'flex',
1983
+ alignItems: 'center'
1984
+ }
1985
+ });
1986
+ function RoutesOverview(props) {
1987
+ if (!props.routes) return null;
1988
+ const swaps = props.routes.result?.swaps;
1989
+ return React__default.createElement(Container$4, null, React__default.createElement("div", {
1990
+ className: "routes"
1991
+ }, swaps?.map((swap, idx) => {
1992
+ const isLast = idx + 1 == swaps.length;
1993
+ return React__default.createElement(React__default.Fragment, null, React__default.createElement("div", {
1994
+ className: "route"
1995
+ }, swap.from.symbol), React__default.createElement(ui.ChevronRightIcon, {
1996
+ size: 12
1997
+ }), isLast ? React__default.createElement("div", {
1998
+ className: "route"
1999
+ }, swap.to.symbol) : null);
2000
+ })), props.totalFee ? React__default.createElement("div", {
2001
+ className: "fee"
2002
+ }, React__default.createElement(ui.GasIcon, {
2003
+ size: 12
2004
+ }), React__default.createElement(ui.Spacer, {
2005
+ size: 4
2006
+ }), "$", props.totalFee) : null);
1859
2007
  }
1860
2008
 
2009
+ var ConfirmSwapErrorTypes;
2010
+ (function (ConfirmSwapErrorTypes) {
2011
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["NO_ROUTE"] = 0] = "NO_ROUTE";
2012
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS"] = 1] = "ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS";
2013
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["REQUEST_FAILED"] = 2] = "REQUEST_FAILED";
2014
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["INSUFFICIENT_SLIPPAGE"] = 3] = "INSUFFICIENT_SLIPPAGE";
2015
+ })(ConfirmSwapErrorTypes || (ConfirmSwapErrorTypes = {}));
2016
+ var ConfirmSwapWarningTypes;
2017
+ (function (ConfirmSwapWarningTypes) {
2018
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_UPDATED"] = 0] = "ROUTE_UPDATED";
2019
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_SWAPPERS_UPDATED"] = 1] = "ROUTE_SWAPPERS_UPDATED";
2020
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_COINS_UPDATED"] = 2] = "ROUTE_COINS_UPDATED";
2021
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_AND_OUTPUT_AMOUNT_UPDATED"] = 3] = "ROUTE_AND_OUTPUT_AMOUNT_UPDATED";
2022
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["INSUFFICIENT_BALANCE"] = 4] = "INSUFFICIENT_BALANCE";
2023
+ })(ConfirmSwapWarningTypes || (ConfirmSwapWarningTypes = {}));
2024
+
1861
2025
  function useConfirmSwap() {
1862
2026
  const fromToken = useBestRouteStore.use.fromToken();
1863
2027
  const toToken = useBestRouteStore.use.toToken();
@@ -1898,6 +2062,7 @@ function useConfirmSwap() {
1898
2062
  proceedAnywayRef.current = false;
1899
2063
  if (confiremedRouteRef.current) {
1900
2064
  const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRouteRef.current, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
2065
+ //@ts-ignore
1901
2066
  return newSwap;
1902
2067
  }
1903
2068
  return;
@@ -1960,6 +2125,7 @@ function useConfirmSwap() {
1960
2125
  disabledSwappersGroups: disabledLiquiditySources
1961
2126
  };
1962
2127
  const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRoute, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
2128
+ //@ts-ignore
1963
2129
  return newSwap;
1964
2130
  } else if (!proceedAnywayRef.current) {
1965
2131
  proceedAnywayRef.current = true;
@@ -1989,62 +2155,262 @@ function useConfirmSwap() {
1989
2155
  };
1990
2156
  }
1991
2157
 
1992
- function ConfirmSwapPage() {
1993
- const setSelectedSwap = useUiStore.use.setSelectedSwap();
1994
- const {
1995
- navigateBackFrom
1996
- } = useNavigateBack();
1997
- const {
1998
- manager
1999
- } = queueManagerReact.useManager();
2158
+ function ChangeSlippageButton() {
2000
2159
  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
- });
2160
+ return React__default.createElement(ui.Button, {
2161
+ type: "primary",
2162
+ variant: "outlined",
2163
+ size: "small",
2164
+ onClick: () => navigate(navigationRoutes.settings)
2165
+ }, "Change Slippage");
2043
2166
  }
2044
2167
 
2045
- const getPendingSwaps = manager => {
2046
- const result = [];
2047
- manager?.getAll().forEach((q, id) => {
2168
+ const StyledMessage = /*#__PURE__*/ui.styled(ui.Typography, {
2169
+ color: '$error500 !important'
2170
+ });
2171
+ function MinRequiredSlippage(_ref) {
2172
+ let {
2173
+ minRequiredSlippage
2174
+ } = _ref;
2175
+ return React__default.createElement(StyledMessage, {
2176
+ variant: "body2"
2177
+ }, "We recommend you to increase slippage to at least \u00A0", minRequiredSlippage, "\u00A0 for this route.", React__default.createElement(ui.Spacer, {
2178
+ size: 8,
2179
+ direction: "vertical"
2180
+ }), React__default.createElement(ChangeSlippageButton, null));
2181
+ }
2182
+
2183
+ function ConfirmSwapErrors(errors) {
2184
+ return errors.flatMap(error => {
2185
+ switch (error.type) {
2186
+ case ConfirmSwapErrorTypes.NO_ROUTE:
2187
+ return React__default.createElement(ui.Typography, {
2188
+ variant: "body2"
2189
+ }, "No routes found. Please try again later.");
2190
+ case ConfirmSwapErrorTypes.REQUEST_FAILED:
2191
+ return React__default.createElement(ui.Typography, {
2192
+ variant: "body2"
2193
+ }, `Failed to confirm swap ${error.status ? `'status': ${error.status})` : ''}, please try again.`);
2194
+ case ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS:
2195
+ return React__default.createElement(ui.Typography, {
2196
+ variant: "body2"
2197
+ }, "Route updated and price impact is too high, try again later!");
2198
+ case ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE:
2199
+ return React__default.createElement(MinRequiredSlippage, {
2200
+ minRequiredSlippage: error.minRequiredSlippage
2201
+ });
2202
+ default:
2203
+ return [];
2204
+ }
2205
+ });
2206
+ }
2207
+
2208
+ const List = /*#__PURE__*/ui.styled('ul', {
2209
+ variants: {
2210
+ showListStyle: {
2211
+ true: {
2212
+ paddingLeft: '$24'
2213
+ }
2214
+ }
2215
+ }
2216
+ });
2217
+ const ListItem = /*#__PURE__*/ui.styled('li', {
2218
+ variants: {
2219
+ showListStyle: {
2220
+ true: {
2221
+ listStyleType: 'disc',
2222
+ listStylePosition: 'outside'
2223
+ }
2224
+ }
2225
+ }
2226
+ });
2227
+ const Message = /*#__PURE__*/ui.styled(ui.Typography, {
2228
+ display: 'block',
2229
+ color: '$warning500 !important'
2230
+ });
2231
+ function BalanceWarnings(_ref) {
2232
+ let {
2233
+ messages
2234
+ } = _ref;
2235
+ const showListStyle = messages.length > 1;
2236
+ return React__default.createElement(List, {
2237
+ showListStyle: showListStyle
2238
+ }, messages.map(warning => React__default.createElement(ListItem, {
2239
+ showListStyle: showListStyle
2240
+ }, React__default.createElement(Message, {
2241
+ variant: "body2"
2242
+ }, warning))));
2243
+ }
2244
+
2245
+ function ConfirmSwapWarnings(warnings) {
2246
+ return warnings.flatMap(warning => {
2247
+ switch (warning.type) {
2248
+ case ConfirmSwapWarningTypes.ROUTE_UPDATED:
2249
+ return React__default.createElement(ui.Typography, {
2250
+ variant: "body2"
2251
+ }, "Route has been updated.");
2252
+ case ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED:
2253
+ return React__default.createElement(ui.Typography, {
2254
+ variant: "body2"
2255
+ }, `Output amount changed to ${warning.newOutputAmount}
2256
+ (${warning.percentageChange}% change).`);
2257
+ case ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED:
2258
+ return React__default.createElement(ui.Typography, {
2259
+ variant: "body2"
2260
+ }, "Route swappers has been updated.");
2261
+ case ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED:
2262
+ return React__default.createElement(ui.Typography, {
2263
+ variant: "body2"
2264
+ }, "Route internal coins has been updated.");
2265
+ case ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE:
2266
+ return React__default.createElement(BalanceWarnings, {
2267
+ messages: warning.messages
2268
+ });
2269
+ default:
2270
+ return [];
2271
+ }
2272
+ });
2273
+ }
2274
+
2275
+ function HighSlippageWarning(props) {
2276
+ const {
2277
+ selectedSlippage
2278
+ } = props;
2279
+ return React__default.createElement(ui.Alert, {
2280
+ type: "warning",
2281
+ footer: React__default.createElement(ChangeSlippageButton, null)
2282
+ }, "Caution, your slippage is high (=", selectedSlippage, "). Your trade may be front run.");
2283
+ }
2284
+
2285
+ function ConfirmSwapExtraMessages(props) {
2286
+ const {
2287
+ selectedSlippage
2288
+ } = props;
2289
+ const highSlippage = selectedSlippage >= HIGH_SLIPPAGE;
2290
+ return React__default.createElement(React__default.Fragment, null, highSlippage && React__default.createElement(HighSlippageWarning, {
2291
+ selectedSlippage: selectedSlippage
2292
+ }));
2293
+ }
2294
+
2295
+ function ConfirmSwapPage() {
2296
+ const navigate = reactRouterDom.useNavigate();
2297
+ const {
2298
+ navigateBackFrom
2299
+ } = useNavigateBack();
2300
+ const bestRoute = useBestRouteStore.use.bestRoute();
2301
+ const fetchingBestRoute = useBestRouteStore.use.loading();
2302
+ const fetchingBestRouteError = useBestRouteStore.use.error();
2303
+ const setSelectedSwap = useUiStore.use.setSelectedSwap();
2304
+ const {
2305
+ blockchains,
2306
+ tokens
2307
+ } = useMetaStore.use.meta();
2308
+ const accounts = useWalletsStore.use.accounts();
2309
+ const selectedWallets = useWalletsStore.use.selectedWallets();
2310
+ const initSelectedWallets = useWalletsStore.use.initSelectedWallets();
2311
+ const setSelectedWallet = useWalletsStore.use.setSelectedWallet();
2312
+ const slippage = useSettingsStore.use.slippage();
2313
+ const customSlippage = useSettingsStore.use.customSlippage();
2314
+ const bestRouteloadingStatus = getBestRouteStatus(fetchingBestRoute, !!fetchingBestRouteError);
2315
+ const {
2316
+ manager
2317
+ } = queueManagerReact.useManager();
2318
+ const {
2319
+ loading,
2320
+ errors,
2321
+ warnings,
2322
+ confirmSwap
2323
+ } = useConfirmSwap();
2324
+ const selectedSlippage = customSlippage || slippage;
2325
+ const showHighSlippageWarning = !errors.find(error => error.type === ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE);
2326
+ const {
2327
+ getWalletInfo,
2328
+ connect
2329
+ } = walletsCore.useWallets();
2330
+ const confirmDisabled = fetchingBestRoute || !requiredWallets(bestRoute).every(chain => selectedWallets.map(wallet => wallet.chain).includes(chain));
2331
+ const firstStep = bestRoute?.result?.swaps[0];
2332
+ const lastStep = bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1];
2333
+ const fromAmount = decimalNumber(firstStep?.fromAmount, 3);
2334
+ const toAmount = decimalNumber(lastStep?.toAmount, 3);
2335
+ React.useEffect(() => {
2336
+ initSelectedWallets();
2337
+ }, []);
2338
+ const selectableWallets = getSelectableWallets(accounts, selectedWallets, getWalletInfo);
2339
+ const handleConnectChain = wallet => {
2340
+ const network = wallet;
2341
+ getKeplrCompatibleConnectedWallets(selectableWallets).forEach(compatibleWallet => connect?.(compatibleWallet, network));
2342
+ };
2343
+ const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
2344
+ return React__default.createElement(ui.ConfirmSwap, {
2345
+ requiredWallets: getRequiredChains(bestRoute),
2346
+ selectableWallets: selectableWallets,
2347
+ onBack: navigateBackFrom.bind(null, navigationRoutes.confirmSwap),
2348
+ onConfirm: () => {
2349
+ confirmSwap?.().then(swap => {
2350
+ if (swap) {
2351
+ manager?.create('swap', {
2352
+ swapDetails: swap
2353
+ }, {
2354
+ id: swap.requestId
2355
+ });
2356
+ setSelectedSwap(swap.requestId);
2357
+ navigate(navigationRoutes.swaps + `/${swap.requestId}`, {
2358
+ replace: true
2359
+ });
2360
+ }
2361
+ });
2362
+ },
2363
+ onChange: wallet => setSelectedWallet(wallet),
2364
+ confirmDisabled: confirmDisabled,
2365
+ handleConnectChain: wallet => handleConnectChain(wallet),
2366
+ isExperimentalChain: wallet => getKeplrCompatibleConnectedWallets(selectableWallets).length > 0 ? isExperimentalChain(blockchains, wallet) : false,
2367
+ previewInputs: React__default.createElement(React__default.Fragment, null, React__default.createElement(TokenPreview, {
2368
+ chain: {
2369
+ displayName: firstStep?.from.blockchain || '',
2370
+ logo: firstStep?.from.blockchainLogo || ''
2371
+ },
2372
+ token: {
2373
+ symbol: firstStep?.from.symbol || '',
2374
+ image: firstStep?.from.logo || ''
2375
+ },
2376
+ usdValue: calcOutputUsdValue(fromAmount, firstStep?.from.usdPrice),
2377
+ amount: fromAmount,
2378
+ label: i18n.t('From'),
2379
+ loadingStatus: bestRouteloadingStatus
2380
+ }), React__default.createElement(ui.Spacer, {
2381
+ size: 12,
2382
+ direction: "vertical"
2383
+ }), React__default.createElement(TokenPreview, {
2384
+ chain: {
2385
+ displayName: lastStep?.to.blockchain || '',
2386
+ logo: lastStep?.to.blockchainLogo || ''
2387
+ },
2388
+ token: {
2389
+ symbol: lastStep?.to.symbol || '',
2390
+ image: lastStep?.to.logo || ''
2391
+ },
2392
+ usdValue: calcOutputUsdValue(toAmount, lastStep?.to.usdPrice),
2393
+ amount: toAmount,
2394
+ label: i18n.t('To'),
2395
+ loadingStatus: bestRouteloadingStatus
2396
+ })),
2397
+ previewRoutes: React__default.createElement(RoutesOverview, {
2398
+ routes: bestRoute,
2399
+ totalFee: numberToString(totalFeeInUsd, 0, 2)
2400
+ }),
2401
+ loading: loading,
2402
+ errors: ConfirmSwapErrors(errors),
2403
+ warnings: ConfirmSwapWarnings(warnings),
2404
+ extraMessages: showHighSlippageWarning && React__default.createElement(ConfirmSwapExtraMessages, {
2405
+ selectedSlippage: selectedSlippage
2406
+ }),
2407
+ confirmButtonTitle: warnings.length > 0 || errors.length > 0 ? 'Proceed anyway!' : 'Confirm swap!'
2408
+ });
2409
+ }
2410
+
2411
+ const getPendingSwaps = manager => {
2412
+ const result = [];
2413
+ manager?.getAll().forEach((q, id) => {
2048
2414
  const storage = q.list.getStorage();
2049
2415
  if (storage?.swapDetails) {
2050
2416
  result.push({
@@ -2056,6 +2422,31 @@ const getPendingSwaps = manager => {
2056
2422
  return result.sort((a, b) => Number(b.swap.creationTime) - Number(a.swap.creationTime));
2057
2423
  };
2058
2424
 
2425
+ const groupSwapsByDate = swaps => {
2426
+ const output = new Map([['today', {
2427
+ title: 'Today',
2428
+ swaps: []
2429
+ }], ['week', {
2430
+ title: 'This week',
2431
+ swaps: []
2432
+ }], ['month', {
2433
+ title: 'This month',
2434
+ swaps: []
2435
+ }], ['year', {
2436
+ title: 'This year',
2437
+ swaps: []
2438
+ }], ['history', {
2439
+ title: 'History',
2440
+ swaps: []
2441
+ }]]);
2442
+ const now = dayjs();
2443
+ swaps.forEach(swap => {
2444
+ const swapDate = dayjs(Number(swap.creationTime));
2445
+ 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);
2446
+ });
2447
+ return Array.from(output.values());
2448
+ };
2449
+
2059
2450
  function HistoryPage() {
2060
2451
  const setSelectedSwap = useUiStore.use.setSelectedSwap();
2061
2452
  const navigate = reactRouterDom.useNavigate();
@@ -2071,16 +2462,14 @@ function HistoryPage() {
2071
2462
  } = _ref;
2072
2463
  return swap;
2073
2464
  });
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
2465
+ return React__default.createElement(ui.History, {
2080
2466
  list: pendingSwaps,
2467
+ groupBy: groupSwapsByDate,
2081
2468
  onSwapClick: requestId => {
2082
2469
  setSelectedSwap(requestId);
2083
- navigate(navigationRoutes.swaps + `/${requestId}`);
2470
+ navigate(navigationRoutes.swaps + `/${requestId}`, {
2471
+ replace: true
2472
+ });
2084
2473
  },
2085
2474
  onBack: navigateBackFrom.bind(null, navigationRoutes.swaps)
2086
2475
  });
@@ -2091,6 +2480,7 @@ function LiquiditySourcePage(_ref) {
2091
2480
  supportedSwappers
2092
2481
  } = _ref;
2093
2482
  const swappers = useMetaStore.use.meta().swappers;
2483
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2094
2484
  const toggleLiquiditySource = useSettingsStore.use.toggleLiquiditySource();
2095
2485
  const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
2096
2486
  const toggleAllLiquiditySources = useSettingsStore.use.toggleAllLiquiditySources();
@@ -2116,7 +2506,8 @@ function LiquiditySourcePage(_ref) {
2116
2506
  toggleAll: toggleAllLiquiditySources,
2117
2507
  list: supportedSwappers !== 'all' ? uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0) : uniqueSwappersGroups,
2118
2508
  onChange: liquiditySource => toggleLiquiditySource(liquiditySource.title),
2119
- onBack: navigateBackFrom.bind(null, navigationRoutes.liquiditySources)
2509
+ onBack: navigateBackFrom.bind(null, navigationRoutes.liquiditySources),
2510
+ loadingStatus: loadingMetaStatus
2120
2511
  });
2121
2512
  }
2122
2513
 
@@ -2159,390 +2550,168 @@ function SelectTokenPage(props) {
2159
2550
  const destinationTokens = useBestRouteStore.use.destinationTokens();
2160
2551
  const supportedSourceTokens = supportedTokens === 'all' ? sourceTokens : sourceTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2161
2552
  const supportedDestinationTokens = supportedTokens === 'all' ? destinationTokens : destinationTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2162
- console.log(supportedSourceTokens);
2163
2553
  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);
2554
+ const toToken = useBestRouteStore.use.toToken();
2555
+ const setFromToken = useBestRouteStore.use.setFromToken();
2556
+ const setToToken = useBestRouteStore.use.setToToken();
2557
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2558
+ return React__default.createElement(ui.TokenSelector, {
2559
+ type: type === 'from' ? 'Source' : 'Destination',
2560
+ list: type == 'from' ? supportedSourceTokens : supportedDestinationTokens,
2561
+ selected: type === 'from' ? fromToken : toToken,
2562
+ onChange: token => {
2563
+ if (type === 'from') setFromToken(token);else setToToken(token);
2564
+ navigateBackFrom(navigationRoutes.fromToken);
2565
+ },
2566
+ onBack: navigateBackFrom.bind(null, navigationRoutes.fromToken),
2567
+ loadingStatus: loadingMetaStatus
2568
+ });
2466
2569
  }
2467
2570
 
2468
- function ConfirmWalletsPage() {
2571
+ function SettingsPage(_ref) {
2572
+ let {
2573
+ supportedSwappers
2574
+ } = _ref;
2575
+ const slippage = useSettingsStore.use.slippage();
2576
+ const setSlippage = useSettingsStore.use.setSlippage();
2577
+ const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
2578
+ const customSlippage = useSettingsStore.use.customSlippage();
2579
+ const setCustomSlippage = useSettingsStore.use.setCustomSlippage();
2580
+ const theme = useSettingsStore.use.theme();
2581
+ const setTheme = useSettingsStore.use.setTheme();
2582
+ const swappers = useMetaStore.use.meta().swappers;
2469
2583
  const navigate = reactRouterDom.useNavigate();
2470
2584
  const {
2471
2585
  navigateBackFrom
2472
2586
  } = useNavigateBack();
2473
- const bestRoute = useBestRouteStore.use.bestRoute();
2587
+ const infiniteApprove = useSettingsStore.use.infiniteApprove();
2588
+ const toggleInfiniteApprove = useSettingsStore.use.toggleInfiniteApprove();
2589
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2590
+ const uniqueSwappersGroups = [];
2591
+ removeDuplicateFrom(swappers.map(s => s.swapperGroup)).map(swapperGroup => {
2592
+ return swappers.find(s => s.swapperGroup === swapperGroup);
2593
+ }).find(s => {
2594
+ if (s) {
2595
+ for (const type of s.types) {
2596
+ uniqueSwappersGroups.push({
2597
+ title: s.swapperGroup,
2598
+ logo: s.logo,
2599
+ type,
2600
+ selected: !disabledLiquiditySources.includes(s.swapperGroup)
2601
+ });
2602
+ }
2603
+ }
2604
+ });
2605
+ supportedSwappers !== 'all' && uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0);
2606
+ const supportedUniqueSwappersGroups = supportedSwappers !== 'all' ? uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0) : uniqueSwappersGroups;
2607
+ return React__default.createElement(ui.Settings, {
2608
+ slippages: SLIPPAGES,
2609
+ selectedSlippage: slippage,
2610
+ onSlippageChange: slippage => setSlippage(slippage),
2611
+ onLiquiditySourcesClick: () => navigate(navigationRoutes.liquiditySources),
2612
+ onBack: navigateBackFrom.bind(null, navigationRoutes.settings),
2613
+ liquiditySources: supportedUniqueSwappersGroups,
2614
+ selectedLiquiditySources: supportedUniqueSwappersGroups.filter(s => s.selected),
2615
+ customSlippage: customSlippage || NaN,
2616
+ onCustomSlippageChange: setCustomSlippage,
2617
+ minSlippage: MIN_SLIPPGAE,
2618
+ maxSlippage: MAX_SLIPPAGE,
2619
+ selectedTheme: theme,
2620
+ onThemeChange: setTheme,
2621
+ infiniteApprove: infiniteApprove,
2622
+ toggleInfiniteApprove: toggleInfiniteApprove,
2623
+ loadingStatus: loadingMetaStatus
2624
+ });
2625
+ }
2626
+
2627
+ const ListContainer = /*#__PURE__*/ui.styled('div', {
2628
+ display: 'grid',
2629
+ gap: '.5rem',
2630
+ gridTemplateColumns: ' repeat(2, minmax(0, 1fr))',
2631
+ alignContent: 'baseline',
2632
+ padding: '0.5rem',
2633
+ overflowY: 'auto'
2634
+ });
2635
+ const LoaderContainer = /*#__PURE__*/ui.styled('div', {
2636
+ display: 'flex',
2637
+ justifyContent: 'center',
2638
+ width: '100%',
2639
+ position: 'absolute',
2640
+ top: '50%'
2641
+ });
2642
+ const AlertContainer = /*#__PURE__*/ui.styled('div', {
2643
+ paddingBottom: '$16'
2644
+ });
2645
+ function WalletsPage(_ref) {
2646
+ let {
2647
+ supportedWallets,
2648
+ multiWallets
2649
+ } = _ref;
2474
2650
  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();
2651
+ navigateBackFrom
2652
+ } = useNavigateBack();
2482
2653
  const {
2654
+ state,
2655
+ disconnect,
2483
2656
  getWalletInfo,
2484
2657
  connect
2485
2658
  } = 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);
2659
+ const wallets = getlistWallet(state, getWalletInfo, supportedWallets === 'all' ? Object.values(walletsShared.WalletType) : supportedWallets);
2660
+ const walletsRef = React.useRef();
2661
+ let sortedWallets = walletsShared.detectMobileScreens() ? wallets.filter(wallet => wallet.showOnMobile) : wallets;
2662
+ sortedWallets = sortWalletsBasedOnState(sortedWallets);
2663
+ const [walletErrorMessage, setWalletErrorMessage] = React.useState('');
2664
+ const toggleConnectWalletsButton = useUiStore.use.toggleConnectWalletsButton();
2665
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2666
+ const {
2667
+ t
2668
+ } = reactI18next.useTranslation();
2669
+ const onSelectWallet = async type => {
2670
+ const wallet = state(type);
2671
+ try {
2672
+ if (walletErrorMessage) setWalletErrorMessage('');
2673
+ if (wallet.connected) {
2674
+ await disconnect(type);
2675
+ } else {
2676
+ if (!multiWallets && !!wallets.find(w => w.state === ui.WalletState.CONNECTED)) {
2677
+ return;
2678
+ }
2679
+ await connect(type);
2680
+ }
2681
+ } catch (e) {
2682
+ setWalletErrorMessage('Error: ' + e?.message);
2683
+ }
2684
+ };
2685
+ const disconnectConnectingWallets = () => {
2686
+ const connectingWallets = walletsRef.current?.filter(wallet => wallet.state === ui.WalletState.CONNECTING) || [];
2687
+ for (const wallet of connectingWallets) {
2688
+ disconnect(wallet.type);
2689
+ }
2690
+ };
2491
2691
  React.useEffect(() => {
2492
- initSelectedWallets();
2692
+ toggleConnectWalletsButton();
2693
+ return () => {
2694
+ disconnectConnectingWallets();
2695
+ toggleConnectWalletsButton();
2696
+ };
2493
2697
  }, []);
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
- });
2698
+ React.useEffect(() => {
2699
+ walletsRef.current = wallets;
2700
+ }, [wallets]);
2701
+ return React__default.createElement(ui.SecondaryPage, {
2702
+ title: t('Select Wallet') || '',
2703
+ textField: false,
2704
+ onBack: navigateBackFrom.bind(null, navigationRoutes.wallets)
2705
+ }, React__default.createElement(React__default.Fragment, null, walletErrorMessage && React__default.createElement(AlertContainer, null, React__default.createElement(ui.Alert, {
2706
+ type: "error"
2707
+ }, walletErrorMessage)), loadingMetaStatus === 'loading' && React__default.createElement(LoaderContainer, {
2708
+ className: "loader"
2709
+ }, React__default.createElement(ui.Spinner, {
2710
+ size: 24
2711
+ })), 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, {
2712
+ key: `${index}-${wallet.type}`,
2713
+ onClick: onSelectWallet
2714
+ }))))));
2546
2715
  }
2547
2716
 
2548
2717
  function useCopyToClipboard(resetInterval) {
@@ -2563,15 +2732,87 @@ function useCopyToClipboard(resetInterval) {
2563
2732
  return [isCopied, handleCopy];
2564
2733
  }
2565
2734
 
2735
+ function timeSince(timeMillis) {
2736
+ const seconds = Math.floor((new Date().getTime() - timeMillis) / 1000);
2737
+ let intervalType;
2738
+ let interval = Math.floor(seconds / 31536000);
2739
+ if (interval >= 1) {
2740
+ intervalType = 'year';
2741
+ } else {
2742
+ interval = Math.floor(seconds / 2592000);
2743
+ if (interval >= 1) {
2744
+ intervalType = 'month';
2745
+ } else {
2746
+ interval = Math.floor(seconds / 86400);
2747
+ if (interval >= 1) {
2748
+ intervalType = 'day';
2749
+ } else {
2750
+ interval = Math.floor(seconds / 3600);
2751
+ if (interval >= 1) {
2752
+ intervalType = 'hour';
2753
+ } else {
2754
+ interval = Math.floor(seconds / 60);
2755
+ if (interval >= 1) {
2756
+ intervalType = 'minute';
2757
+ } else {
2758
+ interval = seconds;
2759
+ intervalType = 'second';
2760
+ }
2761
+ }
2762
+ }
2763
+ }
2764
+ }
2765
+ if (interval > 1 || interval === 0) {
2766
+ intervalType += 's';
2767
+ }
2768
+ return interval + ' ' + intervalType;
2769
+ }
2770
+ function getSwapDate(pendingSwap) {
2771
+ 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()}`;
2772
+ }
2773
+
2774
+ const PlaceholderContainer = /*#__PURE__*/ui.styled('div', {
2775
+ height: '450px'
2776
+ });
2777
+ function SwapDetailsPlaceholder(props) {
2778
+ const {
2779
+ requestId,
2780
+ loading,
2781
+ onBack
2782
+ } = props;
2783
+ return React__default.createElement(ui.SecondaryPage, {
2784
+ title: "Swap Details",
2785
+ textField: false,
2786
+ onBack: onBack
2787
+ }, React__default.createElement(PlaceholderContainer, null, loading ? React__default.createElement(LoaderContainer, null, React__default.createElement(ui.Spinner, {
2788
+ size: 24
2789
+ })) : React__default.createElement(ui.Alert, {
2790
+ type: "secondary",
2791
+ title: `Swap with request ID = ${requestId} not found.`
2792
+ })));
2793
+ }
2794
+
2566
2795
  function SwapDetailsPage() {
2567
2796
  const selectedSwapRequestId = useUiStore.use.selectedSwapRequestId();
2797
+ const {
2798
+ canSwitchNetworkTo,
2799
+ connect
2800
+ } = walletsCore.useWallets();
2801
+ const retry = useBestRouteStore.use.retry();
2802
+ const navigate = reactRouterDom.useNavigate();
2568
2803
  const {
2569
2804
  navigateBackFrom
2570
2805
  } = useNavigateBack();
2806
+ const [isCopied, handleCopy] = useCopyToClipboard(2000);
2571
2807
  const {
2572
2808
  manager
2573
2809
  } = queueManagerReact.useManager();
2574
- const [isCopied, handleCopy] = useCopyToClipboard(2000);
2810
+ const [loading, setLoading] = React.useState(true);
2811
+ React.useEffect(() => {
2812
+ setTimeout(() => {
2813
+ setLoading(false);
2814
+ }, 5000);
2815
+ }, []);
2575
2816
  const pendingSwaps = getPendingSwaps(manager);
2576
2817
  const selectedSwap = pendingSwaps.find(_ref => {
2577
2818
  let {
@@ -2579,92 +2820,161 @@ function SwapDetailsPage() {
2579
2820
  } = _ref;
2580
2821
  return swap.requestId === selectedSwapRequestId;
2581
2822
  });
2582
- //TODO: implement swap cancellation (move queueManager logic to queueManager/rango-preset)
2583
2823
  const onCancel = () => {
2584
- const swap = selectedSwap ? manager?.get(selectedSwap.id) : undefined;
2824
+ const swap = manager?.get(selectedSwap?.id);
2585
2825
  if (swap) queueManagerRangoPreset.cancelSwap(swap);
2586
2826
  };
2587
- return React__default.createElement(ui.SwapHistory, {
2827
+ const swap = selectedSwap?.swap;
2828
+ if (!swap) return React__default.createElement(SwapDetailsPlaceholder, {
2829
+ requestId: selectedSwapRequestId || '',
2830
+ loading: loading,
2831
+ onBack: navigateBackFrom.bind(null, navigationRoutes.swapDetails)
2832
+ });
2833
+ const firstStep = swap.steps[0];
2834
+ const lastStep = swap.steps[swap.steps.length - 1];
2835
+ const fromAmount = numberToString(swap.inputAmount);
2836
+ const toAmount = numberToString(swap.simulationResult.outputAmount);
2837
+ const currentStep = queueManagerRangoPreset.getCurrentStep(swap);
2838
+ const currentStepBlockchain = currentStep ? queueManagerRangoPreset.getCurrentBlockchainOfOrNull(swap, currentStep) : null;
2839
+ const currentStepWallet = currentStep ? queueManagerRangoPreset.getRelatedWalletOrNull(swap, currentStep) : null;
2840
+ const currentStepNetworkStatus = currentStep?.networkStatus;
2841
+ const swapMessages = getSwapMessages(swap, currentStep);
2842
+ const networkWarningState = isNetworkStatusInWarningState(currentStep);
2843
+ const swapDate = getSwapDate(swap);
2844
+ const shouldRetry = shouldRetrySwap(swap);
2845
+ const switchNetwork = !!currentStepBlockchain && !!currentStepWallet?.walletType && currentStepNetworkStatus === queueManagerRangoPreset.PendingSwapNetworkStatus.WaitingForNetworkChange && canSwitchNetworkTo(currentStepWallet?.walletType, currentStepBlockchain) ? connect.bind(null, currentStepWallet.walletType, currentStepBlockchain) : undefined;
2846
+ const lastConvertedTokenInFailedSwap = getLastConvertedTokenInFailedSwap(swap);
2847
+ return React__default.createElement(ui.SwapHistory, Object.assign({
2588
2848
  onBack: navigateBackFrom.bind(null, navigationRoutes.swapDetails),
2849
+ previewInputs: React__default.createElement(React__default.Fragment, null, React__default.createElement(TokenPreview, {
2850
+ chain: {
2851
+ displayName: firstStep?.fromBlockchain || '',
2852
+ // @ts-ignore
2853
+ logo: firstStep?.fromBlockchainLogo || ''
2854
+ },
2855
+ token: {
2856
+ symbol: firstStep?.fromSymbol || '',
2857
+ image: firstStep?.fromLogo || ''
2858
+ },
2859
+ amount: fromAmount,
2860
+ label: i18n.t('From'),
2861
+ loadingStatus: 'success'
2862
+ }), React__default.createElement(ui.Spacer, {
2863
+ size: 12,
2864
+ direction: "vertical"
2865
+ }), React__default.createElement(TokenPreview, {
2866
+ chain: {
2867
+ displayName: lastStep?.toBlockchain || '',
2868
+ // @ts-ignore
2869
+ logo: lastStep?.toBlockchainLogo || ''
2870
+ },
2871
+ token: {
2872
+ symbol: lastStep?.toSymbol || '',
2873
+ image: lastStep?.toLogo || ''
2874
+ },
2875
+ amount: toAmount,
2876
+ label: i18n.t('To'),
2877
+ loadingStatus: 'success'
2878
+ })),
2589
2879
  //todo: move PendingSwap type to rango-types
2590
2880
  //@ts-ignore
2591
- pendingSwap: selectedSwap?.swap,
2881
+ pendingSwap: swap,
2592
2882
  onCopy: handleCopy,
2593
2883
  isCopied: isCopied,
2594
- onCancel: onCancel
2595
- });
2884
+ onCancel: onCancel,
2885
+ shortMessage: swapMessages.shortMessage,
2886
+ detailedMessage: swapMessages.detailedMessage,
2887
+ currentStepBlockchain: currentStepBlockchain || '',
2888
+ switchNetwork: switchNetwork,
2889
+ type: networkWarningState ? 'warning' : swap.extraMessageSeverity || undefined,
2890
+ date: swapDate
2891
+ }, shouldRetry && {
2892
+ onRetry: () => {
2893
+ retry(swap);
2894
+ setTimeout(() => {
2895
+ navigate(navigationRoutes.home);
2896
+ }, 0);
2897
+ }
2898
+ }, lastConvertedTokenInFailedSwap && {
2899
+ lastConvertedTokenInFailedSwap: {
2900
+ blockchain: lastConvertedTokenInFailedSwap.blockchain,
2901
+ outputAmount: lastConvertedTokenInFailedSwap.outputAmount || '',
2902
+ symbol: lastConvertedTokenInFailedSwap.symbol
2903
+ }
2904
+ }));
2596
2905
  }
2597
2906
 
2907
+ const getAbsolutePath = path => path.replace('/', '');
2598
2908
  function AppRoutes(props) {
2599
2909
  const {
2600
2910
  configs
2601
2911
  } = props;
2602
2912
  return reactRouterDom.useRoutes([{
2603
- path: navigationRoutes.home,
2913
+ path: getAbsolutePath(navigationRoutes.home),
2604
2914
  element: React__default.createElement(Home, {
2605
2915
  title: configs?.title,
2606
2916
  titleSize: configs?.titleSize,
2607
2917
  titleWeight: configs?.titleWeight
2608
2918
  })
2609
2919
  }, {
2610
- path: navigationRoutes.fromChain,
2920
+ path: getAbsolutePath(navigationRoutes.fromChain),
2611
2921
  element: React__default.createElement(SelectChainPage, {
2612
2922
  type: "from",
2613
2923
  supportedChains: configs?.fromChains || 'all'
2614
2924
  })
2615
2925
  }, {
2616
- path: navigationRoutes.toChain,
2926
+ path: getAbsolutePath(navigationRoutes.toChain),
2617
2927
  element: React__default.createElement(SelectChainPage, {
2618
2928
  type: "to",
2619
2929
  supportedChains: configs?.toChains || 'all'
2620
2930
  })
2621
2931
  }, {
2622
- path: navigationRoutes.fromToken + '/*',
2932
+ path: getAbsolutePath(navigationRoutes.fromToken),
2623
2933
  element: React__default.createElement(SelectTokenPage, {
2624
2934
  type: "from",
2625
2935
  supportedTokens: configs?.fromTokens || 'all'
2626
2936
  })
2627
2937
  }, {
2628
- path: navigationRoutes.toToken,
2938
+ path: getAbsolutePath(navigationRoutes.toToken),
2629
2939
  element: React__default.createElement(SelectTokenPage, {
2630
2940
  type: "to",
2631
2941
  supportedTokens: configs?.toTokens || 'all'
2632
2942
  })
2633
2943
  }, {
2634
- path: navigationRoutes.settings,
2944
+ path: getAbsolutePath(navigationRoutes.settings),
2635
2945
  element: React__default.createElement(SettingsPage, {
2636
2946
  supportedSwappers: configs?.liquiditySources || 'all'
2637
2947
  })
2638
2948
  }, {
2639
- path: navigationRoutes.liquiditySources,
2949
+ path: getAbsolutePath(navigationRoutes.liquiditySources),
2640
2950
  element: React__default.createElement(LiquiditySourcePage, {
2641
2951
  supportedSwappers: configs?.liquiditySources || 'all'
2642
2952
  })
2643
2953
  }, {
2644
- path: navigationRoutes.swaps,
2954
+ path: getAbsolutePath(navigationRoutes.swaps),
2645
2955
  element: React__default.createElement(HistoryPage, null)
2646
2956
  }, {
2647
2957
  path: navigationRoutes.swapDetails,
2648
2958
  element: React__default.createElement(SwapDetailsPage, null)
2649
2959
  }, {
2650
- path: navigationRoutes.wallets,
2960
+ path: getAbsolutePath(navigationRoutes.wallets),
2651
2961
  element: React__default.createElement(WalletsPage, {
2652
2962
  supportedWallets: configs?.wallets || 'all',
2653
2963
  multiWallets: typeof configs?.multiWallets === 'undefined' ? true : configs.multiWallets
2654
2964
  })
2655
2965
  }, {
2656
- path: navigationRoutes.confirmSwap,
2966
+ path: getAbsolutePath(navigationRoutes.confirmSwap),
2657
2967
  element: React__default.createElement(ConfirmSwapPage, null)
2658
- }, {
2659
- path: navigationRoutes.confirmWallets,
2660
- element: React__default.createElement(ConfirmWalletsPage, null)
2661
2968
  }]);
2662
2969
  }
2663
2970
 
2664
- const Header$1 = /*#__PURE__*/ui.styled('div', {
2971
+ const Header = /*#__PURE__*/ui.styled('div', {
2665
2972
  display: 'flex',
2666
2973
  width: '100%',
2667
- justifyContent: 'end'
2974
+ justifyContent: 'end',
2975
+ '.balance': {
2976
+ display: 'flex'
2977
+ }
2668
2978
  });
2669
2979
  const WalletImage = /*#__PURE__*/ui.styled('img', {
2670
2980
  width: '$24',
@@ -2694,6 +3004,8 @@ function Layout(_ref) {
2694
3004
  const setInputAmount = useBestRouteStore.use.setInputAmount();
2695
3005
  const totalBalance = calculateWalletUsdValue(balances);
2696
3006
  const connectWalletsButtonDisabled = useUiStore.use.connectWalletsButtonDisabled();
3007
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
3008
+ const fetchingBalance = useWalletsStore(fetchingBalanceSelector);
2697
3009
  const {
2698
3010
  t
2699
3011
  } = reactI18next.useTranslation();
@@ -2708,22 +3020,32 @@ function Layout(_ref) {
2708
3020
  setFromToken(configs?.fromToken || null);
2709
3021
  setFromChain(configs?.fromChain || null);
2710
3022
  }, [configs?.fromToken, configs?.fromChain]);
2711
- return React__default.createElement(React__default.Fragment, null, React__default.createElement(Header$1, null, React__default.createElement(ui.Button, {
3023
+ React.useEffect(() => {
3024
+ setToChain(null);
3025
+ setFromChain(null);
3026
+ setFromToken(null);
3027
+ setToToken(null);
3028
+ }, [configs?.fromChains, configs?.toChains, configs?.fromTokens, configs?.toTokens]);
3029
+ return React__default.createElement(React__default.Fragment, null, React__default.createElement(Header, null, React__default.createElement(ui.Button, {
2712
3030
  size: "small",
2713
3031
  suffix: React__default.createElement(ui.AddWalletIcon, {
2714
3032
  size: 20
2715
3033
  }),
2716
3034
  variant: "ghost",
2717
3035
  flexContent: true,
3036
+ loading: loadingMetaStatus === 'loading',
3037
+ disabled: loadingMetaStatus === 'failed',
2718
3038
  onClick: () => {
2719
3039
  if (!connectWalletsButtonDisabled) navigate(navigationRoutes.wallets);
2720
3040
  }
2721
3041
  }, connectedWalletsImages?.length ? connectedWalletsImages.map((walletImage, index) => React__default.createElement(WalletImage, {
2722
3042
  key: index,
2723
3043
  src: walletImage
2724
- })) : React__default.createElement(React__default.Fragment, null), React__default.createElement(ui.Typography, {
3044
+ })) : React__default.createElement(React__default.Fragment, null), React__default.createElement("div", {
3045
+ className: "balance"
3046
+ }, React__default.createElement(ui.Typography, {
2725
3047
  variant: "body2"
2726
- }, !accounts?.length ? t('Connect Wallet') : `$${totalBalance || 0}`))), React__default.createElement(AppRoutes, {
3048
+ }, !accounts?.length ? t('Connect Wallet') : `$${totalBalance || 0}`), fetchingBalance && React__default.createElement(ui.Spinner, null)))), React__default.createElement(AppRoutes, {
2727
3049
  configs: configs
2728
3050
  }));
2729
3051
  }
@@ -2731,10 +3053,12 @@ function Layout(_ref) {
2731
3053
  const globalStyles = /*#__PURE__*/ui.globalCss({
2732
3054
  '*': {
2733
3055
  '&::-webkit-scrollbar': {
2734
- width: '$8'
3056
+ width: '$8',
3057
+ height: '$8'
2735
3058
  },
2736
3059
  '&::-webkit-scrollbar-thumb': {
2737
- backgroundColor: '$neutrals400'
3060
+ backgroundColor: '$neutrals400',
3061
+ borderRadius: '$10'
2738
3062
  },
2739
3063
  '&::-webkit-scrollbar-thumb:hover': {
2740
3064
  backgroundColor: '$neutrals500'
@@ -3008,7 +3332,9 @@ function QueueManager(props) {
3008
3332
  //@ts-ignore
3009
3333
  queuesDefs: [queueManagerRangoPreset.swapQueueDef],
3010
3334
  context: context,
3011
- onPersistedDataLoaded: _manager => {},
3335
+ onPersistedDataLoaded: manager => {
3336
+ queueManagerRangoPreset.checkWaitingForNetworkChange(manager);
3337
+ },
3012
3338
  isPaused: false
3013
3339
  }, props.children);
3014
3340
  }
@@ -3036,8 +3362,10 @@ const SwapBox = _ref => {
3036
3362
  changeLanguage
3037
3363
  } = useSelectLanguage();
3038
3364
  const clearConnectedWallet = useWalletsStore.use.clearConnectedWallet();
3365
+ const [lastConnectedWalletWithNetwork, setLastConnectedWalletWithNetwork] = React.useState('');
3366
+ const [disconnectedWallet, setDisconnectedWallet] = React.useState();
3039
3367
  const evmBasedChainNames = blockchains.filter(rangoSdk.isEvmBlockchain).map(chain => chain.name);
3040
- const onUpdateState = (type, event, value, _, supportedChains) => {
3368
+ const onUpdateState = (type, event, value, state, supportedChains) => {
3041
3369
  if (event === walletsCore.Events.ACCOUNTS) {
3042
3370
  if (value) {
3043
3371
  const supportedChainNames = walletAndSupportedChainsNames(supportedChains);
@@ -3047,6 +3375,16 @@ const SwapBox = _ref => {
3047
3375
  disconnectWallet(type);
3048
3376
  }
3049
3377
  }
3378
+ if (event === walletsCore.Events.ACCOUNTS && state.connected) {
3379
+ const key = `${type}-${state.network}-${value}`;
3380
+ if (state.connected) {
3381
+ setLastConnectedWalletWithNetwork(key);
3382
+ }
3383
+ }
3384
+ if (event === walletsCore.Events.NETWORK && state.network) {
3385
+ const key = `${type}-${state.network}`;
3386
+ setLastConnectedWalletWithNetwork(key);
3387
+ }
3050
3388
  };
3051
3389
  let providers = providerAll.allProviders();
3052
3390
  React.useEffect(() => {
@@ -3078,7 +3416,12 @@ const SwapBox = _ref => {
3078
3416
  }, React__default.createElement(AppRouter, {
3079
3417
  title: configs.title,
3080
3418
  titleSize: configs.titleSize,
3081
- titleWeight: configs.titleWeight
3419
+ titleWeight: configs.titleWeight,
3420
+ lastConnectedWallet: lastConnectedWalletWithNetwork,
3421
+ disconnectedWallet: disconnectedWallet,
3422
+ clearDisconnectedWallet: () => {
3423
+ setDisconnectedWallet(undefined);
3424
+ }
3082
3425
  }, React__default.createElement(Layout, {
3083
3426
  configs: configs
3084
3427
  }))))));