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