From 892bf8fe7db5cc55f8e82fb8e13aa62f57762a12 Mon Sep 17 00:00:00 2001 From: fisher Date: Fri, 24 Jan 2025 11:06:27 +0800 Subject: [PATCH] Fix resolve conflict --- src/components/address-card.tsx | 54 +++-------------------- src/utils/ensName.ts | 76 +++++++++++++++++++++++++++------ 2 files changed, 67 insertions(+), 63 deletions(-) diff --git a/src/components/address-card.tsx b/src/components/address-card.tsx index d75a45d..f9b35dc 100644 --- a/src/components/address-card.tsx +++ b/src/components/address-card.tsx @@ -2,63 +2,21 @@ import Avatar from '@/components/avatar'; import ClipboardIconButton from './clipboard-icon-button'; import { toShortAddress } from '@/utils'; import { useEffect, useState } from 'react'; -import { resolveEnsName } from '@/utils/ensName'; +import { getEnsName } from '@/utils/ensName'; interface AddressCardProps { address?: `0x${string}`; copyable?: boolean; } -const ensCache = new Map(); -let currentRequestId = 0; -const failedRequests = new Set(); -const RETRY_DELAY = 1000; // 1 second delay - const AddressCard = ({ address, copyable = true }: AddressCardProps) => { const [ensName, setEnsName] = useState(); - const [isLoading, setIsLoading] = useState(false); - - const getEnsName = async (connectedAddress: string): Promise => { - if (failedRequests.has(connectedAddress)) { - return; - } - - if (ensCache.has(connectedAddress)) { - setEnsName(ensCache.get(connectedAddress)); - return; - } - - const requestId = ++currentRequestId; - setIsLoading(true); - - try { - const name = await resolveEnsName(connectedAddress); - if (requestId !== currentRequestId) return; - - const resolvedName = name || undefined; - if (resolvedName) { - ensCache.set(connectedAddress, resolvedName); - setEnsName(resolvedName); - } - - } catch (error: unknown) { - if (error && typeof error === 'object' && 'message' in error) { - if (typeof error.message === 'string' && error.message.includes('429')) { - failedRequests.add(connectedAddress); - - setTimeout(() => { - failedRequests.delete(connectedAddress); - }, RETRY_DELAY); - } - } - } finally { - setIsLoading(false); - } - }; useEffect(() => { if (address) { - getEnsName(address); + getEnsName(address).then( + name => setEnsName(name) + ); } }, [address]); @@ -66,9 +24,7 @@ const AddressCard = ({ address, copyable = true }: AddressCardProps) => {
{address && } - {isLoading - ? '...' - : (ensName ? ensName : toShortAddress(address))} + {ensName ? ensName : toShortAddress(address)} {copyable && (
diff --git a/src/utils/ensName.ts b/src/utils/ensName.ts index af09207..9a4382d 100644 --- a/src/utils/ensName.ts +++ b/src/utils/ensName.ts @@ -4,20 +4,68 @@ const ethereumProvider = new ethers.JsonRpcProvider( 'https://mainnet.infura.io/v3/dfbe7a8f440b4342b6bada71dd3df498' ); -export const resolveEnsName = async (address) => { - try { - // Use the Ethereum provider to fetch the ENS name - const ensName = await ethereumProvider.lookupAddress(address); - - if (ensName) { - console.log('ENS Name:', ensName); - return ensName; - } else { - console.log('No ENS name found for this address'); +const ensCache = new Map(); +const failedRequests = new Set(); +const RETRY_DELAY = 1000; // 1 second delay + +// Add a map to track pending promises +const pendingRequests = new Map>(); + +export const getEnsName = async (connectedAddress: string) => { + console.log("Getting ENS name for:", connectedAddress); + if (!connectedAddress) return; + + // Check cache first + if (ensCache.has(connectedAddress)) { + const name = ensCache.get(connectedAddress); + if (name === 'noName') return; + return name; + } + + // Check if there's already a pending request for this address + if (pendingRequests.has(connectedAddress)) { + console.log("Using existing pending request for:", connectedAddress); + return pendingRequests.get(connectedAddress); + } + + // Create new promise for this request + const promise = (async () => { + if (failedRequests.has(connectedAddress)) { return null; } - } catch (error) { - console.error('Error resolving ENS name:', error); - return null; - } + + try { + const name = await resolveEnsName(connectedAddress); + ensCache.set(connectedAddress, name || 'noName'); + console.log("ENS Cache updated:", ensCache); + return name; + } catch (error: unknown) { + if (error && typeof error === 'object' && 'message' in error) { + if (typeof error.message === 'string' && error.message.includes('429')) { + failedRequests.add(connectedAddress); + console.log("Failed Requests:", failedRequests); + + setTimeout(() => { + failedRequests.delete(connectedAddress); + }, RETRY_DELAY); + } + } + return null; + } finally { + // Clean up the pending request + pendingRequests.delete(connectedAddress); + } + })(); + + // Store the promise + pendingRequests.set(connectedAddress, promise); + + return promise; +}; + +export const resolveEnsName = async (address: string) => { + const ensName = await ethereumProvider.lookupAddress(address); + console.log('Address:', address); + console.log('ENS Name:', ensName); + return ensName; };