@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
@@ -1,22 +1,23 @@
1
- import { WalletState, Tooltip, Button, RetryIcon, HistoryIcon, SettingsIcon, styled, css, Typography, InfoCircleIcon, AngleDownIcon, TextField, VerticalSwapIcon, BestRoute, Alert, ConfirmSwap, History, LiquiditySourcesSelector, BlockchainSelector, TokenSelector, Settings, SecondaryPage, Wallet, ConfirmWallets, SwapHistory, AddWalletIcon, globalCss, createTheme, SwapContainer } from '@rango-dev/ui';
1
+ import { WalletState, InfoCircleIcon, AngleDownIcon, Typography, Spacer, Button, TextField, styled, Tooltip, RetryIcon, HistoryIcon, SettingsIcon, Header as Header$1, VerticalSwapIcon, BestRoute, Alert, ChevronRightIcon, GasIcon, ConfirmSwap, History, LiquiditySourcesSelector, BlockchainSelector, TokenSelector, Settings, SecondaryPage, Spinner, LoadingFailedAlert, Wallet, SwapHistory, AddWalletIcon, globalCss, createTheme, SwapContainer } from '@rango-dev/ui';
2
2
  import React, { useRef, useEffect, useState, useLayoutEffect } from 'react';
3
3
  import { useInRouterContext as useInRouterContext$1, MemoryRouter, useLocation as useLocation$1, useNavigate as useNavigate$1 } from 'react-router';
4
+ import { PendingSwapNetworkStatus, useQueueManager, getCurrentStep, getCurrentBlockchainOfOrNull, getRelatedWalletOrNull, cancelSwap, swapQueueDef, checkWaitingForNetworkChange } from '@rango-dev/queue-manager-rango-preset';
5
+ import { isCosmosBlockchain, isEvmBlockchain } from 'rango-types';
4
6
  import { useSearchParams, useLocation, createSearchParams, useNavigate, useInRouterContext, useRoutes } from 'react-router-dom';
5
7
  import { create } from 'zustand';
6
8
  import BigNumber, { BigNumber as BigNumber$1 } from 'bignumber.js';
7
- import { Network, isEvmAddress, detectInstallLink, KEPLR_COMPATIBLE_WALLETS, WalletType, getCosmosExperimentalChainInfo, detectMobileScreens, convertEvmBlockchainMetaToEvmChainInfo } from '@rango-dev/wallets-shared';
8
- import { isCosmosBlockchain } from 'rango-types';
9
+ import { Network, isEvmAddress, KEPLR_COMPATIBLE_WALLETS, detectInstallLink, WalletType, getCosmosExperimentalChainInfo, detectMobileScreens, convertEvmBlockchainMetaToEvmChainInfo } from '@rango-dev/wallets-shared';
9
10
  import { readAccountAddress, useWallets, Provider as Provider$1, Events } from '@rango-dev/wallets-core';
10
11
  import { persist, subscribeWithSelector } from 'zustand/middleware';
11
- import { RangoClient, isEvmBlockchain } from 'rango-sdk';
12
+ import { RangoClient, isEvmBlockchain as isEvmBlockchain$1 } from 'rango-sdk';
12
13
  import { shallow } from 'zustand/shallow';
13
14
  import { useTranslation, initReactI18next } from 'react-i18next';
14
15
  import { styled as styled$1 } from '@rango-dev/ui/src/theme';
15
16
  import { allProviders } from '@rango-dev/provider-all';
17
+ import i18n, { t } from 'i18next';
16
18
  import { useManager, Provider } from '@rango-dev/queue-manager-react';
19
+ import dayjs from 'dayjs';
17
20
  import copy from 'copy-to-clipboard';
18
- import { cancelSwap, swapQueueDef } from '@rango-dev/queue-manager-rango-preset';
19
- import i18n from 'i18next';
20
21
  import Backend from 'i18next-http-backend';
21
22
  import LanguageDetector from 'i18next-browser-languagedetector';
22
23
 
@@ -31,7 +32,6 @@ const navigationRoutes = {
31
32
  swaps: '/swaps',
32
33
  wallets: '/wallets',
33
34
  confirmSwap: '/confirm-swap',
34
- confirmWallets: '/confirm-wallets',
35
35
  swapDetails: '/swaps/:requestId'
36
36
  };
37
37
 
@@ -61,6 +61,22 @@ function shadeColor(color, percent) {
61
61
  var BB = B.toString(16).length == 1 ? '0' + B.toString(16) : B.toString(16);
62
62
  return '#' + RR + GG + BB;
63
63
  }
64
+ function debounce(fn, time) {
65
+ let timeoutId;
66
+ return wrapper;
67
+ function wrapper() {
68
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
69
+ args[_key] = arguments[_key];
70
+ }
71
+ if (timeoutId) {
72
+ clearTimeout(timeoutId);
73
+ }
74
+ timeoutId = setTimeout(() => {
75
+ timeoutId = null;
76
+ fn(...args);
77
+ }, time);
78
+ }
79
+ }
64
80
 
65
81
  const secondsToString = s => {
66
82
  const seconds = (s % 60).toString().padStart(2, '0');
@@ -327,7 +343,7 @@ function getSortedTokens(chain, tokens, balances, otherChainTokens) {
327
343
  return sortTokens(getTokensWithBalance(filteredTokens, balances));
328
344
  }
329
345
  function tokensAreEqual(tokenA, tokenB) {
330
- return tokenA?.blockchain === tokenB?.blockchain && tokenA?.name === tokenB?.name && tokenA?.address === tokenB?.address;
346
+ return tokenA?.blockchain === tokenB?.blockchain && tokenA?.symbol === tokenB?.symbol && tokenA?.address === tokenB?.address;
331
347
  }
332
348
  function getDefaultToken(sortedTokens, otherToken) {
333
349
  let selectedToken;
@@ -337,7 +353,7 @@ function getDefaultToken(sortedTokens, otherToken) {
337
353
  return selectedToken;
338
354
  }
339
355
  function sortWalletsBasedOnState(wallets) {
340
- return wallets.sort((a, b) => Number(b.state === WalletState.CONNECTED) - Number(a.state === WalletState.CONNECTED) || Number(b.state === WalletState.DISCONNECTED) - Number(a.state === WalletState.DISCONNECTED));
356
+ return wallets.sort((a, b) => Number(b.state === WalletState.CONNECTED) - Number(a.state === WalletState.CONNECTED) || Number(b.state === WalletState.DISCONNECTED || b.state === WalletState.CONNECTING) - Number(a.state === WalletState.DISCONNECTED || a.state === WalletState.CONNECTING));
341
357
  }
342
358
 
343
359
  function getOutputRatio(inputUsdValue, outputUsdValue) {
@@ -405,7 +421,7 @@ function LimitErrorMessage(bestRoute) {
405
421
  recommendation
406
422
  };
407
423
  }
408
- function getSwapButtonState(loadingMetaStatus, accounts, loading, bestRoute, hasLimitError, highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath) {
424
+ function getSwapButtonState(loadingMetaStatus, accounts, loading, bestRoute, hasLimitError, highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath, inputIsZero) {
409
425
  if (loadingMetaStatus !== 'success') return {
410
426
  title: 'Connect Wallet',
411
427
  disabled: true
@@ -417,6 +433,9 @@ function getSwapButtonState(loadingMetaStatus, accounts, loading, bestRoute, has
417
433
  if (loading) return {
418
434
  title: 'Finding Best Route...',
419
435
  disabled: true
436
+ };else if (inputIsZero) return {
437
+ title: 'Enter an amount',
438
+ disabled: true
420
439
  };else if (!bestRoute) return {
421
440
  title: 'Swap',
422
441
  disabled: true
@@ -450,6 +469,7 @@ function calculatePendingSwap(inputAmount, bestRoute, wallets, settings, validat
450
469
  finishTime: null,
451
470
  requestId: bestRoute.requestId || '',
452
471
  inputAmount: inputAmount,
472
+ //@ts-ignore
453
473
  wallets,
454
474
  status: 'running',
455
475
  isPaused: false,
@@ -464,6 +484,7 @@ function calculatePendingSwap(inputAmount, bestRoute, wallets, settings, validat
464
484
  settings: settings,
465
485
  simulationResult: simulationResult,
466
486
  validateBalanceOrFee,
487
+ //@ts-ignore
467
488
  steps: bestRoute.result?.swaps?.map((swap, index) => {
468
489
  const swapper = meta.swappers.find(swapper => swapper.id === swap.swapperId);
469
490
  const swapperType = swapper?.types[0];
@@ -549,11 +570,10 @@ function hasHighFee(totalFeeInUsd) {
549
570
  }
550
571
  function getMinRequiredSlippage(route) {
551
572
  const slippages = route.result?.swaps.map(slippage => slippage.recommendedSlippage);
552
- return slippages?.map(s => parseFloat(s?.slippage || '0'))?.filter(s => s > 0)?.sort((a, b) => b - a)?.find(() => true) || null;
573
+ return slippages?.map(s => s?.slippage || '0')?.filter(s => parseFloat(s) > 0)?.sort((a, b) => parseFloat(b) - parseFloat(a))?.find(() => true) || null;
553
574
  }
554
575
  function hasProperSlippage(userSlippage, minRequiredSlippage) {
555
576
  if (!minRequiredSlippage) return true;
556
- //@ts-ignore
557
577
  return parseFloat(userSlippage) >= parseFloat(minRequiredSlippage);
558
578
  }
559
579
  function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, selectedWallets, disabledLiquiditySources, slippage, checkPrerequisites) {
@@ -566,6 +586,7 @@ function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, se
566
586
  addresses: [wallet.address]
567
587
  });
568
588
  });
589
+ const filteredBlockchains = selectedWallets.map(wallet => wallet.chain);
569
590
  const requestBody = {
570
591
  amount: inputAmount.toString(),
571
592
  checkPrerequisites,
@@ -583,8 +604,10 @@ function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, se
583
604
  selectedWallets: selectedWalletsMap,
584
605
  swapperGroups: disabledLiquiditySources,
585
606
  swappersGroupsExclude: true,
586
- //@ts-ignore
587
- slippage: slippage.toString()
607
+ slippage: slippage.toString(),
608
+ ...(checkPrerequisites && {
609
+ blockchains: filteredBlockchains
610
+ })
588
611
  };
589
612
  return requestBody;
590
613
  }
@@ -626,6 +649,65 @@ function getBalanceWarnings(route, selectedWallets) {
626
649
  return warningMessage;
627
650
  });
628
651
  }
652
+ function calcOutputUsdValue(outputAmount, tokenPrice) {
653
+ const amount = !!outputAmount ? new BigNumber(outputAmount) : ZERO;
654
+ return amount.multipliedBy(tokenPrice || 0);
655
+ }
656
+ function isNetworkStatusInWarningState(pendingSwapStep) {
657
+ return !!pendingSwapStep && pendingSwapStep.networkStatus !== null && pendingSwapStep.networkStatus !== PendingSwapNetworkStatus.NetworkChanged;
658
+ }
659
+ function getSwapMessages(pendingSwap, currentStep) {
660
+ const textForRemove = 'bellow button or';
661
+ let message = pendingSwap.extraMessage;
662
+ let detailedMessage = pendingSwap.extraMessageDetail;
663
+ if (pendingSwap.networkStatusExtraMessageDetail?.includes(textForRemove)) {
664
+ pendingSwap.networkStatusExtraMessageDetail = pendingSwap.networkStatusExtraMessageDetail.replace(textForRemove, '');
665
+ }
666
+ const networkWarningState = isNetworkStatusInWarningState(currentStep);
667
+ if (networkWarningState) {
668
+ message = pendingSwap.networkStatusExtraMessage || '';
669
+ detailedMessage = pendingSwap.networkStatusExtraMessageDetail || '';
670
+ switch (currentStep?.networkStatus) {
671
+ case PendingSwapNetworkStatus.WaitingForConnectingWallet:
672
+ message = message || 'Waiting for connecting wallet';
673
+ break;
674
+ case PendingSwapNetworkStatus.WaitingForQueue:
675
+ message = message || 'Waiting for other running tasks to be finished';
676
+ break;
677
+ case PendingSwapNetworkStatus.WaitingForNetworkChange:
678
+ message = message || 'Waiting for changing wallet network';
679
+ break;
680
+ }
681
+ }
682
+ detailedMessage = detailedMessage || '';
683
+ message = message || '';
684
+ const isRpc = message?.indexOf('code') !== -1 && message?.indexOf('reason') !== -1;
685
+ return {
686
+ shortMessage: message,
687
+ detailedMessage: {
688
+ content: detailedMessage,
689
+ long: isRpc
690
+ }
691
+ };
692
+ }
693
+ function getLastConvertedTokenInFailedSwap(pendingSwap) {
694
+ let resultToken = null;
695
+ if (pendingSwap.status === 'failed') {
696
+ const lastSuccessStep = pendingSwap.steps.slice().reverse().filter(step => step.status === 'success')[0];
697
+ if (lastSuccessStep) {
698
+ resultToken = {
699
+ blockchain: lastSuccessStep.toBlockchain,
700
+ symbol: lastSuccessStep.toSymbol,
701
+ outputAmount: lastSuccessStep.outputAmount,
702
+ address: lastSuccessStep.toSymbolAddress
703
+ };
704
+ }
705
+ }
706
+ return resultToken;
707
+ }
708
+ function shouldRetrySwap(pendingSwap) {
709
+ return pendingSwap.status === 'failed' && !!pendingSwap.finishTime && new Date().getTime() - parseInt(pendingSwap.finishTime) < 4 * 3600 * 1000;
710
+ }
629
711
 
630
712
  function searchParamsToToken(tokens, searchParams, chain) {
631
713
  if (!chain) return null;
@@ -663,22 +745,13 @@ function getRequiredBalanceOfWallet(selectedWallet, fee) {
663
745
  return relatedFeeStatus.requiredAssets;
664
746
  }
665
747
  function isRouteParametersChanged(prevParams, currentParams) {
666
- 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;
667
- }
668
- function getBestRouteWithCalculatedFees(bestRoute, tokens) {
669
- if (!bestRoute || !bestRoute.result) return null;
670
- const swapsWithFee = (bestRoute?.result?.swaps || []).map(swap => ({
671
- ...swap,
672
- feeInUsd: numberToString(getUsdFeeOfStep(swap, tokens), 0, 2)
673
- }));
674
- return {
675
- ...bestRoute,
676
- result: {
677
- ...bestRoute.result,
678
- swaps: swapsWithFee
679
- }
680
- };
748
+ 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);
681
749
  }
750
+ //todo: refactor bestRoute store and add loadingStatus
751
+ const getBestRouteStatus = (loading, error) => {
752
+ if (loading) return 'loading';
753
+ if (error) return 'failed';else return 'success';
754
+ };
682
755
 
683
756
  const createSelectors = _store => {
684
757
  let store = _store;
@@ -829,7 +902,7 @@ const useWalletsStore = /*#__PURE__*/createSelectors( /*#__PURE__*/create()( /*#
829
902
  }
830
903
  });
831
904
  return {
832
- selectedWallets: state.selectedWallets.concat(selectedWallets)
905
+ selectedWallets: selectedWallets
833
906
  };
834
907
  }),
835
908
  setSelectedWallet: wallet => set(state => ({
@@ -861,6 +934,7 @@ useWalletsStore.subscribe(state => state.balances, balances => {
861
934
  }, {
862
935
  equalityFn: shallow
863
936
  });
937
+ const fetchingBalanceSelector = state => !!state.balances.find(wallet => wallet.loading);
864
938
 
865
939
  const getUsdValue = (token, amount) => new BigNumber(amount || ZERO).multipliedBy(token?.usdPrice || 0);
866
940
  const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/create()( /*#__PURE__*/subscribeWithSelector(set => ({
@@ -880,9 +954,10 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/create()( /
880
954
  setBestRoute: bestRoute => set(state => {
881
955
  let outputAmount = null;
882
956
  let outputUsdValue = ZERO;
957
+ if (!state.inputAmount || state.inputAmount === '0') return {};
883
958
  if (!!bestRoute) {
884
959
  outputAmount = !!bestRoute.result?.outputAmount ? new BigNumber(bestRoute.result?.outputAmount) : null;
885
- outputUsdValue = new BigNumber(outputAmount || ZERO).multipliedBy(getBestRouteToTokenUsdPrice(bestRoute) || state.toToken?.usdPrice || 0);
960
+ outputUsdValue = calcOutputUsdValue(bestRoute.result?.outputAmount, getBestRouteToTokenUsdPrice(bestRoute) || state.toToken?.usdPrice);
886
961
  }
887
962
  return {
888
963
  bestRoute,
@@ -936,6 +1011,7 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/create()( /
936
1011
  toToken: token
937
1012
  })),
938
1013
  setInputAmount: amount => {
1014
+ console.log(amount, typeof amount);
939
1015
  set(state => ({
940
1016
  inputAmount: amount,
941
1017
  ...(!amount && {
@@ -947,6 +1023,47 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/create()( /
947
1023
  inputUsdValue: getUsdValue(state.fromToken, amount)
948
1024
  })
949
1025
  }));
1026
+ },
1027
+ retry: pendingSwap => {
1028
+ const {
1029
+ tokens,
1030
+ blockchains
1031
+ } = useMetaStore.getState().meta;
1032
+ const balances = useWalletsStore.getState().balances;
1033
+ const failedIndex = pendingSwap.status === 'failed' ? pendingSwap.steps.findIndex(s => s.status === 'failed') : null;
1034
+ if (failedIndex === null || failedIndex < 0) return;
1035
+ const firstStep = pendingSwap.steps[0];
1036
+ const lastStep = pendingSwap.steps[pendingSwap.steps.length - 1];
1037
+ const fromChain = blockchains.find(blockchain => blockchain.name === firstStep.fromBlockchain) || null;
1038
+ const toChain = blockchains.find(blockchain => blockchain.name === lastStep.toBlockchain) || null;
1039
+ const fromToken = tokens.find(token => tokensAreEqual(token, {
1040
+ blockchain: firstStep.fromBlockchain,
1041
+ symbol: firstStep.fromSymbol,
1042
+ address: firstStep.fromSymbolAddress
1043
+ }));
1044
+ const toToken = tokens.find(token => tokensAreEqual(token, {
1045
+ blockchain: lastStep.toBlockchain,
1046
+ symbol: lastStep.toSymbol,
1047
+ address: lastStep.toSymbolAddress
1048
+ }));
1049
+ const sortedSourceTokens = getSortedTokens(fromChain, tokens, balances, []);
1050
+ const sortedDestinationTokens = getSortedTokens(toChain, tokens, balances, []);
1051
+ const inputAmount = pendingSwap.inputAmount;
1052
+ set({
1053
+ fromChain,
1054
+ fromToken,
1055
+ inputAmount,
1056
+ outputAmount: null,
1057
+ inputUsdValue: getUsdValue(fromToken || null, inputAmount),
1058
+ outputUsdValue: new BigNumber(0),
1059
+ toChain,
1060
+ toToken,
1061
+ bestRoute: null,
1062
+ loading: false,
1063
+ error: '',
1064
+ sourceTokens: sortedSourceTokens,
1065
+ destinationTokens: sortedDestinationTokens
1066
+ });
950
1067
  }
951
1068
  }))));
952
1069
  const bestRoute = (bestRouteStore, settingsStore) => {
@@ -962,12 +1079,12 @@ const bestRoute = (bestRouteStore, settingsStore) => {
962
1079
  customSlippage,
963
1080
  disabledLiquiditySources
964
1081
  } = settingsStore.getState();
965
- if (!fromToken || !toToken || !inputAmount) return;
1082
+ if (!fromToken || !toToken || !inputAmount || inputAmount === '0') return;
966
1083
  abortController?.abort();
967
1084
  abortController = new AbortController();
968
1085
  const userSlippage = !!customSlippage ? customSlippage : slippage;
969
1086
  const requestBody = createBestRouteRequestBody(fromToken, toToken, inputAmount, [], [], disabledLiquiditySources, userSlippage, false);
970
- bestRouteStore.setState({
1087
+ if (!bestRouteStore.getState().loading) bestRouteStore.setState({
971
1088
  loading: true,
972
1089
  bestRoute: null,
973
1090
  outputAmount: null,
@@ -992,13 +1109,36 @@ const bestRoute = (bestRouteStore, settingsStore) => {
992
1109
  });
993
1110
  });
994
1111
  };
1112
+ const debouncedFetchBestRoute = debounce(fetchBestRoute, 600);
1113
+ const bestRouteParamsListener = () => {
1114
+ const {
1115
+ fromToken,
1116
+ toToken,
1117
+ inputAmount,
1118
+ inputUsdValue
1119
+ } = useBestRouteStore.getState();
1120
+ if (!inputAmount || inputAmount === '0') return;
1121
+ if (tokensAreEqual(fromToken, toToken)) return bestRouteStore.setState({
1122
+ loading: false,
1123
+ bestRoute: null,
1124
+ outputAmount: new BigNumber(inputAmount),
1125
+ outputUsdValue: inputUsdValue
1126
+ });
1127
+ if (!bestRouteStore.getState().loading) bestRouteStore.setState({
1128
+ loading: true,
1129
+ bestRoute: null,
1130
+ outputAmount: null,
1131
+ outputUsdValue: new BigNumber(0)
1132
+ });
1133
+ debouncedFetchBestRoute();
1134
+ };
995
1135
  useBestRouteStore.subscribe(state => ({
996
1136
  fromChain: state.fromChain,
997
1137
  fromToken: state.fromToken,
998
1138
  toChain: state.toChain,
999
1139
  toToken: state.toToken,
1000
1140
  inputAmount: state.inputAmount
1001
- }), fetchBestRoute.bind(null), {
1141
+ }), bestRouteParamsListener, {
1002
1142
  equalityFn: (prevState, state) => {
1003
1143
  if (isRouteParametersChanged(prevState, state)) return false;else return true;
1004
1144
  }
@@ -1007,7 +1147,7 @@ const bestRoute = (bestRouteStore, settingsStore) => {
1007
1147
  slippage: state.slippage,
1008
1148
  customSlippage: state.customSlippage,
1009
1149
  disabledLiquiditySources: state.disabledLiquiditySources
1010
- }), fetchBestRoute.bind(null), {
1150
+ }), bestRouteParamsListener, {
1011
1151
  equalityFn: (prevState, state) => {
1012
1152
  if (isRouteParametersChanged(prevState, state)) return false;else return true;
1013
1153
  }
@@ -1032,11 +1172,15 @@ var SearchParams;
1032
1172
  const useUiStore = /*#__PURE__*/createSelectors( /*#__PURE__*/create()(set => ({
1033
1173
  connectWalletsButtonDisabled: false,
1034
1174
  selectedSwapRequestId: null,
1175
+ currentPage: '',
1035
1176
  toggleConnectWalletsButton: () => set(state => ({
1036
1177
  connectWalletsButtonDisabled: !state.connectWalletsButtonDisabled
1037
1178
  })),
1038
1179
  setSelectedSwap: requestId => set({
1039
1180
  selectedSwapRequestId: requestId
1181
+ }),
1182
+ setCurrentPage: path => set({
1183
+ currentPage: path
1040
1184
  })
1041
1185
  })));
1042
1186
 
@@ -1077,7 +1221,7 @@ function UpdateUrl() {
1077
1221
  toChainString = '',
1078
1222
  toTokenString = '',
1079
1223
  fromAmount = '';
1080
- if (loadingStatus !== 'success' && ![navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname)) {
1224
+ if (loadingStatus !== 'success' && location.pathname != navigationRoutes.confirmSwap) {
1081
1225
  fromChainString = searchParamsRef.current[SearchParams.FROM_CHAIN];
1082
1226
  fromTokenString = searchParamsRef.current[SearchParams.FROM_TOKEN];
1083
1227
  toChainString = searchParamsRef.current[SearchParams.TO_CHAIN];
@@ -1170,67 +1314,6 @@ function UpdateUrl() {
1170
1314
  return null;
1171
1315
  }
1172
1316
 
1173
- const ButtonsContainer = /*#__PURE__*/styled('div', {
1174
- display: 'flex'
1175
- });
1176
- function HeaderButtons(props) {
1177
- const {
1178
- onClickRefresh
1179
- } = props;
1180
- const navigate = useNavigate();
1181
- return React.createElement(ButtonsContainer, null, React.createElement(Tooltip, {
1182
- content: "Retry"
1183
- }, React.createElement(Button, {
1184
- variant: "ghost",
1185
- onClick: onClickRefresh
1186
- }, React.createElement(RetryIcon, {
1187
- size: 28
1188
- }))), React.createElement(Tooltip, {
1189
- content: "Transactions History"
1190
- }, React.createElement(Button, {
1191
- variant: "ghost",
1192
- onClick: () => navigate(navigationRoutes.swaps)
1193
- }, React.createElement(HistoryIcon, {
1194
- size: 24
1195
- }))), React.createElement(Tooltip, {
1196
- content: "Settings"
1197
- }, React.createElement(Button, {
1198
- variant: "ghost",
1199
- onClick: () => navigate(navigationRoutes.settings)
1200
- }, React.createElement(SettingsIcon, {
1201
- size: 24
1202
- }))));
1203
- }
1204
-
1205
- const HeaderContainer = /*#__PURE__*/styled('div', {
1206
- display: 'flex',
1207
- justifyContent: 'space-between',
1208
- alignItems: 'center',
1209
- width: '100%',
1210
- padding: '$16 0'
1211
- });
1212
- function Header(props) {
1213
- const {
1214
- onClickRefresh,
1215
- title,
1216
- titleSize,
1217
- titleWeight
1218
- } = props;
1219
- const {
1220
- t
1221
- } = useTranslation();
1222
- const titleStyle = css({
1223
- fontSize: `${titleSize}px !important`,
1224
- fontWeight: `${titleWeight} !important`
1225
- });
1226
- return React.createElement(HeaderContainer, null, React.createElement(Typography, {
1227
- variant: "h4",
1228
- className: titleStyle()
1229
- }, title ? t(title.toLocaleLowerCase()) : ''), React.createElement(HeaderButtons, {
1230
- onClickRefresh: onClickRefresh
1231
- }));
1232
- }
1233
-
1234
1317
  const Box = /*#__PURE__*/styled('div', {
1235
1318
  display: 'flex',
1236
1319
  flexDirection: 'column',
@@ -1238,13 +1321,42 @@ const Box = /*#__PURE__*/styled('div', {
1238
1321
  });
1239
1322
  const Container = /*#__PURE__*/styled('div', {
1240
1323
  boxSizing: 'border-box',
1241
- backgroundColor: '$neutrals300',
1242
1324
  borderRadius: '$5',
1243
- padding: '$8 0',
1325
+ padding: '$8 $16 $16 $16',
1326
+ variants: {
1327
+ type: {
1328
+ filled: {
1329
+ backgroundColor: '$neutrals300'
1330
+ },
1331
+ outlined: {
1332
+ border: '1px solid $neutrals300'
1333
+ }
1334
+ }
1335
+ },
1336
+ defaultVariants: {
1337
+ type: 'filled'
1338
+ },
1339
+ '.head': {
1340
+ display: 'flex',
1341
+ justifyContent: 'space-between',
1342
+ alignItems: 'center',
1343
+ minHeight: '32px'
1344
+ },
1244
1345
  '.form': {
1245
1346
  display: 'flex',
1246
1347
  width: '100%',
1247
- padding: '$8 $16'
1348
+ padding: '$2 0',
1349
+ '.selectors': {
1350
+ width: '35%',
1351
+ '._text': {
1352
+ whiteSpace: 'nowrap',
1353
+ overflow: 'hidden',
1354
+ textOverflow: 'ellipsis'
1355
+ }
1356
+ },
1357
+ '.amount': {
1358
+ width: '30%'
1359
+ }
1248
1360
  }
1249
1361
  });
1250
1362
  const StyledImage = /*#__PURE__*/styled('img', {
@@ -1254,7 +1366,10 @@ const StyledImage = /*#__PURE__*/styled('img', {
1254
1366
  const Options = /*#__PURE__*/styled('div', {
1255
1367
  display: 'flex',
1256
1368
  justifyContent: 'flex-end',
1257
- padding: '0 $8'
1369
+ '.balance': {
1370
+ display: 'flex',
1371
+ alignItems: 'center'
1372
+ }
1258
1373
  });
1259
1374
  const ImagePlaceholder = /*#__PURE__*/styled('span', {
1260
1375
  width: '24px',
@@ -1263,10 +1378,9 @@ const ImagePlaceholder = /*#__PURE__*/styled('span', {
1263
1378
  borderRadius: '99999px'
1264
1379
  });
1265
1380
  const OutputContainer = /*#__PURE__*/styled('div', {
1381
+ windth: '100%',
1266
1382
  height: '$48',
1267
1383
  borderRadius: '$5',
1268
- flexGrow: 1,
1269
- width: '70%',
1270
1384
  backgroundColor: '$background',
1271
1385
  border: '1px solid transparent',
1272
1386
  position: 'relative',
@@ -1306,21 +1420,34 @@ function TokenInfo(props) {
1306
1420
  color: "error",
1307
1421
  size: 24
1308
1422
  }), React.createElement(AngleDownIcon, null));
1309
- return React.createElement(Box, null, React.createElement("div", null, React.createElement(Typography, {
1310
- variant: "body2"
1311
- }, t(type))), React.createElement(Container, null, props.type === 'From' && React.createElement(Options, null, React.createElement("div", {
1423
+ return React.createElement(Box, null, React.createElement(Container, {
1424
+ type: props.type === 'From' ? 'filled' : 'outlined'
1425
+ }, React.createElement("div", {
1426
+ className: "head"
1427
+ }, React.createElement(Typography, {
1428
+ variant: "body2",
1429
+ color: "neutrals800"
1430
+ }, t(type)), props.type === 'From' ? React.createElement(Options, null, React.createElement("div", {
1312
1431
  className: "balance",
1313
1432
  onClick: () => {
1314
1433
  if (tokenBalance !== '0') setInputAmount(tokenBalanceReal.split(',').join(''));
1315
1434
  }
1316
- }, React.createElement(Button, {
1317
- variant: "ghost",
1318
- size: "small"
1319
1435
  }, React.createElement(Typography, {
1320
- variant: "body2"
1321
- }, `${t('Max')}: ${tokenBalance} ${fromToken?.symbol || ''}`)))), React.createElement("div", {
1436
+ variant: "body3",
1437
+ color: "neutrals600"
1438
+ }, `${t('Balance')}: ${tokenBalance} ${fromToken?.symbol || ''}`), React.createElement(Spacer, {
1439
+ size: 4
1440
+ }), React.createElement(Button, {
1441
+ type: "primary",
1442
+ variant: "ghost",
1443
+ size: "compact"
1444
+ }, t('Max')))) : React.createElement(Typography, {
1445
+ variant: "caption",
1446
+ color: "neutrals600"
1447
+ }, `$${numberToString(props.outputUsdValue)}`)), React.createElement("div", {
1322
1448
  className: "form"
1323
1449
  }, React.createElement(Button, {
1450
+ className: "selectors",
1324
1451
  onClick: () => {
1325
1452
  navigate(`/${props.type.toLowerCase()}-chain`);
1326
1453
  },
@@ -1332,11 +1459,11 @@ function TokenInfo(props) {
1332
1459
  }) : React.createElement(ImagePlaceholder, null),
1333
1460
  suffix: ItemSuffix,
1334
1461
  align: "start",
1335
- size: "large",
1336
- style: {
1337
- marginRight: '.5rem'
1338
- }
1339
- }, loadingStatus === 'success' && chain ? chain.displayName : t('Chain')), React.createElement(Button, {
1462
+ size: "large"
1463
+ }, loadingStatus === 'success' && chain ? chain.displayName : t('Chain')), React.createElement(Spacer, {
1464
+ size: 12
1465
+ }), React.createElement(Button, {
1466
+ className: "selectors",
1340
1467
  onClick: () => {
1341
1468
  navigate(`/${props.type.toLowerCase()}-token`);
1342
1469
  },
@@ -1348,17 +1475,17 @@ function TokenInfo(props) {
1348
1475
  }) : React.createElement(ImagePlaceholder, null),
1349
1476
  suffix: ItemSuffix,
1350
1477
  size: "large",
1351
- align: "start",
1352
- style: {
1353
- marginRight: '.5rem'
1354
- }
1355
- }, loadingStatus === 'success' && token ? token.symbol : t('Token')), props.type === 'From' ? React.createElement(TextField, {
1478
+ align: "start"
1479
+ }, loadingStatus === 'success' && token ? token.symbol : t('Token')), React.createElement(Spacer, {
1480
+ size: 12
1481
+ }), React.createElement("div", {
1482
+ className: "amount"
1483
+ }, props.type === 'From' ? React.createElement(TextField, {
1356
1484
  type: "number",
1357
1485
  size: "large",
1358
1486
  autoFocus: true,
1359
1487
  placeholder: "0",
1360
1488
  style: {
1361
- width: '70%',
1362
1489
  position: 'relative',
1363
1490
  backgroundColor: '$background !important'
1364
1491
  },
@@ -1369,23 +1496,16 @@ function TokenInfo(props) {
1369
1496
  bottom: '2px'
1370
1497
  }
1371
1498
  }, React.createElement(Typography, {
1372
- variant: "caption"
1499
+ variant: "caption",
1500
+ color: "neutrals800"
1373
1501
  }, `$${numberToString(inputUsdValue)}`)),
1374
1502
  value: props.inputAmount || '',
1375
1503
  onChange: props.type === 'From' ? event => {
1376
1504
  props.onAmountChange(event.target.value);
1377
1505
  } : undefined
1378
1506
  }) : React.createElement(OutputContainer, null, React.createElement(Typography, {
1379
- variant: "body1"
1380
- }, bestRoute ? `≈ ${numberToString(props.outputAmount)}` : inputAmount ? '?' : '0'), React.createElement("span", {
1381
- style: {
1382
- position: 'absolute',
1383
- right: '4px',
1384
- bottom: '2px'
1385
- }
1386
- }, React.createElement(Typography, {
1387
- variant: "caption"
1388
- }, `$${numberToString(props.outputUsdValue)}`))))));
1507
+ variant: "h4"
1508
+ }, bestRoute ? `≈ ${numberToString(props.outputAmount)}` : inputAmount ? '?' : '0'))))));
1389
1509
  }
1390
1510
 
1391
1511
  const Container$1 = /*#__PURE__*/styled$1('div', {
@@ -1481,18 +1601,52 @@ const errorMessages = {
1481
1601
  genericServerError: 'Error connecting server, please reload the app and try again'
1482
1602
  };
1483
1603
 
1604
+ const ButtonsContainer = /*#__PURE__*/styled('div', {
1605
+ display: 'flex'
1606
+ });
1607
+ function HeaderButtons(props) {
1608
+ const {
1609
+ onClickRefresh
1610
+ } = props;
1611
+ const navigate = useNavigate();
1612
+ return React.createElement(ButtonsContainer, null, React.createElement(Tooltip, {
1613
+ content: "Refresh"
1614
+ }, React.createElement(Button, {
1615
+ variant: "ghost",
1616
+ onClick: onClickRefresh,
1617
+ disabled: !onClickRefresh
1618
+ }, React.createElement(RetryIcon, {
1619
+ size: 24
1620
+ }))), React.createElement(Tooltip, {
1621
+ content: "Transactions History"
1622
+ }, React.createElement(Button, {
1623
+ variant: "ghost",
1624
+ onClick: () => navigate(navigationRoutes.swaps)
1625
+ }, React.createElement(HistoryIcon, {
1626
+ size: 24
1627
+ }))), React.createElement(Tooltip, {
1628
+ content: "Settings"
1629
+ }, React.createElement(Button, {
1630
+ variant: "ghost",
1631
+ onClick: () => navigate(navigationRoutes.settings)
1632
+ }, React.createElement(SettingsIcon, {
1633
+ size: 24
1634
+ }))));
1635
+ }
1636
+
1484
1637
  const Container$2 = /*#__PURE__*/styled('div', {
1485
1638
  display: 'flex',
1486
- flexDirection: 'column',
1487
- justifyContent: 'center',
1488
- alignItems: 'center'
1639
+ flexDirection: 'column'
1489
1640
  });
1490
- const SwitchButtonContainer = /*#__PURE__*/styled('div', {
1491
- display: 'flex',
1492
- justifyContent: 'center',
1493
- alignItems: 'center',
1641
+ const FromContainer = /*#__PURE__*/styled('div', {
1494
1642
  position: 'relative',
1495
- top: '11px'
1643
+ paddingBottom: '$12'
1644
+ });
1645
+ const SwitchButtonContainer = /*#__PURE__*/styled('div', {
1646
+ position: 'absolute',
1647
+ bottom: '-12px',
1648
+ left: '50%',
1649
+ transform: 'translate(-50%, 10%)'
1496
1650
  });
1497
1651
  const BestRouteContainer = /*#__PURE__*/styled('div', {
1498
1652
  width: '100%',
@@ -1504,11 +1658,8 @@ const Alerts = /*#__PURE__*/styled('div', {
1504
1658
  });
1505
1659
  function Home(props) {
1506
1660
  const {
1507
- title = 'SWAP',
1508
- titleSize = 18,
1509
- titleWeight = 600
1661
+ title = 'SWAP'
1510
1662
  } = props;
1511
- const waningMessage = '';
1512
1663
  const isRouterInContext = useInRouterContext();
1513
1664
  const navigate = useNavigate();
1514
1665
  const [count, setCount] = useState(0);
@@ -1531,6 +1682,7 @@ function Home(props) {
1531
1682
  const bestRouteError = useBestRouteStore.use.error();
1532
1683
  const loadingMetaStatus = useMetaStore.use.loadingStatus();
1533
1684
  const accounts = useWalletsStore.use.accounts();
1685
+ const setCurrentPage = useUiStore.use.setCurrentPage();
1534
1686
  const swithFromAndTo = () => {
1535
1687
  setFromChain(toChain);
1536
1688
  setFromToken(toToken);
@@ -1550,15 +1702,20 @@ function Home(props) {
1550
1702
  swap
1551
1703
  } = LimitErrorMessage(bestRoute);
1552
1704
  const priceImpactCanNotBeComputed = !canComputePriceImpact(bestRoute, inputAmount, inputUsdValue, outputUsdValue);
1553
- const swapButtonState = getSwapButtonState(loadingMetaStatus, accounts, fetchingBestRoute, bestRoute, hasLimitError(bestRoute), highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath);
1705
+ const inputIsZero = inputAmount === '0';
1706
+ const swapButtonState = getSwapButtonState(loadingMetaStatus, accounts, fetchingBestRoute, bestRoute, hasLimitError(bestRoute), highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath, inputIsZero);
1554
1707
  const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
1555
1708
  const highFee = hasHighFee(totalFeeInUsd);
1556
- return React.createElement(Container$2, null, React.createElement(Header, {
1709
+ useEffect(() => {
1710
+ setCurrentPage(navigationRoutes.home);
1711
+ return setCurrentPage.bind(null, '');
1712
+ }, []);
1713
+ return React.createElement(Container$2, null, React.createElement(Header$1, {
1557
1714
  title: title,
1558
- titleSize: titleSize,
1559
- titleWeight: titleWeight,
1560
- onClickRefresh: fetchBestRoute
1561
- }), React.createElement(TokenInfo, {
1715
+ suffix: React.createElement(HeaderButtons, {
1716
+ onClickRefresh: !!bestRoute ? fetchBestRoute : undefined
1717
+ })
1718
+ }), React.createElement(FromContainer, null, React.createElement(TokenInfo, {
1562
1719
  type: "From",
1563
1720
  chain: fromChain,
1564
1721
  token: fromToken,
@@ -1568,14 +1725,14 @@ function Home(props) {
1568
1725
  variant: "ghost",
1569
1726
  onClick: swithFromAndTo
1570
1727
  }, React.createElement(VerticalSwapIcon, {
1571
- size: 36
1728
+ size: 32
1572
1729
  }), isRouterInContext && React.createElement(SwithFromAndTo, {
1573
1730
  count: count
1574
- }))), React.createElement(TokenInfo, {
1731
+ })))), React.createElement(TokenInfo, {
1575
1732
  type: "To",
1576
1733
  chain: toChain,
1577
1734
  token: toToken,
1578
- outputAmount: outputAmount,
1735
+ outputAmount: outputAmount ? new BigNumber(outputAmount) : new BigNumber(0),
1579
1736
  outputUsdValue: outputUsdValue
1580
1737
  }), showBestRoute && React.createElement(BestRouteContainer, null, React.createElement(BestRoute, {
1581
1738
  error: bestRouteError,
@@ -1584,11 +1741,9 @@ function Home(props) {
1584
1741
  totalFee: numberToString(totalFeeInUsd, 0, 2),
1585
1742
  feeWarning: highFee,
1586
1743
  totalTime: secondsToString(totalArrivalTime(bestRoute))
1587
- })), (errorMessage || waningMessage || hasLimitError(bestRoute)) && React.createElement(Alerts, null, errorMessage && React.createElement(Alert, {
1744
+ })), (errorMessage || hasLimitError(bestRoute)) && React.createElement(Alerts, null, errorMessage && React.createElement(Alert, {
1588
1745
  type: "error"
1589
- }, React.createElement(Typography, {
1590
- variant: "body2"
1591
- }, errorMessage)), hasLimitError(bestRoute) && React.createElement(Alert, {
1746
+ }, errorMessage), hasLimitError(bestRoute) && React.createElement(Alert, {
1592
1747
  type: "error",
1593
1748
  title: `${swap?.swapperId} Limit`
1594
1749
  }, React.createElement(React.Fragment, null, React.createElement(Typography, {
@@ -1597,14 +1752,14 @@ function Home(props) {
1597
1752
  variant: "body2"
1598
1753
  }, "Yours: ", numberToString(swap?.fromAmount || null), swap?.from.symbol), React.createElement("br", null), React.createElement(Typography, {
1599
1754
  variant: "body2"
1600
- }, recommendation))), waningMessage ), React.createElement(Footer, null, React.createElement(Button, {
1755
+ }, recommendation)))), React.createElement(Footer, null, React.createElement(Button, {
1601
1756
  type: "primary",
1602
1757
  align: "grow",
1603
1758
  size: "large",
1604
1759
  disabled: swapButtonState.disabled,
1605
1760
  onClick: () => {
1606
1761
  if (swapButtonState.title === 'Connect Wallet') navigate(navigationRoutes.wallets);else {
1607
- navigate(navigationRoutes.confirmWallets, {
1762
+ navigate(navigationRoutes.confirmSwap, {
1608
1763
  replace: true
1609
1764
  });
1610
1765
  }
@@ -1621,12 +1776,12 @@ const Route = _ref => {
1621
1776
  const navigate = useNavigate$1();
1622
1777
  const ref = useRef(true);
1623
1778
  useEffect(() => {
1624
- if ([navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname) && ref.current) navigate(navigationRoutes.home + location.search, {
1779
+ if (location.pathname === navigationRoutes.confirmSwap && ref.current) navigate(navigationRoutes.home + location.search, {
1625
1780
  state: 'redirect'
1626
1781
  });
1627
1782
  ref.current = false;
1628
1783
  }, []);
1629
- if ([navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname) && ref.current) return React.createElement(Home, Object.assign({}, props));
1784
+ if (location.pathname === navigationRoutes.confirmSwap && ref.current) return React.createElement(Home, Object.assign({}, props));
1630
1785
  return React.createElement(React.Fragment, null, " ", children);
1631
1786
  };
1632
1787
  function AppRouter(_ref2) {
@@ -1636,56 +1791,34 @@ function AppRouter(_ref2) {
1636
1791
  } = _ref2;
1637
1792
  const isRouterInContext = useInRouterContext$1();
1638
1793
  const Router = isRouterInContext ? Route : MemoryRouter;
1639
- return React.createElement(React.Fragment, null, React.createElement(Router, Object.assign({}, props), children), isRouterInContext && React.createElement(UpdateUrl, null));
1640
- }
1641
-
1642
- const StyledButton = /*#__PURE__*/styled(Button, {
1643
- marginTop: '$8'
1644
- });
1645
- function ChangeSlippageButton() {
1646
- const navigate = useNavigate();
1647
- return React.createElement(StyledButton, {
1648
- type: "primary",
1649
- variant: "contained",
1650
- size: "small",
1651
- onClick: () => navigate(navigationRoutes.settings)
1652
- }, "Change Slippage");
1653
- }
1654
-
1655
- function HighSlippageWarning(props) {
1656
- const {
1657
- selectedSlippage
1658
- } = props;
1659
- return React.createElement(Alert, {
1660
- type: "warning"
1661
- }, React.createElement(Typography, {
1662
- variant: "body2"
1663
- }, "Caution, your slippage is high (=", selectedSlippage, "). Your trade may be front run.", React.createElement(ChangeSlippageButton, null)));
1664
- }
1665
-
1666
- function ConfirmSwapExtraMessages(props) {
1667
1794
  const {
1668
- selectedSlippage
1669
- } = props;
1670
- const highSlippage = selectedSlippage >= HIGH_SLIPPAGE;
1671
- return React.createElement(React.Fragment, null, highSlippage && React.createElement(HighSlippageWarning, {
1672
- selectedSlippage: selectedSlippage
1673
- }));
1795
+ blockchains
1796
+ } = useMetaStore.use.meta();
1797
+ const evmChains = blockchains.filter(isEvmBlockchain);
1798
+ useQueueManager({
1799
+ lastConnectedWallet: props.lastConnectedWallet,
1800
+ clearDisconnectedWallet: props.clearDisconnectedWallet,
1801
+ disconnectedWallet: props.disconnectedWallet,
1802
+ evmChains,
1803
+ notifier: () => {}
1804
+ });
1805
+ return React.createElement(React.Fragment, null, React.createElement(Router, Object.assign({}, props), children), isRouterInContext && React.createElement(UpdateUrl, null));
1674
1806
  }
1675
1807
 
1676
1808
  function useNavigateBack() {
1677
1809
  const isRouterInContext = useInRouterContext();
1678
1810
  const navigate = useNavigate();
1679
1811
  const navigateBackFrom = currentRoute => {
1812
+ if (currentRoute === navigationRoutes.swapDetails) return navigate(navigationRoutes.swaps, {
1813
+ replace: true
1814
+ });
1680
1815
  if (!isRouterInContext || window.history.state && window.history.state.idx > 0) navigate(-1);else {
1681
- if ([navigationRoutes.fromChain, navigationRoutes.fromToken, navigationRoutes.toChain, navigationRoutes.toToken, navigationRoutes.settings, navigationRoutes.wallets, navigationRoutes.swaps, navigationRoutes.confirmWallets].includes(currentRoute)) navigate(navigationRoutes.home, {
1816
+ if ([navigationRoutes.fromChain, navigationRoutes.fromToken, navigationRoutes.toChain, navigationRoutes.toToken, navigationRoutes.settings, navigationRoutes.wallets, navigationRoutes.swaps, navigationRoutes.confirmSwap].includes(currentRoute)) navigate(navigationRoutes.home, {
1682
1817
  replace: true
1683
1818
  });else if (currentRoute === navigationRoutes.liquiditySources) navigate(navigationRoutes.settings, {
1684
1819
  replace: true
1685
1820
  });else if (currentRoute === navigationRoutes.swapDetails) navigate(navigationRoutes.swaps, {
1686
1821
  replace: true
1687
- });else if (currentRoute === navigationRoutes.confirmSwap) navigate(navigationRoutes.confirmWallets, {
1688
- replace: true
1689
1822
  });
1690
1823
  }
1691
1824
  };
@@ -1694,122 +1827,192 @@ function useNavigateBack() {
1694
1827
  };
1695
1828
  }
1696
1829
 
1697
- var ConfirmSwapErrorTypes;
1698
- (function (ConfirmSwapErrorTypes) {
1699
- ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["NO_ROUTE"] = 0] = "NO_ROUTE";
1700
- ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS"] = 1] = "ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS";
1701
- ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["REQUEST_FAILED"] = 2] = "REQUEST_FAILED";
1702
- ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["INSUFFICIENT_SLIPPAGE"] = 3] = "INSUFFICIENT_SLIPPAGE";
1703
- })(ConfirmSwapErrorTypes || (ConfirmSwapErrorTypes = {}));
1704
- var ConfirmSwapWarningTypes;
1705
- (function (ConfirmSwapWarningTypes) {
1706
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_UPDATED"] = 0] = "ROUTE_UPDATED";
1707
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_SWAPPERS_UPDATED"] = 1] = "ROUTE_SWAPPERS_UPDATED";
1708
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_COINS_UPDATED"] = 2] = "ROUTE_COINS_UPDATED";
1709
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_AND_OUTPUT_AMOUNT_UPDATED"] = 3] = "ROUTE_AND_OUTPUT_AMOUNT_UPDATED";
1710
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["INSUFFICIENT_BALANCE"] = 4] = "INSUFFICIENT_BALANCE";
1711
- })(ConfirmSwapWarningTypes || (ConfirmSwapWarningTypes = {}));
1712
-
1713
- function MinRequiredSlippage(_ref) {
1714
- let {
1715
- minRequiredSlippage
1716
- } = _ref;
1717
- return React.createElement(Typography, {
1718
- variant: "body2"
1719
- }, "We recommend you to increase slippage to at least \u00A0", minRequiredSlippage, "\u00A0 for this route.", React.createElement(ChangeSlippageButton, null));
1720
- }
1721
-
1722
- function ConfirmSwapErrors(errors) {
1723
- return errors.flatMap(error => {
1724
- switch (error.type) {
1725
- case ConfirmSwapErrorTypes.NO_ROUTE:
1726
- return React.createElement(Typography, {
1727
- variant: "body2"
1728
- }, "No routes found. Please try again later.");
1729
- case ConfirmSwapErrorTypes.REQUEST_FAILED:
1730
- return React.createElement(Typography, {
1731
- variant: "body2"
1732
- }, `Failed to confirm swap ${error.status ? `'status': ${error.status})` : ''}, please try again.`);
1733
- case ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS:
1734
- return React.createElement(Typography, {
1735
- variant: "body2"
1736
- }, "Route updated and price impact is too high, try again later!");
1737
- case ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE:
1738
- return React.createElement(MinRequiredSlippage, {
1739
- minRequiredSlippage: error.minRequiredSlippage
1740
- });
1741
- default:
1742
- return [];
1830
+ const Box$1 = /*#__PURE__*/styled('div', {
1831
+ display: 'flex',
1832
+ flexDirection: 'column',
1833
+ width: '100%'
1834
+ });
1835
+ const Container$3 = /*#__PURE__*/styled('div', {
1836
+ boxSizing: 'border-box',
1837
+ borderRadius: '$5',
1838
+ padding: '$8 $16 $16 $16',
1839
+ variants: {
1840
+ type: {
1841
+ filled: {
1842
+ backgroundColor: '$neutrals300'
1843
+ },
1844
+ outlined: {
1845
+ border: '1px solid $neutrals300'
1846
+ }
1743
1847
  }
1744
- });
1745
- }
1746
-
1747
- const List = /*#__PURE__*/styled('ul', {
1748
- variants: {
1749
- showListStyle: {
1750
- true: {
1751
- paddingLeft: '$24'
1848
+ },
1849
+ defaultVariants: {
1850
+ type: 'filled'
1851
+ },
1852
+ '.head': {
1853
+ display: 'flex',
1854
+ justifyContent: 'space-between',
1855
+ alignItems: 'center',
1856
+ minHeight: '32px'
1857
+ },
1858
+ '.form': {
1859
+ display: 'flex',
1860
+ width: '100%',
1861
+ padding: '$2 0',
1862
+ '.selectors': {
1863
+ width: '35%',
1864
+ '._text': {
1865
+ whiteSpace: 'nowrap',
1866
+ overflow: 'hidden',
1867
+ textOverflow: 'ellipsis'
1752
1868
  }
1869
+ },
1870
+ '.amount': {
1871
+ width: '30%'
1753
1872
  }
1754
1873
  }
1755
1874
  });
1756
- const ListItem = /*#__PURE__*/styled('li', {
1757
- variants: {
1758
- showListStyle: {
1759
- true: {
1760
- listStyleType: 'disc',
1761
- listStylePosition: 'outside'
1762
- }
1763
- }
1764
- }
1875
+ const StyledImage$1 = /*#__PURE__*/styled('img', {
1876
+ width: '$24',
1877
+ maxHeight: '$24'
1765
1878
  });
1766
- const Message = /*#__PURE__*/styled(Typography, {
1767
- display: 'block'
1879
+ const ImagePlaceholder$1 = /*#__PURE__*/styled('span', {
1880
+ width: '24px',
1881
+ height: '24px',
1882
+ backgroundColor: '$neutrals300',
1883
+ borderRadius: '99999px'
1768
1884
  });
1769
- function BalanceWarnings(_ref) {
1770
- let {
1771
- messages
1772
- } = _ref;
1773
- const showListStyle = messages.length > 1;
1774
- return React.createElement(List, {
1775
- showListStyle: showListStyle
1776
- }, messages.map(warning => React.createElement(ListItem, {
1777
- showListStyle: showListStyle
1778
- }, React.createElement(Message, {
1779
- variant: "body2"
1780
- }, warning))));
1885
+ const OutputContainer$1 = /*#__PURE__*/styled('div', {
1886
+ windth: '100%',
1887
+ height: '$48',
1888
+ borderRadius: '$5',
1889
+ backgroundColor: '$background',
1890
+ border: '1px solid transparent',
1891
+ position: 'relative',
1892
+ display: 'flex',
1893
+ alignItems: 'center',
1894
+ paddingLeft: '$8',
1895
+ paddingRight: '$8'
1896
+ });
1897
+ function TokenPreview(props) {
1898
+ const {
1899
+ chain,
1900
+ token,
1901
+ loadingStatus
1902
+ } = props;
1903
+ const {
1904
+ t
1905
+ } = useTranslation();
1906
+ const ItemSuffix = React.createElement("div", {
1907
+ style: {
1908
+ display: 'flex',
1909
+ justifyContent: 'center',
1910
+ alignItems: 'center'
1911
+ }
1912
+ }, loadingStatus === 'failed' && React.createElement(InfoCircleIcon, {
1913
+ color: "error",
1914
+ size: 24
1915
+ }));
1916
+ return React.createElement(Box$1, null, React.createElement(Container$3, {
1917
+ type: 'outlined'
1918
+ }, React.createElement("div", {
1919
+ className: "head"
1920
+ }, React.createElement(Typography, {
1921
+ variant: "body2",
1922
+ color: "neutrals800"
1923
+ }, props.label), props.usdValue && React.createElement(Typography, {
1924
+ variant: "caption",
1925
+ color: "neutrals600"
1926
+ }, `$${numberToString(props.usdValue)}`)), React.createElement("div", {
1927
+ className: "form"
1928
+ }, React.createElement(Button, {
1929
+ className: "selectors",
1930
+ variant: "outlined",
1931
+ loading: loadingStatus === 'loading',
1932
+ prefix: loadingStatus === 'success' && chain ? React.createElement(StyledImage$1, {
1933
+ src: chain.logo
1934
+ }) : React.createElement(ImagePlaceholder$1, null),
1935
+ suffix: ItemSuffix,
1936
+ align: "start",
1937
+ size: "large"
1938
+ }, loadingStatus === 'success' && chain ? chain.displayName : t('Chain')), React.createElement(Spacer, {
1939
+ size: 12
1940
+ }), React.createElement(Button, {
1941
+ className: "selectors",
1942
+ variant: "outlined",
1943
+ loading: loadingStatus === 'loading',
1944
+ prefix: loadingStatus === 'success' && token ? React.createElement(StyledImage$1, {
1945
+ src: token.image
1946
+ }) : React.createElement(ImagePlaceholder$1, null),
1947
+ suffix: ItemSuffix,
1948
+ size: "large",
1949
+ align: "start"
1950
+ }, loadingStatus === 'success' && token ? token.symbol : t('Token')), React.createElement(Spacer, {
1951
+ size: 12
1952
+ }), React.createElement("div", {
1953
+ className: "amount"
1954
+ }, React.createElement(OutputContainer$1, null, React.createElement(Typography, {
1955
+ variant: "h4"
1956
+ }, props.amount))))));
1781
1957
  }
1782
1958
 
1783
- function ConfirmSwapWarnings(warnings) {
1784
- return warnings.flatMap(warning => {
1785
- switch (warning.type) {
1786
- case ConfirmSwapWarningTypes.ROUTE_UPDATED:
1787
- return React.createElement(Typography, {
1788
- variant: "body2"
1789
- }, "Route has been updated.");
1790
- case ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED:
1791
- return React.createElement(Typography, {
1792
- variant: "body2"
1793
- }, `Output amount changed to ${warning.newOutputAmount}
1794
- (${warning.percentageChange}% change).`);
1795
- case ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED:
1796
- return React.createElement(Typography, {
1797
- variant: "body2"
1798
- }, "Route swappers has been updated.");
1799
- case ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED:
1800
- return React.createElement(Typography, {
1801
- variant: "body2"
1802
- }, "Route internal coins has been updated.");
1803
- case ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE:
1804
- return React.createElement(BalanceWarnings, {
1805
- messages: warning.messages
1806
- });
1807
- default:
1808
- return [];
1809
- }
1810
- });
1959
+ const Container$4 = /*#__PURE__*/styled('div', {
1960
+ display: 'flex',
1961
+ alignItems: 'center',
1962
+ justifyContent: 'space-between',
1963
+ padding: '$8',
1964
+ borderRadius: '$5',
1965
+ backgroundColor: '$neutrals300',
1966
+ color: '$neutrals800',
1967
+ fontSize: '$12',
1968
+ '.routes': {
1969
+ display: 'flex',
1970
+ alignItems: 'center'
1971
+ },
1972
+ '.fee': {
1973
+ display: 'flex',
1974
+ alignItems: 'center'
1975
+ }
1976
+ });
1977
+ function RoutesOverview(props) {
1978
+ if (!props.routes) return null;
1979
+ const swaps = props.routes.result?.swaps;
1980
+ return React.createElement(Container$4, null, React.createElement("div", {
1981
+ className: "routes"
1982
+ }, swaps?.map((swap, idx) => {
1983
+ const isLast = idx + 1 == swaps.length;
1984
+ return React.createElement(React.Fragment, null, React.createElement("div", {
1985
+ className: "route"
1986
+ }, swap.from.symbol), React.createElement(ChevronRightIcon, {
1987
+ size: 12
1988
+ }), isLast ? React.createElement("div", {
1989
+ className: "route"
1990
+ }, swap.to.symbol) : null);
1991
+ })), props.totalFee ? React.createElement("div", {
1992
+ className: "fee"
1993
+ }, React.createElement(GasIcon, {
1994
+ size: 12
1995
+ }), React.createElement(Spacer, {
1996
+ size: 4
1997
+ }), "$", props.totalFee) : null);
1811
1998
  }
1812
1999
 
2000
+ var ConfirmSwapErrorTypes;
2001
+ (function (ConfirmSwapErrorTypes) {
2002
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["NO_ROUTE"] = 0] = "NO_ROUTE";
2003
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS"] = 1] = "ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS";
2004
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["REQUEST_FAILED"] = 2] = "REQUEST_FAILED";
2005
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["INSUFFICIENT_SLIPPAGE"] = 3] = "INSUFFICIENT_SLIPPAGE";
2006
+ })(ConfirmSwapErrorTypes || (ConfirmSwapErrorTypes = {}));
2007
+ var ConfirmSwapWarningTypes;
2008
+ (function (ConfirmSwapWarningTypes) {
2009
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_UPDATED"] = 0] = "ROUTE_UPDATED";
2010
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_SWAPPERS_UPDATED"] = 1] = "ROUTE_SWAPPERS_UPDATED";
2011
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_COINS_UPDATED"] = 2] = "ROUTE_COINS_UPDATED";
2012
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_AND_OUTPUT_AMOUNT_UPDATED"] = 3] = "ROUTE_AND_OUTPUT_AMOUNT_UPDATED";
2013
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["INSUFFICIENT_BALANCE"] = 4] = "INSUFFICIENT_BALANCE";
2014
+ })(ConfirmSwapWarningTypes || (ConfirmSwapWarningTypes = {}));
2015
+
1813
2016
  function useConfirmSwap() {
1814
2017
  const fromToken = useBestRouteStore.use.fromToken();
1815
2018
  const toToken = useBestRouteStore.use.toToken();
@@ -1850,6 +2053,7 @@ function useConfirmSwap() {
1850
2053
  proceedAnywayRef.current = false;
1851
2054
  if (confiremedRouteRef.current) {
1852
2055
  const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRouteRef.current, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
2056
+ //@ts-ignore
1853
2057
  return newSwap;
1854
2058
  }
1855
2059
  return;
@@ -1912,6 +2116,7 @@ function useConfirmSwap() {
1912
2116
  disabledSwappersGroups: disabledLiquiditySources
1913
2117
  };
1914
2118
  const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRoute, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
2119
+ //@ts-ignore
1915
2120
  return newSwap;
1916
2121
  } else if (!proceedAnywayRef.current) {
1917
2122
  proceedAnywayRef.current = true;
@@ -1941,31 +2146,196 @@ function useConfirmSwap() {
1941
2146
  };
1942
2147
  }
1943
2148
 
2149
+ function ChangeSlippageButton() {
2150
+ const navigate = useNavigate();
2151
+ return React.createElement(Button, {
2152
+ type: "primary",
2153
+ variant: "outlined",
2154
+ size: "small",
2155
+ onClick: () => navigate(navigationRoutes.settings)
2156
+ }, "Change Slippage");
2157
+ }
2158
+
2159
+ const StyledMessage = /*#__PURE__*/styled(Typography, {
2160
+ color: '$error500 !important'
2161
+ });
2162
+ function MinRequiredSlippage(_ref) {
2163
+ let {
2164
+ minRequiredSlippage
2165
+ } = _ref;
2166
+ return React.createElement(StyledMessage, {
2167
+ variant: "body2"
2168
+ }, "We recommend you to increase slippage to at least \u00A0", minRequiredSlippage, "\u00A0 for this route.", React.createElement(Spacer, {
2169
+ size: 8,
2170
+ direction: "vertical"
2171
+ }), React.createElement(ChangeSlippageButton, null));
2172
+ }
2173
+
2174
+ function ConfirmSwapErrors(errors) {
2175
+ return errors.flatMap(error => {
2176
+ switch (error.type) {
2177
+ case ConfirmSwapErrorTypes.NO_ROUTE:
2178
+ return React.createElement(Typography, {
2179
+ variant: "body2"
2180
+ }, "No routes found. Please try again later.");
2181
+ case ConfirmSwapErrorTypes.REQUEST_FAILED:
2182
+ return React.createElement(Typography, {
2183
+ variant: "body2"
2184
+ }, `Failed to confirm swap ${error.status ? `'status': ${error.status})` : ''}, please try again.`);
2185
+ case ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS:
2186
+ return React.createElement(Typography, {
2187
+ variant: "body2"
2188
+ }, "Route updated and price impact is too high, try again later!");
2189
+ case ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE:
2190
+ return React.createElement(MinRequiredSlippage, {
2191
+ minRequiredSlippage: error.minRequiredSlippage
2192
+ });
2193
+ default:
2194
+ return [];
2195
+ }
2196
+ });
2197
+ }
2198
+
2199
+ const List = /*#__PURE__*/styled('ul', {
2200
+ variants: {
2201
+ showListStyle: {
2202
+ true: {
2203
+ paddingLeft: '$24'
2204
+ }
2205
+ }
2206
+ }
2207
+ });
2208
+ const ListItem = /*#__PURE__*/styled('li', {
2209
+ variants: {
2210
+ showListStyle: {
2211
+ true: {
2212
+ listStyleType: 'disc',
2213
+ listStylePosition: 'outside'
2214
+ }
2215
+ }
2216
+ }
2217
+ });
2218
+ const Message = /*#__PURE__*/styled(Typography, {
2219
+ display: 'block',
2220
+ color: '$warning500 !important'
2221
+ });
2222
+ function BalanceWarnings(_ref) {
2223
+ let {
2224
+ messages
2225
+ } = _ref;
2226
+ const showListStyle = messages.length > 1;
2227
+ return React.createElement(List, {
2228
+ showListStyle: showListStyle
2229
+ }, messages.map(warning => React.createElement(ListItem, {
2230
+ showListStyle: showListStyle
2231
+ }, React.createElement(Message, {
2232
+ variant: "body2"
2233
+ }, warning))));
2234
+ }
2235
+
2236
+ function ConfirmSwapWarnings(warnings) {
2237
+ return warnings.flatMap(warning => {
2238
+ switch (warning.type) {
2239
+ case ConfirmSwapWarningTypes.ROUTE_UPDATED:
2240
+ return React.createElement(Typography, {
2241
+ variant: "body2"
2242
+ }, "Route has been updated.");
2243
+ case ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED:
2244
+ return React.createElement(Typography, {
2245
+ variant: "body2"
2246
+ }, `Output amount changed to ${warning.newOutputAmount}
2247
+ (${warning.percentageChange}% change).`);
2248
+ case ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED:
2249
+ return React.createElement(Typography, {
2250
+ variant: "body2"
2251
+ }, "Route swappers has been updated.");
2252
+ case ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED:
2253
+ return React.createElement(Typography, {
2254
+ variant: "body2"
2255
+ }, "Route internal coins has been updated.");
2256
+ case ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE:
2257
+ return React.createElement(BalanceWarnings, {
2258
+ messages: warning.messages
2259
+ });
2260
+ default:
2261
+ return [];
2262
+ }
2263
+ });
2264
+ }
2265
+
2266
+ function HighSlippageWarning(props) {
2267
+ const {
2268
+ selectedSlippage
2269
+ } = props;
2270
+ return React.createElement(Alert, {
2271
+ type: "warning",
2272
+ footer: React.createElement(ChangeSlippageButton, null)
2273
+ }, "Caution, your slippage is high (=", selectedSlippage, "). Your trade may be front run.");
2274
+ }
2275
+
2276
+ function ConfirmSwapExtraMessages(props) {
2277
+ const {
2278
+ selectedSlippage
2279
+ } = props;
2280
+ const highSlippage = selectedSlippage >= HIGH_SLIPPAGE;
2281
+ return React.createElement(React.Fragment, null, highSlippage && React.createElement(HighSlippageWarning, {
2282
+ selectedSlippage: selectedSlippage
2283
+ }));
2284
+ }
2285
+
1944
2286
  function ConfirmSwapPage() {
1945
- const setSelectedSwap = useUiStore.use.setSelectedSwap();
2287
+ const navigate = useNavigate();
1946
2288
  const {
1947
2289
  navigateBackFrom
1948
2290
  } = useNavigateBack();
1949
- const {
1950
- manager
1951
- } = useManager();
1952
- const navigate = useNavigate();
1953
2291
  const bestRoute = useBestRouteStore.use.bestRoute();
1954
2292
  const fetchingBestRoute = useBestRouteStore.use.loading();
2293
+ const fetchingBestRouteError = useBestRouteStore.use.error();
2294
+ const setSelectedSwap = useUiStore.use.setSelectedSwap();
1955
2295
  const {
2296
+ blockchains,
1956
2297
  tokens
1957
2298
  } = useMetaStore.use.meta();
2299
+ const accounts = useWalletsStore.use.accounts();
2300
+ const selectedWallets = useWalletsStore.use.selectedWallets();
2301
+ const initSelectedWallets = useWalletsStore.use.initSelectedWallets();
2302
+ const setSelectedWallet = useWalletsStore.use.setSelectedWallet();
1958
2303
  const slippage = useSettingsStore.use.slippage();
1959
2304
  const customSlippage = useSettingsStore.use.customSlippage();
1960
- const selectedSlippage = customSlippage || slippage;
2305
+ const bestRouteloadingStatus = getBestRouteStatus(fetchingBestRoute, !!fetchingBestRouteError);
2306
+ const {
2307
+ manager
2308
+ } = useManager();
1961
2309
  const {
1962
2310
  loading,
1963
2311
  errors,
1964
2312
  warnings,
1965
2313
  confirmSwap
1966
2314
  } = useConfirmSwap();
2315
+ const selectedSlippage = customSlippage || slippage;
1967
2316
  const showHighSlippageWarning = !errors.find(error => error.type === ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE);
2317
+ const {
2318
+ getWalletInfo,
2319
+ connect
2320
+ } = useWallets();
2321
+ const confirmDisabled = fetchingBestRoute || !requiredWallets(bestRoute).every(chain => selectedWallets.map(wallet => wallet.chain).includes(chain));
2322
+ const firstStep = bestRoute?.result?.swaps[0];
2323
+ const lastStep = bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1];
2324
+ const fromAmount = decimalNumber(firstStep?.fromAmount, 3);
2325
+ const toAmount = decimalNumber(lastStep?.toAmount, 3);
2326
+ useEffect(() => {
2327
+ initSelectedWallets();
2328
+ }, []);
2329
+ const selectableWallets = getSelectableWallets(accounts, selectedWallets, getWalletInfo);
2330
+ const handleConnectChain = wallet => {
2331
+ const network = wallet;
2332
+ getKeplrCompatibleConnectedWallets(selectableWallets).forEach(compatibleWallet => connect?.(compatibleWallet, network));
2333
+ };
2334
+ const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
1968
2335
  return React.createElement(ConfirmSwap, {
2336
+ requiredWallets: getRequiredChains(bestRoute),
2337
+ selectableWallets: selectableWallets,
2338
+ onBack: navigateBackFrom.bind(null, navigationRoutes.confirmSwap),
1969
2339
  onConfirm: () => {
1970
2340
  confirmSwap?.().then(swap => {
1971
2341
  if (swap) {
@@ -1981,16 +2351,51 @@ function ConfirmSwapPage() {
1981
2351
  }
1982
2352
  });
1983
2353
  },
1984
- onBack: navigateBackFrom.bind(null, navigationRoutes.confirmSwap),
1985
- bestRoute: getBestRouteWithCalculatedFees(bestRoute, tokens),
2354
+ onChange: wallet => setSelectedWallet(wallet),
2355
+ confirmDisabled: confirmDisabled,
2356
+ handleConnectChain: wallet => handleConnectChain(wallet),
2357
+ isExperimentalChain: wallet => getKeplrCompatibleConnectedWallets(selectableWallets).length > 0 ? isExperimentalChain(blockchains, wallet) : false,
2358
+ previewInputs: React.createElement(React.Fragment, null, React.createElement(TokenPreview, {
2359
+ chain: {
2360
+ displayName: firstStep?.from.blockchain || '',
2361
+ logo: firstStep?.from.blockchainLogo || ''
2362
+ },
2363
+ token: {
2364
+ symbol: firstStep?.from.symbol || '',
2365
+ image: firstStep?.from.logo || ''
2366
+ },
2367
+ usdValue: calcOutputUsdValue(fromAmount, firstStep?.from.usdPrice),
2368
+ amount: fromAmount,
2369
+ label: t('From'),
2370
+ loadingStatus: bestRouteloadingStatus
2371
+ }), React.createElement(Spacer, {
2372
+ size: 12,
2373
+ direction: "vertical"
2374
+ }), React.createElement(TokenPreview, {
2375
+ chain: {
2376
+ displayName: lastStep?.to.blockchain || '',
2377
+ logo: lastStep?.to.blockchainLogo || ''
2378
+ },
2379
+ token: {
2380
+ symbol: lastStep?.to.symbol || '',
2381
+ image: lastStep?.to.logo || ''
2382
+ },
2383
+ usdValue: calcOutputUsdValue(toAmount, lastStep?.to.usdPrice),
2384
+ amount: toAmount,
2385
+ label: t('To'),
2386
+ loadingStatus: bestRouteloadingStatus
2387
+ })),
2388
+ previewRoutes: React.createElement(RoutesOverview, {
2389
+ routes: bestRoute,
2390
+ totalFee: numberToString(totalFeeInUsd, 0, 2)
2391
+ }),
1986
2392
  loading: loading,
1987
2393
  errors: ConfirmSwapErrors(errors),
1988
2394
  warnings: ConfirmSwapWarnings(warnings),
1989
2395
  extraMessages: showHighSlippageWarning && React.createElement(ConfirmSwapExtraMessages, {
1990
2396
  selectedSlippage: selectedSlippage
1991
2397
  }),
1992
- confirmButtonTitle: warnings.length > 0 || errors.length > 0 ? 'Proceed anyway!' : 'Confirm swap!',
1993
- confirmButtonDisabled: fetchingBestRoute
2398
+ confirmButtonTitle: warnings.length > 0 || errors.length > 0 ? 'Proceed anyway!' : 'Confirm swap!'
1994
2399
  });
1995
2400
  }
1996
2401
 
@@ -2008,6 +2413,31 @@ const getPendingSwaps = manager => {
2008
2413
  return result.sort((a, b) => Number(b.swap.creationTime) - Number(a.swap.creationTime));
2009
2414
  };
2010
2415
 
2416
+ const groupSwapsByDate = swaps => {
2417
+ const output = new Map([['today', {
2418
+ title: 'Today',
2419
+ swaps: []
2420
+ }], ['week', {
2421
+ title: 'This week',
2422
+ swaps: []
2423
+ }], ['month', {
2424
+ title: 'This month',
2425
+ swaps: []
2426
+ }], ['year', {
2427
+ title: 'This year',
2428
+ swaps: []
2429
+ }], ['history', {
2430
+ title: 'History',
2431
+ swaps: []
2432
+ }]]);
2433
+ const now = dayjs();
2434
+ swaps.forEach(swap => {
2435
+ const swapDate = dayjs(Number(swap.creationTime));
2436
+ 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);
2437
+ });
2438
+ return Array.from(output.values());
2439
+ };
2440
+
2011
2441
  function HistoryPage() {
2012
2442
  const setSelectedSwap = useUiStore.use.setSelectedSwap();
2013
2443
  const navigate = useNavigate();
@@ -2023,16 +2453,14 @@ function HistoryPage() {
2023
2453
  } = _ref;
2024
2454
  return swap;
2025
2455
  });
2026
- return React.createElement(History
2027
- //todo: move PendingSwap type to rango-types
2028
- //@ts-ignore
2029
- , {
2030
- //todo: move PendingSwap type to rango-types
2031
- //@ts-ignore
2456
+ return React.createElement(History, {
2032
2457
  list: pendingSwaps,
2458
+ groupBy: groupSwapsByDate,
2033
2459
  onSwapClick: requestId => {
2034
2460
  setSelectedSwap(requestId);
2035
- navigate(navigationRoutes.swaps + `/${requestId}`);
2461
+ navigate(navigationRoutes.swaps + `/${requestId}`, {
2462
+ replace: true
2463
+ });
2036
2464
  },
2037
2465
  onBack: navigateBackFrom.bind(null, navigationRoutes.swaps)
2038
2466
  });
@@ -2043,6 +2471,7 @@ function LiquiditySourcePage(_ref) {
2043
2471
  supportedSwappers
2044
2472
  } = _ref;
2045
2473
  const swappers = useMetaStore.use.meta().swappers;
2474
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2046
2475
  const toggleLiquiditySource = useSettingsStore.use.toggleLiquiditySource();
2047
2476
  const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
2048
2477
  const toggleAllLiquiditySources = useSettingsStore.use.toggleAllLiquiditySources();
@@ -2068,7 +2497,8 @@ function LiquiditySourcePage(_ref) {
2068
2497
  toggleAll: toggleAllLiquiditySources,
2069
2498
  list: supportedSwappers !== 'all' ? uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0) : uniqueSwappersGroups,
2070
2499
  onChange: liquiditySource => toggleLiquiditySource(liquiditySource.title),
2071
- onBack: navigateBackFrom.bind(null, navigationRoutes.liquiditySources)
2500
+ onBack: navigateBackFrom.bind(null, navigationRoutes.liquiditySources),
2501
+ loadingStatus: loadingMetaStatus
2072
2502
  });
2073
2503
  }
2074
2504
 
@@ -2111,11 +2541,11 @@ function SelectTokenPage(props) {
2111
2541
  const destinationTokens = useBestRouteStore.use.destinationTokens();
2112
2542
  const supportedSourceTokens = supportedTokens === 'all' ? sourceTokens : sourceTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2113
2543
  const supportedDestinationTokens = supportedTokens === 'all' ? destinationTokens : destinationTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2114
- console.log(supportedSourceTokens);
2115
2544
  const fromToken = useBestRouteStore.use.fromToken();
2116
2545
  const toToken = useBestRouteStore.use.toToken();
2117
2546
  const setFromToken = useBestRouteStore.use.setFromToken();
2118
2547
  const setToToken = useBestRouteStore.use.setToToken();
2548
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2119
2549
  return React.createElement(TokenSelector, {
2120
2550
  type: type === 'from' ? 'Source' : 'Destination',
2121
2551
  list: type == 'from' ? supportedSourceTokens : supportedDestinationTokens,
@@ -2124,7 +2554,8 @@ function SelectTokenPage(props) {
2124
2554
  if (type === 'from') setFromToken(token);else setToToken(token);
2125
2555
  navigateBackFrom(navigationRoutes.fromToken);
2126
2556
  },
2127
- onBack: navigateBackFrom.bind(null, navigationRoutes.fromToken)
2557
+ onBack: navigateBackFrom.bind(null, navigationRoutes.fromToken),
2558
+ loadingStatus: loadingMetaStatus
2128
2559
  });
2129
2560
  }
2130
2561
 
@@ -2146,6 +2577,7 @@ function SettingsPage(_ref) {
2146
2577
  } = useNavigateBack();
2147
2578
  const infiniteApprove = useSettingsStore.use.infiniteApprove();
2148
2579
  const toggleInfiniteApprove = useSettingsStore.use.toggleInfiniteApprove();
2580
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2149
2581
  const uniqueSwappersGroups = [];
2150
2582
  removeDuplicateFrom(swappers.map(s => s.swapperGroup)).map(swapperGroup => {
2151
2583
  return swappers.find(s => s.swapperGroup === swapperGroup);
@@ -2178,7 +2610,8 @@ function SettingsPage(_ref) {
2178
2610
  selectedTheme: theme,
2179
2611
  onThemeChange: setTheme,
2180
2612
  infiniteApprove: infiniteApprove,
2181
- toggleInfiniteApprove: toggleInfiniteApprove
2613
+ toggleInfiniteApprove: toggleInfiniteApprove,
2614
+ loadingStatus: loadingMetaStatus
2182
2615
  });
2183
2616
  }
2184
2617
 
@@ -2186,9 +2619,16 @@ const ListContainer = /*#__PURE__*/styled('div', {
2186
2619
  display: 'grid',
2187
2620
  gap: '.5rem',
2188
2621
  gridTemplateColumns: ' repeat(2, minmax(0, 1fr))',
2189
- height: '450px',
2190
2622
  alignContent: 'baseline',
2191
- padding: '0 0.5rem'
2623
+ padding: '0.5rem',
2624
+ overflowY: 'auto'
2625
+ });
2626
+ const LoaderContainer = /*#__PURE__*/styled('div', {
2627
+ display: 'flex',
2628
+ justifyContent: 'center',
2629
+ width: '100%',
2630
+ position: 'absolute',
2631
+ top: '50%'
2192
2632
  });
2193
2633
  const AlertContainer = /*#__PURE__*/styled('div', {
2194
2634
  paddingBottom: '$16'
@@ -2208,10 +2648,12 @@ function WalletsPage(_ref) {
2208
2648
  connect
2209
2649
  } = useWallets();
2210
2650
  const wallets = getlistWallet(state, getWalletInfo, supportedWallets === 'all' ? Object.values(WalletType) : supportedWallets);
2651
+ const walletsRef = useRef();
2211
2652
  let sortedWallets = detectMobileScreens() ? wallets.filter(wallet => wallet.showOnMobile) : wallets;
2212
2653
  sortedWallets = sortWalletsBasedOnState(sortedWallets);
2213
2654
  const [walletErrorMessage, setWalletErrorMessage] = useState('');
2214
2655
  const toggleConnectWalletsButton = useUiStore.use.toggleConnectWalletsButton();
2656
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2215
2657
  const {
2216
2658
  t
2217
2659
  } = useTranslation();
@@ -2231,71 +2673,38 @@ function WalletsPage(_ref) {
2231
2673
  setWalletErrorMessage('Error: ' + e?.message);
2232
2674
  }
2233
2675
  };
2676
+ const disconnectConnectingWallets = () => {
2677
+ const connectingWallets = walletsRef.current?.filter(wallet => wallet.state === WalletState.CONNECTING) || [];
2678
+ for (const wallet of connectingWallets) {
2679
+ disconnect(wallet.type);
2680
+ }
2681
+ };
2234
2682
  useEffect(() => {
2235
2683
  toggleConnectWalletsButton();
2236
- return () => toggleConnectWalletsButton();
2684
+ return () => {
2685
+ disconnectConnectingWallets();
2686
+ toggleConnectWalletsButton();
2687
+ };
2237
2688
  }, []);
2689
+ useEffect(() => {
2690
+ walletsRef.current = wallets;
2691
+ }, [wallets]);
2238
2692
  return React.createElement(SecondaryPage, {
2239
2693
  title: t('Select Wallet') || '',
2240
2694
  textField: false,
2241
2695
  onBack: navigateBackFrom.bind(null, navigationRoutes.wallets)
2242
2696
  }, React.createElement(React.Fragment, null, walletErrorMessage && React.createElement(AlertContainer, null, React.createElement(Alert, {
2243
2697
  type: "error"
2244
- }, React.createElement(Typography, {
2245
- variant: "body2"
2246
- }, walletErrorMessage))), React.createElement(ListContainer, null, sortedWallets.map((wallet, index) => React.createElement(Wallet, Object.assign({}, wallet, {
2698
+ }, walletErrorMessage)), loadingMetaStatus === 'loading' && React.createElement(LoaderContainer, {
2699
+ className: "loader"
2700
+ }, React.createElement(Spinner, {
2701
+ size: 24
2702
+ })), loadingMetaStatus === 'failed' && React.createElement(LoadingFailedAlert, null), React.createElement(ListContainer, null, loadingMetaStatus === 'success' && sortedWallets.map((wallet, index) => React.createElement(Wallet, Object.assign({}, wallet, {
2247
2703
  key: `${index}-${wallet.type}`,
2248
2704
  onClick: onSelectWallet
2249
2705
  }))))));
2250
2706
  }
2251
2707
 
2252
- function ConfirmWalletsPage() {
2253
- const navigate = useNavigate();
2254
- const {
2255
- navigateBackFrom
2256
- } = useNavigateBack();
2257
- const bestRoute = useBestRouteStore.use.bestRoute();
2258
- const {
2259
- blockchains
2260
- } = useMetaStore.use.meta();
2261
- const accounts = useWalletsStore.use.accounts();
2262
- const selectedWallets = useWalletsStore.use.selectedWallets();
2263
- const initSelectedWallets = useWalletsStore.use.initSelectedWallets();
2264
- const setSelectedWallet = useWalletsStore.use.setSelectedWallet();
2265
- const {
2266
- getWalletInfo,
2267
- connect
2268
- } = useWallets();
2269
- const confirmDisabled = !requiredWallets(bestRoute).every(chain => selectedWallets.map(wallet => wallet.chain).includes(chain));
2270
- const firstStep = bestRoute?.result?.swaps[0];
2271
- const lastStep = bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1];
2272
- const fromAmount = decimalNumber(firstStep?.fromAmount, 3);
2273
- const toAmount = decimalNumber(lastStep?.toAmount, 3);
2274
- useEffect(() => {
2275
- initSelectedWallets();
2276
- }, []);
2277
- const selectableWallets = getSelectableWallets(accounts, selectedWallets, getWalletInfo);
2278
- const handleConnectChain = wallet => {
2279
- const network = wallet;
2280
- getKeplrCompatibleConnectedWallets(selectableWallets).forEach(compatibleWallet => connect?.(compatibleWallet, network));
2281
- };
2282
- return React.createElement(ConfirmWallets, {
2283
- requiredWallets: getRequiredChains(bestRoute),
2284
- selectableWallets: selectableWallets,
2285
- onBack: navigateBackFrom.bind(null, navigationRoutes.confirmWallets),
2286
- swap: bestRoute,
2287
- fromAmount: fromAmount,
2288
- toAmount: toAmount,
2289
- onConfirm: () => navigate(navigationRoutes.confirmSwap, {
2290
- replace: true
2291
- }),
2292
- onChange: wallet => setSelectedWallet(wallet),
2293
- confirmDisabled: confirmDisabled,
2294
- handleConnectChain: wallet => handleConnectChain(wallet),
2295
- isExperimentalChain: wallet => getKeplrCompatibleConnectedWallets(selectableWallets).length > 0 ? isExperimentalChain(blockchains, wallet) : false
2296
- });
2297
- }
2298
-
2299
2708
  function useCopyToClipboard(resetInterval) {
2300
2709
  const [isCopied, setCopied] = React.useState(false);
2301
2710
  const handleCopy = React.useCallback(text => {
@@ -2314,15 +2723,87 @@ function useCopyToClipboard(resetInterval) {
2314
2723
  return [isCopied, handleCopy];
2315
2724
  }
2316
2725
 
2726
+ function timeSince(timeMillis) {
2727
+ const seconds = Math.floor((new Date().getTime() - timeMillis) / 1000);
2728
+ let intervalType;
2729
+ let interval = Math.floor(seconds / 31536000);
2730
+ if (interval >= 1) {
2731
+ intervalType = 'year';
2732
+ } else {
2733
+ interval = Math.floor(seconds / 2592000);
2734
+ if (interval >= 1) {
2735
+ intervalType = 'month';
2736
+ } else {
2737
+ interval = Math.floor(seconds / 86400);
2738
+ if (interval >= 1) {
2739
+ intervalType = 'day';
2740
+ } else {
2741
+ interval = Math.floor(seconds / 3600);
2742
+ if (interval >= 1) {
2743
+ intervalType = 'hour';
2744
+ } else {
2745
+ interval = Math.floor(seconds / 60);
2746
+ if (interval >= 1) {
2747
+ intervalType = 'minute';
2748
+ } else {
2749
+ interval = seconds;
2750
+ intervalType = 'second';
2751
+ }
2752
+ }
2753
+ }
2754
+ }
2755
+ }
2756
+ if (interval > 1 || interval === 0) {
2757
+ intervalType += 's';
2758
+ }
2759
+ return interval + ' ' + intervalType;
2760
+ }
2761
+ function getSwapDate(pendingSwap) {
2762
+ 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()}`;
2763
+ }
2764
+
2765
+ const PlaceholderContainer = /*#__PURE__*/styled('div', {
2766
+ height: '450px'
2767
+ });
2768
+ function SwapDetailsPlaceholder(props) {
2769
+ const {
2770
+ requestId,
2771
+ loading,
2772
+ onBack
2773
+ } = props;
2774
+ return React.createElement(SecondaryPage, {
2775
+ title: "Swap Details",
2776
+ textField: false,
2777
+ onBack: onBack
2778
+ }, React.createElement(PlaceholderContainer, null, loading ? React.createElement(LoaderContainer, null, React.createElement(Spinner, {
2779
+ size: 24
2780
+ })) : React.createElement(Alert, {
2781
+ type: "secondary",
2782
+ title: `Swap with request ID = ${requestId} not found.`
2783
+ })));
2784
+ }
2785
+
2317
2786
  function SwapDetailsPage() {
2318
2787
  const selectedSwapRequestId = useUiStore.use.selectedSwapRequestId();
2788
+ const {
2789
+ canSwitchNetworkTo,
2790
+ connect
2791
+ } = useWallets();
2792
+ const retry = useBestRouteStore.use.retry();
2793
+ const navigate = useNavigate();
2319
2794
  const {
2320
2795
  navigateBackFrom
2321
2796
  } = useNavigateBack();
2797
+ const [isCopied, handleCopy] = useCopyToClipboard(2000);
2322
2798
  const {
2323
2799
  manager
2324
2800
  } = useManager();
2325
- const [isCopied, handleCopy] = useCopyToClipboard(2000);
2801
+ const [loading, setLoading] = useState(true);
2802
+ useEffect(() => {
2803
+ setTimeout(() => {
2804
+ setLoading(false);
2805
+ }, 5000);
2806
+ }, []);
2326
2807
  const pendingSwaps = getPendingSwaps(manager);
2327
2808
  const selectedSwap = pendingSwaps.find(_ref => {
2328
2809
  let {
@@ -2330,92 +2811,161 @@ function SwapDetailsPage() {
2330
2811
  } = _ref;
2331
2812
  return swap.requestId === selectedSwapRequestId;
2332
2813
  });
2333
- //TODO: implement swap cancellation (move queueManager logic to queueManager/rango-preset)
2334
2814
  const onCancel = () => {
2335
- const swap = selectedSwap ? manager?.get(selectedSwap.id) : undefined;
2815
+ const swap = manager?.get(selectedSwap?.id);
2336
2816
  if (swap) cancelSwap(swap);
2337
2817
  };
2338
- return React.createElement(SwapHistory, {
2818
+ const swap = selectedSwap?.swap;
2819
+ if (!swap) return React.createElement(SwapDetailsPlaceholder, {
2820
+ requestId: selectedSwapRequestId || '',
2821
+ loading: loading,
2822
+ onBack: navigateBackFrom.bind(null, navigationRoutes.swapDetails)
2823
+ });
2824
+ const firstStep = swap.steps[0];
2825
+ const lastStep = swap.steps[swap.steps.length - 1];
2826
+ const fromAmount = numberToString(swap.inputAmount);
2827
+ const toAmount = numberToString(swap.simulationResult.outputAmount);
2828
+ const currentStep = getCurrentStep(swap);
2829
+ const currentStepBlockchain = currentStep ? getCurrentBlockchainOfOrNull(swap, currentStep) : null;
2830
+ const currentStepWallet = currentStep ? getRelatedWalletOrNull(swap, currentStep) : null;
2831
+ const currentStepNetworkStatus = currentStep?.networkStatus;
2832
+ const swapMessages = getSwapMessages(swap, currentStep);
2833
+ const networkWarningState = isNetworkStatusInWarningState(currentStep);
2834
+ const swapDate = getSwapDate(swap);
2835
+ const shouldRetry = shouldRetrySwap(swap);
2836
+ const switchNetwork = !!currentStepBlockchain && !!currentStepWallet?.walletType && currentStepNetworkStatus === PendingSwapNetworkStatus.WaitingForNetworkChange && canSwitchNetworkTo(currentStepWallet?.walletType, currentStepBlockchain) ? connect.bind(null, currentStepWallet.walletType, currentStepBlockchain) : undefined;
2837
+ const lastConvertedTokenInFailedSwap = getLastConvertedTokenInFailedSwap(swap);
2838
+ return React.createElement(SwapHistory, Object.assign({
2339
2839
  onBack: navigateBackFrom.bind(null, navigationRoutes.swapDetails),
2840
+ previewInputs: React.createElement(React.Fragment, null, React.createElement(TokenPreview, {
2841
+ chain: {
2842
+ displayName: firstStep?.fromBlockchain || '',
2843
+ // @ts-ignore
2844
+ logo: firstStep?.fromBlockchainLogo || ''
2845
+ },
2846
+ token: {
2847
+ symbol: firstStep?.fromSymbol || '',
2848
+ image: firstStep?.fromLogo || ''
2849
+ },
2850
+ amount: fromAmount,
2851
+ label: t('From'),
2852
+ loadingStatus: 'success'
2853
+ }), React.createElement(Spacer, {
2854
+ size: 12,
2855
+ direction: "vertical"
2856
+ }), React.createElement(TokenPreview, {
2857
+ chain: {
2858
+ displayName: lastStep?.toBlockchain || '',
2859
+ // @ts-ignore
2860
+ logo: lastStep?.toBlockchainLogo || ''
2861
+ },
2862
+ token: {
2863
+ symbol: lastStep?.toSymbol || '',
2864
+ image: lastStep?.toLogo || ''
2865
+ },
2866
+ amount: toAmount,
2867
+ label: t('To'),
2868
+ loadingStatus: 'success'
2869
+ })),
2340
2870
  //todo: move PendingSwap type to rango-types
2341
2871
  //@ts-ignore
2342
- pendingSwap: selectedSwap?.swap,
2872
+ pendingSwap: swap,
2343
2873
  onCopy: handleCopy,
2344
2874
  isCopied: isCopied,
2345
- onCancel: onCancel
2346
- });
2875
+ onCancel: onCancel,
2876
+ shortMessage: swapMessages.shortMessage,
2877
+ detailedMessage: swapMessages.detailedMessage,
2878
+ currentStepBlockchain: currentStepBlockchain || '',
2879
+ switchNetwork: switchNetwork,
2880
+ type: networkWarningState ? 'warning' : swap.extraMessageSeverity || undefined,
2881
+ date: swapDate
2882
+ }, shouldRetry && {
2883
+ onRetry: () => {
2884
+ retry(swap);
2885
+ setTimeout(() => {
2886
+ navigate(navigationRoutes.home);
2887
+ }, 0);
2888
+ }
2889
+ }, lastConvertedTokenInFailedSwap && {
2890
+ lastConvertedTokenInFailedSwap: {
2891
+ blockchain: lastConvertedTokenInFailedSwap.blockchain,
2892
+ outputAmount: lastConvertedTokenInFailedSwap.outputAmount || '',
2893
+ symbol: lastConvertedTokenInFailedSwap.symbol
2894
+ }
2895
+ }));
2347
2896
  }
2348
2897
 
2898
+ const getAbsolutePath = path => path.replace('/', '');
2349
2899
  function AppRoutes(props) {
2350
2900
  const {
2351
2901
  configs
2352
2902
  } = props;
2353
2903
  return useRoutes([{
2354
- path: navigationRoutes.home,
2904
+ path: getAbsolutePath(navigationRoutes.home),
2355
2905
  element: React.createElement(Home, {
2356
2906
  title: configs?.title,
2357
2907
  titleSize: configs?.titleSize,
2358
2908
  titleWeight: configs?.titleWeight
2359
2909
  })
2360
2910
  }, {
2361
- path: navigationRoutes.fromChain,
2911
+ path: getAbsolutePath(navigationRoutes.fromChain),
2362
2912
  element: React.createElement(SelectChainPage, {
2363
2913
  type: "from",
2364
2914
  supportedChains: configs?.fromChains || 'all'
2365
2915
  })
2366
2916
  }, {
2367
- path: navigationRoutes.toChain,
2917
+ path: getAbsolutePath(navigationRoutes.toChain),
2368
2918
  element: React.createElement(SelectChainPage, {
2369
2919
  type: "to",
2370
2920
  supportedChains: configs?.toChains || 'all'
2371
2921
  })
2372
2922
  }, {
2373
- path: navigationRoutes.fromToken + '/*',
2923
+ path: getAbsolutePath(navigationRoutes.fromToken),
2374
2924
  element: React.createElement(SelectTokenPage, {
2375
2925
  type: "from",
2376
2926
  supportedTokens: configs?.fromTokens || 'all'
2377
2927
  })
2378
2928
  }, {
2379
- path: navigationRoutes.toToken,
2929
+ path: getAbsolutePath(navigationRoutes.toToken),
2380
2930
  element: React.createElement(SelectTokenPage, {
2381
2931
  type: "to",
2382
2932
  supportedTokens: configs?.toTokens || 'all'
2383
2933
  })
2384
2934
  }, {
2385
- path: navigationRoutes.settings,
2935
+ path: getAbsolutePath(navigationRoutes.settings),
2386
2936
  element: React.createElement(SettingsPage, {
2387
2937
  supportedSwappers: configs?.liquiditySources || 'all'
2388
2938
  })
2389
2939
  }, {
2390
- path: navigationRoutes.liquiditySources,
2940
+ path: getAbsolutePath(navigationRoutes.liquiditySources),
2391
2941
  element: React.createElement(LiquiditySourcePage, {
2392
2942
  supportedSwappers: configs?.liquiditySources || 'all'
2393
2943
  })
2394
2944
  }, {
2395
- path: navigationRoutes.swaps,
2945
+ path: getAbsolutePath(navigationRoutes.swaps),
2396
2946
  element: React.createElement(HistoryPage, null)
2397
2947
  }, {
2398
2948
  path: navigationRoutes.swapDetails,
2399
2949
  element: React.createElement(SwapDetailsPage, null)
2400
2950
  }, {
2401
- path: navigationRoutes.wallets,
2951
+ path: getAbsolutePath(navigationRoutes.wallets),
2402
2952
  element: React.createElement(WalletsPage, {
2403
2953
  supportedWallets: configs?.wallets || 'all',
2404
2954
  multiWallets: typeof configs?.multiWallets === 'undefined' ? true : configs.multiWallets
2405
2955
  })
2406
2956
  }, {
2407
- path: navigationRoutes.confirmSwap,
2957
+ path: getAbsolutePath(navigationRoutes.confirmSwap),
2408
2958
  element: React.createElement(ConfirmSwapPage, null)
2409
- }, {
2410
- path: navigationRoutes.confirmWallets,
2411
- element: React.createElement(ConfirmWalletsPage, null)
2412
2959
  }]);
2413
2960
  }
2414
2961
 
2415
- const Header$1 = /*#__PURE__*/styled('div', {
2962
+ const Header = /*#__PURE__*/styled('div', {
2416
2963
  display: 'flex',
2417
2964
  width: '100%',
2418
- justifyContent: 'end'
2965
+ justifyContent: 'end',
2966
+ '.balance': {
2967
+ display: 'flex'
2968
+ }
2419
2969
  });
2420
2970
  const WalletImage = /*#__PURE__*/styled('img', {
2421
2971
  width: '$24',
@@ -2445,6 +2995,8 @@ function Layout(_ref) {
2445
2995
  const setInputAmount = useBestRouteStore.use.setInputAmount();
2446
2996
  const totalBalance = calculateWalletUsdValue(balances);
2447
2997
  const connectWalletsButtonDisabled = useUiStore.use.connectWalletsButtonDisabled();
2998
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2999
+ const fetchingBalance = useWalletsStore(fetchingBalanceSelector);
2448
3000
  const {
2449
3001
  t
2450
3002
  } = useTranslation();
@@ -2459,22 +3011,32 @@ function Layout(_ref) {
2459
3011
  setFromToken(configs?.fromToken || null);
2460
3012
  setFromChain(configs?.fromChain || null);
2461
3013
  }, [configs?.fromToken, configs?.fromChain]);
2462
- return React.createElement(React.Fragment, null, React.createElement(Header$1, null, React.createElement(Button, {
3014
+ useEffect(() => {
3015
+ setToChain(null);
3016
+ setFromChain(null);
3017
+ setFromToken(null);
3018
+ setToToken(null);
3019
+ }, [configs?.fromChains, configs?.toChains, configs?.fromTokens, configs?.toTokens]);
3020
+ return React.createElement(React.Fragment, null, React.createElement(Header, null, React.createElement(Button, {
2463
3021
  size: "small",
2464
3022
  suffix: React.createElement(AddWalletIcon, {
2465
3023
  size: 20
2466
3024
  }),
2467
3025
  variant: "ghost",
2468
3026
  flexContent: true,
3027
+ loading: loadingMetaStatus === 'loading',
3028
+ disabled: loadingMetaStatus === 'failed',
2469
3029
  onClick: () => {
2470
3030
  if (!connectWalletsButtonDisabled) navigate(navigationRoutes.wallets);
2471
3031
  }
2472
3032
  }, connectedWalletsImages?.length ? connectedWalletsImages.map((walletImage, index) => React.createElement(WalletImage, {
2473
3033
  key: index,
2474
3034
  src: walletImage
2475
- })) : React.createElement(React.Fragment, null), React.createElement(Typography, {
3035
+ })) : React.createElement(React.Fragment, null), React.createElement("div", {
3036
+ className: "balance"
3037
+ }, React.createElement(Typography, {
2476
3038
  variant: "body2"
2477
- }, !accounts?.length ? t('Connect Wallet') : `$${totalBalance || 0}`))), React.createElement(AppRoutes, {
3039
+ }, !accounts?.length ? t('Connect Wallet') : `$${totalBalance || 0}`), fetchingBalance && React.createElement(Spinner, null)))), React.createElement(AppRoutes, {
2478
3040
  configs: configs
2479
3041
  }));
2480
3042
  }
@@ -2482,10 +3044,12 @@ function Layout(_ref) {
2482
3044
  const globalStyles = /*#__PURE__*/globalCss({
2483
3045
  '*': {
2484
3046
  '&::-webkit-scrollbar': {
2485
- width: '$8'
3047
+ width: '$8',
3048
+ height: '$8'
2486
3049
  },
2487
3050
  '&::-webkit-scrollbar-thumb': {
2488
- backgroundColor: '$neutrals400'
3051
+ backgroundColor: '$neutrals400',
3052
+ borderRadius: '$10'
2489
3053
  },
2490
3054
  '&::-webkit-scrollbar-thumb:hover': {
2491
3055
  backgroundColor: '$neutrals500'
@@ -2497,7 +3061,7 @@ const globalStyles = /*#__PURE__*/globalCss({
2497
3061
  });
2498
3062
  const globalFont = fontFamily => globalCss({
2499
3063
  '@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')"],
2500
- [`.font_${fontFamily.replace(/ /g, '')} ._text`]: {
3064
+ body: {
2501
3065
  fontFamily
2502
3066
  }
2503
3067
  })();
@@ -2523,16 +3087,16 @@ function useTheme(_ref) {
2523
3087
  warning = '#F5A623',
2524
3088
  success = '#0070F3',
2525
3089
  fontFamily = 'Robot',
2526
- borderRadius = 5
3090
+ borderRadius = 8
2527
3091
  } = _ref;
2528
3092
  const theme = useSettingsStore.use.theme();
2529
3093
  const fetchMeta = useMetaStore.use.fetchMeta();
2530
3094
  const colors = {
2531
3095
  neutrals200: '#FAFAFA',
2532
- neutrals300: '#EAEAEA',
2533
- neutrals400: '#999999',
2534
- neutrals500: '#888888',
2535
- neutrals600: '#666666',
3096
+ neutrals300: '#f2f2f2',
3097
+ neutrals400: '#dedede',
3098
+ neutrals500: '#cccccc',
3099
+ neutrals600: '#acacac',
2536
3100
  neutrals700: '#444444',
2537
3101
  neutrals800: '#333333',
2538
3102
  neutrals900: '#111111',
@@ -2576,10 +3140,10 @@ function useTheme(_ref) {
2576
3140
  neutrals200: '#111111',
2577
3141
  neutrals300: '#333333',
2578
3142
  neutrals400: '#444444',
2579
- neutrals500: '#666666',
2580
- neutrals600: '#888888',
2581
- neutrals700: '#999999',
2582
- neutrals800: '#EAEAEA',
3143
+ neutrals500: '#acacac',
3144
+ neutrals600: '#cccccc',
3145
+ neutrals700: '#dedede',
3146
+ neutrals800: '#f2f2f2',
2583
3147
  neutrals900: '#FAFAFA',
2584
3148
  foreground: background,
2585
3149
  background: foreground
@@ -2639,8 +3203,9 @@ function useSelectLanguage() {
2639
3203
  }
2640
3204
 
2641
3205
  var swap = "SWAP";
2642
- var From = "From";
2643
- var To = "To";
3206
+ var From = "You sell";
3207
+ var To = "You receive";
3208
+ var Balance = "Balance";
2644
3209
  var Max = "Max";
2645
3210
  var Chain = "Chain";
2646
3211
  var Token = "Token";
@@ -2652,12 +3217,13 @@ var en = {
2652
3217
  "Powered By": "Powered By",
2653
3218
  From: From,
2654
3219
  To: To,
3220
+ Balance: Balance,
2655
3221
  Max: Max,
2656
3222
  Chain: Chain,
2657
3223
  Token: Token,
2658
3224
  Source: Source,
2659
3225
  Destination: Destination,
2660
- "Select Wallet": "Select Wallet"
3226
+ "Select Wallet": "Connect Your Wallet"
2661
3227
  };
2662
3228
 
2663
3229
  var swap$1 = "TAKAS";
@@ -2724,7 +3290,7 @@ function QueueManager(props) {
2724
3290
  };
2725
3291
  // TODO: this code copy & pasted from rango, should be refactored.
2726
3292
  const allBlockchains = blockchains.filter(blockchain => blockchain.enabled).reduce((blockchainsObj, blockchain) => (blockchainsObj[blockchain.name] = blockchain, blockchainsObj), {});
2727
- const evmBasedChains = blockchains.filter(isEvmBlockchain);
3293
+ const evmBasedChains = blockchains.filter(isEvmBlockchain$1);
2728
3294
  const getSupportedChainNames = type => {
2729
3295
  const {
2730
3296
  supportedChains
@@ -2757,7 +3323,9 @@ function QueueManager(props) {
2757
3323
  //@ts-ignore
2758
3324
  queuesDefs: [swapQueueDef],
2759
3325
  context: context,
2760
- onPersistedDataLoaded: _manager => {},
3326
+ onPersistedDataLoaded: manager => {
3327
+ checkWaitingForNetworkChange(manager);
3328
+ },
2761
3329
  isPaused: false
2762
3330
  }, props.children);
2763
3331
  }
@@ -2785,8 +3353,10 @@ const SwapBox = _ref => {
2785
3353
  changeLanguage
2786
3354
  } = useSelectLanguage();
2787
3355
  const clearConnectedWallet = useWalletsStore.use.clearConnectedWallet();
2788
- const evmBasedChainNames = blockchains.filter(isEvmBlockchain).map(chain => chain.name);
2789
- const onUpdateState = (type, event, value, _, supportedChains) => {
3356
+ const [lastConnectedWalletWithNetwork, setLastConnectedWalletWithNetwork] = useState('');
3357
+ const [disconnectedWallet, setDisconnectedWallet] = useState();
3358
+ const evmBasedChainNames = blockchains.filter(isEvmBlockchain$1).map(chain => chain.name);
3359
+ const onUpdateState = (type, event, value, state, supportedChains) => {
2790
3360
  if (event === Events.ACCOUNTS) {
2791
3361
  if (value) {
2792
3362
  const supportedChainNames = walletAndSupportedChainsNames(supportedChains);
@@ -2796,6 +3366,16 @@ const SwapBox = _ref => {
2796
3366
  disconnectWallet(type);
2797
3367
  }
2798
3368
  }
3369
+ if (event === Events.ACCOUNTS && state.connected) {
3370
+ const key = `${type}-${state.network}-${value}`;
3371
+ if (state.connected) {
3372
+ setLastConnectedWalletWithNetwork(key);
3373
+ }
3374
+ }
3375
+ if (event === Events.NETWORK && state.network) {
3376
+ const key = `${type}-${state.network}`;
3377
+ setLastConnectedWalletWithNetwork(key);
3378
+ }
2799
3379
  };
2800
3380
  let providers = allProviders();
2801
3381
  useEffect(() => {
@@ -2827,7 +3407,12 @@ const SwapBox = _ref => {
2827
3407
  }, React.createElement(AppRouter, {
2828
3408
  title: configs.title,
2829
3409
  titleSize: configs.titleSize,
2830
- titleWeight: configs.titleWeight
3410
+ titleWeight: configs.titleWeight,
3411
+ lastConnectedWallet: lastConnectedWalletWithNetwork,
3412
+ disconnectedWallet: disconnectedWallet,
3413
+ clearDisconnectedWallet: () => {
3414
+ setDisconnectedWallet(undefined);
3415
+ }
2831
3416
  }, React.createElement(Layout, {
2832
3417
  configs: configs
2833
3418
  }))))));