diff --git a/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts b/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts index 39e905631e82..847df1204ab3 100644 --- a/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts +++ b/ui/pages/bridge/hooks/useSubmitBridgeTransaction.ts @@ -2,18 +2,25 @@ import { useDispatch, useSelector } from 'react-redux'; import { zeroAddress } from 'ethereumjs-util'; import { useHistory } from 'react-router-dom'; import { TransactionMeta } from '@metamask/transaction-controller'; +import { createProjectLogger, Hex } from '@metamask/utils'; import { QuoteMetadata, QuoteResponse } from '../types'; import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'; import { setDefaultHomeActiveTabName } from '../../../store/actions'; import { startPollingForBridgeTxStatus } from '../../../ducks/bridge-status/actions'; import { getQuoteRequest } from '../../../ducks/bridge/selectors'; +import { CHAIN_IDS } from '../../../../shared/constants/network'; +import { getCurrentChainId } from '../../../../shared/modules/selectors/networks'; import useAddToken from './useAddToken'; import useHandleApprovalTx from './useHandleApprovalTx'; import useHandleBridgeTx from './useHandleBridgeTx'; +const debugLog = createProjectLogger('bridge'); +const LINEA_DELAY_MS = 5000; + export default function useSubmitBridgeTransaction() { const history = useHistory(); const dispatch = useDispatch(); + const srcChainId = useSelector(getCurrentChainId); const { addSourceToken, addDestToken } = useAddToken(); const { handleApprovalTx } = useHandleApprovalTx(); const { handleBridgeTx } = useHandleBridgeTx(); @@ -33,6 +40,24 @@ export default function useSubmitBridgeTransaction() { }); } + if ( + ( + [ + CHAIN_IDS.LINEA_MAINNET, + CHAIN_IDS.LINEA_GOERLI, + CHAIN_IDS.LINEA_SEPOLIA, + ] as Hex[] + ).includes(srcChainId) + ) { + debugLog( + 'Delaying submitting bridge tx to make Linea confirmation more likely', + ); + const waitPromise = new Promise((resolve) => + setTimeout(resolve, LINEA_DELAY_MS), + ); + await waitPromise; + } + const bridgeTxMeta = await handleBridgeTx({ quoteResponse, approvalTxId: approvalTxMeta?.id, diff --git a/ui/pages/bridge/prepare/bridge-cta-button.tsx b/ui/pages/bridge/prepare/bridge-cta-button.tsx index c8738a6551de..931b6cb4e8ea 100644 --- a/ui/pages/bridge/prepare/bridge-cta-button.tsx +++ b/ui/pages/bridge/prepare/bridge-cta-button.tsx @@ -35,6 +35,7 @@ export const BridgeCTAButton = () => { const { maxRefreshCount, refreshRate } = useSelector(getBridgeQuotesConfig); const { submitBridgeTransaction } = useSubmitBridgeTransaction(); + const [isSubmitting, setIsSubmitting] = useState(false); const { isNoQuotesAvailable, isInsufficientBalance } = useSelector(getValidationErrors); @@ -108,20 +109,29 @@ export const BridgeCTAButton = () => { data-testid="bridge-cta-button" onClick={() => { if (activeQuote && isTxSubmittable) { - quoteRequestProperties && - requestMetadataProperties && - tradeProperties && - trackCrossChainSwapsEvent({ - event: MetaMetricsEventName.ActionSubmitted, - properties: { - ...quoteRequestProperties, - ...requestMetadataProperties, - ...tradeProperties, - }, - }); - submitBridgeTransaction(activeQuote); + try { + // We don't need to worry about setting to true if the tx submission succeeds + // because we route immediately to Activity list page + setIsSubmitting(true); + + quoteRequestProperties && + requestMetadataProperties && + tradeProperties && + trackCrossChainSwapsEvent({ + event: MetaMetricsEventName.ActionSubmitted, + properties: { + ...quoteRequestProperties, + ...requestMetadataProperties, + ...tradeProperties, + }, + }); + submitBridgeTransaction(activeQuote); + } catch (error) { + setIsSubmitting(false); + } } }} + loading={isSubmitting} disabled={!isTxSubmittable || isQuoteExpired} > {label}