fix(lite): keep a rejected import key out of the log and Settings

The backend's error for a key it doesn't recognize repeats the key
("'<key>' was not recognized as either a spending key or a viewing
key"). Import passed that text on as its error, so a mistyped private
key was written to the lite log (shown in the Console tab) and to the
Settings status line. A failed import now carries a fixed reason
(unrecognized format, wallet locked, key already exists, could not be
decoded, or rejected), which is all the log records. Settings shows
"Couldn't import the key — check it, unlock the wallet (if encrypted)
and try again." instead, translated in all eight languages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-09 21:09:48 -05:00
co-authored by Claude Opus 5.5
parent 7c24400c83
commit bb84243114
13 changed files with 69 additions and 6 deletions
+16 -4
View File
@@ -163,7 +163,19 @@ LiteNewAddressResult newAddressCore(LiteClientBridge& bridge, bool shielded)
return out;
}
// `key` must be non-empty; it is wiped before returning.
// The backend's import errors can repeat the key itself (do_import_key: "'<key>' was not recognized as either a
// spending key or a viewing key ..."), so that text is never logged or shown: only a fixed, non-secret reason.
std::string liteImportFailureReason(const std::string& backendError)
{
const auto has = [&backendError](const char* s) { return backendError.find(s) != std::string::npos; };
if (has("was not recognized")) return "unrecognized key format";
if (has("locked")) return "wallet is locked";
if (has("already exists")) return "key already exists";
if (has("decode")) return "key could not be decoded";
return "key rejected by the backend";
}
// `key` must be non-empty; it is wiped before returning. A failure's error is a fixed reason, never backend text.
LiteImportResult importKeyCore(LiteClientBridge& bridge, std::string& key, const std::atomic<bool>* retired = nullptr)
{
// Transparent WIFs begin with U/5/K/L (TImportCommand); shielded keys begin with
@@ -180,13 +192,13 @@ LiteImportResult importKeyCore(LiteClientBridge& bridge, std::string& key, const
LiteImportResult r;
const auto result = bridge.execute(command, key);
if (!result.ok) { // do_import_* failures come back "Error:"-prefixed (bridge -> ok=false)
r.error = result.error.empty() ? "key import failed" : result.error;
r.error = liteImportFailureReason(result.error);
return r;
}
try {
const auto j = nlohmann::json::parse(result.value);
if (j.is_object() && j.contains("error")) {
r.error = extractJsonError(j);
r.error = liteImportFailureReason(extractJsonError(j));
return r;
}
} catch (...) {
@@ -207,7 +219,7 @@ LiteImportResult importKeyCore(LiteClientBridge& bridge, std::string& key, const
LiteImportResult alt = runImport(transparentFirst ? "import" : "timport");
if (alt.ok) out = alt;
}
if (!out.ok) liteLog("Key import failed: " + out.error); // error text only — never the key
if (!out.ok) liteLog("Key import failed: " + out.error); // a fixed reason: the backend's text can repeat the key
secureWipeLiteSecret(key); // wipe our copy after both attempts
return out;
}