From a543f856f4732cc51346e7f64a92e6b3df109f6e Mon Sep 17 00:00:00 2001 From: gregs Date: Sat, 29 Jun 2024 21:50:56 -0300 Subject: [PATCH] fix estimated fee (#5885) --- .../Swap/components/EstimatedSwapGasFee.tsx | 2 +- .../screens/Swap/components/GasButton.tsx | 7 +-- .../screens/Swap/components/ReviewPanel.tsx | 7 +-- .../screens/Swap/hooks/useEstimatedGasFee.ts | 15 +++-- .../Swap/hooks/useSwapEstimatedGasLimit.ts | 55 +++++++++---------- src/references/gasUnits.ts | 9 ++- 6 files changed, 46 insertions(+), 49 deletions(-) diff --git a/src/__swaps__/screens/Swap/components/EstimatedSwapGasFee.tsx b/src/__swaps__/screens/Swap/components/EstimatedSwapGasFee.tsx index 5c2ee1852f3..5f510346f37 100644 --- a/src/__swaps__/screens/Swap/components/EstimatedSwapGasFee.tsx +++ b/src/__swaps__/screens/Swap/components/EstimatedSwapGasFee.tsx @@ -10,7 +10,7 @@ import { GasSettings } from '../hooks/useCustomGas'; import { useSwapEstimatedGasFee } from '../hooks/useEstimatedGasFee'; import { useSwapContext } from '../providers/swap-provider'; -type EstimatedSwapGasFeeProps = { gasSettings: GasSettings | undefined } & Partial< +type EstimatedSwapGasFeeProps = { gasSettings?: GasSettings } & Partial< Pick >; export function EstimatedSwapGasFeeSlot({ diff --git a/src/__swaps__/screens/Swap/components/GasButton.tsx b/src/__swaps__/screens/Swap/components/GasButton.tsx index 0783ad312bf..63f3d5f03e3 100644 --- a/src/__swaps__/screens/Swap/components/GasButton.tsx +++ b/src/__swaps__/screens/Swap/components/GasButton.tsx @@ -19,7 +19,7 @@ import { OnPressMenuItemEventObject } from 'react-native-ios-context-menu'; import Animated, { runOnUI, useAnimatedStyle } from 'react-native-reanimated'; import { THICK_BORDER_WIDTH } from '../constants'; import { GasSettings, useCustomGasSettings } from '../hooks/useCustomGas'; -import { setSelectedGasSpeed, useSelectedGas, useSelectedGasSpeed } from '../hooks/useSelectedGas'; +import { setSelectedGasSpeed, useSelectedGasSpeed } from '../hooks/useSelectedGas'; import { NavigationSteps, useSwapContext } from '../providers/swap-provider'; import { EstimatedSwapGasFee, EstimatedSwapGasFeeSlot } from './EstimatedSwapGasFee'; import { GestureHandlerV1Button } from './GestureHandlerV1Button'; @@ -45,16 +45,13 @@ function UnmountWhenGasButtonIsNotInScreen({ placeholder, children }: PropsWithC } function EstimatedGasFee() { - const chainId = swapsStore(s => s.inputAsset?.chainId || ChainId.mainnet); - const gasSettings = useSelectedGas(chainId); - return ( 􀵟 }> - + ); diff --git a/src/__swaps__/screens/Swap/components/ReviewPanel.tsx b/src/__swaps__/screens/Swap/components/ReviewPanel.tsx index bd04fcd4143..0d2a8553086 100644 --- a/src/__swaps__/screens/Swap/components/ReviewPanel.tsx +++ b/src/__swaps__/screens/Swap/components/ReviewPanel.tsx @@ -50,7 +50,7 @@ import Animated, { withSpring, } from 'react-native-reanimated'; import { REVIEW_SHEET_ROW_HEIGHT, THICK_BORDER_WIDTH } from '../constants'; -import { useSelectedGas, useSelectedGasSpeed } from '../hooks/useSelectedGas'; +import { useSelectedGasSpeed } from '../hooks/useSelectedGas'; import { NavigationSteps, useSwapContext } from '../providers/swap-provider'; import { AnimatedSwitch } from './AnimatedSwitch'; import { EstimatedSwapGasFee, EstimatedSwapGasFeeSlot } from './EstimatedSwapGasFee'; @@ -126,10 +126,7 @@ const RainbowFee = () => { }; function EstimatedGasFee() { - const chainId = useSwapsStore(s => s.inputAsset?.chainId || ChainId.mainnet); - const gasSettings = useSelectedGas(chainId); - - return ; + return ; } function EstimatedArrivalTime() { diff --git a/src/__swaps__/screens/Swap/hooks/useEstimatedGasFee.ts b/src/__swaps__/screens/Swap/hooks/useEstimatedGasFee.ts index 58c4e34746c..88aa5a99ca7 100644 --- a/src/__swaps__/screens/Swap/hooks/useEstimatedGasFee.ts +++ b/src/__swaps__/screens/Swap/hooks/useEstimatedGasFee.ts @@ -8,6 +8,7 @@ import { formatUnits } from 'viem'; import { useAccountSettings } from '@/hooks'; import { useSyncedSwapQuoteStore } from '../providers/SyncSwapStateAndSharedValues'; import { GasSettings } from './useCustomGas'; +import { useSelectedGas } from './useSelectedGas'; import { useSwapEstimatedGasLimit } from './useSwapEstimatedGasLimit'; function safeBigInt(value: string) { @@ -51,11 +52,15 @@ export function useEstimatedGasFee({ }, [gasLimit, gasSettings, nativeCurrency, nativeNetworkAsset?.decimals, nativeNetworkAsset?.price]); } -export function useSwapEstimatedGasFee(gasSettings: GasSettings | undefined) { - const { assetToSell, chainId = ChainId.mainnet, quote } = useSyncedSwapQuoteStore(); - const { data: estimatedGasLimit, isFetching } = useSwapEstimatedGasLimit({ chainId, assetToSell, quote }); +export function useSwapEstimatedGasFee(overrideGasSettings?: GasSettings) { + const { assetToSell, quote, chainId = ChainId.mainnet } = useSyncedSwapQuoteStore(); + const gasSettings = useSelectedGas(chainId); - const estimatedFee = useEstimatedGasFee({ chainId, gasLimit: estimatedGasLimit, gasSettings }); + const { data: estimatedGasLimit, isFetching } = useSwapEstimatedGasLimit({ chainId, assetToSell, quote }); + const estimatedFee = useEstimatedGasFee({ chainId, gasLimit: estimatedGasLimit, gasSettings: overrideGasSettings || gasSettings }); - return useMemo(() => ({ isLoading: isFetching, data: estimatedFee }), [estimatedFee, isFetching]); + return { + data: estimatedFee, + isFetching, + }; } diff --git a/src/__swaps__/screens/Swap/hooks/useSwapEstimatedGasLimit.ts b/src/__swaps__/screens/Swap/hooks/useSwapEstimatedGasLimit.ts index c30913f3da9..9149ee472bb 100644 --- a/src/__swaps__/screens/Swap/hooks/useSwapEstimatedGasLimit.ts +++ b/src/__swaps__/screens/Swap/hooks/useSwapEstimatedGasLimit.ts @@ -5,18 +5,14 @@ import { ParsedSearchAsset } from '@/__swaps__/types/assets'; import { ChainId } from '@/__swaps__/types/chains'; import { estimateUnlockAndCrosschainSwap } from '@/raps/unlockAndCrosschainSwap'; import { estimateUnlockAndSwap } from '@/raps/unlockAndSwap'; -import { QueryConfigWithSelect, QueryFunctionArgs, QueryFunctionResult, createQueryKey, queryClient } from '@/react-query'; +import { QueryConfigWithSelect, QueryFunctionArgs, QueryFunctionResult, createQueryKey } from '@/react-query'; import { gasUnits } from '@/references/gasUnits'; // /////////////////////////////////////////////// // Query Types -export type EstimateSwapGasLimitResponse = { - gasLimit: string; -}; - -export type EstimateSwapGasLimitArgs = { - chainId: ChainId; +type EstimateSwapGasLimitArgs = { + chainId?: ChainId; quote?: Quote | CrosschainQuote | QuoteError | null; assetToSell?: ParsedSearchAsset | null; }; @@ -35,8 +31,12 @@ type EstimateSwapGasLimitQueryKey = ReturnType) { + if (!chainId) throw 'chainId is required'; if (!quote || 'error' in quote || !assetToSell) { - return gasUnits.basic_swap[chainId]; + return { + gasLimit: gasUnits.basic_swap[chainId], + chainId, + }; } const gasLimit = await (quote.swapType === SwapType.crossChain @@ -54,31 +54,16 @@ async function estimateSwapGasLimitQueryFunction({ })); if (!gasLimit) { - return gasUnits.basic_swap[chainId]; + return { + gasLimit: gasUnits.basic_swap[chainId], + chainId, + }; } - return gasLimit; + return { gasLimit, chainId }; } type EstimateSwapGasLimitResult = QueryFunctionResult; -// /////////////////////////////////////////////// -// Query Fetcher - -export async function fetchSwapEstimatedGasLimit( - { chainId, quote, assetToSell }: EstimateSwapGasLimitArgs, - config: QueryConfigWithSelect = {} -) { - return await queryClient.fetchQuery( - estimateSwapGasLimitQueryKey({ - chainId, - quote, - assetToSell, - }), - estimateSwapGasLimitQueryFunction, - config - ); -} - // /////////////////////////////////////////////// // Query Hook @@ -86,7 +71,8 @@ export function useSwapEstimatedGasLimit( { chainId, quote, assetToSell }: EstimateSwapGasLimitArgs, config: QueryConfigWithSelect = {} ) { - return useQuery( + const placeholderData = chainId && { chainId, gasLimit: gasUnits.basic_swap[chainId] }; + const { data, isFetching } = useQuery( estimateSwapGasLimitQueryKey({ chainId, quote, @@ -98,8 +84,17 @@ export function useSwapEstimatedGasLimit( cacheTime: 60 * 1000, // 1min notifyOnChangeProps: ['data', 'isFetching'], keepPreviousData: true, - placeholderData: gasUnits.basic_swap[chainId], + enabled: !!chainId && !!quote && !!assetToSell && assetToSell.chainId === chainId, + placeholderData, ...config, } ); + + // we keepPreviousData so we can return the previous gasLimit while fetching + // which is great when refetching for the same chainId, but we don't want to keep the previous data + // when fetching for a different chainId + return { + data: data && data.chainId === chainId ? data.gasLimit : placeholderData?.gasLimit, + isFetching, + }; } diff --git a/src/references/gasUnits.ts b/src/references/gasUnits.ts index 35d2f53118f..d92d4d42df2 100644 --- a/src/references/gasUnits.ts +++ b/src/references/gasUnits.ts @@ -6,12 +6,15 @@ export const gasUnits = { basic_deposit_eth: '200000', basic_swap: { [ChainId.mainnet]: '200000', - [ChainId.arbitrum]: '3500', - [ChainId.optimism]: '1000', - [ChainId.base]: '1000', + [ChainId.arbitrum]: '350000', + [ChainId.optimism]: '350000', + [ChainId.base]: '350000', [ChainId.zora]: '1000000', [ChainId.bsc]: '600000', [ChainId.polygon]: '600000', + [ChainId.avalanche]: '350000', + [ChainId.degen]: '350000', + [ChainId.blast]: '300000', }, basic_swap_permit: '400000', ens_register_with_config: '280000',