Skip to content

Commit d679bcb

Browse files
fix: verify ETH address record matches in usePrimaryName mismatch case
When a name's match property is false (mismatch case), verify that the name's ETH address record actually resolves to the input address before returning the name. This prevents showing a primary name on the address page when the name's ETH address points to a different address than the one being viewed. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent c780282 commit d679bcb

File tree

2 files changed

+38
-5
lines changed

2 files changed

+38
-5
lines changed

src/hooks/ensjs/public/usePrimaryName.test.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { mockFunction } from '@app/test-utils'
22

33
import { describe, expect, it, vi } from 'vitest'
44

5-
import { getName } from '@ensdomains/ensjs/public'
5+
import { getAddressRecord, getName } from '@ensdomains/ensjs/public'
66

77
import { ClientWithEns, ConfigWithEns } from '@app/types'
88

@@ -11,6 +11,7 @@ import { getPrimaryNameQueryFn } from './usePrimaryName'
1111
vi.mock('@ensdomains/ensjs/public')
1212

1313
const mockGetName = mockFunction(getName)
14+
const mockGetAddressRecord = mockFunction(getAddressRecord)
1415

1516
const address = '0xaddress'
1617
const chainId = 1
@@ -96,6 +97,14 @@ describe('getPrimaryNameQueryFn', () => {
9697
reverseResolverAddress: '0xreverseResolver',
9798
}),
9899
)
100+
// Mock getAddressRecord to return the same address so the check passes
101+
mockGetAddressRecord.mockImplementationOnce(() =>
102+
Promise.resolve({
103+
id: 60,
104+
name: 'eth',
105+
value: address,
106+
}),
107+
)
99108
const result = await getPrimaryNameQueryFn(mockConfig)({
100109
queryKey: [{ address, allowMismatch: true }, chainId, address, undefined, 'getName'],
101110
meta: {} as any,
@@ -122,6 +131,14 @@ describe('getPrimaryNameQueryFn', () => {
122131
reverseResolverAddress: '0xreverseResolver',
123132
}),
124133
)
134+
// Mock getAddressRecord to return the same address so the check passes
135+
mockGetAddressRecord.mockImplementationOnce(() =>
136+
Promise.resolve({
137+
id: 60,
138+
name: 'eth',
139+
value: address,
140+
}),
141+
)
125142
const result = await getPrimaryNameQueryFn(mockConfig)({
126143
queryKey: [{ address, allowMismatch: true }, chainId, address, undefined, 'getName'],
127144
meta: {} as any,

src/hooks/ensjs/public/usePrimaryName.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ import { ContractFunctionExecutionError } from 'viem'
33
import { readContract } from 'viem/actions'
44

55
import { universalResolverReverseSnippet } from '@ensdomains/ensjs/contracts'
6-
import { getName, GetNameParameters, GetNameReturnType } from '@ensdomains/ensjs/public'
6+
import {
7+
getAddressRecord,
8+
getName,
9+
GetNameParameters,
10+
GetNameReturnType,
11+
} from '@ensdomains/ensjs/public'
712
import { normalise } from '@ensdomains/ensjs/utils'
813

914
import { useQueryOptions } from '@app/hooks/useQueryOptions'
@@ -83,14 +88,13 @@ export const getPrimaryNameQueryFn =
8388
try {
8489
const normalizedVersion = normalise(originalName)
8590
isNormalized = originalName === normalizedVersion
86-
} catch (error) {
91+
} catch {
8792
// If normalisation fails, treat as non-normalized
8893
isNormalized = false
8994
}
9095
}
9196
}
92-
} catch (error) {
93-
console.error('Failed to get raw reverse name:', error)
97+
} catch {
9498
// Fall back to checking if res.name is normalized
9599
try {
96100
const normalizedVersion = normalise(res.name)
@@ -101,6 +105,18 @@ export const getPrimaryNameQueryFn =
101105
}
102106
} else {
103107
// For mismatch case, res.name is already the raw name
108+
// Check if the ETH address record for the name matches the input address
109+
try {
110+
const ethAddressRecord = await getAddressRecord(client, { name: res.name })
111+
const resolvedAddress = ethAddressRecord?.value
112+
113+
if (!resolvedAddress || resolvedAddress.toLowerCase() !== address.toLowerCase()) {
114+
return null
115+
}
116+
} catch {
117+
return null
118+
}
119+
104120
originalName = res.name
105121
isNormalized = false // Mismatches are treated as non-normalized
106122
}

0 commit comments

Comments
 (0)