Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
14 changes: 10 additions & 4 deletions src/components/Address/AccountAddressFormatted.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ethers } from 'ethers'
import { FC } from 'react'

import { useAddressDisplay } from '../../hooks/useAddressDisplay'
import { useAppSelector } from '../../redux/hooks'
import { Network } from '../../redux/networks'
import {
Expand All @@ -18,31 +19,36 @@ export const AccountAddressFormatted: FC<{
const addressBookEntry = useAppSelector((state) =>
addressBookSelectors.selectById(state, createEntryId(network, address))
)
const addressDisplay = useAddressDisplay(address)

const parsedAddress = ellipsis
? ellipsisAddress(ethers.utils.getAddress(address), ellipsis)
: ethers.utils.getAddress(address)

// Priority: Address Book > Whois recommended name > shortened address
const displayName = addressBookEntry?.nameTag || addressDisplay.recommendedName || null

if (format === 'addressPlusName') {
return (
<>
{parsedAddress}
{!!addressBookEntry?.nameTag && ` (${addressBookEntry.nameTag})`}
{!!displayName && ` (${displayName})`}
</>
)
}

if (format === 'namePlusAddress') {
if (!addressBookEntry?.nameTag) {
if (!displayName) {
return <>{parsedAddress}</>
} else {
return (
<>
{addressBookEntry.nameTag} ({parsedAddress})
{displayName} ({parsedAddress})
</>
)
}
}

// "nameOnly" is default
return <>{addressBookEntry?.nameTag || parsedAddress}</>
return <>{displayName || parsedAddress}</>
}
5 changes: 4 additions & 1 deletion src/components/Address/AddressDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ export default memo(function AddressDisplay({
length = 'short'
}: AddressDisplayProps) {
const addressDisplay = useAddressDisplay(address)
if (addressDisplay.ensName) {

if (addressDisplay.recommendedName) {
return <>{addressDisplay.recommendedName}</>
} else if (addressDisplay.ensName) {
return <>{addressDisplay.ensName}</>
} else {
return (
Expand Down
17 changes: 12 additions & 5 deletions src/components/AddressBook/AddressBook.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import StarBorderIcon from '@mui/icons-material/StarBorder'
import { Avatar, IconButton, SvgIconProps, Tooltip } from '@mui/material'
import { FC, useState } from 'react'

import { useAddressDisplay } from '../../hooks/useAddressDisplay'
import { useAppSelector } from '../../redux/hooks'
import { Network } from '../../redux/networks'
import {
Expand All @@ -21,8 +22,12 @@ export const AddressBookButton: FC<{
addressBookSelectors.selectById(state, createEntryId(network, address))
)
const [isDialogOpen, setIsDialogOpen] = useState(false)
const addressDisplay = useAddressDisplay(address)

const avatarUrl = ensApi.useLookupAvatarQuery(address)
const ensAvatarQuery = ensApi.useLookupAvatarQuery(address, {
skip: !!addressDisplay.recommendedAvatar
})
const avatarUrl = addressDisplay.recommendedAvatar || ensAvatarQuery.currentData?.avatar

return (
<>
Expand All @@ -43,10 +48,12 @@ export const AddressBookButton: FC<{
open={isDialogOpen}
handleClose={() => setIsDialogOpen(false)}
/>
{avatarUrl.currentData ? (
<Avatar alt={address} src={avatarUrl.currentData?.avatar} />
) : (
''
{avatarUrl && (
<Avatar
alt={addressDisplay.recommendedName || address}
src={avatarUrl}
sx={{ width: 32, height: 32 }}
/>
)}
</>
)
Expand Down
38 changes: 34 additions & 4 deletions src/hooks/useAddressDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ import { ethers } from 'ethers'
import { useMemo } from 'react'

import { ensApi } from '../redux/slices/ensResolver.slice'
import { whoisApi } from '../redux/slices/whoisResolver.slice'

interface AddressDisplayResult {
addressChecksummed: string | null | undefined
ensName: string | null | undefined
avatar: string | null | undefined
whoisName: string | null | undefined
whoisAvatar: string | null | undefined
recommendedName: string | null | undefined
recommendedAvatar: string | null | undefined
isFetching: boolean
}

Expand All @@ -32,27 +37,52 @@ export const useName = (name: string, skip: boolean): AddressDisplayResult => {
const ensAddressQuery = ensApi.useResolveNameQuery(name, {
skip
})

const whoisQuery = whoisApi.useResolveAddressQuery(
ensAddressQuery.currentData?.address || 'skip',
{
skip: !ensAddressQuery.currentData?.address
}
)

return {
addressChecksummed: ensAddressQuery.currentData?.address,
ensName: !!ensAddressQuery.currentData?.address ? name : null,
avatar: undefined,
isFetching: ensAddressQuery.isFetching
whoisName: whoisQuery.data?.recommendedName,
whoisAvatar: whoisQuery.data?.recommendedAvatar,
recommendedName: whoisQuery.data?.recommendedName || (!!ensAddressQuery.currentData?.address ? name : null),
recommendedAvatar: whoisQuery.data?.recommendedAvatar || whoisQuery.data?.ENS?.avatarUrl,
isFetching: ensAddressQuery.isFetching || whoisQuery.isFetching
}
}

export const useAddress = (
address: string,
skip: boolean
): AddressDisplayResult => {
const ensLookupQuery = ensApi.useLookupAddressQuery(address, {
const whoisQuery = whoisApi.useResolveAddressQuery(address, {
skip
})

const needsEnsLookup = !skip && !whoisQuery.data?.ENS?.handle && !whoisQuery.isFetching
const ensLookupQuery = ensApi.useLookupAddressQuery(address, {
skip: skip || !needsEnsLookup
})

//Use fallback from ENS if whois is not returning the name
const ensName = whoisQuery.data?.ENS?.handle || ensLookupQuery.data?.name

return {
addressChecksummed: !skip
? ethers.utils.getAddress(address.toLowerCase())
: undefined,
ensName: ensLookupQuery.data?.name,
ensName: ensName,
avatar: undefined,
isFetching: ensLookupQuery.isFetching
whoisName: whoisQuery.data?.recommendedName,
whoisAvatar: whoisQuery.data?.recommendedAvatar,
recommendedName: whoisQuery.data?.recommendedName || ensName,
recommendedAvatar: whoisQuery.data?.recommendedAvatar || whoisQuery.data?.ENS?.avatarUrl,
isFetching: whoisQuery.isFetching || ensLookupQuery.isFetching
}
}
2 changes: 1 addition & 1 deletion src/hooks/useSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ export const useSearch = (searchTerm: string) => {
.map((x) => ({
...x,
id: ethers.utils.getAddress(x.id),
ENS: addressDisplay.ensName
ENS: addressDisplay.recommendedName || addressDisplay.ensName
})),
(x) => x.id
),
Expand Down
10 changes: 4 additions & 6 deletions src/pages/[_network]/accounts/[_id].page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ import EventTableWithInfo from '../../../components/Table/EventTableWithInfo'
import TokenChip from '../../../components/TokenChip/TokenChip'
import IdContext from '../../../contexts/IdContext'
import { useNetworkContext } from '../../../contexts/NetworkContext'
import { useAddressDisplay } from '../../../hooks/useAddressDisplay'
import { useAppSelector } from '../../../redux/hooks'
import {
addressBookSelectors,
createEntryId
} from '../../../redux/slices/addressBook.slice'
import { ensApi } from '../../../redux/slices/ensResolver.slice'
import { sfSubgraph } from '../../../redux/store'
import ellipsisAddress from '../../../utils/ellipsisAddress'
import SubgraphQueryLink from '../../subgraph/SubgraphQueryLink'
Expand Down Expand Up @@ -77,9 +77,7 @@ const AccountPage: NextPage = () => {
id: address
})

const ensAddressQuery = ensApi.useLookupAddressQuery(address)

const ensName = ensAddressQuery.currentData?.name
const addressDisplay = useAddressDisplay(address)

const prefetchStreamsQuery = sfSubgraph.usePrefetch('streams')
const prefetchIndexesQuery = sfSubgraph.usePrefetch('indexes')
Expand Down Expand Up @@ -164,8 +162,8 @@ const AccountPage: NextPage = () => {
component="h1"
sx={{ mx: 1 }}
>
{/* TODO(KK): When there's an address book entry then ENS name is not displayed anywhere. Not sure if I like it... */}
{addressBookEntry ? addressBookEntry.nameTag : ensName}
{/* Priority: Address Book > Whois recommended name */}
{addressBookEntry ? addressBookEntry.nameTag : addressDisplay.recommendedName}
</Typography>
<Typography
data-cy={'address'}
Expand Down
37 changes: 37 additions & 0 deletions src/redux/slices/whoisResolver.slice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { createApi, fakeBaseQuery } from '@reduxjs/toolkit/query/react'

export interface WhoisResponse {
TOREX: { handle: string; avatarUrl?: string } | null
ENS: { handle: string; avatarUrl?: string } | null
Farcaster: { handle: string; avatarUrl?: string } | null
AlfaFrens: { handle: string; avatarUrl?: string } | null
Lens: { handle: string; avatarUrl?: string } | null
recommendedName: string | null
recommendedAvatar: string | null
}

export const whoisApi = createApi({
reducerPath: 'whois',
baseQuery: fakeBaseQuery(),
endpoints: (builder) => ({
resolveAddress: builder.query<WhoisResponse | null, string>({
queryFn: async (address) => {
try {
const response = await fetch(
`https://whois.superfluid.finance/api/resolve/${address}`
)

if (!response.ok) {
return { data: null }
}

const data = await response.json()
return { data }
} catch (error) {
console.error('Whois API error:', error)
return { data: null }
}
}
})
})
})
5 changes: 4 additions & 1 deletion src/redux/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { networks } from './networks'
import { addressBookSlice } from './slices/addressBook.slice'
import { themePreferenceSlice } from './slices/appPreferences.slice'
import { ensApi } from './slices/ensResolver.slice'
import { whoisApi } from './slices/whoisResolver.slice'

export const rpcApi = initializeRpcApiSlice(createApiWithReactHooks)
.injectEndpoints(balanceRpcApiEndpoints)
Expand Down Expand Up @@ -81,7 +82,8 @@ export const makeStore = wrapMakeStore(() => {
[sfSubgraph.reducerPath]: sfSubgraph.reducer,
[themePreferenceSlice.name]: themePreferenceSlice.reducer,
[addressBookSlice.name]: addressBookReducer,
[ensApi.reducerPath]: ensApi.reducer
[ensApi.reducerPath]: ensApi.reducer,
[whoisApi.reducerPath]: whoisApi.reducer
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
Expand All @@ -107,6 +109,7 @@ export const makeStore = wrapMakeStore(() => {
.concat(rpcApi.middleware)
.concat(sfSubgraph.middleware)
.concat(ensApi.middleware)
.concat(whoisApi.middleware)
})

if (!isServer()) {
Expand Down
Loading