@0xsquid/react-hooks 1.0.0
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/.babelrc +7 -0
- package/.eslintignore +1 -0
- package/.eslintrc.json +44 -0
- package/dist/index.js +6 -0
- package/jest.config.ts +28 -0
- package/package.json +124 -0
- package/scripts/copyAssets.js +27 -0
- package/scripts/removeBuildTestFolder.js +28 -0
- package/scripts/replacePaths.js +37 -0
- package/src/assets/images/icons/wallets/binance.svg +4 -0
- package/src/assets/images/icons/wallets/bitget.svg +43 -0
- package/src/assets/images/icons/wallets/bitkeep.svg +9 -0
- package/src/assets/images/icons/wallets/blockchaindotcom.svg +11 -0
- package/src/assets/images/icons/wallets/brave.svg +18 -0
- package/src/assets/images/icons/wallets/c98.svg +3 -0
- package/src/assets/images/icons/wallets/coinbase.svg +5 -0
- package/src/assets/images/icons/wallets/cosmostation.svg +9 -0
- package/src/assets/images/icons/wallets/defiConnect.svg +25 -0
- package/src/assets/images/icons/wallets/exodus.svg +33 -0
- package/src/assets/images/icons/wallets/fetchai.svg +1 -0
- package/src/assets/images/icons/wallets/index.ts +43 -0
- package/src/assets/images/icons/wallets/keplr.svg +9 -0
- package/src/assets/images/icons/wallets/leap.svg +35 -0
- package/src/assets/images/icons/wallets/metamask.svg +48 -0
- package/src/assets/images/icons/wallets/okx.svg +1 -0
- package/src/assets/images/icons/wallets/rabby.svg +1 -0
- package/src/assets/images/icons/wallets/trustwallet.svg +11 -0
- package/src/assets/images/icons/wallets/walletConnect.svg +11 -0
- package/src/assets/images/icons/wallets/wallet_icon.svg +1 -0
- package/src/assets/images/icons/wallets/xdefi.svg +9 -0
- package/src/assets/images/icons/wallets/zerion.svg +11 -0
- package/src/connectors/ExodusConnector.ts +6 -0
- package/src/connectors/LedgerLiveConnector.ts +226 -0
- package/src/contracts/typechain/ERC20.d.ts +441 -0
- package/src/contracts/typechain/factories/ERC20__factory.d.ts +56 -0
- package/src/contracts/typechain/factories/ERC20__factory.ts +340 -0
- package/src/core/constants.ts +549 -0
- package/src/core/externalLinks.ts +26 -0
- package/src/core/index.ts +1 -0
- package/src/core/multicall3.ts +22 -0
- package/src/core/numbers.ts +44 -0
- package/src/core/providers/CosmosProvider.tsx +55 -0
- package/src/core/queries/queries-keys.ts +156 -0
- package/src/core/queries/react-query-config.ts +13 -0
- package/src/core/types/components.ts +16 -0
- package/src/core/types/config.ts +52 -0
- package/src/core/types/dex.ts +31 -0
- package/src/core/types/error.ts +52 -0
- package/src/core/types/event.ts +16 -0
- package/src/core/types/route.ts +21 -0
- package/src/core/types/swap.ts +8 -0
- package/src/core/types/tokens.ts +30 -0
- package/src/core/types/transaction.ts +84 -0
- package/src/core/types/types.ts +37 -0
- package/src/core/types/wallet.ts +83 -0
- package/src/hooks/chains/useSquidChains.ts +66 -0
- package/src/hooks/cosmos/useCosmos.ts +279 -0
- package/src/hooks/cosmos/useCosmosForChain.ts +33 -0
- package/src/hooks/index.ts +32 -0
- package/src/hooks/navigation/useKeyboardNavigation.ts +88 -0
- package/src/hooks/store/useSquidStore.ts +80 -0
- package/src/hooks/swap/useSwap.ts +359 -0
- package/src/hooks/tokens/useAllTokensWithBalance.ts +157 -0
- package/src/hooks/tokens/useBalance.ts +180 -0
- package/src/hooks/tokens/useMultiChainBalance.ts +59 -0
- package/src/hooks/tokens/usePrices.ts +52 -0
- package/src/hooks/tokens/useSingleTokenPrice.ts +45 -0
- package/src/hooks/tokens/useSquidTokens.ts +48 -0
- package/src/hooks/tokens/useTokensWithBalance.ts +169 -0
- package/src/hooks/transaction/useEstimate.ts +397 -0
- package/src/hooks/transaction/useEstimatePriceImpact.ts +39 -0
- package/src/hooks/transaction/useExecuteTransaction.ts +440 -0
- package/src/hooks/transaction/useExpress.ts +46 -0
- package/src/hooks/transaction/useGetRoute.ts +145 -0
- package/src/hooks/transaction/useSingleTransaction.ts +155 -0
- package/src/hooks/transaction/useTransaction.ts +734 -0
- package/src/hooks/user/useUserParams.ts +63 -0
- package/src/hooks/wallet/useAddToken.ts +53 -0
- package/src/hooks/wallet/useAutoConnect.ts +56 -0
- package/src/hooks/wallet/useGnosisContext.ts +84 -0
- package/src/hooks/wallet/useIntegratorContext.ts +44 -0
- package/src/hooks/wallet/useMultiChainWallet.ts +146 -0
- package/src/hooks/wallet/useWallet.ts +86 -0
- package/src/hooks/webapp-router/useSquidRouter.ts +42 -0
- package/src/index.ts +5 -0
- package/src/provider/index.tsx +105 -0
- package/src/react-app-env.d.ts +2 -0
- package/src/services/external/analyticsService.ts +46 -0
- package/src/services/external/coingeckoService.ts +35 -0
- package/src/services/external/rpcService.ts +196 -0
- package/src/services/external/secretService.ts +178 -0
- package/src/services/index.ts +1 -0
- package/src/services/internal/apiService.ts +6 -0
- package/src/services/internal/assetsService.ts +84 -0
- package/src/services/internal/configService.ts +261 -0
- package/src/services/internal/errorService.ts +124 -0
- package/src/services/internal/eventService.ts +93 -0
- package/src/services/internal/priceService.ts +10 -0
- package/src/services/internal/transactionService.ts +255 -0
- package/src/services/internal/transactionStatusService.ts +293 -0
- package/src/services/internal/walletService.ts +158 -0
- package/src/tests/assetsService.test.ts +176 -0
- package/src/tests/configService.test.ts +486 -0
- package/src/tests/fetchSquidData.ts +43 -0
- package/src/tests/jest-svg-transform.ts +19 -0
- package/src/tests/sample.json +0 -0
- package/src/tests/walletService.test.ts +178 -0
- package/tsconfig.json +30 -0
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
import { gasRefundMultiplier } from "@/core/constants";
|
|
2
|
+
import { formatUnitsRounded } from "@/core/numbers";
|
|
3
|
+
import { useSquidStore } from "@/hooks/store/useSquidStore";
|
|
4
|
+
import { useNativeTokenBalanceFromChain } from "@/hooks/tokens/useBalance";
|
|
5
|
+
import { useSingleTokenPrice } from "@/hooks/tokens/useSingleTokenPrice";
|
|
6
|
+
import { useSquidTokens } from "@/hooks/tokens/useSquidTokens";
|
|
7
|
+
import type { Estimate, FeeCost, GasCost } from "@0xsquid/squid-types";
|
|
8
|
+
import { ChainType } from "@0xsquid/squid-types";
|
|
9
|
+
import { BigNumber, constants } from "ethers";
|
|
10
|
+
import { formatUnits } from "ethers/lib/utils";
|
|
11
|
+
import { useMemo } from "react";
|
|
12
|
+
import { useSquidChains } from "../chains/useSquidChains";
|
|
13
|
+
import { useMultiChainBalance } from "../tokens/useMultiChainBalance";
|
|
14
|
+
import { useGetRoute } from "./useGetRoute";
|
|
15
|
+
|
|
16
|
+
export const useEstimate = ({
|
|
17
|
+
squidRoute,
|
|
18
|
+
}: {
|
|
19
|
+
squidRoute: ReturnType<typeof useGetRoute>;
|
|
20
|
+
}) => {
|
|
21
|
+
const { config } = useSquidStore();
|
|
22
|
+
const { balance: nativeTokenBalanceFromChain } =
|
|
23
|
+
useNativeTokenBalanceFromChain();
|
|
24
|
+
const { tokens } = useSquidTokens();
|
|
25
|
+
const { chains } = useSquidChains();
|
|
26
|
+
|
|
27
|
+
const [fromChain, toChain] = useMemo(() => {
|
|
28
|
+
return [
|
|
29
|
+
chains.find((c) => c.chainId === squidRoute.data?.params.fromChain),
|
|
30
|
+
chains.find((c) => c.chainId === squidRoute.data?.params.toChain),
|
|
31
|
+
];
|
|
32
|
+
}, [
|
|
33
|
+
chains,
|
|
34
|
+
squidRoute.data?.params.fromChain,
|
|
35
|
+
squidRoute.data?.params.toChain,
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
const fromToken = useMemo(
|
|
39
|
+
() => tokens.find((t) => t.address === squidRoute.data?.params.fromToken),
|
|
40
|
+
[tokens, squidRoute.data?.params.fromToken]
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const balanceFormatted =
|
|
44
|
+
useMultiChainBalance({
|
|
45
|
+
chain: fromChain,
|
|
46
|
+
token: fromToken,
|
|
47
|
+
userAddress: squidRoute.data?.params.fromAddress ?? "",
|
|
48
|
+
enabled: !!squidRoute.data,
|
|
49
|
+
}).balance ?? "0";
|
|
50
|
+
|
|
51
|
+
const fromAmount = useMemo(
|
|
52
|
+
() => squidRoute.data?.estimate?.fromAmount ?? undefined,
|
|
53
|
+
[squidRoute.data?.estimate?.fromAmount]
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const fromAmountFormatted = useMemo(
|
|
57
|
+
() => (fromAmount ? formatUnits(fromAmount, fromToken?.decimals) : ""),
|
|
58
|
+
[fromAmount, fromToken?.decimals]
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
const sourceChainNativeToken = useMemo(() => {
|
|
62
|
+
return tokens.find(
|
|
63
|
+
(t) =>
|
|
64
|
+
t.symbol === fromChain?.nativeCurrency.symbol &&
|
|
65
|
+
t.chainId == fromChain?.chainId
|
|
66
|
+
);
|
|
67
|
+
}, [tokens, fromChain]);
|
|
68
|
+
|
|
69
|
+
const destChainNativeToken = useMemo(() => {
|
|
70
|
+
return tokens.find(
|
|
71
|
+
(t) =>
|
|
72
|
+
t.symbol === toChain?.nativeCurrency.symbol &&
|
|
73
|
+
t.chainId == toChain?.chainId
|
|
74
|
+
);
|
|
75
|
+
}, [tokens, toChain]);
|
|
76
|
+
|
|
77
|
+
const toAmountUSD = useMemo(
|
|
78
|
+
() => squidRoute.data?.estimate?.toAmountUSD ?? undefined,
|
|
79
|
+
[squidRoute.data?.estimate?.toAmountUSD]
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const toAmountUSDFloat = useMemo(
|
|
83
|
+
() => (toAmountUSD ? parseFloat(toAmountUSD.replace(/,/g, "")) : 0),
|
|
84
|
+
[toAmountUSD]
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const exchangeRate = useMemo(
|
|
88
|
+
() => squidRoute.data?.estimate.exchangeRate ?? "0",
|
|
89
|
+
[squidRoute.data?.estimate.exchangeRate]
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
const toAmountMin = useMemo(() => {
|
|
93
|
+
return formatUnits(
|
|
94
|
+
squidRoute.data?.estimate.toAmountMin ?? "0",
|
|
95
|
+
squidRoute.data?.estimate.toToken.decimals
|
|
96
|
+
);
|
|
97
|
+
}, [
|
|
98
|
+
squidRoute.data?.estimate.toAmountMin,
|
|
99
|
+
squidRoute.data?.estimate.toToken.decimals,
|
|
100
|
+
]);
|
|
101
|
+
|
|
102
|
+
const toAmount = useMemo(() => {
|
|
103
|
+
const formattedAmount = formatUnitsRounded(
|
|
104
|
+
squidRoute.data?.estimate.toAmount ?? "0",
|
|
105
|
+
squidRoute.data?.estimate.toToken.decimals,
|
|
106
|
+
14
|
|
107
|
+
);
|
|
108
|
+
return formattedAmount === "0.0" ? "0" : formattedAmount;
|
|
109
|
+
}, [
|
|
110
|
+
squidRoute.data?.estimate.toAmount,
|
|
111
|
+
squidRoute.data?.estimate.toToken.decimals,
|
|
112
|
+
]);
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* At the moment we're only taking the first item
|
|
116
|
+
* of fees array, but keeping the possibility to display multiple fees
|
|
117
|
+
*/
|
|
118
|
+
const crossChainGasFee = useMemo((): FeeCost | undefined => {
|
|
119
|
+
const estimate = squidRoute.data?.estimate as Estimate;
|
|
120
|
+
return estimate?.feeCosts.length > 0 ? estimate?.feeCosts[0] : undefined;
|
|
121
|
+
}, [squidRoute.data?.estimate]);
|
|
122
|
+
|
|
123
|
+
const allFeeCosts = useMemo((): FeeCost[] => {
|
|
124
|
+
const estimate = squidRoute.data?.estimate as Estimate;
|
|
125
|
+
return estimate?.feeCosts ?? [];
|
|
126
|
+
}, [squidRoute.data?.estimate]);
|
|
127
|
+
|
|
128
|
+
const allGasCosts = useMemo((): GasCost[] => {
|
|
129
|
+
const estimate = squidRoute.data?.estimate as Estimate;
|
|
130
|
+
return estimate?.gasCosts ?? [];
|
|
131
|
+
}, [squidRoute.data?.estimate]);
|
|
132
|
+
|
|
133
|
+
const firstGasCost = useMemo(
|
|
134
|
+
(): GasCost | undefined =>
|
|
135
|
+
allGasCosts.length > 0 ? allGasCosts[0] : undefined,
|
|
136
|
+
[allGasCosts]
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
const firstFeeCost = useMemo(
|
|
140
|
+
(): FeeCost | undefined =>
|
|
141
|
+
allFeeCosts.length > 0 ? allFeeCosts[0] : undefined,
|
|
142
|
+
[allFeeCosts]
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
const integratorFeeCost = useMemo(
|
|
146
|
+
(): FeeCost | undefined =>
|
|
147
|
+
allFeeCosts.length > 0 && config.collectFees
|
|
148
|
+
? // TODO: This is a hack to get the integrator fee, not mapped in squid types yet
|
|
149
|
+
allFeeCosts.find((f) => (f.name as any) === "Integrator Fee")
|
|
150
|
+
: undefined,
|
|
151
|
+
[allFeeCosts, config]
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
const { getUSDValue } = useSingleTokenPrice(firstFeeCost?.token);
|
|
155
|
+
|
|
156
|
+
const expressFeeCost = useMemo(
|
|
157
|
+
(): FeeCost | undefined =>
|
|
158
|
+
allFeeCosts.length > 0
|
|
159
|
+
? allFeeCosts.find((f) => f.name === "Express Fee")
|
|
160
|
+
: undefined,
|
|
161
|
+
[allFeeCosts]
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
const expectedGasRefundCost = useMemo(
|
|
165
|
+
() =>
|
|
166
|
+
BigNumber.from(firstFeeCost?.amount ?? "0")
|
|
167
|
+
.mul(
|
|
168
|
+
// When source is Cosmos we don't refund any gas
|
|
169
|
+
fromChain?.chainType === ChainType.COSMOS ? 0 : gasRefundMultiplier
|
|
170
|
+
)
|
|
171
|
+
.div(100),
|
|
172
|
+
[firstFeeCost?.amount]
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
const sameTokenBetweenFees = useMemo(
|
|
176
|
+
() =>
|
|
177
|
+
firstFeeCost?.token.address === firstGasCost?.token.address &&
|
|
178
|
+
firstFeeCost?.token.chainId === firstGasCost?.token.chainId,
|
|
179
|
+
[
|
|
180
|
+
firstFeeCost?.token.address,
|
|
181
|
+
firstFeeCost?.token.chainId,
|
|
182
|
+
firstGasCost?.token.address,
|
|
183
|
+
firstGasCost?.token.chainId,
|
|
184
|
+
]
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
// From token is the same as the native chain token
|
|
188
|
+
// TODO: This only works for EVM chains
|
|
189
|
+
const isFromTokenNative = useMemo(() => {
|
|
190
|
+
if (fromToken === undefined || fromChain?.chainId === undefined) {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
return fromToken.symbol === fromChain.nativeCurrency.symbol;
|
|
194
|
+
}, [fromToken, fromChain]);
|
|
195
|
+
|
|
196
|
+
const totalNativeFees = useMemo(() => {
|
|
197
|
+
const expressBn = BigNumber.from(expressFeeCost?.amount ?? constants.Zero);
|
|
198
|
+
if (sameTokenBetweenFees) {
|
|
199
|
+
return BigNumber.from(firstFeeCost?.amount ?? constants.Zero)
|
|
200
|
+
.add(BigNumber.from(firstGasCost?.amount ?? constants.Zero))
|
|
201
|
+
.add(expressBn);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return BigNumber.from(firstGasCost?.amount ?? constants.Zero).add(
|
|
205
|
+
expressBn
|
|
206
|
+
);
|
|
207
|
+
}, [
|
|
208
|
+
firstFeeCost?.amount,
|
|
209
|
+
firstGasCost?.amount,
|
|
210
|
+
sameTokenBetweenFees,
|
|
211
|
+
expressFeeCost?.amount,
|
|
212
|
+
]);
|
|
213
|
+
|
|
214
|
+
const totalFeesInNativeTokenPlusRatio = useMemo(() => {
|
|
215
|
+
return totalNativeFees.mul(105).div(100);
|
|
216
|
+
}, [totalNativeFees]);
|
|
217
|
+
|
|
218
|
+
const totalWithRefundEstimate = useMemo(() => {
|
|
219
|
+
const firstFee = {
|
|
220
|
+
BN: BigNumber.from(firstFeeCost?.amount ?? "0"),
|
|
221
|
+
token: firstFeeCost?.token,
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
const expressFee = {
|
|
225
|
+
BN: BigNumber.from(expressFeeCost?.amount ?? "0"),
|
|
226
|
+
token: expressFeeCost?.token,
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
// Big number amount
|
|
230
|
+
const totalBnbAmount = firstFee.BN.add(expressFee.BN).sub(
|
|
231
|
+
expectedGasRefundCost
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
const totalAmount = formatUnits(
|
|
235
|
+
totalBnbAmount,
|
|
236
|
+
firstFee.token?.decimals ?? 18
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
// USD values
|
|
240
|
+
const formattedRefundCost = formatUnits(
|
|
241
|
+
expectedGasRefundCost,
|
|
242
|
+
firstFeeCost?.token.decimals
|
|
243
|
+
);
|
|
244
|
+
const formattedRefundCostUSD = getUSDValue(formattedRefundCost);
|
|
245
|
+
const totalAmountUSD =
|
|
246
|
+
+(firstFeeCost?.amountUsd ?? 0) +
|
|
247
|
+
+(expressFeeCost?.amountUsd ?? 0) -
|
|
248
|
+
+(formattedRefundCostUSD ?? 0);
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
totalAmount,
|
|
252
|
+
totalAmountUSD,
|
|
253
|
+
feeToken: firstFeeCost?.token,
|
|
254
|
+
};
|
|
255
|
+
}, [
|
|
256
|
+
expectedGasRefundCost,
|
|
257
|
+
expressFeeCost?.amount,
|
|
258
|
+
expressFeeCost?.amountUsd,
|
|
259
|
+
expressFeeCost?.token,
|
|
260
|
+
firstFeeCost?.amount,
|
|
261
|
+
firstFeeCost?.amountUsd,
|
|
262
|
+
firstFeeCost?.token,
|
|
263
|
+
getUSDValue,
|
|
264
|
+
]);
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Two cases:
|
|
268
|
+
* 1. If the source token is the same as the native token, check if the balance of native token is less than the (source amount) + (native gas)
|
|
269
|
+
* 2. If the source token is different from the native token, check if the balance of native token is less than (native gas)
|
|
270
|
+
*/
|
|
271
|
+
const fromBalanceEnoughToSwap = useMemo(() => {
|
|
272
|
+
if (squidRoute.isLoading) return true;
|
|
273
|
+
|
|
274
|
+
const fromAmountWei = BigNumber.from(fromAmount ?? constants.Zero);
|
|
275
|
+
const fromBalance = nativeTokenBalanceFromChain.data ?? constants.Zero;
|
|
276
|
+
|
|
277
|
+
if (isFromTokenNative) {
|
|
278
|
+
const fromPlusGas = fromAmountWei.add(totalFeesInNativeTokenPlusRatio);
|
|
279
|
+
if (fromPlusGas.lte(fromBalance)) {
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
282
|
+
} else if (totalFeesInNativeTokenPlusRatio.lte(fromBalance)) {
|
|
283
|
+
return true;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return false;
|
|
287
|
+
}, [
|
|
288
|
+
nativeTokenBalanceFromChain.data,
|
|
289
|
+
fromAmount,
|
|
290
|
+
isFromTokenNative,
|
|
291
|
+
squidRoute.isLoading,
|
|
292
|
+
totalFeesInNativeTokenPlusRatio,
|
|
293
|
+
]);
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* In the case where the source token is the same as the native token,
|
|
297
|
+
* we need to advise the user to change the source amount to be less than the balance of native token minus the gas cost
|
|
298
|
+
*/
|
|
299
|
+
const minAmountValueWarnMsg = useMemo(() => {
|
|
300
|
+
if (!isFromTokenNative) {
|
|
301
|
+
return undefined;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const fromBalance = nativeTokenBalanceFromChain.data ?? constants.Zero;
|
|
305
|
+
|
|
306
|
+
const minAmount = fromBalance.sub(totalFeesInNativeTokenPlusRatio);
|
|
307
|
+
|
|
308
|
+
if (minAmount.gt(constants.Zero)) {
|
|
309
|
+
const parsedMinAmount = formatUnits(
|
|
310
|
+
minAmount,
|
|
311
|
+
sourceChainNativeToken?.decimals ?? 18
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
return parsedMinAmount;
|
|
315
|
+
}
|
|
316
|
+
return "0";
|
|
317
|
+
}, [
|
|
318
|
+
nativeTokenBalanceFromChain.data,
|
|
319
|
+
isFromTokenNative,
|
|
320
|
+
sourceChainNativeToken?.decimals,
|
|
321
|
+
totalFeesInNativeTokenPlusRatio,
|
|
322
|
+
]);
|
|
323
|
+
|
|
324
|
+
const proposedGasDestinationAmount = useMemo(() => {
|
|
325
|
+
// Get native token of chain
|
|
326
|
+
const nativeToken = toChain?.nativeCurrency.symbol;
|
|
327
|
+
let gasDestinationAmount = 0;
|
|
328
|
+
switch (nativeToken) {
|
|
329
|
+
case "GLMR":
|
|
330
|
+
gasDestinationAmount = 5.289;
|
|
331
|
+
break;
|
|
332
|
+
case "ETH":
|
|
333
|
+
gasDestinationAmount = 0.0009;
|
|
334
|
+
break;
|
|
335
|
+
case "AVAX":
|
|
336
|
+
gasDestinationAmount = 0.115;
|
|
337
|
+
break;
|
|
338
|
+
case "BNB":
|
|
339
|
+
gasDestinationAmount = 0.00425;
|
|
340
|
+
break;
|
|
341
|
+
case "FTM":
|
|
342
|
+
gasDestinationAmount = 4.45;
|
|
343
|
+
break;
|
|
344
|
+
case "CELO":
|
|
345
|
+
gasDestinationAmount = 3.052;
|
|
346
|
+
break;
|
|
347
|
+
case "KAVA":
|
|
348
|
+
gasDestinationAmount = 2.339;
|
|
349
|
+
break;
|
|
350
|
+
case "MATIC":
|
|
351
|
+
gasDestinationAmount = 1.795;
|
|
352
|
+
break;
|
|
353
|
+
default:
|
|
354
|
+
gasDestinationAmount = 0;
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
return { value: gasDestinationAmount, currency: nativeToken };
|
|
358
|
+
}, [toChain?.nativeCurrency.symbol]);
|
|
359
|
+
|
|
360
|
+
const enoughBalanceToSwap = useMemo(
|
|
361
|
+
() => +balanceFormatted >= 0 && +balanceFormatted > +fromAmountFormatted,
|
|
362
|
+
[balanceFormatted, fromAmountFormatted]
|
|
363
|
+
);
|
|
364
|
+
|
|
365
|
+
return {
|
|
366
|
+
allFeeCosts,
|
|
367
|
+
allGasCosts,
|
|
368
|
+
crossChainGasFee,
|
|
369
|
+
exchangeRate,
|
|
370
|
+
toAmountMin,
|
|
371
|
+
toAmount,
|
|
372
|
+
fromToken,
|
|
373
|
+
toAmountUSD,
|
|
374
|
+
toAmountUSDFloat,
|
|
375
|
+
isFetching: squidRoute.isLoading,
|
|
376
|
+
squidRouteError: squidRoute.error,
|
|
377
|
+
fromAmount,
|
|
378
|
+
fromAmountFormatted,
|
|
379
|
+
estimatedRouteDuration: squidRoute.data?.estimate?.estimatedRouteDuration,
|
|
380
|
+
minAmountValueWarnMsg,
|
|
381
|
+
fromBalanceEnoughToSwap,
|
|
382
|
+
isFromTokenNative,
|
|
383
|
+
firstFeeCost,
|
|
384
|
+
firstGasCost,
|
|
385
|
+
sameTokenBetweenFees,
|
|
386
|
+
totalFeesInNativeTokenPlusRatio,
|
|
387
|
+
totalNativeFees,
|
|
388
|
+
sourceChainNativeToken,
|
|
389
|
+
expressFeeCost,
|
|
390
|
+
proposedGasDestinationAmount,
|
|
391
|
+
expectedGasRefundCost,
|
|
392
|
+
totalWithRefundEstimate,
|
|
393
|
+
destChainNativeToken,
|
|
394
|
+
integratorFeeCost,
|
|
395
|
+
enoughBalanceToSwap,
|
|
396
|
+
};
|
|
397
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { useSquidStore } from "@/hooks/store/useSquidStore";
|
|
2
|
+
import { useGetRoute } from "@/hooks/transaction/useGetRoute";
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
|
|
5
|
+
export const useEstimatePriceImpact = ({
|
|
6
|
+
squidRoute,
|
|
7
|
+
}: {
|
|
8
|
+
squidRoute: ReturnType<typeof useGetRoute>;
|
|
9
|
+
}) => {
|
|
10
|
+
const { config } = useSquidStore();
|
|
11
|
+
|
|
12
|
+
const priceImpact = useMemo(
|
|
13
|
+
() => squidRoute.data?.estimate?.aggregatePriceImpact ?? undefined,
|
|
14
|
+
[squidRoute.data?.estimate]
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
const priceImpactStatus = useMemo(() => {
|
|
18
|
+
if (config.priceImpactWarnings !== undefined && priceImpact !== undefined) {
|
|
19
|
+
if (
|
|
20
|
+
+priceImpact >= config.priceImpactWarnings.warning &&
|
|
21
|
+
+priceImpact < config.priceImpactWarnings.critical
|
|
22
|
+
) {
|
|
23
|
+
return "warning";
|
|
24
|
+
}
|
|
25
|
+
if (+priceImpact >= config.priceImpactWarnings.critical) {
|
|
26
|
+
return "critical";
|
|
27
|
+
}
|
|
28
|
+
if (+priceImpact < config.priceImpactWarnings.warning) {
|
|
29
|
+
return "normal";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
}, [config.priceImpactWarnings, priceImpact]);
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
priceImpact,
|
|
37
|
+
priceImpactStatus,
|
|
38
|
+
};
|
|
39
|
+
};
|