@rango-dev/widget-embedded 0.1.10-next.99 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App.d.ts.map +1 -1
- package/dist/QueueManager.d.ts.map +1 -1
- package/dist/components/AppRouter.d.ts +6 -1
- package/dist/components/AppRouter.d.ts.map +1 -1
- package/dist/components/AppRoutes.d.ts.map +1 -1
- package/dist/components/HeaderButtons.d.ts +4 -1
- package/dist/components/HeaderButtons.d.ts.map +1 -1
- package/dist/components/Layout.d.ts.map +1 -1
- package/dist/components/SwapDetailsPlaceholder.d.ts +9 -0
- package/dist/components/SwapDetailsPlaceholder.d.ts.map +1 -0
- package/dist/components/TokenPreview.d.ts +1 -1
- package/dist/components/TokenPreview.d.ts.map +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/MinRequiredSlippage.d.ts +1 -1
- package/dist/components/warnings/MinRequiredSlippage.d.ts.map +1 -1
- package/dist/constants/navigationRoutes.d.ts +0 -1
- package/dist/constants/navigationRoutes.d.ts.map +1 -1
- package/dist/globalStyles.d.ts.map +1 -1
- package/dist/hooks/useConfirmSwap.d.ts.map +1 -1
- package/dist/lib.d.ts.map +1 -1
- package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
- package/dist/pages/HistoryPage.d.ts.map +1 -1
- package/dist/pages/Home.d.ts.map +1 -1
- package/dist/pages/LiquiditySourcesPage.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/SwapDetailsPage.d.ts.map +1 -1
- package/dist/pages/WalletsPage.d.ts +1 -0
- package/dist/pages/WalletsPage.d.ts.map +1 -1
- package/dist/store/bestRoute.d.ts +2 -0
- package/dist/store/bestRoute.d.ts.map +1 -1
- package/dist/store/ui.d.ts.map +1 -1
- package/dist/store/wallets.d.ts +14 -0
- package/dist/store/wallets.d.ts.map +1 -1
- package/dist/types/routing.d.ts +1 -1
- package/dist/types/swap.d.ts +6 -0
- package/dist/types/swap.d.ts.map +1 -1
- package/dist/utils/common.d.ts +1 -0
- package/dist/utils/common.d.ts.map +1 -1
- package/dist/utils/date.d.ts +3 -0
- package/dist/utils/date.d.ts.map +1 -0
- package/dist/utils/routing.d.ts +1 -0
- package/dist/utils/routing.d.ts.map +1 -1
- package/dist/utils/swap.d.ts +16 -5
- package/dist/utils/swap.d.ts.map +1 -1
- package/dist/utils/time.d.ts +4 -0
- package/dist/utils/time.d.ts.map +1 -0
- package/dist/utils/wallets.d.ts +1 -1
- package/dist/utils/wallets.d.ts.map +1 -1
- package/dist/widget-embedded.cjs.development.js +1048 -705
- package/dist/widget-embedded.cjs.development.js.map +1 -1
- package/dist/widget-embedded.cjs.production.min.js +1048 -705
- package/dist/widget-embedded.cjs.production.min.js.map +1 -1
- package/dist/widget-embedded.esm.js +1057 -714
- package/dist/widget-embedded.esm.js.map +1 -1
- package/package.json +12 -11
- package/readme.md +1 -2
- package/src/App.tsx +30 -5
- package/src/QueueManager.tsx +5 -2
- package/src/components/AppRouter.tsx +24 -13
- package/src/components/AppRoutes.tsx +15 -12
- package/src/components/HeaderButtons.tsx +9 -2
- package/src/components/Layout.tsx +37 -5
- package/src/components/SwapDetailsPlaceholder.tsx +32 -0
- package/src/components/TokenPreview.tsx +7 -4
- package/src/components/UpdateUrl.tsx +1 -3
- package/src/components/warnings/BalanceWarnings.tsx +1 -0
- package/src/components/warnings/MinRequiredSlippage.tsx +9 -4
- package/src/constants/navigationRoutes.ts +0 -1
- package/src/globalStyles.ts +2 -1
- package/src/hooks/useConfirmSwap.ts +2 -1
- package/src/hooks/useNavigateBack.ts +3 -3
- package/src/lib.tsx +25 -3
- package/src/pages/ConfirmSwapPage.tsx +128 -20
- package/src/pages/HistoryPage.tsx +4 -4
- package/src/pages/Home.tsx +19 -8
- package/src/pages/LiquiditySourcesPage.tsx +2 -0
- package/src/pages/SelectTokenPage.tsx +3 -1
- package/src/pages/SettingsPage.tsx +3 -0
- package/src/pages/SwapDetailsPage.tsx +142 -6
- package/src/pages/WalletsPage.tsx +47 -11
- package/src/store/bestRoute.ts +110 -12
- package/src/store/ui.ts +4 -0
- package/src/store/wallets.ts +4 -1
- package/src/types/routing.ts +1 -1
- package/src/types/swap.ts +7 -0
- package/src/utils/common.ts +14 -0
- package/src/utils/date.ts +62 -0
- package/src/utils/routing.ts +23 -13
- package/src/utils/swap.ts +101 -10
- package/src/utils/time.ts +52 -0
- package/src/utils/wallets.ts +13 -4
- package/dist/components/Header.d.ts +0 -10
- package/dist/components/Header.d.ts.map +0 -1
- package/dist/pages/ConfirmWalletsPage.d.ts +0 -3
- package/dist/pages/ConfirmWalletsPage.d.ts.map +0 -1
- package/src/components/Header.tsx +0 -37
- package/src/pages/ConfirmWalletsPage.tsx +0 -127
|
@@ -4,8 +4,9 @@ import {
|
|
|
4
4
|
styled,
|
|
5
5
|
Wallet,
|
|
6
6
|
WalletState,
|
|
7
|
+
WalletInfo,
|
|
7
8
|
} from '@rango-dev/ui';
|
|
8
|
-
import React, { useEffect, useState } from 'react';
|
|
9
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
9
10
|
import { getlistWallet, sortWalletsBasedOnState } from '../utils/wallets';
|
|
10
11
|
import { WalletType, detectMobileScreens } from '@rango-dev/wallets-shared';
|
|
11
12
|
import { useWallets } from '@rango-dev/wallets-core';
|
|
@@ -14,6 +15,9 @@ import { useUiStore } from '../store/ui';
|
|
|
14
15
|
import { useNavigateBack } from '../hooks/useNavigateBack';
|
|
15
16
|
import { navigationRoutes } from '../constants/navigationRoutes';
|
|
16
17
|
import { useTranslation } from 'react-i18next';
|
|
18
|
+
import { useMetaStore } from '../store/meta';
|
|
19
|
+
import { Spinner } from '@rango-dev/ui';
|
|
20
|
+
import { LoadingFailedAlert } from '@rango-dev/ui';
|
|
17
21
|
|
|
18
22
|
interface PropTypes {
|
|
19
23
|
supportedWallets: 'all' | WalletType[];
|
|
@@ -24,9 +28,17 @@ const ListContainer = styled('div', {
|
|
|
24
28
|
display: 'grid',
|
|
25
29
|
gap: '.5rem',
|
|
26
30
|
gridTemplateColumns: ' repeat(2, minmax(0, 1fr))',
|
|
27
|
-
height: '450px',
|
|
28
31
|
alignContent: 'baseline',
|
|
29
32
|
padding: '0.5rem',
|
|
33
|
+
overflowY: 'auto',
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export const LoaderContainer = styled('div', {
|
|
37
|
+
display: 'flex',
|
|
38
|
+
justifyContent: 'center',
|
|
39
|
+
width: '100%',
|
|
40
|
+
position: 'absolute',
|
|
41
|
+
top: '50%',
|
|
30
42
|
});
|
|
31
43
|
|
|
32
44
|
const AlertContainer = styled('div', {
|
|
@@ -40,6 +52,7 @@ export function WalletsPage({ supportedWallets, multiWallets }: PropTypes) {
|
|
|
40
52
|
getWalletInfo,
|
|
41
53
|
supportedWallets === 'all' ? Object.values(WalletType) : supportedWallets
|
|
42
54
|
);
|
|
55
|
+
const walletsRef = useRef<WalletInfo[]>();
|
|
43
56
|
|
|
44
57
|
let sortedWallets = detectMobileScreens()
|
|
45
58
|
? wallets.filter((wallet) => wallet.showOnMobile)
|
|
@@ -48,6 +61,7 @@ export function WalletsPage({ supportedWallets, multiWallets }: PropTypes) {
|
|
|
48
61
|
const [walletErrorMessage, setWalletErrorMessage] = useState('');
|
|
49
62
|
const toggleConnectWalletsButton =
|
|
50
63
|
useUiStore.use.toggleConnectWalletsButton();
|
|
64
|
+
const loadingMetaStatus = useMetaStore.use.loadingStatus();
|
|
51
65
|
const { t } = useTranslation();
|
|
52
66
|
|
|
53
67
|
const onSelectWallet = async (type: WalletType) => {
|
|
@@ -69,12 +83,27 @@ export function WalletsPage({ supportedWallets, multiWallets }: PropTypes) {
|
|
|
69
83
|
setWalletErrorMessage('Error: ' + (e as any)?.message);
|
|
70
84
|
}
|
|
71
85
|
};
|
|
72
|
-
|
|
86
|
+
const disconnectConnectingWallets = () => {
|
|
87
|
+
const connectingWallets =
|
|
88
|
+
walletsRef.current?.filter(
|
|
89
|
+
(wallet) => wallet.state === WalletState.CONNECTING
|
|
90
|
+
) || [];
|
|
91
|
+
for (const wallet of connectingWallets) {
|
|
92
|
+
disconnect(wallet.type);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
73
95
|
useEffect(() => {
|
|
74
96
|
toggleConnectWalletsButton();
|
|
75
|
-
return () =>
|
|
97
|
+
return () => {
|
|
98
|
+
disconnectConnectingWallets();
|
|
99
|
+
toggleConnectWalletsButton();
|
|
100
|
+
};
|
|
76
101
|
}, []);
|
|
77
102
|
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
walletsRef.current = wallets;
|
|
105
|
+
}, [wallets]);
|
|
106
|
+
|
|
78
107
|
return (
|
|
79
108
|
<SecondaryPage
|
|
80
109
|
title={t('Select Wallet') || ''}
|
|
@@ -87,14 +116,21 @@ export function WalletsPage({ supportedWallets, multiWallets }: PropTypes) {
|
|
|
87
116
|
<Alert type="error">{walletErrorMessage}</Alert>
|
|
88
117
|
</AlertContainer>
|
|
89
118
|
)}
|
|
119
|
+
{loadingMetaStatus === 'loading' && (
|
|
120
|
+
<LoaderContainer className="loader">
|
|
121
|
+
<Spinner size={24} />
|
|
122
|
+
</LoaderContainer>
|
|
123
|
+
)}
|
|
124
|
+
{loadingMetaStatus === 'failed' && <LoadingFailedAlert />}
|
|
90
125
|
<ListContainer>
|
|
91
|
-
{
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
126
|
+
{loadingMetaStatus === 'success' &&
|
|
127
|
+
sortedWallets.map((wallet, index) => (
|
|
128
|
+
<Wallet
|
|
129
|
+
{...wallet}
|
|
130
|
+
key={`${index}-${wallet.type}`}
|
|
131
|
+
onClick={onSelectWallet}
|
|
132
|
+
/>
|
|
133
|
+
))}
|
|
98
134
|
</ListContainer>
|
|
99
135
|
</>
|
|
100
136
|
</SecondaryPage>
|
package/src/store/bestRoute.ts
CHANGED
|
@@ -13,10 +13,15 @@ import { httpService } from '../services/httpService';
|
|
|
13
13
|
import { useSettingsStore } from './settings';
|
|
14
14
|
import { calcOutputUsdValue, createBestRouteRequestBody } from '../utils/swap';
|
|
15
15
|
import { useMetaStore } from './meta';
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
getDefaultToken,
|
|
18
|
+
getSortedTokens,
|
|
19
|
+
tokensAreEqual,
|
|
20
|
+
} from '../utils/wallets';
|
|
17
21
|
import { useWalletsStore } from './wallets';
|
|
18
22
|
import { TokenWithBalance } from '../pages/SelectTokenPage';
|
|
19
|
-
|
|
23
|
+
import { PendingSwap } from '@rango-dev/queue-manager-rango-preset/dist/shared';
|
|
24
|
+
import { debounce } from '../utils/common';
|
|
20
25
|
const getUsdValue = (token: Token | null, amount: string) =>
|
|
21
26
|
new BigNumber(amount || ZERO).multipliedBy(token?.usdPrice || 0);
|
|
22
27
|
|
|
@@ -43,6 +48,7 @@ export interface RouteState {
|
|
|
43
48
|
setInputAmount: (amount: string) => void;
|
|
44
49
|
bestRoute: BestRouteResponse | null;
|
|
45
50
|
setBestRoute: (bestRoute: BestRouteResponse | null) => void;
|
|
51
|
+
retry: (pendingSwap: PendingSwap) => void;
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
export const useBestRouteStore = createSelectors(
|
|
@@ -65,6 +71,7 @@ export const useBestRouteStore = createSelectors(
|
|
|
65
71
|
set((state) => {
|
|
66
72
|
let outputAmount: BigNumber | null = null;
|
|
67
73
|
let outputUsdValue: BigNumber = ZERO;
|
|
74
|
+
if (!state.inputAmount || state.inputAmount === '0') return {};
|
|
68
75
|
if (!!bestRoute) {
|
|
69
76
|
outputAmount = !!bestRoute.result?.outputAmount
|
|
70
77
|
? new BigNumber(bestRoute.result?.outputAmount)
|
|
@@ -139,6 +146,7 @@ export const useBestRouteStore = createSelectors(
|
|
|
139
146
|
toToken: token,
|
|
140
147
|
})),
|
|
141
148
|
setInputAmount: (amount) => {
|
|
149
|
+
console.log(amount, typeof amount);
|
|
142
150
|
set((state) => ({
|
|
143
151
|
inputAmount: amount,
|
|
144
152
|
...(!amount && {
|
|
@@ -151,6 +159,71 @@ export const useBestRouteStore = createSelectors(
|
|
|
151
159
|
}),
|
|
152
160
|
}));
|
|
153
161
|
},
|
|
162
|
+
retry: (pendingSwap) => {
|
|
163
|
+
const { tokens, blockchains } = useMetaStore.getState().meta;
|
|
164
|
+
const balances = useWalletsStore.getState().balances;
|
|
165
|
+
const failedIndex =
|
|
166
|
+
pendingSwap.status === 'failed'
|
|
167
|
+
? pendingSwap.steps.findIndex((s) => s.status === 'failed')
|
|
168
|
+
: null;
|
|
169
|
+
|
|
170
|
+
if (failedIndex === null || failedIndex < 0) return;
|
|
171
|
+
|
|
172
|
+
const firstStep = pendingSwap.steps[0];
|
|
173
|
+
const lastStep = pendingSwap.steps[pendingSwap.steps.length - 1];
|
|
174
|
+
const fromChain =
|
|
175
|
+
blockchains.find(
|
|
176
|
+
(blockchain) => blockchain.name === firstStep.fromBlockchain
|
|
177
|
+
) || null;
|
|
178
|
+
const toChain =
|
|
179
|
+
blockchains.find(
|
|
180
|
+
(blockchain) => blockchain.name === lastStep.toBlockchain
|
|
181
|
+
) || null;
|
|
182
|
+
|
|
183
|
+
const fromToken = tokens.find((token) =>
|
|
184
|
+
tokensAreEqual(token, {
|
|
185
|
+
blockchain: firstStep.fromBlockchain,
|
|
186
|
+
symbol: firstStep.fromSymbol,
|
|
187
|
+
address: firstStep.fromSymbolAddress,
|
|
188
|
+
})
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
const toToken = tokens.find((token) =>
|
|
192
|
+
tokensAreEqual(token, {
|
|
193
|
+
blockchain: lastStep.toBlockchain,
|
|
194
|
+
symbol: lastStep.toSymbol,
|
|
195
|
+
address: lastStep.toSymbolAddress,
|
|
196
|
+
})
|
|
197
|
+
);
|
|
198
|
+
const sortedSourceTokens = getSortedTokens(
|
|
199
|
+
fromChain,
|
|
200
|
+
tokens,
|
|
201
|
+
balances,
|
|
202
|
+
[]
|
|
203
|
+
);
|
|
204
|
+
const sortedDestinationTokens = getSortedTokens(
|
|
205
|
+
toChain,
|
|
206
|
+
tokens,
|
|
207
|
+
balances,
|
|
208
|
+
[]
|
|
209
|
+
);
|
|
210
|
+
const inputAmount = pendingSwap.inputAmount;
|
|
211
|
+
set({
|
|
212
|
+
fromChain,
|
|
213
|
+
fromToken,
|
|
214
|
+
inputAmount,
|
|
215
|
+
outputAmount: null,
|
|
216
|
+
inputUsdValue: getUsdValue(fromToken || null, inputAmount),
|
|
217
|
+
outputUsdValue: new BigNumber(0),
|
|
218
|
+
toChain,
|
|
219
|
+
toToken,
|
|
220
|
+
bestRoute: null,
|
|
221
|
+
loading: false,
|
|
222
|
+
error: '',
|
|
223
|
+
sourceTokens: sortedSourceTokens,
|
|
224
|
+
destinationTokens: sortedDestinationTokens,
|
|
225
|
+
});
|
|
226
|
+
},
|
|
154
227
|
}))
|
|
155
228
|
)
|
|
156
229
|
);
|
|
@@ -164,7 +237,7 @@ const bestRoute = (
|
|
|
164
237
|
const { fromToken, toToken, inputAmount } = bestRouteStore.getState();
|
|
165
238
|
const { slippage, customSlippage, disabledLiquiditySources } =
|
|
166
239
|
settingsStore.getState();
|
|
167
|
-
if (!fromToken || !toToken || !inputAmount) return;
|
|
240
|
+
if (!fromToken || !toToken || !inputAmount || inputAmount === '0') return;
|
|
168
241
|
abortController?.abort();
|
|
169
242
|
abortController = new AbortController();
|
|
170
243
|
const userSlippage = !!customSlippage ? customSlippage : slippage;
|
|
@@ -178,12 +251,13 @@ const bestRoute = (
|
|
|
178
251
|
userSlippage,
|
|
179
252
|
false
|
|
180
253
|
);
|
|
181
|
-
bestRouteStore.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
254
|
+
if (!bestRouteStore.getState().loading)
|
|
255
|
+
bestRouteStore.setState({
|
|
256
|
+
loading: true,
|
|
257
|
+
bestRoute: null,
|
|
258
|
+
outputAmount: null,
|
|
259
|
+
outputUsdValue: new BigNumber(0),
|
|
260
|
+
});
|
|
187
261
|
httpService
|
|
188
262
|
.getBestRoute(requestBody, {
|
|
189
263
|
signal: abortController.signal,
|
|
@@ -203,6 +277,31 @@ const bestRoute = (
|
|
|
203
277
|
});
|
|
204
278
|
};
|
|
205
279
|
|
|
280
|
+
const debouncedFetchBestRoute = debounce(fetchBestRoute, 600);
|
|
281
|
+
|
|
282
|
+
const bestRouteParamsListener = () => {
|
|
283
|
+
const { fromToken, toToken, inputAmount, inputUsdValue } =
|
|
284
|
+
useBestRouteStore.getState();
|
|
285
|
+
if (!inputAmount || inputAmount === '0') return;
|
|
286
|
+
|
|
287
|
+
if (tokensAreEqual(fromToken, toToken))
|
|
288
|
+
return bestRouteStore.setState({
|
|
289
|
+
loading: false,
|
|
290
|
+
bestRoute: null,
|
|
291
|
+
outputAmount: new BigNumber(inputAmount),
|
|
292
|
+
outputUsdValue: inputUsdValue,
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
if (!bestRouteStore.getState().loading)
|
|
296
|
+
bestRouteStore.setState({
|
|
297
|
+
loading: true,
|
|
298
|
+
bestRoute: null,
|
|
299
|
+
outputAmount: null,
|
|
300
|
+
outputUsdValue: new BigNumber(0),
|
|
301
|
+
});
|
|
302
|
+
debouncedFetchBestRoute();
|
|
303
|
+
};
|
|
304
|
+
|
|
206
305
|
useBestRouteStore.subscribe(
|
|
207
306
|
(state) => ({
|
|
208
307
|
fromChain: state.fromChain,
|
|
@@ -211,8 +310,7 @@ const bestRoute = (
|
|
|
211
310
|
toToken: state.toToken,
|
|
212
311
|
inputAmount: state.inputAmount,
|
|
213
312
|
}),
|
|
214
|
-
|
|
215
|
-
fetchBestRoute.bind(null),
|
|
313
|
+
bestRouteParamsListener,
|
|
216
314
|
{
|
|
217
315
|
equalityFn: (prevState, state) => {
|
|
218
316
|
if (isRouteParametersChanged(prevState, state)) return false;
|
|
@@ -227,7 +325,7 @@ const bestRoute = (
|
|
|
227
325
|
customSlippage: state.customSlippage,
|
|
228
326
|
disabledLiquiditySources: state.disabledLiquiditySources,
|
|
229
327
|
}),
|
|
230
|
-
|
|
328
|
+
bestRouteParamsListener,
|
|
231
329
|
{
|
|
232
330
|
equalityFn: (prevState, state) => {
|
|
233
331
|
if (isRouteParametersChanged(prevState, state)) return false;
|
package/src/store/ui.ts
CHANGED
|
@@ -4,18 +4,22 @@ import createSelectors from './selectors';
|
|
|
4
4
|
interface UiState {
|
|
5
5
|
connectWalletsButtonDisabled: boolean;
|
|
6
6
|
selectedSwapRequestId: string | null;
|
|
7
|
+
currentPage: string;
|
|
7
8
|
toggleConnectWalletsButton: () => void;
|
|
8
9
|
setSelectedSwap: (requestId: string | null) => void;
|
|
10
|
+
setCurrentPage: (path: string) => void;
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
export const useUiStore = createSelectors(
|
|
12
14
|
create<UiState>()((set) => ({
|
|
13
15
|
connectWalletsButtonDisabled: false,
|
|
14
16
|
selectedSwapRequestId: null,
|
|
17
|
+
currentPage: '',
|
|
15
18
|
toggleConnectWalletsButton: () =>
|
|
16
19
|
set((state) => ({
|
|
17
20
|
connectWalletsButtonDisabled: !state.connectWalletsButtonDisabled,
|
|
18
21
|
})),
|
|
19
22
|
setSelectedSwap: (requestId) => set({ selectedSwapRequestId: requestId }),
|
|
23
|
+
setCurrentPage: (path) => set({ currentPage: path }),
|
|
20
24
|
}))
|
|
21
25
|
);
|
package/src/store/wallets.ts
CHANGED
|
@@ -142,7 +142,7 @@ export const useWalletsStore = createSelectors(
|
|
|
142
142
|
}
|
|
143
143
|
});
|
|
144
144
|
return {
|
|
145
|
-
selectedWallets:
|
|
145
|
+
selectedWallets: selectedWallets,
|
|
146
146
|
};
|
|
147
147
|
}),
|
|
148
148
|
setSelectedWallet: (wallet) =>
|
|
@@ -188,3 +188,6 @@ useWalletsStore.subscribe(
|
|
|
188
188
|
equalityFn: shallow,
|
|
189
189
|
}
|
|
190
190
|
);
|
|
191
|
+
|
|
192
|
+
export const fetchingBalanceSelector = (state: WalletsStore) =>
|
|
193
|
+
!!state.balances.find((wallet) => wallet.loading);
|
package/src/types/routing.ts
CHANGED
package/src/types/swap.ts
CHANGED
package/src/utils/common.ts
CHANGED
|
@@ -33,3 +33,17 @@ export function shadeColor(color: string, percent: number) {
|
|
|
33
33
|
|
|
34
34
|
return '#' + RR + GG + BB;
|
|
35
35
|
}
|
|
36
|
+
|
|
37
|
+
export function debounce(fn: Function, time: number) {
|
|
38
|
+
let timeoutId: ReturnType<typeof setTimeout> | null;
|
|
39
|
+
return wrapper;
|
|
40
|
+
function wrapper(...args: any) {
|
|
41
|
+
if (timeoutId) {
|
|
42
|
+
clearTimeout(timeoutId);
|
|
43
|
+
}
|
|
44
|
+
timeoutId = setTimeout(() => {
|
|
45
|
+
timeoutId = null;
|
|
46
|
+
fn(...args);
|
|
47
|
+
}, time);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { PendingSwap } from '@rango-dev/queue-manager-rango-preset';
|
|
2
|
+
import dayjs from 'dayjs';
|
|
3
|
+
import { GroupBy } from '@rango-dev/ui';
|
|
4
|
+
|
|
5
|
+
export const groupSwapsByDate: GroupBy = swaps => {
|
|
6
|
+
const output: Map<
|
|
7
|
+
string,
|
|
8
|
+
{
|
|
9
|
+
title: string;
|
|
10
|
+
swaps: PendingSwap[];
|
|
11
|
+
}
|
|
12
|
+
> = new Map([
|
|
13
|
+
[
|
|
14
|
+
'today',
|
|
15
|
+
{
|
|
16
|
+
title: 'Today',
|
|
17
|
+
swaps: [],
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
[
|
|
21
|
+
'week',
|
|
22
|
+
{
|
|
23
|
+
title: 'This week',
|
|
24
|
+
swaps: [],
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
[
|
|
28
|
+
'month',
|
|
29
|
+
{
|
|
30
|
+
title: 'This month',
|
|
31
|
+
swaps: [],
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
[
|
|
35
|
+
'year',
|
|
36
|
+
{
|
|
37
|
+
title: 'This year',
|
|
38
|
+
swaps: [],
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
[
|
|
42
|
+
'history',
|
|
43
|
+
{
|
|
44
|
+
title: 'History',
|
|
45
|
+
swaps: [],
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
]);
|
|
49
|
+
|
|
50
|
+
const now = dayjs();
|
|
51
|
+
swaps.forEach(swap => {
|
|
52
|
+
const swapDate = dayjs(Number(swap.creationTime));
|
|
53
|
+
if (now.isSame(swapDate, 'day')) output.get('today')?.swaps.push(swap);
|
|
54
|
+
else if (now.isSame(swapDate, 'week')) output.get('week')?.swaps.push(swap);
|
|
55
|
+
else if (now.isSame(swapDate, 'month'))
|
|
56
|
+
output.get('month')?.swaps.push(swap);
|
|
57
|
+
else if (now.isSame(swapDate, 'year')) output.get('year')?.swaps.push(swap);
|
|
58
|
+
else output.get('history')?.swaps.push(swap);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
return Array.from(output.values());
|
|
62
|
+
};
|
package/src/utils/routing.ts
CHANGED
|
@@ -117,19 +117,22 @@ export function isRouteParametersChanged(
|
|
|
117
117
|
currentParams: BestRouteParams
|
|
118
118
|
) {
|
|
119
119
|
return (
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
prevParams.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
currentParams.
|
|
120
|
+
!!currentParams.fromToken &&
|
|
121
|
+
!!currentParams.toToken &&
|
|
122
|
+
(prevParams.fromChain?.name !== currentParams.fromChain?.name ||
|
|
123
|
+
prevParams.toChain?.name !== currentParams.toChain?.name ||
|
|
124
|
+
prevParams.fromToken?.symbol !== currentParams.fromToken?.symbol ||
|
|
125
|
+
prevParams.toToken?.symbol !== currentParams.toToken?.symbol ||
|
|
126
|
+
prevParams.fromToken?.blockchain !==
|
|
127
|
+
currentParams.fromToken?.blockchain ||
|
|
128
|
+
prevParams.toToken?.blockchain !== currentParams.toToken?.blockchain ||
|
|
129
|
+
prevParams.fromToken?.address !== currentParams.fromToken?.address ||
|
|
130
|
+
prevParams.toToken?.address !== currentParams.toToken?.address ||
|
|
131
|
+
prevParams.inputAmount !== currentParams.inputAmount ||
|
|
132
|
+
prevParams.slippage !== currentParams.slippage ||
|
|
133
|
+
prevParams.customSlippage !== currentParams.customSlippage ||
|
|
134
|
+
prevParams.disabledLiquiditySources?.length !==
|
|
135
|
+
currentParams.disabledLiquiditySources?.length)
|
|
133
136
|
);
|
|
134
137
|
}
|
|
135
138
|
|
|
@@ -148,3 +151,10 @@ export function getBestRouteWithCalculatedFees(
|
|
|
148
151
|
result: { ...bestRoute.result, swaps: swapsWithFee },
|
|
149
152
|
};
|
|
150
153
|
}
|
|
154
|
+
|
|
155
|
+
//todo: refactor bestRoute store and add loadingStatus
|
|
156
|
+
export const getBestRouteStatus = (loading: boolean, error: boolean) => {
|
|
157
|
+
if (loading) return 'loading';
|
|
158
|
+
if (error) return 'failed';
|
|
159
|
+
else return 'success';
|
|
160
|
+
};
|
package/src/utils/swap.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { PendingSwap } from '@rango-dev/ui/dist/containers/History/types';
|
|
2
1
|
import {
|
|
3
2
|
WalletTypeAndAddress,
|
|
4
3
|
SwapSavedSettings,
|
|
@@ -19,7 +18,12 @@ import { WalletType } from '@rango-dev/wallets-shared';
|
|
|
19
18
|
import { getRequiredBalanceOfWallet } from './routing';
|
|
20
19
|
import { getRequiredChains, SelectedWallet } from './wallets';
|
|
21
20
|
import { LoadingStatus } from '../store/meta';
|
|
22
|
-
import { SwapButtonState } from '../types';
|
|
21
|
+
import { ConvertedToken, SwapButtonState } from '../types';
|
|
22
|
+
import {
|
|
23
|
+
PendingSwapNetworkStatus,
|
|
24
|
+
PendingSwapStep,
|
|
25
|
+
} from '@rango-dev/queue-manager-rango-preset';
|
|
26
|
+
import { PendingSwap } from '@rango-dev/queue-manager-rango-preset';
|
|
23
27
|
|
|
24
28
|
export function getOutputRatio(
|
|
25
29
|
inputUsdValue: BigNumber,
|
|
@@ -187,6 +191,7 @@ export function calculatePendingSwap(
|
|
|
187
191
|
finishTime: null,
|
|
188
192
|
requestId: bestRoute.requestId || '',
|
|
189
193
|
inputAmount: inputAmount,
|
|
194
|
+
//@ts-ignore
|
|
190
195
|
wallets,
|
|
191
196
|
status: 'running',
|
|
192
197
|
isPaused: false,
|
|
@@ -201,6 +206,7 @@ export function calculatePendingSwap(
|
|
|
201
206
|
settings: settings,
|
|
202
207
|
simulationResult: simulationResult,
|
|
203
208
|
validateBalanceOrFee,
|
|
209
|
+
//@ts-ignore
|
|
204
210
|
steps:
|
|
205
211
|
bestRoute.result?.swaps?.map((swap, index) => {
|
|
206
212
|
const swapper = meta.swappers.find(
|
|
@@ -339,25 +345,24 @@ export function hasSlippageError(
|
|
|
339
345
|
|
|
340
346
|
export function getMinRequiredSlippage(
|
|
341
347
|
route: BestRouteResponse
|
|
342
|
-
):
|
|
348
|
+
): string | null {
|
|
343
349
|
const slippages = route.result?.swaps.map(
|
|
344
350
|
(slippage) => slippage.recommendedSlippage
|
|
345
351
|
);
|
|
346
352
|
return (
|
|
347
353
|
slippages
|
|
348
|
-
?.map((s) =>
|
|
349
|
-
?.filter((s) => s > 0)
|
|
350
|
-
?.sort((a, b) => b - a)
|
|
354
|
+
?.map((s) => s?.slippage || '0')
|
|
355
|
+
?.filter((s) => parseFloat(s) > 0)
|
|
356
|
+
?.sort((a, b) => parseFloat(b) - parseFloat(a))
|
|
351
357
|
?.find(() => true) || null
|
|
352
358
|
);
|
|
353
359
|
}
|
|
354
360
|
|
|
355
361
|
export function hasProperSlippage(
|
|
356
362
|
userSlippage: string,
|
|
357
|
-
minRequiredSlippage:
|
|
363
|
+
minRequiredSlippage: string | null
|
|
358
364
|
) {
|
|
359
365
|
if (!minRequiredSlippage) return true;
|
|
360
|
-
//@ts-ignore
|
|
361
366
|
return parseFloat(userSlippage) >= parseFloat(minRequiredSlippage);
|
|
362
367
|
}
|
|
363
368
|
|
|
@@ -386,7 +391,7 @@ export function hasEnoughBalanceAndProperSlippage(
|
|
|
386
391
|
route: BestRouteResponse,
|
|
387
392
|
selectedWallets: SelectedWallet[],
|
|
388
393
|
userSlippage: string,
|
|
389
|
-
minRequiredSlippage:
|
|
394
|
+
minRequiredSlippage: string | null
|
|
390
395
|
): boolean {
|
|
391
396
|
return (
|
|
392
397
|
hasEnoughBalance(route, selectedWallets) &&
|
|
@@ -429,6 +434,8 @@ export function createBestRouteRequestBody(
|
|
|
429
434
|
});
|
|
430
435
|
});
|
|
431
436
|
|
|
437
|
+
const filteredBlockchains = selectedWallets.map((wallet) => wallet.chain);
|
|
438
|
+
|
|
432
439
|
const requestBody: BestRouteRequest = {
|
|
433
440
|
amount: inputAmount.toString(),
|
|
434
441
|
checkPrerequisites,
|
|
@@ -446,8 +453,8 @@ export function createBestRouteRequestBody(
|
|
|
446
453
|
selectedWallets: selectedWalletsMap,
|
|
447
454
|
swapperGroups: disabledLiquiditySources,
|
|
448
455
|
swappersGroupsExclude: true,
|
|
449
|
-
//@ts-ignore
|
|
450
456
|
slippage: slippage.toString(),
|
|
457
|
+
...(checkPrerequisites && { blockchains: filteredBlockchains }),
|
|
451
458
|
};
|
|
452
459
|
|
|
453
460
|
return requestBody;
|
|
@@ -550,3 +557,87 @@ export function calcOutputUsdValue(
|
|
|
550
557
|
|
|
551
558
|
return amount.multipliedBy(tokenPrice || 0);
|
|
552
559
|
}
|
|
560
|
+
|
|
561
|
+
export function isNetworkStatusInWarningState(
|
|
562
|
+
pendingSwapStep: PendingSwapStep | null
|
|
563
|
+
): boolean {
|
|
564
|
+
return (
|
|
565
|
+
!!pendingSwapStep &&
|
|
566
|
+
pendingSwapStep.networkStatus !== null &&
|
|
567
|
+
pendingSwapStep.networkStatus !== PendingSwapNetworkStatus.NetworkChanged
|
|
568
|
+
);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
export function getSwapMessages(
|
|
572
|
+
pendingSwap: PendingSwap,
|
|
573
|
+
currentStep: PendingSwapStep | null
|
|
574
|
+
): {
|
|
575
|
+
shortMessage: string;
|
|
576
|
+
detailedMessage: { content: string; long: boolean };
|
|
577
|
+
} {
|
|
578
|
+
const textForRemove = 'bellow button or';
|
|
579
|
+
let message = pendingSwap.extraMessage;
|
|
580
|
+
let detailedMessage = pendingSwap.extraMessageDetail;
|
|
581
|
+
|
|
582
|
+
if (pendingSwap.networkStatusExtraMessageDetail?.includes(textForRemove)) {
|
|
583
|
+
pendingSwap.networkStatusExtraMessageDetail =
|
|
584
|
+
pendingSwap.networkStatusExtraMessageDetail.replace(textForRemove, '');
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
const networkWarningState = isNetworkStatusInWarningState(currentStep);
|
|
588
|
+
|
|
589
|
+
if (networkWarningState) {
|
|
590
|
+
message = pendingSwap.networkStatusExtraMessage || '';
|
|
591
|
+
detailedMessage = pendingSwap.networkStatusExtraMessageDetail || '';
|
|
592
|
+
switch (currentStep?.networkStatus) {
|
|
593
|
+
case PendingSwapNetworkStatus.WaitingForConnectingWallet:
|
|
594
|
+
message = message || 'Waiting for connecting wallet';
|
|
595
|
+
break;
|
|
596
|
+
case PendingSwapNetworkStatus.WaitingForQueue:
|
|
597
|
+
message = message || 'Waiting for other running tasks to be finished';
|
|
598
|
+
break;
|
|
599
|
+
case PendingSwapNetworkStatus.WaitingForNetworkChange:
|
|
600
|
+
message = message || 'Waiting for changing wallet network';
|
|
601
|
+
break;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
detailedMessage = detailedMessage || '';
|
|
605
|
+
message = message || '';
|
|
606
|
+
const isRpc =
|
|
607
|
+
message?.indexOf('code') !== -1 && message?.indexOf('reason') !== -1;
|
|
608
|
+
|
|
609
|
+
return {
|
|
610
|
+
shortMessage: message,
|
|
611
|
+
detailedMessage: { content: detailedMessage, long: isRpc },
|
|
612
|
+
};
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
export function getLastConvertedTokenInFailedSwap(
|
|
616
|
+
pendingSwap: PendingSwap
|
|
617
|
+
): ConvertedToken {
|
|
618
|
+
let resultToken: ConvertedToken = null;
|
|
619
|
+
if (pendingSwap.status === 'failed') {
|
|
620
|
+
const lastSuccessStep = pendingSwap.steps
|
|
621
|
+
.slice()
|
|
622
|
+
.reverse()
|
|
623
|
+
.filter((step) => step.status === 'success')[0];
|
|
624
|
+
|
|
625
|
+
if (lastSuccessStep) {
|
|
626
|
+
resultToken = {
|
|
627
|
+
blockchain: lastSuccessStep.toBlockchain,
|
|
628
|
+
symbol: lastSuccessStep.toSymbol,
|
|
629
|
+
outputAmount: lastSuccessStep.outputAmount,
|
|
630
|
+
address: lastSuccessStep.toSymbolAddress,
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
return resultToken;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
export function shouldRetrySwap(pendingSwap: PendingSwap) {
|
|
638
|
+
return (
|
|
639
|
+
pendingSwap.status === 'failed' &&
|
|
640
|
+
!!pendingSwap.finishTime &&
|
|
641
|
+
new Date().getTime() - parseInt(pendingSwap.finishTime) < 4 * 3600 * 1000
|
|
642
|
+
);
|
|
643
|
+
}
|