@rango-dev/widget-embedded 0.1.10-next.100

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 (204) hide show
  1. package/dist/App.d.ts +9 -0
  2. package/dist/App.d.ts.map +1 -0
  3. package/dist/QueueManager.d.ts +4 -0
  4. package/dist/QueueManager.d.ts.map +1 -0
  5. package/dist/components/AppRouter.d.ts +9 -0
  6. package/dist/components/AppRouter.d.ts.map +1 -0
  7. package/dist/components/AppRoutes.d.ts +8 -0
  8. package/dist/components/AppRoutes.d.ts.map +1 -0
  9. package/dist/components/BottomLogo.d.ts +3 -0
  10. package/dist/components/BottomLogo.d.ts.map +1 -0
  11. package/dist/components/ChangeSlippageButton.d.ts +3 -0
  12. package/dist/components/ChangeSlippageButton.d.ts.map +1 -0
  13. package/dist/components/ConfirmSwapErrors.d.ts +4 -0
  14. package/dist/components/ConfirmSwapErrors.d.ts.map +1 -0
  15. package/dist/components/ConfirmSwapWarnings.d.ts +4 -0
  16. package/dist/components/ConfirmSwapWarnings.d.ts.map +1 -0
  17. package/dist/components/Footer.d.ts +2 -0
  18. package/dist/components/Footer.d.ts.map +1 -0
  19. package/dist/components/Header.d.ts +10 -0
  20. package/dist/components/Header.d.ts.map +1 -0
  21. package/dist/components/HeaderButtons.d.ts +4 -0
  22. package/dist/components/HeaderButtons.d.ts.map +1 -0
  23. package/dist/components/Layout.d.ts +7 -0
  24. package/dist/components/Layout.d.ts.map +1 -0
  25. package/dist/components/RoutesOverview.d.ts +10 -0
  26. package/dist/components/RoutesOverview.d.ts.map +1 -0
  27. package/dist/components/SwitchFromAndTo.d.ts +4 -0
  28. package/dist/components/SwitchFromAndTo.d.ts.map +1 -0
  29. package/dist/components/TokenInfo.d.ts +18 -0
  30. package/dist/components/TokenInfo.d.ts.map +1 -0
  31. package/dist/components/TokenPreview.d.ts +20 -0
  32. package/dist/components/TokenPreview.d.ts.map +1 -0
  33. package/dist/components/UpdateUrl.d.ts +2 -0
  34. package/dist/components/UpdateUrl.d.ts.map +1 -0
  35. package/dist/components/warnings/BalanceWarnings.d.ts +7 -0
  36. package/dist/components/warnings/BalanceWarnings.d.ts.map +1 -0
  37. package/dist/components/warnings/ConfirmSwapExtraMessages.d.ts +7 -0
  38. package/dist/components/warnings/ConfirmSwapExtraMessages.d.ts.map +1 -0
  39. package/dist/components/warnings/HighSlippageWarning.d.ts +7 -0
  40. package/dist/components/warnings/HighSlippageWarning.d.ts.map +1 -0
  41. package/dist/components/warnings/MinRequiredSlippage.d.ts +7 -0
  42. package/dist/components/warnings/MinRequiredSlippage.d.ts.map +1 -0
  43. package/dist/constants/errors.d.ts +4 -0
  44. package/dist/constants/errors.d.ts.map +1 -0
  45. package/dist/constants/navigationRoutes.d.ts +15 -0
  46. package/dist/constants/navigationRoutes.d.ts.map +1 -0
  47. package/dist/constants/numbers.d.ts +3 -0
  48. package/dist/constants/numbers.d.ts.map +1 -0
  49. package/dist/constants/searchParams.d.ts +8 -0
  50. package/dist/constants/searchParams.d.ts.map +1 -0
  51. package/dist/constants/swapSettings.d.ts +6 -0
  52. package/dist/constants/swapSettings.d.ts.map +1 -0
  53. package/dist/globalStyles.d.ts +3 -0
  54. package/dist/globalStyles.d.ts.map +1 -0
  55. package/dist/hooks/useConfirmSwap.d.ts +11 -0
  56. package/dist/hooks/useConfirmSwap.d.ts.map +1 -0
  57. package/dist/hooks/useCopyToClipboard.d.ts +2 -0
  58. package/dist/hooks/useCopyToClipboard.d.ts.map +1 -0
  59. package/dist/hooks/useNavigateBack.d.ts +4 -0
  60. package/dist/hooks/useNavigateBack.d.ts.map +1 -0
  61. package/dist/hooks/usePrevious.d.ts +2 -0
  62. package/dist/hooks/usePrevious.d.ts.map +1 -0
  63. package/dist/hooks/useSelectLanguage.d.ts +5 -0
  64. package/dist/hooks/useSelectLanguage.d.ts.map +1 -0
  65. package/dist/hooks/useTheme.d.ts +8 -0
  66. package/dist/hooks/useTheme.d.ts.map +1 -0
  67. package/dist/i18n.d.ts +3 -0
  68. package/dist/i18n.d.ts.map +1 -0
  69. package/dist/index.d.ts +2 -0
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.js +8 -0
  72. package/dist/lib.d.ts +8 -0
  73. package/dist/lib.d.ts.map +1 -0
  74. package/dist/mockData/pendingSwap.d.ts +2 -0
  75. package/dist/mockData/pendingSwap.d.ts.map +1 -0
  76. package/dist/pages/ConfirmSwapPage.d.ts +3 -0
  77. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -0
  78. package/dist/pages/ConfirmWalletsPage.d.ts +3 -0
  79. package/dist/pages/ConfirmWalletsPage.d.ts.map +1 -0
  80. package/dist/pages/HistoryPage.d.ts +3 -0
  81. package/dist/pages/HistoryPage.d.ts.map +1 -0
  82. package/dist/pages/Home.d.ts +9 -0
  83. package/dist/pages/Home.d.ts.map +1 -0
  84. package/dist/pages/LiquiditySourcesPage.d.ts +8 -0
  85. package/dist/pages/LiquiditySourcesPage.d.ts.map +1 -0
  86. package/dist/pages/SelectChainPage.d.ts +9 -0
  87. package/dist/pages/SelectChainPage.d.ts.map +1 -0
  88. package/dist/pages/SelectTokenPage.d.ts +15 -0
  89. package/dist/pages/SelectTokenPage.d.ts.map +1 -0
  90. package/dist/pages/SettingsPage.d.ts +8 -0
  91. package/dist/pages/SettingsPage.d.ts.map +1 -0
  92. package/dist/pages/SwapDetailsPage.d.ts +3 -0
  93. package/dist/pages/SwapDetailsPage.d.ts.map +1 -0
  94. package/dist/pages/WalletsPage.d.ts +9 -0
  95. package/dist/pages/WalletsPage.d.ts.map +1 -0
  96. package/dist/services/httpService.d.ts +3 -0
  97. package/dist/services/httpService.d.ts.map +1 -0
  98. package/dist/store/bestRoute.d.ts +28 -0
  99. package/dist/store/bestRoute.d.ts.map +1 -0
  100. package/dist/store/meta.d.ts +9 -0
  101. package/dist/store/meta.d.ts.map +1 -0
  102. package/dist/store/selectors.d.ts +11 -0
  103. package/dist/store/selectors.d.ts.map +1 -0
  104. package/dist/store/settings.d.ts +17 -0
  105. package/dist/store/settings.d.ts.map +1 -0
  106. package/dist/store/ui.d.ts +2 -0
  107. package/dist/store/ui.d.ts.map +1 -0
  108. package/dist/store/wallets.d.ts +28 -0
  109. package/dist/store/wallets.d.ts.map +1 -0
  110. package/dist/types/config.d.ts +40 -0
  111. package/dist/types/config.d.ts.map +1 -0
  112. package/dist/types/index.d.ts +4 -0
  113. package/dist/types/index.d.ts.map +1 -0
  114. package/dist/types/routing.d.ts +45 -0
  115. package/dist/types/routing.d.ts.map +1 -0
  116. package/dist/types/swap.d.ts +11 -0
  117. package/dist/types/swap.d.ts.map +1 -0
  118. package/dist/utils/common.d.ts +4 -0
  119. package/dist/utils/common.d.ts.map +1 -0
  120. package/dist/utils/numbers.d.ts +14 -0
  121. package/dist/utils/numbers.d.ts.map +1 -0
  122. package/dist/utils/queue.d.ts +4 -0
  123. package/dist/utils/queue.d.ts.map +1 -0
  124. package/dist/utils/routing.d.ts +18 -0
  125. package/dist/utils/routing.d.ts.map +1 -0
  126. package/dist/utils/swap.d.ts +45 -0
  127. package/dist/utils/swap.d.ts.map +1 -0
  128. package/dist/utils/wallets.d.ts +29 -0
  129. package/dist/utils/wallets.d.ts.map +1 -0
  130. package/dist/widget-embedded.cjs.development.js +3101 -0
  131. package/dist/widget-embedded.cjs.development.js.map +1 -0
  132. package/dist/widget-embedded.cjs.production.min.js +3101 -0
  133. package/dist/widget-embedded.cjs.production.min.js.map +1 -0
  134. package/dist/widget-embedded.esm.js +3092 -0
  135. package/dist/widget-embedded.esm.js.map +1 -0
  136. package/package.json +55 -0
  137. package/readme.md +2 -0
  138. package/src/App.tsx +91 -0
  139. package/src/QueueManager.tsx +94 -0
  140. package/src/app.css +27 -0
  141. package/src/components/AppRouter.tsx +60 -0
  142. package/src/components/AppRoutes.tsx +105 -0
  143. package/src/components/BottomLogo.tsx +47 -0
  144. package/src/components/ChangeSlippageButton.tsx +19 -0
  145. package/src/components/ConfirmSwapErrors.tsx +38 -0
  146. package/src/components/ConfirmSwapWarnings.tsx +35 -0
  147. package/src/components/Footer.tsx +8 -0
  148. package/src/components/Header.tsx +37 -0
  149. package/src/components/HeaderButtons.tsx +47 -0
  150. package/src/components/Layout.tsx +96 -0
  151. package/src/components/RoutesOverview.tsx +60 -0
  152. package/src/components/SwitchFromAndTo.tsx +30 -0
  153. package/src/components/TokenInfo.tsx +311 -0
  154. package/src/components/TokenPreview.tsx +175 -0
  155. package/src/components/UpdateUrl.tsx +162 -0
  156. package/src/components/warnings/BalanceWarnings.tsx +39 -0
  157. package/src/components/warnings/ConfirmSwapExtraMessages.tsx +20 -0
  158. package/src/components/warnings/HighSlippageWarning.tsx +18 -0
  159. package/src/components/warnings/MinRequiredSlippage.tsx +18 -0
  160. package/src/constants/errors.ts +3 -0
  161. package/src/constants/navigationRoutes.ts +14 -0
  162. package/src/constants/numbers.ts +3 -0
  163. package/src/constants/searchParams.ts +7 -0
  164. package/src/constants/swapSettings.ts +9 -0
  165. package/src/globalStyles.ts +26 -0
  166. package/src/hooks/useConfirmSwap.ts +260 -0
  167. package/src/hooks/useCopyToClipboard.ts +23 -0
  168. package/src/hooks/useNavigateBack.ts +40 -0
  169. package/src/hooks/usePrevious.ts +13 -0
  170. package/src/hooks/useSelectLanguage.ts +15 -0
  171. package/src/hooks/useTheme.ts +127 -0
  172. package/src/i18n.js +30 -0
  173. package/src/index.tsx +14 -0
  174. package/src/languages/en.json +14 -0
  175. package/src/languages/tr.json +11 -0
  176. package/src/lib.tsx +119 -0
  177. package/src/mockData/pendingSwap.ts +607 -0
  178. package/src/pages/ConfirmSwapPage.tsx +72 -0
  179. package/src/pages/ConfirmWalletsPage.tsx +127 -0
  180. package/src/pages/HistoryPage.tsx +29 -0
  181. package/src/pages/Home.tsx +228 -0
  182. package/src/pages/LiquiditySourcesPage.tsx +64 -0
  183. package/src/pages/SelectChainPage.tsx +42 -0
  184. package/src/pages/SelectTokenPage.tsx +64 -0
  185. package/src/pages/SettingsPage.tsx +98 -0
  186. package/src/pages/SwapDetailsPage.tsx +38 -0
  187. package/src/pages/WalletsPage.tsx +119 -0
  188. package/src/services/httpService.ts +5 -0
  189. package/src/store/bestRoute.ts +245 -0
  190. package/src/store/meta.ts +35 -0
  191. package/src/store/selectors.ts +19 -0
  192. package/src/store/settings.ts +84 -0
  193. package/src/store/ui.ts +21 -0
  194. package/src/store/wallets.ts +190 -0
  195. package/src/types/config.ts +44 -0
  196. package/src/types/index.ts +3 -0
  197. package/src/types/routing.ts +60 -0
  198. package/src/types/swap.ts +13 -0
  199. package/src/utils/common.ts +35 -0
  200. package/src/utils/numbers.ts +133 -0
  201. package/src/utils/queue.ts +24 -0
  202. package/src/utils/routing.ts +150 -0
  203. package/src/utils/swap.ts +552 -0
  204. package/src/utils/wallets.ts +481 -0
@@ -0,0 +1,3101 @@
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 BigNumber = require('bignumber.js');
14
+ var BigNumber__default = _interopDefault(BigNumber);
15
+ var walletsShared = require('@rango-dev/wallets-shared');
16
+ var rangoTypes = require('rango-types');
17
+ var walletsCore = require('@rango-dev/wallets-core');
18
+ var middleware = require('zustand/middleware');
19
+ var rangoSdk = require('rango-sdk');
20
+ var shallow = require('zustand/shallow');
21
+ var reactI18next = require('react-i18next');
22
+ var theme = require('@rango-dev/ui/src/theme');
23
+ var providerAll = require('@rango-dev/provider-all');
24
+ var queueManagerReact = require('@rango-dev/queue-manager-react');
25
+ var i18n = require('i18next');
26
+ var i18n__default = _interopDefault(i18n);
27
+ var copy = _interopDefault(require('copy-to-clipboard'));
28
+ var queueManagerRangoPreset = require('@rango-dev/queue-manager-rango-preset');
29
+ var Backend = _interopDefault(require('i18next-http-backend'));
30
+ var LanguageDetector = _interopDefault(require('i18next-browser-languagedetector'));
31
+
32
+ const navigationRoutes = {
33
+ home: '/',
34
+ fromChain: '/from-chain',
35
+ fromToken: '/from-token',
36
+ toChain: '/to-chain',
37
+ toToken: '/to-token',
38
+ settings: '/settings',
39
+ liquiditySources: '/settings/liquidity-sources',
40
+ swaps: '/swaps',
41
+ wallets: '/wallets',
42
+ confirmSwap: '/confirm-swap',
43
+ confirmWallets: '/confirm-wallets',
44
+ swapDetails: '/swaps/:requestId'
45
+ };
46
+
47
+ const ZERO = /*#__PURE__*/new BigNumber__default(0);
48
+
49
+ function removeDuplicateFrom(array) {
50
+ return Array.from(new Set(array));
51
+ }
52
+ function areEqual(array1, array2) {
53
+ return array1.length === array2.length && array1.every((v, i) => v === array2[i]);
54
+ }
55
+ function shadeColor(color, percent) {
56
+ var R = parseInt(color.substring(1, 3), 16);
57
+ var G = parseInt(color.substring(3, 5), 16);
58
+ var B = parseInt(color.substring(5, 7), 16);
59
+ R = R * (100 + percent) / 100;
60
+ G = G * (100 + percent) / 100;
61
+ B = B * (100 + percent) / 100;
62
+ R = R < 255 ? R : 255;
63
+ G = G < 255 ? G : 255;
64
+ B = B < 255 ? B : 255;
65
+ R = Math.round(R);
66
+ G = Math.round(G);
67
+ B = Math.round(B);
68
+ var RR = R.toString(16).length == 1 ? '0' + R.toString(16) : R.toString(16);
69
+ var GG = G.toString(16).length == 1 ? '0' + G.toString(16) : G.toString(16);
70
+ var BB = B.toString(16).length == 1 ? '0' + B.toString(16) : B.toString(16);
71
+ return '#' + RR + GG + BB;
72
+ }
73
+
74
+ const secondsToString = s => {
75
+ const seconds = (s % 60).toString().padStart(2, '0');
76
+ const minutes = parseInt((s / 60).toString()).toString().padStart(2, '0');
77
+ return `${minutes}:${seconds}`;
78
+ };
79
+ const numberToString = function (number, minDecimals, maxDecimals) {
80
+ if (minDecimals === void 0) {
81
+ minDecimals = null;
82
+ }
83
+ if (maxDecimals === void 0) {
84
+ maxDecimals = null;
85
+ }
86
+ if (number === null) return '';
87
+ if (number === '') return '';
88
+ const n = new BigNumber.BigNumber(number);
89
+ const roundingMode = 1;
90
+ let maxI = 1000;
91
+ for (let i = 0; i < 60; i++) {
92
+ if (new BigNumber.BigNumber(n.toFixed(i, roundingMode)).eq(n)) {
93
+ maxI = i;
94
+ break;
95
+ }
96
+ }
97
+ if (n.gte(10000)) return n.toFormat(0, roundingMode);
98
+ if (n.gte(1000)) return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 1))), roundingMode);
99
+ if (n.gte(100)) return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 1))), roundingMode);
100
+ if (n.gte(1)) return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 2))), roundingMode);
101
+ if (n.gte(0.01)) return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 4))), roundingMode);
102
+ 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);
103
+ if (n.isEqualTo(0)) return '0';
104
+ return n.toFormat(Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 8))), roundingMode);
105
+ };
106
+ const totalArrivalTime = data => data?.result?.swaps?.reduce((a, b) => a + b.estimatedTimeInSeconds, 0) || 0;
107
+ const decimalNumber = function (number, toFixed) {
108
+ if (number === void 0) {
109
+ number = '0';
110
+ }
111
+ return parseFloat(number).toFixed(toFixed);
112
+ };
113
+
114
+ function getStateWallet(state) {
115
+ switch (true) {
116
+ case state.connected:
117
+ return ui.WalletState.CONNECTED;
118
+ case state.connecting:
119
+ return ui.WalletState.CONNECTING;
120
+ case !state.installed:
121
+ return ui.WalletState.NOT_INSTALLED;
122
+ default:
123
+ return ui.WalletState.DISCONNECTED;
124
+ }
125
+ }
126
+ function getlistWallet(getState, getWalletInfo, list) {
127
+ const excludedWallets = [walletsShared.WalletType.UNKNOWN, walletsShared.WalletType.TERRA_STATION, walletsShared.WalletType.LEAP];
128
+ return list.filter(wallet => !excludedWallets.includes(wallet)).map(type => {
129
+ const {
130
+ name,
131
+ img: image,
132
+ installLink,
133
+ showOnMobile
134
+ } = getWalletInfo(type);
135
+ const state = getStateWallet(getState(type));
136
+ return {
137
+ name,
138
+ image,
139
+ installLink: walletsShared.detectInstallLink(installLink),
140
+ state,
141
+ type,
142
+ showOnMobile: typeof showOnMobile === 'undefined' ? false : true
143
+ };
144
+ });
145
+ }
146
+ function walletAndSupportedChainsNames(supportedChains) {
147
+ if (!supportedChains) return null;
148
+ let walletAndSupportedChainsNames = [];
149
+ walletAndSupportedChainsNames = supportedChains.map(blockchainMeta => blockchainMeta.name);
150
+ return walletAndSupportedChainsNames;
151
+ }
152
+ function prepareAccountsForWalletStore(wallet, accounts, evmBasedChains, supportedChainNames) {
153
+ const result = [];
154
+ function addAccount(network, address) {
155
+ const newAccount = {
156
+ address,
157
+ chain: network,
158
+ walletType: wallet
159
+ };
160
+ result.push(newAccount);
161
+ }
162
+ const supportedChains = supportedChainNames || [];
163
+ accounts.forEach(account => {
164
+ const {
165
+ address,
166
+ network
167
+ } = walletsCore.readAccountAddress(account);
168
+ const hasLimitation = supportedChains.length > 0;
169
+ const isSupported = supportedChains.includes(network);
170
+ const isUnknown = network === walletsShared.Network.Unknown;
171
+ const notSupportedNetworkByWallet = hasLimitation && !isSupported && !isUnknown;
172
+ // Here we check given `network` is not supported by wallet
173
+ // And also the network is known.
174
+ if (notSupportedNetworkByWallet) return;
175
+ // In some cases we can handle unknown network by checking its address
176
+ // pattern and act on it.
177
+ // Example: showing our evm compatible netwrok when the uknown network is evem.
178
+ // Otherwise, we stop executing this function.
179
+ const isUknownAndEvmBased = network === walletsShared.Network.Unknown && walletsShared.isEvmAddress(address);
180
+ if (isUnknown && !isUknownAndEvmBased) return;
181
+ const isEvmBasedChain = evmBasedChains.includes(network);
182
+ // If it's an evm network, we will add the address to all the evm chains.
183
+ if (isEvmBasedChain || isUknownAndEvmBased) {
184
+ // all evm chains are not supported in wallets, so we are adding
185
+ // only to those that are supported by wallet.
186
+ const evmChainsSupportedByWallet = supportedChains.filter(chain => evmBasedChains.includes(chain));
187
+ evmChainsSupportedByWallet.forEach(network => {
188
+ // EVM addresses are not case sensetive.
189
+ // Some wallets like Binance-chain return some letters in uppercase which produces bugs in our wallet state.
190
+ addAccount(network, address.toLowerCase());
191
+ });
192
+ } else {
193
+ addAccount(network, address);
194
+ }
195
+ });
196
+ return result;
197
+ }
198
+ function getRequiredChains(route) {
199
+ const wallets = [];
200
+ route?.result?.swaps.forEach(swap => {
201
+ const currentStepFromBlockchain = swap.from.blockchain;
202
+ const currentStepToBlockchain = swap.to.blockchain;
203
+ let lastAddedWallet = wallets[wallets.length - 1];
204
+ if (currentStepFromBlockchain != lastAddedWallet) wallets.push(currentStepFromBlockchain);
205
+ lastAddedWallet = wallets[wallets.length - 1];
206
+ if (currentStepToBlockchain != lastAddedWallet) wallets.push(currentStepToBlockchain);
207
+ });
208
+ return wallets;
209
+ }
210
+ function getSelectableWallets(accounts, selectedWallets, getWalletInfo) {
211
+ const connectedWallets = accounts.map(account => ({
212
+ address: account.address,
213
+ walletType: account.walletType,
214
+ chain: account.chain,
215
+ image: getWalletInfo(account.walletType).img,
216
+ name: getWalletInfo(account.walletType).name,
217
+ selected: !!selectedWallets.find(wallet => wallet.chain === account.chain && wallet.walletType === account.walletType)
218
+ }));
219
+ return connectedWallets;
220
+ }
221
+ function getBalanceFromWallet(balances, chain, symbol, address) {
222
+ if (balances.length === 0) return null;
223
+ const selectedChainBalances = balances.filter(balance => balance.chain === chain);
224
+ if (selectedChainBalances.length === 0) return null;
225
+ 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;
226
+ }
227
+ function isAccountAndBalanceMatched(account, balance) {
228
+ return account.address === balance.address && account.chain === balance.chain && account.walletType === balance.walletType;
229
+ }
230
+ function makeBalanceFor(account, retrivedBalance, tokens) {
231
+ const {
232
+ address,
233
+ blockChain: chain,
234
+ explorerUrl,
235
+ balances = []
236
+ } = retrivedBalance;
237
+ return {
238
+ address,
239
+ chain,
240
+ loading: false,
241
+ error: false,
242
+ explorerUrl,
243
+ walletType: account.walletType,
244
+ balances: balances?.map(tokenBalance => ({
245
+ chain,
246
+ symbol: tokenBalance.asset.symbol,
247
+ ticker: tokenBalance.asset.symbol,
248
+ address: tokenBalance.asset.address || null,
249
+ rawAmount: tokenBalance.amount.amount,
250
+ decimal: tokenBalance.amount.decimals,
251
+ amount: new BigNumber__default(tokenBalance.amount.amount).shiftedBy(-tokenBalance.amount.decimals).toFixed(),
252
+ logo: '',
253
+ usdPrice: getUsdPrice(chain, tokenBalance.asset.symbol, tokenBalance.asset.address, tokens) || null
254
+ })) || []
255
+ };
256
+ }
257
+ function resetBalanceState(balance) {
258
+ return {
259
+ ...balance,
260
+ loading: false,
261
+ error: true
262
+ };
263
+ }
264
+ const calculateWalletUsdValue = balance => {
265
+ const uniqueAccountAddresses = new Set();
266
+ const uniqueBalane = balance?.reduce((acc, current) => {
267
+ return acc.findIndex(i => i.address === current.address && i.chain === current.chain) === -1 ? [...acc, current] : acc;
268
+ }, []);
269
+ const modifiedWalletBlockchains = uniqueBalane?.map(chain => {
270
+ const modifiedWalletBlockchain = {
271
+ name: chain.chain,
272
+ accounts: []
273
+ };
274
+ if (!uniqueAccountAddresses.has(chain.address)) {
275
+ uniqueAccountAddresses.add(chain.address);
276
+ }
277
+ uniqueAccountAddresses.forEach(accountAddress => {
278
+ if (chain.address === accountAddress) modifiedWalletBlockchain.accounts.push(chain);
279
+ });
280
+ return modifiedWalletBlockchain;
281
+ });
282
+ 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();
283
+ return numberWithThousandSeperator(total);
284
+ };
285
+ function numberWithThousandSeperator(number) {
286
+ var parts = number.toString().split('.');
287
+ parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
288
+ return parts.join('.');
289
+ }
290
+ const sortTokens = tokens => {
291
+ let walletConnected = !!tokens.some(token => token.balance);
292
+ if (!walletConnected) {
293
+ return tokens.filter(token => !token.address).concat(tokens.filter(token => token.address && !token.isSecondaryCoin), tokens.filter(token => token.isSecondaryCoin));
294
+ }
295
+ return tokens.filter(token => !!token.balance).sort((tokenA, tokenB) => parseFloat(tokenB.balance?.usdValue || '0') - parseFloat(tokenA.balance?.usdValue || '0')).concat(tokens.filter(token => !token.balance && !token.isSecondaryCoin), tokens.filter(token => !token.balance && token.isSecondaryCoin));
296
+ };
297
+ const getUsdPrice = (blockchain, symbol, address, allTokens) => {
298
+ const token = allTokens?.find(t => t.blockchain === blockchain && t.symbol?.toUpperCase() === symbol?.toUpperCase() && t.address === address);
299
+ return token?.usdPrice || null;
300
+ };
301
+ const isExperimentalChain = (blockchains, wallet) => {
302
+ const cosmosExperimentalChainInfo = walletsShared.getCosmosExperimentalChainInfo(Object.entries(blockchains).map(_ref => {
303
+ let [, blockchainMeta] = _ref;
304
+ return blockchainMeta;
305
+ }).filter(rangoTypes.isCosmosBlockchain));
306
+ return cosmosExperimentalChainInfo && !!cosmosExperimentalChainInfo[wallet];
307
+ };
308
+ const getKeplrCompatibleConnectedWallets = selectableWallets => {
309
+ const connectedWalletTypes = new Set(selectableWallets.map(a => a.walletType.toString()));
310
+ return walletsShared.KEPLR_COMPATIBLE_WALLETS.filter(compatibleWallet => connectedWalletTypes.has(compatibleWallet));
311
+ };
312
+ function getTokensWithBalance(tokens, balances) {
313
+ return tokens.map(_ref2 => {
314
+ let {
315
+ balance,
316
+ ...otherProps
317
+ } = _ref2;
318
+ const tokenAmount = numberToString(new BigNumber__default(getBalanceFromWallet(balances, otherProps.blockchain, otherProps.symbol, otherProps.address)?.amount || ZERO));
319
+ let tokenUsdValue = '';
320
+ if (otherProps.usdPrice) tokenUsdValue = numberToString(new BigNumber__default(getBalanceFromWallet(balances, otherProps.blockchain, otherProps.symbol, otherProps.address)?.amount || ZERO).multipliedBy(otherProps.usdPrice));
321
+ return {
322
+ ...otherProps,
323
+ ...(tokenAmount !== '0' && {
324
+ balance: {
325
+ amount: tokenAmount,
326
+ usdValue: tokenUsdValue
327
+ }
328
+ })
329
+ };
330
+ });
331
+ }
332
+ function getSortedTokens(chain, tokens, balances, otherChainTokens) {
333
+ const fromChainEqueulsToToChain = chain?.name === otherChainTokens[0]?.name;
334
+ if (fromChainEqueulsToToChain) return otherChainTokens;
335
+ const filteredTokens = tokens.filter(token => token.blockchain === chain?.name);
336
+ return sortTokens(getTokensWithBalance(filteredTokens, balances));
337
+ }
338
+ function tokensAreEqual(tokenA, tokenB) {
339
+ return tokenA?.blockchain === tokenB?.blockchain && tokenA?.name === tokenB?.name && tokenA?.address === tokenB?.address;
340
+ }
341
+ function getDefaultToken(sortedTokens, otherToken) {
342
+ let selectedToken;
343
+ const firstToken = sortedTokens[0];
344
+ const secondToken = sortedTokens[1];
345
+ if (sortedTokens.length === 1) selectedToken = firstToken;else if (tokensAreEqual(firstToken, otherToken)) selectedToken = secondToken;else selectedToken = firstToken;
346
+ return selectedToken;
347
+ }
348
+ function sortWalletsBasedOnState(wallets) {
349
+ return wallets.sort((a, b) => Number(b.state === ui.WalletState.CONNECTED) - Number(a.state === ui.WalletState.CONNECTED) || Number(b.state === ui.WalletState.DISCONNECTED || b.state === ui.WalletState.CONNECTING) - Number(a.state === ui.WalletState.DISCONNECTED || a.state === ui.WalletState.CONNECTING));
350
+ }
351
+
352
+ function getOutputRatio(inputUsdValue, outputUsdValue) {
353
+ if (inputUsdValue.lte(ZERO) || outputUsdValue.lte(ZERO)) return 0;
354
+ return outputUsdValue.div(inputUsdValue).minus(1).multipliedBy(100);
355
+ }
356
+ function outputRatioHasWarning(inputUsdValue, outputRatio) {
357
+ 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));
358
+ }
359
+ function hasLimitError(bestRoute) {
360
+ return (bestRoute?.result?.swaps || []).filter(swap => {
361
+ const minimum = !!swap.fromAmountMinValue ? new BigNumber__default(swap.fromAmountMinValue) : null;
362
+ const maximum = !!swap.fromAmountMaxValue ? new BigNumber__default(swap.fromAmountMaxValue) : null;
363
+ const isExclusive = swap.fromAmountRestrictionType === 'EXCLUSIVE';
364
+ if (isExclusive) {
365
+ return minimum?.gte(swap.fromAmount) || maximum?.lte(swap.fromAmount);
366
+ } else {
367
+ return minimum?.gt(swap.fromAmount) || maximum?.lt(swap.fromAmount);
368
+ }
369
+ }).length > 0;
370
+ }
371
+ function LimitErrorMessage(bestRoute) {
372
+ if (!bestRoute) return {
373
+ swap: null,
374
+ fromAmountRangeError: '',
375
+ recommendation: ''
376
+ };
377
+ const swap = (bestRoute?.result?.swaps || []).filter(swap => {
378
+ const minimum = !!swap.fromAmountMinValue ? new BigNumber__default(swap.fromAmountMinValue) : null;
379
+ const maximum = !!swap.fromAmountMaxValue ? new BigNumber__default(swap.fromAmountMaxValue) : null;
380
+ const isExclusive = swap.fromAmountRestrictionType === 'EXCLUSIVE';
381
+ if (isExclusive) {
382
+ return minimum?.gte(swap.fromAmount) || maximum?.lte(swap.fromAmount);
383
+ } else {
384
+ return minimum?.gt(swap.fromAmount) || maximum?.lt(swap.fromAmount);
385
+ }
386
+ })[0];
387
+ if (!swap) return {
388
+ swap: null,
389
+ fromAmountRangeError: '',
390
+ recommendation: ''
391
+ };
392
+ const minimum = !!swap.fromAmountMinValue ? new BigNumber__default(swap.fromAmountMinValue) : null;
393
+ const maximum = !!swap.fromAmountMaxValue ? new BigNumber__default(swap.fromAmountMaxValue) : null;
394
+ const isExclusive = swap.fromAmountRestrictionType === 'EXCLUSIVE';
395
+ let fromAmountRangeError = '';
396
+ let recommendation = '';
397
+ if (!isExclusive && !!minimum && minimum.gt(swap.fromAmount)) {
398
+ fromAmountRangeError = `Required: >= ${numberToString(minimum)} ${swap.from.symbol}`;
399
+ recommendation = 'Increase your swap amount';
400
+ } else if (isExclusive && !!minimum && minimum.gte(swap.fromAmount)) {
401
+ fromAmountRangeError = `Required: > ${numberToString(minimum)} ${swap.from.symbol}`;
402
+ recommendation = 'Increase your swap amount';
403
+ }
404
+ if (!isExclusive && !!maximum && maximum.lt(swap.fromAmount)) {
405
+ fromAmountRangeError = `Required: <= ${numberToString(maximum)} ${swap.from.symbol}`;
406
+ recommendation = 'Decrease your swap amount';
407
+ } else if (isExclusive && !!maximum && maximum.lte(swap.fromAmount)) {
408
+ fromAmountRangeError = `Required: < ${numberToString(maximum)} ${swap.from.symbol}`;
409
+ recommendation = 'Decrease your swap amount';
410
+ }
411
+ return {
412
+ swap,
413
+ fromAmountRangeError,
414
+ recommendation
415
+ };
416
+ }
417
+ function getSwapButtonState(loadingMetaStatus, accounts, loading, bestRoute, hasLimitError, highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath, inputIsZero) {
418
+ if (loadingMetaStatus !== 'success') return {
419
+ title: 'Connect Wallet',
420
+ disabled: true
421
+ };
422
+ if (accounts.length == 0) return {
423
+ title: 'Connect Wallet',
424
+ disabled: false
425
+ };
426
+ if (loading) return {
427
+ title: 'Finding Best Route...',
428
+ disabled: true
429
+ };else if (inputIsZero) return {
430
+ title: 'Enter an amount',
431
+ disabled: true
432
+ };else if (!bestRoute) return {
433
+ title: 'Swap',
434
+ disabled: true
435
+ };else if (hasLimitError) return {
436
+ title: 'Limit Error',
437
+ disabled: true
438
+ };else if (highValueLoss) return {
439
+ title: 'Price impact is too high!',
440
+ disabled: true
441
+ };else if (priceImpactCanNotBeComputed) return {
442
+ title: 'USD price is unknown, price impact might be high!',
443
+ disabled: false,
444
+ hasWarning: true
445
+ };else if (needsToWarnEthOnPath) return {
446
+ title: 'The route goes through Ethereum. Continue?',
447
+ disabled: false,
448
+ hasWarning: true
449
+ };else return {
450
+ title: 'Swap',
451
+ disabled: false
452
+ };
453
+ }
454
+ function canComputePriceImpact(bestRoute, inputAmount, inputUsdValue, outputUsdValue) {
455
+ return !((inputUsdValue.lte(ZERO) || outputUsdValue.lte(ZERO)) && !!bestRoute?.result && !!inputAmount && inputAmount !== '0' && parseFloat(inputAmount || '0') !== 0 && !!bestRoute.result);
456
+ }
457
+ function calculatePendingSwap(inputAmount, bestRoute, wallets, settings, validateBalanceOrFee, meta) {
458
+ const simulationResult = bestRoute.result;
459
+ if (!simulationResult) throw Error('Simulation result should not be null');
460
+ return {
461
+ creationTime: new Date().getTime().toString(),
462
+ finishTime: null,
463
+ requestId: bestRoute.requestId || '',
464
+ inputAmount: inputAmount,
465
+ wallets,
466
+ status: 'running',
467
+ isPaused: false,
468
+ extraMessage: null,
469
+ extraMessageSeverity: null,
470
+ extraMessageDetail: null,
471
+ extraMessageErrorCode: null,
472
+ networkStatusExtraMessage: null,
473
+ networkStatusExtraMessageDetail: null,
474
+ lastNotificationTime: null,
475
+ //@ts-ignore
476
+ settings: settings,
477
+ simulationResult: simulationResult,
478
+ validateBalanceOrFee,
479
+ steps: bestRoute.result?.swaps?.map((swap, index) => {
480
+ const swapper = meta.swappers.find(swapper => swapper.id === swap.swapperId);
481
+ const swapperType = swapper?.types[0];
482
+ const fromBlockchain = meta.blockchains.find(blockchain => blockchain.name === swap.from.blockchain);
483
+ const toBlockchain = meta.blockchains.find(blockchain => blockchain.name === swap.to.blockchain);
484
+ return {
485
+ id: index + 1,
486
+ fromBlockchain: swap.from.blockchain,
487
+ fromSymbol: swap.from.symbol,
488
+ fromSymbolAddress: swap.from.address,
489
+ fromDecimals: swap.from.decimals,
490
+ fromAmountPrecision: swap.fromAmountPrecision,
491
+ fromAmountMinValue: swap.fromAmountMinValue,
492
+ fromAmountMaxValue: swap.fromAmountMaxValue,
493
+ toBlockchain: swap.to.blockchain,
494
+ fromLogo: swap.from.logo,
495
+ toSymbol: swap.to.symbol,
496
+ toSymbolAddress: swap.to.address,
497
+ toDecimals: swap.to.decimals,
498
+ toLogo: swap.to.logo,
499
+ startTransactionTime: new Date().getTime(),
500
+ swapperId: swap.swapperId,
501
+ feeInUsd: numberToString(getUsdFeeOfStep(swap, meta.tokens), null, 2),
502
+ expectedOutputAmountHumanReadable: swap.toAmount,
503
+ outputAmount: '',
504
+ status: 'created',
505
+ networkStatus: null,
506
+ executedTransactionId: null,
507
+ externalTransactionId: null,
508
+ explorerUrl: null,
509
+ trackingCode: null,
510
+ cosmosTransaction: null,
511
+ solanaTransaction: null,
512
+ starknetTransaction: null,
513
+ starknetApprovalTransaction: null,
514
+ tronTransaction: null,
515
+ tronApprovalTransaction: null,
516
+ evmTransaction: null,
517
+ evmApprovalTransaction: null,
518
+ transferTransaction: null,
519
+ diagnosisUrl: null,
520
+ internalSteps: null,
521
+ fromBlockchainLogo: fromBlockchain?.logo || '',
522
+ toBlockchainLogo: toBlockchain?.logo || '',
523
+ swapperLogo: swapper?.logo || '',
524
+ swapperType: swapperType || ''
525
+ };
526
+ }) || []
527
+ };
528
+ }
529
+ function requiredWallets(route) {
530
+ const wallets = [];
531
+ route?.result?.swaps.forEach(swap => {
532
+ const currentStepFromBlockchain = swap.from.blockchain;
533
+ const currentStepToBlockchain = swap.to.blockchain;
534
+ let lastAddedWallet = wallets[wallets.length - 1];
535
+ if (currentStepFromBlockchain != lastAddedWallet) wallets.push(currentStepFromBlockchain);
536
+ lastAddedWallet = wallets[wallets.length - 1];
537
+ if (currentStepToBlockchain != lastAddedWallet) wallets.push(currentStepToBlockchain);
538
+ });
539
+ return wallets;
540
+ }
541
+ const getUsdPrice$1 = (blockchain, symbol, address, allTokens) => {
542
+ const token = allTokens?.find(t => t.blockchain === blockchain && t.symbol?.toUpperCase() === symbol?.toUpperCase() && t.address === address);
543
+ return token?.usdPrice || null;
544
+ };
545
+ function getUsdFeeOfStep(step, allTokens) {
546
+ let totalFeeInUsd = ZERO;
547
+ for (let i = 0; i < step.fee.length; i++) {
548
+ const fee = step.fee[i];
549
+ if (fee.expenseType === 'DECREASE_FROM_OUTPUT') continue;
550
+ const unitPrice = getUsdPrice$1(fee.asset.blockchain, fee.asset.symbol, fee.asset.address, allTokens);
551
+ totalFeeInUsd = totalFeeInUsd.plus(new BigNumber__default(fee.amount).multipliedBy(unitPrice || 0));
552
+ }
553
+ return totalFeeInUsd;
554
+ }
555
+ function getTotalFeeInUsd(bestRoute, allTokens) {
556
+ return bestRoute?.result?.swaps.reduce((totalFee, step) => totalFee.plus(getUsdFeeOfStep(step, allTokens)), ZERO) || null;
557
+ }
558
+ function hasHighFee(totalFeeInUsd) {
559
+ if (!totalFeeInUsd) return false;
560
+ return !totalFeeInUsd.lt(new BigNumber__default(30));
561
+ }
562
+ function getMinRequiredSlippage(route) {
563
+ const slippages = route.result?.swaps.map(slippage => slippage.recommendedSlippage);
564
+ return slippages?.map(s => parseFloat(s?.slippage || '0'))?.filter(s => s > 0)?.sort((a, b) => b - a)?.find(() => true) || null;
565
+ }
566
+ function hasProperSlippage(userSlippage, minRequiredSlippage) {
567
+ if (!minRequiredSlippage) return true;
568
+ //@ts-ignore
569
+ return parseFloat(userSlippage) >= parseFloat(minRequiredSlippage);
570
+ }
571
+ function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, selectedWallets, disabledLiquiditySources, slippage, checkPrerequisites) {
572
+ const selectedWalletsMap = selectedWallets.reduce((selectedWalletsMap, selectedWallet) => (selectedWalletsMap[selectedWallet.chain] = selectedWallet.address, selectedWalletsMap), {});
573
+ const connectedWallets = [];
574
+ wallets.forEach(wallet => {
575
+ const chainAndAccounts = connectedWallets.find(connectedWallet => connectedWallet.blockchain === wallet.chain);
576
+ if (!!chainAndAccounts) chainAndAccounts.addresses.push(wallet.address);else connectedWallets.push({
577
+ blockchain: wallet.chain,
578
+ addresses: [wallet.address]
579
+ });
580
+ });
581
+ const requestBody = {
582
+ amount: inputAmount.toString(),
583
+ checkPrerequisites,
584
+ from: {
585
+ address: fromToken.address,
586
+ blockchain: fromToken.blockchain,
587
+ symbol: fromToken.symbol
588
+ },
589
+ to: {
590
+ address: toToken.address,
591
+ blockchain: toToken.blockchain,
592
+ symbol: toToken.symbol
593
+ },
594
+ connectedWallets,
595
+ selectedWallets: selectedWalletsMap,
596
+ swapperGroups: disabledLiquiditySources,
597
+ swappersGroupsExclude: true,
598
+ //@ts-ignore
599
+ slippage: slippage.toString()
600
+ };
601
+ return requestBody;
602
+ }
603
+ function getWalletsForNewSwap(selectedWallets) {
604
+ const wallets = selectedWallets.reduce((selectedWalletsMap, selectedWallet) => (selectedWalletsMap[selectedWallet.chain] = {
605
+ address: selectedWallet.address,
606
+ walletType: selectedWallet.walletType
607
+ }, selectedWalletsMap), {});
608
+ return wallets;
609
+ }
610
+ function getRouteOutputAmount(route) {
611
+ return route?.result?.outputAmount || null;
612
+ }
613
+ function getPercentageChange(oldValue, newValue) {
614
+ if (!oldValue || !newValue) return null;
615
+ return new BigNumber__default(newValue).div(new BigNumber__default(oldValue)).minus(1).multipliedBy(100);
616
+ }
617
+ function isOutputAmountChangedALot(oldRoute, newRoute) {
618
+ const oldOutputAmount = getRouteOutputAmount(oldRoute);
619
+ const newOutputAmount = getRouteOutputAmount(newRoute);
620
+ if (!oldOutputAmount || !newOutputAmount) return false;
621
+ const percentageChange = getPercentageChange(oldOutputAmount, newOutputAmount);
622
+ if (!percentageChange) return true;
623
+ return percentageChange.toNumber() <= -1;
624
+ }
625
+ function getBalanceWarnings(route, selectedWallets) {
626
+ const fee = route.validationStatus;
627
+ const requiredWallets = getRequiredChains(route);
628
+ const walletsSortedByRequiredWallets = selectedWallets.sort((selectedWallet1, selectedWallet2) => requiredWallets.indexOf(selectedWallet1.chain) - requiredWallets.indexOf(selectedWallet2.chain));
629
+ return walletsSortedByRequiredWallets.flatMap(wallet => getRequiredBalanceOfWallet(wallet, fee) || []).filter(asset => !asset.ok).map(asset => {
630
+ const symbol = asset.asset.symbol;
631
+ const currentAmount = numberToString(new BigNumber__default(asset.currentAmount.amount).shiftedBy(-asset.currentAmount.decimals), 8);
632
+ const requiredAmount = numberToString(new BigNumber__default(asset.requiredAmount.amount).shiftedBy(-asset.requiredAmount.decimals), 8);
633
+ let reason = '';
634
+ if (asset.reason === 'FEE') reason = ' for network fee';
635
+ if (asset.reason === 'INPUT_ASSET') reason = ' for swap';
636
+ if (asset.reason === 'FEE_AND_INPUT_ASSET') reason = ' for input and network fee';
637
+ const warningMessage = `Needs ≈ ${requiredAmount} ${symbol}${reason}, but you have ${currentAmount} ${symbol} in your ${asset.asset.blockchain} wallet.`;
638
+ return warningMessage;
639
+ });
640
+ }
641
+ function calcOutputUsdValue(outputAmount, tokenPrice) {
642
+ const amount = !!outputAmount ? new BigNumber__default(outputAmount) : ZERO;
643
+ return amount.multipliedBy(tokenPrice || 0);
644
+ }
645
+
646
+ function searchParamsToToken(tokens, searchParams, chain) {
647
+ if (!chain) return null;
648
+ return tokens.find(token => {
649
+ const symbolAndAddress = searchParams?.split('--');
650
+ if (symbolAndAddress?.length === 1) return token.symbol === symbolAndAddress[0] && token.address === null && token.blockchain === chain.name;
651
+ return token.symbol === symbolAndAddress?.[0] && token.address === symbolAndAddress?.[1] && token.blockchain === chain.name;
652
+ }) || null;
653
+ }
654
+ function getBestRouteToTokenUsdPrice(bestRoute) {
655
+ return bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1].to.usdPrice;
656
+ }
657
+ function isNumberOfSwapsChanged(route1, route2) {
658
+ const route1Swaps = route1.result?.swaps || [];
659
+ const route2Swaps = route2.result?.swaps || [];
660
+ return route1Swaps.length !== route2Swaps.length;
661
+ }
662
+ function isRouteSwappersUpdated(route1, route2) {
663
+ const route1Swappers = route1.result?.swaps.map(swap => swap.swapperId) || [];
664
+ const route2Swappers = route2.result?.swaps.map(swap => swap.swapperId) || [];
665
+ return !areEqual(route1Swappers, route2Swappers);
666
+ }
667
+ function isRouteInternalCoinsUpdated(route1, route2) {
668
+ const route1InternalCoins = route1.result?.swaps.map(swap => swap.to.symbol) || [];
669
+ const route2InternalCoins = route2.result?.swaps.map(swap => swap.to.symbol) || [];
670
+ return !areEqual(route1InternalCoins, route2InternalCoins);
671
+ }
672
+ function isRouteChanged(route1, route2) {
673
+ return isNumberOfSwapsChanged(route1, route2) || isRouteSwappersUpdated(route1, route2) || isRouteInternalCoinsUpdated(route1, route2);
674
+ }
675
+ function getRequiredBalanceOfWallet(selectedWallet, fee) {
676
+ if (fee === null) return null;
677
+ const relatedFeeStatus = fee?.find(item => item.blockchain === selectedWallet.chain)?.wallets.find(wallet => wallet.address?.toLowerCase() === selectedWallet.address.toLowerCase());
678
+ if (!relatedFeeStatus) return null;
679
+ return relatedFeeStatus.requiredAssets;
680
+ }
681
+ function isRouteParametersChanged(prevParams, currentParams) {
682
+ return prevParams.fromChain?.name !== currentParams.fromChain?.name || prevParams.toChain?.name !== currentParams.toChain?.name || prevParams.fromToken?.symbol !== currentParams.fromToken?.symbol || prevParams.toToken?.symbol !== currentParams.toToken?.symbol || prevParams.fromToken?.blockchain !== currentParams.fromToken?.blockchain || prevParams.toToken?.blockchain !== currentParams.toToken?.blockchain || prevParams.fromToken?.address !== currentParams.fromToken?.address || prevParams.toToken?.address !== currentParams.toToken?.address || prevParams.inputAmount !== currentParams.inputAmount || prevParams.slippage !== currentParams.slippage || prevParams.customSlippage !== currentParams.customSlippage || prevParams.disabledLiquiditySources?.length !== currentParams.disabledLiquiditySources?.length;
683
+ }
684
+ function getBestRouteWithCalculatedFees(bestRoute, tokens) {
685
+ if (!bestRoute || !bestRoute.result) return null;
686
+ const swapsWithFee = (bestRoute?.result?.swaps || []).map(swap => ({
687
+ ...swap,
688
+ feeInUsd: numberToString(getUsdFeeOfStep(swap, tokens), 0, 2)
689
+ }));
690
+ return {
691
+ ...bestRoute,
692
+ result: {
693
+ ...bestRoute.result,
694
+ swaps: swapsWithFee
695
+ }
696
+ };
697
+ }
698
+
699
+ const createSelectors = _store => {
700
+ let store = _store;
701
+ store.use = {};
702
+ for (let k of Object.keys(store.getState())) {
703
+ store.use[k] = () => store(s => s[k]);
704
+ }
705
+ return store;
706
+ };
707
+
708
+ const httpService = /*#__PURE__*/new rangoSdk.RangoClient(process.env.REACT_APP_API_KEY);
709
+
710
+ const SLIPPAGES = [0.5, 1, 3, 5, 8, 13, 20];
711
+ const DEFAULT_SLIPPAGE = 1;
712
+ const HIGH_SLIPPAGE = 5;
713
+ const MAX_SLIPPAGE = 100;
714
+ const MIN_SLIPPGAE = 0;
715
+
716
+ const useMetaStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()(set => ({
717
+ meta: {
718
+ blockchains: [],
719
+ popularTokens: [],
720
+ swappers: [],
721
+ tokens: []
722
+ },
723
+ loadingStatus: 'loading',
724
+ fetchMeta: async () => {
725
+ try {
726
+ const response = await httpService.getAllMetadata();
727
+ const chainThatHasTokenInMetaResponse = removeDuplicateFrom(response.tokens.map(t => t.blockchain));
728
+ const enabledChains = response.blockchains.filter(chain => chain.enabled && chainThatHasTokenInMetaResponse.includes(chain.name));
729
+ response.blockchains = enabledChains.sort((a, b) => a.sort - b.sort);
730
+ set({
731
+ meta: response,
732
+ loadingStatus: 'success'
733
+ });
734
+ } catch (error) {
735
+ set({
736
+ loadingStatus: 'failed'
737
+ });
738
+ }
739
+ }
740
+ })));
741
+
742
+ const useSettingsStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/middleware.persist( /*#__PURE__*/middleware.subscribeWithSelector(set => ({
743
+ slippage: DEFAULT_SLIPPAGE,
744
+ customSlippage: null,
745
+ infiniteApprove: false,
746
+ disabledLiquiditySources: [],
747
+ theme: 'auto',
748
+ setSlippage: slippage => set(() => ({
749
+ slippage: slippage
750
+ })),
751
+ setCustomSlippage: customSlippage => set(() => ({
752
+ customSlippage: customSlippage
753
+ })),
754
+ toggleAllLiquiditySources: () => set(state => {
755
+ const {
756
+ swappers
757
+ } = useMetaStore.getState().meta;
758
+ const swappersGroup = removeDuplicateFrom(swappers.map(swapper => swapper.swapperGroup));
759
+ if (swappersGroup.length === state.disabledLiquiditySources.length) return {
760
+ disabledLiquiditySources: []
761
+ };else {
762
+ return {
763
+ disabledLiquiditySources: swappersGroup
764
+ };
765
+ }
766
+ }),
767
+ toggleInfiniteApprove: () => set(state => ({
768
+ infiniteApprove: !state.infiniteApprove
769
+ })),
770
+ toggleLiquiditySource: name => set(state => {
771
+ if (state.disabledLiquiditySources.includes(name)) return {
772
+ disabledLiquiditySources: state.disabledLiquiditySources.filter(liquiditySource => liquiditySource != name)
773
+ };else return {
774
+ disabledLiquiditySources: state.disabledLiquiditySources.concat(name)
775
+ };
776
+ }),
777
+ setTheme: theme => set(() => ({
778
+ theme
779
+ }))
780
+ })), {
781
+ name: 'user-settings'
782
+ })));
783
+
784
+ const useWalletsStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/middleware.subscribeWithSelector(set => ({
785
+ accounts: [],
786
+ balances: [],
787
+ selectedWallets: [],
788
+ connectWallet: accounts => {
789
+ const tokens = useMetaStore.getState().meta.tokens;
790
+ set(state => ({
791
+ accounts: state.accounts.concat(accounts),
792
+ balances: state.balances.concat(accounts.map(account => ({
793
+ balances: [],
794
+ address: account.address,
795
+ chain: account.chain,
796
+ loading: true,
797
+ walletType: account.walletType,
798
+ error: false,
799
+ explorerUrl: null
800
+ })))
801
+ }));
802
+ accounts.forEach(async account => {
803
+ try {
804
+ const response = await httpService.getWalletsDetails([{
805
+ address: account.address,
806
+ blockchain: account.chain
807
+ }]);
808
+ const retrivedBalance = response.wallets[0];
809
+ if (retrivedBalance) {
810
+ set(state => ({
811
+ balances: state.balances.map(balance => {
812
+ return isAccountAndBalanceMatched(account, balance) ? makeBalanceFor(account, retrivedBalance, tokens) : balance;
813
+ })
814
+ }));
815
+ } else throw new Error('Wallet not found');
816
+ } catch (error) {
817
+ set(state => ({
818
+ balances: state.balances.map(balance => {
819
+ return isAccountAndBalanceMatched(account, balance) ? resetBalanceState(balance) : balance;
820
+ })
821
+ }));
822
+ }
823
+ });
824
+ },
825
+ disconnectWallet: walletType => {
826
+ set(state => ({
827
+ accounts: state.accounts.filter(account => account.walletType !== walletType),
828
+ balances: state.balances.filter(balance => balance.walletType !== walletType),
829
+ selectedWallets: state.selectedWallets.filter(wallet => wallet.walletType != walletType)
830
+ }));
831
+ },
832
+ initSelectedWallets: () => set(state => {
833
+ const requiredChains = getRequiredChains(useBestRouteStore.getState().bestRoute);
834
+ const connectedWallets = state.accounts;
835
+ const selectedWallets = [];
836
+ requiredChains.forEach(chain => {
837
+ const anyWalletSelected = !!state.selectedWallets.find(wallet => wallet.chain === chain);
838
+ if (!anyWalletSelected) {
839
+ const firstWalletWithMatchedChain = connectedWallets.find(wallet => wallet.chain === chain);
840
+ if (!!firstWalletWithMatchedChain) selectedWallets.push({
841
+ address: firstWalletWithMatchedChain.address,
842
+ chain: firstWalletWithMatchedChain.chain,
843
+ walletType: firstWalletWithMatchedChain.walletType
844
+ });
845
+ }
846
+ });
847
+ return {
848
+ selectedWallets: state.selectedWallets.concat(selectedWallets)
849
+ };
850
+ }),
851
+ setSelectedWallet: wallet => set(state => ({
852
+ selectedWallets: state.selectedWallets.filter(selectedWallet => selectedWallet.chain !== wallet.chain).concat({
853
+ chain: wallet.chain,
854
+ address: wallet.address,
855
+ walletType: wallet.walletType
856
+ })
857
+ })),
858
+ clearConnectedWallet: () => set(() => ({
859
+ accounts: [],
860
+ balances: [],
861
+ selectedWallets: []
862
+ }))
863
+ }))));
864
+ useWalletsStore.subscribe(state => state.balances, balances => {
865
+ useBestRouteStore.setState(_ref => {
866
+ let {
867
+ sourceTokens,
868
+ destinationTokens
869
+ } = _ref;
870
+ const sourceTokensWithBalance = getTokensWithBalance(sourceTokens, balances);
871
+ const destinationTokensWithBalance = getTokensWithBalance(destinationTokens, balances);
872
+ return {
873
+ sourceTokens: sortTokens(sourceTokensWithBalance),
874
+ destinationTokens: sortTokens(destinationTokensWithBalance)
875
+ };
876
+ });
877
+ }, {
878
+ equalityFn: shallow.shallow
879
+ });
880
+
881
+ const getUsdValue = (token, amount) => new BigNumber__default(amount || ZERO).multipliedBy(token?.usdPrice || 0);
882
+ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/middleware.subscribeWithSelector(set => ({
883
+ fromChain: null,
884
+ fromToken: null,
885
+ inputAmount: '',
886
+ outputAmount: null,
887
+ inputUsdValue: new BigNumber__default(0),
888
+ outputUsdValue: new BigNumber__default(0),
889
+ toChain: null,
890
+ toToken: null,
891
+ bestRoute: null,
892
+ loading: false,
893
+ error: '',
894
+ sourceTokens: [],
895
+ destinationTokens: [],
896
+ setBestRoute: bestRoute => set(state => {
897
+ let outputAmount = null;
898
+ let outputUsdValue = ZERO;
899
+ if (!!bestRoute) {
900
+ outputAmount = !!bestRoute.result?.outputAmount ? new BigNumber__default(bestRoute.result?.outputAmount) : null;
901
+ outputUsdValue = calcOutputUsdValue(bestRoute.result?.outputAmount, getBestRouteToTokenUsdPrice(bestRoute) || state.toToken?.usdPrice);
902
+ }
903
+ return {
904
+ bestRoute,
905
+ ...(!!bestRoute && {
906
+ outputAmount,
907
+ outputUsdValue
908
+ })
909
+ };
910
+ }),
911
+ setFromChain: (chain, setDefaultToken) => {
912
+ set(state => {
913
+ if (state.fromChain?.name === chain?.name) return {};
914
+ const tokens = useMetaStore.getState().meta.tokens;
915
+ const balances = useWalletsStore.getState().balances;
916
+ const sortedTokens = getSortedTokens(chain, tokens, balances, state.destinationTokens);
917
+ const fromToken = getDefaultToken(sortedTokens, state.toToken);
918
+ return {
919
+ fromChain: chain,
920
+ sourceTokens: sortedTokens,
921
+ ...(setDefaultToken && {
922
+ fromToken
923
+ }),
924
+ ...(!!state.inputAmount && {
925
+ inputUsdValue: getUsdValue(fromToken, state.inputAmount)
926
+ })
927
+ };
928
+ });
929
+ },
930
+ setFromToken: token => set(state => ({
931
+ fromToken: token,
932
+ ...(!!state.inputAmount && {
933
+ inputUsdValue: getUsdValue(token, state.inputAmount)
934
+ })
935
+ })),
936
+ setToChain: (chain, setDefaultToken) => {
937
+ set(state => {
938
+ if (state.toChain?.name === chain?.name) return {};
939
+ const tokens = useMetaStore.getState().meta.tokens;
940
+ const balances = useWalletsStore.getState().balances;
941
+ const sortedTokens = getSortedTokens(chain, tokens, balances, state.destinationTokens);
942
+ return {
943
+ toChain: chain,
944
+ destinationTokens: sortedTokens,
945
+ ...(setDefaultToken && {
946
+ toToken: getDefaultToken(sortedTokens, state.fromToken)
947
+ })
948
+ };
949
+ });
950
+ },
951
+ setToToken: token => set(() => ({
952
+ toToken: token
953
+ })),
954
+ setInputAmount: amount => {
955
+ set(state => ({
956
+ inputAmount: amount,
957
+ ...(!amount && {
958
+ outputAmount: new BigNumber__default(0),
959
+ outputUsdValue: new BigNumber__default(0),
960
+ bestRoute: null
961
+ }),
962
+ ...(!!state.fromToken && {
963
+ inputUsdValue: getUsdValue(state.fromToken, amount)
964
+ })
965
+ }));
966
+ }
967
+ }))));
968
+ const bestRoute = (bestRouteStore, settingsStore) => {
969
+ let abortController = null;
970
+ const fetchBestRoute = () => {
971
+ const {
972
+ fromToken,
973
+ toToken,
974
+ inputAmount
975
+ } = bestRouteStore.getState();
976
+ const {
977
+ slippage,
978
+ customSlippage,
979
+ disabledLiquiditySources
980
+ } = settingsStore.getState();
981
+ if (!fromToken || !toToken || !inputAmount) return;
982
+ abortController?.abort();
983
+ abortController = new AbortController();
984
+ const userSlippage = !!customSlippage ? customSlippage : slippage;
985
+ const requestBody = createBestRouteRequestBody(fromToken, toToken, inputAmount, [], [], disabledLiquiditySources, userSlippage, false);
986
+ bestRouteStore.setState({
987
+ loading: true,
988
+ bestRoute: null,
989
+ outputAmount: null,
990
+ outputUsdValue: new BigNumber__default(0)
991
+ });
992
+ httpService.getBestRoute(requestBody, {
993
+ signal: abortController.signal
994
+ }).then(res => {
995
+ const {
996
+ setBestRoute
997
+ } = bestRouteStore.getState();
998
+ setBestRoute(res);
999
+ bestRouteStore.setState({
1000
+ loading: false
1001
+ });
1002
+ abortController = null;
1003
+ }).catch(error => {
1004
+ if (error.code === 'ERR_CANCELED') return;
1005
+ bestRouteStore.setState({
1006
+ error: error.message,
1007
+ loading: false
1008
+ });
1009
+ });
1010
+ };
1011
+ useBestRouteStore.subscribe(state => ({
1012
+ fromChain: state.fromChain,
1013
+ fromToken: state.fromToken,
1014
+ toChain: state.toChain,
1015
+ toToken: state.toToken,
1016
+ inputAmount: state.inputAmount
1017
+ }), fetchBestRoute.bind(null), {
1018
+ equalityFn: (prevState, state) => {
1019
+ if (isRouteParametersChanged(prevState, state)) return false;else return true;
1020
+ }
1021
+ });
1022
+ useSettingsStore.subscribe(state => ({
1023
+ slippage: state.slippage,
1024
+ customSlippage: state.customSlippage,
1025
+ disabledLiquiditySources: state.disabledLiquiditySources
1026
+ }), fetchBestRoute.bind(null), {
1027
+ equalityFn: (prevState, state) => {
1028
+ if (isRouteParametersChanged(prevState, state)) return false;else return true;
1029
+ }
1030
+ });
1031
+ return {
1032
+ fetchBestRoute
1033
+ };
1034
+ };
1035
+ const {
1036
+ fetchBestRoute
1037
+ } = /*#__PURE__*/bestRoute(useBestRouteStore, useSettingsStore);
1038
+
1039
+ var SearchParams;
1040
+ (function (SearchParams) {
1041
+ SearchParams["FROM_CHAIN"] = "fromChain";
1042
+ SearchParams["FROM_TOKEN"] = "fromToken";
1043
+ SearchParams["TO_CHAIN"] = "toChain";
1044
+ SearchParams["TO_TOKEN"] = "toToken";
1045
+ SearchParams["FROM_AMOUNT"] = "fromAmount";
1046
+ })(SearchParams || (SearchParams = {}));
1047
+
1048
+ const useUiStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()(set => ({
1049
+ connectWalletsButtonDisabled: false,
1050
+ selectedSwapRequestId: null,
1051
+ toggleConnectWalletsButton: () => set(state => ({
1052
+ connectWalletsButtonDisabled: !state.connectWalletsButtonDisabled
1053
+ })),
1054
+ setSelectedSwap: requestId => set({
1055
+ selectedSwapRequestId: requestId
1056
+ })
1057
+ })));
1058
+
1059
+ function UpdateUrl() {
1060
+ const firstRender = React.useRef(true);
1061
+ const [searchParams, setSearchParams] = reactRouterDom.useSearchParams();
1062
+ const location = reactRouterDom.useLocation();
1063
+ const firstRenderSearchParams = React.useRef(location.search);
1064
+ const searchParamsRef = React.useRef({});
1065
+ const fromChain = useBestRouteStore.use.fromChain();
1066
+ const toChain = useBestRouteStore.use.toChain();
1067
+ const fromToken = useBestRouteStore.use.fromToken();
1068
+ const toToken = useBestRouteStore.use.toToken();
1069
+ const setFromChain = useBestRouteStore.use.setFromChain();
1070
+ const setFromToken = useBestRouteStore.use.setFromToken();
1071
+ const setToChain = useBestRouteStore.use.setToChain();
1072
+ const setToToken = useBestRouteStore.use.setToToken();
1073
+ const inputAmount = useBestRouteStore.use.inputAmount();
1074
+ const setInputAmount = useBestRouteStore.use.setInputAmount();
1075
+ const loadingStatus = useMetaStore.use.loadingStatus();
1076
+ const {
1077
+ blockchains,
1078
+ tokens
1079
+ } = useMetaStore.use.meta();
1080
+ const setSelectedSwap = useUiStore.use.setSelectedSwap();
1081
+ React.useEffect(() => {
1082
+ const params = {};
1083
+ reactRouterDom.createSearchParams(firstRenderSearchParams.current).forEach((value, key) => {
1084
+ params[key] = value;
1085
+ });
1086
+ searchParamsRef.current = params;
1087
+ const requestId = location.pathname.split(navigationRoutes.swaps + '/')[1] || null;
1088
+ if (requestId) setSelectedSwap(requestId);
1089
+ }, []);
1090
+ React.useEffect(() => {
1091
+ let fromChainString = '',
1092
+ fromTokenString = '',
1093
+ toChainString = '',
1094
+ toTokenString = '',
1095
+ fromAmount = '';
1096
+ if (loadingStatus !== 'success' && ![navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname)) {
1097
+ fromChainString = searchParamsRef.current[SearchParams.FROM_CHAIN];
1098
+ fromTokenString = searchParamsRef.current[SearchParams.FROM_TOKEN];
1099
+ toChainString = searchParamsRef.current[SearchParams.TO_CHAIN];
1100
+ toTokenString = searchParamsRef.current[SearchParams.TO_TOKEN];
1101
+ fromAmount = searchParamsRef.current[SearchParams.FROM_AMOUNT];
1102
+ setSearchParams({
1103
+ ...(fromChainString && {
1104
+ [SearchParams.FROM_CHAIN]: fromChainString
1105
+ }),
1106
+ ...(fromTokenString && {
1107
+ [SearchParams.FROM_TOKEN]: fromTokenString
1108
+ }),
1109
+ ...(toChainString && {
1110
+ [SearchParams.TO_CHAIN]: toChainString
1111
+ }),
1112
+ ...(toTokenString && {
1113
+ [SearchParams.TO_TOKEN]: toTokenString
1114
+ }),
1115
+ ...(fromAmount && {
1116
+ [SearchParams.FROM_AMOUNT]: fromAmount.toString()
1117
+ })
1118
+ }, {
1119
+ replace: true
1120
+ });
1121
+ }
1122
+ if (!firstRender.current) {
1123
+ let fromChainString = '',
1124
+ fromTokenString = '',
1125
+ toChainString = '',
1126
+ toTokenString = '',
1127
+ fromAmount = '';
1128
+ if (loadingStatus !== 'success') {
1129
+ fromChainString = searchParamsRef.current[SearchParams.FROM_CHAIN];
1130
+ fromTokenString = searchParamsRef.current[SearchParams.FROM_TOKEN];
1131
+ toChainString = searchParamsRef.current[SearchParams.TO_CHAIN];
1132
+ toTokenString = searchParamsRef.current[SearchParams.TO_TOKEN];
1133
+ fromAmount = searchParamsRef.current[SearchParams.FROM_AMOUNT];
1134
+ } else {
1135
+ if (location.state === 'redirect') return;
1136
+ fromChainString = fromChain?.name || '';
1137
+ fromTokenString = (fromToken?.symbol || '') + (fromToken?.address ? `--${fromToken?.address}` : '');
1138
+ toChainString = toChain?.name || '';
1139
+ toTokenString = (toToken?.symbol || '') + (toToken?.address ? `--${toToken?.address}` : '');
1140
+ fromAmount = inputAmount;
1141
+ setSearchParams({
1142
+ ...(fromChainString && {
1143
+ [SearchParams.FROM_CHAIN]: fromChainString
1144
+ }),
1145
+ ...(fromTokenString && {
1146
+ [SearchParams.FROM_TOKEN]: fromTokenString
1147
+ }),
1148
+ ...(toChainString && {
1149
+ [SearchParams.TO_CHAIN]: toChainString
1150
+ }),
1151
+ ...(toTokenString && {
1152
+ [SearchParams.TO_TOKEN]: toTokenString
1153
+ }),
1154
+ ...(fromAmount && {
1155
+ [SearchParams.FROM_AMOUNT]: fromAmount.toString()
1156
+ })
1157
+ }, {
1158
+ replace: true
1159
+ });
1160
+ }
1161
+ }
1162
+ firstRender.current = false;
1163
+ }, [location.pathname, inputAmount]);
1164
+ React.useEffect(() => {
1165
+ if (loadingStatus === 'success') {
1166
+ const fromChainString = searchParams.get(SearchParams.FROM_CHAIN);
1167
+ const fromTokenString = searchParams.get(SearchParams.FROM_TOKEN);
1168
+ const toChainString = searchParams.get(SearchParams.TO_CHAIN);
1169
+ const toTokenString = searchParams.get(SearchParams.TO_TOKEN);
1170
+ const fromAmount = searchParams.get(SearchParams.FROM_AMOUNT);
1171
+ const fromChain = blockchains.find(blockchain => blockchain.name === fromChainString);
1172
+ const fromToken = searchParamsToToken(tokens, fromTokenString, fromChain || null);
1173
+ const toChain = blockchains.find(blockchain => blockchain.name === toChainString);
1174
+ const toToken = searchParamsToToken(tokens, toTokenString, toChain || null);
1175
+ if (!!fromChain) {
1176
+ setFromChain(fromChain);
1177
+ if (!!fromToken) setFromToken(fromToken);
1178
+ }
1179
+ if (!!toChain) {
1180
+ setToChain(toChain);
1181
+ if (!!toToken) setToToken(toToken);
1182
+ }
1183
+ if (fromAmount) setInputAmount(fromAmount);
1184
+ }
1185
+ }, [loadingStatus]);
1186
+ return null;
1187
+ }
1188
+
1189
+ const ButtonsContainer = /*#__PURE__*/ui.styled('div', {
1190
+ display: 'flex'
1191
+ });
1192
+ function HeaderButtons(props) {
1193
+ const {
1194
+ onClickRefresh
1195
+ } = props;
1196
+ const navigate = reactRouterDom.useNavigate();
1197
+ return React__default.createElement(ButtonsContainer, null, React__default.createElement(ui.Tooltip, {
1198
+ content: "Refresh"
1199
+ }, React__default.createElement(ui.Button, {
1200
+ variant: "ghost",
1201
+ onClick: onClickRefresh
1202
+ }, React__default.createElement(ui.RetryIcon, {
1203
+ size: 24
1204
+ }))), React__default.createElement(ui.Tooltip, {
1205
+ content: "Transactions History"
1206
+ }, React__default.createElement(ui.Button, {
1207
+ variant: "ghost",
1208
+ onClick: () => navigate(navigationRoutes.swaps)
1209
+ }, React__default.createElement(ui.HistoryIcon, {
1210
+ size: 24
1211
+ }))), React__default.createElement(ui.Tooltip, {
1212
+ content: "Settings"
1213
+ }, React__default.createElement(ui.Button, {
1214
+ variant: "ghost",
1215
+ onClick: () => navigate(navigationRoutes.settings)
1216
+ }, React__default.createElement(ui.SettingsIcon, {
1217
+ size: 24
1218
+ }))));
1219
+ }
1220
+
1221
+ const HeaderContainer = /*#__PURE__*/ui.styled('div', {
1222
+ display: 'flex',
1223
+ justifyContent: 'space-between',
1224
+ alignItems: 'center',
1225
+ width: '100%',
1226
+ padding: '$16 0'
1227
+ });
1228
+ function Header(props) {
1229
+ const {
1230
+ onClickRefresh,
1231
+ title,
1232
+ titleSize,
1233
+ titleWeight
1234
+ } = props;
1235
+ const {
1236
+ t
1237
+ } = reactI18next.useTranslation();
1238
+ const titleStyle = ui.css({
1239
+ fontSize: `${titleSize}px !important`,
1240
+ fontWeight: `${titleWeight} !important`
1241
+ });
1242
+ return React__default.createElement(HeaderContainer, null, React__default.createElement(ui.Typography, {
1243
+ variant: "h4",
1244
+ className: titleStyle()
1245
+ }, title ? t(title.toLocaleLowerCase()) : ''), React__default.createElement(HeaderButtons, {
1246
+ onClickRefresh: onClickRefresh
1247
+ }));
1248
+ }
1249
+
1250
+ const Box = /*#__PURE__*/ui.styled('div', {
1251
+ display: 'flex',
1252
+ flexDirection: 'column',
1253
+ width: '100%'
1254
+ });
1255
+ const Container = /*#__PURE__*/ui.styled('div', {
1256
+ boxSizing: 'border-box',
1257
+ borderRadius: '$5',
1258
+ padding: '$8 $16 $16 $16',
1259
+ variants: {
1260
+ type: {
1261
+ filled: {
1262
+ backgroundColor: '$neutrals300'
1263
+ },
1264
+ outlined: {
1265
+ border: '1px solid $neutrals300'
1266
+ }
1267
+ }
1268
+ },
1269
+ defaultVariants: {
1270
+ type: 'filled'
1271
+ },
1272
+ '.head': {
1273
+ display: 'flex',
1274
+ justifyContent: 'space-between',
1275
+ alignItems: 'center',
1276
+ minHeight: '32px'
1277
+ },
1278
+ '.form': {
1279
+ display: 'flex',
1280
+ width: '100%',
1281
+ padding: '$2 0',
1282
+ '.selectors': {
1283
+ width: '35%',
1284
+ '._text': {
1285
+ whiteSpace: 'nowrap',
1286
+ overflow: 'hidden',
1287
+ textOverflow: 'ellipsis'
1288
+ }
1289
+ },
1290
+ '.amount': {
1291
+ width: '30%'
1292
+ }
1293
+ }
1294
+ });
1295
+ const StyledImage = /*#__PURE__*/ui.styled('img', {
1296
+ width: '$24',
1297
+ maxHeight: '$24'
1298
+ });
1299
+ const Options = /*#__PURE__*/ui.styled('div', {
1300
+ display: 'flex',
1301
+ justifyContent: 'flex-end',
1302
+ '.balance': {
1303
+ display: 'flex',
1304
+ alignItems: 'center'
1305
+ }
1306
+ });
1307
+ const ImagePlaceholder = /*#__PURE__*/ui.styled('span', {
1308
+ width: '24px',
1309
+ height: '24px',
1310
+ backgroundColor: '$neutrals300',
1311
+ borderRadius: '99999px'
1312
+ });
1313
+ const OutputContainer = /*#__PURE__*/ui.styled('div', {
1314
+ windth: '100%',
1315
+ height: '$48',
1316
+ borderRadius: '$5',
1317
+ backgroundColor: '$background',
1318
+ border: '1px solid transparent',
1319
+ position: 'relative',
1320
+ display: 'flex',
1321
+ alignItems: 'center',
1322
+ paddingLeft: '$8',
1323
+ paddingRight: '$8'
1324
+ });
1325
+ function TokenInfo(props) {
1326
+ const {
1327
+ type,
1328
+ chain,
1329
+ token
1330
+ } = props;
1331
+ const loadingStatus = useMetaStore.use.loadingStatus();
1332
+ const fromChain = useBestRouteStore.use.fromChain();
1333
+ const toChain = useBestRouteStore.use.toChain();
1334
+ const inputUsdValue = useBestRouteStore.use.inputUsdValue();
1335
+ const fromToken = useBestRouteStore.use.fromToken();
1336
+ const setInputAmount = useBestRouteStore.use.setInputAmount();
1337
+ const bestRoute = useBestRouteStore.use.bestRoute();
1338
+ const inputAmount = useBestRouteStore.use.inputAmount();
1339
+ const balances = useWalletsStore.use.balances();
1340
+ const navigate = reactRouterDom.useNavigate();
1341
+ const {
1342
+ t
1343
+ } = reactI18next.useTranslation();
1344
+ const tokenBalance = !!fromChain && !!fromToken ? numberToString(getBalanceFromWallet(balances, fromChain?.name, fromToken?.symbol, fromToken?.address)?.amount || '0', 8) : '0';
1345
+ 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';
1346
+ const ItemSuffix = React__default.createElement("div", {
1347
+ style: {
1348
+ display: 'flex',
1349
+ justifyContent: 'center',
1350
+ alignItems: 'center'
1351
+ }
1352
+ }, loadingStatus === 'failed' && React__default.createElement(ui.InfoCircleIcon, {
1353
+ color: "error",
1354
+ size: 24
1355
+ }), React__default.createElement(ui.AngleDownIcon, null));
1356
+ return React__default.createElement(Box, null, React__default.createElement(Container, {
1357
+ type: props.type === 'From' ? 'filled' : 'outlined'
1358
+ }, React__default.createElement("div", {
1359
+ className: "head"
1360
+ }, React__default.createElement(ui.Typography, {
1361
+ variant: "body2",
1362
+ color: "neutrals800"
1363
+ }, t(type)), props.type === 'From' ? React__default.createElement(Options, null, React__default.createElement("div", {
1364
+ className: "balance",
1365
+ onClick: () => {
1366
+ if (tokenBalance !== '0') setInputAmount(tokenBalanceReal.split(',').join(''));
1367
+ }
1368
+ }, React__default.createElement(ui.Typography, {
1369
+ variant: "body3",
1370
+ color: "neutrals600"
1371
+ }, `${t('Balance')}: ${tokenBalance} ${fromToken?.symbol || ''}`), React__default.createElement(ui.Spacer, {
1372
+ size: 4
1373
+ }), React__default.createElement(ui.Button, {
1374
+ type: "primary",
1375
+ variant: "ghost",
1376
+ size: "compact"
1377
+ }, t('Max')))) : React__default.createElement(ui.Typography, {
1378
+ variant: "caption",
1379
+ color: "neutrals600"
1380
+ }, `$${numberToString(props.outputUsdValue)}`)), React__default.createElement("div", {
1381
+ className: "form"
1382
+ }, React__default.createElement(ui.Button, {
1383
+ className: "selectors",
1384
+ onClick: () => {
1385
+ navigate(`/${props.type.toLowerCase()}-chain`);
1386
+ },
1387
+ variant: "outlined",
1388
+ disabled: loadingStatus === 'failed',
1389
+ loading: loadingStatus === 'loading',
1390
+ prefix: loadingStatus === 'success' && chain ? React__default.createElement(StyledImage, {
1391
+ src: chain.logo
1392
+ }) : React__default.createElement(ImagePlaceholder, null),
1393
+ suffix: ItemSuffix,
1394
+ align: "start",
1395
+ size: "large"
1396
+ }, loadingStatus === 'success' && chain ? chain.displayName : t('Chain')), React__default.createElement(ui.Spacer, {
1397
+ size: 12
1398
+ }), React__default.createElement(ui.Button, {
1399
+ className: "selectors",
1400
+ onClick: () => {
1401
+ navigate(`/${props.type.toLowerCase()}-token`);
1402
+ },
1403
+ variant: "outlined",
1404
+ disabled: loadingStatus === 'failed' || type === 'From' && !fromChain || type === 'To' && !toChain,
1405
+ loading: loadingStatus === 'loading',
1406
+ prefix: loadingStatus === 'success' && token ? React__default.createElement(StyledImage, {
1407
+ src: token.image
1408
+ }) : React__default.createElement(ImagePlaceholder, null),
1409
+ suffix: ItemSuffix,
1410
+ size: "large",
1411
+ align: "start"
1412
+ }, loadingStatus === 'success' && token ? token.symbol : t('Token')), React__default.createElement(ui.Spacer, {
1413
+ size: 12
1414
+ }), React__default.createElement("div", {
1415
+ className: "amount"
1416
+ }, props.type === 'From' ? React__default.createElement(ui.TextField, {
1417
+ type: "number",
1418
+ size: "large",
1419
+ autoFocus: true,
1420
+ placeholder: "0",
1421
+ style: {
1422
+ position: 'relative',
1423
+ backgroundColor: '$background !important'
1424
+ },
1425
+ suffix: React__default.createElement("span", {
1426
+ style: {
1427
+ position: 'absolute',
1428
+ right: '4px',
1429
+ bottom: '2px'
1430
+ }
1431
+ }, React__default.createElement(ui.Typography, {
1432
+ variant: "caption",
1433
+ color: "neutrals800"
1434
+ }, `$${numberToString(inputUsdValue)}`)),
1435
+ value: props.inputAmount || '',
1436
+ onChange: props.type === 'From' ? event => {
1437
+ props.onAmountChange(event.target.value);
1438
+ } : undefined
1439
+ }) : React__default.createElement(OutputContainer, null, React__default.createElement(ui.Typography, {
1440
+ variant: "h4"
1441
+ }, bestRoute ? `≈ ${numberToString(props.outputAmount)}` : inputAmount ? '?' : '0'))))));
1442
+ }
1443
+
1444
+ const Container$1 = /*#__PURE__*/theme.styled('div', {
1445
+ display: 'flex',
1446
+ width: '100%',
1447
+ justifyContent: 'end',
1448
+ alignItems: 'center',
1449
+ paddingTop: '$16'
1450
+ });
1451
+ const Logo = /*#__PURE__*/theme.styled('svg', {
1452
+ fill: '$foreground',
1453
+ width: '$24',
1454
+ margin: '0 $8 0 $16'
1455
+ });
1456
+ const StyledAnchor = /*#__PURE__*/theme.styled('a', {
1457
+ display: 'flex',
1458
+ justifyContent: 'center',
1459
+ alignItems: 'center',
1460
+ textDecoration: 'none'
1461
+ });
1462
+ function BottomLogo() {
1463
+ const {
1464
+ t
1465
+ } = reactI18next.useTranslation();
1466
+ return React__default.createElement(Container$1, null, React__default.createElement(ui.Typography, {
1467
+ variant: "caption"
1468
+ }, t('Powered By')), React__default.createElement(StyledAnchor, {
1469
+ href: "https://rango.exchange",
1470
+ target: "_blank"
1471
+ }, React__default.createElement(Logo, {
1472
+ xmlns: "http://www.w3.org/2000/svg",
1473
+ viewBox: "0 0 33.68 29"
1474
+ }, React__default.createElement("defs", null), React__default.createElement("g", {
1475
+ id: "Layer_2",
1476
+ "data-name": "Layer 2"
1477
+ }, React__default.createElement("g", {
1478
+ id: "Layer_1-2",
1479
+ "data-name": "Layer 1"
1480
+ }, React__default.createElement("path", {
1481
+ 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"
1482
+ }), React__default.createElement("path", {
1483
+ 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"
1484
+ })))), React__default.createElement(ui.Typography, {
1485
+ variant: "body2"
1486
+ }, "RANGO")));
1487
+ }
1488
+
1489
+ function SwithFromAndTo(_ref) {
1490
+ let {
1491
+ count
1492
+ } = _ref;
1493
+ const firstRender = React.useRef(true);
1494
+ const [searchParams, setSearchParams] = reactRouterDom.useSearchParams();
1495
+ const outputAmount = useBestRouteStore.use.outputAmount();
1496
+ React.useEffect(() => {
1497
+ if (!firstRender.current) {
1498
+ const fromChainString = searchParams.get(SearchParams.FROM_CHAIN);
1499
+ const fromTokenString = searchParams.get(SearchParams.FROM_TOKEN);
1500
+ const toChainString = searchParams.get(SearchParams.TO_CHAIN);
1501
+ const toTokenString = searchParams.get(SearchParams.TO_TOKEN);
1502
+ setSearchParams({
1503
+ ...(toChainString && {
1504
+ [SearchParams.FROM_CHAIN]: toChainString
1505
+ }),
1506
+ ...(toTokenString && {
1507
+ [SearchParams.FROM_TOKEN]: toTokenString
1508
+ }),
1509
+ ...(fromChainString && {
1510
+ [SearchParams.TO_CHAIN]: fromChainString
1511
+ }),
1512
+ ...(fromTokenString && {
1513
+ [SearchParams.TO_TOKEN]: fromTokenString
1514
+ }),
1515
+ ...(outputAmount && {
1516
+ [SearchParams.FROM_AMOUNT]: outputAmount.toString()
1517
+ })
1518
+ });
1519
+ } else {
1520
+ firstRender.current = false;
1521
+ }
1522
+ }, [count]);
1523
+ return null;
1524
+ }
1525
+
1526
+ const Footer = /*#__PURE__*/ui.styled('div', {
1527
+ display: 'flex',
1528
+ flexDirection: 'column',
1529
+ width: '100%',
1530
+ paddingTop: '$16'
1531
+ });
1532
+
1533
+ const errorMessages = {
1534
+ genericServerError: 'Error connecting server, please reload the app and try again'
1535
+ };
1536
+
1537
+ const Container$2 = /*#__PURE__*/ui.styled('div', {
1538
+ display: 'flex',
1539
+ flexDirection: 'column'
1540
+ });
1541
+ const FromContainer = /*#__PURE__*/ui.styled('div', {
1542
+ position: 'relative',
1543
+ paddingBottom: '$12'
1544
+ });
1545
+ const SwitchButtonContainer = /*#__PURE__*/ui.styled('div', {
1546
+ position: 'absolute',
1547
+ bottom: '-12px',
1548
+ left: '50%',
1549
+ transform: 'translate(-50%, 10%)'
1550
+ });
1551
+ const BestRouteContainer = /*#__PURE__*/ui.styled('div', {
1552
+ width: '100%',
1553
+ paddingTop: '$16'
1554
+ });
1555
+ const Alerts = /*#__PURE__*/ui.styled('div', {
1556
+ width: '100%',
1557
+ paddingTop: '$16'
1558
+ });
1559
+ function Home(props) {
1560
+ const {
1561
+ title = 'SWAP',
1562
+ titleSize = 18,
1563
+ titleWeight = 600
1564
+ } = props;
1565
+ const isRouterInContext = reactRouterDom.useInRouterContext();
1566
+ const navigate = reactRouterDom.useNavigate();
1567
+ const [count, setCount] = React.useState(0);
1568
+ const fromChain = useBestRouteStore.use.fromChain();
1569
+ const fromToken = useBestRouteStore.use.fromToken();
1570
+ const toChain = useBestRouteStore.use.toChain();
1571
+ const toToken = useBestRouteStore.use.toToken();
1572
+ const setFromChain = useBestRouteStore.use.setFromChain();
1573
+ const setFromToken = useBestRouteStore.use.setFromToken();
1574
+ const setToChain = useBestRouteStore.use.setToChain();
1575
+ const setToToken = useBestRouteStore.use.setToToken();
1576
+ const setInputAmount = useBestRouteStore.use.setInputAmount();
1577
+ const inputUsdValue = useBestRouteStore.use.inputUsdValue();
1578
+ const inputAmount = useBestRouteStore.use.inputAmount();
1579
+ const outputAmount = useBestRouteStore.use.outputAmount();
1580
+ const outputUsdValue = useBestRouteStore.use.outputUsdValue();
1581
+ const bestRoute = useBestRouteStore.use.bestRoute();
1582
+ const tokens = useMetaStore.use.meta().tokens;
1583
+ const fetchingBestRoute = useBestRouteStore.use.loading();
1584
+ const bestRouteError = useBestRouteStore.use.error();
1585
+ const loadingMetaStatus = useMetaStore.use.loadingStatus();
1586
+ const accounts = useWalletsStore.use.accounts();
1587
+ const swithFromAndTo = () => {
1588
+ setFromChain(toChain);
1589
+ setFromToken(toToken);
1590
+ setToChain(fromChain);
1591
+ setToToken(fromToken);
1592
+ setInputAmount(outputAmount?.toString() || '');
1593
+ setCount(prev => prev + 1);
1594
+ };
1595
+ const errorMessage = loadingMetaStatus === 'failed' ? errorMessages.genericServerError : bestRouteError;
1596
+ const needsToWarnEthOnPath = false;
1597
+ const showBestRoute = inputAmount && (!!bestRoute || fetchingBestRoute || bestRouteError);
1598
+ const outToInRatio = getOutputRatio(inputUsdValue, outputUsdValue);
1599
+ const highValueLoss = outputRatioHasWarning(inputUsdValue, outToInRatio);
1600
+ const {
1601
+ fromAmountRangeError,
1602
+ recommendation,
1603
+ swap
1604
+ } = LimitErrorMessage(bestRoute);
1605
+ const priceImpactCanNotBeComputed = !canComputePriceImpact(bestRoute, inputAmount, inputUsdValue, outputUsdValue);
1606
+ const inputIsZero = inputAmount === '0';
1607
+ const swapButtonState = getSwapButtonState(loadingMetaStatus, accounts, fetchingBestRoute, bestRoute, hasLimitError(bestRoute), highValueLoss, priceImpactCanNotBeComputed, needsToWarnEthOnPath, inputIsZero);
1608
+ const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
1609
+ const highFee = hasHighFee(totalFeeInUsd);
1610
+ return React__default.createElement(Container$2, null, React__default.createElement(Header, {
1611
+ title: title,
1612
+ titleSize: titleSize,
1613
+ titleWeight: titleWeight,
1614
+ onClickRefresh: fetchBestRoute
1615
+ }), React__default.createElement(FromContainer, null, React__default.createElement(TokenInfo, {
1616
+ type: "From",
1617
+ chain: fromChain,
1618
+ token: fromToken,
1619
+ onAmountChange: setInputAmount,
1620
+ inputAmount: inputAmount
1621
+ }), React__default.createElement(SwitchButtonContainer, null, React__default.createElement(ui.Button, {
1622
+ variant: "ghost",
1623
+ onClick: swithFromAndTo
1624
+ }, React__default.createElement(ui.VerticalSwapIcon, {
1625
+ size: 24
1626
+ }), isRouterInContext && React__default.createElement(SwithFromAndTo, {
1627
+ count: count
1628
+ })))), React__default.createElement(TokenInfo, {
1629
+ type: "To",
1630
+ chain: toChain,
1631
+ token: toToken,
1632
+ outputAmount: outputAmount ? new BigNumber__default(outputAmount) : new BigNumber__default(0),
1633
+ outputUsdValue: outputUsdValue
1634
+ }), showBestRoute && React__default.createElement(BestRouteContainer, null, React__default.createElement(ui.BestRoute, {
1635
+ error: bestRouteError,
1636
+ loading: fetchingBestRoute,
1637
+ data: bestRoute,
1638
+ totalFee: numberToString(totalFeeInUsd, 0, 2),
1639
+ feeWarning: highFee,
1640
+ totalTime: secondsToString(totalArrivalTime(bestRoute))
1641
+ })), (errorMessage || hasLimitError(bestRoute)) && React__default.createElement(Alerts, null, errorMessage && React__default.createElement(ui.Alert, {
1642
+ type: "error"
1643
+ }, errorMessage), hasLimitError(bestRoute) && React__default.createElement(ui.Alert, {
1644
+ type: "error",
1645
+ title: `${swap?.swapperId} Limit`
1646
+ }, React__default.createElement(React__default.Fragment, null, React__default.createElement(ui.Typography, {
1647
+ variant: "body2"
1648
+ }, fromAmountRangeError), React__default.createElement("br", null), React__default.createElement(ui.Typography, {
1649
+ variant: "body2"
1650
+ }, "Yours: ", numberToString(swap?.fromAmount || null), swap?.from.symbol), React__default.createElement("br", null), React__default.createElement(ui.Typography, {
1651
+ variant: "body2"
1652
+ }, recommendation)))), React__default.createElement(Footer, null, React__default.createElement(ui.Button, {
1653
+ type: "primary",
1654
+ align: "grow",
1655
+ size: "large",
1656
+ disabled: swapButtonState.disabled,
1657
+ onClick: () => {
1658
+ if (swapButtonState.title === 'Connect Wallet') navigate(navigationRoutes.wallets);else {
1659
+ navigate(navigationRoutes.confirmWallets, {
1660
+ replace: true
1661
+ });
1662
+ }
1663
+ }
1664
+ }, swapButtonState.title), React__default.createElement(BottomLogo, null)));
1665
+ }
1666
+
1667
+ const Route = _ref => {
1668
+ let {
1669
+ children,
1670
+ ...props
1671
+ } = _ref;
1672
+ const location = reactRouter.useLocation();
1673
+ const navigate = reactRouter.useNavigate();
1674
+ const ref = React.useRef(true);
1675
+ React.useEffect(() => {
1676
+ if ([navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname) && ref.current) navigate(navigationRoutes.home + location.search, {
1677
+ state: 'redirect'
1678
+ });
1679
+ ref.current = false;
1680
+ }, []);
1681
+ if ([navigationRoutes.confirmWallets, navigationRoutes.confirmSwap].includes(location.pathname) && ref.current) return React__default.createElement(Home, Object.assign({}, props));
1682
+ return React__default.createElement(React__default.Fragment, null, " ", children);
1683
+ };
1684
+ function AppRouter(_ref2) {
1685
+ let {
1686
+ children,
1687
+ ...props
1688
+ } = _ref2;
1689
+ const isRouterInContext = reactRouter.useInRouterContext();
1690
+ const Router = isRouterInContext ? Route : reactRouter.MemoryRouter;
1691
+ return React__default.createElement(React__default.Fragment, null, React__default.createElement(Router, Object.assign({}, props), children), isRouterInContext && React__default.createElement(UpdateUrl, null));
1692
+ }
1693
+
1694
+ function ChangeSlippageButton() {
1695
+ const navigate = reactRouterDom.useNavigate();
1696
+ return React__default.createElement(ui.Button, {
1697
+ type: "primary",
1698
+ variant: "outlined",
1699
+ size: "small",
1700
+ onClick: () => navigate(navigationRoutes.settings)
1701
+ }, "Change Slippage");
1702
+ }
1703
+
1704
+ function HighSlippageWarning(props) {
1705
+ const {
1706
+ selectedSlippage
1707
+ } = props;
1708
+ return React__default.createElement(ui.Alert, {
1709
+ type: "warning",
1710
+ footer: React__default.createElement(ChangeSlippageButton, null)
1711
+ }, "Caution, your slippage is high (=", selectedSlippage, "). Your trade may be front run.");
1712
+ }
1713
+
1714
+ function ConfirmSwapExtraMessages(props) {
1715
+ const {
1716
+ selectedSlippage
1717
+ } = props;
1718
+ const highSlippage = selectedSlippage >= HIGH_SLIPPAGE;
1719
+ return React__default.createElement(React__default.Fragment, null, highSlippage && React__default.createElement(HighSlippageWarning, {
1720
+ selectedSlippage: selectedSlippage
1721
+ }));
1722
+ }
1723
+
1724
+ function useNavigateBack() {
1725
+ const isRouterInContext = reactRouterDom.useInRouterContext();
1726
+ const navigate = reactRouterDom.useNavigate();
1727
+ const navigateBackFrom = currentRoute => {
1728
+ if (!isRouterInContext || window.history.state && window.history.state.idx > 0) navigate(-1);else {
1729
+ if ([navigationRoutes.fromChain, navigationRoutes.fromToken, navigationRoutes.toChain, navigationRoutes.toToken, navigationRoutes.settings, navigationRoutes.wallets, navigationRoutes.swaps, navigationRoutes.confirmWallets].includes(currentRoute)) navigate(navigationRoutes.home, {
1730
+ replace: true
1731
+ });else if (currentRoute === navigationRoutes.liquiditySources) navigate(navigationRoutes.settings, {
1732
+ replace: true
1733
+ });else if (currentRoute === navigationRoutes.swapDetails) navigate(navigationRoutes.swaps, {
1734
+ replace: true
1735
+ });else if (currentRoute === navigationRoutes.confirmSwap) navigate(navigationRoutes.confirmWallets, {
1736
+ replace: true
1737
+ });
1738
+ }
1739
+ };
1740
+ return {
1741
+ navigateBackFrom
1742
+ };
1743
+ }
1744
+
1745
+ var ConfirmSwapErrorTypes;
1746
+ (function (ConfirmSwapErrorTypes) {
1747
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["NO_ROUTE"] = 0] = "NO_ROUTE";
1748
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS"] = 1] = "ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS";
1749
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["REQUEST_FAILED"] = 2] = "REQUEST_FAILED";
1750
+ ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["INSUFFICIENT_SLIPPAGE"] = 3] = "INSUFFICIENT_SLIPPAGE";
1751
+ })(ConfirmSwapErrorTypes || (ConfirmSwapErrorTypes = {}));
1752
+ var ConfirmSwapWarningTypes;
1753
+ (function (ConfirmSwapWarningTypes) {
1754
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_UPDATED"] = 0] = "ROUTE_UPDATED";
1755
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_SWAPPERS_UPDATED"] = 1] = "ROUTE_SWAPPERS_UPDATED";
1756
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_COINS_UPDATED"] = 2] = "ROUTE_COINS_UPDATED";
1757
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_AND_OUTPUT_AMOUNT_UPDATED"] = 3] = "ROUTE_AND_OUTPUT_AMOUNT_UPDATED";
1758
+ ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["INSUFFICIENT_BALANCE"] = 4] = "INSUFFICIENT_BALANCE";
1759
+ })(ConfirmSwapWarningTypes || (ConfirmSwapWarningTypes = {}));
1760
+
1761
+ function MinRequiredSlippage(_ref) {
1762
+ let {
1763
+ minRequiredSlippage
1764
+ } = _ref;
1765
+ return React__default.createElement(ui.Typography, {
1766
+ variant: "body2"
1767
+ }, "We recommend you to increase slippage to at least \u00A0", minRequiredSlippage, "\u00A0 for this route.", React__default.createElement(ChangeSlippageButton, null));
1768
+ }
1769
+
1770
+ function ConfirmSwapErrors(errors) {
1771
+ return errors.flatMap(error => {
1772
+ switch (error.type) {
1773
+ case ConfirmSwapErrorTypes.NO_ROUTE:
1774
+ return React__default.createElement(ui.Typography, {
1775
+ variant: "body2"
1776
+ }, "No routes found. Please try again later.");
1777
+ case ConfirmSwapErrorTypes.REQUEST_FAILED:
1778
+ return React__default.createElement(ui.Typography, {
1779
+ variant: "body2"
1780
+ }, `Failed to confirm swap ${error.status ? `'status': ${error.status})` : ''}, please try again.`);
1781
+ case ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS:
1782
+ return React__default.createElement(ui.Typography, {
1783
+ variant: "body2"
1784
+ }, "Route updated and price impact is too high, try again later!");
1785
+ case ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE:
1786
+ return React__default.createElement(MinRequiredSlippage, {
1787
+ minRequiredSlippage: error.minRequiredSlippage
1788
+ });
1789
+ default:
1790
+ return [];
1791
+ }
1792
+ });
1793
+ }
1794
+
1795
+ const List = /*#__PURE__*/ui.styled('ul', {
1796
+ variants: {
1797
+ showListStyle: {
1798
+ true: {
1799
+ paddingLeft: '$24'
1800
+ }
1801
+ }
1802
+ }
1803
+ });
1804
+ const ListItem = /*#__PURE__*/ui.styled('li', {
1805
+ variants: {
1806
+ showListStyle: {
1807
+ true: {
1808
+ listStyleType: 'disc',
1809
+ listStylePosition: 'outside'
1810
+ }
1811
+ }
1812
+ }
1813
+ });
1814
+ const Message = /*#__PURE__*/ui.styled(ui.Typography, {
1815
+ display: 'block'
1816
+ });
1817
+ function BalanceWarnings(_ref) {
1818
+ let {
1819
+ messages
1820
+ } = _ref;
1821
+ const showListStyle = messages.length > 1;
1822
+ return React__default.createElement(List, {
1823
+ showListStyle: showListStyle
1824
+ }, messages.map(warning => React__default.createElement(ListItem, {
1825
+ showListStyle: showListStyle
1826
+ }, React__default.createElement(Message, {
1827
+ variant: "body2"
1828
+ }, warning))));
1829
+ }
1830
+
1831
+ function ConfirmSwapWarnings(warnings) {
1832
+ return warnings.flatMap(warning => {
1833
+ switch (warning.type) {
1834
+ case ConfirmSwapWarningTypes.ROUTE_UPDATED:
1835
+ return React__default.createElement(ui.Typography, {
1836
+ variant: "body2"
1837
+ }, "Route has been updated.");
1838
+ case ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED:
1839
+ return React__default.createElement(ui.Typography, {
1840
+ variant: "body2"
1841
+ }, `Output amount changed to ${warning.newOutputAmount}
1842
+ (${warning.percentageChange}% change).`);
1843
+ case ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED:
1844
+ return React__default.createElement(ui.Typography, {
1845
+ variant: "body2"
1846
+ }, "Route swappers has been updated.");
1847
+ case ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED:
1848
+ return React__default.createElement(ui.Typography, {
1849
+ variant: "body2"
1850
+ }, "Route internal coins has been updated.");
1851
+ case ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE:
1852
+ return React__default.createElement(BalanceWarnings, {
1853
+ messages: warning.messages
1854
+ });
1855
+ default:
1856
+ return [];
1857
+ }
1858
+ });
1859
+ }
1860
+
1861
+ function useConfirmSwap() {
1862
+ const fromToken = useBestRouteStore.use.fromToken();
1863
+ const toToken = useBestRouteStore.use.toToken();
1864
+ const inputAmount = useBestRouteStore.use.inputAmount();
1865
+ const initialRoute = useBestRouteStore.use.bestRoute();
1866
+ const setBestRoute = useBestRouteStore.use.setBestRoute();
1867
+ const inputUsdValue = useBestRouteStore.use.inputUsdValue();
1868
+ const accounts = useWalletsStore.use.accounts();
1869
+ const selectedWallets = useWalletsStore.use.selectedWallets();
1870
+ const meta = useMetaStore.use.meta();
1871
+ const customSlippage = useSettingsStore.use.customSlippage();
1872
+ const slippage = useSettingsStore.use.slippage();
1873
+ const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
1874
+ const userSlippage = customSlippage || slippage;
1875
+ const proceedAnywayRef = React.useRef(false);
1876
+ const confiremedRouteRef = React.useRef(null);
1877
+ let abortControllerRef = React.useRef(null);
1878
+ const [loading, setLoading] = React.useState(false);
1879
+ const [errors, setErrors] = React.useState([]);
1880
+ const [warnings, setWarnings] = React.useState([]);
1881
+ React.useEffect(() => {
1882
+ return () => abortControllerRef.current?.abort();
1883
+ }, []);
1884
+ if (!fromToken || !toToken || !inputAmount || !initialRoute) return {
1885
+ loading: false,
1886
+ warnings: [],
1887
+ errors: [],
1888
+ confirmSwap: null
1889
+ };
1890
+ const confirmSwap = async () => {
1891
+ if (proceedAnywayRef.current) {
1892
+ const swapSettings = {
1893
+ slippage: userSlippage.toString(),
1894
+ disabledSwappersGroups: disabledLiquiditySources
1895
+ };
1896
+ if (errors.length > 0) setErrors([]);
1897
+ if (warnings.length > 0) setWarnings([]);
1898
+ proceedAnywayRef.current = false;
1899
+ if (confiremedRouteRef.current) {
1900
+ const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRouteRef.current, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
1901
+ return newSwap;
1902
+ }
1903
+ return;
1904
+ }
1905
+ abortControllerRef.current = new AbortController();
1906
+ setLoading(true);
1907
+ const requestBody = createBestRouteRequestBody(fromToken, toToken, inputAmount, accounts, selectedWallets, disabledLiquiditySources, userSlippage, true);
1908
+ try {
1909
+ const confiremedRoute = await httpService.getBestRoute(requestBody, {
1910
+ signal: abortControllerRef.current?.signal
1911
+ });
1912
+ abortControllerRef.current = null;
1913
+ setLoading(false);
1914
+ if (!confiremedRoute.result || !new BigNumber__default(confiremedRoute.requestAmount).isEqualTo(new BigNumber__default(inputAmount || '-1'))) {
1915
+ setErrors(prevState => prevState.concat({
1916
+ type: ConfirmSwapErrorTypes.NO_ROUTE
1917
+ }));
1918
+ return;
1919
+ }
1920
+ const confirmSwapState = {
1921
+ errors: [],
1922
+ warnings: []
1923
+ };
1924
+ const routeChanged = isRouteChanged(initialRoute, confiremedRoute);
1925
+ if (routeChanged) {
1926
+ setBestRoute(confiremedRoute);
1927
+ const newRouteOutputUsdValue = new BigNumber__default(confiremedRoute.result?.outputAmount || '0').multipliedBy(toToken.usdPrice || 0);
1928
+ const outputRatio = getOutputRatio(inputUsdValue, newRouteOutputUsdValue);
1929
+ const highValueLoss = outputRatioHasWarning(inputUsdValue, outputRatio);
1930
+ if (highValueLoss) confirmSwapState.errors.push({
1931
+ type: ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS
1932
+ });else if (isOutputAmountChangedALot(initialRoute, confiremedRoute)) confirmSwapState.warnings.push({
1933
+ type: ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED,
1934
+ newOutputAmount: numberToString(getRouteOutputAmount(confiremedRoute)),
1935
+ percentageChange: numberToString(getPercentageChange(getRouteOutputAmount(initialRoute), getRouteOutputAmount(confiremedRoute)), null, 2)
1936
+ });else if (isRouteInternalCoinsUpdated(initialRoute, confiremedRoute)) confirmSwapState.warnings.push({
1937
+ type: ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED
1938
+ });else if (isNumberOfSwapsChanged(initialRoute, confiremedRoute)) confirmSwapState.warnings.push({
1939
+ type: ConfirmSwapWarningTypes.ROUTE_UPDATED
1940
+ });else if (isRouteSwappersUpdated(initialRoute, confiremedRoute)) confirmSwapState.warnings.push({
1941
+ type: ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED
1942
+ });
1943
+ }
1944
+ const balanceWarnings = getBalanceWarnings(confiremedRoute, selectedWallets);
1945
+ const enoughBalance = balanceWarnings.length === 0;
1946
+ if (!enoughBalance) confirmSwapState.warnings.push({
1947
+ type: ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE,
1948
+ messages: balanceWarnings
1949
+ });
1950
+ const minRequiredSlippage = getMinRequiredSlippage(initialRoute);
1951
+ if (!hasProperSlippage(userSlippage.toString(), minRequiredSlippage)) confirmSwapState.errors.push({
1952
+ type: ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE,
1953
+ minRequiredSlippage
1954
+ });
1955
+ const noErrors = confirmSwapState.errors.length === 0;
1956
+ const noWarnings = confirmSwapState.warnings.length === 0;
1957
+ if ((noErrors || !noErrors && proceedAnywayRef.current) && (noWarnings || !noWarnings && proceedAnywayRef.current)) {
1958
+ const swapSettings = {
1959
+ slippage: userSlippage.toString(),
1960
+ disabledSwappersGroups: disabledLiquiditySources
1961
+ };
1962
+ const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRoute, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
1963
+ return newSwap;
1964
+ } else if (!proceedAnywayRef.current) {
1965
+ proceedAnywayRef.current = true;
1966
+ setErrors(confirmSwapState.errors);
1967
+ setWarnings(confirmSwapState.warnings);
1968
+ confiremedRouteRef.current = confiremedRoute;
1969
+ }
1970
+ return;
1971
+ } catch (error) {
1972
+ if (error?.code === 'ERR_CANCELED') {
1973
+ return;
1974
+ }
1975
+ const status = error?.response?.status;
1976
+ setLoading(false);
1977
+ setErrors([{
1978
+ type: ConfirmSwapErrorTypes.REQUEST_FAILED,
1979
+ status
1980
+ }]);
1981
+ return;
1982
+ }
1983
+ };
1984
+ return {
1985
+ loading,
1986
+ warnings,
1987
+ errors,
1988
+ confirmSwap
1989
+ };
1990
+ }
1991
+
1992
+ function ConfirmSwapPage() {
1993
+ const setSelectedSwap = useUiStore.use.setSelectedSwap();
1994
+ const {
1995
+ navigateBackFrom
1996
+ } = useNavigateBack();
1997
+ const {
1998
+ manager
1999
+ } = queueManagerReact.useManager();
2000
+ const navigate = reactRouterDom.useNavigate();
2001
+ const bestRoute = useBestRouteStore.use.bestRoute();
2002
+ const fetchingBestRoute = useBestRouteStore.use.loading();
2003
+ const {
2004
+ tokens
2005
+ } = useMetaStore.use.meta();
2006
+ const slippage = useSettingsStore.use.slippage();
2007
+ const customSlippage = useSettingsStore.use.customSlippage();
2008
+ const selectedSlippage = customSlippage || slippage;
2009
+ const {
2010
+ loading,
2011
+ errors,
2012
+ warnings,
2013
+ confirmSwap
2014
+ } = useConfirmSwap();
2015
+ const showHighSlippageWarning = !errors.find(error => error.type === ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE);
2016
+ return React__default.createElement(ui.ConfirmSwap, {
2017
+ onConfirm: () => {
2018
+ confirmSwap?.().then(swap => {
2019
+ if (swap) {
2020
+ manager?.create('swap', {
2021
+ swapDetails: swap
2022
+ }, {
2023
+ id: swap.requestId
2024
+ });
2025
+ setSelectedSwap(swap.requestId);
2026
+ navigate(navigationRoutes.swaps + `/${swap.requestId}`, {
2027
+ replace: true
2028
+ });
2029
+ }
2030
+ });
2031
+ },
2032
+ onBack: navigateBackFrom.bind(null, navigationRoutes.confirmSwap),
2033
+ bestRoute: getBestRouteWithCalculatedFees(bestRoute, tokens),
2034
+ loading: loading,
2035
+ errors: ConfirmSwapErrors(errors),
2036
+ warnings: ConfirmSwapWarnings(warnings),
2037
+ extraMessages: showHighSlippageWarning && React__default.createElement(ConfirmSwapExtraMessages, {
2038
+ selectedSlippage: selectedSlippage
2039
+ }),
2040
+ confirmButtonTitle: warnings.length > 0 || errors.length > 0 ? 'Proceed anyway!' : 'Confirm swap!',
2041
+ confirmButtonDisabled: fetchingBestRoute
2042
+ });
2043
+ }
2044
+
2045
+ const getPendingSwaps = manager => {
2046
+ const result = [];
2047
+ manager?.getAll().forEach((q, id) => {
2048
+ const storage = q.list.getStorage();
2049
+ if (storage?.swapDetails) {
2050
+ result.push({
2051
+ id,
2052
+ swap: storage?.swapDetails
2053
+ });
2054
+ }
2055
+ });
2056
+ return result.sort((a, b) => Number(b.swap.creationTime) - Number(a.swap.creationTime));
2057
+ };
2058
+
2059
+ function HistoryPage() {
2060
+ const setSelectedSwap = useUiStore.use.setSelectedSwap();
2061
+ const navigate = reactRouterDom.useNavigate();
2062
+ const {
2063
+ navigateBackFrom
2064
+ } = useNavigateBack();
2065
+ const {
2066
+ manager
2067
+ } = queueManagerReact.useManager();
2068
+ const pendingSwaps = getPendingSwaps(manager).map(_ref => {
2069
+ let {
2070
+ swap
2071
+ } = _ref;
2072
+ return swap;
2073
+ });
2074
+ return React__default.createElement(ui.History
2075
+ //todo: move PendingSwap type to rango-types
2076
+ //@ts-ignore
2077
+ , {
2078
+ //todo: move PendingSwap type to rango-types
2079
+ //@ts-ignore
2080
+ list: pendingSwaps,
2081
+ onSwapClick: requestId => {
2082
+ setSelectedSwap(requestId);
2083
+ navigate(navigationRoutes.swaps + `/${requestId}`);
2084
+ },
2085
+ onBack: navigateBackFrom.bind(null, navigationRoutes.swaps)
2086
+ });
2087
+ }
2088
+
2089
+ function LiquiditySourcePage(_ref) {
2090
+ let {
2091
+ supportedSwappers
2092
+ } = _ref;
2093
+ const swappers = useMetaStore.use.meta().swappers;
2094
+ const toggleLiquiditySource = useSettingsStore.use.toggleLiquiditySource();
2095
+ const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
2096
+ const toggleAllLiquiditySources = useSettingsStore.use.toggleAllLiquiditySources();
2097
+ const {
2098
+ navigateBackFrom
2099
+ } = useNavigateBack();
2100
+ const uniqueSwappersGroups = [];
2101
+ removeDuplicateFrom(swappers.map(s => s.swapperGroup)).map(swapperGroup => {
2102
+ return swappers.find(s => s.swapperGroup === swapperGroup);
2103
+ }).find(s => {
2104
+ if (s) {
2105
+ for (const type of s.types) {
2106
+ uniqueSwappersGroups.push({
2107
+ title: s.swapperGroup,
2108
+ logo: s.logo,
2109
+ type,
2110
+ selected: !disabledLiquiditySources.includes(s.swapperGroup)
2111
+ });
2112
+ }
2113
+ }
2114
+ });
2115
+ return React__default.createElement(ui.LiquiditySourcesSelector, {
2116
+ toggleAll: toggleAllLiquiditySources,
2117
+ list: supportedSwappers !== 'all' ? uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0) : uniqueSwappersGroups,
2118
+ onChange: liquiditySource => toggleLiquiditySource(liquiditySource.title),
2119
+ onBack: navigateBackFrom.bind(null, navigationRoutes.liquiditySources)
2120
+ });
2121
+ }
2122
+
2123
+ function SelectChainPage(props) {
2124
+ const {
2125
+ type,
2126
+ supportedChains
2127
+ } = props;
2128
+ const blockchains = supportedChains === 'all' ? useMetaStore.use.meta().blockchains : supportedChains;
2129
+ const loadingStatus = useMetaStore.use.loadingStatus();
2130
+ const fromChain = useBestRouteStore.use.fromChain();
2131
+ const toChain = useBestRouteStore.use.toChain();
2132
+ const setFromChain = useBestRouteStore.use.setFromChain();
2133
+ const setToChain = useBestRouteStore.use.setToChain();
2134
+ const {
2135
+ navigateBackFrom
2136
+ } = useNavigateBack();
2137
+ return React__default.createElement(ui.BlockchainSelector, {
2138
+ type: type === 'from' ? 'Source' : 'Destination',
2139
+ list: blockchains,
2140
+ selected: type === 'from' ? fromChain : toChain,
2141
+ loadingStatus: loadingStatus,
2142
+ onChange: chain => {
2143
+ if (type === 'from') setFromChain(chain, true);else setToChain(chain, true);
2144
+ navigateBackFrom(navigationRoutes.fromChain);
2145
+ },
2146
+ onBack: navigateBackFrom.bind(null, navigationRoutes.fromChain)
2147
+ });
2148
+ }
2149
+
2150
+ function SelectTokenPage(props) {
2151
+ const {
2152
+ navigateBackFrom
2153
+ } = useNavigateBack();
2154
+ const {
2155
+ type,
2156
+ supportedTokens
2157
+ } = props;
2158
+ const sourceTokens = useBestRouteStore.use.sourceTokens();
2159
+ const destinationTokens = useBestRouteStore.use.destinationTokens();
2160
+ const supportedSourceTokens = supportedTokens === 'all' ? sourceTokens : sourceTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2161
+ const supportedDestinationTokens = supportedTokens === 'all' ? destinationTokens : destinationTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
2162
+ console.log(supportedSourceTokens);
2163
+ const fromToken = useBestRouteStore.use.fromToken();
2164
+ const toToken = useBestRouteStore.use.toToken();
2165
+ const setFromToken = useBestRouteStore.use.setFromToken();
2166
+ const setToToken = useBestRouteStore.use.setToToken();
2167
+ return React__default.createElement(ui.TokenSelector, {
2168
+ type: type === 'from' ? 'Source' : 'Destination',
2169
+ list: type == 'from' ? supportedSourceTokens : supportedDestinationTokens,
2170
+ selected: type === 'from' ? fromToken : toToken,
2171
+ onChange: token => {
2172
+ if (type === 'from') setFromToken(token);else setToToken(token);
2173
+ navigateBackFrom(navigationRoutes.fromToken);
2174
+ },
2175
+ onBack: navigateBackFrom.bind(null, navigationRoutes.fromToken)
2176
+ });
2177
+ }
2178
+
2179
+ function SettingsPage(_ref) {
2180
+ let {
2181
+ supportedSwappers
2182
+ } = _ref;
2183
+ const slippage = useSettingsStore.use.slippage();
2184
+ const setSlippage = useSettingsStore.use.setSlippage();
2185
+ const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
2186
+ const customSlippage = useSettingsStore.use.customSlippage();
2187
+ const setCustomSlippage = useSettingsStore.use.setCustomSlippage();
2188
+ const theme = useSettingsStore.use.theme();
2189
+ const setTheme = useSettingsStore.use.setTheme();
2190
+ const swappers = useMetaStore.use.meta().swappers;
2191
+ const navigate = reactRouterDom.useNavigate();
2192
+ const {
2193
+ navigateBackFrom
2194
+ } = useNavigateBack();
2195
+ const infiniteApprove = useSettingsStore.use.infiniteApprove();
2196
+ const toggleInfiniteApprove = useSettingsStore.use.toggleInfiniteApprove();
2197
+ const uniqueSwappersGroups = [];
2198
+ removeDuplicateFrom(swappers.map(s => s.swapperGroup)).map(swapperGroup => {
2199
+ return swappers.find(s => s.swapperGroup === swapperGroup);
2200
+ }).find(s => {
2201
+ if (s) {
2202
+ for (const type of s.types) {
2203
+ uniqueSwappersGroups.push({
2204
+ title: s.swapperGroup,
2205
+ logo: s.logo,
2206
+ type,
2207
+ selected: !disabledLiquiditySources.includes(s.swapperGroup)
2208
+ });
2209
+ }
2210
+ }
2211
+ });
2212
+ supportedSwappers !== 'all' && uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0);
2213
+ const supportedUniqueSwappersGroups = supportedSwappers !== 'all' ? uniqueSwappersGroups.filter(item => supportedSwappers.filter(s => s.title === item.title && s.type === item.type).length > 0) : uniqueSwappersGroups;
2214
+ return React__default.createElement(ui.Settings, {
2215
+ slippages: SLIPPAGES,
2216
+ selectedSlippage: slippage,
2217
+ onSlippageChange: slippage => setSlippage(slippage),
2218
+ onLiquiditySourcesClick: () => navigate(navigationRoutes.liquiditySources),
2219
+ onBack: navigateBackFrom.bind(null, navigationRoutes.settings),
2220
+ liquiditySources: supportedUniqueSwappersGroups,
2221
+ selectedLiquiditySources: supportedUniqueSwappersGroups.filter(s => s.selected),
2222
+ customSlippage: customSlippage || NaN,
2223
+ onCustomSlippageChange: setCustomSlippage,
2224
+ minSlippage: MIN_SLIPPGAE,
2225
+ maxSlippage: MAX_SLIPPAGE,
2226
+ selectedTheme: theme,
2227
+ onThemeChange: setTheme,
2228
+ infiniteApprove: infiniteApprove,
2229
+ toggleInfiniteApprove: toggleInfiniteApprove
2230
+ });
2231
+ }
2232
+
2233
+ const ListContainer = /*#__PURE__*/ui.styled('div', {
2234
+ display: 'grid',
2235
+ gap: '.5rem',
2236
+ gridTemplateColumns: ' repeat(2, minmax(0, 1fr))',
2237
+ height: '450px',
2238
+ alignContent: 'baseline',
2239
+ padding: '0.5rem'
2240
+ });
2241
+ const AlertContainer = /*#__PURE__*/ui.styled('div', {
2242
+ paddingBottom: '$16'
2243
+ });
2244
+ function WalletsPage(_ref) {
2245
+ let {
2246
+ supportedWallets,
2247
+ multiWallets
2248
+ } = _ref;
2249
+ const {
2250
+ navigateBackFrom
2251
+ } = useNavigateBack();
2252
+ const {
2253
+ state,
2254
+ disconnect,
2255
+ getWalletInfo,
2256
+ connect
2257
+ } = walletsCore.useWallets();
2258
+ const wallets = getlistWallet(state, getWalletInfo, supportedWallets === 'all' ? Object.values(walletsShared.WalletType) : supportedWallets);
2259
+ const walletsRef = React.useRef();
2260
+ let sortedWallets = walletsShared.detectMobileScreens() ? wallets.filter(wallet => wallet.showOnMobile) : wallets;
2261
+ sortedWallets = sortWalletsBasedOnState(sortedWallets);
2262
+ const [walletErrorMessage, setWalletErrorMessage] = React.useState('');
2263
+ const toggleConnectWalletsButton = useUiStore.use.toggleConnectWalletsButton();
2264
+ const {
2265
+ t
2266
+ } = reactI18next.useTranslation();
2267
+ const onSelectWallet = async type => {
2268
+ const wallet = state(type);
2269
+ try {
2270
+ if (walletErrorMessage) setWalletErrorMessage('');
2271
+ if (wallet.connected) {
2272
+ await disconnect(type);
2273
+ } else {
2274
+ if (!multiWallets && !!wallets.find(w => w.state === ui.WalletState.CONNECTED)) {
2275
+ return;
2276
+ }
2277
+ await connect(type);
2278
+ }
2279
+ } catch (e) {
2280
+ setWalletErrorMessage('Error: ' + e?.message);
2281
+ }
2282
+ };
2283
+ const disconnectConnectingWallets = () => {
2284
+ const connectingWallets = walletsRef.current?.filter(wallet => wallet.state === ui.WalletState.CONNECTING) || [];
2285
+ for (const wallet of connectingWallets) {
2286
+ disconnect(wallet.type);
2287
+ }
2288
+ };
2289
+ React.useEffect(() => {
2290
+ toggleConnectWalletsButton();
2291
+ return () => {
2292
+ disconnectConnectingWallets();
2293
+ toggleConnectWalletsButton();
2294
+ };
2295
+ }, []);
2296
+ React.useEffect(() => {
2297
+ walletsRef.current = wallets;
2298
+ }, [wallets]);
2299
+ return React__default.createElement(ui.SecondaryPage, {
2300
+ title: t('Select Wallet') || '',
2301
+ textField: false,
2302
+ onBack: navigateBackFrom.bind(null, navigationRoutes.wallets)
2303
+ }, React__default.createElement(React__default.Fragment, null, walletErrorMessage && React__default.createElement(AlertContainer, null, React__default.createElement(ui.Alert, {
2304
+ type: "error"
2305
+ }, walletErrorMessage)), React__default.createElement(ListContainer, null, sortedWallets.map((wallet, index) => React__default.createElement(ui.Wallet, Object.assign({}, wallet, {
2306
+ key: `${index}-${wallet.type}`,
2307
+ onClick: onSelectWallet
2308
+ }))))));
2309
+ }
2310
+
2311
+ const Box$1 = /*#__PURE__*/ui.styled('div', {
2312
+ display: 'flex',
2313
+ flexDirection: 'column',
2314
+ width: '100%'
2315
+ });
2316
+ const Container$3 = /*#__PURE__*/ui.styled('div', {
2317
+ boxSizing: 'border-box',
2318
+ borderRadius: '$5',
2319
+ padding: '$8 $16 $16 $16',
2320
+ variants: {
2321
+ type: {
2322
+ filled: {
2323
+ backgroundColor: '$neutrals300'
2324
+ },
2325
+ outlined: {
2326
+ border: '1px solid $neutrals300'
2327
+ }
2328
+ }
2329
+ },
2330
+ defaultVariants: {
2331
+ type: 'filled'
2332
+ },
2333
+ '.head': {
2334
+ display: 'flex',
2335
+ justifyContent: 'space-between',
2336
+ alignItems: 'center',
2337
+ minHeight: '32px'
2338
+ },
2339
+ '.form': {
2340
+ display: 'flex',
2341
+ width: '100%',
2342
+ padding: '$2 0',
2343
+ '.selectors': {
2344
+ width: '35%',
2345
+ '._text': {
2346
+ whiteSpace: 'nowrap',
2347
+ overflow: 'hidden',
2348
+ textOverflow: 'ellipsis'
2349
+ }
2350
+ },
2351
+ '.amount': {
2352
+ width: '30%'
2353
+ }
2354
+ }
2355
+ });
2356
+ const StyledImage$1 = /*#__PURE__*/ui.styled('img', {
2357
+ width: '$24',
2358
+ maxHeight: '$24'
2359
+ });
2360
+ const ImagePlaceholder$1 = /*#__PURE__*/ui.styled('span', {
2361
+ width: '24px',
2362
+ height: '24px',
2363
+ backgroundColor: '$neutrals300',
2364
+ borderRadius: '99999px'
2365
+ });
2366
+ const OutputContainer$1 = /*#__PURE__*/ui.styled('div', {
2367
+ windth: '100%',
2368
+ height: '$48',
2369
+ borderRadius: '$5',
2370
+ backgroundColor: '$background',
2371
+ border: '1px solid transparent',
2372
+ position: 'relative',
2373
+ display: 'flex',
2374
+ alignItems: 'center',
2375
+ paddingLeft: '$8',
2376
+ paddingRight: '$8'
2377
+ });
2378
+ function TokenPreview(props) {
2379
+ const {
2380
+ chain,
2381
+ token,
2382
+ loadingStatus
2383
+ } = props;
2384
+ const {
2385
+ t
2386
+ } = reactI18next.useTranslation();
2387
+ const ItemSuffix = React__default.createElement("div", {
2388
+ style: {
2389
+ display: 'flex',
2390
+ justifyContent: 'center',
2391
+ alignItems: 'center'
2392
+ }
2393
+ }, loadingStatus === 'failed' && React__default.createElement(ui.InfoCircleIcon, {
2394
+ color: "error",
2395
+ size: 24
2396
+ }));
2397
+ return React__default.createElement(Box$1, null, React__default.createElement(Container$3, {
2398
+ type: 'outlined'
2399
+ }, React__default.createElement("div", {
2400
+ className: "head"
2401
+ }, React__default.createElement(ui.Typography, {
2402
+ variant: "body2",
2403
+ color: "neutrals800"
2404
+ }, props.label), React__default.createElement(ui.Typography, {
2405
+ variant: "caption",
2406
+ color: "neutrals600"
2407
+ }, `$${numberToString(props.usdValue)}`)), React__default.createElement("div", {
2408
+ className: "form"
2409
+ }, React__default.createElement(ui.Button, {
2410
+ className: "selectors",
2411
+ variant: "outlined",
2412
+ loading: loadingStatus === 'loading',
2413
+ prefix: loadingStatus === 'success' && chain ? React__default.createElement(StyledImage$1, {
2414
+ src: chain.logo
2415
+ }) : React__default.createElement(ImagePlaceholder$1, null),
2416
+ suffix: ItemSuffix,
2417
+ align: "start",
2418
+ size: "large"
2419
+ }, loadingStatus === 'success' && chain ? chain.displayName : t('Chain')), React__default.createElement(ui.Spacer, {
2420
+ size: 12
2421
+ }), React__default.createElement(ui.Button, {
2422
+ className: "selectors",
2423
+ variant: "outlined",
2424
+ loading: loadingStatus === 'loading',
2425
+ prefix: loadingStatus === 'success' && token ? React__default.createElement(StyledImage$1, {
2426
+ src: token.image
2427
+ }) : React__default.createElement(ImagePlaceholder$1, null),
2428
+ suffix: ItemSuffix,
2429
+ size: "large",
2430
+ align: "start"
2431
+ }, loadingStatus === 'success' && token ? token.symbol : t('Token')), React__default.createElement(ui.Spacer, {
2432
+ size: 12
2433
+ }), React__default.createElement("div", {
2434
+ className: "amount"
2435
+ }, React__default.createElement(OutputContainer$1, null, React__default.createElement(ui.Typography, {
2436
+ variant: "h4"
2437
+ }, props.amount))))));
2438
+ }
2439
+
2440
+ const Container$4 = /*#__PURE__*/ui.styled('div', {
2441
+ display: 'flex',
2442
+ alignItems: 'center',
2443
+ justifyContent: 'space-between',
2444
+ padding: '$8',
2445
+ borderRadius: '$5',
2446
+ backgroundColor: '$neutrals300',
2447
+ color: '$neutrals800',
2448
+ fontSize: '$12',
2449
+ '.routes': {
2450
+ display: 'flex',
2451
+ alignItems: 'center'
2452
+ },
2453
+ '.fee': {
2454
+ display: 'flex',
2455
+ alignItems: 'center'
2456
+ }
2457
+ });
2458
+ function RoutesOverview(props) {
2459
+ if (!props.routes) return null;
2460
+ const swaps = props.routes.result?.swaps;
2461
+ return React__default.createElement(Container$4, null, React__default.createElement("div", {
2462
+ className: "routes"
2463
+ }, swaps?.map((swap, idx) => {
2464
+ const isLast = idx + 1 == swaps.length;
2465
+ return React__default.createElement(React__default.Fragment, null, React__default.createElement("div", {
2466
+ className: "route"
2467
+ }, swap.from.symbol), React__default.createElement(ui.ChevronRightIcon, {
2468
+ size: 12
2469
+ }), isLast ? React__default.createElement("div", {
2470
+ className: "route"
2471
+ }, swap.to.symbol) : null);
2472
+ })), props.totalFee ? React__default.createElement("div", {
2473
+ className: "fee"
2474
+ }, React__default.createElement(ui.GasIcon, {
2475
+ size: 12
2476
+ }), React__default.createElement(ui.Spacer, {
2477
+ size: 4
2478
+ }), "$", props.totalFee) : null);
2479
+ }
2480
+
2481
+ function ConfirmWalletsPage() {
2482
+ const navigate = reactRouterDom.useNavigate();
2483
+ const {
2484
+ navigateBackFrom
2485
+ } = useNavigateBack();
2486
+ const bestRoute = useBestRouteStore.use.bestRoute();
2487
+ const {
2488
+ blockchains,
2489
+ tokens
2490
+ } = useMetaStore.use.meta();
2491
+ const accounts = useWalletsStore.use.accounts();
2492
+ const selectedWallets = useWalletsStore.use.selectedWallets();
2493
+ const initSelectedWallets = useWalletsStore.use.initSelectedWallets();
2494
+ const setSelectedWallet = useWalletsStore.use.setSelectedWallet();
2495
+ const {
2496
+ getWalletInfo,
2497
+ connect
2498
+ } = walletsCore.useWallets();
2499
+ const confirmDisabled = !requiredWallets(bestRoute).every(chain => selectedWallets.map(wallet => wallet.chain).includes(chain));
2500
+ const firstStep = bestRoute?.result?.swaps[0];
2501
+ const lastStep = bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1];
2502
+ const fromAmount = decimalNumber(firstStep?.fromAmount, 3);
2503
+ const toAmount = decimalNumber(lastStep?.toAmount, 3);
2504
+ React.useEffect(() => {
2505
+ initSelectedWallets();
2506
+ }, []);
2507
+ const selectableWallets = getSelectableWallets(accounts, selectedWallets, getWalletInfo);
2508
+ const handleConnectChain = wallet => {
2509
+ const network = wallet;
2510
+ getKeplrCompatibleConnectedWallets(selectableWallets).forEach(compatibleWallet => connect?.(compatibleWallet, network));
2511
+ };
2512
+ const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens);
2513
+ return React__default.createElement(ui.ConfirmWallets, {
2514
+ requiredWallets: getRequiredChains(bestRoute),
2515
+ selectableWallets: selectableWallets,
2516
+ onBack: navigateBackFrom.bind(null, navigationRoutes.confirmWallets),
2517
+ onConfirm: () => navigate(navigationRoutes.confirmSwap, {
2518
+ replace: true
2519
+ }),
2520
+ onChange: wallet => setSelectedWallet(wallet),
2521
+ confirmDisabled: confirmDisabled,
2522
+ handleConnectChain: wallet => handleConnectChain(wallet),
2523
+ isExperimentalChain: wallet => getKeplrCompatibleConnectedWallets(selectableWallets).length > 0 ? isExperimentalChain(blockchains, wallet) : false,
2524
+ previewInputs: React__default.createElement(React__default.Fragment, null, React__default.createElement(TokenPreview, {
2525
+ chain: {
2526
+ displayName: firstStep?.from.blockchain || '',
2527
+ logo: firstStep?.from.blockchainLogo || ''
2528
+ },
2529
+ token: {
2530
+ symbol: firstStep?.from.symbol || '',
2531
+ image: firstStep?.from.logo || ''
2532
+ },
2533
+ usdValue: calcOutputUsdValue(fromAmount, firstStep?.from.usdPrice),
2534
+ amount: fromAmount,
2535
+ label: i18n.t('From'),
2536
+ loadingStatus: 'success'
2537
+ }), React__default.createElement(ui.Spacer, {
2538
+ size: 12,
2539
+ direction: "vertical"
2540
+ }), React__default.createElement(TokenPreview, {
2541
+ chain: {
2542
+ displayName: lastStep?.to.blockchain || '',
2543
+ logo: lastStep?.to.blockchainLogo || ''
2544
+ },
2545
+ token: {
2546
+ symbol: lastStep?.to.symbol || '',
2547
+ image: lastStep?.to.logo || ''
2548
+ },
2549
+ usdValue: calcOutputUsdValue(toAmount, lastStep?.to.usdPrice),
2550
+ amount: toAmount,
2551
+ label: i18n.t('To'),
2552
+ loadingStatus: 'success'
2553
+ })),
2554
+ previewRoutes: React__default.createElement(RoutesOverview, {
2555
+ routes: bestRoute,
2556
+ totalFee: numberToString(totalFeeInUsd, 0, 2)
2557
+ })
2558
+ });
2559
+ }
2560
+
2561
+ function useCopyToClipboard(resetInterval) {
2562
+ const [isCopied, setCopied] = React__default.useState(false);
2563
+ const handleCopy = React__default.useCallback(text => {
2564
+ copy(text.toString());
2565
+ setCopied(true);
2566
+ }, []);
2567
+ React__default.useEffect(() => {
2568
+ let timeout;
2569
+ if (isCopied && resetInterval) {
2570
+ timeout = setTimeout(() => setCopied(false), resetInterval);
2571
+ }
2572
+ return () => {
2573
+ clearTimeout(timeout);
2574
+ };
2575
+ }, [isCopied, resetInterval]);
2576
+ return [isCopied, handleCopy];
2577
+ }
2578
+
2579
+ function SwapDetailsPage() {
2580
+ const selectedSwapRequestId = useUiStore.use.selectedSwapRequestId();
2581
+ const {
2582
+ navigateBackFrom
2583
+ } = useNavigateBack();
2584
+ const {
2585
+ manager
2586
+ } = queueManagerReact.useManager();
2587
+ const [isCopied, handleCopy] = useCopyToClipboard(2000);
2588
+ const pendingSwaps = getPendingSwaps(manager);
2589
+ const selectedSwap = pendingSwaps.find(_ref => {
2590
+ let {
2591
+ swap
2592
+ } = _ref;
2593
+ return swap.requestId === selectedSwapRequestId;
2594
+ });
2595
+ //TODO: implement swap cancellation (move queueManager logic to queueManager/rango-preset)
2596
+ const onCancel = () => {
2597
+ const swap = selectedSwap ? manager?.get(selectedSwap.id) : undefined;
2598
+ if (swap) queueManagerRangoPreset.cancelSwap(swap);
2599
+ };
2600
+ return React__default.createElement(ui.SwapHistory, {
2601
+ onBack: navigateBackFrom.bind(null, navigationRoutes.swapDetails),
2602
+ //todo: move PendingSwap type to rango-types
2603
+ //@ts-ignore
2604
+ pendingSwap: selectedSwap?.swap,
2605
+ onCopy: handleCopy,
2606
+ isCopied: isCopied,
2607
+ onCancel: onCancel
2608
+ });
2609
+ }
2610
+
2611
+ function AppRoutes(props) {
2612
+ const {
2613
+ configs
2614
+ } = props;
2615
+ return reactRouterDom.useRoutes([{
2616
+ path: navigationRoutes.home,
2617
+ element: React__default.createElement(Home, {
2618
+ title: configs?.title,
2619
+ titleSize: configs?.titleSize,
2620
+ titleWeight: configs?.titleWeight
2621
+ })
2622
+ }, {
2623
+ path: navigationRoutes.fromChain,
2624
+ element: React__default.createElement(SelectChainPage, {
2625
+ type: "from",
2626
+ supportedChains: configs?.fromChains || 'all'
2627
+ })
2628
+ }, {
2629
+ path: navigationRoutes.toChain,
2630
+ element: React__default.createElement(SelectChainPage, {
2631
+ type: "to",
2632
+ supportedChains: configs?.toChains || 'all'
2633
+ })
2634
+ }, {
2635
+ path: navigationRoutes.fromToken + '/*',
2636
+ element: React__default.createElement(SelectTokenPage, {
2637
+ type: "from",
2638
+ supportedTokens: configs?.fromTokens || 'all'
2639
+ })
2640
+ }, {
2641
+ path: navigationRoutes.toToken,
2642
+ element: React__default.createElement(SelectTokenPage, {
2643
+ type: "to",
2644
+ supportedTokens: configs?.toTokens || 'all'
2645
+ })
2646
+ }, {
2647
+ path: navigationRoutes.settings,
2648
+ element: React__default.createElement(SettingsPage, {
2649
+ supportedSwappers: configs?.liquiditySources || 'all'
2650
+ })
2651
+ }, {
2652
+ path: navigationRoutes.liquiditySources,
2653
+ element: React__default.createElement(LiquiditySourcePage, {
2654
+ supportedSwappers: configs?.liquiditySources || 'all'
2655
+ })
2656
+ }, {
2657
+ path: navigationRoutes.swaps,
2658
+ element: React__default.createElement(HistoryPage, null)
2659
+ }, {
2660
+ path: navigationRoutes.swapDetails,
2661
+ element: React__default.createElement(SwapDetailsPage, null)
2662
+ }, {
2663
+ path: navigationRoutes.wallets,
2664
+ element: React__default.createElement(WalletsPage, {
2665
+ supportedWallets: configs?.wallets || 'all',
2666
+ multiWallets: typeof configs?.multiWallets === 'undefined' ? true : configs.multiWallets
2667
+ })
2668
+ }, {
2669
+ path: navigationRoutes.confirmSwap,
2670
+ element: React__default.createElement(ConfirmSwapPage, null)
2671
+ }, {
2672
+ path: navigationRoutes.confirmWallets,
2673
+ element: React__default.createElement(ConfirmWalletsPage, null)
2674
+ }]);
2675
+ }
2676
+
2677
+ const Header$1 = /*#__PURE__*/ui.styled('div', {
2678
+ display: 'flex',
2679
+ width: '100%',
2680
+ justifyContent: 'end'
2681
+ });
2682
+ const WalletImage = /*#__PURE__*/ui.styled('img', {
2683
+ width: '$24',
2684
+ height: '$24',
2685
+ marginLeft: -15,
2686
+ marginRight: '$6',
2687
+ borderRadius: '99999px'
2688
+ });
2689
+ function Layout(_ref) {
2690
+ let {
2691
+ configs
2692
+ } = _ref;
2693
+ const navigate = reactRouterDom.useNavigate();
2694
+ const {
2695
+ balances,
2696
+ accounts,
2697
+ selectedWallets
2698
+ } = useWalletsStore();
2699
+ const {
2700
+ getWalletInfo
2701
+ } = walletsCore.useWallets();
2702
+ const connectedWalletsImages = removeDuplicateFrom(getSelectableWallets(accounts, selectedWallets, getWalletInfo).map(w => w.image));
2703
+ const setFromChain = useBestRouteStore.use.setFromChain();
2704
+ const setFromToken = useBestRouteStore.use.setFromToken();
2705
+ const setToChain = useBestRouteStore.use.setToChain();
2706
+ const setToToken = useBestRouteStore.use.setToToken();
2707
+ const setInputAmount = useBestRouteStore.use.setInputAmount();
2708
+ const totalBalance = calculateWalletUsdValue(balances);
2709
+ const connectWalletsButtonDisabled = useUiStore.use.connectWalletsButtonDisabled();
2710
+ const {
2711
+ t
2712
+ } = reactI18next.useTranslation();
2713
+ React.useEffect(() => {
2714
+ setToChain(configs?.toChain || null);
2715
+ setToToken(configs?.toToken || null);
2716
+ }, [configs?.toChain, configs?.toToken]);
2717
+ React.useEffect(() => {
2718
+ setInputAmount(configs?.fromAmount?.toString() || '');
2719
+ }, [configs?.fromAmount]);
2720
+ React.useEffect(() => {
2721
+ setFromToken(configs?.fromToken || null);
2722
+ setFromChain(configs?.fromChain || null);
2723
+ }, [configs?.fromToken, configs?.fromChain]);
2724
+ return React__default.createElement(React__default.Fragment, null, React__default.createElement(Header$1, null, React__default.createElement(ui.Button, {
2725
+ size: "small",
2726
+ suffix: React__default.createElement(ui.AddWalletIcon, {
2727
+ size: 20
2728
+ }),
2729
+ variant: "ghost",
2730
+ flexContent: true,
2731
+ onClick: () => {
2732
+ if (!connectWalletsButtonDisabled) navigate(navigationRoutes.wallets);
2733
+ }
2734
+ }, connectedWalletsImages?.length ? connectedWalletsImages.map((walletImage, index) => React__default.createElement(WalletImage, {
2735
+ key: index,
2736
+ src: walletImage
2737
+ })) : React__default.createElement(React__default.Fragment, null), React__default.createElement(ui.Typography, {
2738
+ variant: "body2"
2739
+ }, !accounts?.length ? t('Connect Wallet') : `$${totalBalance || 0}`))), React__default.createElement(AppRoutes, {
2740
+ configs: configs
2741
+ }));
2742
+ }
2743
+
2744
+ const globalStyles = /*#__PURE__*/ui.globalCss({
2745
+ '*': {
2746
+ '&::-webkit-scrollbar': {
2747
+ width: '$8'
2748
+ },
2749
+ '&::-webkit-scrollbar-thumb': {
2750
+ backgroundColor: '$neutrals400'
2751
+ },
2752
+ '&::-webkit-scrollbar-thumb:hover': {
2753
+ backgroundColor: '$neutrals500'
2754
+ },
2755
+ '&::-webkit-scrollbar-track': {
2756
+ backgroundColor: '$neutrals300'
2757
+ }
2758
+ }
2759
+ });
2760
+ const globalFont = fontFamily => ui.globalCss({
2761
+ '@import': ["url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap')", "url('https://fonts.cdnfonts.com/css/times-new-roman')"],
2762
+ body: {
2763
+ fontFamily
2764
+ }
2765
+ })();
2766
+
2767
+ function usePrevious(value) {
2768
+ // The ref object is a generic container whose current property is mutable ...
2769
+ // ... and can hold any value, similar to an instance property on a class
2770
+ const ref = React.useRef();
2771
+ // Store current value in ref
2772
+ React.useEffect(() => {
2773
+ ref.current = value;
2774
+ }, [value]); // Only re-run if value changes
2775
+ // Return previous value (happens before update in useEffect above)
2776
+ return ref.current;
2777
+ }
2778
+
2779
+ function useTheme(_ref) {
2780
+ let {
2781
+ primary = '#5FA425',
2782
+ background = '#fff',
2783
+ foreground = '#000',
2784
+ error = '#FF0000',
2785
+ warning = '#F5A623',
2786
+ success = '#0070F3',
2787
+ fontFamily = 'Robot',
2788
+ borderRadius = 8
2789
+ } = _ref;
2790
+ const theme = useSettingsStore.use.theme();
2791
+ const fetchMeta = useMetaStore.use.fetchMeta();
2792
+ const colors = {
2793
+ neutrals200: '#FAFAFA',
2794
+ neutrals300: '#f2f2f2',
2795
+ neutrals400: '#dedede',
2796
+ neutrals500: '#cccccc',
2797
+ neutrals600: '#acacac',
2798
+ neutrals700: '#444444',
2799
+ neutrals800: '#333333',
2800
+ neutrals900: '#111111',
2801
+ primary,
2802
+ primary100: shadeColor(primary, 15),
2803
+ primary200: shadeColor(primary, -10),
2804
+ primary300: shadeColor(primary, -15),
2805
+ primary400: shadeColor(primary, -20),
2806
+ primary500: shadeColor(primary, -25),
2807
+ primary600: shadeColor(primary, -30),
2808
+ primary700: shadeColor(primary, -35),
2809
+ primary800: shadeColor(primary, -40),
2810
+ primary900: shadeColor(primary, -45),
2811
+ background,
2812
+ foreground,
2813
+ error,
2814
+ error100: shadeColor(error, 50),
2815
+ error300: shadeColor(error, -10),
2816
+ error500: shadeColor(error, -20),
2817
+ error700: shadeColor(error, -30),
2818
+ warning,
2819
+ warning100: shadeColor(warning, 50),
2820
+ warning300: shadeColor(warning, -10),
2821
+ warning500: shadeColor(warning, -20),
2822
+ warning700: shadeColor(warning, -30),
2823
+ success,
2824
+ success100: shadeColor(success, 50),
2825
+ success300: shadeColor(success, -10),
2826
+ success500: shadeColor(success, -20),
2827
+ success700: shadeColor(success, -30)
2828
+ };
2829
+ const customeLightTheme = ui.createTheme({
2830
+ colors,
2831
+ radii: {
2832
+ 5: `${borderRadius}px`
2833
+ }
2834
+ });
2835
+ const customeDarkTheme = ui.createTheme({
2836
+ colors: {
2837
+ ...colors,
2838
+ neutrals200: '#111111',
2839
+ neutrals300: '#333333',
2840
+ neutrals400: '#444444',
2841
+ neutrals500: '#acacac',
2842
+ neutrals600: '#cccccc',
2843
+ neutrals700: '#dedede',
2844
+ neutrals800: '#f2f2f2',
2845
+ neutrals900: '#FAFAFA',
2846
+ foreground: background,
2847
+ background: foreground
2848
+ },
2849
+ radii: {
2850
+ 5: `${borderRadius}px`
2851
+ }
2852
+ });
2853
+ const [OSTheme, setOSTheme] = React.useState(customeLightTheme);
2854
+ React.useEffect(() => {
2855
+ (async () => {
2856
+ await fetchMeta();
2857
+ })();
2858
+ const switchTheme = event => {
2859
+ if (event.matches) setOSTheme(customeDarkTheme);else setOSTheme(customeLightTheme);
2860
+ };
2861
+ if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
2862
+ setOSTheme(customeDarkTheme);
2863
+ }
2864
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', switchTheme);
2865
+ return () => {
2866
+ window.matchMedia('(prefers-color-scheme: dark)').removeEventListener('change', switchTheme);
2867
+ };
2868
+ }, []);
2869
+ const prevFont = usePrevious(fontFamily);
2870
+ React.useLayoutEffect(() => {
2871
+ const {
2872
+ classList
2873
+ } = document.body;
2874
+ if (prevFont) classList.remove(`font_${prevFont.replace(/ /g, '')}`);
2875
+ classList.add(`font_${fontFamily.replace(/ /g, '')}`);
2876
+ }, [fontFamily]);
2877
+ const getActiveTheme = () => {
2878
+ if (theme === 'auto') return OSTheme;else return theme === 'dark' ? customeDarkTheme : customeLightTheme;
2879
+ };
2880
+ return {
2881
+ activeTheme: getActiveTheme()
2882
+ };
2883
+ }
2884
+
2885
+ function useSelectLanguage() {
2886
+ const {
2887
+ i18n
2888
+ } = reactI18next.useTranslation();
2889
+ // @ts-ignore
2890
+ const currentLanguage = i18n?.language || 'en';
2891
+ const changeLanguage = value => {
2892
+ if (currentLanguage !== value) {
2893
+ // @ts-ignore
2894
+ i18n.changeLanguage(value);
2895
+ }
2896
+ };
2897
+ return {
2898
+ changeLanguage,
2899
+ currentLanguage
2900
+ };
2901
+ }
2902
+
2903
+ var swap = "SWAP";
2904
+ var From = "You sell";
2905
+ var To = "You receive";
2906
+ var Balance = "Balance";
2907
+ var Max = "Max";
2908
+ var Chain = "Chain";
2909
+ var Token = "Token";
2910
+ var Source = "Source";
2911
+ var Destination = "Destination";
2912
+ var en = {
2913
+ swap: swap,
2914
+ "Connect Wallet": "Connect Wallet",
2915
+ "Powered By": "Powered By",
2916
+ From: From,
2917
+ To: To,
2918
+ Balance: Balance,
2919
+ Max: Max,
2920
+ Chain: Chain,
2921
+ Token: Token,
2922
+ Source: Source,
2923
+ Destination: Destination,
2924
+ "Select Wallet": "Connect Your Wallet"
2925
+ };
2926
+
2927
+ var swap$1 = "TAKAS";
2928
+ var From$1 = "İtibaren";
2929
+ var To$1 = "İle";
2930
+ var Max$1 = "maks.";
2931
+ var Chain$1 = "Zincir";
2932
+ var Token$1 = "Jeton";
2933
+ var tr = {
2934
+ swap: swap$1,
2935
+ "Select Wallet": "Cüzdan Seç",
2936
+ "Powered By": "Tarafından desteklenmektedir",
2937
+ "Connect Wallet": "Cüzdanı Bağla",
2938
+ From: From$1,
2939
+ To: To$1,
2940
+ Max: Max$1,
2941
+ Chain: Chain$1,
2942
+ Token: Token$1
2943
+ };
2944
+
2945
+ const languages = ['en', 'tr'];
2946
+ i18n__default.use(Backend)
2947
+ // detect user language
2948
+ .use(LanguageDetector)
2949
+ // pass the i18n instance to react-i18next.
2950
+ .use(reactI18next.initReactI18next).init({
2951
+ resources: {
2952
+ en: {
2953
+ translation: en
2954
+ },
2955
+ tr: {
2956
+ translation: tr
2957
+ }
2958
+ },
2959
+ fallbackLng: 'en',
2960
+ debug: true,
2961
+ whitelist: languages
2962
+ });
2963
+
2964
+ function QueueManager(props) {
2965
+ const {
2966
+ providers,
2967
+ getSigners,
2968
+ state,
2969
+ connect,
2970
+ canSwitchNetworkTo,
2971
+ getWalletInfo
2972
+ } = walletsCore.useWallets();
2973
+ const {
2974
+ blockchains
2975
+ } = useMetaStore.use.meta();
2976
+ const balances = useWalletsStore.use.balances();
2977
+ const wallets = {
2978
+ blockchains: balances.map(wallet => ({
2979
+ accounts: [wallet],
2980
+ name: wallet.chain
2981
+ }))
2982
+ };
2983
+ const switchNetwork = (wallet, network) => {
2984
+ if (!canSwitchNetworkTo(wallet, network)) {
2985
+ return undefined;
2986
+ }
2987
+ return connect(wallet, network);
2988
+ };
2989
+ // TODO: this code copy & pasted from rango, should be refactored.
2990
+ const allBlockchains = blockchains.filter(blockchain => blockchain.enabled).reduce((blockchainsObj, blockchain) => (blockchainsObj[blockchain.name] = blockchain, blockchainsObj), {});
2991
+ const evmBasedChains = blockchains.filter(rangoSdk.isEvmBlockchain);
2992
+ const getSupportedChainNames = type => {
2993
+ const {
2994
+ supportedChains
2995
+ } = getWalletInfo(type);
2996
+ return walletAndSupportedChainsNames(supportedChains);
2997
+ };
2998
+ const allProviders = providers();
2999
+ const context = {
3000
+ meta: {
3001
+ blockchains: allBlockchains,
3002
+ evmBasedChains: evmBasedChains,
3003
+ evmNetworkChainInfo: walletsShared.convertEvmBlockchainMetaToEvmChainInfo(evmBasedChains),
3004
+ getSupportedChainNames
3005
+ },
3006
+ getSigners,
3007
+ //todo: remove Network type
3008
+ //@ts-ignore
3009
+ wallets,
3010
+ providers: allProviders,
3011
+ switchNetwork,
3012
+ connect,
3013
+ state,
3014
+ notifier: message => {
3015
+ console.log('[notifier]', message);
3016
+ }
3017
+ };
3018
+ return React__default.createElement(queueManagerReact.Provider
3019
+ //@ts-ignore
3020
+ , {
3021
+ //@ts-ignore
3022
+ queuesDefs: [queueManagerRangoPreset.swapQueueDef],
3023
+ context: context,
3024
+ onPersistedDataLoaded: _manager => {},
3025
+ isPaused: false
3026
+ }, props.children);
3027
+ }
3028
+
3029
+ const SwapBox = _ref => {
3030
+ let {
3031
+ configs
3032
+ } = _ref;
3033
+ globalStyles();
3034
+ globalFont(configs?.fontFamily || 'Roboto');
3035
+ const {
3036
+ activeTheme
3037
+ } = useTheme({
3038
+ ...configs.colors,
3039
+ borderRadius: configs?.borderRadius,
3040
+ fontFamily: configs?.fontFamily
3041
+ });
3042
+ const {
3043
+ blockchains
3044
+ } = useMetaStore.use.meta();
3045
+ const disconnectWallet = useWalletsStore.use.disconnectWallet();
3046
+ const connectWallet = useWalletsStore.use.connectWallet();
3047
+ const setTheme = useSettingsStore.use.setTheme();
3048
+ const {
3049
+ changeLanguage
3050
+ } = useSelectLanguage();
3051
+ const clearConnectedWallet = useWalletsStore.use.clearConnectedWallet();
3052
+ const evmBasedChainNames = blockchains.filter(rangoSdk.isEvmBlockchain).map(chain => chain.name);
3053
+ const onUpdateState = (type, event, value, _, supportedChains) => {
3054
+ if (event === walletsCore.Events.ACCOUNTS) {
3055
+ if (value) {
3056
+ const supportedChainNames = walletAndSupportedChainsNames(supportedChains);
3057
+ const data = prepareAccountsForWalletStore(type, value, evmBasedChainNames, supportedChainNames);
3058
+ connectWallet(data);
3059
+ } else {
3060
+ disconnectWallet(type);
3061
+ }
3062
+ }
3063
+ };
3064
+ let providers = providerAll.allProviders();
3065
+ React.useEffect(() => {
3066
+ if (configs.theme !== 'auto') setTheme(configs.theme);
3067
+ }, [configs.theme]);
3068
+ React.useEffect(() => {
3069
+ const wallets = configs.wallets;
3070
+ clearConnectedWallet();
3071
+ providers = wallets === 'all' ? providerAll.allProviders() : providerAll.allProviders().filter(provider => {
3072
+ const type = provider.config.type;
3073
+ return wallets.find(w => w === type);
3074
+ });
3075
+ }, [configs?.wallets]);
3076
+ React.useEffect(() => {
3077
+ changeLanguage(configs?.languege);
3078
+ }, [configs?.languege]);
3079
+ return React__default.createElement(walletsCore.Provider, {
3080
+ allBlockChains: blockchains,
3081
+ providers: providers,
3082
+ onUpdateState: onUpdateState
3083
+ }, React__default.createElement("div", {
3084
+ id: "pageContainer",
3085
+ className: activeTheme
3086
+ }, React__default.createElement(QueueManager, null, React__default.createElement(ui.SwapContainer, {
3087
+ style: {
3088
+ width: configs?.width || 'auto',
3089
+ height: configs?.height || 'auto'
3090
+ }
3091
+ }, React__default.createElement(AppRouter, {
3092
+ title: configs.title,
3093
+ titleSize: configs.titleSize,
3094
+ titleWeight: configs.titleWeight
3095
+ }, React__default.createElement(Layout, {
3096
+ configs: configs
3097
+ }))))));
3098
+ };
3099
+
3100
+ exports.SwapBox = SwapBox;
3101
+ //# sourceMappingURL=widget-embedded.cjs.development.js.map