@rango-dev/widget-embedded 0.1.10-next.92 → 0.1.10-next.94

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 (80) hide show
  1. package/dist/QueueManager.d.ts.map +1 -1
  2. package/dist/components/AppRoutes.d.ts +5 -1
  3. package/dist/components/AppRoutes.d.ts.map +1 -1
  4. package/dist/components/ConfirmSwapErrors.d.ts +3 -2
  5. package/dist/components/ConfirmSwapErrors.d.ts.map +1 -1
  6. package/dist/components/ConfirmSwapWarnings.d.ts +3 -2
  7. package/dist/components/ConfirmSwapWarnings.d.ts.map +1 -1
  8. package/dist/components/Layout.d.ts +1 -1
  9. package/dist/components/Layout.d.ts.map +1 -1
  10. package/dist/components/SwitchFromAndTo.d.ts +1 -1
  11. package/dist/components/SwitchFromAndTo.d.ts.map +1 -1
  12. package/dist/components/UpdateUrl.d.ts +1 -1
  13. package/dist/components/UpdateUrl.d.ts.map +1 -1
  14. package/dist/components/warnings/BalanceWarnings.d.ts.map +1 -1
  15. package/dist/components/warnings/ConfirmSwapExtraMessages.d.ts.map +1 -1
  16. package/dist/hooks/useConfirmSwap.d.ts +11 -0
  17. package/dist/hooks/useConfirmSwap.d.ts.map +1 -0
  18. package/dist/hooks/usePrevious.d.ts +1 -1
  19. package/dist/hooks/usePrevious.d.ts.map +1 -1
  20. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  21. package/dist/pages/Home.d.ts.map +1 -1
  22. package/dist/pages/SelectChainPage.d.ts.map +1 -1
  23. package/dist/pages/SelectTokenPage.d.ts.map +1 -1
  24. package/dist/pages/SettingsPage.d.ts.map +1 -1
  25. package/dist/pages/WalletsPage.d.ts.map +1 -1
  26. package/dist/store/bestRoute.d.ts +25 -0
  27. package/dist/store/bestRoute.d.ts.map +1 -1
  28. package/dist/store/settings.d.ts +15 -0
  29. package/dist/store/settings.d.ts.map +1 -1
  30. package/dist/store/wallets.d.ts.map +1 -1
  31. package/dist/types/index.d.ts +1 -0
  32. package/dist/types/index.d.ts.map +1 -1
  33. package/dist/{store/confirmSwap.d.ts → types/routing.d.ts} +14 -5
  34. package/dist/types/routing.d.ts.map +1 -0
  35. package/dist/utils/numbers.d.ts +1 -1
  36. package/dist/utils/numbers.d.ts.map +1 -1
  37. package/dist/utils/routing.d.ts +11 -5
  38. package/dist/utils/routing.d.ts.map +1 -1
  39. package/dist/utils/swap.d.ts +4 -3
  40. package/dist/utils/swap.d.ts.map +1 -1
  41. package/dist/utils/wallets.d.ts +7 -2
  42. package/dist/utils/wallets.d.ts.map +1 -1
  43. package/dist/widget-embedded.cjs.development.js +581 -492
  44. package/dist/widget-embedded.cjs.development.js.map +1 -1
  45. package/dist/widget-embedded.cjs.production.min.js +581 -492
  46. package/dist/widget-embedded.cjs.production.min.js.map +1 -1
  47. package/dist/widget-embedded.esm.js +582 -493
  48. package/dist/widget-embedded.esm.js.map +1 -1
  49. package/package.json +1 -1
  50. package/src/QueueManager.tsx +1 -0
  51. package/src/components/AppRoutes.tsx +54 -21
  52. package/src/components/ChangeSlippageButton.tsx +1 -1
  53. package/src/components/ConfirmSwapErrors.tsx +1 -1
  54. package/src/components/ConfirmSwapWarnings.tsx +1 -4
  55. package/src/components/Header.tsx +1 -1
  56. package/src/components/Layout.tsx +10 -11
  57. package/src/components/UpdateUrl.tsx +13 -22
  58. package/src/components/warnings/BalanceWarnings.tsx +27 -4
  59. package/src/components/warnings/ConfirmSwapExtraMessages.tsx +7 -1
  60. package/src/components/warnings/HighSlippageWarning.tsx +1 -1
  61. package/src/components/warnings/MinRequiredSlippage.tsx +2 -2
  62. package/src/hooks/useConfirmSwap.ts +260 -0
  63. package/src/pages/ConfirmSwapPage.tsx +17 -8
  64. package/src/pages/ConfirmWalletsPage.tsx +1 -1
  65. package/src/pages/Home.tsx +0 -1
  66. package/src/pages/SelectChainPage.tsx +2 -7
  67. package/src/pages/SelectTokenPage.tsx +22 -57
  68. package/src/pages/SettingsPage.tsx +8 -9
  69. package/src/pages/WalletsPage.tsx +16 -6
  70. package/src/store/bestRoute.ts +82 -37
  71. package/src/store/settings.ts +2 -2
  72. package/src/store/wallets.ts +26 -0
  73. package/src/types/index.ts +1 -0
  74. package/src/types/routing.ts +60 -0
  75. package/src/utils/numbers.ts +38 -17
  76. package/src/utils/routing.ts +115 -24
  77. package/src/utils/swap.ts +19 -11
  78. package/src/utils/wallets.ts +117 -73
  79. package/dist/store/confirmSwap.d.ts.map +0 -1
  80. package/src/store/confirmSwap.ts +0 -342
@@ -6,11 +6,14 @@ import { useSettingsStore } from '../store/settings';
6
6
  import { ConfirmSwapExtraMessages } from '../components/warnings/ConfirmSwapExtraMessages';
7
7
  import { useNavigateBack } from '../hooks/useNavigateBack';
8
8
  import { navigationRoutes } from '../constants/navigationRoutes';
9
- import { confirmSwap, useConfirmSwapStore } from '../store/confirmSwap';
10
9
  import { ConfirmSwapErrors } from '../components/ConfirmSwapErrors';
11
10
  import { ConfirmSwapWarnings } from '../components/ConfirmSwapWarnings';
12
11
  import { useManager } from '@rango-dev/queue-manager-react';
13
12
  import { useUiStore } from '../store/ui';
13
+ import { useConfirmSwap } from '../hooks/useConfirmSwap';
14
+ import { ConfirmSwapErrorTypes } from '../types';
15
+ import { useMetaStore } from '../store/meta';
16
+ import { getBestRouteWithCalculatedFees } from '../utils/routing';
14
17
 
15
18
  export function ConfirmSwapPage() {
16
19
  const setSelectedSwap = useUiStore.use.setSelectedSwap();
@@ -19,18 +22,22 @@ export function ConfirmSwapPage() {
19
22
  const navigate = useNavigate();
20
23
 
21
24
  const bestRoute = useBestRouteStore.use.bestRoute();
25
+ const fetchingBestRoute = useBestRouteStore.use.loading();
26
+ const { tokens } = useMetaStore.use.meta();
22
27
 
23
- const loading = useConfirmSwapStore.use.loading();
24
- const warnings = useConfirmSwapStore.use.warnings();
25
- const errors = useConfirmSwapStore.use.errors();
26
28
  const slippage = useSettingsStore.use.slippage();
27
29
  const customSlippage = useSettingsStore.use.customSlippage();
28
30
  const selectedSlippage = customSlippage || slippage;
31
+ const { loading, errors, warnings, confirmSwap } = useConfirmSwap();
32
+
33
+ const showHighSlippageWarning = !errors.find(
34
+ (error) => error.type === ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE
35
+ );
29
36
 
30
37
  return (
31
38
  <ConfirmSwap
32
39
  onConfirm={() => {
33
- confirmSwap().then((swap) => {
40
+ confirmSwap?.().then((swap) => {
34
41
  if (swap) {
35
42
  manager?.create('swap', { swapDetails: swap });
36
43
  setSelectedSwap(swap.requestId);
@@ -41,19 +48,21 @@ export function ConfirmSwapPage() {
41
48
  });
42
49
  }}
43
50
  onBack={navigateBackFrom.bind(null, navigationRoutes.confirmSwap)}
44
- bestRoute={bestRoute}
51
+ bestRoute={getBestRouteWithCalculatedFees(bestRoute, tokens)}
45
52
  loading={loading}
46
53
  errors={ConfirmSwapErrors(errors)}
47
54
  warnings={ConfirmSwapWarnings(warnings)}
48
55
  extraMessages={
49
- <ConfirmSwapExtraMessages selectedSlippage={selectedSlippage} />
56
+ showHighSlippageWarning && (
57
+ <ConfirmSwapExtraMessages selectedSlippage={selectedSlippage} />
58
+ )
50
59
  }
51
60
  confirmButtonTitle={
52
61
  warnings.length > 0 || errors.length > 0
53
62
  ? 'Proceed anyway!'
54
63
  : 'Confirm swap!'
55
64
  }
56
- confirmButtonDisabled={errors.length > 0}
65
+ confirmButtonDisabled={fetchingBestRoute}
57
66
  />
58
67
  );
59
68
  }
@@ -61,7 +61,7 @@ export function ConfirmWalletsPage() {
61
61
  requiredWallets={getRequiredChains(bestRoute)}
62
62
  selectableWallets={selectableWallets}
63
63
  onBack={navigateBackFrom.bind(null, navigationRoutes.confirmWallets)}
64
- swap={bestRoute!}
64
+ swap={bestRoute}
65
65
  fromAmount={fromAmount}
66
66
  toAmount={toAmount}
67
67
  onConfirm={() =>
@@ -87,7 +87,6 @@ export function Home(props: PropTypes) {
87
87
  const tokens = useMetaStore.use.meta().tokens;
88
88
  const fetchingBestRoute = useBestRouteStore.use.loading();
89
89
  const bestRouteError = useBestRouteStore.use.error();
90
-
91
90
  const loadingMetaStatus = useMetaStore.use.loadingStatus();
92
91
  const accounts = useWalletsStore.use.accounts();
93
92
 
@@ -22,8 +22,6 @@ export function SelectChainPage(props: PropTypes) {
22
22
  const toChain = useBestRouteStore.use.toChain();
23
23
  const setFromChain = useBestRouteStore.use.setFromChain();
24
24
  const setToChain = useBestRouteStore.use.setToChain();
25
- const setFromToken = useBestRouteStore.use.setFromToken();
26
- const setToToken = useBestRouteStore.use.setToToken();
27
25
 
28
26
  const { navigateBackFrom } = useNavigateBack();
29
27
 
@@ -34,11 +32,8 @@ export function SelectChainPage(props: PropTypes) {
34
32
  selected={type === 'from' ? fromChain : toChain}
35
33
  loadingStatus={loadingStatus}
36
34
  onChange={(chain) => {
37
- if (type === 'from') setFromChain(chain);
38
- else setToChain(chain);
39
- if (type === 'from' && fromChain?.name != chain.name)
40
- setFromToken(null);
41
- if (type === 'to' && toChain?.name != chain.name) setToToken(null);
35
+ if (type === 'from') setFromChain(chain, true);
36
+ else setToChain(chain, true);
42
37
  navigateBackFrom(navigationRoutes.fromChain);
43
38
  }}
44
39
  onBack={navigateBackFrom.bind(null, navigationRoutes.fromChain)}
@@ -1,16 +1,10 @@
1
1
  import React from 'react';
2
2
  import { TokenSelector } from '@rango-dev/ui';
3
3
  import { useBestRouteStore } from '../store/bestRoute';
4
- import { useMetaStore } from '../store/meta';
5
4
  import { Token } from 'rango-sdk';
6
- import { numberToString } from '../utils/numbers';
7
- import BigNumber from 'bignumber.js';
8
- import { getBalanceFromWallet } from '../utils/wallets';
9
- import { useWalletsStore } from '../store/wallets';
10
- import { sortedTokens } from '../utils/wallets';
11
- import { ZERO } from '../constants/numbers';
12
5
  import { useNavigateBack } from '../hooks/useNavigateBack';
13
6
  import { navigationRoutes } from '../constants/navigationRoutes';
7
+ import { tokensAreEqual } from '../utils/wallets';
14
8
 
15
9
  interface PropTypes {
16
10
  type: 'from' | 'to';
@@ -28,65 +22,36 @@ export function SelectTokenPage(props: PropTypes) {
28
22
  const { navigateBackFrom } = useNavigateBack();
29
23
 
30
24
  const { type, supportedTokens } = props;
31
- const tokens =
25
+ const sourceTokens = useBestRouteStore.use.sourceTokens();
26
+ const destinationTokens = useBestRouteStore.use.destinationTokens();
27
+ const supportedSourceTokens =
32
28
  supportedTokens === 'all'
33
- ? useMetaStore.use.meta().tokens
34
- : supportedTokens;
35
- const fromChain = useBestRouteStore.use.fromChain();
36
- const toChain = useBestRouteStore.use.toChain();
29
+ ? sourceTokens
30
+ : sourceTokens.filter((token) =>
31
+ supportedTokens.some((supportedToken) =>
32
+ tokensAreEqual(supportedToken, token)
33
+ )
34
+ );
35
+
36
+ const supportedDestinationTokens =
37
+ supportedTokens === 'all'
38
+ ? destinationTokens
39
+ : destinationTokens.filter((token) =>
40
+ supportedTokens.some((supportedToken) =>
41
+ tokensAreEqual(supportedToken, token)
42
+ )
43
+ );
44
+ console.log(supportedSourceTokens);
45
+
37
46
  const fromToken = useBestRouteStore.use.fromToken();
38
47
  const toToken = useBestRouteStore.use.toToken();
39
48
  const setFromToken = useBestRouteStore.use.setFromToken();
40
49
  const setToToken = useBestRouteStore.use.setToToken();
41
50
 
42
- const balance = useWalletsStore.use.balances();
43
-
44
- const tokenWithSelectedChain = tokens.filter((token) => {
45
- if (type === 'from') return token.blockchain === fromChain?.name;
46
- return token.blockchain === toChain?.name;
47
- });
48
-
49
- const TokensWithBalance: TokenWithBalance[] = tokenWithSelectedChain.map(
50
- (token) => {
51
- const tokenAmount = numberToString(
52
- new BigNumber(
53
- getBalanceFromWallet(
54
- balance,
55
- token.blockchain,
56
- token.symbol,
57
- token.address
58
- )?.amount || ZERO
59
- )
60
- );
61
-
62
- let tokenUsdValue = '';
63
- if (token.usdPrice)
64
- tokenUsdValue = numberToString(
65
- new BigNumber(
66
- getBalanceFromWallet(
67
- balance,
68
- token.blockchain,
69
- token.symbol,
70
- token.address
71
- )?.amount || ZERO
72
- ).multipliedBy(token.usdPrice)
73
- );
74
- return {
75
- ...token,
76
- balance: {
77
- amount: tokenAmount !== '0' ? tokenAmount : '',
78
- usdValue: tokenUsdValue !== '0' ? tokenUsdValue : '',
79
- },
80
- };
81
- }
82
- );
83
-
84
- const sortedTokenList = sortedTokens(TokensWithBalance, type, balance);
85
-
86
51
  return (
87
52
  <TokenSelector
88
53
  type={type === 'from' ? 'Source' : 'Destination'}
89
- list={sortedTokenList}
54
+ list={type == 'from' ? supportedSourceTokens : supportedDestinationTokens}
90
55
  selected={type === 'from' ? fromToken : toToken}
91
56
  onChange={(token) => {
92
57
  if (type === 'from') setFromToken(token);
@@ -36,11 +36,11 @@ export function SettingsPage({ supportedSwappers }: PropTypes) {
36
36
  type: 'BRIDGE' | 'AGGREGATOR' | 'DEX';
37
37
  selected: boolean;
38
38
  }> = [];
39
- removeDuplicateFrom(swappers.map(s => s.swapperGroup))
40
- .map(swapperGroup => {
41
- return swappers.find(s => s.swapperGroup === swapperGroup);
39
+ removeDuplicateFrom(swappers.map((s) => s.swapperGroup))
40
+ .map((swapperGroup) => {
41
+ return swappers.find((s) => s.swapperGroup === swapperGroup);
42
42
  })
43
- .find(s => {
43
+ .find((s) => {
44
44
  if (s) {
45
45
  for (const type of s.types) {
46
46
  if (supportedSwappers !== 'all') {
@@ -76,11 +76,10 @@ export function SettingsPage({ supportedSwappers }: PropTypes) {
76
76
  <Settings
77
77
  slippages={SLIPPAGES}
78
78
  selectedSlippage={slippage}
79
- onSlippageChange={slippage => setSlippage(slippage)}
80
- onLiquiditySourcesClick={navigate.bind(
81
- null,
82
- navigationRoutes.liquiditySources
83
- )}
79
+ onSlippageChange={(slippage) => setSlippage(slippage)}
80
+ onLiquiditySourcesClick={() =>
81
+ navigate(navigationRoutes.liquiditySources)
82
+ }
84
83
  onBack={navigateBackFrom.bind(null, navigationRoutes.settings)}
85
84
  liquiditySources={supportedUniqueSwappersGroups}
86
85
  selectedLiquiditySources={supportedUniqueSwappersGroups.filter(
@@ -7,9 +7,10 @@ import {
7
7
  WalletState,
8
8
  } from '@rango-dev/ui';
9
9
  import React, { useEffect, useState } from 'react';
10
- import { getlistWallet } from '../utils/wallets';
11
- import { WalletType } from '@rango-dev/wallets-shared';
10
+ import { getlistWallet, sortWalletsBasedOnState } from '../utils/wallets';
11
+ import { WalletType, detectMobileScreens } from '@rango-dev/wallets-shared';
12
12
  import { useWallets } from '@rango-dev/wallets-core';
13
+
13
14
  import { useUiStore } from '../store/ui';
14
15
  import { useNavigateBack } from '../hooks/useNavigateBack';
15
16
  import { navigationRoutes } from '../constants/navigationRoutes';
@@ -40,6 +41,11 @@ export function WalletsPage({ supportedWallets, multiWallets }: PropTypes) {
40
41
  getWalletInfo,
41
42
  supportedWallets === 'all' ? Object.values(WalletType) : supportedWallets
42
43
  );
44
+
45
+ let sortedWallets = detectMobileScreens()
46
+ ? wallets.filter((wallet) => wallet.showOnMobile)
47
+ : wallets;
48
+ sortedWallets = sortWalletsBasedOnState(sortedWallets);
43
49
  const [walletErrorMessage, setWalletErrorMessage] = useState('');
44
50
  const toggleConnectWalletsButton =
45
51
  useUiStore.use.toggleConnectWalletsButton();
@@ -61,7 +67,7 @@ export function WalletsPage({ supportedWallets, multiWallets }: PropTypes) {
61
67
  await connect(type);
62
68
  }
63
69
  } catch (e) {
64
- setWalletErrorMessage('Error: ' + e.message);
70
+ setWalletErrorMessage('Error: ' + (e as any)?.message);
65
71
  }
66
72
  };
67
73
 
@@ -72,7 +78,7 @@ export function WalletsPage({ supportedWallets, multiWallets }: PropTypes) {
72
78
 
73
79
  return (
74
80
  <SecondaryPage
75
- title={t('Select Wallet')}
81
+ title={t('Select Wallet') || ''}
76
82
  textField={false}
77
83
  onBack={navigateBackFrom.bind(null, navigationRoutes.wallets)}
78
84
  >
@@ -85,8 +91,12 @@ export function WalletsPage({ supportedWallets, multiWallets }: PropTypes) {
85
91
  </AlertContainer>
86
92
  )}
87
93
  <ListContainer>
88
- {wallets.map((info, index) => (
89
- <Wallet {...info} key={index} onClick={onSelectWallet} />
94
+ {sortedWallets.map((wallet, index) => (
95
+ <Wallet
96
+ {...wallet}
97
+ key={`${index}-${wallet.type}`}
98
+ onClick={onSelectWallet}
99
+ />
90
100
  ))}
91
101
  </ListContainer>
92
102
  </>
@@ -3,29 +3,41 @@ import { Token } from 'rango-sdk';
3
3
  import { create } from 'zustand';
4
4
  import BigNumber from 'bignumber.js';
5
5
  import { ZERO } from '../constants/numbers';
6
- import { getBestRouteToTokenUsdPrice } from '../utils/routing';
6
+ import {
7
+ getBestRouteToTokenUsdPrice,
8
+ isRouteParametersChanged,
9
+ } from '../utils/routing';
7
10
  import createSelectors from './selectors';
8
11
  import { subscribeWithSelector } from 'zustand/middleware';
9
12
  import { httpService } from '../services/httpService';
10
13
  import { useSettingsStore } from './settings';
11
14
  import { createBestRouteRequestBody } from '../utils/swap';
15
+ import { useMetaStore } from './meta';
16
+ import { getDefaultToken, getSortedTokens } from '../utils/wallets';
17
+ import { useWalletsStore } from './wallets';
18
+ import { TokenWithBalance } from '../pages/SelectTokenPage';
12
19
 
13
20
  const getUsdValue = (token: Token | null, amount: string) =>
14
21
  new BigNumber(amount || ZERO).multipliedBy(token?.usdPrice || 0);
15
22
 
16
- interface RouteState {
23
+ export interface RouteState {
17
24
  fromChain: BlockchainMeta | null;
18
25
  toChain: BlockchainMeta | null;
19
26
  inputAmount: string;
20
27
  inputUsdValue: BigNumber;
21
28
  outputAmount: BigNumber | null;
22
29
  outputUsdValue: BigNumber;
23
- fromToken: Token | null;
24
- toToken: Token | null;
30
+ fromToken: TokenWithBalance | null;
31
+ toToken: TokenWithBalance | null;
25
32
  loading: boolean;
26
33
  error: string;
27
- setFromChain: (chain: BlockchainMeta | null) => void;
28
- setToChain: (chian: BlockchainMeta | null) => void;
34
+ sourceTokens: Token[];
35
+ destinationTokens: Token[];
36
+ setFromChain: (
37
+ chain: BlockchainMeta | null,
38
+ setDefaultToken?: boolean
39
+ ) => void;
40
+ setToChain: (chian: BlockchainMeta | null, setDefaultToken?: boolean) => void;
29
41
  setFromToken: (token: Token | null) => void;
30
42
  setToToken: (token: Token | null) => void;
31
43
  setInputAmount: (amount: string) => void;
@@ -47,6 +59,8 @@ export const useBestRouteStore = createSelectors(
47
59
  bestRoute: null,
48
60
  loading: false,
49
61
  error: '',
62
+ sourceTokens: [],
63
+ destinationTokens: [],
50
64
  setBestRoute: (bestRoute) =>
51
65
  set((state) => {
52
66
  let outputAmount: BigNumber | null = null;
@@ -69,10 +83,30 @@ export const useBestRouteStore = createSelectors(
69
83
  }),
70
84
  };
71
85
  }),
72
- setFromChain: (chain) =>
73
- set(() => ({
74
- fromChain: chain,
75
- })),
86
+ setFromChain: (chain, setDefaultToken) => {
87
+ set((state) => {
88
+ if (state.fromChain?.name === chain?.name) return {};
89
+ const tokens = useMetaStore.getState().meta.tokens;
90
+ const balances = useWalletsStore.getState().balances;
91
+ const sortedTokens = getSortedTokens(
92
+ chain,
93
+ tokens,
94
+ balances,
95
+ state.destinationTokens
96
+ );
97
+ const fromToken = getDefaultToken(sortedTokens, state.toToken);
98
+ return {
99
+ fromChain: chain,
100
+ sourceTokens: sortedTokens,
101
+ ...(setDefaultToken && {
102
+ fromToken,
103
+ }),
104
+ ...(!!state.inputAmount && {
105
+ inputUsdValue: getUsdValue(fromToken, state.inputAmount),
106
+ }),
107
+ };
108
+ });
109
+ },
76
110
  setFromToken: (token) =>
77
111
  set((state) => ({
78
112
  fromToken: token,
@@ -80,21 +114,44 @@ export const useBestRouteStore = createSelectors(
80
114
  inputUsdValue: getUsdValue(token, state.inputAmount),
81
115
  }),
82
116
  })),
83
- setToChain: (chain) =>
84
- set(() => ({
85
- toChain: chain,
86
- })),
117
+ setToChain: (chain, setDefaultToken) => {
118
+ set((state) => {
119
+ if (state.toChain?.name === chain?.name) return {};
120
+ const tokens = useMetaStore.getState().meta.tokens;
121
+ const balances = useWalletsStore.getState().balances;
122
+ const sortedTokens = getSortedTokens(
123
+ chain,
124
+ tokens,
125
+ balances,
126
+ state.destinationTokens
127
+ );
128
+
129
+ return {
130
+ toChain: chain,
131
+ destinationTokens: sortedTokens,
132
+ ...(setDefaultToken && {
133
+ toToken: getDefaultToken(sortedTokens, state.fromToken),
134
+ }),
135
+ };
136
+ });
137
+ },
87
138
  setToToken: (token) =>
88
139
  set(() => ({
89
140
  toToken: token,
90
141
  })),
91
- setInputAmount: (amount) =>
142
+ setInputAmount: (amount) => {
92
143
  set((state) => ({
93
144
  inputAmount: amount,
145
+ ...(!amount && {
146
+ outputAmount: new BigNumber(0),
147
+ outputUsdValue: new BigNumber(0),
148
+ bestRoute: null,
149
+ }),
94
150
  ...(!!state.fromToken && {
95
151
  inputUsdValue: getUsdValue(state.fromToken, amount),
96
152
  }),
97
- })),
153
+ }));
154
+ },
98
155
  }))
99
156
  )
100
157
  );
@@ -111,7 +168,7 @@ const bestRoute = (
111
168
  if (!fromToken || !toToken || !inputAmount) return;
112
169
  abortController?.abort();
113
170
  abortController = new AbortController();
114
- const userSlippage = customSlippage | slippage;
171
+ const userSlippage = !!customSlippage ? customSlippage : slippage;
115
172
  const requestBody = createBestRouteRequestBody(
116
173
  fromToken,
117
174
  toToken,
@@ -122,7 +179,12 @@ const bestRoute = (
122
179
  userSlippage,
123
180
  false
124
181
  );
125
- bestRouteStore.setState({ loading: true, bestRoute: null });
182
+ bestRouteStore.setState({
183
+ loading: true,
184
+ bestRoute: null,
185
+ outputAmount: null,
186
+ outputUsdValue: new BigNumber(0),
187
+ });
126
188
  httpService
127
189
  .getBestRoute(requestBody, {
128
190
  signal: abortController.signal,
@@ -154,18 +216,7 @@ const bestRoute = (
154
216
  fetchBestRoute.bind(null),
155
217
  {
156
218
  equalityFn: (prevState, state) => {
157
- if (
158
- prevState.fromChain?.name !== state.fromChain?.name ||
159
- prevState.toChain?.name !== state.toChain?.name ||
160
- prevState.fromToken?.symbol !== state.fromToken?.symbol ||
161
- prevState.toToken?.symbol !== state.toToken?.symbol ||
162
- prevState.fromToken?.blockchain !== state.fromToken?.blockchain ||
163
- prevState.toToken?.blockchain !== state.toToken?.blockchain ||
164
- prevState.fromToken?.address !== state.fromToken?.address ||
165
- prevState.toToken?.address !== state.toToken?.address ||
166
- prevState.inputAmount !== state.inputAmount
167
- )
168
- return false;
219
+ if (isRouteParametersChanged(prevState, state)) return false;
169
220
  else return true;
170
221
  },
171
222
  }
@@ -180,13 +231,7 @@ const bestRoute = (
180
231
  fetchBestRoute.bind(null),
181
232
  {
182
233
  equalityFn: (prevState, state) => {
183
- if (
184
- prevState.slippage !== state.slippage ||
185
- prevState.customSlippage !== state.customSlippage ||
186
- prevState.disabledLiquiditySources.length !==
187
- state.disabledLiquiditySources.length
188
- )
189
- return false;
234
+ if (isRouteParametersChanged(prevState, state)) return false;
190
235
  else return true;
191
236
  },
192
237
  }
@@ -7,7 +7,7 @@ import createSelectors from './selectors';
7
7
 
8
8
  type Theme = 'auto' | 'dark' | 'light';
9
9
 
10
- interface Settings {
10
+ export interface SettingsState {
11
11
  slippage: number;
12
12
  customSlippage: number | null;
13
13
  infiniteApprove: boolean;
@@ -22,7 +22,7 @@ interface Settings {
22
22
  }
23
23
 
24
24
  export const useSettingsStore = createSelectors(
25
- create<Settings>()(
25
+ create<SettingsState>()(
26
26
  persist(
27
27
  subscribeWithSelector((set) => ({
28
28
  slippage: DEFAULT_SLIPPAGE,
@@ -5,14 +5,17 @@ import { subscribeWithSelector } from 'zustand/middleware';
5
5
  import { httpService } from '../services/httpService';
6
6
  import {
7
7
  getRequiredChains,
8
+ getTokensWithBalance,
8
9
  isAccountAndBalanceMatched,
9
10
  makeBalanceFor,
10
11
  resetBalanceState,
11
12
  SelectedWallet,
13
+ sortTokens,
12
14
  } from '../utils/wallets';
13
15
  import { useBestRouteStore } from './bestRoute';
14
16
  import { useMetaStore } from './meta';
15
17
  import createSelectors from './selectors';
18
+ import { shallow } from 'zustand/shallow';
16
19
 
17
20
  export interface Account {
18
21
  chain: string;
@@ -162,3 +165,26 @@ export const useWalletsStore = createSelectors(
162
165
  }))
163
166
  )
164
167
  );
168
+
169
+ useWalletsStore.subscribe(
170
+ (state) => state.balances,
171
+ (balances) => {
172
+ useBestRouteStore.setState(({ sourceTokens, destinationTokens }) => {
173
+ const sourceTokensWithBalance = getTokensWithBalance(
174
+ sourceTokens,
175
+ balances
176
+ );
177
+ const destinationTokensWithBalance = getTokensWithBalance(
178
+ destinationTokens,
179
+ balances
180
+ );
181
+ return {
182
+ sourceTokens: sortTokens(sourceTokensWithBalance),
183
+ destinationTokens: sortTokens(destinationTokensWithBalance),
184
+ };
185
+ });
186
+ },
187
+ {
188
+ equalityFn: shallow,
189
+ }
190
+ );
@@ -1,2 +1,3 @@
1
1
  export * from './swap';
2
2
  export * from './config';
3
+ export * from './routing';
@@ -0,0 +1,60 @@
1
+ import { RouteState } from '../store/bestRoute';
2
+ import { SettingsState } from '../store/settings';
3
+
4
+ export interface BestRouteParams {
5
+ fromChain?: RouteState['fromChain'];
6
+ toChain?: RouteState['toChain'];
7
+ fromToken?: RouteState['fromToken'];
8
+ toToken?: RouteState['toToken'];
9
+ inputAmount?: RouteState['inputAmount'];
10
+ slippage?: SettingsState['slippage'];
11
+ customSlippage?: SettingsState['customSlippage'];
12
+ disabledLiquiditySources?: SettingsState['disabledLiquiditySources'];
13
+ }
14
+
15
+ export enum ConfirmSwapErrorTypes {
16
+ NO_ROUTE,
17
+ ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS,
18
+ REQUEST_FAILED,
19
+ INSUFFICIENT_SLIPPAGE,
20
+ }
21
+
22
+ export type ConfirmSwapError =
23
+ | {
24
+ type: ConfirmSwapErrorTypes.REQUEST_FAILED;
25
+ status?: number;
26
+ }
27
+ | {
28
+ type: ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE;
29
+ minRequiredSlippage: number | null;
30
+ }
31
+ | {
32
+ type: Exclude<
33
+ ConfirmSwapErrorTypes,
34
+ | ConfirmSwapErrorTypes.REQUEST_FAILED
35
+ | ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE
36
+ >;
37
+ };
38
+
39
+ export type ConfirmSwapWarnings =
40
+ | {
41
+ type: ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED;
42
+ newOutputAmount: string;
43
+ percentageChange: string;
44
+ }
45
+ | { type: ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE; messages: string[] }
46
+ | {
47
+ type: Exclude<
48
+ ConfirmSwapWarningTypes,
49
+ | ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED
50
+ | ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE
51
+ >;
52
+ };
53
+
54
+ export enum ConfirmSwapWarningTypes {
55
+ ROUTE_UPDATED,
56
+ ROUTE_SWAPPERS_UPDATED,
57
+ ROUTE_COINS_UPDATED,
58
+ ROUTE_AND_OUTPUT_AMOUNT_UPDATED,
59
+ INSUFFICIENT_BALANCE,
60
+ }