Skip to content

Commit

Permalink
fix: add guardian validation + test periods
Browse files Browse the repository at this point in the history
  • Loading branch information
iamacook committed Nov 22, 2023
1 parent c9d7f56 commit 3bffc0b
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import { getRecoveryUpsertTransactions } from '@/services/recovery/setup'
import { useWeb3 } from '@/hooks/wallets/web3'
import useSafeInfo from '@/hooks/useSafeInfo'
import { SvgIcon, Tooltip, Typography } from '@mui/material'
import { UpsertRecoveryFlowFields, RecoveryDelayPeriods, RecoveryExpirationPeriods } from '.'
import { useRecoveryPeriods } from './useRecoveryPeriods'
import { TxDataRow } from '@/components/transactions/TxDetails/Summary/TxDataRow'
import InfoIcon from '@/public/images/notifications/info.svg'
import EthHashInfo from '@/components/common/EthHashInfo'
import { UpsertRecoveryFlowFields } from '.'
import type { UpsertRecoveryFlowProps } from '.'

export function UpsertRecoveryFlowReview({
Expand All @@ -26,9 +27,10 @@ export function UpsertRecoveryFlowReview({
const { safe, safeAddress } = useSafeInfo()
const { setSafeTx, safeTxError, setSafeTxError } = useContext(SafeTxContext)

const periods = useRecoveryPeriods()
const guardian = params[UpsertRecoveryFlowFields.guardian]
const delay = RecoveryDelayPeriods.find(({ value }) => value === params[UpsertRecoveryFlowFields.txCooldown])!.label
const expiration = RecoveryExpirationPeriods.find(
const delay = periods.delay.find(({ value }) => value === params[UpsertRecoveryFlowFields.txCooldown])!.label
const expiration = periods.expiration.find(
({ value }) => value === params[UpsertRecoveryFlowFields.txExpiration],
)!.label
const emailAddress = params[UpsertRecoveryFlowFields.emailAddress]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ import type { TextFieldProps } from '@mui/material'
import type { ReactElement } from 'react'

import TxCard from '../../common/TxCard'
import { UpsertRecoveryFlowFields, RecoveryDelayPeriods, RecoveryExpirationPeriods } from '.'
import { UpsertRecoveryFlowFields } from '.'
import { useRecoveryPeriods } from './useRecoveryPeriods'
import AddressBookInput from '@/components/common/AddressBookInput'
import CircleCheckIcon from '@/public/images/common/circle-check.svg'
import { useDarkMode } from '@/hooks/useDarkMode'
import { sameAddress } from '@/utils/addresses'
import useSafeInfo from '@/hooks/useSafeInfo'
import type { UpsertRecoveryFlowProps } from '.'

import commonCss from '@/components/tx-flow/common/styles.module.css'
Expand All @@ -34,15 +37,23 @@ export function UpsertRecoveryFlowSettings({
params: UpsertRecoveryFlowProps
onSubmit: (formData: UpsertRecoveryFlowProps) => void
}): ReactElement {
const { safeAddress } = useSafeInfo()
const [showAdvanced, setShowAdvanced] = useState(params[UpsertRecoveryFlowFields.txExpiration] !== '0')
const [understandsRisk, setUnderstandsRisk] = useState(false)
const isDarkMode = useDarkMode()
const periods = useRecoveryPeriods()

const formMethods = useForm<UpsertRecoveryFlowProps>({
defaultValues: params,
mode: 'onChange',
})

const validateGuardian = (guardian: string) => {
if (sameAddress(guardian, safeAddress)) {
return 'The Safe Account cannot be a guardian of itself'
}
}

const emailAddress = formMethods.watch(UpsertRecoveryFlowFields.emailAddress)

const onShowAdvanced = () => setShowAdvanced((prev) => !prev)
Expand All @@ -63,7 +74,13 @@ export function UpsertRecoveryFlowSettings({
</Typography>
</div>

<AddressBookInput label="Guardian address" name={UpsertRecoveryFlowFields.guardian} required fullWidth />
<AddressBookInput
label="Guardian address"
name={UpsertRecoveryFlowFields.guardian}
required
fullWidth
validate={validateGuardian}
/>

<div>
<Typography variant="h5" gutterBottom>
Expand All @@ -80,7 +97,7 @@ export function UpsertRecoveryFlowSettings({
name={UpsertRecoveryFlowFields.txCooldown}
render={({ field }) => (
<SelectField label="Recovery delay" fullWidth {...field}>
{RecoveryDelayPeriods.map(({ label, value }, index) => (
{periods.delay.map(({ label, value }, index) => (
<MenuItem key={index} value={value}>
{label}
</MenuItem>
Expand All @@ -105,7 +122,7 @@ export function UpsertRecoveryFlowSettings({
shouldUnregister={false}
render={({ field }) => (
<SelectField label="Transaction expiry" fullWidth {...field}>
{RecoveryExpirationPeriods.map(({ label, value }, index) => (
{periods.expiration.map(({ label, value }, index) => (
<MenuItem key={index} value={value}>
{label}
</MenuItem>
Expand Down
36 changes: 2 additions & 34 deletions src/components/tx-flow/flows/UpsertRecovery/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,9 @@ import useTxStepper from '../../useTxStepper'
import { UpsertRecoveryFlowReview as UpsertRecoveryFlowReview } from './UpsertRecoveryFlowReview'
import { UpsertRecoveryFlowSettings as UpsertRecoveryFlowSettings } from './UpsertRecoveryFlowSettings'
import { UpsertRecoveryFlowIntro as UpsertRecoveryFlowIntro } from './UpsertRecoveryFlowIntro'
import { DAY_IN_SECONDS } from './useRecoveryPeriods'
import type { RecoveryState } from '@/store/recoverySlice'

const DAY_SECONDS = 60 * 60 * 24

export const RecoveryDelayPeriods = [
{
label: '2 days',
value: `${DAY_SECONDS}`,
},
{
label: '7 days',
value: `${DAY_SECONDS * 7}`,
},
{
label: '14 days',
value: `${DAY_SECONDS * 14}`,
},
{
label: '28 days',
value: `${DAY_SECONDS * 28}`,
},
{
label: '56 days',
value: `${DAY_SECONDS * 56}`,
},
] as const

export const RecoveryExpirationPeriods = [
{
label: 'Never',
value: '0',
},
...RecoveryDelayPeriods,
] as const

const Subtitles = ['How does recovery work?', 'Set up recovery settings', 'Set up account recovery']

export enum UpsertRecoveryFlowFields {
Expand All @@ -60,7 +28,7 @@ export type UpsertRecoveryFlowProps = {
export function UpsertRecoveryFlow({ recovery }: { recovery?: RecoveryState[number] }): ReactElement {
const { data, step, nextStep, prevStep } = useTxStepper<UpsertRecoveryFlowProps>({
[UpsertRecoveryFlowFields.guardian]: recovery?.guardians?.[0] ?? '',
[UpsertRecoveryFlowFields.txCooldown]: recovery?.txCooldown?.toString() ?? `${DAY_SECONDS * 28}`, // 28 days in seconds
[UpsertRecoveryFlowFields.txCooldown]: recovery?.txCooldown?.toString() ?? `${DAY_IN_SECONDS * 28}`, // 28 days in seconds
[UpsertRecoveryFlowFields.txExpiration]: recovery?.txExpiration?.toString() ?? '0',
[UpsertRecoveryFlowFields.emailAddress]: '',
})
Expand Down
75 changes: 75 additions & 0 deletions src/components/tx-flow/flows/UpsertRecovery/useRecoveryPeriods.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import chains from '@/config/chains'
import { useCurrentChain } from '@/hooks/useChains'

export const DAY_IN_SECONDS = 60 * 60 * 24

const DefaultRecoveryDelayPeriods = [
{
label: '2 days',
value: `${DAY_IN_SECONDS * 2}`,
},
{
label: '7 days',
value: `${DAY_IN_SECONDS * 7}`,
},
{
label: '14 days',
value: `${DAY_IN_SECONDS * 14}`,
},
{
label: '28 days',
value: `${DAY_IN_SECONDS * 28}`,
},
{
label: '56 days',
value: `${DAY_IN_SECONDS * 56}`,
},
]

const DefaultRecoveryExpirationPeriods = [
{
label: 'Never',
value: '0',
},
...DefaultRecoveryDelayPeriods,
]

const TestRecoveryDelayPeriods = [
{
label: '1 minute',
value: 60,
},
{
label: '5 minutes',
value: 60 * 5,
},
{
label: '1 hour',
value: DAY_IN_SECONDS,
},
...DefaultRecoveryDelayPeriods,
]

const TestRecoveryExpirationPeriods = [
{
label: 'Never',
value: '0',
},
...TestRecoveryDelayPeriods,
]

export function useRecoveryPeriods() {
const chain = useCurrentChain()

if (!chain || [chains.gor, chains.sep].includes(chain.chainId)) {
return {
delay: TestRecoveryDelayPeriods,
expiration: TestRecoveryExpirationPeriods,
}
}

return {
delay: DefaultRecoveryDelayPeriods,
expiration: DefaultRecoveryExpirationPeriods,
}
}

0 comments on commit 3bffc0b

Please sign in to comment.