diff --git a/src/api/address-resolver/CompositeAddressResolver.ts b/src/api/address-resolver/CompositeAddressResolver.ts index bee73da..7c11f3d 100644 --- a/src/api/address-resolver/CompositeAddressResolver.ts +++ b/src/api/address-resolver/CompositeAddressResolver.ts @@ -1,21 +1,25 @@ import { BaseProvider } from "@ethersproject/providers"; import { IAddressResolver } from "./address-resolver"; -export class CompositeAddressResolver implements IAddressResolver { - private resolvers: IAddressResolver[] = []; +export type SelectedResolvedName = [IAddressResolver, T]; - addResolver(resolver: IAddressResolver) { +export class CompositeAddressResolver + implements IAddressResolver> +{ + private resolvers: IAddressResolver[] = []; + + addResolver(resolver: IAddressResolver) { this.resolvers.push(resolver); } async resolveAddress( provider: BaseProvider, address: string - ): Promise { + ): Promise | undefined> { for (const r of this.resolvers) { - const name = r.resolveAddress(provider, address); + const name = await r.resolveAddress(provider, address); if (name !== undefined) { - return name; + return [r, name]; } } diff --git a/src/api/address-resolver/ENSAddressResolver.ts b/src/api/address-resolver/ENSAddressResolver.ts index ef45a64..820a51f 100644 --- a/src/api/address-resolver/ENSAddressResolver.ts +++ b/src/api/address-resolver/ENSAddressResolver.ts @@ -1,7 +1,7 @@ import { BaseProvider } from "@ethersproject/providers"; import { IAddressResolver } from "./address-resolver"; -export class ENSAddressResolver implements IAddressResolver { +export class ENSAddressResolver implements IAddressResolver { async resolveAddress( provider: BaseProvider, address: string diff --git a/src/api/address-resolver/ERCTokenResolver.ts b/src/api/address-resolver/ERCTokenResolver.ts new file mode 100644 index 0000000..dc8bb74 --- /dev/null +++ b/src/api/address-resolver/ERCTokenResolver.ts @@ -0,0 +1,24 @@ +import { BaseProvider } from "@ethersproject/providers"; +import { Contract } from "@ethersproject/contracts"; +import { IAddressResolver } from "./address-resolver"; +import erc20 from "../../erc20.json"; + +export class ERCTokenResolver implements IAddressResolver { + async resolveAddress( + provider: BaseProvider, + address: string + ): Promise { + const erc20Contract = new Contract(address, erc20, provider); + try { + const [name, symbol, decimals] = await Promise.all([ + erc20Contract.name(), + erc20Contract.symbol(), + erc20Contract.decimals(), + ]); + return name; + } catch (err) { + console.warn(`Couldn't get token ${address} metadata; ignoring`, err); + } + return undefined; + } +} diff --git a/src/api/address-resolver/address-resolver.ts b/src/api/address-resolver/address-resolver.ts index 246db34..87ed8b8 100644 --- a/src/api/address-resolver/address-resolver.ts +++ b/src/api/address-resolver/address-resolver.ts @@ -1,8 +1,8 @@ import { BaseProvider } from "@ethersproject/providers"; -export interface IAddressResolver { +export interface IAddressResolver { resolveAddress( provider: BaseProvider, address: string - ): Promise; + ): Promise; } diff --git a/src/api/address-resolver/index.ts b/src/api/address-resolver/index.ts index cc4fe1b..dd8b549 100644 --- a/src/api/address-resolver/index.ts +++ b/src/api/address-resolver/index.ts @@ -1,34 +1,40 @@ import { BaseProvider } from "@ethersproject/providers"; import { IAddressResolver } from "./address-resolver"; -import { CompositeAddressResolver } from "./CompositeAddressResolver"; +import { + CompositeAddressResolver, + SelectedResolvedName, +} from "./CompositeAddressResolver"; import { ENSAddressResolver } from "./ENSAddressResolver"; -export type ResolvedAddresses = Record; +export type ResolvedAddresses = Record>; // Create and configure the main resolver -const _mainResolver = new CompositeAddressResolver(); -_mainResolver.addResolver(new ENSAddressResolver()); +export const ensResolver = new ENSAddressResolver(); -export const mainResolver: IAddressResolver = _mainResolver; +const _mainResolver = new CompositeAddressResolver(); +_mainResolver.addResolver(ensResolver); + +export const mainResolver: IAddressResolver> = + _mainResolver; export const batchPopulate = async ( provider: BaseProvider, addresses: string[] ): Promise => { - const solvers: Promise[] = []; + const solvers: Promise | undefined>[] = []; for (const a of addresses) { solvers.push(mainResolver.resolveAddress(provider, a)); } const results = await Promise.all(solvers); - const cache: ResolvedAddresses = {}; + const resultMap: ResolvedAddresses = {}; for (let i = 0; i < results.length; i++) { const r = results[i]; if (r === undefined) { continue; } - cache[addresses[i]] = r; + resultMap[addresses[i]] = r; } - return cache; + return resultMap; }; diff --git a/src/components/AddressOrENSName.tsx b/src/components/AddressOrENSName.tsx index 23ba6cd..dd865d7 100644 --- a/src/components/AddressOrENSName.tsx +++ b/src/components/AddressOrENSName.tsx @@ -3,7 +3,7 @@ import Address from "./Address"; import AddressLink from "./AddressLink"; import ENSName from "./ENSName"; import ENSNameLink from "./ENSNameLink"; -import { ResolvedAddresses } from "../api/address-resolver"; +import { ensResolver, ResolvedAddresses } from "../api/address-resolver"; type AddressOrENSNameProps = { address: string; @@ -25,17 +25,17 @@ const AddressOrENSName: React.FC = ({ <> {address === selectedAddress ? ( <> - {name ? ( - + {name?.[0] === ensResolver ? ( + ) : (
)} ) : ( <> - {name ? ( + {name?.[0] ? (