fix(lite): import-key fallback on mis-routed key + clamp shield fee
- importKey routed transparent vs. shielded purely by the first character, which can mis-route (e.g. testnet/regtest WIFs). On failure, try the other import command before reporting an error (each validates the encoding, so a wrong command rejects rather than mis-imports). The key copy is wiped after both tries. - Clamp the shield dialog's fee input to [0, 1] DRGX, mirroring the UTXO-limit clamp, so a negative or fat-fingered huge fee can't be submitted. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -138,6 +138,8 @@ void ShieldDialog::render(App* app)
|
||||
ImGui::Text("%s", TR("fee_label"));
|
||||
ImGui::SetNextItemWidth(feeInput.width);
|
||||
ImGui::InputDouble("##Fee", &s_fee, 0.0001, 0.001, "%.8f");
|
||||
if (s_fee < 0.0) s_fee = 0.0; // no negative fee
|
||||
if (s_fee > 1.0) s_fee = 1.0; // guard a fat-fingered huge fee (mirrors utxo clamp)
|
||||
ImGui::SameLine();
|
||||
ImGui::TextDisabled("DRGX");
|
||||
|
||||
|
||||
@@ -465,27 +465,40 @@ LiteImportResult LiteWalletController::importKey(std::string spendingOrViewingKe
|
||||
return out;
|
||||
}
|
||||
// Transparent WIFs begin with U/5/K/L (TImportCommand); shielded keys begin with
|
||||
// "secret-..." / viewing keys "zxview...", so this prefix check won't collide.
|
||||
// "secret-..." / viewing keys "zxview...", so this prefix check usually won't collide.
|
||||
const char first = spendingOrViewingKey[0];
|
||||
const bool transparentWif = (first == 'U' || first == '5' || first == 'K' || first == 'L');
|
||||
const auto result = bridge_->execute(transparentWif ? "timport" : "import", spendingOrViewingKey);
|
||||
secureWipeLiteSecret(spendingOrViewingKey); // wipe our copy ASAP
|
||||
const bool transparentFirst = (first == 'U' || first == '5' || first == 'K' || first == 'L');
|
||||
|
||||
if (!result.ok) { // do_import_* failures come back "Error:"-prefixed (bridge -> ok=false)
|
||||
out.error = result.error.empty() ? "key import failed" : result.error;
|
||||
return out;
|
||||
}
|
||||
try {
|
||||
const auto j = nlohmann::json::parse(result.value);
|
||||
if (j.is_object() && j.contains("error")) {
|
||||
out.error = extractJsonError(j);
|
||||
return out;
|
||||
auto runImport = [&](const char* command) -> LiteImportResult {
|
||||
LiteImportResult r;
|
||||
const auto result = bridge_->execute(command, spendingOrViewingKey);
|
||||
if (!result.ok) { // do_import_* failures come back "Error:"-prefixed (bridge -> ok=false)
|
||||
r.error = result.error.empty() ? "key import failed" : result.error;
|
||||
return r;
|
||||
}
|
||||
} catch (...) {
|
||||
// A non-JSON success payload is acceptable; fall through.
|
||||
try {
|
||||
const auto j = nlohmann::json::parse(result.value);
|
||||
if (j.is_object() && j.contains("error")) {
|
||||
r.error = extractJsonError(j);
|
||||
return r;
|
||||
}
|
||||
} catch (...) {
|
||||
// A non-JSON success payload is acceptable; fall through.
|
||||
}
|
||||
r.detail = result.value;
|
||||
r.ok = true;
|
||||
return r;
|
||||
};
|
||||
|
||||
out = runImport(transparentFirst ? "timport" : "import");
|
||||
if (!out.ok) {
|
||||
// The single-char heuristic can mis-route (e.g. testnet/regtest WIFs). Try the other
|
||||
// command before giving up — the wrong command rejects the key (each validates the
|
||||
// encoding), it never imports it as the wrong type.
|
||||
LiteImportResult alt = runImport(transparentFirst ? "import" : "timport");
|
||||
if (alt.ok) out = alt;
|
||||
}
|
||||
out.detail = result.value;
|
||||
out.ok = true;
|
||||
secureWipeLiteSecret(spendingOrViewingKey); // wipe our copy after both attempts
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user