Skip to content

Commit bd933be

Browse files
authored
Revert "fix: ens refactor" (#2914)
1 parent 3e74f20 commit bd933be

File tree

7 files changed

+131
-142
lines changed

7 files changed

+131
-142
lines changed

src/hooks/governance/useGovernanceProposals.ts

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ChainId } from '@aave/contract-helpers';
22
import { normalizeBN } from '@aave/math-utils';
33
import { useInfiniteQuery, useQuery } from '@tanstack/react-query';
4-
import { constants } from 'ethers';
4+
import { constants, Contract } from 'ethers';
55
import { gql } from 'graphql-request';
66
import {
77
adaptCacheProposalToDetail,
@@ -26,7 +26,7 @@ import {
2626
import { useRootStore } from 'src/store/root';
2727
import { governanceV3Config } from 'src/ui-config/governanceConfig';
2828
import { useSharedDependencies } from 'src/ui-config/SharedDependenciesProvider';
29-
import { getEnsProfilesMap } from 'src/utils/ens';
29+
import { getProvider } from 'src/utils/marketsAndNetworksConfig';
3030
import { subgraphRequest } from 'src/utils/subgraphRequest';
3131

3232
import { getProposal } from './useProposal';
@@ -42,6 +42,7 @@ const USE_GOVERNANCE_CACHE = process.env.NEXT_PUBLIC_USE_GOVERNANCE_CACHE === 't
4242
const PAGE_SIZE = 10;
4343
const VOTES_PAGE_SIZE = 50;
4444
const SEARCH_RESULTS_LIMIT = 10;
45+
export const ENS_REVERSE_REGISTRAR = '0x3671aE578E63FdF66ad4F3E12CC0c0d71Ac7510C';
4546

4647
// ============================================
4748
// Subgraph search query
@@ -77,6 +78,16 @@ const getProposalVotesQuery = gql`
7778
}
7879
`;
7980

81+
const ensAbi = [
82+
{
83+
inputs: [{ internalType: 'address[]', name: 'addresses', type: 'address[]' }],
84+
name: 'getNames',
85+
outputs: [{ internalType: 'string[]', name: 'r', type: 'string[]' }],
86+
stateMutability: 'view',
87+
type: 'function',
88+
},
89+
];
90+
8091
type SubgraphVote = {
8192
proposalId: string;
8293
support: boolean;
@@ -323,13 +334,18 @@ export const useGovernanceVotersSplit = (
323334
const { data: graphVotes, isFetching: graphFetching } = useQuery({
324335
queryFn: async () => {
325336
const votes = await fetchSubgraphVotes(proposalId, votingChainId as ChainId);
326-
const ensProfiles = await getEnsProfilesMap(votes.map((vote) => vote.voter));
327-
328-
return votes.map((vote) => ({
329-
...vote,
330-
ensName: ensProfiles[vote.voter.toLowerCase()]?.name,
331-
ensAvatar: ensProfiles[vote.voter.toLowerCase()]?.avatar,
332-
}));
337+
try {
338+
const provider = getProvider(governanceV3Config.coreChainId);
339+
const contract = new Contract(ENS_REVERSE_REGISTRAR, ensAbi);
340+
const connectedContract = contract.connect(provider);
341+
const ensNames: string[] = await connectedContract.getNames(votes.map((v) => v.voter));
342+
return votes.map((vote, i) => ({
343+
...vote,
344+
ensName: ensNames[i] || undefined,
345+
}));
346+
} catch {
347+
return votes;
348+
}
333349
},
334350
queryKey: ['governance-voters-graph', proposalId],
335351
enabled: !USE_GOVERNANCE_CACHE && votingChainId !== undefined && !isNaN(proposalId),
@@ -346,8 +362,18 @@ export const useGovernanceVotersSplit = (
346362
]
347363
: [];
348364

349-
const { data: cacheEnsProfiles } = useQuery({
350-
queryFn: () => getEnsProfilesMap(cacheVoterAddresses),
365+
const { data: cacheEnsNames } = useQuery({
366+
queryFn: async () => {
367+
const provider = getProvider(governanceV3Config.coreChainId);
368+
const contract = new Contract(ENS_REVERSE_REGISTRAR, ensAbi);
369+
const connectedContract = contract.connect(provider);
370+
const names: string[] = await connectedContract.getNames(cacheVoterAddresses);
371+
const map: Record<string, string> = {};
372+
cacheVoterAddresses.forEach((addr, i) => {
373+
if (names[i]) map[addr.toLowerCase()] = names[i];
374+
});
375+
return map;
376+
},
351377
queryKey: ['governance-voters-ens', proposalId, cacheVoterAddresses],
352378
enabled: USE_GOVERNANCE_CACHE && cacheVoterAddresses.length > 0,
353379
refetchOnMount: false,
@@ -358,8 +384,7 @@ export const useGovernanceVotersSplit = (
358384
if (USE_GOVERNANCE_CACHE) {
359385
const withEns = (vote: VoteDisplay): VoteDisplay => ({
360386
...vote,
361-
ensName: cacheEnsProfiles?.[vote.voter.toLowerCase()]?.name,
362-
ensAvatar: cacheEnsProfiles?.[vote.voter.toLowerCase()]?.avatar,
387+
ensName: cacheEnsNames?.[vote.voter.toLowerCase()],
363388
});
364389
const yaeVotes = (cacheForData?.pages.flatMap((p) => p.votes.map(adaptCacheVote)) || []).map(
365390
withEns
@@ -386,13 +411,11 @@ export const useGovernanceVotersSplit = (
386411
support: boolean;
387412
votingPower: string;
388413
ensName?: string;
389-
ensAvatar?: string;
390414
}): VoteDisplay => ({
391415
voter: v.voter,
392416
support: v.support,
393417
votingPower: v.votingPower,
394418
ensName: v.ensName,
395-
ensAvatar: v.ensAvatar,
396419
});
397420

398421
const yaeVotes =

src/hooks/governance/useProposalVotes.ts

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import { ChainId } from '@aave/contract-helpers';
22
import { normalizeBN } from '@aave/math-utils';
33
import { useQuery, UseQueryResult } from '@tanstack/react-query';
4+
import { Contract } from 'ethers';
45
import { gql } from 'graphql-request';
56
import { governanceV3Config } from 'src/ui-config/governanceConfig';
6-
import { getEnsProfilesMap } from 'src/utils/ens';
7+
import { getProvider } from 'src/utils/marketsAndNetworksConfig';
78
import { subgraphRequest } from 'src/utils/subgraphRequest';
89

10+
import { ENS_REVERSE_REGISTRAR } from './useGovernanceProposals';
11+
912
export type ProposalVote = {
1013
proposalId: string;
1114
support: boolean;
@@ -15,7 +18,6 @@ export type ProposalVote = {
1518

1619
export type EnhancedProposalVote = ProposalVote & {
1720
ensName?: string;
18-
ensAvatar?: string;
1921
};
2022

2123
export interface ProposalVotes {
@@ -25,6 +27,21 @@ export interface ProposalVotes {
2527
isFetching: boolean;
2628
}
2729

30+
const abi = [
31+
{
32+
inputs: [{ internalType: 'contract ENS', name: '_ens', type: 'address' }],
33+
stateMutability: 'nonpayable',
34+
type: 'constructor',
35+
},
36+
{
37+
inputs: [{ internalType: 'address[]', name: 'addresses', type: 'address[]' }],
38+
name: 'getNames',
39+
outputs: [{ internalType: 'string[]', name: 'r', type: 'string[]' }],
40+
stateMutability: 'view',
41+
type: 'function',
42+
},
43+
];
44+
2845
const getProposalVotes = gql`
2946
query getProposalVotes($proposalId: Int!) {
3047
voteEmitteds(where: { proposalId: $proposalId }) {
@@ -54,6 +71,13 @@ const fetchProposalVotes = async (
5471
}));
5572
};
5673

74+
const fetchProposalVotesEnsNames = async (addresses: string[]) => {
75+
const provider = getProvider(governanceV3Config.coreChainId);
76+
const contract = new Contract(ENS_REVERSE_REGISTRAR, abi);
77+
const connectedContract = contract.connect(provider);
78+
return connectedContract.getNames(addresses) as Promise<string[]>;
79+
};
80+
5781
export const useProposalVotesQuery = ({
5882
proposalId,
5983
votingChainId,
@@ -64,12 +88,8 @@ export const useProposalVotesQuery = ({
6488
return useQuery({
6589
queryFn: async () => {
6690
const votes = await fetchProposalVotes(proposalId, votingChainId as ChainId);
67-
const ensProfiles = await getEnsProfilesMap(votes.map((vote) => vote.voter));
68-
return votes.map((vote) => ({
69-
...vote,
70-
ensName: ensProfiles[vote.voter.toLowerCase()]?.name,
71-
ensAvatar: ensProfiles[vote.voter.toLowerCase()]?.avatar,
72-
}));
91+
const votesEnsNames = await fetchProposalVotesEnsNames(votes.map((vote) => vote.voter));
92+
return votes.map((vote, index) => ({ ...vote, ensName: votesEnsNames[index] }));
7393
},
7494
queryKey: ['proposalVotes', proposalId],
7595
enabled: votingChainId !== undefined && !isNaN(proposalId),

src/libs/hooks/use-get-ens.tsx

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { blo } from 'blo';
2+
import { utils } from 'ethers';
23
import { useEffect, useState } from 'react';
3-
import { getEnsAvatar, getEnsName } from 'src/utils/ens';
4+
import { getENSProvider } from 'src/utils/marketsAndNetworksConfig';
5+
6+
const mainnetProvider = getENSProvider();
47

58
interface EnsResponse {
69
name?: string;
@@ -10,42 +13,46 @@ interface EnsResponse {
1013
const useGetEns = (address: string): EnsResponse => {
1114
const [ensName, setEnsName] = useState<string | undefined>(undefined);
1215
const [ensAvatar, setEnsAvatar] = useState<string | undefined>(undefined);
16+
const getName = async (address: string) => {
17+
try {
18+
const name = await mainnetProvider.lookupAddress(address);
19+
setEnsName(name ? name : undefined);
20+
} catch (error) {
21+
console.error('ENS name lookup error', error);
22+
}
23+
};
24+
25+
const getAvatar = async (name: string) => {
26+
try {
27+
const labelHash = utils.keccak256(utils.toUtf8Bytes(name?.replace('.eth', '')));
28+
const result: { background_image: string } = await (
29+
await fetch(
30+
`https://metadata.ens.domains/mainnet/0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85/${labelHash}/`
31+
)
32+
).json();
33+
setEnsAvatar(
34+
result && result.background_image ? result.background_image : blo(address as `0x${string}`)
35+
);
36+
} catch (error) {
37+
console.error('ENS avatar lookup error', error);
38+
}
39+
};
1340

1441
useEffect(() => {
15-
let cancelled = false;
16-
17-
const loadEns = async () => {
18-
if (!address) {
19-
setEnsName(undefined);
20-
setEnsAvatar(undefined);
21-
return;
22-
}
23-
24-
const fallbackAvatar = blo(address as `0x${string}`);
25-
42+
if (address) {
43+
setEnsAvatar(blo(address as `0x${string}`));
44+
getName(address);
45+
} else {
2646
setEnsName(undefined);
27-
setEnsAvatar(fallbackAvatar);
28-
29-
const name = await getEnsName(address);
30-
if (cancelled) return;
31-
32-
setEnsName(name ?? undefined);
33-
34-
if (!name) return;
35-
36-
const avatar = await getEnsAvatar(name);
37-
if (cancelled) return;
38-
39-
setEnsAvatar(avatar ?? fallbackAvatar);
40-
};
41-
42-
loadEns();
43-
44-
return () => {
45-
cancelled = true;
46-
};
47+
}
4748
}, [address]);
4849

50+
useEffect(() => {
51+
if (ensName) {
52+
getAvatar(ensName);
53+
}
54+
}, [ensName]);
55+
4956
return { name: ensName, avatar: ensAvatar };
5057
};
5158

src/modules/governance/proposal/VotersListItem.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ type VotersListItemProps = {
1919
};
2020

2121
export const VotersListItem = ({ compact, voter }: VotersListItemProps): JSX.Element | null => {
22-
const { voter: address, ensAvatar, ensName } = voter;
22+
const { voter: address, ensName } = voter;
2323
const blockieAvatar = blo(address !== '' ? (address as `0x${string}`) : '0x');
2424
const trackEvent = useRootStore((store) => store.trackEvent);
2525

@@ -55,7 +55,7 @@ export const VotersListItem = ({ compact, voter }: VotersListItemProps): JSX.Ele
5555
<Box sx={{ my: 6, '&:first-of-type': { mt: 0 }, '&:last-of-type': { mb: 0 } }}>
5656
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
5757
<Box sx={{ display: 'flex', justifyContent: 'flex-start', alignItems: 'center' }}>
58-
<Avatar src={ensAvatar || blockieAvatar} sx={{ width: 24, height: 24, mr: 2 }} />
58+
<Avatar src={blockieAvatar} sx={{ width: 24, height: 24, mr: 2 }} />
5959
<Link
6060
href={`https://etherscan.io/address/${address}`}
6161
onClick={() =>

src/modules/governance/types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ export type VoteDisplay = {
8282
support: boolean;
8383
votingPower: string;
8484
ensName?: string;
85-
ensAvatar?: string;
8685
};
8786

8887
/**

src/store/utils/domain-fetchers/ens.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
import { DomainType, WalletDomain } from 'src/store/walletDomains';
2-
import { getEnsAvatar, getEnsName } from 'src/utils/ens';
2+
import { getENSProvider } from 'src/utils/marketsAndNetworksConfig';
3+
import { tFetch } from 'src/utils/tFetch';
4+
5+
const mainnetProvider = getENSProvider();
6+
7+
const getEnsName = async (address: string): Promise<string | null> => {
8+
try {
9+
const name = await mainnetProvider.lookupAddress(address);
10+
return name;
11+
} catch (error) {
12+
console.error('ENS name lookup error', error);
13+
}
14+
return null;
15+
};
16+
17+
const getEnsAvatar = async (name: string): Promise<string | undefined> => {
18+
try {
19+
const image = `https://metadata.ens.domains/mainnet/avatar/${name}/`;
20+
await tFetch<never>(image, { method: 'HEAD' });
21+
return image;
22+
} catch (error) {
23+
console.error('ENS avatar lookup error', error);
24+
}
25+
};
326

427
export const getEnsDomain = async (address: string): Promise<WalletDomain | null> => {
528
const name = await getEnsName(address);

0 commit comments

Comments
 (0)