Skip to content

Commit 06257be

Browse files
committed
feat(gas-profiler): make explorer links network-aware and hide mainnet-only tools
- add getEtherscanBaseUrl() to return correct subdomain for hoodi/sepolia - add isMainnet() to decide when to show Tenderly/Phalcon links - replace hard-coded etherscan.io URLs with dynamic ones - hide Tenderly/Phalcon links on non-mainnet networks
1 parent aabf5f8 commit 06257be

File tree

7 files changed

+149
-97
lines changed

7 files changed

+149
-97
lines changed

src/pages/ethereum/execution/gas-profiler/BlockPage.tsx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ import {
4343
} from './components';
4444
import type { ContractInteractionItem, TopGasItem } from './components';
4545
import { useNetwork } from '@/hooks/useNetwork';
46-
import { CATEGORY_COLORS, CALL_TYPE_COLORS, getOpcodeCategory } from './utils';
46+
import { CATEGORY_COLORS, CALL_TYPE_COLORS, getOpcodeCategory, getEtherscanBaseUrl, isMainnet } from './utils';
4747
import type { GasProfilerBlockSearch } from './IndexPage.types';
4848

4949
/**
@@ -943,23 +943,25 @@ export function BlockPage(): JSX.Element {
943943
<div className="flex w-full items-center justify-between gap-2 sm:w-auto sm:justify-start">
944944
<div className="flex items-center gap-2">
945945
<a
946-
href={`https://etherscan.io/block/${blockNumber}`}
946+
href={`${getEtherscanBaseUrl(currentNetwork?.name)}/block/${blockNumber}`}
947947
target="_blank"
948948
rel="noopener noreferrer"
949949
className="rounded-full bg-surface p-1.5 text-muted transition-colors hover:text-foreground"
950950
title="View on Etherscan"
951951
>
952952
<EtherscanIcon className="size-4" />
953953
</a>
954-
<a
955-
href={`https://dashboard.tenderly.co/block/1/${blockNumber}/txs`}
956-
target="_blank"
957-
rel="noopener noreferrer"
958-
className="rounded-full bg-surface p-1.5 transition-colors hover:opacity-80"
959-
title="View on Tenderly"
960-
>
961-
<TenderlyIcon className="size-4" />
962-
</a>
954+
{isMainnet(currentNetwork?.name) && (
955+
<a
956+
href={`https://dashboard.tenderly.co/block/1/${blockNumber}/txs`}
957+
target="_blank"
958+
rel="noopener noreferrer"
959+
className="rounded-full bg-surface p-1.5 transition-colors hover:opacity-80"
960+
title="View on Tenderly"
961+
>
962+
<TenderlyIcon className="size-4" />
963+
</a>
964+
)}
963965
</div>
964966

965967
<div className="hidden h-4 w-px bg-border sm:block" />

src/pages/ethereum/execution/gas-profiler/CallPage.tsx

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ import {
3434
CallTraceView,
3535
ContractStorageCTA,
3636
} from './components';
37-
import { CATEGORY_COLORS, getOpcodeCategory } from './utils';
37+
import { useNetwork } from '@/hooks/useNetwork';
38+
import { CATEGORY_COLORS, getOpcodeCategory, getEtherscanBaseUrl, isMainnet } from './utils';
3839
import type { IntTransactionCallFrame } from '@/api/types.gen';
3940

4041
/**
@@ -83,6 +84,7 @@ export function CallPage(): JSX.Element {
8384
const { block: blockFromSearch } = Route.useSearch();
8485
const callIdNum = parseInt(callId, 10);
8586

87+
const { currentNetwork } = useNetwork();
8688
const [copied, setCopied] = useState(false);
8789

8890
// Fetch all transaction data
@@ -545,7 +547,7 @@ export function CallPage(): JSX.Element {
545547
<div className="flex items-center gap-2">
546548
{currentFrame.target_address && (
547549
<a
548-
href={`https://etherscan.io/address/${currentFrame.target_address}`}
550+
href={`${getEtherscanBaseUrl(currentNetwork?.name)}/address/${currentFrame.target_address}`}
549551
target="_blank"
550552
rel="noopener noreferrer"
551553
className="rounded-full bg-surface p-1.5 text-muted transition-colors hover:text-foreground"
@@ -554,24 +556,28 @@ export function CallPage(): JSX.Element {
554556
<EtherscanIcon className="size-4" />
555557
</a>
556558
)}
557-
<a
558-
href={`https://dashboard.tenderly.co/tx/mainnet/${txHash}`}
559-
target="_blank"
560-
rel="noopener noreferrer"
561-
className="rounded-full bg-surface p-1.5 transition-colors hover:opacity-80"
562-
title="View TX on Tenderly"
563-
>
564-
<TenderlyIcon className="size-4" />
565-
</a>
566-
<a
567-
href={`https://phalcon.blocksec.com/explorer/tx/eth/${txHash}`}
568-
target="_blank"
569-
rel="noopener noreferrer"
570-
className="rounded-full bg-surface p-1.5 text-muted transition-colors hover:text-foreground"
571-
title="View TX on Phalcon"
572-
>
573-
<PhalconIcon className="size-4" />
574-
</a>
559+
{isMainnet(currentNetwork?.name) && (
560+
<>
561+
<a
562+
href={`https://dashboard.tenderly.co/tx/mainnet/${txHash}`}
563+
target="_blank"
564+
rel="noopener noreferrer"
565+
className="rounded-full bg-surface p-1.5 transition-colors hover:opacity-80"
566+
title="View TX on Tenderly"
567+
>
568+
<TenderlyIcon className="size-4" />
569+
</a>
570+
<a
571+
href={`https://phalcon.blocksec.com/explorer/tx/eth/${txHash}`}
572+
target="_blank"
573+
rel="noopener noreferrer"
574+
className="rounded-full bg-surface p-1.5 text-muted transition-colors hover:text-foreground"
575+
title="View TX on Phalcon"
576+
>
577+
<PhalconIcon className="size-4" />
578+
</a>
579+
</>
580+
)}
575581
</div>
576582
</div>
577583

src/pages/ethereum/execution/gas-profiler/TransactionPage.tsx

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,14 @@ import {
3939
import type { TopGasItem, CallFrameData } from './components';
4040
import { getCallLabel } from './hooks/useTransactionGasData';
4141
import { useNetwork } from '@/hooks/useNetwork';
42-
import { CATEGORY_COLORS, CALL_TYPE_COLORS, getOpcodeCategory, getEffectiveGasRefund } from './utils';
42+
import {
43+
CATEGORY_COLORS,
44+
CALL_TYPE_COLORS,
45+
getOpcodeCategory,
46+
getEffectiveGasRefund,
47+
getEtherscanBaseUrl,
48+
isMainnet,
49+
} from './utils';
4350
import type { CallTreeNode, OpcodeStats } from './IndexPage.types';
4451

4552
/**
@@ -725,32 +732,36 @@ export function TransactionPage(): JSX.Element {
725732
)}
726733
<div className="flex items-center gap-2">
727734
<a
728-
href={`https://etherscan.io/tx/${txHash}`}
735+
href={`${getEtherscanBaseUrl(currentNetwork?.name)}/tx/${txHash}`}
729736
target="_blank"
730737
rel="noopener noreferrer"
731738
className="rounded-full bg-surface p-1.5 text-muted transition-colors hover:text-foreground"
732739
title="View on Etherscan"
733740
>
734741
<EtherscanIcon className="size-4" />
735742
</a>
736-
<a
737-
href={`https://dashboard.tenderly.co/tx/mainnet/${txHash}`}
738-
target="_blank"
739-
rel="noopener noreferrer"
740-
className="rounded-full bg-surface p-1.5 transition-colors hover:opacity-80"
741-
title="View on Tenderly"
742-
>
743-
<TenderlyIcon className="size-4" />
744-
</a>
745-
<a
746-
href={`https://phalcon.blocksec.com/explorer/tx/eth/${txHash}`}
747-
target="_blank"
748-
rel="noopener noreferrer"
749-
className="rounded-full bg-surface p-1.5 text-muted transition-colors hover:text-foreground"
750-
title="View on Phalcon"
751-
>
752-
<PhalconIcon className="size-4" />
753-
</a>
743+
{isMainnet(currentNetwork?.name) && (
744+
<>
745+
<a
746+
href={`https://dashboard.tenderly.co/tx/mainnet/${txHash}`}
747+
target="_blank"
748+
rel="noopener noreferrer"
749+
className="rounded-full bg-surface p-1.5 transition-colors hover:opacity-80"
750+
title="View on Tenderly"
751+
>
752+
<TenderlyIcon className="size-4" />
753+
</a>
754+
<a
755+
href={`https://phalcon.blocksec.com/explorer/tx/eth/${txHash}`}
756+
target="_blank"
757+
rel="noopener noreferrer"
758+
className="rounded-full bg-surface p-1.5 text-muted transition-colors hover:text-foreground"
759+
title="View on Phalcon"
760+
>
761+
<PhalconIcon className="size-4" />
762+
</a>
763+
</>
764+
)}
754765
</div>
755766
</div>
756767

src/pages/ethereum/execution/gas-profiler/components/BlockSimulationResultsV2/BlockSimulationResultsV2.tsx

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import { ScrollableTabs } from '@/components/Navigation/ScrollableTabs';
2020
import { EtherscanIcon } from '@/components/Ethereum/EtherscanIcon';
2121
import { TenderlyIcon } from '@/components/Ethereum/TenderlyIcon';
2222
import { PhalconIcon } from '@/components/Ethereum/PhalconIcon';
23+
import { useNetwork } from '@/hooks/useNetwork';
2324
import { getOpcodeCategory, CATEGORY_COLORS } from '../../utils/opcodeUtils';
25+
import { getEtherscanBaseUrl, isMainnet } from '../../utils/explorerLinks';
2426
import type { BlockSimulationResult, TxSummary, OpcodeSummary, CallError } from '../../SimulatePage.types';
2527

2628
// ============================================================================
@@ -606,6 +608,7 @@ function TransactionImpactView({
606608
blockNumber: number;
607609
onEnableMaxGasLimit?: () => void;
608610
}): JSX.Element {
611+
const { currentNetwork } = useNetwork();
609612
const [filter, setFilter] = useState<TxFilter>('all');
610613
const [sortBy, setSortBy] = useState<TxSort>('delta');
611614
const [sortDir, setSortDir] = useState<'asc' | 'desc'>('desc');
@@ -920,32 +923,36 @@ function TransactionImpactView({
920923
</Link>
921924
<div className="ml-auto flex items-center gap-2">
922925
<a
923-
href={`https://etherscan.io/tx/${tx.hash}`}
926+
href={`${getEtherscanBaseUrl(currentNetwork?.name)}/tx/${tx.hash}`}
924927
target="_blank"
925928
rel="noopener noreferrer"
926929
className="rounded-full bg-surface p-1.5 text-muted transition-colors hover:text-foreground"
927930
title="View tx on Etherscan"
928931
>
929932
<EtherscanIcon className="size-4" />
930933
</a>
931-
<a
932-
href={`https://dashboard.tenderly.co/tx/1/${tx.hash}`}
933-
target="_blank"
934-
rel="noopener noreferrer"
935-
className="rounded-full bg-surface p-1.5 transition-colors hover:opacity-80"
936-
title="View tx on Tenderly"
937-
>
938-
<TenderlyIcon className="size-4" />
939-
</a>
940-
<a
941-
href={`https://phalcon.blocksec.com/explorer/tx/eth/${tx.hash}`}
942-
target="_blank"
943-
rel="noopener noreferrer"
944-
className="rounded-full bg-surface p-1.5 text-muted transition-colors hover:text-foreground"
945-
title="View tx on Phalcon"
946-
>
947-
<PhalconIcon className="size-4" />
948-
</a>
934+
{isMainnet(currentNetwork?.name) && (
935+
<>
936+
<a
937+
href={`https://dashboard.tenderly.co/tx/1/${tx.hash}`}
938+
target="_blank"
939+
rel="noopener noreferrer"
940+
className="rounded-full bg-surface p-1.5 transition-colors hover:opacity-80"
941+
title="View tx on Tenderly"
942+
>
943+
<TenderlyIcon className="size-4" />
944+
</a>
945+
<a
946+
href={`https://phalcon.blocksec.com/explorer/tx/eth/${tx.hash}`}
947+
target="_blank"
948+
rel="noopener noreferrer"
949+
className="rounded-full bg-surface p-1.5 text-muted transition-colors hover:text-foreground"
950+
title="View tx on Phalcon"
951+
>
952+
<PhalconIcon className="size-4" />
953+
</a>
954+
</>
955+
)}
949956
</div>
950957
</div>
951958
</div>
@@ -984,6 +991,8 @@ export function BlockSimulationResultsV2({
984991
onEnableMaxGasLimit,
985992
className,
986993
}: BlockSimulationResultsV2Props): JSX.Element {
994+
const { currentNetwork } = useNetwork();
995+
987996
// Overall gas delta
988997
const overallDelta = useMemo(() => {
989998
if (result.original.gasUsed === 0) return 0;
@@ -1080,23 +1089,25 @@ export function BlockSimulationResultsV2({
10801089
</ScrollableTabs>
10811090
<div className="flex items-center gap-2 pb-2">
10821091
<a
1083-
href={`https://etherscan.io/block/${result.blockNumber}`}
1092+
href={`${getEtherscanBaseUrl(currentNetwork?.name)}/block/${result.blockNumber}`}
10841093
target="_blank"
10851094
rel="noopener noreferrer"
10861095
className="rounded-full bg-surface p-1.5 text-muted transition-colors hover:text-foreground"
10871096
title="View block on Etherscan"
10881097
>
10891098
<EtherscanIcon className="size-4" />
10901099
</a>
1091-
<a
1092-
href={`https://dashboard.tenderly.co/block/1/${result.blockNumber}/txs`}
1093-
target="_blank"
1094-
rel="noopener noreferrer"
1095-
className="rounded-full bg-surface p-1.5 transition-colors hover:opacity-80"
1096-
title="View block on Tenderly"
1097-
>
1098-
<TenderlyIcon className="size-4" />
1099-
</a>
1100+
{isMainnet(currentNetwork?.name) && (
1101+
<a
1102+
href={`https://dashboard.tenderly.co/block/1/${result.blockNumber}/txs`}
1103+
target="_blank"
1104+
rel="noopener noreferrer"
1105+
className="rounded-full bg-surface p-1.5 transition-colors hover:opacity-80"
1106+
title="View block on Tenderly"
1107+
>
1108+
<TenderlyIcon className="size-4" />
1109+
</a>
1110+
)}
11001111
</div>
11011112
</div>
11021113

src/pages/ethereum/execution/gas-profiler/components/TransactionRow/TransactionRow.tsx

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { CallTreeSection } from '../CallTreeSection';
99
import { GasBreakdownCard } from '../GasBreakdownCard';
1010
import { OpcodeDistribution } from '../OpcodeDistribution';
1111
import type { CallTreeNode } from '../../IndexPage.types';
12+
import { getEtherscanBaseUrl, isMainnet } from '../../utils';
1213

1314
export interface TransactionRowProps {
1415
/** Transaction summary data */
@@ -174,29 +175,33 @@ export function TransactionRow({
174175
{/* External links */}
175176
<div className="flex gap-2 pt-2">
176177
<a
177-
href={`https://etherscan.io/tx/${transaction.transactionHash}`}
178+
href={`${getEtherscanBaseUrl(network?.name)}/tx/${transaction.transactionHash}`}
178179
target="_blank"
179180
rel="noopener noreferrer"
180181
className="rounded-xs bg-surface px-2 py-1 text-xs text-muted transition-colors hover:text-foreground"
181182
>
182183
Etherscan ↗
183184
</a>
184-
<a
185-
href={`https://dashboard.tenderly.co/tx/mainnet/${transaction.transactionHash}`}
186-
target="_blank"
187-
rel="noopener noreferrer"
188-
className="rounded-xs bg-surface px-2 py-1 text-xs text-muted transition-colors hover:text-foreground"
189-
>
190-
Tenderly ↗
191-
</a>
192-
<a
193-
href={`https://phalcon.blocksec.com/explorer/tx/eth/${transaction.transactionHash}`}
194-
target="_blank"
195-
rel="noopener noreferrer"
196-
className="rounded-xs bg-surface px-2 py-1 text-xs text-muted transition-colors hover:text-foreground"
197-
>
198-
Phalcon ↗
199-
</a>
185+
{isMainnet(network?.name) && (
186+
<>
187+
<a
188+
href={`https://dashboard.tenderly.co/tx/mainnet/${transaction.transactionHash}`}
189+
target="_blank"
190+
rel="noopener noreferrer"
191+
className="rounded-xs bg-surface px-2 py-1 text-xs text-muted transition-colors hover:text-foreground"
192+
>
193+
Tenderly ↗
194+
</a>
195+
<a
196+
href={`https://phalcon.blocksec.com/explorer/tx/eth/${transaction.transactionHash}`}
197+
target="_blank"
198+
rel="noopener noreferrer"
199+
className="rounded-xs bg-surface px-2 py-1 text-xs text-muted transition-colors hover:text-foreground"
200+
>
201+
Phalcon ↗
202+
</a>
203+
</>
204+
)}
200205
</div>
201206
</div>
202207
)}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/** Returns the base Etherscan URL for a given network name. */
2+
export function getEtherscanBaseUrl(networkName?: string | null): string {
3+
switch (networkName) {
4+
case 'hoodi':
5+
return 'https://hoodi.etherscan.io';
6+
case 'sepolia':
7+
return 'https://sepolia.etherscan.io';
8+
default:
9+
return 'https://etherscan.io';
10+
}
11+
}
12+
13+
/** Returns whether Tenderly and Phalcon links should be shown (mainnet only). */
14+
export function isMainnet(networkName?: string | null): boolean {
15+
return !networkName || networkName === 'mainnet';
16+
}

src/pages/ethereum/execution/gas-profiler/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ export {
99
} from './opcodeUtils';
1010
export { addOpcodesToCallTree, isOpcodeNode, type AddOpcodesToCallTreeOptions } from './callTreeWithOpcodes';
1111
export { getEffectiveGasRefund } from './gasRefund';
12+
export { getEtherscanBaseUrl, isMainnet } from './explorerLinks';

0 commit comments

Comments
 (0)