Skip to content

Commit

Permalink
fix: export account key in modal dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
schmanu committed Oct 19, 2023
1 parent 6c59117 commit 09a1626
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 70 deletions.
126 changes: 126 additions & 0 deletions src/components/settings/ExportMPCAccount/ExportMPCAccountModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { MpcWalletContext } from '@/components/common/ConnectWallet/MPCWalletProvider'
import CopyButton from '@/components/common/CopyButton'
import ModalDialog from '@/components/common/ModalDialog'
import { Box, Button, DialogContent, DialogTitle, IconButton, TextField, Typography } from '@mui/material'
import { useContext, useState } from 'react'
import { useForm } from 'react-hook-form'
import { Visibility, VisibilityOff, Close } from '@mui/icons-material'
import css from './styles.module.css'

enum ExportFieldNames {
password = 'password',
}

type ExportFormData = {
[ExportFieldNames.password]: string
}

const ExportMPCAccountModal = ({ onClose, open }: { onClose: () => void; open: boolean }) => {
const { exportPk } = useContext(MpcWalletContext)

const [pk, setPk] = useState<string | undefined>()
const [isExporting, setIsExporting] = useState(false)
const [showPassword, setShowPassword] = useState(false)
const formMethods = useForm<ExportFormData>({
mode: 'all',
defaultValues: {
[ExportFieldNames.password]: '',
},
})
const { register, formState, handleSubmit, setValue } = formMethods

const onSubmit = async (data: ExportFormData) => {
try {
setIsExporting(true)
const pk = await exportPk(data[ExportFieldNames.password])
setPk(pk)
} catch (err) {
console.error(err)
} finally {
setIsExporting(false)
}
}

const handleClose = () => {
setValue(ExportFieldNames.password, '')
setPk(undefined)
onClose()
}
return (
<ModalDialog open={open} onClose={handleClose}>
<DialogTitle>
<Typography variant="h6" fontWeight={700}>
Export your account
</Typography>
</DialogTitle>
<IconButton className={css.close} aria-label="close" onClick={handleClose} size="small">
<Close fontSize="large" />
</IconButton>

<DialogContent>
<form onSubmit={handleSubmit(onSubmit)}>
<Box display="flex" flexDirection="column" gap={2} alignItems="flex-start" sx={{ width: '100%' }}>
<Typography>For security reasons you have to enter your password to reveal your account key.</Typography>

{pk ? (
<Box display="flex" flexDirection="row" alignItems="center" gap={1} width="100%">
<TextField
fullWidth
multiline={showPassword}
maxRows={3}
label="Private key"
value={pk}
type="password"
InputProps={{
readOnly: true,
endAdornment: (
<>
<IconButton size="small" onClick={() => setShowPassword((prev) => !prev)}>
{showPassword ? <VisibilityOff fontSize="small" /> : <Visibility fontSize="small" />}
</IconButton>
<CopyButton text={pk} />
</>
),
}}
/>
</Box>
) : (
<>
<TextField
placeholder="Password"
label="Password"
type="password"
fullWidth
error={!!formState.errors[ExportFieldNames.password]}
helperText={formState.errors[ExportFieldNames.password]?.message}
{...register(ExportFieldNames.password, {
required: true,
})}
/>
</>
)}
<Box
mt={3}
display="flex"
flexDirection="row"
justifyContent="space-between"
alignItems="center"
width="100%"
>
<Button variant="outlined" onClick={handleClose}>
Close
</Button>
{pk === undefined && (
<Button color="primary" variant="contained" disabled={isExporting} type="submit">
Export
</Button>
)}
</Box>
</Box>
</form>
</DialogContent>
</ModalDialog>
)
}

export default ExportMPCAccountModal
86 changes: 16 additions & 70 deletions src/components/settings/ExportMPCAccount/index.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,12 @@
import { MpcWalletContext } from '@/components/common/ConnectWallet/MPCWalletProvider'
import CopyButton from '@/components/common/CopyButton'
import { Alert, Box, Button, TextField, Typography } from '@mui/material'
import { useContext, useState } from 'react'
import { useForm } from 'react-hook-form'

enum ExportFieldNames {
password = 'password',
}

type ExportFormData = {
[ExportFieldNames.password]: string
}
import { Alert, Box, Button, Typography } from '@mui/material'
import { useState } from 'react'
import ExportMPCAccountModal from './ExportMPCAccountModal'

const ExportMPCAccount = () => {
const { exportPk, walletState } = useContext(MpcWalletContext)

const [pk, setPk] = useState<string | undefined>()
const [isExporting, setIsExporting] = useState(false)
const formMethods = useForm<ExportFormData>({
mode: 'all',
defaultValues: {
[ExportFieldNames.password]: '',
},
})
const { register, formState, handleSubmit } = formMethods

const onSubmit = async (data: ExportFormData) => {
try {
setIsExporting(true)
const pk = await exportPk(data[ExportFieldNames.password])
setPk(pk)
} catch (err) {
} finally {
setIsExporting(false)
}
}

const hidePK = () => {
setPk(undefined)
}
const [isModalOpen, setIsModalOpen] = useState(false)

return (
<form onSubmit={handleSubmit(onSubmit)}>
<>
<Box display="flex" flexDirection="column" gap={1} alignItems="flex-start">
<Typography>
Accounts created via Google can be exported and imported to any non-custodial wallet outside of Safe.
Expand All @@ -50,37 +15,18 @@ const ExportMPCAccount = () => {
Never disclose your keys or seed phrase to anyone. If someone gains access to them, they have full access over
your signer account.
</Alert>
{pk ? (
<Box display="flex" flexDirection="row" alignItems="center" gap={1}>
<TextField
label="Signer account key"
value={pk}
type="password"
InputProps={{ readOnly: true, endAdornment: <CopyButton text={pk} /> }}
></TextField>
<Button color="primary" variant="contained" onClick={hidePK}>
Hide
</Button>
</Box>
) : (
<>
<TextField
placeholder="Enter recovery password"
label="Password"
type="password"
error={!!formState.errors[ExportFieldNames.password]}
helperText={formState.errors[ExportFieldNames.password]?.message}
{...register(ExportFieldNames.password, {
required: true,
})}
/>
<Button color="primary" variant="contained" disabled={isExporting} type="submit" sx={{ mt: 3 }}>
Export
</Button>
</>
)}
<Button
color="primary"
variant="contained"
disabled={isModalOpen}
onClick={() => setIsModalOpen(true)}
sx={{ mt: 3 }}
>
Reveal private key
</Button>
</Box>
</form>
<ExportMPCAccountModal onClose={() => setIsModalOpen(false)} open={isModalOpen} />
</>
)
}

Expand Down
5 changes: 5 additions & 0 deletions src/components/settings/ExportMPCAccount/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.close {
position: absolute;
right: var(--space-1);
top: var(--space-1);
}

0 comments on commit 09a1626

Please sign in to comment.