Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions packages/mask/popups/components/WalletAvatar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Icons } from '@masknet/icons'
import { Image } from '@masknet/shared'
import { PersistentStorages } from '@masknet/shared-base'
import { makeStyles } from '@masknet/theme'
import { isSameAddress } from '@masknet/web3-shared-base'
import { useWallets } from '@privy-io/react-auth'
import { memo, useMemo } from 'react'
import { useSubscription } from 'use-subscription'

const useStyles = makeStyles()((theme) => ({
container: {
position: 'relative',
},
badgeIcon: {
position: 'absolute',
right: -3,
bottom: -1,
border: `1px solid ${theme.palette.common.white}`,
borderRadius: '50%',
},
}))

interface Props {
size?: number
address: string
}
export const WalletAvatar = memo<Props>(function WalletAvatar({ size = 30, address }) {
const { classes } = useStyles()
const { wallets: fireflyWallets } = useWallets()

const isFireflyWallet = useMemo(
() => fireflyWallets.some((w) => isSameAddress(w.address, address)),
[fireflyWallets, address],
)
const fireflyAccount = useSubscription(PersistentStorages.Settings.storage.firefly_account.subscription)

if (isFireflyWallet && fireflyAccount)
return (
<div className={classes.container}>
<Image size={size} src={fireflyAccount.avatar} rounded />
<Icons.Firefly className={classes.badgeIcon} size={12} />
</div>
)
return <Icons.MaskBlue size={size} />
})
21 changes: 16 additions & 5 deletions packages/mask/popups/components/WalletItem/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { memo, useCallback } from 'react'
import { memo, useCallback, useMemo } from 'react'
import { makeStyles } from '@masknet/theme'
import { formatDomainName, formatEthereumAddress } from '@masknet/web3-shared-evm'
import { NetworkPluginID, ImportSource, type Wallet } from '@masknet/shared-base'
import { NetworkPluginID, ImportSource, type Wallet, PersistentStorages } from '@masknet/shared-base'
import { useReverseAddress } from '@masknet/web3-hooks-base'
import { Icons } from '@masknet/icons'
import {
Box,
ListItem,
Expand All @@ -16,6 +15,10 @@ import {
import { FormattedAddress } from '@masknet/shared'
import { WalletBalance } from '../index.js'
import { Trans } from '@lingui/react/macro'
import { WalletAvatar } from '../WalletAvatar/index.js'
import { useWallets } from '@privy-io/react-auth'
import { isSameAddress } from '@masknet/web3-shared-base'
import { useSubscription } from 'use-subscription'

const useStyles = makeStyles()((theme) => ({
item: {
Expand Down Expand Up @@ -106,18 +109,26 @@ export const WalletItem = memo<WalletItemProps>(function WalletItem({
}, [wallet])

const extraName = domain && domain !== wallet.name ? ` (${formatDomainName(domain)})` : ''
const { wallets: fireflyWallets } = useWallets()
const isFireflyWallet = useMemo(
() => fireflyWallets.some((w) => isSameAddress(w.address, wallet.address)),
[fireflyWallets, wallet.address],
)
const fireflyAccount = useSubscription(PersistentStorages.Settings.storage.firefly_account.subscription)

return (
<ListItem
className={cx(classes.item, className)}
onClick={handleSelect}
secondaryAction={<Radio sx={{ marginLeft: 0.75 }} checked={isSelected} />}
{...rest}>
<Icons.MaskBlue size={24} />
<WalletAvatar address={wallet.address} size={24} />
<Box className={classes.text}>
<Box width={180} overflow="auto">
<Typography className={classes.mainLine} component="div">
<Typography className={classes.name}>{`${wallet.name}${extraName}`}</Typography>
<Typography className={classes.name}>
{isFireflyWallet ? fireflyAccount.displayName : `${wallet.name}${extraName}`}
</Typography>
{wallet.source === ImportSource.LocalGenerated || hiddenTag ? null : (
<Typography component="span" className={classes.badge}>
<Trans>Imported</Trans>
Expand Down
7 changes: 4 additions & 3 deletions packages/mask/popups/modals/WalletRenameModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ import { Trans } from '@lingui/react/macro'

interface WalletRenameDrawerProps extends BottomDrawerProps {
wallet?: Wallet
walletName?: string
}

function WalletRenameDrawer({ wallet, ...rest }: WalletRenameDrawerProps) {
function WalletRenameDrawer({ wallet, walletName, ...rest }: WalletRenameDrawerProps) {
const theme = useTheme()
const [name, setName] = useState('')
const [name, setName] = useState(walletName || '')
const [error, setError] = useState<ReactNode>()
const contacts = useContacts()

Expand Down Expand Up @@ -60,7 +61,7 @@ function WalletRenameDrawer({ wallet, ...rest }: WalletRenameDrawerProps) {
sx={{ mt: 2 }}
fullWidth
autoFocus
placeholder={wallet?.name}
placeholder={walletName || wallet?.name}
error={!!error}
value={name}
onChange={(e) => {
Expand Down
16 changes: 15 additions & 1 deletion packages/mask/popups/pages/Wallet/WalletSettings/Rename.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,21 @@ import { Box, ListItem, Typography } from '@mui/material'
import { useStyles } from './useStyles.js'
import { WalletRenameModal } from '../../../modals/modal-controls.js'
import { Trans } from '@lingui/react/macro'
import { useWallets } from '@privy-io/react-auth'
import { useMemo } from 'react'
import { isSameAddress } from '@masknet/web3-shared-base'
import { useSubscription } from 'use-subscription'
import { PersistentStorages } from '@masknet/shared-base'

export function Rename() {
const wallet = useWallet()
const { classes, theme } = useStyles()
const { wallets: fireflyWallets } = useWallets()
const isFireflyWallet = useMemo(
() => fireflyWallets.some((w) => isSameAddress(w.address, wallet?.address)),
[fireflyWallets, wallet?.address],
)
const fireflyAccount = useSubscription(PersistentStorages.Settings.storage.firefly_account.subscription)

if (!wallet) return null

Expand All @@ -17,6 +28,7 @@ export function Rename() {
onClick={() =>
WalletRenameModal.open({
wallet,
walletName: wallet.name || (isFireflyWallet ? fireflyAccount.displayName : wallet.name),
title: <Trans>Rename</Trans>,
})
}>
Expand All @@ -27,7 +39,9 @@ export function Rename() {
</Typography>
</Box>
<Box className={classes.itemBox}>
<Typography className={classes.itemText}>{wallet.name}</Typography>
<Typography className={classes.itemText}>
{isFireflyWallet ? fireflyAccount.displayName : wallet.name}
</Typography>
<Icons.ArrowRight color={theme.palette.maskColor.second} size={24} />
</Box>
</ListItem>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
import { Trans } from '@lingui/react/macro'
import { Icons } from '@masknet/icons'
import { Box, ListItem, Typography } from '@mui/material'
import { useStyles } from './useStyles.js'
import { ShowPrivateKeyModal } from '../../../modals/modal-controls.js'
import { Trans } from '@lingui/react/macro'
import { useStyles } from './useStyles.js'

export function ShowPrivateKey() {
interface Props {
disabled?: boolean
}
export const ShowPrivateKey = function ShowPrivateKey({ disabled }: Props) {
const { classes, theme } = useStyles()

return (
<ListItem
className={classes.item}
onClick={() =>
sx={disabled ? { opacity: 0.5, cursor: 'not-allowed' } : undefined}
onClick={() => {
if (disabled) return
ShowPrivateKeyModal.open({
title: <Trans>Enter Payment Password</Trans>,
})
}>
}}>
<Box className={classes.itemBox}>
<Icons.PublicKey2 size={20} color={theme.palette.maskColor.second} />
<Typography className={classes.itemText}>
Expand Down
19 changes: 15 additions & 4 deletions packages/mask/popups/pages/Wallet/WalletSettings/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Icons } from '@masknet/icons'
import { EMPTY_LIST, PopupModalRoutes } from '@masknet/shared-base'
import { EMPTY_LIST, PersistentStorages, PopupModalRoutes } from '@masknet/shared-base'
import { ActionButton } from '@masknet/theme'
import { useWallet, useWallets } from '@masknet/web3-hooks-base'
import { useWallets as usePrivyWallets } from '@privy-io/react-auth'
import { isSameAddress } from '@masknet/web3-shared-base'
import { Box, List, Typography } from '@mui/material'
import { first } from 'lodash-es'
Expand All @@ -21,6 +22,8 @@ import { useStyles } from './useStyles.js'
import { HidingScamTx } from './HidingScamTx.js'
import { Trans, useLingui } from '@lingui/react/macro'
import { DisablePermit } from './DisablePermit.js'
import { useSubscription } from 'use-subscription'
import { WalletAvatar } from '../../../components/WalletAvatar/index.js'

function getPathIndex(path?: string) {
const rawIndex = path?.split('/').pop()
Expand All @@ -33,6 +36,12 @@ export const Component = memo(function WalletSettings() {
const modalNavigate = useModalNavigate()
const wallet = useWallet()
const allWallets = useWallets()
const { wallets: fireflyWallets } = usePrivyWallets()
const isFireflyWallet = useMemo(
() => fireflyWallets.some((w) => isSameAddress(w.address, wallet?.address)),
[fireflyWallets, wallet?.address],
)
const fireflyAccount = useSubscription(PersistentStorages.Settings.storage.firefly_account.subscription)

const handleSwitchWallet = useCallback(() => {
modalNavigate(PopupModalRoutes.WalletAccount)
Expand Down Expand Up @@ -65,9 +74,11 @@ export const Component = memo(function WalletSettings() {
<div className={classes.content}>
<Box className={cx(classes.item, classes.primaryItem)} onClick={handleSwitchWallet}>
<Box className={classes.primaryItemBox}>
<Icons.MaskBlue size={24} className={classes.maskBlue} />
<WalletAvatar size={24} address={wallet.address} />
<div className={classes.walletInfo}>
<Typography className={classes.primaryItemText}>{wallet.name}</Typography>
<Typography className={classes.primaryItemText}>
{isFireflyWallet ? fireflyAccount.displayName : wallet.name}
</Typography>
<Typography className={classes.primaryItemSecondText}>{wallet.address}</Typography>
</div>
</Box>
Expand All @@ -82,7 +93,7 @@ export const Component = memo(function WalletSettings() {
<AutoLock />
<ChangeCurrency />
<ChangePaymentPassword />
<ShowPrivateKey />
<ShowPrivateKey disabled={isFireflyWallet} />
<ChangeNetwork />
</List>
<Box className={classes.bottomAction}>
Expand Down
23 changes: 17 additions & 6 deletions packages/mask/popups/pages/Wallet/components/WalletHeader/UI.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import { Trans } from '@lingui/react/macro'
import { Icons } from '@masknet/icons'
import { ChainIcon, CopyButton, FormattedAddress, ImageIcon, ProgressiveText } from '@masknet/shared'
import type { Wallet } from '@masknet/shared-base'
import { PersistentStorages, type Wallet } from '@masknet/shared-base'
import { makeStyles, TextOverflowTooltip } from '@masknet/theme'
import { EVMExplorerResolver } from '@masknet/web3-providers'
import type { ReasonableNetwork } from '@masknet/web3-shared-base'
import { isSameAddress, type ReasonableNetwork } from '@masknet/web3-shared-base'
import { formatEthereumAddress, type ChainId, type NetworkType, type SchemaType } from '@masknet/web3-shared-evm'
import { Box, Link, Typography } from '@mui/material'
import { memo, type MouseEvent } from 'react'
import { memo, useMemo, type MouseEvent } from 'react'
import { useConnectedWallets } from '../../hooks/useConnected.js'
import { ActionGroup } from '../ActionGroup/index.js'
import { WalletAssetsValue } from './WalletAssetsValue.js'
import { Trans } from '@lingui/react/macro'
import { useWallets } from '@privy-io/react-auth'
import { useSubscription } from 'use-subscription'
import { WalletAvatar } from '../../../../components/WalletAvatar/index.js'

const useStyles = makeStyles<{ disabled: boolean }>()((theme, { disabled }) => {
const isDark = theme.palette.mode === 'dark'
Expand Down Expand Up @@ -144,7 +147,13 @@ export const WalletHeaderUI = memo<WalletHeaderUIProps>(function WalletHeaderUI(
}) {
const { classes, cx } = useStyles({ disabled })
const { data: connectedWallets, isPending } = useConnectedWallets(origin)
const { wallets: fireflyWallets } = useWallets()
const connected = connectedWallets?.has(wallet.address)
const isFireflyWallet = useMemo(
() => fireflyWallets.some((w) => isSameAddress(w.address, wallet.address)),
[fireflyWallets, wallet.address],
)
const fireflyAccount = useSubscription(PersistentStorages.Settings.storage.firefly_account.subscription)
const addressLink = EVMExplorerResolver.addressLink(chainId, wallet.address)

const networkName = currentNetwork?.name || currentNetwork?.fullName
Expand Down Expand Up @@ -199,10 +208,12 @@ export const WalletHeaderUI = memo<WalletHeaderUIProps>(function WalletHeaderUI(
if (disabled) return
onActionClick()
}}>
<Icons.MaskBlue size={30} />
<WalletAvatar address={wallet.address} size={30} />
<Box ml={0.5} overflow="hidden">
<TextOverflowTooltip title={wallet.name}>
<Typography className={classes.nickname}>{wallet.name}</Typography>
<Typography className={classes.nickname}>
{isFireflyWallet ? fireflyAccount.displayName : wallet.name}
</Typography>
</TextOverflowTooltip>
<Typography className={classes.identifier}>
<FormattedAddress address={wallet.address} formatter={formatEthereumAddress} size={4} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export class MaskWalletProvider extends BaseHostedProvider {
const privyWallets = await Privy.getEvmWallets()
const formattedPrivyWallets: Wallet[] = privyWallets.map((wallet) => ({
id: wallet.address,
name: 'Privy Wallet',
name: '',
source: ImportSource.Privy,
address: wallet.address,
configurable: false,
Expand Down