chore(environment): etherscan link (#3193)

This commit is contained in:
Art 2023-03-15 09:24:20 +01:00 committed by GitHub
parent 66a85cce2a
commit f407110e95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 91 additions and 125 deletions

View File

@ -21,7 +21,7 @@ import { JsonViewerDialog } from '../../components/dialogs/json-viewer-dialog';
import { PageTitle } from '../../components/page-helpers/page-title';
import BigNumber from 'bignumber.js';
import {
ContractAddressLink,
EtherscanLink,
DApp,
TOKEN_VALIDATOR,
useLinks,
@ -224,7 +224,7 @@ export const ValidatorsPage = () => {
<KeyValueTableRow>
<div>{t('Ethereum address')}</div>
<div className="break-all text-xs">
<ContractAddressLink address={v.ethereumAddress} />{' '}
<EtherscanLink address={v.ethereumAddress} />{' '}
<CopyWithTooltip text={v.ethereumAddress}>
<button title={t('Copy address to clipboard')}>
<Icon size={3} name="duplicate" />

View File

@ -1,7 +1,6 @@
import {
KeyValueTable,
KeyValueTableRow,
Link,
RoundedWrapper,
} from '@vegaprotocol/ui-toolkit';
import { Link as RouterLink } from 'react-router-dom';
@ -11,7 +10,7 @@ import { useParams } from 'react-router';
import { Navigate } from 'react-router-dom';
import { formatNumber } from '@vegaprotocol/utils';
import { useEnvironment } from '@vegaprotocol/environment';
import { EtherscanLink } from '@vegaprotocol/environment';
import { TrancheItem } from '../redemption/tranche-item';
import Routes from '../routes';
import { TrancheLabel } from './tranche-label';
@ -19,7 +18,6 @@ import { useTranches } from '../../lib/tranches/tranches-store';
export const Tranche = () => {
const tranches = useTranches((state) => state.tranches);
const { ETHERSCAN_URL } = useEnvironment();
const { t } = useTranslation();
const { trancheId } = useParams<{ trancheId: string; address: string }>();
const { chainId } = useWeb3React();
@ -59,16 +57,7 @@ export const Tranche = () => {
</KeyValueTableRow>
{tranche.users.map((user) => (
<KeyValueTableRow key={user}>
{
<Link
title={t('View on Etherscan (opens in a new tab)')}
href={`${ETHERSCAN_URL}/address/${user}`}
target="_blank"
>
{user}
</Link>
}
{
<EtherscanLink address={user} data-testid="link" />
<RouterLink
className="underline"
title={t('View vesting information')}
@ -77,7 +66,6 @@ export const Tranche = () => {
>
{t('View vesting information')}
</RouterLink>
}
</KeyValueTableRow>
))}
</KeyValueTable>

View File

@ -1,6 +1,6 @@
import type { ReactNode } from 'react';
import { useAssetsDataProvider } from '@vegaprotocol/assets';
import { ETHERSCAN_TX, useEtherscanLink } from '@vegaprotocol/environment';
import { EtherscanLink } from '@vegaprotocol/environment';
import { formatNumber, toBigNum } from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import type { Toast, ToastContent } from '@vegaprotocol/ui-toolkit';
@ -8,7 +8,7 @@ import { ToastHeading } from '@vegaprotocol/ui-toolkit';
import { Panel } from '@vegaprotocol/ui-toolkit';
import { CLOSE_AFTER } from '@vegaprotocol/ui-toolkit';
import { useToasts } from '@vegaprotocol/ui-toolkit';
import { ExternalLink, Intent, ProgressBar } from '@vegaprotocol/ui-toolkit';
import { Intent, ProgressBar } from '@vegaprotocol/ui-toolkit';
import { useCallback } from 'react';
import compact from 'lodash/compact';
import type { EthStoredTxState } from '@vegaprotocol/web3';
@ -103,7 +103,7 @@ const EthTxPendingToastContent = ({ tx }: EthTxToastContentProps) => {
<>
<ToastHeading>{t('Awaiting confirmation')}</ToastHeading>
<p>{t('Please wait for your transaction to be confirmed.')}</p>
<EtherscanLink tx={tx} />
{tx.txHash && <EtherscanLink tx={tx.txHash} />}
<EthTransactionDetails tx={tx} />
</>
);
@ -126,26 +126,12 @@ const EthTxErrorToastContent = ({ tx }: EthTxToastContentProps) => {
);
};
const EtherscanLink = ({ tx }: EthTxToastContentProps) => {
const etherscanLink = useEtherscanLink();
return tx.txHash ? (
<p className="break-all">
<ExternalLink
href={etherscanLink(ETHERSCAN_TX.replace(':hash', tx.txHash))}
rel="noreferrer"
>
{t('View on Etherscan')}
</ExternalLink>
</p>
) : null;
};
const EthTxConfirmedToastContent = ({ tx }: EthTxToastContentProps) => {
return (
<>
<ToastHeading>{t('Transaction confirmed')}</ToastHeading>
<p>{t('Your transaction has been confirmed.')}</p>
<EtherscanLink tx={tx} />
{tx.txHash && <EtherscanLink tx={tx.txHash} />}
<EthTransactionDetails tx={tx} />
</>
);
@ -162,7 +148,7 @@ const EthTxCompletedToastContent = ({ tx }: EthTxToastContentProps) => {
{t('Your transaction has been completed.')}{' '}
{isDeposit && t('Waiting for deposit confirmation.')}
</p>
<EtherscanLink tx={tx} />
{tx.txHash && <EtherscanLink tx={tx.txHash} />}
<EthTransactionDetails tx={tx} />
</>
);

View File

@ -1,4 +1,4 @@
import { ContractAddressLink } from '@vegaprotocol/environment';
import { EtherscanLink } from '@vegaprotocol/environment';
import { addDecimalsFormatNumber } from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import type * as Schema from '@vegaprotocol/types';
@ -108,7 +108,7 @@ export const rows: Rows = [
return (
<>
<ContractAddressLink address={asset.source.contractAddress} />{' '}
<EtherscanLink address={asset.source.contractAddress} />{' '}
<CopyWithTooltip text={asset.source.contractAddress}>
<button title={t('Copy address to clipboard')}>
<Icon size={3} name="duplicate" />

View File

@ -1,7 +1,7 @@
import type { Asset } from '@vegaprotocol/assets';
import { useEnvironment } from '@vegaprotocol/environment';
import { EtherscanLink } from '@vegaprotocol/environment';
import { t } from '@vegaprotocol/i18n';
import { ExternalLink, Intent, Notification } from '@vegaprotocol/ui-toolkit';
import { Intent, Notification } from '@vegaprotocol/ui-toolkit';
import { formatNumber } from '@vegaprotocol/utils';
import type { EthStoredTxState } from '@vegaprotocol/web3';
import { EthTxStatus, useEthTransactionStore } from '@vegaprotocol/web3';
@ -126,14 +126,10 @@ const ApprovalTxFeedback = ({
selectedAsset: Asset;
allowance?: BigNumber;
}) => {
const { ETHERSCAN_URL } = useEnvironment();
if (!tx) return null;
const txLink = tx.txHash && (
<ExternalLink href={`${ETHERSCAN_URL}/tx/${tx.txHash}`}>
{t('View on Etherscan')}
</ExternalLink>
<EtherscanLink tx={tx.txHash}>{t('View on Etherscan')}</EtherscanLink>
);
if (tx.status === EthTxStatus.Error) {

View File

@ -8,7 +8,6 @@ import {
} from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import type { AgGridReact } from 'ag-grid-react';
import { Link } from '@vegaprotocol/ui-toolkit';
import { AgGridDynamic as AgGrid } from '@vegaprotocol/datagrid';
import type {
VegaICellRendererParams,
@ -16,14 +15,13 @@ import type {
TypedDataAgGrid,
} from '@vegaprotocol/datagrid';
import type { DepositFieldsFragment } from './__generated__/Deposit';
import { useEnvironment } from '@vegaprotocol/environment';
import { EtherscanLink } from '@vegaprotocol/environment';
import { DepositStatusMapping } from '@vegaprotocol/types';
export const DepositsTable = forwardRef<
AgGridReact,
TypedDataAgGrid<DepositFieldsFragment>
>((props, ref) => {
const { ETHERSCAN_URL } = useEnvironment();
return (
<AgGrid
ref={ref}
@ -77,14 +75,9 @@ export const DepositsTable = forwardRef<
if (!data) return null;
if (!value) return '-';
return (
<Link
title={t('View transaction on Etherscan')}
href={`${ETHERSCAN_URL}/tx/${value}`}
data-testid="etherscan-link"
target="_blank"
>
<EtherscanLink tx={value} data-testid="etherscan-link">
{truncateByChars(value)}
</Link>
</EtherscanLink>
);
}}
/>

View File

@ -1,7 +1,7 @@
import type { Asset } from '@vegaprotocol/assets';
import { useEnvironment } from '@vegaprotocol/environment';
import { EtherscanLink } from '@vegaprotocol/environment';
import { t } from '@vegaprotocol/i18n';
import { ExternalLink, Intent, Notification } from '@vegaprotocol/ui-toolkit';
import { Intent, Notification } from '@vegaprotocol/ui-toolkit';
import { EthTxStatus, useEthTransactionStore } from '@vegaprotocol/web3';
import { getFaucetError } from './get-faucet-error';
@ -19,7 +19,6 @@ export const FaucetNotification = ({
selectedAsset,
faucetTxId,
}: FaucetNotificationProps) => {
const { ETHERSCAN_URL } = useEnvironment();
const tx = useEthTransactionStore((state) => {
return state.transactions.find((t) => t?.id === faucetTxId);
});
@ -79,9 +78,9 @@ export const FaucetNotification = ({
</p>
{tx.txHash && (
<p>
<ExternalLink href={`${ETHERSCAN_URL}/tx/${tx.txHash}`}>
<EtherscanLink tx={tx.txHash}>
{t('View on Etherscan')}
</ExternalLink>
</EtherscanLink>
</p>
)}
</>
@ -107,9 +106,9 @@ export const FaucetNotification = ({
</p>
{tx.txHash && (
<p>
<ExternalLink href={`${ETHERSCAN_URL}/tx/${tx.txHash}`}>
<EtherscanLink tx={tx.txHash}>
{t('View on Etherscan')}
</ExternalLink>
</EtherscanLink>
</p>
)}
</>

View File

@ -1,13 +0,0 @@
import { t } from '@vegaprotocol/i18n';
import { Link } from '@vegaprotocol/ui-toolkit';
import { useEtherscanLink } from '../hooks';
export const ContractAddressLink = ({ address }: { address: string }) => {
const etherscanLink = useEtherscanLink();
const href = etherscanLink(`/address/${address}`);
return (
<Link href={href} target="_blank" title={t('View on etherscan')}>
{address}
</Link>
);
};

View File

@ -0,0 +1,38 @@
import { t } from '@vegaprotocol/i18n';
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
import type { ComponentProps } from 'react';
import { ETHERSCAN_ADDRESS, ETHERSCAN_TX, useEtherscanLink } from '../hooks';
export const EtherscanLink = ({
address,
tx,
children,
...props
}: {
address?: string;
tx?: string;
} & ComponentProps<typeof ExternalLink>) => {
const etherscanLink = useEtherscanLink();
let href = '';
if ((!address && !tx) || (address && tx)) {
return null;
}
if (address) {
href = etherscanLink(ETHERSCAN_ADDRESS.replace(':hash', address));
}
if (tx) {
href = etherscanLink(ETHERSCAN_TX.replace(':hash', tx));
}
return (
<ExternalLink
href={href}
title={t('View on Etherscan (opens in a new tab)')}
{...props}
>
{children || address || tx}
</ExternalLink>
);
};

View File

@ -2,4 +2,4 @@ export * from './network-loader';
export * from './network-switcher';
export * from './node-guard';
export * from './node-switcher';
export * from './contract-address-link';
export * from './etherscan-link';

View File

@ -103,6 +103,7 @@ export const TOKEN_VALIDATOR = '/validators/:id';
export const EXPLORER_TX = '/txs/:hash';
// Etherscan pages
export const ETHERSCAN_ADDRESS = '/address/:hash';
export const ETHERSCAN_TX = '/tx/:hash';
// Console pages

View File

@ -1,6 +1,6 @@
import { t } from '@vegaprotocol/i18n';
import { Link } from '@vegaprotocol/ui-toolkit';
import { useEnvironment } from '@vegaprotocol/environment';
import { EtherscanLink, useEnvironment } from '@vegaprotocol/environment';
import { EthTxStatus } from '../use-ethereum-transaction';
const ACTIVE_CLASSES = 'text-black dark:text-white';
@ -62,14 +62,14 @@ export const TxRow = ({
}`}
>
<span>{t('Ethereum transaction complete')}</span>
<Link
href={`${ETHERSCAN_URL}/tx/${txHash}`}
title={t('View on Etherscan')}
{txHash && (
<EtherscanLink
tx={txHash}
className="text-vega-pink dark:text-vega-yellow"
target="_blank"
>
{t('View transaction on Etherscan')}
</Link>
</EtherscanLink>
)}
</p>
);
}

View File

@ -9,14 +9,14 @@ import {
} from '@vegaprotocol/utils';
import { useBottomPlaceholder } from '@vegaprotocol/react-helpers';
import { t } from '@vegaprotocol/i18n';
import { Link, ButtonLink } from '@vegaprotocol/ui-toolkit';
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
import { AgGridDynamic as AgGrid } from '@vegaprotocol/datagrid';
import type {
TypedDataAgGrid,
VegaICellRendererParams,
VegaValueFormatterParams,
} from '@vegaprotocol/datagrid';
import { useEnvironment } from '@vegaprotocol/environment';
import { EtherscanLink } from '@vegaprotocol/environment';
import type { WithdrawalFieldsFragment } from './__generated__/Withdrawal';
import { useEthWithdrawApprovalsStore } from '@vegaprotocol/web3';
import * as Schema from '@vegaprotocol/types';
@ -27,7 +27,6 @@ export const WithdrawalsTable = (
props: TypedDataAgGrid<WithdrawalFieldsFragment>
) => {
const gridRef = useRef<AgGridReact | null>(null);
const { ETHERSCAN_URL } = useEnvironment();
const createWithdrawApproval = useEthWithdrawApprovalsStore(
(store) => store.create
);
@ -66,7 +65,6 @@ export const WithdrawalsTable = (
headerName={t('Recipient')}
field="details.receiverAddress"
cellRenderer="RecipientCell"
cellRendererParams={{ ethUrl: ETHERSCAN_URL }}
valueFormatter={({
value,
data,
@ -126,7 +124,6 @@ export const WithdrawalsTable = (
complete: (withdrawal: WithdrawalFieldsFragment) => {
createWithdrawApproval(withdrawal);
},
ethUrl: ETHERSCAN_URL,
}}
cellRendererSelector={({
data,
@ -160,20 +157,12 @@ export const CompleteCell = ({ data, complete }: CompleteCellProps) => {
export const EtherscanLinkCell = ({
value,
ethUrl,
}: VegaValueFormatterParams<WithdrawalFieldsFragment, 'txHash'> & {
ethUrl: string;
}) => {
}: VegaValueFormatterParams<WithdrawalFieldsFragment, 'txHash'>) => {
if (!value) return '-';
return (
<Link
title={t('View transaction on Etherscan')}
href={`${ethUrl}/tx/${value}`}
data-testid="etherscan-link"
target="_blank"
>
<EtherscanLink tx={value} data-testid="etherscan-link">
{truncateByChars(value)}
</Link>
</EtherscanLink>
);
};
@ -193,28 +182,17 @@ export const StatusCell = ({ data }: { data: WithdrawalFieldsFragment }) => {
return <span>{t('Failed')}</span>;
};
export interface RecipientCellProps
extends VegaICellRendererParams<
WithdrawalFieldsFragment,
'details.receiverAddress'
> {
ethUrl: string;
}
const RecipientCell = ({
ethUrl,
value,
valueFormatted,
}: RecipientCellProps) => {
}: VegaICellRendererParams<
WithdrawalFieldsFragment,
'details.receiverAddress'
>) => {
return (
<Link
title={t('View on Etherscan (opens in a new tab)')}
href={`${ethUrl}/address/${value}`}
data-testid="etherscan-link"
target="_blank"
>
<EtherscanLink address={value} data-testid="etherscan-link">
{valueFormatted}
</Link>
</EtherscanLink>
);
};