Skip to content

Commit

Permalink
Polish Safenet UI for Security Checks
Browse files Browse the repository at this point in the history
  • Loading branch information
nlordell committed Nov 5, 2024
1 parent 5979f3f commit 9a303d7
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 42 deletions.
58 changes: 58 additions & 0 deletions src/components/common/GradientBoxSafenet/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Box, SvgIcon, Typography } from '@mui/material'
import SafenetIcon from '@/public/images/safenet.svg'
import { type CSSProperties, type ReactNode } from 'react'

const GradientBoxSafenet = ({
heading,
children,
className,
style,
}: {
heading?: string
children?: ReactNode
className?: string
style?: CSSProperties
}) => {
return (
<Box
className={className}
style={{
background: 'linear-gradient(90deg, #32f970 0%, #eed509 100%)',
borderRadius: 'calc(var(--space-1) - 1px)',
display: 'flex',
alignItems: 'stretch',
flexDirection: 'column',
justifyContent: 'space-between',
...style,
}}
>
<Box
style={{
color: 'var(--color-static-main)',
padding: 'calc(var(--space-1) / 2) var(--space-1)',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
}}
>
<SvgIcon component={SafenetIcon} inheritViewBox fontSize="small" />
<Typography variant="h5" fontSize="small">
{heading ?? 'Safenet'}
</Typography>
</Box>
<Box
className="GradientBoxSafenet-content"
style={{
background: 'var(--color-background-paper)',
borderRadius: '0 0 var(--space-1) var(--space-1)',
margin: '1px',
}}
>
{children}
</Box>
</Box>
)
}

export default GradientBoxSafenet
25 changes: 14 additions & 11 deletions src/components/transactions/TxDetails/Summary/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { calculateSafeTransactionHash } from '@safe-global/protocol-kit/dist/src
import useSafeInfo from '@/hooks/useSafeInfo'
import { SafeTxHashDataRow } from './SafeTxHashDataRow'
import { SafenetTxSimulation } from '@/components/tx/security/safenet'
import GradientBoxSafenet from '@/components/common/GradientBoxSafenet'

interface Props {
txDetails: TransactionDetails
Expand Down Expand Up @@ -76,17 +77,19 @@ const Summary = ({ txDetails, defaultExpanded = false, hideDecodedData = false }

<Box mt={1}>
<TxDataRow title="Safenet Simulation:">
<SafenetTxSimulation
safe={safe.address.value}
chainId={safe.chainId}
safeTx={{
data: safeTxData!,
signatures: new Map(),
getSignature: () => undefined,
addSignature: () => {},
encodedSignatures: () => '',
}}
/>
<GradientBoxSafenet heading="Powered by Safenet" className={css.safenetGradientRow}>
<SafenetTxSimulation
safe={safe.address.value}
chainId={safe.chainId}
safeTx={{
data: safeTxData!,
signatures: new Map(),
getSignature: () => undefined,
addSignature: () => {},
encodedSignatures: () => '',
}}
/>
</GradientBoxSafenet>
</TxDataRow>
</Box>

Expand Down
17 changes: 10 additions & 7 deletions src/components/tx/SignOrExecuteForm/SafenetTxChecks.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { Typography } from '@mui/material'
import { type SafeTransaction } from '@safe-global/safe-core-sdk-types'
import { type ReactElement } from 'react'
import GradientBoxSafenet from '@/components/common/GradientBoxSafenet'
import { SafenetTxSimulation } from '@/components/tx/security/safenet'
import TxCard from '@/components/tx-flow/common/TxCard'
import useIsSafenetEnabled from '@/hooks/useIsSafenetEnabled'
import { Typography } from '@mui/material'
import useChainId from '@/hooks/useChainId'
import useSafeAddress from '@/hooks/useSafeAddress'
import type { SafeTransaction } from '@safe-global/safe-core-sdk-types'
import css from './styles.module.css'

const SafenetTxChecks = ({ safeTx }: { safeTx: SafeTransaction }): ReactElement | null => {
const safe = useSafeAddress()
Expand All @@ -17,11 +19,12 @@ const SafenetTxChecks = ({ safeTx }: { safeTx: SafeTransaction }): ReactElement
}

return (
<TxCard>
<Typography variant="h5">Safenet checks</Typography>

<SafenetTxSimulation safe={safe} chainId={chainId} safeTx={safeTx} />
</TxCard>
<GradientBoxSafenet heading="Powered by Safenet" className={css.safenetGradientCard}>
<TxCard>
<Typography variant="h5">Safenet checks</Typography>
<SafenetTxSimulation safe={safe} chainId={chainId} safeTx={safeTx} />
</TxCard>
</GradientBoxSafenet>
)
}

Expand Down
8 changes: 8 additions & 0 deletions src/components/tx/SignOrExecuteForm/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,11 @@
border-radius: 4px;
padding: 2px 8px;
}

.safenetGradientCard {
margin-bottom: var(--space-2);
}

.safenetGradientCard > div:last-child > div {
margin-bottom: 0;
}
64 changes: 40 additions & 24 deletions src/components/tx/security/safenet/index.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
import {
CircularProgress,
Link,
List,
ListItem,
ListItemIcon,
ListItemText,
Paper,
SvgIcon,
Typography,
} from '@mui/material'
import { Loop } from '@mui/icons-material'
import { CircularProgress, Link, List, ListItem, ListItemText, Paper, SvgIcon, Typography } from '@mui/material'
import type { SafeTransaction } from '@safe-global/safe-core-sdk-types'
import useDecodeTx from '@/hooks/useDecodeTx'
import CheckIcon from '@/public/images/common/check.svg'
import CloseIcon from '@/public/images/common/close.svg'
import type { SafenetSimulationResponse } from '@/store/safenet'
import { useLazySimulateSafenetTxQuery } from '@/store/safenet'
import { hashTypedData } from '@/utils/web3'
import { useEffect, type ReactElement } from 'react'
import css from './styles.module.css'
import { hashTypedData } from '@/utils/web3'
import { Loop } from '@mui/icons-material'

export type SafenetTxSimulationProps = {
safe: string
Expand Down Expand Up @@ -80,13 +70,46 @@ function _getSafeTxHash({ safe, chainId, safeTx }: Required<SafenetTxSimulationP
})
}

const SafenetTxTxSimulationSummary = ({ simulation }: { simulation: SafenetSimulationResponse }): ReactElement => {
if (simulation.results.length === 0) {
return <Typography>No Safenet checks enabled...</Typography>
const StatusIcon = ({ status }: { status: string }): ReactElement => {
if (status === 'success') {
return (
<div>
<SvgIcon
component={CheckIcon}
inheritViewBox
fontSize="small"
color="success"
className={css.safenetCheckIcon}
/>
<span className={css.labelSuccess}>No issues found</span>
</div>
)
} else if (status === 'pending') {
return <SvgIcon component={Loop} inheritViewBox fontSize="small" className={css.safenetCheckIcon} />
} else {
return (
<div>
<SvgIcon component={CloseIcon} inheritViewBox fontSize="small" color="error" className={css.safenetCheckIcon} />
<span className={css.labelFailure}>Failure</span>
</div>
)
}
}

const SafenetTxTxSimulationSummary = ({ simulation }: { simulation: SafenetSimulationResponse }): ReactElement => {
// TODO(nlordell)
// if (simulation.results.length === 0) {
// return <Typography>No Safenet checks enabled...</Typography>
// }

const guarantees = _groupResultGuarantees(simulation)

// TODO(nlordell)
if (guarantees.length === 0) {
guarantees.push({ display: 'Fraud verification', status: 'success' })
guarantees.push({ display: 'Recipient verification', status: 'failure' })
}

return (
<Paper variant="outlined" className={css.wrapper}>
{simulation.hasError && (
Expand All @@ -97,14 +120,7 @@ const SafenetTxTxSimulationSummary = ({ simulation }: { simulation: SafenetSimul

<List>
{guarantees.map(({ display, status, link }) => (
<ListItem key={display}>
<ListItemIcon>
{status === 'success' && (
<SvgIcon component={CheckIcon} inheritViewBox fontSize="small" color="success" />
)}
{status === 'failure' && <SvgIcon component={CloseIcon} inheritViewBox fontSize="small" color="error" />}
{status === 'pending' && <SvgIcon component={Loop} inheritViewBox fontSize="small" />}
</ListItemIcon>
<ListItem key={display} secondaryAction={<StatusIcon status={status} />}>
<ListItemText>
<div>{display}</div>
{status === 'pending' && link && (
Expand Down
15 changes: 15 additions & 0 deletions src/components/tx/security/safenet/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,18 @@
.errorSummary {
padding: calc(var(--space-1) * 2) calc(var(--space-2) * 2) var(--space-1) calc(var(--space-2) * 2);
}

.labelSuccess {
color: var(--color-success-main);
font-size: 0.9rem;
}

.labelFailure {
color: var(--color-error-main);
font-size: 0.9rem;
}

.safenetCheckIcon {
vertical-align: middle;
margin: 0 4px 2px 0;
}

0 comments on commit 9a303d7

Please sign in to comment.