@rango-dev/widget-embedded 0.1.10-next.93 → 0.1.10-next.94
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/QueueManager.d.ts.map +1 -1
- package/dist/components/AppRoutes.d.ts +5 -1
- package/dist/components/AppRoutes.d.ts.map +1 -1
- package/dist/components/ConfirmSwapErrors.d.ts +3 -2
- package/dist/components/ConfirmSwapErrors.d.ts.map +1 -1
- package/dist/components/ConfirmSwapWarnings.d.ts +3 -2
- package/dist/components/ConfirmSwapWarnings.d.ts.map +1 -1
- package/dist/components/Layout.d.ts +1 -1
- package/dist/components/Layout.d.ts.map +1 -1
- package/dist/components/SwitchFromAndTo.d.ts +1 -1
- package/dist/components/SwitchFromAndTo.d.ts.map +1 -1
- package/dist/components/UpdateUrl.d.ts +1 -1
- package/dist/components/UpdateUrl.d.ts.map +1 -1
- package/dist/components/warnings/BalanceWarnings.d.ts.map +1 -1
- package/dist/components/warnings/ConfirmSwapExtraMessages.d.ts.map +1 -1
- package/dist/hooks/useConfirmSwap.d.ts +11 -0
- package/dist/hooks/useConfirmSwap.d.ts.map +1 -0
- package/dist/hooks/usePrevious.d.ts +1 -1
- package/dist/hooks/usePrevious.d.ts.map +1 -1
- package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
- package/dist/pages/Home.d.ts.map +1 -1
- package/dist/pages/SelectChainPage.d.ts.map +1 -1
- package/dist/pages/SelectTokenPage.d.ts.map +1 -1
- package/dist/pages/SettingsPage.d.ts.map +1 -1
- package/dist/pages/WalletsPage.d.ts.map +1 -1
- package/dist/store/bestRoute.d.ts +25 -0
- package/dist/store/bestRoute.d.ts.map +1 -1
- package/dist/store/settings.d.ts +15 -0
- package/dist/store/settings.d.ts.map +1 -1
- package/dist/store/wallets.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/{store/confirmSwap.d.ts → types/routing.d.ts} +14 -5
- package/dist/types/routing.d.ts.map +1 -0
- package/dist/utils/numbers.d.ts +1 -1
- package/dist/utils/numbers.d.ts.map +1 -1
- package/dist/utils/routing.d.ts +11 -5
- package/dist/utils/routing.d.ts.map +1 -1
- package/dist/utils/swap.d.ts +4 -3
- package/dist/utils/swap.d.ts.map +1 -1
- package/dist/utils/wallets.d.ts +7 -2
- package/dist/utils/wallets.d.ts.map +1 -1
- package/dist/widget-embedded.cjs.development.js +574 -478
- package/dist/widget-embedded.cjs.development.js.map +1 -1
- package/dist/widget-embedded.cjs.production.min.js +574 -478
- package/dist/widget-embedded.cjs.production.min.js.map +1 -1
- package/dist/widget-embedded.esm.js +575 -479
- package/dist/widget-embedded.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/QueueManager.tsx +1 -0
- package/src/components/AppRoutes.tsx +54 -21
- package/src/components/ChangeSlippageButton.tsx +1 -1
- package/src/components/ConfirmSwapErrors.tsx +1 -1
- package/src/components/ConfirmSwapWarnings.tsx +1 -4
- package/src/components/Header.tsx +1 -1
- package/src/components/Layout.tsx +3 -3
- package/src/components/UpdateUrl.tsx +13 -22
- package/src/components/warnings/BalanceWarnings.tsx +27 -4
- package/src/components/warnings/ConfirmSwapExtraMessages.tsx +7 -1
- package/src/components/warnings/HighSlippageWarning.tsx +1 -1
- package/src/components/warnings/MinRequiredSlippage.tsx +2 -2
- package/src/hooks/useConfirmSwap.ts +260 -0
- package/src/pages/ConfirmSwapPage.tsx +17 -8
- package/src/pages/ConfirmWalletsPage.tsx +1 -1
- package/src/pages/Home.tsx +0 -1
- package/src/pages/SelectChainPage.tsx +2 -7
- package/src/pages/SelectTokenPage.tsx +22 -57
- package/src/pages/SettingsPage.tsx +8 -9
- package/src/pages/WalletsPage.tsx +16 -6
- package/src/store/bestRoute.ts +82 -37
- package/src/store/settings.ts +2 -2
- package/src/store/wallets.ts +26 -0
- package/src/types/index.ts +1 -0
- package/src/types/routing.ts +60 -0
- package/src/utils/numbers.ts +38 -17
- package/src/utils/routing.ts +115 -24
- package/src/utils/swap.ts +19 -11
- package/src/utils/wallets.ts +117 -73
- package/dist/store/confirmSwap.d.ts.map +0 -1
- package/src/store/confirmSwap.ts +0 -342
|
@@ -12,15 +12,15 @@ var reactRouterDom = require('react-router-dom');
|
|
|
12
12
|
var zustand = require('zustand');
|
|
13
13
|
var BigNumber = require('bignumber.js');
|
|
14
14
|
var BigNumber__default = _interopDefault(BigNumber);
|
|
15
|
-
var middleware = require('zustand/middleware');
|
|
16
|
-
var rangoSdk = require('rango-sdk');
|
|
17
15
|
var walletsShared = require('@rango-dev/wallets-shared');
|
|
18
16
|
var rangoTypes = require('rango-types');
|
|
19
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');
|
|
20
21
|
var reactI18next = require('react-i18next');
|
|
21
22
|
var theme = require('@rango-dev/ui/src/theme');
|
|
22
23
|
var providerAll = require('@rango-dev/provider-all');
|
|
23
|
-
var shallow = require('zustand/shallow');
|
|
24
24
|
var queueManagerReact = require('@rango-dev/queue-manager-react');
|
|
25
25
|
var copy = _interopDefault(require('copy-to-clipboard'));
|
|
26
26
|
var i18n = _interopDefault(require('i18next'));
|
|
@@ -70,117 +70,6 @@ function shadeColor(color, percent) {
|
|
|
70
70
|
return '#' + RR + GG + BB;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
const getBestRouteToTokenUsdPrice = bestRoute => bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1].to.usdPrice;
|
|
74
|
-
function isNumberOfSwapsChanged(route1, route2) {
|
|
75
|
-
const route1Swaps = route1.result?.swaps || [];
|
|
76
|
-
const route2Swaps = route2.result?.swaps || [];
|
|
77
|
-
return route1Swaps.length !== route2Swaps.length;
|
|
78
|
-
}
|
|
79
|
-
function isRouteSwappersUpdated(route1, route2) {
|
|
80
|
-
const route1Swappers = route1.result?.swaps.map(swap => swap.swapperId) || [];
|
|
81
|
-
const route2Swappers = route2.result?.swaps.map(swap => swap.swapperId) || [];
|
|
82
|
-
return !areEqual(route1Swappers, route2Swappers);
|
|
83
|
-
}
|
|
84
|
-
function isRouteInternalCoinsUpdated(route1, route2) {
|
|
85
|
-
const route1InternalCoins = route1.result?.swaps.map(swap => swap.to.symbol) || [];
|
|
86
|
-
const route2InternalCoins = route2.result?.swaps.map(swap => swap.to.symbol) || [];
|
|
87
|
-
return !areEqual(route1InternalCoins, route2InternalCoins);
|
|
88
|
-
}
|
|
89
|
-
const isRouteChanged = (route1, route2) => {
|
|
90
|
-
return isNumberOfSwapsChanged(route1, route2) || isRouteSwappersUpdated(route1, route2) || isRouteInternalCoinsUpdated(route1, route2);
|
|
91
|
-
};
|
|
92
|
-
const getRequiredBalanceOfWallet = (selectedWallet, fee) => {
|
|
93
|
-
if (fee === null) return null;
|
|
94
|
-
const relatedFeeStatus = fee?.find(item => item.blockchain === selectedWallet.chain)?.wallets.find(wallet => wallet.address?.toLowerCase() === selectedWallet.address.toLowerCase());
|
|
95
|
-
if (!relatedFeeStatus) return null;
|
|
96
|
-
return relatedFeeStatus.requiredAssets;
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
const createSelectors = _store => {
|
|
100
|
-
let store = _store;
|
|
101
|
-
store.use = {};
|
|
102
|
-
for (let k of Object.keys(store.getState())) {
|
|
103
|
-
store.use[k] = () => store(s => s[k]);
|
|
104
|
-
}
|
|
105
|
-
return store;
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
const httpService = /*#__PURE__*/new rangoSdk.RangoClient(process.env.REACT_APP_API_KEY);
|
|
109
|
-
|
|
110
|
-
const SLIPPAGES = [0.5, 1, 3, 5, 8, 13, 20];
|
|
111
|
-
const DEFAULT_SLIPPAGE = 1;
|
|
112
|
-
const HIGH_SLIPPAGE = 5;
|
|
113
|
-
const MAX_SLIPPAGE = 100;
|
|
114
|
-
const MIN_SLIPPGAE = 0;
|
|
115
|
-
|
|
116
|
-
const useMetaStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()(set => ({
|
|
117
|
-
meta: {
|
|
118
|
-
blockchains: [],
|
|
119
|
-
popularTokens: [],
|
|
120
|
-
swappers: [],
|
|
121
|
-
tokens: []
|
|
122
|
-
},
|
|
123
|
-
loadingStatus: 'loading',
|
|
124
|
-
fetchMeta: async () => {
|
|
125
|
-
try {
|
|
126
|
-
const response = await httpService.getAllMetadata();
|
|
127
|
-
const chainThatHasTokenInMetaResponse = removeDuplicateFrom(response.tokens.map(t => t.blockchain));
|
|
128
|
-
const enabledChains = response.blockchains.filter(chain => chain.enabled && chainThatHasTokenInMetaResponse.includes(chain.name));
|
|
129
|
-
response.blockchains = enabledChains.sort((a, b) => a.sort - b.sort);
|
|
130
|
-
set({
|
|
131
|
-
meta: response,
|
|
132
|
-
loadingStatus: 'success'
|
|
133
|
-
});
|
|
134
|
-
} catch (error) {
|
|
135
|
-
set({
|
|
136
|
-
loadingStatus: 'failed'
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
})));
|
|
141
|
-
|
|
142
|
-
const useSettingsStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/middleware.persist( /*#__PURE__*/middleware.subscribeWithSelector(set => ({
|
|
143
|
-
slippage: DEFAULT_SLIPPAGE,
|
|
144
|
-
customSlippage: null,
|
|
145
|
-
infiniteApprove: false,
|
|
146
|
-
disabledLiquiditySources: [],
|
|
147
|
-
theme: 'auto',
|
|
148
|
-
setSlippage: slippage => set(() => ({
|
|
149
|
-
slippage: slippage
|
|
150
|
-
})),
|
|
151
|
-
setCustomSlippage: customSlippage => set(() => ({
|
|
152
|
-
customSlippage: customSlippage
|
|
153
|
-
})),
|
|
154
|
-
toggleAllLiquiditySources: () => set(state => {
|
|
155
|
-
const {
|
|
156
|
-
swappers
|
|
157
|
-
} = useMetaStore.getState().meta;
|
|
158
|
-
const swappersGroup = removeDuplicateFrom(swappers.map(swapper => swapper.swapperGroup));
|
|
159
|
-
if (swappersGroup.length === state.disabledLiquiditySources.length) return {
|
|
160
|
-
disabledLiquiditySources: []
|
|
161
|
-
};else {
|
|
162
|
-
return {
|
|
163
|
-
disabledLiquiditySources: swappersGroup
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
}),
|
|
167
|
-
toggleInfiniteApprove: () => set(state => ({
|
|
168
|
-
infiniteApprove: !state.infiniteApprove
|
|
169
|
-
})),
|
|
170
|
-
toggleLiquiditySource: name => set(state => {
|
|
171
|
-
if (state.disabledLiquiditySources.includes(name)) return {
|
|
172
|
-
disabledLiquiditySources: state.disabledLiquiditySources.filter(liquiditySource => liquiditySource != name)
|
|
173
|
-
};else return {
|
|
174
|
-
disabledLiquiditySources: state.disabledLiquiditySources.concat(name)
|
|
175
|
-
};
|
|
176
|
-
}),
|
|
177
|
-
setTheme: theme => set(() => ({
|
|
178
|
-
theme
|
|
179
|
-
}))
|
|
180
|
-
})), {
|
|
181
|
-
name: 'user-settings'
|
|
182
|
-
})));
|
|
183
|
-
|
|
184
73
|
const secondsToString = s => {
|
|
185
74
|
const seconds = (s % 60).toString().padStart(2, '0');
|
|
186
75
|
const minutes = parseInt((s / 60).toString()).toString().padStart(2, '0');
|
|
@@ -239,15 +128,17 @@ function getlistWallet(getState, getWalletInfo, list) {
|
|
|
239
128
|
const {
|
|
240
129
|
name,
|
|
241
130
|
img: image,
|
|
242
|
-
installLink
|
|
131
|
+
installLink,
|
|
132
|
+
showOnMobile
|
|
243
133
|
} = getWalletInfo(type);
|
|
244
134
|
const state = getStateWallet(getState(type));
|
|
245
135
|
return {
|
|
246
136
|
name,
|
|
247
137
|
image,
|
|
248
|
-
installLink,
|
|
138
|
+
installLink: walletsShared.detectInstallLink(installLink),
|
|
249
139
|
state,
|
|
250
|
-
type
|
|
140
|
+
type,
|
|
141
|
+
showOnMobile: typeof showOnMobile === 'undefined' ? false : true
|
|
251
142
|
};
|
|
252
143
|
});
|
|
253
144
|
}
|
|
@@ -395,18 +286,12 @@ function numberWithThousandSeperator(number) {
|
|
|
395
286
|
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
|
396
287
|
return parts.join('.');
|
|
397
288
|
}
|
|
398
|
-
const
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
const compareBalance = (tokenA, tokenB, wallet) => {
|
|
405
|
-
if (!tokenA.usdPrice || !tokenB.usdPrice) return 0;
|
|
406
|
-
const tokenAUsdValue = new BigNumber__default(getBalanceFromWallet(wallet, tokenA.blockchain, tokenA.symbol, tokenA.address)?.amount || ZERO).multipliedBy(tokenA.usdPrice);
|
|
407
|
-
const tokenBUsdValue = new BigNumber__default(getBalanceFromWallet(wallet, tokenB.blockchain, tokenB.symbol, tokenB.address)?.amount || ZERO).multipliedBy(tokenB.usdPrice);
|
|
408
|
-
if (tokenAUsdValue.gt(tokenBUsdValue)) return -1;
|
|
409
|
-
return 1;
|
|
289
|
+
const sortTokens = tokens => {
|
|
290
|
+
let walletConnected = !!tokens.some(token => token.balance);
|
|
291
|
+
if (!walletConnected) {
|
|
292
|
+
return tokens.filter(token => !token.address).concat(tokens.filter(token => token.address && !token.isSecondaryCoin), tokens.filter(token => token.isSecondaryCoin));
|
|
293
|
+
}
|
|
294
|
+
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));
|
|
410
295
|
};
|
|
411
296
|
const getUsdPrice = (blockchain, symbol, address, allTokens) => {
|
|
412
297
|
const token = allTokens?.find(t => t.blockchain === blockchain && t.symbol?.toUpperCase() === symbol?.toUpperCase() && t.address === address);
|
|
@@ -423,6 +308,45 @@ const getKeplrCompatibleConnectedWallets = selectableWallets => {
|
|
|
423
308
|
const connectedWalletTypes = new Set(selectableWallets.map(a => a.walletType.toString()));
|
|
424
309
|
return walletsShared.KEPLR_COMPATIBLE_WALLETS.filter(compatibleWallet => connectedWalletTypes.has(compatibleWallet));
|
|
425
310
|
};
|
|
311
|
+
function getTokensWithBalance(tokens, balances) {
|
|
312
|
+
return tokens.map(_ref2 => {
|
|
313
|
+
let {
|
|
314
|
+
balance,
|
|
315
|
+
...otherProps
|
|
316
|
+
} = _ref2;
|
|
317
|
+
const tokenAmount = numberToString(new BigNumber__default(getBalanceFromWallet(balances, otherProps.blockchain, otherProps.symbol, otherProps.address)?.amount || ZERO));
|
|
318
|
+
let tokenUsdValue = '';
|
|
319
|
+
if (otherProps.usdPrice) tokenUsdValue = numberToString(new BigNumber__default(getBalanceFromWallet(balances, otherProps.blockchain, otherProps.symbol, otherProps.address)?.amount || ZERO).multipliedBy(otherProps.usdPrice));
|
|
320
|
+
return {
|
|
321
|
+
...otherProps,
|
|
322
|
+
...(tokenAmount !== '0' && {
|
|
323
|
+
balance: {
|
|
324
|
+
amount: tokenAmount,
|
|
325
|
+
usdValue: tokenUsdValue
|
|
326
|
+
}
|
|
327
|
+
})
|
|
328
|
+
};
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
function getSortedTokens(chain, tokens, balances, otherChainTokens) {
|
|
332
|
+
const fromChainEqueulsToToChain = chain?.name === otherChainTokens[0]?.name;
|
|
333
|
+
if (fromChainEqueulsToToChain) return otherChainTokens;
|
|
334
|
+
const filteredTokens = tokens.filter(token => token.blockchain === chain?.name);
|
|
335
|
+
return sortTokens(getTokensWithBalance(filteredTokens, balances));
|
|
336
|
+
}
|
|
337
|
+
function tokensAreEqual(tokenA, tokenB) {
|
|
338
|
+
return tokenA?.blockchain === tokenB?.blockchain && tokenA?.name === tokenB?.name && tokenA?.address === tokenB?.address;
|
|
339
|
+
}
|
|
340
|
+
function getDefaultToken(sortedTokens, otherToken) {
|
|
341
|
+
let selectedToken;
|
|
342
|
+
const firstToken = sortedTokens[0];
|
|
343
|
+
const secondToken = sortedTokens[1];
|
|
344
|
+
if (sortedTokens.length === 1) selectedToken = firstToken;else if (tokensAreEqual(firstToken, otherToken)) selectedToken = secondToken;else selectedToken = firstToken;
|
|
345
|
+
return selectedToken;
|
|
346
|
+
}
|
|
347
|
+
function sortWalletsBasedOnState(wallets) {
|
|
348
|
+
return wallets.sort((a, b) => Number(b.state === ui.WalletState.CONNECTED) - Number(a.state === ui.WalletState.CONNECTED) || Number(b.state === ui.WalletState.DISCONNECTED) - Number(a.state === ui.WalletState.DISCONNECTED));
|
|
349
|
+
}
|
|
426
350
|
|
|
427
351
|
function getOutputRatio(inputUsdValue, outputUsdValue) {
|
|
428
352
|
if (inputUsdValue.lte(ZERO) || outputUsdValue.lte(ZERO)) return 0;
|
|
@@ -590,10 +514,10 @@ function calculatePendingSwap(inputAmount, bestRoute, wallets, settings, validat
|
|
|
590
514
|
transferTransaction: null,
|
|
591
515
|
diagnosisUrl: null,
|
|
592
516
|
internalSteps: null,
|
|
593
|
-
fromBlockchainLogo: fromBlockchain
|
|
594
|
-
toBlockchainLogo: toBlockchain
|
|
595
|
-
swapperLogo: swapper?.logo,
|
|
596
|
-
swapperType: swapperType
|
|
517
|
+
fromBlockchainLogo: fromBlockchain?.logo || '',
|
|
518
|
+
toBlockchainLogo: toBlockchain?.logo || '',
|
|
519
|
+
swapperLogo: swapper?.logo || '',
|
|
520
|
+
swapperType: swapperType || ''
|
|
597
521
|
};
|
|
598
522
|
}) || []
|
|
599
523
|
};
|
|
@@ -637,7 +561,8 @@ function getMinRequiredSlippage(route) {
|
|
|
637
561
|
}
|
|
638
562
|
function hasProperSlippage(userSlippage, minRequiredSlippage) {
|
|
639
563
|
if (!minRequiredSlippage) return true;
|
|
640
|
-
|
|
564
|
+
//@ts-ignore
|
|
565
|
+
return parseFloat(userSlippage) >= parseFloat(minRequiredSlippage);
|
|
641
566
|
}
|
|
642
567
|
function createBestRouteRequestBody(fromToken, toToken, inputAmount, wallets, selectedWallets, disabledLiquiditySources, slippage, checkPrerequisites) {
|
|
643
568
|
const selectedWalletsMap = selectedWallets.reduce((selectedWalletsMap, selectedWallet) => (selectedWalletsMap[selectedWallet.chain] = selectedWallet.address, selectedWalletsMap), {});
|
|
@@ -679,9 +604,10 @@ function getWalletsForNewSwap(selectedWallets) {
|
|
|
679
604
|
return wallets;
|
|
680
605
|
}
|
|
681
606
|
function getRouteOutputAmount(route) {
|
|
682
|
-
return route
|
|
607
|
+
return route?.result?.outputAmount || null;
|
|
683
608
|
}
|
|
684
609
|
function getPercentageChange(oldValue, newValue) {
|
|
610
|
+
if (!oldValue || !newValue) return null;
|
|
685
611
|
return new BigNumber__default(newValue).div(new BigNumber__default(oldValue)).minus(1).multipliedBy(100);
|
|
686
612
|
}
|
|
687
613
|
function isOutputAmountChangedALot(oldRoute, newRoute) {
|
|
@@ -689,6 +615,7 @@ function isOutputAmountChangedALot(oldRoute, newRoute) {
|
|
|
689
615
|
const newOutputAmount = getRouteOutputAmount(newRoute);
|
|
690
616
|
if (!oldOutputAmount || !newOutputAmount) return false;
|
|
691
617
|
const percentageChange = getPercentageChange(oldOutputAmount, newOutputAmount);
|
|
618
|
+
if (!percentageChange) return true;
|
|
692
619
|
return percentageChange.toNumber() <= -1;
|
|
693
620
|
}
|
|
694
621
|
function getBalanceWarnings(route, selectedWallets) {
|
|
@@ -706,7 +633,242 @@ function getBalanceWarnings(route, selectedWallets) {
|
|
|
706
633
|
const warningMessage = `Needs ≈ ${requiredAmount} ${symbol}${reason}, but you have ${currentAmount} ${symbol} in your ${asset.asset.blockchain} wallet.`;
|
|
707
634
|
return warningMessage;
|
|
708
635
|
});
|
|
709
|
-
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
function searchParamsToToken(tokens, searchParams, chain) {
|
|
639
|
+
if (!chain) return null;
|
|
640
|
+
return tokens.find(token => {
|
|
641
|
+
const symbolAndAddress = searchParams?.split('--');
|
|
642
|
+
if (symbolAndAddress?.length === 1) return token.symbol === symbolAndAddress[0] && token.address === null && token.blockchain === chain.name;
|
|
643
|
+
return token.symbol === symbolAndAddress?.[0] && token.address === symbolAndAddress?.[1] && token.blockchain === chain.name;
|
|
644
|
+
}) || null;
|
|
645
|
+
}
|
|
646
|
+
function getBestRouteToTokenUsdPrice(bestRoute) {
|
|
647
|
+
return bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1].to.usdPrice;
|
|
648
|
+
}
|
|
649
|
+
function isNumberOfSwapsChanged(route1, route2) {
|
|
650
|
+
const route1Swaps = route1.result?.swaps || [];
|
|
651
|
+
const route2Swaps = route2.result?.swaps || [];
|
|
652
|
+
return route1Swaps.length !== route2Swaps.length;
|
|
653
|
+
}
|
|
654
|
+
function isRouteSwappersUpdated(route1, route2) {
|
|
655
|
+
const route1Swappers = route1.result?.swaps.map(swap => swap.swapperId) || [];
|
|
656
|
+
const route2Swappers = route2.result?.swaps.map(swap => swap.swapperId) || [];
|
|
657
|
+
return !areEqual(route1Swappers, route2Swappers);
|
|
658
|
+
}
|
|
659
|
+
function isRouteInternalCoinsUpdated(route1, route2) {
|
|
660
|
+
const route1InternalCoins = route1.result?.swaps.map(swap => swap.to.symbol) || [];
|
|
661
|
+
const route2InternalCoins = route2.result?.swaps.map(swap => swap.to.symbol) || [];
|
|
662
|
+
return !areEqual(route1InternalCoins, route2InternalCoins);
|
|
663
|
+
}
|
|
664
|
+
function isRouteChanged(route1, route2) {
|
|
665
|
+
return isNumberOfSwapsChanged(route1, route2) || isRouteSwappersUpdated(route1, route2) || isRouteInternalCoinsUpdated(route1, route2);
|
|
666
|
+
}
|
|
667
|
+
function getRequiredBalanceOfWallet(selectedWallet, fee) {
|
|
668
|
+
if (fee === null) return null;
|
|
669
|
+
const relatedFeeStatus = fee?.find(item => item.blockchain === selectedWallet.chain)?.wallets.find(wallet => wallet.address?.toLowerCase() === selectedWallet.address.toLowerCase());
|
|
670
|
+
if (!relatedFeeStatus) return null;
|
|
671
|
+
return relatedFeeStatus.requiredAssets;
|
|
672
|
+
}
|
|
673
|
+
function isRouteParametersChanged(prevParams, currentParams) {
|
|
674
|
+
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;
|
|
675
|
+
}
|
|
676
|
+
function getBestRouteWithCalculatedFees(bestRoute, tokens) {
|
|
677
|
+
if (!bestRoute || !bestRoute.result) return null;
|
|
678
|
+
const swapsWithFee = (bestRoute?.result?.swaps || []).map(swap => ({
|
|
679
|
+
...swap,
|
|
680
|
+
feeInUsd: numberToString(getUsdFeeOfStep(swap, tokens), 0, 2)
|
|
681
|
+
}));
|
|
682
|
+
return {
|
|
683
|
+
...bestRoute,
|
|
684
|
+
result: {
|
|
685
|
+
...bestRoute.result,
|
|
686
|
+
swaps: swapsWithFee
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
const createSelectors = _store => {
|
|
692
|
+
let store = _store;
|
|
693
|
+
store.use = {};
|
|
694
|
+
for (let k of Object.keys(store.getState())) {
|
|
695
|
+
store.use[k] = () => store(s => s[k]);
|
|
696
|
+
}
|
|
697
|
+
return store;
|
|
698
|
+
};
|
|
699
|
+
|
|
700
|
+
const httpService = /*#__PURE__*/new rangoSdk.RangoClient(process.env.REACT_APP_API_KEY);
|
|
701
|
+
|
|
702
|
+
const SLIPPAGES = [0.5, 1, 3, 5, 8, 13, 20];
|
|
703
|
+
const DEFAULT_SLIPPAGE = 1;
|
|
704
|
+
const HIGH_SLIPPAGE = 5;
|
|
705
|
+
const MAX_SLIPPAGE = 100;
|
|
706
|
+
const MIN_SLIPPGAE = 0;
|
|
707
|
+
|
|
708
|
+
const useMetaStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()(set => ({
|
|
709
|
+
meta: {
|
|
710
|
+
blockchains: [],
|
|
711
|
+
popularTokens: [],
|
|
712
|
+
swappers: [],
|
|
713
|
+
tokens: []
|
|
714
|
+
},
|
|
715
|
+
loadingStatus: 'loading',
|
|
716
|
+
fetchMeta: async () => {
|
|
717
|
+
try {
|
|
718
|
+
const response = await httpService.getAllMetadata();
|
|
719
|
+
const chainThatHasTokenInMetaResponse = removeDuplicateFrom(response.tokens.map(t => t.blockchain));
|
|
720
|
+
const enabledChains = response.blockchains.filter(chain => chain.enabled && chainThatHasTokenInMetaResponse.includes(chain.name));
|
|
721
|
+
response.blockchains = enabledChains.sort((a, b) => a.sort - b.sort);
|
|
722
|
+
set({
|
|
723
|
+
meta: response,
|
|
724
|
+
loadingStatus: 'success'
|
|
725
|
+
});
|
|
726
|
+
} catch (error) {
|
|
727
|
+
set({
|
|
728
|
+
loadingStatus: 'failed'
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
})));
|
|
733
|
+
|
|
734
|
+
const useSettingsStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/middleware.persist( /*#__PURE__*/middleware.subscribeWithSelector(set => ({
|
|
735
|
+
slippage: DEFAULT_SLIPPAGE,
|
|
736
|
+
customSlippage: null,
|
|
737
|
+
infiniteApprove: false,
|
|
738
|
+
disabledLiquiditySources: [],
|
|
739
|
+
theme: 'auto',
|
|
740
|
+
setSlippage: slippage => set(() => ({
|
|
741
|
+
slippage: slippage
|
|
742
|
+
})),
|
|
743
|
+
setCustomSlippage: customSlippage => set(() => ({
|
|
744
|
+
customSlippage: customSlippage
|
|
745
|
+
})),
|
|
746
|
+
toggleAllLiquiditySources: () => set(state => {
|
|
747
|
+
const {
|
|
748
|
+
swappers
|
|
749
|
+
} = useMetaStore.getState().meta;
|
|
750
|
+
const swappersGroup = removeDuplicateFrom(swappers.map(swapper => swapper.swapperGroup));
|
|
751
|
+
if (swappersGroup.length === state.disabledLiquiditySources.length) return {
|
|
752
|
+
disabledLiquiditySources: []
|
|
753
|
+
};else {
|
|
754
|
+
return {
|
|
755
|
+
disabledLiquiditySources: swappersGroup
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
}),
|
|
759
|
+
toggleInfiniteApprove: () => set(state => ({
|
|
760
|
+
infiniteApprove: !state.infiniteApprove
|
|
761
|
+
})),
|
|
762
|
+
toggleLiquiditySource: name => set(state => {
|
|
763
|
+
if (state.disabledLiquiditySources.includes(name)) return {
|
|
764
|
+
disabledLiquiditySources: state.disabledLiquiditySources.filter(liquiditySource => liquiditySource != name)
|
|
765
|
+
};else return {
|
|
766
|
+
disabledLiquiditySources: state.disabledLiquiditySources.concat(name)
|
|
767
|
+
};
|
|
768
|
+
}),
|
|
769
|
+
setTheme: theme => set(() => ({
|
|
770
|
+
theme
|
|
771
|
+
}))
|
|
772
|
+
})), {
|
|
773
|
+
name: 'user-settings'
|
|
774
|
+
})));
|
|
775
|
+
|
|
776
|
+
const useWalletsStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/middleware.subscribeWithSelector(set => ({
|
|
777
|
+
accounts: [],
|
|
778
|
+
balances: [],
|
|
779
|
+
selectedWallets: [],
|
|
780
|
+
connectWallet: accounts => {
|
|
781
|
+
const tokens = useMetaStore.getState().meta.tokens;
|
|
782
|
+
set(state => ({
|
|
783
|
+
accounts: state.accounts.concat(accounts),
|
|
784
|
+
balances: state.balances.concat(accounts.map(account => ({
|
|
785
|
+
balances: [],
|
|
786
|
+
address: account.address,
|
|
787
|
+
chain: account.chain,
|
|
788
|
+
loading: true,
|
|
789
|
+
walletType: account.walletType,
|
|
790
|
+
error: false,
|
|
791
|
+
explorerUrl: null
|
|
792
|
+
})))
|
|
793
|
+
}));
|
|
794
|
+
accounts.forEach(async account => {
|
|
795
|
+
try {
|
|
796
|
+
const response = await httpService.getWalletsDetails([{
|
|
797
|
+
address: account.address,
|
|
798
|
+
blockchain: account.chain
|
|
799
|
+
}]);
|
|
800
|
+
const retrivedBalance = response.wallets[0];
|
|
801
|
+
if (retrivedBalance) {
|
|
802
|
+
set(state => ({
|
|
803
|
+
balances: state.balances.map(balance => {
|
|
804
|
+
return isAccountAndBalanceMatched(account, balance) ? makeBalanceFor(account, retrivedBalance, tokens) : balance;
|
|
805
|
+
})
|
|
806
|
+
}));
|
|
807
|
+
} else throw new Error('Wallet not found');
|
|
808
|
+
} catch (error) {
|
|
809
|
+
set(state => ({
|
|
810
|
+
balances: state.balances.map(balance => {
|
|
811
|
+
return isAccountAndBalanceMatched(account, balance) ? resetBalanceState(balance) : balance;
|
|
812
|
+
})
|
|
813
|
+
}));
|
|
814
|
+
}
|
|
815
|
+
});
|
|
816
|
+
},
|
|
817
|
+
disconnectWallet: walletType => {
|
|
818
|
+
set(state => ({
|
|
819
|
+
accounts: state.accounts.filter(account => account.walletType !== walletType),
|
|
820
|
+
balances: state.balances.filter(balance => balance.walletType !== walletType),
|
|
821
|
+
selectedWallets: state.selectedWallets.filter(wallet => wallet.walletType != walletType)
|
|
822
|
+
}));
|
|
823
|
+
},
|
|
824
|
+
initSelectedWallets: () => set(state => {
|
|
825
|
+
const requiredChains = getRequiredChains(useBestRouteStore.getState().bestRoute);
|
|
826
|
+
const connectedWallets = state.accounts;
|
|
827
|
+
const selectedWallets = [];
|
|
828
|
+
requiredChains.forEach(chain => {
|
|
829
|
+
const anyWalletSelected = !!state.selectedWallets.find(wallet => wallet.chain === chain);
|
|
830
|
+
if (!anyWalletSelected) {
|
|
831
|
+
const firstWalletWithMatchedChain = connectedWallets.find(wallet => wallet.chain === chain);
|
|
832
|
+
if (!!firstWalletWithMatchedChain) selectedWallets.push({
|
|
833
|
+
address: firstWalletWithMatchedChain.address,
|
|
834
|
+
chain: firstWalletWithMatchedChain.chain,
|
|
835
|
+
walletType: firstWalletWithMatchedChain.walletType
|
|
836
|
+
});
|
|
837
|
+
}
|
|
838
|
+
});
|
|
839
|
+
return {
|
|
840
|
+
selectedWallets: state.selectedWallets.concat(selectedWallets)
|
|
841
|
+
};
|
|
842
|
+
}),
|
|
843
|
+
setSelectedWallet: wallet => set(state => ({
|
|
844
|
+
selectedWallets: state.selectedWallets.filter(selectedWallet => selectedWallet.chain !== wallet.chain).concat({
|
|
845
|
+
chain: wallet.chain,
|
|
846
|
+
address: wallet.address,
|
|
847
|
+
walletType: wallet.walletType
|
|
848
|
+
})
|
|
849
|
+
})),
|
|
850
|
+
clearConnectedWallet: () => set(() => ({
|
|
851
|
+
accounts: [],
|
|
852
|
+
balances: [],
|
|
853
|
+
selectedWallets: []
|
|
854
|
+
}))
|
|
855
|
+
}))));
|
|
856
|
+
useWalletsStore.subscribe(state => state.balances, balances => {
|
|
857
|
+
useBestRouteStore.setState(_ref => {
|
|
858
|
+
let {
|
|
859
|
+
sourceTokens,
|
|
860
|
+
destinationTokens
|
|
861
|
+
} = _ref;
|
|
862
|
+
const sourceTokensWithBalance = getTokensWithBalance(sourceTokens, balances);
|
|
863
|
+
const destinationTokensWithBalance = getTokensWithBalance(destinationTokens, balances);
|
|
864
|
+
return {
|
|
865
|
+
sourceTokens: sortTokens(sourceTokensWithBalance),
|
|
866
|
+
destinationTokens: sortTokens(destinationTokensWithBalance)
|
|
867
|
+
};
|
|
868
|
+
});
|
|
869
|
+
}, {
|
|
870
|
+
equalityFn: shallow.shallow
|
|
871
|
+
});
|
|
710
872
|
|
|
711
873
|
const getUsdValue = (token, amount) => new BigNumber__default(amount || ZERO).multipliedBy(token?.usdPrice || 0);
|
|
712
874
|
const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/middleware.subscribeWithSelector(set => ({
|
|
@@ -721,6 +883,8 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.cre
|
|
|
721
883
|
bestRoute: null,
|
|
722
884
|
loading: false,
|
|
723
885
|
error: '',
|
|
886
|
+
sourceTokens: [],
|
|
887
|
+
destinationTokens: [],
|
|
724
888
|
setBestRoute: bestRoute => set(state => {
|
|
725
889
|
let outputAmount = null;
|
|
726
890
|
let outputUsdValue = ZERO;
|
|
@@ -736,27 +900,62 @@ const useBestRouteStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.cre
|
|
|
736
900
|
})
|
|
737
901
|
};
|
|
738
902
|
}),
|
|
739
|
-
setFromChain: chain
|
|
740
|
-
|
|
741
|
-
|
|
903
|
+
setFromChain: (chain, setDefaultToken) => {
|
|
904
|
+
set(state => {
|
|
905
|
+
if (state.fromChain?.name === chain?.name) return {};
|
|
906
|
+
const tokens = useMetaStore.getState().meta.tokens;
|
|
907
|
+
const balances = useWalletsStore.getState().balances;
|
|
908
|
+
const sortedTokens = getSortedTokens(chain, tokens, balances, state.destinationTokens);
|
|
909
|
+
const fromToken = getDefaultToken(sortedTokens, state.toToken);
|
|
910
|
+
return {
|
|
911
|
+
fromChain: chain,
|
|
912
|
+
sourceTokens: sortedTokens,
|
|
913
|
+
...(setDefaultToken && {
|
|
914
|
+
fromToken
|
|
915
|
+
}),
|
|
916
|
+
...(!!state.inputAmount && {
|
|
917
|
+
inputUsdValue: getUsdValue(fromToken, state.inputAmount)
|
|
918
|
+
})
|
|
919
|
+
};
|
|
920
|
+
});
|
|
921
|
+
},
|
|
742
922
|
setFromToken: token => set(state => ({
|
|
743
923
|
fromToken: token,
|
|
744
924
|
...(!!state.inputAmount && {
|
|
745
925
|
inputUsdValue: getUsdValue(token, state.inputAmount)
|
|
746
926
|
})
|
|
747
927
|
})),
|
|
748
|
-
setToChain: chain
|
|
749
|
-
|
|
750
|
-
|
|
928
|
+
setToChain: (chain, setDefaultToken) => {
|
|
929
|
+
set(state => {
|
|
930
|
+
if (state.toChain?.name === chain?.name) return {};
|
|
931
|
+
const tokens = useMetaStore.getState().meta.tokens;
|
|
932
|
+
const balances = useWalletsStore.getState().balances;
|
|
933
|
+
const sortedTokens = getSortedTokens(chain, tokens, balances, state.destinationTokens);
|
|
934
|
+
return {
|
|
935
|
+
toChain: chain,
|
|
936
|
+
destinationTokens: sortedTokens,
|
|
937
|
+
...(setDefaultToken && {
|
|
938
|
+
toToken: getDefaultToken(sortedTokens, state.fromToken)
|
|
939
|
+
})
|
|
940
|
+
};
|
|
941
|
+
});
|
|
942
|
+
},
|
|
751
943
|
setToToken: token => set(() => ({
|
|
752
944
|
toToken: token
|
|
753
945
|
})),
|
|
754
|
-
setInputAmount: amount =>
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
946
|
+
setInputAmount: amount => {
|
|
947
|
+
set(state => ({
|
|
948
|
+
inputAmount: amount,
|
|
949
|
+
...(!amount && {
|
|
950
|
+
outputAmount: new BigNumber__default(0),
|
|
951
|
+
outputUsdValue: new BigNumber__default(0),
|
|
952
|
+
bestRoute: null
|
|
953
|
+
}),
|
|
954
|
+
...(!!state.fromToken && {
|
|
955
|
+
inputUsdValue: getUsdValue(state.fromToken, amount)
|
|
956
|
+
})
|
|
957
|
+
}));
|
|
958
|
+
}
|
|
760
959
|
}))));
|
|
761
960
|
const bestRoute = (bestRouteStore, settingsStore) => {
|
|
762
961
|
let abortController = null;
|
|
@@ -774,11 +973,13 @@ const bestRoute = (bestRouteStore, settingsStore) => {
|
|
|
774
973
|
if (!fromToken || !toToken || !inputAmount) return;
|
|
775
974
|
abortController?.abort();
|
|
776
975
|
abortController = new AbortController();
|
|
777
|
-
const userSlippage = customSlippage
|
|
976
|
+
const userSlippage = !!customSlippage ? customSlippage : slippage;
|
|
778
977
|
const requestBody = createBestRouteRequestBody(fromToken, toToken, inputAmount, [], [], disabledLiquiditySources, userSlippage, false);
|
|
779
978
|
bestRouteStore.setState({
|
|
780
979
|
loading: true,
|
|
781
|
-
bestRoute: null
|
|
980
|
+
bestRoute: null,
|
|
981
|
+
outputAmount: null,
|
|
982
|
+
outputUsdValue: new BigNumber__default(0)
|
|
782
983
|
});
|
|
783
984
|
httpService.getBestRoute(requestBody, {
|
|
784
985
|
signal: abortController.signal
|
|
@@ -807,7 +1008,7 @@ const bestRoute = (bestRouteStore, settingsStore) => {
|
|
|
807
1008
|
inputAmount: state.inputAmount
|
|
808
1009
|
}), fetchBestRoute.bind(null), {
|
|
809
1010
|
equalityFn: (prevState, state) => {
|
|
810
|
-
if (prevState
|
|
1011
|
+
if (isRouteParametersChanged(prevState, state)) return false;else return true;
|
|
811
1012
|
}
|
|
812
1013
|
});
|
|
813
1014
|
useSettingsStore.subscribe(state => ({
|
|
@@ -816,7 +1017,7 @@ const bestRoute = (bestRouteStore, settingsStore) => {
|
|
|
816
1017
|
disabledLiquiditySources: state.disabledLiquiditySources
|
|
817
1018
|
}), fetchBestRoute.bind(null), {
|
|
818
1019
|
equalityFn: (prevState, state) => {
|
|
819
|
-
if (prevState
|
|
1020
|
+
if (isRouteParametersChanged(prevState, state)) return false;else return true;
|
|
820
1021
|
}
|
|
821
1022
|
});
|
|
822
1023
|
return {
|
|
@@ -847,13 +1048,6 @@ const useUiStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()(s
|
|
|
847
1048
|
})
|
|
848
1049
|
})));
|
|
849
1050
|
|
|
850
|
-
function searchParamsToToken(tokens, searchParams) {
|
|
851
|
-
return tokens.find(token => {
|
|
852
|
-
const symbolAndAddress = searchParams?.split('--');
|
|
853
|
-
if (symbolAndAddress?.length === 1) return token.symbol === symbolAndAddress[0] && token.address === null;
|
|
854
|
-
return token.symbol === symbolAndAddress?.[0] && token.address === symbolAndAddress?.[1];
|
|
855
|
-
}) || null;
|
|
856
|
-
}
|
|
857
1051
|
function UpdateUrl() {
|
|
858
1052
|
const firstRender = React.useRef(true);
|
|
859
1053
|
const [searchParams, setSearchParams] = reactRouterDom.useSearchParams();
|
|
@@ -961,15 +1155,15 @@ function UpdateUrl() {
|
|
|
961
1155
|
}, [location.pathname, inputAmount]);
|
|
962
1156
|
React.useEffect(() => {
|
|
963
1157
|
if (loadingStatus === 'success') {
|
|
964
|
-
const
|
|
1158
|
+
const fromChainString = searchParams.get(SearchParams.FROM_CHAIN);
|
|
965
1159
|
const fromTokenString = searchParams.get(SearchParams.FROM_TOKEN);
|
|
966
1160
|
const toChainString = searchParams.get(SearchParams.TO_CHAIN);
|
|
967
1161
|
const toTokenString = searchParams.get(SearchParams.TO_TOKEN);
|
|
968
1162
|
const fromAmount = searchParams.get(SearchParams.FROM_AMOUNT);
|
|
969
|
-
const fromChain = blockchains.find(blockchain => blockchain.name ===
|
|
970
|
-
const fromToken = searchParamsToToken(tokens, fromTokenString);
|
|
1163
|
+
const fromChain = blockchains.find(blockchain => blockchain.name === fromChainString);
|
|
1164
|
+
const fromToken = searchParamsToToken(tokens, fromTokenString, fromChain || null);
|
|
971
1165
|
const toChain = blockchains.find(blockchain => blockchain.name === toChainString);
|
|
972
|
-
const toToken = searchParamsToToken(tokens, toTokenString);
|
|
1166
|
+
const toToken = searchParamsToToken(tokens, toTokenString, toChain || null);
|
|
973
1167
|
if (!!fromChain) {
|
|
974
1168
|
setFromChain(fromChain);
|
|
975
1169
|
if (!!fromToken) setFromToken(fromToken);
|
|
@@ -1040,92 +1234,11 @@ function Header(props) {
|
|
|
1040
1234
|
return React__default.createElement(HeaderContainer, null, React__default.createElement(ui.Typography, {
|
|
1041
1235
|
variant: "h4",
|
|
1042
1236
|
className: titleStyle()
|
|
1043
|
-
}, t(title.toLocaleLowerCase())
|
|
1237
|
+
}, title ? t(title.toLocaleLowerCase()) : ''), React__default.createElement(HeaderButtons, {
|
|
1044
1238
|
onClickRefresh: onClickRefresh
|
|
1045
1239
|
}));
|
|
1046
1240
|
}
|
|
1047
1241
|
|
|
1048
|
-
const useWalletsStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/middleware.subscribeWithSelector(set => ({
|
|
1049
|
-
accounts: [],
|
|
1050
|
-
balances: [],
|
|
1051
|
-
selectedWallets: [],
|
|
1052
|
-
connectWallet: accounts => {
|
|
1053
|
-
const tokens = useMetaStore.getState().meta.tokens;
|
|
1054
|
-
set(state => ({
|
|
1055
|
-
accounts: state.accounts.concat(accounts),
|
|
1056
|
-
balances: state.balances.concat(accounts.map(account => ({
|
|
1057
|
-
balances: [],
|
|
1058
|
-
address: account.address,
|
|
1059
|
-
chain: account.chain,
|
|
1060
|
-
loading: true,
|
|
1061
|
-
walletType: account.walletType,
|
|
1062
|
-
error: false,
|
|
1063
|
-
explorerUrl: null
|
|
1064
|
-
})))
|
|
1065
|
-
}));
|
|
1066
|
-
accounts.forEach(async account => {
|
|
1067
|
-
try {
|
|
1068
|
-
const response = await httpService.getWalletsDetails([{
|
|
1069
|
-
address: account.address,
|
|
1070
|
-
blockchain: account.chain
|
|
1071
|
-
}]);
|
|
1072
|
-
const retrivedBalance = response.wallets[0];
|
|
1073
|
-
if (retrivedBalance) {
|
|
1074
|
-
set(state => ({
|
|
1075
|
-
balances: state.balances.map(balance => {
|
|
1076
|
-
return isAccountAndBalanceMatched(account, balance) ? makeBalanceFor(account, retrivedBalance, tokens) : balance;
|
|
1077
|
-
})
|
|
1078
|
-
}));
|
|
1079
|
-
} else throw new Error('Wallet not found');
|
|
1080
|
-
} catch (error) {
|
|
1081
|
-
set(state => ({
|
|
1082
|
-
balances: state.balances.map(balance => {
|
|
1083
|
-
return isAccountAndBalanceMatched(account, balance) ? resetBalanceState(balance) : balance;
|
|
1084
|
-
})
|
|
1085
|
-
}));
|
|
1086
|
-
}
|
|
1087
|
-
});
|
|
1088
|
-
},
|
|
1089
|
-
disconnectWallet: walletType => {
|
|
1090
|
-
set(state => ({
|
|
1091
|
-
accounts: state.accounts.filter(account => account.walletType !== walletType),
|
|
1092
|
-
balances: state.balances.filter(balance => balance.walletType !== walletType),
|
|
1093
|
-
selectedWallets: state.selectedWallets.filter(wallet => wallet.walletType != walletType)
|
|
1094
|
-
}));
|
|
1095
|
-
},
|
|
1096
|
-
initSelectedWallets: () => set(state => {
|
|
1097
|
-
const requiredChains = getRequiredChains(useBestRouteStore.getState().bestRoute);
|
|
1098
|
-
const connectedWallets = state.accounts;
|
|
1099
|
-
const selectedWallets = [];
|
|
1100
|
-
requiredChains.forEach(chain => {
|
|
1101
|
-
const anyWalletSelected = !!state.selectedWallets.find(wallet => wallet.chain === chain);
|
|
1102
|
-
if (!anyWalletSelected) {
|
|
1103
|
-
const firstWalletWithMatchedChain = connectedWallets.find(wallet => wallet.chain === chain);
|
|
1104
|
-
if (!!firstWalletWithMatchedChain) selectedWallets.push({
|
|
1105
|
-
address: firstWalletWithMatchedChain.address,
|
|
1106
|
-
chain: firstWalletWithMatchedChain.chain,
|
|
1107
|
-
walletType: firstWalletWithMatchedChain.walletType
|
|
1108
|
-
});
|
|
1109
|
-
}
|
|
1110
|
-
});
|
|
1111
|
-
return {
|
|
1112
|
-
selectedWallets: state.selectedWallets.concat(selectedWallets)
|
|
1113
|
-
};
|
|
1114
|
-
}),
|
|
1115
|
-
setSelectedWallet: wallet => set(state => ({
|
|
1116
|
-
selectedWallets: state.selectedWallets.filter(selectedWallet => selectedWallet.chain !== wallet.chain).concat({
|
|
1117
|
-
chain: wallet.chain,
|
|
1118
|
-
address: wallet.address,
|
|
1119
|
-
walletType: wallet.walletType
|
|
1120
|
-
})
|
|
1121
|
-
})),
|
|
1122
|
-
clearConnectedWallet: () => set(() => ({
|
|
1123
|
-
accounts: [],
|
|
1124
|
-
balances: [],
|
|
1125
|
-
selectedWallets: []
|
|
1126
|
-
}))
|
|
1127
|
-
}))));
|
|
1128
|
-
|
|
1129
1242
|
const Box = /*#__PURE__*/ui.styled('div', {
|
|
1130
1243
|
display: 'flex',
|
|
1131
1244
|
flexDirection: 'column',
|
|
@@ -1543,7 +1656,7 @@ function ChangeSlippageButton() {
|
|
|
1543
1656
|
type: "primary",
|
|
1544
1657
|
variant: "contained",
|
|
1545
1658
|
size: "small",
|
|
1546
|
-
onClick: navigate
|
|
1659
|
+
onClick: () => navigate(navigationRoutes.settings)
|
|
1547
1660
|
}, "Change Slippage");
|
|
1548
1661
|
}
|
|
1549
1662
|
|
|
@@ -1555,7 +1668,7 @@ function HighSlippageWarning(props) {
|
|
|
1555
1668
|
type: "warning"
|
|
1556
1669
|
}, React__default.createElement(ui.Typography, {
|
|
1557
1670
|
variant: "body2"
|
|
1558
|
-
}, "
|
|
1671
|
+
}, "Caution, your slippage is high (=", selectedSlippage, "). Your trade may be front run.", React__default.createElement(ChangeSlippageButton, null)));
|
|
1559
1672
|
}
|
|
1560
1673
|
|
|
1561
1674
|
function ConfirmSwapExtraMessages(props) {
|
|
@@ -1589,12 +1702,6 @@ function useNavigateBack() {
|
|
|
1589
1702
|
};
|
|
1590
1703
|
}
|
|
1591
1704
|
|
|
1592
|
-
const useConfirmSwapStore = /*#__PURE__*/createSelectors( /*#__PURE__*/zustand.create()( /*#__PURE__*/middleware.subscribeWithSelector(() => ({
|
|
1593
|
-
loading: false,
|
|
1594
|
-
errors: [],
|
|
1595
|
-
warnings: [],
|
|
1596
|
-
proceedAnyway: false
|
|
1597
|
-
}))));
|
|
1598
1705
|
var ConfirmSwapErrorTypes;
|
|
1599
1706
|
(function (ConfirmSwapErrorTypes) {
|
|
1600
1707
|
ConfirmSwapErrorTypes[ConfirmSwapErrorTypes["NO_ROUTE"] = 0] = "NO_ROUTE";
|
|
@@ -1610,161 +1717,6 @@ var ConfirmSwapWarningTypes;
|
|
|
1610
1717
|
ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["ROUTE_AND_OUTPUT_AMOUNT_UPDATED"] = 3] = "ROUTE_AND_OUTPUT_AMOUNT_UPDATED";
|
|
1611
1718
|
ConfirmSwapWarningTypes[ConfirmSwapWarningTypes["INSUFFICIENT_BALANCE"] = 4] = "INSUFFICIENT_BALANCE";
|
|
1612
1719
|
})(ConfirmSwapWarningTypes || (ConfirmSwapWarningTypes = {}));
|
|
1613
|
-
const confirmSwap = async () => {
|
|
1614
|
-
const {
|
|
1615
|
-
fromToken,
|
|
1616
|
-
toToken,
|
|
1617
|
-
inputAmount,
|
|
1618
|
-
bestRoute: initialRoute,
|
|
1619
|
-
inputUsdValue,
|
|
1620
|
-
setBestRoute
|
|
1621
|
-
} = useBestRouteStore.getState();
|
|
1622
|
-
const {
|
|
1623
|
-
accounts,
|
|
1624
|
-
selectedWallets
|
|
1625
|
-
} = useWalletsStore.getState();
|
|
1626
|
-
const {
|
|
1627
|
-
proceedAnyway
|
|
1628
|
-
} = useConfirmSwapStore.getState();
|
|
1629
|
-
const {
|
|
1630
|
-
disabledLiquiditySources,
|
|
1631
|
-
slippage,
|
|
1632
|
-
customSlippage
|
|
1633
|
-
} = useSettingsStore.getState();
|
|
1634
|
-
const {
|
|
1635
|
-
meta
|
|
1636
|
-
} = useMetaStore.getState();
|
|
1637
|
-
const userSlippage = customSlippage || slippage;
|
|
1638
|
-
if (!fromToken || !toToken || !inputAmount || !initialRoute) return undefined;
|
|
1639
|
-
if (proceedAnyway) {
|
|
1640
|
-
const swapSettings = {
|
|
1641
|
-
slippage: userSlippage.toString(),
|
|
1642
|
-
disabledSwappersGroups: disabledLiquiditySources
|
|
1643
|
-
};
|
|
1644
|
-
const newSwap = calculatePendingSwap(inputAmount.toString(), initialRoute, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
|
|
1645
|
-
console.log('new swap:', newSwap);
|
|
1646
|
-
// queueManager?.create('swap', { swapDetails: newSwap });
|
|
1647
|
-
useConfirmSwapStore.setState({
|
|
1648
|
-
errors: [],
|
|
1649
|
-
warnings: [],
|
|
1650
|
-
proceedAnyway: false
|
|
1651
|
-
});
|
|
1652
|
-
return newSwap;
|
|
1653
|
-
}
|
|
1654
|
-
let abortController = new AbortController();
|
|
1655
|
-
useConfirmSwapStore.setState({
|
|
1656
|
-
loading: true
|
|
1657
|
-
});
|
|
1658
|
-
const requestBody = createBestRouteRequestBody(fromToken, toToken, inputAmount, accounts, selectedWallets, disabledLiquiditySources, userSlippage, true);
|
|
1659
|
-
const unsubscribeFromBestRouteStore = useBestRouteStore.subscribe(state => state.bestRoute, () => {
|
|
1660
|
-
abortController.abort();
|
|
1661
|
-
}, {
|
|
1662
|
-
equalityFn: shallow.shallow
|
|
1663
|
-
});
|
|
1664
|
-
const unsubscribeFromWalletsStore = useWalletsStore.subscribe(state => state.selectedWallets, () => {
|
|
1665
|
-
abortController?.abort();
|
|
1666
|
-
}, {
|
|
1667
|
-
equalityFn: (prevState, state) => {
|
|
1668
|
-
const selectedWalletsChanged = !state.every(wallet => !!prevState.find(prevWallet => wallet.address === prevWallet.address && wallet.chain === prevWallet.chain));
|
|
1669
|
-
if (selectedWalletsChanged) return false;else return true;
|
|
1670
|
-
}
|
|
1671
|
-
});
|
|
1672
|
-
const newSwap = await httpService.getBestRoute(requestBody, {
|
|
1673
|
-
signal: abortController.signal
|
|
1674
|
-
}).then(confiremedRoute => {
|
|
1675
|
-
useConfirmSwapStore.setState({
|
|
1676
|
-
loading: false
|
|
1677
|
-
});
|
|
1678
|
-
if (!confiremedRoute.result || !new BigNumber__default(confiremedRoute.requestAmount).isEqualTo(new BigNumber__default(inputAmount || '-1'))) {
|
|
1679
|
-
useConfirmSwapStore.setState(prevState => ({
|
|
1680
|
-
errors: prevState.errors.concat({
|
|
1681
|
-
type: ConfirmSwapErrorTypes.NO_ROUTE
|
|
1682
|
-
})
|
|
1683
|
-
}));
|
|
1684
|
-
return undefined;
|
|
1685
|
-
}
|
|
1686
|
-
const confirmSwap = {
|
|
1687
|
-
loading: false,
|
|
1688
|
-
errors: [],
|
|
1689
|
-
warnings: [],
|
|
1690
|
-
proceedAnyway
|
|
1691
|
-
};
|
|
1692
|
-
const routeChanged = isRouteChanged(initialRoute, confiremedRoute);
|
|
1693
|
-
if (routeChanged) {
|
|
1694
|
-
setBestRoute(confiremedRoute);
|
|
1695
|
-
const newRouteOutputUsdValue = new BigNumber__default(confiremedRoute.result?.outputAmount || '0').multipliedBy(toToken.usdPrice || 0);
|
|
1696
|
-
const outputRatio = getOutputRatio(inputUsdValue, newRouteOutputUsdValue);
|
|
1697
|
-
const highValueLoss = outputRatioHasWarning(inputUsdValue, outputRatio);
|
|
1698
|
-
if (isNumberOfSwapsChanged(initialRoute, confiremedRoute)) confirmSwap.warnings.push({
|
|
1699
|
-
type: ConfirmSwapWarningTypes.ROUTE_UPDATED
|
|
1700
|
-
});else if (isRouteSwappersUpdated(initialRoute, confiremedRoute)) confirmSwap.warnings.push({
|
|
1701
|
-
type: ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED
|
|
1702
|
-
});else isRouteInternalCoinsUpdated(initialRoute, confiremedRoute);
|
|
1703
|
-
confirmSwap.warnings.push({
|
|
1704
|
-
type: ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED
|
|
1705
|
-
});
|
|
1706
|
-
if (highValueLoss) confirmSwap.errors.push({
|
|
1707
|
-
type: ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS
|
|
1708
|
-
});else if (isOutputAmountChangedALot(initialRoute, confiremedRoute)) confirmSwap.warnings.push({
|
|
1709
|
-
type: ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED,
|
|
1710
|
-
newOutputAmount: numberToString(getRouteOutputAmount(confiremedRoute)),
|
|
1711
|
-
percentageChange: numberToString(getPercentageChange(getRouteOutputAmount(initialRoute), getRouteOutputAmount(confiremedRoute)), null, 2)
|
|
1712
|
-
});
|
|
1713
|
-
}
|
|
1714
|
-
const balanceWarnings = getBalanceWarnings(confiremedRoute, selectedWallets);
|
|
1715
|
-
const enoughBalance = balanceWarnings.length === 0;
|
|
1716
|
-
if (!enoughBalance) confirmSwap.warnings.push({
|
|
1717
|
-
type: ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE,
|
|
1718
|
-
messages: balanceWarnings
|
|
1719
|
-
});
|
|
1720
|
-
const minRequiredSlippage = getMinRequiredSlippage(initialRoute);
|
|
1721
|
-
if (!hasProperSlippage(userSlippage.toString(), minRequiredSlippage)) confirmSwap.errors.push({
|
|
1722
|
-
type: ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE,
|
|
1723
|
-
minRequiredSlippage
|
|
1724
|
-
});
|
|
1725
|
-
const noErrors = confirmSwap.errors.length === 0;
|
|
1726
|
-
const noWarnings = confirmSwap.warnings.length === 0;
|
|
1727
|
-
if ((noErrors || !noErrors && proceedAnyway) && (noWarnings || !noWarnings && proceedAnyway)) {
|
|
1728
|
-
const swapSettings = {
|
|
1729
|
-
slippage: userSlippage.toString(),
|
|
1730
|
-
disabledSwappersGroups: disabledLiquiditySources
|
|
1731
|
-
};
|
|
1732
|
-
const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRoute, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
|
|
1733
|
-
console.log('new swap:', newSwap);
|
|
1734
|
-
return newSwap;
|
|
1735
|
-
} else if (!proceedAnyway) {
|
|
1736
|
-
confirmSwap.proceedAnyway = true;
|
|
1737
|
-
useConfirmSwapStore.setState(confirmSwap);
|
|
1738
|
-
}
|
|
1739
|
-
return undefined;
|
|
1740
|
-
}).then(result => {
|
|
1741
|
-
abortController = null;
|
|
1742
|
-
unsubscribeFromBestRouteStore();
|
|
1743
|
-
unsubscribeFromWalletsStore();
|
|
1744
|
-
return result;
|
|
1745
|
-
}).catch(error => {
|
|
1746
|
-
abortController = null;
|
|
1747
|
-
if (error.code === 'ERR_CANCELED') {
|
|
1748
|
-
useConfirmSwapStore.setState({
|
|
1749
|
-
errors: [],
|
|
1750
|
-
warnings: [],
|
|
1751
|
-
loading: false,
|
|
1752
|
-
proceedAnyway: false
|
|
1753
|
-
});
|
|
1754
|
-
unsubscribeFromBestRouteStore();
|
|
1755
|
-
unsubscribeFromWalletsStore();
|
|
1756
|
-
}
|
|
1757
|
-
const status = error.response?.status;
|
|
1758
|
-
useConfirmSwapStore.setState(prevState => ({
|
|
1759
|
-
loading: false,
|
|
1760
|
-
errors: prevState.errors.concat({
|
|
1761
|
-
type: ConfirmSwapErrorTypes.REQUEST_FAILED,
|
|
1762
|
-
status
|
|
1763
|
-
})
|
|
1764
|
-
}));
|
|
1765
|
-
});
|
|
1766
|
-
return newSwap || undefined;
|
|
1767
|
-
};
|
|
1768
1720
|
|
|
1769
1721
|
function MinRequiredSlippage(_ref) {
|
|
1770
1722
|
let {
|
|
@@ -1772,7 +1724,7 @@ function MinRequiredSlippage(_ref) {
|
|
|
1772
1724
|
} = _ref;
|
|
1773
1725
|
return React__default.createElement(ui.Typography, {
|
|
1774
1726
|
variant: "body2"
|
|
1775
|
-
}, "
|
|
1727
|
+
}, "We recommend you to increase slippage to at least \u00A0", minRequiredSlippage, "\u00A0 for this route.", React__default.createElement(ChangeSlippageButton, null));
|
|
1776
1728
|
}
|
|
1777
1729
|
|
|
1778
1730
|
function ConfirmSwapErrors(errors) {
|
|
@@ -1800,13 +1752,40 @@ function ConfirmSwapErrors(errors) {
|
|
|
1800
1752
|
});
|
|
1801
1753
|
}
|
|
1802
1754
|
|
|
1755
|
+
const List = /*#__PURE__*/ui.styled('ul', {
|
|
1756
|
+
variants: {
|
|
1757
|
+
showListStyle: {
|
|
1758
|
+
true: {
|
|
1759
|
+
paddingLeft: '$24'
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
});
|
|
1764
|
+
const ListItem = /*#__PURE__*/ui.styled('li', {
|
|
1765
|
+
variants: {
|
|
1766
|
+
showListStyle: {
|
|
1767
|
+
true: {
|
|
1768
|
+
listStyleType: 'disc',
|
|
1769
|
+
listStylePosition: 'outside'
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
});
|
|
1774
|
+
const Message = /*#__PURE__*/ui.styled(ui.Typography, {
|
|
1775
|
+
display: 'block'
|
|
1776
|
+
});
|
|
1803
1777
|
function BalanceWarnings(_ref) {
|
|
1804
1778
|
let {
|
|
1805
1779
|
messages
|
|
1806
1780
|
} = _ref;
|
|
1807
|
-
|
|
1781
|
+
const showListStyle = messages.length > 1;
|
|
1782
|
+
return React__default.createElement(List, {
|
|
1783
|
+
showListStyle: showListStyle
|
|
1784
|
+
}, messages.map(warning => React__default.createElement(ListItem, {
|
|
1785
|
+
showListStyle: showListStyle
|
|
1786
|
+
}, React__default.createElement(Message, {
|
|
1808
1787
|
variant: "body2"
|
|
1809
|
-
}, warning)));
|
|
1788
|
+
}, warning))));
|
|
1810
1789
|
}
|
|
1811
1790
|
|
|
1812
1791
|
function ConfirmSwapWarnings(warnings) {
|
|
@@ -1839,6 +1818,137 @@ function ConfirmSwapWarnings(warnings) {
|
|
|
1839
1818
|
});
|
|
1840
1819
|
}
|
|
1841
1820
|
|
|
1821
|
+
function useConfirmSwap() {
|
|
1822
|
+
const fromToken = useBestRouteStore.use.fromToken();
|
|
1823
|
+
const toToken = useBestRouteStore.use.toToken();
|
|
1824
|
+
const inputAmount = useBestRouteStore.use.inputAmount();
|
|
1825
|
+
const initialRoute = useBestRouteStore.use.bestRoute();
|
|
1826
|
+
const setBestRoute = useBestRouteStore.use.setBestRoute();
|
|
1827
|
+
const inputUsdValue = useBestRouteStore.use.inputUsdValue();
|
|
1828
|
+
const accounts = useWalletsStore.use.accounts();
|
|
1829
|
+
const selectedWallets = useWalletsStore.use.selectedWallets();
|
|
1830
|
+
const meta = useMetaStore.use.meta();
|
|
1831
|
+
const customSlippage = useSettingsStore.use.customSlippage();
|
|
1832
|
+
const slippage = useSettingsStore.use.slippage();
|
|
1833
|
+
const disabledLiquiditySources = useSettingsStore.use.disabledLiquiditySources();
|
|
1834
|
+
const userSlippage = customSlippage || slippage;
|
|
1835
|
+
const proceedAnywayRef = React.useRef(false);
|
|
1836
|
+
const confiremedRouteRef = React.useRef(null);
|
|
1837
|
+
let abortControllerRef = React.useRef(null);
|
|
1838
|
+
const [loading, setLoading] = React.useState(false);
|
|
1839
|
+
const [errors, setErrors] = React.useState([]);
|
|
1840
|
+
const [warnings, setWarnings] = React.useState([]);
|
|
1841
|
+
React.useEffect(() => {
|
|
1842
|
+
return () => abortControllerRef.current?.abort();
|
|
1843
|
+
}, []);
|
|
1844
|
+
if (!fromToken || !toToken || !inputAmount || !initialRoute) return {
|
|
1845
|
+
loading: false,
|
|
1846
|
+
warnings: [],
|
|
1847
|
+
errors: [],
|
|
1848
|
+
confirmSwap: null
|
|
1849
|
+
};
|
|
1850
|
+
const confirmSwap = async () => {
|
|
1851
|
+
if (proceedAnywayRef.current) {
|
|
1852
|
+
const swapSettings = {
|
|
1853
|
+
slippage: userSlippage.toString(),
|
|
1854
|
+
disabledSwappersGroups: disabledLiquiditySources
|
|
1855
|
+
};
|
|
1856
|
+
if (errors.length > 0) setErrors([]);
|
|
1857
|
+
if (warnings.length > 0) setWarnings([]);
|
|
1858
|
+
proceedAnywayRef.current = false;
|
|
1859
|
+
if (confiremedRouteRef.current) {
|
|
1860
|
+
const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRouteRef.current, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
|
|
1861
|
+
return newSwap;
|
|
1862
|
+
}
|
|
1863
|
+
return;
|
|
1864
|
+
}
|
|
1865
|
+
abortControllerRef.current = new AbortController();
|
|
1866
|
+
setLoading(true);
|
|
1867
|
+
const requestBody = createBestRouteRequestBody(fromToken, toToken, inputAmount, accounts, selectedWallets, disabledLiquiditySources, userSlippage, true);
|
|
1868
|
+
try {
|
|
1869
|
+
const confiremedRoute = await httpService.getBestRoute(requestBody, {
|
|
1870
|
+
signal: abortControllerRef.current?.signal
|
|
1871
|
+
});
|
|
1872
|
+
abortControllerRef.current = null;
|
|
1873
|
+
setLoading(false);
|
|
1874
|
+
if (!confiremedRoute.result || !new BigNumber__default(confiremedRoute.requestAmount).isEqualTo(new BigNumber__default(inputAmount || '-1'))) {
|
|
1875
|
+
setErrors(prevState => prevState.concat({
|
|
1876
|
+
type: ConfirmSwapErrorTypes.NO_ROUTE
|
|
1877
|
+
}));
|
|
1878
|
+
return;
|
|
1879
|
+
}
|
|
1880
|
+
const confirmSwapState = {
|
|
1881
|
+
errors: [],
|
|
1882
|
+
warnings: []
|
|
1883
|
+
};
|
|
1884
|
+
const routeChanged = isRouteChanged(initialRoute, confiremedRoute);
|
|
1885
|
+
if (routeChanged) {
|
|
1886
|
+
setBestRoute(confiremedRoute);
|
|
1887
|
+
const newRouteOutputUsdValue = new BigNumber__default(confiremedRoute.result?.outputAmount || '0').multipliedBy(toToken.usdPrice || 0);
|
|
1888
|
+
const outputRatio = getOutputRatio(inputUsdValue, newRouteOutputUsdValue);
|
|
1889
|
+
const highValueLoss = outputRatioHasWarning(inputUsdValue, outputRatio);
|
|
1890
|
+
if (highValueLoss) confirmSwapState.errors.push({
|
|
1891
|
+
type: ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS
|
|
1892
|
+
});else if (isOutputAmountChangedALot(initialRoute, confiremedRoute)) confirmSwapState.warnings.push({
|
|
1893
|
+
type: ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED,
|
|
1894
|
+
newOutputAmount: numberToString(getRouteOutputAmount(confiremedRoute)),
|
|
1895
|
+
percentageChange: numberToString(getPercentageChange(getRouteOutputAmount(initialRoute), getRouteOutputAmount(confiremedRoute)), null, 2)
|
|
1896
|
+
});else if (isRouteInternalCoinsUpdated(initialRoute, confiremedRoute)) confirmSwapState.warnings.push({
|
|
1897
|
+
type: ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED
|
|
1898
|
+
});else if (isNumberOfSwapsChanged(initialRoute, confiremedRoute)) confirmSwapState.warnings.push({
|
|
1899
|
+
type: ConfirmSwapWarningTypes.ROUTE_UPDATED
|
|
1900
|
+
});else if (isRouteSwappersUpdated(initialRoute, confiremedRoute)) confirmSwapState.warnings.push({
|
|
1901
|
+
type: ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED
|
|
1902
|
+
});
|
|
1903
|
+
}
|
|
1904
|
+
const balanceWarnings = getBalanceWarnings(confiremedRoute, selectedWallets);
|
|
1905
|
+
const enoughBalance = balanceWarnings.length === 0;
|
|
1906
|
+
if (!enoughBalance) confirmSwapState.warnings.push({
|
|
1907
|
+
type: ConfirmSwapWarningTypes.INSUFFICIENT_BALANCE,
|
|
1908
|
+
messages: balanceWarnings
|
|
1909
|
+
});
|
|
1910
|
+
const minRequiredSlippage = getMinRequiredSlippage(initialRoute);
|
|
1911
|
+
if (!hasProperSlippage(userSlippage.toString(), minRequiredSlippage)) confirmSwapState.errors.push({
|
|
1912
|
+
type: ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE,
|
|
1913
|
+
minRequiredSlippage
|
|
1914
|
+
});
|
|
1915
|
+
const noErrors = confirmSwapState.errors.length === 0;
|
|
1916
|
+
const noWarnings = confirmSwapState.warnings.length === 0;
|
|
1917
|
+
if ((noErrors || !noErrors && proceedAnywayRef.current) && (noWarnings || !noWarnings && proceedAnywayRef.current)) {
|
|
1918
|
+
const swapSettings = {
|
|
1919
|
+
slippage: userSlippage.toString(),
|
|
1920
|
+
disabledSwappersGroups: disabledLiquiditySources
|
|
1921
|
+
};
|
|
1922
|
+
const newSwap = calculatePendingSwap(inputAmount.toString(), confiremedRoute, getWalletsForNewSwap(selectedWallets), swapSettings, false, meta);
|
|
1923
|
+
return newSwap;
|
|
1924
|
+
} else if (!proceedAnywayRef.current) {
|
|
1925
|
+
proceedAnywayRef.current = true;
|
|
1926
|
+
setErrors(confirmSwapState.errors);
|
|
1927
|
+
setWarnings(confirmSwapState.warnings);
|
|
1928
|
+
confiremedRouteRef.current = confiremedRoute;
|
|
1929
|
+
}
|
|
1930
|
+
return;
|
|
1931
|
+
} catch (error) {
|
|
1932
|
+
if (error?.code === 'ERR_CANCELED') {
|
|
1933
|
+
return;
|
|
1934
|
+
}
|
|
1935
|
+
const status = error?.response?.status;
|
|
1936
|
+
setLoading(false);
|
|
1937
|
+
setErrors([{
|
|
1938
|
+
type: ConfirmSwapErrorTypes.REQUEST_FAILED,
|
|
1939
|
+
status
|
|
1940
|
+
}]);
|
|
1941
|
+
return;
|
|
1942
|
+
}
|
|
1943
|
+
};
|
|
1944
|
+
return {
|
|
1945
|
+
loading,
|
|
1946
|
+
warnings,
|
|
1947
|
+
errors,
|
|
1948
|
+
confirmSwap
|
|
1949
|
+
};
|
|
1950
|
+
}
|
|
1951
|
+
|
|
1842
1952
|
function ConfirmSwapPage() {
|
|
1843
1953
|
const setSelectedSwap = useUiStore.use.setSelectedSwap();
|
|
1844
1954
|
const {
|
|
@@ -1849,15 +1959,23 @@ function ConfirmSwapPage() {
|
|
|
1849
1959
|
} = queueManagerReact.useManager();
|
|
1850
1960
|
const navigate = reactRouterDom.useNavigate();
|
|
1851
1961
|
const bestRoute = useBestRouteStore.use.bestRoute();
|
|
1852
|
-
const
|
|
1853
|
-
const
|
|
1854
|
-
|
|
1962
|
+
const fetchingBestRoute = useBestRouteStore.use.loading();
|
|
1963
|
+
const {
|
|
1964
|
+
tokens
|
|
1965
|
+
} = useMetaStore.use.meta();
|
|
1855
1966
|
const slippage = useSettingsStore.use.slippage();
|
|
1856
1967
|
const customSlippage = useSettingsStore.use.customSlippage();
|
|
1857
1968
|
const selectedSlippage = customSlippage || slippage;
|
|
1969
|
+
const {
|
|
1970
|
+
loading,
|
|
1971
|
+
errors,
|
|
1972
|
+
warnings,
|
|
1973
|
+
confirmSwap
|
|
1974
|
+
} = useConfirmSwap();
|
|
1975
|
+
const showHighSlippageWarning = !errors.find(error => error.type === ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE);
|
|
1858
1976
|
return React__default.createElement(ui.ConfirmSwap, {
|
|
1859
1977
|
onConfirm: () => {
|
|
1860
|
-
confirmSwap().then(swap => {
|
|
1978
|
+
confirmSwap?.().then(swap => {
|
|
1861
1979
|
if (swap) {
|
|
1862
1980
|
manager?.create('swap', {
|
|
1863
1981
|
swapDetails: swap
|
|
@@ -1870,15 +1988,15 @@ function ConfirmSwapPage() {
|
|
|
1870
1988
|
});
|
|
1871
1989
|
},
|
|
1872
1990
|
onBack: navigateBackFrom.bind(null, navigationRoutes.confirmSwap),
|
|
1873
|
-
bestRoute: bestRoute,
|
|
1991
|
+
bestRoute: getBestRouteWithCalculatedFees(bestRoute, tokens),
|
|
1874
1992
|
loading: loading,
|
|
1875
1993
|
errors: ConfirmSwapErrors(errors),
|
|
1876
1994
|
warnings: ConfirmSwapWarnings(warnings),
|
|
1877
|
-
extraMessages: React__default.createElement(ConfirmSwapExtraMessages, {
|
|
1995
|
+
extraMessages: showHighSlippageWarning && React__default.createElement(ConfirmSwapExtraMessages, {
|
|
1878
1996
|
selectedSlippage: selectedSlippage
|
|
1879
1997
|
}),
|
|
1880
1998
|
confirmButtonTitle: warnings.length > 0 || errors.length > 0 ? 'Proceed anyway!' : 'Confirm swap!',
|
|
1881
|
-
confirmButtonDisabled:
|
|
1999
|
+
confirmButtonDisabled: fetchingBestRoute
|
|
1882
2000
|
});
|
|
1883
2001
|
}
|
|
1884
2002
|
|
|
@@ -1971,8 +2089,6 @@ function SelectChainPage(props) {
|
|
|
1971
2089
|
const toChain = useBestRouteStore.use.toChain();
|
|
1972
2090
|
const setFromChain = useBestRouteStore.use.setFromChain();
|
|
1973
2091
|
const setToChain = useBestRouteStore.use.setToChain();
|
|
1974
|
-
const setFromToken = useBestRouteStore.use.setFromToken();
|
|
1975
|
-
const setToToken = useBestRouteStore.use.setToToken();
|
|
1976
2092
|
const {
|
|
1977
2093
|
navigateBackFrom
|
|
1978
2094
|
} = useNavigateBack();
|
|
@@ -1982,9 +2098,7 @@ function SelectChainPage(props) {
|
|
|
1982
2098
|
selected: type === 'from' ? fromChain : toChain,
|
|
1983
2099
|
loadingStatus: loadingStatus,
|
|
1984
2100
|
onChange: chain => {
|
|
1985
|
-
if (type === 'from') setFromChain(chain);else setToChain(chain);
|
|
1986
|
-
if (type === 'from' && fromChain?.name != chain.name) setFromToken(null);
|
|
1987
|
-
if (type === 'to' && toChain?.name != chain.name) setToToken(null);
|
|
2101
|
+
if (type === 'from') setFromChain(chain, true);else setToChain(chain, true);
|
|
1988
2102
|
navigateBackFrom(navigationRoutes.fromChain);
|
|
1989
2103
|
},
|
|
1990
2104
|
onBack: navigateBackFrom.bind(null, navigationRoutes.fromChain)
|
|
@@ -1999,34 +2113,18 @@ function SelectTokenPage(props) {
|
|
|
1999
2113
|
type,
|
|
2000
2114
|
supportedTokens
|
|
2001
2115
|
} = props;
|
|
2002
|
-
const
|
|
2003
|
-
const
|
|
2004
|
-
const
|
|
2116
|
+
const sourceTokens = useBestRouteStore.use.sourceTokens();
|
|
2117
|
+
const destinationTokens = useBestRouteStore.use.destinationTokens();
|
|
2118
|
+
const supportedSourceTokens = supportedTokens === 'all' ? sourceTokens : sourceTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
|
|
2119
|
+
const supportedDestinationTokens = supportedTokens === 'all' ? destinationTokens : destinationTokens.filter(token => supportedTokens.some(supportedToken => tokensAreEqual(supportedToken, token)));
|
|
2120
|
+
console.log(supportedSourceTokens);
|
|
2005
2121
|
const fromToken = useBestRouteStore.use.fromToken();
|
|
2006
2122
|
const toToken = useBestRouteStore.use.toToken();
|
|
2007
2123
|
const setFromToken = useBestRouteStore.use.setFromToken();
|
|
2008
2124
|
const setToToken = useBestRouteStore.use.setToToken();
|
|
2009
|
-
const balance = useWalletsStore.use.balances();
|
|
2010
|
-
const tokenWithSelectedChain = tokens.filter(token => {
|
|
2011
|
-
if (type === 'from') return token.blockchain === fromChain?.name;
|
|
2012
|
-
return token.blockchain === toChain?.name;
|
|
2013
|
-
});
|
|
2014
|
-
const TokensWithBalance = tokenWithSelectedChain.map(token => {
|
|
2015
|
-
const tokenAmount = numberToString(new BigNumber__default(getBalanceFromWallet(balance, token.blockchain, token.symbol, token.address)?.amount || ZERO));
|
|
2016
|
-
let tokenUsdValue = '';
|
|
2017
|
-
if (token.usdPrice) tokenUsdValue = numberToString(new BigNumber__default(getBalanceFromWallet(balance, token.blockchain, token.symbol, token.address)?.amount || ZERO).multipliedBy(token.usdPrice));
|
|
2018
|
-
return {
|
|
2019
|
-
...token,
|
|
2020
|
-
balance: {
|
|
2021
|
-
amount: tokenAmount !== '0' ? tokenAmount : '',
|
|
2022
|
-
usdValue: tokenUsdValue !== '0' ? tokenUsdValue : ''
|
|
2023
|
-
}
|
|
2024
|
-
};
|
|
2025
|
-
});
|
|
2026
|
-
const sortedTokenList = sortedTokens(TokensWithBalance, type, balance);
|
|
2027
2125
|
return React__default.createElement(ui.TokenSelector, {
|
|
2028
2126
|
type: type === 'from' ? 'Source' : 'Destination',
|
|
2029
|
-
list:
|
|
2127
|
+
list: type == 'from' ? supportedSourceTokens : supportedDestinationTokens,
|
|
2030
2128
|
selected: type === 'from' ? fromToken : toToken,
|
|
2031
2129
|
onChange: token => {
|
|
2032
2130
|
if (type === 'from') setFromToken(token);else setToToken(token);
|
|
@@ -2075,7 +2173,7 @@ function SettingsPage(_ref) {
|
|
|
2075
2173
|
slippages: SLIPPAGES,
|
|
2076
2174
|
selectedSlippage: slippage,
|
|
2077
2175
|
onSlippageChange: slippage => setSlippage(slippage),
|
|
2078
|
-
onLiquiditySourcesClick: navigate
|
|
2176
|
+
onLiquiditySourcesClick: () => navigate(navigationRoutes.liquiditySources),
|
|
2079
2177
|
onBack: navigateBackFrom.bind(null, navigationRoutes.settings),
|
|
2080
2178
|
liquiditySources: supportedUniqueSwappersGroups,
|
|
2081
2179
|
selectedLiquiditySources: supportedUniqueSwappersGroups.filter(s => s.selected),
|
|
@@ -2116,6 +2214,8 @@ function WalletsPage(_ref) {
|
|
|
2116
2214
|
connect
|
|
2117
2215
|
} = walletsCore.useWallets();
|
|
2118
2216
|
const wallets = getlistWallet(state, getWalletInfo, supportedWallets === 'all' ? Object.values(walletsShared.WalletType) : supportedWallets);
|
|
2217
|
+
let sortedWallets = walletsShared.detectMobileScreens() ? wallets.filter(wallet => wallet.showOnMobile) : wallets;
|
|
2218
|
+
sortedWallets = sortWalletsBasedOnState(sortedWallets);
|
|
2119
2219
|
const [walletErrorMessage, setWalletErrorMessage] = React.useState('');
|
|
2120
2220
|
const toggleConnectWalletsButton = useUiStore.use.toggleConnectWalletsButton();
|
|
2121
2221
|
const {
|
|
@@ -2134,7 +2234,7 @@ function WalletsPage(_ref) {
|
|
|
2134
2234
|
await connect(type);
|
|
2135
2235
|
}
|
|
2136
2236
|
} catch (e) {
|
|
2137
|
-
setWalletErrorMessage('Error: ' + e
|
|
2237
|
+
setWalletErrorMessage('Error: ' + e?.message);
|
|
2138
2238
|
}
|
|
2139
2239
|
};
|
|
2140
2240
|
React.useEffect(() => {
|
|
@@ -2142,15 +2242,15 @@ function WalletsPage(_ref) {
|
|
|
2142
2242
|
return () => toggleConnectWalletsButton();
|
|
2143
2243
|
}, []);
|
|
2144
2244
|
return React__default.createElement(ui.SecondaryPage, {
|
|
2145
|
-
title: t('Select Wallet'),
|
|
2245
|
+
title: t('Select Wallet') || '',
|
|
2146
2246
|
textField: false,
|
|
2147
2247
|
onBack: navigateBackFrom.bind(null, navigationRoutes.wallets)
|
|
2148
2248
|
}, React__default.createElement(React__default.Fragment, null, walletErrorMessage && React__default.createElement(AlertContainer, null, React__default.createElement(ui.Alert, {
|
|
2149
2249
|
type: "error"
|
|
2150
2250
|
}, React__default.createElement(ui.Typography, {
|
|
2151
2251
|
variant: "body2"
|
|
2152
|
-
}, walletErrorMessage))), React__default.createElement(ListContainer, null,
|
|
2153
|
-
key: index
|
|
2252
|
+
}, walletErrorMessage))), React__default.createElement(ListContainer, null, sortedWallets.map((wallet, index) => React__default.createElement(ui.Wallet, Object.assign({}, wallet, {
|
|
2253
|
+
key: `${index}-${wallet.type}`,
|
|
2154
2254
|
onClick: onSelectWallet
|
|
2155
2255
|
}))))));
|
|
2156
2256
|
}
|
|
@@ -2248,59 +2348,50 @@ function SwapDetailsPage() {
|
|
|
2248
2348
|
});
|
|
2249
2349
|
}
|
|
2250
2350
|
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
fromTokens = 'all',
|
|
2256
|
-
toTokens = 'all',
|
|
2257
|
-
liquiditySources = 'all',
|
|
2258
|
-
wallets = 'all',
|
|
2259
|
-
title,
|
|
2260
|
-
multiWallets = true,
|
|
2261
|
-
titleSize,
|
|
2262
|
-
titleWeight
|
|
2263
|
-
} = _ref;
|
|
2351
|
+
function AppRoutes(props) {
|
|
2352
|
+
const {
|
|
2353
|
+
configs
|
|
2354
|
+
} = props;
|
|
2264
2355
|
return reactRouterDom.useRoutes([{
|
|
2265
2356
|
path: navigationRoutes.home,
|
|
2266
2357
|
element: React__default.createElement(Home, {
|
|
2267
|
-
title: title,
|
|
2268
|
-
titleSize: titleSize,
|
|
2269
|
-
titleWeight: titleWeight
|
|
2358
|
+
title: configs?.title,
|
|
2359
|
+
titleSize: configs?.titleSize,
|
|
2360
|
+
titleWeight: configs?.titleWeight
|
|
2270
2361
|
})
|
|
2271
2362
|
}, {
|
|
2272
2363
|
path: navigationRoutes.fromChain,
|
|
2273
2364
|
element: React__default.createElement(SelectChainPage, {
|
|
2274
2365
|
type: "from",
|
|
2275
|
-
supportedChains: fromChains
|
|
2366
|
+
supportedChains: configs?.fromChains || 'all'
|
|
2276
2367
|
})
|
|
2277
2368
|
}, {
|
|
2278
2369
|
path: navigationRoutes.toChain,
|
|
2279
2370
|
element: React__default.createElement(SelectChainPage, {
|
|
2280
2371
|
type: "to",
|
|
2281
|
-
supportedChains: toChains
|
|
2372
|
+
supportedChains: configs?.toChains || 'all'
|
|
2282
2373
|
})
|
|
2283
2374
|
}, {
|
|
2284
2375
|
path: navigationRoutes.fromToken + '/*',
|
|
2285
2376
|
element: React__default.createElement(SelectTokenPage, {
|
|
2286
2377
|
type: "from",
|
|
2287
|
-
supportedTokens: fromTokens
|
|
2378
|
+
supportedTokens: configs?.fromTokens || 'all'
|
|
2288
2379
|
})
|
|
2289
2380
|
}, {
|
|
2290
2381
|
path: navigationRoutes.toToken,
|
|
2291
2382
|
element: React__default.createElement(SelectTokenPage, {
|
|
2292
2383
|
type: "to",
|
|
2293
|
-
supportedTokens: toTokens
|
|
2384
|
+
supportedTokens: configs?.toTokens || 'all'
|
|
2294
2385
|
})
|
|
2295
2386
|
}, {
|
|
2296
2387
|
path: navigationRoutes.settings,
|
|
2297
2388
|
element: React__default.createElement(SettingsPage, {
|
|
2298
|
-
supportedSwappers: liquiditySources
|
|
2389
|
+
supportedSwappers: configs?.liquiditySources || 'all'
|
|
2299
2390
|
})
|
|
2300
2391
|
}, {
|
|
2301
2392
|
path: navigationRoutes.liquiditySources,
|
|
2302
2393
|
element: React__default.createElement(LiquiditySourcePage, {
|
|
2303
|
-
supportedSwappers: liquiditySources
|
|
2394
|
+
supportedSwappers: configs?.liquiditySources || 'all'
|
|
2304
2395
|
})
|
|
2305
2396
|
}, {
|
|
2306
2397
|
path: navigationRoutes.swaps,
|
|
@@ -2311,8 +2402,8 @@ const AppRoutes = _ref => {
|
|
|
2311
2402
|
}, {
|
|
2312
2403
|
path: navigationRoutes.wallets,
|
|
2313
2404
|
element: React__default.createElement(WalletsPage, {
|
|
2314
|
-
supportedWallets: wallets,
|
|
2315
|
-
multiWallets: multiWallets
|
|
2405
|
+
supportedWallets: configs?.wallets || 'all',
|
|
2406
|
+
multiWallets: typeof configs?.multiWallets === 'undefined' ? true : configs.multiWallets
|
|
2316
2407
|
})
|
|
2317
2408
|
}, {
|
|
2318
2409
|
path: navigationRoutes.confirmSwap,
|
|
@@ -2321,7 +2412,7 @@ const AppRoutes = _ref => {
|
|
|
2321
2412
|
path: navigationRoutes.confirmWallets,
|
|
2322
2413
|
element: React__default.createElement(ConfirmWalletsPage, null)
|
|
2323
2414
|
}]);
|
|
2324
|
-
}
|
|
2415
|
+
}
|
|
2325
2416
|
|
|
2326
2417
|
const Header$1 = /*#__PURE__*/ui.styled('div', {
|
|
2327
2418
|
display: 'flex',
|
|
@@ -2364,7 +2455,7 @@ function Layout(_ref) {
|
|
|
2364
2455
|
setToToken(configs?.toToken || null);
|
|
2365
2456
|
}, [configs?.toChain, configs?.toToken]);
|
|
2366
2457
|
React.useEffect(() => {
|
|
2367
|
-
setInputAmount(configs?.fromAmount
|
|
2458
|
+
setInputAmount(configs?.fromAmount?.toString() || '');
|
|
2368
2459
|
}, [configs?.fromAmount]);
|
|
2369
2460
|
React.useEffect(() => {
|
|
2370
2461
|
setFromToken(configs?.fromToken || null);
|
|
@@ -2385,7 +2476,9 @@ function Layout(_ref) {
|
|
|
2385
2476
|
src: walletImage
|
|
2386
2477
|
})) : React__default.createElement(React__default.Fragment, null), React__default.createElement(ui.Typography, {
|
|
2387
2478
|
variant: "body2"
|
|
2388
|
-
}, !accounts?.length ? t('Connect Wallet') : `$${totalBalance || 0}`))), React__default.createElement(AppRoutes,
|
|
2479
|
+
}, !accounts?.length ? t('Connect Wallet') : `$${totalBalance || 0}`))), React__default.createElement(AppRoutes, {
|
|
2480
|
+
configs: configs
|
|
2481
|
+
}));
|
|
2389
2482
|
}
|
|
2390
2483
|
|
|
2391
2484
|
const globalStyles = /*#__PURE__*/ui.globalCss({
|
|
@@ -2660,7 +2753,10 @@ function QueueManager(props) {
|
|
|
2660
2753
|
console.log('[notifier]', message);
|
|
2661
2754
|
}
|
|
2662
2755
|
};
|
|
2663
|
-
return React__default.createElement(queueManagerReact.Provider
|
|
2756
|
+
return React__default.createElement(queueManagerReact.Provider
|
|
2757
|
+
//@ts-ignore
|
|
2758
|
+
, {
|
|
2759
|
+
//@ts-ignore
|
|
2664
2760
|
queuesDefs: [queueManagerRangoPreset.swapQueueDef],
|
|
2665
2761
|
context: context,
|
|
2666
2762
|
onPersistedDataLoaded: _manager => {},
|