From 05bd343fc565f152eb0c22dd7cb2c4600528ecc5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Mar 2022 21:49:25 +0000 Subject: [PATCH 01/22] Bump ethers from 5.6.1 to 5.6.2 (#223) --- package-lock.json | 62 +++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2589006..7c11a7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,7 @@ "@types/react-highlight": "^0.12.5", "@types/react-syntax-highlighter": "^13.5.2", "chart.js": "^3.7.1", - "ethers": "^5.6.1", + "ethers": "^5.6.2", "highlightjs-solidity": "^2.0.5", "react": "^17.0.2", "react-blockies": "^1.4.1", @@ -1594,9 +1594,9 @@ } }, "node_modules/@ethersproject/bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.0.tgz", - "integrity": "sha512-3hJPlYemb9V4VLfJF5BfN0+55vltPZSHU3QKUyP9M3Y2TcajbiRrz65UG+xVHOzBereB1b9mn7r12o177xgN7w==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.1.tgz", + "integrity": "sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==", "funding": [ { "type": "individual", @@ -1775,9 +1775,9 @@ ] }, "node_modules/@ethersproject/networks": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.0.tgz", - "integrity": "sha512-DaVzgyThzHgSDLuURhvkp4oviGoGe9iTZW4jMEORHDRCgSZ9K9THGFKqL+qGXqPAYLEgZTf5z2w56mRrPR1MjQ==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.1.tgz", + "integrity": "sha512-b2rrupf3kCTcc3jr9xOWBuHylSFtbpJf79Ga7QR98ienU2UqGimPGEsYMgbI29KHJfA5Us89XwGVmxrlxmSrMg==", "funding": [ { "type": "individual", @@ -1830,9 +1830,9 @@ } }, "node_modules/@ethersproject/providers": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.1.tgz", - "integrity": "sha512-w8Wx15nH+aVDvnoKCyI1f3x0B5idmk/bDJXMEUqCfdO8Eadd0QpDx9lDMTMmenhOmf9vufLJXjpSm24D3ZnVpg==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.2.tgz", + "integrity": "sha512-6/EaFW/hNWz+224FXwl8+HdMRzVHt8DpPmu5MZaIQqx/K/ELnC9eY236SMV7mleCM3NnEArFwcAAxH5kUUgaRg==", "funding": [ { "type": "individual", @@ -8266,9 +8266,9 @@ } }, "node_modules/ethers": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.1.tgz", - "integrity": "sha512-qtl/2W+dwmUa5Z3JqwsbV3JEBZZHNARe5K/A2ePcNAuhJYnEKIgGOT/O9ouPwBijSqVoQnmQMzi5D48LFNOY2A==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.2.tgz", + "integrity": "sha512-EzGCbns24/Yluu7+ToWnMca3SXJ1Jk1BvWB7CCmVNxyOeM4LLvw2OLuIHhlkhQk1dtOcj9UMsdkxUh8RiG1dxQ==", "funding": [ { "type": "individual", @@ -8287,7 +8287,7 @@ "@ethersproject/base64": "5.6.0", "@ethersproject/basex": "5.6.0", "@ethersproject/bignumber": "5.6.0", - "@ethersproject/bytes": "5.6.0", + "@ethersproject/bytes": "5.6.1", "@ethersproject/constants": "5.6.0", "@ethersproject/contracts": "5.6.0", "@ethersproject/hash": "5.6.0", @@ -8295,10 +8295,10 @@ "@ethersproject/json-wallets": "5.6.0", "@ethersproject/keccak256": "5.6.0", "@ethersproject/logger": "5.6.0", - "@ethersproject/networks": "5.6.0", + "@ethersproject/networks": "5.6.1", "@ethersproject/pbkdf2": "5.6.0", "@ethersproject/properties": "5.6.0", - "@ethersproject/providers": "5.6.1", + "@ethersproject/providers": "5.6.2", "@ethersproject/random": "5.6.0", "@ethersproject/rlp": "5.6.0", "@ethersproject/sha2": "5.6.0", @@ -20690,9 +20690,9 @@ } }, "@ethersproject/bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.0.tgz", - "integrity": "sha512-3hJPlYemb9V4VLfJF5BfN0+55vltPZSHU3QKUyP9M3Y2TcajbiRrz65UG+xVHOzBereB1b9mn7r12o177xgN7w==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.1.tgz", + "integrity": "sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==", "requires": { "@ethersproject/logger": "^5.6.0" } @@ -20791,9 +20791,9 @@ "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==" }, "@ethersproject/networks": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.0.tgz", - "integrity": "sha512-DaVzgyThzHgSDLuURhvkp4oviGoGe9iTZW4jMEORHDRCgSZ9K9THGFKqL+qGXqPAYLEgZTf5z2w56mRrPR1MjQ==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.1.tgz", + "integrity": "sha512-b2rrupf3kCTcc3jr9xOWBuHylSFtbpJf79Ga7QR98ienU2UqGimPGEsYMgbI29KHJfA5Us89XwGVmxrlxmSrMg==", "requires": { "@ethersproject/logger": "^5.6.0" } @@ -20816,9 +20816,9 @@ } }, "@ethersproject/providers": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.1.tgz", - "integrity": "sha512-w8Wx15nH+aVDvnoKCyI1f3x0B5idmk/bDJXMEUqCfdO8Eadd0QpDx9lDMTMmenhOmf9vufLJXjpSm24D3ZnVpg==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.6.2.tgz", + "integrity": "sha512-6/EaFW/hNWz+224FXwl8+HdMRzVHt8DpPmu5MZaIQqx/K/ELnC9eY236SMV7mleCM3NnEArFwcAAxH5kUUgaRg==", "requires": { "@ethersproject/abstract-provider": "^5.6.0", "@ethersproject/abstract-signer": "^5.6.0", @@ -25126,9 +25126,9 @@ "version": "1.8.1" }, "ethers": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.1.tgz", - "integrity": "sha512-qtl/2W+dwmUa5Z3JqwsbV3JEBZZHNARe5K/A2ePcNAuhJYnEKIgGOT/O9ouPwBijSqVoQnmQMzi5D48LFNOY2A==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.6.2.tgz", + "integrity": "sha512-EzGCbns24/Yluu7+ToWnMca3SXJ1Jk1BvWB7CCmVNxyOeM4LLvw2OLuIHhlkhQk1dtOcj9UMsdkxUh8RiG1dxQ==", "requires": { "@ethersproject/abi": "5.6.0", "@ethersproject/abstract-provider": "5.6.0", @@ -25137,7 +25137,7 @@ "@ethersproject/base64": "5.6.0", "@ethersproject/basex": "5.6.0", "@ethersproject/bignumber": "5.6.0", - "@ethersproject/bytes": "5.6.0", + "@ethersproject/bytes": "5.6.1", "@ethersproject/constants": "5.6.0", "@ethersproject/contracts": "5.6.0", "@ethersproject/hash": "5.6.0", @@ -25145,10 +25145,10 @@ "@ethersproject/json-wallets": "5.6.0", "@ethersproject/keccak256": "5.6.0", "@ethersproject/logger": "5.6.0", - "@ethersproject/networks": "5.6.0", + "@ethersproject/networks": "5.6.1", "@ethersproject/pbkdf2": "5.6.0", "@ethersproject/properties": "5.6.0", - "@ethersproject/providers": "5.6.1", + "@ethersproject/providers": "5.6.2", "@ethersproject/random": "5.6.0", "@ethersproject/rlp": "5.6.0", "@ethersproject/sha2": "5.6.0", diff --git a/package.json b/package.json index 0b78604..be3c113 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "@types/react-highlight": "^0.12.5", "@types/react-syntax-highlighter": "^13.5.2", "chart.js": "^3.7.1", - "ethers": "^5.6.1", + "ethers": "^5.6.2", "highlightjs-solidity": "^2.0.5", "react": "^17.0.2", "react-blockies": "^1.4.1", From 1a493e23dd1a06a093e4b55c0b13384d77d5ebf9 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 30 Mar 2022 19:26:46 -0300 Subject: [PATCH 02/22] Update trustwallet assets --- trustwallet | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trustwallet b/trustwallet index b8d1c58..dd4ba75 160000 --- a/trustwallet +++ b/trustwallet @@ -1 +1 @@ -Subproject commit b8d1c58acfd93b1b698fe5854f2c09bff70e9fdf +Subproject commit dd4ba75fb6da47c3ec1130109c4411c006267d56 From 562f490e27a296646a4c582ad9362ba732ec6f44 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 30 Mar 2022 22:58:25 -0300 Subject: [PATCH 03/22] Handle stopped assets container when running locally --- src/useChainInfo.ts | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/useChainInfo.ts b/src/useChainInfo.ts index 0d494b9..5cd0f01 100644 --- a/src/useChainInfo.ts +++ b/src/useChainInfo.ts @@ -25,24 +25,30 @@ export const useChainInfoFromMetadataFile = ( const [chainInfo, setChainInfo] = useState(undefined); useEffect(() => { - if (chainId === undefined) { + if (assetsURLPrefix === undefined || chainId === undefined) { setChainInfo(undefined); return; } const readChainInfo = async () => { - const res = await fetch(chainInfoURL(assetsURLPrefix!, chainId)); - if (!res.ok) { + try { + const res = await fetch(chainInfoURL(assetsURLPrefix, chainId)); + if (!res.ok) { + setChainInfo(defaultChainInfo); + return; + } + const info = await res.json(); + + setChainInfo({ + nativeName: info.nativeCurrency.name, + nativeDecimals: info.nativeCurrency.decimals, + nativeSymbol: info.nativeCurrency.symbol, + }); + } catch (err) { + // ignore setChainInfo(defaultChainInfo); return; } - const info = await res.json(); - - setChainInfo({ - nativeName: info.nativeCurrency.name, - nativeDecimals: info.nativeCurrency.decimals, - nativeSymbol: info.nativeCurrency.symbol, - }); }; readChainInfo(); }, [assetsURLPrefix, chainId]); From 9d78cab7535b27fc3da02b89174008caca7912b7 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 30 Mar 2022 23:09:03 -0300 Subject: [PATCH 04/22] Fix default resolver not being caught for testnets --- src/api/address-resolver/index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/api/address-resolver/index.ts b/src/api/address-resolver/index.ts index 5997e01..313b7cd 100644 --- a/src/api/address-resolver/index.ts +++ b/src/api/address-resolver/index.ts @@ -45,11 +45,11 @@ const resolvers: Record>> = { export const getResolver = ( chainId: number ): IAddressResolver> => { - const resolver = resolvers[chainId]; - if (resolver === undefined) { - return resolver[0]; // default MAGIC NUMBER + const res = resolvers[chainId]; + if (res === undefined) { + return resolvers[0]; // default MAGIC NUMBER } - return resolver; + return res; }; export const resolverRendererRegistry = new Map< From 932505fd50039de41384fd9dd7c6f7f50cd5c4d7 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 30 Mar 2022 23:09:41 -0300 Subject: [PATCH 05/22] Add FaucETH address for sepolia --- src/api/address-resolver/hardcoded-addresses/11155111.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/api/address-resolver/hardcoded-addresses/11155111.json diff --git a/src/api/address-resolver/hardcoded-addresses/11155111.json b/src/api/address-resolver/hardcoded-addresses/11155111.json new file mode 100644 index 0000000..d2a62ab --- /dev/null +++ b/src/api/address-resolver/hardcoded-addresses/11155111.json @@ -0,0 +1,3 @@ +{ + "0xcFe95817aC44C3f8CE75F1EE6EC1431F586AB5A3": "FaucETH: Hot wallet" +} \ No newline at end of file From 5086b6f8565fc665669b6e3349f404420a5e9d1d Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 2 Apr 2022 14:56:36 -0300 Subject: [PATCH 06/22] Use native ethereum-lists/chains json format; dont reinvent the wheel --- src/Block.tsx | 8 +++++--- src/PriceBox.tsx | 8 +++++--- src/components/InternalSelfDestruct.tsx | 6 ++++-- src/components/InternalTransfer.tsx | 6 ++++-- src/components/TransactionValue.tsx | 10 ++++++---- src/components/USDValue.tsx | 6 ++++-- src/special/london/BlockRow.tsx | 9 +++++---- src/transaction/Details.tsx | 18 +++++++++--------- src/transaction/RewardSplit.tsx | 8 +++++--- src/transaction/TraceInput.tsx | 7 ++++--- src/useChainInfo.ts | 24 +++++++++++++++--------- 11 files changed, 66 insertions(+), 44 deletions(-) diff --git a/src/Block.tsx b/src/Block.tsx index 97b14ba..c8afe43 100644 --- a/src/Block.tsx +++ b/src/Block.tsx @@ -34,7 +34,9 @@ const Block: React.FC = () => { if (blockNumberOrHash === undefined) { throw new Error("blockNumberOrHash couldn't be undefined here"); } - const { nativeName, nativeSymbol } = useChainInfo(); + const { + nativeCurrency: { name, symbol }, + } = useChainInfo(); const block = useBlockData(provider, blockNumberOrHash); useEffect(() => { @@ -146,7 +148,7 @@ const Block: React.FC = () => { {" "} - {nativeSymbol} + {symbol} @@ -165,7 +167,7 @@ const Block: React.FC = () => { {extraStr} (Hex:{" "} {block.extraData}) - + diff --git a/src/PriceBox.tsx b/src/PriceBox.tsx index 2f5bd4d..1e2586a 100644 --- a/src/PriceBox.tsx +++ b/src/PriceBox.tsx @@ -14,7 +14,9 @@ const ETH_FEED_DECIMALS = 8; // TODO: reduce duplication with useETHUSDOracle const PriceBox: React.FC = () => { const { provider } = useContext(RuntimeContext); - const { nativeSymbol } = useChainInfo(); + const { + nativeCurrency: { symbol }, + } = useChainInfo(); const latestBlock = useLatestBlock(provider); const maybeOutdated: boolean = @@ -82,9 +84,9 @@ const PriceBox: React.FC = () => { } font-sans text-xs text-gray-800`} > - {nativeSymbol}: ${latestPrice} + {symbol}: ${latestPrice} {latestGasData && ( <> diff --git a/src/components/InternalSelfDestruct.tsx b/src/components/InternalSelfDestruct.tsx index 9bcb0ad..8cb828e 100644 --- a/src/components/InternalSelfDestruct.tsx +++ b/src/components/InternalSelfDestruct.tsx @@ -17,7 +17,9 @@ const InternalSelfDestruct: React.FC = ({ txData, internalOp, }) => { - const { nativeSymbol } = useChainInfo(); + const { + nativeCurrency: { symbol }, + } = useChainInfo(); const toMiner = txData.confirmedData?.miner !== undefined && internalOp.to === txData.confirmedData.miner; @@ -46,7 +48,7 @@ const InternalSelfDestruct: React.FC = ({ TRANSFER - {formatEther(internalOp.value)} {nativeSymbol} + {formatEther(internalOp.value)} {symbol}
To diff --git a/src/components/InternalTransfer.tsx b/src/components/InternalTransfer.tsx index b73bdf0..b52acb9 100644 --- a/src/components/InternalTransfer.tsx +++ b/src/components/InternalTransfer.tsx @@ -18,7 +18,9 @@ const InternalTransfer: React.FC = ({ txData, internalOp, }) => { - const { nativeSymbol } = useChainInfo(); + const { + nativeCurrency: { symbol }, + } = useChainInfo(); const fromMiner = txData.confirmedData?.miner !== undefined && internalOp.from === txData.confirmedData.miner; @@ -44,7 +46,7 @@ const InternalTransfer: React.FC = ({ TRANSFER - {formatEther(internalOp.value)} {nativeSymbol} + {formatEther(internalOp.value)} {symbol}
From diff --git a/src/components/TransactionValue.tsx b/src/components/TransactionValue.tsx index b4a9d54..53f9300 100644 --- a/src/components/TransactionValue.tsx +++ b/src/components/TransactionValue.tsx @@ -22,16 +22,18 @@ const TransactionValue: React.FC = ({ value, hideUnit, }) => { - const { nativeSymbol, nativeDecimals } = useChainInfo(); - const formattedValue = formatValue(value, nativeDecimals); + const { + nativeCurrency: { symbol, decimals }, + } = useChainInfo(); + const formattedValue = formatValue(value, decimals); return ( {formattedValue} - {!hideUnit && ` ${nativeSymbol}`} + {!hideUnit && ` ${symbol}`} ); }; diff --git a/src/components/USDValue.tsx b/src/components/USDValue.tsx index 9554e41..90da1c2 100644 --- a/src/components/USDValue.tsx +++ b/src/components/USDValue.tsx @@ -10,7 +10,9 @@ type USDValueProps = { }; const USDValue: React.FC = ({ value }) => { - const { nativeSymbol } = useChainInfo(); + const { + nativeCurrency: { symbol }, + } = useChainInfo(); return ( @@ -24,7 +26,7 @@ const USDValue: React.FC = ({ value }) => { .toString() )} {" "} - / {nativeSymbol} + / {symbol} ) : ( "N/A" diff --git a/src/special/london/BlockRow.tsx b/src/special/london/BlockRow.tsx index 3d1cf8f..3bec637 100644 --- a/src/special/london/BlockRow.tsx +++ b/src/special/london/BlockRow.tsx @@ -16,7 +16,9 @@ type BlockRowProps = { }; const BlockRow: React.FC = ({ now, block, baseFeeDelta }) => { - const { nativeSymbol } = useChainInfo(); + const { + nativeCurrency: { symbol }, + } = useChainInfo(); const gasTarget = block.gasLimit.div(ELASTICITY_MULTIPLIER); const burntFees = block?.baseFeePerGas && block.baseFeePerGas.mul(block.gasUsed); @@ -55,11 +57,10 @@ const BlockRow: React.FC = ({ now, block, baseFeeDelta }) => {
- {commify(formatEther(totalReward))} {nativeSymbol} + {commify(formatEther(totalReward))} {symbol}
- {commify(formatEther(block.gasUsed.mul(block.baseFeePerGas!)))}{" "} - {nativeSymbol} + {commify(formatEther(block.gasUsed.mul(block.baseFeePerGas!)))} {symbol}
diff --git a/src/transaction/Details.tsx b/src/transaction/Details.tsx index e845d5e..a5d0661 100644 --- a/src/transaction/Details.tsx +++ b/src/transaction/Details.tsx @@ -87,7 +87,9 @@ const Details: React.FC = ({ const devMethod = txDesc ? devDoc?.methods[txDesc.signature] : undefined; const { provider } = useContext(RuntimeContext); - const { nativeName, nativeSymbol } = useChainInfo(); + const { + nativeCurrency: { name, symbol }, + } = useChainInfo(); const addresses = useMemo(() => { const _addresses: ChecksummedAddress[] = []; if (txData.to) { @@ -315,7 +317,7 @@ const Details: React.FC = ({ )} - {nativeSymbol}{" "} + {symbol}{" "} {!txData.value.isZero() && ethUSDPrice && ( @@ -338,8 +340,7 @@ const Details: React.FC = ({ {txData.type === 2 && ( <> - {" "} - {nativeSymbol} ( + {symbol} ( = ({ Gwei) - {nativeSymbol} ( + {symbol} ( Gwei) @@ -356,7 +357,7 @@ const Details: React.FC = ({
- {nativeSymbol} ( + {symbol} ( Gwei) {sendsEthToMiner && ( @@ -407,8 +408,7 @@ const Details: React.FC = ({
- {" "} - {nativeSymbol}{" "} + {symbol}{" "} {ethUSDPrice && ( = ({ {hasEIP1559 && }
- + diff --git a/src/transaction/RewardSplit.tsx b/src/transaction/RewardSplit.tsx index d6e47b3..b9268c4 100644 --- a/src/transaction/RewardSplit.tsx +++ b/src/transaction/RewardSplit.tsx @@ -12,7 +12,9 @@ type RewardSplitProps = { }; const RewardSplit: React.FC = ({ txData }) => { - const { nativeSymbol } = useChainInfo(); + const { + nativeCurrency: { symbol }, + } = useChainInfo(); const paidFees = txData.gasPrice.mul(txData.confirmedData!.gasUsed); const burntFees = txData.confirmedData!.blockBaseFeePerGas!.mul( txData.confirmedData!.gasUsed @@ -41,7 +43,7 @@ const RewardSplit: React.FC = ({ txData }) => { {" "} - {nativeSymbol} + {symbol}
@@ -57,7 +59,7 @@ const RewardSplit: React.FC = ({ txData }) => { - {nativeSymbol} + {symbol}
diff --git a/src/transaction/TraceInput.tsx b/src/transaction/TraceInput.tsx index c21adfc..f8f469a 100644 --- a/src/transaction/TraceInput.tsx +++ b/src/transaction/TraceInput.tsx @@ -19,7 +19,9 @@ type TraceInputProps = { }; const TraceInput: React.FC = ({ t }) => { - const { nativeSymbol } = useChainInfo(); + const { + nativeCurrency: { symbol }, + } = useChainInfo(); const raw4Bytes = extract4Bytes(t.input); const fourBytes = use4Bytes(raw4Bytes); const sigText = @@ -57,8 +59,7 @@ const TraceInput: React.FC = ({ t }) => { {t.value && !t.value.isZero() && ( - {"{"}value: {" "} - {nativeSymbol} + {"{"}value: {symbol} {"}"} )} diff --git a/src/useChainInfo.ts b/src/useChainInfo.ts index 5cd0f01..1d62904 100644 --- a/src/useChainInfo.ts +++ b/src/useChainInfo.ts @@ -3,15 +3,19 @@ import { chainInfoURL } from "./url"; import { OtterscanRuntime } from "./useRuntime"; export type ChainInfo = { - nativeName: string; - nativeSymbol: string; - nativeDecimals: number; + nativeCurrency: { + name: string; + symbol: string; + decimals: number; + }; }; export const defaultChainInfo: ChainInfo = { - nativeName: "Ether", - nativeSymbol: "ETH", - nativeDecimals: 18, + nativeCurrency: { + name: "Ether", + symbol: "ETH", + decimals: 18, + }, }; export const ChainInfoContext = createContext(undefined); @@ -40,9 +44,11 @@ export const useChainInfoFromMetadataFile = ( const info = await res.json(); setChainInfo({ - nativeName: info.nativeCurrency.name, - nativeDecimals: info.nativeCurrency.decimals, - nativeSymbol: info.nativeCurrency.symbol, + nativeCurrency: { + name: info.nativeCurrency.name, + decimals: info.nativeCurrency.decimals, + symbol: info.nativeCurrency.symbol, + }, }); } catch (err) { // ignore From 00893de2e230af6622b1d6c1b1efc90dae1a2784 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Tue, 5 Apr 2022 18:21:51 -0300 Subject: [PATCH 07/22] Rename and standardize Faucet prefix --- src/api/address-resolver/hardcoded-addresses/11155111.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/address-resolver/hardcoded-addresses/11155111.json b/src/api/address-resolver/hardcoded-addresses/11155111.json index d2a62ab..e534bca 100644 --- a/src/api/address-resolver/hardcoded-addresses/11155111.json +++ b/src/api/address-resolver/hardcoded-addresses/11155111.json @@ -1,3 +1,3 @@ { - "0xcFe95817aC44C3f8CE75F1EE6EC1431F586AB5A3": "FaucETH: Hot wallet" + "0xcFe95817aC44C3f8CE75F1EE6EC1431F586AB5A3": "Faucet: FaucETH" } \ No newline at end of file From 45441884e1ce95f08905bf7753c8a866542aaf8d Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Tue, 5 Apr 2022 22:38:27 -0300 Subject: [PATCH 08/22] Add faucets support --- src/Address.tsx | 8 ++++ src/App.tsx | 9 +++-- src/Faucets.tsx | 85 +++++++++++++++++++++++++++++++++++++++ src/components/Faucet.tsx | 26 ++++++++++++ src/useChainInfo.ts | 12 ++---- 5 files changed, 128 insertions(+), 12 deletions(-) create mode 100644 src/Faucets.tsx create mode 100644 src/components/Faucet.tsx diff --git a/src/Address.tsx b/src/Address.tsx index f739e7b..24260c3 100644 --- a/src/Address.tsx +++ b/src/Address.tsx @@ -15,6 +15,7 @@ import StandardFrame from "./StandardFrame"; import StandardSubtitle from "./StandardSubtitle"; import AddressOrENSNameNotFound from "./components/AddressOrENSNameNotFound"; import Copy from "./components/Copy"; +import Faucet from "./components/Faucet"; import NavTab from "./components/NavTab"; import SourcifyLogo from "./sourcify/SourcifyLogo"; import AddressTransactionResults from "./address/AddressTransactionResults"; @@ -25,6 +26,7 @@ import { useAddressOrENS } from "./useResolvedAddresses"; import { useMultipleMetadata } from "./sourcify/useSourcify"; import { ChecksummedAddress } from "./types"; import { useAddressesWithCode } from "./useErigonHooks"; +import { useChainInfo } from "./useChainInfo"; const AddressTransactionByNonce = React.lazy( () => @@ -86,6 +88,8 @@ const Address: React.FC = () => { ? metadatas[checksummedAddress] : undefined; + const { faucets } = useChainInfo(); + // Search address by nonce === transaction @ nonce const rawNonce = searchParams.get("nonce"); if (rawNonce !== null) { @@ -119,6 +123,10 @@ const Address: React.FC = () => { {checksummedAddress}
+ {/* Only display faucets for testnets who actually have any */} + {faucets && faucets.length > 0 && ( + + )} {isENS && ( ENS: {addressOrName} diff --git a/src/App.tsx b/src/App.tsx index 81116d7..523dc5e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -27,10 +27,10 @@ const Transaction = React.lazy( import(/* webpackChunkName: "tx", webpackPrefetch: true */ "./Transaction") ); const London = React.lazy( - () => - import( - /* webpackChunkName: "london", webpackPrefetch: true */ "./special/london/London" - ) + () => import(/* webpackChunkName: "london" */ "./special/london/London") +); +const Faucets = React.lazy( + () => import(/* webpackChunkName: "faucets" */ "./Faucets") ); const PageNotFound = React.lazy( () => @@ -74,6 +74,7 @@ const App = () => { path="address/:addressOrName/*" element={
} /> + } /> } /> diff --git a/src/Faucets.tsx b/src/Faucets.tsx new file mode 100644 index 0000000..7e26bd1 --- /dev/null +++ b/src/Faucets.tsx @@ -0,0 +1,85 @@ +import React, { useMemo } from "react"; +import { useLocation } from "react-router-dom"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faTriangleExclamation } from "@fortawesome/free-solid-svg-icons/faTriangleExclamation"; +import { faFaucetDrip } from "@fortawesome/free-solid-svg-icons/faFaucetDrip"; +import ExternalLink from "./components/ExternalLink"; +import ContentFrame from "./ContentFrame"; +import StandardFrame from "./StandardFrame"; +import StandardSubtitle from "./StandardSubtitle"; +import { useChainInfo } from "./useChainInfo"; +const Faucets: React.FC = () => { + const { faucets } = useChainInfo(); + const loc = useLocation(); + const urls = useMemo(() => { + const s = new URLSearchParams(loc.search); + const address = s.get("address"); + + const _urls = faucets.map((u) => + address !== null ? u.replaceAll("${ADDRESS}", address) : u + ); + + // Shuffle faucets to avoid UI bias + for (let i = _urls.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [_urls[i], _urls[j]] = [_urls[j], _urls[i]]; + } + + return _urls; + }, [faucets, loc]); + + return ( + + Faucets + +
+ {urls.length > 0 && ( +
+ + + The following external links come from + https://github.com/ethereum-lists/chains and are *NOT* endorsed + by us. Use at your own risk. + +
+ )} + {/* Display the shuffling notice only if there are 1+ faucets */} + {urls.length > 1 && ( +
+ + The faucet links below are shuffled on page load. +
+ )} + {urls.length > 0 ? ( +
+ {urls.map((url) => ( +
+ + + {url} + +
+ ))} +
+ ) : ( +
There are no registered faucets.
+ )} +
+
+
+ ); +}; + +export default Faucets; diff --git a/src/components/Faucet.tsx b/src/components/Faucet.tsx new file mode 100644 index 0000000..a0480df --- /dev/null +++ b/src/components/Faucet.tsx @@ -0,0 +1,26 @@ +import React from "react"; +import { NavLink } from "react-router-dom"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faFaucetDrip } from "@fortawesome/free-solid-svg-icons/faFaucetDrip"; +import { ChecksummedAddress } from "../types"; + +type FaucetProps = { + address: ChecksummedAddress; + rounded?: boolean; +}; + +const Faucet: React.FC = ({ address, rounded }) => ( + + + +); + +export default React.memo(Faucet); diff --git a/src/useChainInfo.ts b/src/useChainInfo.ts index 1d62904..c737c68 100644 --- a/src/useChainInfo.ts +++ b/src/useChainInfo.ts @@ -3,6 +3,7 @@ import { chainInfoURL } from "./url"; import { OtterscanRuntime } from "./useRuntime"; export type ChainInfo = { + faucets: string[]; nativeCurrency: { name: string; symbol: string; @@ -11,6 +12,7 @@ export type ChainInfo = { }; export const defaultChainInfo: ChainInfo = { + faucets: [], nativeCurrency: { name: "Ether", symbol: "ETH", @@ -41,15 +43,9 @@ export const useChainInfoFromMetadataFile = ( setChainInfo(defaultChainInfo); return; } - const info = await res.json(); - setChainInfo({ - nativeCurrency: { - name: info.nativeCurrency.name, - decimals: info.nativeCurrency.decimals, - symbol: info.nativeCurrency.symbol, - }, - }); + const info: ChainInfo = await res.json(); + setChainInfo(info); } catch (err) { // ignore setChainInfo(defaultChainInfo); From c59d07d17219ebadfc79e41a938ffca4c372b70f Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Tue, 5 Apr 2022 22:48:25 -0300 Subject: [PATCH 09/22] Update ethereum-lists/chains submodule --- chains | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chains b/chains index af79eb7..f795a1a 160000 --- a/chains +++ b/chains @@ -1 +1 @@ -Subproject commit af79eb7387b2a4f747bf31cb318d4f1db43c4d84 +Subproject commit f795a1a1ec5a6e87012f34eb148419a358bec04b From 6e5831af4b31060bedef8e3cc766b276a6ad318d Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Tue, 5 Apr 2022 22:51:34 -0300 Subject: [PATCH 10/22] Supress eslint because the template is intentional --- src/Faucets.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Faucets.tsx b/src/Faucets.tsx index 7e26bd1..d9c1eab 100644 --- a/src/Faucets.tsx +++ b/src/Faucets.tsx @@ -16,6 +16,7 @@ const Faucets: React.FC = () => { const address = s.get("address"); const _urls = faucets.map((u) => + // eslint-disable-next-line no-template-curly-in-string address !== null ? u.replaceAll("${ADDRESS}", address) : u ); From d236c926d23a69fa34c85f2fd1bf3c3d3e8043a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Apr 2022 01:58:38 +0000 Subject: [PATCH 11/22] Bump @testing-library/jest-dom from 5.16.3 to 5.16.4 (#231) --- 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 7c11a7a..4d50976 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "@fortawesome/free-solid-svg-icons": "^6.1.1", "@fortawesome/react-fontawesome": "^0.1.18", "@headlessui/react": "^1.5.0", - "@testing-library/jest-dom": "^5.16.3", + "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", "@types/jest": "^26.0.24", @@ -2970,9 +2970,9 @@ } }, "node_modules/@testing-library/jest-dom": { - "version": "5.16.3", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.3.tgz", - "integrity": "sha512-u5DfKj4wfSt6akfndfu1eG06jsdyA/IUrlX2n3pyq5UXgXMhXY+NJb8eNK/7pqPWAhCKsCGWDdDO0zKMKAYkEA==", + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz", + "integrity": "sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA==", "dependencies": { "@babel/runtime": "^7.9.2", "@types/testing-library__jest-dom": "^5.9.1", @@ -21506,9 +21506,9 @@ } }, "@testing-library/jest-dom": { - "version": "5.16.3", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.3.tgz", - "integrity": "sha512-u5DfKj4wfSt6akfndfu1eG06jsdyA/IUrlX2n3pyq5UXgXMhXY+NJb8eNK/7pqPWAhCKsCGWDdDO0zKMKAYkEA==", + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz", + "integrity": "sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA==", "requires": { "@babel/runtime": "^7.9.2", "@types/testing-library__jest-dom": "^5.9.1", diff --git a/package.json b/package.json index be3c113..1439d35 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "@fortawesome/free-solid-svg-icons": "^6.1.1", "@fortawesome/react-fontawesome": "^0.1.18", "@headlessui/react": "^1.5.0", - "@testing-library/jest-dom": "^5.16.3", + "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", "@types/jest": "^26.0.24", From fe20885b0790d75f82982e3fb9eb340107c24a3e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Apr 2022 01:59:10 +0000 Subject: [PATCH 12/22] Bump react-router-dom from 6.2.2 to 6.3.0 (#228) --- package-lock.json | 30 +++++++++++++++--------------- package.json | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4d50976..7cc00c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "react-error-boundary": "^3.1.4", "react-helmet-async": "^1.2.3", "react-image": "^4.0.3", - "react-router-dom": "^6.2.2", + "react-router-dom": "^6.3.0", "react-scripts": "4.0.3", "react-syntax-highlighter": "^15.5.0", "serve": "^13.0.2", @@ -14692,9 +14692,9 @@ } }, "node_modules/react-router": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.2.tgz", - "integrity": "sha512-/MbxyLzd7Q7amp4gDOGaYvXwhEojkJD5BtExkuKmj39VEE0m3l/zipf6h2WIB2jyAO0lI6NGETh4RDcktRm4AQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz", + "integrity": "sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==", "dependencies": { "history": "^5.2.0" }, @@ -14703,12 +14703,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.2.tgz", - "integrity": "sha512-AtYEsAST7bDD4dLSQHDnk/qxWLJdad5t1HFa1qJyUrCeGgEuCSw0VB/27ARbF9Fi/W5598ujvJOm3ujUCVzuYQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.3.0.tgz", + "integrity": "sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==", "dependencies": { "history": "^5.2.0", - "react-router": "6.2.2" + "react-router": "6.3.0" }, "peerDependencies": { "react": ">=16.8", @@ -29417,20 +29417,20 @@ "version": "0.8.3" }, "react-router": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.2.tgz", - "integrity": "sha512-/MbxyLzd7Q7amp4gDOGaYvXwhEojkJD5BtExkuKmj39VEE0m3l/zipf6h2WIB2jyAO0lI6NGETh4RDcktRm4AQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz", + "integrity": "sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==", "requires": { "history": "^5.2.0" } }, "react-router-dom": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.2.tgz", - "integrity": "sha512-AtYEsAST7bDD4dLSQHDnk/qxWLJdad5t1HFa1qJyUrCeGgEuCSw0VB/27ARbF9Fi/W5598ujvJOm3ujUCVzuYQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.3.0.tgz", + "integrity": "sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==", "requires": { "history": "^5.2.0", - "react-router": "6.2.2" + "react-router": "6.3.0" } }, "react-scripts": { diff --git a/package.json b/package.json index 1439d35..db92561 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "react-error-boundary": "^3.1.4", "react-helmet-async": "^1.2.3", "react-image": "^4.0.3", - "react-router-dom": "^6.2.2", + "react-router-dom": "^6.3.0", "react-scripts": "4.0.3", "react-syntax-highlighter": "^15.5.0", "serve": "^13.0.2", From c804b192846049bcb86d7278bcd2a96a90e7caae Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 6 Apr 2022 00:27:35 -0300 Subject: [PATCH 13/22] Revamp token transfer list table --- src/TokenTransferItem.tsx | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/TokenTransferItem.tsx b/src/TokenTransferItem.tsx index 0869a17..f616922 100644 --- a/src/TokenTransferItem.tsx +++ b/src/TokenTransferItem.tsx @@ -1,6 +1,7 @@ import React from "react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faCaretRight } from "@fortawesome/free-solid-svg-icons/faCaretRight"; +import { faSackDollar } from "@fortawesome/free-solid-svg-icons/faSackDollar"; import TransactionAddress from "./components/TransactionAddress"; import ValueHighlighter from "./components/ValueHighlighter"; import FormattedBalance from "./components/FormattedBalance"; @@ -26,12 +27,8 @@ const TokenTransferItem: React.FC = ({ }) => { return (
- - - -
-
- From +
+
= ({ showCodeIndicator />
-
- To +
+ + + = ({ showCodeIndicator />
-
- For +
+ + + Date: Wed, 6 Apr 2022 01:15:40 -0300 Subject: [PATCH 14/22] Simplify internal transfer table --- src/components/InternalCreate.tsx | 12 ++-- src/components/InternalSelfDestruct.tsx | 1 - src/components/InternalTransfer.tsx | 94 ++++++++++++++----------- 3 files changed, 60 insertions(+), 47 deletions(-) diff --git a/src/components/InternalCreate.tsx b/src/components/InternalCreate.tsx index fbb7f8f..7fa5850 100644 --- a/src/components/InternalCreate.tsx +++ b/src/components/InternalCreate.tsx @@ -1,6 +1,7 @@ import React from "react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faAngleRight } from "@fortawesome/free-solid-svg-icons/faAngleRight"; +import { faCaretRight } from "@fortawesome/free-solid-svg-icons/faCaretRight"; import TransactionAddress from "./TransactionAddress"; import AddressHighlighter from "./AddressHighlighter"; import DecoratedAddressLink from "./DecoratedAddressLink"; @@ -15,16 +16,17 @@ const InternalCreate: React.FC = ({ internalOp }) => ( CREATE - Contract + + + + + +
- - (Creator:{" "} - ) -
); diff --git a/src/components/InternalSelfDestruct.tsx b/src/components/InternalSelfDestruct.tsx index 8cb828e..bc6029b 100644 --- a/src/components/InternalSelfDestruct.tsx +++ b/src/components/InternalSelfDestruct.tsx @@ -30,7 +30,6 @@ const InternalSelfDestruct: React.FC = ({ SELF DESTRUCT - Contract
diff --git a/src/components/InternalTransfer.tsx b/src/components/InternalTransfer.tsx index b52acb9..09c3111 100644 --- a/src/components/InternalTransfer.tsx +++ b/src/components/InternalTransfer.tsx @@ -2,6 +2,8 @@ import React, { useContext } from "react"; import { formatEther } from "@ethersproject/units"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faAngleRight } from "@fortawesome/free-solid-svg-icons/faAngleRight"; +import { faCaretRight } from "@fortawesome/free-solid-svg-icons/faCaretRight"; +import { faSackDollar } from "@fortawesome/free-solid-svg-icons/faSackDollar"; import AddressHighlighter from "./AddressHighlighter"; import DecoratedAddressLink from "./DecoratedAddressLink"; import { RuntimeContext } from "../useRuntime"; @@ -41,48 +43,58 @@ const InternalTransfer: React.FC = ({ ); return ( -
- - TRANSFER - - - {formatEther(internalOp.value)} {symbol} - -
- From - -
- +
+
+
+ + TRANSFER + +
+ +
+ +
+
- -
-
- To - -
- -
-
+
+
+ + + + +
+ +
+
+
+
+ + + + + {formatEther(internalOp.value)} {symbol} + +
); From d8ee4f044097d6aab7fe7f13cb7ba94cd90569c0 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 6 Apr 2022 15:15:47 -0300 Subject: [PATCH 15/22] Update ethereum-lists/chains submodule; pull updated ethereum testnets files --- chains | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chains b/chains index f795a1a..9a90800 160000 --- a/chains +++ b/chains @@ -1 +1 @@ -Subproject commit f795a1a1ec5a6e87012f34eb148419a358bec04b +Subproject commit 9a908009cd88293a08222f75888d7f1bb82c13c8 From f1ac5a6b2b1ea2466ebcfeeceee598d4a08986ad Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Thu, 7 Apr 2022 01:44:08 -0300 Subject: [PATCH 16/22] Update topic0 to 0.2.4 --- topic0 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/topic0 b/topic0 index cb6abe8..e7be61f 160000 --- a/topic0 +++ b/topic0 @@ -1 +1 @@ -Subproject commit cb6abe87055d2e2d54ba6a985903031420c4cbb1 +Subproject commit e7be61f955f53fa2131cd14155d6891993772ff7 From f39cc4184f00f22bba7fb29d538ab78d1e6e9f5d Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Thu, 7 Apr 2022 22:48:59 -0300 Subject: [PATCH 17/22] First working version of token/usd oracle support; add support to token transfers section on tx details --- src/TokenTransferItem.tsx | 20 ++++++++- src/components/USDAmount.tsx | 44 ++++++++++++++++++++ src/usePriceOracle.ts | 80 ++++++++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 src/components/USDAmount.tsx diff --git a/src/TokenTransferItem.tsx b/src/TokenTransferItem.tsx index f616922..5838428 100644 --- a/src/TokenTransferItem.tsx +++ b/src/TokenTransferItem.tsx @@ -1,17 +1,21 @@ -import React from "react"; +import React, { useContext } from "react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faCaretRight } from "@fortawesome/free-solid-svg-icons/faCaretRight"; import { faSackDollar } from "@fortawesome/free-solid-svg-icons/faSackDollar"; import TransactionAddress from "./components/TransactionAddress"; import ValueHighlighter from "./components/ValueHighlighter"; import FormattedBalance from "./components/FormattedBalance"; +import USDAmount from "./components/USDAmount"; import { AddressContext, ChecksummedAddress, TokenMeta, TokenTransfer, } from "./types"; +import { RuntimeContext } from "./useRuntime"; +import { useBlockNumberContext } from "./useBlockTagContext"; import { Metadata } from "./sourcify/useSourcify"; +import { useTokenUSDOracle } from "./usePriceOracle"; type TokenTransferItemProps = { t: TokenTransfer; @@ -25,6 +29,10 @@ const TokenTransferItem: React.FC = ({ tokenMeta, metadatas, }) => { + const { provider } = useContext(RuntimeContext); + const blockNumber = useBlockNumberContext(); + const [quote, decimals] = useTokenUSDOracle(provider, blockNumber, t.token); + return (
@@ -60,6 +68,16 @@ const TokenTransferItem: React.FC = ({ + {tokenMeta && quote !== undefined && decimals !== undefined && ( + + + + )}
diff --git a/src/components/USDAmount.tsx b/src/components/USDAmount.tsx new file mode 100644 index 0000000..9ba7221 --- /dev/null +++ b/src/components/USDAmount.tsx @@ -0,0 +1,44 @@ +import React from "react"; +import { BigNumber, FixedNumber } from "@ethersproject/bignumber"; +import { commify } from "@ethersproject/units"; + +type USDAmountProps = { + amount: BigNumber; + amountDecimals: number; + quote: BigNumber; + quoteDecimals: number; +}; + +// TODO: fix the duplication mess with other currency display components + +/** + * Basic display of USD amount WITHOUT box decoration, only + * text formatting. + * + * USD amounts are displayed commified with 2 decimals places and $ prefix, + * i.e., "$1,000.00". + */ +const USDAmount: React.FC = ({ + amount, + amountDecimals, + quote, + quoteDecimals, +}) => { + const value = amount.mul(quote); + const decimals = amountDecimals + quoteDecimals; + + return ( + + $ + + {commify( + FixedNumber.fromValue(value, decimals, `ufixed256x${decimals}`) + .round(2) + .toString() + )} + + + ); +}; + +export default React.memo(USDAmount); diff --git a/src/usePriceOracle.ts b/src/usePriceOracle.ts index 2e49afd..737c398 100644 --- a/src/usePriceOracle.ts +++ b/src/usePriceOracle.ts @@ -3,6 +3,85 @@ import { JsonRpcProvider, BlockTag } from "@ethersproject/providers"; import { Contract } from "@ethersproject/contracts"; import { BigNumber } from "@ethersproject/bignumber"; import AggregatorV3Interface from "@chainlink/contracts/abi/v0.8/AggregatorV3Interface.json"; +import FeedRegistryInterface from "@chainlink/contracts/abi/v0.8/FeedRegistryInterface.json"; +import { ChecksummedAddress } from "./types"; + +const FEED_REGISTRY_MAINNET: ChecksummedAddress = + "0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf"; + +// The USD "token" address for Chainlink feed registry's purposes +const USD = "0x0000000000000000000000000000000000000348"; + +export const useTokenUSDOracle = ( + provider: JsonRpcProvider | undefined, + blockTag: BlockTag | undefined, + tokenAddress: ChecksummedAddress +): [BigNumber | undefined, number | undefined] => { + const feedRegistry = useMemo(() => { + // It work works on ethereum mainnet and kovan, see: + // https://docs.chain.link/docs/feed-registry/ + if (!provider || provider.network.chainId !== 1) { + return undefined; + } + + try { + return new Contract( + FEED_REGISTRY_MAINNET, + FeedRegistryInterface, + provider + ); + } catch (err) { + console.error(err); + return undefined; + } + }, [provider]); + + const [decimals, setDecimals] = useState(); + useEffect(() => { + if (!feedRegistry || blockTag === undefined) { + return; + } + + const readData = async () => { + try { + const _decimals = await feedRegistry.decimals(tokenAddress, USD, { + blockTag, + }); + setDecimals(_decimals); + } catch (err) { + // Silently ignore on purpose; it means the network or block number does + // not contain the chainlink feed contract + return undefined; + } + }; + readData(); + }, [feedRegistry, blockTag, tokenAddress]); + + const [latestPriceData, setLatestPriceData] = useState(); + useEffect(() => { + if (!feedRegistry || blockTag === undefined) { + return; + } + + const readData = async () => { + try { + const priceData = await feedRegistry.latestRoundData( + tokenAddress, + USD, + { blockTag } + ); + setLatestPriceData(BigNumber.from(priceData.answer)); + } catch (err) { + // Silently ignore on purpose; it means the network or block number does + // not contain the chainlink feed contract + return undefined; + } + }; + readData(); + }, [feedRegistry, blockTag, tokenAddress]); + + return [latestPriceData, decimals]; +}; export const useETHUSDOracle = ( provider: JsonRpcProvider | undefined, @@ -22,6 +101,7 @@ export const useMultipleETHUSDOracle = ( blockTags: (BlockTag | undefined)[] ) => { const ethFeed = useMemo(() => { + // TODO: it currently is hardcoded to support only mainnet if (!provider || provider.network.chainId !== 1) { return undefined; } From e9907f5925f8ae668ba067ba3dc6efdbc66f3b2d Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sun, 10 Apr 2022 01:35:01 -0300 Subject: [PATCH 18/22] Apply SWR; extract fetcher --- src/usePriceOracle.ts | 116 +++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 64 deletions(-) diff --git a/src/usePriceOracle.ts b/src/usePriceOracle.ts index 737c398..3a9cda6 100644 --- a/src/usePriceOracle.ts +++ b/src/usePriceOracle.ts @@ -4,6 +4,7 @@ import { Contract } from "@ethersproject/contracts"; import { BigNumber } from "@ethersproject/bignumber"; import AggregatorV3Interface from "@chainlink/contracts/abi/v0.8/AggregatorV3Interface.json"; import FeedRegistryInterface from "@chainlink/contracts/abi/v0.8/FeedRegistryInterface.json"; +import useSWRImmutable from "swr/immutable"; import { ChecksummedAddress } from "./types"; const FEED_REGISTRY_MAINNET: ChecksummedAddress = @@ -12,75 +13,62 @@ const FEED_REGISTRY_MAINNET: ChecksummedAddress = // The USD "token" address for Chainlink feed registry's purposes const USD = "0x0000000000000000000000000000000000000348"; +const feedRegistryFetcherKey = ( + tokenAddress: ChecksummedAddress, + blockTag: BlockTag | undefined +): [ChecksummedAddress, BlockTag] | null => { + if (blockTag === undefined) { + return null; + } + return [tokenAddress, blockTag]; +}; + +const feedRegistryFetcher = + (provider: JsonRpcProvider | undefined) => + async ( + tokenAddress: ChecksummedAddress, + blockTag: BlockTag + ): Promise<[BigNumber | undefined, number | undefined]> => { + // It work works on ethereum mainnet and kovan, see: + // https://docs.chain.link/docs/feed-registry/ + if (!provider || provider.network.chainId !== 1) { + return [undefined, undefined]; + } + + try { + const feedRegistry = new Contract( + FEED_REGISTRY_MAINNET, + FeedRegistryInterface, + provider + ); + const priceData = await feedRegistry.latestRoundData(tokenAddress, USD, { + blockTag, + }); + const quote = BigNumber.from(priceData.answer); + const decimals = await feedRegistry.decimals(tokenAddress, USD, { + blockTag, + }); + return [quote, decimals]; + } catch (err) { + console.error(err); + return [undefined, undefined]; + } + }; + export const useTokenUSDOracle = ( provider: JsonRpcProvider | undefined, blockTag: BlockTag | undefined, tokenAddress: ChecksummedAddress ): [BigNumber | undefined, number | undefined] => { - const feedRegistry = useMemo(() => { - // It work works on ethereum mainnet and kovan, see: - // https://docs.chain.link/docs/feed-registry/ - if (!provider || provider.network.chainId !== 1) { - return undefined; - } - - try { - return new Contract( - FEED_REGISTRY_MAINNET, - FeedRegistryInterface, - provider - ); - } catch (err) { - console.error(err); - return undefined; - } - }, [provider]); - - const [decimals, setDecimals] = useState(); - useEffect(() => { - if (!feedRegistry || blockTag === undefined) { - return; - } - - const readData = async () => { - try { - const _decimals = await feedRegistry.decimals(tokenAddress, USD, { - blockTag, - }); - setDecimals(_decimals); - } catch (err) { - // Silently ignore on purpose; it means the network or block number does - // not contain the chainlink feed contract - return undefined; - } - }; - readData(); - }, [feedRegistry, blockTag, tokenAddress]); - - const [latestPriceData, setLatestPriceData] = useState(); - useEffect(() => { - if (!feedRegistry || blockTag === undefined) { - return; - } - - const readData = async () => { - try { - const priceData = await feedRegistry.latestRoundData( - tokenAddress, - USD, - { blockTag } - ); - setLatestPriceData(BigNumber.from(priceData.answer)); - } catch (err) { - // Silently ignore on purpose; it means the network or block number does - // not contain the chainlink feed contract - return undefined; - } - }; - readData(); - }, [feedRegistry, blockTag, tokenAddress]); - - return [latestPriceData, decimals]; + const fetcher = feedRegistryFetcher(provider); + const { data, error } = useSWRImmutable( + feedRegistryFetcherKey(tokenAddress, blockTag), + fetcher + ); + if (error) { + return [undefined, undefined]; + } + return data ?? [undefined, undefined]; }; export const useETHUSDOracle = ( From c2e9ad7bd823b0ed5bd60e11c244b3a733a7cfeb Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sun, 10 Apr 2022 01:51:52 -0300 Subject: [PATCH 19/22] Simplify SWR code --- src/usePriceOracle.ts | 51 +++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/src/usePriceOracle.ts b/src/usePriceOracle.ts index 3a9cda6..f39230f 100644 --- a/src/usePriceOracle.ts +++ b/src/usePriceOracle.ts @@ -4,6 +4,7 @@ import { Contract } from "@ethersproject/contracts"; import { BigNumber } from "@ethersproject/bignumber"; import AggregatorV3Interface from "@chainlink/contracts/abi/v0.8/AggregatorV3Interface.json"; import FeedRegistryInterface from "@chainlink/contracts/abi/v0.8/FeedRegistryInterface.json"; +import { Fetcher } from "swr"; import useSWRImmutable from "swr/immutable"; import { ChecksummedAddress } from "./types"; @@ -13,10 +14,13 @@ const FEED_REGISTRY_MAINNET: ChecksummedAddress = // The USD "token" address for Chainlink feed registry's purposes const USD = "0x0000000000000000000000000000000000000348"; +type FeedRegistryFetcherKey = [ChecksummedAddress, BlockTag]; +type FeedRegistryFetcherData = [BigNumber | undefined, number | undefined]; + const feedRegistryFetcherKey = ( tokenAddress: ChecksummedAddress, blockTag: BlockTag | undefined -): [ChecksummedAddress, BlockTag] | null => { +): FeedRegistryFetcherKey | null => { if (blockTag === undefined) { return null; } @@ -24,35 +28,30 @@ const feedRegistryFetcherKey = ( }; const feedRegistryFetcher = - (provider: JsonRpcProvider | undefined) => - async ( - tokenAddress: ChecksummedAddress, - blockTag: BlockTag - ): Promise<[BigNumber | undefined, number | undefined]> => { + ( + provider: JsonRpcProvider | undefined + ): Fetcher => + async (tokenAddress, blockTag) => { // It work works on ethereum mainnet and kovan, see: // https://docs.chain.link/docs/feed-registry/ - if (!provider || provider.network.chainId !== 1) { - return [undefined, undefined]; + if (provider!.network.chainId !== 1) { + throw new Error("FeedRegistry is supported only on mainnet"); } - try { - const feedRegistry = new Contract( - FEED_REGISTRY_MAINNET, - FeedRegistryInterface, - provider - ); - const priceData = await feedRegistry.latestRoundData(tokenAddress, USD, { - blockTag, - }); - const quote = BigNumber.from(priceData.answer); - const decimals = await feedRegistry.decimals(tokenAddress, USD, { - blockTag, - }); - return [quote, decimals]; - } catch (err) { - console.error(err); - return [undefined, undefined]; - } + // Let SWR handle error + const feedRegistry = new Contract( + FEED_REGISTRY_MAINNET, + FeedRegistryInterface, + provider + ); + const priceData = await feedRegistry.latestRoundData(tokenAddress, USD, { + blockTag, + }); + const quote = BigNumber.from(priceData.answer); + const decimals = await feedRegistry.decimals(tokenAddress, USD, { + blockTag, + }); + return [quote, decimals]; }; export const useTokenUSDOracle = ( From d198a5c5b2706d29b5e22e89e52a45d7b6103e28 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 11 Apr 2022 01:04:56 -0300 Subject: [PATCH 20/22] Only enable faucets on chains explicitly flagged as network === testnet --- src/Address.tsx | 4 ++-- src/Faucets.tsx | 16 ++++++++++------ src/useChainInfo.ts | 2 ++ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/Address.tsx b/src/Address.tsx index 24260c3..2e1d3bb 100644 --- a/src/Address.tsx +++ b/src/Address.tsx @@ -88,7 +88,7 @@ const Address: React.FC = () => { ? metadatas[checksummedAddress] : undefined; - const { faucets } = useChainInfo(); + const { network, faucets } = useChainInfo(); // Search address by nonce === transaction @ nonce const rawNonce = searchParams.get("nonce"); @@ -124,7 +124,7 @@ const Address: React.FC = () => { {/* Only display faucets for testnets who actually have any */} - {faucets && faucets.length > 0 && ( + {network === "testnet" && faucets && faucets.length > 0 && ( )} {isENS && ( diff --git a/src/Faucets.tsx b/src/Faucets.tsx index d9c1eab..9e4527d 100644 --- a/src/Faucets.tsx +++ b/src/Faucets.tsx @@ -8,17 +8,21 @@ import ContentFrame from "./ContentFrame"; import StandardFrame from "./StandardFrame"; import StandardSubtitle from "./StandardSubtitle"; import { useChainInfo } from "./useChainInfo"; + const Faucets: React.FC = () => { - const { faucets } = useChainInfo(); + const { network, faucets } = useChainInfo(); const loc = useLocation(); const urls = useMemo(() => { const s = new URLSearchParams(loc.search); const address = s.get("address"); - const _urls = faucets.map((u) => - // eslint-disable-next-line no-template-curly-in-string - address !== null ? u.replaceAll("${ADDRESS}", address) : u - ); + const _urls: string[] = + network === "testnet" + ? faucets.map((u) => + // eslint-disable-next-line no-template-curly-in-string + address !== null ? u.replaceAll("${ADDRESS}", address) : u + ) + : []; // Shuffle faucets to avoid UI bias for (let i = _urls.length - 1; i > 0; i--) { @@ -27,7 +31,7 @@ const Faucets: React.FC = () => { } return _urls; - }, [faucets, loc]); + }, [network, faucets, loc]); return ( diff --git a/src/useChainInfo.ts b/src/useChainInfo.ts index c737c68..dec3798 100644 --- a/src/useChainInfo.ts +++ b/src/useChainInfo.ts @@ -3,6 +3,7 @@ import { chainInfoURL } from "./url"; import { OtterscanRuntime } from "./useRuntime"; export type ChainInfo = { + network: string | undefined; faucets: string[]; nativeCurrency: { name: string; @@ -12,6 +13,7 @@ export type ChainInfo = { }; export const defaultChainInfo: ChainInfo = { + network: undefined, faucets: [], nativeCurrency: { name: "Ether", From a1edc3d6324530e7d53ac9aad9608733c9ce15e2 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 11 Apr 2022 14:34:49 -0300 Subject: [PATCH 21/22] Push down oracle info read --- src/TransactionPageContent.tsx | 7 ------- src/transaction/Details.tsx | 23 +++++++++++++++-------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/TransactionPageContent.tsx b/src/TransactionPageContent.tsx index 31a7974..501ff46 100644 --- a/src/TransactionPageContent.tsx +++ b/src/TransactionPageContent.tsx @@ -10,7 +10,6 @@ import { useInternalOperations, useTxData } from "./useErigonHooks"; import { SelectionContext, useSelection } from "./useSelection"; import { SelectedTransactionContext } from "./useSelectedTransaction"; import { BlockNumberContext } from "./useBlockTagContext"; -import { useETHUSDOracle } from "./usePriceOracle"; import { useAppConfigContext } from "./useAppConfig"; import { useSourcify, useTransactionDescription } from "./sourcify/useSourcify"; @@ -60,11 +59,6 @@ const TransactionPageContent: React.FC = ({ const selectionCtx = useSelection(); - const blockETHUSDPrice = useETHUSDOracle( - provider, - txData?.confirmedData?.blockNumber - ); - const { sourcifySource } = useAppConfigContext(); const metadata = useSourcify( txData?.to, @@ -114,7 +108,6 @@ const TransactionPageContent: React.FC = ({ devDoc={metadata?.output.devdoc} internalOps={internalOps} sendsEthToMiner={sendsEthToMiner} - ethUSDPrice={blockETHUSDPrice} /> } /> diff --git a/src/transaction/Details.tsx b/src/transaction/Details.tsx index a5d0661..5764d99 100644 --- a/src/transaction/Details.tsx +++ b/src/transaction/Details.tsx @@ -1,7 +1,6 @@ import React, { useContext, useMemo, useState } from "react"; import { Tab } from "@headlessui/react"; import { TransactionDescription } from "@ethersproject/abi"; -import { BigNumber } from "@ethersproject/bignumber"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faCheckCircle } from "@fortawesome/free-solid-svg-icons/faCheckCircle"; import { faCube } from "@fortawesome/free-solid-svg-icons/faCube"; @@ -47,6 +46,7 @@ import { RuntimeContext } from "../useRuntime"; import { useContractsMetadata } from "../hooks"; import { useTransactionError } from "../useErigonHooks"; import { useChainInfo } from "../useChainInfo"; +import { useETHUSDOracle } from "../usePriceOracle"; type DetailsProps = { txData: TransactionData; @@ -56,7 +56,6 @@ type DetailsProps = { devDoc?: DevDoc | undefined; internalOps?: InternalOperation[]; sendsEthToMiner: boolean; - ethUSDPrice: BigNumber | undefined; }; const Details: React.FC = ({ @@ -67,7 +66,6 @@ const Details: React.FC = ({ devDoc, internalOps, sendsEthToMiner, - ethUSDPrice, }) => { const hasEIP1559 = txData.confirmedData?.blockBaseFeePerGas !== undefined && @@ -90,6 +88,12 @@ const Details: React.FC = ({ const { nativeCurrency: { name, symbol }, } = useChainInfo(); + + const blockETHUSDPrice = useETHUSDOracle( + provider, + txData?.confirmedData?.blockNumber + ); + const addresses = useMemo(() => { const _addresses: ChecksummedAddress[] = []; if (txData.to) { @@ -318,9 +322,12 @@ const Details: React.FC = ({ )} {symbol}{" "} - {!txData.value.isZero() && ethUSDPrice && ( + {!txData.value.isZero() && blockETHUSDPrice && ( - + )} @@ -409,11 +416,11 @@ const Details: React.FC = ({
{symbol}{" "} - {ethUSDPrice && ( + {blockETHUSDPrice && ( )} @@ -422,7 +429,7 @@ const Details: React.FC = ({
- + )} From 2c0f576d23ba87918b78632a0b6534afd0ebc3df Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 11 Apr 2022 14:56:16 -0300 Subject: [PATCH 22/22] Apply USD oracle to internal ETH transfers section --- .../InternalTransactionOperation.tsx | 38 +++++++++++-------- src/components/InternalTransfer.tsx | 18 ++++++++- src/transaction/Details.tsx | 1 + 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/components/InternalTransactionOperation.tsx b/src/components/InternalTransactionOperation.tsx index 5870336..3037dd2 100644 --- a/src/components/InternalTransactionOperation.tsx +++ b/src/components/InternalTransactionOperation.tsx @@ -1,4 +1,5 @@ import React from "react"; +import { BigNumber } from "@ethersproject/bignumber"; import InternalTransfer from "./InternalTransfer"; import InternalSelfDestruct from "./InternalSelfDestruct"; import InternalCreate from "./InternalCreate"; @@ -7,22 +8,29 @@ import { TransactionData, InternalOperation, OperationType } from "../types"; type InternalTransactionOperationProps = { txData: TransactionData; internalOp: InternalOperation; + // TODO: migrate all this logic to SWR + ethUSDPrice: BigNumber | undefined; }; -const InternalTransactionOperation: React.FC = - ({ txData, internalOp }) => ( - <> - {internalOp.type === OperationType.TRANSFER && ( - - )} - {internalOp.type === OperationType.SELF_DESTRUCT && ( - - )} - {(internalOp.type === OperationType.CREATE || - internalOp.type === OperationType.CREATE2) && ( - - )} - - ); +const InternalTransactionOperation: React.FC< + InternalTransactionOperationProps +> = ({ txData, internalOp, ethUSDPrice }) => ( + <> + {internalOp.type === OperationType.TRANSFER && ( + + )} + {internalOp.type === OperationType.SELF_DESTRUCT && ( + + )} + {(internalOp.type === OperationType.CREATE || + internalOp.type === OperationType.CREATE2) && ( + + )} + +); export default React.memo(InternalTransactionOperation); diff --git a/src/components/InternalTransfer.tsx b/src/components/InternalTransfer.tsx index 09c3111..af7001d 100644 --- a/src/components/InternalTransfer.tsx +++ b/src/components/InternalTransfer.tsx @@ -1,4 +1,5 @@ import React, { useContext } from "react"; +import { BigNumber } from "@ethersproject/bignumber"; import { formatEther } from "@ethersproject/units"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faAngleRight } from "@fortawesome/free-solid-svg-icons/faAngleRight"; @@ -6,6 +7,7 @@ import { faCaretRight } from "@fortawesome/free-solid-svg-icons/faCaretRight"; import { faSackDollar } from "@fortawesome/free-solid-svg-icons/faSackDollar"; import AddressHighlighter from "./AddressHighlighter"; import DecoratedAddressLink from "./DecoratedAddressLink"; +import USDAmount from "./USDAmount"; import { RuntimeContext } from "../useRuntime"; import { useHasCode } from "../useErigonHooks"; import { useChainInfo } from "../useChainInfo"; @@ -14,14 +16,17 @@ import { TransactionData, InternalOperation } from "../types"; type InternalTransferProps = { txData: TransactionData; internalOp: InternalOperation; + // TODO: migrate all this logic to SWR + ethUSDPrice: BigNumber | undefined; }; const InternalTransfer: React.FC = ({ txData, internalOp, + ethUSDPrice, }) => { const { - nativeCurrency: { symbol }, + nativeCurrency: { symbol, decimals }, } = useChainInfo(); const fromMiner = txData.confirmedData?.miner !== undefined && @@ -94,6 +99,17 @@ const InternalTransfer: React.FC = ({ {formatEther(internalOp.value)} {symbol} + {ethUSDPrice && ( + + + + )}
diff --git a/src/transaction/Details.tsx b/src/transaction/Details.tsx index 5764d99..e39346b 100644 --- a/src/transaction/Details.tsx +++ b/src/transaction/Details.tsx @@ -298,6 +298,7 @@ const Details: React.FC = ({ key={i} txData={txData} internalOp={op} + ethUSDPrice={blockETHUSDPrice} /> ))}