Commit f9006626 authored by Brendan Wong's avatar Brendan Wong Committed by GitHub

fix: bring back safeNamehash (#7050)

* fix: bring back safeNamehash

* Update safeNamehash.test.ts
parent 1daf15df
import { namehash } from '@ethersproject/hash'
import { NEVER_RELOAD, useMainnetSingleCallResult } from 'lib/hooks/multicall' import { NEVER_RELOAD, useMainnetSingleCallResult } from 'lib/hooks/multicall'
import { useMemo } from 'react' import { useMemo } from 'react'
import { safeNamehash } from 'utils/safeNamehash'
import isZero from '../utils/isZero' import isZero from '../utils/isZero'
import { useENSRegistrarContract, useENSResolverContract } from './useContract' import { useENSRegistrarContract, useENSResolverContract } from './useContract'
...@@ -11,7 +11,7 @@ import useDebounce from './useDebounce' ...@@ -11,7 +11,7 @@ import useDebounce from './useDebounce'
*/ */
export default function useENSAddress(ensName?: string | null): { loading: boolean; address: string | null } { export default function useENSAddress(ensName?: string | null): { loading: boolean; address: string | null } {
const debouncedName = useDebounce(ensName, 200) const debouncedName = useDebounce(ensName, 200)
const ensNodeArgument = useMemo(() => [debouncedName ? namehash(debouncedName) : undefined], [debouncedName]) const ensNodeArgument = useMemo(() => [debouncedName ? safeNamehash(debouncedName) : undefined], [debouncedName])
const registrarContract = useENSRegistrarContract() const registrarContract = useENSRegistrarContract()
const resolverAddress = useMainnetSingleCallResult(registrarContract, 'resolver', ensNodeArgument, NEVER_RELOAD) const resolverAddress = useMainnetSingleCallResult(registrarContract, 'resolver', ensNodeArgument, NEVER_RELOAD)
const resolverAddressResult = resolverAddress.result?.[0] const resolverAddressResult = resolverAddress.result?.[0]
......
import { BigNumber } from '@ethersproject/bignumber' import { BigNumber } from '@ethersproject/bignumber'
import { hexZeroPad } from '@ethersproject/bytes' import { hexZeroPad } from '@ethersproject/bytes'
import { namehash } from '@ethersproject/hash'
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import { NEVER_RELOAD, useMainnetSingleCallResult } from 'lib/hooks/multicall' import { NEVER_RELOAD, useMainnetSingleCallResult } from 'lib/hooks/multicall'
import uriToHttp from 'lib/utils/uriToHttp' import uriToHttp from 'lib/utils/uriToHttp'
import { useEffect, useMemo, useState } from 'react' import { useEffect, useMemo, useState } from 'react'
import { safeNamehash } from 'utils/safeNamehash'
import { isAddress } from '../utils' import { isAddress } from '../utils'
import isZero from '../utils/isZero' import isZero from '../utils/isZero'
...@@ -23,12 +23,12 @@ export default function useENSAvatar( ...@@ -23,12 +23,12 @@ export default function useENSAvatar(
const debouncedAddress = useDebounce(address, 200) const debouncedAddress = useDebounce(address, 200)
const node = useMemo(() => { const node = useMemo(() => {
if (!debouncedAddress || !isAddress(debouncedAddress)) return undefined if (!debouncedAddress || !isAddress(debouncedAddress)) return undefined
return namehash(`${debouncedAddress.toLowerCase().substr(2)}.addr.reverse`) return safeNamehash(`${debouncedAddress.toLowerCase().substr(2)}.addr.reverse`)
}, [debouncedAddress]) }, [debouncedAddress])
const addressAvatar = useAvatarFromNode(node) const addressAvatar = useAvatarFromNode(node)
const ENSName = useENSName(address).ENSName const ENSName = useENSName(address).ENSName
const nameAvatar = useAvatarFromNode(ENSName === null ? undefined : namehash(ENSName)) const nameAvatar = useAvatarFromNode(ENSName === null ? undefined : safeNamehash(ENSName))
let avatar = addressAvatar.avatar || nameAvatar.avatar let avatar = addressAvatar.avatar || nameAvatar.avatar
const nftAvatar = useAvatarFromNFT(avatar, enforceOwnership) const nftAvatar = useAvatarFromNFT(avatar, enforceOwnership)
......
import { namehash } from '@ethersproject/hash'
import { NEVER_RELOAD, useMainnetSingleCallResult } from 'lib/hooks/multicall' import { NEVER_RELOAD, useMainnetSingleCallResult } from 'lib/hooks/multicall'
import { useMemo } from 'react' import { useMemo } from 'react'
import { safeNamehash } from 'utils/safeNamehash'
import isZero from '../utils/isZero' import isZero from '../utils/isZero'
import { useENSRegistrarContract, useENSResolverContract } from './useContract' import { useENSRegistrarContract, useENSResolverContract } from './useContract'
...@@ -9,7 +9,7 @@ import { useENSRegistrarContract, useENSResolverContract } from './useContract' ...@@ -9,7 +9,7 @@ import { useENSRegistrarContract, useENSResolverContract } from './useContract'
* Does a lookup for an ENS name to find its contenthash. * Does a lookup for an ENS name to find its contenthash.
*/ */
export default function useENSContentHash(ensName?: string | null): { loading: boolean; contenthash: string | null } { export default function useENSContentHash(ensName?: string | null): { loading: boolean; contenthash: string | null } {
const ensNodeArgument = useMemo(() => [ensName ? namehash(ensName) : undefined], [ensName]) const ensNodeArgument = useMemo(() => [ensName ? safeNamehash(ensName) : undefined], [ensName])
const registrarContract = useENSRegistrarContract() const registrarContract = useENSRegistrarContract()
const resolverAddressResult = useMainnetSingleCallResult(registrarContract, 'resolver', ensNodeArgument, NEVER_RELOAD) const resolverAddressResult = useMainnetSingleCallResult(registrarContract, 'resolver', ensNodeArgument, NEVER_RELOAD)
const resolverAddress = resolverAddressResult.result?.[0] const resolverAddress = resolverAddressResult.result?.[0]
......
import { namehash } from '@ethersproject/hash'
import { NEVER_RELOAD, useMainnetSingleCallResult } from 'lib/hooks/multicall' import { NEVER_RELOAD, useMainnetSingleCallResult } from 'lib/hooks/multicall'
import { useMemo } from 'react' import { useMemo } from 'react'
import { safeNamehash } from 'utils/safeNamehash'
import { isAddress } from '../utils' import { isAddress } from '../utils'
import isZero from '../utils/isZero' import isZero from '../utils/isZero'
...@@ -16,7 +16,7 @@ export default function useENSName(address?: string): { ENSName: string | null; ...@@ -16,7 +16,7 @@ export default function useENSName(address?: string): { ENSName: string | null;
const debouncedAddress = useDebounce(address, 200) const debouncedAddress = useDebounce(address, 200)
const ensNodeArgument = useMemo(() => { const ensNodeArgument = useMemo(() => {
if (!debouncedAddress || !isAddress(debouncedAddress)) return [undefined] if (!debouncedAddress || !isAddress(debouncedAddress)) return [undefined]
return [namehash(`${debouncedAddress.toLowerCase().substr(2)}.addr.reverse`)] return [safeNamehash(`${debouncedAddress.toLowerCase().substr(2)}.addr.reverse`)]
}, [debouncedAddress]) }, [debouncedAddress])
const registrarContract = useENSRegistrarContract() const registrarContract = useENSRegistrarContract()
const resolverAddress = useMainnetSingleCallResult(registrarContract, 'resolver', ensNodeArgument, NEVER_RELOAD) const resolverAddress = useMainnetSingleCallResult(registrarContract, 'resolver', ensNodeArgument, NEVER_RELOAD)
......
import { Provider } from '@ethersproject/abstract-provider' import { Provider } from '@ethersproject/abstract-provider'
import { Contract } from '@ethersproject/contracts' import { Contract } from '@ethersproject/contracts'
import { namehash } from '@ethersproject/hash' import { safeNamehash } from 'utils/safeNamehash'
const REGISTRAR_ABI = [ const REGISTRAR_ABI = [
{ {
...@@ -61,7 +61,7 @@ function resolverContract(resolverAddress: string, provider: Provider): Contract ...@@ -61,7 +61,7 @@ function resolverContract(resolverAddress: string, provider: Provider): Contract
*/ */
export default async function resolveENSContentHash(ensName: string, provider: Provider): Promise<string> { export default async function resolveENSContentHash(ensName: string, provider: Provider): Promise<string> {
const ensRegistrarContract = new Contract(REGISTRAR_ADDRESS, REGISTRAR_ABI, provider) const ensRegistrarContract = new Contract(REGISTRAR_ADDRESS, REGISTRAR_ABI, provider)
const hash = namehash(ensName) const hash = safeNamehash(ensName)
const resolverAddress = await ensRegistrarContract.resolver(hash) const resolverAddress = await ensRegistrarContract.resolver(hash)
return resolverContract(resolverAddress, provider).contenthash(hash) return resolverContract(resolverAddress, provider).contenthash(hash)
} }
import { namehash } from '@ethersproject/hash'
import { safeNamehash } from 'utils/safeNamehash'
describe('safeNamehash', () => {
const emoji = '🤔'
const zeroWidthJoiner = ''
it('namehash works', () => {
expect(namehash(emoji)).toEqual('0x9c0c5bf9a185012d3b3b586a357a19ab95718d9eb5a2bf845924c40cc13f82b0')
})
// suppress console.debug for the next test
beforeEach(() => {
// eslint-disable-next-line @typescript-eslint/no-empty-function
jest.spyOn(console, 'debug').mockImplementation(() => {})
})
it('namehash does not work', () => {
expect(() => namehash(zeroWidthJoiner)).toThrow()
})
it('safenamehash works', () => {
expect(safeNamehash(zeroWidthJoiner)).toEqual(undefined)
})
})
import { namehash } from '@ethersproject/hash'
export function safeNamehash(name?: string): string | undefined {
if (name === undefined) return undefined
try {
return namehash(name)
} catch (error) {
console.debug(error)
return undefined
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment