From 4b85cc8cd5328f62d16b0c04b365db55c71934a0 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Fri, 25 Mar 2022 21:38:12 -0300 Subject: [PATCH 1/5] Parameterize components by chain native name/token symbol/decimals --- src/App.tsx | 52 ++++++++++++++----------- src/Block.tsx | 8 ++-- src/PriceBox.tsx | 6 ++- src/components/InternalSelfDestruct.tsx | 8 +++- src/components/InternalTransfer.tsx | 6 ++- src/components/TransactionValue.tsx | 12 +++--- src/components/USDValue.tsx | 41 +++++++++++-------- src/special/london/BlockRow.tsx | 9 +++-- src/transaction/Details.tsx | 16 +++++--- src/transaction/RewardSplit.tsx | 8 ++-- src/transaction/TraceInput.tsx | 6 ++- src/useChainInfo.ts | 23 +++++++++++ 12 files changed, 127 insertions(+), 68 deletions(-) create mode 100644 src/useChainInfo.ts 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; +}; From 247596e58a64e3c52dd57fd510075e2690f6caa6 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Fri, 25 Mar 2022 21:40:54 -0300 Subject: [PATCH 2/5] Remove unnecessary parameter --- src/transaction/Trace.tsx | 7 +------ src/transaction/TraceInput.tsx | 4 +--- src/transaction/TraceItem.tsx | 29 ++++++++++++----------------- 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/src/transaction/Trace.tsx b/src/transaction/Trace.tsx index 5a2a4f9..a04bcdb 100644 --- a/src/transaction/Trace.tsx +++ b/src/transaction/Trace.tsx @@ -24,12 +24,7 @@ const Trace: React.FC = ({ txData }) => {
{traces.map((t, i, a) => ( - + ))}
diff --git a/src/transaction/TraceInput.tsx b/src/transaction/TraceInput.tsx index 2ae54e9..c21adfc 100644 --- a/src/transaction/TraceInput.tsx +++ b/src/transaction/TraceInput.tsx @@ -13,14 +13,12 @@ import { useTransactionDescription, } from "../use4Bytes"; import { useChainInfo } from "../useChainInfo"; -import { TransactionData } from "../types"; type TraceInputProps = { t: TraceEntry; - txData: TransactionData; }; -const TraceInput: React.FC = ({ t, txData }) => { +const TraceInput: React.FC = ({ t }) => { const { nativeSymbol } = useChainInfo(); const raw4Bytes = extract4Bytes(t.input); const fourBytes = use4Bytes(raw4Bytes); diff --git a/src/transaction/TraceItem.tsx b/src/transaction/TraceItem.tsx index 5dd4a3d..d6a4d7d 100644 --- a/src/transaction/TraceItem.tsx +++ b/src/transaction/TraceItem.tsx @@ -5,15 +5,13 @@ import { faMinusSquare } from "@fortawesome/free-regular-svg-icons/faMinusSquare import { Switch } from "@headlessui/react"; import { TraceGroup } from "../useErigonHooks"; import TraceInput from "./TraceInput"; -import { TransactionData } from "../types"; type TraceItemProps = { t: TraceGroup; last: boolean; - txData: TransactionData; }; -const TraceItem: React.FC = ({ t, last, txData }) => { +const TraceItem: React.FC = ({ t, last }) => { const [expanded, setExpanded] = useState(true); return ( @@ -35,7 +33,7 @@ const TraceItem: React.FC = ({ t, last, txData }) => { /> )} - + {t.children && (
= ({ t, last, txData }) => { expanded ? "" : "hidden" }`} > - +
)} @@ -52,19 +50,16 @@ const TraceItem: React.FC = ({ t, last, txData }) => { type TraceChildrenProps = { c: TraceGroup[]; - txData: TransactionData; }; -const TraceChildren: React.FC = React.memo( - ({ c, txData }) => { - return ( - <> - {c.map((tc, i, a) => ( - - ))} - - ); - } -); +const TraceChildren: React.FC = React.memo(({ c }) => { + return ( + <> + {c.map((tc, i, a) => ( + + ))} + + ); +}); export default TraceItem; From 6e9db8a14585cfb140648b4f3822948322ff7cad Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 26 Mar 2022 14:37:17 -0300 Subject: [PATCH 3/5] Add ethereum-lists/chains submodule --- .gitmodules | 4 ++++ chains | 1 + 2 files changed, 5 insertions(+) create mode 160000 chains diff --git a/.gitmodules b/.gitmodules index e55ad32..0e9bd10 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,7 @@ path = topic0 url = https://github.com/wmitsuda/topic0.git ignore = dirty +[submodule "chains"] + path = chains + url = https://github.com/ethereum-lists/chains.git + ignore = dirty diff --git a/chains b/chains new file mode 160000 index 0000000..af79eb7 --- /dev/null +++ b/chains @@ -0,0 +1 @@ +Subproject commit af79eb7387b2a4f747bf31cb318d4f1db43c4d84 From 88926bd777e7c2166bc4fae33b7e407932852ec2 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 28 Mar 2022 14:10:42 -0300 Subject: [PATCH 4/5] Parameterize chain info using ethereum-lists/chains submodule --- nginx/conf.d/default.conf | 34 ++++++++++++++++++++++++++++++++++ package.json | 4 ++-- src/App.tsx | 8 +++++--- src/url.ts | 5 +++++ src/useChainInfo.ts | 38 +++++++++++++++++++++++++++++++++++++- 5 files changed, 83 insertions(+), 6 deletions(-) diff --git a/nginx/conf.d/default.conf b/nginx/conf.d/default.conf index 4fdf9a1..2866389 100644 --- a/nginx/conf.d/default.conf +++ b/nginx/conf.d/default.conf @@ -113,6 +113,40 @@ server { } } + location /chains { + root /usr/share/nginx/html; + expires 30d; + + # Base on: https://michielkalkman.com/snippets/nginx-cors-open-configuration/ + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Allow-Origin' '*'; + # + # Om nom nom cookies + # + add_header 'Access-Control-Allow-Credentials' 'true'; + add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS'; + + # + # Custom headers and headers various browsers *should* be OK with but aren't + # + add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; + + # + # Tell client that this pre-flight info is valid for 20 days + # + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Content-Length' 0; + return 204; + } + if ($request_method = 'GET') { + add_header 'Access-Control-Allow-Origin' '*' always; + add_header 'Access-Control-Allow-Credentials' 'true' always; + add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always; + add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type' always; + } + } + location / { root /usr/share/nginx/html; index index.html; diff --git a/package.json b/package.json index 505e22a..6ba5274 100644 --- a/package.json +++ b/package.json @@ -52,8 +52,8 @@ "test": "craco test", "eject": "react-scripts eject", "source-map-explorer": "source-map-explorer build/static/js/*.js", - "assets-start": "docker run --rm -p 3001:80 --name otterscan-assets -d -v$(pwd)/4bytes/signatures:/usr/share/nginx/html/signatures/ -v$(pwd)/trustwallet/blockchains/ethereum/assets:/usr/share/nginx/html/assets/1 -v$(pwd)/topic0/with_parameter_names:/usr/share/nginx/html/topic0/ -v$(pwd)/nginx/nginx.conf:/etc/nginx/nginx.conf -v$(pwd)/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf nginx:1.21.1-alpine", - "assets-start-with-param-names": "docker run --rm -p 3001:80 --name otterscan-assets -d -v$(pwd)/4bytes/with_parameter_names:/usr/share/nginx/html/signatures/ -v$(pwd)/trustwallet/blockchains/ethereum/assets:/usr/share/nginx/html/assets/1 -v$(pwd)/topic0/with_parameter_names:/usr/share/nginx/html/topic0/ -v$(pwd)/nginx/nginx.conf:/etc/nginx/nginx.conf -v$(pwd)/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf nginx:1.21.1-alpine", + "assets-start": "docker run --rm -p 3001:80 --name otterscan-assets -d -v$(pwd)/4bytes/signatures:/usr/share/nginx/html/signatures/ -v$(pwd)/trustwallet/blockchains/ethereum/assets:/usr/share/nginx/html/assets/1 -v$(pwd)/topic0/with_parameter_names:/usr/share/nginx/html/topic0/ -v$(pwd)/chains/_data/chains:/usr/share/nginx/html/chains/ -v$(pwd)/nginx/nginx.conf:/etc/nginx/nginx.conf -v$(pwd)/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf nginx:1.21.1-alpine", + "assets-start-with-param-names": "docker run --rm -p 3001:80 --name otterscan-assets -d -v$(pwd)/4bytes/with_parameter_names:/usr/share/nginx/html/signatures/ -v$(pwd)/trustwallet/blockchains/ethereum/assets:/usr/share/nginx/html/assets/1 -v$(pwd)/topic0/with_parameter_names:/usr/share/nginx/html/topic0/ -v$(pwd)/chains/_data/chains:/usr/share/nginx/html/chains/ -v$(pwd)/nginx/nginx.conf:/etc/nginx/nginx.conf -v$(pwd)/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf nginx:1.21.1-alpine", "assets-stop": "docker stop otterscan-assets", "docker-build": "DOCKER_BUILDKIT=1 docker build -t otterscan -f Dockerfile .", "docker-start": "docker run --rm -p 5000:80 --name otterscan -d otterscan", diff --git a/src/App.tsx b/src/App.tsx index e9c3f20..81116d7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -7,7 +7,7 @@ import ConnectionErrorPanel from "./ConnectionErrorPanel"; import Footer from "./Footer"; import { ConnectionStatus } from "./types"; import { RuntimeContext, useRuntime } from "./useRuntime"; -import { ChainInfoContext, defaultChainInfo } from "./useChainInfo"; +import { ChainInfoContext, useChainInfoFromMetadataFile } from "./useChainInfo"; const Block = React.lazy( () => import(/* webpackChunkName: "block", webpackPrefetch: true */ "./Block") @@ -41,17 +41,19 @@ const PageNotFound = React.lazy( const App = () => { const runtime = useRuntime(); + const chainInfo = useChainInfoFromMetadataFile(runtime); return ( - {runtime.connStatus !== ConnectionStatus.CONNECTED ? ( + {runtime.connStatus !== ConnectionStatus.CONNECTED || + chainInfo === undefined ? ( ) : ( - +
diff --git a/src/url.ts b/src/url.ts index a67b708..6a7a411 100644 --- a/src/url.ts +++ b/src/url.ts @@ -15,6 +15,11 @@ export const tokenLogoURL = ( address: string ): string => `${assetsURLPrefix}/assets/${chainId}/${address}/logo.png`; +export const chainInfoURL = ( + assetsURLPrefix: string, + chainId: number +): string => `${assetsURLPrefix}/chains/eip155-${chainId}.json`; + export const blockURL = (blockNum: BlockTag) => `/block/${blockNum}`; export const blockTxsURL = (blockNum: BlockTag) => `/block/${blockNum}/txs`; diff --git a/src/useChainInfo.ts b/src/useChainInfo.ts index f1de917..0d494b9 100644 --- a/src/useChainInfo.ts +++ b/src/useChainInfo.ts @@ -1,4 +1,6 @@ -import { createContext, useContext } from "react"; +import { createContext, useContext, useEffect, useState } from "react"; +import { chainInfoURL } from "./url"; +import { OtterscanRuntime } from "./useRuntime"; export type ChainInfo = { nativeName: string; @@ -14,6 +16,40 @@ export const defaultChainInfo: ChainInfo = { export const ChainInfoContext = createContext(undefined); +export const useChainInfoFromMetadataFile = ( + runtime: OtterscanRuntime | undefined +): ChainInfo | undefined => { + const assetsURLPrefix = runtime?.config?.assetsURLPrefix; + const chainId = runtime?.provider?.network.chainId; + + const [chainInfo, setChainInfo] = useState(undefined); + + useEffect(() => { + if (chainId === undefined) { + setChainInfo(undefined); + return; + } + + const readChainInfo = async () => { + 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, + }); + }; + readChainInfo(); + }, [assetsURLPrefix, chainId]); + + return chainInfo; +}; + export const useChainInfo = (): ChainInfo => { const chainInfo = useContext(ChainInfoContext); if (chainInfo === undefined) { From fe7293883594a01fe5ef1d65b2f45f37287ea4fb Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 28 Mar 2022 15:35:51 -0300 Subject: [PATCH 5/5] Add chain info to production docker image --- .dockerignore | 2 ++ Dockerfile | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/.dockerignore b/.dockerignore index 1cf24b2..dcc2b50 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,3 +7,5 @@ trustwallet !trustwallet/blockchains/ethereum/assets !trustwallet/blockchains/polygon/assets !trustwallet/blockchains/smartchain/assets +chains +!chains/_data/chains diff --git a/Dockerfile b/Dockerfile index 15a9a15..49b3209 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,6 +24,10 @@ FROM alpine:3.15.0 AS topic0builder WORKDIR /topic0 COPY topic0/with_parameter_names /topic0/ +FROM alpine:3.15.0 AS chainsbuilder +WORKDIR /chains +COPY chains/_data/chains /chains/ + # Add brotli module to official nginx image # Based on: https://github.com/nginxinc/docker-nginx/tree/master/modules FROM nginx:1.21.3-alpine as nginxbuilder @@ -87,6 +91,7 @@ RUN set -ex \ done \ && rm -rf /tmp/packages RUN apk update && apk add jq +COPY --from=chainsbuilder /chains /usr/share/nginx/html/chains/ COPY --from=topic0builder /topic0 /usr/share/nginx/html/topic0/ COPY --from=fourbytesbuilder /signatures /usr/share/nginx/html/signatures/ COPY --from=logobuilder /assets /usr/share/nginx/html/assets/