feat(ui): explain mining addresses everywhere and stop offering them for payment

Follow-up to 5246898. A transparent address only ever receives mining
rewards on DragonX (private chain), so:

- One explainer ("Receives solo-mining rewards only - the network rejects
  payments to it. Rewards are shielded automatically once they mature.")
  on the Overview row hover, the Receive picker hover, the Receive card
  and the Validate Address result (now typed "Mining address
  (transparent)").
- Receive: a selected mining address shows the explainer and a "Use a
  shielded address" button (creates one if none exists) instead of the
  payment request, and a "Not for payments" panel instead of a QR code.
  The default selection prefers a shielded address; the "All" filter
  hides empty mining addresses unless solo mining or marked as a mining
  address; the filter reads All / Shielded / Mining.
- Request Payment: no transparent section, never prefilled with one.
- Overview: no "Mining - Mining" tag on a marked transparent row.
- FAQ: address answers rewritten; the send and memo answers no longer
  imply you can pay a transparent address. All 8 languages.

i18n: 4 new keys, 6 FAQ answers updated in place, 2 dead keys removed,
CJK subset rebuilt. UI sweep: receive-mining-address and
modal-validate-mining targets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-02 20:32:34 -05:00
co-authored by Claude Opus 5.5
parent 5246898968
commit 31d8742ce7
19 changed files with 478 additions and 304 deletions
+6 -20
View File
@@ -6,6 +6,7 @@
#include "../../app.h"
#include "../../util/i18n.h"
#include "../../util/payment_uri.h"
#include "../../util/address_validation.h"
#include "../notifications.h"
#include "../schema/ui_schema.h"
#include "../widgets/qr_code.h"
@@ -47,8 +48,10 @@ void RequestPaymentDialog::show(const std::string& address)
s_label[0] = '\0';
s_uri_dirty = true;
if (!address.empty()) {
// Only a shielded address can be paid (DragonX is a private chain): never prefill a mining address.
if (!address.empty() && !util::isTransparentAddress(address)) {
strncpy(s_address, address.c_str(), sizeof(s_address) - 1);
s_address[sizeof(s_address) - 1] = '\0';
} else {
s_address[0] = '\0';
}
@@ -78,9 +81,6 @@ void RequestPaymentDialog::render(App* app)
auto zAddrLbl = S.label("dialogs.request-payment", "z-addr-label");
auto zAddrFrontLbl = S.label("dialogs.request-payment", "z-addr-front-label");
auto zAddrBackLbl = S.label("dialogs.request-payment", "z-addr-back-label");
auto tAddrLbl = S.label("dialogs.request-payment", "t-addr-label");
auto tAddrFrontLbl = S.label("dialogs.request-payment", "t-addr-front-label");
auto tAddrBackLbl = S.label("dialogs.request-payment", "t-addr-back-label");
auto amountInput = S.input("dialogs.request-payment", "amount-input");
auto memoInput = S.input("dialogs.request-payment", "memo-input");
auto qr = S.drawElement("dialogs.request-payment", "qr-code");
@@ -124,22 +124,8 @@ void RequestPaymentDialog::render(App* app)
}
}
// T-addresses
if (!state.t_addresses.empty()) {
ImGui::TextDisabled("%s", TR("request_transparent_addrs"));
for (size_t i = 0; i < state.t_addresses.size(); i++) {
const auto& addr = state.t_addresses[i];
std::string label = addr.address;
if (label.length() > static_cast<size_t>(tAddrLbl.truncate)) {
label = label.substr(0, tAddrFrontLbl.truncate) + "..." + label.substr(label.length() - tAddrBackLbl.truncate);
}
if (ImGui::Selectable(label.c_str(), addr.address == s_address)) {
strncpy(s_address, addr.address.c_str(), sizeof(s_address) - 1);
s_uri_dirty = true;
}
}
}
// No mining (transparent) addresses: they only receive mining rewards, so a request to one
// could never be paid.
ImGui::EndCombo();
}