Skip to content

Revert "fix: ens resolve"#2894

Merged
foodaka merged 1 commit intomainfrom
revert-2892-fix/ens-resolve
Mar 10, 2026
Merged

Revert "fix: ens resolve"#2894
foodaka merged 1 commit intomainfrom
revert-2892-fix/ens-resolve

Conversation

@foodaka
Copy link
Collaborator

@foodaka foodaka commented Mar 10, 2026

Reverts #2892

Copilot AI review requested due to automatic review settings March 10, 2026 12:10
@vercel
Copy link

vercel bot commented Mar 10, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
interface Building Building Preview, Comment Mar 10, 2026 0:10am

Request Review

@foodaka foodaka merged commit f076cbb into main Mar 10, 2026
11 of 12 checks passed
@foodaka foodaka deleted the revert-2892-fix/ens-resolve branch March 10, 2026 12:12
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Reverts prior ENS-resolution changes by switching ENS lookups away from viem and back to ethers providers, and updates governance vote/voter flows accordingly.

Changes:

  • Replace viem ENS client usage with an ethers mainnet provider for name/address resolution.
  • Update governance voter ENS enrichment to use a ReverseRecords getNames contract call.
  • Simplify voter list avatar rendering back to blockies.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/utils/marketsAndNetworksConfig.ts Removes viem client creation and introduces getENSProvider using StaticJsonRpcProvider.
src/store/utils/domain-fetchers/ens.ts Updates ENS name lookup to use lookupAddress on the ethers provider.
src/modules/governance/proposal/VotersListItem.tsx Removes ENS avatar URL handling; renders blockie avatar only.
src/libs/hooks/use-get-ens.tsx Switches ENS name lookup to ethers provider; replaces avatar resolution logic with metadata fetch.
src/hooks/governance/useProposalVotes.ts Replaces per-address ENS lookups with a batched getNames contract call.
src/hooks/governance/useGovernanceProposals.ts Adds ReverseRecords constant/ABI and uses getNames for voter ENS enrichment (graph + cache paths).
src/components/transactions/Bridge/BridgeDestinationInput.tsx Updates ENS destination resolution to provider.resolveName.
src/components/WalletConnection/ReadOnlyModal.tsx Updates ENS resolution to provider.resolveName and adds provider instantiation.
Comments suppressed due to low confidence (1)

src/components/transactions/Bridge/BridgeDestinationInput.tsx:57

  • The ENS lookup effect does not handle errors from resolveName. If it throws, setValidatingENS(false) is never reached and the loading spinner can get stuck. Wrap the resolution in try/catch/finally (and consider reusing a single cached provider instead of calling getENSProvider() inside the effect).
  useEffect(() => {
    const checkENS = async () => {
      setValidatingENS(true);
      const resolvedAddress = await getENSProvider().resolveName(destinationAccount);
      if (resolvedAddress) {
        setDestinationAccount(resolvedAddress.toLowerCase());
      }
      setValidatingENS(false);
    };

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +46 to 49
const resolvedAddress = await mainnetProvider.resolveName(normalizedENS);
if (resolvedAddress && utils.isAddress(resolvedAddress)) {
saveAndClose(resolvedAddress);
} else {
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolveName is awaited without try/catch. If the RPC call fails, the handler will throw and the UI won't set validAddressError, leaving the modal in a broken state. Catch resolution errors and treat them as an invalid ENS (set the error state and avoid throwing).

Suggested change
const resolvedAddress = await mainnetProvider.resolveName(normalizedENS);
if (resolvedAddress && utils.isAddress(resolvedAddress)) {
saveAndClose(resolvedAddress);
} else {
try {
const resolvedAddress = await mainnetProvider.resolveName(normalizedENS);
if (resolvedAddress && utils.isAddress(resolvedAddress)) {
saveAndClose(resolvedAddress);
} else {
setValidAddressError(true);
}
} catch {
// Treat resolution errors as invalid ENS

Copilot uses AI. Check for mistakes.
Comment on lines +191 to 195
export const getENSProvider = () => {
const chainId = 1;
const config = getNetworkConfig(chainId);
return new StaticJsonRpcProvider(config.publicJsonRPCUrl[0], chainId);
};
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getENSProvider hard-codes chainId = 1 and always uses publicJsonRPCUrl[0], bypassing the existing provider caching/rotation logic in getProvider. This reduces resilience (no RPC failover) and introduces a magic number. Consider using ChainId.mainnet and returning a cached mainnet provider (e.g., reusing getProvider(ChainId.mainnet) or a module-level singleton) so ENS lookups benefit from the same fallback behavior.

Copilot uses AI. Check for mistakes.
Comment on lines 25 to +35
const getAvatar = async (name: string) => {
try {
const avatar = await viemClient.getEnsAvatar({ name });
setEnsAvatar(avatar ?? blo(address as `0x${string}`));
const labelHash = utils.keccak256(utils.toUtf8Bytes(name?.replace('.eth', '')));
const result: { background_image: string } = await (
await fetch(
`https://metadata.ens.domains/mainnet/0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85/${labelHash}/`
)
).json();
setEnsAvatar(
result && result.background_image ? result.background_image : blo(address as `0x${string}`)
);
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getAvatar is building an ENS NFT metadata URL and reading background_image, which is not the ENS avatar text-record and will likely return unrelated data (or fail) for many names/subdomains/TLDs. Ethers providers support ENS avatars directly (e.g., provider.getAvatar(name)), which matches the previous behavior more closely. Also, name.replace('.eth', '') is not anchored and can transform unexpected inputs.

Copilot uses AI. Check for mistakes.
Comment on lines +74 to +78
const fetchProposalVotesEnsNames = async (addresses: string[]) => {
const provider = getProvider(governanceV3Config.coreChainId);
const contract = new Contract(ENS_REVERSE_REGISTRAR, abi);
const connectedContract = contract.connect(provider);
return connectedContract.getNames(addresses) as Promise<string[]>;
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fetchProposalVotesEnsNames now performs a single getNames call without any error handling. If the RPC call fails/reverts (rate limits, payload too large, etc.), the entire useProposalVotesQuery will reject and votes won't render. Wrap the ENS fetch in try/catch and fall back to empty strings/undefined, and consider chunking/deduping large address lists to avoid oversized eth_call payloads.

Copilot uses AI. Check for mistakes.
Comment on lines 357 to +370
// ENS resolution for cache path voters
const cacheVoterAddresses = USE_GOVERNANCE_CACHE
? [
...(cacheForData?.pages.flatMap((p) => p.votes.map((v) => v.voter)) || []),
...(cacheAgainstData?.pages.flatMap((p) => p.votes.map((v) => v.voter)) || []),
]
: [];

const { data: cacheEnsNames } = useQuery({
queryFn: async () => {
const names = await Promise.all(
cacheVoterAddresses.map((addr) =>
viemClient.getEnsName({ address: addr as `0x${string}` }).catch(() => null)
)
);
const provider = getProvider(governanceV3Config.coreChainId);
const contract = new Contract(ENS_REVERSE_REGISTRAR, ensAbi);
const connectedContract = contract.connect(provider);
const names: string[] = await connectedContract.getNames(cacheVoterAddresses);
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ENS name resolution for cached voters calls getNames(cacheVoterAddresses) with the raw flattened list, which can contain duplicates and can grow with each loaded page. This can lead to large calldata and RPC failures. Consider deduplicating addresses and chunking requests (then remapping results) to keep eth_call payloads bounded.

Copilot uses AI. Check for mistakes.
Comment on lines 32 to 35
const { breakpoints } = useTheme();
const sm = useMediaQuery(breakpoints.down('sm'));
const mainnetProvider = getENSProvider();
const trackEvent = useRootStore((store) => store.trackEvent);
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mainnetProvider is created inside the component body, so a new StaticJsonRpcProvider instance is constructed on every render. This can create unnecessary connections and makes caching harder. Prefer a module-level singleton (like other ENS helpers) or useMemo to construct it once.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link

@github-actions
Copy link

📦 Next.js Bundle Analysis for aave-ui

This analysis was generated by the Next.js Bundle Analysis action. 🤖

This PR introduced no changes to the JavaScript bundle! 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants