Opening the transaction-history cache always derived its encryption key
with Argon2id, even for an unencrypted wallet. For those wallets the
passphrase is just a value derivable from the database itself, so the
~50-100 ms Argon2id stall bought no additional secrecy and ran on the
UI thread at open.
- Unencrypted wallets now derive the cache key with a cheap,
domain-separated BLAKE2b KDF over the wallet identity, keyed by the
per-wallet salt. The secret is derivable from the DB, so this is
security-equivalent for the unencrypted case and avoids the stall.
- Passphrase-encrypted wallets are unchanged: they keep the Argon2id
key derivation. The two paths use separate domain labels, so the
fast-path key and the Argon2id key never collide for the same DB and
salt; a cache written under one cannot be read under the other.
Tests cover the fast-path round-trip and reopen, and assert that an
Argon2id unlock of the same DB produces a different key and fails to
read the fast-path snapshot.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>