Skip to content

Commit

Permalink
feat: Trigger block data after trx to reflect changes immediately wit…
Browse files Browse the repository at this point in the history
…hout waiting interval (#10308)

<!--
Before opening a pull request, please read the [contributing
guidelines](https://github.com/pancakeswap/pancake-frontend/blob/develop/CONTRIBUTING.md)
first
-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces improvements related to transaction handling and
block data fetching.

### Detailed summary
- Updated transaction handling logic in
`usePublicNodeWaitForTransaction`
- Refactored block data fetching with `useFetchBlockData`
- Updated dependencies and imports in various files

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your
question}`

<!-- end pr-codex -->
  • Loading branch information
memoyil authored Aug 7, 2024
1 parent 4451cb0 commit 97ba821
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 19 deletions.
5 changes: 0 additions & 5 deletions apps/web/src/hooks/useCatchTxError.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,6 @@ export default function useCatchTxError(params?: Params) {
try {
setTxResponseLoading(true)

/**
* https://github.com/vercel/swr/pull/1450
*
* wait for useSWRMutation finished, so we could apply SWR in case manually trigger tx call
*/
tx = await callTx()

if (!tx) return null
Expand Down
16 changes: 13 additions & 3 deletions apps/web/src/hooks/usePublicNodeWaitForTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
http,
} from 'viem'
import { usePublicClient } from 'wagmi'
import { useFetchBlockData } from '@pancakeswap/wagmi'
import { useActiveChainId } from './useActiveChainId'

export const viemClientsPublicNodes = CHAINS.reduce((prev, cur) => {
Expand Down Expand Up @@ -45,6 +46,7 @@ export type PublicNodeWaitForTransactionParams = GetTransactionReceiptParameters
export function usePublicNodeWaitForTransaction() {
const { chainId } = useActiveChainId()
const provider = usePublicClient({ chainId })
const refetchBlockData = useFetchBlockData(chainId)

const waitForTransaction_ = useCallback(
async (opts: PublicNodeWaitForTransactionParams): Promise<TransactionReceipt> => {
Expand All @@ -53,12 +55,20 @@ export function usePublicNodeWaitForTransaction() {
const selectedChain = opts?.chainId ?? chainId
// our custom node might be late to sync up
if (selectedChain && viemClientsPublicNodes[selectedChain]) {
return await viemClientsPublicNodes[selectedChain].getTransactionReceipt({ hash: opts.hash })
const receipt = await viemClientsPublicNodes[selectedChain].getTransactionReceipt({ hash: opts.hash })
if (receipt.status === 'success') {
refetchBlockData()
}
return receipt
}

if (!provider) return undefined

return await provider.getTransactionReceipt({ hash: opts.hash })
const receipt = await provider.getTransactionReceipt({ hash: opts.hash })
if (receipt.status === 'success') {
refetchBlockData()
}
return receipt
} catch (error) {
if (error instanceof TransactionNotFoundError) {
throw new RetryableError(`Transaction not found: ${opts.hash}`)
Expand All @@ -79,7 +89,7 @@ export function usePublicNodeWaitForTransaction() {
delay: (chainId ? AVERAGE_CHAIN_BLOCK_TIMES[chainId] : BSC_BLOCK_TIME) * 1000 + 1000,
}).promise as Promise<TransactionReceipt>
},
[chainId, provider],
[chainId, provider, refetchBlockData],
)

return {
Expand Down
6 changes: 3 additions & 3 deletions apps/web/src/state/block/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ export const useChainCurrentBlock = (chainId: number) => {
const { chainId: activeChainId } = useActiveChainId()
const activeChainBlockNumber = useCurrentBlock()
const isTargetDifferent = Boolean(chainId && activeChainId !== chainId)
const { data: currentBlock } = useWagmiBlockNumber({
const { data: targetChainBlockNumber } = useWagmiBlockNumber({
chainId,
watch: true,
query: {
enabled: Boolean(isTargetDifferent),
enabled: isTargetDifferent,
select: (data) => (data !== undefined ? Number(data) : undefined),
},
})
const targetChainBlockNumber = currentBlock !== undefined ? Number(currentBlock) : undefined

return isTargetDifferent ? targetChainBlockNumber : activeChainBlockNumber
}
Expand Down
12 changes: 11 additions & 1 deletion apps/web/src/state/transactions/updater.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { retry, RetryableError } from 'state/multicall/retry'
import { useQuery } from '@tanstack/react-query'
import { AVERAGE_CHAIN_BLOCK_TIMES } from 'config/constants/averageChainBlockTimes'
import { BSC_BLOCK_TIME } from 'config'
import { useFetchBlockData } from '@pancakeswap/wagmi'
import {
FarmTransactionStatus,
MsgStatus,
Expand All @@ -43,6 +44,7 @@ export const Updater: React.FC<{ chainId: number }> = ({ chainId }) => {

const dispatch = useAppDispatch()
const transactions = useAllChainTransactions(chainId)
const refetchBlockData = useFetchBlockData(chainId)

const { toastError, toastSuccess } = useToast()

Expand All @@ -51,6 +53,8 @@ export const Updater: React.FC<{ chainId: number }> = ({ chainId }) => {
useEffect(() => {
if (!chainId || !provider) return

let toRefetchBlockData = false

forEach(
pickBy(transactions, (transaction) => shouldCheck(fetchedTransactions.current, transaction)),
(transaction) => {
Expand All @@ -75,6 +79,9 @@ export const Updater: React.FC<{ chainId: number }> = ({ chainId }) => {
}),
)
const toast = receipt.status === 'success' ? toastSuccess : toastError
if (!toRefetchBlockData && receipt.status === 'success') {
toRefetchBlockData = true
}
toast(
t('Transaction receipt'),
<ToastDescriptionWithTx txHash={receipt.transactionHash} txChainId={chainId} />,
Expand Down Expand Up @@ -102,7 +109,10 @@ export const Updater: React.FC<{ chainId: number }> = ({ chainId }) => {
})
},
)
}, [chainId, provider, transactions, dispatch, toastSuccess, toastError, t])
if (toRefetchBlockData) {
refetchBlockData()
}
}, [chainId, provider, transactions, dispatch, toastSuccess, toastError, t, refetchBlockData])

const crossChainFarmPendingTxns = useMemo(
() =>
Expand Down
43 changes: 36 additions & 7 deletions packages/wagmi/src/hooks/useBlock.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useQuery, useQueryClient } from '@tanstack/react-query'
import { useBlock, useWatchBlocks, useBlockNumber as useWagmiBlockNumber } from 'wagmi'
import { useEffect } from 'react'
import { QueryClient, useQuery, useQueryClient } from '@tanstack/react-query'
import { useBlock, useWatchBlocks, useBlockNumber as useWagmiBlockNumber, usePublicClient } from 'wagmi'
import { useCallback, useEffect } from 'react'

type Params = {
chainId?: number
Expand All @@ -13,6 +13,20 @@ function createKeyGetter(name: string) {
}
}

const updateBlockQueryData = (
queryClient: QueryClient,
chainId: number | undefined,
block: { number: bigint; timestamp: bigint },
) => {
if (chainId) {
const blockNumber = Number(block.number)
const timestamp = Number(block.timestamp)

queryClient.setQueryData(getBlockNumberQueryKey(chainId), blockNumber)
queryClient.setQueryData(getBlockTimestampQueryKey(chainId), timestamp)
}
}

export const getBlockNumberQueryKey = createKeyGetter('blockNumber')
export const getBlockTimestampQueryKey = createKeyGetter('blockTimestamp')
export const getInitialBlockNumberQueryKey = createKeyGetter('initialBlockNumber')
Expand Down Expand Up @@ -61,10 +75,7 @@ export function useWatchBlock({ chainId, enabled }: Params) {
blockTag: 'latest',
enabled: queryEnabled,
onBlock: (data) => {
const blockNumber = Number(data.number)
const timestamp = Number(data.timestamp)
queryClient.setQueryData(getBlockNumberQueryKey(chainId), blockNumber)
queryClient.setQueryData(getBlockTimestampQueryKey(chainId), timestamp)
updateBlockQueryData(queryClient, chainId, data)
},
})
}
Expand Down Expand Up @@ -119,3 +130,21 @@ export function useInitialBlockTimestamp({ chainId }: Omit<Params, 'enabled'>) {
refetchOnMount: false,
})
}

export const useFetchBlockData = (chainId: number) => {
const queryClient = useQueryClient()
const provider = usePublicClient({ chainId })

const refetchBlockData = useCallback(async () => {
try {
if (provider) {
const block = await provider.getBlock()
updateBlockQueryData(queryClient, chainId, block)
}
} catch (error) {
console.error('Error fetching block data:', error)
}
}, [provider, queryClient, chainId])

return refetchBlockData
}

0 comments on commit 97ba821

Please sign in to comment.