import React from 'react' import type { BrowserWalletReady } from '../../wallet/browserWallet.js' import { supportedErc8004ChainForId } from '../../registry/erc8004.js' import { runTokenTransferStorageSubmit, runTokenTransferTargetSubmit, } from './effects.js' import type { EffectCallbacks, TokenTransferProgress, } from '../shared/effects/types.js' import type { Step } from '../reducer.js' import { BusyScreen } from '../shared/components/BusyScreen.js' import { RebackupStorageScreen } from '../continuity/RebackupStorageScreen.js' import { TokenTransferReadyScreen, TokenTransferSigningScreen, TokenTransferTargetScreen, } from './TokenTransferScreens.js' type TokenTransferStep = Extract type TokenTransferFlowProps = { step: TokenTransferStep callbacks: EffectCallbacks footer: React.ReactNode progress: TokenTransferProgress | null walletSession: BrowserWalletReady | null onSetStep: (step: Step) => void onBack: () => void } export function isTokenTransferStep(step: Step): step is TokenTransferStep { return step.kind === 'token-transfer-target' || step.kind === 'token-transfer-resolving' || step.kind === 'token-transfer-storage' || step.kind === 'token-transfer-signing' || step.kind === 'token-transfer-ready' } export const TokenTransferFlow: React.FC = ({ step, callbacks, footer, progress, walletSession, onSetStep, onBack, }) => { const resolveAbortRef = React.useRef(null) const tokenNetworkLabel = networkLabelForChainId(step.registry.chainId) const readyBackHint = tokenTransferBackHint(step.returnTo) if (step.kind === 'token-transfer-target') { return ( { resolveAbortRef.current?.abort() const controller = new AbortController() resolveAbortRef.current = controller try { await runTokenTransferTargetSubmit(value, step, callbacks, { signal: controller.signal }) } catch (err: unknown) { if (controller.signal.aborted) return onSetStep({ ...step, error: (err as Error).message }) } finally { if (resolveAbortRef.current === controller) resolveAbortRef.current = null } }} onBack={onBack} /> ) } if (step.kind === 'token-transfer-resolving') { return ( { resolveAbortRef.current?.abort() resolveAbortRef.current = null onBack() }} /> ) } if (step.kind === 'token-transfer-storage') { return ( { try { await runTokenTransferStorageSubmit(input, step, callbacks) } catch (err: unknown) { onSetStep({ ...step, error: (err as Error).message }) } }} onCancel={onBack} /> ) } if (step.kind === 'token-transfer-signing') { return ( ) } return ( ) } function networkLabelForChainId(chainId: number): string { return supportedErc8004ChainForId(chainId)?.name ?? `Chain ${chainId}` } function tokenTransferBackHint(returnTo: Step | undefined): string { if (returnTo?.kind === 'edit-profile-ens') return 'Return to ENS setup' return 'Return to menu' }