From b4142caf84a42898de3944612c7e1d05804dc0fe Mon Sep 17 00:00:00 2001 From: Evgeny Taktarov Date: Mon, 9 Sep 2024 18:08:37 +0700 Subject: [PATCH 1/6] fix: higher block fetch interval --- config/groups/web3.ts | 2 +- shared/hooks/use-balance.ts | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/config/groups/web3.ts b/config/groups/web3.ts index 0cbb31961..3e072920d 100644 --- a/config/groups/web3.ts +++ b/config/groups/web3.ts @@ -1,7 +1,7 @@ import { parseEther } from '@ethersproject/units'; // interval in ms for RPC event polling for token balance and tx updates -export const PROVIDER_POLLING_INTERVAL = 7_000; +export const PROVIDER_POLLING_INTERVAL = 12_000; // how long in ms to wait for RPC batching(multicall and provider) export const PROVIDER_BATCH_TIME = 150; diff --git a/shared/hooks/use-balance.ts b/shared/hooks/use-balance.ts index 15184941e..000ecfd1e 100644 --- a/shared/hooks/use-balance.ts +++ b/shared/hooks/use-balance.ts @@ -16,6 +16,7 @@ import { import type { AbstractLidoSDKErc20 } from '@lidofinance/lido-ethereum-sdk/erc20'; import type { GetBalanceData } from 'wagmi/query'; import type { Address, WatchContractEventOnLogsFn } from 'viem'; +import { config } from 'config'; const nativeToBN = (data: bigint) => BigNumber.from(data.toString()); @@ -24,10 +25,22 @@ const balanceToBN = (data: GetBalanceData) => nativeToBN(data.value); export const useEthereumBalance = () => { const queryClient = useQueryClient(); const { address } = useAccount(); - const { data: blockNumber } = useBlockNumber({ watch: !!address }); + const { data: blockNumber } = useBlockNumber({ + watch: { + poll: true, + pollingInterval: config.PROVIDER_POLLING_INTERVAL, + enabled: !!address, + }, + cacheTime: config.PROVIDER_POLLING_INTERVAL, + }); const queryData = useBalance({ address, - query: { select: balanceToBN, staleTime: 7000, enabled: !!address }, + query: { + select: balanceToBN, + // because we subscribe to block + staleTime: Infinity, + enabled: !!address, + }, }); useEffect(() => { From de5b5a8d974b981df6546d3d86cf9c66c14a7a0e Mon Sep 17 00:00:00 2001 From: Evgeny Taktarov Date: Mon, 9 Sep 2024 18:28:03 +0700 Subject: [PATCH 2/6] fix: disable agressive default --- providers/web3.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/providers/web3.tsx b/providers/web3.tsx index 5eeeccdd1..a7abd995f 100644 --- a/providers/web3.tsx +++ b/providers/web3.tsx @@ -22,7 +22,13 @@ type ChainsList = [wagmiChains.Chain, ...wagmiChains.Chain[]]; const wagmiChainsArray = Object.values(wagmiChains) as any as ChainsList; -const queryClient = new QueryClient(); +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + refetchOnWindowFocus: false, + }, + }, +}); const Web3Provider: FC = ({ children }) => { const { From 7a65a1e0e4116b6f9a914fec68e8c845d1151042 Mon Sep 17 00:00:00 2001 From: Evgeny Taktarov Date: Mon, 9 Sep 2024 18:34:48 +0700 Subject: [PATCH 3/6] fix: unstable query key --- shared/hooks/use-balance.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shared/hooks/use-balance.ts b/shared/hooks/use-balance.ts index 000ecfd1e..3eabdd4b3 100644 --- a/shared/hooks/use-balance.ts +++ b/shared/hooks/use-balance.ts @@ -33,6 +33,7 @@ export const useEthereumBalance = () => { }, cacheTime: config.PROVIDER_POLLING_INTERVAL, }); + const queryData = useBalance({ address, query: { @@ -50,7 +51,9 @@ export const useEthereumBalance = () => { // dedups rpc requests { cancelRefetch: false }, ); - }, [blockNumber, queryClient, queryData.queryKey]); + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [blockNumber]); return queryData; }; From dcf6b230ff8a21abdc11f391cbc571b494ffaa58 Mon Sep 17 00:00:00 2001 From: Evgeny Taktarov Date: Mon, 9 Sep 2024 18:48:24 +0700 Subject: [PATCH 4/6] fix: refetch allowance data --- features/withdrawals/hooks/contract/useRequest.ts | 8 +++++++- features/wsteth/wrap/hooks/use-wrap-tx-approve.ts | 3 +++ .../wrap/wrap-form-context/wrap-form-context.tsx | 10 +++++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/features/withdrawals/hooks/contract/useRequest.ts b/features/withdrawals/hooks/contract/useRequest.ts index 990cbe3ac..82c7d17c3 100644 --- a/features/withdrawals/hooks/contract/useRequest.ts +++ b/features/withdrawals/hooks/contract/useRequest.ts @@ -218,6 +218,7 @@ export const useWithdrawalRequest = ({ needsApprove, allowance, isLoading: loadingUseApprove, + refetch: refetchAllowance, } = useApprove( valueBN, tokenContract.address, @@ -321,7 +322,11 @@ export const useWithdrawalRequest = ({ ); } - await onConfirm?.(); + await Promise.all([ + onConfirm?.(), + isApprovalFlow && + refetchAllowance({ throwOnError: false, cancelRefetch: false }), + ]); txModalStages.success(amount, token, txHash); return true; } catch (error) { @@ -341,6 +346,7 @@ export const useWithdrawalRequest = ({ needsApprove, onConfirm, onRetry, + refetchAllowance, txModalStages, waitForTx, ], diff --git a/features/wsteth/wrap/hooks/use-wrap-tx-approve.ts b/features/wsteth/wrap/hooks/use-wrap-tx-approve.ts index 549736d85..f8fd6396f 100644 --- a/features/wsteth/wrap/hooks/use-wrap-tx-approve.ts +++ b/features/wsteth/wrap/hooks/use-wrap-tx-approve.ts @@ -32,6 +32,7 @@ export const useWrapTxApprove = ({ amount, token }: UseWrapTxApproveArgs) => { needsApprove, allowance, isLoading: isApprovalLoading, + refetch: refetchAllowance, } = useApprove( amount, stethTokenAddress, @@ -49,6 +50,7 @@ export const useWrapTxApprove = ({ amount, token }: UseWrapTxApproveArgs) => { allowance, isApprovalLoading, isApprovalNeededBeforeWrap, + refetchAllowance, }), [ allowance, @@ -56,6 +58,7 @@ export const useWrapTxApprove = ({ amount, token }: UseWrapTxApproveArgs) => { needsApprove, isApprovalLoading, processApproveTx, + refetchAllowance, ], ); }; diff --git a/features/wsteth/wrap/wrap-form-context/wrap-form-context.tsx b/features/wsteth/wrap/wrap-form-context/wrap-form-context.tsx index 245582359..b2bf010d4 100644 --- a/features/wsteth/wrap/wrap-form-context/wrap-form-context.tsx +++ b/features/wsteth/wrap/wrap-form-context/wrap-form-context.tsx @@ -5,6 +5,7 @@ import { useMemo, createContext, useContext, + useCallback, } from 'react'; import { useForm, FormProvider } from 'react-hook-form'; import { useWrapTxApprove } from '../hooks/use-wrap-tx-approve'; @@ -72,9 +73,16 @@ export const WrapFormProvider: FC = ({ children }) => { const approvalData = useWrapTxApprove({ amount: amount ?? Zero, token }); const isSteth = token === TOKENS_TO_WRAP.STETH; + const onConfirm = useCallback(async () => { + await Promise.allSettled([ + networkData.revalidateWrapFormData(), + approvalData.refetchAllowance(), + ]); + }, [networkData, approvalData]); + const processWrapFormFlow = useWrapFormProcessor({ approvalData, - onConfirm: networkData.revalidateWrapFormData, + onConfirm, onRetry: retryFire, }); From 5e226a81d177cc65673d090c5ed2a9c6e1ea9569 Mon Sep 17 00:00:00 2001 From: Evgeny Taktarov Date: Mon, 9 Sep 2024 20:22:22 +0700 Subject: [PATCH 5/6] fix: allowance events --- shared/hooks/use-allowance.ts | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/shared/hooks/use-allowance.ts b/shared/hooks/use-allowance.ts index 2111f11ac..63061d661 100644 --- a/shared/hooks/use-allowance.ts +++ b/shared/hooks/use-allowance.ts @@ -1,7 +1,7 @@ import { useQueryClient } from '@tanstack/react-query'; import { BigNumber } from 'ethers'; import { useCallback, useMemo } from 'react'; -import { Address } from 'viem'; +import { Address, WatchContractEventOnLogsFn } from 'viem'; import { useReadContract, useWatchContractEvent } from 'wagmi'; const nativeToBN = (data: bigint) => BigNumber.from(data.toString()); @@ -50,6 +50,12 @@ const Erc20AllowanceAbi = [ }, ] as const; +type OnLogsFn = WatchContractEventOnLogsFn< + typeof Erc20AllowanceAbi, + 'Transfer' | 'Approval', + true +>; + type UseAllowanceProps = { token: Address; account: Address; @@ -72,14 +78,19 @@ export const useAllowance = ({ query: { enabled, select: nativeToBN }, }); - const onLogs = useCallback(() => { - void queryClient.invalidateQueries( - { - queryKey: allowanceQuery.queryKey, - }, - { cancelRefetch: false }, - ); - }, [allowanceQuery.queryKey, queryClient]); + const onLogs: OnLogsFn = useCallback( + () => { + void queryClient.invalidateQueries( + { + queryKey: allowanceQuery.queryKey, + }, + { cancelRefetch: false }, + ); + }, + // queryKey is unstable + // eslint-disable-next-line react-hooks/exhaustive-deps + [account, spender, token], + ); useWatchContractEvent({ abi: Erc20AllowanceAbi, From 491b420a4f501a2a14e6007483f556449dbb206c Mon Sep 17 00:00:00 2001 From: Evgeny Taktarov Date: Mon, 9 Sep 2024 21:05:56 +0700 Subject: [PATCH 6/6] test: remove deprecated endpoints from test --- test/consts.ts | 69 -------------------------------------------------- 1 file changed, 69 deletions(-) diff --git a/test/consts.ts b/test/consts.ts index 8dae119cd..47faf7e0a 100644 --- a/test/consts.ts +++ b/test/consts.ts @@ -13,68 +13,7 @@ export interface PostRequest { schema: object; } -const FLOAT_REGEX = /^\d+(\.\d+)?$/; - export const GET_REQUESTS: GetRequest[] = [ - { - uri: '/api/oneinch-rate?token=ETH', - isDeprecated: true, - schema: { - type: 'object', - properties: { - rate: { type: 'number', min: 0 }, - toReceive: { type: 'string' }, - fromAmount: { type: 'string' }, - }, - required: ['rate', 'toReceive', 'fromAmount'], - additionalProperties: false, - }, - }, - { - uri: `/api/short-lido-stats?chainId=${CONFIG.STAND_CONFIG.chainId}`, - isDeprecated: true, - schema: { - type: 'object', - properties: { - uniqueAnytimeHolders: { type: 'string' }, - uniqueHolders: { type: 'string' }, - totalStaked: { type: 'string' }, - marketCap: { type: 'number' }, - }, - required: [ - 'totalStaked', - 'marketCap', - 'uniqueAnytimeHolders', - 'uniqueHolders', - ], - additionalProperties: true, - }, - }, - { - uri: '/api/eth-apr', - isDeprecated: true, - schema: { type: 'string', pattern: FLOAT_REGEX }, - }, - { - uri: '/api/totalsupply', - isDeprecated: true, - schema: { type: 'string', pattern: FLOAT_REGEX }, - }, - { - uri: '/api/eth-price', - isDeprecated: true, - schema: { - type: 'object', - properties: { - price: { - type: 'number', - min: 0, - }, - }, - required: ['price'], - additionalProperties: true, - }, - }, { uri: '/api/rewards?address=0x87c0e047F4e4D3e289A56a36570D4CB957A37Ef1¤cy=usd&onlyRewards=false&archiveRate=true&skip=0&limit=10', skipTestnet: true, // api/rewards don't work on testnet @@ -121,14 +60,6 @@ export const GET_REQUESTS: GetRequest[] = [ }, }, }, - { - uri: '/api/sma-steth-apr', - isDeprecated: true, - schema: { - type: 'string', - pattern: FLOAT_REGEX, - }, - }, ]; export const POST_REQUESTS: PostRequest[] = [