Skip to content

Commit

Permalink
fix: disable approval of unsupported sessions (#2639)
Browse files Browse the repository at this point in the history
* fix: disable approval of unsupported sessions

* fix: rephrase info + variable

* fix: rename "chains" to "networks
  • Loading branch information
iamacook authored Oct 16, 2023
1 parent 935609e commit a17eb18
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 34 deletions.
56 changes: 26 additions & 30 deletions src/components/walletconnect/ProposalForm/ChainWarning.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Alert, Typography } from '@mui/material'
import { useMemo } from 'react'
import type { AlertColor } from '@mui/material'
import type { ReactElement } from 'react'
import type { Web3WalletTypes } from '@walletconnect/web3wallet'
import type { ChainInfo } from '@safe-global/safe-gateway-typescript-sdk'

import ChainIndicator from '@/components/common/ChainIndicator'
import useChains from '@/hooks/useChains'
Expand All @@ -12,57 +11,54 @@ import { getEip155ChainId } from '@/services/walletconnect/utils'

import css from './styles.module.css'

const ChainInformation = {
UNSUPPORTED:
'This dApp does not support the Safe Account network. If you want to interact with it, please switch to a Safe Account on a supported network.',
WRONG: 'Please make sure that the dApp is connected to %%chain%%.',
const ChainInformation: Record<string, { severity: AlertColor; message: string }> = {
UNSUPPORTED: {
severity: 'error',
message:
'This dApp does not support the Safe Account network. If you want to interact with this dApp, please switch to a Safe Account on a supported network.',
},
WRONG: {
severity: 'info',
message: 'Please make sure that the dApp is connected to %%chain%%.',
},
}

const getSupportedChainIds = (configs: Array<ChainInfo>, proposal: Web3WalletTypes.SessionProposal): Array<string> => {
const { requiredNamespaces, optionalNamespaces } = proposal.params

const requiredChains = requiredNamespaces[EIP155]?.chains ?? []
const optionalChains = optionalNamespaces[EIP155]?.chains ?? []

return configs
.filter((chain) => {
const eipChainId = getEip155ChainId(chain.chainId)
return requiredChains.includes(eipChainId) || optionalChains.includes(eipChainId)
})
.map((chain) => chain.chainId)
}

export const ChainWarning = ({ proposal }: { proposal: Web3WalletTypes.SessionProposal }): ReactElement | null => {
export const ChainWarning = ({
proposal,
chainIds,
}: {
proposal: Web3WalletTypes.SessionProposal
chainIds: Array<string>
}): ReactElement | null => {
const { configs } = useChains()
const { safe } = useSafeInfo()

const chainIds = useMemo(() => getSupportedChainIds(configs, proposal), [configs, proposal])
const supportsSafe = chainIds.includes(safe.chainId)
const supportsCurrentChain = chainIds.includes(safe.chainId)

const requiredChains = proposal.params.requiredNamespaces[EIP155]?.chains ?? []
const isCorrectChain = requiredChains.includes(getEip155ChainId(safe.chainId))

if (supportsSafe && isCorrectChain) {
if (supportsCurrentChain && isCorrectChain) {
return null
}

if (supportsSafe) {
if (supportsCurrentChain) {
const chainName = configs.find((chain) => chain.chainId === safe.chainId)?.chainName ?? ''
ChainInformation.WRONG = ChainInformation.WRONG.replace('%%chain%%', chainName)
ChainInformation.WRONG.message = ChainInformation.WRONG.message.replace('%%chain%%', chainName)
}

const message = supportsSafe ? ChainInformation.WRONG : ChainInformation.UNSUPPORTED
const { severity, message } = supportsCurrentChain ? ChainInformation.WRONG : ChainInformation.UNSUPPORTED

return (
<>
<Alert severity="info" className={css.alert}>
<Alert severity={severity} className={css.alert}>
{message}
</Alert>

{!supportsSafe && (
{!supportsCurrentChain && (
<>
<Typography mt={3} mb={1}>
Supported chains
Supported networks
</Typography>

<div>
Expand Down
16 changes: 12 additions & 4 deletions src/components/walletconnect/ProposalForm/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { Button, Checkbox, Divider, FormControlLabel, Typography } from '@mui/material'
import { useState } from 'react'
import { useMemo, useState } from 'react'
import type { ReactElement } from 'react'
import type { Web3WalletTypes } from '@walletconnect/web3wallet'

import SafeAppIconCard from '@/components/safe-apps/SafeAppIconCard'
import css from './styles.module.css'
import ProposalVerification from './ProposalVerification'
import { ChainWarning } from './ChainWarning'
import useChains from '@/hooks/useChains'
import useSafeInfo from '@/hooks/useSafeInfo'
import { getSupportedChainIds } from '@/services/walletconnect/utils'

type ProposalFormProps = {
proposal: Web3WalletTypes.SessionProposal
Expand All @@ -15,12 +18,17 @@ type ProposalFormProps = {
}

const ProposalForm = ({ proposal, onApprove, onReject }: ProposalFormProps): ReactElement => {
const { configs } = useChains()
const { safe } = useSafeInfo()
const [understandsRisk, setUnderstandsRisk] = useState(false)
const { proposer } = proposal.params
const { isScam } = proposal.verifyContext.verified

const chainIds = useMemo(() => getSupportedChainIds(configs, proposal.params), [configs, proposal.params])
const supportsCurrentChain = chainIds.includes(safe.chainId)

const isHighRisk = proposal.verifyContext.verified.validation === 'INVALID'
const disabled = isScam || (isHighRisk && !understandsRisk)
const disabled = !supportsCurrentChain || isScam || (isHighRisk && !understandsRisk)

return (
<div className={css.container}>
Expand All @@ -46,10 +54,10 @@ const ProposalForm = ({ proposal, onApprove, onReject }: ProposalFormProps): Rea
<div className={css.info}>
<ProposalVerification proposal={proposal} />

<ChainWarning proposal={proposal} />
<ChainWarning proposal={proposal} chainIds={chainIds} />
</div>

{isHighRisk && (
{supportsCurrentChain && isHighRisk && (
<FormControlLabel
className={css.checkbox}
control={<Checkbox checked={understandsRisk} onChange={(_, checked) => setUnderstandsRisk(checked)} />}
Expand Down
17 changes: 17 additions & 0 deletions src/services/walletconnect/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import type { ChainInfo } from '@safe-global/safe-apps-sdk'
import type { ProposalTypes } from '@walletconnect/types'

import { EIP155 } from './constants'

export const getEip155ChainId = (chainId: string): string => {
Expand All @@ -7,3 +10,17 @@ export const getEip155ChainId = (chainId: string): string => {
export const stripEip155Prefix = (eip155Address: string): string => {
return eip155Address.split(':').pop() ?? ''
}

export const getSupportedChainIds = (configs: Array<ChainInfo>, params: ProposalTypes.Struct): Array<string> => {
const { requiredNamespaces, optionalNamespaces } = params

const requiredChains = requiredNamespaces[EIP155]?.chains ?? []
const optionalChains = optionalNamespaces[EIP155]?.chains ?? []

return configs
.filter((chain) => {
const eipChainId = getEip155ChainId(chain.chainId)
return requiredChains.includes(eipChainId) || optionalChains.includes(eipChainId)
})
.map((chain) => chain.chainId)
}

0 comments on commit a17eb18

Please sign in to comment.