import type { ReactNode } from 'react'; import { useAssetsDataProvider } from '@vegaprotocol/assets'; import { ETHERSCAN_TX, useEtherscanLink } from '@vegaprotocol/environment'; import { formatNumber, t, toBigNum } from '@vegaprotocol/react-helpers'; import type { Toast, ToastContent } from '@vegaprotocol/ui-toolkit'; import { ExternalLink, Intent, ProgressBar } from '@vegaprotocol/ui-toolkit'; import { useCallback, useMemo } from 'react'; import compact from 'lodash/compact'; import type { EthStoredTxState } from '@vegaprotocol/web3'; import { EthTxStatus, isEthereumError, TransactionContent, useEthTransactionStore, } from '@vegaprotocol/web3'; const intentMap: { [s in EthTxStatus]: Intent } = { Default: Intent.Primary, Requested: Intent.Warning, Pending: Intent.Warning, Error: Intent.Danger, Complete: Intent.Warning, Confirmed: Intent.Success, }; const isWithdrawTransaction = (tx: EthStoredTxState) => tx.methodName === 'withdraw_asset'; const isDepositTransaction = (tx: EthStoredTxState) => tx.methodName === 'withdraw_asset'; const EthTransactionDetails = ({ tx }: { tx: EthStoredTxState }) => { const { data: assets } = useAssetsDataProvider(); if (!assets) return null; const isWithdraw = isWithdrawTransaction(tx); const isDeposit = isDepositTransaction(tx); let assetInfo: ReactNode; if ((isWithdraw || isDeposit) && tx.args.length > 2 && tx.assetId) { const asset = assets.find((a) => a.id === tx.assetId); if (asset) { let label = ''; if (isWithdraw) label = t('Withdraw'); if (isDeposit) label = t('Deposit'); assetInfo = (
{label}{' '} {formatNumber(toBigNum(tx.args[1], asset.decimals), asset.decimals)}{' '} {asset.symbol}
); } } return ( <> {assetInfo} {tx.status === EthTxStatus.Pending && (
{t('Awaiting confirmations')}{' '} {`(${tx.confirmations}/${tx.requiredConfirmations})`}
)} ); }; type EthTxToastContentProps = { tx: EthStoredTxState; }; const EthTxRequestedToastContent = ({ tx }: EthTxToastContentProps) => { return (

{t('Action required')}

{t( 'Please go to your wallet application and approve or reject the transaction.' )}

); }; const EthTxPendingToastContent = ({ tx }: EthTxToastContentProps) => { return (

{t('Awaiting confirmation')}

{t('Please wait for your transaction to be confirmed')}

); }; const EthTxErrorToastContent = ({ tx }: EthTxToastContentProps) => { let errorMessage = ''; if (isEthereumError(tx.error)) { errorMessage = tx.error.reason; } else if (tx.error instanceof Error) { errorMessage = tx.error.message; } return (

{t('Error occurred')}

{errorMessage}

); }; const EtherscanLink = ({ tx }: EthTxToastContentProps) => { const etherscanLink = useEtherscanLink(); return tx.txHash ? (

{t('View on Etherscan')}

) : null; }; const EthTxConfirmedToastContent = ({ tx }: EthTxToastContentProps) => { return (

{t('Transaction confirmed')}

{t('Your transaction has been confirmed')}

); }; const EthTxCompletedToastContent = ({ tx }: EthTxToastContentProps) => { const isDeposit = isDepositTransaction(tx); return (

{t('Processing')} {isDeposit && 'deposit'}

{t('Your transaction has been completed.')} {isDeposit && t('Waiting for deposit confirmation')}

); }; export const useEthereumTransactionToasts = () => { const ethTransactions = useEthTransactionStore((state) => state.transactions.filter((transaction) => transaction?.dialogOpen) ); const dismissEthTransaction = useEthTransactionStore( (state) => state.dismiss ); const fromEthTransaction = useCallback( (tx: EthStoredTxState): Toast => { let content: ToastContent = ; if (tx.status === EthTxStatus.Requested) { content = ; } if (tx.status === EthTxStatus.Pending) { content = ; } if (tx.status === EthTxStatus.Complete) { content = ; } if (tx.status === EthTxStatus.Confirmed) { content = ; } if (tx.status === EthTxStatus.Error) { content = ; } return { id: `eth-${tx.id}`, intent: intentMap[tx.status], onClose: () => dismissEthTransaction(tx.id), loader: [EthTxStatus.Pending, EthTxStatus.Complete].includes(tx.status), content, }; }, [dismissEthTransaction] ); return useMemo(() => { return [...compact(ethTransactions).map(fromEthTransaction)]; }, [ethTransactions, fromEthTransaction]); };