diff --git a/src/components/tx-flow/SafeTxProvider.tsx b/src/components/tx-flow/SafeTxProvider.tsx index 61a7393698..a268244484 100644 --- a/src/components/tx-flow/SafeTxProvider.tsx +++ b/src/components/tx-flow/SafeTxProvider.tsx @@ -13,6 +13,8 @@ export const SafeTxContext = createContext<{ nonce?: number setNonce: Dispatch> + nonceNeeded?: boolean + setNonceNeeded: Dispatch> safeTxGas?: number setSafeTxGas: Dispatch> @@ -22,6 +24,7 @@ export const SafeTxContext = createContext<{ setSafeTx: () => {}, setSafeTxError: () => {}, setNonce: () => {}, + setNonceNeeded: () => {}, setSafeTxGas: () => {}, }) @@ -31,6 +34,7 @@ const SafeTxProvider = ({ children }: { children: ReactNode }): ReactElement => const [safeTx, setSafeTx] = useState() const [safeTxError, setSafeTxError] = useState() const [nonce, setNonce] = useState() + const [nonceNeeded, setNonceNeeded] = useState(true) const [safeTxGas, setSafeTxGas] = useState() // Signed txs cannot be updated @@ -63,6 +67,8 @@ const SafeTxProvider = ({ children }: { children: ReactNode }): ReactElement => setSafeTxError, nonce: finalNonce, setNonce, + nonceNeeded, + setNonceNeeded, safeTxGas: finalSafeTxGas, setSafeTxGas, recommendedNonce, diff --git a/src/components/tx-flow/common/TxLayout/index.tsx b/src/components/tx-flow/common/TxLayout/index.tsx index 49835873f4..652f633055 100644 --- a/src/components/tx-flow/common/TxLayout/index.tsx +++ b/src/components/tx-flow/common/TxLayout/index.tsx @@ -1,10 +1,10 @@ -import { type ComponentType, type ReactElement, type ReactNode, useEffect, useState } from 'react' +import { type ComponentType, type ReactElement, type ReactNode, useContext, useEffect, useState } from 'react' import { Box, Container, Grid, Typography, Button, Paper, SvgIcon, IconButton, useMediaQuery } from '@mui/material' import { useTheme } from '@mui/material/styles' import type { TransactionSummary } from '@safe-global/safe-gateway-typescript-sdk' import classnames from 'classnames' import { ProgressBar } from '@/components/common/ProgressBar' -import SafeTxProvider from '../../SafeTxProvider' +import SafeTxProvider, { SafeTxContext } from '../../SafeTxProvider' import { TxInfoProvider } from '@/components/tx-flow/TxInfoProvider' import TxNonce from '../TxNonce' import TxStatusWidget from '../TxStatusWidget' @@ -15,6 +15,38 @@ import { RedefineMessage } from '@/components/tx/security/redefine' import { TxSecurityProvider } from '@/components/tx/security/shared/TxSecurityContext' import ChainIndicator from '@/components/common/ChainIndicator' +const TxLayoutHeader = ({ + hideNonce, + icon, + subtitle, +}: { + hideNonce: TxLayoutProps['hideNonce'] + icon: TxLayoutProps['icon'] + subtitle: TxLayoutProps['subtitle'] +}) => { + const { nonceNeeded } = useContext(SafeTxContext) + + if (hideNonce && !icon && !subtitle) return null + + return ( + + + {icon && ( +
+ +
+ )} + + + {subtitle} + +
+ + {!hideNonce && nonceNeeded && } +
+ ) +} + type TxLayoutProps = { title: ReactNode children: ReactNode @@ -87,23 +119,7 @@ const TxLayout = ({ - {!hideNonce || icon || subtitle ? ( - - - {icon && ( -
- -
- )} - - - {subtitle} - -
- - {!hideNonce && } -
- ) : null} +
diff --git a/src/components/tx-flow/common/TxStatusWidget/index.tsx b/src/components/tx-flow/common/TxStatusWidget/index.tsx index f9b52edca1..30862c0516 100644 --- a/src/components/tx-flow/common/TxStatusWidget/index.tsx +++ b/src/components/tx-flow/common/TxStatusWidget/index.tsx @@ -9,6 +9,8 @@ import css from './styles.module.css' import CloseIcon from '@mui/icons-material/Close' import useWallet from '@/hooks/wallets/useWallet' import SafeLogo from '@/public/images/logo-no-text.svg' +import { useContext } from 'react' +import { SafeTxContext } from '@/components/tx-flow/SafeTxProvider' const confirmedMessage = (threshold: number, confirmations: number) => { return ( @@ -33,6 +35,7 @@ const TxStatusWidget = ({ }) => { const wallet = useWallet() const { safe } = useSafeInfo() + const { nonceNeeded } = useContext(SafeTxContext) const { threshold } = safe const { executionInfo = undefined } = txSummary || {} @@ -73,6 +76,8 @@ const TxStatusWidget = ({ {isBatch ? ( 'Create batch' + ) : !nonceNeeded ? ( + 'Confirmed' ) : ( <> {confirmedMessage(threshold, confirmationsSubmitted)} diff --git a/src/components/tx-flow/flows/TokenTransfer/ReviewSpendingLimitTx.tsx b/src/components/tx-flow/flows/TokenTransfer/ReviewSpendingLimitTx.tsx index 4ea209735f..de888e8f7a 100644 --- a/src/components/tx-flow/flows/TokenTransfer/ReviewSpendingLimitTx.tsx +++ b/src/components/tx-flow/flows/TokenTransfer/ReviewSpendingLimitTx.tsx @@ -1,5 +1,5 @@ import type { ReactElement, SyntheticEvent } from 'react' -import { useMemo, useState } from 'react' +import { useContext, useMemo, useState } from 'react' import type { BigNumberish, BytesLike } from 'ethers' import { Button, CardActions, Typography } from '@mui/material' import SendToBlock from '@/components/tx-flow/flows/TokenTransfer/SendToBlock' @@ -22,6 +22,7 @@ import useOnboard from '@/hooks/wallets/useOnboard' import { WrongChainWarning } from '@/components/tx/WrongChainWarning' import { asError } from '@/services/exceptions/utils' import TxCard from '@/components/tx-flow/common/TxCard' +import { TxModalContext } from '@/components/tx-flow' export type SpendingLimitTxParams = { safeAddress: string @@ -43,6 +44,7 @@ const ReviewSpendingLimitTx = ({ }): ReactElement => { const [isSubmittable, setIsSubmittable] = useState(true) const [submitError, setSubmitError] = useState() + const { setTxFlow } = useContext(TxModalContext) const currentChain = useCurrentChain() const onboard = useOnboard() const { safe, safeAddress } = useSafeInfo() @@ -88,7 +90,7 @@ const ReviewSpendingLimitTx = ({ try { await dispatchSpendingLimitTxExecution(txParams, txOptions, onboard, safe.chainId, safeAddress) - + setTxFlow(undefined) onSubmit() } catch (_err) { const err = asError(_err) diff --git a/src/components/tx/SpendingLimitRow/index.tsx b/src/components/tx/SpendingLimitRow/index.tsx index a85e6a3990..6a4a1e9279 100644 --- a/src/components/tx/SpendingLimitRow/index.tsx +++ b/src/components/tx/SpendingLimitRow/index.tsx @@ -12,6 +12,8 @@ import { HelpCenterArticle } from '@/config/constants' import css from './styles.module.css' import { TokenAmountFields } from '@/components/common/TokenAmountInput' +import { useContext } from 'react' +import { SafeTxContext } from '@/components/tx-flow/SafeTxProvider' const SpendingLimitRow = ({ availableAmount, @@ -22,6 +24,7 @@ const SpendingLimitRow = ({ }) => { const { control, trigger } = useFormContext() const isOnlySpendLimitBeneficiary = useIsOnlySpendingLimitBeneficiary() + const { setNonceNeeded } = useContext(SafeTxContext) const formattedAmount = safeFormatUnits(availableAmount, selectedToken?.decimals) @@ -40,6 +43,8 @@ const SpendingLimitRow = ({ onChange={(e) => { onChange(e) + setNonceNeeded(e.target.value === TokenTransferType.multiSig) + // Validate only after the field is changed setTimeout(() => { trigger(TokenAmountFields.amount)