diff --git a/src/App.tsx b/src/App.tsx index 62d3b2c..e9c3f20 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -7,6 +7,7 @@ import ConnectionErrorPanel from "./ConnectionErrorPanel"; import Footer from "./Footer"; import { ConnectionStatus } from "./types"; import { RuntimeContext, useRuntime } from "./useRuntime"; +import { ChainInfoContext, defaultChainInfo } from "./useChainInfo"; const Block = React.lazy( () => import(/* webpackChunkName: "block", webpackPrefetch: true */ "./Block") @@ -50,29 +51,34 @@ const App = () => { /> ) : ( -
- - - - } /> - } /> - }> - } /> - } - /> - } /> - } - /> - } /> - - - -
-
+ +
+ + + + } /> + } /> + }> + } + /> + } + /> + } /> + } + /> + } /> + + + +
+
)} diff --git a/src/Block.tsx b/src/Block.tsx index 0b96cda..97b14ba 100644 --- a/src/Block.tsx +++ b/src/Block.tsx @@ -9,6 +9,7 @@ import StandardFrame from "./StandardFrame"; import StandardSubtitle from "./StandardSubtitle"; import NavBlock from "./block/NavBlock"; import ContentFrame from "./ContentFrame"; +import BlockNotFound from "./components/BlockNotFound"; import InfoRow from "./components/InfoRow"; import Timestamp from "./components/Timestamp"; import GasValue from "./components/GasValue"; @@ -25,7 +26,7 @@ import { useLatestBlockNumber } from "./useLatestBlock"; import { blockTxsURL } from "./url"; import { useBlockData } from "./useErigonHooks"; import { useETHUSDOracle } from "./usePriceOracle"; -import BlockNotFound from "./components/BlockNotFound"; +import { useChainInfo } from "./useChainInfo"; const Block: React.FC = () => { const { provider } = useContext(RuntimeContext); @@ -33,6 +34,7 @@ const Block: React.FC = () => { if (blockNumberOrHash === undefined) { throw new Error("blockNumberOrHash couldn't be undefined here"); } + const { nativeName, nativeSymbol } = useChainInfo(); const block = useBlockData(provider, blockNumberOrHash); useEffect(() => { @@ -144,7 +146,7 @@ const Block: React.FC = () => { {" "} - Ether + {nativeSymbol} @@ -163,7 +165,7 @@ const Block: React.FC = () => { {extraStr} (Hex:{" "} {block.extraData}) - + diff --git a/src/PriceBox.tsx b/src/PriceBox.tsx index 2ebb5d7..2f5bd4d 100644 --- a/src/PriceBox.tsx +++ b/src/PriceBox.tsx @@ -7,12 +7,14 @@ import AggregatorV3Interface from "@chainlink/contracts/abi/v0.8/AggregatorV3Int import { RuntimeContext } from "./useRuntime"; import { formatValue } from "./components/formatter"; import { useLatestBlock } from "./useLatestBlock"; +import { useChainInfo } from "./useChainInfo"; const ETH_FEED_DECIMALS = 8; // TODO: reduce duplication with useETHUSDOracle const PriceBox: React.FC = () => { const { provider } = useContext(RuntimeContext); + const { nativeSymbol } = useChainInfo(); const latestBlock = useLatestBlock(provider); const maybeOutdated: boolean = @@ -80,9 +82,9 @@ const PriceBox: React.FC = () => { } font-sans text-xs text-gray-800`} > - Eth: ${latestPrice} + {nativeSymbol}: ${latestPrice} {latestGasData && ( <> diff --git a/src/components/InternalSelfDestruct.tsx b/src/components/InternalSelfDestruct.tsx index 4df2119..9bcb0ad 100644 --- a/src/components/InternalSelfDestruct.tsx +++ b/src/components/InternalSelfDestruct.tsx @@ -4,8 +4,9 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faAngleRight } from "@fortawesome/free-solid-svg-icons/faAngleRight"; import AddressHighlighter from "./AddressHighlighter"; import DecoratedAddressLink from "./DecoratedAddressLink"; -import { TransactionData, InternalOperation } from "../types"; import TransactionAddress from "./TransactionAddress"; +import { useChainInfo } from "../useChainInfo"; +import { TransactionData, InternalOperation } from "../types"; type InternalSelfDestructProps = { txData: TransactionData; @@ -16,6 +17,7 @@ const InternalSelfDestruct: React.FC = ({ txData, internalOp, }) => { + const { nativeSymbol } = useChainInfo(); const toMiner = txData.confirmedData?.miner !== undefined && internalOp.to === txData.confirmedData.miner; @@ -43,7 +45,9 @@ const InternalSelfDestruct: React.FC = ({ TRANSFER - {formatEther(internalOp.value)} Ether + + {formatEther(internalOp.value)} {nativeSymbol} +
To diff --git a/src/components/InternalTransfer.tsx b/src/components/InternalTransfer.tsx index 5a9f8cd..b73bdf0 100644 --- a/src/components/InternalTransfer.tsx +++ b/src/components/InternalTransfer.tsx @@ -6,6 +6,7 @@ import AddressHighlighter from "./AddressHighlighter"; import DecoratedAddressLink from "./DecoratedAddressLink"; import { RuntimeContext } from "../useRuntime"; import { useHasCode } from "../useErigonHooks"; +import { useChainInfo } from "../useChainInfo"; import { TransactionData, InternalOperation } from "../types"; type InternalTransferProps = { @@ -17,6 +18,7 @@ const InternalTransfer: React.FC = ({ txData, internalOp, }) => { + const { nativeSymbol } = useChainInfo(); const fromMiner = txData.confirmedData?.miner !== undefined && internalOp.from === txData.confirmedData.miner; @@ -41,7 +43,9 @@ const InternalTransfer: React.FC = ({ TRANSFER - {formatEther(internalOp.value)} Ether + + {formatEther(internalOp.value)} {nativeSymbol} +
From diff --git a/src/components/TransactionValue.tsx b/src/components/TransactionValue.tsx index c7a8d2c..b4a9d54 100644 --- a/src/components/TransactionValue.tsx +++ b/src/components/TransactionValue.tsx @@ -1,12 +1,11 @@ import React from "react"; import { BigNumber } from "@ethersproject/bignumber"; +import { useChainInfo } from "../useChainInfo"; import { formatValue } from "./formatter"; type TransactionValueProps = { value: BigNumber; - decimals?: number; hideUnit?: boolean; - unitName?: string; }; /** @@ -21,19 +20,18 @@ type TransactionValueProps = { */ const TransactionValue: React.FC = ({ value, - decimals = 18, hideUnit, - unitName = "ETH", }) => { - const formattedValue = formatValue(value, decimals); + const { nativeSymbol, nativeDecimals } = useChainInfo(); + const formattedValue = formatValue(value, nativeDecimals); return ( {formattedValue} - {!hideUnit && ` ${unitName}`} + {!hideUnit && ` ${nativeSymbol}`} ); }; diff --git a/src/components/USDValue.tsx b/src/components/USDValue.tsx index e488d25..9554e41 100644 --- a/src/components/USDValue.tsx +++ b/src/components/USDValue.tsx @@ -1,6 +1,7 @@ import React from "react"; import { BigNumber, FixedNumber } from "@ethersproject/bignumber"; import { commify } from "@ethersproject/units"; +import { useChainInfo } from "../useChainInfo"; const ETH_FEED_DECIMALS = 8; @@ -8,22 +9,28 @@ type USDValueProps = { value: BigNumber | undefined; }; -const USDValue: React.FC = ({ value }) => ( - - {value ? ( - <> - $ - - {commify( - FixedNumber.fromValue(value, ETH_FEED_DECIMALS).round(2).toString() - )} - {" "} - / ETH - - ) : ( - "N/A" - )} - -); +const USDValue: React.FC = ({ value }) => { + const { nativeSymbol } = useChainInfo(); + + return ( + + {value ? ( + <> + $ + + {commify( + FixedNumber.fromValue(value, ETH_FEED_DECIMALS) + .round(2) + .toString() + )} + {" "} + / {nativeSymbol} + + ) : ( + "N/A" + )} + + ); +}; export default React.memo(USDValue); diff --git a/src/special/london/BlockRow.tsx b/src/special/london/BlockRow.tsx index df22a85..3d1cf8f 100644 --- a/src/special/london/BlockRow.tsx +++ b/src/special/london/BlockRow.tsx @@ -3,8 +3,9 @@ import { FixedNumber } from "@ethersproject/bignumber"; import { commify, formatEther } from "@ethersproject/units"; import BlockLink from "../../components/BlockLink"; import TimestampAge from "../../components/TimestampAge"; -import { ExtendedBlock } from "../../useErigonHooks"; import Blip from "./Blip"; +import { ExtendedBlock } from "../../useErigonHooks"; +import { useChainInfo } from "../../useChainInfo"; const ELASTICITY_MULTIPLIER = 2; @@ -15,6 +16,7 @@ type BlockRowProps = { }; const BlockRow: React.FC = ({ now, block, baseFeeDelta }) => { + const { nativeSymbol } = useChainInfo(); const gasTarget = block.gasLimit.div(ELASTICITY_MULTIPLIER); const burntFees = block?.baseFeePerGas && block.baseFeePerGas.mul(block.gasUsed); @@ -53,10 +55,11 @@ const BlockRow: React.FC = ({ now, block, baseFeeDelta }) => {
- {commify(formatEther(totalReward))} Ether + {commify(formatEther(totalReward))} {nativeSymbol}
- {commify(formatEther(block.gasUsed.mul(block.baseFeePerGas!)))} Ether + {commify(formatEther(block.gasUsed.mul(block.baseFeePerGas!)))}{" "} + {nativeSymbol}
diff --git a/src/transaction/Details.tsx b/src/transaction/Details.tsx index f8243f0..e845d5e 100644 --- a/src/transaction/Details.tsx +++ b/src/transaction/Details.tsx @@ -46,6 +46,7 @@ import { DevDoc, Metadata, useError, UserDoc } from "../sourcify/useSourcify"; import { RuntimeContext } from "../useRuntime"; import { useContractsMetadata } from "../hooks"; import { useTransactionError } from "../useErigonHooks"; +import { useChainInfo } from "../useChainInfo"; type DetailsProps = { txData: TransactionData; @@ -86,6 +87,7 @@ const Details: React.FC = ({ const devMethod = txDesc ? devDoc?.methods[txDesc.signature] : undefined; const { provider } = useContext(RuntimeContext); + const { nativeName, nativeSymbol } = useChainInfo(); const addresses = useMemo(() => { const _addresses: ChecksummedAddress[] = []; if (txData.to) { @@ -313,7 +315,7 @@ const Details: React.FC = ({ )} - Ether{" "} + {nativeSymbol}{" "} {!txData.value.isZero() && ethUSDPrice && ( @@ -336,7 +338,8 @@ const Details: React.FC = ({ {txData.type === 2 && ( <> - Ether ( + {" "} + {nativeSymbol} ( = ({ Gwei) - Ether ( + {nativeSymbol} ( Gwei) @@ -353,7 +356,7 @@ const Details: React.FC = ({
- Ether ( + {nativeSymbol} ( Gwei) {sendsEthToMiner && ( @@ -404,7 +407,8 @@ const Details: React.FC = ({
- Ether{" "} + {" "} + {nativeSymbol}{" "} {ethUSDPrice && ( = ({ {hasEIP1559 && }
- + diff --git a/src/transaction/RewardSplit.tsx b/src/transaction/RewardSplit.tsx index 7d35a7e..d6e47b3 100644 --- a/src/transaction/RewardSplit.tsx +++ b/src/transaction/RewardSplit.tsx @@ -3,14 +3,16 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faBurn } from "@fortawesome/free-solid-svg-icons/faBurn"; import { faCoins } from "@fortawesome/free-solid-svg-icons/faCoins"; import FormattedBalance from "../components/FormattedBalance"; -import { TransactionData } from "../types"; import PercentageGauge from "../components/PercentageGauge"; +import { TransactionData } from "../types"; +import { useChainInfo } from "../useChainInfo"; type RewardSplitProps = { txData: TransactionData; }; const RewardSplit: React.FC = ({ txData }) => { + const { nativeSymbol } = useChainInfo(); const paidFees = txData.gasPrice.mul(txData.confirmedData!.gasUsed); const burntFees = txData.confirmedData!.blockBaseFeePerGas!.mul( txData.confirmedData!.gasUsed @@ -39,7 +41,7 @@ const RewardSplit: React.FC = ({ txData }) => { {" "} - Ether + {nativeSymbol}
@@ -55,7 +57,7 @@ const RewardSplit: React.FC = ({ txData }) => { - Ether + {nativeSymbol}
diff --git a/src/transaction/TraceInput.tsx b/src/transaction/TraceInput.tsx index 7b917ff..2ae54e9 100644 --- a/src/transaction/TraceInput.tsx +++ b/src/transaction/TraceInput.tsx @@ -12,6 +12,7 @@ import { use4Bytes, useTransactionDescription, } from "../use4Bytes"; +import { useChainInfo } from "../useChainInfo"; import { TransactionData } from "../types"; type TraceInputProps = { @@ -20,6 +21,7 @@ type TraceInputProps = { }; const TraceInput: React.FC = ({ t, txData }) => { + const { nativeSymbol } = useChainInfo(); const raw4Bytes = extract4Bytes(t.input); const fourBytes = use4Bytes(raw4Bytes); const sigText = @@ -57,7 +59,9 @@ const TraceInput: React.FC = ({ t, txData }) => { {t.value && !t.value.isZero() && ( - {"{"}value: ETH{"}"} + {"{"}value: {" "} + {nativeSymbol} + {"}"} )} diff --git a/src/useChainInfo.ts b/src/useChainInfo.ts new file mode 100644 index 0000000..f1de917 --- /dev/null +++ b/src/useChainInfo.ts @@ -0,0 +1,23 @@ +import { createContext, useContext } from "react"; + +export type ChainInfo = { + nativeName: string; + nativeSymbol: string; + nativeDecimals: number; +}; + +export const defaultChainInfo: ChainInfo = { + nativeName: "Ether", + nativeSymbol: "ETH", + nativeDecimals: 18, +}; + +export const ChainInfoContext = createContext(undefined); + +export const useChainInfo = (): ChainInfo => { + const chainInfo = useContext(ChainInfoContext); + if (chainInfo === undefined) { + throw new Error("no chain info"); + } + return chainInfo; +};