@rango-dev/widget-embedded 0.1.10-next.72 → 0.1.10-next.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/App.d.ts +20 -0
  2. package/dist/App.d.ts.map +1 -0
  3. package/dist/components/AppRouter.d.ts +3 -0
  4. package/dist/components/AppRouter.d.ts.map +1 -0
  5. package/dist/components/AppRoutes.d.ts +3 -0
  6. package/dist/components/AppRoutes.d.ts.map +1 -0
  7. package/dist/components/BottomLogo.d.ts +2 -0
  8. package/dist/components/BottomLogo.d.ts.map +1 -0
  9. package/dist/components/Footer.d.ts +2 -0
  10. package/dist/components/Footer.d.ts.map +1 -0
  11. package/dist/components/Header.d.ts +6 -0
  12. package/dist/components/Header.d.ts.map +1 -0
  13. package/dist/components/HeaderButtons.d.ts +3 -0
  14. package/dist/components/HeaderButtons.d.ts.map +1 -0
  15. package/dist/components/Layout.d.ts +2 -0
  16. package/dist/components/Layout.d.ts.map +1 -0
  17. package/dist/components/SwitchFromAndTo.d.ts +4 -0
  18. package/dist/components/SwitchFromAndTo.d.ts.map +1 -0
  19. package/dist/components/TokenInfo.d.ts +17 -0
  20. package/dist/components/TokenInfo.d.ts.map +1 -0
  21. package/dist/components/UpdateUrl.d.ts +2 -0
  22. package/dist/components/UpdateUrl.d.ts.map +1 -0
  23. package/dist/constants/errors.d.ts +4 -0
  24. package/dist/constants/errors.d.ts.map +1 -0
  25. package/dist/constants/navigationRoutes.d.ts +15 -0
  26. package/dist/constants/navigationRoutes.d.ts.map +1 -0
  27. package/dist/constants/numbers.d.ts +3 -0
  28. package/dist/constants/numbers.d.ts.map +1 -0
  29. package/dist/constants/searchParams.d.ts +8 -0
  30. package/dist/constants/searchParams.d.ts.map +1 -0
  31. package/dist/globalStyles.d.ts +2 -0
  32. package/dist/globalStyles.d.ts.map +1 -0
  33. package/dist/hooks/useBestRoute.d.ts +8 -0
  34. package/dist/hooks/useBestRoute.d.ts.map +1 -0
  35. package/dist/hooks/useConfirmSwap.d.ts +12 -0
  36. package/dist/hooks/useConfirmSwap.d.ts.map +1 -0
  37. package/dist/hooks/useTheme.d.ts +4 -0
  38. package/dist/hooks/useTheme.d.ts.map +1 -0
  39. package/dist/index.d.ts +2 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +8 -0
  42. package/dist/lib.d.ts +3 -0
  43. package/dist/lib.d.ts.map +1 -0
  44. package/dist/mockData/pendingSwap.d.ts +2 -0
  45. package/dist/mockData/pendingSwap.d.ts.map +1 -0
  46. package/dist/pages/ConfirmSwapPage.d.ts +2 -0
  47. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -0
  48. package/dist/pages/ConfirmWalletsPage.d.ts +7 -0
  49. package/dist/pages/ConfirmWalletsPage.d.ts.map +1 -0
  50. package/dist/pages/HistoryPage.d.ts +4 -0
  51. package/dist/pages/HistoryPage.d.ts.map +1 -0
  52. package/dist/pages/Home.d.ts +2 -0
  53. package/dist/pages/Home.d.ts.map +1 -0
  54. package/dist/pages/LiquiditySourcesPage.d.ts +2 -0
  55. package/dist/pages/LiquiditySourcesPage.d.ts.map +1 -0
  56. package/dist/pages/SelectChainPage.d.ts +6 -0
  57. package/dist/pages/SelectChainPage.d.ts.map +1 -0
  58. package/dist/pages/SelectTokenPage.d.ts +13 -0
  59. package/dist/pages/SelectTokenPage.d.ts.map +1 -0
  60. package/dist/pages/SettingsPage.d.ts +2 -0
  61. package/dist/pages/SettingsPage.d.ts.map +1 -0
  62. package/dist/pages/SwapDetailsPage.d.ts +2 -0
  63. package/dist/pages/SwapDetailsPage.d.ts.map +1 -0
  64. package/dist/pages/WalletsPage.d.ts +2 -0
  65. package/dist/pages/WalletsPage.d.ts.map +1 -0
  66. package/dist/services/httpService.d.ts +3 -0
  67. package/dist/services/httpService.d.ts.map +1 -0
  68. package/dist/store/bestRoute.d.ts +2 -0
  69. package/dist/store/bestRoute.d.ts.map +1 -0
  70. package/dist/store/meta.d.ts +9 -0
  71. package/dist/store/meta.d.ts.map +1 -0
  72. package/dist/store/selectors.d.ts +11 -0
  73. package/dist/store/selectors.d.ts.map +1 -0
  74. package/dist/store/settings.d.ts +2 -0
  75. package/dist/store/settings.d.ts.map +1 -0
  76. package/dist/store/wallets.d.ts +28 -0
  77. package/dist/store/wallets.d.ts.map +1 -0
  78. package/dist/swapBox.d.ts +3 -0
  79. package/dist/swapBox.d.ts.map +1 -0
  80. package/dist/utils/common.d.ts +2 -0
  81. package/dist/utils/common.d.ts.map +1 -0
  82. package/dist/utils/numbers.d.ts +9 -0
  83. package/dist/utils/numbers.d.ts.map +1 -0
  84. package/dist/utils/routing.d.ts +14 -0
  85. package/dist/utils/routing.d.ts.map +1 -0
  86. package/dist/utils/swap.d.ts +15 -0
  87. package/dist/utils/swap.d.ts.map +1 -0
  88. package/dist/utils/wallets.d.ts +23 -0
  89. package/dist/utils/wallets.d.ts.map +1 -0
  90. package/dist/widget-embedded.cjs.development.js +2868 -0
  91. package/dist/widget-embedded.cjs.development.js.map +1 -0
  92. package/dist/widget-embedded.cjs.production.min.js +2868 -0
  93. package/dist/widget-embedded.cjs.production.min.js.map +1 -0
  94. package/dist/widget-embedded.esm.js +2860 -0
  95. package/dist/widget-embedded.esm.js.map +1 -0
  96. package/package.json +5 -5
@@ -0,0 +1,2860 @@
1
+ import { WalletState, ConfirmSwap, History, Tooltip, Button, RetryIcon, HistoryIcon, SettingsIcon, styled, Typography, InfoCircleIcon, AngleDownIcon, TextField, VerticalSwapIcon, BestRoute, Alert, LiquiditySourcesSelector, BlockchainSelector, TokenSelector, Settings, SecondaryPage, Wallet, ConfirmWallets, SwapHistory, AddWalletIcon, globalCss, lightTheme, darkTheme, SwapContainer } from '@rango-dev/ui';
2
+ import React, { useRef, useEffect, Fragment, useState } from 'react';
3
+ import { useInRouterContext, MemoryRouter } from 'react-router';
4
+ import { useSearchParams, useLocation, useNavigate, useInRouterContext as useInRouterContext$1, useRoutes } from 'react-router-dom';
5
+ import { create } from 'zustand';
6
+ import { immer } from 'zustand/middleware/immer';
7
+ import BigNumber, { BigNumber as BigNumber$1 } from 'bignumber.js';
8
+ import { RangoClient, TransactionType } from 'rango-sdk';
9
+ import { readAccountAddress, useWallets, Provider, Events } from '@rango-dev/wallets-core';
10
+ import { allProviders } from '@rango-dev/provider-all';
11
+ import { Network, isEvmAddress, WalletType, isEvmBlockchain } from '@rango-dev/wallets-shared';
12
+ import { persist } from 'zustand/middleware';
13
+ import { styled as styled$1 } from '@rango-dev/ui/src/theme';
14
+
15
+ const ZERO = /*#__PURE__*/new BigNumber(0);
16
+
17
+ const numberToString = function (number, minDecimals, maxDecimals) {
18
+ if (minDecimals === void 0) {
19
+ minDecimals = null;
20
+ }
21
+ if (maxDecimals === void 0) {
22
+ maxDecimals = null;
23
+ }
24
+ if (number === null) return '';
25
+ if (number === '') return '';
26
+ const n = new BigNumber$1(number);
27
+ const roundingMode = 1;
28
+ let maxI = 1000;
29
+ for (let i = 0; i < 60; i++) {
30
+ if (new BigNumber$1(n.toFixed(i, roundingMode)).eq(n)) {
31
+ maxI = i;
32
+ break;
33
+ }
34
+ }
35
+ if (n.gte(10000)) return n.toFormat(0, roundingMode);
36
+ if (n.gte(1000)) return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 1))), roundingMode);
37
+ if (n.gte(100)) return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 1))), roundingMode);
38
+ if (n.gte(1)) return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 2))), roundingMode);
39
+ if (n.gte(0.01)) return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 4))), roundingMode);
40
+ 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);
41
+ if (n.isEqualTo(0)) return '0';
42
+ return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 8))), roundingMode);
43
+ };
44
+
45
+ const getBestRouteToTokenUsdPrice = bestRoute => bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1].to.usdPrice;
46
+ const compareRoutes = (route1, route2, inputAmount, fromTokenUsdPrice, toTokenUsdPrice) => {
47
+ let outUsdValue = (new BigNumber(route2.result?.outputAmount || '0') || ZERO).multipliedBy(toTokenUsdPrice || 0);
48
+ if (outUsdValue.isNaN()) outUsdValue = ZERO;
49
+ let inUsdValue = new BigNumber(inputAmount || '0').multipliedBy(fromTokenUsdPrice || 0);
50
+ if (inUsdValue.isNaN()) inUsdValue = ZERO;
51
+ const outToInRatio = inUsdValue === null || inUsdValue.lte(ZERO) ? 0 : outUsdValue === null || outUsdValue.lte(ZERO) ? 0 : outUsdValue.div(inUsdValue).minus(1).multipliedBy(100);
52
+ const disableSwapButton = parseInt(outToInRatio?.toFixed(2) || '0') <= -10 && (inUsdValue === null || inUsdValue.gte(new BigNumber(400))) || parseInt(outToInRatio?.toFixed(2) || '0') <= -5 && (inUsdValue === null || inUsdValue.gte(new BigNumber(1000)));
53
+ if (disableSwapButton) {
54
+ return {
55
+ isChanged: true,
56
+ warningMessage: 'Route updated and price impact is too high, try again later!'
57
+ };
58
+ }
59
+ const out1 = route1.result?.outputAmount || null;
60
+ const out2 = route2.result?.outputAmount || null;
61
+ if (!!out1 && !!out2) {
62
+ const changePercent = new BigNumber(out2).div(new BigNumber(out1)).minus(1).multipliedBy(100);
63
+ if (changePercent.toNumber() <= -1) {
64
+ return {
65
+ isChanged: true,
66
+ warningMessage: `Output amount changed to ${numberToString(out2)}
67
+ (${numberToString(changePercent, null, 2)}% change).`
68
+ };
69
+ }
70
+ }
71
+ const route1Swaps = route1.result?.swaps || [];
72
+ const route2Swaps = route2.result?.swaps || [];
73
+ if (route1Swaps.length !== route2Swaps.length) return {
74
+ isChanged: true,
75
+ warningMessage: 'Route has been updated.'
76
+ };else {
77
+ for (let i = 0; i < route1Swaps.length; i++) {
78
+ if (route1Swaps[i].swapperId !== route2Swaps[i].swapperId) return {
79
+ isChanged: true,
80
+ warningMessage: 'Route swappers has been updated.'
81
+ };else if (route1Swaps[i].to.symbol !== route2Swaps[i].to.symbol) return {
82
+ isChanged: true,
83
+ warningMessage: 'Route internal coins has been updated.'
84
+ };
85
+ }
86
+ }
87
+ return {
88
+ isChanged: false
89
+ };
90
+ };
91
+ const getRequiredBalanceOfWallet = (wallet, fee) => {
92
+ if (fee === null) return null;
93
+ const relatedFeeStatus = fee?.find(item => item.blockchain === wallet.chain)?.wallets.find(it => it.address?.toLowerCase() === wallet.address.toLowerCase());
94
+ if (!relatedFeeStatus) return null;
95
+ return relatedFeeStatus.requiredAssets;
96
+ };
97
+
98
+ const createSelectors = _store => {
99
+ let store = _store;
100
+ store.use = {};
101
+ for (let k of Object.keys(store.getState())) {
102
+ store.use[k] = () => store(s => s[k]);
103
+ }
104
+ return store;
105
+ };
106
+
107
+ const getUsdValue = (token, amount) => new BigNumber(amount || ZERO).multipliedBy(token?.usdPrice || 0);
108
+ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/create()( /*#__PURE__*/immer(set => ({
109
+ fromChain: null,
110
+ fromToken: null,
111
+ inputAmount: '',
112
+ outputAmount: null,
113
+ inputUsdValue: new BigNumber(0),
114
+ outputUsdValue: new BigNumber(0),
115
+ toChain: null,
116
+ toToken: null,
117
+ bestRoute: null,
118
+ setBestRoute: bestRoute => set(state => {
119
+ state.bestRoute = bestRoute;
120
+ if (!!bestRoute) {
121
+ const outputAmount = !!bestRoute.result?.outputAmount ? new BigNumber(bestRoute.result?.outputAmount) : null;
122
+ state.outputAmount = outputAmount;
123
+ state.outputUsdValue = new BigNumber(outputAmount || ZERO).multipliedBy(getBestRouteToTokenUsdPrice(bestRoute) || state.toToken?.usdPrice || 0);
124
+ }
125
+ }),
126
+ setFromChain: chain => set(state => {
127
+ state.fromChain = chain;
128
+ }),
129
+ setFromToken: token => set(state => {
130
+ state.fromToken = token;
131
+ if (!!state.inputAmount) state.inputUsdValue = getUsdValue(state.fromToken, state.inputAmount);
132
+ }),
133
+ setToChain: chain => set(state => {
134
+ state.toChain = chain;
135
+ }),
136
+ setToToken: token => set(state => {
137
+ state.toToken = token;
138
+ }),
139
+ setInputAmount: amount => set(state => {
140
+ state.inputAmount = amount;
141
+ if (!!state.fromToken) state.inputUsdValue = getUsdValue(state.fromToken, state.inputAmount);
142
+ })
143
+ }))));
144
+
145
+ const httpService = /*#__PURE__*/new RangoClient(process.env.REACT_API_KEY);
146
+
147
+ function removeDuplicateFrom(array) {
148
+ return Array.from(new Set(array));
149
+ }
150
+
151
+ const useMetaStore = /*#__PURE__*/createSelectors( /*#__PURE__*/create()(set => ({
152
+ meta: {
153
+ blockchains: [],
154
+ popularTokens: [],
155
+ swappers: [],
156
+ tokens: []
157
+ },
158
+ loadingStatus: 'loading',
159
+ fetchMeta: async () => {
160
+ try {
161
+ const response = await httpService.getAllMetadata();
162
+ const chainThatHasTokenInMetaResponse = removeDuplicateFrom(response.tokens.map(t => t.blockchain));
163
+ const enabledChains = response.blockchains.filter(chain => chain.enabled && chainThatHasTokenInMetaResponse.includes(chain.name));
164
+ response.blockchains = enabledChains.sort((a, b) => a.sort - b.sort);
165
+ set({
166
+ meta: response,
167
+ loadingStatus: 'success'
168
+ });
169
+ } catch (error) {
170
+ set({
171
+ loadingStatus: 'failed'
172
+ });
173
+ }
174
+ }
175
+ })));
176
+
177
+ var SearchParams;
178
+ (function (SearchParams) {
179
+ SearchParams["FROM_CHAIN"] = "fromChain";
180
+ SearchParams["FROM_TOKEN"] = "fromToken";
181
+ SearchParams["TO_CHAIN"] = "toChain";
182
+ SearchParams["TO_TOKEN"] = "toToken";
183
+ SearchParams["FROM_AMOUNT"] = "fromAmount";
184
+ })(SearchParams || (SearchParams = {}));
185
+
186
+ function searchParamsToToken(tokens, searchParams) {
187
+ return tokens.find(token => {
188
+ const symbolAndAddress = searchParams?.split('--');
189
+ if (symbolAndAddress?.length === 1) return token.symbol === symbolAndAddress[0] && token.address === null;
190
+ return token.symbol === symbolAndAddress?.[0] && token.address === symbolAndAddress?.[1];
191
+ }) || null;
192
+ }
193
+ function UpdateUrl() {
194
+ const firstRender = useRef(true);
195
+ const [searchParams, setSearchParams] = useSearchParams();
196
+ const location = useLocation();
197
+ const fromChain = useBestRouteStore.use.fromChain();
198
+ const toChain = useBestRouteStore.use.toChain();
199
+ const fromToken = useBestRouteStore.use.fromToken();
200
+ const toToken = useBestRouteStore.use.toToken();
201
+ const setFromChain = useBestRouteStore.use.setFromChain();
202
+ const setFromToken = useBestRouteStore.use.setFromToken();
203
+ const setToChain = useBestRouteStore.use.setToChain();
204
+ const setToToken = useBestRouteStore.use.setToToken();
205
+ const inputAmount = useBestRouteStore.use.inputAmount();
206
+ const setInputAmount = useBestRouteStore.use.setInputAmount();
207
+ const loadingStatus = useMetaStore.use.loadingStatus();
208
+ const {
209
+ blockchains,
210
+ tokens
211
+ } = useMetaStore.use.meta();
212
+ useEffect(() => {
213
+ if (!firstRender.current) {
214
+ const fromChainString = fromChain?.name || '';
215
+ const fromTokenString = (fromToken?.symbol || '') + (fromToken?.address ? `--${fromToken?.address}` : '');
216
+ const toChainString = toChain?.name || '';
217
+ const toTokenString = (toToken?.symbol || '') + (toToken?.address ? `--${toToken?.address}` : '');
218
+ const fromAmount = inputAmount;
219
+ setSearchParams({
220
+ ...(fromChainString && {
221
+ [SearchParams.FROM_CHAIN]: fromChainString
222
+ }),
223
+ ...(fromTokenString && {
224
+ [SearchParams.FROM_TOKEN]: fromTokenString
225
+ }),
226
+ ...(toChainString && {
227
+ [SearchParams.TO_CHAIN]: toChainString
228
+ }),
229
+ ...(toTokenString && {
230
+ [SearchParams.TO_TOKEN]: toTokenString
231
+ }),
232
+ ...(fromAmount && {
233
+ [SearchParams.FROM_AMOUNT]: fromAmount.toString()
234
+ })
235
+ }, {
236
+ replace: true
237
+ });
238
+ }
239
+ firstRender.current = false;
240
+ }, [location.pathname, inputAmount]);
241
+ useEffect(() => {
242
+ if (loadingStatus === 'success') {
243
+ const fronChainString = searchParams.get(SearchParams.FROM_CHAIN);
244
+ const fromTokenString = searchParams.get(SearchParams.FROM_TOKEN);
245
+ const toChainString = searchParams.get(SearchParams.TO_CHAIN);
246
+ const toTokenString = searchParams.get(SearchParams.TO_TOKEN);
247
+ const fromAmount = searchParams.get(SearchParams.FROM_AMOUNT);
248
+ const fromChain = blockchains.find(blockchain => blockchain.name === fronChainString);
249
+ const fromToken = searchParamsToToken(tokens, fromTokenString);
250
+ const toChain = blockchains.find(blockchain => blockchain.name === toChainString);
251
+ const toToken = searchParamsToToken(tokens, toTokenString);
252
+ if (!!fromChain) {
253
+ setFromChain(fromChain);
254
+ if (!!fromToken) setFromToken(fromToken);
255
+ }
256
+ if (!!toChain) {
257
+ setToChain(toChain);
258
+ if (!!toToken) setToToken(toToken);
259
+ }
260
+ if (fromAmount) setInputAmount(fromAmount);
261
+ }
262
+ }, [loadingStatus]);
263
+ return null;
264
+ }
265
+
266
+ function AppRouter(_ref) {
267
+ let {
268
+ children
269
+ } = _ref;
270
+ const isRouterInContext = useInRouterContext();
271
+ const Router = isRouterInContext ? Fragment : MemoryRouter;
272
+ return React.createElement(React.Fragment, null, React.createElement(Router, null, children), isRouterInContext && React.createElement(UpdateUrl, null));
273
+ }
274
+
275
+ function getStateWallet(state) {
276
+ switch (true) {
277
+ case state.connected:
278
+ return WalletState.CONNECTED;
279
+ case state.connecting:
280
+ return WalletState.CONNECTING;
281
+ case !state.installed:
282
+ return WalletState.NOT_INSTALLED;
283
+ default:
284
+ return WalletState.DISCONNECTED;
285
+ }
286
+ }
287
+ function getlistWallet(getState, getWalletInfo, list) {
288
+ const excludedWallets = [WalletType.UNKNOWN, WalletType.TERRA_STATION, WalletType.LEAP];
289
+ return list.filter(wallet => !excludedWallets.includes(wallet)).map(type => {
290
+ const {
291
+ name,
292
+ img: image,
293
+ installLink
294
+ } = getWalletInfo(type);
295
+ const state = getStateWallet(getState(type));
296
+ return {
297
+ name,
298
+ image,
299
+ installLink,
300
+ state,
301
+ type
302
+ };
303
+ });
304
+ }
305
+ function walletAndSupportedChainsNames(supportedChains) {
306
+ if (!supportedChains) return null;
307
+ let walletAndSupportedChainsNames = [];
308
+ walletAndSupportedChainsNames = supportedChains.map(blockchainMeta => blockchainMeta.name);
309
+ return walletAndSupportedChainsNames;
310
+ }
311
+ function prepareAccountsForWalletStore(wallet, accounts, evmBasedChains, supportedChainNames) {
312
+ const result = [];
313
+ function addAccount(network, address) {
314
+ const newAccount = {
315
+ address,
316
+ chain: network,
317
+ walletType: wallet
318
+ };
319
+ result.push(newAccount);
320
+ }
321
+ const supportedChains = supportedChainNames || [];
322
+ accounts.forEach(account => {
323
+ const {
324
+ address,
325
+ network
326
+ } = readAccountAddress(account);
327
+ const hasLimitation = supportedChains.length > 0;
328
+ const isSupported = supportedChains.includes(network);
329
+ const isUnknown = network === Network.Unknown;
330
+ const notSupportedNetworkByWallet = hasLimitation && !isSupported && !isUnknown;
331
+ // Here we check given `network` is not supported by wallet
332
+ // And also the network is known.
333
+ if (notSupportedNetworkByWallet) return;
334
+ // In some cases we can handle unknown network by checking its address
335
+ // pattern and act on it.
336
+ // Example: showing our evm compatible netwrok when the uknown network is evem.
337
+ // Otherwise, we stop executing this function.
338
+ const isUknownAndEvmBased = network === Network.Unknown && isEvmAddress(address);
339
+ if (isUnknown && !isUknownAndEvmBased) return;
340
+ const isEvmBasedChain = evmBasedChains.includes(network);
341
+ // If it's an evm network, we will add the address to all the evm chains.
342
+ if (isEvmBasedChain || isUknownAndEvmBased) {
343
+ // all evm chains are not supported in wallets, so we are adding
344
+ // only to those that are supported by wallet.
345
+ const evmChainsSupportedByWallet = supportedChains.filter(chain => evmBasedChains.includes(chain));
346
+ evmChainsSupportedByWallet.forEach(network => {
347
+ // EVM addresses are not case sensetive.
348
+ // Some wallets like Binance-chain return some letters in uppercase which produces bugs in our wallet state.
349
+ addAccount(network, address.toLowerCase());
350
+ });
351
+ } else {
352
+ addAccount(network, address);
353
+ }
354
+ });
355
+ return result;
356
+ }
357
+ function getRequiredChains(route) {
358
+ const wallets = [];
359
+ route?.result?.swaps.forEach(swap => {
360
+ const currentStepFromBlockchain = swap.from.blockchain;
361
+ const currentStepToBlockchain = swap.to.blockchain;
362
+ let lastAddedWallet = wallets[wallets.length - 1];
363
+ if (currentStepFromBlockchain != lastAddedWallet) wallets.push(currentStepFromBlockchain);
364
+ lastAddedWallet = wallets[wallets.length - 1];
365
+ if (currentStepToBlockchain != lastAddedWallet) wallets.push(currentStepToBlockchain);
366
+ });
367
+ return wallets;
368
+ }
369
+ function getSelectableWallets(accounts, selectedWallets, getWalletInfo, requiredChains) {
370
+ const connectedWallets = accounts.map(account => ({
371
+ address: account.address,
372
+ walletType: account.walletType,
373
+ chain: account.chain,
374
+ image: getWalletInfo(account.walletType).img,
375
+ selected: !!selectedWallets.find(wallet => wallet.chain === account.chain)
376
+ }));
377
+ return requiredChains ? connectedWallets.filter(wallet => requiredChains.includes(wallet.chain)) : removeDuplicateWallets(connectedWallets, 'walletType');
378
+ }
379
+ const removeDuplicateWallets = (arr, key) => {
380
+ return [...new Map(arr.map(item => [item[key], item])).values()];
381
+ };
382
+ function getBalanceFromWallet(balances, chain, symbol, address) {
383
+ if (balances.length === 0) return null;
384
+ const selectedChainBalances = balances.filter(balance => balance.chain === chain);
385
+ if (selectedChainBalances.length === 0) return null;
386
+ return selectedChainBalances.map(a => a.balances?.find(bl => address !== null && bl.address === address || address === null && bl.address === address && bl.symbol === symbol) || null).filter(b => b !== null).sort((a, b) => parseFloat(b?.amount || '0') - parseFloat(a?.amount || '1')).find(() => true) || null;
387
+ }
388
+ function isAccountAndBalanceMatched(account, balance) {
389
+ return account.address === balance.address && account.chain === balance.chain && account.walletType === balance.walletType;
390
+ }
391
+ function makeBalanceFor(account, retrivedBalance, tokens) {
392
+ const {
393
+ address,
394
+ blockChain: chain,
395
+ explorerUrl,
396
+ balances = []
397
+ } = retrivedBalance;
398
+ return {
399
+ address,
400
+ chain,
401
+ loading: false,
402
+ error: false,
403
+ explorerUrl,
404
+ walletType: account.walletType,
405
+ balances: balances?.map(tokenBalance => ({
406
+ chain,
407
+ symbol: tokenBalance.asset.symbol,
408
+ ticker: tokenBalance.asset.symbol,
409
+ address: tokenBalance.asset.address || null,
410
+ rawAmount: tokenBalance.amount.amount,
411
+ decimal: tokenBalance.amount.decimals,
412
+ amount: new BigNumber(tokenBalance.amount.amount).shiftedBy(-tokenBalance.amount.decimals).toFixed(),
413
+ logo: '',
414
+ usdPrice: getUsdPrice(chain, tokenBalance.asset.symbol, tokenBalance.asset.address, tokens) || null
415
+ })) || []
416
+ };
417
+ }
418
+ function resetBalanceState(balance) {
419
+ return {
420
+ ...balance,
421
+ loading: false,
422
+ error: true
423
+ };
424
+ }
425
+ const calculateWalletUsdValue = balance => {
426
+ const uniqueAccountAddresses = new Set();
427
+ const uniqueBalane = balance?.reduce((acc, current) => {
428
+ return acc.findIndex(i => i.address === current.address && i.chain === current.chain) === -1 ? [...acc, current] : acc;
429
+ }, []);
430
+ const modifiedWalletBlockchains = uniqueBalane?.map(chain => {
431
+ const modifiedWalletBlockchain = {
432
+ name: chain.chain,
433
+ accounts: []
434
+ };
435
+ if (!uniqueAccountAddresses.has(chain.address)) {
436
+ uniqueAccountAddresses.add(chain.address);
437
+ }
438
+ uniqueAccountAddresses.forEach(accountAddress => {
439
+ if (chain.address === accountAddress) modifiedWalletBlockchain.accounts.push(chain);
440
+ });
441
+ return modifiedWalletBlockchain;
442
+ });
443
+ const total = numberToString(modifiedWalletBlockchains?.flatMap(b => b.accounts)?.flatMap(a => a?.balances)?.map(b => new BigNumber(b?.amount || ZERO).multipliedBy(b?.usdPrice || 0))?.reduce((a, b) => a.plus(b), ZERO) || ZERO).toString();
444
+ console.log('total');
445
+ console.log(total);
446
+ return numberWithThousandSeperator(total);
447
+ };
448
+ function numberWithThousandSeperator(number) {
449
+ var parts = number.toString().split('.');
450
+ parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
451
+ return parts.join('.');
452
+ }
453
+ const sortedTokens = (tokens, position, balance) => {
454
+ if (!tokens) return [];
455
+ const walletSymbols = new Set((balance || []).flatMap(a => a.balances || []).filter(b => (new BigNumber(b?.rawAmount) || ZERO).gt(0)).map(b => `${b?.chain}.${b?.symbol}.${b?.address}`));
456
+ let sortedList = [...tokens.filter(t => !t.address && walletSymbols.size && position === 'to'), ...tokens.filter(t => !(position === 'to' && !t.address) && walletSymbols.has(`${t.blockchain}.${t.symbol}.${t.address}`)).sort((tokenA, tokenB) => compareBalance(tokenA, tokenB, balance)), ...tokens.filter(t => !walletSymbols.has(`${t.blockchain}.${t.symbol}.${t.address}`) && !t.address && (!walletSymbols.size || position === 'from')), ...tokens.filter(t => !walletSymbols.has(`${t.blockchain}.${t.symbol}.${t.address}`) && t.address && !t.isSecondaryCoin), ...tokens.filter(t => !walletSymbols.has(`${t.blockchain}.${t.symbol}.${t.address}`) && t.isSecondaryCoin)];
457
+ return sortedList;
458
+ };
459
+ const compareBalance = (tokenA, tokenB, wallet) => {
460
+ if (!tokenA.usdPrice || !tokenB.usdPrice) return 0;
461
+ const tokenAUsdValue = new BigNumber(getBalanceFromWallet(wallet, tokenA.blockchain, tokenA.symbol, tokenA.address)?.amount || ZERO).multipliedBy(tokenA.usdPrice);
462
+ const tokenBUsdValue = new BigNumber(getBalanceFromWallet(wallet, tokenB.blockchain, tokenB.symbol, tokenB.address)?.amount || ZERO).multipliedBy(tokenB.usdPrice);
463
+ if (tokenAUsdValue.gt(tokenBUsdValue)) return -1;
464
+ return 1;
465
+ };
466
+ const getUsdPrice = (blockchain, symbol, address, allTokens) => {
467
+ const token = allTokens?.find(t => t.blockchain === blockchain && t.symbol?.toUpperCase() === symbol?.toUpperCase() && t.address === address);
468
+ return token?.usdPrice || null;
469
+ };
470
+
471
+ const useWalletsStore = /*#__PURE__*/createSelectors( /*#__PURE__*/create()(set => ({
472
+ accounts: [],
473
+ balances: [],
474
+ selectedWallets: [],
475
+ connectWallet: accounts => {
476
+ const tokens = useMetaStore.getState().meta.tokens;
477
+ set(state => ({
478
+ accounts: state.accounts.concat(accounts),
479
+ balances: state.balances.concat(accounts.map(account => ({
480
+ balances: [],
481
+ address: account.address,
482
+ chain: account.chain,
483
+ loading: true,
484
+ walletType: account.walletType,
485
+ error: false,
486
+ explorerUrl: null
487
+ })))
488
+ }));
489
+ accounts.forEach(async account => {
490
+ try {
491
+ const response = await httpService.getWalletsDetails([{
492
+ address: account.address,
493
+ blockchain: account.chain
494
+ }]);
495
+ const retrivedBalance = response.wallets[0];
496
+ if (retrivedBalance) {
497
+ set(state => ({
498
+ balances: state.balances.map(balance => {
499
+ return isAccountAndBalanceMatched(account, balance) ? makeBalanceFor(account, retrivedBalance, tokens) : balance;
500
+ })
501
+ }));
502
+ } else throw new Error('Wallet not found');
503
+ } catch (error) {
504
+ set(state => ({
505
+ balances: state.balances.map(balance => {
506
+ return isAccountAndBalanceMatched(account, balance) ? resetBalanceState(balance) : balance;
507
+ })
508
+ }));
509
+ }
510
+ });
511
+ },
512
+ disconnectWallet: walletType => {
513
+ set(state => ({
514
+ accounts: state.accounts.filter(account => account.walletType !== walletType),
515
+ balances: state.balances.filter(balance => balance.walletType !== walletType),
516
+ selectedWallets: state.selectedWallets.filter(wallet => wallet.walletType != walletType)
517
+ }));
518
+ },
519
+ initSelectedWallets: () => set(state => {
520
+ const requiredChains = getRequiredChains(useBestRouteStore.getState().bestRoute);
521
+ const connectedWallets = state.accounts;
522
+ const selectedWallets = [];
523
+ requiredChains.forEach(chain => {
524
+ const anyWalletSelected = !!state.selectedWallets.find(wallet => wallet.chain === chain);
525
+ if (!anyWalletSelected) {
526
+ const firstWalletWithMatchedChain = connectedWallets.find(wallet => wallet.chain === chain);
527
+ if (!!firstWalletWithMatchedChain) selectedWallets.push({
528
+ address: firstWalletWithMatchedChain.address,
529
+ chain: firstWalletWithMatchedChain.chain,
530
+ walletType: firstWalletWithMatchedChain.walletType
531
+ });
532
+ }
533
+ });
534
+ return {
535
+ selectedWallets: state.selectedWallets.concat(selectedWallets)
536
+ };
537
+ }),
538
+ setSelectedWallet: wallet => set(state => ({
539
+ selectedWallets: state.selectedWallets.filter(selectedWallet => selectedWallet.chain !== wallet.chain).concat({
540
+ chain: wallet.chain,
541
+ address: wallet.address,
542
+ walletType: wallet.walletType
543
+ })
544
+ }))
545
+ })));
546
+
547
+ const navigationRoutes = {
548
+ home: '/',
549
+ fromChain: '/from-chain',
550
+ fromToken: '/from-token',
551
+ toChain: '/to-chain',
552
+ toToken: '/to-token',
553
+ settings: '/settings',
554
+ liquiditySources: '/liquidity-sources',
555
+ history: '/history',
556
+ wallets: '/wallets',
557
+ confirmSwap: '/confirm-swap',
558
+ confirmWallets: '/confirm-wallets',
559
+ swapDetails: '/swap-details'
560
+ };
561
+
562
+ const useSettingsStore = /*#__PURE__*/createSelectors( /*#__PURE__*/create()( /*#__PURE__*/persist( /*#__PURE__*/immer(set => ({
563
+ slippage: 1,
564
+ customSlippage: null,
565
+ infinitApprove: false,
566
+ disabledLiquiditySources: [],
567
+ theme: 'auto',
568
+ setSlippage: slippage => set(state => {
569
+ state.slippage = slippage;
570
+ }),
571
+ setCustomSlippage: customSlippage => {
572
+ return set(state => {
573
+ state.customSlippage = customSlippage;
574
+ });
575
+ },
576
+ toggleAllLiquiditySources: () => set(state => {
577
+ const {
578
+ swappers
579
+ } = useMetaStore.getState().meta;
580
+ if (swappers.length - state.disabledLiquiditySources.length === 0) state.disabledLiquiditySources = [];else {
581
+ const allSwappers = swappers.map(swapper => swapper.swapperGroup);
582
+ state.disabledLiquiditySources = allSwappers;
583
+ }
584
+ }),
585
+ toggleInfinitApprove: () => set(state => {
586
+ state.infinitApprove = !state.infinitApprove;
587
+ }),
588
+ toggleLiquiditySource: name => set(state => {
589
+ state.disabledLiquiditySources = state.disabledLiquiditySources.includes(name) ? state.disabledLiquiditySources.filter(liquiditySource => liquiditySource != name) : state.disabledLiquiditySources.concat(name);
590
+ }),
591
+ setTheme: theme => set(state => {
592
+ state.theme = theme;
593
+ })
594
+ })), {
595
+ name: 'user-settings'
596
+ })));
597
+
598
+ function getOutputRatio(inputUsdValue, outputUsdValue) {
599
+ if (inputUsdValue.lte(ZERO) || outputUsdValue.lte(ZERO)) return 0;
600
+ return outputUsdValue.div(inputUsdValue).minus(1).multipliedBy(100);
601
+ }
602
+ function outputRatioHasWarning(inputUsdValue, outputRatio) {
603
+ return parseInt(outputRatio.toFixed(2) || '0') <= -10 && inputUsdValue.gte(new BigNumber(400)) || parseInt(outputRatio.toFixed(2) || '0') <= -5 && inputUsdValue.gte(new BigNumber(1000));
604
+ }
605
+ function hasLimitError(bestRoute) {
606
+ return (bestRoute?.result?.swaps || []).filter(swap => {
607
+ const minimum = !!swap.fromAmountMinValue ? new BigNumber(swap.fromAmountMinValue) : null;
608
+ const maximum = !!swap.fromAmountMaxValue ? new BigNumber(swap.fromAmountMaxValue) : null;
609
+ const isExclusive = swap.fromAmountRestrictionType === 'EXCLUSIVE';
610
+ if (isExclusive) {
611
+ return minimum?.gte(swap.fromAmount) || maximum?.lte(swap.fromAmount);
612
+ } else {
613
+ return minimum?.gt(swap.fromAmount) || maximum?.lt(swap.fromAmount);
614
+ }
615
+ }).length > 0;
616
+ }
617
+ function getSwapButtonTitle(accounts, loading, hasLimitError, highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath) {
618
+ if (loading) return 'Finding Best Route...';
619
+ if (accounts.length == 0) return 'Connect Wallet';else if (hasLimitError) return 'Limit Error';else if (highValueLoss) return 'Price impact is too high!';else if (priceImpactCanNotBeComputed) return 'USD price is unknown, price impact might be high!';else if (needsToWarnEthOnPath) return 'The route goes through Ethereum. Continue?';else return 'Swap';
620
+ }
621
+ function canComputePriceImpact(bestRoute, inputAmount, inputUsdValue, outputUsdValue) {
622
+ return !((inputUsdValue.lte(ZERO) || outputUsdValue.lte(ZERO)) && !!bestRoute?.result && !!inputAmount && inputAmount !== '0' && parseFloat(inputAmount || '0') !== 0);
623
+ }
624
+ function calculatePendingSwap(inputAmount, bestRoute, wallets, settings, validateBalanceOrFee) {
625
+ const simulationResult = bestRoute.result;
626
+ if (!simulationResult) throw Error('Simulation result should not be null');
627
+ return {
628
+ creationTime: new Date().getTime().toString(),
629
+ finishTime: null,
630
+ requestId: bestRoute.requestId || '',
631
+ inputAmount: inputAmount,
632
+ wallets,
633
+ status: 'running',
634
+ isPaused: false,
635
+ extraMessage: null,
636
+ extraMessageSeverity: null,
637
+ extraMessageDetail: null,
638
+ extraMessageErrorCode: null,
639
+ networkStatusExtraMessage: null,
640
+ networkStatusExtraMessageDetail: null,
641
+ lastNotificationTime: null,
642
+ settings: settings,
643
+ simulationResult: simulationResult,
644
+ validateBalanceOrFee,
645
+ //TODO: finalize PendingSwap type and remove ts-ignore
646
+ //@ts-ignore
647
+ steps: bestRoute.result?.swaps?.map((s, i) => ({
648
+ id: i + 1,
649
+ fromBlockchain: s.from.blockchain,
650
+ fromSymbol: s.from.symbol,
651
+ fromSymbolAddress: s.from.address,
652
+ fromDecimals: s.from.decimals,
653
+ fromAmountPrecision: s.fromAmountPrecision,
654
+ fromAmountMinValue: s.fromAmountMinValue,
655
+ fromAmountMaxValue: s.fromAmountMaxValue,
656
+ toBlockchain: s.to.blockchain,
657
+ fromLogo: s.from.logo,
658
+ toSymbol: s.to.symbol,
659
+ toSymbolAddress: s.to.address,
660
+ toDecimals: s.to.decimals,
661
+ toLogo: s.to.logo,
662
+ startTransactionTime: new Date().getTime(),
663
+ swapperId: s.swapperId,
664
+ expectedOutputAmountHumanReadable: s.toAmount,
665
+ outputAmount: null,
666
+ status: 'created',
667
+ networkStatus: null,
668
+ executedTransactionId: null,
669
+ externalTransactionId: null,
670
+ explorerUrl: null,
671
+ trackingCode: null,
672
+ cosmosTransaction: null,
673
+ solanaTransaction: null,
674
+ starknetTransaction: null,
675
+ starknetApprovalTransaction: null,
676
+ tronTransaction: null,
677
+ tronApprovalTransaction: null,
678
+ evmTransaction: null,
679
+ evmApprovalTransaction: null,
680
+ transferTransaction: null,
681
+ diagnosisUrl: null,
682
+ internalSteps: null,
683
+ fromBlockchainLogo: '',
684
+ toBlockchainLogo: '',
685
+ swapperLogo: '',
686
+ swapperType: ''
687
+ })) || []
688
+ };
689
+ }
690
+ function requiredWallets(route) {
691
+ const wallets = [];
692
+ route?.result?.swaps.forEach(swap => {
693
+ const currentStepFromBlockchain = swap.from.blockchain;
694
+ const currentStepToBlockchain = swap.to.blockchain;
695
+ let lastAddedWallet = wallets[wallets.length - 1];
696
+ if (currentStepFromBlockchain != lastAddedWallet) wallets.push(currentStepFromBlockchain);
697
+ lastAddedWallet = wallets[wallets.length - 1];
698
+ if (currentStepToBlockchain != lastAddedWallet) wallets.push(currentStepToBlockchain);
699
+ });
700
+ return wallets;
701
+ }
702
+
703
+ function useConfirmSwap() {
704
+ const fromToken = useBestRouteStore.use.fromToken();
705
+ const toToken = useBestRouteStore.use.toToken();
706
+ const inputAmount = useBestRouteStore.use.inputAmount();
707
+ const bestRoute = useBestRouteStore.use.bestRoute();
708
+ const setBestRoute = useBestRouteStore.use.setBestRoute();
709
+ const accounts = useWalletsStore.use.accounts();
710
+ const selectedWallets = useWalletsStore.use.selectedWallets();
711
+ const slippage = useSettingsStore.use.slippage();
712
+ const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
713
+ const [loading, setLoading] = useState(false);
714
+ const [error, setError] = useState('');
715
+ const [warning, setWarning] = useState('');
716
+ const [data, setData] = useState(null);
717
+ const [feeStatus, setFeeStatus] = useState(null);
718
+ const [bestRouteChanged, setBestRouteChanged] = useState(false);
719
+ const [enoughBalance, setEnoughBalance] = useState(null);
720
+ const hasEnoughBalanceOrProperSlippage = (route, selectedWallets, userSlippage, routeChanged) => {
721
+ const fee = route.validationStatus;
722
+ if (fee === null || fee.length === 0) return {
723
+ balance: true,
724
+ slippage: true,
725
+ routeChanged
726
+ };
727
+ for (const wallet of selectedWallets) {
728
+ const requiredAssets = getRequiredBalanceOfWallet(wallet, fee);
729
+ if (!requiredAssets) continue;
730
+ const hasEnoughBalance = requiredAssets?.map(it => it.ok).reduce((a, b) => a && b);
731
+ if (!hasEnoughBalance) return {
732
+ balance: false,
733
+ slippage: true,
734
+ routeChanged
735
+ };
736
+ }
737
+ const slippages = route.result?.swaps?.map(s => s.recommendedSlippage);
738
+ const slippageError = (slippages?.filter(s => !!s?.error)?.length || 0) > 0;
739
+ const minSlippage = slippages?.map(s => parseFloat(s?.slippage.toString() || '0') || 0).filter(s => s > 0).sort((a, b) => b - a).find(() => true) || null;
740
+ if (slippageError) {
741
+ setError('Server cannot calculated required slippage for your swap');
742
+ return {
743
+ balance: true,
744
+ slippage: false,
745
+ routeChanged
746
+ };
747
+ } else if (minSlippage !== null && minSlippage > parseFloat(userSlippage)) {
748
+ setError(`Your slippage should be ${minSlippage} at least`);
749
+ return {
750
+ balance: true,
751
+ slippage: false,
752
+ routeChanged
753
+ };
754
+ }
755
+ return {
756
+ balance: true,
757
+ slippage: true,
758
+ routeChanged
759
+ };
760
+ };
761
+ const checkFeeAndBalance = async selectedWallets => {
762
+ setLoading(true);
763
+ setFeeStatus(null);
764
+ const selectedWalletsMap = selectedWallets.reduce((selectedWalletsMap, selectedWallet) => (selectedWalletsMap[selectedWallet.chain] = selectedWallet.address, selectedWalletsMap), {});
765
+ const connectedWallets = [];
766
+ accounts.forEach(account => {
767
+ const chainAndAccounts = connectedWallets.find(wallet => wallet.blockchain);
768
+ if (!!chainAndAccounts) chainAndAccounts.addresses.push(account.address);else connectedWallets.push({
769
+ blockchain: account.chain,
770
+ addresses: [account.address]
771
+ });
772
+ });
773
+ const r = await httpService.getBestRoute({
774
+ amount: inputAmount.toString(),
775
+ checkPrerequisites: true,
776
+ from: {
777
+ address: fromToken.address,
778
+ blockchain: fromToken.blockchain,
779
+ symbol: fromToken.symbol
780
+ },
781
+ to: {
782
+ address: toToken.address,
783
+ blockchain: toToken.blockchain,
784
+ symbol: toToken.symbol
785
+ },
786
+ connectedWallets,
787
+ selectedWallets: selectedWalletsMap,
788
+ //@ts-ignore
789
+ swapperGroups: disabledLiquiditySources,
790
+ swappersGroupsExclude: true
791
+ }).catch(error => {
792
+ setError(error.message);
793
+ setLoading(false);
794
+ });
795
+ setLoading(false);
796
+ if (!r || !r.result || !bestRoute) return {
797
+ bestRoute: null
798
+ };
799
+ if (!new BigNumber(r.requestAmount).isEqualTo(new BigNumber(inputAmount || '-1'))) return null;
800
+ setFeeStatus(r.validationStatus);
801
+ const routeChangeStatus = compareRoutes(bestRoute, r, inputAmount.toString(), fromToken.usdPrice, toToken.usdPrice);
802
+ setBestRoute(r);
803
+ const isChanged = routeChangeStatus.isChanged;
804
+ setBestRouteChanged(isChanged);
805
+ setWarning('Best route changed');
806
+ setData(r);
807
+ return {
808
+ hasEnoughBalanceOrSlippage: hasEnoughBalanceOrProperSlippage(r, selectedWallets, slippage.toString(), isChanged),
809
+ bestRoute: r
810
+ };
811
+ };
812
+ const swap = () => {
813
+ if (!bestRoute) return;
814
+ if (inputAmount.toString() === '') return;
815
+ const wallets = selectedWallets.reduce((selectedWalletsMap, selectedWallet) => (selectedWalletsMap[selectedWallet.chain] = {
816
+ address: selectedWallet.address,
817
+ walletType: selectedWallet.walletType
818
+ }, selectedWalletsMap), {});
819
+ const proceedAnyway = enoughBalance !== null;
820
+ const settings = {
821
+ slippage: slippage.toString(),
822
+ disabledSwappersGroups: ['Osmosis'],
823
+ disabledSwappersIds: []
824
+ };
825
+ if (proceedAnyway) {
826
+ const newSwap = calculatePendingSwap(inputAmount.toString(), bestRoute, wallets, settings, false);
827
+ }
828
+ !proceedAnyway && checkFeeAndBalance(selectedWallets).then(data => {
829
+ if (!data) {
830
+ setError('confirm swap error');
831
+ return;
832
+ }
833
+ if (!data.bestRoute) {
834
+ setError('confirm swap error');
835
+ return;
836
+ } else {
837
+ const {
838
+ hasEnoughBalanceOrSlippage,
839
+ bestRoute: newBestRoute
840
+ } = data;
841
+ if (!hasEnoughBalanceOrSlippage) {
842
+ return;
843
+ }
844
+ setEnoughBalance(hasEnoughBalanceOrSlippage.balance && hasEnoughBalanceOrSlippage.slippage);
845
+ if (hasEnoughBalanceOrSlippage.balance && hasEnoughBalanceOrSlippage.slippage && !hasEnoughBalanceOrSlippage.routeChanged) {
846
+ const newSwap = calculatePendingSwap(inputAmount.toString(), newBestRoute, wallets, settings, true);
847
+ } else if (!hasEnoughBalanceOrSlippage.balance) {
848
+ setError('not enough balance');
849
+ }
850
+ }
851
+ }).catch(error => {
852
+ console.log('unexpected error', error);
853
+ });
854
+ };
855
+ return {
856
+ loading,
857
+ error,
858
+ data,
859
+ warning,
860
+ feeStatus,
861
+ bestRouteChanged,
862
+ enoughBalance,
863
+ swap
864
+ };
865
+ }
866
+
867
+ function ConfirmSwapPage() {
868
+ const navigate = useNavigate();
869
+ const bestRoute = useBestRouteStore.use.bestRoute();
870
+ const {
871
+ error,
872
+ loading,
873
+ warning,
874
+ swap
875
+ } = useConfirmSwap();
876
+ return React.createElement(ConfirmSwap, {
877
+ onConfirm: swap.bind(null),
878
+ onBack: navigate.bind(null, -1),
879
+ bestRoute: bestRoute,
880
+ loading: loading,
881
+ error: error,
882
+ warning: warning
883
+ });
884
+ }
885
+
886
+ const pendingSwap = [{
887
+ creationTime: '1673164511955',
888
+ finishTime: '1673164550137',
889
+ requestId: '51e211d9-d61c-45d2-a4d4-1f9f7f90ee85',
890
+ inputAmount: '1',
891
+ wallets: {
892
+ OSMOSIS: {
893
+ walletType: 'keplr',
894
+ address: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl'
895
+ }
896
+ },
897
+ status: 'running',
898
+ isPaused: false,
899
+ extraMessage: null,
900
+ extraMessageSeverity: 'info',
901
+ extraMessageDetail: '',
902
+ extraMessageErrorCode: null,
903
+ networkStatusExtraMessage: null,
904
+ networkStatusExtraMessageDetail: null,
905
+ lastNotificationTime: null,
906
+ settings: {
907
+ slippage: '1.0',
908
+ disabledSwappersIds: [],
909
+ disabledSwappersGroups: []
910
+ },
911
+ simulationResult: {
912
+ outputAmount: '1.540670',
913
+ swaps: [{
914
+ swapperId: 'Osmosis',
915
+ swapperType: 'DEX',
916
+ swapperLogo: '',
917
+ // @ts-ignore
918
+ result: null,
919
+ from: {
920
+ symbol: 'JUNO',
921
+ logo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png',
922
+ address: 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed',
923
+ blockchain: 'OSMOSIS',
924
+ blockchainLogo: '',
925
+ decimals: 6,
926
+ usdPrice: 1.1091996179668873
927
+ },
928
+ to: {
929
+ symbol: 'OSMO',
930
+ logo: 'https://api.rango.exchange/i/mJQPS2',
931
+ address: null,
932
+ blockchain: 'OSMOSIS',
933
+ decimals: 6,
934
+ blockchainLogo: '',
935
+ usdPrice: 0.7192435454440882
936
+ },
937
+ fromAmount: '1.000000',
938
+ fromAmountPrecision: null,
939
+ fromAmountMinValue: null,
940
+ fromAmountMaxValue: null,
941
+ toAmount: '1.540670',
942
+ fee: [{
943
+ name: '',
944
+ asset: {
945
+ blockchain: 'OSMOSIS',
946
+ symbol: 'OSMO',
947
+ address: null
948
+ },
949
+ expenseType: 'FROM_SOURCE_WALLET',
950
+ amount: '0'
951
+ }],
952
+ estimatedTimeInSeconds: 45,
953
+ swapChainType: 'INTRA_CHAIN',
954
+ routes: [{
955
+ nodes: [{
956
+ nodes: [{
957
+ marketName: 'pool#498',
958
+ marketId: null,
959
+ percent: 1
960
+ }],
961
+ from: 'JUNO',
962
+ fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png',
963
+ fromAddress: 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed',
964
+ fromBlockchain: 'OSMOSIS',
965
+ to: 'ATOM',
966
+ toLogo: 'https://api.rango.exchange/tokens/COSMOS/ATOM.png',
967
+ toAddress: 'ibc/27394fb092d2eccd56123c74f36e4c1f926001ceada9ca97ea622b25f41e5eb2',
968
+ toBlockchain: 'OSMOSIS'
969
+ }, {
970
+ nodes: [{
971
+ marketName: 'pool#8',
972
+ marketId: null,
973
+ percent: 1
974
+ }],
975
+ from: 'ATOM',
976
+ fromLogo: 'https://api.rango.exchange/tokens/COSMOS/ATOM.png',
977
+ fromAddress: 'ibc/27394fb092d2eccd56123c74f36e4c1f926001ceada9ca97ea622b25f41e5eb2',
978
+ fromBlockchain: 'OSMOSIS',
979
+ to: 'IRIS',
980
+ toLogo: 'https://api.rango.exchange/tokens/COSMOS/IRIS.png',
981
+ toAddress: 'ibc/7c4d60aa95e5a7558b0a364860979ca34b7ff8aaf255b87af9e879374470cec0',
982
+ toBlockchain: 'OSMOSIS'
983
+ }, {
984
+ nodes: [{
985
+ marketName: 'pool#7',
986
+ marketId: null,
987
+ percent: 1
988
+ }],
989
+ from: 'IRIS',
990
+ fromLogo: 'https://api.rango.exchange/tokens/COSMOS/IRIS.png',
991
+ fromAddress: 'ibc/7c4d60aa95e5a7558b0a364860979ca34b7ff8aaf255b87af9e879374470cec0',
992
+ fromBlockchain: 'OSMOSIS',
993
+ to: 'OSMO',
994
+ toLogo: 'https://api.rango.exchange/tokens/COSMOS/OSMO.png',
995
+ toAddress: null,
996
+ toBlockchain: 'OSMOSIS'
997
+ }]
998
+ }],
999
+ recommendedSlippage: null,
1000
+ timeStat: {
1001
+ min: 6,
1002
+ avg: 40,
1003
+ max: 241
1004
+ },
1005
+ includesDestinationTx: false
1006
+ }]
1007
+ },
1008
+ validateBalanceOrFee: true,
1009
+ steps: [{
1010
+ id: 1,
1011
+ fromBlockchain: 'OSMOSIS',
1012
+ fromSymbol: 'JUNO',
1013
+ fromSymbolAddress: 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed',
1014
+ fromDecimals: 6,
1015
+ fromAmountPrecision: null,
1016
+ fromAmountMinValue: null,
1017
+ swapperLogo: '',
1018
+ swapperType: '',
1019
+ fromAmountMaxValue: null,
1020
+ toBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png',
1021
+ fromBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png',
1022
+ toBlockchain: 'OSMOSIS',
1023
+ fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png',
1024
+ toSymbol: 'OSMO',
1025
+ toSymbolAddress: null,
1026
+ toDecimals: 6,
1027
+ toLogo: 'https://api.rango.exchange/i/mJQPS2',
1028
+ startTransactionTime: 1673164519916,
1029
+ swapperId: 'Osmosis',
1030
+ expectedOutputAmountHumanReadable: '1.540670',
1031
+ outputAmount: '1.540658',
1032
+ status: 'running',
1033
+ networkStatus: null,
1034
+ executedTransactionId: '0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b',
1035
+ explorerUrl: [{
1036
+ url: 'https://www.mintscan.io/osmosis/txs/0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b',
1037
+ description: null
1038
+ }],
1039
+ cosmosTransaction: {
1040
+ type: TransactionType.COSMOS,
1041
+ fromWalletAddress: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl',
1042
+ blockChain: 'OSMOSIS',
1043
+ data: {
1044
+ chainId: 'osmosis-1',
1045
+ account_number: 102721,
1046
+ sequence: '308',
1047
+ msgs: [{
1048
+ __type: 'OsmosisSwapMessage',
1049
+ type: 'osmosis/gamm/swap-exact-amount-in',
1050
+ value: {
1051
+ sender: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl',
1052
+ routes: [{
1053
+ pool_id: '498',
1054
+ token_out_denom: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2'
1055
+ }, {
1056
+ pool_id: '8',
1057
+ token_out_denom: 'ibc/7C4D60AA95E5A7558B0A364860979CA34B7FF8AAF255B87AF9E879374470CEC0'
1058
+ }, {
1059
+ pool_id: '7',
1060
+ token_out_denom: 'uosmo'
1061
+ }],
1062
+ token_in: {
1063
+ denom: 'ibc/46B44899322F3CD854D2D46DEEF881958467CDD4B3B10086DA49296BBED94BED',
1064
+ amount: '1000000'
1065
+ },
1066
+ token_out_min_amount: '1525264'
1067
+ }
1068
+ }],
1069
+ protoMsgs: [{
1070
+ type_url: '/osmosis.gamm.v1beta1.MsgSwapExactAmountIn',
1071
+ 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]
1072
+ }],
1073
+ memo: '',
1074
+ source: null,
1075
+ fee: {
1076
+ gas: '900000',
1077
+ amount: [{
1078
+ denom: 'uosmo',
1079
+ amount: '0'
1080
+ }]
1081
+ },
1082
+ signType: 'AMINO',
1083
+ rpcUrl: ''
1084
+ },
1085
+ rawTransfer: null
1086
+ },
1087
+ solanaTransaction: null,
1088
+ evmTransaction: null,
1089
+ evmApprovalTransaction: null,
1090
+ transferTransaction: null,
1091
+ diagnosisUrl: null,
1092
+ internalSteps: null
1093
+ }]
1094
+ }, {
1095
+ creationTime: '1673164511955',
1096
+ finishTime: '1673164550137',
1097
+ requestId: '51e211d9-d61c-45d2-a4d4-1f9f7f90ee85',
1098
+ inputAmount: '1',
1099
+ wallets: {
1100
+ OSMOSIS: {
1101
+ walletType: 'keplr',
1102
+ address: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl'
1103
+ }
1104
+ },
1105
+ status: 'failed',
1106
+ isPaused: false,
1107
+ extraMessage: null,
1108
+ extraMessageSeverity: 'info',
1109
+ extraMessageDetail: '',
1110
+ extraMessageErrorCode: null,
1111
+ networkStatusExtraMessage: null,
1112
+ networkStatusExtraMessageDetail: null,
1113
+ lastNotificationTime: null,
1114
+ settings: {
1115
+ slippage: '1.0',
1116
+ disabledSwappersIds: [],
1117
+ disabledSwappersGroups: []
1118
+ },
1119
+ simulationResult: {
1120
+ outputAmount: '1.540670',
1121
+ swaps: [{
1122
+ swapperId: 'Osmosis',
1123
+ swapperLogo: '',
1124
+ // @ts-ignore
1125
+ result: null,
1126
+ swapperType: 'DEX',
1127
+ from: {
1128
+ symbol: 'JUNO',
1129
+ logo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png',
1130
+ address: 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed',
1131
+ blockchain: 'OSMOSIS',
1132
+ blockchainLogo: '',
1133
+ decimals: 6,
1134
+ usdPrice: 1.1091996179668873
1135
+ },
1136
+ to: {
1137
+ symbol: 'OSMO',
1138
+ logo: 'https://api.rango.exchange/i/mJQPS2',
1139
+ address: null,
1140
+ blockchain: 'OSMOSIS',
1141
+ decimals: 6,
1142
+ blockchainLogo: '',
1143
+ usdPrice: 0.7192435454440882
1144
+ },
1145
+ fromAmount: '1.000000',
1146
+ fromAmountPrecision: null,
1147
+ fromAmountMinValue: null,
1148
+ fromAmountMaxValue: null,
1149
+ toAmount: '1.540670',
1150
+ fee: [{
1151
+ name: '',
1152
+ asset: {
1153
+ blockchain: 'OSMOSIS',
1154
+ symbol: 'OSMO',
1155
+ address: null
1156
+ },
1157
+ expenseType: 'FROM_SOURCE_WALLET',
1158
+ amount: '0'
1159
+ }],
1160
+ estimatedTimeInSeconds: 45,
1161
+ swapChainType: 'INTRA_CHAIN',
1162
+ routes: [{
1163
+ nodes: [{
1164
+ nodes: [{
1165
+ marketName: 'pool#498',
1166
+ marketId: null,
1167
+ percent: 1
1168
+ }],
1169
+ from: 'JUNO',
1170
+ fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png',
1171
+ fromAddress: 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed',
1172
+ fromBlockchain: 'OSMOSIS',
1173
+ to: 'ATOM',
1174
+ toLogo: 'https://api.rango.exchange/tokens/COSMOS/ATOM.png',
1175
+ toAddress: 'ibc/27394fb092d2eccd56123c74f36e4c1f926001ceada9ca97ea622b25f41e5eb2',
1176
+ toBlockchain: 'OSMOSIS'
1177
+ }, {
1178
+ nodes: [{
1179
+ marketName: 'pool#8',
1180
+ marketId: null,
1181
+ percent: 1
1182
+ }],
1183
+ from: 'ATOM',
1184
+ fromLogo: 'https://api.rango.exchange/tokens/COSMOS/ATOM.png',
1185
+ fromAddress: 'ibc/27394fb092d2eccd56123c74f36e4c1f926001ceada9ca97ea622b25f41e5eb2',
1186
+ fromBlockchain: 'OSMOSIS',
1187
+ to: 'IRIS',
1188
+ toLogo: 'https://api.rango.exchange/tokens/COSMOS/IRIS.png',
1189
+ toAddress: 'ibc/7c4d60aa95e5a7558b0a364860979ca34b7ff8aaf255b87af9e879374470cec0',
1190
+ toBlockchain: 'OSMOSIS'
1191
+ }, {
1192
+ nodes: [{
1193
+ marketName: 'pool#7',
1194
+ marketId: null,
1195
+ percent: 1
1196
+ }],
1197
+ from: 'IRIS',
1198
+ fromLogo: 'https://api.rango.exchange/tokens/COSMOS/IRIS.png',
1199
+ fromAddress: 'ibc/7c4d60aa95e5a7558b0a364860979ca34b7ff8aaf255b87af9e879374470cec0',
1200
+ fromBlockchain: 'OSMOSIS',
1201
+ to: 'OSMO',
1202
+ toLogo: 'https://api.rango.exchange/tokens/COSMOS/OSMO.png',
1203
+ toAddress: null,
1204
+ toBlockchain: 'OSMOSIS'
1205
+ }]
1206
+ }],
1207
+ recommendedSlippage: null,
1208
+ timeStat: {
1209
+ min: 6,
1210
+ avg: 40,
1211
+ max: 241
1212
+ },
1213
+ includesDestinationTx: false
1214
+ }]
1215
+ },
1216
+ validateBalanceOrFee: true,
1217
+ steps: [{
1218
+ id: 1,
1219
+ fromBlockchain: 'OSMOSIS',
1220
+ fromSymbol: 'JUNO',
1221
+ fromSymbolAddress: 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed',
1222
+ fromDecimals: 6,
1223
+ fromAmountPrecision: null,
1224
+ fromAmountMinValue: null,
1225
+ fromAmountMaxValue: null,
1226
+ toBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png',
1227
+ fromBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png',
1228
+ toBlockchain: 'OSMOSIS',
1229
+ swapperLogo: '',
1230
+ swapperType: '',
1231
+ fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png',
1232
+ toSymbol: 'OSMO',
1233
+ toSymbolAddress: null,
1234
+ toDecimals: 6,
1235
+ toLogo: 'https://api.rango.exchange/i/mJQPS2',
1236
+ startTransactionTime: 1673164519916,
1237
+ swapperId: 'Osmosis',
1238
+ expectedOutputAmountHumanReadable: '1.540670',
1239
+ outputAmount: '1.540658',
1240
+ status: 'failed',
1241
+ networkStatus: null,
1242
+ executedTransactionId: '0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b',
1243
+ explorerUrl: [{
1244
+ url: 'https://www.mintscan.io/osmosis/txs/0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b',
1245
+ description: null
1246
+ }],
1247
+ cosmosTransaction: {
1248
+ type: TransactionType.COSMOS,
1249
+ fromWalletAddress: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl',
1250
+ blockChain: 'OSMOSIS',
1251
+ data: {
1252
+ chainId: 'osmosis-1',
1253
+ account_number: 102721,
1254
+ sequence: '308',
1255
+ msgs: [{
1256
+ __type: 'OsmosisSwapMessage',
1257
+ type: 'osmosis/gamm/swap-exact-amount-in',
1258
+ value: {
1259
+ sender: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl',
1260
+ routes: [{
1261
+ pool_id: '498',
1262
+ token_out_denom: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2'
1263
+ }, {
1264
+ pool_id: '8',
1265
+ token_out_denom: 'ibc/7C4D60AA95E5A7558B0A364860979CA34B7FF8AAF255B87AF9E879374470CEC0'
1266
+ }, {
1267
+ pool_id: '7',
1268
+ token_out_denom: 'uosmo'
1269
+ }],
1270
+ token_in: {
1271
+ denom: 'ibc/46B44899322F3CD854D2D46DEEF881958467CDD4B3B10086DA49296BBED94BED',
1272
+ amount: '1000000'
1273
+ },
1274
+ token_out_min_amount: '1525264'
1275
+ }
1276
+ }],
1277
+ protoMsgs: [{
1278
+ type_url: '/osmosis.gamm.v1beta1.MsgSwapExactAmountIn',
1279
+ 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]
1280
+ }],
1281
+ memo: '',
1282
+ source: null,
1283
+ fee: {
1284
+ gas: '900000',
1285
+ amount: [{
1286
+ denom: 'uosmo',
1287
+ amount: '0'
1288
+ }]
1289
+ },
1290
+ signType: 'AMINO',
1291
+ rpcUrl: ''
1292
+ },
1293
+ rawTransfer: null
1294
+ },
1295
+ solanaTransaction: null,
1296
+ evmTransaction: null,
1297
+ evmApprovalTransaction: null,
1298
+ transferTransaction: null,
1299
+ diagnosisUrl: null,
1300
+ internalSteps: null
1301
+ }]
1302
+ }, {
1303
+ creationTime: '1673164511955',
1304
+ finishTime: '1673164550137',
1305
+ requestId: '51e211d9-d61c-45d2-a4d4-1f9f7f90ee85',
1306
+ inputAmount: '1',
1307
+ wallets: {
1308
+ OSMOSIS: {
1309
+ walletType: 'keplr',
1310
+ address: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl'
1311
+ }
1312
+ },
1313
+ status: 'success',
1314
+ isPaused: false,
1315
+ extraMessage: null,
1316
+ extraMessageSeverity: 'info',
1317
+ extraMessageDetail: '',
1318
+ extraMessageErrorCode: null,
1319
+ networkStatusExtraMessage: null,
1320
+ networkStatusExtraMessageDetail: null,
1321
+ lastNotificationTime: null,
1322
+ settings: {
1323
+ slippage: '1.0',
1324
+ disabledSwappersIds: [],
1325
+ disabledSwappersGroups: []
1326
+ },
1327
+ simulationResult: {
1328
+ outputAmount: '1.540670',
1329
+ swaps: [{
1330
+ // @ts-ignore
1331
+ result: [],
1332
+ swapperId: 'Osmosis',
1333
+ swapperType: 'DEX',
1334
+ swapperLogo: '',
1335
+ from: {
1336
+ symbol: 'JUNO',
1337
+ logo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png',
1338
+ address: 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed',
1339
+ blockchain: 'OSMOSIS',
1340
+ blockchainLogo: '',
1341
+ decimals: 6,
1342
+ usdPrice: 1.1091996179668873
1343
+ },
1344
+ to: {
1345
+ symbol: 'OSMO',
1346
+ logo: 'https://api.rango.exchange/i/mJQPS2',
1347
+ address: null,
1348
+ blockchain: 'OSMOSIS',
1349
+ decimals: 6,
1350
+ blockchainLogo: '',
1351
+ usdPrice: 0.7192435454440882
1352
+ },
1353
+ fromAmount: '1.000000',
1354
+ fromAmountPrecision: null,
1355
+ fromAmountMinValue: null,
1356
+ fromAmountMaxValue: null,
1357
+ toAmount: '1.540670',
1358
+ fee: [{
1359
+ name: '',
1360
+ asset: {
1361
+ blockchain: 'OSMOSIS',
1362
+ symbol: 'OSMO',
1363
+ address: null
1364
+ },
1365
+ expenseType: 'FROM_SOURCE_WALLET',
1366
+ amount: '0'
1367
+ }],
1368
+ estimatedTimeInSeconds: 45,
1369
+ swapChainType: 'INTRA_CHAIN',
1370
+ routes: [{
1371
+ nodes: [{
1372
+ nodes: [{
1373
+ marketName: 'pool#498',
1374
+ marketId: null,
1375
+ percent: 1
1376
+ }],
1377
+ from: 'JUNO',
1378
+ fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png',
1379
+ fromAddress: 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed',
1380
+ fromBlockchain: 'OSMOSIS',
1381
+ to: 'ATOM',
1382
+ toLogo: 'https://api.rango.exchange/tokens/COSMOS/ATOM.png',
1383
+ toAddress: 'ibc/27394fb092d2eccd56123c74f36e4c1f926001ceada9ca97ea622b25f41e5eb2',
1384
+ toBlockchain: 'OSMOSIS'
1385
+ }, {
1386
+ nodes: [{
1387
+ marketName: 'pool#8',
1388
+ marketId: null,
1389
+ percent: 1
1390
+ }],
1391
+ from: 'ATOM',
1392
+ fromLogo: 'https://api.rango.exchange/tokens/COSMOS/ATOM.png',
1393
+ fromAddress: 'ibc/27394fb092d2eccd56123c74f36e4c1f926001ceada9ca97ea622b25f41e5eb2',
1394
+ fromBlockchain: 'OSMOSIS',
1395
+ to: 'IRIS',
1396
+ toLogo: 'https://api.rango.exchange/tokens/COSMOS/IRIS.png',
1397
+ toAddress: 'ibc/7c4d60aa95e5a7558b0a364860979ca34b7ff8aaf255b87af9e879374470cec0',
1398
+ toBlockchain: 'OSMOSIS'
1399
+ }, {
1400
+ nodes: [{
1401
+ marketName: 'pool#7',
1402
+ marketId: null,
1403
+ percent: 1
1404
+ }],
1405
+ from: 'IRIS',
1406
+ fromLogo: 'https://api.rango.exchange/tokens/COSMOS/IRIS.png',
1407
+ fromAddress: 'ibc/7c4d60aa95e5a7558b0a364860979ca34b7ff8aaf255b87af9e879374470cec0',
1408
+ fromBlockchain: 'OSMOSIS',
1409
+ to: 'OSMO',
1410
+ toLogo: 'https://api.rango.exchange/tokens/COSMOS/OSMO.png',
1411
+ toAddress: null,
1412
+ toBlockchain: 'OSMOSIS'
1413
+ }]
1414
+ }],
1415
+ recommendedSlippage: null,
1416
+ timeStat: {
1417
+ min: 6,
1418
+ avg: 40,
1419
+ max: 241
1420
+ },
1421
+ includesDestinationTx: false
1422
+ }]
1423
+ },
1424
+ validateBalanceOrFee: true,
1425
+ steps: [{
1426
+ id: 1,
1427
+ fromBlockchain: 'OSMOSIS',
1428
+ fromSymbol: 'JUNO',
1429
+ fromSymbolAddress: 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed',
1430
+ fromDecimals: 6,
1431
+ fromAmountPrecision: null,
1432
+ fromAmountMinValue: null,
1433
+ swapperLogo: '',
1434
+ swapperType: '',
1435
+ fromAmountMaxValue: null,
1436
+ toBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png',
1437
+ fromBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png',
1438
+ toBlockchain: 'OSMOSIS',
1439
+ fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png',
1440
+ toSymbol: 'OSMO',
1441
+ toSymbolAddress: null,
1442
+ toDecimals: 6,
1443
+ toLogo: 'https://api.rango.exchange/i/mJQPS2',
1444
+ startTransactionTime: 1673164519916,
1445
+ swapperId: 'Osmosis',
1446
+ expectedOutputAmountHumanReadable: '1.540670',
1447
+ outputAmount: '1.540658',
1448
+ status: 'success',
1449
+ networkStatus: null,
1450
+ executedTransactionId: '0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b',
1451
+ explorerUrl: [{
1452
+ url: 'https://www.mintscan.io/osmosis/txs/0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b',
1453
+ description: null
1454
+ }],
1455
+ cosmosTransaction: {
1456
+ type: TransactionType.COSMOS,
1457
+ fromWalletAddress: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl',
1458
+ blockChain: 'OSMOSIS',
1459
+ data: {
1460
+ chainId: 'osmosis-1',
1461
+ account_number: 102721,
1462
+ sequence: '308',
1463
+ msgs: [{
1464
+ __type: 'OsmosisSwapMessage',
1465
+ type: 'osmosis/gamm/swap-exact-amount-in',
1466
+ value: {
1467
+ sender: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl',
1468
+ routes: [{
1469
+ pool_id: '498',
1470
+ token_out_denom: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2'
1471
+ }, {
1472
+ pool_id: '8',
1473
+ token_out_denom: 'ibc/7C4D60AA95E5A7558B0A364860979CA34B7FF8AAF255B87AF9E879374470CEC0'
1474
+ }, {
1475
+ pool_id: '7',
1476
+ token_out_denom: 'uosmo'
1477
+ }],
1478
+ token_in: {
1479
+ denom: 'ibc/46B44899322F3CD854D2D46DEEF881958467CDD4B3B10086DA49296BBED94BED',
1480
+ amount: '1000000'
1481
+ },
1482
+ token_out_min_amount: '1525264'
1483
+ }
1484
+ }],
1485
+ protoMsgs: [{
1486
+ type_url: '/osmosis.gamm.v1beta1.MsgSwapExactAmountIn',
1487
+ 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]
1488
+ }],
1489
+ memo: '',
1490
+ source: null,
1491
+ fee: {
1492
+ gas: '900000',
1493
+ amount: [{
1494
+ denom: 'uosmo',
1495
+ amount: '0'
1496
+ }]
1497
+ },
1498
+ signType: 'AMINO',
1499
+ rpcUrl: ''
1500
+ },
1501
+ rawTransfer: null
1502
+ },
1503
+ solanaTransaction: null,
1504
+ evmTransaction: null,
1505
+ evmApprovalTransaction: null,
1506
+ transferTransaction: null,
1507
+ diagnosisUrl: null,
1508
+ internalSteps: null
1509
+ }]
1510
+ }];
1511
+ function HistoryPage() {
1512
+ const navigate = useNavigate();
1513
+ return React.createElement(History, {
1514
+ list: pendingSwap,
1515
+ onSwapClick: () => navigate(navigationRoutes.swapDetails),
1516
+ onBack: () => {
1517
+ navigate(-1);
1518
+ }
1519
+ });
1520
+ }
1521
+
1522
+ const ButtonsContainer = /*#__PURE__*/styled('div', {
1523
+ display: 'flex'
1524
+ });
1525
+ function HeaderButtons(props) {
1526
+ const {
1527
+ onClickRefresh
1528
+ } = props;
1529
+ const navigate = useNavigate();
1530
+ return React.createElement(ButtonsContainer, null, React.createElement(Tooltip, {
1531
+ content: "Retry"
1532
+ }, React.createElement(Button, {
1533
+ variant: "ghost",
1534
+ onClick: onClickRefresh.bind(null)
1535
+ }, React.createElement(RetryIcon, {
1536
+ size: 28
1537
+ }))), React.createElement(Tooltip, {
1538
+ content: "Transactions History"
1539
+ }, React.createElement(Button, {
1540
+ variant: "ghost",
1541
+ onClick: () => navigate(navigationRoutes.history)
1542
+ }, React.createElement(HistoryIcon, {
1543
+ size: 24
1544
+ }))), React.createElement(Tooltip, {
1545
+ content: "Settings"
1546
+ }, React.createElement(Button, {
1547
+ variant: "ghost",
1548
+ onClick: () => navigate(navigationRoutes.settings)
1549
+ }, React.createElement(SettingsIcon, {
1550
+ size: 24
1551
+ }))));
1552
+ }
1553
+
1554
+ const HeaderContainer = /*#__PURE__*/styled('div', {
1555
+ display: 'flex',
1556
+ justifyContent: 'space-between',
1557
+ alignItems: 'center',
1558
+ width: '100%',
1559
+ padding: '$16 0'
1560
+ });
1561
+ function Header(props) {
1562
+ const {
1563
+ onClickRefresh
1564
+ } = props;
1565
+ return React.createElement(HeaderContainer, null, React.createElement(Typography, {
1566
+ variant: "h4"
1567
+ }, "SWAP"), React.createElement(HeaderButtons, {
1568
+ onClickRefresh: onClickRefresh
1569
+ }));
1570
+ }
1571
+
1572
+ const Box = /*#__PURE__*/styled('div', {
1573
+ display: 'flex',
1574
+ flexDirection: 'column',
1575
+ width: '100%'
1576
+ });
1577
+ const Container = /*#__PURE__*/styled('div', {
1578
+ boxSizing: 'border-box',
1579
+ backgroundColor: '$neutrals300',
1580
+ borderRadius: '$5',
1581
+ padding: '$8 0',
1582
+ '.form': {
1583
+ display: 'flex',
1584
+ width: '100%',
1585
+ padding: '$8 $16'
1586
+ }
1587
+ });
1588
+ const StyledImage = /*#__PURE__*/styled('img', {
1589
+ width: '$24',
1590
+ maxHeight: '$24'
1591
+ });
1592
+ const Options = /*#__PURE__*/styled('div', {
1593
+ display: 'flex',
1594
+ justifyContent: 'flex-end',
1595
+ padding: '0 $8'
1596
+ });
1597
+ const ImagePlaceholder = /*#__PURE__*/styled('span', {
1598
+ width: '24px',
1599
+ height: '24px',
1600
+ backgroundColor: '$neutrals300',
1601
+ borderRadius: '99999px'
1602
+ });
1603
+ const OutputContainer = /*#__PURE__*/styled('div', {
1604
+ height: '$48',
1605
+ borderRadius: '$5',
1606
+ flexGrow: 1,
1607
+ width: '70%',
1608
+ backgroundColor: '$background',
1609
+ border: '1px solid transparent',
1610
+ position: 'relative',
1611
+ display: 'flex',
1612
+ alignItems: 'center',
1613
+ paddingLeft: '$8',
1614
+ paddingRight: '$8'
1615
+ });
1616
+ function TokenInfo(props) {
1617
+ const {
1618
+ type,
1619
+ chain,
1620
+ token
1621
+ } = props;
1622
+ const loadingStatus = useMetaStore.use.loadingStatus();
1623
+ const fromChain = useBestRouteStore.use.fromChain();
1624
+ const toChain = useBestRouteStore.use.toChain();
1625
+ const inputUsdValue = useBestRouteStore.use.inputUsdValue();
1626
+ const fromToken = useBestRouteStore.use.fromToken();
1627
+ const setInputAmount = useBestRouteStore.use.setInputAmount();
1628
+ const bestRoute = useBestRouteStore.use.bestRoute();
1629
+ const inputAmount = useBestRouteStore.use.inputAmount();
1630
+ const balances = useWalletsStore.use.balances();
1631
+ const navigate = useNavigate();
1632
+ const tokenBalance = !!fromChain && !!fromToken ? numberToString(getBalanceFromWallet(balances, fromChain?.name, fromToken?.symbol, fromToken?.address)?.amount || '0', 8) : '0';
1633
+ 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';
1634
+ const ItemSuffix = React.createElement("div", {
1635
+ style: {
1636
+ display: 'flex',
1637
+ justifyContent: 'center',
1638
+ alignItems: 'center'
1639
+ }
1640
+ }, loadingStatus === 'failed' && React.createElement(InfoCircleIcon, {
1641
+ color: "error",
1642
+ size: 24
1643
+ }), React.createElement(AngleDownIcon, null));
1644
+ return React.createElement(Box, null, React.createElement("div", null, React.createElement(Typography, {
1645
+ variant: "body2"
1646
+ }, type)), React.createElement(Container, null, props.type === 'From' && React.createElement(Options, null, React.createElement("div", {
1647
+ className: "balance",
1648
+ onClick: () => {
1649
+ if (tokenBalance !== '0') setInputAmount(tokenBalanceReal.split(',').join(''));
1650
+ }
1651
+ }, React.createElement(Button, {
1652
+ variant: "ghost",
1653
+ size: "small"
1654
+ }, React.createElement(Typography, {
1655
+ variant: "body2"
1656
+ }, `Max: ${tokenBalance} ${fromToken?.symbol || ''}`)))), React.createElement("div", {
1657
+ className: "form"
1658
+ }, React.createElement(Button, {
1659
+ onClick: () => {
1660
+ navigate(`/${props.type.toLowerCase()}-chain`);
1661
+ },
1662
+ variant: "outlined",
1663
+ disabled: loadingStatus === 'failed',
1664
+ loading: loadingStatus === 'loading',
1665
+ prefix: loadingStatus === 'success' && chain ? React.createElement(StyledImage, {
1666
+ src: chain.logo
1667
+ }) : React.createElement(ImagePlaceholder, null),
1668
+ suffix: ItemSuffix,
1669
+ align: "start",
1670
+ size: "large",
1671
+ style: {
1672
+ marginRight: '.5rem'
1673
+ }
1674
+ }, loadingStatus === 'success' && chain ? chain.name : 'Chain'), React.createElement(Button, {
1675
+ onClick: () => {
1676
+ navigate(`/${props.type.toLowerCase()}-token`);
1677
+ },
1678
+ variant: "outlined",
1679
+ disabled: loadingStatus === 'failed' || type === 'From' && !fromChain || type === 'To' && !toChain,
1680
+ loading: loadingStatus === 'loading',
1681
+ prefix: loadingStatus === 'success' && token ? React.createElement(StyledImage, {
1682
+ src: token.image
1683
+ }) : React.createElement(ImagePlaceholder, null),
1684
+ suffix: ItemSuffix,
1685
+ size: "large",
1686
+ align: "start",
1687
+ style: {
1688
+ marginRight: '.5rem'
1689
+ }
1690
+ }, loadingStatus === 'success' && token ? token.symbol : 'Token'), props.type === 'From' ? React.createElement(TextField, {
1691
+ type: "number",
1692
+ size: "large",
1693
+ autoFocus: true,
1694
+ placeholder: "0",
1695
+ style: {
1696
+ width: '70%',
1697
+ position: 'relative',
1698
+ backgroundColor: '$background !important'
1699
+ },
1700
+ suffix: React.createElement("span", {
1701
+ style: {
1702
+ position: 'absolute',
1703
+ right: '4px',
1704
+ bottom: '2px'
1705
+ }
1706
+ }, React.createElement(Typography, {
1707
+ variant: "caption"
1708
+ }, `$${numberToString(inputUsdValue)}`)),
1709
+ value: props.inputAmount || '',
1710
+ onChange: props.type === 'From' ? event => {
1711
+ props.onAmountChange(event.target.value);
1712
+ } : undefined
1713
+ }) : React.createElement(OutputContainer, null, React.createElement(Typography, {
1714
+ variant: "body1"
1715
+ }, bestRoute ? `≈ ${numberToString(props.outputAmount)}` : inputAmount ? '?' : '0'), React.createElement("span", {
1716
+ style: {
1717
+ position: 'absolute',
1718
+ right: '4px',
1719
+ bottom: '2px'
1720
+ }
1721
+ }, React.createElement(Typography, {
1722
+ variant: "caption"
1723
+ }, `$${numberToString(props.outputUsdValue)}`))))));
1724
+ }
1725
+
1726
+ const Container$1 = /*#__PURE__*/styled$1('div', {
1727
+ display: 'flex',
1728
+ width: '100%',
1729
+ justifyContent: 'end',
1730
+ alignItems: 'center',
1731
+ paddingTop: '$16'
1732
+ });
1733
+ const Logo = /*#__PURE__*/styled$1('svg', {
1734
+ fill: '$foreground',
1735
+ width: '$24',
1736
+ margin: '0 $8 0 $16'
1737
+ });
1738
+ const StyledAnchor = /*#__PURE__*/styled$1('a', {
1739
+ display: 'flex',
1740
+ justifyContent: 'center',
1741
+ alignItems: 'center',
1742
+ textDecoration: 'none'
1743
+ });
1744
+ function BottomLogo() {
1745
+ return React.createElement(Container$1, null, React.createElement(Typography, {
1746
+ variant: "caption"
1747
+ }, "Powered By"), React.createElement(StyledAnchor, {
1748
+ href: "https://rango.exchange",
1749
+ target: "_blank"
1750
+ }, React.createElement(Logo, {
1751
+ xmlns: "http://www.w3.org/2000/svg",
1752
+ viewBox: "0 0 33.68 29"
1753
+ }, React.createElement("defs", null), React.createElement("g", {
1754
+ id: "Layer_2",
1755
+ "data-name": "Layer 2"
1756
+ }, React.createElement("g", {
1757
+ id: "Layer_1-2",
1758
+ "data-name": "Layer 1"
1759
+ }, React.createElement("path", {
1760
+ 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"
1761
+ }), React.createElement("path", {
1762
+ 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"
1763
+ })))), React.createElement(Typography, {
1764
+ variant: "body2"
1765
+ }, "RANGO")));
1766
+ }
1767
+
1768
+ function SwithFromAndTo(_ref) {
1769
+ let {
1770
+ count
1771
+ } = _ref;
1772
+ const firstRender = useRef(true);
1773
+ const [searchParams, setSearchParams] = useSearchParams();
1774
+ const outputAmount = useBestRouteStore.use.outputAmount();
1775
+ useEffect(() => {
1776
+ if (!firstRender.current) {
1777
+ const fromChainString = searchParams.get(SearchParams.FROM_CHAIN);
1778
+ const fromTokenString = searchParams.get(SearchParams.FROM_TOKEN);
1779
+ const toChainString = searchParams.get(SearchParams.TO_CHAIN);
1780
+ const toTokenString = searchParams.get(SearchParams.TO_TOKEN);
1781
+ setSearchParams({
1782
+ ...(toChainString && {
1783
+ [SearchParams.FROM_CHAIN]: toChainString
1784
+ }),
1785
+ ...(toTokenString && {
1786
+ [SearchParams.FROM_TOKEN]: toTokenString
1787
+ }),
1788
+ ...(fromChainString && {
1789
+ [SearchParams.TO_CHAIN]: fromChainString
1790
+ }),
1791
+ ...(fromTokenString && {
1792
+ [SearchParams.TO_TOKEN]: fromTokenString
1793
+ }),
1794
+ ...(outputAmount && {
1795
+ [SearchParams.FROM_AMOUNT]: outputAmount.toString()
1796
+ })
1797
+ });
1798
+ } else {
1799
+ firstRender.current = false;
1800
+ }
1801
+ }, [count]);
1802
+ return null;
1803
+ }
1804
+
1805
+ const Footer = /*#__PURE__*/styled('div', {
1806
+ display: 'flex',
1807
+ flexDirection: 'column',
1808
+ width: '100%',
1809
+ paddingTop: '$16'
1810
+ });
1811
+
1812
+ function useBestRoute() {
1813
+ const fromToken = useBestRouteStore.use.fromToken();
1814
+ const toToken = useBestRouteStore.use.toToken();
1815
+ const inputAmount = useBestRouteStore.use.inputAmount();
1816
+ const slippage = useSettingsStore.use.slippage();
1817
+ const customSlippage = useSettingsStore.use.customSlippage();
1818
+ const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
1819
+ const [count, setCount] = useState(0);
1820
+ const [loading, setLoading] = useState(false);
1821
+ const [error, setError] = useState('');
1822
+ const [data, setData] = useState(null);
1823
+ const abortControllerRef = useRef(null);
1824
+ const retry = () => {
1825
+ setCount(prev => prev + 1);
1826
+ };
1827
+ useEffect(() => {
1828
+ if (abortControllerRef.current) abortControllerRef.current.abort();
1829
+ const abortController = new AbortController();
1830
+ abortControllerRef.current = abortController;
1831
+ if (!!fromToken && !!toToken && !!inputAmount) {
1832
+ if (!!data) setData(null);
1833
+ const requestBody = {
1834
+ amount: inputAmount?.toString(),
1835
+ connectedWallets: [],
1836
+ selectedWallets: {},
1837
+ checkPrerequisites: false,
1838
+ swapperGroups: disabledLiquiditySources,
1839
+ swappersGroupsExclude: true,
1840
+ from: {
1841
+ address: fromToken.address,
1842
+ blockchain: fromToken.blockchain,
1843
+ symbol: fromToken.symbol
1844
+ },
1845
+ to: {
1846
+ address: toToken.address,
1847
+ blockchain: toToken.blockchain,
1848
+ symbol: toToken.symbol
1849
+ }
1850
+ };
1851
+ setLoading(true);
1852
+ httpService.getBestRoute(requestBody, {
1853
+ signal: abortControllerRef.current.signal
1854
+ }).then(res => {
1855
+ setData(res);
1856
+ setLoading(false);
1857
+ abortControllerRef.current = null;
1858
+ }).catch(error => {
1859
+ if (error.code === 'ERR_CANCELED') return;
1860
+ setError(error.message);
1861
+ setLoading(false);
1862
+ });
1863
+ }
1864
+ }, [fromToken, toToken, inputAmount, count, slippage, customSlippage, disabledLiquiditySources.length]);
1865
+ return {
1866
+ loading,
1867
+ error,
1868
+ data,
1869
+ retry
1870
+ };
1871
+ }
1872
+
1873
+ const errorMessages = {
1874
+ genericServerError: 'Error connecting server, please reload the app and try again'
1875
+ };
1876
+
1877
+ const Container$2 = /*#__PURE__*/styled('div', {
1878
+ display: 'flex',
1879
+ flexDirection: 'column',
1880
+ justifyContent: 'center',
1881
+ alignItems: 'center'
1882
+ });
1883
+ const SwitchButtonContainer = /*#__PURE__*/styled('div', {
1884
+ display: 'flex',
1885
+ justifyContent: 'center',
1886
+ alignItems: 'center',
1887
+ position: 'relative',
1888
+ top: '11px'
1889
+ });
1890
+ const BestRouteContainer = /*#__PURE__*/styled('div', {
1891
+ width: '100%',
1892
+ paddingTop: '$16'
1893
+ });
1894
+ const Alerts = /*#__PURE__*/styled('div', {
1895
+ paddingTop: '$16'
1896
+ });
1897
+ function Home() {
1898
+ const waningMessage = '';
1899
+ const isRouterInContext = useInRouterContext$1();
1900
+ const navigate = useNavigate();
1901
+ const [count, setCount] = useState(0);
1902
+ const fromChain = useBestRouteStore.use.fromChain();
1903
+ const fromToken = useBestRouteStore.use.fromToken();
1904
+ const toChain = useBestRouteStore.use.toChain();
1905
+ const toToken = useBestRouteStore.use.toToken();
1906
+ const setFromChain = useBestRouteStore.use.setFromChain();
1907
+ const setFromToken = useBestRouteStore.use.setFromToken();
1908
+ const setToChain = useBestRouteStore.use.setToChain();
1909
+ const setToToken = useBestRouteStore.use.setToToken();
1910
+ const setBestRoute = useBestRouteStore.use.setBestRoute();
1911
+ const inputUsdValue = useBestRouteStore.use.inputUsdValue();
1912
+ const inputAmount = useBestRouteStore.use.inputAmount();
1913
+ const setInputAmount = useBestRouteStore.use.setInputAmount();
1914
+ const outputAmount = useBestRouteStore.use.outputAmount();
1915
+ const outputUsdValue = useBestRouteStore.use.outputUsdValue();
1916
+ const bestRoute = useBestRouteStore.use.bestRoute();
1917
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
1918
+ const accounts = useWalletsStore.use.accounts();
1919
+ const swithFromAndTo = () => {
1920
+ setFromChain(toChain);
1921
+ setFromToken(toToken);
1922
+ setToChain(fromChain);
1923
+ setToToken(fromToken);
1924
+ setInputAmount(outputAmount?.toString() || '');
1925
+ setCount(prev => prev + 1);
1926
+ };
1927
+ const {
1928
+ data,
1929
+ loading: fetchingBestRoute,
1930
+ error: bestRouteError,
1931
+ retry
1932
+ } = useBestRoute();
1933
+ const noConnectedWallet = accounts.length > 0;
1934
+ const noRoutesFound = !bestRoute?.result;
1935
+ const errorMessage = loadingMetaStatus === 'failed' ? errorMessages.genericServerError : bestRouteError;
1936
+ const needsToWarnEthOnPath = false;
1937
+ const showBestRoute = inputAmount && (!!data || fetchingBestRoute || bestRouteError);
1938
+ const outToInRatio = getOutputRatio(inputUsdValue, outputUsdValue);
1939
+ const highValueLoss = outputRatioHasWarning(inputUsdValue, outToInRatio);
1940
+ const priceImpactCanNotBeComputed = !canComputePriceImpact(bestRoute, inputAmount, inputUsdValue, outputUsdValue);
1941
+ const buttonTitle = getSwapButtonTitle(accounts, fetchingBestRoute, hasLimitError(bestRoute), highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath);
1942
+ const buttonDisabled = loadingMetaStatus != 'success' || fetchingBestRoute || highValueLoss || noConnectedWallet && noRoutesFound || hasLimitError(bestRoute);
1943
+ useEffect(() => {
1944
+ setBestRoute(data);
1945
+ }, [data]);
1946
+ return React.createElement(Container$2, null, React.createElement(Header, {
1947
+ onClickRefresh: retry
1948
+ }), React.createElement(TokenInfo, {
1949
+ type: "From",
1950
+ chain: fromChain,
1951
+ token: fromToken,
1952
+ onAmountChange: setInputAmount,
1953
+ inputAmount: inputAmount
1954
+ }), React.createElement(SwitchButtonContainer, null, React.createElement(Button, {
1955
+ variant: "ghost",
1956
+ onClick: swithFromAndTo
1957
+ }, React.createElement(VerticalSwapIcon, {
1958
+ size: 36
1959
+ }), isRouterInContext && React.createElement(SwithFromAndTo, {
1960
+ count: count
1961
+ }))), React.createElement(TokenInfo, {
1962
+ type: "To",
1963
+ chain: toChain,
1964
+ token: toToken,
1965
+ outputAmount: outputAmount,
1966
+ outputUsdValue: outputUsdValue
1967
+ }), showBestRoute && React.createElement(BestRouteContainer, null, React.createElement(BestRoute, {
1968
+ error: bestRouteError,
1969
+ loading: fetchingBestRoute,
1970
+ data: data
1971
+ })), (errorMessage || waningMessage) && React.createElement(Alerts, null, errorMessage && React.createElement(Alert, {
1972
+ description: errorMessage,
1973
+ type: "error"
1974
+ }), waningMessage ), React.createElement(Footer, null, React.createElement(Button, {
1975
+ type: "primary",
1976
+ align: "grow",
1977
+ size: "large",
1978
+ disabled: buttonDisabled,
1979
+ onClick: () => {
1980
+ if (buttonTitle === 'Connect Wallet') navigate(navigationRoutes.wallets);else {
1981
+ navigate(navigationRoutes.confirmWallets);
1982
+ }
1983
+ }
1984
+ }, buttonTitle), React.createElement(BottomLogo, null)));
1985
+ }
1986
+
1987
+ function LiquiditySourcePage() {
1988
+ const {
1989
+ swappers
1990
+ } = useMetaStore.use.meta();
1991
+ const toggleLiquiditySource = useSettingsStore.use.toggleLiquiditySource();
1992
+ const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
1993
+ const toggleAllLiquiditySources = useSettingsStore.use.toggleAllLiquiditySources();
1994
+ const navigate = useNavigate();
1995
+ const uniqueSwappersGroups = [];
1996
+ removeDuplicateFrom(swappers.map(s => s.swapperGroup)).map(swapperGroup => {
1997
+ return swappers.find(s => s.swapperGroup === swapperGroup);
1998
+ }).find(s => {
1999
+ if (s) {
2000
+ for (const type of s.types) {
2001
+ uniqueSwappersGroups.push({
2002
+ title: s.swapperGroup,
2003
+ logo: s.logo,
2004
+ type,
2005
+ selected: !disabledLiquiditySources.includes(s.swapperGroup)
2006
+ });
2007
+ }
2008
+ }
2009
+ });
2010
+ return React.createElement(LiquiditySourcesSelector, {
2011
+ toggleAll: toggleAllLiquiditySources,
2012
+ list: uniqueSwappersGroups,
2013
+ onChange: liquiditySource => toggleLiquiditySource(liquiditySource.title),
2014
+ onBack: () => {
2015
+ navigate(-1);
2016
+ }
2017
+ });
2018
+ }
2019
+
2020
+ function SelectChainPage(props) {
2021
+ const {
2022
+ type
2023
+ } = props;
2024
+ const accounts = useWalletsStore.use.accounts();
2025
+ const {
2026
+ blockchains
2027
+ } = useMetaStore.use.meta();
2028
+ const loadingStatus = useMetaStore.use.loadingStatus();
2029
+ const fromChain = useBestRouteStore.use.fromChain();
2030
+ const toChain = useBestRouteStore.use.toChain();
2031
+ const setFromChain = useBestRouteStore.use.setFromChain();
2032
+ const setToChain = useBestRouteStore.use.setToChain();
2033
+ const setFromToken = useBestRouteStore.use.setFromToken();
2034
+ const setToToken = useBestRouteStore.use.setToToken();
2035
+ const navigate = useNavigate();
2036
+ const [list, setList] = useState(blockchains);
2037
+ useEffect(() => {
2038
+ let chainSortedByConnectedWallets = [];
2039
+ if (accounts.length !== 0) {
2040
+ const connectedChains = removeDuplicateFrom(accounts.map(account => account.chain));
2041
+ chainSortedByConnectedWallets = blockchains.sort((blockchainA, blockchainB) => connectedChains.lastIndexOf(blockchainA.name) - connectedChains.lastIndexOf(blockchainB.name));
2042
+ } else {
2043
+ chainSortedByConnectedWallets = blockchains;
2044
+ }
2045
+ setList(chainSortedByConnectedWallets);
2046
+ }, [blockchains.length, accounts.length]);
2047
+ return React.createElement(BlockchainSelector, {
2048
+ type: type === 'from' ? 'Source' : 'Destination',
2049
+ list: list,
2050
+ selected: type === 'from' ? fromChain : toChain,
2051
+ loadingStatus: loadingStatus,
2052
+ onChange: chain => {
2053
+ if (type === 'from') setFromChain(chain);else setToChain(chain);
2054
+ if (type === 'from' && fromChain?.name != chain.name) setFromToken(null);
2055
+ if (type === 'to' && toChain?.name != chain.name) setToToken(null);
2056
+ navigate(-1);
2057
+ },
2058
+ onBack: navigate.bind(null, -1)
2059
+ });
2060
+ }
2061
+
2062
+ function SelectTokenPage(props) {
2063
+ const {
2064
+ type
2065
+ } = props;
2066
+ const navigate = useNavigate();
2067
+ const {
2068
+ tokens
2069
+ } = useMetaStore.use.meta();
2070
+ const fromChain = useBestRouteStore.use.fromChain();
2071
+ const toChain = useBestRouteStore.use.toChain();
2072
+ const fromToken = useBestRouteStore.use.fromToken();
2073
+ const toToken = useBestRouteStore.use.toToken();
2074
+ const setFromToken = useBestRouteStore.use.setFromToken();
2075
+ const setToToken = useBestRouteStore.use.setToToken();
2076
+ const balance = useWalletsStore.use.balances();
2077
+ const tokenWithSelectedChain = tokens.filter(token => {
2078
+ if (type === 'from') return token.blockchain === fromChain?.name;
2079
+ return token.blockchain === toChain?.name;
2080
+ });
2081
+ const TokensWithBalance = tokenWithSelectedChain.map(token => {
2082
+ const tokenAmount = numberToString(new BigNumber(getBalanceFromWallet(balance, token.blockchain, token.symbol, token.address)?.amount || ZERO));
2083
+ let tokenUsdValue = '';
2084
+ if (token.usdPrice) tokenUsdValue = numberToString(new BigNumber(getBalanceFromWallet(balance, token.blockchain, token.symbol, token.address)?.amount || ZERO).multipliedBy(token.usdPrice));
2085
+ return {
2086
+ ...token,
2087
+ balance: {
2088
+ amount: tokenAmount !== '0' ? tokenAmount : '',
2089
+ usdValue: tokenUsdValue !== '0' ? tokenUsdValue : ''
2090
+ }
2091
+ };
2092
+ });
2093
+ const sortedTokenList = sortedTokens(TokensWithBalance, type, balance);
2094
+ return React.createElement(TokenSelector, {
2095
+ type: type === 'from' ? 'Source' : 'Destination',
2096
+ list: sortedTokenList,
2097
+ selected: type === 'from' ? fromToken : toToken,
2098
+ onChange: token => {
2099
+ if (type === 'from') setFromToken(token);else setToToken(token);
2100
+ navigate(-1);
2101
+ },
2102
+ onBack: navigate.bind(null, -1)
2103
+ });
2104
+ }
2105
+
2106
+ function SettingsPage() {
2107
+ const slippage = useSettingsStore.use.slippage();
2108
+ const setSlippage = useSettingsStore.use.setSlippage();
2109
+ const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
2110
+ const customSlippage = useSettingsStore.use.customSlippage();
2111
+ const setCustomSlippage = useSettingsStore.use.setCustomSlippage();
2112
+ const theme = useSettingsStore.use.theme();
2113
+ const setTheme = useSettingsStore.use.setTheme();
2114
+ const {
2115
+ swappers
2116
+ } = useMetaStore.use.meta();
2117
+ const navigate = useNavigate();
2118
+ const uniqueSwappersGroups = [];
2119
+ removeDuplicateFrom(swappers.map(s => s.swapperGroup)).map(swapperGroup => {
2120
+ return swappers.find(s => s.swapperGroup === swapperGroup);
2121
+ }).find(s => {
2122
+ if (s) {
2123
+ for (const type of s.types) {
2124
+ uniqueSwappersGroups.push({
2125
+ title: s.swapperGroup,
2126
+ logo: s.logo,
2127
+ type,
2128
+ selected: !disabledLiquiditySources.includes(s.swapperGroup)
2129
+ });
2130
+ }
2131
+ }
2132
+ });
2133
+ return React.createElement(Settings, {
2134
+ slippages: [1, 2, 3, 4],
2135
+ selectedSlippage: slippage,
2136
+ onSlippageChange: slippage => setSlippage(slippage),
2137
+ liquiditySources: uniqueSwappersGroups,
2138
+ selectedLiquiditySources: uniqueSwappersGroups.filter(s => s.selected),
2139
+ onLiquiditySourcesClick: () => navigate(navigationRoutes.liquiditySources),
2140
+ onBack: navigate.bind(null, -1),
2141
+ customSlippage: customSlippage || NaN,
2142
+ onCustomSlippageChange: setCustomSlippage,
2143
+ minSlippage: 1,
2144
+ maxSlippage: 10,
2145
+ selectedTheme: theme,
2146
+ onThemeChange: setTheme
2147
+ });
2148
+ }
2149
+
2150
+ const ListContainer = /*#__PURE__*/styled('div', {
2151
+ display: 'grid',
2152
+ gap: '.5rem',
2153
+ gridTemplateColumns: ' repeat(2, minmax(0, 1fr))',
2154
+ height: '450px',
2155
+ alignContent: 'baseline'
2156
+ });
2157
+ const AlertContainer = /*#__PURE__*/styled('div', {
2158
+ paddingBottom: '$16'
2159
+ });
2160
+ function WalletsPage() {
2161
+ const navigate = useNavigate();
2162
+ const {
2163
+ state,
2164
+ disconnect,
2165
+ getWalletInfo,
2166
+ connect
2167
+ } = useWallets();
2168
+ const wallets = getlistWallet(state, getWalletInfo, Object.values(WalletType));
2169
+ const [walletErrorMessage, setWalletErrorMessage] = useState('');
2170
+ const onSelectWallet = async type => {
2171
+ const wallet = state(type);
2172
+ try {
2173
+ if (walletErrorMessage) setWalletErrorMessage('');
2174
+ if (wallet.connected) {
2175
+ await disconnect(type);
2176
+ } else {
2177
+ await connect(type);
2178
+ }
2179
+ } catch (e) {
2180
+ setWalletErrorMessage('Error: ' + e.message);
2181
+ }
2182
+ };
2183
+ return React.createElement(SecondaryPage, {
2184
+ title: "Select Wallet",
2185
+ textField: false,
2186
+ onBack: () => {
2187
+ navigate(-1);
2188
+ },
2189
+ Content: React.createElement(React.Fragment, null, walletErrorMessage && React.createElement(AlertContainer, null, React.createElement(Alert, {
2190
+ type: "error",
2191
+ description: walletErrorMessage
2192
+ })), React.createElement(ListContainer, null, wallets.map((info, index) => React.createElement(Wallet, Object.assign({}, info, {
2193
+ key: index,
2194
+ onClick: onSelectWallet
2195
+ })))))
2196
+ });
2197
+ }
2198
+
2199
+ function ConfirmWalletsPage() {
2200
+ const navigate = useNavigate();
2201
+ const bestRoute = useBestRouteStore.use.bestRoute();
2202
+ const accounts = useWalletsStore.use.accounts();
2203
+ const selectedWallets = useWalletsStore.use.selectedWallets();
2204
+ const initSelectedWallets = useWalletsStore.use.initSelectedWallets();
2205
+ const setSelectedWallet = useWalletsStore.use.setSelectedWallet();
2206
+ const {
2207
+ getWalletInfo
2208
+ } = useWallets();
2209
+ const confirmDisabled = !requiredWallets(bestRoute).every(chain => selectedWallets.map(wallet => wallet.chain).includes(chain));
2210
+ useEffect(() => {
2211
+ initSelectedWallets();
2212
+ }, []);
2213
+ return React.createElement(ConfirmWallets, {
2214
+ requiredWallets: getRequiredChains(bestRoute),
2215
+ selectableWallets: getSelectableWallets(accounts, selectedWallets, getWalletInfo, getRequiredChains(bestRoute)),
2216
+ onBack: () => navigate(-1),
2217
+ swap: bestRoute,
2218
+ onConfirm: () => navigate(navigationRoutes.confirmSwap),
2219
+ onChange: wallet => setSelectedWallet(wallet),
2220
+ confirmDisabled: confirmDisabled
2221
+ });
2222
+ }
2223
+
2224
+ //TODO: remove mock data after queue manager integration
2225
+ const pendingSwap$1 = {
2226
+ creationTime: '1675837879344',
2227
+ finishTime: '1675842500799',
2228
+ requestId: 'c40b81cd-fdac-4dad-bfef-1c7b2cff715f',
2229
+ inputAmount: '2',
2230
+ wallets: {
2231
+ POLYGON: {
2232
+ walletType: 'metamask',
2233
+ address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c'
2234
+ },
2235
+ SOLANA: {
2236
+ walletType: 'phantom',
2237
+ address: '9QoVnPEHj5HNL4cVicXUF8CVmyhBxTDqUUigVn3UPWwk'
2238
+ }
2239
+ },
2240
+ status: 'success',
2241
+ isPaused: false,
2242
+ extraMessage: null,
2243
+ extraMessageSeverity: 'info',
2244
+ extraMessageDetail: '',
2245
+ extraMessageErrorCode: null,
2246
+ networkStatusExtraMessage: '',
2247
+ networkStatusExtraMessageDetail: '',
2248
+ lastNotificationTime: null,
2249
+ settings: {
2250
+ slippage: '13.0',
2251
+ disabledSwappersIds: ['PancakeSwapBsc', 'ThorChain', 'Horizon Bridge', 'OneInchOptimism', 'OneInchGnosis', 'OneInchBsc', 'OneInchArbitrum', 'OpenOceanFantom', 'SushiHarmony', 'SushiArbitrum', 'OkcSwap', 'CherrySwap', 'Osmosis', 'SolanaWrapper', 'Jupiter', 'stargate', 'AnySwap', 'Satellite', 'Diffusion', 'JunoSwap', 'PangolinSwap', 'MMFinance', 'CronaSwap', 'VVSFinance', 'MDexHeco', 'ParaSwap Polygon', 'ParaSwap Bsc', 'ParaSwap Avalanche', 'AuroraSwap', 'Across', 'Arbitrum Bridge', 'TrisolarisSwap', 'Polygon Bridge', 'SpookySwap', 'Rainbow Bridge', 'Lido', 'Symbiosis', 'Avalanche Bridge', 'VoltageSwap', 'Stargate Aggregator', 'Across Aggregator', 'THORChain Aggregator', 'CBridge Aggregator', 'AnySwap Aggregator', 'Hyphen Aggregator', 'Optimism Bridge', 'OolongSwap', 'QuickSwap', 'StellaSwap', 'Hyphen', 'ViperSwap', 'cBridge v2.0', 'FinKujira', 'Hop', 'BeamSwap', 'SolarbeamSwap', 'Sifchain', 'Wormhole', 'EthUniSwapV2', 'OneInchPolygon'],
2252
+ disabledSwappersGroups: []
2253
+ },
2254
+ simulationResult: {
2255
+ outputAmount: '0.084249153',
2256
+ swaps: [{
2257
+ swapperId: 'QuickSwap',
2258
+ swapperLogo: 'https://api.rango.exchange/swappers/quick-swap.png',
2259
+ swapperType: 'DEX',
2260
+ from: {
2261
+ symbol: 'USDC',
2262
+ logo: 'https://api.rango.exchange/i/ns0AMf',
2263
+ blockchainLogo: 'https://api.rango.exchange/blockchains/polygon.svg',
2264
+ address: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174',
2265
+ blockchain: 'POLYGON',
2266
+ decimals: 6,
2267
+ usdPrice: 0.999792
2268
+ },
2269
+ to: {
2270
+ symbol: 'SOL',
2271
+ logo: 'https://api.rango.exchange/i/YhJ1nK',
2272
+ blockchainLogo: 'https://api.rango.exchange/blockchains/polygon.svg',
2273
+ address: '0xd93f7e271cb87c23aaa73edc008a79646d1f9912',
2274
+ blockchain: 'POLYGON',
2275
+ decimals: 9,
2276
+ usdPrice: 23.700913462284028
2277
+ },
2278
+ fromAmount: '2.000000',
2279
+ fromAmountPrecision: null,
2280
+ fromAmountMinValue: null,
2281
+ fromAmountMaxValue: null,
2282
+ fromAmountRestrictionType: null,
2283
+ toAmount: '0.084249153',
2284
+ fee: [{
2285
+ asset: {
2286
+ blockchain: 'POLYGON',
2287
+ symbol: 'USDC',
2288
+ address: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174'
2289
+ },
2290
+ expenseType: 'DECREASE_FROM_OUTPUT',
2291
+ amount: '0.006000000000000000124900090270330110797658562660217285156250000000',
2292
+ name: 'Swapper Fee'
2293
+ }, {
2294
+ asset: {
2295
+ blockchain: 'POLYGON',
2296
+ symbol: 'MATIC',
2297
+ address: null
2298
+ },
2299
+ expenseType: 'FROM_SOURCE_WALLET',
2300
+ amount: '0.032758180196833611',
2301
+ name: 'Network Fee'
2302
+ }],
2303
+ estimatedTimeInSeconds: 60,
2304
+ swapChainType: 'INTER_CHAIN',
2305
+ routes: [{
2306
+ nodes: [{
2307
+ nodes: [{
2308
+ marketName: 'QuickSwap',
2309
+ marketId: 'QuickSwap',
2310
+ percent: 1
2311
+ }],
2312
+ from: 'USDC',
2313
+ fromLogo: '',
2314
+ fromAddress: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174',
2315
+ fromBlockchain: 'POLYGON',
2316
+ to: 'SOL',
2317
+ toLogo: '',
2318
+ toAddress: '0xd93f7e271cb87c23aaa73edc008a79646d1f9912',
2319
+ toBlockchain: 'POLYGON'
2320
+ }]
2321
+ }],
2322
+ recommendedSlippage: null,
2323
+ warnings: [],
2324
+ timeStat: {
2325
+ min: 7,
2326
+ avg: 59,
2327
+ max: 736
2328
+ },
2329
+ includesDestinationTx: false,
2330
+ internalSwaps: null,
2331
+ maxRequiredSign: 1,
2332
+ fromAsset: {
2333
+ blockchain: 'POLYGON',
2334
+ symbol: 'USDC',
2335
+ address: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174'
2336
+ },
2337
+ toAsset: {
2338
+ blockchain: 'POLYGON',
2339
+ symbol: 'SOL',
2340
+ address: '0xd93f7e271cb87c23aaa73edc008a79646d1f9912'
2341
+ }
2342
+ }, {
2343
+ swapperId: 'Wormhole',
2344
+ swapperLogo: 'https://api.rango.exchange/swappers/wormhole.png',
2345
+ swapperType: 'BRIDGE',
2346
+ from: {
2347
+ symbol: 'SOL',
2348
+ logo: 'https://api.rango.exchange/i/YhJ1nK',
2349
+ blockchainLogo: 'https://api.rango.exchange/blockchains/polygon.svg',
2350
+ address: '0xd93f7e271cb87c23aaa73edc008a79646d1f9912',
2351
+ blockchain: 'POLYGON',
2352
+ decimals: 9,
2353
+ usdPrice: 23.700913462284028
2354
+ },
2355
+ to: {
2356
+ symbol: 'SOL',
2357
+ logo: 'https://api.rango.exchange/i/eLHYrb',
2358
+ blockchainLogo: 'https://api.rango.exchange/blockchains/solana.svg',
2359
+ address: null,
2360
+ blockchain: 'SOLANA',
2361
+ decimals: 9,
2362
+ usdPrice: 23.97093428787272
2363
+ },
2364
+ fromAmount: '0.084249153',
2365
+ fromAmountPrecision: null,
2366
+ fromAmountMinValue: null,
2367
+ fromAmountMaxValue: null,
2368
+ fromAmountRestrictionType: null,
2369
+ toAmount: '0.084249153',
2370
+ fee: [{
2371
+ asset: {
2372
+ blockchain: 'POLYGON',
2373
+ symbol: 'MATIC',
2374
+ address: null
2375
+ },
2376
+ expenseType: 'FROM_SOURCE_WALLET',
2377
+ amount: '0.042205949048288939',
2378
+ name: 'Network Fee'
2379
+ }, {
2380
+ asset: {
2381
+ blockchain: 'SOLANA',
2382
+ symbol: 'SOL',
2383
+ address: null
2384
+ },
2385
+ expenseType: 'FROM_DESTINATION_WALLET',
2386
+ amount: '0.000070000',
2387
+ name: 'Swapper Fee'
2388
+ }],
2389
+ estimatedTimeInSeconds: 150,
2390
+ swapChainType: 'INTRA_CHAIN',
2391
+ routes: null,
2392
+ recommendedSlippage: null,
2393
+ warnings: [],
2394
+ timeStat: {
2395
+ min: 42,
2396
+ avg: 146,
2397
+ max: 5582
2398
+ },
2399
+ includesDestinationTx: true,
2400
+ internalSwaps: null,
2401
+ maxRequiredSign: 6,
2402
+ fromAsset: {
2403
+ blockchain: 'POLYGON',
2404
+ symbol: 'SOL',
2405
+ address: '0xd93f7e271cb87c23aaa73edc008a79646d1f9912'
2406
+ },
2407
+ toAsset: {
2408
+ blockchain: 'SOLANA',
2409
+ symbol: 'SOL',
2410
+ address: null
2411
+ }
2412
+ }],
2413
+ resultType: 'OK'
2414
+ },
2415
+ validateBalanceOrFee: true,
2416
+ steps: [{
2417
+ id: 1,
2418
+ fromBlockchain: 'POLYGON',
2419
+ fromSymbol: 'USDC',
2420
+ fromSymbolAddress: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174',
2421
+ fromDecimals: 6,
2422
+ fromAmountPrecision: null,
2423
+ fromAmountMinValue: null,
2424
+ fromAmountMaxValue: null,
2425
+ toBlockchain: 'POLYGON',
2426
+ fromLogo: 'https://api.rango.exchange/i/ns0AMf',
2427
+ fromBlockchainLogo: 'https://api.rango.exchange/blockchains/polygon.svg',
2428
+ toBlockchainLogo: 'https://api.rango.exchange/blockchains/solana.svg',
2429
+ toSymbol: 'SOL',
2430
+ toSymbolAddress: '0xd93f7e271cb87c23aaa73edc008a79646d1f9912',
2431
+ toDecimals: 9,
2432
+ toLogo: 'https://api.rango.exchange/i/YhJ1nK',
2433
+ startTransactionTime: 1675837904769,
2434
+ swapperId: 'QuickSwap',
2435
+ swapperLogo: 'https://api.rango.exchange/swappers/quick-swap.png',
2436
+ expectedOutputAmountHumanReadable: '0.084249153',
2437
+ outputAmount: '0.084206923',
2438
+ status: 'success',
2439
+ networkStatus: 'networkChanged',
2440
+ executedTransactionId: '0xb2a6b1b497b660bd58d8583d05425ea1b89fa19efc18c9b3baa501abf5f8cee9',
2441
+ externalTransactionId: null,
2442
+ explorerUrl: [{
2443
+ url: 'https://polygonscan.com/tx/0xb2a6b1b497b660bd58d8583d05425ea1b89fa19efc18c9b3baa501abf5f8cee9',
2444
+ description: 'swap'
2445
+ }],
2446
+ trackingCode: null,
2447
+ cosmosTransaction: null,
2448
+ solanaTransaction: null,
2449
+ evmTransaction: {
2450
+ type: 'EVM',
2451
+ blockChain: 'POLYGON',
2452
+ isApprovalTx: false,
2453
+ from: '0x2702d89c1c8658b49c45dd460deebcc45faec03c',
2454
+ to: '0x38F7Aa5370439E879370E24AdD063a11Bd74610D',
2455
+ spender: null,
2456
+ data: '0xa60fdfb60000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174000000000000000000000000d93f7e271cb87c23aaa73edc008a79646d1f991200000000000000000000000000000000000000000000000000000000001e84800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a5e0829caced8ffdd4de3c43696c57f7d7a678ff0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000010438ed173900000000000000000000000000000000000000000000000000000000001e848000000000000000000000000000000000000000000000000000000000045e6b7b00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000038f7aa5370439e879370e24add063a11bd74610d0000000000000000000000000000000000000000000000000000000063e348d800000000000000000000000000000000000000000000000000000000000000020000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174000000000000000000000000d93f7e271cb87c23aaa73edc008a79646d1f991200000000000000000000000000000000000000000000000000000000',
2457
+ value: null,
2458
+ gasLimit: '0x62f20',
2459
+ gasPrice: '247516799843',
2460
+ nonce: null
2461
+ },
2462
+ evmApprovalTransaction: null,
2463
+ transferTransaction: null,
2464
+ diagnosisUrl: null,
2465
+ internalSteps: null
2466
+ }, {
2467
+ id: 2,
2468
+ fromBlockchain: 'POLYGON',
2469
+ fromSymbol: 'SOL',
2470
+ fromSymbolAddress: '0xd93f7e271cb87c23aaa73edc008a79646d1f9912',
2471
+ fromDecimals: 9,
2472
+ fromAmountPrecision: null,
2473
+ fromAmountMinValue: null,
2474
+ fromAmountMaxValue: null,
2475
+ toBlockchain: 'SOLANA',
2476
+ fromLogo: 'https://api.rango.exchange/i/YhJ1nK',
2477
+ fromBlockchainLogo: 'https://api.rango.exchange/blockchains/polygon.svg',
2478
+ toBlockchainLogo: 'https://api.rango.exchange/blockchains/solana.svg',
2479
+ toSymbol: 'SOL',
2480
+ toSymbolAddress: null,
2481
+ toDecimals: 9,
2482
+ toLogo: 'https://api.rango.exchange/i/eLHYrb',
2483
+ startTransactionTime: 1675842459076,
2484
+ swapperId: 'Wormhole',
2485
+ swapperLogo: 'https://api.rango.exchange/swappers/wormhole.png',
2486
+ expectedOutputAmountHumanReadable: '0.084249153',
2487
+ outputAmount: '0.08420692',
2488
+ status: 'failed',
2489
+ networkStatus: 'networkChanged',
2490
+ executedTransactionId: '5MGhqrNRwRKkHGU11S37mgF7LscXWhAvwBeAWEdxcmV9AD6bNqig6iCCzC4mKBH41JBexKb6kj4axLfcH4XZQsT9',
2491
+ externalTransactionId: null,
2492
+ explorerUrl: [{
2493
+ url: 'https://solscan.io/tx/2wvqHEy5hCDfpwZM5sZhBpFxXZL7p6PRqpDdCZGpGF85deGQU9oiBC9Jgoszdo8x9hjkySktGPYzubcXP8pxW3H4',
2494
+ description: 'Associate Token'
2495
+ }, {
2496
+ url: 'https://polygonscan.com/tx/0xcdd0c684fc203d41a0eaacfba2201ab0a48845bb6d0f0805fb4a70a0f971a599',
2497
+ description: 'Transfer'
2498
+ }, {
2499
+ url: 'https://solscan.io/tx/5rc5EHfMrChB749RsJew1ze35yQMddafkQqy5JFqcdKPJ6j2NiggGT7UDmFDAXzP2AwHGyFj2XjaYr7RQjjc1KmH',
2500
+ description: 'Verify vaa 1'
2501
+ }, {
2502
+ url: 'https://solscan.io/tx/5xNgHvdzu63fmF7uojrHuqcHC3NgErpdGiSg38X7KZ7EEjTyPWt8W1QUtuyUFcNcSjGkFGrGzfnkRUbe4Hj6oY2v',
2503
+ description: 'Verify vaa 2'
2504
+ }, {
2505
+ url: 'https://solscan.io/tx/3FnXLYwwpc93o2TyjKNDfiBcRDZ9W1qJVdmCjTRw3kz4Jrwjr5zQzLSbsbbBzqFNMSxBFcUDaiQ7pP4DL5coUGq',
2506
+ description: 'Post vaa'
2507
+ }, {
2508
+ url: 'https://solscan.io/tx/5MGhqrNRwRKkHGU11S37mgF7LscXWhAvwBeAWEdxcmV9AD6bNqig6iCCzC4mKBH41JBexKb6kj4axLfcH4XZQsT9',
2509
+ description: 'Redeem'
2510
+ }],
2511
+ trackingCode: null,
2512
+ cosmosTransaction: null,
2513
+ solanaTransaction: {
2514
+ type: 'SOLANA',
2515
+ blockChain: 'SOLANA',
2516
+ from: '9QoVnPEHj5HNL4cVicXUF8CVmyhBxTDqUUigVn3UPWwk',
2517
+ identifier: 'redeem',
2518
+ instructions: [{
2519
+ keys: [{
2520
+ pubkey: '9QoVnPEHj5HNL4cVicXUF8CVmyhBxTDqUUigVn3UPWwk',
2521
+ isSigner: true,
2522
+ isWritable: true
2523
+ }, {
2524
+ pubkey: 'DapiQYH3BGonhN8cngWcXQ6SrqSm3cwysoznoHr6Sbsx',
2525
+ isSigner: false,
2526
+ isWritable: false
2527
+ }, {
2528
+ pubkey: 'Wf8aqunuZ9y1tprCihMateij299Pa57XL15a6EQz9qt',
2529
+ isSigner: false,
2530
+ isWritable: false
2531
+ }, {
2532
+ pubkey: 'FTWSFuqyc6B5BbarBzuHdBofA2ks12eyRNmUfKmDiUN1',
2533
+ isSigner: false,
2534
+ isWritable: true
2535
+ }, {
2536
+ pubkey: 'J6fNPeeJc1E2zDRUtvD9aaC9kBsEq7JaFr1oa97DAJhj',
2537
+ isSigner: false,
2538
+ isWritable: false
2539
+ }, {
2540
+ pubkey: '8nUPRxuXUJPbWiCbqCPrVLkmXqR8LdifLrRW3VjCQDhZ',
2541
+ isSigner: false,
2542
+ isWritable: true
2543
+ }, {
2544
+ pubkey: '8nUPRxuXUJPbWiCbqCPrVLkmXqR8LdifLrRW3VjCQDhZ',
2545
+ isSigner: false,
2546
+ isWritable: true
2547
+ }, {
2548
+ pubkey: '2nQNF8F9LLWMqdjymiLK2u8HoHMvYa4orCXsp3w65fQ2',
2549
+ isSigner: false,
2550
+ isWritable: true
2551
+ }, {
2552
+ pubkey: 'So11111111111111111111111111111111111111112',
2553
+ isSigner: false,
2554
+ isWritable: false
2555
+ }, {
2556
+ pubkey: 'GugU1tP7doLeTw9hQP51xRJyS8Da1fWxuiy2rVrnMD2m',
2557
+ isSigner: false,
2558
+ isWritable: false
2559
+ }, {
2560
+ pubkey: 'SysvarRent111111111111111111111111111111111',
2561
+ isSigner: false,
2562
+ isWritable: false
2563
+ }, {
2564
+ pubkey: '11111111111111111111111111111111',
2565
+ isSigner: false,
2566
+ isWritable: false
2567
+ }, {
2568
+ pubkey: 'worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth',
2569
+ isSigner: false,
2570
+ isWritable: false
2571
+ }, {
2572
+ pubkey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
2573
+ isSigner: false,
2574
+ isWritable: false
2575
+ }],
2576
+ programId: 'wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb',
2577
+ data: [2]
2578
+ }, {
2579
+ keys: [{
2580
+ pubkey: '9QoVnPEHj5HNL4cVicXUF8CVmyhBxTDqUUigVn3UPWwk',
2581
+ isSigner: true,
2582
+ isWritable: true
2583
+ }, {
2584
+ pubkey: '72pK2FqwMYPr9ajAhzLNQq8e5S2Rf33MGpVXxdXwCT6V',
2585
+ isSigner: true,
2586
+ isWritable: true
2587
+ }],
2588
+ programId: '11111111111111111111111111111111',
2589
+ data: [0, 0, 0, 0, -16, 29, 31, 0, 0, 0, 0, 0, -91, 0, 0, 0, 0, 0, 0, 0, 6, -35, -10, -31, -41, 101, -95, -109, -39, -53, -31, 70, -50, -21, 121, -84, 28, -76, -123, -19, 95, 91, 55, -111, 58, -116, -11, -123, 126, -1, 0, -87]
2590
+ }, {
2591
+ keys: [{
2592
+ pubkey: '72pK2FqwMYPr9ajAhzLNQq8e5S2Rf33MGpVXxdXwCT6V',
2593
+ isSigner: false,
2594
+ isWritable: true
2595
+ }, {
2596
+ pubkey: 'So11111111111111111111111111111111111111112',
2597
+ isSigner: false,
2598
+ isWritable: false
2599
+ }, {
2600
+ pubkey: '9QoVnPEHj5HNL4cVicXUF8CVmyhBxTDqUUigVn3UPWwk',
2601
+ isSigner: false,
2602
+ isWritable: false
2603
+ }, {
2604
+ pubkey: 'SysvarRent111111111111111111111111111111111',
2605
+ isSigner: false,
2606
+ isWritable: false
2607
+ }],
2608
+ programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
2609
+ data: [1]
2610
+ }, {
2611
+ keys: [{
2612
+ pubkey: '8nUPRxuXUJPbWiCbqCPrVLkmXqR8LdifLrRW3VjCQDhZ',
2613
+ isSigner: false,
2614
+ isWritable: true
2615
+ }, {
2616
+ pubkey: '72pK2FqwMYPr9ajAhzLNQq8e5S2Rf33MGpVXxdXwCT6V',
2617
+ isSigner: false,
2618
+ isWritable: true
2619
+ }, {
2620
+ pubkey: '9QoVnPEHj5HNL4cVicXUF8CVmyhBxTDqUUigVn3UPWwk',
2621
+ isSigner: true,
2622
+ isWritable: false
2623
+ }],
2624
+ programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
2625
+ data: [3, 72, -27, 4, 5, 0, 0, 0, 0]
2626
+ }, {
2627
+ keys: [{
2628
+ pubkey: '72pK2FqwMYPr9ajAhzLNQq8e5S2Rf33MGpVXxdXwCT6V',
2629
+ isSigner: false,
2630
+ isWritable: true
2631
+ }, {
2632
+ pubkey: '9QoVnPEHj5HNL4cVicXUF8CVmyhBxTDqUUigVn3UPWwk',
2633
+ isSigner: false,
2634
+ isWritable: true
2635
+ }, {
2636
+ pubkey: '9QoVnPEHj5HNL4cVicXUF8CVmyhBxTDqUUigVn3UPWwk',
2637
+ isSigner: true,
2638
+ isWritable: false
2639
+ }],
2640
+ programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
2641
+ data: [9]
2642
+ }],
2643
+ recentBlockhash: '2wBCvR3jVNj6wzL8vHSuqTRtxBYiwhtoY6Gkp6WaBxSG',
2644
+ signatures: [{
2645
+ publicKey: '72pK2FqwMYPr9ajAhzLNQq8e5S2Rf33MGpVXxdXwCT6V',
2646
+ signature: [-116, 17, -5, 86, -122, 120, -7, -53, -29, -15, -70, -100, 16, 48, 113, -42, 8, 126, 75, -13, 63, -31, -17, 1, 74, 85, 77, 90, 98, -15, 104, 63, 4, -74, 45, -3, -3, -117, -24, -56, 20, -89, -40, 33, 125, -120, -44, -75, 17, 69, 20, -48, 106, 48, 16, -19, 83, 123, -77, 93, -20, -27, -77, 7]
2647
+ }],
2648
+ serializedMessage: null
2649
+ },
2650
+ evmTransaction: null,
2651
+ evmApprovalTransaction: null,
2652
+ transferTransaction: null,
2653
+ diagnosisUrl: null,
2654
+ internalSteps: [{
2655
+ name: 'associate token address',
2656
+ state: 'SUCCESSED',
2657
+ current: false
2658
+ }, {
2659
+ name: 'transfer',
2660
+ state: 'SUCCESSED',
2661
+ current: false
2662
+ }, {
2663
+ name: 'signed vaa',
2664
+ state: 'SUCCESSED',
2665
+ current: false
2666
+ }, {
2667
+ name: 'verify vaa#1',
2668
+ state: 'SUCCESSED',
2669
+ current: false
2670
+ }, {
2671
+ name: 'verify vaa#2',
2672
+ state: 'SUCCESSED',
2673
+ current: false
2674
+ }, {
2675
+ name: 'post vaa',
2676
+ state: 'SUCCESSED',
2677
+ current: false
2678
+ }, {
2679
+ name: 'redeem',
2680
+ state: 'SUCCESSED',
2681
+ current: true
2682
+ }]
2683
+ }]
2684
+ };
2685
+
2686
+ function SwapDetailsPage() {
2687
+ const navigate = useNavigate();
2688
+ return React.createElement(SwapHistory, {
2689
+ onBack: navigate.bind(null, -1),
2690
+ pendingSwap: pendingSwap$1
2691
+ });
2692
+ }
2693
+
2694
+ const AppRoutes = () => useRoutes([{
2695
+ path: navigationRoutes.home,
2696
+ element: React.createElement(Home, null)
2697
+ }, {
2698
+ path: navigationRoutes.fromChain,
2699
+ element: React.createElement(SelectChainPage, {
2700
+ type: "from"
2701
+ })
2702
+ }, {
2703
+ path: navigationRoutes.toChain,
2704
+ element: React.createElement(SelectChainPage, {
2705
+ type: "to"
2706
+ })
2707
+ }, {
2708
+ path: navigationRoutes.fromToken + '/*',
2709
+ element: React.createElement(SelectTokenPage, {
2710
+ type: "from"
2711
+ })
2712
+ }, {
2713
+ path: navigationRoutes.toToken,
2714
+ element: React.createElement(SelectTokenPage, {
2715
+ type: "to"
2716
+ })
2717
+ }, {
2718
+ path: navigationRoutes.settings,
2719
+ element: React.createElement(SettingsPage, null)
2720
+ }, {
2721
+ path: navigationRoutes.liquiditySources,
2722
+ element: React.createElement(LiquiditySourcePage, null)
2723
+ }, {
2724
+ path: navigationRoutes.history,
2725
+ element: React.createElement(HistoryPage, null)
2726
+ }, {
2727
+ path: navigationRoutes.wallets,
2728
+ element: React.createElement(WalletsPage, null)
2729
+ }, {
2730
+ path: navigationRoutes.confirmSwap,
2731
+ element: React.createElement(ConfirmSwapPage, null)
2732
+ }, {
2733
+ path: navigationRoutes.confirmWallets,
2734
+ element: React.createElement(ConfirmWalletsPage, null)
2735
+ }, {
2736
+ path: navigationRoutes.swapDetails,
2737
+ element: React.createElement(SwapDetailsPage, null)
2738
+ }]);
2739
+
2740
+ const Header$1 = /*#__PURE__*/styled('div', {
2741
+ display: 'flex',
2742
+ width: '100%',
2743
+ justifyContent: 'end'
2744
+ });
2745
+ const WalletImage = /*#__PURE__*/styled('img', {
2746
+ width: '$24',
2747
+ height: '$24',
2748
+ marginLeft: -15,
2749
+ marginRight: '$6',
2750
+ borderRadius: '99999px'
2751
+ });
2752
+ function Layout() {
2753
+ const navigate = useNavigate();
2754
+ const {
2755
+ balances,
2756
+ accounts,
2757
+ selectedWallets
2758
+ } = useWalletsStore();
2759
+ const {
2760
+ getWalletInfo
2761
+ } = useWallets();
2762
+ const filterSelelectedWallets = getSelectableWallets(accounts, selectedWallets, getWalletInfo);
2763
+ const totalBalance = calculateWalletUsdValue(balances);
2764
+ return React.createElement(React.Fragment, null, React.createElement(Header$1, null, React.createElement(Button, {
2765
+ size: "small",
2766
+ suffix: React.createElement(AddWalletIcon, {
2767
+ size: 20
2768
+ }),
2769
+ variant: "ghost",
2770
+ flexContent: true,
2771
+ onClick: () => navigate(navigationRoutes.wallets)
2772
+ }, accounts?.length ? filterSelelectedWallets.map((selectedWallet, index) => React.createElement(WalletImage, {
2773
+ key: index,
2774
+ src: selectedWallet.image
2775
+ })) : React.createElement(React.Fragment, null), React.createElement(Typography, {
2776
+ variant: "body2"
2777
+ }, !accounts?.length ? 'Connect Wallet' : `$${totalBalance || 0}`))), React.createElement(AppRoutes, null));
2778
+ }
2779
+
2780
+ const globalStyles = /*#__PURE__*/globalCss({
2781
+ '*': {
2782
+ '&::-webkit-scrollbar': {
2783
+ width: '$8'
2784
+ },
2785
+ '&::-webkit-scrollbar-thumb': {
2786
+ backgroundColor: '$neutrals400'
2787
+ },
2788
+ '&::-webkit-scrollbar-thumb:hover': {
2789
+ backgroundColor: '$neutrals500'
2790
+ },
2791
+ '&::-webkit-scrollbar-track': {
2792
+ backgroundColor: '$neutrals300'
2793
+ }
2794
+ }
2795
+ });
2796
+
2797
+ function useTheme() {
2798
+ const theme = useSettingsStore.use.theme();
2799
+ const fetchMeta = useMetaStore.use.fetchMeta();
2800
+ const [OSTheme, setOSTheme] = useState(lightTheme);
2801
+ useEffect(() => {
2802
+ (async () => {
2803
+ await fetchMeta();
2804
+ })();
2805
+ const switchTheme = event => {
2806
+ if (event.matches) setOSTheme(darkTheme);else setOSTheme(lightTheme);
2807
+ };
2808
+ if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
2809
+ setOSTheme(darkTheme);
2810
+ }
2811
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', switchTheme);
2812
+ return () => {
2813
+ window.matchMedia('(prefers-color-scheme: dark)').removeEventListener('change', switchTheme);
2814
+ };
2815
+ }, []);
2816
+ const getActiveTheme = () => {
2817
+ if (theme === 'auto') return OSTheme;else return theme === 'dark' ? darkTheme : lightTheme;
2818
+ };
2819
+ return {
2820
+ activeTheme: getActiveTheme()
2821
+ };
2822
+ }
2823
+
2824
+ const providers = /*#__PURE__*/allProviders();
2825
+ const SwapBox = () => {
2826
+ globalStyles();
2827
+ const {
2828
+ activeTheme
2829
+ } = useTheme();
2830
+ const {
2831
+ blockchains
2832
+ } = useMetaStore.use.meta();
2833
+ const disconnectWallet = useWalletsStore.use.disconnectWallet();
2834
+ const connectWallet = useWalletsStore.use.connectWallet();
2835
+ const evmBasedChainNames = blockchains.filter(isEvmBlockchain).map(chain => chain.name);
2836
+ const onUpdateState = (type, event, value, supportedChains) => {
2837
+ if (event === Events.ACCOUNTS) {
2838
+ if (value) {
2839
+ const supportedChainNames =
2840
+ //@ts-ignore
2841
+ walletAndSupportedChainsNames(supportedChains);
2842
+ const data = prepareAccountsForWalletStore(type, value, evmBasedChainNames, supportedChainNames);
2843
+ connectWallet(data);
2844
+ } else {
2845
+ disconnectWallet(type);
2846
+ }
2847
+ }
2848
+ };
2849
+ return React.createElement(Provider, {
2850
+ allBlockChains: blockchains,
2851
+ providers: providers,
2852
+ onUpdateState: onUpdateState
2853
+ }, React.createElement("div", {
2854
+ id: "pageContainer",
2855
+ className: activeTheme
2856
+ }, React.createElement(SwapContainer, null, React.createElement(AppRouter, null, React.createElement(Layout, null)))));
2857
+ };
2858
+
2859
+ export { SwapBox };
2860
+ //# sourceMappingURL=widget-embedded.esm.js.map