@rango-dev/widget-embedded 0.1.10-next.98 → 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 (110) 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/ChangeSlippageButton.d.ts.map +1 -1
  7. package/dist/components/HeaderButtons.d.ts +4 -1
  8. package/dist/components/HeaderButtons.d.ts.map +1 -1
  9. package/dist/components/Layout.d.ts.map +1 -1
  10. package/dist/components/RoutesOverview.d.ts +10 -0
  11. package/dist/components/RoutesOverview.d.ts.map +1 -0
  12. package/dist/components/SwapDetailsPlaceholder.d.ts +9 -0
  13. package/dist/components/SwapDetailsPlaceholder.d.ts.map +1 -0
  14. package/dist/components/TokenInfo.d.ts.map +1 -1
  15. package/dist/components/TokenPreview.d.ts +20 -0
  16. package/dist/components/TokenPreview.d.ts.map +1 -0
  17. package/dist/components/UpdateUrl.d.ts.map +1 -1
  18. package/dist/components/warnings/BalanceWarnings.d.ts.map +1 -1
  19. package/dist/components/warnings/HighSlippageWarning.d.ts.map +1 -1
  20. package/dist/components/warnings/MinRequiredSlippage.d.ts +1 -1
  21. package/dist/components/warnings/MinRequiredSlippage.d.ts.map +1 -1
  22. package/dist/constants/navigationRoutes.d.ts +0 -1
  23. package/dist/constants/navigationRoutes.d.ts.map +1 -1
  24. package/dist/globalStyles.d.ts.map +1 -1
  25. package/dist/hooks/useConfirmSwap.d.ts.map +1 -1
  26. package/dist/lib.d.ts.map +1 -1
  27. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  28. package/dist/pages/HistoryPage.d.ts.map +1 -1
  29. package/dist/pages/Home.d.ts.map +1 -1
  30. package/dist/pages/LiquiditySourcesPage.d.ts.map +1 -1
  31. package/dist/pages/SelectTokenPage.d.ts.map +1 -1
  32. package/dist/pages/SettingsPage.d.ts.map +1 -1
  33. package/dist/pages/SwapDetailsPage.d.ts.map +1 -1
  34. package/dist/pages/WalletsPage.d.ts +1 -0
  35. package/dist/pages/WalletsPage.d.ts.map +1 -1
  36. package/dist/store/bestRoute.d.ts +2 -0
  37. package/dist/store/bestRoute.d.ts.map +1 -1
  38. package/dist/store/ui.d.ts.map +1 -1
  39. package/dist/store/wallets.d.ts +14 -0
  40. package/dist/store/wallets.d.ts.map +1 -1
  41. package/dist/types/routing.d.ts +1 -1
  42. package/dist/types/swap.d.ts +6 -0
  43. package/dist/types/swap.d.ts.map +1 -1
  44. package/dist/utils/common.d.ts +1 -0
  45. package/dist/utils/common.d.ts.map +1 -1
  46. package/dist/utils/date.d.ts +3 -0
  47. package/dist/utils/date.d.ts.map +1 -0
  48. package/dist/utils/routing.d.ts +1 -0
  49. package/dist/utils/routing.d.ts.map +1 -1
  50. package/dist/utils/swap.d.ts +18 -6
  51. package/dist/utils/swap.d.ts.map +1 -1
  52. package/dist/utils/time.d.ts +4 -0
  53. package/dist/utils/time.d.ts.map +1 -0
  54. package/dist/utils/wallets.d.ts +1 -1
  55. package/dist/utils/wallets.d.ts.map +1 -1
  56. package/dist/widget-embedded.cjs.development.js +1004 -418
  57. package/dist/widget-embedded.cjs.development.js.map +1 -1
  58. package/dist/widget-embedded.cjs.production.min.js +1004 -418
  59. package/dist/widget-embedded.cjs.production.min.js.map +1 -1
  60. package/dist/widget-embedded.esm.js +1008 -423
  61. package/dist/widget-embedded.esm.js.map +1 -1
  62. package/package.json +12 -11
  63. package/readme.md +1 -2
  64. package/src/App.tsx +30 -5
  65. package/src/QueueManager.tsx +5 -2
  66. package/src/components/AppRouter.tsx +24 -13
  67. package/src/components/AppRoutes.tsx +15 -12
  68. package/src/components/ChangeSlippageButton.tsx +4 -8
  69. package/src/components/HeaderButtons.tsx +11 -4
  70. package/src/components/Layout.tsx +37 -5
  71. package/src/components/RoutesOverview.tsx +60 -0
  72. package/src/components/SwapDetailsPlaceholder.tsx +32 -0
  73. package/src/components/TokenInfo.tsx +125 -77
  74. package/src/components/TokenPreview.tsx +178 -0
  75. package/src/components/UpdateUrl.tsx +1 -3
  76. package/src/components/warnings/BalanceWarnings.tsx +1 -0
  77. package/src/components/warnings/HighSlippageWarning.tsx +4 -7
  78. package/src/components/warnings/MinRequiredSlippage.tsx +9 -4
  79. package/src/constants/navigationRoutes.ts +0 -1
  80. package/src/globalStyles.ts +3 -2
  81. package/src/hooks/useConfirmSwap.ts +2 -1
  82. package/src/hooks/useNavigateBack.ts +3 -3
  83. package/src/hooks/useTheme.ts +9 -9
  84. package/src/languages/en.json +9 -8
  85. package/src/lib.tsx +25 -3
  86. package/src/pages/ConfirmSwapPage.tsx +128 -20
  87. package/src/pages/HistoryPage.tsx +4 -4
  88. package/src/pages/Home.tsx +51 -42
  89. package/src/pages/LiquiditySourcesPage.tsx +2 -0
  90. package/src/pages/SelectTokenPage.tsx +3 -1
  91. package/src/pages/SettingsPage.tsx +3 -0
  92. package/src/pages/SwapDetailsPage.tsx +142 -6
  93. package/src/pages/WalletsPage.tsx +49 -16
  94. package/src/store/bestRoute.ts +114 -17
  95. package/src/store/ui.ts +4 -0
  96. package/src/store/wallets.ts +4 -1
  97. package/src/types/routing.ts +1 -1
  98. package/src/types/swap.ts +7 -0
  99. package/src/utils/common.ts +14 -0
  100. package/src/utils/date.ts +62 -0
  101. package/src/utils/routing.ts +23 -13
  102. package/src/utils/swap.ts +113 -11
  103. package/src/utils/time.ts +52 -0
  104. package/src/utils/wallets.ts +13 -4
  105. package/dist/components/Header.d.ts +0 -10
  106. package/dist/components/Header.d.ts.map +0 -1
  107. package/dist/pages/ConfirmWalletsPage.d.ts +0 -3
  108. package/dist/pages/ConfirmWalletsPage.d.ts.map +0 -1
  109. package/src/components/Header.tsx +0 -37
  110. package/src/pages/ConfirmWalletsPage.tsx +0 -80
@@ -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,10 +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');
25
+ var i18n = require('i18next');
26
+ var i18n__default = _interopDefault(i18n);
24
27
  var queueManagerReact = require('@rango-dev/queue-manager-react');
28
+ var dayjs = _interopDefault(require('dayjs'));
25
29
  var copy = _interopDefault(require('copy-to-clipboard'));
26
- var queueManagerRangoPreset = require('@rango-dev/queue-manager-rango-preset');
27
- var i18n = _interopDefault(require('i18next'));
28
30
  var Backend = _interopDefault(require('i18next-http-backend'));
29
31
  var LanguageDetector = _interopDefault(require('i18next-browser-languagedetector'));
30
32
 
@@ -39,7 +41,6 @@ const navigationRoutes = {
39
41
  swaps: '/swaps',
40
42
  wallets: '/wallets',
41
43
  confirmSwap: '/confirm-swap',
42
- confirmWallets: '/confirm-wallets',
43
44
  swapDetails: '/swaps/:requestId'
44
45
  };
45
46
 
@@ -69,6 +70,22 @@ function shadeColor(color, percent) {
69
70
  var BB = B.toString(16).length == 1 ? '0' + B.toString(16) : B.toString(16);
70
71
  return '#' + RR + GG + BB;
71
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
+ }
72
89
 
73
90
  const secondsToString = s => {
74
91
  const seconds = (s % 60).toString().padStart(2, '0');
@@ -335,7 +352,7 @@ function getSortedTokens(chain, tokens, balances, otherChainTokens) {
335
352
  return sortTokens(getTokensWithBalance(filteredTokens, balances));
336
353
  }
337
354
  function tokensAreEqual(tokenA, tokenB) {
338
- 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;
339
356
  }
340
357
  function getDefaultToken(sortedTokens, otherToken) {
341
358
  let selectedToken;
@@ -345,7 +362,7 @@ function getDefaultToken(sortedTokens, otherToken) {
345
362
  return selectedToken;
346
363
  }
347
364
  function sortWalletsBasedOnState(wallets) {
348
- 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));
349
366
  }
350
367
 
351
368
  function getOutputRatio(inputUsdValue, outputUsdValue) {
@@ -413,7 +430,7 @@ function LimitErrorMessage(bestRoute) {
413
430
  recommendation
414
431
  };
415
432
  }
416
- function getSwapButtonState(loadingMetaStatus, accounts, loading, bestRoute, hasLimitError, highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath) {
433
+ function getSwapButtonState(loadingMetaStatus, accounts, loading, bestRoute, hasLimitError, highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath, inputIsZero) {
417
434
  if (loadingMetaStatus !== 'success') return {
418
435
  title: 'Connect Wallet',
419
436
  disabled: true
@@ -425,6 +442,9 @@ function getSwapButtonState(loadingMetaStatus, accounts, loading, bestRoute, has
425
442
  if (loading) return {
426
443
  title: 'Finding Best Route...',
427
444
  disabled: true
445
+ };else if (inputIsZero) return {
446
+ title: 'Enter an amount',
447
+ disabled: true
428
448
  };else if (!bestRoute) return {
429
449
  title: 'Swap',
430
450
  disabled: true
@@ -458,6 +478,7 @@ function calculatePendingSwap(inputAmount, bestRoute, wallets, settings, validat
458
478
  finishTime: null,
459
479
  requestId: bestRoute.requestId || '',
460
480
  inputAmount: inputAmount,
481
+ //@ts-ignore
461
482
  wallets,
462
483
  status: 'running',
463
484
  isPaused: false,
@@ -472,6 +493,7 @@ function calculatePendingSwap(inputAmount, bestRoute, wallets, settings, validat
472
493
  settings: settings,
473
494
  simulationResult: simulationResult,
474
495
  validateBalanceOrFee,
496
+ //@ts-ignore
475
497
  steps: bestRoute.result?.swaps?.map((swap, index) => {
476
498
  const swapper = meta.swappers.find(swapper => swapper.id === swap.swapperId);
477
499
  const swapperType = swapper?.types[0];
@@ -557,11 +579,10 @@ function hasHighFee(totalFeeInUsd) {
557
579
  }
558
580
  function getMinRequiredSlippage(route) {
559
581
  const slippages = route.result?.swaps.map(slippage => slippage.recommendedSlippage);
560
- 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;
561
583
  }
562
584
  function hasProperSlippage(userSlippage, minRequiredSlippage) {
563
585
  if (!minRequiredSlippage) return true;
564
- //@ts-ignore
565
586
  return parseFloat(userSlippage) >= parseFloat(minRequiredSlippage);
566
587
  }
567
588
  function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, selectedWallets, disabledLiquiditySources, slippage, checkPrerequisites) {
@@ -574,6 +595,7 @@ function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, se
574
595
  addresses: [wallet.address]
575
596
  });
576
597
  });
598
+ const filteredBlockchains = selectedWallets.map(wallet => wallet.chain);
577
599
  const requestBody = {
578
600
  amount: inputAmount.toString(),
579
601
  checkPrerequisites,
@@ -591,8 +613,10 @@ function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, se
591
613
  selectedWallets: selectedWalletsMap,
592
614
  swapperGroups: disabledLiquiditySources,
593
615
  swappersGroupsExclude: true,
594
- //@ts-ignore
595
- slippage: slippage.toString()
616
+ slippage: slippage.toString(),
617
+ ...(checkPrerequisites && {
618
+ blockchains: filteredBlockchains
619
+ })
596
620
  };
597
621
  return requestBody;
598
622
  }
@@ -634,6 +658,65 @@ function getBalanceWarnings(route, selectedWallets) {
634
658
  return warningMessage;
635
659
  });
636
660
  }
661
+ function calcOutputUsdValue(outputAmount, tokenPrice) {
662
+ const amount = !!outputAmount ? new BigNumber__default(outputAmount) : ZERO;
663
+ return amount.multipliedBy(tokenPrice || 0);
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
+ }
637
720
 
638
721
  function searchParamsToToken(tokens, searchParams, chain) {
639
722
  if (!chain) return null;
@@ -671,22 +754,13 @@ function getRequiredBalanceOfWallet(selectedWallet, fee) {
671
754
  return relatedFeeStatus.requiredAssets;
672
755
  }
673
756
  function isRouteParametersChanged(prevParams, currentParams) {
674
- 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;
675
- }
676
- function getBestRouteWithCalculatedFees(bestRoute, tokens) {
677
- if (!bestRoute || !bestRoute.result) return null;
678
- const swapsWithFee = (bestRoute?.result?.swaps || []).map(swap => ({
679
- ...swap,
680
- feeInUsd: numberToString(getUsdFeeOfStep(swap, tokens), 0, 2)
681
- }));
682
- return {
683
- ...bestRoute,
684
- result: {
685
- ...bestRoute.result,
686
- swaps: swapsWithFee
687
- }
688
- };
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);
689
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
+ };
690
764
 
691
765
  const createSelectors = _store => {
692
766
  let store = _store;
@@ -837,7 +911,7 @@ const useWalletsStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.creat
837
911
  }
838
912
  });
839
913
  return {
840
- selectedWallets: state.selectedWallets.concat(selectedWallets)
914
+ selectedWallets: selectedWallets
841
915
  };
842
916
  }),
843
917
  setSelectedWallet: wallet => set(state => ({
@@ -869,6 +943,7 @@ useWalletsStore.subscribe(state => state.balances, balances => {
869
943
  }, {
870
944
  equalityFn: shallow.shallow
871
945
  });
946
+ const fetchingBalanceSelector = state => !!state.balances.find(wallet => wallet.loading);
872
947
 
873
948
  const getUsdValue = (token, amount) => new BigNumber__default(amount || ZERO).multipliedBy(token?.usdPrice || 0);
874
949
  const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/middleware.subscribeWithSelector(set => ({
@@ -888,9 +963,10 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.cre
888
963
  setBestRoute: bestRoute => set(state => {
889
964
  let outputAmount = null;
890
965
  let outputUsdValue = ZERO;
966
+ if (!state.inputAmount || state.inputAmount === '0') return {};
891
967
  if (!!bestRoute) {
892
968
  outputAmount = !!bestRoute.result?.outputAmount ? new BigNumber__default(bestRoute.result?.outputAmount) : null;
893
- outputUsdValue = new BigNumber__default(outputAmount || ZERO).multipliedBy(getBestRouteToTokenUsdPrice(bestRoute) || state.toToken?.usdPrice || 0);
969
+ outputUsdValue = calcOutputUsdValue(bestRoute.result?.outputAmount, getBestRouteToTokenUsdPrice(bestRoute) || state.toToken?.usdPrice);
894
970
  }
895
971
  return {
896
972
  bestRoute,
@@ -944,6 +1020,7 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.cre
944
1020
  toToken: token
945
1021
  })),
946
1022
  setInputAmount: amount => {
1023
+ console.log(amount, typeof amount);
947
1024
  set(state => ({
948
1025
  inputAmount: amount,
949
1026
  ...(!amount && {
@@ -955,6 +1032,47 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.cre
955
1032
  inputUsdValue: getUsdValue(state.fromToken, amount)
956
1033
  })
957
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
+ });
958
1076
  }
959
1077
  }))));
960
1078
  const bestRoute = (bestRouteStore, settingsStore) => {
@@ -970,12 +1088,12 @@ const bestRoute = (bestRouteStore, settingsStore) => {
970
1088
  customSlippage,
971
1089
  disabledLiquiditySources
972
1090
  } = settingsStore.getState();
973
- if (!fromToken || !toToken || !inputAmount) return;
1091
+ if (!fromToken || !toToken || !inputAmount || inputAmount === '0') return;
974
1092
  abortController?.abort();
975
1093
  abortController = new AbortController();
976
1094
  const userSlippage = !!customSlippage ? customSlippage : slippage;
977
1095
  const requestBody = createBestRouteRequestBody(fromToken, toToken, inputAmount, [], [], disabledLiquiditySources, userSlippage, false);
978
- bestRouteStore.setState({
1096
+ if (!bestRouteStore.getState().loading) bestRouteStore.setState({
979
1097
  loading: true,
980
1098
  bestRoute: null,
981
1099
  outputAmount: null,
@@ -1000,13 +1118,36 @@ const bestRoute = (bestRouteStore, settingsStore) => {
1000
1118
  });
1001
1119
  });
1002
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
+ };
1003
1144
  useBestRouteStore.subscribe(state => ({
1004
1145
  fromChain: state.fromChain,
1005
1146
  fromToken: state.fromToken,
1006
1147
  toChain: state.toChain,
1007
1148
  toToken: state.toToken,
1008
1149
  inputAmount: state.inputAmount
1009
- }), fetchBestRoute.bind(null), {
1150
+ }), bestRouteParamsListener, {
1010
1151
  equalityFn: (prevState, state) => {
1011
1152
  if (isRouteParametersChanged(prevState, state)) return false;else return true;
1012
1153
  }
@@ -1015,7 +1156,7 @@ const bestRoute = (bestRouteStore, settingsStore) => {
1015
1156
  slippage: state.slippage,
1016
1157
  customSlippage: state.customSlippage,
1017
1158
  disabledLiquiditySources: state.disabledLiquiditySources
1018
- }), fetchBestRoute.bind(null), {
1159
+ }), bestRouteParamsListener, {
1019
1160
  equalityFn: (prevState, state) => {
1020
1161
  if (isRouteParametersChanged(prevState, state)) return false;else return true;
1021
1162
  }
@@ -1040,11 +1181,15 @@ var SearchParams;
1040
1181
  const useUiStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()(set => ({
1041
1182
  connectWalletsButtonDisabled: false,
1042
1183
  selectedSwapRequestId: null,
1184
+ currentPage: '',
1043
1185
  toggleConnectWalletsButton: () => set(state => ({
1044
1186
  connectWalletsButtonDisabled: !state.connectWalletsButtonDisabled
1045
1187
  })),
1046
1188
  setSelectedSwap: requestId => set({
1047
1189
  selectedSwapRequestId: requestId
1190
+ }),
1191
+ setCurrentPage: path => set({
1192
+ currentPage: path
1048
1193
  })
1049
1194
  })));
1050
1195
 
@@ -1085,7 +1230,7 @@ function UpdateUrl() {
1085
1230
  toChainString = '',
1086
1231
  toTokenString = '',
1087
1232
  fromAmount = '';
1088
- if (loadingStatus !== 'success' && ![navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname)) {
1233
+ if (loadingStatus !== 'success' && location.pathname != navigationRoutes.confirmSwap) {
1089
1234
  fromChainString = searchParamsRef.current[SearchParams.FROM_CHAIN];
1090
1235
  fromTokenString = searchParamsRef.current[SearchParams.FROM_TOKEN];
1091
1236
  toChainString = searchParamsRef.current[SearchParams.TO_CHAIN];
@@ -1178,67 +1323,6 @@ function UpdateUrl() {
1178
1323
  return null;
1179
1324
  }
1180
1325
 
1181
- const ButtonsContainer = /*#__PURE__*/ui.styled('div', {
1182
- display: 'flex'
1183
- });
1184
- function HeaderButtons(props) {
1185
- const {
1186
- onClickRefresh
1187
- } = props;
1188
- const navigate = reactRouterDom.useNavigate();
1189
- return React__default.createElement(ButtonsContainer, null, React__default.createElement(ui.Tooltip, {
1190
- content: "Retry"
1191
- }, React__default.createElement(ui.Button, {
1192
- variant: "ghost",
1193
- onClick: onClickRefresh
1194
- }, React__default.createElement(ui.RetryIcon, {
1195
- size: 28
1196
- }))), React__default.createElement(ui.Tooltip, {
1197
- content: "Transactions History"
1198
- }, React__default.createElement(ui.Button, {
1199
- variant: "ghost",
1200
- onClick: () => navigate(navigationRoutes.swaps)
1201
- }, React__default.createElement(ui.HistoryIcon, {
1202
- size: 24
1203
- }))), React__default.createElement(ui.Tooltip, {
1204
- content: "Settings"
1205
- }, React__default.createElement(ui.Button, {
1206
- variant: "ghost",
1207
- onClick: () => navigate(navigationRoutes.settings)
1208
- }, React__default.createElement(ui.SettingsIcon, {
1209
- size: 24
1210
- }))));
1211
- }
1212
-
1213
- const HeaderContainer = /*#__PURE__*/ui.styled('div', {
1214
- display: 'flex',
1215
- justifyContent: 'space-between',
1216
- alignItems: 'center',
1217
- width: '100%',
1218
- padding: '$16 0'
1219
- });
1220
- function Header(props) {
1221
- const {
1222
- onClickRefresh,
1223
- title,
1224
- titleSize,
1225
- titleWeight
1226
- } = props;
1227
- const {
1228
- t
1229
- } = reactI18next.useTranslation();
1230
- const titleStyle = ui.css({
1231
- fontSize: `${titleSize}px !important`,
1232
- fontWeight: `${titleWeight} !important`
1233
- });
1234
- return React__default.createElement(HeaderContainer, null, React__default.createElement(ui.Typography, {
1235
- variant: "h4",
1236
- className: titleStyle()
1237
- }, title ? t(title.toLocaleLowerCase()) : ''), React__default.createElement(HeaderButtons, {
1238
- onClickRefresh: onClickRefresh
1239
- }));
1240
- }
1241
-
1242
1326
  const Box = /*#__PURE__*/ui.styled('div', {
1243
1327
  display: 'flex',
1244
1328
  flexDirection: 'column',
@@ -1246,13 +1330,42 @@ const Box = /*#__PURE__*/ui.styled('div', {
1246
1330
  });
1247
1331
  const Container = /*#__PURE__*/ui.styled('div', {
1248
1332
  boxSizing: 'border-box',
1249
- backgroundColor: '$neutrals300',
1250
1333
  borderRadius: '$5',
1251
- padding: '$8 0',
1334
+ padding: '$8 $16 $16 $16',
1335
+ variants: {
1336
+ type: {
1337
+ filled: {
1338
+ backgroundColor: '$neutrals300'
1339
+ },
1340
+ outlined: {
1341
+ border: '1px solid $neutrals300'
1342
+ }
1343
+ }
1344
+ },
1345
+ defaultVariants: {
1346
+ type: 'filled'
1347
+ },
1348
+ '.head': {
1349
+ display: 'flex',
1350
+ justifyContent: 'space-between',
1351
+ alignItems: 'center',
1352
+ minHeight: '32px'
1353
+ },
1252
1354
  '.form': {
1253
1355
  display: 'flex',
1254
1356
  width: '100%',
1255
- padding: '$8 $16'
1357
+ padding: '$2 0',
1358
+ '.selectors': {
1359
+ width: '35%',
1360
+ '._text': {
1361
+ whiteSpace: 'nowrap',
1362
+ overflow: 'hidden',
1363
+ textOverflow: 'ellipsis'
1364
+ }
1365
+ },
1366
+ '.amount': {
1367
+ width: '30%'
1368
+ }
1256
1369
  }
1257
1370
  });
1258
1371
  const StyledImage = /*#__PURE__*/ui.styled('img', {
@@ -1262,7 +1375,10 @@ const StyledImage = /*#__PURE__*/ui.styled('img', {
1262
1375
  const Options = /*#__PURE__*/ui.styled('div', {
1263
1376
  display: 'flex',
1264
1377
  justifyContent: 'flex-end',
1265
- padding: '0 $8'
1378
+ '.balance': {
1379
+ display: 'flex',
1380
+ alignItems: 'center'
1381
+ }
1266
1382
  });
1267
1383
  const ImagePlaceholder = /*#__PURE__*/ui.styled('span', {
1268
1384
  width: '24px',
@@ -1271,10 +1387,9 @@ const ImagePlaceholder = /*#__PURE__*/ui.styled('span', {
1271
1387
  borderRadius: '99999px'
1272
1388
  });
1273
1389
  const OutputContainer = /*#__PURE__*/ui.styled('div', {
1390
+ windth: '100%',
1274
1391
  height: '$48',
1275
1392
  borderRadius: '$5',
1276
- flexGrow: 1,
1277
- width: '70%',
1278
1393
  backgroundColor: '$background',
1279
1394
  border: '1px solid transparent',
1280
1395
  position: 'relative',
@@ -1314,21 +1429,34 @@ function TokenInfo(props) {
1314
1429
  color: "error",
1315
1430
  size: 24
1316
1431
  }), React__default.createElement(ui.AngleDownIcon, null));
1317
- return React__default.createElement(Box, null, React__default.createElement("div", null, React__default.createElement(ui.Typography, {
1318
- variant: "body2"
1319
- }, t(type))), React__default.createElement(Container, null, props.type === 'From' && React__default.createElement(Options, null, React__default.createElement("div", {
1432
+ return React__default.createElement(Box, null, React__default.createElement(Container, {
1433
+ type: props.type === 'From' ? 'filled' : 'outlined'
1434
+ }, React__default.createElement("div", {
1435
+ className: "head"
1436
+ }, React__default.createElement(ui.Typography, {
1437
+ variant: "body2",
1438
+ color: "neutrals800"
1439
+ }, t(type)), props.type === 'From' ? React__default.createElement(Options, null, React__default.createElement("div", {
1320
1440
  className: "balance",
1321
1441
  onClick: () => {
1322
1442
  if (tokenBalance !== '0') setInputAmount(tokenBalanceReal.split(',').join(''));
1323
1443
  }
1324
- }, React__default.createElement(ui.Button, {
1325
- variant: "ghost",
1326
- size: "small"
1327
1444
  }, React__default.createElement(ui.Typography, {
1328
- variant: "body2"
1329
- }, `${t('Max')}: ${tokenBalance} ${fromToken?.symbol || ''}`)))), React__default.createElement("div", {
1445
+ variant: "body3",
1446
+ color: "neutrals600"
1447
+ }, `${t('Balance')}: ${tokenBalance} ${fromToken?.symbol || ''}`), React__default.createElement(ui.Spacer, {
1448
+ size: 4
1449
+ }), React__default.createElement(ui.Button, {
1450
+ type: "primary",
1451
+ variant: "ghost",
1452
+ size: "compact"
1453
+ }, t('Max')))) : React__default.createElement(ui.Typography, {
1454
+ variant: "caption",
1455
+ color: "neutrals600"
1456
+ }, `$${numberToString(props.outputUsdValue)}`)), React__default.createElement("div", {
1330
1457
  className: "form"
1331
1458
  }, React__default.createElement(ui.Button, {
1459
+ className: "selectors",
1332
1460
  onClick: () => {
1333
1461
  navigate(`/${props.type.toLowerCase()}-chain`);
1334
1462
  },
@@ -1340,11 +1468,11 @@ function TokenInfo(props) {
1340
1468
  }) : React__default.createElement(ImagePlaceholder, null),
1341
1469
  suffix: ItemSuffix,
1342
1470
  align: "start",
1343
- size: "large",
1344
- style: {
1345
- marginRight: '.5rem'
1346
- }
1347
- }, loadingStatus === 'success' && chain ? chain.displayName : t('Chain')), React__default.createElement(ui.Button, {
1471
+ size: "large"
1472
+ }, loadingStatus === 'success' && chain ? chain.displayName : t('Chain')), React__default.createElement(ui.Spacer, {
1473
+ size: 12
1474
+ }), React__default.createElement(ui.Button, {
1475
+ className: "selectors",
1348
1476
  onClick: () => {
1349
1477
  navigate(`/${props.type.toLowerCase()}-token`);
1350
1478
  },
@@ -1356,17 +1484,17 @@ function TokenInfo(props) {
1356
1484
  }) : React__default.createElement(ImagePlaceholder, null),
1357
1485
  suffix: ItemSuffix,
1358
1486
  size: "large",
1359
- align: "start",
1360
- style: {
1361
- marginRight: '.5rem'
1362
- }
1363
- }, loadingStatus === 'success' && token ? token.symbol : t('Token')), props.type === 'From' ? React__default.createElement(ui.TextField, {
1487
+ align: "start"
1488
+ }, loadingStatus === 'success' && token ? token.symbol : t('Token')), React__default.createElement(ui.Spacer, {
1489
+ size: 12
1490
+ }), React__default.createElement("div", {
1491
+ className: "amount"
1492
+ }, props.type === 'From' ? React__default.createElement(ui.TextField, {
1364
1493
  type: "number",
1365
1494
  size: "large",
1366
1495
  autoFocus: true,
1367
1496
  placeholder: "0",
1368
1497
  style: {
1369
- width: '70%',
1370
1498
  position: 'relative',
1371
1499
  backgroundColor: '$background !important'
1372
1500
  },
@@ -1377,23 +1505,16 @@ function TokenInfo(props) {
1377
1505
  bottom: '2px'
1378
1506
  }
1379
1507
  }, React__default.createElement(ui.Typography, {
1380
- variant: "caption"
1508
+ variant: "caption",
1509
+ color: "neutrals800"
1381
1510
  }, `$${numberToString(inputUsdValue)}`)),
1382
1511
  value: props.inputAmount || '',
1383
1512
  onChange: props.type === 'From' ? event => {
1384
1513
  props.onAmountChange(event.target.value);
1385
1514
  } : undefined
1386
1515
  }) : React__default.createElement(OutputContainer, null, React__default.createElement(ui.Typography, {
1387
- variant: "body1"
1388
- }, bestRoute ? `≈ ${numberToString(props.outputAmount)}` : inputAmount ? '?' : '0'), React__default.createElement("span", {
1389
- style: {
1390
- position: 'absolute',
1391
- right: '4px',
1392
- bottom: '2px'
1393
- }
1394
- }, React__default.createElement(ui.Typography, {
1395
- variant: "caption"
1396
- }, `$${numberToString(props.outputUsdValue)}`))))));
1516
+ variant: "h4"
1517
+ }, bestRoute ? `≈ ${numberToString(props.outputAmount)}` : inputAmount ? '?' : '0'))))));
1397
1518
  }
1398
1519
 
1399
1520
  const Container$1 = /*#__PURE__*/theme.styled('div', {
@@ -1489,18 +1610,52 @@ const errorMessages = {
1489
1610
  genericServerError: 'Error connecting server, please reload the app and try again'
1490
1611
  };
1491
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
+
1492
1646
  const Container$2 = /*#__PURE__*/ui.styled('div', {
1493
1647
  display: 'flex',
1494
- flexDirection: 'column',
1495
- justifyContent: 'center',
1496
- alignItems: 'center'
1648
+ flexDirection: 'column'
1497
1649
  });
1498
- const SwitchButtonContainer = /*#__PURE__*/ui.styled('div', {
1499
- display: 'flex',
1500
- justifyContent: 'center',
1501
- alignItems: 'center',
1650
+ const FromContainer = /*#__PURE__*/ui.styled('div', {
1502
1651
  position: 'relative',
1503
- top: '11px'
1652
+ paddingBottom: '$12'
1653
+ });
1654
+ const SwitchButtonContainer = /*#__PURE__*/ui.styled('div', {
1655
+ position: 'absolute',
1656
+ bottom: '-12px',
1657
+ left: '50%',
1658
+ transform: 'translate(-50%, 10%)'
1504
1659
  });
1505
1660
  const BestRouteContainer = /*#__PURE__*/ui.styled('div', {
1506
1661
  width: '100%',
@@ -1512,11 +1667,8 @@ const Alerts = /*#__PURE__*/ui.styled('div', {
1512
1667
  });
1513
1668
  function Home(props) {
1514
1669
  const {
1515
- title = 'SWAP',
1516
- titleSize = 18,
1517
- titleWeight = 600
1670
+ title = 'SWAP'
1518
1671
  } = props;
1519
- const waningMessage = '';
1520
1672
  const isRouterInContext = reactRouterDom.useInRouterContext();
1521
1673
  const navigate = reactRouterDom.useNavigate();
1522
1674
  const [count, setCount] = React.useState(0);
@@ -1539,6 +1691,7 @@ function Home(props) {
1539
1691
  const bestRouteError = useBestRouteStore.use.error();
1540
1692
  const loadingMetaStatus = useMetaStore.use.loadingStatus();
1541
1693
  const accounts = useWalletsStore.use.accounts();
1694
+ const setCurrentPage = useUiStore.use.setCurrentPage();
1542
1695
  const swithFromAndTo = () => {
1543
1696
  setFromChain(toChain);
1544
1697
  setFromToken(toToken);
@@ -1558,15 +1711,20 @@ function Home(props) {
1558
1711
  swap
1559
1712
  } = LimitErrorMessage(bestRoute);
1560
1713
  const priceImpactCanNotBeComputed = !canComputePriceImpact(bestRoute, inputAmount, inputUsdValue, outputUsdValue);
1561
- const swapButtonState = getSwapButtonState(loadingMetaStatus, accounts, fetchingBestRoute, bestRoute, hasLimitError(bestRoute), highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath);
1714
+ const inputIsZero = inputAmount === '0';
1715
+ const swapButtonState = getSwapButtonState(loadingMetaStatus, accounts, fetchingBestRoute, bestRoute, hasLimitError(bestRoute), highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath, inputIsZero);
1562
1716
  const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
1563
1717
  const highFee = hasHighFee(totalFeeInUsd);
1564
- 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, {
1565
1723
  title: title,
1566
- titleSize: titleSize,
1567
- titleWeight: titleWeight,
1568
- onClickRefresh: fetchBestRoute
1569
- }), React__default.createElement(TokenInfo, {
1724
+ suffix: React__default.createElement(HeaderButtons, {
1725
+ onClickRefresh: !!bestRoute ? fetchBestRoute : undefined
1726
+ })
1727
+ }), React__default.createElement(FromContainer, null, React__default.createElement(TokenInfo, {
1570
1728
  type: "From",
1571
1729
  chain: fromChain,
1572
1730
  token: fromToken,
@@ -1576,14 +1734,14 @@ function Home(props) {
1576
1734
  variant: "ghost",
1577
1735
  onClick: swithFromAndTo
1578
1736
  }, React__default.createElement(ui.VerticalSwapIcon, {
1579
- size: 36
1737
+ size: 32
1580
1738
  }), isRouterInContext && React__default.createElement(SwithFromAndTo, {
1581
1739
  count: count
1582
- }))), React__default.createElement(TokenInfo, {
1740
+ })))), React__default.createElement(TokenInfo, {
1583
1741
  type: "To",
1584
1742
  chain: toChain,
1585
1743
  token: toToken,
1586
- outputAmount: outputAmount,
1744
+ outputAmount: outputAmount ? new BigNumber__default(outputAmount) : new BigNumber__default(0),
1587
1745
  outputUsdValue: outputUsdValue
1588
1746
  }), showBestRoute && React__default.createElement(BestRouteContainer, null, React__default.createElement(ui.BestRoute, {
1589
1747
  error: bestRouteError,
@@ -1592,11 +1750,9 @@ function Home(props) {
1592
1750
  totalFee: numberToString(totalFeeInUsd, 0, 2),
1593
1751
  feeWarning: highFee,
1594
1752
  totalTime: secondsToString(totalArrivalTime(bestRoute))
1595
- })), (errorMessage || waningMessage || hasLimitError(bestRoute)) && React__default.createElement(Alerts, null, errorMessage && React__default.createElement(ui.Alert, {
1753
+ })), (errorMessage || hasLimitError(bestRoute)) && React__default.createElement(Alerts, null, errorMessage && React__default.createElement(ui.Alert, {
1596
1754
  type: "error"
1597
- }, React__default.createElement(ui.Typography, {
1598
- variant: "body2"
1599
- }, errorMessage)), hasLimitError(bestRoute) && React__default.createElement(ui.Alert, {
1755
+ }, errorMessage), hasLimitError(bestRoute) && React__default.createElement(ui.Alert, {
1600
1756
  type: "error",
1601
1757
  title: `${swap?.swapperId} Limit`
1602
1758
  }, React__default.createElement(React__default.Fragment, null, React__default.createElement(ui.Typography, {
@@ -1605,14 +1761,14 @@ function Home(props) {
1605
1761
  variant: "body2"
1606
1762
  }, "Yours: ", numberToString(swap?.fromAmount || null), swap?.from.symbol), React__default.createElement("br", null), React__default.createElement(ui.Typography, {
1607
1763
  variant: "body2"
1608
- }, recommendation))), waningMessage ), React__default.createElement(Footer, null, React__default.createElement(ui.Button, {
1764
+ }, recommendation)))), React__default.createElement(Footer, null, React__default.createElement(ui.Button, {
1609
1765
  type: "primary",
1610
1766
  align: "grow",
1611
1767
  size: "large",
1612
1768
  disabled: swapButtonState.disabled,
1613
1769
  onClick: () => {
1614
1770
  if (swapButtonState.title === 'Connect Wallet') navigate(navigationRoutes.wallets);else {
1615
- navigate(navigationRoutes.confirmWallets, {
1771
+ navigate(navigationRoutes.confirmSwap, {
1616
1772
  replace: true
1617
1773
  });
1618
1774
  }
@@ -1629,12 +1785,12 @@ const Route = _ref => {
1629
1785
  const navigate = reactRouter.useNavigate();
1630
1786
  const ref = React.useRef(true);
1631
1787
  React.useEffect(() => {
1632
- 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, {
1633
1789
  state: 'redirect'
1634
1790
  });
1635
1791
  ref.current = false;
1636
1792
  }, []);
1637
- 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));
1638
1794
  return React__default.createElement(React__default.Fragment, null, " ", children);
1639
1795
  };
1640
1796
  function AppRouter(_ref2) {
@@ -1644,56 +1800,34 @@ function AppRouter(_ref2) {
1644
1800
  } = _ref2;
1645
1801
  const isRouterInContext = reactRouter.useInRouterContext();
1646
1802
  const Router = isRouterInContext ? Route : reactRouter.MemoryRouter;
1647
- return React__default.createElement(React__default.Fragment, null, React__default.createElement(Router, Object.assign({}, props), children), isRouterInContext && React__default.createElement(UpdateUrl, null));
1648
- }
1649
-
1650
- const StyledButton = /*#__PURE__*/ui.styled(ui.Button, {
1651
- marginTop: '$8'
1652
- });
1653
- function ChangeSlippageButton() {
1654
- const navigate = reactRouterDom.useNavigate();
1655
- return React__default.createElement(StyledButton, {
1656
- type: "primary",
1657
- variant: "contained",
1658
- size: "small",
1659
- onClick: () => navigate(navigationRoutes.settings)
1660
- }, "Change Slippage");
1661
- }
1662
-
1663
- function HighSlippageWarning(props) {
1664
- const {
1665
- selectedSlippage
1666
- } = props;
1667
- return React__default.createElement(ui.Alert, {
1668
- type: "warning"
1669
- }, React__default.createElement(ui.Typography, {
1670
- variant: "body2"
1671
- }, "Caution, your slippage is high (=", selectedSlippage, "). Your trade may be front run.", React__default.createElement(ChangeSlippageButton, null)));
1672
- }
1673
-
1674
- function ConfirmSwapExtraMessages(props) {
1675
1803
  const {
1676
- selectedSlippage
1677
- } = props;
1678
- const highSlippage = selectedSlippage >= HIGH_SLIPPAGE;
1679
- return React__default.createElement(React__default.Fragment, null, highSlippage && React__default.createElement(HighSlippageWarning, {
1680
- selectedSlippage: selectedSlippage
1681
- }));
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));
1682
1815
  }
1683
1816
 
1684
1817
  function useNavigateBack() {
1685
1818
  const isRouterInContext = reactRouterDom.useInRouterContext();
1686
1819
  const navigate = reactRouterDom.useNavigate();
1687
1820
  const navigateBackFrom = currentRoute => {
1821
+ if (currentRoute === navigationRoutes.swapDetails) return navigate(navigationRoutes.swaps, {
1822
+ replace: true
1823
+ });
1688
1824
  if (!isRouterInContext || window.history.state && window.history.state.idx > 0) navigate(-1);else {
1689
- 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, {
1690
1826
  replace: true
1691
1827
  });else if (currentRoute === navigationRoutes.liquiditySources) navigate(navigationRoutes.settings, {
1692
1828
  replace: true
1693
1829
  });else if (currentRoute === navigationRoutes.swapDetails) navigate(navigationRoutes.swaps, {
1694
1830
  replace: true
1695
- });else if (currentRoute === navigationRoutes.confirmSwap) navigate(navigationRoutes.confirmWallets, {
1696
- replace: true
1697
1831
  });
1698
1832
  }
1699
1833
  };
@@ -1702,122 +1836,192 @@ function useNavigateBack() {
1702
1836
  };
1703
1837
  }
1704
1838
 
1705
- var ConfirmSwapErrorTypes;
1706
- (function (ConfirmSwapErrorTypes) {
1707
- ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["NO_ROUTE"] = 0] = "NO_ROUTE";
1708
- ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS"] = 1] = "ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS";
1709
- ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["REQUEST_FAILED"] = 2] = "REQUEST_FAILED";
1710
- ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["INSUFFICIENT_SLIPPAGE"] = 3] = "INSUFFICIENT_SLIPPAGE";
1711
- })(ConfirmSwapErrorTypes || (ConfirmSwapErrorTypes = {}));
1712
- var ConfirmSwapWarningTypes;
1713
- (function (ConfirmSwapWarningTypes) {
1714
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_UPDATED"] = 0] = "ROUTE_UPDATED";
1715
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_SWAPPERS_UPDATED"] = 1] = "ROUTE_SWAPPERS_UPDATED";
1716
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_COINS_UPDATED"] = 2] = "ROUTE_COINS_UPDATED";
1717
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_AND_OUTPUT_AMOUNT_UPDATED"] = 3] = "ROUTE_AND_OUTPUT_AMOUNT_UPDATED";
1718
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["INSUFFICIENT_BALANCE"] = 4] = "INSUFFICIENT_BALANCE";
1719
- })(ConfirmSwapWarningTypes || (ConfirmSwapWarningTypes = {}));
1720
-
1721
- function MinRequiredSlippage(_ref) {
1722
- let {
1723
- minRequiredSlippage
1724
- } = _ref;
1725
- return React__default.createElement(ui.Typography, {
1726
- variant: "body2"
1727
- }, "We recommend you to increase slippage to at least \u00A0", minRequiredSlippage, "\u00A0 for this route.", React__default.createElement(ChangeSlippageButton, null));
1728
- }
1729
-
1730
- function ConfirmSwapErrors(errors) {
1731
- return errors.flatMap(error => {
1732
- switch (error.type) {
1733
- case ConfirmSwapErrorTypes.NO_ROUTE:
1734
- return React__default.createElement(ui.Typography, {
1735
- variant: "body2"
1736
- }, "No routes found. Please try again later.");
1737
- case ConfirmSwapErrorTypes.REQUEST_FAILED:
1738
- return React__default.createElement(ui.Typography, {
1739
- variant: "body2"
1740
- }, `Failed to confirm swap ${error.status ? `'status': ${error.status})` : ''}, please try again.`);
1741
- case ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS:
1742
- return React__default.createElement(ui.Typography, {
1743
- variant: "body2"
1744
- }, "Route updated and price impact is too high, try again later!");
1745
- case ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE:
1746
- return React__default.createElement(MinRequiredSlippage, {
1747
- minRequiredSlippage: error.minRequiredSlippage
1748
- });
1749
- default:
1750
- return [];
1751
- }
1752
- });
1753
- }
1754
-
1755
- const List = /*#__PURE__*/ui.styled('ul', {
1839
+ const Box$1 = /*#__PURE__*/ui.styled('div', {
1840
+ display: 'flex',
1841
+ flexDirection: 'column',
1842
+ width: '100%'
1843
+ });
1844
+ const Container$3 = /*#__PURE__*/ui.styled('div', {
1845
+ boxSizing: 'border-box',
1846
+ borderRadius: '$5',
1847
+ padding: '$8 $16 $16 $16',
1756
1848
  variants: {
1757
- showListStyle: {
1758
- true: {
1759
- paddingLeft: '$24'
1849
+ type: {
1850
+ filled: {
1851
+ backgroundColor: '$neutrals300'
1852
+ },
1853
+ outlined: {
1854
+ border: '1px solid $neutrals300'
1760
1855
  }
1761
1856
  }
1762
- }
1763
- });
1764
- const ListItem = /*#__PURE__*/ui.styled('li', {
1765
- variants: {
1766
- showListStyle: {
1767
- true: {
1768
- listStyleType: 'disc',
1769
- listStylePosition: 'outside'
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'
1770
1877
  }
1878
+ },
1879
+ '.amount': {
1880
+ width: '30%'
1771
1881
  }
1772
1882
  }
1773
1883
  });
1774
- const Message = /*#__PURE__*/ui.styled(ui.Typography, {
1775
- display: 'block'
1884
+ const StyledImage$1 = /*#__PURE__*/ui.styled('img', {
1885
+ width: '$24',
1886
+ maxHeight: '$24'
1776
1887
  });
1777
- function BalanceWarnings(_ref) {
1778
- let {
1779
- messages
1780
- } = _ref;
1781
- const showListStyle = messages.length > 1;
1782
- return React__default.createElement(List, {
1783
- showListStyle: showListStyle
1784
- }, messages.map(warning => React__default.createElement(ListItem, {
1785
- showListStyle: showListStyle
1786
- }, React__default.createElement(Message, {
1787
- variant: "body2"
1788
- }, warning))));
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))))));
1789
1966
  }
1790
1967
 
1791
- function ConfirmSwapWarnings(warnings) {
1792
- return warnings.flatMap(warning => {
1793
- switch (warning.type) {
1794
- case ConfirmSwapWarningTypes.ROUTE_UPDATED:
1795
- return React__default.createElement(ui.Typography, {
1796
- variant: "body2"
1797
- }, "Route has been updated.");
1798
- case ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED:
1799
- return React__default.createElement(ui.Typography, {
1800
- variant: "body2"
1801
- }, `Output amount changed to ${warning.newOutputAmount}
1802
- (${warning.percentageChange}% change).`);
1803
- case ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED:
1804
- return React__default.createElement(ui.Typography, {
1805
- variant: "body2"
1806
- }, "Route swappers has been updated.");
1807
- case ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED:
1808
- return React__default.createElement(ui.Typography, {
1809
- variant: "body2"
1810
- }, "Route internal coins has been updated.");
1811
- case ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE:
1812
- return React__default.createElement(BalanceWarnings, {
1813
- messages: warning.messages
1814
- });
1815
- default:
1816
- return [];
1817
- }
1818
- });
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);
1819
2007
  }
1820
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
+
1821
2025
  function useConfirmSwap() {
1822
2026
  const fromToken = useBestRouteStore.use.fromToken();
1823
2027
  const toToken = useBestRouteStore.use.toToken();
@@ -1858,6 +2062,7 @@ function useConfirmSwap() {
1858
2062
  proceedAnywayRef.current = false;
1859
2063
  if (confiremedRouteRef.current) {
1860
2064
  const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRouteRef.current, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
2065
+ //@ts-ignore
1861
2066
  return newSwap;
1862
2067
  }
1863
2068
  return;
@@ -1920,6 +2125,7 @@ function useConfirmSwap() {
1920
2125
  disabledSwappersGroups: disabledLiquiditySources
1921
2126
  };
1922
2127
  const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRoute, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
2128
+ //@ts-ignore
1923
2129
  return newSwap;
1924
2130
  } else if (!proceedAnywayRef.current) {
1925
2131
  proceedAnywayRef.current = true;
@@ -1949,31 +2155,196 @@ function useConfirmSwap() {
1949
2155
  };
1950
2156
  }
1951
2157
 
2158
+ function ChangeSlippageButton() {
2159
+ const navigate = reactRouterDom.useNavigate();
2160
+ return React__default.createElement(ui.Button, {
2161
+ type: "primary",
2162
+ variant: "outlined",
2163
+ size: "small",
2164
+ onClick: () => navigate(navigationRoutes.settings)
2165
+ }, "Change Slippage");
2166
+ }
2167
+
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
+
1952
2295
  function ConfirmSwapPage() {
1953
- const setSelectedSwap = useUiStore.use.setSelectedSwap();
2296
+ const navigate = reactRouterDom.useNavigate();
1954
2297
  const {
1955
2298
  navigateBackFrom
1956
2299
  } = useNavigateBack();
1957
- const {
1958
- manager
1959
- } = queueManagerReact.useManager();
1960
- const navigate = reactRouterDom.useNavigate();
1961
2300
  const bestRoute = useBestRouteStore.use.bestRoute();
1962
2301
  const fetchingBestRoute = useBestRouteStore.use.loading();
2302
+ const fetchingBestRouteError = useBestRouteStore.use.error();
2303
+ const setSelectedSwap = useUiStore.use.setSelectedSwap();
1963
2304
  const {
2305
+ blockchains,
1964
2306
  tokens
1965
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();
1966
2312
  const slippage = useSettingsStore.use.slippage();
1967
2313
  const customSlippage = useSettingsStore.use.customSlippage();
1968
- const selectedSlippage = customSlippage || slippage;
2314
+ const bestRouteloadingStatus = getBestRouteStatus(fetchingBestRoute, !!fetchingBestRouteError);
2315
+ const {
2316
+ manager
2317
+ } = queueManagerReact.useManager();
1969
2318
  const {
1970
2319
  loading,
1971
2320
  errors,
1972
2321
  warnings,
1973
2322
  confirmSwap
1974
2323
  } = useConfirmSwap();
2324
+ const selectedSlippage = customSlippage || slippage;
1975
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);
1976
2344
  return React__default.createElement(ui.ConfirmSwap, {
2345
+ requiredWallets: getRequiredChains(bestRoute),
2346
+ selectableWallets: selectableWallets,
2347
+ onBack: navigateBackFrom.bind(null, navigationRoutes.confirmSwap),
1977
2348
  onConfirm: () => {
1978
2349
  confirmSwap?.().then(swap => {
1979
2350
  if (swap) {
@@ -1989,16 +2360,51 @@ function ConfirmSwapPage() {
1989
2360
  }
1990
2361
  });
1991
2362
  },
1992
- onBack: navigateBackFrom.bind(null, navigationRoutes.confirmSwap),
1993
- bestRoute: getBestRouteWithCalculatedFees(bestRoute, tokens),
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
+ }),
1994
2401
  loading: loading,
1995
2402
  errors: ConfirmSwapErrors(errors),
1996
2403
  warnings: ConfirmSwapWarnings(warnings),
1997
2404
  extraMessages: showHighSlippageWarning && React__default.createElement(ConfirmSwapExtraMessages, {
1998
2405
  selectedSlippage: selectedSlippage
1999
2406
  }),
2000
- confirmButtonTitle: warnings.length > 0 || errors.length > 0 ? 'Proceed anyway!' : 'Confirm swap!',
2001
- confirmButtonDisabled: fetchingBestRoute
2407
+ confirmButtonTitle: warnings.length > 0 || errors.length > 0 ? 'Proceed anyway!' : 'Confirm swap!'
2002
2408
  });
2003
2409
  }
2004
2410
 
@@ -2016,6 +2422,31 @@ const getPendingSwaps = manager => {
2016
2422
  return result.sort((a, b) => Number(b.swap.creationTime) - Number(a.swap.creationTime));
2017
2423
  };
2018
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
+
2019
2450
  function HistoryPage() {
2020
2451
  const setSelectedSwap = useUiStore.use.setSelectedSwap();
2021
2452
  const navigate = reactRouterDom.useNavigate();
@@ -2031,16 +2462,14 @@ function HistoryPage() {
2031
2462
  } = _ref;
2032
2463
  return swap;
2033
2464
  });
2034
- return React__default.createElement(ui.History
2035
- //todo: move PendingSwap type to rango-types
2036
- //@ts-ignore
2037
- , {
2038
- //todo: move PendingSwap type to rango-types
2039
- //@ts-ignore
2465
+ return React__default.createElement(ui.History, {
2040
2466
  list: pendingSwaps,
2467
+ groupBy: groupSwapsByDate,
2041
2468
  onSwapClick: requestId => {
2042
2469
  setSelectedSwap(requestId);
2043
- navigate(navigationRoutes.swaps + `/${requestId}`);
2470
+ navigate(navigationRoutes.swaps + `/${requestId}`, {
2471
+ replace: true
2472
+ });
2044
2473
  },
2045
2474
  onBack: navigateBackFrom.bind(null, navigationRoutes.swaps)
2046
2475
  });
@@ -2051,6 +2480,7 @@ function LiquiditySourcePage(_ref) {
2051
2480
  supportedSwappers
2052
2481
  } = _ref;
2053
2482
  const swappers = useMetaStore.use.meta().swappers;
2483
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2054
2484
  const toggleLiquiditySource = useSettingsStore.use.toggleLiquiditySource();
2055
2485
  const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
2056
2486
  const toggleAllLiquiditySources = useSettingsStore.use.toggleAllLiquiditySources();
@@ -2076,7 +2506,8 @@ function LiquiditySourcePage(_ref) {
2076
2506
  toggleAll: toggleAllLiquiditySources,
2077
2507
  list: supportedSwappers !== 'all' ? uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0) : uniqueSwappersGroups,
2078
2508
  onChange: liquiditySource => toggleLiquiditySource(liquiditySource.title),
2079
- onBack: navigateBackFrom.bind(null, navigationRoutes.liquiditySources)
2509
+ onBack: navigateBackFrom.bind(null, navigationRoutes.liquiditySources),
2510
+ loadingStatus: loadingMetaStatus
2080
2511
  });
2081
2512
  }
2082
2513
 
@@ -2119,11 +2550,11 @@ function SelectTokenPage(props) {
2119
2550
  const destinationTokens = useBestRouteStore.use.destinationTokens();
2120
2551
  const supportedSourceTokens = supportedTokens === 'all' ? sourceTokens : sourceTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2121
2552
  const supportedDestinationTokens = supportedTokens === 'all' ? destinationTokens : destinationTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2122
- console.log(supportedSourceTokens);
2123
2553
  const fromToken = useBestRouteStore.use.fromToken();
2124
2554
  const toToken = useBestRouteStore.use.toToken();
2125
2555
  const setFromToken = useBestRouteStore.use.setFromToken();
2126
2556
  const setToToken = useBestRouteStore.use.setToToken();
2557
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2127
2558
  return React__default.createElement(ui.TokenSelector, {
2128
2559
  type: type === 'from' ? 'Source' : 'Destination',
2129
2560
  list: type == 'from' ? supportedSourceTokens : supportedDestinationTokens,
@@ -2132,7 +2563,8 @@ function SelectTokenPage(props) {
2132
2563
  if (type === 'from') setFromToken(token);else setToToken(token);
2133
2564
  navigateBackFrom(navigationRoutes.fromToken);
2134
2565
  },
2135
- onBack: navigateBackFrom.bind(null, navigationRoutes.fromToken)
2566
+ onBack: navigateBackFrom.bind(null, navigationRoutes.fromToken),
2567
+ loadingStatus: loadingMetaStatus
2136
2568
  });
2137
2569
  }
2138
2570
 
@@ -2154,6 +2586,7 @@ function SettingsPage(_ref) {
2154
2586
  } = useNavigateBack();
2155
2587
  const infiniteApprove = useSettingsStore.use.infiniteApprove();
2156
2588
  const toggleInfiniteApprove = useSettingsStore.use.toggleInfiniteApprove();
2589
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2157
2590
  const uniqueSwappersGroups = [];
2158
2591
  removeDuplicateFrom(swappers.map(s => s.swapperGroup)).map(swapperGroup => {
2159
2592
  return swappers.find(s => s.swapperGroup === swapperGroup);
@@ -2186,7 +2619,8 @@ function SettingsPage(_ref) {
2186
2619
  selectedTheme: theme,
2187
2620
  onThemeChange: setTheme,
2188
2621
  infiniteApprove: infiniteApprove,
2189
- toggleInfiniteApprove: toggleInfiniteApprove
2622
+ toggleInfiniteApprove: toggleInfiniteApprove,
2623
+ loadingStatus: loadingMetaStatus
2190
2624
  });
2191
2625
  }
2192
2626
 
@@ -2194,9 +2628,16 @@ const ListContainer = /*#__PURE__*/ui.styled('div', {
2194
2628
  display: 'grid',
2195
2629
  gap: '.5rem',
2196
2630
  gridTemplateColumns: ' repeat(2, minmax(0, 1fr))',
2197
- height: '450px',
2198
2631
  alignContent: 'baseline',
2199
- padding: '0 0.5rem'
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%'
2200
2641
  });
2201
2642
  const AlertContainer = /*#__PURE__*/ui.styled('div', {
2202
2643
  paddingBottom: '$16'
@@ -2216,10 +2657,12 @@ function WalletsPage(_ref) {
2216
2657
  connect
2217
2658
  } = walletsCore.useWallets();
2218
2659
  const wallets = getlistWallet(state, getWalletInfo, supportedWallets === 'all' ? Object.values(walletsShared.WalletType) : supportedWallets);
2660
+ const walletsRef = React.useRef();
2219
2661
  let sortedWallets = walletsShared.detectMobileScreens() ? wallets.filter(wallet => wallet.showOnMobile) : wallets;
2220
2662
  sortedWallets = sortWalletsBasedOnState(sortedWallets);
2221
2663
  const [walletErrorMessage, setWalletErrorMessage] = React.useState('');
2222
2664
  const toggleConnectWalletsButton = useUiStore.use.toggleConnectWalletsButton();
2665
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2223
2666
  const {
2224
2667
  t
2225
2668
  } = reactI18next.useTranslation();
@@ -2239,71 +2682,38 @@ function WalletsPage(_ref) {
2239
2682
  setWalletErrorMessage('Error: ' + e?.message);
2240
2683
  }
2241
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
+ };
2242
2691
  React.useEffect(() => {
2243
2692
  toggleConnectWalletsButton();
2244
- return () => toggleConnectWalletsButton();
2693
+ return () => {
2694
+ disconnectConnectingWallets();
2695
+ toggleConnectWalletsButton();
2696
+ };
2245
2697
  }, []);
2698
+ React.useEffect(() => {
2699
+ walletsRef.current = wallets;
2700
+ }, [wallets]);
2246
2701
  return React__default.createElement(ui.SecondaryPage, {
2247
2702
  title: t('Select Wallet') || '',
2248
2703
  textField: false,
2249
2704
  onBack: navigateBackFrom.bind(null, navigationRoutes.wallets)
2250
2705
  }, React__default.createElement(React__default.Fragment, null, walletErrorMessage && React__default.createElement(AlertContainer, null, React__default.createElement(ui.Alert, {
2251
2706
  type: "error"
2252
- }, React__default.createElement(ui.Typography, {
2253
- variant: "body2"
2254
- }, walletErrorMessage))), React__default.createElement(ListContainer, null, sortedWallets.map((wallet, index) => React__default.createElement(ui.Wallet, Object.assign({}, wallet, {
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, {
2255
2712
  key: `${index}-${wallet.type}`,
2256
2713
  onClick: onSelectWallet
2257
2714
  }))))));
2258
2715
  }
2259
2716
 
2260
- function ConfirmWalletsPage() {
2261
- const navigate = reactRouterDom.useNavigate();
2262
- const {
2263
- navigateBackFrom
2264
- } = useNavigateBack();
2265
- const bestRoute = useBestRouteStore.use.bestRoute();
2266
- const {
2267
- blockchains
2268
- } = useMetaStore.use.meta();
2269
- const accounts = useWalletsStore.use.accounts();
2270
- const selectedWallets = useWalletsStore.use.selectedWallets();
2271
- const initSelectedWallets = useWalletsStore.use.initSelectedWallets();
2272
- const setSelectedWallet = useWalletsStore.use.setSelectedWallet();
2273
- const {
2274
- getWalletInfo,
2275
- connect
2276
- } = walletsCore.useWallets();
2277
- const confirmDisabled = !requiredWallets(bestRoute).every(chain => selectedWallets.map(wallet => wallet.chain).includes(chain));
2278
- const firstStep = bestRoute?.result?.swaps[0];
2279
- const lastStep = bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1];
2280
- const fromAmount = decimalNumber(firstStep?.fromAmount, 3);
2281
- const toAmount = decimalNumber(lastStep?.toAmount, 3);
2282
- React.useEffect(() => {
2283
- initSelectedWallets();
2284
- }, []);
2285
- const selectableWallets = getSelectableWallets(accounts, selectedWallets, getWalletInfo);
2286
- const handleConnectChain = wallet => {
2287
- const network = wallet;
2288
- getKeplrCompatibleConnectedWallets(selectableWallets).forEach(compatibleWallet => connect?.(compatibleWallet, network));
2289
- };
2290
- return React__default.createElement(ui.ConfirmWallets, {
2291
- requiredWallets: getRequiredChains(bestRoute),
2292
- selectableWallets: selectableWallets,
2293
- onBack: navigateBackFrom.bind(null, navigationRoutes.confirmWallets),
2294
- swap: bestRoute,
2295
- fromAmount: fromAmount,
2296
- toAmount: toAmount,
2297
- onConfirm: () => navigate(navigationRoutes.confirmSwap, {
2298
- replace: true
2299
- }),
2300
- onChange: wallet => setSelectedWallet(wallet),
2301
- confirmDisabled: confirmDisabled,
2302
- handleConnectChain: wallet => handleConnectChain(wallet),
2303
- isExperimentalChain: wallet => getKeplrCompatibleConnectedWallets(selectableWallets).length > 0 ? isExperimentalChain(blockchains, wallet) : false
2304
- });
2305
- }
2306
-
2307
2717
  function useCopyToClipboard(resetInterval) {
2308
2718
  const [isCopied, setCopied] = React__default.useState(false);
2309
2719
  const handleCopy = React__default.useCallback(text => {
@@ -2322,15 +2732,87 @@ function useCopyToClipboard(resetInterval) {
2322
2732
  return [isCopied, handleCopy];
2323
2733
  }
2324
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
+
2325
2795
  function SwapDetailsPage() {
2326
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();
2327
2803
  const {
2328
2804
  navigateBackFrom
2329
2805
  } = useNavigateBack();
2806
+ const [isCopied, handleCopy] = useCopyToClipboard(2000);
2330
2807
  const {
2331
2808
  manager
2332
2809
  } = queueManagerReact.useManager();
2333
- const [isCopied, handleCopy] = useCopyToClipboard(2000);
2810
+ const [loading, setLoading] = React.useState(true);
2811
+ React.useEffect(() => {
2812
+ setTimeout(() => {
2813
+ setLoading(false);
2814
+ }, 5000);
2815
+ }, []);
2334
2816
  const pendingSwaps = getPendingSwaps(manager);
2335
2817
  const selectedSwap = pendingSwaps.find(_ref => {
2336
2818
  let {
@@ -2338,92 +2820,161 @@ function SwapDetailsPage() {
2338
2820
  } = _ref;
2339
2821
  return swap.requestId === selectedSwapRequestId;
2340
2822
  });
2341
- //TODO: implement swap cancellation (move queueManager logic to queueManager/rango-preset)
2342
2823
  const onCancel = () => {
2343
- const swap = selectedSwap ? manager?.get(selectedSwap.id) : undefined;
2824
+ const swap = manager?.get(selectedSwap?.id);
2344
2825
  if (swap) queueManagerRangoPreset.cancelSwap(swap);
2345
2826
  };
2346
- 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({
2347
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
+ })),
2348
2879
  //todo: move PendingSwap type to rango-types
2349
2880
  //@ts-ignore
2350
- pendingSwap: selectedSwap?.swap,
2881
+ pendingSwap: swap,
2351
2882
  onCopy: handleCopy,
2352
2883
  isCopied: isCopied,
2353
- onCancel: onCancel
2354
- });
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
+ }));
2355
2905
  }
2356
2906
 
2907
+ const getAbsolutePath = path => path.replace('/', '');
2357
2908
  function AppRoutes(props) {
2358
2909
  const {
2359
2910
  configs
2360
2911
  } = props;
2361
2912
  return reactRouterDom.useRoutes([{
2362
- path: navigationRoutes.home,
2913
+ path: getAbsolutePath(navigationRoutes.home),
2363
2914
  element: React__default.createElement(Home, {
2364
2915
  title: configs?.title,
2365
2916
  titleSize: configs?.titleSize,
2366
2917
  titleWeight: configs?.titleWeight
2367
2918
  })
2368
2919
  }, {
2369
- path: navigationRoutes.fromChain,
2920
+ path: getAbsolutePath(navigationRoutes.fromChain),
2370
2921
  element: React__default.createElement(SelectChainPage, {
2371
2922
  type: "from",
2372
2923
  supportedChains: configs?.fromChains || 'all'
2373
2924
  })
2374
2925
  }, {
2375
- path: navigationRoutes.toChain,
2926
+ path: getAbsolutePath(navigationRoutes.toChain),
2376
2927
  element: React__default.createElement(SelectChainPage, {
2377
2928
  type: "to",
2378
2929
  supportedChains: configs?.toChains || 'all'
2379
2930
  })
2380
2931
  }, {
2381
- path: navigationRoutes.fromToken + '/*',
2932
+ path: getAbsolutePath(navigationRoutes.fromToken),
2382
2933
  element: React__default.createElement(SelectTokenPage, {
2383
2934
  type: "from",
2384
2935
  supportedTokens: configs?.fromTokens || 'all'
2385
2936
  })
2386
2937
  }, {
2387
- path: navigationRoutes.toToken,
2938
+ path: getAbsolutePath(navigationRoutes.toToken),
2388
2939
  element: React__default.createElement(SelectTokenPage, {
2389
2940
  type: "to",
2390
2941
  supportedTokens: configs?.toTokens || 'all'
2391
2942
  })
2392
2943
  }, {
2393
- path: navigationRoutes.settings,
2944
+ path: getAbsolutePath(navigationRoutes.settings),
2394
2945
  element: React__default.createElement(SettingsPage, {
2395
2946
  supportedSwappers: configs?.liquiditySources || 'all'
2396
2947
  })
2397
2948
  }, {
2398
- path: navigationRoutes.liquiditySources,
2949
+ path: getAbsolutePath(navigationRoutes.liquiditySources),
2399
2950
  element: React__default.createElement(LiquiditySourcePage, {
2400
2951
  supportedSwappers: configs?.liquiditySources || 'all'
2401
2952
  })
2402
2953
  }, {
2403
- path: navigationRoutes.swaps,
2954
+ path: getAbsolutePath(navigationRoutes.swaps),
2404
2955
  element: React__default.createElement(HistoryPage, null)
2405
2956
  }, {
2406
2957
  path: navigationRoutes.swapDetails,
2407
2958
  element: React__default.createElement(SwapDetailsPage, null)
2408
2959
  }, {
2409
- path: navigationRoutes.wallets,
2960
+ path: getAbsolutePath(navigationRoutes.wallets),
2410
2961
  element: React__default.createElement(WalletsPage, {
2411
2962
  supportedWallets: configs?.wallets || 'all',
2412
2963
  multiWallets: typeof configs?.multiWallets === 'undefined' ? true : configs.multiWallets
2413
2964
  })
2414
2965
  }, {
2415
- path: navigationRoutes.confirmSwap,
2966
+ path: getAbsolutePath(navigationRoutes.confirmSwap),
2416
2967
  element: React__default.createElement(ConfirmSwapPage, null)
2417
- }, {
2418
- path: navigationRoutes.confirmWallets,
2419
- element: React__default.createElement(ConfirmWalletsPage, null)
2420
2968
  }]);
2421
2969
  }
2422
2970
 
2423
- const Header$1 = /*#__PURE__*/ui.styled('div', {
2971
+ const Header = /*#__PURE__*/ui.styled('div', {
2424
2972
  display: 'flex',
2425
2973
  width: '100%',
2426
- justifyContent: 'end'
2974
+ justifyContent: 'end',
2975
+ '.balance': {
2976
+ display: 'flex'
2977
+ }
2427
2978
  });
2428
2979
  const WalletImage = /*#__PURE__*/ui.styled('img', {
2429
2980
  width: '$24',
@@ -2453,6 +3004,8 @@ function Layout(_ref) {
2453
3004
  const setInputAmount = useBestRouteStore.use.setInputAmount();
2454
3005
  const totalBalance = calculateWalletUsdValue(balances);
2455
3006
  const connectWalletsButtonDisabled = useUiStore.use.connectWalletsButtonDisabled();
3007
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
3008
+ const fetchingBalance = useWalletsStore(fetchingBalanceSelector);
2456
3009
  const {
2457
3010
  t
2458
3011
  } = reactI18next.useTranslation();
@@ -2467,22 +3020,32 @@ function Layout(_ref) {
2467
3020
  setFromToken(configs?.fromToken || null);
2468
3021
  setFromChain(configs?.fromChain || null);
2469
3022
  }, [configs?.fromToken, configs?.fromChain]);
2470
- 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, {
2471
3030
  size: "small",
2472
3031
  suffix: React__default.createElement(ui.AddWalletIcon, {
2473
3032
  size: 20
2474
3033
  }),
2475
3034
  variant: "ghost",
2476
3035
  flexContent: true,
3036
+ loading: loadingMetaStatus === 'loading',
3037
+ disabled: loadingMetaStatus === 'failed',
2477
3038
  onClick: () => {
2478
3039
  if (!connectWalletsButtonDisabled) navigate(navigationRoutes.wallets);
2479
3040
  }
2480
3041
  }, connectedWalletsImages?.length ? connectedWalletsImages.map((walletImage, index) => React__default.createElement(WalletImage, {
2481
3042
  key: index,
2482
3043
  src: walletImage
2483
- })) : 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, {
2484
3047
  variant: "body2"
2485
- }, !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, {
2486
3049
  configs: configs
2487
3050
  }));
2488
3051
  }
@@ -2490,10 +3053,12 @@ function Layout(_ref) {
2490
3053
  const globalStyles = /*#__PURE__*/ui.globalCss({
2491
3054
  '*': {
2492
3055
  '&::-webkit-scrollbar': {
2493
- width: '$8'
3056
+ width: '$8',
3057
+ height: '$8'
2494
3058
  },
2495
3059
  '&::-webkit-scrollbar-thumb': {
2496
- backgroundColor: '$neutrals400'
3060
+ backgroundColor: '$neutrals400',
3061
+ borderRadius: '$10'
2497
3062
  },
2498
3063
  '&::-webkit-scrollbar-thumb:hover': {
2499
3064
  backgroundColor: '$neutrals500'
@@ -2505,7 +3070,7 @@ const globalStyles = /*#__PURE__*/ui.globalCss({
2505
3070
  });
2506
3071
  const globalFont = fontFamily => ui.globalCss({
2507
3072
  '@import': ["url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap')", "url('https://fonts.cdnfonts.com/css/times-new-roman')"],
2508
- [`.font_${fontFamily.replace(/ /g, '')} ._text`]: {
3073
+ body: {
2509
3074
  fontFamily
2510
3075
  }
2511
3076
  })();
@@ -2531,16 +3096,16 @@ function useTheme(_ref) {
2531
3096
  warning = '#F5A623',
2532
3097
  success = '#0070F3',
2533
3098
  fontFamily = 'Robot',
2534
- borderRadius = 5
3099
+ borderRadius = 8
2535
3100
  } = _ref;
2536
3101
  const theme = useSettingsStore.use.theme();
2537
3102
  const fetchMeta = useMetaStore.use.fetchMeta();
2538
3103
  const colors = {
2539
3104
  neutrals200: '#FAFAFA',
2540
- neutrals300: '#EAEAEA',
2541
- neutrals400: '#999999',
2542
- neutrals500: '#888888',
2543
- neutrals600: '#666666',
3105
+ neutrals300: '#f2f2f2',
3106
+ neutrals400: '#dedede',
3107
+ neutrals500: '#cccccc',
3108
+ neutrals600: '#acacac',
2544
3109
  neutrals700: '#444444',
2545
3110
  neutrals800: '#333333',
2546
3111
  neutrals900: '#111111',
@@ -2584,10 +3149,10 @@ function useTheme(_ref) {
2584
3149
  neutrals200: '#111111',
2585
3150
  neutrals300: '#333333',
2586
3151
  neutrals400: '#444444',
2587
- neutrals500: '#666666',
2588
- neutrals600: '#888888',
2589
- neutrals700: '#999999',
2590
- neutrals800: '#EAEAEA',
3152
+ neutrals500: '#acacac',
3153
+ neutrals600: '#cccccc',
3154
+ neutrals700: '#dedede',
3155
+ neutrals800: '#f2f2f2',
2591
3156
  neutrals900: '#FAFAFA',
2592
3157
  foreground: background,
2593
3158
  background: foreground
@@ -2647,8 +3212,9 @@ function useSelectLanguage() {
2647
3212
  }
2648
3213
 
2649
3214
  var swap = "SWAP";
2650
- var From = "From";
2651
- var To = "To";
3215
+ var From = "You sell";
3216
+ var To = "You receive";
3217
+ var Balance = "Balance";
2652
3218
  var Max = "Max";
2653
3219
  var Chain = "Chain";
2654
3220
  var Token = "Token";
@@ -2660,12 +3226,13 @@ var en = {
2660
3226
  "Powered By": "Powered By",
2661
3227
  From: From,
2662
3228
  To: To,
3229
+ Balance: Balance,
2663
3230
  Max: Max,
2664
3231
  Chain: Chain,
2665
3232
  Token: Token,
2666
3233
  Source: Source,
2667
3234
  Destination: Destination,
2668
- "Select Wallet": "Select Wallet"
3235
+ "Select Wallet": "Connect Your Wallet"
2669
3236
  };
2670
3237
 
2671
3238
  var swap$1 = "TAKAS";
@@ -2687,7 +3254,7 @@ var tr = {
2687
3254
  };
2688
3255
 
2689
3256
  const languages = ['en', 'tr'];
2690
- i18n.use(Backend)
3257
+ i18n__default.use(Backend)
2691
3258
  // detect user language
2692
3259
  .use(LanguageDetector)
2693
3260
  // pass the i18n instance to react-i18next.
@@ -2765,7 +3332,9 @@ function QueueManager(props) {
2765
3332
  //@ts-ignore
2766
3333
  queuesDefs: [queueManagerRangoPreset.swapQueueDef],
2767
3334
  context: context,
2768
- onPersistedDataLoaded: _manager => {},
3335
+ onPersistedDataLoaded: manager => {
3336
+ queueManagerRangoPreset.checkWaitingForNetworkChange(manager);
3337
+ },
2769
3338
  isPaused: false
2770
3339
  }, props.children);
2771
3340
  }
@@ -2793,8 +3362,10 @@ const SwapBox = _ref => {
2793
3362
  changeLanguage
2794
3363
  } = useSelectLanguage();
2795
3364
  const clearConnectedWallet = useWalletsStore.use.clearConnectedWallet();
3365
+ const [lastConnectedWalletWithNetwork, setLastConnectedWalletWithNetwork] = React.useState('');
3366
+ const [disconnectedWallet, setDisconnectedWallet] = React.useState();
2796
3367
  const evmBasedChainNames = blockchains.filter(rangoSdk.isEvmBlockchain).map(chain => chain.name);
2797
- const onUpdateState = (type, event, value, _, supportedChains) => {
3368
+ const onUpdateState = (type, event, value, state, supportedChains) => {
2798
3369
  if (event === walletsCore.Events.ACCOUNTS) {
2799
3370
  if (value) {
2800
3371
  const supportedChainNames = walletAndSupportedChainsNames(supportedChains);
@@ -2804,6 +3375,16 @@ const SwapBox = _ref => {
2804
3375
  disconnectWallet(type);
2805
3376
  }
2806
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
+ }
2807
3388
  };
2808
3389
  let providers = providerAll.allProviders();
2809
3390
  React.useEffect(() => {
@@ -2835,7 +3416,12 @@ const SwapBox = _ref => {
2835
3416
  }, React__default.createElement(AppRouter, {
2836
3417
  title: configs.title,
2837
3418
  titleSize: configs.titleSize,
2838
- titleWeight: configs.titleWeight
3419
+ titleWeight: configs.titleWeight,
3420
+ lastConnectedWallet: lastConnectedWalletWithNetwork,
3421
+ disconnectedWallet: disconnectedWallet,
3422
+ clearDisconnectedWallet: () => {
3423
+ setDisconnectedWallet(undefined);
3424
+ }
2839
3425
  }, React__default.createElement(Layout, {
2840
3426
  configs: configs
2841
3427
  }))))));