fix(wallets): don't mislabel a legacy HD wallet as "Seed phrase"

The Wallets modal's "Seed phrase" vs "Legacy" badge came from the offline
wallet.dat probe, which flags hdseed/chdseed/hdchain. But hdchain is present in
BOTH a BIP39-mnemonic wallet AND a legacy HD wallet (DragonX has no separate
mnemonic DB record — the mnemonic is derived from the HD seed), so a legacy HD
wallet was shown as "Seed phrase".

For the ACTIVE wallet the app already knows the truth at runtime via
z_exportmnemonic (wallet_seed_status_). The active row's badge now uses that
authoritative status (activeWalletSeedBadge: seed-phrase / legacy / undecided)
and only falls back to the probe for non-active or not-yet-decided wallets; the
"unknown" seed badge is suppressed once the runtime status is authoritative.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-15 16:02:50 -05:00
parent 928335dd6b
commit 5874142186
2 changed files with 18 additions and 3 deletions

View File

@@ -389,6 +389,14 @@ public:
// True when the current full-node wallet is a legacy, pre-seed-phrase wallet (no BIP39 mnemonic)
// that a capable daemon could migrate — the Migrate-to-seed button glows to nudge the user.
bool isPreSeedWallet() const { return wallet_seed_status_ == WalletSeedStatus::NoMnemonic; }
// Authoritative BIP39-mnemonic status of the ACTIVE wallet, decided at runtime by z_exportmnemonic
// (not the offline file probe, which can't tell an HD-but-no-mnemonic wallet from a seed-phrase one).
// 0 = unknown/undecidable, 1 = has a seed phrase, 2 = legacy (no mnemonic).
int activeWalletSeedBadge() const {
if (wallet_seed_status_ == WalletSeedStatus::HasMnemonic) return 1;
if (wallet_seed_status_ == WalletSeedStatus::NoMnemonic) return 2;
return 0;
}
void showAboutDialog() { show_about_ = true; }
// Legacy tab compat — maps int to NavPage

View File

@@ -288,9 +288,16 @@ public:
// encryption — so absence of a lock never falsely reads as "unencrypted" on a huge wallet.
const ProbeResult pres = probeAt(i); // from the frame-consistent snapshot above
const bool bLock = pres.probed && pres.encrypted;
const bool bSeed = pres.probed && pres.hdSeed;
const bool bLegacy = pres.probed && pres.complete && !pres.hdSeed;
const bool bUnknown = pres.probed && !pres.complete && !pres.encrypted;
// Seed-phrase vs legacy: the offline probe only sees HD records (hdseed/hdchain), which
// are present in BOTH mnemonic and legacy-HD wallets — so it can't tell them apart. For
// the ACTIVE wallet the app knows the truth (z_exportmnemonic → activeWalletSeedBadge);
// prefer that and fall back to the probe only for non-active or not-yet-decided wallets.
const int activeBadge = rowActive[i] ? app->activeWalletSeedBadge() : 0;
const bool bSeed = (activeBadge == 1) || (activeBadge == 0 && pres.probed && pres.hdSeed);
const bool bLegacy = (activeBadge == 2) ||
(activeBadge == 0 && pres.probed && pres.complete && !pres.hdSeed);
// No "unknown" seed badge once the runtime status is authoritative for the active wallet.
const bool bUnknown = (activeBadge == 0) && pres.probed && !pres.complete && !pres.encrypted;
struct Badge { const char* glyph; ImU32 col; const char* label; const char* tip; };
Badge bl[4]; int nb = 0;
if (bSeed) bl[nb++] = { ICON_MD_ECO, WithAlpha(Success(), 235), TR("wallets_badge_seed_short"), TR("wallets_badge_seed") };