import { useState } from 'react'; import { Eye, Loader2, TriangleAlert } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { useLockActions } from '../useWalletData'; // Show the recovery phrase again — the one path back to it after creation, and the reason the create-time // modal can say "not without your passphrase" rather than "never". // // Two things live only in this component and nowhere else: the passphrase (cleared the moment the request // settles) and the returned mnemonic (held in local state, dropped when the dialog closes). The mutation // deliberately has no onSuccess cache write, so the phrase never enters React Query. No copy button, for // the same reason as SeedBackupDialog. type ExportSeedDialogProps = { open: boolean; onOpenChange: (open: boolean) => void; walletId: number }; export const ExportSeedDialog = ({ open, onOpenChange, walletId }: ExportSeedDialogProps) => { const { exportSeed } = useLockActions(walletId); // Never persisted: no localStorage, no sessionStorage, no React Query cache, no URL. const [passphrase, setPassphrase] = useState(''); const [revealed, setRevealed] = useState<{ mnemonic: string; hasBip39Passphrase: boolean } | null>(null); const close = () => { setPassphrase(''); setRevealed(null); onOpenChange(false); }; const submit = async (ev: React.FormEvent) => { ev.preventDefault(); if (!passphrase) return; try { setRevealed(await exportSeed.mutateAsync({ passphrase })); } finally { setPassphrase(''); } }; const words = revealed ? revealed.mnemonic.trim().split(/\s+/) : []; return ( (next ? onOpenChange(true) : close())}> {revealed ? ( <> Recovery phrase Anyone who reads these {words.length} words can spend this wallet. Close this as soon as you are done.
    {words.map((word, i) => (
  1. {i + 1} {word}
  2. ))}
{revealed.hasBip39Passphrase && (

This seed also has a BIP39 passphrase. The words alone will not restore the wallet — you need both.

)} ) : (
Show recovery phrase The phrase is decrypted for display only. It is not stored by the browser and nothing is written anywhere on this side.
{/* Controlled input → request body → cleared. Never written to any store. */} setPassphrase(ev.target.value)} />
)}
); };