Skip to content

Commit 4124936

Browse files
authored
Explorer links (#3313)
* feat: show explorer links on redeem page * refactor * fix urls * remove unnecessary dep
1 parent 3b46858 commit 4124936

File tree

4 files changed

+98
-27
lines changed

4 files changed

+98
-27
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React from 'react';
2+
import Link from '@mui/material/Link';
3+
import ArrowOutwardIcon from '@mui/icons-material/ArrowOutward';
4+
import { makeStyles } from 'tss-react/mui';
5+
6+
const useStyles = makeStyles()((theme) => ({
7+
addressLink: {
8+
display: 'inline-flex',
9+
alignItems: 'center',
10+
overflow: 'hidden',
11+
color: theme.palette.text.primary,
12+
opacity: 0.6,
13+
},
14+
}));
15+
16+
interface ExplorerLinkProps {
17+
url: string;
18+
text: string;
19+
}
20+
21+
const ExplorerLink: React.FC<ExplorerLinkProps> = ({ url, text }) => {
22+
const { classes } = useStyles();
23+
24+
if (!(url && text)) return null;
25+
26+
return (
27+
<Link
28+
onClick={(e) => e.stopPropagation()}
29+
className={classes.addressLink}
30+
href={url}
31+
rel="noreferrer noopener"
32+
target="_blank"
33+
>
34+
{text}
35+
<ArrowOutwardIcon
36+
sx={{
37+
height: '10px',
38+
width: '10px',
39+
marginLeft: '2px',
40+
}}
41+
/>
42+
</Link>
43+
);
44+
};
45+
46+
export default ExplorerLink;

wormhole-connect/src/utils/index.ts

+31-16
Original file line numberDiff line numberDiff line change
@@ -284,25 +284,40 @@ export const isEmptyObject = (value: object | null | undefined) => {
284284
return true;
285285
};
286286

287-
export const getTokenExplorerUrl = (chain: Chain, address: string) => {
288-
const chainConfig = config.chains[chain]!;
289-
let explorerUrl = '';
287+
export type ExplorerPathType = 'wallet' | 'tx' | 'token';
290288

291-
if (chain === 'Sui') {
292-
explorerUrl = `${chainConfig.explorerUrl}coin/${address}`;
293-
} else if (chain === 'Aptos') {
294-
if (isHexString(address)) {
295-
explorerUrl = `${chainConfig.explorerUrl}fungible_asset/${address}`;
296-
} else {
297-
explorerUrl = `${chainConfig.explorerUrl}coin/${address}`;
298-
}
299-
} else {
300-
explorerUrl = `${chainConfig.explorerUrl}address/${address}`;
289+
export const getExplorerUrl = (
290+
chain: Chain,
291+
path: string,
292+
pathType: ExplorerPathType,
293+
) => {
294+
const chainConfig = config.chains[chain]!;
295+
const baseUrl = chainConfig.explorerUrl;
296+
297+
switch (pathType) {
298+
case 'wallet':
299+
return chain === 'Aptos'
300+
? `${baseUrl}account/${path}`
301+
: `${baseUrl}address/${path}`;
302+
case 'tx':
303+
return chain === 'Aptos'
304+
? `${baseUrl}txn/${path}`
305+
: `${baseUrl}tx/${path}`;
306+
default:
307+
switch (chain) {
308+
case 'Sui':
309+
return `${baseUrl}coin/${path}`;
310+
case 'Aptos':
311+
return `${baseUrl}${
312+
isHexString(path) ? 'fungible_asset' : 'coin'
313+
}/${path}`;
314+
case 'Solana':
315+
return `${baseUrl}address/${path}`;
316+
default:
317+
return `${baseUrl}token/${path}`;
318+
}
301319
}
302-
303-
return explorerUrl;
304320
};
305-
306321
// Frankenstein tokens are wormhole-wrapped tokens that are not native to the chain
307322
// and likely have no liquidity.
308323
// An example of a Frankenstein token is wormhole-wrapped Arbitrum WETH on Solana.

wormhole-connect/src/views/v2/Bridge/AssetPicker/TokenItem.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import TokenIcon from 'icons/TokenIcons';
1515
import { Token } from 'config/tokens';
1616

1717
import type { Chain } from '@wormhole-foundation/sdk';
18-
import { chainDisplayName, getTokenExplorerUrl } from 'utils';
18+
import { chainDisplayName, getExplorerUrl } from 'utils';
1919
import ChainIcon from 'icons/ChainIcons';
2020

2121
const useStyles = makeStyles()((theme) => ({
@@ -59,10 +59,10 @@ function TokenItem(props: TokenItemProps) {
5959
const theme = useTheme();
6060

6161
const { chain, token } = props;
62-
// If the token is native to the chain, show the token's address.
63-
// Otherwise, show the wrapped token's address.
6462
const address = token.tokenId?.address.toString();
65-
const explorerURL = address ? getTokenExplorerUrl(chain, address) : undefined;
63+
const explorerURL = address
64+
? getExplorerUrl(chain, address, 'token')
65+
: undefined;
6666
const addressDisplay = `${token.shortAddress}`;
6767

6868
return (

wormhole-connect/src/views/v2/Redeem/TransactionDetails/index.tsx

+17-7
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ import { makeStyles } from 'tss-react/mui';
1313
import config from 'config';
1414
import { RouteContext } from 'contexts/RouteContext';
1515
import AssetBadge from 'components/AssetBadge';
16+
import ExplorerLink from 'components/ExplorerLink';
1617
import {
1718
calculateUSDPrice,
19+
getExplorerUrl,
1820
millisToHumanString,
1921
trimAddress,
20-
trimTxHash,
2122
} from 'utils';
2223
import { getExplorerInfo } from 'utils/sdkv2';
2324
import { amount as sdkAmount } from '@wormhole-foundation/sdk';
@@ -88,6 +89,9 @@ const TransactionDetails = () => {
8889
);
8990

9091
const senderAddress = sender ? trimAddress(sender) : '';
92+
const explorerUrl = sender
93+
? getExplorerUrl(fromChain, sender, 'wallet')
94+
: '';
9195

9296
const formattedAmount = sdkAmount.display(sdkAmount.truncate(amount, 6));
9397

@@ -107,7 +111,7 @@ const TransactionDetails = () => {
107111
{usdAmount ? separator : null}
108112
{sourceChainConfig.displayName}
109113
{separator}
110-
{senderAddress}
114+
<ExplorerLink url={explorerUrl} text={senderAddress} />
111115
</>
112116
)}
113117
</Typography>
@@ -141,6 +145,9 @@ const TransactionDetails = () => {
141145
);
142146

143147
const recipientAddress = recipient ? trimAddress(recipient) : '';
148+
const explorerUrl = recipient
149+
? getExplorerUrl(toChain, recipient, 'wallet')
150+
: '';
144151

145152
const formattedReceiveAmount = receiveAmount
146153
? sdkAmount.display(sdkAmount.truncate(receiveAmount, 6))
@@ -162,7 +169,7 @@ const TransactionDetails = () => {
162169
{usdAmount ? separator : null}
163170
{destChainConfig.displayName}
164171
{separator}
165-
{recipientAddress}
172+
<ExplorerLink url={explorerUrl} text={recipientAddress} />
166173
</>
167174
)}
168175
</Typography>
@@ -335,14 +342,17 @@ const TransactionDetails = () => {
335342
);
336343
}, [eta, theme.palette.text.secondary, toChain]);
337344

345+
const trimmedTx = sendTx ? trimAddress(sendTx) : '';
346+
const explorerUrl = sendTx ? getExplorerUrl(fromChain, sendTx, 'tx') : '';
347+
338348
return (
339349
<div className={classes.container}>
340350
<Card className={classes.card}>
341351
<CardContent>
342-
<Typography
343-
color={theme.palette.text.secondary}
344-
marginBottom="12px"
345-
>{`Transaction #${trimTxHash(sendTx)}`}</Typography>
352+
<Typography color={theme.palette.text.secondary} marginBottom="12px">
353+
{`Transaction #`}
354+
<ExplorerLink url={explorerUrl} text={trimmedTx} />
355+
</Typography>
346356
{sentAmount}
347357
{verticalConnector}
348358
{receivedAmount}

0 commit comments

Comments
 (0)