From 6fefb2e7f94e666ee720ec44ea4ac67cd31bc477 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 30 Oct 2021 05:04:19 -0300 Subject: [PATCH 01/28] Update topic0 to 0.2.1 --- topic0 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/topic0 b/topic0 index 52559d5..5026a20 160000 --- a/topic0 +++ b/topic0 @@ -1 +1 @@ -Subproject commit 52559d5690d491f8191a2d3fdb3c037516adc68f +Subproject commit 5026a20b712c1cad66878821c38e1f070e4a3799 From 19f7af84a5c8f3df70f0d0e0c67ddb07103f3423 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 30 Oct 2021 21:06:11 -0300 Subject: [PATCH 02/28] Extract resolver api --- .../CompositeAddressResolver.ts | 26 +++++++++++++++ .../address-resolver/ENSAddressResolver.ts | 15 +++++++++ src/api/address-resolver/address-resolver.ts | 8 +++++ src/api/address-resolver/index.ts | 33 +++++++++++++++++++ src/types.ts | 4 +-- src/useReverseCache.ts | 16 ++------- 6 files changed, 85 insertions(+), 17 deletions(-) create mode 100644 src/api/address-resolver/CompositeAddressResolver.ts create mode 100644 src/api/address-resolver/ENSAddressResolver.ts create mode 100644 src/api/address-resolver/address-resolver.ts create mode 100644 src/api/address-resolver/index.ts diff --git a/src/api/address-resolver/CompositeAddressResolver.ts b/src/api/address-resolver/CompositeAddressResolver.ts new file mode 100644 index 0000000..bee73da --- /dev/null +++ b/src/api/address-resolver/CompositeAddressResolver.ts @@ -0,0 +1,26 @@ +import { BaseProvider } from "@ethersproject/providers"; +import { IAddressResolver } from "./address-resolver"; + +export class CompositeAddressResolver implements IAddressResolver { + private resolvers: IAddressResolver[] = []; + + addResolver(resolver: IAddressResolver) { + this.resolvers.push(resolver); + } + + async resolveAddress( + provider: BaseProvider, + address: string + ): Promise { + for (const r of this.resolvers) { + const name = r.resolveAddress(provider, address); + if (name !== undefined) { + return name; + } + } + + return undefined; + // TODO: fallback to address itself + // return address; + } +} diff --git a/src/api/address-resolver/ENSAddressResolver.ts b/src/api/address-resolver/ENSAddressResolver.ts new file mode 100644 index 0000000..ef45a64 --- /dev/null +++ b/src/api/address-resolver/ENSAddressResolver.ts @@ -0,0 +1,15 @@ +import { BaseProvider } from "@ethersproject/providers"; +import { IAddressResolver } from "./address-resolver"; + +export class ENSAddressResolver implements IAddressResolver { + async resolveAddress( + provider: BaseProvider, + address: string + ): Promise { + const name = await provider.lookupAddress(address); + if (name === null) { + return undefined; + } + return name; + } +} diff --git a/src/api/address-resolver/address-resolver.ts b/src/api/address-resolver/address-resolver.ts new file mode 100644 index 0000000..246db34 --- /dev/null +++ b/src/api/address-resolver/address-resolver.ts @@ -0,0 +1,8 @@ +import { BaseProvider } from "@ethersproject/providers"; + +export interface IAddressResolver { + resolveAddress( + provider: BaseProvider, + address: string + ): Promise; +} diff --git a/src/api/address-resolver/index.ts b/src/api/address-resolver/index.ts new file mode 100644 index 0000000..a9b4ff6 --- /dev/null +++ b/src/api/address-resolver/index.ts @@ -0,0 +1,33 @@ +import { BaseProvider } from "@ethersproject/providers"; +import { ENSReverseCache } from "../../types"; +import { IAddressResolver } from "./address-resolver"; +import { CompositeAddressResolver } from "./CompositeAddressResolver"; +import { ENSAddressResolver } from "./ENSAddressResolver"; + +// Create and configure the main resolver +const _mainResolver = new CompositeAddressResolver(); +_mainResolver.addResolver(new ENSAddressResolver()); + +export const mainResolver: IAddressResolver = _mainResolver; + +export const batchPopulate = async ( + provider: BaseProvider, + addresses: string[] +): Promise => { + const solvers: Promise[] = []; + for (const a of addresses) { + solvers.push(mainResolver.resolveAddress(provider, a)); + } + + const results = await Promise.all(solvers); + const cache: ENSReverseCache = {}; + for (let i = 0; i < results.length; i++) { + const r = results[i]; + if (r === undefined) { + continue; + } + cache[addresses[i]] = r; + } + + return cache; +}; diff --git a/src/types.ts b/src/types.ts index 5904b31..76a1944 100644 --- a/src/types.ts +++ b/src/types.ts @@ -32,9 +32,7 @@ export type TransactionChunk = { lastPage: boolean; }; -export type ENSReverseCache = { - [address: string]: string; -}; +export type ENSReverseCache = Record; export type TransactionData = { transactionHash: string; diff --git a/src/useReverseCache.ts b/src/useReverseCache.ts index 365888a..fa0ca1a 100644 --- a/src/useReverseCache.ts +++ b/src/useReverseCache.ts @@ -1,6 +1,7 @@ import { useState, useEffect } from "react"; import { JsonRpcProvider } from "@ethersproject/providers"; import { ENSReverseCache, ProcessedTransaction } from "./types"; +import { batchPopulate } from "./api/address-resolver"; export const useENSCache = ( provider?: JsonRpcProvider, @@ -25,20 +26,7 @@ export const useENSCache = ( const addresses = Array.from(addrSet); const reverseResolve = async () => { - const solvers: Promise[] = []; - for (const a of addresses) { - solvers.push(provider.lookupAddress(a)); - } - - const results = await Promise.all(solvers); - const cache: ENSReverseCache = {}; - for (let i = 0; i < results.length; i++) { - const r = results[i]; - if (r === null) { - continue; - } - cache[addresses[i]] = r; - } + const cache = await batchPopulate(provider, addresses); setReverseCache(cache); }; reverseResolve(); From b8eea08f4d623a944e1d5ecc3f9a205b913d1052 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 30 Oct 2021 21:08:10 -0300 Subject: [PATCH 03/28] Move type --- src/api/address-resolver/index.ts | 3 ++- src/search/TransactionItem.tsx | 3 ++- src/types.ts | 2 -- src/useReverseCache.ts | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/api/address-resolver/index.ts b/src/api/address-resolver/index.ts index a9b4ff6..9bc5833 100644 --- a/src/api/address-resolver/index.ts +++ b/src/api/address-resolver/index.ts @@ -1,9 +1,10 @@ import { BaseProvider } from "@ethersproject/providers"; -import { ENSReverseCache } from "../../types"; import { IAddressResolver } from "./address-resolver"; import { CompositeAddressResolver } from "./CompositeAddressResolver"; import { ENSAddressResolver } from "./ENSAddressResolver"; +export type ENSReverseCache = Record; + // Create and configure the main resolver const _mainResolver = new CompositeAddressResolver(); _mainResolver.addResolver(new ENSAddressResolver()); diff --git a/src/search/TransactionItem.tsx b/src/search/TransactionItem.tsx index 76e58e7..57fb7e4 100644 --- a/src/search/TransactionItem.tsx +++ b/src/search/TransactionItem.tsx @@ -14,10 +14,11 @@ import TransactionDirection, { Flags, } from "../components/TransactionDirection"; import TransactionValue from "../components/TransactionValue"; -import { ENSReverseCache, ProcessedTransaction } from "../types"; +import { ProcessedTransaction } from "../types"; import { FeeDisplay } from "./useFeeToggler"; import { formatValue } from "../components/formatter"; import ETH2USDValue from "../components/ETH2USDValue"; +import { ENSReverseCache } from "../api/address-resolver"; type TransactionItemProps = { tx: ProcessedTransaction; diff --git a/src/types.ts b/src/types.ts index 76a1944..12763bb 100644 --- a/src/types.ts +++ b/src/types.ts @@ -32,8 +32,6 @@ export type TransactionChunk = { lastPage: boolean; }; -export type ENSReverseCache = Record; - export type TransactionData = { transactionHash: string; from: string; diff --git a/src/useReverseCache.ts b/src/useReverseCache.ts index fa0ca1a..25d0774 100644 --- a/src/useReverseCache.ts +++ b/src/useReverseCache.ts @@ -1,7 +1,7 @@ import { useState, useEffect } from "react"; import { JsonRpcProvider } from "@ethersproject/providers"; -import { ENSReverseCache, ProcessedTransaction } from "./types"; -import { batchPopulate } from "./api/address-resolver"; +import { ProcessedTransaction } from "./types"; +import { batchPopulate, ENSReverseCache } from "./api/address-resolver"; export const useENSCache = ( provider?: JsonRpcProvider, From 60ead1ba494227cebe8cfd946993a366ab5ca3d6 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 30 Oct 2021 21:10:15 -0300 Subject: [PATCH 04/28] Rename type --- src/api/address-resolver/index.ts | 6 +++--- src/search/TransactionItem.tsx | 4 ++-- src/useReverseCache.ts | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/api/address-resolver/index.ts b/src/api/address-resolver/index.ts index 9bc5833..cc4fe1b 100644 --- a/src/api/address-resolver/index.ts +++ b/src/api/address-resolver/index.ts @@ -3,7 +3,7 @@ import { IAddressResolver } from "./address-resolver"; import { CompositeAddressResolver } from "./CompositeAddressResolver"; import { ENSAddressResolver } from "./ENSAddressResolver"; -export type ENSReverseCache = Record; +export type ResolvedAddresses = Record; // Create and configure the main resolver const _mainResolver = new CompositeAddressResolver(); @@ -14,14 +14,14 @@ export const mainResolver: IAddressResolver = _mainResolver; export const batchPopulate = async ( provider: BaseProvider, addresses: string[] -): Promise => { +): Promise => { const solvers: Promise[] = []; for (const a of addresses) { solvers.push(mainResolver.resolveAddress(provider, a)); } const results = await Promise.all(solvers); - const cache: ENSReverseCache = {}; + const cache: ResolvedAddresses = {}; for (let i = 0; i < results.length; i++) { const r = results[i]; if (r === undefined) { diff --git a/src/search/TransactionItem.tsx b/src/search/TransactionItem.tsx index 57fb7e4..3917e24 100644 --- a/src/search/TransactionItem.tsx +++ b/src/search/TransactionItem.tsx @@ -18,11 +18,11 @@ import { ProcessedTransaction } from "../types"; import { FeeDisplay } from "./useFeeToggler"; import { formatValue } from "../components/formatter"; import ETH2USDValue from "../components/ETH2USDValue"; -import { ENSReverseCache } from "../api/address-resolver"; +import { ResolvedAddresses } from "../api/address-resolver"; type TransactionItemProps = { tx: ProcessedTransaction; - ensCache?: ENSReverseCache; + ensCache?: ResolvedAddresses; selectedAddress?: string; feeDisplay: FeeDisplay; priceMap: Record; diff --git a/src/useReverseCache.ts b/src/useReverseCache.ts index 25d0774..e931e58 100644 --- a/src/useReverseCache.ts +++ b/src/useReverseCache.ts @@ -1,13 +1,13 @@ import { useState, useEffect } from "react"; import { JsonRpcProvider } from "@ethersproject/providers"; import { ProcessedTransaction } from "./types"; -import { batchPopulate, ENSReverseCache } from "./api/address-resolver"; +import { batchPopulate, ResolvedAddresses } from "./api/address-resolver"; export const useENSCache = ( provider?: JsonRpcProvider, page?: ProcessedTransaction[] ) => { - const [reverseCache, setReverseCache] = useState(); + const [reverseCache, setReverseCache] = useState(); useEffect(() => { if (!provider || !page) { From 9da41d0a2e8406563d59d2ee493556e047121e33 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 30 Oct 2021 21:14:11 -0300 Subject: [PATCH 05/28] Typo fix --- src/components/DecoratedAddressLink.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/DecoratedAddressLink.tsx b/src/components/DecoratedAddressLink.tsx index 0b38fab..ca42a90 100644 --- a/src/components/DecoratedAddressLink.tsx +++ b/src/components/DecoratedAddressLink.tsx @@ -23,7 +23,7 @@ type DecoratedAddressLinkProps = { tokenMeta?: TokenMeta; }; -const DecoratedAddresssLink: React.FC = ({ +const DecoratedAddressLink: React.FC = ({ address, ensName, selectedAddress, @@ -90,4 +90,4 @@ const DecoratedAddresssLink: React.FC = ({ ); }; -export default React.memo(DecoratedAddresssLink); +export default React.memo(DecoratedAddressLink); From a0675c637780eb45c8539c467e4f5f211ec4f460 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 30 Oct 2021 21:31:31 -0300 Subject: [PATCH 06/28] Use ResolvedAddresses table instead of pre-resolved name parameter --- src/AddressTransactions.tsx | 4 +- src/block/BlockTransactionResults.tsx | 4 +- src/components/AddressOrENSName.tsx | 66 +++++++++++++------------ src/components/DecoratedAddressLink.tsx | 7 +-- src/search/TransactionItem.tsx | 16 ++---- 5 files changed, 48 insertions(+), 49 deletions(-) diff --git a/src/AddressTransactions.tsx b/src/AddressTransactions.tsx index 53f92bf..3bbd6df 100644 --- a/src/AddressTransactions.tsx +++ b/src/AddressTransactions.tsx @@ -165,7 +165,7 @@ const AddressTransactions: React.FC = () => { }, [provider, checksummedAddress, params.direction, hash, controller]); const page = useMemo(() => controller?.getPage(), [controller]); - const reverseCache = useENSCache(provider, page); + const resolvedAddresses = useENSCache(provider, page); const blockTags: BlockTag[] = useMemo(() => { if (!page) { @@ -283,7 +283,7 @@ const AddressTransactions: React.FC = () => { = ({ const selectionCtx = useSelection(); const [feeDisplay, feeDisplayToggler] = useFeeToggler(); const { provider } = useContext(RuntimeContext); - const reverseCache = useENSCache(provider, page); + const resolvedAddresses = useENSCache(provider, page); const blockTags = useMemo(() => [blockTag], [blockTag]); const priceMap = useMultipleETHUSDOracle(provider, blockTags); @@ -59,7 +59,7 @@ const BlockTransactionResults: React.FC = ({ diff --git a/src/components/AddressOrENSName.tsx b/src/components/AddressOrENSName.tsx index 9cb2f9e..43d40e1 100644 --- a/src/components/AddressOrENSName.tsx +++ b/src/components/AddressOrENSName.tsx @@ -3,49 +3,53 @@ import Address from "./Address"; import AddressLink from "./AddressLink"; import ENSName from "./ENSName"; import ENSNameLink from "./ENSNameLink"; +import { ResolvedAddresses } from "../api/address-resolver"; type AddressOrENSNameProps = { address: string; - ensName?: string; selectedAddress?: string; text?: string; dontOverrideColors?: boolean; + resolvedAddresses?: ResolvedAddresses | undefined; }; const AddressOrENSName: React.FC = ({ address, - ensName, selectedAddress, text, dontOverrideColors, -}) => ( - <> - {address === selectedAddress ? ( - <> - {ensName ? ( - - ) : ( -
- )} - - ) : ( - <> - {ensName ? ( - - ) : ( - - )} - - )} - -); + resolvedAddresses, +}) => { + const name = resolvedAddresses?.[address]; + return ( + <> + {address === selectedAddress ? ( + <> + {name ? ( + + ) : ( +
+ )} + + ) : ( + <> + {name ? ( + + ) : ( + + )} + + )} + + ); +}; export default React.memo(AddressOrENSName); diff --git a/src/components/DecoratedAddressLink.tsx b/src/components/DecoratedAddressLink.tsx index ca42a90..ee88b31 100644 --- a/src/components/DecoratedAddressLink.tsx +++ b/src/components/DecoratedAddressLink.tsx @@ -8,10 +8,10 @@ import { faCoins } from "@fortawesome/free-solid-svg-icons/faCoins"; import TokenLogo from "./TokenLogo"; import AddressOrENSName from "./AddressOrENSName"; import { AddressContext, TokenMeta, ZERO_ADDRESS } from "../types"; +import { ResolvedAddresses } from "../api/address-resolver"; type DecoratedAddressLinkProps = { address: string; - ensName?: string; selectedAddress?: string; text?: string; addressCtx?: AddressContext; @@ -21,11 +21,11 @@ type DecoratedAddressLinkProps = { txFrom?: boolean; txTo?: boolean; tokenMeta?: TokenMeta; + resolvedAddresses?: ResolvedAddresses | undefined; }; const DecoratedAddressLink: React.FC = ({ address, - ensName, selectedAddress, text, addressCtx, @@ -35,6 +35,7 @@ const DecoratedAddressLink: React.FC = ({ txFrom, txTo, tokenMeta, + resolvedAddresses, }) => { const mint = addressCtx === AddressContext.FROM && address === ZERO_ADDRESS; const burn = addressCtx === AddressContext.TO && address === ZERO_ADDRESS; @@ -81,10 +82,10 @@ const DecoratedAddressLink: React.FC = ({ )} ); diff --git a/src/search/TransactionItem.tsx b/src/search/TransactionItem.tsx index 3917e24..f71457e 100644 --- a/src/search/TransactionItem.tsx +++ b/src/search/TransactionItem.tsx @@ -22,7 +22,7 @@ import { ResolvedAddresses } from "../api/address-resolver"; type TransactionItemProps = { tx: ProcessedTransaction; - ensCache?: ResolvedAddresses; + resolvedAddresses?: ResolvedAddresses; selectedAddress?: string; feeDisplay: FeeDisplay; priceMap: Record; @@ -30,7 +30,7 @@ type TransactionItemProps = { const TransactionItem: React.FC = ({ tx, - ensCache, + resolvedAddresses, selectedAddress, feeDisplay, priceMap, @@ -51,12 +51,6 @@ const TransactionItem: React.FC = ({ } } - const ensFrom = ensCache && tx.from && ensCache[tx.from]; - const ensTo = ensCache && tx.to && ensCache[tx.to]; - const ensCreated = - ensCache && - tx.createdContractAddress && - ensCache[tx.createdContractAddress]; const flash = tx.gasPrice.isZero() && tx.internalMinerInteraction; return ( @@ -88,9 +82,9 @@ const TransactionItem: React.FC = ({ )} @@ -108,18 +102,18 @@ const TransactionItem: React.FC = ({ ) : ( )} From b770bb5fb5863e89e3cf154461d3c3bf1c79cb38 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 30 Oct 2021 21:49:23 -0300 Subject: [PATCH 07/28] Migrate search results to page collector name hooks --- src/AddressTransactions.tsx | 5 +-- src/block/BlockTransactionResults.tsx | 5 +-- src/useResolvedAddresses.ts | 48 +++++++++++++++++++++++++++ src/useReverseCache.ts | 36 -------------------- 4 files changed, 54 insertions(+), 40 deletions(-) create mode 100644 src/useResolvedAddresses.ts delete mode 100644 src/useReverseCache.ts diff --git a/src/AddressTransactions.tsx b/src/AddressTransactions.tsx index 3bbd6df..9fbbec6 100644 --- a/src/AddressTransactions.tsx +++ b/src/AddressTransactions.tsx @@ -26,7 +26,7 @@ import PendingResults from "./search/PendingResults"; import TransactionItem from "./search/TransactionItem"; import { SearchController } from "./search/search"; import { RuntimeContext } from "./useRuntime"; -import { useENSCache } from "./useReverseCache"; +import { pageCollector, useResolvedAddresses } from "./useResolvedAddresses"; import { useFeeToggler } from "./search/useFeeToggler"; import { SelectionContext, useSelection } from "./useSelection"; import { useMultipleETHUSDOracle } from "./usePriceOracle"; @@ -165,7 +165,8 @@ const AddressTransactions: React.FC = () => { }, [provider, checksummedAddress, params.direction, hash, controller]); const page = useMemo(() => controller?.getPage(), [controller]); - const resolvedAddresses = useENSCache(provider, page); + const addrCollector = useMemo(() => pageCollector(page), [page]); + const resolvedAddresses = useResolvedAddresses(provider, addrCollector); const blockTags: BlockTag[] = useMemo(() => { if (!page) { diff --git a/src/block/BlockTransactionResults.tsx b/src/block/BlockTransactionResults.tsx index f6eb4de..f9cfc27 100644 --- a/src/block/BlockTransactionResults.tsx +++ b/src/block/BlockTransactionResults.tsx @@ -8,7 +8,7 @@ import TransactionItem from "../search/TransactionItem"; import { useFeeToggler } from "../search/useFeeToggler"; import { RuntimeContext } from "../useRuntime"; import { SelectionContext, useSelection } from "../useSelection"; -import { useENSCache } from "../useReverseCache"; +import { pageCollector, useResolvedAddresses } from "../useResolvedAddresses"; import { ProcessedTransaction } from "../types"; import { PAGE_SIZE } from "../params"; import { useMultipleETHUSDOracle } from "../usePriceOracle"; @@ -29,7 +29,8 @@ const BlockTransactionResults: React.FC = ({ const selectionCtx = useSelection(); const [feeDisplay, feeDisplayToggler] = useFeeToggler(); const { provider } = useContext(RuntimeContext); - const resolvedAddresses = useENSCache(provider, page); + const addrCollector = useMemo(() => pageCollector(page), [page]); + const resolvedAddresses = useResolvedAddresses(provider, addrCollector); const blockTags = useMemo(() => [blockTag], [blockTag]); const priceMap = useMultipleETHUSDOracle(provider, blockTags); diff --git a/src/useResolvedAddresses.ts b/src/useResolvedAddresses.ts new file mode 100644 index 0000000..3eefdf0 --- /dev/null +++ b/src/useResolvedAddresses.ts @@ -0,0 +1,48 @@ +import { useState, useEffect } from "react"; +import { JsonRpcProvider } from "@ethersproject/providers"; +import { ProcessedTransaction } from "./types"; +import { batchPopulate, ResolvedAddresses } from "./api/address-resolver"; + +export type AddressCollector = () => string[]; + +export const pageCollector = + (page: ProcessedTransaction[] | undefined): AddressCollector => + () => { + if (!page) { + return []; + } + + const uniqueAddresses = new Set(); + for (const tx of page) { + if (tx.from) { + uniqueAddresses.add(tx.from); + } + if (tx.to) { + uniqueAddresses.add(tx.to); + } + } + + return Array.from(uniqueAddresses); + }; + +export const useResolvedAddresses = ( + provider: JsonRpcProvider | undefined, + addrCollector: AddressCollector +) => { + const [names, setNames] = useState(); + + useEffect(() => { + if (!provider) { + return; + } + + const populate = async () => { + const _addresses = addrCollector(); + const _names = await batchPopulate(provider, _addresses); + setNames(_names); + }; + populate(); + }, [provider, addrCollector]); + + return names; +}; diff --git a/src/useReverseCache.ts b/src/useReverseCache.ts deleted file mode 100644 index e931e58..0000000 --- a/src/useReverseCache.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { useState, useEffect } from "react"; -import { JsonRpcProvider } from "@ethersproject/providers"; -import { ProcessedTransaction } from "./types"; -import { batchPopulate, ResolvedAddresses } from "./api/address-resolver"; - -export const useENSCache = ( - provider?: JsonRpcProvider, - page?: ProcessedTransaction[] -) => { - const [reverseCache, setReverseCache] = useState(); - - useEffect(() => { - if (!provider || !page) { - return; - } - - const addrSet = new Set(); - for (const tx of page) { - if (tx.from) { - addrSet.add(tx.from); - } - if (tx.to) { - addrSet.add(tx.to); - } - } - const addresses = Array.from(addrSet); - - const reverseResolve = async () => { - const cache = await batchPopulate(provider, addresses); - setReverseCache(cache); - }; - reverseResolve(); - }, [provider, page]); - - return reverseCache; -}; From 7708fa75e512c43c6aac52917d30cff084120cad Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 30 Oct 2021 21:54:05 -0300 Subject: [PATCH 08/28] Remove unnecessary nested span --- src/components/Address.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Address.tsx b/src/components/Address.tsx index d7694e5..62891a3 100644 --- a/src/components/Address.tsx +++ b/src/components/Address.tsx @@ -6,7 +6,7 @@ type AddressProps = { const Address: React.FC = ({ address }) => ( - {address} + {address} ); From 8341c274f61198c956bcd86e445d0afb660c3cc1 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 30 Oct 2021 21:56:32 -0300 Subject: [PATCH 09/28] Remove unnecessary React.memo --- src/components/Address.tsx | 2 +- src/components/AddressLink.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Address.tsx b/src/components/Address.tsx index 62891a3..478f4f6 100644 --- a/src/components/Address.tsx +++ b/src/components/Address.tsx @@ -10,4 +10,4 @@ const Address: React.FC = ({ address }) => ( ); -export default React.memo(Address); +export default Address; diff --git a/src/components/AddressLink.tsx b/src/components/AddressLink.tsx index a8fd5c3..4b6f99e 100644 --- a/src/components/AddressLink.tsx +++ b/src/components/AddressLink.tsx @@ -24,4 +24,4 @@ const AddressLink: React.FC = ({ ); -export default React.memo(AddressLink); +export default AddressLink; From 119cb67b00237401b73cc51fbd96e164c894a313 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 30 Oct 2021 22:00:03 -0300 Subject: [PATCH 10/28] Remove unnecessary nested span --- src/components/AddressLink.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/AddressLink.tsx b/src/components/AddressLink.tsx index 4b6f99e..8353457 100644 --- a/src/components/AddressLink.tsx +++ b/src/components/AddressLink.tsx @@ -17,10 +17,9 @@ const AddressLink: React.FC = ({ dontOverrideColors ? "" : "text-link-blue hover:text-link-blue-hover" } font-address truncate`} to={`/address/${address}`} + title={text ?? address} > - - {text ?? address} - + {text ?? address} ); From 4c59cd188f144e3a2015e4485fa77d8cbefc029b Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 30 Oct 2021 22:05:26 -0300 Subject: [PATCH 11/28] Remove redundant React.memo --- src/components/AddressOrENSName.tsx | 2 +- src/components/ENSName.tsx | 2 +- src/components/ENSNameLink.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/AddressOrENSName.tsx b/src/components/AddressOrENSName.tsx index 43d40e1..23ba6cd 100644 --- a/src/components/AddressOrENSName.tsx +++ b/src/components/AddressOrENSName.tsx @@ -52,4 +52,4 @@ const AddressOrENSName: React.FC = ({ ); }; -export default React.memo(AddressOrENSName); +export default AddressOrENSName; diff --git a/src/components/ENSName.tsx b/src/components/ENSName.tsx index 7bc8032..95f1e1f 100644 --- a/src/components/ENSName.tsx +++ b/src/components/ENSName.tsx @@ -22,4 +22,4 @@ const ENSName: React.FC = ({ name, address }) => ( ); -export default React.memo(ENSName); +export default ENSName; diff --git a/src/components/ENSNameLink.tsx b/src/components/ENSNameLink.tsx index c1da646..ad5df4d 100644 --- a/src/components/ENSNameLink.tsx +++ b/src/components/ENSNameLink.tsx @@ -31,4 +31,4 @@ const ENSNameLink: React.FC = ({ ); -export default React.memo(ENSNameLink); +export default ENSNameLink; From 3211befaeac1eb4f4466b93c47dfe78d8f5cc7f7 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 30 Oct 2021 22:14:16 -0300 Subject: [PATCH 12/28] Remove redundant React.memo --- src/search/TransactionItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search/TransactionItem.tsx b/src/search/TransactionItem.tsx index f71457e..2e6132d 100644 --- a/src/search/TransactionItem.tsx +++ b/src/search/TransactionItem.tsx @@ -139,4 +139,4 @@ const TransactionItem: React.FC = ({ ); }; -export default React.memo(TransactionItem); +export default TransactionItem; From 41be42d1ced1b271ea31e64b96d7f2f67f4216e0 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 30 Oct 2021 22:14:37 -0300 Subject: [PATCH 13/28] Save 1 array construction --- src/AddressTransactions.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AddressTransactions.tsx b/src/AddressTransactions.tsx index 9fbbec6..19d41bb 100644 --- a/src/AddressTransactions.tsx +++ b/src/AddressTransactions.tsx @@ -278,9 +278,9 @@ const AddressTransactions: React.FC = () => { feeDisplay={feeDisplay} feeDisplayToggler={feeDisplayToggler} /> - {controller ? ( + {page ? ( - {controller.getPage().map((tx) => ( + {page.map((tx) => ( Date: Sat, 30 Oct 2021 22:44:33 -0300 Subject: [PATCH 14/28] Retrofit name resolvers into transaction/* pages --- src/Transaction.tsx | 16 ++++++++++++++- src/transaction/Details.tsx | 6 ++++++ src/transaction/LogEntry.tsx | 10 +++++++++- src/transaction/Logs.tsx | 5 ++++- src/useResolvedAddresses.ts | 38 +++++++++++++++++++++++++++++++++++- 5 files changed, 71 insertions(+), 4 deletions(-) diff --git a/src/Transaction.tsx b/src/Transaction.tsx index a240c7e..7107b32 100644 --- a/src/Transaction.tsx +++ b/src/Transaction.tsx @@ -11,6 +11,10 @@ import { useInternalOperations, useTxData } from "./useErigonHooks"; import { useETHUSDOracle } from "./usePriceOracle"; import { useAppConfigContext } from "./useAppConfig"; import { useSourcify, useTransactionDescription } from "./useSourcify"; +import { + transactionDataCollector, + useResolvedAddresses, +} from "./useResolvedAddresses"; const Details = React.lazy( () => @@ -36,6 +40,11 @@ const Transaction: React.FC = () => { const { txhash } = params; const txData = useTxData(provider, txhash); + const addrCollector = useMemo( + () => transactionDataCollector(txData), + [txData] + ); + const resolvedAddresses = useResolvedAddresses(provider, addrCollector); const internalOps = useInternalOperations(provider, txData); const sendsEthToMiner = useMemo(() => { @@ -100,10 +109,15 @@ const Transaction: React.FC = () => { internalOps={internalOps} sendsEthToMiner={sendsEthToMiner} ethUSDPrice={blockETHUSDPrice} + resolvedAddresses={resolvedAddresses} /> - + diff --git a/src/transaction/Details.tsx b/src/transaction/Details.tsx index 4746cc5..72f448a 100644 --- a/src/transaction/Details.tsx +++ b/src/transaction/Details.tsx @@ -38,6 +38,7 @@ import ModeTab from "../components/ModeTab"; import DecodedParamsTable from "./decoder/DecodedParamsTable"; import { rawInputTo4Bytes, use4Bytes } from "../use4Bytes"; import { DevDoc, UserDoc } from "../useSourcify"; +import { ResolvedAddresses } from "../api/address-resolver"; type DetailsProps = { txData: TransactionData; @@ -47,6 +48,7 @@ type DetailsProps = { internalOps?: InternalOperation[]; sendsEthToMiner: boolean; ethUSDPrice: BigNumber | undefined; + resolvedAddresses: ResolvedAddresses | undefined; }; const Details: React.FC = ({ @@ -57,6 +59,7 @@ const Details: React.FC = ({ internalOps, sendsEthToMiner, ethUSDPrice, + resolvedAddresses, }) => { const hasEIP1559 = txData.confirmedData?.blockBaseFeePerGas !== undefined && @@ -154,6 +157,7 @@ const Details: React.FC = ({ address={txData.from} miner={txData.from === txData.confirmedData?.miner} txFrom + resolvedAddresses={resolvedAddresses} /> @@ -171,6 +175,7 @@ const Details: React.FC = ({ address={txData.to} miner={txData.to === txData.confirmedData?.miner} txTo + resolvedAddresses={resolvedAddresses} /> @@ -188,6 +193,7 @@ const Details: React.FC = ({ address={txData.confirmedData.createdContractAddress!} creation txTo + resolvedAddresses={resolvedAddresses} /> diff --git a/src/transaction/LogEntry.tsx b/src/transaction/LogEntry.tsx index 23ab883..2993e16 100644 --- a/src/transaction/LogEntry.tsx +++ b/src/transaction/LogEntry.tsx @@ -10,14 +10,21 @@ import DecodedParamsTable from "./decoder/DecodedParamsTable"; import DecodedLogSignature from "./decoder/DecodedLogSignature"; import { TransactionData } from "../types"; import { useTopic0 } from "../useTopic0"; +import { ResolvedAddresses } from "../api/address-resolver"; type LogEntryProps = { txData: TransactionData; log: Log; logDesc: LogDescription | null | undefined; + resolvedAddresses: ResolvedAddresses | undefined; }; -const LogEntry: React.FC = ({ txData, log, logDesc }) => { +const LogEntry: React.FC = ({ + txData, + log, + logDesc, + resolvedAddresses, +}) => { const rawTopic0 = log.topics[0]; const topic0 = useTopic0(rawTopic0); @@ -62,6 +69,7 @@ const LogEntry: React.FC = ({ txData, log, logDesc }) => { miner={log.address === txData.confirmedData?.miner} txFrom={log.address === txData.from} txTo={log.address === txData.to} + resolvedAddresses={resolvedAddresses} /> diff --git a/src/transaction/Logs.tsx b/src/transaction/Logs.tsx index 45fe491..1fd4207 100644 --- a/src/transaction/Logs.tsx +++ b/src/transaction/Logs.tsx @@ -5,13 +5,15 @@ import LogEntry from "./LogEntry"; import { TransactionData } from "../types"; import { useAppConfigContext } from "../useAppConfig"; import { Metadata, useMultipleMetadata } from "../useSourcify"; +import { ResolvedAddresses } from "../api/address-resolver"; type LogsProps = { txData: TransactionData; metadata: Metadata | null | undefined; + resolvedAddresses: ResolvedAddresses | undefined; }; -const Logs: React.FC = ({ txData, metadata }) => { +const Logs: React.FC = ({ txData, metadata, resolvedAddresses }) => { const baseMetadatas = useMemo((): Record => { if (!txData.to || metadata === undefined) { return {}; @@ -70,6 +72,7 @@ const Logs: React.FC = ({ txData, metadata }) => { txData={txData} log={l} logDesc={logDescs?.[i]} + resolvedAddresses={resolvedAddresses} /> ))} diff --git a/src/useResolvedAddresses.ts b/src/useResolvedAddresses.ts index 3eefdf0..74042e5 100644 --- a/src/useResolvedAddresses.ts +++ b/src/useResolvedAddresses.ts @@ -1,6 +1,6 @@ import { useState, useEffect } from "react"; import { JsonRpcProvider } from "@ethersproject/providers"; -import { ProcessedTransaction } from "./types"; +import { ProcessedTransaction, TransactionData } from "./types"; import { batchPopulate, ResolvedAddresses } from "./api/address-resolver"; export type AddressCollector = () => string[]; @@ -25,6 +25,42 @@ export const pageCollector = return Array.from(uniqueAddresses); }; +export const transactionDataCollector = + (txData: TransactionData | null | undefined): AddressCollector => + () => { + if (!txData) { + return []; + } + + const uniqueAddresses = new Set(); + + // Standard fields + uniqueAddresses.add(txData.from); + if (txData.to) { + uniqueAddresses.add(txData.to); + } + if (txData.confirmedData?.createdContractAddress) { + uniqueAddresses.add(txData.confirmedData?.createdContractAddress); + } + + // Dig token transfers + for (const t of txData.tokenTransfers) { + uniqueAddresses.add(t.from); + uniqueAddresses.add(t.to); + uniqueAddresses.add(t.token); + } + + // Dig log addresses + if (txData.confirmedData) { + for (const l of txData.confirmedData.logs) { + uniqueAddresses.add(l.address); + // TODO: find a way to dig over decoded address log attributes + } + } + + return Array.from(uniqueAddresses); + }; + export const useResolvedAddresses = ( provider: JsonRpcProvider | undefined, addrCollector: AddressCollector From 3a0401d25eb67c3116d20a9320647c381cfc52f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 31 Oct 2021 01:47:18 +0000 Subject: [PATCH 15/28] Bump react-error-boundary from 3.1.3 to 3.1.4 (#109) --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index e441646..ef51571 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,7 @@ "react-blockies": "^1.4.1", "react-chartjs-2": "^3.3.0", "react-dom": "^17.0.2", - "react-error-boundary": "^3.1.3", + "react-error-boundary": "^3.1.4", "react-helmet-async": "^1.1.2", "react-image": "^4.0.3", "react-router-dom": "^5.3.0", @@ -14621,9 +14621,9 @@ } }, "node_modules/react-error-boundary": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.3.tgz", - "integrity": "sha512-A+F9HHy9fvt9t8SNDlonq01prnU8AmkjvGKV4kk8seB9kU3xMEO8J/PQlLVmoOIDODl5U2kufSBs4vrWIqhsAA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", + "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", "dependencies": { "@babel/runtime": "^7.12.5" }, @@ -29543,9 +29543,9 @@ } }, "react-error-boundary": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.3.tgz", - "integrity": "sha512-A+F9HHy9fvt9t8SNDlonq01prnU8AmkjvGKV4kk8seB9kU3xMEO8J/PQlLVmoOIDODl5U2kufSBs4vrWIqhsAA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", + "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", "requires": { "@babel/runtime": "^7.12.5" } diff --git a/package.json b/package.json index 64fe411..d301e67 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "react-blockies": "^1.4.1", "react-chartjs-2": "^3.3.0", "react-dom": "^17.0.2", - "react-error-boundary": "^3.1.3", + "react-error-boundary": "^3.1.4", "react-helmet-async": "^1.1.2", "react-image": "^4.0.3", "react-router-dom": "^5.3.0", From 25cc823c91ba440df3d08aa1272b0d28eb532ebf Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sun, 31 Oct 2021 02:38:41 -0300 Subject: [PATCH 16/28] Generalize resolver framework to allow tracking of the resolver source --- .../CompositeAddressResolver.ts | 16 ++++++++----- .../address-resolver/ENSAddressResolver.ts | 2 +- src/api/address-resolver/ERCTokenResolver.ts | 24 +++++++++++++++++++ src/api/address-resolver/address-resolver.ts | 4 ++-- src/api/address-resolver/index.ts | 24 ++++++++++++------- src/components/AddressOrENSName.tsx | 10 ++++---- 6 files changed, 57 insertions(+), 23 deletions(-) create mode 100644 src/api/address-resolver/ERCTokenResolver.ts 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] ? ( From 887e35ce491d8f621904566a4adbd8833aff5c92 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sun, 31 Oct 2021 03:16:03 -0300 Subject: [PATCH 17/28] Generalize plain address/ens rendering logic --- src/components/Address.tsx | 13 ------ src/components/AddressLink.tsx | 26 ------------ src/components/AddressOrENSName.tsx | 64 ++++++++++++++--------------- src/components/ENSName.tsx | 51 +++++++++++++++++++---- src/components/ENSNameLink.tsx | 34 --------------- src/components/PlainAddress.tsx | 38 +++++++++++++++++ 6 files changed, 112 insertions(+), 114 deletions(-) delete mode 100644 src/components/Address.tsx delete mode 100644 src/components/AddressLink.tsx delete mode 100644 src/components/ENSNameLink.tsx create mode 100644 src/components/PlainAddress.tsx diff --git a/src/components/Address.tsx b/src/components/Address.tsx deleted file mode 100644 index 478f4f6..0000000 --- a/src/components/Address.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from "react"; - -type AddressProps = { - address: string; -}; - -const Address: React.FC = ({ address }) => ( - - {address} - -); - -export default Address; diff --git a/src/components/AddressLink.tsx b/src/components/AddressLink.tsx deleted file mode 100644 index 8353457..0000000 --- a/src/components/AddressLink.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from "react"; -import { NavLink } from "react-router-dom"; - -type AddressLinkProps = { - address: string; - text?: string; - dontOverrideColors?: boolean; -}; - -const AddressLink: React.FC = ({ - address, - text, - dontOverrideColors, -}) => ( - - {text ?? address} - -); - -export default AddressLink; diff --git a/src/components/AddressOrENSName.tsx b/src/components/AddressOrENSName.tsx index dd865d7..83fd0cd 100644 --- a/src/components/AddressOrENSName.tsx +++ b/src/components/AddressOrENSName.tsx @@ -1,9 +1,7 @@ import React from "react"; -import Address from "./Address"; -import AddressLink from "./AddressLink"; -import ENSName from "./ENSName"; -import ENSNameLink from "./ENSNameLink"; import { ensResolver, ResolvedAddresses } from "../api/address-resolver"; +import PlainAddress from "./PlainAddress"; +import ENSName from "./ENSName"; type AddressOrENSNameProps = { address: string; @@ -20,36 +18,34 @@ const AddressOrENSName: React.FC = ({ dontOverrideColors, resolvedAddresses, }) => { - const name = resolvedAddresses?.[address]; - return ( - <> - {address === selectedAddress ? ( - <> - {name?.[0] === ensResolver ? ( - - ) : ( -
- )} - - ) : ( - <> - {name?.[0] ? ( - - ) : ( - - )} - - )} - - ); + const resolvedAddress = resolvedAddresses?.[address]; + const linkable = address !== selectedAddress; + + if (resolvedAddress === undefined) { + return ( + + ); + } + + const [resolver, resolvedName] = resolvedAddress; + if (resolver === ensResolver) { + return ( + + ); + } + + return <>; }; export default AddressOrENSName; diff --git a/src/components/ENSName.tsx b/src/components/ENSName.tsx index 95f1e1f..ac1b038 100644 --- a/src/components/ENSName.tsx +++ b/src/components/ENSName.tsx @@ -1,25 +1,62 @@ import React from "react"; +import { NavLink } from "react-router-dom"; import ENSLogo from "./ensLogo.svg"; type ENSNameProps = { name: string; address: string; + text: string | undefined; + linkable: boolean; + dontOverrideColors?: boolean; }; -const ENSName: React.FC = ({ name, address }) => ( -
+const ENSName: React.FC = ({ + name, + address, + text, + linkable, + dontOverrideColors, +}) => { + if (linkable) { + return ( + + + + ); + } + + return ( +
+ +
+ ); +}; + +type ContentProps = { + linkable: boolean; + name: string; +}; + +const Content: React.FC = ({ linkable, name }) => ( + <> ENS Logo {name} -
+ ); export default ENSName; diff --git a/src/components/ENSNameLink.tsx b/src/components/ENSNameLink.tsx deleted file mode 100644 index ad5df4d..0000000 --- a/src/components/ENSNameLink.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from "react"; -import { NavLink } from "react-router-dom"; -import ENSLogo from "./ensLogo.svg"; - -type ENSNameLinkProps = { - name: string; - address: string; - dontOverrideColors?: boolean; -}; - -const ENSNameLink: React.FC = ({ - name, - address, - dontOverrideColors, -}) => ( - - ENS Logo - {name} - -); - -export default ENSNameLink; diff --git a/src/components/PlainAddress.tsx b/src/components/PlainAddress.tsx new file mode 100644 index 0000000..6ebe634 --- /dev/null +++ b/src/components/PlainAddress.tsx @@ -0,0 +1,38 @@ +import React from "react"; +import { NavLink } from "react-router-dom"; + +type PlainAddressProps = { + address: string; + text: string | undefined; + linkable: boolean; + dontOverrideColors: boolean | undefined; +}; + +const PlainAddress: React.FC = ({ + address, + text, + linkable, + dontOverrideColors, +}) => { + if (linkable) { + return ( + + <>{text ?? address} + + ); + } + + return ( + + {address} + + ); +}; + +export default PlainAddress; From 59ff4fd40112ac2c5274322b1085aa138d43ca1a Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sun, 31 Oct 2021 05:10:42 -0300 Subject: [PATCH 18/28] Extract renderer interface --- src/api/address-resolver/address-resolver.ts | 8 ++++++++ src/api/address-resolver/index.ts | 9 ++++++++- src/components/AddressOrENSName.tsx | 14 ++++++++------ src/components/ENSName.tsx | 17 +++++++++++++++-- 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/api/address-resolver/address-resolver.ts b/src/api/address-resolver/address-resolver.ts index 87ed8b8..0527b04 100644 --- a/src/api/address-resolver/address-resolver.ts +++ b/src/api/address-resolver/address-resolver.ts @@ -1,3 +1,4 @@ +import React from "react"; import { BaseProvider } from "@ethersproject/providers"; export interface IAddressResolver { @@ -6,3 +7,10 @@ export interface IAddressResolver { address: string ): Promise; } + +export type ResolvedAddressRenderer = ( + address: string, + resolvedAddress: string, + linkable: boolean, + dontOverrideColors: boolean +) => React.ReactElement; diff --git a/src/api/address-resolver/index.ts b/src/api/address-resolver/index.ts index dd8b549..6db1b1e 100644 --- a/src/api/address-resolver/index.ts +++ b/src/api/address-resolver/index.ts @@ -1,5 +1,6 @@ import { BaseProvider } from "@ethersproject/providers"; -import { IAddressResolver } from "./address-resolver"; +import { ensRenderer } from "../../components/ENSName"; +import { IAddressResolver, ResolvedAddressRenderer } from "./address-resolver"; import { CompositeAddressResolver, SelectedResolvedName, @@ -17,6 +18,12 @@ _mainResolver.addResolver(ensResolver); export const mainResolver: IAddressResolver> = _mainResolver; +export const resolverRendererRegistry = new Map< + IAddressResolver, + ResolvedAddressRenderer +>(); +resolverRendererRegistry.set(ensResolver, ensRenderer); + export const batchPopulate = async ( provider: BaseProvider, addresses: string[] diff --git a/src/components/AddressOrENSName.tsx b/src/components/AddressOrENSName.tsx index 83fd0cd..b10c0eb 100644 --- a/src/components/AddressOrENSName.tsx +++ b/src/components/AddressOrENSName.tsx @@ -1,7 +1,9 @@ import React from "react"; -import { ensResolver, ResolvedAddresses } from "../api/address-resolver"; +import { + ResolvedAddresses, + resolverRendererRegistry, +} from "../api/address-resolver"; import PlainAddress from "./PlainAddress"; -import ENSName from "./ENSName"; type AddressOrENSNameProps = { address: string; @@ -33,19 +35,19 @@ const AddressOrENSName: React.FC = ({ } const [resolver, resolvedName] = resolvedAddress; - if (resolver === ensResolver) { + const renderer = resolverRendererRegistry.get(resolver); + if (renderer === undefined) { return ( - ); } - return <>; + return renderer(address, resolvedName, linkable, !!dontOverrideColors); }; export default AddressOrENSName; diff --git a/src/components/ENSName.tsx b/src/components/ENSName.tsx index ac1b038..05fe27c 100644 --- a/src/components/ENSName.tsx +++ b/src/components/ENSName.tsx @@ -1,11 +1,11 @@ import React from "react"; import { NavLink } from "react-router-dom"; +import { ResolvedAddressRenderer } from "../api/address-resolver/address-resolver"; import ENSLogo from "./ensLogo.svg"; type ENSNameProps = { name: string; address: string; - text: string | undefined; linkable: boolean; dontOverrideColors?: boolean; }; @@ -13,7 +13,6 @@ type ENSNameProps = { const ENSName: React.FC = ({ name, address, - text, linkable, dontOverrideColors, }) => { @@ -59,4 +58,18 @@ const Content: React.FC = ({ linkable, name }) => ( ); +export const ensRenderer: ResolvedAddressRenderer = ( + address, + resolvedAddress, + linkable, + dontOverrideColors +) => ( + +); + export default ENSName; From 099c1465b01372a16c20ed95a9854d8c957f3f8e Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sun, 31 Oct 2021 19:51:11 -0300 Subject: [PATCH 19/28] Add ERC token address resolver --- .../CompositeAddressResolver.ts | 8 +- src/api/address-resolver/ERCTokenResolver.ts | 14 +++- src/api/address-resolver/address-resolver.ts | 4 +- src/api/address-resolver/index.ts | 17 +++-- src/components/ENSName.tsx | 2 +- src/components/TokenLogo.tsx | 2 +- src/components/TokenName.tsx | 73 +++++++++++++++++++ 7 files changed, 102 insertions(+), 18 deletions(-) create mode 100644 src/components/TokenName.tsx diff --git a/src/api/address-resolver/CompositeAddressResolver.ts b/src/api/address-resolver/CompositeAddressResolver.ts index 7c11f3d..3590f3d 100644 --- a/src/api/address-resolver/CompositeAddressResolver.ts +++ b/src/api/address-resolver/CompositeAddressResolver.ts @@ -3,7 +3,7 @@ import { IAddressResolver } from "./address-resolver"; export type SelectedResolvedName = [IAddressResolver, T]; -export class CompositeAddressResolver +export class CompositeAddressResolver implements IAddressResolver> { private resolvers: IAddressResolver[] = []; @@ -17,9 +17,9 @@ export class CompositeAddressResolver address: string ): Promise | undefined> { for (const r of this.resolvers) { - const name = await r.resolveAddress(provider, address); - if (name !== undefined) { - return [r, name]; + const resolvedAddress = await r.resolveAddress(provider, address); + if (resolvedAddress !== undefined) { + return [r, resolvedAddress]; } } diff --git a/src/api/address-resolver/ERCTokenResolver.ts b/src/api/address-resolver/ERCTokenResolver.ts index dc8bb74..02625dc 100644 --- a/src/api/address-resolver/ERCTokenResolver.ts +++ b/src/api/address-resolver/ERCTokenResolver.ts @@ -2,12 +2,13 @@ import { BaseProvider } from "@ethersproject/providers"; import { Contract } from "@ethersproject/contracts"; import { IAddressResolver } from "./address-resolver"; import erc20 from "../../erc20.json"; +import { TokenMeta } from "../../types"; -export class ERCTokenResolver implements IAddressResolver { +export class ERCTokenResolver implements IAddressResolver { async resolveAddress( provider: BaseProvider, address: string - ): Promise { + ): Promise { const erc20Contract = new Contract(address, erc20, provider); try { const [name, symbol, decimals] = await Promise.all([ @@ -15,9 +16,14 @@ export class ERCTokenResolver implements IAddressResolver { erc20Contract.symbol(), erc20Contract.decimals(), ]); - return name; + return { + name, + symbol, + decimals, + }; } catch (err) { - console.warn(`Couldn't get token ${address} metadata; ignoring`, err); + // Ignore on purpose; this indicates the probe failed and the address + // is not a token } return undefined; } diff --git a/src/api/address-resolver/address-resolver.ts b/src/api/address-resolver/address-resolver.ts index 0527b04..12d289e 100644 --- a/src/api/address-resolver/address-resolver.ts +++ b/src/api/address-resolver/address-resolver.ts @@ -8,9 +8,9 @@ export interface IAddressResolver { ): Promise; } -export type ResolvedAddressRenderer = ( +export type ResolvedAddressRenderer = ( address: string, - resolvedAddress: string, + resolvedAddress: T, linkable: boolean, dontOverrideColors: boolean ) => React.ReactElement; diff --git a/src/api/address-resolver/index.ts b/src/api/address-resolver/index.ts index 6db1b1e..d0a0500 100644 --- a/src/api/address-resolver/index.ts +++ b/src/api/address-resolver/index.ts @@ -1,34 +1,39 @@ import { BaseProvider } from "@ethersproject/providers"; import { ensRenderer } from "../../components/ENSName"; +import { tokenRenderer } from "../../components/TokenName"; import { IAddressResolver, ResolvedAddressRenderer } from "./address-resolver"; import { CompositeAddressResolver, SelectedResolvedName, } from "./CompositeAddressResolver"; import { ENSAddressResolver } from "./ENSAddressResolver"; +import { ERCTokenResolver } from "./ERCTokenResolver"; -export type ResolvedAddresses = Record>; +export type ResolvedAddresses = Record>; // Create and configure the main resolver export const ensResolver = new ENSAddressResolver(); +export const ercTokenResolver = new ERCTokenResolver(); -const _mainResolver = new CompositeAddressResolver(); +const _mainResolver = new CompositeAddressResolver(); _mainResolver.addResolver(ensResolver); +_mainResolver.addResolver(ercTokenResolver); -export const mainResolver: IAddressResolver> = +export const mainResolver: IAddressResolver> = _mainResolver; export const resolverRendererRegistry = new Map< - IAddressResolver, - ResolvedAddressRenderer + IAddressResolver, + ResolvedAddressRenderer >(); resolverRendererRegistry.set(ensResolver, ensRenderer); +resolverRendererRegistry.set(ercTokenResolver, tokenRenderer); export const batchPopulate = async ( provider: BaseProvider, addresses: string[] ): Promise => { - const solvers: Promise | undefined>[] = []; + const solvers: Promise | undefined>[] = []; for (const a of addresses) { solvers.push(mainResolver.resolveAddress(provider, a)); } diff --git a/src/components/ENSName.tsx b/src/components/ENSName.tsx index 05fe27c..f12f416 100644 --- a/src/components/ENSName.tsx +++ b/src/components/ENSName.tsx @@ -58,7 +58,7 @@ const Content: React.FC = ({ linkable, name }) => ( ); -export const ensRenderer: ResolvedAddressRenderer = ( +export const ensRenderer: ResolvedAddressRenderer = ( address, resolvedAddress, linkable, diff --git a/src/components/TokenLogo.tsx b/src/components/TokenLogo.tsx index c6f5b8b..8568a0b 100644 --- a/src/components/TokenLogo.tsx +++ b/src/components/TokenLogo.tsx @@ -9,7 +9,7 @@ type TokenLogoProps = { }; const TokenLogo: React.FC = (props) => ( - }> + ); diff --git a/src/components/TokenName.tsx b/src/components/TokenName.tsx new file mode 100644 index 0000000..7301676 --- /dev/null +++ b/src/components/TokenName.tsx @@ -0,0 +1,73 @@ +import React from "react"; +import { NavLink } from "react-router-dom"; +import TokenLogo from "./TokenLogo"; +import { ResolvedAddressRenderer } from "../api/address-resolver/address-resolver"; +import { TokenMeta } from "../types"; + +type TokenNameProps = { + name: string; + address: string; + linkable: boolean; + dontOverrideColors?: boolean; +}; + +const TokenName: React.FC = ({ + name, + address, + linkable, + dontOverrideColors, +}) => { + if (linkable) { + return ( + + + + ); + } + + return ( +
+ +
+ ); +}; + +type ContentProps = { + address: string; + linkable: boolean; + name: string; +}; + +const Content: React.FC = ({ address, linkable, name }) => ( + <> +
+ +
+ {name} + +); + +export const tokenRenderer: ResolvedAddressRenderer = ( + address, + resolvedAddress, + linkable, + dontOverrideColors +) => ( + +); + +export default TokenName; From 9b2dcf0acab0a5f4204fd52ffeffff9dab36a4ca Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sun, 31 Oct 2021 19:55:09 -0300 Subject: [PATCH 20/28] Fix token address link --- src/components/TokenName.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/TokenName.tsx b/src/components/TokenName.tsx index 7301676..f57dd07 100644 --- a/src/components/TokenName.tsx +++ b/src/components/TokenName.tsx @@ -23,7 +23,7 @@ const TokenName: React.FC = ({ className={`flex items-baseline space-x-1 font-sans ${ dontOverrideColors ? "" : "text-link-blue hover:text-link-blue-hover" } truncate`} - to={`/address/${name}`} + to={`/address/${address}`} title={`${name}: ${address}`} > From 9879290a38fb29994691770d60852086726d95ae Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sun, 31 Oct 2021 19:59:14 -0300 Subject: [PATCH 21/28] Add symbol support --- src/components/TokenName.tsx | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/components/TokenName.tsx b/src/components/TokenName.tsx index f57dd07..0553d4a 100644 --- a/src/components/TokenName.tsx +++ b/src/components/TokenName.tsx @@ -6,6 +6,7 @@ import { TokenMeta } from "../types"; type TokenNameProps = { name: string; + symbol: string; address: string; linkable: boolean; dontOverrideColors?: boolean; @@ -13,6 +14,7 @@ type TokenNameProps = { const TokenName: React.FC = ({ name, + symbol, address, linkable, dontOverrideColors, @@ -24,9 +26,14 @@ const TokenName: React.FC = ({ dontOverrideColors ? "" : "text-link-blue hover:text-link-blue-hover" } truncate`} to={`/address/${address}`} - title={`${name}: ${address}`} + title={`${name} (${symbol}): ${address}`} > - + ); } @@ -34,9 +41,9 @@ const TokenName: React.FC = ({ return (
- +
); }; @@ -45,14 +52,22 @@ type ContentProps = { address: string; linkable: boolean; name: string; + symbol: string; }; -const Content: React.FC = ({ address, linkable, name }) => ( +const Content: React.FC = ({ + address, + linkable, + name, + symbol, +}) => ( <>
- {name} + + {name} ({symbol}) + ); @@ -65,6 +80,7 @@ export const tokenRenderer: ResolvedAddressRenderer = ( From ba86907ec2083a2e3a9cb091b890e1f12daab209 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sun, 31 Oct 2021 20:00:40 -0300 Subject: [PATCH 22/28] Add TODO --- src/api/address-resolver/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/api/address-resolver/index.ts b/src/api/address-resolver/index.ts index d0a0500..6212653 100644 --- a/src/api/address-resolver/index.ts +++ b/src/api/address-resolver/index.ts @@ -29,6 +29,7 @@ export const resolverRendererRegistry = new Map< resolverRendererRegistry.set(ensResolver, ensRenderer); resolverRendererRegistry.set(ercTokenResolver, tokenRenderer); +// TODO: implement progressive resolving export const batchPopulate = async ( provider: BaseProvider, addresses: string[] From 378d5a0c25fb0ded95dec0c53f069fdb074f110d Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 1 Nov 2021 01:32:35 -0300 Subject: [PATCH 23/28] Reorder attributes --- src/components/TokenName.tsx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/components/TokenName.tsx b/src/components/TokenName.tsx index 0553d4a..5c3e91b 100644 --- a/src/components/TokenName.tsx +++ b/src/components/TokenName.tsx @@ -5,17 +5,17 @@ import { ResolvedAddressRenderer } from "../api/address-resolver/address-resolve import { TokenMeta } from "../types"; type TokenNameProps = { + address: string; name: string; symbol: string; - address: string; linkable: boolean; dontOverrideColors?: boolean; }; const TokenName: React.FC = ({ + address, name, symbol, - address, linkable, dontOverrideColors, }) => { @@ -50,19 +50,21 @@ const TokenName: React.FC = ({ type ContentProps = { address: string; - linkable: boolean; name: string; symbol: string; + linkable: boolean; }; const Content: React.FC = ({ address, - linkable, name, symbol, + linkable, }) => ( <> -
+
@@ -73,14 +75,14 @@ const Content: React.FC = ({ export const tokenRenderer: ResolvedAddressRenderer = ( address, - resolvedAddress, + tokenMeta, linkable, dontOverrideColors ) => ( From e22b564a71c1f3ebacf23d271f24d5bf4e67509d Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 1 Nov 2021 04:15:12 -0300 Subject: [PATCH 24/28] Add in-page cache capabilities to main resolver --- .../CompositeAddressResolver.ts | 6 ++-- src/api/address-resolver/index.ts | 12 ++++--- src/components/AddressOrENSName.tsx | 2 +- src/useResolvedAddresses.ts | 32 ++++++++++++------- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/api/address-resolver/CompositeAddressResolver.ts b/src/api/address-resolver/CompositeAddressResolver.ts index 3590f3d..55a7318 100644 --- a/src/api/address-resolver/CompositeAddressResolver.ts +++ b/src/api/address-resolver/CompositeAddressResolver.ts @@ -1,7 +1,7 @@ import { BaseProvider } from "@ethersproject/providers"; import { IAddressResolver } from "./address-resolver"; -export type SelectedResolvedName = [IAddressResolver, T]; +export type SelectedResolvedName = [IAddressResolver, T] | null; export class CompositeAddressResolver implements IAddressResolver> @@ -23,8 +23,6 @@ export class CompositeAddressResolver } } - return undefined; - // TODO: fallback to address itself - // return address; + return null; } } diff --git a/src/api/address-resolver/index.ts b/src/api/address-resolver/index.ts index 6212653..dc72a9f 100644 --- a/src/api/address-resolver/index.ts +++ b/src/api/address-resolver/index.ts @@ -32,21 +32,25 @@ resolverRendererRegistry.set(ercTokenResolver, tokenRenderer); // TODO: implement progressive resolving export const batchPopulate = async ( provider: BaseProvider, - addresses: string[] + addresses: string[], + currentMap: ResolvedAddresses | undefined ): Promise => { const solvers: Promise | undefined>[] = []; - for (const a of addresses) { + const unresolvedAddresses = addresses.filter( + (a) => currentMap?.[a] === undefined + ); + for (const a of unresolvedAddresses) { solvers.push(mainResolver.resolveAddress(provider, a)); } + const resultMap: ResolvedAddresses = currentMap ? { ...currentMap } : {}; const results = await Promise.all(solvers); - const resultMap: ResolvedAddresses = {}; for (let i = 0; i < results.length; i++) { const r = results[i]; if (r === undefined) { continue; } - resultMap[addresses[i]] = r; + resultMap[unresolvedAddresses[i]] = r; } return resultMap; diff --git a/src/components/AddressOrENSName.tsx b/src/components/AddressOrENSName.tsx index b10c0eb..9e4b65b 100644 --- a/src/components/AddressOrENSName.tsx +++ b/src/components/AddressOrENSName.tsx @@ -23,7 +23,7 @@ const AddressOrENSName: React.FC = ({ const resolvedAddress = resolvedAddresses?.[address]; const linkable = address !== selectedAddress; - if (resolvedAddress === undefined) { + if (!resolvedAddress) { return ( { const [names, setNames] = useState(); - + const ref = useRef(); useEffect(() => { - if (!provider) { - return; - } + ref.current = names; + }); - const populate = async () => { - const _addresses = addrCollector(); - const _names = await batchPopulate(provider, _addresses); - setNames(_names); - }; - populate(); - }, [provider, addrCollector]); + useEffect( + () => { + if (!provider) { + return; + } + + const populate = async () => { + const _addresses = addrCollector(); + const _names = await batchPopulate(provider, _addresses, ref.current); + setNames(_names); + }; + populate(); + }, + // DON'T put names variables in dependency array; this is intentional; useRef + [provider, addrCollector] + ); return names; }; From 91a888c73b3999bb0b9049198ed94508d0d672dd Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 1 Nov 2021 04:26:19 -0300 Subject: [PATCH 25/28] Migrate remaining token decoration support to the new resolver framework --- src/TokenTransferItem.tsx | 8 ++++---- src/components/AddressOrENSName.tsx | 4 ---- src/components/DecoratedAddressLink.tsx | 13 +------------ src/components/PlainAddress.tsx | 6 ++---- src/transaction/Details.tsx | 1 + 5 files changed, 8 insertions(+), 24 deletions(-) diff --git a/src/TokenTransferItem.tsx b/src/TokenTransferItem.tsx index 083f7f0..03fa198 100644 --- a/src/TokenTransferItem.tsx +++ b/src/TokenTransferItem.tsx @@ -11,11 +11,13 @@ import { TokenTransfer, TransactionData, } from "./types"; +import { ResolvedAddresses } from "./api/address-resolver"; type TokenTransferItemProps = { t: TokenTransfer; txData: TransactionData; tokenMeta?: TokenMeta | undefined; + resolvedAddresses: ResolvedAddresses | undefined; }; // TODO: handle partial @@ -23,6 +25,7 @@ const TokenTransferItem: React.FC = ({ t, txData, tokenMeta, + resolvedAddresses, }) => (
@@ -64,10 +67,7 @@ const TokenTransferItem: React.FC = ({
diff --git a/src/components/AddressOrENSName.tsx b/src/components/AddressOrENSName.tsx index 9e4b65b..62ee289 100644 --- a/src/components/AddressOrENSName.tsx +++ b/src/components/AddressOrENSName.tsx @@ -8,7 +8,6 @@ import PlainAddress from "./PlainAddress"; type AddressOrENSNameProps = { address: string; selectedAddress?: string; - text?: string; dontOverrideColors?: boolean; resolvedAddresses?: ResolvedAddresses | undefined; }; @@ -16,7 +15,6 @@ type AddressOrENSNameProps = { const AddressOrENSName: React.FC = ({ address, selectedAddress, - text, dontOverrideColors, resolvedAddresses, }) => { @@ -27,7 +25,6 @@ const AddressOrENSName: React.FC = ({ return ( @@ -40,7 +37,6 @@ const AddressOrENSName: React.FC = ({ return ( diff --git a/src/components/DecoratedAddressLink.tsx b/src/components/DecoratedAddressLink.tsx index ee88b31..cadc77f 100644 --- a/src/components/DecoratedAddressLink.tsx +++ b/src/components/DecoratedAddressLink.tsx @@ -5,36 +5,31 @@ import { faBomb } from "@fortawesome/free-solid-svg-icons/faBomb"; import { faMoneyBillAlt } from "@fortawesome/free-solid-svg-icons/faMoneyBillAlt"; import { faBurn } from "@fortawesome/free-solid-svg-icons/faBurn"; import { faCoins } from "@fortawesome/free-solid-svg-icons/faCoins"; -import TokenLogo from "./TokenLogo"; import AddressOrENSName from "./AddressOrENSName"; -import { AddressContext, TokenMeta, ZERO_ADDRESS } from "../types"; +import { AddressContext, ZERO_ADDRESS } from "../types"; import { ResolvedAddresses } from "../api/address-resolver"; type DecoratedAddressLinkProps = { address: string; selectedAddress?: string; - text?: string; addressCtx?: AddressContext; creation?: boolean; miner?: boolean; selfDestruct?: boolean; txFrom?: boolean; txTo?: boolean; - tokenMeta?: TokenMeta; resolvedAddresses?: ResolvedAddresses | undefined; }; const DecoratedAddressLink: React.FC = ({ address, selectedAddress, - text, addressCtx, creation, miner, selfDestruct, txFrom, txTo, - tokenMeta, resolvedAddresses, }) => { const mint = addressCtx === AddressContext.FROM && address === ZERO_ADDRESS; @@ -75,15 +70,9 @@ const DecoratedAddressLink: React.FC = ({
)} - {tokenMeta && ( -
- -
- )} diff --git a/src/components/PlainAddress.tsx b/src/components/PlainAddress.tsx index 6ebe634..fbc37ca 100644 --- a/src/components/PlainAddress.tsx +++ b/src/components/PlainAddress.tsx @@ -3,14 +3,12 @@ import { NavLink } from "react-router-dom"; type PlainAddressProps = { address: string; - text: string | undefined; linkable: boolean; dontOverrideColors: boolean | undefined; }; const PlainAddress: React.FC = ({ address, - text, linkable, dontOverrideColors, }) => { @@ -21,9 +19,9 @@ const PlainAddress: React.FC = ({ dontOverrideColors ? "" : "text-link-blue hover:text-link-blue-hover" } font-address truncate`} to={`/address/${address}`} - title={text ?? address} + title={address} > - <>{text ?? address} + {address} ); } diff --git a/src/transaction/Details.tsx b/src/transaction/Details.tsx index 72f448a..6286efa 100644 --- a/src/transaction/Details.tsx +++ b/src/transaction/Details.tsx @@ -225,6 +225,7 @@ const Details: React.FC = ({ t={t} txData={txData} tokenMeta={txData.tokenMetas[t.token]} + resolvedAddresses={resolvedAddresses} /> ))}
From 66be71f89d2988fb0629c622d02a681792a06ed5 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 1 Nov 2021 04:46:19 -0300 Subject: [PATCH 26/28] TODO: must finish reverse token address support on internal ETH transfers section --- src/components/InternalTransactionOperation.tsx | 10 ++++++++-- src/components/InternalTransfer.tsx | 3 +++ src/transaction/Details.tsx | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/components/InternalTransactionOperation.tsx b/src/components/InternalTransactionOperation.tsx index 095162f..7de3bb2 100644 --- a/src/components/InternalTransactionOperation.tsx +++ b/src/components/InternalTransactionOperation.tsx @@ -3,17 +3,23 @@ import InternalTransfer from "./InternalTransfer"; import InternalSelfDestruct from "./InternalSelfDestruct"; import InternalCreate from "./InternalCreate"; import { TransactionData, InternalOperation, OperationType } from "../types"; +import { ResolvedAddresses } from "../api/address-resolver"; type InternalTransactionOperationProps = { txData: TransactionData; internalOp: InternalOperation; + resolvedAddresses: ResolvedAddresses | undefined; }; const InternalTransactionOperation: React.FC = - ({ txData, internalOp }) => ( + ({ txData, internalOp, resolvedAddresses }) => ( <> {internalOp.type === OperationType.TRANSFER && ( - + )} {internalOp.type === OperationType.SELF_DESTRUCT && ( diff --git a/src/components/InternalTransfer.tsx b/src/components/InternalTransfer.tsx index dc53d05..2958452 100644 --- a/src/components/InternalTransfer.tsx +++ b/src/components/InternalTransfer.tsx @@ -5,15 +5,18 @@ import { faAngleRight } from "@fortawesome/free-solid-svg-icons/faAngleRight"; import AddressHighlighter from "./AddressHighlighter"; import DecoratedAddressLink from "./DecoratedAddressLink"; import { TransactionData, InternalOperation } from "../types"; +import { ResolvedAddresses } from "../api/address-resolver"; type InternalTransferProps = { txData: TransactionData; internalOp: InternalOperation; + resolvedAddresses: ResolvedAddresses | undefined; }; const InternalTransfer: React.FC = ({ txData, internalOp, + resolvedAddresses, }) => { const fromMiner = txData.confirmedData?.miner !== undefined && diff --git a/src/transaction/Details.tsx b/src/transaction/Details.tsx index 6286efa..9c9e29d 100644 --- a/src/transaction/Details.tsx +++ b/src/transaction/Details.tsx @@ -206,6 +206,7 @@ const Details: React.FC = ({ key={i} txData={txData} internalOp={op} + resolvedAddresses={resolvedAddresses} /> ))} From 74a9b05c04e5d524fd0bc07d9220a79c6920cf07 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 1 Nov 2021 15:37:10 -0300 Subject: [PATCH 27/28] Typo fix --- src/url.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/url.ts b/src/url.ts index 4639738..647fc42 100644 --- a/src/url.ts +++ b/src/url.ts @@ -38,7 +38,7 @@ const resolveSourcifySource = (source: SourcifySource) => { return sourcifyHttpRepoPrefix; } - throw new Error(`Unknown Sourcify intergration source code: ${source}`); + throw new Error(`Unknown Sourcify integration source code: ${source}`); }; export const sourcifyMetadata = ( From 2dd4850eb019b5bcc60330243449e66339ba7b96 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 1 Nov 2021 16:17:48 -0300 Subject: [PATCH 28/28] Start using JsonRpcBatchProvider from ethers instead of the regular one to optimize for big txs --- src/useProvider.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/useProvider.ts b/src/useProvider.ts index 7f89f36..b189b7f 100644 --- a/src/useProvider.ts +++ b/src/useProvider.ts @@ -1,5 +1,9 @@ import { useEffect, useState } from "react"; -import { JsonRpcProvider, WebSocketProvider } from "@ethersproject/providers"; +import { + JsonRpcProvider, + JsonRpcBatchProvider, + WebSocketProvider, +} from "@ethersproject/providers"; import { ConnectionStatus } from "./types"; import { MIN_API_LEVEL } from "./params"; @@ -35,7 +39,7 @@ export const useProvider = ( if (erigonURL?.startsWith("ws://") || erigonURL?.startsWith("wss://")) { provider = new WebSocketProvider(erigonURL); } else { - provider = new JsonRpcProvider(erigonURL); + provider = new JsonRpcBatchProvider(erigonURL); } // Check if it is at least a regular ETH node