From the app-wide robustness audit (calibrated to the import-key dialog). These are the safety-critical fixes; several could cost users funds: - Backup/export false success (FUND LOSS): exportAllKeys pre-seeded a header, so a keyless result (the usual case when the wallet is encrypted+locked) still looked non-empty and backupWallet wrote a private-key-less file and reported "Backup saved". Now exportAllKeys returns an exported count; backupWallet and the export-all dialog refuse to write / report success on 0 keys, disclose the count, flag partial results as INCOMPLETE, and the backup dialog confirms before overwriting an existing file (+ trims the path). - Bootstrap: fail CLOSED — refuse to install an unverified multi-GB archive when no checksum is published (was `return true`), mirroring the xmrig/daemon updaters. - Restore-from-seed: require a valid BIP39 word count (12/15/18/21/24) with a live "should be 24 words — you have N" hint instead of accepting any non-empty text. - Encryption passphrase: detect leading/trailing whitespace and BLOCK with a warning (not a silent trim, which would change the passphrase and lock the user out). - Receive payment QR: emit the canonical `drgx:` scheme with a URL-encoded memo via a new shared util::buildPaymentUri (the request-payment dialog now routes through it too, so they can't diverge); the old "dragonx:" + raw memo was unparseable by the wallet's own scanner. Also clamps the receive "Recent Received" list to the 4 most recent (companion to the recent-lists commit). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
67 lines
1.8 KiB
C++
67 lines
1.8 KiB
C++
// DragonX Wallet - ImGui Edition
|
|
// Copyright 2024-2026 The Hush Developers
|
|
// Released under the GPLv3
|
|
|
|
#pragma once
|
|
|
|
#include <string>
|
|
|
|
namespace dragonx {
|
|
namespace util {
|
|
|
|
/**
|
|
* @brief Parsed payment URI data
|
|
*/
|
|
struct PaymentURI {
|
|
std::string address;
|
|
double amount = 0.0;
|
|
std::string label;
|
|
std::string memo;
|
|
std::string message;
|
|
bool valid = false;
|
|
std::string error;
|
|
};
|
|
|
|
/**
|
|
* @brief Parse a DragonX/HUSH payment URI
|
|
*
|
|
* Supports format: drgx:<address>?amount=<amount>&label=<label>&memo=<memo>&message=<message>
|
|
* Also supports hush: prefix for backwards compatibility
|
|
*
|
|
* @param uri The payment URI to parse
|
|
* @return PaymentURI struct with parsed data
|
|
*/
|
|
PaymentURI parsePaymentURI(const std::string& uri);
|
|
|
|
/**
|
|
* @brief URL decode a string
|
|
* @param encoded URL-encoded string
|
|
* @return Decoded string
|
|
*/
|
|
std::string urlDecode(const std::string& encoded);
|
|
|
|
/**
|
|
* @brief URL-encode a string (RFC 3986 unreserved kept; ' ' -> %20; others -> %HH).
|
|
*/
|
|
std::string urlEncode(const std::string& value);
|
|
|
|
/**
|
|
* @brief Build a canonical DragonX payment URI: drgx:<address>[?amount=..&label=..&memo=..],
|
|
* with query parameters URL-encoded. amount<=0 and empty label/memo are omitted.
|
|
*
|
|
* Single source of truth so the receive tab and the request-payment dialog can't diverge on the
|
|
* scheme or encoding (the receive tab previously emitted an unparseable "dragonx:" URI with a raw memo).
|
|
*/
|
|
std::string buildPaymentUri(const std::string& address, double amount = 0.0,
|
|
const std::string& label = "", const std::string& memo = "");
|
|
|
|
/**
|
|
* @brief Check if a string is a valid payment URI
|
|
* @param str String to check
|
|
* @return true if it starts with drgx: or hush:
|
|
*/
|
|
bool isPaymentURI(const std::string& str);
|
|
|
|
} // namespace util
|
|
} // namespace dragonx
|