diff --git a/apps/web/src/hooks/usePublicNodeWaitForTransaction.ts b/apps/web/src/hooks/usePublicNodeWaitForTransaction.ts index 4a6c449099739..d482fbd007a35 100644 --- a/apps/web/src/hooks/usePublicNodeWaitForTransaction.ts +++ b/apps/web/src/hooks/usePublicNodeWaitForTransaction.ts @@ -103,7 +103,7 @@ export function usePublicNodeWaitForTransaction(chainId_?: number) { } } const bufferedAvgBlockTime = - (selectedChain ? AVERAGE_CHAIN_BLOCK_TIMES[selectedChain] : BSC_BLOCK_TIME) * 1000 + 1000 + (selectedChain ? AVERAGE_CHAIN_BLOCK_TIMES[selectedChain] ?? BSC_BLOCK_TIME : BSC_BLOCK_TIME) * 1000 + 1000 return retryExp(getTransaction, { n: 10, base: bufferedAvgBlockTime, diff --git a/apps/web/src/state/transactions/updater.tsx b/apps/web/src/state/transactions/updater.tsx index a488a956e3ab5..45558c48487c7 100644 --- a/apps/web/src/state/transactions/updater.tsx +++ b/apps/web/src/state/transactions/updater.tsx @@ -14,7 +14,7 @@ import { WaitForTransactionReceiptTimeoutError, } from 'viem' import { usePublicClient } from 'wagmi' -import { retry, RetryableError } from 'state/multicall/retry' +import { RetryableError, retryExp } from 'state/multicall/retry' import { useQuery } from '@tanstack/react-query' import { AVERAGE_CHAIN_BLOCK_TIMES, NonEVMChainId } from '@pancakeswap/chains' import { BSC_BLOCK_TIME } from 'config' @@ -108,11 +108,13 @@ export const Updater: React.FC<{ chainId: number }> = ({ chainId }) => { merge(fetchedTransactions.current, { [transaction.hash]: transactions[transaction.hash] }) } } - retry(getTransaction, { + const bufferedAvgBlockTime = + (chainId ? AVERAGE_CHAIN_BLOCK_TIMES[chainId] ?? BSC_BLOCK_TIME : BSC_BLOCK_TIME) * 1000 + 1000 + retryExp(getTransaction, { n: 10, - minWait: 5000, - maxWait: 10000, - delay: (AVERAGE_CHAIN_BLOCK_TIMES[chainId] ?? BSC_BLOCK_TIME) * 1000 + 1000, + base: bufferedAvgBlockTime, + delay: bufferedAvgBlockTime, + factor: 1.5, }) }, ) @@ -302,11 +304,12 @@ export const SolanaTransactionUpdater = () => { merge(fetchedTransactions.current, { [transaction.hash]: transactions[transaction.hash] }) } } - retry(getTransaction, { + const bufferedAvgBlockTime = (AVERAGE_CHAIN_BLOCK_TIMES[NonEVMChainId.SOLANA] ?? BSC_BLOCK_TIME) * 1000 + 1000 + retryExp(getTransaction, { n: 10, - minWait: 5000, - maxWait: 10000, - delay: BSC_BLOCK_TIME * 1000 + 1000, + base: bufferedAvgBlockTime, + delay: bufferedAvgBlockTime, + factor: 1.5, }) }, ) diff --git a/apps/web/src/views/Swap/V3Swap/hooks/steps/useBatchSwapTransaction.ts b/apps/web/src/views/Swap/V3Swap/hooks/steps/useBatchSwapTransaction.ts index 309a48adfa841..dd386cf610fa3 100644 --- a/apps/web/src/views/Swap/V3Swap/hooks/steps/useBatchSwapTransaction.ts +++ b/apps/web/src/views/Swap/V3Swap/hooks/steps/useBatchSwapTransaction.ts @@ -6,14 +6,15 @@ import { useTranslation } from '@pancakeswap/localization' import { useToast } from '@pancakeswap/uikit' import { useEIP5792Status } from 'hooks/useIsEIP5792Supported' import { ConfirmModalState } from '@pancakeswap/widgets-internal' -import { RetryableError, retry } from 'state/multicall/retry' +import { RetryableError, retryExp } from 'state/multicall/retry' import { useActiveChainId } from 'hooks/useAccountActiveChain' -import { ChainId as EvmChainId } from '@pancakeswap/chains' +import { AVERAGE_CHAIN_BLOCK_TIMES, ChainId as EvmChainId } from '@pancakeswap/chains' import { InterfaceOrder, isBridgeOrder } from 'views/Swap/utils' import { activeBridgeOrderMetadataAtom } from 'views/Swap/Bridge/CrossChainConfirmSwapModal/state/orderDataState' import { useSetAtom } from 'jotai' import { useTransactionAdder } from 'state/transactions/hooks' +import { BSC_BLOCK_TIME } from 'config' import { BatchCall, getBatchedTransaction as getBatchedTransactionHelper } from '../batchHelper' import { eip5792UserRejectUpgradeError, userRejectedError } from '../useSendSwapTransaction' import useSwapRecordTransaction from '../useSwapRecordTransaction' @@ -141,8 +142,10 @@ export const useBatchSwapTransaction = ({ if (!result?.id || !result.client) { return } - - const { promise: statusPromise } = retry( + const chainId = order?.trade?.inputAmount?.currency?.chainId + const bufferedAvgBlockTime = + (chainId ? AVERAGE_CHAIN_BLOCK_TIMES[chainId] ?? BSC_BLOCK_TIME : BSC_BLOCK_TIME) * 1000 + 1000 + const { promise: statusPromise } = retryExp( async () => { const status = await result.client.getCallsStatus({ id: result.id }) @@ -154,7 +157,12 @@ export const useBatchSwapTransaction = ({ } return status }, - { n: 10, minWait: 2000, maxWait: 3500 }, + { + n: 10, + base: bufferedAvgBlockTime, + delay: bufferedAvgBlockTime, + factor: 1.5, + }, ) const status = await statusPromise diff --git a/apps/web/src/views/Swap/V3Swap/hooks/steps/useSolSwapStep.tsx b/apps/web/src/views/Swap/V3Swap/hooks/steps/useSolSwapStep.tsx index d339a27655ad6..01197846c1ed1 100644 --- a/apps/web/src/views/Swap/V3Swap/hooks/steps/useSolSwapStep.tsx +++ b/apps/web/src/views/Swap/V3Swap/hooks/steps/useSolSwapStep.tsx @@ -4,7 +4,7 @@ import { useToast } from '@pancakeswap/uikit' import { ConfirmModalState } from '@pancakeswap/widgets-internal' import { SolanaDescriptionWithTx } from 'components/Toast' import { useCallback, useMemo } from 'react' -import { RetryableError, retry } from 'state/multicall/retry' +import { RetryableError, retryExp } from 'state/multicall/retry' import { isSVMOrder } from 'views/Swap/utils' import { VersionedTransaction } from '@solana/web3.js' import { UltraSwapError, UltraSwapErrorType, ultraSwapService } from '@pancakeswap/solana-router-sdk' @@ -15,6 +15,8 @@ import { useRefreshSolanaTokenBalances } from 'state/token/solanaTokenBalances' import { useSolanaConnectionWithRpcAtom } from 'hooks/solana/useSolanaConnectionWithRpcAtom' import MultisigToastDescription from 'components/Toast/MultisigToastDescription' import { isMultisigWallet } from 'utils/solana/isMultisigWallet' +import { AVERAGE_CHAIN_BLOCK_TIMES, NonEVMChainId } from '@pancakeswap/chains' +import { BSC_BLOCK_TIME } from 'config' import useSwapRecordTransaction from '../useSwapRecordTransaction' import { ConfirmStepContext } from './step.type' @@ -37,7 +39,13 @@ export const useSolSwapStep = (context: ConfirmStepContext) => { throw new RetryableError() } } - const { promise } = retry(waitTx, { n: 5, minWait: 3000, maxWait: 5000 }) + const bufferedAvgBlockTime = (AVERAGE_CHAIN_BLOCK_TIMES[NonEVMChainId.SOLANA] ?? BSC_BLOCK_TIME) * 1000 + 1000 + const { promise } = retryExp(waitTx, { + n: 10, + base: bufferedAvgBlockTime, + delay: bufferedAvgBlockTime, + factor: 1.5, + }) return promise }, [connection], diff --git a/apps/web/src/views/Swap/V3Swap/hooks/useConfirmModalState.tsx b/apps/web/src/views/Swap/V3Swap/hooks/useConfirmModalState.tsx index 08a61635cc9e4..9cce84c364360 100644 --- a/apps/web/src/views/Swap/V3Swap/hooks/useConfirmModalState.tsx +++ b/apps/web/src/views/Swap/V3Swap/hooks/useConfirmModalState.tsx @@ -17,7 +17,7 @@ import { usePermit2Requires } from 'hooks/usePermit2Requires' import { useSafeTxHashTransformer } from 'hooks/useSafeTxHashTransformer' import { useTransactionDeadline } from 'hooks/useTransactionDeadline' import { useCallback, useEffect, useMemo, useState } from 'react' -import { RetryableError, retry } from 'state/multicall/retry' +import { RetryableError, retryExp } from 'state/multicall/retry' import { useCurrencyBalance } from 'state/wallet/hooks' import { logGTMSwapTxSentEvent } from 'utils/customGTMEventTracking' import { UserUnexpectedTxError } from 'utils/errors' @@ -42,7 +42,7 @@ import { useSetAtom } from 'jotai' import { getBridgeCalldata, getSolanaToEVMBridgeCalldata } from 'views/Swap/Bridge/api' import { useBridgeCheckApproval } from 'views/Swap/Bridge/hooks' -import { ChainId as EvmChainId, isSolana } from '@pancakeswap/chains' +import { AVERAGE_CHAIN_BLOCK_TIMES, ChainId as EvmChainId, isSolana } from '@pancakeswap/chains' import { useUserSlippage } from '@pancakeswap/utils/user' import { useSwapState } from 'state/swap/hooks' import { activeBridgeOrderMetadataAtom } from 'views/Swap/Bridge/CrossChainConfirmSwapModal/state/orderDataState' @@ -62,6 +62,7 @@ import { calculateGasMargin } from 'utils' import { viemClients } from 'utils/viem' import MultisigToastDescription from 'components/Toast/MultisigToastDescription' import { isMultisigWallet } from 'utils/solana/isMultisigWallet' +import { BSC_BLOCK_TIME } from 'config' import { ConfirmStepContext, ConfirmAction } from './steps/step.type' import { useBatchSwapTransaction } from './steps/useBatchSwapTransaction' import { useSolSwapStep } from './steps/useSolSwapStep' @@ -236,10 +237,13 @@ const useConfirmActions = ( throw error } } - const { promise } = retry(getReceipt, { - n: 6, - minWait: 2000, - maxWait: confirmations ? confirmations * 5000 : 5000, + const bufferedAvgBlockTime = + (chainId ? AVERAGE_CHAIN_BLOCK_TIMES[chainId] ?? BSC_BLOCK_TIME : BSC_BLOCK_TIME) * 1000 + 1000 + const { promise } = retryExp(getReceipt, { + n: 10, + base: bufferedAvgBlockTime, + delay: bufferedAvgBlockTime, + factor: 1.5, }) return promise } diff --git a/packages/chains/src/averageChainBlockTimes.ts b/packages/chains/src/averageChainBlockTimes.ts index ba4893848f52d..230de437eb8bd 100644 --- a/packages/chains/src/averageChainBlockTimes.ts +++ b/packages/chains/src/averageChainBlockTimes.ts @@ -1,10 +1,10 @@ -import { ChainId } from './chainId' +import { ChainId, NonEVMChainId, UnifiedChainId } from './chainId' -export const AVERAGE_CHAIN_BLOCK_TIMES: Record = { +export const AVERAGE_CHAIN_BLOCK_TIMES: Record = { [ChainId.BSC]: 0.45, [ChainId.BSC_TESTNET]: 0.45, - [ChainId.OPBNB]: 0.5, - [ChainId.OPBNB_TESTNET]: 0.5, + [ChainId.OPBNB]: 0.25, + [ChainId.OPBNB_TESTNET]: 0.25, [ChainId.ETHEREUM]: 12, [ChainId.GOERLI]: 3, [ChainId.ZKSYNC]: 2, @@ -21,4 +21,6 @@ export const AVERAGE_CHAIN_BLOCK_TIMES: Record = { [ChainId.SEPOLIA]: 0, [ChainId.MONAD_MAINNET]: 1, [ChainId.MONAD_TESTNET]: 1, + [NonEVMChainId.SOLANA]: 0.4, + [NonEVMChainId.APTOS]: 0.1, }