Skip to content

Commit 0197c5c

Browse files
authored
fix(popups): mf-6756 privy signing (#12307)
* fix(popups): mf-6756 privy signing, wallet avatar & selection fixes use WalletAvatar with forwarded props; add privy wallet personal_sign fallback; tighten select-wallet param handling, default selection and resolveMaskAccount guard; minor refactors and cleanup. * fix(popups): mf-6757 prevent long error codes from overflowing modal
1 parent 3767304 commit 0197c5c

File tree

6 files changed

+91
-81
lines changed

6 files changed

+91
-81
lines changed

packages/mask/popups/components/ConnectedWallet/index.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Services from '#services'
22
import { Trans } from '@lingui/react/macro'
33
import { Icons } from '@masknet/icons'
4-
import { ConfirmDialog, FormattedAddress, ImageIcon, PersonaContext, ProgressiveText } from '@masknet/shared'
4+
import { ConfirmDialog, FormattedAddress, PersonaContext, ProgressiveText } from '@masknet/shared'
55
import {
66
MaskMessages,
77
NetworkPluginID,
@@ -21,6 +21,7 @@ import { useQueries } from '@tanstack/react-query'
2121
import { memo, useCallback } from 'react'
2222
import { useVerifiedWallets } from '../../hooks/index.js'
2323
import { useModalNavigate } from '../ActionModal/index.js'
24+
import { WalletAvatar } from '../WalletAvatar/index.js'
2425

2526
const useStyles = makeStyles()((theme) => ({
2627
walletList: {
@@ -159,7 +160,7 @@ export const ConnectedWallet = memo(function ConnectedWallet() {
159160
return (
160161
<Box className={classes.wallet} key={index}>
161162
<Box display="flex" alignItems="center">
162-
<ImageIcon size={24} icon={networkDescriptor?.icon} className={classes.walletIcon} />
163+
<WalletAvatar size={24} className={classes.walletIcon} address={wallet.identity} />
163164
<Typography className={classes.walletInfo} component="div">
164165
<ProgressiveText
165166
className={classes.walletName}

packages/mask/popups/components/PopupLayout/index.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ const GlobalCss = (
2828
display: 'none',
2929
},
3030
},
31+
// privy modal error text overflow
32+
'#privy-modal-content [class^=TransactionErrorScreenContainer] [class^=ErrorCode]': {
33+
wordBreak: 'break-all',
34+
},
3135
}}
3236
/>
3337
)

packages/mask/popups/components/WalletAvatar/index.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { PersistentStorages } from '@masknet/shared-base'
44
import { makeStyles } from '@masknet/theme'
55
import { isSameAddress } from '@masknet/web3-shared-base'
66
import { useWallets } from '@privy-io/react-auth'
7-
import { memo, useMemo } from 'react'
7+
import { memo, useMemo, type HTMLProps } from 'react'
88
import { useSubscription } from 'use-subscription'
99

1010
const useStyles = makeStyles()((theme) => ({
@@ -20,12 +20,12 @@ const useStyles = makeStyles()((theme) => ({
2020
},
2121
}))
2222

23-
interface Props {
23+
interface Props extends HTMLProps<HTMLDivElement> {
2424
size?: number
2525
address: string
2626
}
27-
export const WalletAvatar = memo<Props>(function WalletAvatar({ size = 30, address }) {
28-
const { classes } = useStyles()
27+
export const WalletAvatar = memo<Props>(function WalletAvatar({ size = 30, address, ...rest }) {
28+
const { classes, cx } = useStyles()
2929
const { wallets: fireflyWallets } = useWallets()
3030

3131
const isFireflyWallet = useMemo(
@@ -36,10 +36,10 @@ export const WalletAvatar = memo<Props>(function WalletAvatar({ size = 30, addre
3636

3737
if (isFireflyWallet && fireflyAccount)
3838
return (
39-
<div className={classes.container}>
39+
<div {...rest} className={cx(classes.container, rest.className)}>
4040
<Image size={size} src={fireflyAccount.avatar} rounded />
4141
<Icons.Firefly className={classes.badgeIcon} size={12} />
4242
</div>
4343
)
44-
return <Icons.MaskBlue size={size} />
44+
return <Icons.MaskBlue size={size} className={rest.className} />
4545
})

packages/mask/popups/components/WalletItem/index.tsx

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1-
import { memo, useCallback, useMemo } from 'react'
1+
import { Trans } from '@lingui/react/macro'
2+
import { FormattedAddress } from '@masknet/shared'
3+
import { ImportSource, NetworkPluginID, PersistentStorages, type Wallet } from '@masknet/shared-base'
24
import { makeStyles } from '@masknet/theme'
3-
import { formatDomainName, formatEthereumAddress } from '@masknet/web3-shared-evm'
4-
import { NetworkPluginID, ImportSource, type Wallet, PersistentStorages } from '@masknet/shared-base'
55
import { useReverseAddress } from '@masknet/web3-hooks-base'
6+
import { isSameAddress } from '@masknet/web3-shared-base'
7+
import { formatDomainName, formatEthereumAddress } from '@masknet/web3-shared-evm'
68
import {
79
Box,
810
ListItem,
9-
Typography,
10-
type ListItemProps,
11-
Tooltip,
1211
Radio,
12+
Tooltip,
13+
Typography,
1314
listItemSecondaryActionClasses,
15+
type ListItemProps,
1416
} from '@mui/material'
15-
import { FormattedAddress } from '@masknet/shared'
16-
import { WalletBalance } from '../index.js'
17-
import { Trans } from '@lingui/react/macro'
18-
import { WalletAvatar } from '../WalletAvatar/index.js'
1917
import { useWallets } from '@privy-io/react-auth'
20-
import { isSameAddress } from '@masknet/web3-shared-base'
18+
import { memo, useCallback, useMemo } from 'react'
2119
import { useSubscription } from 'use-subscription'
20+
import { WalletBalance } from '../index.js'
21+
import { WalletAvatar } from '../WalletAvatar/index.js'
2222

2323
const useStyles = makeStyles()((theme) => ({
2424
item: {
@@ -118,6 +118,7 @@ export const WalletItem = memo<WalletItemProps>(function WalletItem({
118118

119119
if (wallet.owner) return null
120120

121+
const walletName = wallet.name || (isFireflyWallet ? fireflyAccount.displayName : `${wallet.name}${extraName}`)
121122
return (
122123
<ListItem
123124
className={cx(classes.item, className)}
@@ -128,9 +129,7 @@ export const WalletItem = memo<WalletItemProps>(function WalletItem({
128129
<Box className={classes.text}>
129130
<Box width={180} overflow="auto">
130131
<Typography className={classes.mainLine} component="div">
131-
<Typography className={classes.name}>
132-
{isFireflyWallet ? fireflyAccount.displayName : `${wallet.name}${extraName}`}
133-
</Typography>
132+
<Typography className={classes.name}>{walletName}</Typography>
134133
{wallet.source === ImportSource.LocalGenerated || hiddenTag ? null : (
135134
<Typography component="span" className={classes.badge}>
136135
<Trans>Imported</Trans>

packages/mask/popups/pages/Personas/ConnectWallet/index.tsx

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,39 @@
1-
import { memo, useCallback } from 'react'
2-
import urlcat from 'urlcat'
3-
import { useAsync, useAsyncFn } from 'react-use'
4-
import { useNavigate } from 'react-router-dom'
5-
import { Avatar, Box, Button, Link, Typography } from '@mui/material'
6-
import { ActionButton, makeStyles, usePopupCustomSnackbar } from '@masknet/theme'
1+
import { Icons } from '@masknet/icons'
2+
import { FormattedAddress, PersonaContext, PopupHomeTabType, WalletIcon } from '@masknet/shared'
73
import {
8-
NextIDPlatform,
9-
type NetworkPluginID,
4+
MaskMessages,
105
NextIDAction,
6+
NextIDPlatform,
7+
PopupModalRoutes,
8+
PopupRoutes,
119
SignType,
10+
type NetworkPluginID,
1211
type NextIDPayload,
13-
PopupRoutes,
14-
PopupModalRoutes,
15-
MaskMessages,
1612
} from '@masknet/shared-base'
17-
import { formatDomainName, formatEthereumAddress, ProviderType } from '@masknet/web3-shared-evm'
18-
import { FormattedAddress, PersonaContext, PopupHomeTabType, WalletIcon } from '@masknet/shared'
19-
import { EVMExplorerResolver, NextIDProof, EVMProviderResolver, EVMWeb3 } from '@masknet/web3-providers'
13+
import { ActionButton, makeStyles, usePopupCustomSnackbar } from '@masknet/theme'
2014
import {
2115
useChainContext,
2216
useNetworkContext,
17+
usePrivyWallet,
2318
useProviderDescriptor,
2419
useReverseAddress,
2520
useWallets,
2621
} from '@masknet/web3-hooks-base'
22+
import { EVMExplorerResolver, EVMProviderResolver, EVMWeb3, NextIDProof } from '@masknet/web3-providers'
2723
import { isSameAddress } from '@masknet/web3-shared-base'
28-
import { Icons } from '@masknet/icons'
24+
import { EthereumMethodType, formatDomainName, formatEthereumAddress, ProviderType } from '@masknet/web3-shared-evm'
25+
import { Avatar, Box, Button, Link, Typography } from '@mui/material'
26+
import { memo, useCallback } from 'react'
27+
import { useNavigate } from 'react-router-dom'
28+
import { useAsync, useAsyncFn } from 'react-use'
29+
import urlcat from 'urlcat'
2930

30-
import { useTitle } from '../../../hooks/index.js'
31-
import { BottomController } from '../../../components/BottomController/index.js'
32-
import { LoadingMask } from '../../../components/LoadingMask/index.js'
3331
import Services from '#services'
34-
import { useModalNavigate } from '../../../components/index.js'
3532
import { Trans, useLingui } from '@lingui/react/macro'
33+
import { BottomController } from '../../../components/BottomController/index.js'
34+
import { useModalNavigate } from '../../../components/index.js'
35+
import { LoadingMask } from '../../../components/LoadingMask/index.js'
36+
import { useTitle } from '../../../hooks/index.js'
3637

3738
const useStyles = makeStyles()((theme) => ({
3839
provider: {
@@ -158,6 +159,7 @@ export const Component = memo(function ConnectWalletPage() {
158159
[account, currentPersona],
159160
)
160161

162+
const privyWallet = usePrivyWallet(account)
161163
const [{ value: signResult, loading }, handleSign] = useAsyncFn(async () => {
162164
try {
163165
if (!currentPersona?.identifier || !account) return
@@ -178,12 +180,21 @@ export const Component = memo(function ConnectWalletPage() {
178180
true,
179181
)
180182

181-
const walletSignature = await EVMWeb3.signMessage('message', payload.signPayload, {
182-
chainId,
183-
account,
184-
providerType,
185-
silent: providerType === ProviderType.MaskWallet,
186-
})
183+
let walletSignature = ''
184+
if (privyWallet?.isConnected) {
185+
const provider = await privyWallet.getEthereumProvider()
186+
walletSignature = await provider.request({
187+
method: EthereumMethodType.personal_sign,
188+
params: [payload.signPayload, account],
189+
})
190+
} else {
191+
walletSignature = await EVMWeb3.signMessage('message', payload.signPayload, {
192+
chainId,
193+
account,
194+
providerType,
195+
silent: providerType === ProviderType.MaskWallet,
196+
})
197+
}
187198

188199
const result = await bindProof(payload, walletSignature, personaSignature)
189200

packages/mask/popups/pages/Wallet/SelectWallet/index.tsx

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ export const Component = memo(function SelectWallet() {
4141
const [params] = useSearchParams()
4242
const source = params.get('source')
4343
const chainIdSearched = params.get('chainId')
44-
const isVerifyWalletFlow = params.get('verifyWallet')
45-
const isSettingNFTAvatarFlow = params.get('setNFTAvatar')
44+
const isVerifyWalletFlow = params.has('verifyWallet')
45+
const isSettingNFTAvatarFlow = params.has('setNFTAvatar')
4646

4747
const { Network } = useWeb3State(NetworkPluginID.PLUGIN_EVM)
4848
const { proofs } = PersonaContext.useContainer()
@@ -64,8 +64,9 @@ export const Component = memo(function SelectWallet() {
6464
if (!allWallets.length && localWallets.length) return localWallets
6565
return allWallets
6666
}, [localWallets, allWallets])
67-
const defaultWallet = params.get('address') || account || (first(wallets)?.address ?? '')
67+
const defaultWallet = params.get('address') || account || first(wallets)?.address
6868
const [selected = defaultWallet, setSelected] = useState<string>()
69+
console.log('bindingWallets', { bindingWallets, wallets, selected })
6970

7071
const handleCancel = useCallback(async () => {
7172
if (isVerifyWalletFlow) {
@@ -103,11 +104,13 @@ export const Component = memo(function SelectWallet() {
103104

104105
if (wallet && source) await Services.Wallet.internalWalletConnect(wallet.address, source)
105106

106-
await Services.Wallet.resolveMaskAccount([
107-
{
108-
address: selected,
109-
},
110-
])
107+
if (selected) {
108+
await Services.Wallet.resolveMaskAccount([
109+
{
110+
address: selected,
111+
},
112+
])
113+
}
111114

112115
return Services.Helper.removePopupWindow()
113116
}, [source, isVerifyWalletFlow, selected, chainId, wallets, isSettingNFTAvatarFlow, networks, Network])
@@ -126,37 +129,29 @@ export const Component = memo(function SelectWallet() {
126129
return (
127130
<Box overflow="auto" data-hide-scrollbar>
128131
<Box pt={1} pb={9} px={2} display="flex" flexDirection="column" rowGap="6px">
129-
{wallets
130-
.filter((x) => {
131-
if (!isVerifyWalletFlow && !isSettingNFTAvatarFlow) return true
132-
return false
133-
})
134-
.map((item) => {
135-
const disabled =
136-
isVerifyWalletFlow && bindingWallets?.some((x) => isSameAddress(x.identity, item.address))
137-
138-
return (
139-
<WalletItem
140-
className={cx(classes.item, disabled ? classes.disabled : undefined)}
141-
wallet={item}
142-
key={item.address}
143-
isSelected={isSameAddress(item.address, selected)}
144-
onSelect={() => {
145-
if (disabled) return
146-
setSelected(item.address)
147-
}}
148-
/>
149-
)
150-
})}
132+
{wallets.map((item) => {
133+
const disabled =
134+
isVerifyWalletFlow && bindingWallets?.some((x) => isSameAddress(x.identity, item.address))
135+
136+
return (
137+
<WalletItem
138+
className={cx(classes.item, disabled ? classes.disabled : undefined)}
139+
wallet={item}
140+
key={item.address}
141+
isSelected={isSameAddress(item.address, selected)}
142+
onSelect={() => {
143+
if (disabled) return
144+
setSelected(item.address)
145+
}}
146+
/>
147+
)
148+
})}
151149
</Box>
152150
<BottomController>
153151
<Button variant="outlined" fullWidth onClick={handleCancel}>
154152
<Trans>Cancel</Trans>
155153
</Button>
156-
<ActionButton
157-
fullWidth
158-
onClick={handleConfirm}
159-
disabled={isVerifyWalletFlow ? !!wallets?.some((x) => isSameAddress(x.address, selected)) : false}>
154+
<ActionButton fullWidth onClick={handleConfirm} disabled={!isVerifyWalletFlow}>
160155
<Trans>Confirm</Trans>
161156
</ActionButton>
162157
</BottomController>

0 commit comments

Comments
 (0)