diff --git a/src/AddressTransactions.tsx b/src/AddressTransactions.tsx index a598cc8..b7985fa 100644 --- a/src/AddressTransactions.tsx +++ b/src/AddressTransactions.tsx @@ -1,5 +1,6 @@ import React, { useState, useEffect, useMemo } from "react"; import { useParams, useLocation, useHistory } from "react-router-dom"; +import { ethers } from "ethers"; import queryString from "query-string"; import Blockies from "react-blockies"; import StandardFrame from "./StandardFrame"; @@ -12,10 +13,10 @@ import PendingResults from "./search/PendingResults"; import TransactionItem from "./search/TransactionItem"; import { SearchController } from "./search/search"; import { useFeeToggler } from "./search/useFeeToggler"; -import { ethers } from "ethers"; +import { provider } from "./ethersconfig"; type BlockParams = { - address: string; + addressOrName: string; direction?: string; }; @@ -33,13 +34,37 @@ const AddressTransactions: React.FC = () => { hash = qs.h as string; } - // Normalize to checksummed address - const checksummedAddress = useMemo( - () => ethers.utils.getAddress(params.address), - [params.address] - ); - if (params.address !== checksummedAddress) { - console.log("NORMALIZE"); + const [checksummedAddress, setChecksummedAddress] = useState(); + const [isENS, setENS] = useState(); + const [error, setError] = useState(); + + // If it looks like it is an ENS name, try to resolve it + useEffect(() => { + if (ethers.utils.isAddress(params.addressOrName)) { + // Normalize to checksummed address + setChecksummedAddress(ethers.utils.getAddress(params.addressOrName)); + return; + } + + const resolveName = async () => { + const resolvedAddress = await provider.resolveName(params.addressOrName); + if (resolvedAddress !== null) { + setENS(true); + setChecksummedAddress(resolvedAddress); + setError(false); + } else { + setError(true); + } + }; + resolveName(); + }, [params.addressOrName]); + + // Request came with a non-checksummed address; fix the URL + if ( + !isENS && + checksummedAddress && + params.addressOrName !== checksummedAddress + ) { history.replace( `/address/${checksummedAddress}${ params.direction ? "/" + params.direction : "" @@ -49,6 +74,10 @@ const AddressTransactions: React.FC = () => { const [controller, setController] = useState(); useEffect(() => { + if (!checksummedAddress) { + return; + } + const readFirstPage = async () => { const _controller = await SearchController.firstPage(checksummedAddress); setController(_controller); @@ -100,77 +129,92 @@ const AddressTransactions: React.FC = () => { const page = useMemo(() => controller?.getPage(), [controller]); - document.title = `Address ${params.address} | Otterscan`; + document.title = `Address ${params.addressOrName} | Otterscan`; const [feeDisplay, feeDisplayToggler] = useFeeToggler(); return ( - -
- - Address - - {params.address} - - -
-
- -
-
- {page === undefined ? ( - <>Waiting for search results... - ) : ( - <>{page.length} transactions on this page - )} -
- -
- - {controller ? ( + {error ? ( + + "{params.addressOrName}" is not an ETH address or ENS name. + + ) : ( + checksummedAddress && ( <> - {controller.getPage().map((tx) => ( - - ))} -
-
- {page !== undefined && ( - <>{page.length} transactions on this page + +
+ + Address + + {checksummedAddress} + + + {isENS && ( + + ENS: {params.addressOrName} + )}
- + +
+
+ {page === undefined ? ( + <>Waiting for search results... + ) : ( + <>{page.length} transactions on this page + )} +
+ +
+ -
+ {controller ? ( + <> + {controller.getPage().map((tx) => ( + + ))} +
+
+ {page !== undefined && ( + <>{page.length} transactions on this page + )} +
+ +
+ + ) : ( + + )} + - ) : ( - - )} - + ) + )} ); }; diff --git a/src/App.tsx b/src/App.tsx index 3ce405f..9082f6f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -30,7 +30,7 @@ const App = () => ( - + diff --git a/src/Home.tsx b/src/Home.tsx index a67796a..7b7a814 100644 --- a/src/Home.tsx +++ b/src/Home.tsx @@ -64,8 +64,9 @@ const Home: React.FC = () => { className="w-full border rounded focus:outline-none px-2 py-1 mb-10" type="text" size={50} - placeholder="Search by address / txn hash / block number" + placeholder="Search by address / txn hash / block number / ENS name" onChange={handleChange} + autoFocus >