@rango-dev/widget-embedded 0.1.10-next.77 → 0.1.10-next.81
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/components/AppRouter.d.ts.map +1 -1
- package/dist/components/AppRoutes.d.ts.map +1 -1
- package/dist/components/ChangeSlippageButton.d.ts +2 -0
- package/dist/components/ChangeSlippageButton.d.ts.map +1 -0
- package/dist/components/ConfirmSwapErrors.d.ts +3 -0
- package/dist/components/ConfirmSwapErrors.d.ts.map +1 -0
- package/dist/components/ConfirmSwapWarnings.d.ts +3 -0
- package/dist/components/ConfirmSwapWarnings.d.ts.map +1 -0
- package/dist/components/Layout.d.ts.map +1 -1
- package/dist/components/UpdateUrl.d.ts.map +1 -1
- package/dist/components/warnings/BalanceWarnings.d.ts +6 -0
- package/dist/components/warnings/BalanceWarnings.d.ts.map +1 -0
- package/dist/components/warnings/ConfirmSwapExtraMessages.d.ts +6 -0
- package/dist/components/warnings/ConfirmSwapExtraMessages.d.ts.map +1 -0
- package/dist/components/warnings/HighSlippageWarning.d.ts +6 -0
- package/dist/components/warnings/HighSlippageWarning.d.ts.map +1 -0
- package/dist/components/warnings/MinRequiredSlippage.d.ts +6 -0
- package/dist/components/warnings/MinRequiredSlippage.d.ts.map +1 -0
- package/dist/constants/swapSettings.d.ts +6 -0
- package/dist/constants/swapSettings.d.ts.map +1 -0
- package/dist/hooks/useNavigateBack.d.ts +4 -0
- package/dist/hooks/useNavigateBack.d.ts.map +1 -0
- package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
- package/dist/pages/ConfirmWalletsPage.d.ts +0 -5
- package/dist/pages/ConfirmWalletsPage.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/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/SwapDetailsPage.d.ts.map +1 -1
- package/dist/pages/WalletsPage.d.ts.map +1 -1
- package/dist/store/bestRoute.d.ts +1 -0
- package/dist/store/bestRoute.d.ts.map +1 -1
- package/dist/store/confirmSwap.d.ts +35 -0
- package/dist/store/confirmSwap.d.ts.map +1 -0
- package/dist/store/settings.d.ts.map +1 -1
- package/dist/store/ui.d.ts +2 -0
- package/dist/store/ui.d.ts.map +1 -0
- package/dist/store/wallets.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/swap.d.ts +11 -0
- package/dist/types/swap.d.ts.map +1 -0
- package/dist/utils/common.d.ts +1 -0
- package/dist/utils/common.d.ts.map +1 -1
- package/dist/utils/numbers.d.ts +5 -0
- package/dist/utils/numbers.d.ts.map +1 -1
- package/dist/utils/routing.d.ts +5 -7
- package/dist/utils/routing.d.ts.map +1 -1
- package/dist/utils/swap.d.ts +31 -3
- package/dist/utils/swap.d.ts.map +1 -1
- package/dist/utils/wallets.d.ts +2 -3
- package/dist/utils/wallets.d.ts.map +1 -1
- package/dist/widget-embedded.cjs.development.js +1790 -1357
- package/dist/widget-embedded.cjs.development.js.map +1 -1
- package/dist/widget-embedded.cjs.production.min.js +1790 -1357
- package/dist/widget-embedded.cjs.production.min.js.map +1 -1
- package/dist/widget-embedded.esm.js +1794 -1361
- package/dist/widget-embedded.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/AppRouter.tsx +38 -3
- package/src/components/AppRoutes.tsx +8 -2
- package/src/components/ChangeSlippageButton.tsx +23 -0
- package/src/components/ConfirmSwapErrors.tsx +38 -0
- package/src/components/ConfirmSwapWarnings.tsx +38 -0
- package/src/components/Layout.tsx +22 -6
- package/src/components/UpdateUrl.tsx +100 -18
- package/src/components/warnings/BalanceWarnings.tsx +16 -0
- package/src/components/warnings/ConfirmSwapExtraMessages.tsx +14 -0
- package/src/components/warnings/HighSlippageWarning.tsx +21 -0
- package/src/components/warnings/MinRequiredSlippage.tsx +18 -0
- package/src/constants/navigationRoutes.ts +2 -2
- package/src/constants/swapSettings.ts +9 -0
- package/src/hooks/useNavigateBack.ts +37 -0
- package/src/pages/ConfirmSwapPage.tsx +30 -8
- package/src/pages/ConfirmWalletsPage.tsx +30 -17
- package/src/pages/HistoryPage.tsx +4 -4
- package/src/pages/Home.tsx +79 -36
- package/src/pages/LiquiditySourcesPage.tsx +11 -8
- package/src/pages/SelectChainPage.tsx +9 -28
- package/src/pages/SelectTokenPage.tsx +38 -27
- package/src/pages/SettingsPage.tsx +17 -6
- package/src/pages/SwapDetailsPage.tsx +9 -3
- package/src/pages/WalletsPage.tsx +43 -23
- package/src/store/bestRoute.ts +147 -28
- package/src/store/confirmSwap.ts +327 -0
- package/src/store/settings.ts +40 -28
- package/src/store/ui.ts +15 -0
- package/src/store/wallets.ts +93 -80
- package/src/swapBox.tsx +5 -5
- package/src/types/index.ts +1 -0
- package/src/types/swap.ts +13 -0
- package/src/utils/common.ts +4 -0
- package/src/utils/numbers.ts +17 -0
- package/src/utils/routing.ts +28 -77
- package/src/utils/swap.ts +445 -67
- package/src/utils/wallets.ts +4 -19
- package/dist/hooks/useBestRoute.d.ts +0 -8
- package/dist/hooks/useBestRoute.d.ts.map +0 -1
- package/dist/hooks/useConfirmSwap.d.ts +0 -12
- package/dist/hooks/useConfirmSwap.d.ts.map +0 -1
- package/src/hooks/useBestRoute.ts +0 -70
- package/src/hooks/useConfirmSwap.ts +0 -234
|
@@ -10,95 +10,62 @@ var React__default = _interopDefault(React);
|
|
|
10
10
|
var reactRouter = require('react-router');
|
|
11
11
|
var reactRouterDom = require('react-router-dom');
|
|
12
12
|
var zustand = require('zustand');
|
|
13
|
-
var immer = require('zustand/middleware/immer');
|
|
14
13
|
var BigNumber = require('bignumber.js');
|
|
15
14
|
var BigNumber__default = _interopDefault(BigNumber);
|
|
15
|
+
var middleware = require('zustand/middleware');
|
|
16
16
|
var rangoSdk = require('rango-sdk');
|
|
17
|
-
var walletsCore = require('@rango-dev/wallets-core');
|
|
18
|
-
var providerAll = require('@rango-dev/provider-all');
|
|
19
17
|
var walletsShared = require('@rango-dev/wallets-shared');
|
|
20
|
-
var
|
|
18
|
+
var walletsCore = require('@rango-dev/wallets-core');
|
|
21
19
|
var theme = require('@rango-dev/ui/src/theme');
|
|
20
|
+
var providerAll = require('@rango-dev/provider-all');
|
|
21
|
+
var shallow = require('zustand/shallow');
|
|
22
|
+
|
|
23
|
+
const navigationRoutes = {
|
|
24
|
+
home: '/',
|
|
25
|
+
fromChain: '/from-chain',
|
|
26
|
+
fromToken: '/from-token',
|
|
27
|
+
toChain: '/to-chain',
|
|
28
|
+
toToken: '/to-token',
|
|
29
|
+
settings: '/settings',
|
|
30
|
+
liquiditySources: '/settings/liquidity-sources',
|
|
31
|
+
history: '/history',
|
|
32
|
+
wallets: '/wallets',
|
|
33
|
+
confirmSwap: '/confirm-swap',
|
|
34
|
+
confirmWallets: '/confirm-wallets',
|
|
35
|
+
swapDetails: '/history/swap-details'
|
|
36
|
+
};
|
|
22
37
|
|
|
23
38
|
const ZERO = /*#__PURE__*/new BigNumber__default(0);
|
|
24
39
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
if (number === null) return '';
|
|
33
|
-
if (number === '') return '';
|
|
34
|
-
const n = new BigNumber.BigNumber(number);
|
|
35
|
-
const roundingMode = 1;
|
|
36
|
-
let maxI = 1000;
|
|
37
|
-
for (let i = 0; i < 60; i++) {
|
|
38
|
-
if (new BigNumber.BigNumber(n.toFixed(i, roundingMode)).eq(n)) {
|
|
39
|
-
maxI = i;
|
|
40
|
-
break;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
if (n.gte(10000)) return n.toFormat(0, roundingMode);
|
|
44
|
-
if (n.gte(1000)) return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 1))), roundingMode);
|
|
45
|
-
if (n.gte(100)) return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 1))), roundingMode);
|
|
46
|
-
if (n.gte(1)) return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 2))), roundingMode);
|
|
47
|
-
if (n.gte(0.01)) return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 4))), roundingMode);
|
|
48
|
-
for (let i = minDecimals || 4; i < 17; i++) if (n.gte(Math.pow(10, -i))) return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, i))), roundingMode);
|
|
49
|
-
if (n.isEqualTo(0)) return '0';
|
|
50
|
-
return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 8))), roundingMode);
|
|
51
|
-
};
|
|
40
|
+
function removeDuplicateFrom(array) {
|
|
41
|
+
return Array.from(new Set(array));
|
|
42
|
+
}
|
|
43
|
+
function areEqual(array1, array2) {
|
|
44
|
+
return array1.length === array2.length && array1.every((v, i) => v === array2[i]);
|
|
45
|
+
}
|
|
52
46
|
|
|
53
47
|
const getBestRouteToTokenUsdPrice = bestRoute => bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1].to.usdPrice;
|
|
54
|
-
|
|
55
|
-
let outUsdValue = (new BigNumber__default(route2.result?.outputAmount || '0') || ZERO).multipliedBy(toTokenUsdPrice || 0);
|
|
56
|
-
if (outUsdValue.isNaN()) outUsdValue = ZERO;
|
|
57
|
-
let inUsdValue = new BigNumber__default(inputAmount || '0').multipliedBy(fromTokenUsdPrice || 0);
|
|
58
|
-
if (inUsdValue.isNaN()) inUsdValue = ZERO;
|
|
59
|
-
const outToInRatio = inUsdValue === null || inUsdValue.lte(ZERO) ? 0 : outUsdValue === null || outUsdValue.lte(ZERO) ? 0 : outUsdValue.div(inUsdValue).minus(1).multipliedBy(100);
|
|
60
|
-
const disableSwapButton = parseInt(outToInRatio?.toFixed(2) || '0') <= -10 && (inUsdValue === null || inUsdValue.gte(new BigNumber__default(400))) || parseInt(outToInRatio?.toFixed(2) || '0') <= -5 && (inUsdValue === null || inUsdValue.gte(new BigNumber__default(1000)));
|
|
61
|
-
if (disableSwapButton) {
|
|
62
|
-
return {
|
|
63
|
-
isChanged: true,
|
|
64
|
-
warningMessage: 'Route updated and price impact is too high, try again later!'
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
const out1 = route1.result?.outputAmount || null;
|
|
68
|
-
const out2 = route2.result?.outputAmount || null;
|
|
69
|
-
if (!!out1 && !!out2) {
|
|
70
|
-
const changePercent = new BigNumber__default(out2).div(new BigNumber__default(out1)).minus(1).multipliedBy(100);
|
|
71
|
-
if (changePercent.toNumber() <= -1) {
|
|
72
|
-
return {
|
|
73
|
-
isChanged: true,
|
|
74
|
-
warningMessage: `Output amount changed to ${numberToString(out2)}
|
|
75
|
-
(${numberToString(changePercent, null, 2)}% change).`
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
}
|
|
48
|
+
function isNumberOfSwapsChanged(route1, route2) {
|
|
79
49
|
const route1Swaps = route1.result?.swaps || [];
|
|
80
50
|
const route2Swaps = route2.result?.swaps || [];
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
isChanged: false
|
|
97
|
-
};
|
|
51
|
+
return route1Swaps.length !== route2Swaps.length;
|
|
52
|
+
}
|
|
53
|
+
function isRouteSwappersUpdated(route1, route2) {
|
|
54
|
+
const route1Swappers = route1.result?.swaps.map(swap => swap.swapperId) || [];
|
|
55
|
+
const route2Swappers = route2.result?.swaps.map(swap => swap.swapperId) || [];
|
|
56
|
+
return !areEqual(route1Swappers, route2Swappers);
|
|
57
|
+
}
|
|
58
|
+
function isRouteInternalCoinsUpdated(route1, route2) {
|
|
59
|
+
const route1InternalCoins = route1.result?.swaps.map(swap => swap.to.symbol) || [];
|
|
60
|
+
const route2InternalCoins = route2.result?.swaps.map(swap => swap.to.symbol) || [];
|
|
61
|
+
return !areEqual(route1InternalCoins, route2InternalCoins);
|
|
62
|
+
}
|
|
63
|
+
const isRouteChanged = (route1, route2) => {
|
|
64
|
+
return isNumberOfSwapsChanged(route1, route2) || isRouteSwappersUpdated(route1, route2) || isRouteInternalCoinsUpdated(route1, route2);
|
|
98
65
|
};
|
|
99
|
-
const getRequiredBalanceOfWallet = (
|
|
66
|
+
const getRequiredBalanceOfWallet = (selectedWallet, fee) => {
|
|
100
67
|
if (fee === null) return null;
|
|
101
|
-
const relatedFeeStatus = fee?.find(item => item.blockchain ===
|
|
68
|
+
const relatedFeeStatus = fee?.find(item => item.blockchain === selectedWallet.chain)?.wallets.find(wallet => wallet.address?.toLowerCase() === selectedWallet.address.toLowerCase());
|
|
102
69
|
if (!relatedFeeStatus) return null;
|
|
103
70
|
return relatedFeeStatus.requiredAssets;
|
|
104
71
|
};
|
|
@@ -112,49 +79,13 @@ const createSelectors = _store => {
|
|
|
112
79
|
return store;
|
|
113
80
|
};
|
|
114
81
|
|
|
115
|
-
const getUsdValue = (token, amount) => new BigNumber__default(amount || ZERO).multipliedBy(token?.usdPrice || 0);
|
|
116
|
-
const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/immer.immer(set => ({
|
|
117
|
-
fromChain: null,
|
|
118
|
-
fromToken: null,
|
|
119
|
-
inputAmount: '',
|
|
120
|
-
outputAmount: null,
|
|
121
|
-
inputUsdValue: new BigNumber__default(0),
|
|
122
|
-
outputUsdValue: new BigNumber__default(0),
|
|
123
|
-
toChain: null,
|
|
124
|
-
toToken: null,
|
|
125
|
-
bestRoute: null,
|
|
126
|
-
setBestRoute: bestRoute => set(state => {
|
|
127
|
-
state.bestRoute = bestRoute;
|
|
128
|
-
if (!!bestRoute) {
|
|
129
|
-
const outputAmount = !!bestRoute.result?.outputAmount ? new BigNumber__default(bestRoute.result?.outputAmount) : null;
|
|
130
|
-
state.outputAmount = outputAmount;
|
|
131
|
-
state.outputUsdValue = new BigNumber__default(outputAmount || ZERO).multipliedBy(getBestRouteToTokenUsdPrice(bestRoute) || state.toToken?.usdPrice || 0);
|
|
132
|
-
}
|
|
133
|
-
}),
|
|
134
|
-
setFromChain: chain => set(state => {
|
|
135
|
-
state.fromChain = chain;
|
|
136
|
-
}),
|
|
137
|
-
setFromToken: token => set(state => {
|
|
138
|
-
state.fromToken = token;
|
|
139
|
-
if (!!state.inputAmount) state.inputUsdValue = getUsdValue(state.fromToken, state.inputAmount);
|
|
140
|
-
}),
|
|
141
|
-
setToChain: chain => set(state => {
|
|
142
|
-
state.toChain = chain;
|
|
143
|
-
}),
|
|
144
|
-
setToToken: token => set(state => {
|
|
145
|
-
state.toToken = token;
|
|
146
|
-
}),
|
|
147
|
-
setInputAmount: amount => set(state => {
|
|
148
|
-
state.inputAmount = amount;
|
|
149
|
-
if (!!state.fromToken) state.inputUsdValue = getUsdValue(state.fromToken, state.inputAmount);
|
|
150
|
-
})
|
|
151
|
-
}))));
|
|
152
|
-
|
|
153
82
|
const httpService = /*#__PURE__*/new rangoSdk.RangoClient(process.env.REACT_API_KEY);
|
|
154
83
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
84
|
+
const SLIPPAGES = [0.5, 1, 3, 5, 8, 13, 20];
|
|
85
|
+
const DEFAULT_SLIPPAGE = 1;
|
|
86
|
+
const HIGH_SLIPPAGE = 5;
|
|
87
|
+
const MAX_SLIPPAGE = 100;
|
|
88
|
+
const MIN_SLIPPGAE = 0;
|
|
158
89
|
|
|
159
90
|
const useMetaStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()(set => ({
|
|
160
91
|
meta: {
|
|
@@ -182,103 +113,87 @@ const useMetaStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()
|
|
|
182
113
|
}
|
|
183
114
|
})));
|
|
184
115
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
const toToken = useBestRouteStore.use.toToken();
|
|
209
|
-
const setFromChain = useBestRouteStore.use.setFromChain();
|
|
210
|
-
const setFromToken = useBestRouteStore.use.setFromToken();
|
|
211
|
-
const setToChain = useBestRouteStore.use.setToChain();
|
|
212
|
-
const setToToken = useBestRouteStore.use.setToToken();
|
|
213
|
-
const inputAmount = useBestRouteStore.use.inputAmount();
|
|
214
|
-
const setInputAmount = useBestRouteStore.use.setInputAmount();
|
|
215
|
-
const loadingStatus = useMetaStore.use.loadingStatus();
|
|
216
|
-
const {
|
|
217
|
-
blockchains,
|
|
218
|
-
tokens
|
|
219
|
-
} = useMetaStore.use.meta();
|
|
220
|
-
React.useEffect(() => {
|
|
221
|
-
if (!firstRender.current) {
|
|
222
|
-
const fromChainString = fromChain?.name || '';
|
|
223
|
-
const fromTokenString = (fromToken?.symbol || '') + (fromToken?.address ? `--${fromToken?.address}` : '');
|
|
224
|
-
const toChainString = toChain?.name || '';
|
|
225
|
-
const toTokenString = (toToken?.symbol || '') + (toToken?.address ? `--${toToken?.address}` : '');
|
|
226
|
-
const fromAmount = inputAmount;
|
|
227
|
-
setSearchParams({
|
|
228
|
-
...(fromChainString && {
|
|
229
|
-
[SearchParams.FROM_CHAIN]: fromChainString
|
|
230
|
-
}),
|
|
231
|
-
...(fromTokenString && {
|
|
232
|
-
[SearchParams.FROM_TOKEN]: fromTokenString
|
|
233
|
-
}),
|
|
234
|
-
...(toChainString && {
|
|
235
|
-
[SearchParams.TO_CHAIN]: toChainString
|
|
236
|
-
}),
|
|
237
|
-
...(toTokenString && {
|
|
238
|
-
[SearchParams.TO_TOKEN]: toTokenString
|
|
239
|
-
}),
|
|
240
|
-
...(fromAmount && {
|
|
241
|
-
[SearchParams.FROM_AMOUNT]: fromAmount.toString()
|
|
242
|
-
})
|
|
243
|
-
}, {
|
|
244
|
-
replace: true
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
firstRender.current = false;
|
|
248
|
-
}, [location.pathname, inputAmount]);
|
|
249
|
-
React.useEffect(() => {
|
|
250
|
-
if (loadingStatus === 'success') {
|
|
251
|
-
const fronChainString = searchParams.get(SearchParams.FROM_CHAIN);
|
|
252
|
-
const fromTokenString = searchParams.get(SearchParams.FROM_TOKEN);
|
|
253
|
-
const toChainString = searchParams.get(SearchParams.TO_CHAIN);
|
|
254
|
-
const toTokenString = searchParams.get(SearchParams.TO_TOKEN);
|
|
255
|
-
const fromAmount = searchParams.get(SearchParams.FROM_AMOUNT);
|
|
256
|
-
const fromChain = blockchains.find(blockchain => blockchain.name === fronChainString);
|
|
257
|
-
const fromToken = searchParamsToToken(tokens, fromTokenString);
|
|
258
|
-
const toChain = blockchains.find(blockchain => blockchain.name === toChainString);
|
|
259
|
-
const toToken = searchParamsToToken(tokens, toTokenString);
|
|
260
|
-
if (!!fromChain) {
|
|
261
|
-
setFromChain(fromChain);
|
|
262
|
-
if (!!fromToken) setFromToken(fromToken);
|
|
263
|
-
}
|
|
264
|
-
if (!!toChain) {
|
|
265
|
-
setToChain(toChain);
|
|
266
|
-
if (!!toToken) setToToken(toToken);
|
|
267
|
-
}
|
|
268
|
-
if (fromAmount) setInputAmount(fromAmount);
|
|
116
|
+
const useSettingsStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/middleware.persist( /*#__PURE__*/middleware.subscribeWithSelector(set => ({
|
|
117
|
+
slippage: DEFAULT_SLIPPAGE,
|
|
118
|
+
customSlippage: null,
|
|
119
|
+
infinitApprove: false,
|
|
120
|
+
disabledLiquiditySources: [],
|
|
121
|
+
theme: 'auto',
|
|
122
|
+
setSlippage: slippage => set(() => ({
|
|
123
|
+
slippage: slippage
|
|
124
|
+
})),
|
|
125
|
+
setCustomSlippage: customSlippage => set(() => ({
|
|
126
|
+
customSlippage: customSlippage
|
|
127
|
+
})),
|
|
128
|
+
toggleAllLiquiditySources: () => set(state => {
|
|
129
|
+
const {
|
|
130
|
+
swappers
|
|
131
|
+
} = useMetaStore.getState().meta;
|
|
132
|
+
const swappersGroup = removeDuplicateFrom(swappers.map(swapper => swapper.swapperGroup));
|
|
133
|
+
if (swappersGroup.length === state.disabledLiquiditySources.length) return {
|
|
134
|
+
disabledLiquiditySources: []
|
|
135
|
+
};else {
|
|
136
|
+
return {
|
|
137
|
+
disabledLiquiditySources: swappersGroup
|
|
138
|
+
};
|
|
269
139
|
}
|
|
270
|
-
},
|
|
271
|
-
|
|
272
|
-
|
|
140
|
+
}),
|
|
141
|
+
toggleInfinitApprove: () => set(state => ({
|
|
142
|
+
infinitApprove: !state.infinitApprove
|
|
143
|
+
})),
|
|
144
|
+
toggleLiquiditySource: name => set(state => {
|
|
145
|
+
if (state.disabledLiquiditySources.includes(name)) return {
|
|
146
|
+
disabledLiquiditySources: state.disabledLiquiditySources.filter(liquiditySource => liquiditySource != name)
|
|
147
|
+
};else return {
|
|
148
|
+
disabledLiquiditySources: state.disabledLiquiditySources.concat(name)
|
|
149
|
+
};
|
|
150
|
+
}),
|
|
151
|
+
setTheme: theme => set(() => ({
|
|
152
|
+
theme
|
|
153
|
+
}))
|
|
154
|
+
})), {
|
|
155
|
+
name: 'user-settings'
|
|
156
|
+
})));
|
|
273
157
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
158
|
+
const secondsToString = s => {
|
|
159
|
+
const seconds = (s % 60).toString().padStart(2, '0');
|
|
160
|
+
const minutes = parseInt((s / 60).toString()).toString().padStart(2, '0');
|
|
161
|
+
return `${minutes}:${seconds}`;
|
|
162
|
+
};
|
|
163
|
+
const numberToString = function (number, minDecimals, maxDecimals) {
|
|
164
|
+
if (minDecimals === void 0) {
|
|
165
|
+
minDecimals = null;
|
|
166
|
+
}
|
|
167
|
+
if (maxDecimals === void 0) {
|
|
168
|
+
maxDecimals = null;
|
|
169
|
+
}
|
|
170
|
+
if (number === null) return '';
|
|
171
|
+
if (number === '') return '';
|
|
172
|
+
const n = new BigNumber.BigNumber(number);
|
|
173
|
+
const roundingMode = 1;
|
|
174
|
+
let maxI = 1000;
|
|
175
|
+
for (let i = 0; i < 60; i++) {
|
|
176
|
+
if (new BigNumber.BigNumber(n.toFixed(i, roundingMode)).eq(n)) {
|
|
177
|
+
maxI = i;
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (n.gte(10000)) return n.toFormat(0, roundingMode);
|
|
182
|
+
if (n.gte(1000)) return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 1))), roundingMode);
|
|
183
|
+
if (n.gte(100)) return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 1))), roundingMode);
|
|
184
|
+
if (n.gte(1)) return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 2))), roundingMode);
|
|
185
|
+
if (n.gte(0.01)) return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 4))), roundingMode);
|
|
186
|
+
for (let i = minDecimals || 4; i < 17; i++) if (n.gte(Math.pow(10, -i))) return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, i))), roundingMode);
|
|
187
|
+
if (n.isEqualTo(0)) return '0';
|
|
188
|
+
return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 8))), roundingMode);
|
|
189
|
+
};
|
|
190
|
+
const totalArrivalTime = data => data?.result?.swaps?.reduce((a, b) => a + b.estimatedTimeInSeconds, 0) || 0;
|
|
191
|
+
const decimalNumber = function (number, toFixed) {
|
|
192
|
+
if (number === void 0) {
|
|
193
|
+
number = '0';
|
|
194
|
+
}
|
|
195
|
+
return parseFloat(number).toFixed(toFixed);
|
|
196
|
+
};
|
|
282
197
|
|
|
283
198
|
function getStateWallet(state) {
|
|
284
199
|
switch (true) {
|
|
@@ -374,7 +289,7 @@ function getRequiredChains(route) {
|
|
|
374
289
|
});
|
|
375
290
|
return wallets;
|
|
376
291
|
}
|
|
377
|
-
function getSelectableWallets(accounts, selectedWallets, getWalletInfo
|
|
292
|
+
function getSelectableWallets(accounts, selectedWallets, getWalletInfo) {
|
|
378
293
|
const connectedWallets = accounts.map(account => ({
|
|
379
294
|
address: account.address,
|
|
380
295
|
walletType: account.walletType,
|
|
@@ -383,12 +298,8 @@ function getSelectableWallets(accounts, selectedWallets, getWalletInfo, required
|
|
|
383
298
|
name: getWalletInfo(account.walletType).name,
|
|
384
299
|
selected: !!selectedWallets.find(wallet => wallet.chain === account.chain && wallet.walletType === account.walletType)
|
|
385
300
|
}));
|
|
386
|
-
return
|
|
301
|
+
return connectedWallets;
|
|
387
302
|
}
|
|
388
|
-
const removeDuplicateWallets = (arr, key) => {
|
|
389
|
-
const map = new Map(arr.map(item => [item[key], item]));
|
|
390
|
-
return Array.from(map.values());
|
|
391
|
-
};
|
|
392
303
|
function getBalanceFromWallet(balances, chain, symbol, address) {
|
|
393
304
|
if (balances.length === 0) return null;
|
|
394
305
|
const selectedChainBalances = balances.filter(balance => balance.chain === chain);
|
|
@@ -487,133 +398,6 @@ const getKeplrCompatibleConnectedWallets = selectableWallets => {
|
|
|
487
398
|
return walletsShared.KEPLR_COMPATIBLE_WALLETS.filter(compatibleWallet => connectedWalletTypes.has(compatibleWallet));
|
|
488
399
|
};
|
|
489
400
|
|
|
490
|
-
const useWalletsStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()(set => ({
|
|
491
|
-
accounts: [],
|
|
492
|
-
balances: [],
|
|
493
|
-
selectedWallets: [],
|
|
494
|
-
connectWallet: accounts => {
|
|
495
|
-
const tokens = useMetaStore.getState().meta.tokens;
|
|
496
|
-
set(state => ({
|
|
497
|
-
accounts: state.accounts.concat(accounts),
|
|
498
|
-
balances: state.balances.concat(accounts.map(account => ({
|
|
499
|
-
balances: [],
|
|
500
|
-
address: account.address,
|
|
501
|
-
chain: account.chain,
|
|
502
|
-
loading: true,
|
|
503
|
-
walletType: account.walletType,
|
|
504
|
-
error: false,
|
|
505
|
-
explorerUrl: null
|
|
506
|
-
})))
|
|
507
|
-
}));
|
|
508
|
-
accounts.forEach(async account => {
|
|
509
|
-
try {
|
|
510
|
-
const response = await httpService.getWalletsDetails([{
|
|
511
|
-
address: account.address,
|
|
512
|
-
blockchain: account.chain
|
|
513
|
-
}]);
|
|
514
|
-
const retrivedBalance = response.wallets[0];
|
|
515
|
-
if (retrivedBalance) {
|
|
516
|
-
set(state => ({
|
|
517
|
-
balances: state.balances.map(balance => {
|
|
518
|
-
return isAccountAndBalanceMatched(account, balance) ? makeBalanceFor(account, retrivedBalance, tokens) : balance;
|
|
519
|
-
})
|
|
520
|
-
}));
|
|
521
|
-
} else throw new Error('Wallet not found');
|
|
522
|
-
} catch (error) {
|
|
523
|
-
set(state => ({
|
|
524
|
-
balances: state.balances.map(balance => {
|
|
525
|
-
return isAccountAndBalanceMatched(account, balance) ? resetBalanceState(balance) : balance;
|
|
526
|
-
})
|
|
527
|
-
}));
|
|
528
|
-
}
|
|
529
|
-
});
|
|
530
|
-
},
|
|
531
|
-
disconnectWallet: walletType => {
|
|
532
|
-
set(state => ({
|
|
533
|
-
accounts: state.accounts.filter(account => account.walletType !== walletType),
|
|
534
|
-
balances: state.balances.filter(balance => balance.walletType !== walletType),
|
|
535
|
-
selectedWallets: state.selectedWallets.filter(wallet => wallet.walletType != walletType)
|
|
536
|
-
}));
|
|
537
|
-
},
|
|
538
|
-
initSelectedWallets: () => set(state => {
|
|
539
|
-
const requiredChains = getRequiredChains(useBestRouteStore.getState().bestRoute);
|
|
540
|
-
const connectedWallets = state.accounts;
|
|
541
|
-
const selectedWallets = [];
|
|
542
|
-
requiredChains.forEach(chain => {
|
|
543
|
-
const anyWalletSelected = !!state.selectedWallets.find(wallet => wallet.chain === chain);
|
|
544
|
-
if (!anyWalletSelected) {
|
|
545
|
-
const firstWalletWithMatchedChain = connectedWallets.find(wallet => wallet.chain === chain);
|
|
546
|
-
if (!!firstWalletWithMatchedChain) selectedWallets.push({
|
|
547
|
-
address: firstWalletWithMatchedChain.address,
|
|
548
|
-
chain: firstWalletWithMatchedChain.chain,
|
|
549
|
-
walletType: firstWalletWithMatchedChain.walletType
|
|
550
|
-
});
|
|
551
|
-
}
|
|
552
|
-
});
|
|
553
|
-
return {
|
|
554
|
-
selectedWallets: state.selectedWallets.concat(selectedWallets)
|
|
555
|
-
};
|
|
556
|
-
}),
|
|
557
|
-
setSelectedWallet: wallet => set(state => ({
|
|
558
|
-
selectedWallets: state.selectedWallets.filter(selectedWallet => selectedWallet.chain !== wallet.chain).concat({
|
|
559
|
-
chain: wallet.chain,
|
|
560
|
-
address: wallet.address,
|
|
561
|
-
walletType: wallet.walletType
|
|
562
|
-
})
|
|
563
|
-
}))
|
|
564
|
-
})));
|
|
565
|
-
|
|
566
|
-
const navigationRoutes = {
|
|
567
|
-
home: '/',
|
|
568
|
-
fromChain: '/from-chain',
|
|
569
|
-
fromToken: '/from-token',
|
|
570
|
-
toChain: '/to-chain',
|
|
571
|
-
toToken: '/to-token',
|
|
572
|
-
settings: '/settings',
|
|
573
|
-
liquiditySources: '/liquidity-sources',
|
|
574
|
-
history: '/history',
|
|
575
|
-
wallets: '/wallets',
|
|
576
|
-
confirmSwap: '/confirm-swap',
|
|
577
|
-
confirmWallets: '/confirm-wallets',
|
|
578
|
-
swapDetails: '/swap-details'
|
|
579
|
-
};
|
|
580
|
-
|
|
581
|
-
const useSettingsStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/middleware.persist( /*#__PURE__*/immer.immer(set => ({
|
|
582
|
-
slippage: 1,
|
|
583
|
-
customSlippage: null,
|
|
584
|
-
infinitApprove: false,
|
|
585
|
-
disabledLiquiditySources: [],
|
|
586
|
-
theme: 'auto',
|
|
587
|
-
setSlippage: slippage => set(state => {
|
|
588
|
-
state.slippage = slippage;
|
|
589
|
-
}),
|
|
590
|
-
setCustomSlippage: customSlippage => {
|
|
591
|
-
return set(state => {
|
|
592
|
-
state.customSlippage = customSlippage;
|
|
593
|
-
});
|
|
594
|
-
},
|
|
595
|
-
toggleAllLiquiditySources: () => set(state => {
|
|
596
|
-
const {
|
|
597
|
-
swappers
|
|
598
|
-
} = useMetaStore.getState().meta;
|
|
599
|
-
if (swappers.length - state.disabledLiquiditySources.length === 0) state.disabledLiquiditySources = [];else {
|
|
600
|
-
const allSwappers = swappers.map(swapper => swapper.swapperGroup);
|
|
601
|
-
state.disabledLiquiditySources = allSwappers;
|
|
602
|
-
}
|
|
603
|
-
}),
|
|
604
|
-
toggleInfinitApprove: () => set(state => {
|
|
605
|
-
state.infinitApprove = !state.infinitApprove;
|
|
606
|
-
}),
|
|
607
|
-
toggleLiquiditySource: name => set(state => {
|
|
608
|
-
state.disabledLiquiditySources = state.disabledLiquiditySources.includes(name) ? state.disabledLiquiditySources.filter(liquiditySource => liquiditySource != name) : state.disabledLiquiditySources.concat(name);
|
|
609
|
-
}),
|
|
610
|
-
setTheme: theme => set(state => {
|
|
611
|
-
state.theme = theme;
|
|
612
|
-
})
|
|
613
|
-
})), {
|
|
614
|
-
name: 'user-settings'
|
|
615
|
-
})));
|
|
616
|
-
|
|
617
401
|
function getOutputRatio(inputUsdValue, outputUsdValue) {
|
|
618
402
|
if (inputUsdValue.lte(ZERO) || outputUsdValue.lte(ZERO)) return 0;
|
|
619
403
|
return outputUsdValue.div(inputUsdValue).minus(1).multipliedBy(100);
|
|
@@ -633,14 +417,90 @@ function hasLimitError(bestRoute) {
|
|
|
633
417
|
}
|
|
634
418
|
}).length > 0;
|
|
635
419
|
}
|
|
636
|
-
function
|
|
637
|
-
if (
|
|
638
|
-
|
|
420
|
+
function LimitErrorMessage(bestRoute) {
|
|
421
|
+
if (!bestRoute) return {
|
|
422
|
+
swap: null,
|
|
423
|
+
fromAmountRangeError: '',
|
|
424
|
+
recommendation: ''
|
|
425
|
+
};
|
|
426
|
+
const swap = (bestRoute?.result?.swaps || []).filter(swap => {
|
|
427
|
+
const minimum = !!swap.fromAmountMinValue ? new BigNumber__default(swap.fromAmountMinValue) : null;
|
|
428
|
+
const maximum = !!swap.fromAmountMaxValue ? new BigNumber__default(swap.fromAmountMaxValue) : null;
|
|
429
|
+
const isExclusive = swap.fromAmountRestrictionType === 'EXCLUSIVE';
|
|
430
|
+
if (isExclusive) {
|
|
431
|
+
return minimum?.gte(swap.fromAmount) || maximum?.lte(swap.fromAmount);
|
|
432
|
+
} else {
|
|
433
|
+
return minimum?.gt(swap.fromAmount) || maximum?.lt(swap.fromAmount);
|
|
434
|
+
}
|
|
435
|
+
})[0];
|
|
436
|
+
if (!swap) return {
|
|
437
|
+
swap: null,
|
|
438
|
+
fromAmountRangeError: '',
|
|
439
|
+
recommendation: ''
|
|
440
|
+
};
|
|
441
|
+
const minimum = !!swap.fromAmountMinValue ? new BigNumber__default(swap.fromAmountMinValue) : null;
|
|
442
|
+
const maximum = !!swap.fromAmountMaxValue ? new BigNumber__default(swap.fromAmountMaxValue) : null;
|
|
443
|
+
const isExclusive = swap.fromAmountRestrictionType === 'EXCLUSIVE';
|
|
444
|
+
let fromAmountRangeError = '';
|
|
445
|
+
let recommendation = '';
|
|
446
|
+
if (!isExclusive && !!minimum && minimum.gt(swap.fromAmount)) {
|
|
447
|
+
fromAmountRangeError = `Required: >= ${numberToString(minimum)} ${swap.from.symbol}`;
|
|
448
|
+
recommendation = 'Increase your swap amount';
|
|
449
|
+
} else if (isExclusive && !!minimum && minimum.gte(swap.fromAmount)) {
|
|
450
|
+
fromAmountRangeError = `Required: > ${numberToString(minimum)} ${swap.from.symbol}`;
|
|
451
|
+
recommendation = 'Increase your swap amount';
|
|
452
|
+
}
|
|
453
|
+
if (!isExclusive && !!maximum && maximum.lt(swap.fromAmount)) {
|
|
454
|
+
fromAmountRangeError = `Required: <= ${numberToString(maximum)} ${swap.from.symbol}`;
|
|
455
|
+
recommendation = 'Decrease your swap amount';
|
|
456
|
+
} else if (isExclusive && !!maximum && maximum.lte(swap.fromAmount)) {
|
|
457
|
+
fromAmountRangeError = `Required: < ${numberToString(maximum)} ${swap.from.symbol}`;
|
|
458
|
+
recommendation = 'Decrease your swap amount';
|
|
459
|
+
}
|
|
460
|
+
return {
|
|
461
|
+
swap,
|
|
462
|
+
fromAmountRangeError,
|
|
463
|
+
recommendation
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
function getSwapButtonState(loadingMetaStatus, accounts, loading, bestRoute, hasLimitError, highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath) {
|
|
467
|
+
if (loadingMetaStatus !== 'success') return {
|
|
468
|
+
title: 'Connect Wallet',
|
|
469
|
+
disabled: true
|
|
470
|
+
};
|
|
471
|
+
if (accounts.length == 0) return {
|
|
472
|
+
title: 'Connect Wallet',
|
|
473
|
+
disabled: false
|
|
474
|
+
};
|
|
475
|
+
if (loading) return {
|
|
476
|
+
title: 'Finding Best Route...',
|
|
477
|
+
disabled: true
|
|
478
|
+
};else if (!bestRoute) return {
|
|
479
|
+
title: 'Swap',
|
|
480
|
+
disabled: true
|
|
481
|
+
};else if (hasLimitError) return {
|
|
482
|
+
title: 'Limit Error',
|
|
483
|
+
disabled: true
|
|
484
|
+
};else if (highValueLoss) return {
|
|
485
|
+
title: 'Price impact is too high!',
|
|
486
|
+
disabled: true
|
|
487
|
+
};else if (priceImpactCanNotBeComputed) return {
|
|
488
|
+
title: 'USD price is unknown, price impact might be high!',
|
|
489
|
+
disabled: false,
|
|
490
|
+
hasWarning: true
|
|
491
|
+
};else if (needsToWarnEthOnPath) return {
|
|
492
|
+
title: 'The route goes through Ethereum. Continue?',
|
|
493
|
+
disabled: false,
|
|
494
|
+
hasWarning: true
|
|
495
|
+
};else return {
|
|
496
|
+
title: 'Swap',
|
|
497
|
+
disabled: false
|
|
498
|
+
};
|
|
639
499
|
}
|
|
640
500
|
function canComputePriceImpact(bestRoute, inputAmount, inputUsdValue, outputUsdValue) {
|
|
641
|
-
return !((inputUsdValue.lte(ZERO) || outputUsdValue.lte(ZERO)) && !!bestRoute?.result && !!inputAmount && inputAmount !== '0' && parseFloat(inputAmount || '0') !== 0);
|
|
501
|
+
return !((inputUsdValue.lte(ZERO) || outputUsdValue.lte(ZERO)) && !!bestRoute?.result && !!inputAmount && inputAmount !== '0' && parseFloat(inputAmount || '0') !== 0 && !!bestRoute.result);
|
|
642
502
|
}
|
|
643
|
-
function calculatePendingSwap(inputAmount, bestRoute, wallets, settings, validateBalanceOrFee) {
|
|
503
|
+
function calculatePendingSwap(inputAmount, bestRoute, wallets, settings, validateBalanceOrFee, meta) {
|
|
644
504
|
const simulationResult = bestRoute.result;
|
|
645
505
|
if (!simulationResult) throw Error('Simulation result should not be null');
|
|
646
506
|
return {
|
|
@@ -658,52 +518,58 @@ function calculatePendingSwap(inputAmount, bestRoute, wallets, settings, validat
|
|
|
658
518
|
networkStatusExtraMessage: null,
|
|
659
519
|
networkStatusExtraMessageDetail: null,
|
|
660
520
|
lastNotificationTime: null,
|
|
521
|
+
//@ts-ignore
|
|
661
522
|
settings: settings,
|
|
662
523
|
simulationResult: simulationResult,
|
|
663
524
|
validateBalanceOrFee,
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
525
|
+
steps: bestRoute.result?.swaps?.map((swap, index) => {
|
|
526
|
+
const swapper = meta.swappers.find(swapper => swapper.id === swap.swapperId);
|
|
527
|
+
const swapperType = swapper?.types[0];
|
|
528
|
+
const fromBlockchain = meta.blockchains.find(blockchain => blockchain.name === swap.from.blockchain);
|
|
529
|
+
const toBlockchain = meta.blockchains.find(blockchain => blockchain.name === swap.to.blockchain);
|
|
530
|
+
return {
|
|
531
|
+
id: index + 1,
|
|
532
|
+
fromBlockchain: swap.from.blockchain,
|
|
533
|
+
fromSymbol: swap.from.symbol,
|
|
534
|
+
fromSymbolAddress: swap.from.address,
|
|
535
|
+
fromDecimals: swap.from.decimals,
|
|
536
|
+
fromAmountPrecision: swap.fromAmountPrecision,
|
|
537
|
+
fromAmountMinValue: swap.fromAmountMinValue,
|
|
538
|
+
fromAmountMaxValue: swap.fromAmountMaxValue,
|
|
539
|
+
toBlockchain: swap.to.blockchain,
|
|
540
|
+
fromLogo: swap.from.logo,
|
|
541
|
+
toSymbol: swap.to.symbol,
|
|
542
|
+
toSymbolAddress: swap.to.address,
|
|
543
|
+
toDecimals: swap.to.decimals,
|
|
544
|
+
toLogo: swap.to.logo,
|
|
545
|
+
startTransactionTime: new Date().getTime(),
|
|
546
|
+
swapperId: swap.swapperId,
|
|
547
|
+
feeInUsd: numberToString(getUsdFeeOfStep(swap, meta.tokens), null, 2),
|
|
548
|
+
expectedOutputAmountHumanReadable: swap.toAmount,
|
|
549
|
+
outputAmount: '',
|
|
550
|
+
status: 'created',
|
|
551
|
+
networkStatus: null,
|
|
552
|
+
executedTransactionId: null,
|
|
553
|
+
externalTransactionId: null,
|
|
554
|
+
explorerUrl: null,
|
|
555
|
+
trackingCode: null,
|
|
556
|
+
cosmosTransaction: null,
|
|
557
|
+
solanaTransaction: null,
|
|
558
|
+
starknetTransaction: null,
|
|
559
|
+
starknetApprovalTransaction: null,
|
|
560
|
+
tronTransaction: null,
|
|
561
|
+
tronApprovalTransaction: null,
|
|
562
|
+
evmTransaction: null,
|
|
563
|
+
evmApprovalTransaction: null,
|
|
564
|
+
transferTransaction: null,
|
|
565
|
+
diagnosisUrl: null,
|
|
566
|
+
internalSteps: null,
|
|
567
|
+
fromBlockchainLogo: fromBlockchain.logo,
|
|
568
|
+
toBlockchainLogo: toBlockchain.logo,
|
|
569
|
+
swapperLogo: swapper?.logo,
|
|
570
|
+
swapperType: swapperType
|
|
571
|
+
};
|
|
572
|
+
}) || []
|
|
707
573
|
};
|
|
708
574
|
}
|
|
709
575
|
function requiredWallets(route) {
|
|
@@ -718,399 +584,1207 @@ function requiredWallets(route) {
|
|
|
718
584
|
});
|
|
719
585
|
return wallets;
|
|
720
586
|
}
|
|
587
|
+
const getUsdPrice$1 = (blockchain, symbol, address, allTokens) => {
|
|
588
|
+
const token = allTokens?.find(t => t.blockchain === blockchain && t.symbol?.toUpperCase() === symbol?.toUpperCase() && t.address === address);
|
|
589
|
+
return token?.usdPrice || null;
|
|
590
|
+
};
|
|
591
|
+
function getUsdFeeOfStep(step, allTokens) {
|
|
592
|
+
let totalFeeInUsd = ZERO;
|
|
593
|
+
for (let i = 0; i < step.fee.length; i++) {
|
|
594
|
+
const fee = step.fee[i];
|
|
595
|
+
if (fee.expenseType === 'DECREASE_FROM_OUTPUT') continue;
|
|
596
|
+
const unitPrice = getUsdPrice$1(fee.asset.blockchain, fee.asset.symbol, fee.asset.address, allTokens);
|
|
597
|
+
totalFeeInUsd = totalFeeInUsd.plus(new BigNumber__default(fee.amount).multipliedBy(unitPrice || 0));
|
|
598
|
+
}
|
|
599
|
+
return totalFeeInUsd;
|
|
600
|
+
}
|
|
601
|
+
function getTotalFeeInUsd(bestRoute, allTokens) {
|
|
602
|
+
return bestRoute?.result?.swaps.reduce((totalFee, step) => totalFee.plus(getUsdFeeOfStep(step, allTokens)), ZERO) || null;
|
|
603
|
+
}
|
|
604
|
+
function hasHighFee(totalFeeInUsd) {
|
|
605
|
+
if (!totalFeeInUsd) return false;
|
|
606
|
+
return !totalFeeInUsd.lt(new BigNumber__default(30));
|
|
607
|
+
}
|
|
608
|
+
function getMinRequiredSlippage(route) {
|
|
609
|
+
const slippages = route.result?.swaps.map(slippage => slippage.recommendedSlippage);
|
|
610
|
+
return slippages?.map(s => s?.slippage || 0)?.filter(s => s > 0)?.sort((a, b) => b - a)?.find(() => true) || null;
|
|
611
|
+
}
|
|
612
|
+
function hasProperSlippage(userSlippage, minRequiredSlippage) {
|
|
613
|
+
if (!minRequiredSlippage) return true;
|
|
614
|
+
return parseFloat(userSlippage) > minRequiredSlippage;
|
|
615
|
+
}
|
|
616
|
+
function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, selectedWallets, disabledLiquiditySources, slippage, checkPrerequisites) {
|
|
617
|
+
const selectedWalletsMap = selectedWallets.reduce((selectedWalletsMap, selectedWallet) => (selectedWalletsMap[selectedWallet.chain] = selectedWallet.address, selectedWalletsMap), {});
|
|
618
|
+
const connectedWallets = [];
|
|
619
|
+
wallets.forEach(wallet => {
|
|
620
|
+
const chainAndAccounts = connectedWallets.find(connectedWallet => connectedWallet.blockchain === wallet.chain);
|
|
621
|
+
if (!!chainAndAccounts) chainAndAccounts.addresses.push(wallet.address);else connectedWallets.push({
|
|
622
|
+
blockchain: wallet.chain,
|
|
623
|
+
addresses: [wallet.address]
|
|
624
|
+
});
|
|
625
|
+
});
|
|
626
|
+
const requestBody = {
|
|
627
|
+
amount: inputAmount.toString(),
|
|
628
|
+
checkPrerequisites,
|
|
629
|
+
from: {
|
|
630
|
+
address: fromToken.address,
|
|
631
|
+
blockchain: fromToken.blockchain,
|
|
632
|
+
symbol: fromToken.symbol
|
|
633
|
+
},
|
|
634
|
+
to: {
|
|
635
|
+
address: toToken.address,
|
|
636
|
+
blockchain: toToken.blockchain,
|
|
637
|
+
symbol: toToken.symbol
|
|
638
|
+
},
|
|
639
|
+
connectedWallets,
|
|
640
|
+
selectedWallets: selectedWalletsMap,
|
|
641
|
+
swapperGroups: disabledLiquiditySources,
|
|
642
|
+
swappersGroupsExclude: true,
|
|
643
|
+
//@ts-ignore
|
|
644
|
+
slippage: slippage.toString()
|
|
645
|
+
};
|
|
646
|
+
return requestBody;
|
|
647
|
+
}
|
|
648
|
+
function getWalletsForNewSwap(selectedWallets) {
|
|
649
|
+
const wallets = selectedWallets.reduce((selectedWalletsMap, selectedWallet) => (selectedWalletsMap[selectedWallet.chain] = {
|
|
650
|
+
address: selectedWallet.address,
|
|
651
|
+
walletType: selectedWallet.walletType
|
|
652
|
+
}, selectedWalletsMap), {});
|
|
653
|
+
return wallets;
|
|
654
|
+
}
|
|
655
|
+
function getRouteOutputAmount(route) {
|
|
656
|
+
return route.result?.outputAmount || null;
|
|
657
|
+
}
|
|
658
|
+
function getPercentageChange(oldValue, newValue) {
|
|
659
|
+
return new BigNumber__default(newValue).div(new BigNumber__default(oldValue)).minus(1).multipliedBy(100);
|
|
660
|
+
}
|
|
661
|
+
function isOutputAmountChangedALot(oldRoute, newRoute) {
|
|
662
|
+
const oldOutputAmount = getRouteOutputAmount(oldRoute);
|
|
663
|
+
const newOutputAmount = getRouteOutputAmount(newRoute);
|
|
664
|
+
if (!oldOutputAmount || !newOutputAmount) return false;
|
|
665
|
+
const percentageChange = getPercentageChange(oldOutputAmount, newOutputAmount);
|
|
666
|
+
return percentageChange.toNumber() <= -1;
|
|
667
|
+
}
|
|
668
|
+
function getBalanceWarnings(route, selectedWallets) {
|
|
669
|
+
const fee = route.validationStatus;
|
|
670
|
+
const requiredWallets = getRequiredChains(route);
|
|
671
|
+
const walletsSortedByRequiredWallets = selectedWallets.sort((selectedWallet1, selectedWallet2) => requiredWallets.indexOf(selectedWallet1.chain) - requiredWallets.indexOf(selectedWallet2.chain));
|
|
672
|
+
return walletsSortedByRequiredWallets.flatMap(wallet => getRequiredBalanceOfWallet(wallet, fee) || []).filter(asset => !asset.ok).map(asset => {
|
|
673
|
+
const symbol = asset.asset.symbol;
|
|
674
|
+
const currentAmount = numberToString(new BigNumber__default(asset.currentAmount.amount).shiftedBy(-asset.currentAmount.decimals), 8);
|
|
675
|
+
const requiredAmount = numberToString(new BigNumber__default(asset.requiredAmount.amount).shiftedBy(-asset.requiredAmount.decimals), 8);
|
|
676
|
+
let reason = '';
|
|
677
|
+
if (asset.reason === 'FEE') reason = ' for network fee';
|
|
678
|
+
if (asset.reason === 'INPUT_ASSET') reason = ' for swap';
|
|
679
|
+
if (asset.reason === 'FEE_AND_INPUT_ASSET') reason = ' for input and network fee';
|
|
680
|
+
const warningMessage = `Needs ≈ ${requiredAmount} ${symbol}${reason}, but you have ${currentAmount} ${symbol} in your ${asset.asset.blockchain} wallet.`;
|
|
681
|
+
return warningMessage;
|
|
682
|
+
});
|
|
683
|
+
}
|
|
721
684
|
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
if (fee === null || fee.length === 0) return {
|
|
742
|
-
balance: true,
|
|
743
|
-
slippage: true,
|
|
744
|
-
routeChanged
|
|
745
|
-
};
|
|
746
|
-
for (const wallet of selectedWallets) {
|
|
747
|
-
const requiredAssets = getRequiredBalanceOfWallet(wallet, fee);
|
|
748
|
-
if (!requiredAssets) continue;
|
|
749
|
-
const hasEnoughBalance = requiredAssets?.map(it => it.ok).reduce((a, b) => a && b);
|
|
750
|
-
if (!hasEnoughBalance) return {
|
|
751
|
-
balance: false,
|
|
752
|
-
slippage: true,
|
|
753
|
-
routeChanged
|
|
754
|
-
};
|
|
755
|
-
}
|
|
756
|
-
const slippages = route.result?.swaps?.map(s => s.recommendedSlippage);
|
|
757
|
-
const slippageError = (slippages?.filter(s => !!s?.error)?.length || 0) > 0;
|
|
758
|
-
const minSlippage = slippages?.map(s => parseFloat(s?.slippage.toString() || '0') || 0).filter(s => s > 0).sort((a, b) => b - a).find(() => true) || null;
|
|
759
|
-
if (slippageError) {
|
|
760
|
-
setError('Server cannot calculated required slippage for your swap');
|
|
761
|
-
return {
|
|
762
|
-
balance: true,
|
|
763
|
-
slippage: false,
|
|
764
|
-
routeChanged
|
|
765
|
-
};
|
|
766
|
-
} else if (minSlippage !== null && minSlippage > parseFloat(userSlippage)) {
|
|
767
|
-
setError(`Your slippage should be ${minSlippage} at least`);
|
|
768
|
-
return {
|
|
769
|
-
balance: true,
|
|
770
|
-
slippage: false,
|
|
771
|
-
routeChanged
|
|
772
|
-
};
|
|
685
|
+
const getUsdValue = (token, amount) => new BigNumber__default(amount || ZERO).multipliedBy(token?.usdPrice || 0);
|
|
686
|
+
const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/middleware.subscribeWithSelector(set => ({
|
|
687
|
+
fromChain: null,
|
|
688
|
+
fromToken: null,
|
|
689
|
+
inputAmount: '',
|
|
690
|
+
outputAmount: null,
|
|
691
|
+
inputUsdValue: new BigNumber__default(0),
|
|
692
|
+
outputUsdValue: new BigNumber__default(0),
|
|
693
|
+
toChain: null,
|
|
694
|
+
toToken: null,
|
|
695
|
+
bestRoute: null,
|
|
696
|
+
loading: false,
|
|
697
|
+
error: '',
|
|
698
|
+
setBestRoute: bestRoute => set(state => {
|
|
699
|
+
let outputAmount = null;
|
|
700
|
+
let outputUsdValue = ZERO;
|
|
701
|
+
if (!!bestRoute) {
|
|
702
|
+
outputAmount = !!bestRoute.result?.outputAmount ? new BigNumber__default(bestRoute.result?.outputAmount) : null;
|
|
703
|
+
outputUsdValue = new BigNumber__default(outputAmount || ZERO).multipliedBy(getBestRouteToTokenUsdPrice(bestRoute) || state.toToken?.usdPrice || 0);
|
|
773
704
|
}
|
|
774
705
|
return {
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
706
|
+
bestRoute,
|
|
707
|
+
...(!!bestRoute && {
|
|
708
|
+
outputAmount,
|
|
709
|
+
outputUsdValue
|
|
710
|
+
})
|
|
778
711
|
};
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
712
|
+
}),
|
|
713
|
+
setFromChain: chain => set(() => ({
|
|
714
|
+
fromChain: chain
|
|
715
|
+
})),
|
|
716
|
+
setFromToken: token => set(state => ({
|
|
717
|
+
fromToken: token,
|
|
718
|
+
...(!!state.inputAmount && {
|
|
719
|
+
inputUsdValue: getUsdValue(token, state.inputAmount)
|
|
720
|
+
})
|
|
721
|
+
})),
|
|
722
|
+
setToChain: chain => set(() => ({
|
|
723
|
+
toChain: chain
|
|
724
|
+
})),
|
|
725
|
+
setToToken: token => set(() => ({
|
|
726
|
+
toToken: token
|
|
727
|
+
})),
|
|
728
|
+
setInputAmount: amount => set(state => ({
|
|
729
|
+
inputAmount: amount,
|
|
730
|
+
...(!!state.fromToken && {
|
|
731
|
+
inputUsdValue: getUsdValue(state.fromToken, amount)
|
|
732
|
+
})
|
|
733
|
+
}))
|
|
734
|
+
}))));
|
|
735
|
+
const bestRoute = (bestRouteStore, settingsStore) => {
|
|
736
|
+
let abortController = null;
|
|
737
|
+
const fetchBestRoute = () => {
|
|
738
|
+
const {
|
|
739
|
+
fromToken,
|
|
740
|
+
toToken,
|
|
741
|
+
inputAmount
|
|
742
|
+
} = bestRouteStore.getState();
|
|
743
|
+
const {
|
|
744
|
+
slippage,
|
|
745
|
+
customSlippage,
|
|
746
|
+
disabledLiquiditySources
|
|
747
|
+
} = settingsStore.getState();
|
|
748
|
+
if (!fromToken || !toToken || !inputAmount) return;
|
|
749
|
+
abortController?.abort();
|
|
750
|
+
abortController = new AbortController();
|
|
751
|
+
const userSlippage = customSlippage | slippage;
|
|
752
|
+
const requestBody = createBestRouteRequestBody(fromToken, toToken, inputAmount, [], [], disabledLiquiditySources, userSlippage, false);
|
|
753
|
+
bestRouteStore.setState({
|
|
754
|
+
loading: true,
|
|
755
|
+
bestRoute: null
|
|
791
756
|
});
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
symbol: toToken.symbol
|
|
804
|
-
},
|
|
805
|
-
connectedWallets,
|
|
806
|
-
selectedWallets: selectedWalletsMap,
|
|
807
|
-
//@ts-ignore
|
|
808
|
-
swapperGroups: disabledLiquiditySources,
|
|
809
|
-
swappersGroupsExclude: true
|
|
757
|
+
httpService.getBestRoute(requestBody, {
|
|
758
|
+
signal: abortController.signal
|
|
759
|
+
}).then(res => {
|
|
760
|
+
const {
|
|
761
|
+
setBestRoute
|
|
762
|
+
} = bestRouteStore.getState();
|
|
763
|
+
setBestRoute(res);
|
|
764
|
+
bestRouteStore.setState({
|
|
765
|
+
loading: false
|
|
766
|
+
});
|
|
767
|
+
abortController = null;
|
|
810
768
|
}).catch(error => {
|
|
811
|
-
|
|
812
|
-
|
|
769
|
+
if (error.code === 'ERR_CANCELED') return;
|
|
770
|
+
bestRouteStore.setState({
|
|
771
|
+
error: error.message,
|
|
772
|
+
loading: false
|
|
773
|
+
});
|
|
813
774
|
});
|
|
814
|
-
setLoading(false);
|
|
815
|
-
if (!r || !r.result || !bestRoute) return {
|
|
816
|
-
bestRoute: null
|
|
817
|
-
};
|
|
818
|
-
if (!new BigNumber__default(r.requestAmount).isEqualTo(new BigNumber__default(inputAmount || '-1'))) return null;
|
|
819
|
-
setFeeStatus(r.validationStatus);
|
|
820
|
-
const routeChangeStatus = compareRoutes(bestRoute, r, inputAmount.toString(), fromToken.usdPrice, toToken.usdPrice);
|
|
821
|
-
setBestRoute(r);
|
|
822
|
-
const isChanged = routeChangeStatus.isChanged;
|
|
823
|
-
setBestRouteChanged(isChanged);
|
|
824
|
-
setWarning('Best route changed');
|
|
825
|
-
setData(r);
|
|
826
|
-
return {
|
|
827
|
-
hasEnoughBalanceOrSlippage: hasEnoughBalanceOrProperSlippage(r, selectedWallets, slippage.toString(), isChanged),
|
|
828
|
-
bestRoute: r
|
|
829
|
-
};
|
|
830
775
|
};
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
slippage: slippage.toString(),
|
|
841
|
-
disabledSwappersGroups: ['Osmosis'],
|
|
842
|
-
disabledSwappersIds: []
|
|
843
|
-
};
|
|
844
|
-
if (proceedAnyway) {
|
|
845
|
-
const newSwap = calculatePendingSwap(inputAmount.toString(), bestRoute, wallets, settings, false);
|
|
776
|
+
useBestRouteStore.subscribe(state => ({
|
|
777
|
+
fromChain: state.fromChain,
|
|
778
|
+
fromToken: state.fromToken,
|
|
779
|
+
toChain: state.toChain,
|
|
780
|
+
toToken: state.toToken,
|
|
781
|
+
inputAmount: state.inputAmount
|
|
782
|
+
}), fetchBestRoute.bind(null), {
|
|
783
|
+
equalityFn: (prevState, state) => {
|
|
784
|
+
if (prevState.fromChain?.name !== state.fromChain?.name || prevState.toChain?.name !== state.toChain?.name || prevState.fromToken?.symbol !== state.fromToken?.symbol || prevState.toToken?.symbol !== state.toToken?.symbol || prevState.fromToken?.blockchain !== state.fromToken?.blockchain || prevState.toToken?.blockchain !== state.toToken?.blockchain || prevState.fromToken?.address !== state.fromToken?.address || prevState.toToken?.address !== state.toToken?.address || prevState.inputAmount !== state.inputAmount) return false;else return true;
|
|
846
785
|
}
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
hasEnoughBalanceOrSlippage,
|
|
858
|
-
bestRoute: newBestRoute
|
|
859
|
-
} = data;
|
|
860
|
-
if (!hasEnoughBalanceOrSlippage) {
|
|
861
|
-
return;
|
|
862
|
-
}
|
|
863
|
-
setEnoughBalance(hasEnoughBalanceOrSlippage.balance && hasEnoughBalanceOrSlippage.slippage);
|
|
864
|
-
if (hasEnoughBalanceOrSlippage.balance && hasEnoughBalanceOrSlippage.slippage && !hasEnoughBalanceOrSlippage.routeChanged) {
|
|
865
|
-
const newSwap = calculatePendingSwap(inputAmount.toString(), newBestRoute, wallets, settings, true);
|
|
866
|
-
} else if (!hasEnoughBalanceOrSlippage.balance) {
|
|
867
|
-
setError('not enough balance');
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
}).catch(error => {
|
|
871
|
-
console.log('unexpected error', error);
|
|
872
|
-
});
|
|
873
|
-
};
|
|
786
|
+
});
|
|
787
|
+
useSettingsStore.subscribe(state => ({
|
|
788
|
+
slippage: state.slippage,
|
|
789
|
+
customSlippage: state.customSlippage,
|
|
790
|
+
disabledLiquiditySources: state.disabledLiquiditySources
|
|
791
|
+
}), fetchBestRoute.bind(null), {
|
|
792
|
+
equalityFn: (prevState, state) => {
|
|
793
|
+
if (prevState.slippage !== state.slippage || prevState.customSlippage !== state.customSlippage || prevState.disabledLiquiditySources.length !== state.disabledLiquiditySources.length) return false;else return true;
|
|
794
|
+
}
|
|
795
|
+
});
|
|
874
796
|
return {
|
|
875
|
-
|
|
876
|
-
error,
|
|
877
|
-
data,
|
|
878
|
-
warning,
|
|
879
|
-
feeStatus,
|
|
880
|
-
bestRouteChanged,
|
|
881
|
-
enoughBalance,
|
|
882
|
-
swap
|
|
797
|
+
fetchBestRoute
|
|
883
798
|
};
|
|
884
|
-
}
|
|
799
|
+
};
|
|
800
|
+
const {
|
|
801
|
+
fetchBestRoute
|
|
802
|
+
} = /*#__PURE__*/bestRoute(useBestRouteStore, useSettingsStore);
|
|
885
803
|
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
} = useConfirmSwap();
|
|
895
|
-
return React__default.createElement(ui.ConfirmSwap, {
|
|
896
|
-
onConfirm: swap.bind(null),
|
|
897
|
-
onBack: navigate.bind(null, -1),
|
|
898
|
-
bestRoute: bestRoute,
|
|
899
|
-
loading: loading,
|
|
900
|
-
error: error,
|
|
901
|
-
warning: warning
|
|
902
|
-
});
|
|
903
|
-
}
|
|
804
|
+
var SearchParams;
|
|
805
|
+
(function (SearchParams) {
|
|
806
|
+
SearchParams["FROM_CHAIN"] = "fromChain";
|
|
807
|
+
SearchParams["FROM_TOKEN"] = "fromToken";
|
|
808
|
+
SearchParams["TO_CHAIN"] = "toChain";
|
|
809
|
+
SearchParams["TO_TOKEN"] = "toToken";
|
|
810
|
+
SearchParams["FROM_AMOUNT"] = "fromAmount";
|
|
811
|
+
})(SearchParams || (SearchParams = {}));
|
|
904
812
|
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
}
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
813
|
+
function searchParamsToToken(tokens, searchParams) {
|
|
814
|
+
return tokens.find(token => {
|
|
815
|
+
const symbolAndAddress = searchParams?.split('--');
|
|
816
|
+
if (symbolAndAddress?.length === 1) return token.symbol === symbolAndAddress[0] && token.address === null;
|
|
817
|
+
return token.symbol === symbolAndAddress?.[0] && token.address === symbolAndAddress?.[1];
|
|
818
|
+
}) || null;
|
|
819
|
+
}
|
|
820
|
+
function UpdateUrl() {
|
|
821
|
+
const firstRender = React.useRef(true);
|
|
822
|
+
const [searchParams, setSearchParams] = reactRouterDom.useSearchParams();
|
|
823
|
+
const location = reactRouterDom.useLocation();
|
|
824
|
+
const firstRenderSearchParams = React.useRef(location.search);
|
|
825
|
+
const searchParamsRef = React.useRef({});
|
|
826
|
+
React.useEffect(() => {
|
|
827
|
+
const params = {};
|
|
828
|
+
reactRouterDom.createSearchParams(firstRenderSearchParams.current).forEach((value, key) => {
|
|
829
|
+
params[key] = value;
|
|
830
|
+
});
|
|
831
|
+
searchParamsRef.current = params;
|
|
832
|
+
}, []);
|
|
833
|
+
const fromChain = useBestRouteStore.use.fromChain();
|
|
834
|
+
const toChain = useBestRouteStore.use.toChain();
|
|
835
|
+
const fromToken = useBestRouteStore.use.fromToken();
|
|
836
|
+
const toToken = useBestRouteStore.use.toToken();
|
|
837
|
+
const setFromChain = useBestRouteStore.use.setFromChain();
|
|
838
|
+
const setFromToken = useBestRouteStore.use.setFromToken();
|
|
839
|
+
const setToChain = useBestRouteStore.use.setToChain();
|
|
840
|
+
const setToToken = useBestRouteStore.use.setToToken();
|
|
841
|
+
const inputAmount = useBestRouteStore.use.inputAmount();
|
|
842
|
+
const setInputAmount = useBestRouteStore.use.setInputAmount();
|
|
843
|
+
const loadingStatus = useMetaStore.use.loadingStatus();
|
|
844
|
+
const {
|
|
845
|
+
blockchains,
|
|
846
|
+
tokens
|
|
847
|
+
} = useMetaStore.use.meta();
|
|
848
|
+
React.useEffect(() => {
|
|
849
|
+
let fromChainString = '',
|
|
850
|
+
fromTokenString = '',
|
|
851
|
+
toChainString = '',
|
|
852
|
+
toTokenString = '',
|
|
853
|
+
fromAmount = '';
|
|
854
|
+
if (loadingStatus !== 'success' && ![navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname)) {
|
|
855
|
+
fromChainString = searchParamsRef.current[SearchParams.FROM_CHAIN];
|
|
856
|
+
fromTokenString = searchParamsRef.current[SearchParams.FROM_TOKEN];
|
|
857
|
+
toChainString = searchParamsRef.current[SearchParams.TO_CHAIN];
|
|
858
|
+
toTokenString = searchParamsRef.current[SearchParams.TO_TOKEN];
|
|
859
|
+
fromAmount = searchParamsRef.current[SearchParams.FROM_AMOUNT];
|
|
860
|
+
setSearchParams({
|
|
861
|
+
...(fromChainString && {
|
|
862
|
+
[SearchParams.FROM_CHAIN]: fromChainString
|
|
863
|
+
}),
|
|
864
|
+
...(fromTokenString && {
|
|
865
|
+
[SearchParams.FROM_TOKEN]: fromTokenString
|
|
866
|
+
}),
|
|
867
|
+
...(toChainString && {
|
|
868
|
+
[SearchParams.TO_CHAIN]: toChainString
|
|
869
|
+
}),
|
|
870
|
+
...(toTokenString && {
|
|
871
|
+
[SearchParams.TO_TOKEN]: toTokenString
|
|
872
|
+
}),
|
|
873
|
+
...(fromAmount && {
|
|
874
|
+
[SearchParams.FROM_AMOUNT]: fromAmount.toString()
|
|
875
|
+
})
|
|
876
|
+
}, {
|
|
877
|
+
replace: true
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
if (!firstRender.current) {
|
|
881
|
+
let fromChainString = '',
|
|
882
|
+
fromTokenString = '',
|
|
883
|
+
toChainString = '',
|
|
884
|
+
toTokenString = '',
|
|
885
|
+
fromAmount = '';
|
|
886
|
+
if (loadingStatus !== 'success') {
|
|
887
|
+
fromChainString = searchParamsRef.current[SearchParams.FROM_CHAIN];
|
|
888
|
+
fromTokenString = searchParamsRef.current[SearchParams.FROM_TOKEN];
|
|
889
|
+
toChainString = searchParamsRef.current[SearchParams.TO_CHAIN];
|
|
890
|
+
toTokenString = searchParamsRef.current[SearchParams.TO_TOKEN];
|
|
891
|
+
fromAmount = searchParamsRef.current[SearchParams.FROM_AMOUNT];
|
|
892
|
+
} else {
|
|
893
|
+
if (location.state === 'redirect') return;
|
|
894
|
+
fromChainString = fromChain?.name || '';
|
|
895
|
+
fromTokenString = (fromToken?.symbol || '') + (fromToken?.address ? `--${fromToken?.address}` : '');
|
|
896
|
+
toChainString = toChain?.name || '';
|
|
897
|
+
toTokenString = (toToken?.symbol || '') + (toToken?.address ? `--${toToken?.address}` : '');
|
|
898
|
+
fromAmount = inputAmount;
|
|
899
|
+
setSearchParams({
|
|
900
|
+
...(fromChainString && {
|
|
901
|
+
[SearchParams.FROM_CHAIN]: fromChainString
|
|
902
|
+
}),
|
|
903
|
+
...(fromTokenString && {
|
|
904
|
+
[SearchParams.FROM_TOKEN]: fromTokenString
|
|
905
|
+
}),
|
|
906
|
+
...(toChainString && {
|
|
907
|
+
[SearchParams.TO_CHAIN]: toChainString
|
|
908
|
+
}),
|
|
909
|
+
...(toTokenString && {
|
|
910
|
+
[SearchParams.TO_TOKEN]: toTokenString
|
|
911
|
+
}),
|
|
912
|
+
...(fromAmount && {
|
|
913
|
+
[SearchParams.FROM_AMOUNT]: fromAmount.toString()
|
|
914
|
+
})
|
|
1002
915
|
}, {
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
|
|
916
|
+
replace: true
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
firstRender.current = false;
|
|
921
|
+
}, [location.pathname, inputAmount]);
|
|
922
|
+
React.useEffect(() => {
|
|
923
|
+
if (loadingStatus === 'success') {
|
|
924
|
+
const fronChainString = searchParams.get(SearchParams.FROM_CHAIN);
|
|
925
|
+
const fromTokenString = searchParams.get(SearchParams.FROM_TOKEN);
|
|
926
|
+
const toChainString = searchParams.get(SearchParams.TO_CHAIN);
|
|
927
|
+
const toTokenString = searchParams.get(SearchParams.TO_TOKEN);
|
|
928
|
+
const fromAmount = searchParams.get(SearchParams.FROM_AMOUNT);
|
|
929
|
+
const fromChain = blockchains.find(blockchain => blockchain.name === fronChainString);
|
|
930
|
+
const fromToken = searchParamsToToken(tokens, fromTokenString);
|
|
931
|
+
const toChain = blockchains.find(blockchain => blockchain.name === toChainString);
|
|
932
|
+
const toToken = searchParamsToToken(tokens, toTokenString);
|
|
933
|
+
if (!!fromChain) {
|
|
934
|
+
setFromChain(fromChain);
|
|
935
|
+
if (!!fromToken) setFromToken(fromToken);
|
|
936
|
+
}
|
|
937
|
+
if (!!toChain) {
|
|
938
|
+
setToChain(toChain);
|
|
939
|
+
if (!!toToken) setToToken(toToken);
|
|
940
|
+
}
|
|
941
|
+
if (fromAmount) setInputAmount(fromAmount);
|
|
942
|
+
}
|
|
943
|
+
}, [loadingStatus]);
|
|
944
|
+
return null;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
const ButtonsContainer = /*#__PURE__*/ui.styled('div', {
|
|
948
|
+
display: 'flex'
|
|
949
|
+
});
|
|
950
|
+
function HeaderButtons(props) {
|
|
951
|
+
const {
|
|
952
|
+
onClickRefresh
|
|
953
|
+
} = props;
|
|
954
|
+
const navigate = reactRouterDom.useNavigate();
|
|
955
|
+
return React__default.createElement(ButtonsContainer, null, React__default.createElement(ui.Tooltip, {
|
|
956
|
+
content: "Retry"
|
|
957
|
+
}, React__default.createElement(ui.Button, {
|
|
958
|
+
variant: "ghost",
|
|
959
|
+
onClick: onClickRefresh.bind(null)
|
|
960
|
+
}, React__default.createElement(ui.RetryIcon, {
|
|
961
|
+
size: 28
|
|
962
|
+
}))), React__default.createElement(ui.Tooltip, {
|
|
963
|
+
content: "Transactions History"
|
|
964
|
+
}, React__default.createElement(ui.Button, {
|
|
965
|
+
variant: "ghost",
|
|
966
|
+
onClick: () => navigate(navigationRoutes.history)
|
|
967
|
+
}, React__default.createElement(ui.HistoryIcon, {
|
|
968
|
+
size: 24
|
|
969
|
+
}))), React__default.createElement(ui.Tooltip, {
|
|
970
|
+
content: "Settings"
|
|
971
|
+
}, React__default.createElement(ui.Button, {
|
|
972
|
+
variant: "ghost",
|
|
973
|
+
onClick: () => navigate(navigationRoutes.settings)
|
|
974
|
+
}, React__default.createElement(ui.SettingsIcon, {
|
|
975
|
+
size: 24
|
|
976
|
+
}))));
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
const HeaderContainer = /*#__PURE__*/ui.styled('div', {
|
|
980
|
+
display: 'flex',
|
|
981
|
+
justifyContent: 'space-between',
|
|
982
|
+
alignItems: 'center',
|
|
983
|
+
width: '100%',
|
|
984
|
+
padding: '$16 0'
|
|
985
|
+
});
|
|
986
|
+
function Header(props) {
|
|
987
|
+
const {
|
|
988
|
+
onClickRefresh
|
|
989
|
+
} = props;
|
|
990
|
+
return React__default.createElement(HeaderContainer, null, React__default.createElement(ui.Typography, {
|
|
991
|
+
variant: "h4"
|
|
992
|
+
}, "SWAP"), React__default.createElement(HeaderButtons, {
|
|
993
|
+
onClickRefresh: onClickRefresh
|
|
994
|
+
}));
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
const useWalletsStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/middleware.subscribeWithSelector(set => ({
|
|
998
|
+
accounts: [],
|
|
999
|
+
balances: [],
|
|
1000
|
+
selectedWallets: [],
|
|
1001
|
+
connectWallet: accounts => {
|
|
1002
|
+
const tokens = useMetaStore.getState().meta.tokens;
|
|
1003
|
+
set(state => ({
|
|
1004
|
+
accounts: state.accounts.concat(accounts),
|
|
1005
|
+
balances: state.balances.concat(accounts.map(account => ({
|
|
1006
|
+
balances: [],
|
|
1007
|
+
address: account.address,
|
|
1008
|
+
chain: account.chain,
|
|
1009
|
+
loading: true,
|
|
1010
|
+
walletType: account.walletType,
|
|
1011
|
+
error: false,
|
|
1012
|
+
explorerUrl: null
|
|
1013
|
+
})))
|
|
1014
|
+
}));
|
|
1015
|
+
accounts.forEach(async account => {
|
|
1016
|
+
try {
|
|
1017
|
+
const response = await httpService.getWalletsDetails([{
|
|
1018
|
+
address: account.address,
|
|
1019
|
+
blockchain: account.chain
|
|
1020
|
+
}]);
|
|
1021
|
+
const retrivedBalance = response.wallets[0];
|
|
1022
|
+
if (retrivedBalance) {
|
|
1023
|
+
set(state => ({
|
|
1024
|
+
balances: state.balances.map(balance => {
|
|
1025
|
+
return isAccountAndBalanceMatched(account, balance) ? makeBalanceFor(account, retrivedBalance, tokens) : balance;
|
|
1026
|
+
})
|
|
1027
|
+
}));
|
|
1028
|
+
} else throw new Error('Wallet not found');
|
|
1029
|
+
} catch (error) {
|
|
1030
|
+
set(state => ({
|
|
1031
|
+
balances: state.balances.map(balance => {
|
|
1032
|
+
return isAccountAndBalanceMatched(account, balance) ? resetBalanceState(balance) : balance;
|
|
1033
|
+
})
|
|
1034
|
+
}));
|
|
1035
|
+
}
|
|
1036
|
+
});
|
|
1026
1037
|
},
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1038
|
+
disconnectWallet: walletType => {
|
|
1039
|
+
set(state => ({
|
|
1040
|
+
accounts: state.accounts.filter(account => account.walletType !== walletType),
|
|
1041
|
+
balances: state.balances.filter(balance => balance.walletType !== walletType),
|
|
1042
|
+
selectedWallets: state.selectedWallets.filter(wallet => wallet.walletType != walletType)
|
|
1043
|
+
}));
|
|
1044
|
+
},
|
|
1045
|
+
initSelectedWallets: () => set(state => {
|
|
1046
|
+
const requiredChains = getRequiredChains(useBestRouteStore.getState().bestRoute);
|
|
1047
|
+
const connectedWallets = state.accounts;
|
|
1048
|
+
const selectedWallets = [];
|
|
1049
|
+
requiredChains.forEach(chain => {
|
|
1050
|
+
const anyWalletSelected = !!state.selectedWallets.find(wallet => wallet.chain === chain);
|
|
1051
|
+
if (!anyWalletSelected) {
|
|
1052
|
+
const firstWalletWithMatchedChain = connectedWallets.find(wallet => wallet.chain === chain);
|
|
1053
|
+
if (!!firstWalletWithMatchedChain) selectedWallets.push({
|
|
1054
|
+
address: firstWalletWithMatchedChain.address,
|
|
1055
|
+
chain: firstWalletWithMatchedChain.chain,
|
|
1056
|
+
walletType: firstWalletWithMatchedChain.walletType
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1059
|
+
});
|
|
1060
|
+
return {
|
|
1061
|
+
selectedWallets: state.selectedWallets.concat(selectedWallets)
|
|
1062
|
+
};
|
|
1063
|
+
}),
|
|
1064
|
+
setSelectedWallet: wallet => set(state => ({
|
|
1065
|
+
selectedWallets: state.selectedWallets.filter(selectedWallet => selectedWallet.chain !== wallet.chain).concat({
|
|
1066
|
+
chain: wallet.chain,
|
|
1067
|
+
address: wallet.address,
|
|
1068
|
+
walletType: wallet.walletType
|
|
1069
|
+
})
|
|
1070
|
+
}))
|
|
1071
|
+
}))));
|
|
1072
|
+
|
|
1073
|
+
const Box = /*#__PURE__*/ui.styled('div', {
|
|
1074
|
+
display: 'flex',
|
|
1075
|
+
flexDirection: 'column',
|
|
1076
|
+
width: '100%'
|
|
1077
|
+
});
|
|
1078
|
+
const Container = /*#__PURE__*/ui.styled('div', {
|
|
1079
|
+
boxSizing: 'border-box',
|
|
1080
|
+
backgroundColor: '$neutrals300',
|
|
1081
|
+
borderRadius: '$5',
|
|
1082
|
+
padding: '$8 0',
|
|
1083
|
+
'.form': {
|
|
1084
|
+
display: 'flex',
|
|
1085
|
+
width: '100%',
|
|
1086
|
+
padding: '$8 $16'
|
|
1087
|
+
}
|
|
1088
|
+
});
|
|
1089
|
+
const StyledImage = /*#__PURE__*/ui.styled('img', {
|
|
1090
|
+
width: '$24',
|
|
1091
|
+
maxHeight: '$24'
|
|
1092
|
+
});
|
|
1093
|
+
const Options = /*#__PURE__*/ui.styled('div', {
|
|
1094
|
+
display: 'flex',
|
|
1095
|
+
justifyContent: 'flex-end',
|
|
1096
|
+
padding: '0 $8'
|
|
1097
|
+
});
|
|
1098
|
+
const ImagePlaceholder = /*#__PURE__*/ui.styled('span', {
|
|
1099
|
+
width: '24px',
|
|
1100
|
+
height: '24px',
|
|
1101
|
+
backgroundColor: '$neutrals300',
|
|
1102
|
+
borderRadius: '99999px'
|
|
1103
|
+
});
|
|
1104
|
+
const OutputContainer = /*#__PURE__*/ui.styled('div', {
|
|
1105
|
+
height: '$48',
|
|
1106
|
+
borderRadius: '$5',
|
|
1107
|
+
flexGrow: 1,
|
|
1108
|
+
width: '70%',
|
|
1109
|
+
backgroundColor: '$background',
|
|
1110
|
+
border: '1px solid transparent',
|
|
1111
|
+
position: 'relative',
|
|
1112
|
+
display: 'flex',
|
|
1113
|
+
alignItems: 'center',
|
|
1114
|
+
paddingLeft: '$8',
|
|
1115
|
+
paddingRight: '$8'
|
|
1116
|
+
});
|
|
1117
|
+
function TokenInfo(props) {
|
|
1118
|
+
const {
|
|
1119
|
+
type,
|
|
1120
|
+
chain,
|
|
1121
|
+
token
|
|
1122
|
+
} = props;
|
|
1123
|
+
const loadingStatus = useMetaStore.use.loadingStatus();
|
|
1124
|
+
const fromChain = useBestRouteStore.use.fromChain();
|
|
1125
|
+
const toChain = useBestRouteStore.use.toChain();
|
|
1126
|
+
const inputUsdValue = useBestRouteStore.use.inputUsdValue();
|
|
1127
|
+
const fromToken = useBestRouteStore.use.fromToken();
|
|
1128
|
+
const setInputAmount = useBestRouteStore.use.setInputAmount();
|
|
1129
|
+
const bestRoute = useBestRouteStore.use.bestRoute();
|
|
1130
|
+
const inputAmount = useBestRouteStore.use.inputAmount();
|
|
1131
|
+
const balances = useWalletsStore.use.balances();
|
|
1132
|
+
const navigate = reactRouterDom.useNavigate();
|
|
1133
|
+
const tokenBalance = !!fromChain && !!fromToken ? numberToString(getBalanceFromWallet(balances, fromChain?.name, fromToken?.symbol, fromToken?.address)?.amount || '0', 8) : '0';
|
|
1134
|
+
const tokenBalanceReal = !!fromChain && !!fromToken ? numberToString(getBalanceFromWallet(balances, fromChain?.name, fromToken?.symbol, fromToken?.address)?.amount || '0', getBalanceFromWallet(balances, fromChain?.name, fromToken?.symbol, fromToken?.address)?.decimal) : '0';
|
|
1135
|
+
const ItemSuffix = React__default.createElement("div", {
|
|
1136
|
+
style: {
|
|
1137
|
+
display: 'flex',
|
|
1138
|
+
justifyContent: 'center',
|
|
1139
|
+
alignItems: 'center'
|
|
1140
|
+
}
|
|
1141
|
+
}, loadingStatus === 'failed' && React__default.createElement(ui.InfoCircleIcon, {
|
|
1142
|
+
color: "error",
|
|
1143
|
+
size: 24
|
|
1144
|
+
}), React__default.createElement(ui.AngleDownIcon, null));
|
|
1145
|
+
return React__default.createElement(Box, null, React__default.createElement("div", null, React__default.createElement(ui.Typography, {
|
|
1146
|
+
variant: "body2"
|
|
1147
|
+
}, type)), React__default.createElement(Container, null, props.type === 'From' && React__default.createElement(Options, null, React__default.createElement("div", {
|
|
1148
|
+
className: "balance",
|
|
1149
|
+
onClick: () => {
|
|
1150
|
+
if (tokenBalance !== '0') setInputAmount(tokenBalanceReal.split(',').join(''));
|
|
1151
|
+
}
|
|
1152
|
+
}, React__default.createElement(ui.Button, {
|
|
1153
|
+
variant: "ghost",
|
|
1154
|
+
size: "small"
|
|
1155
|
+
}, React__default.createElement(ui.Typography, {
|
|
1156
|
+
variant: "body2"
|
|
1157
|
+
}, `Max: ${tokenBalance} ${fromToken?.symbol || ''}`)))), React__default.createElement("div", {
|
|
1158
|
+
className: "form"
|
|
1159
|
+
}, React__default.createElement(ui.Button, {
|
|
1160
|
+
onClick: () => {
|
|
1161
|
+
navigate(`/${props.type.toLowerCase()}-chain`);
|
|
1105
1162
|
},
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1163
|
+
variant: "outlined",
|
|
1164
|
+
disabled: loadingStatus === 'failed',
|
|
1165
|
+
loading: loadingStatus === 'loading',
|
|
1166
|
+
prefix: loadingStatus === 'success' && chain ? React__default.createElement(StyledImage, {
|
|
1167
|
+
src: chain.logo
|
|
1168
|
+
}) : React__default.createElement(ImagePlaceholder, null),
|
|
1169
|
+
suffix: ItemSuffix,
|
|
1170
|
+
align: "start",
|
|
1171
|
+
size: "large",
|
|
1172
|
+
style: {
|
|
1173
|
+
marginRight: '.5rem'
|
|
1174
|
+
}
|
|
1175
|
+
}, loadingStatus === 'success' && chain ? chain.displayName : 'Chain'), React__default.createElement(ui.Button, {
|
|
1176
|
+
onClick: () => {
|
|
1177
|
+
navigate(`/${props.type.toLowerCase()}-token`);
|
|
1178
|
+
},
|
|
1179
|
+
variant: "outlined",
|
|
1180
|
+
disabled: loadingStatus === 'failed' || type === 'From' && !fromChain || type === 'To' && !toChain,
|
|
1181
|
+
loading: loadingStatus === 'loading',
|
|
1182
|
+
prefix: loadingStatus === 'success' && token ? React__default.createElement(StyledImage, {
|
|
1183
|
+
src: token.image
|
|
1184
|
+
}) : React__default.createElement(ImagePlaceholder, null),
|
|
1185
|
+
suffix: ItemSuffix,
|
|
1186
|
+
size: "large",
|
|
1187
|
+
align: "start",
|
|
1188
|
+
style: {
|
|
1189
|
+
marginRight: '.5rem'
|
|
1190
|
+
}
|
|
1191
|
+
}, loadingStatus === 'success' && token ? token.symbol : 'Token'), props.type === 'From' ? React__default.createElement(ui.TextField, {
|
|
1192
|
+
type: "number",
|
|
1193
|
+
size: "large",
|
|
1194
|
+
autoFocus: true,
|
|
1195
|
+
placeholder: "0",
|
|
1196
|
+
style: {
|
|
1197
|
+
width: '70%',
|
|
1198
|
+
position: 'relative',
|
|
1199
|
+
backgroundColor: '$background !important'
|
|
1200
|
+
},
|
|
1201
|
+
suffix: React__default.createElement("span", {
|
|
1202
|
+
style: {
|
|
1203
|
+
position: 'absolute',
|
|
1204
|
+
right: '4px',
|
|
1205
|
+
bottom: '2px'
|
|
1206
|
+
}
|
|
1207
|
+
}, React__default.createElement(ui.Typography, {
|
|
1208
|
+
variant: "caption"
|
|
1209
|
+
}, `$${numberToString(inputUsdValue)}`)),
|
|
1210
|
+
value: props.inputAmount || '',
|
|
1211
|
+
onChange: props.type === 'From' ? event => {
|
|
1212
|
+
props.onAmountChange(event.target.value);
|
|
1213
|
+
} : undefined
|
|
1214
|
+
}) : React__default.createElement(OutputContainer, null, React__default.createElement(ui.Typography, {
|
|
1215
|
+
variant: "body1"
|
|
1216
|
+
}, bestRoute ? `≈ ${numberToString(props.outputAmount)}` : inputAmount ? '?' : '0'), React__default.createElement("span", {
|
|
1217
|
+
style: {
|
|
1218
|
+
position: 'absolute',
|
|
1219
|
+
right: '4px',
|
|
1220
|
+
bottom: '2px'
|
|
1221
|
+
}
|
|
1222
|
+
}, React__default.createElement(ui.Typography, {
|
|
1223
|
+
variant: "caption"
|
|
1224
|
+
}, `$${numberToString(props.outputUsdValue)}`))))));
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
const Container$1 = /*#__PURE__*/theme.styled('div', {
|
|
1228
|
+
display: 'flex',
|
|
1229
|
+
width: '100%',
|
|
1230
|
+
justifyContent: 'end',
|
|
1231
|
+
alignItems: 'center',
|
|
1232
|
+
paddingTop: '$16'
|
|
1233
|
+
});
|
|
1234
|
+
const Logo = /*#__PURE__*/theme.styled('svg', {
|
|
1235
|
+
fill: '$foreground',
|
|
1236
|
+
width: '$24',
|
|
1237
|
+
margin: '0 $8 0 $16'
|
|
1238
|
+
});
|
|
1239
|
+
const StyledAnchor = /*#__PURE__*/theme.styled('a', {
|
|
1240
|
+
display: 'flex',
|
|
1241
|
+
justifyContent: 'center',
|
|
1242
|
+
alignItems: 'center',
|
|
1243
|
+
textDecoration: 'none'
|
|
1244
|
+
});
|
|
1245
|
+
function BottomLogo() {
|
|
1246
|
+
return React__default.createElement(Container$1, null, React__default.createElement(ui.Typography, {
|
|
1247
|
+
variant: "caption"
|
|
1248
|
+
}, "Powered By"), React__default.createElement(StyledAnchor, {
|
|
1249
|
+
href: "https://rango.exchange",
|
|
1250
|
+
target: "_blank"
|
|
1251
|
+
}, React__default.createElement(Logo, {
|
|
1252
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1253
|
+
viewBox: "0 0 33.68 29"
|
|
1254
|
+
}, React__default.createElement("defs", null), React__default.createElement("g", {
|
|
1255
|
+
id: "Layer_2",
|
|
1256
|
+
"data-name": "Layer 2"
|
|
1257
|
+
}, React__default.createElement("g", {
|
|
1258
|
+
id: "Layer_1-2",
|
|
1259
|
+
"data-name": "Layer 1"
|
|
1260
|
+
}, React__default.createElement("path", {
|
|
1261
|
+
d: "M33.68,18.05A17.93,17.93,0,0,0,28.34,5.29,18.31,18.31,0,0,0,15.45,0H13.54V7.41L6.07,0H.69L9.83,9.07H0V11A17.93,17.93,0,0,0,5.34,23.71,18.32,18.32,0,0,0,18.24,29h1.9V21.59l7.38,7.31h5.39l-9-9h9.82ZM17.37,16.16H12.49a1.93,1.93,0,0,0-1.35.55,1.89,1.89,0,0,0-.56,1.34,1.85,1.85,0,0,0,.56,1.33,1.93,1.93,0,0,0,1.35.55h3.84V25.1A14.43,14.43,0,0,1,8,21a14.21,14.21,0,0,1-4.1-8.2H21.2a1.86,1.86,0,0,0,.74-.13,1.92,1.92,0,0,0,.64-.4,2,2,0,0,0,.43-.62,1.88,1.88,0,0,0,0-1.47,2,2,0,0,0-.43-.62,1.92,1.92,0,0,0-.64-.4,1.86,1.86,0,0,0-.74-.13H17.35V3.9A14.43,14.43,0,0,1,25.64,8a14.19,14.19,0,0,1,4.11,8.2Zm2.12-5.27a1.43,1.43,0,0,1,.26-.83,1.52,1.52,0,0,1,.67-.56,1.55,1.55,0,0,1,.88-.08,1.51,1.51,0,0,1,.77.4,1.54,1.54,0,0,1,.42.77,1.41,1.41,0,0,1-.09.86,1.47,1.47,0,0,1-.55.68,1.56,1.56,0,0,1-.84.25,1.52,1.52,0,0,1-1.52-1.49Z"
|
|
1262
|
+
}), React__default.createElement("path", {
|
|
1263
|
+
d: "M21.7,11.57a.68.68,0,0,0-.12-.38.64.64,0,0,0-.31-.25.68.68,0,0,0-.75.15.61.61,0,0,0-.19.35.62.62,0,0,0,0,.4.67.67,0,0,0,.25.3.69.69,0,0,0,.39.12.7.7,0,0,0,.49-.2A.68.68,0,0,0,21.7,11.57Z"
|
|
1264
|
+
})))), React__default.createElement(ui.Typography, {
|
|
1265
|
+
variant: "body2"
|
|
1266
|
+
}, "RANGO")));
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
function SwithFromAndTo(_ref) {
|
|
1270
|
+
let {
|
|
1271
|
+
count
|
|
1272
|
+
} = _ref;
|
|
1273
|
+
const firstRender = React.useRef(true);
|
|
1274
|
+
const [searchParams, setSearchParams] = reactRouterDom.useSearchParams();
|
|
1275
|
+
const outputAmount = useBestRouteStore.use.outputAmount();
|
|
1276
|
+
React.useEffect(() => {
|
|
1277
|
+
if (!firstRender.current) {
|
|
1278
|
+
const fromChainString = searchParams.get(SearchParams.FROM_CHAIN);
|
|
1279
|
+
const fromTokenString = searchParams.get(SearchParams.FROM_TOKEN);
|
|
1280
|
+
const toChainString = searchParams.get(SearchParams.TO_CHAIN);
|
|
1281
|
+
const toTokenString = searchParams.get(SearchParams.TO_TOKEN);
|
|
1282
|
+
setSearchParams({
|
|
1283
|
+
...(toChainString && {
|
|
1284
|
+
[SearchParams.FROM_CHAIN]: toChainString
|
|
1285
|
+
}),
|
|
1286
|
+
...(toTokenString && {
|
|
1287
|
+
[SearchParams.FROM_TOKEN]: toTokenString
|
|
1288
|
+
}),
|
|
1289
|
+
...(fromChainString && {
|
|
1290
|
+
[SearchParams.TO_CHAIN]: fromChainString
|
|
1291
|
+
}),
|
|
1292
|
+
...(fromTokenString && {
|
|
1293
|
+
[SearchParams.TO_TOKEN]: fromTokenString
|
|
1294
|
+
}),
|
|
1295
|
+
...(outputAmount && {
|
|
1296
|
+
[SearchParams.FROM_AMOUNT]: outputAmount.toString()
|
|
1297
|
+
})
|
|
1298
|
+
});
|
|
1299
|
+
} else {
|
|
1300
|
+
firstRender.current = false;
|
|
1301
|
+
}
|
|
1302
|
+
}, [count]);
|
|
1303
|
+
return null;
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
const Footer = /*#__PURE__*/ui.styled('div', {
|
|
1307
|
+
display: 'flex',
|
|
1308
|
+
flexDirection: 'column',
|
|
1309
|
+
width: '100%',
|
|
1310
|
+
paddingTop: '$16'
|
|
1311
|
+
});
|
|
1312
|
+
|
|
1313
|
+
const errorMessages = {
|
|
1314
|
+
genericServerError: 'Error connecting server, please reload the app and try again'
|
|
1315
|
+
};
|
|
1316
|
+
|
|
1317
|
+
const Container$2 = /*#__PURE__*/ui.styled('div', {
|
|
1318
|
+
display: 'flex',
|
|
1319
|
+
flexDirection: 'column',
|
|
1320
|
+
justifyContent: 'center',
|
|
1321
|
+
alignItems: 'center'
|
|
1322
|
+
});
|
|
1323
|
+
const SwitchButtonContainer = /*#__PURE__*/ui.styled('div', {
|
|
1324
|
+
display: 'flex',
|
|
1325
|
+
justifyContent: 'center',
|
|
1326
|
+
alignItems: 'center',
|
|
1327
|
+
position: 'relative',
|
|
1328
|
+
top: '11px'
|
|
1329
|
+
});
|
|
1330
|
+
const BestRouteContainer = /*#__PURE__*/ui.styled('div', {
|
|
1331
|
+
width: '100%',
|
|
1332
|
+
paddingTop: '$16'
|
|
1333
|
+
});
|
|
1334
|
+
const Alerts = /*#__PURE__*/ui.styled('div', {
|
|
1335
|
+
width: '100%',
|
|
1336
|
+
paddingTop: '$16'
|
|
1337
|
+
});
|
|
1338
|
+
function Home() {
|
|
1339
|
+
const waningMessage = '';
|
|
1340
|
+
const isRouterInContext = reactRouterDom.useInRouterContext();
|
|
1341
|
+
const navigate = reactRouterDom.useNavigate();
|
|
1342
|
+
const [count, setCount] = React.useState(0);
|
|
1343
|
+
const fromChain = useBestRouteStore.use.fromChain();
|
|
1344
|
+
const fromToken = useBestRouteStore.use.fromToken();
|
|
1345
|
+
const toChain = useBestRouteStore.use.toChain();
|
|
1346
|
+
const toToken = useBestRouteStore.use.toToken();
|
|
1347
|
+
const setFromChain = useBestRouteStore.use.setFromChain();
|
|
1348
|
+
const setFromToken = useBestRouteStore.use.setFromToken();
|
|
1349
|
+
const setToChain = useBestRouteStore.use.setToChain();
|
|
1350
|
+
const setToToken = useBestRouteStore.use.setToToken();
|
|
1351
|
+
const inputUsdValue = useBestRouteStore.use.inputUsdValue();
|
|
1352
|
+
const inputAmount = useBestRouteStore.use.inputAmount();
|
|
1353
|
+
const setInputAmount = useBestRouteStore.use.setInputAmount();
|
|
1354
|
+
const outputAmount = useBestRouteStore.use.outputAmount();
|
|
1355
|
+
const outputUsdValue = useBestRouteStore.use.outputUsdValue();
|
|
1356
|
+
const bestRoute = useBestRouteStore.use.bestRoute();
|
|
1357
|
+
const tokens = useMetaStore.use.meta().tokens;
|
|
1358
|
+
const fetchingBestRoute = useBestRouteStore.use.loading();
|
|
1359
|
+
const bestRouteError = useBestRouteStore.use.error();
|
|
1360
|
+
const loadingMetaStatus = useMetaStore.use.loadingStatus();
|
|
1361
|
+
const accounts = useWalletsStore.use.accounts();
|
|
1362
|
+
const swithFromAndTo = () => {
|
|
1363
|
+
setFromChain(toChain);
|
|
1364
|
+
setFromToken(toToken);
|
|
1365
|
+
setToChain(fromChain);
|
|
1366
|
+
setToToken(fromToken);
|
|
1367
|
+
setInputAmount(outputAmount?.toString() || '');
|
|
1368
|
+
setCount(prev => prev + 1);
|
|
1369
|
+
};
|
|
1370
|
+
const errorMessage = loadingMetaStatus === 'failed' ? errorMessages.genericServerError : bestRouteError;
|
|
1371
|
+
const needsToWarnEthOnPath = false;
|
|
1372
|
+
const showBestRoute = inputAmount && (!!bestRoute || fetchingBestRoute || bestRouteError);
|
|
1373
|
+
const outToInRatio = getOutputRatio(inputUsdValue, outputUsdValue);
|
|
1374
|
+
const highValueLoss = outputRatioHasWarning(inputUsdValue, outToInRatio);
|
|
1375
|
+
const {
|
|
1376
|
+
fromAmountRangeError,
|
|
1377
|
+
recommendation,
|
|
1378
|
+
swap
|
|
1379
|
+
} = LimitErrorMessage(bestRoute);
|
|
1380
|
+
const priceImpactCanNotBeComputed = !canComputePriceImpact(bestRoute, inputAmount, inputUsdValue, outputUsdValue);
|
|
1381
|
+
const swapButtonState = getSwapButtonState(loadingMetaStatus, accounts, fetchingBestRoute, bestRoute, hasLimitError(bestRoute), highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath);
|
|
1382
|
+
const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
|
|
1383
|
+
const highFee = hasHighFee(totalFeeInUsd);
|
|
1384
|
+
return React__default.createElement(Container$2, null, React__default.createElement(Header, {
|
|
1385
|
+
onClickRefresh: fetchBestRoute
|
|
1386
|
+
}), React__default.createElement(TokenInfo, {
|
|
1387
|
+
type: "From",
|
|
1388
|
+
chain: fromChain,
|
|
1389
|
+
token: fromToken,
|
|
1390
|
+
onAmountChange: setInputAmount,
|
|
1391
|
+
inputAmount: inputAmount
|
|
1392
|
+
}), React__default.createElement(SwitchButtonContainer, null, React__default.createElement(ui.Button, {
|
|
1393
|
+
variant: "ghost",
|
|
1394
|
+
onClick: swithFromAndTo
|
|
1395
|
+
}, React__default.createElement(ui.VerticalSwapIcon, {
|
|
1396
|
+
size: 36
|
|
1397
|
+
}), isRouterInContext && React__default.createElement(SwithFromAndTo, {
|
|
1398
|
+
count: count
|
|
1399
|
+
}))), React__default.createElement(TokenInfo, {
|
|
1400
|
+
type: "To",
|
|
1401
|
+
chain: toChain,
|
|
1402
|
+
token: toToken,
|
|
1403
|
+
outputAmount: outputAmount,
|
|
1404
|
+
outputUsdValue: outputUsdValue
|
|
1405
|
+
}), showBestRoute && React__default.createElement(BestRouteContainer, null, React__default.createElement(ui.BestRoute, {
|
|
1406
|
+
error: bestRouteError,
|
|
1407
|
+
loading: fetchingBestRoute,
|
|
1408
|
+
data: bestRoute,
|
|
1409
|
+
totalFee: numberToString(totalFeeInUsd, 0, 2),
|
|
1410
|
+
feeWarning: highFee,
|
|
1411
|
+
totalTime: secondsToString(totalArrivalTime(bestRoute))
|
|
1412
|
+
})), (errorMessage || waningMessage || hasLimitError(bestRoute)) && React__default.createElement(Alerts, null, errorMessage && React__default.createElement(ui.Alert, {
|
|
1413
|
+
type: "error"
|
|
1414
|
+
}, React__default.createElement(ui.Typography, {
|
|
1415
|
+
variant: "body2"
|
|
1416
|
+
}, errorMessage)), hasLimitError(bestRoute) && React__default.createElement(ui.Alert, {
|
|
1417
|
+
type: "error",
|
|
1418
|
+
title: `${swap?.swapperId} Limit`
|
|
1419
|
+
}, React__default.createElement(React__default.Fragment, null, React__default.createElement(ui.Typography, {
|
|
1420
|
+
variant: "body2"
|
|
1421
|
+
}, fromAmountRangeError), React__default.createElement("br", null), React__default.createElement(ui.Typography, {
|
|
1422
|
+
variant: "body2"
|
|
1423
|
+
}, "Yours: ", numberToString(swap?.fromAmount || null), swap?.from.symbol), React__default.createElement("br", null), React__default.createElement(ui.Typography, {
|
|
1424
|
+
variant: "body2"
|
|
1425
|
+
}, recommendation))), waningMessage ), React__default.createElement(Footer, null, React__default.createElement(ui.Button, {
|
|
1426
|
+
type: "primary",
|
|
1427
|
+
align: "grow",
|
|
1428
|
+
size: "large",
|
|
1429
|
+
disabled: swapButtonState.disabled,
|
|
1430
|
+
onClick: () => {
|
|
1431
|
+
if (swapButtonState.title === 'Connect Wallet') navigate(navigationRoutes.wallets);else {
|
|
1432
|
+
navigate(navigationRoutes.confirmWallets);
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
}, swapButtonState.title), React__default.createElement(BottomLogo, null)));
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
const Route = props => {
|
|
1439
|
+
const location = reactRouter.useLocation();
|
|
1440
|
+
const navigate = reactRouter.useNavigate();
|
|
1441
|
+
const ref = React.useRef(true);
|
|
1442
|
+
React.useEffect(() => {
|
|
1443
|
+
if ([navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname) && ref.current) navigate(navigationRoutes.home + location.search, {
|
|
1444
|
+
state: 'redirect'
|
|
1445
|
+
});
|
|
1446
|
+
ref.current = false;
|
|
1447
|
+
}, []);
|
|
1448
|
+
if ([navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname) && ref.current) return React__default.createElement(Home, null);
|
|
1449
|
+
return React__default.createElement(React__default.Fragment, null, " ", props.children);
|
|
1450
|
+
};
|
|
1451
|
+
function AppRouter(_ref) {
|
|
1452
|
+
let {
|
|
1453
|
+
children
|
|
1454
|
+
} = _ref;
|
|
1455
|
+
const isRouterInContext = reactRouter.useInRouterContext();
|
|
1456
|
+
const Router = isRouterInContext ? Route : reactRouter.MemoryRouter;
|
|
1457
|
+
return React__default.createElement(React__default.Fragment, null, React__default.createElement(Router, null, children), isRouterInContext && React__default.createElement(UpdateUrl, null));
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
const useUiStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()(set => ({
|
|
1461
|
+
connectWalletsButtonDisabled: false,
|
|
1462
|
+
toggleConnectWalletsButton: () => set(state => ({
|
|
1463
|
+
connectWalletsButtonDisabled: !state.connectWalletsButtonDisabled
|
|
1464
|
+
}))
|
|
1465
|
+
})));
|
|
1466
|
+
|
|
1467
|
+
const StyledButton = /*#__PURE__*/ui.styled(ui.Button, {
|
|
1468
|
+
marginTop: '$8'
|
|
1469
|
+
});
|
|
1470
|
+
function ChangeSlippageButton() {
|
|
1471
|
+
const navigate = reactRouterDom.useNavigate();
|
|
1472
|
+
return React__default.createElement(StyledButton, {
|
|
1473
|
+
type: "primary",
|
|
1474
|
+
variant: "contained",
|
|
1475
|
+
size: "small",
|
|
1476
|
+
onClick: navigate.bind(null, navigationRoutes.settings)
|
|
1477
|
+
}, "Change Slippage");
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
function HighSlippageWarning(props) {
|
|
1481
|
+
const {
|
|
1482
|
+
selectedSlippage
|
|
1483
|
+
} = props;
|
|
1484
|
+
return React__default.createElement(ui.Alert, {
|
|
1485
|
+
type: "warning"
|
|
1486
|
+
}, React__default.createElement(ui.Typography, {
|
|
1487
|
+
variant: "body2"
|
|
1488
|
+
}, "slippage is high=> Caution, your slippage is high (=", selectedSlippage, "). Your trade may be front run.", React__default.createElement(ChangeSlippageButton, null)));
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
function ConfirmSwapExtraMessages(props) {
|
|
1492
|
+
const {
|
|
1493
|
+
selectedSlippage
|
|
1494
|
+
} = props;
|
|
1495
|
+
const highSlippage = selectedSlippage >= HIGH_SLIPPAGE;
|
|
1496
|
+
return React__default.createElement(React__default.Fragment, null, highSlippage && React__default.createElement(HighSlippageWarning, {
|
|
1497
|
+
selectedSlippage: selectedSlippage
|
|
1498
|
+
}));
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
function useNavigateBack() {
|
|
1502
|
+
const isRouterInContext = reactRouterDom.useInRouterContext();
|
|
1503
|
+
const navigate = reactRouterDom.useNavigate();
|
|
1504
|
+
const navigateBackFrom = currentRoute => {
|
|
1505
|
+
if (!isRouterInContext || window.history.state && window.history.state.idx > 0) navigate(-1);else {
|
|
1506
|
+
if ([navigationRoutes.fromChain, navigationRoutes.fromToken, navigationRoutes.toChain, navigationRoutes.toToken, navigationRoutes.settings, navigationRoutes.wallets, navigationRoutes.history].includes(currentRoute)) navigate(navigationRoutes.home, {
|
|
1507
|
+
replace: true
|
|
1508
|
+
});else if (currentRoute === navigationRoutes.liquiditySources) {
|
|
1509
|
+
navigate(navigationRoutes.settings, {
|
|
1510
|
+
replace: true
|
|
1511
|
+
});
|
|
1512
|
+
} else if (currentRoute === navigationRoutes.swapDetails) navigate(navigationRoutes.history, {
|
|
1513
|
+
replace: true
|
|
1514
|
+
});
|
|
1515
|
+
}
|
|
1516
|
+
};
|
|
1517
|
+
return {
|
|
1518
|
+
navigateBackFrom
|
|
1519
|
+
};
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
const useConfirmSwapStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/middleware.subscribeWithSelector(() => ({
|
|
1523
|
+
loading: false,
|
|
1524
|
+
errors: [],
|
|
1525
|
+
warnings: [],
|
|
1526
|
+
proceedAnyway: false
|
|
1527
|
+
}))));
|
|
1528
|
+
var ConfirmSwapErrorTypes;
|
|
1529
|
+
(function (ConfirmSwapErrorTypes) {
|
|
1530
|
+
ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["NO_ROUTE"] = 0] = "NO_ROUTE";
|
|
1531
|
+
ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS"] = 1] = "ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS";
|
|
1532
|
+
ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["REQUEST_FAILED"] = 2] = "REQUEST_FAILED";
|
|
1533
|
+
ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["INSUFFICIENT_SLIPPAGE"] = 3] = "INSUFFICIENT_SLIPPAGE";
|
|
1534
|
+
})(ConfirmSwapErrorTypes || (ConfirmSwapErrorTypes = {}));
|
|
1535
|
+
var ConfirmSwapWarningTypes;
|
|
1536
|
+
(function (ConfirmSwapWarningTypes) {
|
|
1537
|
+
ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_UPDATED"] = 0] = "ROUTE_UPDATED";
|
|
1538
|
+
ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_SWAPPERS_UPDATED"] = 1] = "ROUTE_SWAPPERS_UPDATED";
|
|
1539
|
+
ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_COINS_UPDATED"] = 2] = "ROUTE_COINS_UPDATED";
|
|
1540
|
+
ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_AND_OUTPUT_AMOUNT_UPDATED"] = 3] = "ROUTE_AND_OUTPUT_AMOUNT_UPDATED";
|
|
1541
|
+
ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["INSUFFICIENT_BALANCE"] = 4] = "INSUFFICIENT_BALANCE";
|
|
1542
|
+
})(ConfirmSwapWarningTypes || (ConfirmSwapWarningTypes = {}));
|
|
1543
|
+
const confirmSwap = () => {
|
|
1544
|
+
const {
|
|
1545
|
+
fromToken,
|
|
1546
|
+
toToken,
|
|
1547
|
+
inputAmount,
|
|
1548
|
+
bestRoute: initialRoute,
|
|
1549
|
+
inputUsdValue,
|
|
1550
|
+
setBestRoute
|
|
1551
|
+
} = useBestRouteStore.getState();
|
|
1552
|
+
const {
|
|
1553
|
+
accounts,
|
|
1554
|
+
selectedWallets
|
|
1555
|
+
} = useWalletsStore.getState();
|
|
1556
|
+
const {
|
|
1557
|
+
proceedAnyway
|
|
1558
|
+
} = useConfirmSwapStore.getState();
|
|
1559
|
+
const {
|
|
1560
|
+
disabledLiquiditySources,
|
|
1561
|
+
slippage,
|
|
1562
|
+
customSlippage
|
|
1563
|
+
} = useSettingsStore.getState();
|
|
1564
|
+
const {
|
|
1565
|
+
meta
|
|
1566
|
+
} = useMetaStore.getState();
|
|
1567
|
+
const userSlippage = customSlippage || slippage;
|
|
1568
|
+
if (!fromToken || !toToken || !inputAmount || !initialRoute) return;
|
|
1569
|
+
if (proceedAnyway) {
|
|
1570
|
+
const swapSettings = {
|
|
1571
|
+
slippage: userSlippage.toString(),
|
|
1572
|
+
disabledSwappersGroups: disabledLiquiditySources
|
|
1573
|
+
};
|
|
1574
|
+
const newSwap = calculatePendingSwap(inputAmount.toString(), initialRoute, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
|
|
1575
|
+
console.log('new swap:', newSwap);
|
|
1576
|
+
return useConfirmSwapStore.setState({
|
|
1577
|
+
errors: [],
|
|
1578
|
+
warnings: [],
|
|
1579
|
+
proceedAnyway: false
|
|
1580
|
+
});
|
|
1581
|
+
}
|
|
1582
|
+
let abortController = new AbortController();
|
|
1583
|
+
useConfirmSwapStore.setState({
|
|
1584
|
+
loading: true
|
|
1585
|
+
});
|
|
1586
|
+
const requestBody = createBestRouteRequestBody(fromToken, toToken, inputAmount, accounts, selectedWallets, disabledLiquiditySources, userSlippage, true);
|
|
1587
|
+
const unsubscribeFromBestRouteStore = useBestRouteStore.subscribe(state => state.bestRoute, () => {
|
|
1588
|
+
abortController.abort();
|
|
1589
|
+
}, {
|
|
1590
|
+
equalityFn: shallow.shallow
|
|
1591
|
+
});
|
|
1592
|
+
const unsubscribeFromWalletsStore = useWalletsStore.subscribe(state => state.selectedWallets, () => {
|
|
1593
|
+
abortController?.abort();
|
|
1594
|
+
}, {
|
|
1595
|
+
equalityFn: (prevState, state) => {
|
|
1596
|
+
const selectedWalletsChanged = !state.every(wallet => !!prevState.find(prevWallet => wallet.address === prevWallet.address && wallet.chain === prevWallet.chain));
|
|
1597
|
+
if (selectedWalletsChanged) return false;else return true;
|
|
1598
|
+
}
|
|
1599
|
+
});
|
|
1600
|
+
httpService.getBestRoute(requestBody, {
|
|
1601
|
+
signal: abortController.signal
|
|
1602
|
+
}).then(confiremedRoute => {
|
|
1603
|
+
useConfirmSwapStore.setState({
|
|
1604
|
+
loading: false
|
|
1605
|
+
});
|
|
1606
|
+
if (!confiremedRoute.result || !new BigNumber__default(confiremedRoute.requestAmount).isEqualTo(new BigNumber__default(inputAmount || '-1'))) return useConfirmSwapStore.setState(prevState => ({
|
|
1607
|
+
errors: prevState.errors.concat({
|
|
1608
|
+
type: ConfirmSwapErrorTypes.NO_ROUTE
|
|
1609
|
+
})
|
|
1610
|
+
}));
|
|
1611
|
+
const confirmSwap = {
|
|
1612
|
+
loading: false,
|
|
1613
|
+
errors: [],
|
|
1614
|
+
warnings: [],
|
|
1615
|
+
proceedAnyway
|
|
1616
|
+
};
|
|
1617
|
+
const routeChanged = isRouteChanged(initialRoute, confiremedRoute);
|
|
1618
|
+
if (routeChanged) {
|
|
1619
|
+
setBestRoute(confiremedRoute);
|
|
1620
|
+
const newRouteOutputUsdValue = new BigNumber__default(confiremedRoute.result?.outputAmount || '0').multipliedBy(toToken.usdPrice || 0);
|
|
1621
|
+
const outputRatio = getOutputRatio(inputUsdValue, newRouteOutputUsdValue);
|
|
1622
|
+
const highValueLoss = outputRatioHasWarning(inputUsdValue, outputRatio);
|
|
1623
|
+
if (isNumberOfSwapsChanged(initialRoute, confiremedRoute)) confirmSwap.warnings.push({
|
|
1624
|
+
type: ConfirmSwapWarningTypes.ROUTE_UPDATED
|
|
1625
|
+
});else if (isRouteSwappersUpdated(initialRoute, confiremedRoute)) confirmSwap.warnings.push({
|
|
1626
|
+
type: ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED
|
|
1627
|
+
});else isRouteInternalCoinsUpdated(initialRoute, confiremedRoute);
|
|
1628
|
+
confirmSwap.warnings.push({
|
|
1629
|
+
type: ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED
|
|
1630
|
+
});
|
|
1631
|
+
if (highValueLoss) confirmSwap.errors.push({
|
|
1632
|
+
type: ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS
|
|
1633
|
+
});else if (isOutputAmountChangedALot(initialRoute, confiremedRoute)) confirmSwap.warnings.push({
|
|
1634
|
+
type: ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED,
|
|
1635
|
+
newOutputAmount: numberToString(getRouteOutputAmount(confiremedRoute)),
|
|
1636
|
+
percentageChange: numberToString(getPercentageChange(getRouteOutputAmount(initialRoute), getRouteOutputAmount(confiremedRoute)), null, 2)
|
|
1637
|
+
});
|
|
1638
|
+
}
|
|
1639
|
+
const balanceWarnings = getBalanceWarnings(confiremedRoute, selectedWallets);
|
|
1640
|
+
const enoughBalance = balanceWarnings.length === 0;
|
|
1641
|
+
if (!enoughBalance) confirmSwap.warnings.push({
|
|
1642
|
+
type: ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE,
|
|
1643
|
+
messages: balanceWarnings
|
|
1644
|
+
});
|
|
1645
|
+
const minRequiredSlippage = getMinRequiredSlippage(initialRoute);
|
|
1646
|
+
if (!hasProperSlippage(userSlippage.toString(), minRequiredSlippage)) confirmSwap.errors.push({
|
|
1647
|
+
type: ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE,
|
|
1648
|
+
minRequiredSlippage
|
|
1649
|
+
});
|
|
1650
|
+
const noErrors = confirmSwap.errors.length === 0;
|
|
1651
|
+
const noWarnings = confirmSwap.warnings.length === 0;
|
|
1652
|
+
if ((noErrors || !noErrors && proceedAnyway) && (noWarnings || !noWarnings && proceedAnyway)) {
|
|
1653
|
+
const swapSettings = {
|
|
1654
|
+
slippage: userSlippage.toString(),
|
|
1655
|
+
disabledSwappersGroups: disabledLiquiditySources
|
|
1656
|
+
};
|
|
1657
|
+
const newSwap = calculatePendingSwap(inputAmount.toString(), initialRoute, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
|
|
1658
|
+
console.log('new swap:', newSwap);
|
|
1659
|
+
} else if (!proceedAnyway) confirmSwap.proceedAnyway = true;
|
|
1660
|
+
abortController = null;
|
|
1661
|
+
useConfirmSwapStore.setState(confirmSwap);
|
|
1662
|
+
unsubscribeFromBestRouteStore();
|
|
1663
|
+
unsubscribeFromWalletsStore();
|
|
1664
|
+
}).catch(error => {
|
|
1665
|
+
abortController = null;
|
|
1666
|
+
if (error.code === 'ERR_CANCELED') {
|
|
1667
|
+
useConfirmSwapStore.setState({
|
|
1668
|
+
errors: [],
|
|
1669
|
+
warnings: [],
|
|
1670
|
+
loading: false,
|
|
1671
|
+
proceedAnyway: false
|
|
1672
|
+
});
|
|
1673
|
+
unsubscribeFromBestRouteStore();
|
|
1674
|
+
unsubscribeFromWalletsStore();
|
|
1675
|
+
}
|
|
1676
|
+
const status = error.response?.status;
|
|
1677
|
+
useConfirmSwapStore.setState(prevState => ({
|
|
1678
|
+
loading: false,
|
|
1679
|
+
errors: prevState.errors.concat({
|
|
1680
|
+
type: ConfirmSwapErrorTypes.REQUEST_FAILED,
|
|
1681
|
+
status
|
|
1682
|
+
})
|
|
1683
|
+
}));
|
|
1684
|
+
});
|
|
1685
|
+
};
|
|
1686
|
+
|
|
1687
|
+
function MinRequiredSlippage(_ref) {
|
|
1688
|
+
let {
|
|
1689
|
+
minRequiredSlippage
|
|
1690
|
+
} = _ref;
|
|
1691
|
+
return React__default.createElement(ui.Typography, {
|
|
1692
|
+
variant: "body2"
|
|
1693
|
+
}, "slippage is low => We recommend you to increase slippage to at least", minRequiredSlippage, "for this route.", React__default.createElement(ChangeSlippageButton, null));
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
function ConfirmSwapErrors(errors) {
|
|
1697
|
+
return errors.flatMap(error => {
|
|
1698
|
+
switch (error.type) {
|
|
1699
|
+
case ConfirmSwapErrorTypes.NO_ROUTE:
|
|
1700
|
+
return React__default.createElement(ui.Typography, {
|
|
1701
|
+
variant: "body2"
|
|
1702
|
+
}, "No routes found. Please try again later.");
|
|
1703
|
+
case ConfirmSwapErrorTypes.REQUEST_FAILED:
|
|
1704
|
+
return React__default.createElement(ui.Typography, {
|
|
1705
|
+
variant: "body2"
|
|
1706
|
+
}, `Failed to confirm swap ${error.status ? `'status': ${error.status})` : ''}, please try again.`);
|
|
1707
|
+
case ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS:
|
|
1708
|
+
return React__default.createElement(ui.Typography, {
|
|
1709
|
+
variant: "body2"
|
|
1710
|
+
}, "Route updated and price impact is too high, try again later!");
|
|
1711
|
+
case ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE:
|
|
1712
|
+
return React__default.createElement(MinRequiredSlippage, {
|
|
1713
|
+
minRequiredSlippage: error.minRequiredSlippage
|
|
1714
|
+
});
|
|
1715
|
+
default:
|
|
1716
|
+
return [];
|
|
1717
|
+
}
|
|
1718
|
+
});
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
function BalanceWarnings(_ref) {
|
|
1722
|
+
let {
|
|
1723
|
+
messages
|
|
1724
|
+
} = _ref;
|
|
1725
|
+
return React__default.createElement("div", null, messages.map(warning => React__default.createElement(ui.Typography, {
|
|
1726
|
+
variant: "body2"
|
|
1727
|
+
}, warning)));
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1730
|
+
function ConfirmSwapWarnings(warnings) {
|
|
1731
|
+
return warnings.flatMap(warning => {
|
|
1732
|
+
switch (warning.type) {
|
|
1733
|
+
case ConfirmSwapWarningTypes.ROUTE_UPDATED:
|
|
1734
|
+
return React__default.createElement(ui.Typography, {
|
|
1735
|
+
variant: "body2"
|
|
1736
|
+
}, "Route has been updated.");
|
|
1737
|
+
case ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED:
|
|
1738
|
+
return React__default.createElement(ui.Typography, {
|
|
1739
|
+
variant: "body2"
|
|
1740
|
+
}, `Output amount changed to ${warning.newOutputAmount}
|
|
1741
|
+
(${warning.percentageChange}% change).`);
|
|
1742
|
+
case ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED:
|
|
1743
|
+
return React__default.createElement(ui.Typography, {
|
|
1744
|
+
variant: "body2"
|
|
1745
|
+
}, "Route swappers has been updated.");
|
|
1746
|
+
case ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED:
|
|
1747
|
+
return React__default.createElement(ui.Typography, {
|
|
1748
|
+
variant: "body2"
|
|
1749
|
+
}, "Route internal coins has been updated.");
|
|
1750
|
+
case ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE:
|
|
1751
|
+
return React__default.createElement(BalanceWarnings, {
|
|
1752
|
+
messages: warning.messages
|
|
1753
|
+
});
|
|
1754
|
+
default:
|
|
1755
|
+
return [];
|
|
1756
|
+
}
|
|
1757
|
+
});
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
function ConfirmSwapPage() {
|
|
1761
|
+
const {
|
|
1762
|
+
navigateBackFrom
|
|
1763
|
+
} = useNavigateBack();
|
|
1764
|
+
const bestRoute = useBestRouteStore.use.bestRoute();
|
|
1765
|
+
const loading = useConfirmSwapStore.use.loading();
|
|
1766
|
+
const warnings = useConfirmSwapStore.use.warnings();
|
|
1767
|
+
const errors = useConfirmSwapStore.use.errors();
|
|
1768
|
+
console.log('loading:', loading, 'warnings:', warnings, 'errors:', errors);
|
|
1769
|
+
const slippage = useSettingsStore.use.slippage();
|
|
1770
|
+
const customSlippage = useSettingsStore.use.customSlippage();
|
|
1771
|
+
const selectedSlippage = customSlippage || slippage;
|
|
1772
|
+
return React__default.createElement(ui.ConfirmSwap, {
|
|
1773
|
+
onConfirm: confirmSwap.bind(null),
|
|
1774
|
+
onBack: navigateBackFrom.bind(null, navigationRoutes.confirmSwap),
|
|
1775
|
+
bestRoute: bestRoute,
|
|
1776
|
+
loading: loading,
|
|
1777
|
+
errors: ConfirmSwapErrors(errors),
|
|
1778
|
+
warnings: ConfirmSwapWarnings(warnings),
|
|
1779
|
+
extraMessages: React__default.createElement(ConfirmSwapExtraMessages, {
|
|
1780
|
+
selectedSlippage: selectedSlippage
|
|
1781
|
+
}),
|
|
1782
|
+
confirmButtonTitle: warnings.length > 0 || errors.length > 0 ? 'Proceed anyway!' : 'Confirm swap!',
|
|
1783
|
+
confirmButtonDisabled: errors.length > 0
|
|
1784
|
+
});
|
|
1785
|
+
}
|
|
1786
|
+
|
|
1787
|
+
const pendingSwap = [{
|
|
1114
1788
|
creationTime: '1673164511955',
|
|
1115
1789
|
finishTime: '1673164550137',
|
|
1116
1790
|
requestId: '51e211d9-d61c-45d2-a4d4-1f9f7f90ee85',
|
|
@@ -1121,7 +1795,7 @@ const pendingSwap = [{
|
|
|
1121
1795
|
address: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl'
|
|
1122
1796
|
}
|
|
1123
1797
|
},
|
|
1124
|
-
status: '
|
|
1798
|
+
status: 'running',
|
|
1125
1799
|
isPaused: false,
|
|
1126
1800
|
extraMessage: null,
|
|
1127
1801
|
extraMessageSeverity: 'info',
|
|
@@ -1139,10 +1813,10 @@ const pendingSwap = [{
|
|
|
1139
1813
|
outputAmount: '1.540670',
|
|
1140
1814
|
swaps: [{
|
|
1141
1815
|
swapperId: 'Osmosis',
|
|
1816
|
+
swapperType: 'DEX',
|
|
1142
1817
|
swapperLogo: '',
|
|
1143
1818
|
// @ts-ignore
|
|
1144
1819
|
result: null,
|
|
1145
|
-
swapperType: 'DEX',
|
|
1146
1820
|
from: {
|
|
1147
1821
|
symbol: 'JUNO',
|
|
1148
1822
|
logo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png',
|
|
@@ -1241,12 +1915,12 @@ const pendingSwap = [{
|
|
|
1241
1915
|
fromDecimals: 6,
|
|
1242
1916
|
fromAmountPrecision: null,
|
|
1243
1917
|
fromAmountMinValue: null,
|
|
1918
|
+
swapperLogo: '',
|
|
1919
|
+
swapperType: '',
|
|
1244
1920
|
fromAmountMaxValue: null,
|
|
1245
1921
|
toBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png',
|
|
1246
1922
|
fromBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png',
|
|
1247
1923
|
toBlockchain: 'OSMOSIS',
|
|
1248
|
-
swapperLogo: '',
|
|
1249
|
-
swapperType: '',
|
|
1250
1924
|
fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png',
|
|
1251
1925
|
toSymbol: 'OSMO',
|
|
1252
1926
|
toSymbolAddress: null,
|
|
@@ -1256,7 +1930,7 @@ const pendingSwap = [{
|
|
|
1256
1930
|
swapperId: 'Osmosis',
|
|
1257
1931
|
expectedOutputAmountHumanReadable: '1.540670',
|
|
1258
1932
|
outputAmount: '1.540658',
|
|
1259
|
-
status: '
|
|
1933
|
+
status: 'running',
|
|
1260
1934
|
networkStatus: null,
|
|
1261
1935
|
executedTransactionId: '0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b',
|
|
1262
1936
|
explorerUrl: [{
|
|
@@ -1329,7 +2003,7 @@ const pendingSwap = [{
|
|
|
1329
2003
|
address: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl'
|
|
1330
2004
|
}
|
|
1331
2005
|
},
|
|
1332
|
-
status: '
|
|
2006
|
+
status: 'failed',
|
|
1333
2007
|
isPaused: false,
|
|
1334
2008
|
extraMessage: null,
|
|
1335
2009
|
extraMessageSeverity: 'info',
|
|
@@ -1346,11 +2020,11 @@ const pendingSwap = [{
|
|
|
1346
2020
|
simulationResult: {
|
|
1347
2021
|
outputAmount: '1.540670',
|
|
1348
2022
|
swaps: [{
|
|
1349
|
-
// @ts-ignore
|
|
1350
|
-
result: [],
|
|
1351
2023
|
swapperId: 'Osmosis',
|
|
1352
|
-
swapperType: 'DEX',
|
|
1353
2024
|
swapperLogo: '',
|
|
2025
|
+
// @ts-ignore
|
|
2026
|
+
result: null,
|
|
2027
|
+
swapperType: 'DEX',
|
|
1354
2028
|
from: {
|
|
1355
2029
|
symbol: 'JUNO',
|
|
1356
2030
|
logo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png',
|
|
@@ -1449,12 +2123,12 @@ const pendingSwap = [{
|
|
|
1449
2123
|
fromDecimals: 6,
|
|
1450
2124
|
fromAmountPrecision: null,
|
|
1451
2125
|
fromAmountMinValue: null,
|
|
1452
|
-
swapperLogo: '',
|
|
1453
|
-
swapperType: '',
|
|
1454
2126
|
fromAmountMaxValue: null,
|
|
1455
2127
|
toBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png',
|
|
1456
2128
|
fromBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png',
|
|
1457
2129
|
toBlockchain: 'OSMOSIS',
|
|
2130
|
+
swapperLogo: '',
|
|
2131
|
+
swapperType: '',
|
|
1458
2132
|
fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png',
|
|
1459
2133
|
toSymbol: 'OSMO',
|
|
1460
2134
|
toSymbolAddress: null,
|
|
@@ -1464,543 +2138,287 @@ const pendingSwap = [{
|
|
|
1464
2138
|
swapperId: 'Osmosis',
|
|
1465
2139
|
expectedOutputAmountHumanReadable: '1.540670',
|
|
1466
2140
|
outputAmount: '1.540658',
|
|
1467
|
-
status: '
|
|
2141
|
+
status: 'failed',
|
|
1468
2142
|
networkStatus: null,
|
|
1469
2143
|
executedTransactionId: '0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b',
|
|
1470
2144
|
explorerUrl: [{
|
|
1471
2145
|
url: 'https://www.mintscan.io/osmosis/txs/0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b',
|
|
1472
2146
|
description: null
|
|
1473
|
-
}],
|
|
1474
|
-
cosmosTransaction: {
|
|
1475
|
-
type: rangoSdk.TransactionType.COSMOS,
|
|
1476
|
-
fromWalletAddress: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl',
|
|
1477
|
-
blockChain: 'OSMOSIS',
|
|
1478
|
-
data: {
|
|
1479
|
-
chainId: 'osmosis-1',
|
|
1480
|
-
account_number: 102721,
|
|
1481
|
-
sequence: '308',
|
|
1482
|
-
msgs: [{
|
|
1483
|
-
__type: 'OsmosisSwapMessage',
|
|
1484
|
-
type: 'osmosis/gamm/swap-exact-amount-in',
|
|
1485
|
-
value: {
|
|
1486
|
-
sender: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl',
|
|
1487
|
-
routes: [{
|
|
1488
|
-
pool_id: '498',
|
|
1489
|
-
token_out_denom: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2'
|
|
1490
|
-
}, {
|
|
1491
|
-
pool_id: '8',
|
|
1492
|
-
token_out_denom: 'ibc/7C4D60AA95E5A7558B0A364860979CA34B7FF8AAF255B87AF9E879374470CEC0'
|
|
1493
|
-
}, {
|
|
1494
|
-
pool_id: '7',
|
|
1495
|
-
token_out_denom: 'uosmo'
|
|
1496
|
-
}],
|
|
1497
|
-
token_in: {
|
|
1498
|
-
denom: 'ibc/46B44899322F3CD854D2D46DEEF881958467CDD4B3B10086DA49296BBED94BED',
|
|
1499
|
-
amount: '1000000'
|
|
1500
|
-
},
|
|
1501
|
-
token_out_min_amount: '1525264'
|
|
1502
|
-
}
|
|
1503
|
-
}],
|
|
1504
|
-
protoMsgs: [{
|
|
1505
|
-
type_url: '/osmosis.gamm.v1beta1.MsgSwapExactAmountIn',
|
|
1506
|
-
value: [10, 43, 111, 115, 109, 111, 49, 117, 110, 102, 50, 114, 99, 121, 116, 106, 120, 102, 112, 122, 56, 120, 56, 97, 114, 54, 51, 104, 52, 113, 101, 102, 116, 97, 100, 112, 116, 103, 53, 116, 48, 110, 113, 99, 108, 18, 73, 8, -14, 3, 18, 68, 105, 98, 99, 47, 50, 55, 51, 57, 52, 70, 66, 48, 57, 50, 68, 50, 69, 67, 67, 68, 53, 54, 49, 50, 51, 67, 55, 52, 70, 51, 54, 69, 52, 67, 49, 70, 57, 50, 54, 48, 48, 49, 67, 69, 65, 68, 65, 57, 67, 65, 57, 55, 69, 65, 54, 50, 50, 66, 50, 53, 70, 52, 49, 69, 53, 69, 66, 50, 18, 72, 8, 8, 18, 68, 105, 98, 99, 47, 55, 67, 52, 68, 54, 48, 65, 65, 57, 53, 69, 53, 65, 55, 53, 53, 56, 66, 48, 65, 51, 54, 52, 56, 54, 48, 57, 55, 57, 67, 65, 51, 52, 66, 55, 70, 70, 56, 65, 65, 70, 50, 53, 53, 66, 56, 55, 65, 70, 57, 69, 56, 55, 57, 51, 55, 52, 52, 55, 48, 67, 69, 67, 48, 18, 9, 8, 7, 18, 5, 117, 111, 115, 109, 111, 26, 79, 10, 68, 105, 98, 99, 47, 52, 54, 66, 52, 52, 56, 57, 57, 51, 50, 50, 70, 51, 67, 68, 56, 53, 52, 68, 50, 68, 52, 54, 68, 69, 69, 70, 56, 56, 49, 57, 53, 56, 52, 54, 55, 67, 68, 68, 52, 66, 51, 66, 49, 48, 48, 56, 54, 68, 65, 52, 57, 50, 57, 54, 66, 66, 69, 68, 57, 52, 66, 69, 68, 18, 7, 49, 48, 48, 48, 48, 48, 48, 34, 7, 49, 53, 50, 53, 50, 54, 52]
|
|
1507
|
-
}],
|
|
1508
|
-
memo: '',
|
|
1509
|
-
source: null,
|
|
1510
|
-
fee: {
|
|
1511
|
-
gas: '900000',
|
|
1512
|
-
amount: [{
|
|
1513
|
-
denom: 'uosmo',
|
|
1514
|
-
amount: '0'
|
|
1515
|
-
}]
|
|
1516
|
-
},
|
|
1517
|
-
signType: 'AMINO',
|
|
1518
|
-
rpcUrl: ''
|
|
1519
|
-
},
|
|
1520
|
-
rawTransfer: null
|
|
1521
|
-
},
|
|
1522
|
-
solanaTransaction: null,
|
|
1523
|
-
evmTransaction: null,
|
|
1524
|
-
evmApprovalTransaction: null,
|
|
1525
|
-
transferTransaction: null,
|
|
1526
|
-
diagnosisUrl: null,
|
|
1527
|
-
internalSteps: null
|
|
1528
|
-
}]
|
|
1529
|
-
}];
|
|
1530
|
-
function HistoryPage() {
|
|
1531
|
-
const navigate = reactRouterDom.useNavigate();
|
|
1532
|
-
return React__default.createElement(ui.History, {
|
|
1533
|
-
list: pendingSwap,
|
|
1534
|
-
onSwapClick: () => navigate(navigationRoutes.swapDetails),
|
|
1535
|
-
onBack: () => {
|
|
1536
|
-
navigate(-1);
|
|
1537
|
-
}
|
|
1538
|
-
});
|
|
1539
|
-
}
|
|
1540
|
-
|
|
1541
|
-
const ButtonsContainer = /*#__PURE__*/ui.styled('div', {
|
|
1542
|
-
display: 'flex'
|
|
1543
|
-
});
|
|
1544
|
-
function HeaderButtons(props) {
|
|
1545
|
-
const {
|
|
1546
|
-
onClickRefresh
|
|
1547
|
-
} = props;
|
|
1548
|
-
const navigate = reactRouterDom.useNavigate();
|
|
1549
|
-
return React__default.createElement(ButtonsContainer, null, React__default.createElement(ui.Tooltip, {
|
|
1550
|
-
content: "Retry"
|
|
1551
|
-
}, React__default.createElement(ui.Button, {
|
|
1552
|
-
variant: "ghost",
|
|
1553
|
-
onClick: onClickRefresh.bind(null)
|
|
1554
|
-
}, React__default.createElement(ui.RetryIcon, {
|
|
1555
|
-
size: 28
|
|
1556
|
-
}))), React__default.createElement(ui.Tooltip, {
|
|
1557
|
-
content: "Transactions History"
|
|
1558
|
-
}, React__default.createElement(ui.Button, {
|
|
1559
|
-
variant: "ghost",
|
|
1560
|
-
onClick: () => navigate(navigationRoutes.history)
|
|
1561
|
-
}, React__default.createElement(ui.HistoryIcon, {
|
|
1562
|
-
size: 24
|
|
1563
|
-
}))), React__default.createElement(ui.Tooltip, {
|
|
1564
|
-
content: "Settings"
|
|
1565
|
-
}, React__default.createElement(ui.Button, {
|
|
1566
|
-
variant: "ghost",
|
|
1567
|
-
onClick: () => navigate(navigationRoutes.settings)
|
|
1568
|
-
}, React__default.createElement(ui.SettingsIcon, {
|
|
1569
|
-
size: 24
|
|
1570
|
-
}))));
|
|
1571
|
-
}
|
|
1572
|
-
|
|
1573
|
-
const HeaderContainer = /*#__PURE__*/ui.styled('div', {
|
|
1574
|
-
display: 'flex',
|
|
1575
|
-
justifyContent: 'space-between',
|
|
1576
|
-
alignItems: 'center',
|
|
1577
|
-
width: '100%',
|
|
1578
|
-
padding: '$16 0'
|
|
1579
|
-
});
|
|
1580
|
-
function Header(props) {
|
|
1581
|
-
const {
|
|
1582
|
-
onClickRefresh
|
|
1583
|
-
} = props;
|
|
1584
|
-
return React__default.createElement(HeaderContainer, null, React__default.createElement(ui.Typography, {
|
|
1585
|
-
variant: "h4"
|
|
1586
|
-
}, "SWAP"), React__default.createElement(HeaderButtons, {
|
|
1587
|
-
onClickRefresh: onClickRefresh
|
|
1588
|
-
}));
|
|
1589
|
-
}
|
|
1590
|
-
|
|
1591
|
-
const Box = /*#__PURE__*/ui.styled('div', {
|
|
1592
|
-
display: 'flex',
|
|
1593
|
-
flexDirection: 'column',
|
|
1594
|
-
width: '100%'
|
|
1595
|
-
});
|
|
1596
|
-
const Container = /*#__PURE__*/ui.styled('div', {
|
|
1597
|
-
boxSizing: 'border-box',
|
|
1598
|
-
backgroundColor: '$neutrals300',
|
|
1599
|
-
borderRadius: '$5',
|
|
1600
|
-
padding: '$8 0',
|
|
1601
|
-
'.form': {
|
|
1602
|
-
display: 'flex',
|
|
1603
|
-
width: '100%',
|
|
1604
|
-
padding: '$8 $16'
|
|
1605
|
-
}
|
|
1606
|
-
});
|
|
1607
|
-
const StyledImage = /*#__PURE__*/ui.styled('img', {
|
|
1608
|
-
width: '$24',
|
|
1609
|
-
maxHeight: '$24'
|
|
1610
|
-
});
|
|
1611
|
-
const Options = /*#__PURE__*/ui.styled('div', {
|
|
1612
|
-
display: 'flex',
|
|
1613
|
-
justifyContent: 'flex-end',
|
|
1614
|
-
padding: '0 $8'
|
|
1615
|
-
});
|
|
1616
|
-
const ImagePlaceholder = /*#__PURE__*/ui.styled('span', {
|
|
1617
|
-
width: '24px',
|
|
1618
|
-
height: '24px',
|
|
1619
|
-
backgroundColor: '$neutrals300',
|
|
1620
|
-
borderRadius: '99999px'
|
|
1621
|
-
});
|
|
1622
|
-
const OutputContainer = /*#__PURE__*/ui.styled('div', {
|
|
1623
|
-
height: '$48',
|
|
1624
|
-
borderRadius: '$5',
|
|
1625
|
-
flexGrow: 1,
|
|
1626
|
-
width: '70%',
|
|
1627
|
-
backgroundColor: '$background',
|
|
1628
|
-
border: '1px solid transparent',
|
|
1629
|
-
position: 'relative',
|
|
1630
|
-
display: 'flex',
|
|
1631
|
-
alignItems: 'center',
|
|
1632
|
-
paddingLeft: '$8',
|
|
1633
|
-
paddingRight: '$8'
|
|
1634
|
-
});
|
|
1635
|
-
function TokenInfo(props) {
|
|
1636
|
-
const {
|
|
1637
|
-
type,
|
|
1638
|
-
chain,
|
|
1639
|
-
token
|
|
1640
|
-
} = props;
|
|
1641
|
-
const loadingStatus = useMetaStore.use.loadingStatus();
|
|
1642
|
-
const fromChain = useBestRouteStore.use.fromChain();
|
|
1643
|
-
const toChain = useBestRouteStore.use.toChain();
|
|
1644
|
-
const inputUsdValue = useBestRouteStore.use.inputUsdValue();
|
|
1645
|
-
const fromToken = useBestRouteStore.use.fromToken();
|
|
1646
|
-
const setInputAmount = useBestRouteStore.use.setInputAmount();
|
|
1647
|
-
const bestRoute = useBestRouteStore.use.bestRoute();
|
|
1648
|
-
const inputAmount = useBestRouteStore.use.inputAmount();
|
|
1649
|
-
const balances = useWalletsStore.use.balances();
|
|
1650
|
-
const navigate = reactRouterDom.useNavigate();
|
|
1651
|
-
const tokenBalance = !!fromChain && !!fromToken ? numberToString(getBalanceFromWallet(balances, fromChain?.name, fromToken?.symbol, fromToken?.address)?.amount || '0', 8) : '0';
|
|
1652
|
-
const tokenBalanceReal = !!fromChain && !!fromToken ? numberToString(getBalanceFromWallet(balances, fromChain?.name, fromToken?.symbol, fromToken?.address)?.amount || '0', getBalanceFromWallet(balances, fromChain?.name, fromToken?.symbol, fromToken?.address)?.decimal) : '0';
|
|
1653
|
-
const ItemSuffix = React__default.createElement("div", {
|
|
1654
|
-
style: {
|
|
1655
|
-
display: 'flex',
|
|
1656
|
-
justifyContent: 'center',
|
|
1657
|
-
alignItems: 'center'
|
|
1658
|
-
}
|
|
1659
|
-
}, loadingStatus === 'failed' && React__default.createElement(ui.InfoCircleIcon, {
|
|
1660
|
-
color: "error",
|
|
1661
|
-
size: 24
|
|
1662
|
-
}), React__default.createElement(ui.AngleDownIcon, null));
|
|
1663
|
-
return React__default.createElement(Box, null, React__default.createElement("div", null, React__default.createElement(ui.Typography, {
|
|
1664
|
-
variant: "body2"
|
|
1665
|
-
}, type)), React__default.createElement(Container, null, props.type === 'From' && React__default.createElement(Options, null, React__default.createElement("div", {
|
|
1666
|
-
className: "balance",
|
|
1667
|
-
onClick: () => {
|
|
1668
|
-
if (tokenBalance !== '0') setInputAmount(tokenBalanceReal.split(',').join(''));
|
|
1669
|
-
}
|
|
1670
|
-
}, React__default.createElement(ui.Button, {
|
|
1671
|
-
variant: "ghost",
|
|
1672
|
-
size: "small"
|
|
1673
|
-
}, React__default.createElement(ui.Typography, {
|
|
1674
|
-
variant: "body2"
|
|
1675
|
-
}, `Max: ${tokenBalance} ${fromToken?.symbol || ''}`)))), React__default.createElement("div", {
|
|
1676
|
-
className: "form"
|
|
1677
|
-
}, React__default.createElement(ui.Button, {
|
|
1678
|
-
onClick: () => {
|
|
1679
|
-
navigate(`/${props.type.toLowerCase()}-chain`);
|
|
1680
|
-
},
|
|
1681
|
-
variant: "outlined",
|
|
1682
|
-
disabled: loadingStatus === 'failed',
|
|
1683
|
-
loading: loadingStatus === 'loading',
|
|
1684
|
-
prefix: loadingStatus === 'success' && chain ? React__default.createElement(StyledImage, {
|
|
1685
|
-
src: chain.logo
|
|
1686
|
-
}) : React__default.createElement(ImagePlaceholder, null),
|
|
1687
|
-
suffix: ItemSuffix,
|
|
1688
|
-
align: "start",
|
|
1689
|
-
size: "large",
|
|
1690
|
-
style: {
|
|
1691
|
-
marginRight: '.5rem'
|
|
1692
|
-
}
|
|
1693
|
-
}, loadingStatus === 'success' && chain ? chain.displayName : 'Chain'), React__default.createElement(ui.Button, {
|
|
1694
|
-
onClick: () => {
|
|
1695
|
-
navigate(`/${props.type.toLowerCase()}-token`);
|
|
1696
|
-
},
|
|
1697
|
-
variant: "outlined",
|
|
1698
|
-
disabled: loadingStatus === 'failed' || type === 'From' && !fromChain || type === 'To' && !toChain,
|
|
1699
|
-
loading: loadingStatus === 'loading',
|
|
1700
|
-
prefix: loadingStatus === 'success' && token ? React__default.createElement(StyledImage, {
|
|
1701
|
-
src: token.image
|
|
1702
|
-
}) : React__default.createElement(ImagePlaceholder, null),
|
|
1703
|
-
suffix: ItemSuffix,
|
|
1704
|
-
size: "large",
|
|
1705
|
-
align: "start",
|
|
1706
|
-
style: {
|
|
1707
|
-
marginRight: '.5rem'
|
|
1708
|
-
}
|
|
1709
|
-
}, loadingStatus === 'success' && token ? token.symbol : 'Token'), props.type === 'From' ? React__default.createElement(ui.TextField, {
|
|
1710
|
-
type: "number",
|
|
1711
|
-
size: "large",
|
|
1712
|
-
autoFocus: true,
|
|
1713
|
-
placeholder: "0",
|
|
1714
|
-
style: {
|
|
1715
|
-
width: '70%',
|
|
1716
|
-
position: 'relative',
|
|
1717
|
-
backgroundColor: '$background !important'
|
|
2147
|
+
}],
|
|
2148
|
+
cosmosTransaction: {
|
|
2149
|
+
type: rangoSdk.TransactionType.COSMOS,
|
|
2150
|
+
fromWalletAddress: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl',
|
|
2151
|
+
blockChain: 'OSMOSIS',
|
|
2152
|
+
data: {
|
|
2153
|
+
chainId: 'osmosis-1',
|
|
2154
|
+
account_number: 102721,
|
|
2155
|
+
sequence: '308',
|
|
2156
|
+
msgs: [{
|
|
2157
|
+
__type: 'OsmosisSwapMessage',
|
|
2158
|
+
type: 'osmosis/gamm/swap-exact-amount-in',
|
|
2159
|
+
value: {
|
|
2160
|
+
sender: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl',
|
|
2161
|
+
routes: [{
|
|
2162
|
+
pool_id: '498',
|
|
2163
|
+
token_out_denom: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2'
|
|
2164
|
+
}, {
|
|
2165
|
+
pool_id: '8',
|
|
2166
|
+
token_out_denom: 'ibc/7C4D60AA95E5A7558B0A364860979CA34B7FF8AAF255B87AF9E879374470CEC0'
|
|
2167
|
+
}, {
|
|
2168
|
+
pool_id: '7',
|
|
2169
|
+
token_out_denom: 'uosmo'
|
|
2170
|
+
}],
|
|
2171
|
+
token_in: {
|
|
2172
|
+
denom: 'ibc/46B44899322F3CD854D2D46DEEF881958467CDD4B3B10086DA49296BBED94BED',
|
|
2173
|
+
amount: '1000000'
|
|
2174
|
+
},
|
|
2175
|
+
token_out_min_amount: '1525264'
|
|
2176
|
+
}
|
|
2177
|
+
}],
|
|
2178
|
+
protoMsgs: [{
|
|
2179
|
+
type_url: '/osmosis.gamm.v1beta1.MsgSwapExactAmountIn',
|
|
2180
|
+
value: [10, 43, 111, 115, 109, 111, 49, 117, 110, 102, 50, 114, 99, 121, 116, 106, 120, 102, 112, 122, 56, 120, 56, 97, 114, 54, 51, 104, 52, 113, 101, 102, 116, 97, 100, 112, 116, 103, 53, 116, 48, 110, 113, 99, 108, 18, 73, 8, -14, 3, 18, 68, 105, 98, 99, 47, 50, 55, 51, 57, 52, 70, 66, 48, 57, 50, 68, 50, 69, 67, 67, 68, 53, 54, 49, 50, 51, 67, 55, 52, 70, 51, 54, 69, 52, 67, 49, 70, 57, 50, 54, 48, 48, 49, 67, 69, 65, 68, 65, 57, 67, 65, 57, 55, 69, 65, 54, 50, 50, 66, 50, 53, 70, 52, 49, 69, 53, 69, 66, 50, 18, 72, 8, 8, 18, 68, 105, 98, 99, 47, 55, 67, 52, 68, 54, 48, 65, 65, 57, 53, 69, 53, 65, 55, 53, 53, 56, 66, 48, 65, 51, 54, 52, 56, 54, 48, 57, 55, 57, 67, 65, 51, 52, 66, 55, 70, 70, 56, 65, 65, 70, 50, 53, 53, 66, 56, 55, 65, 70, 57, 69, 56, 55, 57, 51, 55, 52, 52, 55, 48, 67, 69, 67, 48, 18, 9, 8, 7, 18, 5, 117, 111, 115, 109, 111, 26, 79, 10, 68, 105, 98, 99, 47, 52, 54, 66, 52, 52, 56, 57, 57, 51, 50, 50, 70, 51, 67, 68, 56, 53, 52, 68, 50, 68, 52, 54, 68, 69, 69, 70, 56, 56, 49, 57, 53, 56, 52, 54, 55, 67, 68, 68, 52, 66, 51, 66, 49, 48, 48, 56, 54, 68, 65, 52, 57, 50, 57, 54, 66, 66, 69, 68, 57, 52, 66, 69, 68, 18, 7, 49, 48, 48, 48, 48, 48, 48, 34, 7, 49, 53, 50, 53, 50, 54, 52]
|
|
2181
|
+
}],
|
|
2182
|
+
memo: '',
|
|
2183
|
+
source: null,
|
|
2184
|
+
fee: {
|
|
2185
|
+
gas: '900000',
|
|
2186
|
+
amount: [{
|
|
2187
|
+
denom: 'uosmo',
|
|
2188
|
+
amount: '0'
|
|
2189
|
+
}]
|
|
2190
|
+
},
|
|
2191
|
+
signType: 'AMINO',
|
|
2192
|
+
rpcUrl: ''
|
|
2193
|
+
},
|
|
2194
|
+
rawTransfer: null
|
|
1718
2195
|
},
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
style: {
|
|
1736
|
-
position: 'absolute',
|
|
1737
|
-
right: '4px',
|
|
1738
|
-
bottom: '2px'
|
|
1739
|
-
}
|
|
1740
|
-
}, React__default.createElement(ui.Typography, {
|
|
1741
|
-
variant: "caption"
|
|
1742
|
-
}, `$${numberToString(props.outputUsdValue)}`))))));
|
|
1743
|
-
}
|
|
1744
|
-
|
|
1745
|
-
const Container$1 = /*#__PURE__*/theme.styled('div', {
|
|
1746
|
-
display: 'flex',
|
|
1747
|
-
width: '100%',
|
|
1748
|
-
justifyContent: 'end',
|
|
1749
|
-
alignItems: 'center',
|
|
1750
|
-
paddingTop: '$16'
|
|
1751
|
-
});
|
|
1752
|
-
const Logo = /*#__PURE__*/theme.styled('svg', {
|
|
1753
|
-
fill: '$foreground',
|
|
1754
|
-
width: '$24',
|
|
1755
|
-
margin: '0 $8 0 $16'
|
|
1756
|
-
});
|
|
1757
|
-
const StyledAnchor = /*#__PURE__*/theme.styled('a', {
|
|
1758
|
-
display: 'flex',
|
|
1759
|
-
justifyContent: 'center',
|
|
1760
|
-
alignItems: 'center',
|
|
1761
|
-
textDecoration: 'none'
|
|
1762
|
-
});
|
|
1763
|
-
function BottomLogo() {
|
|
1764
|
-
return React__default.createElement(Container$1, null, React__default.createElement(ui.Typography, {
|
|
1765
|
-
variant: "caption"
|
|
1766
|
-
}, "Powered By"), React__default.createElement(StyledAnchor, {
|
|
1767
|
-
href: "https://rango.exchange",
|
|
1768
|
-
target: "_blank"
|
|
1769
|
-
}, React__default.createElement(Logo, {
|
|
1770
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1771
|
-
viewBox: "0 0 33.68 29"
|
|
1772
|
-
}, React__default.createElement("defs", null), React__default.createElement("g", {
|
|
1773
|
-
id: "Layer_2",
|
|
1774
|
-
"data-name": "Layer 2"
|
|
1775
|
-
}, React__default.createElement("g", {
|
|
1776
|
-
id: "Layer_1-2",
|
|
1777
|
-
"data-name": "Layer 1"
|
|
1778
|
-
}, React__default.createElement("path", {
|
|
1779
|
-
d: "M33.68,18.05A17.93,17.93,0,0,0,28.34,5.29,18.31,18.31,0,0,0,15.45,0H13.54V7.41L6.07,0H.69L9.83,9.07H0V11A17.93,17.93,0,0,0,5.34,23.71,18.32,18.32,0,0,0,18.24,29h1.9V21.59l7.38,7.31h5.39l-9-9h9.82ZM17.37,16.16H12.49a1.93,1.93,0,0,0-1.35.55,1.89,1.89,0,0,0-.56,1.34,1.85,1.85,0,0,0,.56,1.33,1.93,1.93,0,0,0,1.35.55h3.84V25.1A14.43,14.43,0,0,1,8,21a14.21,14.21,0,0,1-4.1-8.2H21.2a1.86,1.86,0,0,0,.74-.13,1.92,1.92,0,0,0,.64-.4,2,2,0,0,0,.43-.62,1.88,1.88,0,0,0,0-1.47,2,2,0,0,0-.43-.62,1.92,1.92,0,0,0-.64-.4,1.86,1.86,0,0,0-.74-.13H17.35V3.9A14.43,14.43,0,0,1,25.64,8a14.19,14.19,0,0,1,4.11,8.2Zm2.12-5.27a1.43,1.43,0,0,1,.26-.83,1.52,1.52,0,0,1,.67-.56,1.55,1.55,0,0,1,.88-.08,1.51,1.51,0,0,1,.77.4,1.54,1.54,0,0,1,.42.77,1.41,1.41,0,0,1-.09.86,1.47,1.47,0,0,1-.55.68,1.56,1.56,0,0,1-.84.25,1.52,1.52,0,0,1-1.52-1.49Z"
|
|
1780
|
-
}), React__default.createElement("path", {
|
|
1781
|
-
d: "M21.7,11.57a.68.68,0,0,0-.12-.38.64.64,0,0,0-.31-.25.68.68,0,0,0-.75.15.61.61,0,0,0-.19.35.62.62,0,0,0,0,.4.67.67,0,0,0,.25.3.69.69,0,0,0,.39.12.7.7,0,0,0,.49-.2A.68.68,0,0,0,21.7,11.57Z"
|
|
1782
|
-
})))), React__default.createElement(ui.Typography, {
|
|
1783
|
-
variant: "body2"
|
|
1784
|
-
}, "RANGO")));
|
|
1785
|
-
}
|
|
1786
|
-
|
|
1787
|
-
function SwithFromAndTo(_ref) {
|
|
1788
|
-
let {
|
|
1789
|
-
count
|
|
1790
|
-
} = _ref;
|
|
1791
|
-
const firstRender = React.useRef(true);
|
|
1792
|
-
const [searchParams, setSearchParams] = reactRouterDom.useSearchParams();
|
|
1793
|
-
const outputAmount = useBestRouteStore.use.outputAmount();
|
|
1794
|
-
React.useEffect(() => {
|
|
1795
|
-
if (!firstRender.current) {
|
|
1796
|
-
const fromChainString = searchParams.get(SearchParams.FROM_CHAIN);
|
|
1797
|
-
const fromTokenString = searchParams.get(SearchParams.FROM_TOKEN);
|
|
1798
|
-
const toChainString = searchParams.get(SearchParams.TO_CHAIN);
|
|
1799
|
-
const toTokenString = searchParams.get(SearchParams.TO_TOKEN);
|
|
1800
|
-
setSearchParams({
|
|
1801
|
-
...(toChainString && {
|
|
1802
|
-
[SearchParams.FROM_CHAIN]: toChainString
|
|
1803
|
-
}),
|
|
1804
|
-
...(toTokenString && {
|
|
1805
|
-
[SearchParams.FROM_TOKEN]: toTokenString
|
|
1806
|
-
}),
|
|
1807
|
-
...(fromChainString && {
|
|
1808
|
-
[SearchParams.TO_CHAIN]: fromChainString
|
|
1809
|
-
}),
|
|
1810
|
-
...(fromTokenString && {
|
|
1811
|
-
[SearchParams.TO_TOKEN]: fromTokenString
|
|
1812
|
-
}),
|
|
1813
|
-
...(outputAmount && {
|
|
1814
|
-
[SearchParams.FROM_AMOUNT]: outputAmount.toString()
|
|
1815
|
-
})
|
|
1816
|
-
});
|
|
1817
|
-
} else {
|
|
1818
|
-
firstRender.current = false;
|
|
2196
|
+
solanaTransaction: null,
|
|
2197
|
+
evmTransaction: null,
|
|
2198
|
+
evmApprovalTransaction: null,
|
|
2199
|
+
transferTransaction: null,
|
|
2200
|
+
diagnosisUrl: null,
|
|
2201
|
+
internalSteps: null
|
|
2202
|
+
}]
|
|
2203
|
+
}, {
|
|
2204
|
+
creationTime: '1673164511955',
|
|
2205
|
+
finishTime: '1673164550137',
|
|
2206
|
+
requestId: '51e211d9-d61c-45d2-a4d4-1f9f7f90ee85',
|
|
2207
|
+
inputAmount: '1',
|
|
2208
|
+
wallets: {
|
|
2209
|
+
OSMOSIS: {
|
|
2210
|
+
walletType: 'keplr',
|
|
2211
|
+
address: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl'
|
|
1819
2212
|
}
|
|
1820
|
-
},
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
2213
|
+
},
|
|
2214
|
+
status: 'success',
|
|
2215
|
+
isPaused: false,
|
|
2216
|
+
extraMessage: null,
|
|
2217
|
+
extraMessageSeverity: 'info',
|
|
2218
|
+
extraMessageDetail: '',
|
|
2219
|
+
extraMessageErrorCode: null,
|
|
2220
|
+
networkStatusExtraMessage: null,
|
|
2221
|
+
networkStatusExtraMessageDetail: null,
|
|
2222
|
+
lastNotificationTime: null,
|
|
2223
|
+
settings: {
|
|
2224
|
+
slippage: '1.0',
|
|
2225
|
+
disabledSwappersIds: [],
|
|
2226
|
+
disabledSwappersGroups: []
|
|
2227
|
+
},
|
|
2228
|
+
simulationResult: {
|
|
2229
|
+
outputAmount: '1.540670',
|
|
2230
|
+
swaps: [{
|
|
2231
|
+
// @ts-ignore
|
|
2232
|
+
result: [],
|
|
2233
|
+
swapperId: 'Osmosis',
|
|
2234
|
+
swapperType: 'DEX',
|
|
2235
|
+
swapperLogo: '',
|
|
2236
|
+
from: {
|
|
2237
|
+
symbol: 'JUNO',
|
|
2238
|
+
logo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png',
|
|
2239
|
+
address: 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed',
|
|
2240
|
+
blockchain: 'OSMOSIS',
|
|
2241
|
+
blockchainLogo: '',
|
|
2242
|
+
decimals: 6,
|
|
2243
|
+
usdPrice: 1.1091996179668873
|
|
2244
|
+
},
|
|
2245
|
+
to: {
|
|
2246
|
+
symbol: 'OSMO',
|
|
2247
|
+
logo: 'https://api.rango.exchange/i/mJQPS2',
|
|
2248
|
+
address: null,
|
|
2249
|
+
blockchain: 'OSMOSIS',
|
|
2250
|
+
decimals: 6,
|
|
2251
|
+
blockchainLogo: '',
|
|
2252
|
+
usdPrice: 0.7192435454440882
|
|
2253
|
+
},
|
|
2254
|
+
fromAmount: '1.000000',
|
|
2255
|
+
fromAmountPrecision: null,
|
|
2256
|
+
fromAmountMinValue: null,
|
|
2257
|
+
fromAmountMaxValue: null,
|
|
2258
|
+
toAmount: '1.540670',
|
|
2259
|
+
fee: [{
|
|
2260
|
+
name: '',
|
|
2261
|
+
asset: {
|
|
2262
|
+
blockchain: 'OSMOSIS',
|
|
2263
|
+
symbol: 'OSMO',
|
|
2264
|
+
address: null
|
|
2265
|
+
},
|
|
2266
|
+
expenseType: 'FROM_SOURCE_WALLET',
|
|
2267
|
+
amount: '0'
|
|
2268
|
+
}],
|
|
2269
|
+
estimatedTimeInSeconds: 45,
|
|
2270
|
+
swapChainType: 'INTRA_CHAIN',
|
|
2271
|
+
routes: [{
|
|
2272
|
+
nodes: [{
|
|
2273
|
+
nodes: [{
|
|
2274
|
+
marketName: 'pool#498',
|
|
2275
|
+
marketId: null,
|
|
2276
|
+
percent: 1
|
|
2277
|
+
}],
|
|
2278
|
+
from: 'JUNO',
|
|
2279
|
+
fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png',
|
|
2280
|
+
fromAddress: 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed',
|
|
2281
|
+
fromBlockchain: 'OSMOSIS',
|
|
2282
|
+
to: 'ATOM',
|
|
2283
|
+
toLogo: 'https://api.rango.exchange/tokens/COSMOS/ATOM.png',
|
|
2284
|
+
toAddress: 'ibc/27394fb092d2eccd56123c74f36e4c1f926001ceada9ca97ea622b25f41e5eb2',
|
|
2285
|
+
toBlockchain: 'OSMOSIS'
|
|
2286
|
+
}, {
|
|
2287
|
+
nodes: [{
|
|
2288
|
+
marketName: 'pool#8',
|
|
2289
|
+
marketId: null,
|
|
2290
|
+
percent: 1
|
|
2291
|
+
}],
|
|
2292
|
+
from: 'ATOM',
|
|
2293
|
+
fromLogo: 'https://api.rango.exchange/tokens/COSMOS/ATOM.png',
|
|
2294
|
+
fromAddress: 'ibc/27394fb092d2eccd56123c74f36e4c1f926001ceada9ca97ea622b25f41e5eb2',
|
|
2295
|
+
fromBlockchain: 'OSMOSIS',
|
|
2296
|
+
to: 'IRIS',
|
|
2297
|
+
toLogo: 'https://api.rango.exchange/tokens/COSMOS/IRIS.png',
|
|
2298
|
+
toAddress: 'ibc/7c4d60aa95e5a7558b0a364860979ca34b7ff8aaf255b87af9e879374470cec0',
|
|
2299
|
+
toBlockchain: 'OSMOSIS'
|
|
2300
|
+
}, {
|
|
2301
|
+
nodes: [{
|
|
2302
|
+
marketName: 'pool#7',
|
|
2303
|
+
marketId: null,
|
|
2304
|
+
percent: 1
|
|
2305
|
+
}],
|
|
2306
|
+
from: 'IRIS',
|
|
2307
|
+
fromLogo: 'https://api.rango.exchange/tokens/COSMOS/IRIS.png',
|
|
2308
|
+
fromAddress: 'ibc/7c4d60aa95e5a7558b0a364860979ca34b7ff8aaf255b87af9e879374470cec0',
|
|
2309
|
+
fromBlockchain: 'OSMOSIS',
|
|
2310
|
+
to: 'OSMO',
|
|
2311
|
+
toLogo: 'https://api.rango.exchange/tokens/COSMOS/OSMO.png',
|
|
2312
|
+
toAddress: null,
|
|
2313
|
+
toBlockchain: 'OSMOSIS'
|
|
2314
|
+
}]
|
|
2315
|
+
}],
|
|
2316
|
+
recommendedSlippage: null,
|
|
2317
|
+
timeStat: {
|
|
2318
|
+
min: 6,
|
|
2319
|
+
avg: 40,
|
|
2320
|
+
max: 241
|
|
2321
|
+
},
|
|
2322
|
+
includesDestinationTx: false
|
|
2323
|
+
}]
|
|
2324
|
+
},
|
|
2325
|
+
validateBalanceOrFee: true,
|
|
2326
|
+
steps: [{
|
|
2327
|
+
id: 1,
|
|
2328
|
+
fromBlockchain: 'OSMOSIS',
|
|
2329
|
+
fromSymbol: 'JUNO',
|
|
2330
|
+
fromSymbolAddress: 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed',
|
|
2331
|
+
fromDecimals: 6,
|
|
2332
|
+
fromAmountPrecision: null,
|
|
2333
|
+
fromAmountMinValue: null,
|
|
2334
|
+
swapperLogo: '',
|
|
2335
|
+
swapperType: '',
|
|
2336
|
+
fromAmountMaxValue: null,
|
|
2337
|
+
toBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png',
|
|
2338
|
+
fromBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png',
|
|
2339
|
+
toBlockchain: 'OSMOSIS',
|
|
2340
|
+
fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png',
|
|
2341
|
+
toSymbol: 'OSMO',
|
|
2342
|
+
toSymbolAddress: null,
|
|
2343
|
+
toDecimals: 6,
|
|
2344
|
+
toLogo: 'https://api.rango.exchange/i/mJQPS2',
|
|
2345
|
+
startTransactionTime: 1673164519916,
|
|
2346
|
+
swapperId: 'Osmosis',
|
|
2347
|
+
expectedOutputAmountHumanReadable: '1.540670',
|
|
2348
|
+
outputAmount: '1.540658',
|
|
2349
|
+
status: 'success',
|
|
2350
|
+
networkStatus: null,
|
|
2351
|
+
executedTransactionId: '0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b',
|
|
2352
|
+
explorerUrl: [{
|
|
2353
|
+
url: 'https://www.mintscan.io/osmosis/txs/0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b',
|
|
2354
|
+
description: null
|
|
2355
|
+
}],
|
|
2356
|
+
cosmosTransaction: {
|
|
2357
|
+
type: rangoSdk.TransactionType.COSMOS,
|
|
2358
|
+
fromWalletAddress: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl',
|
|
2359
|
+
blockChain: 'OSMOSIS',
|
|
2360
|
+
data: {
|
|
2361
|
+
chainId: 'osmosis-1',
|
|
2362
|
+
account_number: 102721,
|
|
2363
|
+
sequence: '308',
|
|
2364
|
+
msgs: [{
|
|
2365
|
+
__type: 'OsmosisSwapMessage',
|
|
2366
|
+
type: 'osmosis/gamm/swap-exact-amount-in',
|
|
2367
|
+
value: {
|
|
2368
|
+
sender: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl',
|
|
2369
|
+
routes: [{
|
|
2370
|
+
pool_id: '498',
|
|
2371
|
+
token_out_denom: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2'
|
|
2372
|
+
}, {
|
|
2373
|
+
pool_id: '8',
|
|
2374
|
+
token_out_denom: 'ibc/7C4D60AA95E5A7558B0A364860979CA34B7FF8AAF255B87AF9E879374470CEC0'
|
|
2375
|
+
}, {
|
|
2376
|
+
pool_id: '7',
|
|
2377
|
+
token_out_denom: 'uosmo'
|
|
2378
|
+
}],
|
|
2379
|
+
token_in: {
|
|
2380
|
+
denom: 'ibc/46B44899322F3CD854D2D46DEEF881958467CDD4B3B10086DA49296BBED94BED',
|
|
2381
|
+
amount: '1000000'
|
|
2382
|
+
},
|
|
2383
|
+
token_out_min_amount: '1525264'
|
|
2384
|
+
}
|
|
2385
|
+
}],
|
|
2386
|
+
protoMsgs: [{
|
|
2387
|
+
type_url: '/osmosis.gamm.v1beta1.MsgSwapExactAmountIn',
|
|
2388
|
+
value: [10, 43, 111, 115, 109, 111, 49, 117, 110, 102, 50, 114, 99, 121, 116, 106, 120, 102, 112, 122, 56, 120, 56, 97, 114, 54, 51, 104, 52, 113, 101, 102, 116, 97, 100, 112, 116, 103, 53, 116, 48, 110, 113, 99, 108, 18, 73, 8, -14, 3, 18, 68, 105, 98, 99, 47, 50, 55, 51, 57, 52, 70, 66, 48, 57, 50, 68, 50, 69, 67, 67, 68, 53, 54, 49, 50, 51, 67, 55, 52, 70, 51, 54, 69, 52, 67, 49, 70, 57, 50, 54, 48, 48, 49, 67, 69, 65, 68, 65, 57, 67, 65, 57, 55, 69, 65, 54, 50, 50, 66, 50, 53, 70, 52, 49, 69, 53, 69, 66, 50, 18, 72, 8, 8, 18, 68, 105, 98, 99, 47, 55, 67, 52, 68, 54, 48, 65, 65, 57, 53, 69, 53, 65, 55, 53, 53, 56, 66, 48, 65, 51, 54, 52, 56, 54, 48, 57, 55, 57, 67, 65, 51, 52, 66, 55, 70, 70, 56, 65, 65, 70, 50, 53, 53, 66, 56, 55, 65, 70, 57, 69, 56, 55, 57, 51, 55, 52, 52, 55, 48, 67, 69, 67, 48, 18, 9, 8, 7, 18, 5, 117, 111, 115, 109, 111, 26, 79, 10, 68, 105, 98, 99, 47, 52, 54, 66, 52, 52, 56, 57, 57, 51, 50, 50, 70, 51, 67, 68, 56, 53, 52, 68, 50, 68, 52, 54, 68, 69, 69, 70, 56, 56, 49, 57, 53, 56, 52, 54, 55, 67, 68, 68, 52, 66, 51, 66, 49, 48, 48, 56, 54, 68, 65, 52, 57, 50, 57, 54, 66, 66, 69, 68, 57, 52, 66, 69, 68, 18, 7, 49, 48, 48, 48, 48, 48, 48, 34, 7, 49, 53, 50, 53, 50, 54, 52]
|
|
2389
|
+
}],
|
|
2390
|
+
memo: '',
|
|
2391
|
+
source: null,
|
|
2392
|
+
fee: {
|
|
2393
|
+
gas: '900000',
|
|
2394
|
+
amount: [{
|
|
2395
|
+
denom: 'uosmo',
|
|
2396
|
+
amount: '0'
|
|
2397
|
+
}]
|
|
1863
2398
|
},
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
if (error.code === 'ERR_CANCELED') return;
|
|
1879
|
-
setError(error.message);
|
|
1880
|
-
setLoading(false);
|
|
1881
|
-
});
|
|
1882
|
-
}
|
|
1883
|
-
}, [fromToken, toToken, inputAmount, count, slippage, customSlippage, disabledLiquiditySources.length]);
|
|
1884
|
-
return {
|
|
1885
|
-
loading,
|
|
1886
|
-
error,
|
|
1887
|
-
data,
|
|
1888
|
-
retry
|
|
1889
|
-
};
|
|
1890
|
-
}
|
|
1891
|
-
|
|
1892
|
-
const errorMessages = {
|
|
1893
|
-
genericServerError: 'Error connecting server, please reload the app and try again'
|
|
1894
|
-
};
|
|
1895
|
-
|
|
1896
|
-
const Container$2 = /*#__PURE__*/ui.styled('div', {
|
|
1897
|
-
display: 'flex',
|
|
1898
|
-
flexDirection: 'column',
|
|
1899
|
-
justifyContent: 'center',
|
|
1900
|
-
alignItems: 'center'
|
|
1901
|
-
});
|
|
1902
|
-
const SwitchButtonContainer = /*#__PURE__*/ui.styled('div', {
|
|
1903
|
-
display: 'flex',
|
|
1904
|
-
justifyContent: 'center',
|
|
1905
|
-
alignItems: 'center',
|
|
1906
|
-
position: 'relative',
|
|
1907
|
-
top: '11px'
|
|
1908
|
-
});
|
|
1909
|
-
const BestRouteContainer = /*#__PURE__*/ui.styled('div', {
|
|
1910
|
-
width: '100%',
|
|
1911
|
-
paddingTop: '$16'
|
|
1912
|
-
});
|
|
1913
|
-
const Alerts = /*#__PURE__*/ui.styled('div', {
|
|
1914
|
-
paddingTop: '$16'
|
|
1915
|
-
});
|
|
1916
|
-
function Home() {
|
|
1917
|
-
const waningMessage = '';
|
|
1918
|
-
const isRouterInContext = reactRouterDom.useInRouterContext();
|
|
2399
|
+
signType: 'AMINO',
|
|
2400
|
+
rpcUrl: ''
|
|
2401
|
+
},
|
|
2402
|
+
rawTransfer: null
|
|
2403
|
+
},
|
|
2404
|
+
solanaTransaction: null,
|
|
2405
|
+
evmTransaction: null,
|
|
2406
|
+
evmApprovalTransaction: null,
|
|
2407
|
+
transferTransaction: null,
|
|
2408
|
+
diagnosisUrl: null,
|
|
2409
|
+
internalSteps: null
|
|
2410
|
+
}]
|
|
2411
|
+
}];
|
|
2412
|
+
function HistoryPage() {
|
|
1919
2413
|
const navigate = reactRouterDom.useNavigate();
|
|
1920
|
-
const [count, setCount] = React.useState(0);
|
|
1921
|
-
const fromChain = useBestRouteStore.use.fromChain();
|
|
1922
|
-
const fromToken = useBestRouteStore.use.fromToken();
|
|
1923
|
-
const toChain = useBestRouteStore.use.toChain();
|
|
1924
|
-
const toToken = useBestRouteStore.use.toToken();
|
|
1925
|
-
const setFromChain = useBestRouteStore.use.setFromChain();
|
|
1926
|
-
const setFromToken = useBestRouteStore.use.setFromToken();
|
|
1927
|
-
const setToChain = useBestRouteStore.use.setToChain();
|
|
1928
|
-
const setToToken = useBestRouteStore.use.setToToken();
|
|
1929
|
-
const setBestRoute = useBestRouteStore.use.setBestRoute();
|
|
1930
|
-
const inputUsdValue = useBestRouteStore.use.inputUsdValue();
|
|
1931
|
-
const inputAmount = useBestRouteStore.use.inputAmount();
|
|
1932
|
-
const setInputAmount = useBestRouteStore.use.setInputAmount();
|
|
1933
|
-
const outputAmount = useBestRouteStore.use.outputAmount();
|
|
1934
|
-
const outputUsdValue = useBestRouteStore.use.outputUsdValue();
|
|
1935
|
-
const bestRoute = useBestRouteStore.use.bestRoute();
|
|
1936
|
-
const loadingMetaStatus = useMetaStore.use.loadingStatus();
|
|
1937
|
-
const accounts = useWalletsStore.use.accounts();
|
|
1938
|
-
const swithFromAndTo = () => {
|
|
1939
|
-
setFromChain(toChain);
|
|
1940
|
-
setFromToken(toToken);
|
|
1941
|
-
setToChain(fromChain);
|
|
1942
|
-
setToToken(fromToken);
|
|
1943
|
-
setInputAmount(outputAmount?.toString() || '');
|
|
1944
|
-
setCount(prev => prev + 1);
|
|
1945
|
-
};
|
|
1946
2414
|
const {
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
const errorMessage = loadingMetaStatus === 'failed' ? errorMessages.genericServerError : bestRouteError;
|
|
1955
|
-
const needsToWarnEthOnPath = false;
|
|
1956
|
-
const showBestRoute = inputAmount && (!!data || fetchingBestRoute || bestRouteError);
|
|
1957
|
-
const outToInRatio = getOutputRatio(inputUsdValue, outputUsdValue);
|
|
1958
|
-
const highValueLoss = outputRatioHasWarning(inputUsdValue, outToInRatio);
|
|
1959
|
-
const priceImpactCanNotBeComputed = !canComputePriceImpact(bestRoute, inputAmount, inputUsdValue, outputUsdValue);
|
|
1960
|
-
const buttonTitle = getSwapButtonTitle(accounts, fetchingBestRoute, hasLimitError(bestRoute), highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath);
|
|
1961
|
-
const buttonDisabled = loadingMetaStatus != 'success' || fetchingBestRoute || highValueLoss || noConnectedWallet && noRoutesFound || hasLimitError(bestRoute);
|
|
1962
|
-
React.useEffect(() => {
|
|
1963
|
-
setBestRoute(data);
|
|
1964
|
-
}, [data]);
|
|
1965
|
-
return React__default.createElement(Container$2, null, React__default.createElement(Header, {
|
|
1966
|
-
onClickRefresh: retry
|
|
1967
|
-
}), React__default.createElement(TokenInfo, {
|
|
1968
|
-
type: "From",
|
|
1969
|
-
chain: fromChain,
|
|
1970
|
-
token: fromToken,
|
|
1971
|
-
onAmountChange: setInputAmount,
|
|
1972
|
-
inputAmount: inputAmount
|
|
1973
|
-
}), React__default.createElement(SwitchButtonContainer, null, React__default.createElement(ui.Button, {
|
|
1974
|
-
variant: "ghost",
|
|
1975
|
-
onClick: swithFromAndTo
|
|
1976
|
-
}, React__default.createElement(ui.VerticalSwapIcon, {
|
|
1977
|
-
size: 36
|
|
1978
|
-
}), isRouterInContext && React__default.createElement(SwithFromAndTo, {
|
|
1979
|
-
count: count
|
|
1980
|
-
}))), React__default.createElement(TokenInfo, {
|
|
1981
|
-
type: "To",
|
|
1982
|
-
chain: toChain,
|
|
1983
|
-
token: toToken,
|
|
1984
|
-
outputAmount: outputAmount,
|
|
1985
|
-
outputUsdValue: outputUsdValue
|
|
1986
|
-
}), showBestRoute && React__default.createElement(BestRouteContainer, null, React__default.createElement(ui.BestRoute, {
|
|
1987
|
-
error: bestRouteError,
|
|
1988
|
-
loading: fetchingBestRoute,
|
|
1989
|
-
data: data
|
|
1990
|
-
})), (errorMessage || waningMessage) && React__default.createElement(Alerts, null, errorMessage && React__default.createElement(ui.Alert, {
|
|
1991
|
-
description: errorMessage,
|
|
1992
|
-
type: "error"
|
|
1993
|
-
}), waningMessage ), React__default.createElement(Footer, null, React__default.createElement(ui.Button, {
|
|
1994
|
-
type: "primary",
|
|
1995
|
-
align: "grow",
|
|
1996
|
-
size: "large",
|
|
1997
|
-
disabled: buttonDisabled,
|
|
1998
|
-
onClick: () => {
|
|
1999
|
-
if (buttonTitle === 'Connect Wallet') navigate(navigationRoutes.wallets);else {
|
|
2000
|
-
navigate(navigationRoutes.confirmWallets);
|
|
2001
|
-
}
|
|
2002
|
-
}
|
|
2003
|
-
}, buttonTitle), React__default.createElement(BottomLogo, null)));
|
|
2415
|
+
navigateBackFrom
|
|
2416
|
+
} = useNavigateBack();
|
|
2417
|
+
return React__default.createElement(ui.History, {
|
|
2418
|
+
list: pendingSwap,
|
|
2419
|
+
onSwapClick: navigate.bind(null, navigationRoutes.swapDetails),
|
|
2420
|
+
onBack: navigateBackFrom.bind(null, navigationRoutes.history)
|
|
2421
|
+
});
|
|
2004
2422
|
}
|
|
2005
2423
|
|
|
2006
2424
|
function LiquiditySourcePage() {
|
|
@@ -2010,7 +2428,9 @@ function LiquiditySourcePage() {
|
|
|
2010
2428
|
const toggleLiquiditySource = useSettingsStore.use.toggleLiquiditySource();
|
|
2011
2429
|
const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
|
|
2012
2430
|
const toggleAllLiquiditySources = useSettingsStore.use.toggleAllLiquiditySources();
|
|
2013
|
-
const
|
|
2431
|
+
const {
|
|
2432
|
+
navigateBackFrom
|
|
2433
|
+
} = useNavigateBack();
|
|
2014
2434
|
const uniqueSwappersGroups = [];
|
|
2015
2435
|
removeDuplicateFrom(swappers.map(s => s.swapperGroup)).map(swapperGroup => {
|
|
2016
2436
|
return swappers.find(s => s.swapperGroup === swapperGroup);
|
|
@@ -2030,9 +2450,7 @@ function LiquiditySourcePage() {
|
|
|
2030
2450
|
toggleAll: toggleAllLiquiditySources,
|
|
2031
2451
|
list: uniqueSwappersGroups,
|
|
2032
2452
|
onChange: liquiditySource => toggleLiquiditySource(liquiditySource.title),
|
|
2033
|
-
onBack: ()
|
|
2034
|
-
navigate(-1);
|
|
2035
|
-
}
|
|
2453
|
+
onBack: navigateBackFrom.bind(null, navigationRoutes.liquiditySources)
|
|
2036
2454
|
});
|
|
2037
2455
|
}
|
|
2038
2456
|
|
|
@@ -2040,7 +2458,6 @@ function SelectChainPage(props) {
|
|
|
2040
2458
|
const {
|
|
2041
2459
|
type
|
|
2042
2460
|
} = props;
|
|
2043
|
-
const accounts = useWalletsStore.use.accounts();
|
|
2044
2461
|
const {
|
|
2045
2462
|
blockchains
|
|
2046
2463
|
} = useMetaStore.use.meta();
|
|
@@ -2051,30 +2468,21 @@ function SelectChainPage(props) {
|
|
|
2051
2468
|
const setToChain = useBestRouteStore.use.setToChain();
|
|
2052
2469
|
const setFromToken = useBestRouteStore.use.setFromToken();
|
|
2053
2470
|
const setToToken = useBestRouteStore.use.setToToken();
|
|
2054
|
-
const
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
let chainSortedByConnectedWallets = [];
|
|
2058
|
-
if (accounts.length !== 0) {
|
|
2059
|
-
const connectedChains = removeDuplicateFrom(accounts.map(account => account.chain));
|
|
2060
|
-
chainSortedByConnectedWallets = blockchains.sort((blockchainA, blockchainB) => connectedChains.lastIndexOf(blockchainA.name) - connectedChains.lastIndexOf(blockchainB.name));
|
|
2061
|
-
} else {
|
|
2062
|
-
chainSortedByConnectedWallets = blockchains;
|
|
2063
|
-
}
|
|
2064
|
-
setList(chainSortedByConnectedWallets);
|
|
2065
|
-
}, [blockchains.length, accounts.length]);
|
|
2471
|
+
const {
|
|
2472
|
+
navigateBackFrom
|
|
2473
|
+
} = useNavigateBack();
|
|
2066
2474
|
return React__default.createElement(ui.BlockchainSelector, {
|
|
2067
2475
|
type: type === 'from' ? 'Source' : 'Destination',
|
|
2068
|
-
list:
|
|
2476
|
+
list: blockchains,
|
|
2069
2477
|
selected: type === 'from' ? fromChain : toChain,
|
|
2070
2478
|
loadingStatus: loadingStatus,
|
|
2071
2479
|
onChange: chain => {
|
|
2072
2480
|
if (type === 'from') setFromChain(chain);else setToChain(chain);
|
|
2073
2481
|
if (type === 'from' && fromChain?.name != chain.name) setFromToken(null);
|
|
2074
2482
|
if (type === 'to' && toChain?.name != chain.name) setToToken(null);
|
|
2075
|
-
|
|
2483
|
+
navigateBackFrom(navigationRoutes.fromChain);
|
|
2076
2484
|
},
|
|
2077
|
-
onBack:
|
|
2485
|
+
onBack: navigateBackFrom.bind(null, navigationRoutes.fromChain)
|
|
2078
2486
|
});
|
|
2079
2487
|
}
|
|
2080
2488
|
|
|
@@ -2082,7 +2490,9 @@ function SelectTokenPage(props) {
|
|
|
2082
2490
|
const {
|
|
2083
2491
|
type
|
|
2084
2492
|
} = props;
|
|
2085
|
-
const
|
|
2493
|
+
const {
|
|
2494
|
+
navigateBackFrom
|
|
2495
|
+
} = useNavigateBack();
|
|
2086
2496
|
const {
|
|
2087
2497
|
tokens
|
|
2088
2498
|
} = useMetaStore.use.meta();
|
|
@@ -2116,9 +2526,9 @@ function SelectTokenPage(props) {
|
|
|
2116
2526
|
selected: type === 'from' ? fromToken : toToken,
|
|
2117
2527
|
onChange: token => {
|
|
2118
2528
|
if (type === 'from') setFromToken(token);else setToToken(token);
|
|
2119
|
-
|
|
2529
|
+
navigateBackFrom(navigationRoutes.fromToken);
|
|
2120
2530
|
},
|
|
2121
|
-
onBack:
|
|
2531
|
+
onBack: navigateBackFrom.bind(null, navigationRoutes.fromToken)
|
|
2122
2532
|
});
|
|
2123
2533
|
}
|
|
2124
2534
|
|
|
@@ -2134,6 +2544,9 @@ function SettingsPage() {
|
|
|
2134
2544
|
swappers
|
|
2135
2545
|
} = useMetaStore.use.meta();
|
|
2136
2546
|
const navigate = reactRouterDom.useNavigate();
|
|
2547
|
+
const {
|
|
2548
|
+
navigateBackFrom
|
|
2549
|
+
} = useNavigateBack();
|
|
2137
2550
|
const uniqueSwappersGroups = [];
|
|
2138
2551
|
removeDuplicateFrom(swappers.map(s => s.swapperGroup)).map(swapperGroup => {
|
|
2139
2552
|
return swappers.find(s => s.swapperGroup === swapperGroup);
|
|
@@ -2150,17 +2563,17 @@ function SettingsPage() {
|
|
|
2150
2563
|
}
|
|
2151
2564
|
});
|
|
2152
2565
|
return React__default.createElement(ui.Settings, {
|
|
2153
|
-
slippages:
|
|
2566
|
+
slippages: SLIPPAGES,
|
|
2154
2567
|
selectedSlippage: slippage,
|
|
2155
2568
|
onSlippageChange: slippage => setSlippage(slippage),
|
|
2156
2569
|
liquiditySources: uniqueSwappersGroups,
|
|
2157
2570
|
selectedLiquiditySources: uniqueSwappersGroups.filter(s => s.selected),
|
|
2158
|
-
onLiquiditySourcesClick: (
|
|
2159
|
-
onBack:
|
|
2571
|
+
onLiquiditySourcesClick: navigate.bind(null, navigationRoutes.liquiditySources),
|
|
2572
|
+
onBack: navigateBackFrom.bind(null, navigationRoutes.settings),
|
|
2160
2573
|
customSlippage: customSlippage || NaN,
|
|
2161
2574
|
onCustomSlippageChange: setCustomSlippage,
|
|
2162
|
-
minSlippage:
|
|
2163
|
-
maxSlippage:
|
|
2575
|
+
minSlippage: MIN_SLIPPGAE,
|
|
2576
|
+
maxSlippage: MAX_SLIPPAGE,
|
|
2164
2577
|
selectedTheme: theme,
|
|
2165
2578
|
onThemeChange: setTheme
|
|
2166
2579
|
});
|
|
@@ -2171,13 +2584,16 @@ const ListContainer = /*#__PURE__*/ui.styled('div', {
|
|
|
2171
2584
|
gap: '.5rem',
|
|
2172
2585
|
gridTemplateColumns: ' repeat(2, minmax(0, 1fr))',
|
|
2173
2586
|
height: '450px',
|
|
2174
|
-
alignContent: 'baseline'
|
|
2587
|
+
alignContent: 'baseline',
|
|
2588
|
+
padding: '0 0.5rem'
|
|
2175
2589
|
});
|
|
2176
2590
|
const AlertContainer = /*#__PURE__*/ui.styled('div', {
|
|
2177
2591
|
paddingBottom: '$16'
|
|
2178
2592
|
});
|
|
2179
2593
|
function WalletsPage() {
|
|
2180
|
-
const
|
|
2594
|
+
const {
|
|
2595
|
+
navigateBackFrom
|
|
2596
|
+
} = useNavigateBack();
|
|
2181
2597
|
const {
|
|
2182
2598
|
state,
|
|
2183
2599
|
disconnect,
|
|
@@ -2186,6 +2602,7 @@ function WalletsPage() {
|
|
|
2186
2602
|
} = walletsCore.useWallets();
|
|
2187
2603
|
const wallets = getlistWallet(state, getWalletInfo, Object.values(walletsShared.WalletType));
|
|
2188
2604
|
const [walletErrorMessage, setWalletErrorMessage] = React.useState('');
|
|
2605
|
+
const toggleConnectWalletsButton = useUiStore.use.toggleConnectWalletsButton();
|
|
2189
2606
|
const onSelectWallet = async type => {
|
|
2190
2607
|
const wallet = state(type);
|
|
2191
2608
|
try {
|
|
@@ -2199,24 +2616,29 @@ function WalletsPage() {
|
|
|
2199
2616
|
setWalletErrorMessage('Error: ' + e.message);
|
|
2200
2617
|
}
|
|
2201
2618
|
};
|
|
2619
|
+
React.useEffect(() => {
|
|
2620
|
+
toggleConnectWalletsButton();
|
|
2621
|
+
return () => toggleConnectWalletsButton();
|
|
2622
|
+
}, []);
|
|
2202
2623
|
return React__default.createElement(ui.SecondaryPage, {
|
|
2203
2624
|
title: "Select Wallet",
|
|
2204
2625
|
textField: false,
|
|
2205
|
-
onBack: ()
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
})))))
|
|
2215
|
-
});
|
|
2626
|
+
onBack: navigateBackFrom.bind(null, navigationRoutes.wallets)
|
|
2627
|
+
}, React__default.createElement(React__default.Fragment, null, walletErrorMessage && React__default.createElement(AlertContainer, null, React__default.createElement(ui.Alert, {
|
|
2628
|
+
type: "error"
|
|
2629
|
+
}, React__default.createElement(ui.Typography, {
|
|
2630
|
+
variant: "body2"
|
|
2631
|
+
}, walletErrorMessage))), React__default.createElement(ListContainer, null, wallets.map((info, index) => React__default.createElement(ui.Wallet, Object.assign({}, info, {
|
|
2632
|
+
key: index,
|
|
2633
|
+
onClick: onSelectWallet
|
|
2634
|
+
}))))));
|
|
2216
2635
|
}
|
|
2217
2636
|
|
|
2218
2637
|
function ConfirmWalletsPage() {
|
|
2219
2638
|
const navigate = reactRouterDom.useNavigate();
|
|
2639
|
+
const {
|
|
2640
|
+
navigateBackFrom
|
|
2641
|
+
} = useNavigateBack();
|
|
2220
2642
|
const bestRoute = useBestRouteStore.use.bestRoute();
|
|
2221
2643
|
const {
|
|
2222
2644
|
blockchains
|
|
@@ -2230,10 +2652,14 @@ function ConfirmWalletsPage() {
|
|
|
2230
2652
|
connect
|
|
2231
2653
|
} = walletsCore.useWallets();
|
|
2232
2654
|
const confirmDisabled = !requiredWallets(bestRoute).every(chain => selectedWallets.map(wallet => wallet.chain).includes(chain));
|
|
2655
|
+
const firstStep = bestRoute?.result?.swaps[0];
|
|
2656
|
+
const lastStep = bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1];
|
|
2657
|
+
const fromAmount = decimalNumber(firstStep?.fromAmount, 3);
|
|
2658
|
+
const toAmount = decimalNumber(lastStep?.toAmount, 3);
|
|
2233
2659
|
React.useEffect(() => {
|
|
2234
2660
|
initSelectedWallets();
|
|
2235
2661
|
}, []);
|
|
2236
|
-
const selectableWallets = getSelectableWallets(accounts, selectedWallets, getWalletInfo
|
|
2662
|
+
const selectableWallets = getSelectableWallets(accounts, selectedWallets, getWalletInfo);
|
|
2237
2663
|
const handleConnectChain = wallet => {
|
|
2238
2664
|
const network = wallet;
|
|
2239
2665
|
getKeplrCompatibleConnectedWallets(selectableWallets).forEach(compatibleWallet => connect?.(compatibleWallet, network));
|
|
@@ -2241,9 +2667,11 @@ function ConfirmWalletsPage() {
|
|
|
2241
2667
|
return React__default.createElement(ui.ConfirmWallets, {
|
|
2242
2668
|
requiredWallets: getRequiredChains(bestRoute),
|
|
2243
2669
|
selectableWallets: selectableWallets,
|
|
2244
|
-
onBack: (
|
|
2670
|
+
onBack: navigateBackFrom.bind(null, navigationRoutes.confirmWallets),
|
|
2245
2671
|
swap: bestRoute,
|
|
2246
|
-
|
|
2672
|
+
fromAmount: fromAmount,
|
|
2673
|
+
toAmount: toAmount,
|
|
2674
|
+
onConfirm: navigate.bind(null, navigationRoutes.confirmSwap),
|
|
2247
2675
|
onChange: wallet => setSelectedWallet(wallet),
|
|
2248
2676
|
confirmDisabled: confirmDisabled,
|
|
2249
2677
|
handleConnectChain: wallet => handleConnectChain(wallet),
|
|
@@ -2714,9 +3142,11 @@ const pendingSwap$1 = {
|
|
|
2714
3142
|
};
|
|
2715
3143
|
|
|
2716
3144
|
function SwapDetailsPage() {
|
|
2717
|
-
const
|
|
3145
|
+
const {
|
|
3146
|
+
navigateBackFrom
|
|
3147
|
+
} = useNavigateBack();
|
|
2718
3148
|
return React__default.createElement(ui.SwapHistory, {
|
|
2719
|
-
onBack:
|
|
3149
|
+
onBack: navigateBackFrom.bind(null, navigationRoutes.swapDetails),
|
|
2720
3150
|
pendingSwap: pendingSwap$1
|
|
2721
3151
|
});
|
|
2722
3152
|
}
|
|
@@ -2789,8 +3219,9 @@ function Layout() {
|
|
|
2789
3219
|
const {
|
|
2790
3220
|
getWalletInfo
|
|
2791
3221
|
} = walletsCore.useWallets();
|
|
2792
|
-
const
|
|
3222
|
+
const connectedWalletsImages = removeDuplicateFrom(getSelectableWallets(accounts, selectedWallets, getWalletInfo).map(w => w.image));
|
|
2793
3223
|
const totalBalance = calculateWalletUsdValue(balances);
|
|
3224
|
+
const connectWalletsButtonDisabled = useUiStore.use.connectWalletsButtonDisabled();
|
|
2794
3225
|
return React__default.createElement(React__default.Fragment, null, React__default.createElement(Header$1, null, React__default.createElement(ui.Button, {
|
|
2795
3226
|
size: "small",
|
|
2796
3227
|
suffix: React__default.createElement(ui.AddWalletIcon, {
|
|
@@ -2798,10 +3229,12 @@ function Layout() {
|
|
|
2798
3229
|
}),
|
|
2799
3230
|
variant: "ghost",
|
|
2800
3231
|
flexContent: true,
|
|
2801
|
-
onClick: () =>
|
|
2802
|
-
|
|
3232
|
+
onClick: () => {
|
|
3233
|
+
if (!connectWalletsButtonDisabled) navigate(navigationRoutes.wallets);
|
|
3234
|
+
}
|
|
3235
|
+
}, connectedWalletsImages?.length ? connectedWalletsImages.map((walletImage, index) => React__default.createElement(WalletImage, {
|
|
2803
3236
|
key: index,
|
|
2804
|
-
src:
|
|
3237
|
+
src: walletImage
|
|
2805
3238
|
})) : React__default.createElement(React__default.Fragment, null), React__default.createElement(ui.Typography, {
|
|
2806
3239
|
variant: "body2"
|
|
2807
3240
|
}, !accounts?.length ? 'Connect Wallet' : `$${totalBalance || 0}`))), React__default.createElement(AppRoutes, null));
|