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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user