feat(wallets): show "HD wallet" instead of "?" when the seed flag is unreadable

When a row is probed as an HD wallet (has hdseed/hdchain records) but the
mnemonic flag can't be read — e.g. the rare tier-1 byte-scan fallback on an
unusual BDB variant or a >256 MB file — it now shows a neutral "HD wallet"
badge (ICON_MD_ACCOUNT_TREE) rather than a bare "?", which read as alarming.
"Unknown" (?) is reserved for a scan that couldn't even establish it's HD
(incomplete, no HD marker seen). Both still yield to the Lock badge when
encrypted. Seed/legacy/hd/unknown remain mutually exclusive.

Adds wallets_badge_hd / _hd_short strings (EN source + all 8 languages,
additive) and rebuilds the CJK subset font for the new glyphs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-15 16:47:17 -05:00
parent e6c78da062
commit bb5124c1ae
11 changed files with 27 additions and 5 deletions

View File

@@ -301,15 +301,19 @@ public:
}
const bool bSeed = (seed == 1);
const bool bLegacy = (seed == 2);
// Undecided: probed but neither the runtime status nor the on-disk flag could classify it
// (incomplete scan, or an unreadable hdchain value) — show a question mark rather than
// mislabel. Suppressed for encrypted rows, which still carry a definitive Lock badge.
const bool bUnknown = (seed == 0) && pres.probed && !pres.encrypted;
// seed==0 splits by what the probe DID learn: if it saw HD records we know it's an HD
// wallet (we just couldn't read the phrase flag — e.g. the tier-1 byte-scan fallback), so
// label it "HD wallet" rather than a bare "?"; only a scan that couldn't even establish
// that (incomplete, no HD marker yet) stays "Unknown". Both yield to the Lock badge when
// encrypted, so an encrypted-but-unclassified row shows just the lock.
const bool bHd = (seed == 0) && pres.probed && pres.hdSeed && !pres.encrypted;
const bool bUnknown = (seed == 0) && pres.probed && !pres.hdSeed && !pres.encrypted;
struct Badge { const char* glyph; ImU32 col; const char* label; const char* tip; };
Badge bl[4]; int nb = 0;
Badge bl[4]; int nb = 0; // seed/legacy/hd/unknown are mutually exclusive → at most one + lock
if (bSeed) bl[nb++] = { ICON_MD_ECO, WithAlpha(Success(), 235), TR("wallets_badge_seed_short"), TR("wallets_badge_seed") };
if (bLock) bl[nb++] = { ICON_MD_LOCK, WithAlpha(Warning(), 240), TR("wallets_badge_encrypted_short"), TR("wallets_badge_encrypted") };
if (bLegacy) bl[nb++] = { ICON_MD_HISTORY, WithAlpha(OnSurfaceMedium(), 220), TR("wallets_badge_legacy_short"), TR("wallets_badge_legacy") };
if (bHd) bl[nb++] = { ICON_MD_ACCOUNT_TREE, WithAlpha(OnSurfaceMedium(), 210), TR("wallets_badge_hd_short"), TR("wallets_badge_hd") };
if (bUnknown) bl[nb++] = { ICON_MD_HELP_OUTLINE, WithAlpha(OnSurfaceMedium(), 185), TR("wallets_badge_unknown_short"), TR("wallets_badge_unknown") };
const float bGap = Layout::spacingSm();
float maxLabelW = 0.0f;

View File

@@ -276,9 +276,11 @@ void I18n::loadBuiltinEnglish()
strings_["wallets_badge_seed"] = "Seed phrase wallet (HD)";
strings_["wallets_badge_legacy"] = "Legacy wallet (no seed phrase)";
strings_["wallets_badge_unknown"] = "Wallet type not fully determined (large file — open to confirm)";
strings_["wallets_badge_hd"] = "HD wallet — can't confirm a seed phrase without opening it";
strings_["wallets_badge_seed_short"] = "Seed phrase";
strings_["wallets_badge_encrypted_short"] = "Encrypted";
strings_["wallets_badge_legacy_short"] = "Legacy";
strings_["wallets_badge_hd_short"] = "HD wallet";
strings_["wallets_badge_unknown_short"] = "Unknown";
strings_["wallets_open"] = "Open";
strings_["wallets_open_folder"] = "Open folder location";