import type { ExecutionAction, LiFiStepExtended, RouteExtended, } from '@lifi/sdk' import type { ReactNode } from 'react' import { useMemo } from 'react' import { useExplorer } from '../../hooks/useExplorer.js' import { prepareActions } from '../../utils/prepareActions.js' import { SentToWalletRow } from './SentToWalletRow.js' import { StepActionRow } from './StepActionRow.js' /** * A row in an execution list: either a completed/failed action with an explorer * link, or the recipient wallet row appended when a route has a `toAddress`. */ export type ExecutionRow = | { kind: 'action' step: LiFiStepExtended action: ExecutionAction href: string } | { kind: 'wallet'; toAddress: string; toChainId: number } /** * The rows to display for a route: every `DONE`/`FAILED` action that has a * transaction link, plus a wallet row when `toAddress` is set. Shared by the * static step lists and the animated checklist. */ export function useExecutionRows( route: RouteExtended, toAddress?: string ): ExecutionRow[] { const { getTransactionLink } = useExplorer() return useMemo(() => { const rows: ExecutionRow[] = [] for (const step of route.steps) { const groups = prepareActions(step.execution?.actions ?? []) for (const group of groups) { const action = group.at(-1) if (!action) { continue } const isDoneOrFailed = action.status === 'DONE' || action.status === 'FAILED' if (!isDoneOrFailed) { continue } const href = getTransactionLink({ txHash: action.txHash, txLink: action.txLink, chain: action.chainId, }) if (!href) { continue } rows.push({ kind: 'action', step, action, href }) } } if (toAddress) { rows.push({ kind: 'wallet', toAddress, toChainId: route.toChainId }) } return rows }, [route, toAddress, getTransactionLink]) } /** * Renders an {@link ExecutionRow} as the appropriate row component. * Callers are responsible for React keys on the returned node. */ export function renderExecutionRow( row: ExecutionRow, isLast: boolean ): ReactNode { return row.kind === 'action' ? ( ) : ( ) }