import type { RouteExtended } from '@lifi/sdk'; import { ExpandLess, ExpandMore, LocalGasStationRounded, } from '@mui/icons-material'; import type { CardProps } from '@mui/material'; import { Box, Collapse, Tooltip, Typography } from '@mui/material'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { formatUnits } from 'viem'; import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'; import { isRouteDone } from '../stores/routes/utils.js'; import { getAccumulatedFeeCostsBreakdown } from '../utils/fees.js'; import { formatTokenAmount, formatTokenPrice } from '../utils/format.js'; import { Card } from './Card/Card.js'; import { CardIconButton } from './Card/CardIconButton.js'; import { FeeBreakdownTooltip } from './FeeBreakdownTooltip.js'; import { IconTypography } from './IconTypography.js'; import { TokenRate } from './TokenRate/TokenRate.js'; import { TON_CHAIN_ID } from '../utils/constants.js'; import { safeBigInt } from '../utils/utils.js'; interface TransactionDetailsProps extends CardProps { route: RouteExtended; } export const TransactionDetails: React.FC = ({ route, ...props }) => { const { t } = useTranslation(); const { feeConfig } = useWidgetConfig(); const [cardExpanded, setCardExpanded] = useState(false); // const toggleCard = () => { // setCardExpanded((cardExpanded) => !cardExpanded); // }; const { gasCosts, feeCosts, gasCostUSD, feeCostUSD, combinedFeesUSD } = getAccumulatedFeeCostsBreakdown(route); const fromTokenAmount = formatTokenAmount( safeBigInt(route?.fromAmount), route?.fromToken?.decimals || 0, ); const fromTokenPrice = formatTokenPrice( fromTokenAmount, route.fromToken.priceUSD, ); const toTokenAmount = formatTokenAmount( safeBigInt(route?.toAmount), route?.toToken?.decimals || 0, ); const toTokenPrice = formatTokenPrice(toTokenAmount, route?.toToken?.priceUSD) || 0.01; const priceImpact = toTokenPrice / fromTokenPrice - 1; const feeCollectionStep = route?.steps?.[0]?.includedSteps?.find( (includedStep) => includedStep.tool === 'feeCollection', ); let formatCombinedFeesUSD = combinedFeesUSD; let formatGasCostUSD = gasCostUSD; let formatFeeCostUSD = feeCostUSD; if (route?.fromChainId === TON_CHAIN_ID) { formatCombinedFeesUSD = combinedFeesUSD / 10; formatGasCostUSD = gasCostUSD / 10; formatFeeCostUSD = feeCostUSD / 10; } let feeAmountUSD: number = 0; if (feeCollectionStep) { const estimatedFromAmount = safeBigInt(feeCollectionStep.estimate.fromAmount) - safeBigInt(feeCollectionStep.estimate.toAmount); const feeAmount = formatUnits( estimatedFromAmount, feeCollectionStep.action.fromToken.decimals, ); feeAmountUSD = parseFloat(feeAmount) * parseFloat(feeCollectionStep.action.fromToken.priceUSD || '0'); } // Move state updates out of render const handleCardToggle = () => { Promise.resolve().then(() => { setCardExpanded(!cardExpanded); }); }; const showIntegratorFeeCollectionDetails = feeAmountUSD || Number.isFinite(feeConfig?.fee); return ( {!!formatCombinedFeesUSD && ( {t(`format.currency`, { value: formatCombinedFeesUSD })} )} {cardExpanded ? ( ) : ( )} {t('main.fees.network')} {t(`format.currency`, { value: formatGasCostUSD, })} {feeCosts.length ? ( {t('main.fees.provider')} {t(`format.currency`, { value: formatFeeCostUSD, })} ) : null} {showIntegratorFeeCollectionDetails ? ( {feeConfig?.name ? t('main.fees.integrator', { tool: feeConfig.name }) : t('main.fees.defaultIntegrator')} {feeConfig?.name ? ( {t(`format.currency`, { value: feeAmountUSD, })} ) : ( {t(`format.currency`, { value: feeAmountUSD, })} )} ) : null} {t('main.priceImpact')} {t('format.percent', { value: priceImpact })} {!isRouteDone(route) ? ( <> {t('main.maxSlippage')} {t('format.percent', { value: route.steps[0].action.slippage, })} {t('main.minReceived')} {t('format.number', { value: formatTokenAmount( safeBigInt(route?.toAmountMin), route?.toToken?.decimals || 0, ), })}{' '} {route?.toToken?.symbol} ) : null} ); };