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::Text("%s", TR("fee_label"));
|
||||||
ImGui::SetNextItemWidth(feeInput.width);
|
ImGui::SetNextItemWidth(feeInput.width);
|
||||||
ImGui::InputDouble("##Fee", &s_fee, 0.0001, 0.001, "%.8f");
|
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::SameLine();
|
||||||
ImGui::TextDisabled("DRGX");
|
ImGui::TextDisabled("DRGX");
|
||||||
|
|
||||||
|
|||||||
@@ -465,27 +465,40 @@ LiteImportResult LiteWalletController::importKey(std::string spendingOrViewingKe
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
// Transparent WIFs begin with U/5/K/L (TImportCommand); shielded keys begin with
|
// 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 char first = spendingOrViewingKey[0];
|
||||||
const bool transparentWif = (first == 'U' || first == '5' || first == 'K' || first == 'L');
|
const bool transparentFirst = (first == 'U' || first == '5' || first == 'K' || first == 'L');
|
||||||
const auto result = bridge_->execute(transparentWif ? "timport" : "import", spendingOrViewingKey);
|
|
||||||
secureWipeLiteSecret(spendingOrViewingKey); // wipe our copy ASAP
|
|
||||||
|
|
||||||
if (!result.ok) { // do_import_* failures come back "Error:"-prefixed (bridge -> ok=false)
|
auto runImport = [&](const char* command) -> LiteImportResult {
|
||||||
out.error = result.error.empty() ? "key import failed" : result.error;
|
LiteImportResult r;
|
||||||
return out;
|
const auto result = bridge_->execute(command, spendingOrViewingKey);
|
||||||
}
|
if (!result.ok) { // do_import_* failures come back "Error:"-prefixed (bridge -> ok=false)
|
||||||
try {
|
r.error = result.error.empty() ? "key import failed" : result.error;
|
||||||
const auto j = nlohmann::json::parse(result.value);
|
return r;
|
||||||
if (j.is_object() && j.contains("error")) {
|
|
||||||
out.error = extractJsonError(j);
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
} catch (...) {
|
try {
|
||||||
// A non-JSON success payload is acceptable; fall through.
|
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;
|
secureWipeLiteSecret(spendingOrViewingKey); // wipe our copy after both attempts
|
||||||
out.ok = true;
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user