diff --git a/frontend/src/pages/addresses/[address].tsx b/frontend/src/pages/addresses/[address].tsx index b9be8fe..432c4a7 100644 --- a/frontend/src/pages/addresses/[address].tsx +++ b/frontend/src/pages/addresses/[address].tsx @@ -51,14 +51,17 @@ export default function AddressDetailPage() { const [watchlistEntries, setWatchlistEntries] = useState([]) const [methodResults, setMethodResults] = useState>({}) const [methodInputs, setMethodInputs] = useState>({}) - const [loading, setLoading] = useState(true) + const [addressInfoLoading, setAddressInfoLoading] = useState(true) + const [activityLoading, setActivityLoading] = useState(true) const loadAddressInfo = useCallback(async () => { + setAddressInfoLoading(true) try { const { ok, data } = await addressesApi.getSafe(chainId, address) if (!ok) { setAddressInfo(null) setContractProfile(null) + setGruProfile(null) return } setAddressInfo(data ?? null) @@ -82,10 +85,13 @@ export default function AddressDetailPage() { setAddressInfo(null) setContractProfile(null) setGruProfile(null) + } finally { + setAddressInfoLoading(false) } }, [chainId, address]) const loadTransactions = useCallback(async () => { + setActivityLoading(true) try { const [transactionsResult, balancesResult, transfersResult] = await Promise.all([ addressesApi.getTransactionsSafe(chainId, address, 1, 20), @@ -102,27 +108,37 @@ export default function AddressDetailPage() { setTokenBalances([]) setTokenTransfers([]) } finally { - setLoading(false) + setActivityLoading(false) } }, [chainId, address]) useEffect(() => { if (!router.isReady || !address) { - setLoading(router.isReady ? false : true) + setAddressInfoLoading(!router.isReady) + setActivityLoading(!router.isReady) if (router.isReady && !address) { setAddressInfo(null) setTransactions([]) + setTokenBalances([]) + setTokenTransfers([]) } return } if (!isValidAddressParam) { - setLoading(false) + setAddressInfoLoading(false) + setActivityLoading(false) setAddressInfo(null) setTransactions([]) + setTokenBalances([]) + setTokenTransfers([]) return } - loadAddressInfo() - loadTransactions() + setAddressInfo(null) + setTransactions([]) + setTokenBalances([]) + setTokenTransfers([]) + void loadAddressInfo() + void loadTransactions() }, [address, isValidAddressParam, loadAddressInfo, loadTransactions, router.isReady]) useEffect(() => { @@ -403,6 +419,8 @@ export default function AddressDetailPage() { const gruTransferCount = tokenTransfers.filter((transfer) => Boolean(getGruExplorerMetadata({ address: transfer.token_address, symbol: transfer.token_symbol })), ).length + const showPrimaryLoadingState = !router.isReady || (addressInfoLoading && !addressInfo) + const resolvedAddressInfo = addressInfo as AddressInfo return (
@@ -426,7 +444,7 @@ export default function AddressDetailPage() { Search this address )} - {watchlistAddress && router.isReady && !loading && ( + {watchlistAddress && router.isReady && !addressInfoLoading && (
- ) : !addressInfo ? ( + ) : !addressInfoLoading && !addressInfo ? (

Address not found.

@@ -470,68 +488,69 @@ export default function AddressDetailPage() {
-
+
- {addressInfo.balance && ( - {formatWeiAsEth(addressInfo.balance)} + {resolvedAddressInfo.balance && ( + {formatWeiAsEth(resolvedAddressInfo.balance)} )} {isSavedToWatchlist ? 'Saved for quick access' : 'Not saved yet'}
- + {contractProfile?.source_verified ? : null} {contractProfile?.abi_available ? : null} - {addressInfo.token_contract ? : null} + {resolvedAddressInfo.token_contract ? : null}
- {addressInfo.token_contract && ( + {resolvedAddressInfo.token_contract && (
- {addressInfo.token_contract.symbol || addressInfo.token_contract.name || 'Token contract'} · {addressInfo.token_contract.type || 'Token'} + {resolvedAddressInfo.token_contract.symbol || resolvedAddressInfo.token_contract.name || 'Token contract'} · {resolvedAddressInfo.token_contract.type || 'Token'}
- + Open token detail →
)} - {addressInfo.tags.length > 0 && ( + {resolvedAddressInfo.tags.length > 0 && ( - {addressInfo.tags.map((tag, i) => ( + {resolvedAddressInfo.tags.map((tag, i) => ( ))} )} - {addressInfo.transaction_count} - {addressInfo.token_count} - {addressInfo.is_contract ? 'Contract' : 'EOA'} + {resolvedAddressInfo.transaction_count} + {resolvedAddressInfo.token_count} + {resolvedAddressInfo.is_contract ? 'Contract' : 'EOA'} - {incomingTransactions} incoming / {outgoingTransactions} outgoing txs + {activityLoading ? 'Loading recent activity...' : `${incomingTransactions} incoming / ${outgoingTransactions} outgoing txs`} - {addressInfo.internal_transaction_count != null && ( - {addressInfo.internal_transaction_count} + {resolvedAddressInfo.internal_transaction_count != null && ( + {resolvedAddressInfo.internal_transaction_count} )} - {addressInfo.logs_count != null && ( - {addressInfo.logs_count} + {resolvedAddressInfo.logs_count != null && ( + {resolvedAddressInfo.logs_count} )} - {incomingTokenTransfers} incoming / {outgoingTokenTransfers} outgoing token transfers - {addressInfo.token_transfer_count != null ? ` · ${addressInfo.token_transfer_count} total indexed` : ''} + {activityLoading + ? 'Loading token transfer activity...' + : `${incomingTokenTransfers} incoming / ${outgoingTokenTransfers} outgoing token transfers${resolvedAddressInfo.token_transfer_count != null ? ` · ${resolvedAddressInfo.token_transfer_count} total indexed` : ''}`} - {addressInfo.creation_transaction_hash && ( + {resolvedAddressInfo.creation_transaction_hash && ( - -
+ +
)}
- {addressInfo.is_contract && ( + {resolvedAddressInfo.is_contract && (
@@ -771,12 +790,16 @@ export default function AddressDetailPage() {
) : null} - balance.token_address || `${balance.token_symbol}-${balance.value}`} - /> + {activityLoading ? ( +

Loading token balances...

+ ) : ( +
balance.token_address || `${balance.token_symbol}-${balance.value}`} + /> + )} @@ -791,21 +814,29 @@ export default function AddressDetailPage() { ) : null} -
`${transfer.transaction_hash}-${transfer.token_address}-${transfer.value}`} - /> + {activityLoading ? ( +

Loading token transfers...

+ ) : ( +
`${transfer.transaction_hash}-${transfer.token_address}-${transfer.value}`} + /> + )} -
tx.hash} - /> + {activityLoading ? ( +

Loading recent transactions...

+ ) : ( +
tx.hash} + /> + )} )}