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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/dist/App.d.ts.map +1 -1
  2. package/dist/QueueManager.d.ts.map +1 -1
  3. package/dist/components/AppRouter.d.ts +6 -1
  4. package/dist/components/AppRouter.d.ts.map +1 -1
  5. package/dist/components/AppRoutes.d.ts.map +1 -1
  6. package/dist/components/HeaderButtons.d.ts +4 -1
  7. package/dist/components/HeaderButtons.d.ts.map +1 -1
  8. package/dist/components/Layout.d.ts.map +1 -1
  9. package/dist/components/PercentageChange.d.ts +9 -0
  10. package/dist/components/PercentageChange.d.ts.map +1 -0
  11. package/dist/components/SwapDetailsPlaceholder.d.ts +9 -0
  12. package/dist/components/SwapDetailsPlaceholder.d.ts.map +1 -0
  13. package/dist/components/TokenInfo.d.ts.map +1 -1
  14. package/dist/components/TokenPreview.d.ts +3 -2
  15. package/dist/components/TokenPreview.d.ts.map +1 -1
  16. package/dist/components/UpdateUrl.d.ts.map +1 -1
  17. package/dist/components/warnings/BalanceWarnings.d.ts.map +1 -1
  18. package/dist/components/warnings/MinRequiredSlippage.d.ts +1 -1
  19. package/dist/components/warnings/MinRequiredSlippage.d.ts.map +1 -1
  20. package/dist/constants/navigationRoutes.d.ts +0 -1
  21. package/dist/constants/navigationRoutes.d.ts.map +1 -1
  22. package/dist/globalStyles.d.ts.map +1 -1
  23. package/dist/hooks/useConfirmSwap.d.ts.map +1 -1
  24. package/dist/lib.d.ts.map +1 -1
  25. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  26. package/dist/pages/HistoryPage.d.ts.map +1 -1
  27. package/dist/pages/Home.d.ts.map +1 -1
  28. package/dist/pages/LiquiditySourcesPage.d.ts.map +1 -1
  29. package/dist/pages/SelectTokenPage.d.ts.map +1 -1
  30. package/dist/pages/SettingsPage.d.ts.map +1 -1
  31. package/dist/pages/SwapDetailsPage.d.ts.map +1 -1
  32. package/dist/pages/WalletsPage.d.ts +1 -0
  33. package/dist/pages/WalletsPage.d.ts.map +1 -1
  34. package/dist/store/bestRoute.d.ts +3 -0
  35. package/dist/store/bestRoute.d.ts.map +1 -1
  36. package/dist/store/ui.d.ts.map +1 -1
  37. package/dist/store/wallets.d.ts +14 -0
  38. package/dist/store/wallets.d.ts.map +1 -1
  39. package/dist/types/routing.d.ts +15 -2
  40. package/dist/types/routing.d.ts.map +1 -1
  41. package/dist/types/swap.d.ts +6 -0
  42. package/dist/types/swap.d.ts.map +1 -1
  43. package/dist/utils/common.d.ts +1 -0
  44. package/dist/utils/common.d.ts.map +1 -1
  45. package/dist/utils/date.d.ts +3 -0
  46. package/dist/utils/date.d.ts.map +1 -0
  47. package/dist/utils/routing.d.ts +3 -2
  48. package/dist/utils/routing.d.ts.map +1 -1
  49. package/dist/utils/swap.d.ts +16 -5
  50. package/dist/utils/swap.d.ts.map +1 -1
  51. package/dist/utils/time.d.ts +4 -0
  52. package/dist/utils/time.d.ts.map +1 -0
  53. package/dist/utils/wallets.d.ts +1 -1
  54. package/dist/utils/wallets.d.ts.map +1 -1
  55. package/dist/widget-embedded.cjs.development.js +1122 -719
  56. package/dist/widget-embedded.cjs.development.js.map +1 -1
  57. package/dist/widget-embedded.cjs.production.min.js +1122 -719
  58. package/dist/widget-embedded.cjs.production.min.js.map +1 -1
  59. package/dist/widget-embedded.esm.js +1131 -728
  60. package/dist/widget-embedded.esm.js.map +1 -1
  61. package/package.json +12 -11
  62. package/readme.md +1 -2
  63. package/src/App.tsx +30 -5
  64. package/src/QueueManager.tsx +5 -2
  65. package/src/components/AppRouter.tsx +24 -13
  66. package/src/components/AppRoutes.tsx +15 -12
  67. package/src/components/HeaderButtons.tsx +9 -2
  68. package/src/components/Layout.tsx +37 -5
  69. package/src/components/PercentageChange.tsx +33 -0
  70. package/src/components/SwapDetailsPlaceholder.tsx +32 -0
  71. package/src/components/TokenInfo.tsx +20 -4
  72. package/src/components/TokenPreview.tsx +17 -6
  73. package/src/components/UpdateUrl.tsx +1 -3
  74. package/src/components/warnings/BalanceWarnings.tsx +1 -0
  75. package/src/components/warnings/MinRequiredSlippage.tsx +9 -4
  76. package/src/constants/navigationRoutes.ts +0 -1
  77. package/src/globalStyles.ts +2 -1
  78. package/src/hooks/useConfirmSwap.ts +2 -1
  79. package/src/hooks/useNavigateBack.ts +3 -3
  80. package/src/lib.tsx +25 -3
  81. package/src/pages/ConfirmSwapPage.tsx +133 -20
  82. package/src/pages/HistoryPage.tsx +4 -4
  83. package/src/pages/Home.tsx +27 -22
  84. package/src/pages/LiquiditySourcesPage.tsx +2 -0
  85. package/src/pages/SelectTokenPage.tsx +3 -1
  86. package/src/pages/SettingsPage.tsx +3 -0
  87. package/src/pages/SwapDetailsPage.tsx +142 -6
  88. package/src/pages/WalletsPage.tsx +47 -11
  89. package/src/store/bestRoute.ts +143 -16
  90. package/src/store/ui.ts +4 -0
  91. package/src/store/wallets.ts +4 -1
  92. package/src/types/routing.ts +18 -2
  93. package/src/types/swap.ts +7 -0
  94. package/src/utils/common.ts +14 -0
  95. package/src/utils/date.ts +62 -0
  96. package/src/utils/routing.ts +36 -20
  97. package/src/utils/swap.ts +103 -11
  98. package/src/utils/time.ts +52 -0
  99. package/src/utils/wallets.ts +13 -4
  100. package/dist/components/Header.d.ts +0 -10
  101. package/dist/components/Header.d.ts.map +0 -1
  102. package/dist/pages/ConfirmWalletsPage.d.ts +0 -3
  103. package/dist/pages/ConfirmWalletsPage.d.ts.map +0 -1
  104. package/src/components/Header.tsx +0 -37
  105. package/src/pages/ConfirmWalletsPage.tsx +0 -127
@@ -1,22 +1,23 @@
1
- import { WalletState, Tooltip, Button, RetryIcon, HistoryIcon, SettingsIcon, styled, css, Typography, InfoCircleIcon, AngleDownIcon, Spacer, TextField, VerticalSwapIcon, BestRoute, Alert, ConfirmSwap, History, LiquiditySourcesSelector, BlockchainSelector, TokenSelector, Settings, SecondaryPage, Wallet, ChevronRightIcon, GasIcon, ConfirmWallets, SwapHistory, AddWalletIcon, globalCss, createTheme, SwapContainer } from '@rango-dev/ui';
1
+ import { WalletState, Typography, InfoCircleIcon, AngleDownIcon, 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';
16
- import { useManager, Provider } from '@rango-dev/queue-manager-react';
17
17
  import i18n, { t } from 'i18next';
18
+ import { useManager, Provider } from '@rango-dev/queue-manager-react';
19
+ import dayjs from 'dayjs';
18
20
  import copy from 'copy-to-clipboard';
19
- import { cancelSwap, swapQueueDef } from '@rango-dev/queue-manager-rango-preset';
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) {
@@ -420,7 +436,7 @@ function getSwapButtonState(loadingMetaStatus, accounts, loading, bestRoute, has
420
436
  };else if (inputIsZero) return {
421
437
  title: 'Enter an amount',
422
438
  disabled: true
423
- };else if (!bestRoute) return {
439
+ };else if (!bestRoute || !bestRoute.result) return {
424
440
  title: 'Swap',
425
441
  disabled: true
426
442
  };else if (hasLimitError) return {
@@ -453,6 +469,7 @@ function calculatePendingSwap(inputAmount, bestRoute, wallets, settings, validat
453
469
  finishTime: null,
454
470
  requestId: bestRoute.requestId || '',
455
471
  inputAmount: inputAmount,
472
+ //@ts-ignore
456
473
  wallets,
457
474
  status: 'running',
458
475
  isPaused: false,
@@ -467,6 +484,7 @@ function calculatePendingSwap(inputAmount, bestRoute, wallets, settings, validat
467
484
  settings: settings,
468
485
  simulationResult: simulationResult,
469
486
  validateBalanceOrFee,
487
+ //@ts-ignore
470
488
  steps: bestRoute.result?.swaps?.map((swap, index) => {
471
489
  const swapper = meta.swappers.find(swapper => swapper.id === swap.swapperId);
472
490
  const swapperType = swapper?.types[0];
@@ -552,11 +570,10 @@ function hasHighFee(totalFeeInUsd) {
552
570
  }
553
571
  function getMinRequiredSlippage(route) {
554
572
  const slippages = route.result?.swaps.map(slippage => slippage.recommendedSlippage);
555
- 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;
556
574
  }
557
575
  function hasProperSlippage(userSlippage, minRequiredSlippage) {
558
576
  if (!minRequiredSlippage) return true;
559
- //@ts-ignore
560
577
  return parseFloat(userSlippage) >= parseFloat(minRequiredSlippage);
561
578
  }
562
579
  function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, selectedWallets, disabledLiquiditySources, slippage, checkPrerequisites) {
@@ -569,6 +586,7 @@ function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, se
569
586
  addresses: [wallet.address]
570
587
  });
571
588
  });
589
+ const filteredBlockchains = selectedWallets.map(wallet => wallet.chain);
572
590
  const requestBody = {
573
591
  amount: inputAmount.toString(),
574
592
  checkPrerequisites,
@@ -586,8 +604,10 @@ function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, se
586
604
  selectedWallets: selectedWalletsMap,
587
605
  swapperGroups: disabledLiquiditySources,
588
606
  swappersGroupsExclude: true,
589
- //@ts-ignore
590
- slippage: slippage.toString()
607
+ slippage: slippage.toString(),
608
+ ...(checkPrerequisites && {
609
+ blockchains: filteredBlockchains
610
+ })
591
611
  };
592
612
  return requestBody;
593
613
  }
@@ -633,6 +653,61 @@ function calcOutputUsdValue(outputAmount, tokenPrice) {
633
653
  const amount = !!outputAmount ? new BigNumber(outputAmount) : ZERO;
634
654
  return amount.multipliedBy(tokenPrice || 0);
635
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
+ }
636
711
 
637
712
  function searchParamsToToken(tokens, searchParams, chain) {
638
713
  if (!chain) return null;
@@ -669,23 +744,27 @@ function getRequiredBalanceOfWallet(selectedWallet, fee) {
669
744
  if (!relatedFeeStatus) return null;
670
745
  return relatedFeeStatus.requiredAssets;
671
746
  }
672
- function isRouteParametersChanged(prevParams, currentParams) {
673
- 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;
674
- }
675
- function getBestRouteWithCalculatedFees(bestRoute, tokens) {
676
- if (!bestRoute || !bestRoute.result) return null;
677
- const swapsWithFee = (bestRoute?.result?.swaps || []).map(swap => ({
678
- ...swap,
679
- feeInUsd: numberToString(getUsdFeeOfStep(swap, tokens), 0, 2)
680
- }));
681
- return {
682
- ...bestRoute,
683
- result: {
684
- ...bestRoute.result,
685
- swaps: swapsWithFee
686
- }
687
- };
747
+ function isRouteParametersChanged(params) {
748
+ if (params.store === 'bestRoute') {
749
+ const {
750
+ prevState,
751
+ currentState
752
+ } = params;
753
+ return !!currentState.fromToken && !!currentState.toToken && (prevState.fromChain?.name !== currentState.fromChain?.name || prevState.toChain?.name !== currentState.toChain?.name || prevState.fromToken?.symbol !== currentState.fromToken?.symbol || prevState.toToken?.symbol !== currentState.toToken?.symbol || prevState.fromToken?.blockchain !== prevState.fromToken?.blockchain || prevState.toToken?.blockchain !== currentState.toToken?.blockchain || prevState.fromToken?.address !== currentState.fromToken?.address || prevState.toToken?.address !== currentState.toToken?.address || prevState.inputAmount !== currentState.inputAmount);
754
+ } else if (params.store === 'settings') {
755
+ const {
756
+ prevState,
757
+ currentState
758
+ } = params;
759
+ return prevState.slippage !== currentState.slippage || prevState.customSlippage !== currentState.customSlippage || prevState.disabledLiquiditySources?.length !== currentState.disabledLiquiditySources?.length || prevState.infiniteApprove || currentState.infiniteApprove;
760
+ }
761
+ return false;
688
762
  }
763
+ //todo: refactor bestRoute store and add loadingStatus
764
+ const getBestRouteStatus = (loading, error) => {
765
+ if (loading) return 'loading';
766
+ if (error) return 'failed';else return 'success';
767
+ };
689
768
 
690
769
  const createSelectors = _store => {
691
770
  let store = _store;
@@ -836,7 +915,7 @@ const useWalletsStore = /*#__PURE__*/createSelectors( /*#__PURE__*/create()( /*#
836
915
  }
837
916
  });
838
917
  return {
839
- selectedWallets: state.selectedWallets.concat(selectedWallets)
918
+ selectedWallets: selectedWallets
840
919
  };
841
920
  }),
842
921
  setSelectedWallet: wallet => set(state => ({
@@ -868,6 +947,7 @@ useWalletsStore.subscribe(state => state.balances, balances => {
868
947
  }, {
869
948
  equalityFn: shallow
870
949
  });
950
+ const fetchingBalanceSelector = state => !!state.balances.find(wallet => wallet.loading);
871
951
 
872
952
  const getUsdValue = (token, amount) => new BigNumber(amount || ZERO).multipliedBy(token?.usdPrice || 0);
873
953
  const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/create()( /*#__PURE__*/subscribeWithSelector(set => ({
@@ -887,6 +967,7 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/create()( /
887
967
  setBestRoute: bestRoute => set(state => {
888
968
  let outputAmount = null;
889
969
  let outputUsdValue = ZERO;
970
+ if (!state.inputAmount || state.inputAmount === '0') return {};
890
971
  if (!!bestRoute) {
891
972
  outputAmount = !!bestRoute.result?.outputAmount ? new BigNumber(bestRoute.result?.outputAmount) : null;
892
973
  outputUsdValue = calcOutputUsdValue(bestRoute.result?.outputAmount, getBestRouteToTokenUsdPrice(bestRoute) || state.toToken?.usdPrice);
@@ -954,7 +1035,58 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/create()( /
954
1035
  inputUsdValue: getUsdValue(state.fromToken, amount)
955
1036
  })
956
1037
  }));
957
- }
1038
+ },
1039
+ retry: pendingSwap => {
1040
+ const {
1041
+ tokens,
1042
+ blockchains
1043
+ } = useMetaStore.getState().meta;
1044
+ const balances = useWalletsStore.getState().balances;
1045
+ const failedIndex = pendingSwap.status === 'failed' ? pendingSwap.steps.findIndex(s => s.status === 'failed') : null;
1046
+ if (failedIndex === null || failedIndex < 0) return;
1047
+ const firstStep = pendingSwap.steps[0];
1048
+ const lastStep = pendingSwap.steps[pendingSwap.steps.length - 1];
1049
+ const fromChain = blockchains.find(blockchain => blockchain.name === firstStep.fromBlockchain) || null;
1050
+ const toChain = blockchains.find(blockchain => blockchain.name === lastStep.toBlockchain) || null;
1051
+ const fromToken = tokens.find(token => tokensAreEqual(token, {
1052
+ blockchain: firstStep.fromBlockchain,
1053
+ symbol: firstStep.fromSymbol,
1054
+ address: firstStep.fromSymbolAddress
1055
+ }));
1056
+ const toToken = tokens.find(token => tokensAreEqual(token, {
1057
+ blockchain: lastStep.toBlockchain,
1058
+ symbol: lastStep.toSymbol,
1059
+ address: lastStep.toSymbolAddress
1060
+ }));
1061
+ const sortedSourceTokens = getSortedTokens(fromChain, tokens, balances, []);
1062
+ const sortedDestinationTokens = getSortedTokens(toChain, tokens, balances, []);
1063
+ const inputAmount = pendingSwap.inputAmount;
1064
+ set({
1065
+ fromChain,
1066
+ fromToken,
1067
+ inputAmount,
1068
+ outputAmount: null,
1069
+ inputUsdValue: getUsdValue(fromToken || null, inputAmount),
1070
+ outputUsdValue: new BigNumber(0),
1071
+ toChain,
1072
+ toToken,
1073
+ bestRoute: null,
1074
+ loading: false,
1075
+ error: '',
1076
+ sourceTokens: sortedSourceTokens,
1077
+ destinationTokens: sortedDestinationTokens
1078
+ });
1079
+ },
1080
+ switchFromAndTo: () => set(state => ({
1081
+ fromChain: state.toChain,
1082
+ fromToken: state.toToken,
1083
+ toChain: state.fromChain,
1084
+ toToken: state.fromToken,
1085
+ sourceTokens: state.destinationTokens,
1086
+ destinationTokens: state.sourceTokens,
1087
+ inputAmount: state.outputAmount?.toString() || '',
1088
+ inputUsdValue: getUsdValue(state.toToken, state.outputAmount?.toString() || '')
1089
+ }))
958
1090
  }))));
959
1091
  const bestRoute = (bestRouteStore, settingsStore) => {
960
1092
  let abortController = null;
@@ -969,12 +1101,12 @@ const bestRoute = (bestRouteStore, settingsStore) => {
969
1101
  customSlippage,
970
1102
  disabledLiquiditySources
971
1103
  } = settingsStore.getState();
972
- if (!fromToken || !toToken || !inputAmount) return;
1104
+ if (!fromToken || !toToken || !inputAmount || inputAmount === '0') return;
973
1105
  abortController?.abort();
974
1106
  abortController = new AbortController();
975
1107
  const userSlippage = !!customSlippage ? customSlippage : slippage;
976
1108
  const requestBody = createBestRouteRequestBody(fromToken, toToken, inputAmount, [], [], disabledLiquiditySources, userSlippage, false);
977
- bestRouteStore.setState({
1109
+ if (!bestRouteStore.getState().loading) bestRouteStore.setState({
978
1110
  loading: true,
979
1111
  bestRoute: null,
980
1112
  outputAmount: null,
@@ -999,24 +1131,56 @@ const bestRoute = (bestRouteStore, settingsStore) => {
999
1131
  });
1000
1132
  });
1001
1133
  };
1134
+ const debouncedFetchBestRoute = debounce(fetchBestRoute, 600);
1135
+ const bestRouteParamsListener = () => {
1136
+ const {
1137
+ fromToken,
1138
+ toToken,
1139
+ inputAmount,
1140
+ inputUsdValue
1141
+ } = useBestRouteStore.getState();
1142
+ if (!inputAmount || inputAmount === '0' || inputUsdValue.eq(0)) return;
1143
+ if (tokensAreEqual(fromToken, toToken)) return bestRouteStore.setState({
1144
+ loading: false,
1145
+ bestRoute: null,
1146
+ outputAmount: new BigNumber(inputAmount),
1147
+ outputUsdValue: inputUsdValue
1148
+ });
1149
+ if (!bestRouteStore.getState().loading) bestRouteStore.setState({
1150
+ loading: true,
1151
+ bestRoute: null,
1152
+ outputAmount: null,
1153
+ outputUsdValue: new BigNumber(0)
1154
+ });
1155
+ debouncedFetchBestRoute();
1156
+ };
1002
1157
  useBestRouteStore.subscribe(state => ({
1003
1158
  fromChain: state.fromChain,
1004
1159
  fromToken: state.fromToken,
1005
1160
  toChain: state.toChain,
1006
1161
  toToken: state.toToken,
1007
1162
  inputAmount: state.inputAmount
1008
- }), fetchBestRoute.bind(null), {
1009
- equalityFn: (prevState, state) => {
1010
- if (isRouteParametersChanged(prevState, state)) return false;else return true;
1163
+ }), bestRouteParamsListener, {
1164
+ equalityFn: (prevState, currentState) => {
1165
+ if (isRouteParametersChanged({
1166
+ store: 'bestRoute',
1167
+ prevState,
1168
+ currentState
1169
+ })) return false;else return true;
1011
1170
  }
1012
1171
  });
1013
1172
  useSettingsStore.subscribe(state => ({
1014
1173
  slippage: state.slippage,
1015
1174
  customSlippage: state.customSlippage,
1016
- disabledLiquiditySources: state.disabledLiquiditySources
1017
- }), fetchBestRoute.bind(null), {
1018
- equalityFn: (prevState, state) => {
1019
- if (isRouteParametersChanged(prevState, state)) return false;else return true;
1175
+ disabledLiquiditySources: state.disabledLiquiditySources,
1176
+ infiniteApprove: state.infiniteApprove
1177
+ }), bestRouteParamsListener, {
1178
+ equalityFn: (prevState, currentState) => {
1179
+ if (isRouteParametersChanged({
1180
+ store: 'settings',
1181
+ prevState,
1182
+ currentState
1183
+ })) return false;else return true;
1020
1184
  }
1021
1185
  });
1022
1186
  return {
@@ -1039,11 +1203,15 @@ var SearchParams;
1039
1203
  const useUiStore = /*#__PURE__*/createSelectors( /*#__PURE__*/create()(set => ({
1040
1204
  connectWalletsButtonDisabled: false,
1041
1205
  selectedSwapRequestId: null,
1206
+ currentPage: '',
1042
1207
  toggleConnectWalletsButton: () => set(state => ({
1043
1208
  connectWalletsButtonDisabled: !state.connectWalletsButtonDisabled
1044
1209
  })),
1045
1210
  setSelectedSwap: requestId => set({
1046
1211
  selectedSwapRequestId: requestId
1212
+ }),
1213
+ setCurrentPage: path => set({
1214
+ currentPage: path
1047
1215
  })
1048
1216
  })));
1049
1217
 
@@ -1084,7 +1252,7 @@ function UpdateUrl() {
1084
1252
  toChainString = '',
1085
1253
  toTokenString = '',
1086
1254
  fromAmount = '';
1087
- if (loadingStatus !== 'success' && ![navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname)) {
1255
+ if (loadingStatus !== 'success' && location.pathname != navigationRoutes.confirmSwap) {
1088
1256
  fromChainString = searchParamsRef.current[SearchParams.FROM_CHAIN];
1089
1257
  fromTokenString = searchParamsRef.current[SearchParams.FROM_TOKEN];
1090
1258
  toChainString = searchParamsRef.current[SearchParams.TO_CHAIN];
@@ -1177,65 +1345,18 @@ function UpdateUrl() {
1177
1345
  return null;
1178
1346
  }
1179
1347
 
1180
- const ButtonsContainer = /*#__PURE__*/styled('div', {
1181
- display: 'flex'
1182
- });
1183
- function HeaderButtons(props) {
1184
- const {
1185
- onClickRefresh
1186
- } = props;
1187
- const navigate = useNavigate();
1188
- return React.createElement(ButtonsContainer, null, React.createElement(Tooltip, {
1189
- content: "Refresh"
1190
- }, React.createElement(Button, {
1191
- variant: "ghost",
1192
- onClick: onClickRefresh
1193
- }, React.createElement(RetryIcon, {
1194
- size: 24
1195
- }))), React.createElement(Tooltip, {
1196
- content: "Transactions History"
1197
- }, React.createElement(Button, {
1198
- variant: "ghost",
1199
- onClick: () => navigate(navigationRoutes.swaps)
1200
- }, React.createElement(HistoryIcon, {
1201
- size: 24
1202
- }))), React.createElement(Tooltip, {
1203
- content: "Settings"
1204
- }, React.createElement(Button, {
1205
- variant: "ghost",
1206
- onClick: () => navigate(navigationRoutes.settings)
1207
- }, React.createElement(SettingsIcon, {
1208
- size: 24
1209
- }))));
1210
- }
1211
-
1212
- const HeaderContainer = /*#__PURE__*/styled('div', {
1213
- display: 'flex',
1214
- justifyContent: 'space-between',
1215
- alignItems: 'center',
1216
- width: '100%',
1217
- padding: '$16 0'
1218
- });
1219
- function Header(props) {
1348
+ function PercentageChange(props) {
1220
1349
  const {
1221
- onClickRefresh,
1222
- title,
1223
- titleSize,
1224
- titleWeight
1350
+ inputUsdValue,
1351
+ outputUsdValue
1225
1352
  } = props;
1226
- const {
1227
- t
1228
- } = useTranslation();
1229
- const titleStyle = css({
1230
- fontSize: `${titleSize}px !important`,
1231
- fontWeight: `${titleWeight} !important`
1232
- });
1233
- return React.createElement(HeaderContainer, null, React.createElement(Typography, {
1234
- variant: "h4",
1235
- className: titleStyle()
1236
- }, title ? t(title.toLocaleLowerCase()) : ''), React.createElement(HeaderButtons, {
1237
- onClickRefresh: onClickRefresh
1238
- }));
1353
+ if (!inputUsdValue || !outputUsdValue || !outputUsdValue.gt(0)) return null;
1354
+ const percentageChange = getPercentageChange(inputUsdValue.toNumber(), outputUsdValue.toNumber());
1355
+ const showPercentageChange = percentageChange?.lt(0);
1356
+ return React.createElement(React.Fragment, null, showPercentageChange && React.createElement(Typography, {
1357
+ variant: "caption",
1358
+ color: "$error500"
1359
+ }, `(${numberToString(percentageChange, 0, 2)}%)`));
1239
1360
  }
1240
1361
 
1241
1362
  const Box = /*#__PURE__*/styled('div', {
@@ -1281,6 +1402,13 @@ const Container = /*#__PURE__*/styled('div', {
1281
1402
  '.amount': {
1282
1403
  width: '30%'
1283
1404
  }
1405
+ },
1406
+ '.output-usd': {
1407
+ display: 'flex',
1408
+ div: {
1409
+ display: 'flex',
1410
+ paddingLeft: '$8'
1411
+ }
1284
1412
  }
1285
1413
  });
1286
1414
  const StyledImage = /*#__PURE__*/styled('img', {
@@ -1365,10 +1493,15 @@ function TokenInfo(props) {
1365
1493
  type: "primary",
1366
1494
  variant: "ghost",
1367
1495
  size: "compact"
1368
- }, t('Max')))) : React.createElement(Typography, {
1496
+ }, t('Max')))) : React.createElement("div", {
1497
+ className: "output-usd"
1498
+ }, React.createElement(PercentageChange, {
1499
+ inputUsdValue: inputUsdValue,
1500
+ outputUsdValue: props.outputUsdValue
1501
+ }), React.createElement("div", null, React.createElement(Typography, {
1369
1502
  variant: "caption",
1370
1503
  color: "neutrals600"
1371
- }, `$${numberToString(props.outputUsdValue)}`)), React.createElement("div", {
1504
+ }, `$${numberToString(props.outputUsdValue)}`)))), React.createElement("div", {
1372
1505
  className: "form"
1373
1506
  }, React.createElement(Button, {
1374
1507
  className: "selectors",
@@ -1525,6 +1658,39 @@ const errorMessages = {
1525
1658
  genericServerError: 'Error connecting server, please reload the app and try again'
1526
1659
  };
1527
1660
 
1661
+ const ButtonsContainer = /*#__PURE__*/styled('div', {
1662
+ display: 'flex'
1663
+ });
1664
+ function HeaderButtons(props) {
1665
+ const {
1666
+ onClickRefresh
1667
+ } = props;
1668
+ const navigate = useNavigate();
1669
+ return React.createElement(ButtonsContainer, null, React.createElement(Tooltip, {
1670
+ content: "Refresh"
1671
+ }, React.createElement(Button, {
1672
+ variant: "ghost",
1673
+ onClick: onClickRefresh,
1674
+ disabled: !onClickRefresh
1675
+ }, React.createElement(RetryIcon, {
1676
+ size: 24
1677
+ }))), React.createElement(Tooltip, {
1678
+ content: "Transactions History"
1679
+ }, React.createElement(Button, {
1680
+ variant: "ghost",
1681
+ onClick: () => navigate(navigationRoutes.swaps)
1682
+ }, React.createElement(HistoryIcon, {
1683
+ size: 24
1684
+ }))), React.createElement(Tooltip, {
1685
+ content: "Settings"
1686
+ }, React.createElement(Button, {
1687
+ variant: "ghost",
1688
+ onClick: () => navigate(navigationRoutes.settings)
1689
+ }, React.createElement(SettingsIcon, {
1690
+ size: 24
1691
+ }))));
1692
+ }
1693
+
1528
1694
  const Container$2 = /*#__PURE__*/styled('div', {
1529
1695
  display: 'flex',
1530
1696
  flexDirection: 'column'
@@ -1549,9 +1715,7 @@ const Alerts = /*#__PURE__*/styled('div', {
1549
1715
  });
1550
1716
  function Home(props) {
1551
1717
  const {
1552
- title = 'SWAP',
1553
- titleSize = 18,
1554
- titleWeight = 600
1718
+ title = 'SWAP'
1555
1719
  } = props;
1556
1720
  const isRouterInContext = useInRouterContext();
1557
1721
  const navigate = useNavigate();
@@ -1560,10 +1724,6 @@ function Home(props) {
1560
1724
  const fromToken = useBestRouteStore.use.fromToken();
1561
1725
  const toChain = useBestRouteStore.use.toChain();
1562
1726
  const toToken = useBestRouteStore.use.toToken();
1563
- const setFromChain = useBestRouteStore.use.setFromChain();
1564
- const setFromToken = useBestRouteStore.use.setFromToken();
1565
- const setToChain = useBestRouteStore.use.setToChain();
1566
- const setToToken = useBestRouteStore.use.setToToken();
1567
1727
  const setInputAmount = useBestRouteStore.use.setInputAmount();
1568
1728
  const inputUsdValue = useBestRouteStore.use.inputUsdValue();
1569
1729
  const inputAmount = useBestRouteStore.use.inputAmount();
@@ -1575,14 +1735,8 @@ function Home(props) {
1575
1735
  const bestRouteError = useBestRouteStore.use.error();
1576
1736
  const loadingMetaStatus = useMetaStore.use.loadingStatus();
1577
1737
  const accounts = useWalletsStore.use.accounts();
1578
- const swithFromAndTo = () => {
1579
- setFromChain(toChain);
1580
- setFromToken(toToken);
1581
- setToChain(fromChain);
1582
- setToToken(fromToken);
1583
- setInputAmount(outputAmount?.toString() || '');
1584
- setCount(prev => prev + 1);
1585
- };
1738
+ const setCurrentPage = useUiStore.use.setCurrentPage();
1739
+ const switchFromAndTo = useBestRouteStore.use.switchFromAndTo();
1586
1740
  const errorMessage = loadingMetaStatus === 'failed' ? errorMessages.genericServerError : bestRouteError;
1587
1741
  const needsToWarnEthOnPath = false;
1588
1742
  const showBestRoute = inputAmount && (!!bestRoute || fetchingBestRoute || bestRouteError);
@@ -1598,11 +1752,15 @@ function Home(props) {
1598
1752
  const swapButtonState = getSwapButtonState(loadingMetaStatus, accounts, fetchingBestRoute, bestRoute, hasLimitError(bestRoute), highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath, inputIsZero);
1599
1753
  const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
1600
1754
  const highFee = hasHighFee(totalFeeInUsd);
1601
- return React.createElement(Container$2, null, React.createElement(Header, {
1755
+ useEffect(() => {
1756
+ setCurrentPage(navigationRoutes.home);
1757
+ return setCurrentPage.bind(null, '');
1758
+ }, []);
1759
+ return React.createElement(Container$2, null, React.createElement(Header$1, {
1602
1760
  title: title,
1603
- titleSize: titleSize,
1604
- titleWeight: titleWeight,
1605
- onClickRefresh: fetchBestRoute
1761
+ suffix: React.createElement(HeaderButtons, {
1762
+ onClickRefresh: !!bestRoute ? fetchBestRoute : undefined
1763
+ })
1606
1764
  }), React.createElement(FromContainer, null, React.createElement(TokenInfo, {
1607
1765
  type: "From",
1608
1766
  chain: fromChain,
@@ -1611,9 +1769,12 @@ function Home(props) {
1611
1769
  inputAmount: inputAmount
1612
1770
  }), React.createElement(SwitchButtonContainer, null, React.createElement(Button, {
1613
1771
  variant: "ghost",
1614
- onClick: swithFromAndTo
1772
+ onClick: () => {
1773
+ switchFromAndTo();
1774
+ setCount(prev => prev + 1);
1775
+ }
1615
1776
  }, React.createElement(VerticalSwapIcon, {
1616
- size: 24
1777
+ size: 32
1617
1778
  }), isRouterInContext && React.createElement(SwithFromAndTo, {
1618
1779
  count: count
1619
1780
  })))), React.createElement(TokenInfo, {
@@ -1647,7 +1808,7 @@ function Home(props) {
1647
1808
  disabled: swapButtonState.disabled,
1648
1809
  onClick: () => {
1649
1810
  if (swapButtonState.title === 'Connect Wallet') navigate(navigationRoutes.wallets);else {
1650
- navigate(navigationRoutes.confirmWallets, {
1811
+ navigate(navigationRoutes.confirmSwap, {
1651
1812
  replace: true
1652
1813
  });
1653
1814
  }
@@ -1664,12 +1825,12 @@ const Route = _ref => {
1664
1825
  const navigate = useNavigate$1();
1665
1826
  const ref = useRef(true);
1666
1827
  useEffect(() => {
1667
- if ([navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname) && ref.current) navigate(navigationRoutes.home + location.search, {
1828
+ if (location.pathname === navigationRoutes.confirmSwap && ref.current) navigate(navigationRoutes.home + location.search, {
1668
1829
  state: 'redirect'
1669
1830
  });
1670
1831
  ref.current = false;
1671
1832
  }, []);
1672
- if ([navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname) && ref.current) return React.createElement(Home, Object.assign({}, props));
1833
+ if (location.pathname === navigationRoutes.confirmSwap && ref.current) return React.createElement(Home, Object.assign({}, props));
1673
1834
  return React.createElement(React.Fragment, null, " ", children);
1674
1835
  };
1675
1836
  function AppRouter(_ref2) {
@@ -1679,52 +1840,34 @@ function AppRouter(_ref2) {
1679
1840
  } = _ref2;
1680
1841
  const isRouterInContext = useInRouterContext$1();
1681
1842
  const Router = isRouterInContext ? Route : MemoryRouter;
1682
- return React.createElement(React.Fragment, null, React.createElement(Router, Object.assign({}, props), children), isRouterInContext && React.createElement(UpdateUrl, null));
1683
- }
1684
-
1685
- function ChangeSlippageButton() {
1686
- const navigate = useNavigate();
1687
- return React.createElement(Button, {
1688
- type: "primary",
1689
- variant: "outlined",
1690
- size: "small",
1691
- onClick: () => navigate(navigationRoutes.settings)
1692
- }, "Change Slippage");
1693
- }
1694
-
1695
- function HighSlippageWarning(props) {
1696
1843
  const {
1697
- selectedSlippage
1698
- } = props;
1699
- return React.createElement(Alert, {
1700
- type: "warning",
1701
- footer: React.createElement(ChangeSlippageButton, null)
1702
- }, "Caution, your slippage is high (=", selectedSlippage, "). Your trade may be front run.");
1703
- }
1704
-
1705
- function ConfirmSwapExtraMessages(props) {
1706
- const {
1707
- selectedSlippage
1708
- } = props;
1709
- const highSlippage = selectedSlippage >= HIGH_SLIPPAGE;
1710
- return React.createElement(React.Fragment, null, highSlippage && React.createElement(HighSlippageWarning, {
1711
- selectedSlippage: selectedSlippage
1712
- }));
1844
+ blockchains
1845
+ } = useMetaStore.use.meta();
1846
+ const evmChains = blockchains.filter(isEvmBlockchain);
1847
+ useQueueManager({
1848
+ lastConnectedWallet: props.lastConnectedWallet,
1849
+ clearDisconnectedWallet: props.clearDisconnectedWallet,
1850
+ disconnectedWallet: props.disconnectedWallet,
1851
+ evmChains,
1852
+ notifier: () => {}
1853
+ });
1854
+ return React.createElement(React.Fragment, null, React.createElement(Router, Object.assign({}, props), children), isRouterInContext && React.createElement(UpdateUrl, null));
1713
1855
  }
1714
1856
 
1715
1857
  function useNavigateBack() {
1716
1858
  const isRouterInContext = useInRouterContext();
1717
1859
  const navigate = useNavigate();
1718
1860
  const navigateBackFrom = currentRoute => {
1861
+ if (currentRoute === navigationRoutes.swapDetails) return navigate(navigationRoutes.swaps, {
1862
+ replace: true
1863
+ });
1719
1864
  if (!isRouterInContext || window.history.state && window.history.state.idx > 0) navigate(-1);else {
1720
- if ([navigationRoutes.fromChain, navigationRoutes.fromToken, navigationRoutes.toChain, navigationRoutes.toToken, navigationRoutes.settings, navigationRoutes.wallets, navigationRoutes.swaps, navigationRoutes.confirmWallets].includes(currentRoute)) navigate(navigationRoutes.home, {
1865
+ if ([navigationRoutes.fromChain, navigationRoutes.fromToken, navigationRoutes.toChain, navigationRoutes.toToken, navigationRoutes.settings, navigationRoutes.wallets, navigationRoutes.swaps, navigationRoutes.confirmSwap].includes(currentRoute)) navigate(navigationRoutes.home, {
1721
1866
  replace: true
1722
1867
  });else if (currentRoute === navigationRoutes.liquiditySources) navigate(navigationRoutes.settings, {
1723
1868
  replace: true
1724
1869
  });else if (currentRoute === navigationRoutes.swapDetails) navigate(navigationRoutes.swaps, {
1725
1870
  replace: true
1726
- });else if (currentRoute === navigationRoutes.confirmSwap) navigate(navigationRoutes.confirmWallets, {
1727
- replace: true
1728
1871
  });
1729
1872
  }
1730
1873
  };
@@ -1733,122 +1876,197 @@ function useNavigateBack() {
1733
1876
  };
1734
1877
  }
1735
1878
 
1736
- var ConfirmSwapErrorTypes;
1737
- (function (ConfirmSwapErrorTypes) {
1738
- ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["NO_ROUTE"] = 0] = "NO_ROUTE";
1739
- ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS"] = 1] = "ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS";
1740
- ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["REQUEST_FAILED"] = 2] = "REQUEST_FAILED";
1741
- ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["INSUFFICIENT_SLIPPAGE"] = 3] = "INSUFFICIENT_SLIPPAGE";
1742
- })(ConfirmSwapErrorTypes || (ConfirmSwapErrorTypes = {}));
1743
- var ConfirmSwapWarningTypes;
1744
- (function (ConfirmSwapWarningTypes) {
1745
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_UPDATED"] = 0] = "ROUTE_UPDATED";
1746
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_SWAPPERS_UPDATED"] = 1] = "ROUTE_SWAPPERS_UPDATED";
1747
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_COINS_UPDATED"] = 2] = "ROUTE_COINS_UPDATED";
1748
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_AND_OUTPUT_AMOUNT_UPDATED"] = 3] = "ROUTE_AND_OUTPUT_AMOUNT_UPDATED";
1749
- ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["INSUFFICIENT_BALANCE"] = 4] = "INSUFFICIENT_BALANCE";
1750
- })(ConfirmSwapWarningTypes || (ConfirmSwapWarningTypes = {}));
1751
-
1752
- function MinRequiredSlippage(_ref) {
1753
- let {
1754
- minRequiredSlippage
1755
- } = _ref;
1756
- return React.createElement(Typography, {
1757
- variant: "body2"
1758
- }, "We recommend you to increase slippage to at least \u00A0", minRequiredSlippage, "\u00A0 for this route.", React.createElement(ChangeSlippageButton, null));
1759
- }
1760
-
1761
- function ConfirmSwapErrors(errors) {
1762
- return errors.flatMap(error => {
1763
- switch (error.type) {
1764
- case ConfirmSwapErrorTypes.NO_ROUTE:
1765
- return React.createElement(Typography, {
1766
- variant: "body2"
1767
- }, "No routes found. Please try again later.");
1768
- case ConfirmSwapErrorTypes.REQUEST_FAILED:
1769
- return React.createElement(Typography, {
1770
- variant: "body2"
1771
- }, `Failed to confirm swap ${error.status ? `'status': ${error.status})` : ''}, please try again.`);
1772
- case ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS:
1773
- return React.createElement(Typography, {
1774
- variant: "body2"
1775
- }, "Route updated and price impact is too high, try again later!");
1776
- case ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE:
1777
- return React.createElement(MinRequiredSlippage, {
1778
- minRequiredSlippage: error.minRequiredSlippage
1779
- });
1780
- default:
1781
- return [];
1782
- }
1783
- });
1784
- }
1785
-
1786
- const List = /*#__PURE__*/styled('ul', {
1879
+ const Box$1 = /*#__PURE__*/styled('div', {
1880
+ display: 'flex',
1881
+ flexDirection: 'column',
1882
+ width: '100%'
1883
+ });
1884
+ const Container$3 = /*#__PURE__*/styled('div', {
1885
+ boxSizing: 'border-box',
1886
+ borderRadius: '$5',
1887
+ padding: '$8 $16 $16 $16',
1787
1888
  variants: {
1788
- showListStyle: {
1789
- true: {
1790
- paddingLeft: '$24'
1889
+ type: {
1890
+ filled: {
1891
+ backgroundColor: '$neutrals300'
1892
+ },
1893
+ outlined: {
1894
+ border: '1px solid $neutrals300'
1791
1895
  }
1792
1896
  }
1793
- }
1794
- });
1795
- const ListItem = /*#__PURE__*/styled('li', {
1796
- variants: {
1797
- showListStyle: {
1798
- true: {
1799
- listStyleType: 'disc',
1800
- listStylePosition: 'outside'
1897
+ },
1898
+ defaultVariants: {
1899
+ type: 'filled'
1900
+ },
1901
+ '.head': {
1902
+ display: 'flex',
1903
+ justifyContent: 'space-between',
1904
+ alignItems: 'center',
1905
+ minHeight: '32px',
1906
+ '.usd-value': {
1907
+ paddingLeft: '$8'
1908
+ }
1909
+ },
1910
+ '.form': {
1911
+ display: 'flex',
1912
+ width: '100%',
1913
+ padding: '$2 0',
1914
+ '.selectors': {
1915
+ width: '35%',
1916
+ '._text': {
1917
+ whiteSpace: 'nowrap',
1918
+ overflow: 'hidden',
1919
+ textOverflow: 'ellipsis'
1801
1920
  }
1921
+ },
1922
+ '.amount': {
1923
+ width: '30%'
1802
1924
  }
1803
1925
  }
1804
1926
  });
1805
- const Message = /*#__PURE__*/styled(Typography, {
1806
- display: 'block'
1927
+ const StyledImage$1 = /*#__PURE__*/styled('img', {
1928
+ width: '$24',
1929
+ maxHeight: '$24'
1807
1930
  });
1808
- function BalanceWarnings(_ref) {
1809
- let {
1810
- messages
1811
- } = _ref;
1812
- const showListStyle = messages.length > 1;
1813
- return React.createElement(List, {
1814
- showListStyle: showListStyle
1815
- }, messages.map(warning => React.createElement(ListItem, {
1816
- showListStyle: showListStyle
1817
- }, React.createElement(Message, {
1818
- variant: "body2"
1819
- }, warning))));
1931
+ const ImagePlaceholder$1 = /*#__PURE__*/styled('span', {
1932
+ width: '24px',
1933
+ height: '24px',
1934
+ backgroundColor: '$neutrals300',
1935
+ borderRadius: '99999px'
1936
+ });
1937
+ const OutputContainer$1 = /*#__PURE__*/styled('div', {
1938
+ windth: '100%',
1939
+ height: '$48',
1940
+ borderRadius: '$5',
1941
+ backgroundColor: '$background',
1942
+ border: '1px solid transparent',
1943
+ position: 'relative',
1944
+ display: 'flex',
1945
+ alignItems: 'center',
1946
+ paddingLeft: '$8',
1947
+ paddingRight: '$8'
1948
+ });
1949
+ function TokenPreview(props) {
1950
+ const {
1951
+ chain,
1952
+ token,
1953
+ loadingStatus,
1954
+ percentageChange
1955
+ } = props;
1956
+ const {
1957
+ t
1958
+ } = useTranslation();
1959
+ const ItemSuffix = React.createElement("div", {
1960
+ style: {
1961
+ display: 'flex',
1962
+ justifyContent: 'center',
1963
+ alignItems: 'center'
1964
+ }
1965
+ }, loadingStatus === 'failed' && React.createElement(InfoCircleIcon, {
1966
+ color: "error",
1967
+ size: 24
1968
+ }));
1969
+ return React.createElement(Box$1, null, React.createElement(Container$3, {
1970
+ type: 'outlined'
1971
+ }, React.createElement("div", {
1972
+ className: "head"
1973
+ }, React.createElement(Typography, {
1974
+ variant: "body2",
1975
+ color: "neutrals800"
1976
+ }, props.label), React.createElement("div", null, percentageChange, props.usdValue && React.createElement(Typography, {
1977
+ variant: "caption",
1978
+ color: "neutrals600",
1979
+ className: "usd-value"
1980
+ }, `$${numberToString(props.usdValue)}`))), React.createElement("div", {
1981
+ className: "form"
1982
+ }, React.createElement(Button, {
1983
+ className: "selectors",
1984
+ variant: "outlined",
1985
+ loading: loadingStatus === 'loading',
1986
+ prefix: loadingStatus === 'success' && chain ? React.createElement(StyledImage$1, {
1987
+ src: chain.logo
1988
+ }) : React.createElement(ImagePlaceholder$1, null),
1989
+ suffix: ItemSuffix,
1990
+ align: "start",
1991
+ size: "large"
1992
+ }, loadingStatus === 'success' && chain ? chain.displayName : t('Chain')), React.createElement(Spacer, {
1993
+ size: 12
1994
+ }), React.createElement(Button, {
1995
+ className: "selectors",
1996
+ variant: "outlined",
1997
+ loading: loadingStatus === 'loading',
1998
+ prefix: loadingStatus === 'success' && token ? React.createElement(StyledImage$1, {
1999
+ src: token.image
2000
+ }) : React.createElement(ImagePlaceholder$1, null),
2001
+ suffix: ItemSuffix,
2002
+ size: "large",
2003
+ align: "start"
2004
+ }, loadingStatus === 'success' && token ? token.symbol : t('Token')), React.createElement(Spacer, {
2005
+ size: 12
2006
+ }), React.createElement("div", {
2007
+ className: "amount"
2008
+ }, React.createElement(OutputContainer$1, null, React.createElement(Typography, {
2009
+ variant: "h4"
2010
+ }, props.amount))))));
1820
2011
  }
1821
2012
 
1822
- function ConfirmSwapWarnings(warnings) {
1823
- return warnings.flatMap(warning => {
1824
- switch (warning.type) {
1825
- case ConfirmSwapWarningTypes.ROUTE_UPDATED:
1826
- return React.createElement(Typography, {
1827
- variant: "body2"
1828
- }, "Route has been updated.");
1829
- case ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED:
1830
- return React.createElement(Typography, {
1831
- variant: "body2"
1832
- }, `Output amount changed to ${warning.newOutputAmount}
1833
- (${warning.percentageChange}% change).`);
1834
- case ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED:
1835
- return React.createElement(Typography, {
1836
- variant: "body2"
1837
- }, "Route swappers has been updated.");
1838
- case ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED:
1839
- return React.createElement(Typography, {
1840
- variant: "body2"
1841
- }, "Route internal coins has been updated.");
1842
- case ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE:
1843
- return React.createElement(BalanceWarnings, {
1844
- messages: warning.messages
1845
- });
1846
- default:
1847
- return [];
1848
- }
1849
- });
2013
+ const Container$4 = /*#__PURE__*/styled('div', {
2014
+ display: 'flex',
2015
+ alignItems: 'center',
2016
+ justifyContent: 'space-between',
2017
+ padding: '$8',
2018
+ borderRadius: '$5',
2019
+ backgroundColor: '$neutrals300',
2020
+ color: '$neutrals800',
2021
+ fontSize: '$12',
2022
+ '.routes': {
2023
+ display: 'flex',
2024
+ alignItems: 'center'
2025
+ },
2026
+ '.fee': {
2027
+ display: 'flex',
2028
+ alignItems: 'center'
2029
+ }
2030
+ });
2031
+ function RoutesOverview(props) {
2032
+ if (!props.routes) return null;
2033
+ const swaps = props.routes.result?.swaps;
2034
+ return React.createElement(Container$4, null, React.createElement("div", {
2035
+ className: "routes"
2036
+ }, swaps?.map((swap, idx) => {
2037
+ const isLast = idx + 1 == swaps.length;
2038
+ return React.createElement(React.Fragment, null, React.createElement("div", {
2039
+ className: "route"
2040
+ }, swap.from.symbol), React.createElement(ChevronRightIcon, {
2041
+ size: 12
2042
+ }), isLast ? React.createElement("div", {
2043
+ className: "route"
2044
+ }, swap.to.symbol) : null);
2045
+ })), props.totalFee ? React.createElement("div", {
2046
+ className: "fee"
2047
+ }, React.createElement(GasIcon, {
2048
+ size: 12
2049
+ }), React.createElement(Spacer, {
2050
+ size: 4
2051
+ }), "$", props.totalFee) : null);
1850
2052
  }
1851
2053
 
2054
+ var ConfirmSwapErrorTypes;
2055
+ (function (ConfirmSwapErrorTypes) {
2056
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["NO_ROUTE"] = 0] = "NO_ROUTE";
2057
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS"] = 1] = "ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS";
2058
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["REQUEST_FAILED"] = 2] = "REQUEST_FAILED";
2059
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["INSUFFICIENT_SLIPPAGE"] = 3] = "INSUFFICIENT_SLIPPAGE";
2060
+ })(ConfirmSwapErrorTypes || (ConfirmSwapErrorTypes = {}));
2061
+ var ConfirmSwapWarningTypes;
2062
+ (function (ConfirmSwapWarningTypes) {
2063
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_UPDATED"] = 0] = "ROUTE_UPDATED";
2064
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_SWAPPERS_UPDATED"] = 1] = "ROUTE_SWAPPERS_UPDATED";
2065
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_COINS_UPDATED"] = 2] = "ROUTE_COINS_UPDATED";
2066
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_AND_OUTPUT_AMOUNT_UPDATED"] = 3] = "ROUTE_AND_OUTPUT_AMOUNT_UPDATED";
2067
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["INSUFFICIENT_BALANCE"] = 4] = "INSUFFICIENT_BALANCE";
2068
+ })(ConfirmSwapWarningTypes || (ConfirmSwapWarningTypes = {}));
2069
+
1852
2070
  function useConfirmSwap() {
1853
2071
  const fromToken = useBestRouteStore.use.fromToken();
1854
2072
  const toToken = useBestRouteStore.use.toToken();
@@ -1889,6 +2107,7 @@ function useConfirmSwap() {
1889
2107
  proceedAnywayRef.current = false;
1890
2108
  if (confiremedRouteRef.current) {
1891
2109
  const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRouteRef.current, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
2110
+ //@ts-ignore
1892
2111
  return newSwap;
1893
2112
  }
1894
2113
  return;
@@ -1951,6 +2170,7 @@ function useConfirmSwap() {
1951
2170
  disabledSwappersGroups: disabledLiquiditySources
1952
2171
  };
1953
2172
  const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRoute, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
2173
+ //@ts-ignore
1954
2174
  return newSwap;
1955
2175
  } else if (!proceedAnywayRef.current) {
1956
2176
  proceedAnywayRef.current = true;
@@ -1980,63 +2200,269 @@ function useConfirmSwap() {
1980
2200
  };
1981
2201
  }
1982
2202
 
1983
- function ConfirmSwapPage() {
1984
- const setSelectedSwap = useUiStore.use.setSelectedSwap();
1985
- const {
1986
- navigateBackFrom
1987
- } = useNavigateBack();
1988
- const {
1989
- manager
1990
- } = useManager();
2203
+ function ChangeSlippageButton() {
1991
2204
  const navigate = useNavigate();
1992
- const bestRoute = useBestRouteStore.use.bestRoute();
1993
- const fetchingBestRoute = useBestRouteStore.use.loading();
1994
- const {
1995
- tokens
1996
- } = useMetaStore.use.meta();
1997
- const slippage = useSettingsStore.use.slippage();
1998
- const customSlippage = useSettingsStore.use.customSlippage();
1999
- const selectedSlippage = customSlippage || slippage;
2000
- const {
2001
- loading,
2002
- errors,
2003
- warnings,
2004
- confirmSwap
2005
- } = useConfirmSwap();
2006
- const showHighSlippageWarning = !errors.find(error => error.type === ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE);
2007
- return React.createElement(ConfirmSwap, {
2008
- onConfirm: () => {
2009
- confirmSwap?.().then(swap => {
2010
- if (swap) {
2011
- manager?.create('swap', {
2012
- swapDetails: swap
2013
- }, {
2014
- id: swap.requestId
2015
- });
2016
- setSelectedSwap(swap.requestId);
2017
- navigate(navigationRoutes.swaps + `/${swap.requestId}`, {
2018
- replace: true
2019
- });
2020
- }
2021
- });
2022
- },
2023
- onBack: navigateBackFrom.bind(null, navigationRoutes.confirmSwap),
2024
- bestRoute: getBestRouteWithCalculatedFees(bestRoute, tokens),
2025
- loading: loading,
2026
- errors: ConfirmSwapErrors(errors),
2027
- warnings: ConfirmSwapWarnings(warnings),
2028
- extraMessages: showHighSlippageWarning && React.createElement(ConfirmSwapExtraMessages, {
2029
- selectedSlippage: selectedSlippage
2030
- }),
2031
- confirmButtonTitle: warnings.length > 0 || errors.length > 0 ? 'Proceed anyway!' : 'Confirm swap!',
2032
- confirmButtonDisabled: fetchingBestRoute
2033
- });
2205
+ return React.createElement(Button, {
2206
+ type: "primary",
2207
+ variant: "outlined",
2208
+ size: "small",
2209
+ onClick: () => navigate(navigationRoutes.settings)
2210
+ }, "Change Slippage");
2034
2211
  }
2035
2212
 
2036
- const getPendingSwaps = manager => {
2037
- const result = [];
2038
- manager?.getAll().forEach((q, id) => {
2039
- const storage = q.list.getStorage();
2213
+ const StyledMessage = /*#__PURE__*/styled(Typography, {
2214
+ color: '$error500 !important'
2215
+ });
2216
+ function MinRequiredSlippage(_ref) {
2217
+ let {
2218
+ minRequiredSlippage
2219
+ } = _ref;
2220
+ return React.createElement(StyledMessage, {
2221
+ variant: "body2"
2222
+ }, "We recommend you to increase slippage to at least \u00A0", minRequiredSlippage, "\u00A0 for this route.", React.createElement(Spacer, {
2223
+ size: 8,
2224
+ direction: "vertical"
2225
+ }), React.createElement(ChangeSlippageButton, null));
2226
+ }
2227
+
2228
+ function ConfirmSwapErrors(errors) {
2229
+ return errors.flatMap(error => {
2230
+ switch (error.type) {
2231
+ case ConfirmSwapErrorTypes.NO_ROUTE:
2232
+ return React.createElement(Typography, {
2233
+ variant: "body2"
2234
+ }, "No routes found. Please try again later.");
2235
+ case ConfirmSwapErrorTypes.REQUEST_FAILED:
2236
+ return React.createElement(Typography, {
2237
+ variant: "body2"
2238
+ }, `Failed to confirm swap ${error.status ? `'status': ${error.status})` : ''}, please try again.`);
2239
+ case ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS:
2240
+ return React.createElement(Typography, {
2241
+ variant: "body2"
2242
+ }, "Route updated and price impact is too high, try again later!");
2243
+ case ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE:
2244
+ return React.createElement(MinRequiredSlippage, {
2245
+ minRequiredSlippage: error.minRequiredSlippage
2246
+ });
2247
+ default:
2248
+ return [];
2249
+ }
2250
+ });
2251
+ }
2252
+
2253
+ const List = /*#__PURE__*/styled('ul', {
2254
+ variants: {
2255
+ showListStyle: {
2256
+ true: {
2257
+ paddingLeft: '$24'
2258
+ }
2259
+ }
2260
+ }
2261
+ });
2262
+ const ListItem = /*#__PURE__*/styled('li', {
2263
+ variants: {
2264
+ showListStyle: {
2265
+ true: {
2266
+ listStyleType: 'disc',
2267
+ listStylePosition: 'outside'
2268
+ }
2269
+ }
2270
+ }
2271
+ });
2272
+ const Message = /*#__PURE__*/styled(Typography, {
2273
+ display: 'block',
2274
+ color: '$warning500 !important'
2275
+ });
2276
+ function BalanceWarnings(_ref) {
2277
+ let {
2278
+ messages
2279
+ } = _ref;
2280
+ const showListStyle = messages.length > 1;
2281
+ return React.createElement(List, {
2282
+ showListStyle: showListStyle
2283
+ }, messages.map(warning => React.createElement(ListItem, {
2284
+ showListStyle: showListStyle
2285
+ }, React.createElement(Message, {
2286
+ variant: "body2"
2287
+ }, warning))));
2288
+ }
2289
+
2290
+ function ConfirmSwapWarnings(warnings) {
2291
+ return warnings.flatMap(warning => {
2292
+ switch (warning.type) {
2293
+ case ConfirmSwapWarningTypes.ROUTE_UPDATED:
2294
+ return React.createElement(Typography, {
2295
+ variant: "body2"
2296
+ }, "Route has been updated.");
2297
+ case ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED:
2298
+ return React.createElement(Typography, {
2299
+ variant: "body2"
2300
+ }, `Output amount changed to ${warning.newOutputAmount}
2301
+ (${warning.percentageChange}% change).`);
2302
+ case ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED:
2303
+ return React.createElement(Typography, {
2304
+ variant: "body2"
2305
+ }, "Route swappers has been updated.");
2306
+ case ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED:
2307
+ return React.createElement(Typography, {
2308
+ variant: "body2"
2309
+ }, "Route internal coins has been updated.");
2310
+ case ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE:
2311
+ return React.createElement(BalanceWarnings, {
2312
+ messages: warning.messages
2313
+ });
2314
+ default:
2315
+ return [];
2316
+ }
2317
+ });
2318
+ }
2319
+
2320
+ function HighSlippageWarning(props) {
2321
+ const {
2322
+ selectedSlippage
2323
+ } = props;
2324
+ return React.createElement(Alert, {
2325
+ type: "warning",
2326
+ footer: React.createElement(ChangeSlippageButton, null)
2327
+ }, "Caution, your slippage is high (=", selectedSlippage, "). Your trade may be front run.");
2328
+ }
2329
+
2330
+ function ConfirmSwapExtraMessages(props) {
2331
+ const {
2332
+ selectedSlippage
2333
+ } = props;
2334
+ const highSlippage = selectedSlippage >= HIGH_SLIPPAGE;
2335
+ return React.createElement(React.Fragment, null, highSlippage && React.createElement(HighSlippageWarning, {
2336
+ selectedSlippage: selectedSlippage
2337
+ }));
2338
+ }
2339
+
2340
+ function ConfirmSwapPage() {
2341
+ const navigate = useNavigate();
2342
+ const {
2343
+ navigateBackFrom
2344
+ } = useNavigateBack();
2345
+ const bestRoute = useBestRouteStore.use.bestRoute();
2346
+ const fetchingBestRoute = useBestRouteStore.use.loading();
2347
+ const fetchingBestRouteError = useBestRouteStore.use.error();
2348
+ const setSelectedSwap = useUiStore.use.setSelectedSwap();
2349
+ const {
2350
+ blockchains,
2351
+ tokens
2352
+ } = useMetaStore.use.meta();
2353
+ const accounts = useWalletsStore.use.accounts();
2354
+ const selectedWallets = useWalletsStore.use.selectedWallets();
2355
+ const initSelectedWallets = useWalletsStore.use.initSelectedWallets();
2356
+ const setSelectedWallet = useWalletsStore.use.setSelectedWallet();
2357
+ const slippage = useSettingsStore.use.slippage();
2358
+ const customSlippage = useSettingsStore.use.customSlippage();
2359
+ const inputUsdValue = useBestRouteStore.use.inputUsdValue();
2360
+ const outputUsdValue = useBestRouteStore.use.outputUsdValue();
2361
+ const bestRouteloadingStatus = getBestRouteStatus(fetchingBestRoute, !!fetchingBestRouteError);
2362
+ const {
2363
+ manager
2364
+ } = useManager();
2365
+ const {
2366
+ loading,
2367
+ errors,
2368
+ warnings,
2369
+ confirmSwap
2370
+ } = useConfirmSwap();
2371
+ const selectedSlippage = customSlippage || slippage;
2372
+ const showHighSlippageWarning = !errors.find(error => error.type === ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE);
2373
+ const {
2374
+ getWalletInfo,
2375
+ connect
2376
+ } = useWallets();
2377
+ const confirmDisabled = fetchingBestRoute || !requiredWallets(bestRoute).every(chain => selectedWallets.map(wallet => wallet.chain).includes(chain));
2378
+ const firstStep = bestRoute?.result?.swaps[0];
2379
+ const lastStep = bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1];
2380
+ const fromAmount = decimalNumber(firstStep?.fromAmount, 3);
2381
+ const toAmount = decimalNumber(lastStep?.toAmount, 3);
2382
+ useEffect(() => {
2383
+ initSelectedWallets();
2384
+ }, []);
2385
+ const selectableWallets = getSelectableWallets(accounts, selectedWallets, getWalletInfo);
2386
+ const handleConnectChain = wallet => {
2387
+ const network = wallet;
2388
+ getKeplrCompatibleConnectedWallets(selectableWallets).forEach(compatibleWallet => connect?.(compatibleWallet, network));
2389
+ };
2390
+ const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
2391
+ return React.createElement(ConfirmSwap, {
2392
+ requiredWallets: getRequiredChains(bestRoute),
2393
+ selectableWallets: selectableWallets,
2394
+ onBack: navigateBackFrom.bind(null, navigationRoutes.confirmSwap),
2395
+ onConfirm: () => {
2396
+ confirmSwap?.().then(swap => {
2397
+ if (swap) {
2398
+ manager?.create('swap', {
2399
+ swapDetails: swap
2400
+ }, {
2401
+ id: swap.requestId
2402
+ });
2403
+ setSelectedSwap(swap.requestId);
2404
+ navigate(navigationRoutes.swaps + `/${swap.requestId}`, {
2405
+ replace: true
2406
+ });
2407
+ }
2408
+ });
2409
+ },
2410
+ onChange: wallet => setSelectedWallet(wallet),
2411
+ confirmDisabled: confirmDisabled,
2412
+ handleConnectChain: wallet => handleConnectChain(wallet),
2413
+ isExperimentalChain: wallet => getKeplrCompatibleConnectedWallets(selectableWallets).length > 0 ? isExperimentalChain(blockchains, wallet) : false,
2414
+ previewInputs: React.createElement(React.Fragment, null, React.createElement(TokenPreview, {
2415
+ chain: {
2416
+ displayName: firstStep?.from.blockchain || '',
2417
+ logo: firstStep?.from.blockchainLogo || ''
2418
+ },
2419
+ token: {
2420
+ symbol: firstStep?.from.symbol || '',
2421
+ image: firstStep?.from.logo || ''
2422
+ },
2423
+ usdValue: inputUsdValue,
2424
+ amount: fromAmount,
2425
+ label: t('From'),
2426
+ loadingStatus: bestRouteloadingStatus
2427
+ }), React.createElement(Spacer, {
2428
+ size: 12,
2429
+ direction: "vertical"
2430
+ }), React.createElement(TokenPreview, {
2431
+ chain: {
2432
+ displayName: lastStep?.to.blockchain || '',
2433
+ logo: lastStep?.to.blockchainLogo || ''
2434
+ },
2435
+ token: {
2436
+ symbol: lastStep?.to.symbol || '',
2437
+ image: lastStep?.to.logo || ''
2438
+ },
2439
+ usdValue: outputUsdValue,
2440
+ amount: toAmount,
2441
+ label: t('To'),
2442
+ loadingStatus: bestRouteloadingStatus,
2443
+ percentageChange: React.createElement(PercentageChange, {
2444
+ inputUsdValue: inputUsdValue,
2445
+ outputUsdValue: outputUsdValue
2446
+ })
2447
+ })),
2448
+ previewRoutes: React.createElement(RoutesOverview, {
2449
+ routes: bestRoute,
2450
+ totalFee: numberToString(totalFeeInUsd, 0, 2)
2451
+ }),
2452
+ loading: loading,
2453
+ errors: ConfirmSwapErrors(errors),
2454
+ warnings: ConfirmSwapWarnings(warnings),
2455
+ extraMessages: showHighSlippageWarning && React.createElement(ConfirmSwapExtraMessages, {
2456
+ selectedSlippage: selectedSlippage
2457
+ }),
2458
+ confirmButtonTitle: warnings.length > 0 || errors.length > 0 ? 'Proceed anyway!' : 'Confirm swap!'
2459
+ });
2460
+ }
2461
+
2462
+ const getPendingSwaps = manager => {
2463
+ const result = [];
2464
+ manager?.getAll().forEach((q, id) => {
2465
+ const storage = q.list.getStorage();
2040
2466
  if (storage?.swapDetails) {
2041
2467
  result.push({
2042
2468
  id,
@@ -2047,6 +2473,31 @@ const getPendingSwaps = manager => {
2047
2473
  return result.sort((a, b) => Number(b.swap.creationTime) - Number(a.swap.creationTime));
2048
2474
  };
2049
2475
 
2476
+ const groupSwapsByDate = swaps => {
2477
+ const output = new Map([['today', {
2478
+ title: 'Today',
2479
+ swaps: []
2480
+ }], ['week', {
2481
+ title: 'This week',
2482
+ swaps: []
2483
+ }], ['month', {
2484
+ title: 'This month',
2485
+ swaps: []
2486
+ }], ['year', {
2487
+ title: 'This year',
2488
+ swaps: []
2489
+ }], ['history', {
2490
+ title: 'History',
2491
+ swaps: []
2492
+ }]]);
2493
+ const now = dayjs();
2494
+ swaps.forEach(swap => {
2495
+ const swapDate = dayjs(Number(swap.creationTime));
2496
+ 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);
2497
+ });
2498
+ return Array.from(output.values());
2499
+ };
2500
+
2050
2501
  function HistoryPage() {
2051
2502
  const setSelectedSwap = useUiStore.use.setSelectedSwap();
2052
2503
  const navigate = useNavigate();
@@ -2062,16 +2513,14 @@ function HistoryPage() {
2062
2513
  } = _ref;
2063
2514
  return swap;
2064
2515
  });
2065
- return React.createElement(History
2066
- //todo: move PendingSwap type to rango-types
2067
- //@ts-ignore
2068
- , {
2069
- //todo: move PendingSwap type to rango-types
2070
- //@ts-ignore
2516
+ return React.createElement(History, {
2071
2517
  list: pendingSwaps,
2518
+ groupBy: groupSwapsByDate,
2072
2519
  onSwapClick: requestId => {
2073
2520
  setSelectedSwap(requestId);
2074
- navigate(navigationRoutes.swaps + `/${requestId}`);
2521
+ navigate(navigationRoutes.swaps + `/${requestId}`, {
2522
+ replace: true
2523
+ });
2075
2524
  },
2076
2525
  onBack: navigateBackFrom.bind(null, navigationRoutes.swaps)
2077
2526
  });
@@ -2082,6 +2531,7 @@ function LiquiditySourcePage(_ref) {
2082
2531
  supportedSwappers
2083
2532
  } = _ref;
2084
2533
  const swappers = useMetaStore.use.meta().swappers;
2534
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2085
2535
  const toggleLiquiditySource = useSettingsStore.use.toggleLiquiditySource();
2086
2536
  const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
2087
2537
  const toggleAllLiquiditySources = useSettingsStore.use.toggleAllLiquiditySources();
@@ -2107,7 +2557,8 @@ function LiquiditySourcePage(_ref) {
2107
2557
  toggleAll: toggleAllLiquiditySources,
2108
2558
  list: supportedSwappers !== 'all' ? uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0) : uniqueSwappersGroups,
2109
2559
  onChange: liquiditySource => toggleLiquiditySource(liquiditySource.title),
2110
- onBack: navigateBackFrom.bind(null, navigationRoutes.liquiditySources)
2560
+ onBack: navigateBackFrom.bind(null, navigationRoutes.liquiditySources),
2561
+ loadingStatus: loadingMetaStatus
2111
2562
  });
2112
2563
  }
2113
2564
 
@@ -2149,391 +2600,169 @@ function SelectTokenPage(props) {
2149
2600
  const sourceTokens = useBestRouteStore.use.sourceTokens();
2150
2601
  const destinationTokens = useBestRouteStore.use.destinationTokens();
2151
2602
  const supportedSourceTokens = supportedTokens === 'all' ? sourceTokens : sourceTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2152
- const supportedDestinationTokens = supportedTokens === 'all' ? destinationTokens : destinationTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2153
- console.log(supportedSourceTokens);
2154
- const fromToken = useBestRouteStore.use.fromToken();
2155
- const toToken = useBestRouteStore.use.toToken();
2156
- const setFromToken = useBestRouteStore.use.setFromToken();
2157
- const setToToken = useBestRouteStore.use.setToToken();
2158
- return React.createElement(TokenSelector, {
2159
- type: type === 'from' ? 'Source' : 'Destination',
2160
- list: type == 'from' ? supportedSourceTokens : supportedDestinationTokens,
2161
- selected: type === 'from' ? fromToken : toToken,
2162
- onChange: token => {
2163
- if (type === 'from') setFromToken(token);else setToToken(token);
2164
- navigateBackFrom(navigationRoutes.fromToken);
2165
- },
2166
- onBack: navigateBackFrom.bind(null, navigationRoutes.fromToken)
2167
- });
2168
- }
2169
-
2170
- function SettingsPage(_ref) {
2171
- let {
2172
- supportedSwappers
2173
- } = _ref;
2174
- const slippage = useSettingsStore.use.slippage();
2175
- const setSlippage = useSettingsStore.use.setSlippage();
2176
- const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
2177
- const customSlippage = useSettingsStore.use.customSlippage();
2178
- const setCustomSlippage = useSettingsStore.use.setCustomSlippage();
2179
- const theme = useSettingsStore.use.theme();
2180
- const setTheme = useSettingsStore.use.setTheme();
2181
- const swappers = useMetaStore.use.meta().swappers;
2182
- const navigate = useNavigate();
2183
- const {
2184
- navigateBackFrom
2185
- } = useNavigateBack();
2186
- const infiniteApprove = useSettingsStore.use.infiniteApprove();
2187
- const toggleInfiniteApprove = useSettingsStore.use.toggleInfiniteApprove();
2188
- const uniqueSwappersGroups = [];
2189
- removeDuplicateFrom(swappers.map(s => s.swapperGroup)).map(swapperGroup => {
2190
- return swappers.find(s => s.swapperGroup === swapperGroup);
2191
- }).find(s => {
2192
- if (s) {
2193
- for (const type of s.types) {
2194
- uniqueSwappersGroups.push({
2195
- title: s.swapperGroup,
2196
- logo: s.logo,
2197
- type,
2198
- selected: !disabledLiquiditySources.includes(s.swapperGroup)
2199
- });
2200
- }
2201
- }
2202
- });
2203
- supportedSwappers !== 'all' && uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0);
2204
- const supportedUniqueSwappersGroups = supportedSwappers !== 'all' ? uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0) : uniqueSwappersGroups;
2205
- return React.createElement(Settings, {
2206
- slippages: SLIPPAGES,
2207
- selectedSlippage: slippage,
2208
- onSlippageChange: slippage => setSlippage(slippage),
2209
- onLiquiditySourcesClick: () => navigate(navigationRoutes.liquiditySources),
2210
- onBack: navigateBackFrom.bind(null, navigationRoutes.settings),
2211
- liquiditySources: supportedUniqueSwappersGroups,
2212
- selectedLiquiditySources: supportedUniqueSwappersGroups.filter(s => s.selected),
2213
- customSlippage: customSlippage || NaN,
2214
- onCustomSlippageChange: setCustomSlippage,
2215
- minSlippage: MIN_SLIPPGAE,
2216
- maxSlippage: MAX_SLIPPAGE,
2217
- selectedTheme: theme,
2218
- onThemeChange: setTheme,
2219
- infiniteApprove: infiniteApprove,
2220
- toggleInfiniteApprove: toggleInfiniteApprove
2221
- });
2222
- }
2223
-
2224
- const ListContainer = /*#__PURE__*/styled('div', {
2225
- display: 'grid',
2226
- gap: '.5rem',
2227
- gridTemplateColumns: ' repeat(2, minmax(0, 1fr))',
2228
- height: '450px',
2229
- alignContent: 'baseline',
2230
- padding: '0.5rem'
2231
- });
2232
- const AlertContainer = /*#__PURE__*/styled('div', {
2233
- paddingBottom: '$16'
2234
- });
2235
- function WalletsPage(_ref) {
2236
- let {
2237
- supportedWallets,
2238
- multiWallets
2239
- } = _ref;
2240
- const {
2241
- navigateBackFrom
2242
- } = useNavigateBack();
2243
- const {
2244
- state,
2245
- disconnect,
2246
- getWalletInfo,
2247
- connect
2248
- } = useWallets();
2249
- const wallets = getlistWallet(state, getWalletInfo, supportedWallets === 'all' ? Object.values(WalletType) : supportedWallets);
2250
- let sortedWallets = detectMobileScreens() ? wallets.filter(wallet => wallet.showOnMobile) : wallets;
2251
- sortedWallets = sortWalletsBasedOnState(sortedWallets);
2252
- const [walletErrorMessage, setWalletErrorMessage] = useState('');
2253
- const toggleConnectWalletsButton = useUiStore.use.toggleConnectWalletsButton();
2254
- const {
2255
- t
2256
- } = useTranslation();
2257
- const onSelectWallet = async type => {
2258
- const wallet = state(type);
2259
- try {
2260
- if (walletErrorMessage) setWalletErrorMessage('');
2261
- if (wallet.connected) {
2262
- await disconnect(type);
2263
- } else {
2264
- if (!multiWallets && !!wallets.find(w => w.state === WalletState.CONNECTED)) {
2265
- return;
2266
- }
2267
- await connect(type);
2268
- }
2269
- } catch (e) {
2270
- setWalletErrorMessage('Error: ' + e?.message);
2271
- }
2272
- };
2273
- useEffect(() => {
2274
- toggleConnectWalletsButton();
2275
- return () => toggleConnectWalletsButton();
2276
- }, []);
2277
- return React.createElement(SecondaryPage, {
2278
- title: t('Select Wallet') || '',
2279
- textField: false,
2280
- onBack: navigateBackFrom.bind(null, navigationRoutes.wallets)
2281
- }, React.createElement(React.Fragment, null, walletErrorMessage && React.createElement(AlertContainer, null, React.createElement(Alert, {
2282
- type: "error"
2283
- }, walletErrorMessage)), React.createElement(ListContainer, null, sortedWallets.map((wallet, index) => React.createElement(Wallet, Object.assign({}, wallet, {
2284
- key: `${index}-${wallet.type}`,
2285
- onClick: onSelectWallet
2286
- }))))));
2287
- }
2288
-
2289
- const Box$1 = /*#__PURE__*/styled('div', {
2290
- display: 'flex',
2291
- flexDirection: 'column',
2292
- width: '100%'
2293
- });
2294
- const Container$3 = /*#__PURE__*/styled('div', {
2295
- boxSizing: 'border-box',
2296
- borderRadius: '$5',
2297
- padding: '$8 $16 $16 $16',
2298
- variants: {
2299
- type: {
2300
- filled: {
2301
- backgroundColor: '$neutrals300'
2302
- },
2303
- outlined: {
2304
- border: '1px solid $neutrals300'
2305
- }
2306
- }
2307
- },
2308
- defaultVariants: {
2309
- type: 'filled'
2310
- },
2311
- '.head': {
2312
- display: 'flex',
2313
- justifyContent: 'space-between',
2314
- alignItems: 'center',
2315
- minHeight: '32px'
2316
- },
2317
- '.form': {
2318
- display: 'flex',
2319
- width: '100%',
2320
- padding: '$2 0',
2321
- '.selectors': {
2322
- width: '35%',
2323
- '._text': {
2324
- whiteSpace: 'nowrap',
2325
- overflow: 'hidden',
2326
- textOverflow: 'ellipsis'
2327
- }
2328
- },
2329
- '.amount': {
2330
- width: '30%'
2331
- }
2332
- }
2333
- });
2334
- const StyledImage$1 = /*#__PURE__*/styled('img', {
2335
- width: '$24',
2336
- maxHeight: '$24'
2337
- });
2338
- const ImagePlaceholder$1 = /*#__PURE__*/styled('span', {
2339
- width: '24px',
2340
- height: '24px',
2341
- backgroundColor: '$neutrals300',
2342
- borderRadius: '99999px'
2343
- });
2344
- const OutputContainer$1 = /*#__PURE__*/styled('div', {
2345
- windth: '100%',
2346
- height: '$48',
2347
- borderRadius: '$5',
2348
- backgroundColor: '$background',
2349
- border: '1px solid transparent',
2350
- position: 'relative',
2351
- display: 'flex',
2352
- alignItems: 'center',
2353
- paddingLeft: '$8',
2354
- paddingRight: '$8'
2355
- });
2356
- function TokenPreview(props) {
2357
- const {
2358
- chain,
2359
- token,
2360
- loadingStatus
2361
- } = props;
2362
- const {
2363
- t
2364
- } = useTranslation();
2365
- const ItemSuffix = React.createElement("div", {
2366
- style: {
2367
- display: 'flex',
2368
- justifyContent: 'center',
2369
- alignItems: 'center'
2370
- }
2371
- }, loadingStatus === 'failed' && React.createElement(InfoCircleIcon, {
2372
- color: "error",
2373
- size: 24
2374
- }));
2375
- return React.createElement(Box$1, null, React.createElement(Container$3, {
2376
- type: 'outlined'
2377
- }, React.createElement("div", {
2378
- className: "head"
2379
- }, React.createElement(Typography, {
2380
- variant: "body2",
2381
- color: "neutrals800"
2382
- }, props.label), React.createElement(Typography, {
2383
- variant: "caption",
2384
- color: "neutrals600"
2385
- }, `$${numberToString(props.usdValue)}`)), React.createElement("div", {
2386
- className: "form"
2387
- }, React.createElement(Button, {
2388
- className: "selectors",
2389
- variant: "outlined",
2390
- loading: loadingStatus === 'loading',
2391
- prefix: loadingStatus === 'success' && chain ? React.createElement(StyledImage$1, {
2392
- src: chain.logo
2393
- }) : React.createElement(ImagePlaceholder$1, null),
2394
- suffix: ItemSuffix,
2395
- align: "start",
2396
- size: "large"
2397
- }, loadingStatus === 'success' && chain ? chain.displayName : t('Chain')), React.createElement(Spacer, {
2398
- size: 12
2399
- }), React.createElement(Button, {
2400
- className: "selectors",
2401
- variant: "outlined",
2402
- loading: loadingStatus === 'loading',
2403
- prefix: loadingStatus === 'success' && token ? React.createElement(StyledImage$1, {
2404
- src: token.image
2405
- }) : React.createElement(ImagePlaceholder$1, null),
2406
- suffix: ItemSuffix,
2407
- size: "large",
2408
- align: "start"
2409
- }, loadingStatus === 'success' && token ? token.symbol : t('Token')), React.createElement(Spacer, {
2410
- size: 12
2411
- }), React.createElement("div", {
2412
- className: "amount"
2413
- }, React.createElement(OutputContainer$1, null, React.createElement(Typography, {
2414
- variant: "h4"
2415
- }, props.amount))))));
2416
- }
2417
-
2418
- const Container$4 = /*#__PURE__*/styled('div', {
2419
- display: 'flex',
2420
- alignItems: 'center',
2421
- justifyContent: 'space-between',
2422
- padding: '$8',
2423
- borderRadius: '$5',
2424
- backgroundColor: '$neutrals300',
2425
- color: '$neutrals800',
2426
- fontSize: '$12',
2427
- '.routes': {
2428
- display: 'flex',
2429
- alignItems: 'center'
2430
- },
2431
- '.fee': {
2432
- display: 'flex',
2433
- alignItems: 'center'
2434
- }
2435
- });
2436
- function RoutesOverview(props) {
2437
- if (!props.routes) return null;
2438
- const swaps = props.routes.result?.swaps;
2439
- return React.createElement(Container$4, null, React.createElement("div", {
2440
- className: "routes"
2441
- }, swaps?.map((swap, idx) => {
2442
- const isLast = idx + 1 == swaps.length;
2443
- return React.createElement(React.Fragment, null, React.createElement("div", {
2444
- className: "route"
2445
- }, swap.from.symbol), React.createElement(ChevronRightIcon, {
2446
- size: 12
2447
- }), isLast ? React.createElement("div", {
2448
- className: "route"
2449
- }, swap.to.symbol) : null);
2450
- })), props.totalFee ? React.createElement("div", {
2451
- className: "fee"
2452
- }, React.createElement(GasIcon, {
2453
- size: 12
2454
- }), React.createElement(Spacer, {
2455
- size: 4
2456
- }), "$", props.totalFee) : null);
2603
+ const supportedDestinationTokens = supportedTokens === 'all' ? destinationTokens : destinationTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2604
+ const fromToken = useBestRouteStore.use.fromToken();
2605
+ const toToken = useBestRouteStore.use.toToken();
2606
+ const setFromToken = useBestRouteStore.use.setFromToken();
2607
+ const setToToken = useBestRouteStore.use.setToToken();
2608
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2609
+ return React.createElement(TokenSelector, {
2610
+ type: type === 'from' ? 'Source' : 'Destination',
2611
+ list: type == 'from' ? supportedSourceTokens : supportedDestinationTokens,
2612
+ selected: type === 'from' ? fromToken : toToken,
2613
+ onChange: token => {
2614
+ if (type === 'from') setFromToken(token);else setToToken(token);
2615
+ navigateBackFrom(navigationRoutes.fromToken);
2616
+ },
2617
+ onBack: navigateBackFrom.bind(null, navigationRoutes.fromToken),
2618
+ loadingStatus: loadingMetaStatus
2619
+ });
2457
2620
  }
2458
2621
 
2459
- function ConfirmWalletsPage() {
2622
+ function SettingsPage(_ref) {
2623
+ let {
2624
+ supportedSwappers
2625
+ } = _ref;
2626
+ const slippage = useSettingsStore.use.slippage();
2627
+ const setSlippage = useSettingsStore.use.setSlippage();
2628
+ const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
2629
+ const customSlippage = useSettingsStore.use.customSlippage();
2630
+ const setCustomSlippage = useSettingsStore.use.setCustomSlippage();
2631
+ const theme = useSettingsStore.use.theme();
2632
+ const setTheme = useSettingsStore.use.setTheme();
2633
+ const swappers = useMetaStore.use.meta().swappers;
2460
2634
  const navigate = useNavigate();
2461
2635
  const {
2462
2636
  navigateBackFrom
2463
2637
  } = useNavigateBack();
2464
- const bestRoute = useBestRouteStore.use.bestRoute();
2638
+ const infiniteApprove = useSettingsStore.use.infiniteApprove();
2639
+ const toggleInfiniteApprove = useSettingsStore.use.toggleInfiniteApprove();
2640
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2641
+ const uniqueSwappersGroups = [];
2642
+ removeDuplicateFrom(swappers.map(s => s.swapperGroup)).map(swapperGroup => {
2643
+ return swappers.find(s => s.swapperGroup === swapperGroup);
2644
+ }).find(s => {
2645
+ if (s) {
2646
+ for (const type of s.types) {
2647
+ uniqueSwappersGroups.push({
2648
+ title: s.swapperGroup,
2649
+ logo: s.logo,
2650
+ type,
2651
+ selected: !disabledLiquiditySources.includes(s.swapperGroup)
2652
+ });
2653
+ }
2654
+ }
2655
+ });
2656
+ supportedSwappers !== 'all' && uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0);
2657
+ const supportedUniqueSwappersGroups = supportedSwappers !== 'all' ? uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0) : uniqueSwappersGroups;
2658
+ return React.createElement(Settings, {
2659
+ slippages: SLIPPAGES,
2660
+ selectedSlippage: slippage,
2661
+ onSlippageChange: slippage => setSlippage(slippage),
2662
+ onLiquiditySourcesClick: () => navigate(navigationRoutes.liquiditySources),
2663
+ onBack: navigateBackFrom.bind(null, navigationRoutes.settings),
2664
+ liquiditySources: supportedUniqueSwappersGroups,
2665
+ selectedLiquiditySources: supportedUniqueSwappersGroups.filter(s => s.selected),
2666
+ customSlippage: customSlippage || NaN,
2667
+ onCustomSlippageChange: setCustomSlippage,
2668
+ minSlippage: MIN_SLIPPGAE,
2669
+ maxSlippage: MAX_SLIPPAGE,
2670
+ selectedTheme: theme,
2671
+ onThemeChange: setTheme,
2672
+ infiniteApprove: infiniteApprove,
2673
+ toggleInfiniteApprove: toggleInfiniteApprove,
2674
+ loadingStatus: loadingMetaStatus
2675
+ });
2676
+ }
2677
+
2678
+ const ListContainer = /*#__PURE__*/styled('div', {
2679
+ display: 'grid',
2680
+ gap: '.5rem',
2681
+ gridTemplateColumns: ' repeat(2, minmax(0, 1fr))',
2682
+ alignContent: 'baseline',
2683
+ padding: '0.5rem',
2684
+ overflowY: 'auto'
2685
+ });
2686
+ const LoaderContainer = /*#__PURE__*/styled('div', {
2687
+ display: 'flex',
2688
+ justifyContent: 'center',
2689
+ width: '100%',
2690
+ position: 'absolute',
2691
+ top: '50%'
2692
+ });
2693
+ const AlertContainer = /*#__PURE__*/styled('div', {
2694
+ paddingBottom: '$16'
2695
+ });
2696
+ function WalletsPage(_ref) {
2697
+ let {
2698
+ supportedWallets,
2699
+ multiWallets
2700
+ } = _ref;
2465
2701
  const {
2466
- blockchains,
2467
- tokens
2468
- } = useMetaStore.use.meta();
2469
- const accounts = useWalletsStore.use.accounts();
2470
- const selectedWallets = useWalletsStore.use.selectedWallets();
2471
- const initSelectedWallets = useWalletsStore.use.initSelectedWallets();
2472
- const setSelectedWallet = useWalletsStore.use.setSelectedWallet();
2702
+ navigateBackFrom
2703
+ } = useNavigateBack();
2473
2704
  const {
2705
+ state,
2706
+ disconnect,
2474
2707
  getWalletInfo,
2475
2708
  connect
2476
2709
  } = useWallets();
2477
- const confirmDisabled = !requiredWallets(bestRoute).every(chain => selectedWallets.map(wallet => wallet.chain).includes(chain));
2478
- const firstStep = bestRoute?.result?.swaps[0];
2479
- const lastStep = bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1];
2480
- const fromAmount = decimalNumber(firstStep?.fromAmount, 3);
2481
- const toAmount = decimalNumber(lastStep?.toAmount, 3);
2710
+ const wallets = getlistWallet(state, getWalletInfo, supportedWallets === 'all' ? Object.values(WalletType) : supportedWallets);
2711
+ const walletsRef = useRef();
2712
+ let sortedWallets = detectMobileScreens() ? wallets.filter(wallet => wallet.showOnMobile) : wallets;
2713
+ sortedWallets = sortWalletsBasedOnState(sortedWallets);
2714
+ const [walletErrorMessage, setWalletErrorMessage] = useState('');
2715
+ const toggleConnectWalletsButton = useUiStore.use.toggleConnectWalletsButton();
2716
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
2717
+ const {
2718
+ t
2719
+ } = useTranslation();
2720
+ const onSelectWallet = async type => {
2721
+ const wallet = state(type);
2722
+ try {
2723
+ if (walletErrorMessage) setWalletErrorMessage('');
2724
+ if (wallet.connected) {
2725
+ await disconnect(type);
2726
+ } else {
2727
+ if (!multiWallets && !!wallets.find(w => w.state === WalletState.CONNECTED)) {
2728
+ return;
2729
+ }
2730
+ await connect(type);
2731
+ }
2732
+ } catch (e) {
2733
+ setWalletErrorMessage('Error: ' + e?.message);
2734
+ }
2735
+ };
2736
+ const disconnectConnectingWallets = () => {
2737
+ const connectingWallets = walletsRef.current?.filter(wallet => wallet.state === WalletState.CONNECTING) || [];
2738
+ for (const wallet of connectingWallets) {
2739
+ disconnect(wallet.type);
2740
+ }
2741
+ };
2482
2742
  useEffect(() => {
2483
- initSelectedWallets();
2743
+ toggleConnectWalletsButton();
2744
+ return () => {
2745
+ disconnectConnectingWallets();
2746
+ toggleConnectWalletsButton();
2747
+ };
2484
2748
  }, []);
2485
- const selectableWallets = getSelectableWallets(accounts, selectedWallets, getWalletInfo);
2486
- const handleConnectChain = wallet => {
2487
- const network = wallet;
2488
- getKeplrCompatibleConnectedWallets(selectableWallets).forEach(compatibleWallet => connect?.(compatibleWallet, network));
2489
- };
2490
- const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
2491
- return React.createElement(ConfirmWallets, {
2492
- requiredWallets: getRequiredChains(bestRoute),
2493
- selectableWallets: selectableWallets,
2494
- onBack: navigateBackFrom.bind(null, navigationRoutes.confirmWallets),
2495
- onConfirm: () => navigate(navigationRoutes.confirmSwap, {
2496
- replace: true
2497
- }),
2498
- onChange: wallet => setSelectedWallet(wallet),
2499
- confirmDisabled: confirmDisabled,
2500
- handleConnectChain: wallet => handleConnectChain(wallet),
2501
- isExperimentalChain: wallet => getKeplrCompatibleConnectedWallets(selectableWallets).length > 0 ? isExperimentalChain(blockchains, wallet) : false,
2502
- previewInputs: React.createElement(React.Fragment, null, React.createElement(TokenPreview, {
2503
- chain: {
2504
- displayName: firstStep?.from.blockchain || '',
2505
- logo: firstStep?.from.blockchainLogo || ''
2506
- },
2507
- token: {
2508
- symbol: firstStep?.from.symbol || '',
2509
- image: firstStep?.from.logo || ''
2510
- },
2511
- usdValue: calcOutputUsdValue(fromAmount, firstStep?.from.usdPrice),
2512
- amount: fromAmount,
2513
- label: t('From'),
2514
- loadingStatus: 'success'
2515
- }), React.createElement(Spacer, {
2516
- size: 12,
2517
- direction: "vertical"
2518
- }), React.createElement(TokenPreview, {
2519
- chain: {
2520
- displayName: lastStep?.to.blockchain || '',
2521
- logo: lastStep?.to.blockchainLogo || ''
2522
- },
2523
- token: {
2524
- symbol: lastStep?.to.symbol || '',
2525
- image: lastStep?.to.logo || ''
2526
- },
2527
- usdValue: calcOutputUsdValue(toAmount, lastStep?.to.usdPrice),
2528
- amount: toAmount,
2529
- label: t('To'),
2530
- loadingStatus: 'success'
2531
- })),
2532
- previewRoutes: React.createElement(RoutesOverview, {
2533
- routes: bestRoute,
2534
- totalFee: numberToString(totalFeeInUsd, 0, 2)
2535
- })
2536
- });
2749
+ useEffect(() => {
2750
+ walletsRef.current = wallets;
2751
+ }, [wallets]);
2752
+ return React.createElement(SecondaryPage, {
2753
+ title: t('Select Wallet') || '',
2754
+ textField: false,
2755
+ onBack: navigateBackFrom.bind(null, navigationRoutes.wallets)
2756
+ }, React.createElement(React.Fragment, null, walletErrorMessage && React.createElement(AlertContainer, null, React.createElement(Alert, {
2757
+ type: "error"
2758
+ }, walletErrorMessage)), loadingMetaStatus === 'loading' && React.createElement(LoaderContainer, {
2759
+ className: "loader"
2760
+ }, React.createElement(Spinner, {
2761
+ size: 24
2762
+ })), loadingMetaStatus === 'failed' && React.createElement(LoadingFailedAlert, null), React.createElement(ListContainer, null, loadingMetaStatus === 'success' && sortedWallets.map((wallet, index) => React.createElement(Wallet, Object.assign({}, wallet, {
2763
+ key: `${index}-${wallet.type}`,
2764
+ onClick: onSelectWallet
2765
+ }))))));
2537
2766
  }
2538
2767
 
2539
2768
  function useCopyToClipboard(resetInterval) {
@@ -2554,15 +2783,87 @@ function useCopyToClipboard(resetInterval) {
2554
2783
  return [isCopied, handleCopy];
2555
2784
  }
2556
2785
 
2786
+ function timeSince(timeMillis) {
2787
+ const seconds = Math.floor((new Date().getTime() - timeMillis) / 1000);
2788
+ let intervalType;
2789
+ let interval = Math.floor(seconds / 31536000);
2790
+ if (interval >= 1) {
2791
+ intervalType = 'year';
2792
+ } else {
2793
+ interval = Math.floor(seconds / 2592000);
2794
+ if (interval >= 1) {
2795
+ intervalType = 'month';
2796
+ } else {
2797
+ interval = Math.floor(seconds / 86400);
2798
+ if (interval >= 1) {
2799
+ intervalType = 'day';
2800
+ } else {
2801
+ interval = Math.floor(seconds / 3600);
2802
+ if (interval >= 1) {
2803
+ intervalType = 'hour';
2804
+ } else {
2805
+ interval = Math.floor(seconds / 60);
2806
+ if (interval >= 1) {
2807
+ intervalType = 'minute';
2808
+ } else {
2809
+ interval = seconds;
2810
+ intervalType = 'second';
2811
+ }
2812
+ }
2813
+ }
2814
+ }
2815
+ }
2816
+ if (interval > 1 || interval === 0) {
2817
+ intervalType += 's';
2818
+ }
2819
+ return interval + ' ' + intervalType;
2820
+ }
2821
+ function getSwapDate(pendingSwap) {
2822
+ 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()}`;
2823
+ }
2824
+
2825
+ const PlaceholderContainer = /*#__PURE__*/styled('div', {
2826
+ height: '450px'
2827
+ });
2828
+ function SwapDetailsPlaceholder(props) {
2829
+ const {
2830
+ requestId,
2831
+ loading,
2832
+ onBack
2833
+ } = props;
2834
+ return React.createElement(SecondaryPage, {
2835
+ title: "Swap Details",
2836
+ textField: false,
2837
+ onBack: onBack
2838
+ }, React.createElement(PlaceholderContainer, null, loading ? React.createElement(LoaderContainer, null, React.createElement(Spinner, {
2839
+ size: 24
2840
+ })) : React.createElement(Alert, {
2841
+ type: "secondary",
2842
+ title: `Swap with request ID = ${requestId} not found.`
2843
+ })));
2844
+ }
2845
+
2557
2846
  function SwapDetailsPage() {
2558
2847
  const selectedSwapRequestId = useUiStore.use.selectedSwapRequestId();
2848
+ const {
2849
+ canSwitchNetworkTo,
2850
+ connect
2851
+ } = useWallets();
2852
+ const retry = useBestRouteStore.use.retry();
2853
+ const navigate = useNavigate();
2559
2854
  const {
2560
2855
  navigateBackFrom
2561
2856
  } = useNavigateBack();
2857
+ const [isCopied, handleCopy] = useCopyToClipboard(2000);
2562
2858
  const {
2563
2859
  manager
2564
2860
  } = useManager();
2565
- const [isCopied, handleCopy] = useCopyToClipboard(2000);
2861
+ const [loading, setLoading] = useState(true);
2862
+ useEffect(() => {
2863
+ setTimeout(() => {
2864
+ setLoading(false);
2865
+ }, 5000);
2866
+ }, []);
2566
2867
  const pendingSwaps = getPendingSwaps(manager);
2567
2868
  const selectedSwap = pendingSwaps.find(_ref => {
2568
2869
  let {
@@ -2570,92 +2871,161 @@ function SwapDetailsPage() {
2570
2871
  } = _ref;
2571
2872
  return swap.requestId === selectedSwapRequestId;
2572
2873
  });
2573
- //TODO: implement swap cancellation (move queueManager logic to queueManager/rango-preset)
2574
2874
  const onCancel = () => {
2575
- const swap = selectedSwap ? manager?.get(selectedSwap.id) : undefined;
2875
+ const swap = manager?.get(selectedSwap?.id);
2576
2876
  if (swap) cancelSwap(swap);
2577
2877
  };
2578
- return React.createElement(SwapHistory, {
2878
+ const swap = selectedSwap?.swap;
2879
+ if (!swap) return React.createElement(SwapDetailsPlaceholder, {
2880
+ requestId: selectedSwapRequestId || '',
2881
+ loading: loading,
2882
+ onBack: navigateBackFrom.bind(null, navigationRoutes.swapDetails)
2883
+ });
2884
+ const firstStep = swap.steps[0];
2885
+ const lastStep = swap.steps[swap.steps.length - 1];
2886
+ const fromAmount = numberToString(swap.inputAmount);
2887
+ const toAmount = numberToString(swap.simulationResult.outputAmount);
2888
+ const currentStep = getCurrentStep(swap);
2889
+ const currentStepBlockchain = currentStep ? getCurrentBlockchainOfOrNull(swap, currentStep) : null;
2890
+ const currentStepWallet = currentStep ? getRelatedWalletOrNull(swap, currentStep) : null;
2891
+ const currentStepNetworkStatus = currentStep?.networkStatus;
2892
+ const swapMessages = getSwapMessages(swap, currentStep);
2893
+ const networkWarningState = isNetworkStatusInWarningState(currentStep);
2894
+ const swapDate = getSwapDate(swap);
2895
+ const shouldRetry = shouldRetrySwap(swap);
2896
+ const switchNetwork = !!currentStepBlockchain && !!currentStepWallet?.walletType && currentStepNetworkStatus === PendingSwapNetworkStatus.WaitingForNetworkChange && canSwitchNetworkTo(currentStepWallet?.walletType, currentStepBlockchain) ? connect.bind(null, currentStepWallet.walletType, currentStepBlockchain) : undefined;
2897
+ const lastConvertedTokenInFailedSwap = getLastConvertedTokenInFailedSwap(swap);
2898
+ return React.createElement(SwapHistory, Object.assign({
2579
2899
  onBack: navigateBackFrom.bind(null, navigationRoutes.swapDetails),
2900
+ previewInputs: React.createElement(React.Fragment, null, React.createElement(TokenPreview, {
2901
+ chain: {
2902
+ displayName: firstStep?.fromBlockchain || '',
2903
+ // @ts-ignore
2904
+ logo: firstStep?.fromBlockchainLogo || ''
2905
+ },
2906
+ token: {
2907
+ symbol: firstStep?.fromSymbol || '',
2908
+ image: firstStep?.fromLogo || ''
2909
+ },
2910
+ amount: fromAmount,
2911
+ label: t('From'),
2912
+ loadingStatus: 'success'
2913
+ }), React.createElement(Spacer, {
2914
+ size: 12,
2915
+ direction: "vertical"
2916
+ }), React.createElement(TokenPreview, {
2917
+ chain: {
2918
+ displayName: lastStep?.toBlockchain || '',
2919
+ // @ts-ignore
2920
+ logo: lastStep?.toBlockchainLogo || ''
2921
+ },
2922
+ token: {
2923
+ symbol: lastStep?.toSymbol || '',
2924
+ image: lastStep?.toLogo || ''
2925
+ },
2926
+ amount: toAmount,
2927
+ label: t('To'),
2928
+ loadingStatus: 'success'
2929
+ })),
2580
2930
  //todo: move PendingSwap type to rango-types
2581
2931
  //@ts-ignore
2582
- pendingSwap: selectedSwap?.swap,
2932
+ pendingSwap: swap,
2583
2933
  onCopy: handleCopy,
2584
2934
  isCopied: isCopied,
2585
- onCancel: onCancel
2586
- });
2935
+ onCancel: onCancel,
2936
+ shortMessage: swapMessages.shortMessage,
2937
+ detailedMessage: swapMessages.detailedMessage,
2938
+ currentStepBlockchain: currentStepBlockchain || '',
2939
+ switchNetwork: switchNetwork,
2940
+ type: networkWarningState ? 'warning' : swap.extraMessageSeverity || undefined,
2941
+ date: swapDate
2942
+ }, shouldRetry && {
2943
+ onRetry: () => {
2944
+ retry(swap);
2945
+ setTimeout(() => {
2946
+ navigate(navigationRoutes.home);
2947
+ }, 0);
2948
+ }
2949
+ }, lastConvertedTokenInFailedSwap && {
2950
+ lastConvertedTokenInFailedSwap: {
2951
+ blockchain: lastConvertedTokenInFailedSwap.blockchain,
2952
+ outputAmount: lastConvertedTokenInFailedSwap.outputAmount || '',
2953
+ symbol: lastConvertedTokenInFailedSwap.symbol
2954
+ }
2955
+ }));
2587
2956
  }
2588
2957
 
2958
+ const getAbsolutePath = path => path.replace('/', '');
2589
2959
  function AppRoutes(props) {
2590
2960
  const {
2591
2961
  configs
2592
2962
  } = props;
2593
2963
  return useRoutes([{
2594
- path: navigationRoutes.home,
2964
+ path: getAbsolutePath(navigationRoutes.home),
2595
2965
  element: React.createElement(Home, {
2596
2966
  title: configs?.title,
2597
2967
  titleSize: configs?.titleSize,
2598
2968
  titleWeight: configs?.titleWeight
2599
2969
  })
2600
2970
  }, {
2601
- path: navigationRoutes.fromChain,
2971
+ path: getAbsolutePath(navigationRoutes.fromChain),
2602
2972
  element: React.createElement(SelectChainPage, {
2603
2973
  type: "from",
2604
2974
  supportedChains: configs?.fromChains || 'all'
2605
2975
  })
2606
2976
  }, {
2607
- path: navigationRoutes.toChain,
2977
+ path: getAbsolutePath(navigationRoutes.toChain),
2608
2978
  element: React.createElement(SelectChainPage, {
2609
2979
  type: "to",
2610
2980
  supportedChains: configs?.toChains || 'all'
2611
2981
  })
2612
2982
  }, {
2613
- path: navigationRoutes.fromToken + '/*',
2983
+ path: getAbsolutePath(navigationRoutes.fromToken),
2614
2984
  element: React.createElement(SelectTokenPage, {
2615
2985
  type: "from",
2616
2986
  supportedTokens: configs?.fromTokens || 'all'
2617
2987
  })
2618
2988
  }, {
2619
- path: navigationRoutes.toToken,
2989
+ path: getAbsolutePath(navigationRoutes.toToken),
2620
2990
  element: React.createElement(SelectTokenPage, {
2621
2991
  type: "to",
2622
2992
  supportedTokens: configs?.toTokens || 'all'
2623
2993
  })
2624
2994
  }, {
2625
- path: navigationRoutes.settings,
2995
+ path: getAbsolutePath(navigationRoutes.settings),
2626
2996
  element: React.createElement(SettingsPage, {
2627
2997
  supportedSwappers: configs?.liquiditySources || 'all'
2628
2998
  })
2629
2999
  }, {
2630
- path: navigationRoutes.liquiditySources,
3000
+ path: getAbsolutePath(navigationRoutes.liquiditySources),
2631
3001
  element: React.createElement(LiquiditySourcePage, {
2632
3002
  supportedSwappers: configs?.liquiditySources || 'all'
2633
3003
  })
2634
3004
  }, {
2635
- path: navigationRoutes.swaps,
3005
+ path: getAbsolutePath(navigationRoutes.swaps),
2636
3006
  element: React.createElement(HistoryPage, null)
2637
3007
  }, {
2638
3008
  path: navigationRoutes.swapDetails,
2639
3009
  element: React.createElement(SwapDetailsPage, null)
2640
3010
  }, {
2641
- path: navigationRoutes.wallets,
3011
+ path: getAbsolutePath(navigationRoutes.wallets),
2642
3012
  element: React.createElement(WalletsPage, {
2643
3013
  supportedWallets: configs?.wallets || 'all',
2644
3014
  multiWallets: typeof configs?.multiWallets === 'undefined' ? true : configs.multiWallets
2645
3015
  })
2646
3016
  }, {
2647
- path: navigationRoutes.confirmSwap,
3017
+ path: getAbsolutePath(navigationRoutes.confirmSwap),
2648
3018
  element: React.createElement(ConfirmSwapPage, null)
2649
- }, {
2650
- path: navigationRoutes.confirmWallets,
2651
- element: React.createElement(ConfirmWalletsPage, null)
2652
3019
  }]);
2653
3020
  }
2654
3021
 
2655
- const Header$1 = /*#__PURE__*/styled('div', {
3022
+ const Header = /*#__PURE__*/styled('div', {
2656
3023
  display: 'flex',
2657
3024
  width: '100%',
2658
- justifyContent: 'end'
3025
+ justifyContent: 'end',
3026
+ '.balance': {
3027
+ display: 'flex'
3028
+ }
2659
3029
  });
2660
3030
  const WalletImage = /*#__PURE__*/styled('img', {
2661
3031
  width: '$24',
@@ -2685,6 +3055,8 @@ function Layout(_ref) {
2685
3055
  const setInputAmount = useBestRouteStore.use.setInputAmount();
2686
3056
  const totalBalance = calculateWalletUsdValue(balances);
2687
3057
  const connectWalletsButtonDisabled = useUiStore.use.connectWalletsButtonDisabled();
3058
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
3059
+ const fetchingBalance = useWalletsStore(fetchingBalanceSelector);
2688
3060
  const {
2689
3061
  t
2690
3062
  } = useTranslation();
@@ -2699,22 +3071,32 @@ function Layout(_ref) {
2699
3071
  setFromToken(configs?.fromToken || null);
2700
3072
  setFromChain(configs?.fromChain || null);
2701
3073
  }, [configs?.fromToken, configs?.fromChain]);
2702
- return React.createElement(React.Fragment, null, React.createElement(Header$1, null, React.createElement(Button, {
3074
+ useEffect(() => {
3075
+ setToChain(null);
3076
+ setFromChain(null);
3077
+ setFromToken(null);
3078
+ setToToken(null);
3079
+ }, [configs?.fromChains, configs?.toChains, configs?.fromTokens, configs?.toTokens]);
3080
+ return React.createElement(React.Fragment, null, React.createElement(Header, null, React.createElement(Button, {
2703
3081
  size: "small",
2704
3082
  suffix: React.createElement(AddWalletIcon, {
2705
3083
  size: 20
2706
3084
  }),
2707
3085
  variant: "ghost",
2708
3086
  flexContent: true,
3087
+ loading: loadingMetaStatus === 'loading',
3088
+ disabled: loadingMetaStatus === 'failed',
2709
3089
  onClick: () => {
2710
3090
  if (!connectWalletsButtonDisabled) navigate(navigationRoutes.wallets);
2711
3091
  }
2712
3092
  }, connectedWalletsImages?.length ? connectedWalletsImages.map((walletImage, index) => React.createElement(WalletImage, {
2713
3093
  key: index,
2714
3094
  src: walletImage
2715
- })) : React.createElement(React.Fragment, null), React.createElement(Typography, {
3095
+ })) : React.createElement(React.Fragment, null), React.createElement("div", {
3096
+ className: "balance"
3097
+ }, React.createElement(Typography, {
2716
3098
  variant: "body2"
2717
- }, !accounts?.length ? t('Connect Wallet') : `$${totalBalance || 0}`))), React.createElement(AppRoutes, {
3099
+ }, !accounts?.length ? t('Connect Wallet') : `$${totalBalance || 0}`), fetchingBalance && React.createElement(Spinner, null)))), React.createElement(AppRoutes, {
2718
3100
  configs: configs
2719
3101
  }));
2720
3102
  }
@@ -2722,10 +3104,12 @@ function Layout(_ref) {
2722
3104
  const globalStyles = /*#__PURE__*/globalCss({
2723
3105
  '*': {
2724
3106
  '&::-webkit-scrollbar': {
2725
- width: '$8'
3107
+ width: '$8',
3108
+ height: '$8'
2726
3109
  },
2727
3110
  '&::-webkit-scrollbar-thumb': {
2728
- backgroundColor: '$neutrals400'
3111
+ backgroundColor: '$neutrals400',
3112
+ borderRadius: '$10'
2729
3113
  },
2730
3114
  '&::-webkit-scrollbar-thumb:hover': {
2731
3115
  backgroundColor: '$neutrals500'
@@ -2966,7 +3350,7 @@ function QueueManager(props) {
2966
3350
  };
2967
3351
  // TODO: this code copy & pasted from rango, should be refactored.
2968
3352
  const allBlockchains = blockchains.filter(blockchain => blockchain.enabled).reduce((blockchainsObj, blockchain) => (blockchainsObj[blockchain.name] = blockchain, blockchainsObj), {});
2969
- const evmBasedChains = blockchains.filter(isEvmBlockchain);
3353
+ const evmBasedChains = blockchains.filter(isEvmBlockchain$1);
2970
3354
  const getSupportedChainNames = type => {
2971
3355
  const {
2972
3356
  supportedChains
@@ -2999,7 +3383,9 @@ function QueueManager(props) {
2999
3383
  //@ts-ignore
3000
3384
  queuesDefs: [swapQueueDef],
3001
3385
  context: context,
3002
- onPersistedDataLoaded: _manager => {},
3386
+ onPersistedDataLoaded: manager => {
3387
+ checkWaitingForNetworkChange(manager);
3388
+ },
3003
3389
  isPaused: false
3004
3390
  }, props.children);
3005
3391
  }
@@ -3027,8 +3413,10 @@ const SwapBox = _ref => {
3027
3413
  changeLanguage
3028
3414
  } = useSelectLanguage();
3029
3415
  const clearConnectedWallet = useWalletsStore.use.clearConnectedWallet();
3030
- const evmBasedChainNames = blockchains.filter(isEvmBlockchain).map(chain => chain.name);
3031
- const onUpdateState = (type, event, value, _, supportedChains) => {
3416
+ const [lastConnectedWalletWithNetwork, setLastConnectedWalletWithNetwork] = useState('');
3417
+ const [disconnectedWallet, setDisconnectedWallet] = useState();
3418
+ const evmBasedChainNames = blockchains.filter(isEvmBlockchain$1).map(chain => chain.name);
3419
+ const onUpdateState = (type, event, value, state, supportedChains) => {
3032
3420
  if (event === Events.ACCOUNTS) {
3033
3421
  if (value) {
3034
3422
  const supportedChainNames = walletAndSupportedChainsNames(supportedChains);
@@ -3038,6 +3426,16 @@ const SwapBox = _ref => {
3038
3426
  disconnectWallet(type);
3039
3427
  }
3040
3428
  }
3429
+ if (event === Events.ACCOUNTS && state.connected) {
3430
+ const key = `${type}-${state.network}-${value}`;
3431
+ if (state.connected) {
3432
+ setLastConnectedWalletWithNetwork(key);
3433
+ }
3434
+ }
3435
+ if (event === Events.NETWORK && state.network) {
3436
+ const key = `${type}-${state.network}`;
3437
+ setLastConnectedWalletWithNetwork(key);
3438
+ }
3041
3439
  };
3042
3440
  let providers = allProviders();
3043
3441
  useEffect(() => {
@@ -3069,7 +3467,12 @@ const SwapBox = _ref => {
3069
3467
  }, React.createElement(AppRouter, {
3070
3468
  title: configs.title,
3071
3469
  titleSize: configs.titleSize,
3072
- titleWeight: configs.titleWeight
3470
+ titleWeight: configs.titleWeight,
3471
+ lastConnectedWallet: lastConnectedWalletWithNetwork,
3472
+ disconnectedWallet: disconnectedWallet,
3473
+ clearDisconnectedWallet: () => {
3474
+ setDisconnectedWallet(undefined);
3475
+ }
3073
3476
  }, React.createElement(Layout, {
3074
3477
  configs: configs
3075
3478
  }))))));