Skip to content

Commit 67b1d88

Browse files
committed
feat: ✨ add option to select recover specific vault account
1 parent d96b4cd commit 67b1d88

File tree

4 files changed

+64
-5
lines changed

4 files changed

+64
-5
lines changed

.changeset/long-donuts-hammer.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@fireblocks/recovery-shared': minor
3+
---
4+
5+
added option for specific vault account recovery

packages/shared/components/Modals/RecoverAccountModal/index.tsx

+36-4
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,24 @@ import React from 'react';
22
import { useRouter } from 'next/router';
33
import { useForm } from 'react-hook-form';
44
import { zodResolver } from '@hookform/resolvers/zod';
5-
import { recoverAccountInput, RecoverAccountInput } from '../../../schemas';
5+
import { Accordion, AccordionDetails, AccordionSummary, InputAdornment, Tooltip, Typography } from '@mui/material';
6+
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
7+
import HelpOutlineIcon from '@mui/icons-material/HelpOutline';
8+
import { RecoverAccountInput, recoverAccountInputByAccounts } from '../../../schemas';
69
import { BaseModal } from '../../BaseModal';
710
import { Button } from '../../Button';
811
import { TextField } from '../../TextField';
912

1013
type Props = {
1114
open: boolean;
15+
accountsKeys: number[];
1216
onClose: VoidFunction;
1317
addAccount: (name: string, id?: number) => number;
1418
};
1519

1620
const defaultValues: RecoverAccountInput = { name: '' };
1721

18-
export const RecoverAccountModal = ({ open, onClose: _onClose, addAccount }: Props) => {
22+
export const RecoverAccountModal = ({ open, onClose: _onClose, accountsKeys, addAccount }: Props) => {
1923
const router = useRouter();
2024

2125
const {
@@ -24,7 +28,7 @@ export const RecoverAccountModal = ({ open, onClose: _onClose, addAccount }: Pro
2428
handleSubmit,
2529
formState: { errors },
2630
} = useForm<RecoverAccountInput>({
27-
resolver: zodResolver(recoverAccountInput),
31+
resolver: zodResolver(recoverAccountInputByAccounts(accountsKeys)),
2832
defaultValues,
2933
});
3034

@@ -35,7 +39,7 @@ export const RecoverAccountModal = ({ open, onClose: _onClose, addAccount }: Pro
3539
};
3640

3741
const onSubmit = (formData: RecoverAccountInput) => {
38-
const accountId = addAccount(formData.name);
42+
const accountId = addAccount(formData.name, formData.id);
3943

4044
router.push({
4145
pathname: '/accounts/vault/[accountId]',
@@ -67,6 +71,34 @@ export const RecoverAccountModal = ({ open, onClose: _onClose, addAccount }: Pro
6771
autoFocus
6872
{...register('name')}
6973
/>
74+
<Typography>&nbsp;</Typography>
75+
<Accordion>
76+
<AccordionSummary expandIcon={<ArrowDownwardIcon />}>
77+
<Typography component='span'>Advanced</Typography>
78+
</AccordionSummary>
79+
<AccordionDetails>
80+
<TextField
81+
id='accountId'
82+
label='Account Id (Optional)'
83+
placeholder='e.g. 1,2,...'
84+
error={errors.id?.message}
85+
autoFocus
86+
inputProps={{ type: 'number' }}
87+
inputMode='numeric'
88+
{...register('id')}
89+
endAdornment={
90+
<InputAdornment position='end'>
91+
<Tooltip
92+
title='Vault Account ID is a unique positive integer that defines each vault.
93+
If you don’t provide this value, the utility will automatically use a new number by adding to the latest number used.'
94+
>
95+
<HelpOutlineIcon />
96+
</Tooltip>
97+
</InputAdornment>
98+
}
99+
/>
100+
</AccordionDetails>
101+
</Accordion>
70102
</BaseModal>
71103
);
72104
};

packages/shared/pages/accounts/vault/index.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,12 @@ export const VaultBasePage = ({ extendedKeys, accounts, addAccount, withdrawModa
231231
</Grid>
232232
</Grid>
233233
)}
234-
<RecoverAccountModal open={isRecoverAccountModalOpen} onClose={handleCloseRecoverAccountModal} addAccount={addAccount} />
234+
<RecoverAccountModal
235+
open={isRecoverAccountModalOpen}
236+
accountsKeys={Array.from(accounts.keys())}
237+
onClose={handleCloseRecoverAccountModal}
238+
addAccount={addAccount}
239+
/>
235240
{!!WithdrawModal && (
236241
<WithdrawModal
237242
key={withdrawalAccountId}

packages/shared/schemas/recoverAccountInput.ts

+17
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,23 @@ import { nonEmptyString } from './scalars';
33

44
export const recoverAccountInput = z.object({
55
name: nonEmptyString('Account name is required').describe('Vault Account name'),
6+
id: z.coerce.number().positive().optional(),
67
});
78

9+
export const recoverAccountInputByAccounts = (accountKeys: number[]) =>
10+
z
11+
.object({
12+
name: nonEmptyString('Account name is required').describe('Vault Account name'),
13+
id: z.coerce.number().positive().optional(),
14+
})
15+
.superRefine((data, ctx) => {
16+
if ((data.id !== undefined && accountKeys.includes(data.id)) || data.id === undefined) {
17+
ctx.addIssue({
18+
code: 'custom',
19+
message: 'Account id is already usd, please select another one',
20+
path: ['id'],
21+
});
22+
}
23+
});
24+
825
export type RecoverAccountInput = z.infer<typeof recoverAccountInput>;

0 commit comments

Comments
 (0)