fix(test_wallet_backup): keep the mnemonic out of the bloc state - #2562
fix(test_wallet_backup): keep the mnemonic out of the bloc state#2562ethicnology wants to merge 2 commits into
Conversation
The freezed state held the full mnemonic and passphrase, and its generated toString() exposed both in clear text to any state log, crash report or debug session. Secrets now stay ephemeral: screens read them at the point of use through a bloc method that never stores them, the word-order game lives in widget state, and VerifyPhysicalBackupUsecase re-reads the seed to compare, returning only a bool. This also corrects two pre-existing flaws made visible by the rewrite: verification compared against the default mainnet wallet instead of the selected one, and the success screen opened before the verification result was known.
|
@wired-pasteque can you test physical backup flow? |
|
Claude finished @ethicnology's task in 7m 44s —— View job Review of PR #2562 — keep the mnemonic out of the bloc state
The security goal is achieved:
🔴 1.
|
TestWalletBackupState(freezed) held the fullmnemonicandpassphrasein bloc state. Freezed's generatedtoString()included both fields in clear text, so any state log, crash report, or debug session could expose the user's 12/24 words. This violates our two load-bearing rules: secrets are ephemeral (read from secure storage at the point of use, never cached in bloc state) and secrets never reach logs.The rewrite also surfaced two pre-existing correctness flaws:
VerifyPhysicalBackupUsecase(then dead code) always verified against the default mainnet wallet, not the selected one.VerifyMnemonicScreenpushed the success screen before the verification result was known.What changes
TestWalletBackupStateis nowstatusError,wallets,selectedWallet,verificationStatus— the regeneratedtoString()is clean by construction.TestWalletBackupBloc.loadSelectedWalletMnemonic(), a presentation-layer method that forwards the use-case result without storing it. The word-order game lives in ephemeral widget state (rule: local widget state stays inStatefulWidget).VerifyPhysicalBackupUsecase(previously orphaned) is now wired and takes the selected wallet's fingerprint; it compares and returns only abool. Success navigation happens only onverificationStatus.success.testBackupErrorIncorrectOrderl10n key.What it deliberately does not change
import_mnemonic's cubit also holds the mnemonic in state — same class of issue, left for a dedicated PR.'Failed to load wallets: $e') — pre-existing rule-Change address must inherint label of outbound transaction label #11 violation, follow-up.CompletePhysicalBackupVerificationUsecasesemantics are unchanged (still marks default wallets).Alternatives considered
ui → presentation → usecaselayering; the bloc method keeps the chain while never persisting the secret.Reading order
chore: remove orphaned planning documents from the repo root— independent cleanup.fix(test_wallet_backup): keep the mnemonic out of the bloc state— the fix, with its tests.