@rango-dev/widget-embedded 0.1.10-next.93 → 0.1.10-next.95
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.
- package/dist/QueueManager.d.ts.map +1 -1
- package/dist/components/AppRoutes.d.ts +5 -1
- package/dist/components/AppRoutes.d.ts.map +1 -1
- package/dist/components/ConfirmSwapErrors.d.ts +3 -2
- package/dist/components/ConfirmSwapErrors.d.ts.map +1 -1
- package/dist/components/ConfirmSwapWarnings.d.ts +3 -2
- package/dist/components/ConfirmSwapWarnings.d.ts.map +1 -1
- package/dist/components/Layout.d.ts +1 -1
- package/dist/components/Layout.d.ts.map +1 -1
- package/dist/components/SwitchFromAndTo.d.ts +1 -1
- package/dist/components/SwitchFromAndTo.d.ts.map +1 -1
- package/dist/components/UpdateUrl.d.ts +1 -1
- package/dist/components/UpdateUrl.d.ts.map +1 -1
- package/dist/components/warnings/BalanceWarnings.d.ts.map +1 -1
- package/dist/components/warnings/ConfirmSwapExtraMessages.d.ts.map +1 -1
- package/dist/hooks/useConfirmSwap.d.ts +11 -0
- package/dist/hooks/useConfirmSwap.d.ts.map +1 -0
- package/dist/hooks/usePrevious.d.ts +1 -1
- package/dist/hooks/usePrevious.d.ts.map +1 -1
- package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
- package/dist/pages/Home.d.ts.map +1 -1
- package/dist/pages/SelectChainPage.d.ts.map +1 -1
- package/dist/pages/SelectTokenPage.d.ts.map +1 -1
- package/dist/pages/SettingsPage.d.ts.map +1 -1
- package/dist/pages/WalletsPage.d.ts.map +1 -1
- package/dist/store/bestRoute.d.ts +25 -0
- package/dist/store/bestRoute.d.ts.map +1 -1
- package/dist/store/settings.d.ts +15 -0
- package/dist/store/settings.d.ts.map +1 -1
- package/dist/store/wallets.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/{store/confirmSwap.d.ts → types/routing.d.ts} +14 -5
- package/dist/types/routing.d.ts.map +1 -0
- package/dist/utils/numbers.d.ts +1 -1
- package/dist/utils/numbers.d.ts.map +1 -1
- package/dist/utils/routing.d.ts +11 -5
- package/dist/utils/routing.d.ts.map +1 -1
- package/dist/utils/swap.d.ts +4 -3
- package/dist/utils/swap.d.ts.map +1 -1
- package/dist/utils/wallets.d.ts +7 -2
- package/dist/utils/wallets.d.ts.map +1 -1
- package/dist/widget-embedded.cjs.development.js +575 -479
- package/dist/widget-embedded.cjs.development.js.map +1 -1
- package/dist/widget-embedded.cjs.production.min.js +575 -479
- package/dist/widget-embedded.cjs.production.min.js.map +1 -1
- package/dist/widget-embedded.esm.js +576 -480
- package/dist/widget-embedded.esm.js.map +1 -1
- package/package.json +3 -3
- package/src/QueueManager.tsx +1 -0
- package/src/components/AppRoutes.tsx +54 -21
- package/src/components/ChangeSlippageButton.tsx +1 -1
- package/src/components/ConfirmSwapErrors.tsx +1 -1
- package/src/components/ConfirmSwapWarnings.tsx +1 -4
- package/src/components/Header.tsx +1 -1
- package/src/components/Layout.tsx +3 -3
- package/src/components/UpdateUrl.tsx +13 -22
- package/src/components/warnings/BalanceWarnings.tsx +27 -4
- package/src/components/warnings/ConfirmSwapExtraMessages.tsx +7 -1
- package/src/components/warnings/HighSlippageWarning.tsx +1 -1
- package/src/components/warnings/MinRequiredSlippage.tsx +2 -2
- package/src/hooks/useConfirmSwap.ts +260 -0
- package/src/pages/ConfirmSwapPage.tsx +17 -8
- package/src/pages/ConfirmWalletsPage.tsx +1 -1
- package/src/pages/Home.tsx +0 -1
- package/src/pages/SelectChainPage.tsx +2 -7
- package/src/pages/SelectTokenPage.tsx +22 -57
- package/src/pages/SettingsPage.tsx +8 -9
- package/src/pages/WalletsPage.tsx +16 -6
- package/src/store/bestRoute.ts +82 -37
- package/src/store/settings.ts +2 -2
- package/src/store/wallets.ts +26 -0
- package/src/types/index.ts +1 -0
- package/src/types/routing.ts +60 -0
- package/src/utils/numbers.ts +38 -17
- package/src/utils/routing.ts +115 -24
- package/src/utils/swap.ts +20 -12
- package/src/utils/wallets.ts +117 -73
- package/dist/store/confirmSwap.d.ts.map +0 -1
- package/src/store/confirmSwap.ts +0 -342
|
@@ -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={() =>
|
package/src/pages/Home.tsx
CHANGED
|
@@ -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
|
|
25
|
+
const sourceTokens = useBestRouteStore.use.sourceTokens();
|
|
26
|
+
const destinationTokens = useBestRouteStore.use.destinationTokens();
|
|
27
|
+
const supportedSourceTokens =
|
|
32
28
|
supportedTokens === 'all'
|
|
33
|
-
?
|
|
34
|
-
:
|
|
35
|
-
|
|
36
|
-
|
|
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={
|
|
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={
|
|
81
|
-
|
|
82
|
-
|
|
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
|
|
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
|
-
{
|
|
89
|
-
<Wallet
|
|
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
|
</>
|
package/src/store/bestRoute.ts
CHANGED
|
@@ -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 {
|
|
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:
|
|
24
|
-
toToken:
|
|
30
|
+
fromToken: TokenWithBalance | null;
|
|
31
|
+
toToken: TokenWithBalance | null;
|
|
25
32
|
loading: boolean;
|
|
26
33
|
error: string;
|
|
27
|
-
|
|
28
|
-
|
|
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
|
|
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
|
|
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
|
|
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({
|
|
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
|
}
|
package/src/store/settings.ts
CHANGED
|
@@ -7,7 +7,7 @@ import createSelectors from './selectors';
|
|
|
7
7
|
|
|
8
8
|
type Theme = 'auto' | 'dark' | 'light';
|
|
9
9
|
|
|
10
|
-
interface
|
|
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<
|
|
25
|
+
create<SettingsState>()(
|
|
26
26
|
persist(
|
|
27
27
|
subscribeWithSelector((set) => ({
|
|
28
28
|
slippage: DEFAULT_SLIPPAGE,
|
package/src/store/wallets.ts
CHANGED
|
@@ -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
|
+
);
|
package/src/types/index.ts
CHANGED
|
@@ -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
|
+
}
|
package/src/utils/numbers.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { BigNumber } from 'bignumber.js';
|
|
2
2
|
import { BestRouteResponse } from 'rango-sdk';
|
|
3
3
|
|
|
4
|
-
export const percentToString = (p: number, fractions = 0): string =>
|
|
4
|
+
export const percentToString = (p: number, fractions = 0): string =>
|
|
5
|
+
(p * 100).toFixed(fractions);
|
|
5
6
|
export const secondsToString = (s: number): string => {
|
|
6
7
|
const seconds = (s % 60).toString().padStart(2, '0');
|
|
7
8
|
const minutes = parseInt((s / 60).toString())
|
|
@@ -13,7 +14,7 @@ export const secondsToString = (s: number): string => {
|
|
|
13
14
|
export const numberToString = (
|
|
14
15
|
number: BigNumber | string | null,
|
|
15
16
|
minDecimals: number | null = null,
|
|
16
|
-
maxDecimals: number | null = null
|
|
17
|
+
maxDecimals: number | null = null
|
|
17
18
|
): string => {
|
|
18
19
|
if (number === null) return '';
|
|
19
20
|
if (number === '') return '';
|
|
@@ -30,39 +31,57 @@ export const numberToString = (
|
|
|
30
31
|
if (n.gte(10000)) return n.toFormat(0, roundingMode);
|
|
31
32
|
if (n.gte(1000))
|
|
32
33
|
return n.toFormat(
|
|
33
|
-
Math.min(
|
|
34
|
-
|
|
34
|
+
Math.min(
|
|
35
|
+
maxI,
|
|
36
|
+
Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 1))
|
|
37
|
+
),
|
|
38
|
+
roundingMode
|
|
35
39
|
);
|
|
36
40
|
if (n.gte(100))
|
|
37
41
|
return n.toFormat(
|
|
38
|
-
Math.min(
|
|
39
|
-
|
|
42
|
+
Math.min(
|
|
43
|
+
maxI,
|
|
44
|
+
Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 1))
|
|
45
|
+
),
|
|
46
|
+
roundingMode
|
|
40
47
|
);
|
|
41
48
|
if (n.gte(1))
|
|
42
49
|
return n.toFormat(
|
|
43
|
-
Math.min(
|
|
44
|
-
|
|
50
|
+
Math.min(
|
|
51
|
+
maxI,
|
|
52
|
+
Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 2))
|
|
53
|
+
),
|
|
54
|
+
roundingMode
|
|
45
55
|
);
|
|
46
56
|
if (n.gte(0.01))
|
|
47
57
|
return n.toFormat(
|
|
48
|
-
Math.min(
|
|
49
|
-
|
|
58
|
+
Math.min(
|
|
59
|
+
maxI,
|
|
60
|
+
Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 4))
|
|
61
|
+
),
|
|
62
|
+
roundingMode
|
|
50
63
|
);
|
|
51
64
|
for (let i = minDecimals || 4; i < 17; i++)
|
|
52
65
|
if (n.gte(Math.pow(10, -i)))
|
|
53
66
|
return n.toFormat(
|
|
54
|
-
Math.min(
|
|
55
|
-
|
|
67
|
+
Math.min(
|
|
68
|
+
maxI,
|
|
69
|
+
Math.min(maxDecimals || 100, Math.max(minDecimals || 0, i))
|
|
70
|
+
),
|
|
71
|
+
roundingMode
|
|
56
72
|
);
|
|
57
73
|
if (n.isEqualTo(0)) return '0';
|
|
58
74
|
|
|
59
75
|
return n.toFormat(
|
|
60
76
|
Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 8))),
|
|
61
|
-
roundingMode
|
|
77
|
+
roundingMode
|
|
62
78
|
);
|
|
63
79
|
};
|
|
64
80
|
|
|
65
|
-
export const convertBigNumberToHex = (
|
|
81
|
+
export const convertBigNumberToHex = (
|
|
82
|
+
value: BigNumber,
|
|
83
|
+
decimals: number
|
|
84
|
+
): string => {
|
|
66
85
|
return '0x' + value.shiftedBy(decimals).toString(16);
|
|
67
86
|
};
|
|
68
87
|
|
|
@@ -100,13 +119,15 @@ export const totalArrivalTime = (data: BestRouteResponse | null) =>
|
|
|
100
119
|
|
|
101
120
|
export const rawFees = (data: BestRouteResponse): string =>
|
|
102
121
|
(
|
|
103
|
-
data?.result?.swaps?.flatMap((s) =>
|
|
104
|
-
|
|
122
|
+
data?.result?.swaps?.flatMap((s) =>
|
|
123
|
+
s.fee.map((f) => ({ swapperId: s.swapperId, fee: f }))
|
|
124
|
+
) || []
|
|
105
125
|
)
|
|
106
126
|
.reduce((partialSum, a) => partialSum + parseFloat(a.fee.amount), 0)
|
|
107
127
|
.toFixed(3);
|
|
108
128
|
|
|
109
|
-
export const decimalNumber = (number = '0', toFixed: number) =>
|
|
129
|
+
export const decimalNumber = (number = '0', toFixed: number) =>
|
|
130
|
+
parseFloat(number).toFixed(toFixed);
|
|
110
131
|
|
|
111
132
|
export const containsText = (text: string, searchText: string) =>
|
|
112
133
|
text.toLowerCase().indexOf(searchText.toLowerCase()) > -1;
|