Files
ObsidianDragon/src/util/i18n.cpp
DanS 384d64ea5d feat(node): one-click "Restore original wallet" after a daemon auto-recovery
Adds the restore action to the wallet-auto-recovery warning: undo the daemon's
salvage by swapping the untouched original (wallet.<ts>.bak) back over the
salvaged copy and clearing the stale BDB env that triggered the false recovery,
then restarting. Modeled on beginAdoptSeedWallet (stop daemon → file ops →
restart on a worker; result pumped to the main thread for notifications).

Safety (fund-adjacent file ops on a real wallet — copy/rename only, never delete
user data):
- picks the newest wallet.<unixtime>.bak via the pure, unit-tested
  newestWalletSalvageBak(); aborts if none.
- verifies the .bak is a real Berkeley DB (probeWalletFile) before touching
  anything — won't overwrite a working wallet with a bad backup.
- stops the daemon first (stopDaemonForWalletSwitch) so wallet.dat is released.
- moves the salvaged copy aside to wallet.dat.salvaged-<ts>.dat (kept), COPIES
  the .bak into place (the .bak stays), moves database/ aside to
  database.pre-restore-<ts>.bak (kept), and drops only the transient __db.*
  BDB region files. Rolls back the move if the copy fails.
- relaunches the node even on failure so it's never left down.

The warning dialog now offers Restore original wallet / Open data folder /
Keep salvaged copy. Full-node only; lite-safe. Build clean, suite green (1/1).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-10 00:45:47 -05:00

2242 lines
142 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// DragonX Wallet - ImGui Edition
// Copyright 2024-2026 The Hush Developers
// Released under the GPLv3
#include "i18n.h"
#include "platform.h"
#include "../config/version.h" // DRAGONX_DEFAULT_RPC_PORT
#include <fstream>
#include <cstdio>
#include <cstring>
#include <nlohmann/json.hpp>
// Embedded language files
#include "embedded/lang_es.h"
#include "embedded/lang_zh.h"
#include "embedded/lang_ru.h"
#include "embedded/lang_de.h"
#include "embedded/lang_fr.h"
#include "embedded/lang_pt.h"
#include "embedded/lang_ja.h"
#include "embedded/lang_ko.h"
#include "../util/logger.h"
namespace dragonx {
namespace util {
using json = nlohmann::json;
namespace {
// Map a printf conversion char to its varargs argument class: 'i' (int-promoted), 'f'
// (double), 'p' (pointer/string). This is what matters for safety — reading a double slot
// as an int (or vice-versa) is undefined behavior; interchanging d/x is merely cosmetic.
char conversionClass(char c)
{
switch (c) {
case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': case 'c': return 'i';
case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': case 'a': case 'A': return 'f';
case 's': case 'p': return 'p';
default: return '?';
}
}
// Ordered argument signature of a printf-style format string (e.g. "%d / %.0f%%" -> "if").
// "%%" is a literal and contributes nothing.
std::string formatSignature(const std::string& s)
{
std::string sig;
for (size_t i = 0; i < s.size(); ++i) {
if (s[i] != '%') continue;
if (++i >= s.size()) break;
if (s[i] == '%') continue; // literal "%%"
while (i < s.size() && std::strchr("-+ #0123456789.*lhLzjtq", s[i])) ++i;
if (i < s.size()) sig.push_back(conversionClass(s[i]));
}
return sig;
}
} // namespace
I18n::I18n()
{
// Register built-in languages
// CJK glyphs are provided by the merged NotoSansCJK-Subset fallback font.
// Cyrillic glyphs are included in the Ubuntu font glyph ranges.
registerLanguage("en", "English");
registerLanguage("es", "Español");
registerLanguage("zh", "中文");
registerLanguage("ru", "Русский");
registerLanguage("de", "Deutsch");
registerLanguage("fr", "Français");
registerLanguage("pt", "Português");
registerLanguage("ja", "日本語");
registerLanguage("ko", "한국어");
// Load default English strings (built-in fallback)
loadLanguage("en");
}
I18n& I18n::instance()
{
static I18n instance;
return instance;
}
void I18n::overlayTranslations(const nlohmann::json& translations)
{
for (auto& [key, value] : translations.items()) {
if (!value.is_string()) continue;
const std::string translated = value.get<std::string>();
// If the English base for this key carries printf specifiers, the translation must
// keep the same argument signature — otherwise it would be passed to printf/ImGui
// with mismatched varargs (UB). On mismatch, keep the safe English string.
const auto base = strings_.find(key);
if (base != strings_.end()) {
const std::string baseSig = formatSignature(base->second);
if (!baseSig.empty() && baseSig != formatSignature(translated)) {
DEBUG_LOGF("i18n: dropping '%s' — format mismatch (\"%s\" vs English)\n",
key.c_str(), translated.c_str());
continue;
}
}
strings_[key] = translated;
}
}
bool I18n::loadLanguage(const std::string& locale)
{
// Try to load from file: CWD-relative first, then exe-relative
std::string rel_path = "res/lang/" + locale + ".json";
std::string exe_path = Platform::getExecutableDirectory() + "/" + rel_path;
// Try both paths; prefer whichever opens successfully
for (const auto& lang_file : { rel_path, exe_path }) {
std::ifstream file(lang_file);
if (!file.is_open()) continue;
try {
json j;
file >> j;
// Load English built-in as fallback base for non-English
if (locale != "en") {
loadBuiltinEnglish();
} else {
strings_.clear();
}
overlayTranslations(j);
current_locale_ = locale;
DEBUG_LOGF("Loaded language file: %s (%zu strings)\n", lang_file.c_str(), strings_.size());
return true;
} catch (const std::exception& e) {
DEBUG_LOGF("Error parsing language file %s: %s\n", lang_file.c_str(), e.what());
}
}
// Try embedded language data
const unsigned char* embedded_data = nullptr;
unsigned int embedded_size = 0;
if (locale == "es") {
embedded_data = res_lang_es_json;
embedded_size = res_lang_es_json_len;
} else if (locale == "zh") {
embedded_data = res_lang_zh_json;
embedded_size = res_lang_zh_json_len;
} else if (locale == "ru") {
embedded_data = res_lang_ru_json;
embedded_size = res_lang_ru_json_len;
} else if (locale == "de") {
embedded_data = res_lang_de_json;
embedded_size = res_lang_de_json_len;
} else if (locale == "fr") {
embedded_data = res_lang_fr_json;
embedded_size = res_lang_fr_json_len;
} else if (locale == "pt") {
embedded_data = res_lang_pt_json;
embedded_size = res_lang_pt_json_len;
} else if (locale == "ja") {
embedded_data = res_lang_ja_json;
embedded_size = res_lang_ja_json_len;
} else if (locale == "ko") {
embedded_data = res_lang_ko_json;
embedded_size = res_lang_ko_json_len;
}
if (embedded_data != nullptr && embedded_size > 0) {
try {
std::string json_str(reinterpret_cast<const char*>(embedded_data), embedded_size);
json j = json::parse(json_str);
// Load English built-in as fallback base for non-English
if (locale != "en") {
loadBuiltinEnglish();
} else {
strings_.clear();
}
overlayTranslations(j);
current_locale_ = locale;
DEBUG_LOGF("Loaded embedded language: %s (%zu strings)\n", locale.c_str(), strings_.size());
return true;
} catch (const std::exception& e) {
DEBUG_LOGF("Error parsing embedded language %s: %s\n", locale.c_str(), e.what());
}
}
// If English, use built-in strings
if (locale == "en") {
loadBuiltinEnglish();
current_locale_ = "en";
return true;
}
return false;
}
void I18n::loadBuiltinEnglish()
{
strings_.clear();
// Navigation & Tabs
strings_["overview"] = "Overview";
strings_["balance"] = "Balance";
strings_["send"] = "Send";
strings_["receive"] = "Receive";
strings_["transactions"] = "Transactions";
strings_["history"] = "History";
strings_["contacts"] = "Contacts";
strings_["chat"] = "Chat";
strings_["chat_locked_hint"] = "Unlock your wallet to load your chats.";
strings_["chat_empty_hint"] = "No conversations yet. Messages you receive will appear here.";
strings_["chat_you"] = "You";
strings_["chat_contact_request"] = "contact request";
strings_["chat_send_failed"] = "not sent";
strings_["chat_new_button"] = "New chat";
strings_["chat_select_hint"] = "Select a conversation to view it.";
strings_["chat_waiting_reply"] = "Waiting for this contact to reply — you can message them once they do.";
strings_["chat_send"] = "Send";
strings_["chat_new_title"] = "New chat";
strings_["chat_new_zaddr"] = "Recipient z-address";
strings_["chat_new_message"] = "Message";
strings_["chat_new_send"] = "Send request";
strings_["chat_cancel"] = "Cancel";
strings_["chat_add_contact"] = "Add contact";
strings_["chat_contact_added"] = "Contact added — rename it in Contacts";
strings_["chat_new_message_toast"] = "New encrypted chat message";
strings_["chat_toast_not_connected"] = "Not connected — chat message not sent.";
strings_["chat_toast_no_zaddr"] = "No z-address available to send chat from.";
strings_["chat_toast_lite_busy"] = "A send is already in progress, or no wallet is open.";
strings_["chat_toast_waiting_reply"] = "Waiting for the contact to reply before you can message them.";
strings_["chat_toast_compose_failed"] = "Could not compose the message (too long?).";
strings_["chat_toast_request_compose_failed"] = "Could not compose the contact request (invalid address / text?).";
strings_["chat_toast_request_queued"] = "Contact request queued.";
strings_["chat_toast_need_funds"] = "Need a small shielded balance to send chat (to cover the fee).";
strings_["chat_sending"] = "sending\xE2\x80\xA6";
strings_["chat_time_now"] = "now";
strings_["chat_retry"] = "Retry";
strings_["chat_jump_latest"] = "Latest";
strings_["chat_empty_title"] = "No conversations yet";
strings_["chat_empty_start"] = "Start one with \"New conversation\".";
strings_["chat_search"] = "Search conversations";
strings_["chat_no_matches"] = "No conversations match your search.";
strings_["chat_export"] = "Export chat\xE2\x80\xA6";
strings_["chat_export_warn"] = "Saves the decrypted messages as plain text. Store the file securely.";
strings_["chat_export_done"] = "Conversation exported";
strings_["chat_export_failed"] = "Could not write the export file.";
strings_["chat_len_over"] = "Message too long";
strings_["chat_mute"] = "Mute";
strings_["chat_unmute"] = "Unmute";
strings_["chat_hide"] = "Hide";
strings_["chat_unhide"] = "Unhide";
strings_["chat_show_hidden"] = "Show hidden";
strings_["chat_emoji_search"] = "Search emoji";
strings_["chat_hide_hidden"] = "Hide hidden";
strings_["chat_hidden_toast"] = "Conversation hidden — a new message brings it back";
strings_["chat_pick_contact"] = "Choose from contacts\xE2\x80\xA6";
strings_["chat_no_z_contacts"] = "No shielded-address contacts yet";
strings_["chat_copy_address_tip"] = "Click to copy address";
strings_["chat_verify_key"] = "Identity key \xE2\x80\x94 compare to verify";
strings_["chat_awaiting_key"] = "Waiting for reply";
strings_["chat_rename"] = "Rename contact";
strings_["chat_rename_hint"] = "Contact name";
strings_["chat_renamed"] = "Contact renamed";
// Chat note-buffer status (status bar, while the Chat tab is active). %d are counts;
// keep the format specifiers intact in translations.
strings_["chat_buffer_sending_one"] = "Chat: sending %d message\xE2\x80\xA6";
strings_["chat_buffer_sending"] = "Chat: sending %d messages\xE2\x80\xA6";
strings_["chat_buffer_preparing"] = "Chat buffer: preparing %d/%d\xE2\x80\xA6";
strings_["chat_buffer_loading"] = "Chat buffer: \xE2\x80\xA6";
strings_["chat_buffer_ready"] = "Chat buffer: %d/%d ready";
// Chat customization (gear modal + Settings → Chat & Contacts)
strings_["chat_settings_title"] = "Chat settings";
strings_["chat_settings_tip"] = "Chat customization";
strings_["chat_settings_section"] = "CHAT & CONTACTS";
strings_["chat_opt_emoji"] = "Emoji style";
strings_["chat_emoji_mono"] = "Monochrome";
strings_["chat_emoji_color"] = "Color";
strings_["chat_opt_poll"] = "Message poll rate";
strings_["chat_opt_bubble_style"] = "Bubble style";
strings_["chat_bubble_rounded"] = "Rounded";
strings_["chat_bubble_square"] = "Square";
strings_["chat_bubble_minimal"] = "Minimal";
strings_["chat_opt_bubble_accent"] = "Bubble color";
strings_["chat_accent_theme"] = "Theme";
strings_["chat_accent_blue"] = "Blue";
strings_["chat_accent_green"] = "Green";
strings_["chat_accent_purple"] = "Purple";
strings_["chat_accent_amber"] = "Amber";
strings_["chat_accent_pink"] = "Pink";
strings_["chat_opt_density"] = "Message density";
strings_["chat_density_comfortable"] = "Comfortable";
strings_["chat_density_compact"] = "Compact";
strings_["chat_opt_font_size"] = "Text size";
strings_["chat_opt_timestamp"] = "Timestamps";
strings_["chat_ts_global"] = "Follow global";
strings_["chat_ts_24h"] = "24-hour";
strings_["chat_ts_12h"] = "12-hour";
strings_["chat_opt_enter_sends"] = "Enter sends message";
strings_["chat_opt_global_clock"] = "Global clock format";
strings_["chat_settings_done"] = "Done";
strings_["chat_ts_global_short"] = "Global";
strings_["chat_sec_appearance"] = "APPEARANCE";
strings_["chat_sec_messaging"] = "MESSAGING";
strings_["chat_today"] = "Today";
strings_["chat_yesterday"] = "Yesterday";
// Seed-phrase backup (full-node)
strings_["seed_backup_button"] = "Seed phrase";
strings_["tt_seed_backup"] = "Show and back up your wallet's 24-word recovery seed phrase";
strings_["seed_backup_title"] = "Back up seed phrase";
strings_["seed_backup_intro"] = "These words are the master backup of your wallet. Anyone who has them controls your funds.";
strings_["seed_backup_warning"] = "Write them down in order, store them offline, and never share or photograph them. If you lose them, your funds cannot be recovered.";
strings_["seed_backup_loading"] = "Loading your seed phrase…";
strings_["seed_backup_locked"] = "Unlock your wallet to reveal its seed phrase.";
strings_["seed_backup_none"] = "This wallet predates seed phrases, so it has no 24-word phrase. Back it up with \"Backup wallet\" or by exporting your private keys instead.";
strings_["seed_backup_load_failed"] = "Could not load the seed phrase.";
strings_["seed_backup_copy"] = "Copy";
strings_["seed_backup_save"] = "Save to file…";
strings_["seed_backup_saved"] = "Saved an UNENCRYPTED seed file — move it to secure offline storage and delete this copy: ";
strings_["seed_backup_save_failed"] = "Could not write ";
strings_["seed_backup_close"] = "Close";
strings_["seed_backup_reminder"] = "Your wallet has a 24-word recovery seed phrase. Back it up now in Settings → Node & Security.";
strings_["seed_migrate_button"] = "Migrate to seed…";
// Multi-wallet: wallet-files list + switcher
strings_["wallets_button"] = "Wallets…";
strings_["tt_wallets_button"] = "List your wallet files and switch between them";
strings_["wallets_title"] = "Wallets";
strings_["wallets_intro"] = "Wallet files in your data directory (and any folders you add). Open one to switch — the node restarts to load it, and each wallet keeps its own data.";
strings_["wallets_col_name"] = "Wallet";
strings_["wallets_col_size"] = "Size";
strings_["wallets_col_addresses"] = "Addresses";
strings_["wallets_col_txs"] = "txs";
strings_["wallets_col_keys"] = "keys";
strings_["wallets_created"] = "created";
strings_["wallets_sort_by"] = "Sort:";
strings_["wallets_sort_created"] = "Created";
strings_["wallets_sort_addresses"] = "Addresses";
strings_["wallets_sort_txs"] = "Txs";
strings_["wallets_sort_size"] = "Size";
strings_["wallets_sort_asc"] = "Ascending (oldest / fewest / smallest first)";
strings_["wallets_sort_desc"] = "Descending (newest / most / largest first)";
strings_["wallets_col_balance"] = "Balance";
strings_["wallets_col_opened"] = "Last opened";
strings_["wallets_current"] = "current";
strings_["wallets_active"] = "Active";
strings_["wallets_badge_encrypted"] = "Encrypted (passphrase-protected)";
strings_["wallets_badge_seed"] = "Seed phrase wallet (HD)";
strings_["wallets_badge_legacy"] = "Legacy wallet (no seed phrase)";
strings_["wallets_badge_unknown"] = "Wallet type not fully determined (large file — open to confirm)";
strings_["wallets_badge_hd"] = "HD wallet — can't confirm a seed phrase without opening it";
strings_["wallets_badge_seed_short"] = "Seed phrase";
strings_["wallets_badge_encrypted_short"] = "Encrypted";
strings_["wallets_badge_legacy_short"] = "Legacy";
strings_["wallets_badge_hd_short"] = "HD wallet";
strings_["wallets_badge_unknown_short"] = "Unknown";
strings_["wallets_open"] = "Open";
strings_["wallets_open_folder"] = "Open folder location";
strings_["wallets_open_inplace_tt"] = "Open this wallet where it is — linked into the data directory (no copy)";
strings_["wallets_open_failed"] = "Couldn't open this wallet in place. It's likely on a different drive than your data directory — move it onto the same drive (on Windows, enabling Developer Mode also lets it link across drives).";
strings_["wallets_never"] = "Never opened";
strings_["wallets_external_tt"] = "Outside your data directory \xE2\x80\x94 Open links it in place (no copy).";
strings_["wallets_scan_folder"] = "Scan another folder for wallets\xE2\x80\xA6";
strings_["wallets_scanned_folders"] = "Scanned folders:";
strings_["wallets_remove_folder"] = "Stop scanning this folder";
strings_["wallets_empty_hint"] = "Scan a folder to find more wallets";
strings_["wallets_folder_invalid"] = "That folder doesn't exist.";
strings_["wallets_new_label"] = "Create a new wallet:";
strings_["wallets_new_hint"] = "Name (e.g. savings)";
strings_["wallets_create"] = "Create wallet";
strings_["wallets_name_invalid"] = "Please enter a valid wallet name.";
strings_["wallets_exists"] = "A wallet with that name already exists.";
strings_["wallets_creating"] = "Creating wallet — the node will restart…";
strings_["wallets_reveal"] = "Reveal folder";
// In-app folder picker (Scan another folder)
strings_["picker_title"] = "Select a folder to scan";
strings_["picker_up"] = "Up one level";
strings_["picker_home"] = "Home folder";
strings_["picker_empty"] = "This folder has no sub-folders or wallet files.";
strings_["picker_dat_count"] = "%d wallet file(s) in this folder";
strings_["picker_dat_none"] = "No wallet files directly in this folder";
strings_["picker_select"] = "Scan this folder";
// In-app image picker (contact avatars)
strings_["img_picker_title"] = "Choose an image";
strings_["img_picker_pictures"] = "Pictures folder";
strings_["img_picker_empty"] = "This folder has no sub-folders or images.";
strings_["img_picker_none"] = "No images in this folder";
strings_["img_picker_count"] = "%d image(s) in this folder";
strings_["img_picker_use"] = "Use image";
strings_["tt_seed_migrate"] = "Create a new seed-phrase wallet and move your funds into it";
// Migrate-to-seed modal
strings_["mig_title"] = "Migrate to a seed wallet";
strings_["mig_intro"] = "This creates a brand-new wallet backed by a 24-word seed phrase, in an isolated node, so you can move your funds into it. Your current wallet is NOT touched and NO funds move in this step — you'll back up the new seed first, then sweep your funds into it as a separate, confirmed step.";
strings_["mig_create"] = "Create seed wallet";
// Intro pre-flight (checking the current wallet before offering to migrate)
strings_["mig_precheck_checking"] = "Checking your wallet";
strings_["mig_already_mnemonic"] = "Your wallet already has a 24-word seed phrase — there's nothing to migrate. Just back it up and keep the words somewhere safe.";
strings_["mig_backup_instead"] = "Back up seed phrase";
strings_["mig_daemon_too_old"] = "Your DragonX node is too old to create a seed wallet — it lacks the mnemonic support this needs. Update the node (Settings → NODE & SECURITY → Install bundled, or Check for updates), then try again.";
strings_["mig_not_connected"] = "Connect to your node first, then reopen this to migrate.";
strings_["mig_unlock_to_migrate"] = "Unlock your wallet first, then reopen this to migrate.";
strings_["mig_check_failed"] = "Couldn't check your wallet. Make sure it's unlocked and connected, then re-check.";
strings_["mig_recheck"] = "Re-check";
// Sweep step: balance still loading / no funds to move
strings_["mig_checking_balance"] = "Checking your balance";
strings_["mig_no_funds"] = "Your wallet has no funds to migrate. You can adopt the new seed wallet directly — it replaces your current (empty) wallet with the seed-backed one. Your old wallet is still moved aside to a timestamped backup, just in case.";
strings_["mig_adopt_now"] = "Adopt seed wallet";
strings_["mig_nofunds_confirm"] = "I understand this replaces my current wallet with the new seed wallet";
// Adopting step note (shown under the spinner while the node restarts + rescans)
strings_["mig_adopting_note"] = "The node is restarting on your new wallet and will rescan the chain — this can take several minutes. Leave the wallet running; it reconnects automatically.";
strings_["mig_working"] = "Creating your new seed wallet in an isolated node — this can take a minute. Your main wallet keeps running.";
strings_["mig_seed_warning"] = "Write these 24 words down in order and store them offline. They are the only backup of your new wallet — if you lose them, the funds you migrate are gone forever.";
strings_["mig_receive_addr"] = "New wallet receive address:";
strings_["mig_copy_seed"] = "Copy seed";
strings_["mig_backed_up"] = "I've written down my seed phrase";
strings_["mig_step1_done"] = "Step 1 of 2 complete — your funds have NOT moved yet. Sweeping them into this new wallet is the next step.";
strings_["mig_continue_sweep"] = "Continue to sweep";
strings_["mig_discard"] = "Discard migration";
strings_["mig_sweep_intro"] = "Now sweep all funds from your current wallet into the new seed wallet. This sends a single transaction to the new wallet's address; your seed phrase (already backed up) controls the funds from here on.";
strings_["mig_balance"] = "Current wallet balance: %.8f DRGX (minus a small fee)";
strings_["mig_to"] = "To: ";
strings_["mig_unlock_first"] = "Unlock your wallet first to spend from it.";
strings_["mig_sweep_all"] = "Sweep all funds";
strings_["mig_later"] = "Later";
strings_["mig_sweeping"] = "Sweeping your funds into the new wallet…";
strings_["mig_confirming"] = "Waiting for the sweep to confirm on-chain before switching wallets — this guarantees your funds have actually moved.";
strings_["mig_confs"] = "Sweep confirmations: %d";
strings_["mig_txid"] = "txid: ";
strings_["mig_remaining"] = "Remaining in old wallet: %.8f DRGX";
strings_["mig_adopt"] = "Make this my wallet";
strings_["mig_remainder"] = "Some funds are still in your old wallet (too many inputs for one transaction) — sweep the remainder before switching.";
strings_["mig_sweep_remaining"] = "Sweep remaining";
strings_["mig_waiting_mine"] = "Waiting for the sweep transaction to be mined…";
strings_["mig_adopting"] = "Installing your new wallet and rescanning…";
strings_["mig_done"] = "Migration complete. Your wallet is now backed by your seed phrase.";
strings_["mig_done_detail"] = "The daemon is rescanning to show your funds — this can take a few minutes. Your previous wallet was saved as a .bak in the data folder.";
strings_["mig_done_btn"] = "Done";
strings_["contacts_search_placeholder"] = "Search contacts...";
strings_["contacts_settings_title"] = "Contacts settings";
strings_["contacts_settings_tip"] = "Contacts customization";
strings_["contacts_avatar_shape"] = "Avatar shape";
strings_["contacts_shape_circle"] = "Circle";
strings_["contacts_shape_square"] = "Square";
strings_["contacts_shape_tab"] = "Left tab";
strings_["contacts_list_scale"] = "List scale";
strings_["contacts_search_no_match"] = "No matching contacts";
strings_["address_book_confirm_delete"] = "Confirm delete?";
strings_["mining"] = "Mining";
strings_["peers"] = "Peers";
strings_["market"] = "Market";
strings_["settings"] = "Settings";
strings_["console"] = "Console";
strings_["tools"] = "TOOLS";
strings_["advanced"] = "ADVANCED";
// Settings sections
strings_["appearance"] = "APPEARANCE";
strings_["theme_language"] = "THEME & LANGUAGE";
strings_["advanced_effects"] = "Advanced Effects...";
strings_["tools_actions"] = "Tools & Actions...";
strings_["wallet"] = "WALLET";
strings_["node_security"] = "NODE & SECURITY";
strings_["node"] = "NODE";
strings_["security"] = "SECURITY";
strings_["explorer_section"] = "EXPLORER";
strings_["about"] = "About";
strings_["backup_data"] = "BACKUP & DATA";
strings_["balance_layout"] = "Balance Layout";
strings_["low_spec_mode"] = "Low-spec mode";
strings_["simple_background"] = "Simple background";
strings_["console_scanline"] = "Console scanline";
strings_["theme_effects"] = "Theme effects";
strings_["animate_avatars"] = "Animate avatars";
strings_["acrylic"] = "Acrylic";
strings_["noise"] = "Noise";
strings_["ui_opacity"] = "UI Opacity";
strings_["window_opacity"] = "Window Opacity";
strings_["font_scale"] = "Font Scale";
strings_["refresh"] = "Refresh";
strings_["website"] = "Website";
strings_["report_bug"] = "Report Bug";
strings_["save_settings"] = "Save Settings";
strings_["reset_to_defaults"] = "Reset to Defaults";
// Wallet settings
strings_["save_z_transactions"] = "Save shielded tx history";
strings_["auto_shield"] = "Auto-shield";
strings_["use_tor"] = "Use Tor";
strings_["keep_daemon"] = "Keep daemon running";
strings_["stop_external"] = "Stop external daemon";
strings_["verbose_logging"] = "Verbose logging";
strings_["screenshot_sweep"] = "Run screenshot sweep";
strings_["screenshot_sweep_full"] = "Full UI sweep";
strings_["screenshot_open_dir"] = "Open location";
strings_["screenshot_sweep_desc"] = "Cycles every theme across every tab and saves a screenshot of each into per-tab subfolders under the config directory's screenshots folder (overwriting the previous sweep). Runs for a few seconds.";
strings_["mine_when_idle"] = "Mine when idle";
strings_["setup_wizard"] = "Run Setup Wizard...";
// RPC / Explorer settings
strings_["rpc_connection"] = "RPC Connection...";
strings_["rpc_host"] = "Host";
strings_["rpc_port"] = "Port";
strings_["rpc_user"] = "Username";
strings_["rpc_pass"] = "Password";
strings_["transaction_url"] = "Transaction URL";
strings_["address_url"] = "Address URL";
strings_["custom_fees"] = "Allow custom transaction fees";
strings_["fetch_prices"] = "Fetch price data from CoinGecko";
strings_["block_explorer"] = "Block Explorer";
strings_["test_connection"] = "Test Connection";
strings_["rescan"] = "Rescan Blockchain";
// Settings: buttons
strings_["settings_address_book"] = "Address Book...";
strings_["settings_validate_address"] = "Validate Address...";
strings_["settings_request_payment"] = "Request Payment...";
strings_["settings_shield_mining"] = "Shield Mining...";
strings_["settings_merge_to_address"] = "Merge to Address...";
strings_["settings_clear_ztx"] = "Clear Z-Tx History";
strings_["settings_import_key"] = "Import Private Key...";
strings_["settings_import_viewkey"] = "Import Viewing Key...";
strings_["settings_export_key"] = "Export Key...";
strings_["settings_export_all"] = "Export All...";
strings_["settings_backup"] = "Backup...";
strings_["settings_export_csv"] = "Export CSV...";
strings_["settings_encrypt_wallet"] = "Encrypt Wallet";
strings_["settings_change_passphrase"] = "Change Passphrase";
strings_["settings_lock_now"] = "Lock Now";
strings_["settings_remove_encryption"] = "Remove Encryption";
strings_["settings_set_pin"] = "Set PIN";
strings_["settings_change_pin"] = "Change PIN";
strings_["settings_remove_pin"] = "Remove PIN";
strings_["settings_restart_daemon"] = "Restart daemon";
strings_["clear_anyway"] = "Clear Anyway";
// Settings: labels / text
strings_["settings_builtin"] = "Built-in";
strings_["settings_custom"] = "Custom";
strings_["settings_not_found"] = "Not found";
strings_["settings_idle_after"] = "after";
strings_["settings_not_encrypted"] = "Not encrypted";
strings_["settings_locked"] = "Locked";
strings_["settings_unlocked"] = "Unlocked";
strings_["settings_quick_unlock_pin"] = "Quick-unlock PIN";
strings_["settings_pin_active"] = "PIN";
strings_["settings_encrypt_first_pin"] = "Encrypt wallet first to enable PIN";
strings_["incorrect_pin"] = "Incorrect PIN";
strings_["incorrect_passphrase"] = "Incorrect passphrase";
strings_["pin_not_set"] = "PIN not set. Use passphrase to unlock.";
strings_["restarting_after_encryption"] = "Restarting daemon after encryption...";
strings_["force_quit"] = "Force Quit";
strings_["force_quit_warning"] = "This will immediately kill the daemon without a clean shutdown. May require a blockchain resync.";
strings_["force_quit_confirm_title"] = "Force Quit?";
strings_["force_quit_confirm_msg"] = "This will immediately kill the daemon without a clean shutdown.\nThis may corrupt the blockchain index and require a resync.";
strings_["force_quit_yes"] = "Force Quit";
strings_["reduce_motion"] = "Reduce Motion";
strings_["tt_reduce_motion"] = "Disable animated transitions and balance lerp for accessibility";
strings_["ago"] = "ago";
strings_["wizard_daemon_start_failed"] = "Failed to start daemon \xe2\x80\x94 it will be retried automatically";
// First-run wizard (app_wizard.cpp). Bootstrap/appearance labels reuse existing keys; these are
// the wizard-specific strings.
strings_["wiz_welcome_title"] = "Welcome to ObsidianDragon!";
strings_["wiz_welcome_sub"] = "A few quick choices and your full node is ready.";
strings_["wiz_step1"] = "Step 1";
strings_["wiz_step2"] = "Step 2";
strings_["wiz_step3"] = "Step 3";
strings_["wiz_appearance"] = "Appearance";
strings_["wiz_theme_builtin"] = "Built-in";
strings_["wiz_theme_custom"] = "Custom";
strings_["wiz_theme_invalid"] = " (invalid)";
strings_["wiz_lowspec_desc"] = "Disable all heavy visual effects";
strings_["wiz_acrylic"] = "Acrylic glass effects";
strings_["wiz_acrylic_desc"] = "Translucent blur on panels (Off disables)";
strings_["wiz_level"] = "Level:";
strings_["wiz_off"] = "Off";
strings_["wiz_theme_effects"] = "Theme visual effects";
strings_["wiz_theme_effects_desc"] = "Animated borders, color wash";
strings_["wiz_ui_opacity_desc"] = "Card & sidebar transparency (1.0 = solid)";
strings_["wiz_scanline_desc"] = "CRT scanline effect in console";
strings_["wiz_bootstrap"] = "Bootstrap";
strings_["wiz_bootstrap_desc"] = "Download a blockchain bootstrap to dramatically speed up initial sync.\n\nYour existing wallet.dat will NOT be modified or replaced.";
strings_["wiz_skip"] = "Skip";
strings_["wiz_bootstrap_failed"] = "Bootstrap failed";
strings_["wiz_download_failed"] = "Download Failed";
strings_["wiz_ext_daemon_running"] = "External daemon running";
strings_["wiz_ext_daemon_warning"] = "It must be stopped before downloading a bootstrap, otherwise chain data could be corrupted.";
strings_["wiz_stop_daemon"] = "Stop Daemon";
strings_["wiz_daemon_sending_stop"] = "Sending stop command...";
strings_["wiz_daemon_waiting_stop"] = "Waiting for daemon to shut down...";
strings_["wiz_daemon_stopped_ok"] = "Daemon stopped.";
strings_["wiz_daemon_stop_failed"] = "Daemon did not stop \xe2\x80\x94 try manually.";
strings_["wiz_encryption"] = "Encryption";
strings_["wiz_pin_title"] = "Quick-Unlock PIN";
strings_["wiz_already_encrypted"] = "Wallet is already encrypted";
strings_["wiz_already_encrypted_desc"] = "Your wallet is protected with a passphrase. No further action is needed.";
strings_["wiz_continue"] = "Continue";
strings_["wiz_encrypt_desc"] = "Encrypt your wallet to protect private keys with a passphrase.";
strings_["wiz_encrypt_warning"] = "If you lose your passphrase, you lose access to your funds.";
strings_["wiz_passphrase"] = "Passphrase:";
// --- Encrypt / change-passphrase dialogs (settings) ---
strings_["enc_desc"] = "Encrypting your wallet protects your private keys with a passphrase. After encryption, the daemon will restart.";
strings_["enc_confirm"] = "Confirm:";
strings_["enc_encrypting"] = "Encrypting wallet...";
strings_["enc_wait"] = "Please wait, do not close the application.";
strings_["enc_success"] = "Wallet encrypted successfully!";
strings_["enc_pin_desc"] = "A 4-8 digit PIN lets you unlock your wallet without typing the full passphrase every time.";
strings_["enc_pin_set_ok"] = "PIN set successfully";
strings_["enc_pin_vault_fail"] = "Failed to create PIN vault";
strings_["enc_pin_skipped"] = "PIN skipped. You can set one later in Settings.";
strings_["change_pass_title"] = "Change Passphrase";
strings_["change_pass_current"] = "Current Passphrase:";
strings_["change_pass_new"] = "New Passphrase:";
strings_["change_pass_confirm"] = "Confirm New:";
// --- Remove-encryption (decrypt) dialog (settings) ---
strings_["decrypt_title"] = "Remove Wallet Encryption";
strings_["decrypt_warning"] = "This will remove encryption from your wallet. Your private keys will be stored unprotected on disk.";
strings_["decrypt_desc"] = "The wallet will be exported, the daemon restarted with a fresh unencrypted wallet, and all keys re-imported. This may take several minutes depending on wallet size.";
strings_["decrypt_step_unlock"] = "Unlocking wallet";
strings_["decrypt_step_export"] = "Exporting wallet keys";
strings_["decrypt_step_stop"] = "Stopping daemon";
strings_["decrypt_step_backup"] = "Backing up encrypted wallet";
strings_["decrypt_step_restart"] = "Restarting daemon";
strings_["decrypt_wait_restart"] = "Waiting for the daemon to finish starting up...";
strings_["decrypt_wait_general"] = "Please wait. The daemon is exporting keys, restarting, and re-importing. This may take several minutes.";
strings_["decrypt_success_title"] = "Wallet decrypted successfully!";
strings_["decrypt_success_desc"] = "Your wallet is now unencrypted. A backup of the encrypted wallet was saved as wallet.dat.encrypted.bak in your data directory.";
strings_["decrypt_error_title"] = "Decryption failed";
strings_["try_again"] = "Try Again";
// --- PIN setup / change / remove dialogs (settings) ---
strings_["pin_setup_desc"] = "Set a 4-8 digit PIN for quick wallet unlock. Your wallet passphrase will be encrypted with this PIN and stored locally.";
strings_["pin_wallet_passphrase"] = "Wallet Passphrase:";
strings_["pin_new_label"] = "New PIN (4-8 digits):";
strings_["pin_change_desc"] = "Change your unlock PIN. You need your current PIN and a new PIN.";
strings_["pin_current_label"] = "Current PIN:";
strings_["pin_confirm_new_label"] = "Confirm New PIN:";
strings_["pin_remove_desc"] = "Enter your current PIN to confirm removal. You will need to use your full passphrase to unlock.";
strings_["wiz_confirm"] = "Confirm:";
strings_["wiz_strength_weak"] = "Weak";
strings_["wiz_strength_fair"] = "Fair";
strings_["wiz_strength_good"] = "Good";
strings_["wiz_strength_strong"] = "Strong";
strings_["wiz_strength"] = "Strength: %s";
strings_["wiz_pass_too_short"] = "Passphrase must be at least 8 characters (%zu/8)";
strings_["wiz_pass_mismatch"] = "Passphrases do not match";
strings_["wiz_pass_spaces"] = "Passphrase has leading/trailing spaces \xe2\x80\x94 remove them";
strings_["wiz_encrypt_continue"] = "Encrypt & Continue";
strings_["wiz_encrypt_bg"] = "Encryption will complete in the background";
strings_["wiz_skip_confirm"] = "Continue WITHOUT encryption? Keys will be stored unencrypted \xe2\x80\x94 click Skip again to confirm.";
strings_["wiz_pin_optional"] = "Quick-Unlock PIN (optional)";
strings_["wiz_pin_label"] = "PIN (4-8 digits):";
strings_["wiz_pin_confirm"] = "Confirm PIN:";
strings_["wiz_pin_invalid"] = "PIN must be 4-8 digits";
strings_["wiz_pin_mismatch"] = "PINs do not match";
strings_["settings_data_dir"] = "Data Dir:";
strings_["settings_wallet_size_label"] = "Wallet Size:";
strings_["settings_debug_changed"] = "Debug categories changed \xe2\x80\x94 restart daemon to apply";
strings_["settings_auto_detected"] = "Auto-detected from DRAGONX.conf";
strings_["settings_visual_effects"] = "Visual Effects";
strings_["settings_acrylic_level"] = "Acrylic Level:";
strings_["settings_noise_opacity"] = "Noise Opacity:";
strings_["settings_privacy"] = "Privacy";
strings_["settings_other"] = "Other";
strings_["settings_rpc_connection"] = "RPC Connection";
strings_["settings_configure_rpc"] = "Configure connection to dragonxd daemon";
strings_["settings_wallet_maintenance"] = "Wallet Maintenance";
strings_["settings_wallet_info"] = "Wallet Info";
strings_["settings_block_explorer_urls"] = "Block Explorer URLs";
strings_["settings_configure_explorer"] = "Configure external block explorer links";
strings_["settings_auto_lock"] = "AUTO-LOCK";
strings_["timeout_off"] = "Off";
strings_["timeout_1min"] = "1 min";
strings_["timeout_5min"] = "5 min";
strings_["timeout_15min"] = "15 min";
strings_["timeout_30min"] = "30 min";
strings_["timeout_1hour"] = "1 hour";
strings_["slider_off"] = "Off";
strings_["settings_wallet_file_size"] = "Wallet file size: %s";
strings_["settings_wallet_location"] = "Wallet location: %s";
strings_["settings_rpc_note"] = "Note: Connection settings are usually auto-detected from DRAGONX.conf";
strings_["settings_explorer_hint"] = "URLs should include a trailing slash. The txid/address will be appended.";
strings_["settings_connection"] = "Connection";
strings_["settings_reduce_transparency"] = "Reduce transparency";
strings_["settings_save_shielded_local"] = "Save shielded transaction history locally";
strings_["settings_auto_shield_funds"] = "Auto-shield transparent funds";
strings_["settings_use_tor_network"] = "Use Tor for network connections";
strings_["settings_gradient_bg"] = "Gradient bg";
// Settings: tooltips
strings_["tt_theme_hotkey"] = "Hotkey: Ctrl+Left/Right to cycle themes";
strings_["tt_layout_hotkey"] = "Hotkey: Left/Right arrow keys to cycle Balance layouts";
strings_["tt_language"] = "Interface language for the wallet UI";
strings_["tt_scan_themes"] = "Scan for new themes.\nPlace theme folders in:\n%s";
strings_["tt_low_spec"] = "Disable all heavy visual effects\nHotkey: Ctrl+Shift+Down";
strings_["tt_simple_bg"] = "Use a simple gradient for the background\nHotkey: Ctrl+Up";
strings_["tt_simple_bg_alt"] = "Use a gradient version of the theme background image\nHotkey: Ctrl+Up";
strings_["tt_scanline"] = "CRT scanline effect in console";
strings_["tt_theme_effects"] = "Shimmer, glow, hue-cycling per theme";
strings_["tt_animate_avatars"] = "Play animated (GIF / WebP) contact avatars; off shows the first frame only";
strings_["tt_blur"] = "Blur amount (0%% = off, 100%% = maximum)";
strings_["tt_noise"] = "Grain texture intensity (0%% = off, 100%% = maximum)";
strings_["tt_ui_opacity"] = "Card and sidebar opacity (100%% = fully opaque, lower = more see-through)";
strings_["tt_window_opacity"] = "Background opacity (lower = desktop visible through window)";
strings_["tt_font_scale"] = "Scale all text and UI (1.0x = default, up to 1.5x). Hotkey: Alt + Scroll Wheel";
strings_["tt_custom_theme"] = "Custom theme active";
strings_["tt_address_book"] = "Manage saved addresses for quick sending";
strings_["tt_validate"] = "Check if a DragonX address is valid";
strings_["tt_request_payment"] = "Generate a payment request with QR code";
strings_["tt_shield_mining"] = "Move transparent mining rewards to a shielded address";
strings_["tt_merge"] = "Consolidate multiple UTXOs into one address";
strings_["tt_clear_ztx"] = "Delete locally cached z-transaction history";
strings_["tt_save_ztx"] = "Store z-address transaction history locally for faster loading";
strings_["tt_auto_shield"] = "Automatically move transparent balance to shielded addresses for privacy";
strings_["tt_tor"] = "Route daemon connections through the Tor network for anonymity";
strings_["tt_keep_daemon"] = "Daemon will still stop when running the setup wizard";
strings_["tt_stop_external"] = "Applies when connecting to a daemon\nyou started outside this wallet";
strings_["tt_verbose"] = "Log detailed connection diagnostics,\ndaemon state, and port owner info\nto the Console tab";
strings_["tt_mine_idle"] = "Automatically start mining when the\nsystem is idle (no keyboard/mouse input)";
strings_["tt_idle_delay"] = "How long to wait before starting mining";
strings_["tt_wizard"] = "Re-run the initial setup wizard\nDaemon will be restarted";
strings_["tt_download_bootstrap"] = "Download blockchain bootstrap to speed up sync\nExisting block data will be replaced";
// --- Full-node Node & Security tooltips ---
strings_["tt_rpc_toggle"] = "Show or hide the read-only RPC connection details (host, port, user, password) for the daemon";
strings_["tt_daemon_refresh"] = "Re-read the installed and bundled dragonxd version, size, and date shown above";
// --- Lite wallet Node & Security tooltips ---
strings_["tt_lite_lifecycle_toggle"] = "Show or hide the create / open / restore controls for managing your lite wallet file";
strings_["tt_lite_lifecycle_op"] = "Choose whether to create a new wallet, open an existing one, or restore one from a seed phrase";
strings_["tt_lite_wallet_path"] = "Path or name of the wallet file to open or restore into";
strings_["tt_lite_restore_seed"] = "The 24-word recovery seed phrase to restore this wallet from; hidden as you type";
strings_["tt_lite_restore_birthday"] = "Block height the wallet was created at; scanning starts here. Use 0 or the earliest height if unsure";
strings_["tt_lite_restore_account"] = "HD account index to restore; leave 0 unless you used multiple accounts under this seed";
strings_["tt_lite_restore_overwrite"] = "Replace an existing wallet file with this restore. Warning: overwrites the current wallet data";
strings_["tt_lite_lifecycle_pass"] = "Passphrase to unlock or set on the wallet during this create / open / restore operation";
strings_["tt_lite_lifecycle_run"] = "Run the selected create / open / restore operation with the values above";
strings_["tt_lite_show_seed"] = "Reveal this wallet's recovery seed phrase and birthday. Anyone with the seed can spend your funds";
strings_["tt_lite_show_keys"] = "Reveal this wallet's private spending keys. Anyone with a key can spend the funds it controls";
strings_["tt_lite_copy"] = "Copy the revealed secret to the clipboard";
strings_["tt_lite_save_seed_file"] = "Write the seed and birthday to an owner-only file (lite-seed-backup.txt) in the config folder";
strings_["tt_lite_hide_wipe"] = "Hide the revealed secret and securely wipe it from memory";
strings_["tt_lite_import_key"] = "Paste a private spending or viewing key to import; its history appears after the next sync";
strings_["tt_lite_import_key_btn"] = "Import the entered private key into this wallet; funds and history appear after the next sync";
strings_["tt_lite_encrypt_pass"] = "Passphrase to encrypt the wallet with. If lost, the wallet cannot be unlocked or recovered";
strings_["tt_lite_encrypt"] = "Encrypt the wallet with the passphrase above; it locks immediately and requires the passphrase to unlock";
strings_["tt_lite_unlock_pass"] = "Enter your passphrase to unlock the encrypted wallet";
strings_["tt_lite_unlock"] = "Unlock the encrypted wallet using the passphrase above";
strings_["tt_lite_lock"] = "Lock the wallet now; a passphrase is required to unlock and any chat session is torn down";
strings_["tt_lite_decrypt_pass"] = "Enter your passphrase to remove encryption from the wallet";
strings_["tt_lite_remove_encrypt"] = "Remove encryption and store the wallet unprotected; no passphrase will be required to open it";
// --- Chat & Contacts tooltips ---
strings_["tt_chat_emoji_style"] = "Render emoji in monochrome outline or full color";
strings_["tt_chat_bubble_style"] = "Message bubble shape: rounded, square, or minimal (flat, borderless)";
strings_["tt_chat_bubble_accent"] = "Accent color for your outgoing message bubbles (or follow the current theme)";
strings_["tt_chat_density"] = "Spacing between messages: Comfortable adds more padding; Compact fits more on screen";
strings_["tt_chat_font_size"] = "Scale chat message text from 0.8x to 1.5x. Affects only the Chat tab, not the rest of the app";
strings_["tt_chat_poll_rate"] = "How often to check for new and 0-conf messages (0.5-15 s). Faster is more responsive but uses more CPU";
strings_["tt_chat_timestamp"] = "Timestamp format for this tab only: follow the app-wide clock, or force 24-hour or 12-hour";
strings_["tt_chat_enter_sends"] = "When on, Enter sends the message and Shift+Enter adds a newline; when off, Enter adds a newline";
// --- Debug Options tooltips ---
strings_["tt_screenshot_sweep"] = "Cycle every theme across every tab, saving a screenshot of each into the config screenshots folder (overwrites the last sweep)";
strings_["tt_screenshot_sweep_full"] = "Like the theme sweep but also captures every modal / dialog / flow using temporary offline demo wallet data";
strings_["tt_screenshot_open_dir"] = "Open the screenshots folder (under the config directory) in your file manager";
strings_["tt_seed_demo_chat"] = "Inject sample conversations into the Chat tab so a sweep captures its UI; in-memory only, gone on restart";
strings_["download_bootstrap"] = "Download Bootstrap";
strings_["download"] = "Download";
strings_["retry"] = "Retry";
strings_["bootstrap_desc"] = "Download a blockchain bootstrap to dramatically speed up initial sync. This downloads a snapshot of the blockchain and extracts it into your data directory.";
strings_["bootstrap_warning"] = "Existing block data (blocks, chainstate, notarizations) will be deleted and replaced. Your wallet.dat will NOT be modified or deleted.";
strings_["bootstrap_trust_warning"] = "Only use bootstrap.dragonx.is or bootstrap2.dragonx.is. Using files from untrusted sources could compromise your node.";
strings_["bootstrap_mirror"] = "Mirror";
strings_["bootstrap_mirror_tooltip"] = "Download from mirror (bootstrap2.dragonx.is).\nUse this if the main download is slow or failing.";
strings_["bootstrap_downloading"] = "Downloading bootstrap...";
strings_["bootstrap_verifying"] = "Verifying checksums...";
strings_["bootstrap_extracting"] = "Extracting blockchain data...";
strings_["bootstrap_wallet_protected"] = "(wallet.dat is protected)";
strings_["bootstrap_daemon_stopping"] = "Daemon stopping...";
strings_["bootstrap_daemon_running"] = "Daemon running";
strings_["bootstrap_daemon_stopped"] = "Daemon stopped";
strings_["bootstrap_success"] = "Bootstrap Complete";
strings_["bootstrap_success_desc"] = "Blockchain data has been extracted successfully. Start the daemon to begin syncing from the bootstrap point.";
strings_["bootstrap_restart_daemon"] = "Restart Daemon";
strings_["bootstrap_failed"] = "Bootstrap Failed";
strings_["tt_open_dir"] = "Click to open in file explorer";
strings_["settings_open_data_dir"] = "Open data folder";
strings_["tt_open_data_dir"] = "Open the folder with your wallet and blockchain data in the file manager";
strings_["settings_open_app_dir"] = "Open app folder";
strings_["tt_open_app_dir"] = "Open the ObsidianDragon folder (settings, themes, logs) in the file manager";
strings_["tt_rpc_host"] = "Hostname of the DragonX daemon";
strings_["tt_rpc_user"] = "RPC authentication username";
strings_["tt_rpc_port"] = "Port for daemon RPC connections";
strings_["tt_rpc_pass"] = "RPC authentication password";
strings_["tt_test_conn"] = "Verify the RPC connection to the daemon";
strings_["tt_rescan"] = "Rescan the blockchain for missing transactions";
strings_["tt_delete_blockchain"] = "Delete all blockchain data and start a fresh sync. Your wallet.dat and config are preserved.";
strings_["delete_blockchain"] = "Delete Blockchain";
strings_["delete_blockchain_confirm"] = "Delete & Resync";
strings_["confirm_delete_blockchain_title"] = "Delete Blockchain Data";
strings_["confirm_delete_blockchain_msg"] = "This will stop the daemon, delete all blockchain data (blocks, chainstate, peers), and start a fresh sync from scratch. This can take several hours to complete.";
strings_["confirm_delete_blockchain_safe"] = "Your wallet.dat, config, and transaction history are safe and will not be deleted.";
strings_["confirm_rescan_title"] = "Rescan Blockchain";
strings_["confirm_rescan_msg"] = "This restarts the daemon and re-scans the entire blockchain for your wallet's transactions. It can take a long time and the wallet stays offline until it finishes.";
strings_["confirm_rescan_safe"] = "Your wallet.dat and blockchain data are not deleted — only re-scanned.";
strings_["rescan_detecting"] = "Checking which blocks your node has on disk…";
strings_["rescan_bootstrapped_msg"] = "Your node was bootstrapped, so blocks below the snapshot aren't on disk and a rescan from genesis would fail. Rescan from a height your snapshot includes to reconcile your wallet's spent balance. Your wallet.dat and chain data are not deleted.";
strings_["rescan_from_height"] = "Rescan from block height:";
strings_["repair_wallet"] = "Repair Wallet";
strings_["tt_repair_wallet"] = "Wipe and rebuild the wallet's transaction records from the blockchain (fixes notes that fail to send after a rescan)";
strings_["confirm_repair_wallet_title"] = "Repair Wallet";
strings_["confirm_repair_wallet_msg"] = "This restarts the daemon with -zapwallettxes=2: it deletes all of the wallet's transaction and note records, then rebuilds them from the blockchain. Use this when transactions fail to build (\"Invalid sapling spend proof\" / \"shielded requirements not met\") even after a full rescan. It takes a long time and the wallet stays offline until it finishes.";
strings_["confirm_repair_wallet_safe"] = "Your keys, addresses and balance are preserved — only the cached transaction records are rebuilt.";
strings_["daemon_binary"] = "Daemon binary";
strings_["daemon_installed"] = "Installed";
strings_["daemon_bundled"] = "Bundled";
strings_["daemon_not_installed"] = "not installed";
strings_["daemon_none_bundled"] = "none in this build";
strings_["daemon_status_match"] = "Installed binary matches the bundled version.";
strings_["daemon_status_differ"] = "Installed binary differs from the bundled version.";
strings_["daemon_status_missing"] = "No daemon installed — install the bundled version.";
strings_["daemon_install_bundled"] = "Install bundled";
strings_["tt_daemon_install_bundled"] = "Stop the node, overwrite the installed dragonxd with the version bundled in this wallet build, then restart";
strings_["confirm_reinstall_daemon_title"] = "Install Bundled Daemon";
strings_["confirm_reinstall_daemon_msg"] = "This stops the daemon, overwrites the installed dragonxd (and dragonx-cli/dragonx-tx) with the versions bundled in this wallet build, then restarts the node. Use this to recover or update the node binary.";
strings_["confirm_reinstall_daemon_safe"] = "Your wallet, keys and blockchain data are not touched — only the daemon program files are replaced.";
strings_["daemon_update_title"] = "Update the node daemon?";
strings_["daemon_update_body"] = "This wallet build bundles a newer DragonX node than the one currently installed. Updating replaces the installed dragonxd (and dragonx-cli/dragonx-tx), then stops and restarts the node so the new version takes effect. Recommended — a newer node can add features (e.g. seed-phrase support) the old one lacks.";
strings_["daemon_update_safe"] = "Your wallet, keys and blockchain data are not touched — only the daemon program files are replaced. If you deliberately run a custom node, choose Keep current.";
strings_["daemon_update_now"] = "Update now";
strings_["daemon_update_keep"] = "Keep current";
strings_["confirm_restart_daemon_title"] = "Restart Daemon";
strings_["confirm_restart_daemon_msg"] = "This stops and restarts the daemon to apply the changed options. The wallet will briefly disconnect and reconnect.";
strings_["lite_maintenance"] = "Maintenance";
strings_["lite_redownload_blocks"] = "Redownload blocks";
strings_["lite_redownload_desc"] = "Re-fetch all blocks from the lite server (use if your balance or history looks wrong).";
strings_["lite_redownload_running"] = "Re-downloading blocks…";
strings_["tt_lite_redownload"] = "Re-download and re-scan all blocks from the lite server";
strings_["confirm_lite_redownload_title"] = "Redownload Blocks";
strings_["confirm_lite_redownload_msg"] = "This clears the wallet's downloaded block data and re-fetches and re-scans every block from the lite server. It can take a while; the wallet shows sync progress until it finishes.";
strings_["confirm_lite_redownload_safe"] = "Your wallet, keys, and seed are not affected — only the block data is re-downloaded.";
// Lite wallet lifecycle / backup / security section
strings_["lite_servers_network_tab"] = "Lite servers are managed in the Network tab.";
strings_["lite_wallet_request"] = "Lite wallet request";
strings_["lite_action"] = "Action";
strings_["lite_op_create"] = "Create";
strings_["lite_op_open"] = "Open";
strings_["lite_op_restore"] = "Restore";
strings_["lite_wallet_label"] = "Wallet";
strings_["lite_seed_label"] = "Seed";
strings_["lite_word_count"] = "%d / 24 words";
strings_["lite_birthday_label"] = "Birthday";
strings_["lite_birthday_hint"] = "Block height to start scanning from. Leave 0 if unknown (slower full scan).";
strings_["lite_account_label"] = "Account";
strings_["lite_overwrite"] = "Overwrite";
strings_["lite_passphrase_label"] = "Passphrase";
strings_["lite_validate"] = "Validate";
strings_["lite_working"] = "Working…";
strings_["lite_wallet_ready"] = "Wallet ready";
strings_["lite_backup_keys"] = "Backup & keys";
strings_["lite_show_seed"] = "Show seed";
strings_["lite_seed_warning"] = "Seed phrase — the ONLY way to restore your wallet. Write it down, store it offline, never share it.";
strings_["lite_show_private_keys"] = "Show private keys";
strings_["lite_private_keys_warning"] = "Private keys — anyone with these can spend your funds";
strings_["lite_birthday_backup"] = "Birthday: %llu (back this up too)";
strings_["lite_copy"] = "Copy";
strings_["lite_save_to_file"] = "Save to file";
strings_["lite_saved_to"] = "Saved (plaintext, owner-only) to ";
strings_["lite_could_not_write"] = "Could not write ";
strings_["lite_hide_wipe"] = "Hide & wipe";
strings_["lite_import_key_label"] = "Import key";
strings_["lite_import"] = "Import";
strings_["lite_key_imported"] = "Key imported — run a sync to scan its history";
strings_["lite_security"] = "Security";
strings_["lite_encrypt_wallet"] = "Encrypt wallet";
strings_["lite_wallet_encrypted"] = "Wallet encrypted";
strings_["lite_unlock"] = "Unlock";
strings_["lite_wallet_unlocked"] = "Wallet unlocked";
strings_["lite_unlock_failed"] = "Unlock failed";
strings_["lite_lock_now"] = "Lock now";
strings_["lite_wallet_locked"] = "Wallet locked";
strings_["lite_lock_failed"] = "Lock failed";
strings_["lite_remove_encryption"] = "Remove encryption";
strings_["lite_encryption_removed"] = "Encryption removed";
strings_["tt_encrypt"] = "Encrypt wallet.dat with a passphrase";
strings_["tt_change_pass"] = "Change the wallet encryption passphrase";
strings_["tt_lock"] = "Lock the wallet immediately";
strings_["tt_remove_encrypt"] = "Remove encryption and store wallet unprotected";
strings_["tt_auto_lock"] = "Lock wallet after this much inactivity";
strings_["tt_set_pin"] = "Set a 4-8 digit PIN for quick unlock";
strings_["tt_change_pin"] = "Change your unlock PIN";
strings_["tt_remove_pin"] = "Remove PIN and require passphrase to unlock";
strings_["tt_tx_url"] = "Base URL for viewing transactions in a block explorer";
strings_["tt_addr_url"] = "Base URL for viewing addresses in a block explorer";
strings_["tt_custom_fees"] = "Enable manual fee entry when sending transactions";
strings_["tt_fetch_prices"] = "Retrieve DRGX market prices from CoinGecko API";
strings_["tt_block_explorer"] = "Open the DragonX block explorer in your browser";
strings_["tt_website"] = "Open the DragonX website";
strings_["tt_report_bug"] = "Report an issue on the project tracker";
strings_["tt_save_settings"] = "Save all settings to disk";
strings_["tt_reset_settings"] = "Reload settings from disk (undo unsaved changes)";
strings_["tt_debug_collapse"] = "Collapse debug logging options";
strings_["tt_debug_expand"] = "Expand debug logging options";
strings_["tt_restart_daemon"] = "Restart the daemon to apply debug logging changes";
// Settings: additional tooltips (keys/data row)
strings_["tt_import_key"] = "Import a private key (zkey or tkey) into this wallet";
strings_["tt_import_viewkey"] = "Import a shielded viewing key to watch an address (read-only)";
strings_["tt_export_key"] = "Export the private key for the selected address";
strings_["tt_export_all"] = "Export all private keys to a file";
strings_["tt_backup"] = "Create a backup of your wallet.dat file";
strings_["tt_export_csv"] = "Export transaction history as a CSV spreadsheet";
// Settings: about / debug
strings_["settings_about_text"] = "A shielded cryptocurrency wallet for DragonX (DRGX), built with Dear ImGui for a lightweight, portable experience.";
strings_["settings_copyright"] = "Copyright 2024-2026 DragonX Developers | GPLv3 License";
strings_["debug_logging"] = "DEBUG OPTIONS";
strings_["settings_debug_select"] = "Select categories to enable daemon debug logging (-debug= flags).";
strings_["settings_debug_restart_note"] = "Changes take effect after restarting the daemon.";
// Debug-options gate (confirmation + optional re-auth)
strings_["debug_gate_title"] = "Show debug options?";
strings_["debug_gate_warning"] = "These are advanced diagnostic and node-tuning options. They can expose sensitive information and change how your node runs. Only continue if you know what you're doing.";
strings_["debug_gate_pin_prompt"] = "Enter your unlock PIN to continue:";
strings_["debug_gate_pass_prompt"] = "Enter your wallet passphrase to continue:";
strings_["debug_gate_confirm"] = "Show debug options";
strings_["debug_gate_incorrect"] = "Incorrect PIN or passphrase.";
strings_["debug_gate_verifying"] = "Verifying\xE2\x80\xA6";
// Settings window (legacy dialog) descriptions
strings_["settings_language_note"] = "Note: Some text requires restart to update";
strings_["settings_solid_colors_desc"] = "Use solid colors instead of blur effects (accessibility)";
strings_["settings_gradient_desc"] = "Replace textured backgrounds with smooth gradients";
strings_["settings_save_shielded_desc"] = "Stores z-addr transactions in a local file for viewing";
strings_["settings_auto_shield_desc"] = "Automatically move transparent funds to shielded addresses";
strings_["settings_tor_desc"] = "Route all connections through Tor for enhanced privacy";
strings_["settings_rescan_desc"] = "Rescan blockchain for missing transactions";
strings_["settings_clear_ztx_long"] = "Clear Saved Z-Transaction History";
strings_["settings_clear_ztx_desc"] = "Delete locally stored shielded transaction data";
strings_["settings_wallet_not_found"] = "Wallet file not found";
// Balance tab: address actions
strings_["hide_zero_balances"] = "Hide 0 Balances";
strings_["restore_address"] = "Restore Address";
strings_["hide_address"] = "Hide Address";
strings_["remove_favorite"] = "Remove Favorite";
strings_["favorite_address"] = "Favorite Address";
strings_["show_hidden"] = "Show Hidden (%d)";
strings_["filter"] = "Filter...";
strings_["no_addresses_yet"] = "No addresses yet";
strings_["showing_x_of_y"] = "Showing %d of %d addresses";
strings_["set_label"] = "Set Label...";
strings_["copied"] = "Copied!";
strings_["hidden_tag"] = " (hidden)";
strings_["z_address"] = "Z-Address";
strings_["t_address"] = "T-Address";
strings_["shielded_address"] = "Shielded Address";
strings_["transparent_address"] = "Transparent Address";
strings_["label_placeholder"] = "e.g. Savings, Mining...";
strings_["choose_icon"] = "Choose Icon";
strings_["clear_icon"] = "Clear Icon";
strings_["search_icons"] = "Search icons...";
strings_["no_icons_found"] = "No icons match your search.";
strings_["transfer_funds"] = "Transfer Funds";
strings_["transfer_to"] = "Transfer to:";
strings_["address_reorder_hint"] = "Drop on a row's edge to reorder, or its centre to transfer";
strings_["deshielding_warning"] = "Warning: This will de-shield funds from a private (Z) address to a transparent (T) address.";
strings_["shielding_notice"] = "Note: This will shield funds from a transparent (T) address to a private (Z) address.";
strings_["result_preview"] = "Result Preview";
strings_["sender_balance"] = "Sender: %.8f \xe2\x86\x92 %.8f DRGX";
strings_["recipient_balance"] = "Recipient: %.8f \xe2\x86\x92 %.8f DRGX";
strings_["insufficient_funds"] = "Insufficient funds for this amount plus fee.";
strings_["sends_full_balance_warning"] = "This sends the full balance. The sending address will have a zero balance.";
strings_["confirm_transfer"] = "Confirm Transfer";
strings_["transfer_sent"] = "Transfer Sent";
strings_["transfer_sent_desc"] = "Your transfer has been submitted to the network.";
strings_["transfer_failed"] = "Transfer Failed";
// Misc dialog strings
strings_["shield_operation_id"] = "Operation ID: %s";
strings_["peers_peer_label"] = "Peer: %s";
strings_["key_export_click_retrieve"] = "Click to retrieve the key from your wallet";
strings_["backup_source"] = "Source: %s";
strings_["export_keys_progress"] = "Exporting %d/%d...";
strings_["import_key_progress"] = "Importing %d/%d...";
strings_["block_click_copy"] = "Click to copy";
strings_["confirm_clear_ztx_title"] = "Confirm Clear Z-Tx History";
strings_["confirm_clear_ztx_warning1"] = "Clearing z-transaction history may cause your shielded balance to show as 0 until a wallet rescan is performed.";
strings_["confirm_clear_ztx_warning2"] = "If this happens, you will need to re-import your z-address private keys with rescan enabled to recover your balance.";
// Send tab
strings_["sending_from"] = "SENDING FROM";
strings_["recent_sends"] = "RECENT SENDS";
strings_["recipient"] = "RECIPIENT";
strings_["memo_optional"] = "MEMO (OPTIONAL)";
strings_["no_recent_sends"] = "No recent sends";
strings_["network_fee"] = "NETWORK FEE";
strings_["amount_details"] = "AMOUNT DETAILS";
strings_["not_connected_to_daemon"] = "Not connected to daemon";
strings_["select_source_address"] = "Select a source address...";
strings_["no_addresses_with_balance"] = "No addresses with balance";
strings_["blockchain_syncing"] = "Blockchain syncing (%.1f%%)... Balances may be inaccurate.";
strings_["wallet_empty"] = "Your wallet is empty";
strings_["wallet_empty_hint"] = "Switch to Receive to get your address and start receiving funds.";
strings_["go_to_receive"] = "Go to Receive";
strings_["review_send"] = "Review Send";
strings_["fee_low"] = "Low";
strings_["fee_normal"] = "Normal";
strings_["fee_high"] = "High";
strings_["submitting_transaction"] = "Submitting transaction...";
strings_["processing_transaction"] = "Processing transaction...";
strings_["tx_progress_submitting"] = "Submitting transaction to daemon";
strings_["tx_progress_waiting_ops"] = "Waiting for operation (%d)";
strings_["tx_progress_balances"] = "Refreshing balances";
strings_["tx_progress_history"] = "Refreshing history";
strings_["tx_progress_finalizing"] = "Finalizing transaction";
strings_["transaction_sent_msg"] = "Transaction sent!";
strings_["copy_error"] = "Copy Error";
strings_["dismiss"] = "Dismiss";
strings_["clear_form_confirm"] = "Clear all form fields?";
strings_["yes_clear"] = "Yes, Clear";
strings_["keep"] = "Keep";
strings_["undo_clear"] = "Undo Clear";
// Receive tab
strings_["recent_received"] = "RECENT RECEIVED";
strings_["payment_request"] = "PAYMENT REQUEST";
strings_["copy"] = "Copy";
strings_["new"] = "+ New";
strings_["share"] = "Share";
strings_["select_receiving_address"] = "Select a receiving address...";
strings_["no_addresses_match"] = "No addresses match filter";
strings_["no_recent_receives"] = "No recent receives";
strings_["waiting_for_daemon"] = "Waiting for daemon connection...";
strings_["addresses_appear_here"] = "Your receiving addresses will appear here once connected.";
strings_["loading_addresses"] = "Loading addresses...";
strings_["clear_request"] = "Clear Request";
strings_["copy_uri"] = "Copy URI";
strings_["qr_unavailable"] = "QR unavailable";
strings_["received_label"] = "Received";
// Transactions tab
strings_["no_transactions"] = "No transactions found";
strings_["loading_transactions"] = "Loading transactions";
strings_["tx_loading_queued"] = "Queued transaction refresh";
strings_["tx_loading_enriching_sends"] = "Checking sent transaction details (%d)";
strings_["tx_loading_scanning_shielded"] = "Scanning shielded history (%d addresses)";
strings_["tx_loading_refreshing_cached"] = "Refreshing wallet history (%d cached)";
strings_["tx_loading_fetching_transparent"] = "Fetching transparent history";
strings_["tx_loading_history_progress"] = "Loading older history (%d%%)";
strings_["no_matching"] = "No matching transactions";
strings_["transaction_id"] = "TRANSACTION ID";
strings_["search_placeholder"] = "Search...";
strings_["all_filter"] = "All";
strings_["sent_filter"] = "Sent";
strings_["received_filter"] = "Received";
strings_["mined_filter"] = "Mined";
strings_["chat_filter"] = "Chat";
strings_["sort_date_newest"] = "Newest first";
strings_["sort_date_oldest"] = "Oldest first";
strings_["sort_amount_high"] = "Largest amount";
strings_["sort_amount_low"] = "Smallest amount";
strings_["export_csv"] = "Export CSV";
strings_["transactions_upper"] = "TRANSACTIONS";
strings_["received_upper"] = "RECEIVED";
strings_["sent_upper"] = "SENT";
strings_["mined_upper"] = "MINED";
strings_["from_upper"] = "FROM";
strings_["to_upper"] = "TO";
strings_["shielded_to"] = "SHIELDED TO";
strings_["address_upper"] = "ADDRESS";
strings_["memo_upper"] = "MEMO";
strings_["shielded_type"] = "Shielded";
strings_["tx_chat_badge"] = "Message";
strings_["recv_type"] = "Recv";
strings_["sent_type"] = "Sent";
strings_["immature_type"] = "Immature";
strings_["mined_type"] = "Mined";
strings_["mature"] = "Mature";
strings_["copy_txid"] = "Copy TxID";
strings_["view_details"] = "View Details";
strings_["full_details"] = "Full Details";
strings_["showing_transactions"] = "Showing %d\xe2\x80\x93%d of %d transactions (total: %zu)";
strings_["txs_count"] = "%d txs";
strings_["conf_count"] = "%d conf";
strings_["confirmations_display"] = "%d confirmations | %s";
strings_["mark_mining_address"] = "Mark as mining address";
strings_["unmark_mining_address"] = "Unmark mining address";
strings_["mining_tag"] = " · Mining";
// Balance Tab
strings_["summary"] = "Summary";
strings_["shielded"] = "Shielded";
strings_["transparent"] = "Transparent";
strings_["total"] = "Total";
strings_["unconfirmed"] = "Unconfirmed";
strings_["recent_transactions"] = "RECENT TRANSACTIONS";
strings_["view_all"] = "View All";
strings_["no_transactions_yet"] = "No transactions yet";
strings_["privacy_great"] = "Great privacy!";
strings_["privacy_medium"] = "Consider shielding more";
strings_["privacy_low"] = "Low privacy — shield funds";
strings_["balance_history_collecting"] = "Balance history — collecting data...";
strings_["balance_shielded_fmt"] = "Shielded: %.8f";
strings_["balance_transparent_fmt"] = "Transparent: %.8f";
strings_["your_addresses"] = "Your Addresses";
strings_["z_addresses"] = "Z-Addresses";
strings_["t_addresses"] = "T-Addresses";
strings_["no_addresses"] = "No addresses found. Create one using the buttons above.";
strings_["new_z_address"] = "New Z-Address";
strings_["new_t_address"] = "New T-Address";
strings_["type"] = "Type";
strings_["address"] = "Address";
strings_["copy_address"] = "Copy Full Address";
strings_["send_from_this_address"] = "Send From This Address";
strings_["export_private_key"] = "Export Private Key";
strings_["export_viewing_key"] = "Export Viewing Key";
strings_["show_qr_code"] = "Show QR Code";
strings_["not_connected"] = "Not connected to daemon...";
// Lite build: there is no daemon — these replace the daemon-centric "not connected"
// strings when no wallet is open (isConnected() tracks the lite wallet in lite builds).
strings_["lite_no_wallet"] = "No wallet open — create or open one in Settings";
strings_["lite_no_wallet_short"] = "No wallet open";
// Lite first-run welcome prompt (shown when no wallet file exists yet).
strings_["lite_welcome_title"] = "Welcome to ObsidianDragon Lite";
strings_["lite_welcome_msg"] = "You don't have a wallet yet. Create a new one or restore from a recovery phrase.";
strings_["lite_welcome_create"] = "Create new wallet";
strings_["lite_welcome_restore"] = "Restore from seed";
strings_["lite_welcome_later"] = "Later";
strings_["lite_welcome_created"] = "Wallet created — back up your recovery phrase now in Settings → Backup & keys";
strings_["lite_welcome_restore_hint"] = "Restore your wallet under Settings → Lite wallet request";
strings_["lite_welcome_create_failed"] = "Could not create wallet";
strings_["lite_restore_title"] = "Restore from seed phrase";
strings_["lite_restore_intro"] = "Enter your recovery seed phrase. The wallet will be restored and then synced from the lite server.";
strings_["lite_restore_seed_label"] = "Seed phrase (words separated by spaces)";
strings_["lite_restore_birthday_label"] = "Birthday block (optional — 0 scans from the start, slower)";
strings_["lite_restore_btn"] = "Restore wallet";
strings_["lite_restore_ok"] = "Wallet restored — syncing from the lite server…";
// Lite send-time unlock prompt.
strings_["lite_unlock_title"] = "Unlock wallet";
strings_["lite_unlock_msg"] = "Enter your passphrase to unlock the wallet for spending.";
strings_["lite_unlock_btn"] = "Unlock";
strings_["lite_unlock_ok"] = "Wallet unlocked — you can send now";
strings_["lite_unlock_failed"] = "Unlock failed — wrong passphrase?";
// Send Tab
strings_["pay_from"] = "Pay From";
strings_["send_to"] = "Send To";
strings_["send_contacts_button"] = "Pick from contacts";
strings_["amount"] = "Amount";
strings_["memo"] = "Memo (optional, encrypted)";
strings_["miner_fee"] = "Miner Fee";
strings_["fee"] = "Fee";
strings_["send_transaction"] = "Send Transaction";
strings_["clear"] = "Clear";
strings_["select_address"] = "Select address...";
strings_["paste"] = "Paste";
strings_["max"] = "Max";
strings_["available"] = "Available";
strings_["invalid_address"] = "Invalid address format";
strings_["memo_z_only"] = "Note: Memos are only available when sending to shielded (z) addresses";
strings_["characters"] = "characters";
strings_["from"] = "From";
strings_["to"] = "To";
strings_["sending"] = "Sending transaction";
strings_["confirm_send"] = "Confirm Send";
strings_["confirm_transaction"] = "Confirm Transaction";
strings_["confirm_and_send"] = "Confirm & Send";
strings_["cancel"] = "Cancel";
// Wallet-switch "stop the running node?" confirmation
strings_["switch_stopnode_title"] = "Stop the running node?";
strings_["switch_stopnode_warn"] = "A node is already running that this wallet didn't start.";
strings_["switch_stopnode_body"] = "Switching wallets restarts the node on the wallet you selected. The running node will be stopped and relaunched on the new wallet — if you kept it running on purpose, it comes back up automatically.";
strings_["switch_stopnode_confirm"] = "Stop node & switch";
// Wallet-switch live progress modal
strings_["switch_progress_title"] = "Switching wallet";
strings_["switch_progress_failed_title"] = "Wallet switch failed";
strings_["switch_progress_stopping"] = "Stopping the current node";
strings_["switch_progress_starting"] = "Starting the node on the new wallet";
strings_["switch_progress_reconnecting"] = "Reconnecting";
strings_["switch_progress_hint"] = "A graceful shutdown can take up to a minute.";
strings_["switch_progress_background"] = "Continue in background";
strings_["switch_progress_from_label"] = "from";
strings_["switch_progress_elapsed"] = "Elapsed";
strings_["switch_progress_default_wallet"] = "Default wallet";
strings_["switch_progress_external_wallet"] = "External wallet";
strings_["switch_corrupt_body"] = "This wallet appears corrupt — the node couldn't open it. Restore it from a backup, re-create it, or try to repair it.";
strings_["switch_corrupt_repair"] = "Try to repair (salvage)";
// Block-database recovery (offered when the node aborts on an unreadable/format-mismatched block DB).
strings_["block_db_reindex_title"] = "Rebuild block database?";
strings_["block_db_reindex_warn"] = "The node can't read its block database.";
strings_["block_db_reindex_body"] = "This usually happens after a daemon update changes the on-disk format, or if the block index is damaged. Your wallet and coins are safe — the node just can't load the chain, so balances show as zero.\n\nRebuilding re-reads your existing block files and can take a while (it also rescans your wallet). Nothing is downloaded.";
strings_["block_db_reindex_confirm"] = "Rebuild block database";
strings_["block_db_reindex_notify"] = "The node can't read its block database (often after a daemon update). Rebuild it to restore your balance — see the prompt, or Settings Node.";
strings_["block_db_reindex_started"] = "Rebuilding the block database from your blocks — this can take a while.";
// Wallet auto-recovery warning (the node moved wallet.dat aside and loaded a salvaged copy).
strings_["wallet_recovered_title"] = "Your wallet was auto-recovered";
strings_["wallet_recovered_warn"] = "The node moved your wallet aside and loaded a salvaged copy.";
strings_["wallet_recovered_body"] = "On startup the node decided your wallet.dat looked damaged and recovered it automatically. Your ORIGINAL wallet was NOT deleted — it was renamed to \"wallet.<numbers>.bak\" in your data folder, and a salvaged copy is loaded now.\n\nThe salvaged copy may be incomplete, so the balance shown here could be wrong — don't treat it as final.\n\nThis is often a false alarm caused by leftover database files (e.g. after moving the wallet between machines). To restore your original: quit the wallet, then in the data folder rename the current wallet.dat aside, rename \"wallet.<numbers>.bak\" back to \"wallet.dat\", delete the \"database\" folder and any \"__db.*\" files, and reopen.";
strings_["wallet_recovered_open_folder"] = "Open data folder";
strings_["wallet_recovered_dismiss"] = "Keep salvaged copy";
strings_["wallet_recovered_restore"] = "Restore original wallet";
strings_["wallet_recovered_notify"] = "The node recovered your wallet and moved the original to a .bak — your shown balance may be incomplete. See the prompt to restore it.";
// One-click "Restore original wallet" flow.
strings_["wallet_restore_started"] = "Restoring your original wallet and restarting the node…";
strings_["wallet_restore_busy"] = "The node is busy restarting — try again in a moment.";
strings_["wallet_restore_ok"] = "Original wallet restored. The node is loading it now.";
strings_["wallet_restore_no_backup"] = "Couldn't find a wallet.<timestamp>.bak to restore. Nothing was changed.";
strings_["wallet_restore_bad_backup"] = "The backup wallet file looks unreadable, so it was NOT restored — your current wallet is unchanged. Restore from your own backup instead.";
strings_["wallet_restore_stop_failed"] = "The node didn't stop in time, so nothing was changed. Try again.";
strings_["wallet_restore_move_failed"] = "Couldn't set the current wallet aside — nothing was changed.";
strings_["wallet_restore_copy_failed"] = "Couldn't install the backup wallet; your current wallet was left in place.";
strings_["wallet_restore_no_restart"] = "Your original wallet was restored, but the node didn't restart — start it from Settings.";
// Receive Tab
strings_["receiving_addresses"] = "Your Receiving Addresses";
strings_["new_z_shielded"] = "New z-Address (Shielded)";
strings_["new_t_transparent"] = "New t-Address (Transparent)";
strings_["address_details"] = "Address Details";
strings_["view_on_explorer"] = "View on Explorer";
strings_["qr_code"] = "QR Code";
strings_["show_qr"] = "Show QR";
strings_["hide_qr"] = "Hide QR";
strings_["request_payment"] = "Request Payment";
// Transactions Tab
strings_["date"] = "Date";
strings_["status"] = "Status";
strings_["confirmations"] = "Confirmations";
strings_["confirmed"] = "Confirmed";
strings_["pending"] = "Pending";
strings_["sent"] = "sent";
strings_["received"] = "received";
strings_["mined"] = "mined";
// Mining Tab
strings_["mining_control"] = "Mining Control";
strings_["start_mining"] = "Start Mining";
strings_["stop_mining"] = "Stop Mining";
strings_["mining_threads"] = "Mining Threads";
strings_["mining_statistics"] = "Mining Statistics";
strings_["local_hashrate"] = "Local Hashrate";
strings_["network_hashrate"] = "Network Hashrate";
strings_["difficulty"] = "Difficulty";
strings_["est_time_to_block"] = "Est. Time to Block";
strings_["mining_off"] = "Mining is OFF";
strings_["mining_on"] = "Mining is ON";
// Peers Tab
strings_["connected_peers"] = "Connected Peers";
strings_["banned_peers"] = "Banned Peers";
strings_["ip_address"] = "IP Address";
strings_["version"] = "Version";
strings_["height"] = "Height";
strings_["ping"] = "Ping";
strings_["ban"] = "Ban";
strings_["unban"] = "Unban";
strings_["clear_all_bans"] = "Clear All Bans";
// Market Tab
strings_["price_chart"] = "Price Chart";
strings_["current_price"] = "Current Price";
strings_["24h_change"] = "24h Change";
strings_["24h_volume"] = "24h Volume";
strings_["market_cap"] = "Market Cap";
// Settings
strings_["general"] = "General";
strings_["display"] = "Display";
strings_["network"] = "Network";
strings_["theme"] = "Theme";
strings_["language"] = "Language";
strings_["clock_format"] = "Clock format";
strings_["tt_clock_format"] = "24-hour or 12-hour clock, used across the app. The Chat tab can override it in its own settings.";
strings_["dragonx_green"] = "DragonX (Green)";
strings_["dark"] = "Dark";
strings_["light"] = "Light";
strings_["allow_custom_fees"] = "Allow custom fees";
strings_["use_embedded_daemon"] = "Use embedded dragonxd";
strings_["save"] = "Save";
strings_["close"] = "Close";
// Menu
strings_["file"] = "File";
strings_["edit"] = "Edit";
strings_["view"] = "View";
strings_["help"] = "Help";
strings_["import_private_key"] = "Import Private Key...";
strings_["backup_wallet"] = "Backup Wallet...";
strings_["exit"] = "Exit";
strings_["about_dragonx"] = "About ObsidianDragon";
strings_["refresh_now"] = "Refresh Now";
// Dialogs
strings_["about"] = "About";
strings_["import"] = "Import";
strings_["export"] = "Export";
strings_["copy_to_clipboard"] = "Copy to Clipboard";
// Status
strings_["connected"] = "Connected";
strings_["disconnected"] = "Disconnected";
strings_["connecting"] = "Connecting...";
strings_["syncing"] = "Syncing...";
strings_["block"] = "Block";
strings_["no_addresses_available"] = "No addresses available";
// Status bar
strings_["sb_warming_up"] = "Warming up...";
strings_["sb_block"] = "Block: %d";
strings_["sb_peers"] = "Peers: %zu";
strings_["sb_net_ghs"] = "Net: %.2f GH/s";
strings_["sb_net_mhs"] = "Net: %.2f MH/s";
strings_["sb_net_khs"] = "Net: %.2f KH/s";
strings_["sb_net_hs"] = "Net: %.1f H/s";
strings_["sb_mining_hs"] = "%.1f H/s";
strings_["sb_syncing_eta"] = "Syncing %.1f%% (%d left, %.0f blk/s, ~%s)";
strings_["sb_syncing_basic"] = "Syncing %.1f%% (%d left)";
strings_["sb_rescanning_pct"] = "Rescanning %.0f%%";
strings_["sb_rescanning"] = "Rescanning";
strings_["sb_building_witnesses_pct"] = "Rebuilding witnesses %.0f%%";
strings_["sb_building_witnesses"] = "Setting witnesses";
strings_["sb_witness_cache"] = "Rebuilding witnesses";
strings_["sb_importing_keys"] = "Importing keys";
strings_["sb_daemon_not_found"] = "Daemon not found";
strings_["sb_loading_config"] = "Loading configuration...";
strings_["sb_waiting_config"] = "Waiting for daemon config...";
strings_["sb_no_conf"] = "No DRAGONX.conf found";
strings_["sb_starting_daemon"] = "Starting dragonxd...";
strings_["sb_connecting_daemon"] = "Connecting to dragonxd...";
strings_["sb_auth_failed"] = "Auth failed — check rpcuser/rpcpassword";
strings_["sb_waiting_daemon"] = "Waiting for dragonxd to start...";
strings_["sb_waiting_daemon_err"] = "Waiting for dragonxd — %s";
strings_["sb_connecting_external"] = "Connecting to external daemon...";
strings_["sb_connecting_generic"] = "Connecting to daemon...";
strings_["sb_connecting_err"] = "Connecting to daemon — %s";
strings_["sb_daemon_crashed"] = "Daemon crashed %d times";
strings_["sb_daemon_start_failed"] = "Couldn't start dragonxd";
strings_["sb_block_db_unreadable"] = "Block database unreadable — rebuild required";
// Persistent node-status banner (App::renderNodeStatusBanner).
strings_["node_banner_offline_title"] = "Not connected to the DragonX node";
strings_["node_banner_crashed_title"] = "The node stopped unexpectedly";
strings_["node_banner_lite_open_failed"] = "Couldn't open your wallet";
strings_["node_banner_reconnect"] = "Reconnect";
strings_["node_banner_restart"] = "Restart node";
// Refresh-staleness badge (W6-2) on the Total Balance card.
strings_["data_stale_prefix"] = "Updated";
strings_["data_stale_tooltip"] =
"Balance may be out of date — the wallet hasn't received a fresh update recently. "
"Check your node connection.";
// Persistent alert-history panel (status-bar bell).
strings_["alerts_history_tooltip"] = "Recent alerts";
strings_["alerts_recent"] = "RECENT ALERTS";
strings_["alerts_none"] = "No alerts yet";
strings_["alerts_clear"] = "Clear alert history";
strings_["daemon_port_busy_warn"] =
"Port " DRAGONX_DEFAULT_RPC_PORT " is in use but isn't responding as a DragonX node. "
"Close the program using it (or free the port), then restart — the wallet can't start "
"its own node while the port is taken.";
strings_["sb_extracting_sapling"] = "Extracting Sapling parameters...";
strings_["sb_sapling_failed"] = "Failed to extract Sapling parameters.";
strings_["sb_sapling_not_found"] = "Sapling parameters not found.";
strings_["sb_daemon_extract_failed"] = "Failed to write daemon files — check free disk space and permissions.";
strings_["sb_daemon_files_failed"] = "Failed to write daemon files to %s — check free disk space and permissions.";
strings_["loading_stall_title"] = "Taking longer than expected";
strings_["loading_stall_body"] = "The daemon has been initializing for %.0fs. This can be normal after an update or on first launch (loading the block index or rescanning) — it will connect automatically once ready.";
strings_["loading_stall_hint"] = "Still stuck? Open Settings and use Restart Daemon, or check the Console for details.";
strings_["sb_plaintext_remote_blocked"] = "Refusing to send RPC credentials over plaintext to a remote host. Add rpcallowplaintext=1 to DRAGONX.conf to allow it, or enable TLS with rpctls=1.";
strings_["settings_open_log_folder"] = "Open log folder";
strings_["settings_copy_diagnostics"] = "Copy diagnostics";
strings_["settings_diagnostics_copied"] = "Diagnostics copied to clipboard";
strings_["tt_open_log_folder"] = "Open the folder containing the debug and crash logs";
strings_["tt_copy_diagnostics"] = "Copy a support snapshot (version, daemon/wallet/log state — no secrets) to the clipboard";
strings_["sb_dragonxd_running"] = "dragonxd running";
strings_["sb_dragonxd_stopping"] = "Stopping dragonxd...";
strings_["sb_dragonxd_stopped"] = "dragonxd stopped";
strings_["sb_restarting_daemon"] = "Restarting daemon...";
// Errors & Messages
strings_["error"] = "Error";
strings_["success"] = "Success";
strings_["warning"] = "Warning";
strings_["amount_exceeds_balance"] = "Amount exceeds balance";
strings_["transaction_sent"] = "Transaction sent successfully";
// --- Common / Shared ---
strings_["add"] = "Add";
strings_["address_copied"] = "Address copied to clipboard";
strings_["address_label"] = "Address:";
strings_["amount_label"] = "Amount:";
strings_["date_label"] = "Date:";
strings_["delete"] = "Delete";
strings_["fee_label"] = "Fee:";
strings_["file_save_location"] = "File will be saved in: ~/.config/ObsidianDragon/";
strings_["hide"] = "Hide";
strings_["label"] = "Label:";
strings_["loading"] = "Loading...";
strings_["memo_label"] = "Memo:";
strings_["notes"] = "Notes";
strings_["notes_optional"] = "Notes (optional):";
strings_["output_filename"] = "Output filename:";
strings_["paste_from_clipboard"] = "Paste from Clipboard";
strings_["show"] = "Show";
strings_["time_days_ago"] = "%d days ago";
strings_["time_hours_ago"] = "%d hours ago";
strings_["time_minutes_ago"] = "%d minutes ago";
strings_["time_seconds_ago"] = "%d seconds ago";
strings_["unknown"] = "Unknown";
strings_["validating"] = "Validating...";
strings_["warning_upper"] = "WARNING!";
// --- About Dialog ---
strings_["about_block_explorer"] = "Block Explorer";
strings_["about_block_height"] = "Block Height:";
strings_["about_build_date"] = "Build Date:";
strings_["about_build_type"] = "Build Type:";
strings_["about_chain"] = "Chain:";
strings_["about_connections"] = "Connections:";
strings_["about_credits"] = "Credits";
strings_["about_daemon"] = "Daemon:";
strings_["about_debug"] = "Debug";
strings_["about_edition"] = "ImGui Edition";
strings_["about_github"] = "GitHub";
strings_["about_imgui"] = "ImGui:";
strings_["about_license"] = "License";
strings_["about_license_text"] = "This software is released under the GNU General Public License v3 (GPLv3). You are free to use, modify, and distribute this software under the terms of the license.";
strings_["about_peers_count"] = "%zu peers";
strings_["about_release"] = "Release";
strings_["about_title"] = "About ObsidianDragon";
strings_["about_version"] = "Version:";
strings_["about_website"] = "Website";
// --- Address Book Dialog ---
strings_["address_book_add"] = "Add Address";
strings_["address_book_add_new"] = "Add New";
strings_["contact_global"] = "Show in every wallet (global contact)";
strings_["contact_global_tt"] = "On: this contact stays visible no matter which wallet you load. Off: it belongs to the current wallet only.";
// Contact edit dialog: live preview + avatar picker
strings_["contact_preview_name"] = "Contact name";
strings_["contact_preview_addr"] = "Address will appear here";
strings_["contact_avatar"] = "AVATAR";
strings_["contact_avatar_badge"] = "Badge";
strings_["contact_avatar_icon"] = "Icon";
strings_["contact_avatar_image"] = "Image";
strings_["contact_avatar_badge_hint"] = "The badge is chosen automatically from the address type.";
strings_["contact_avatar_shielded"] = "Shielded";
strings_["contact_avatar_transparent"] = "Transparent";
strings_["contact_avatar_choose"] = "Choose image\xE2\x80\xA6";
strings_["contact_avatar_remove"] = "Remove";
strings_["contact_avatar_image_hint"] = "The image is copied into the app so it stays available if the original moves.";
strings_["contact_avatar_copy_failed"] = "Could not copy that image.";
strings_["contact_wallet_loading"] = "The wallet is still loading — tick \"Show in every wallet\", or try again in a moment.";
strings_["contact_avatar_bad_image"] = "That image couldn't be loaded.";
strings_["contact_global_badge_tt"] = "Global contact — visible in every wallet";
strings_["address_book_added"] = "Address added to book";
strings_["address_book_count"] = "%zu addresses saved";
strings_["address_book_count_one"] = "%zu address saved";
strings_["address_book_deleted"] = "Entry deleted";
strings_["address_book_edit"] = "Edit Address";
strings_["address_book_empty"] = "No saved addresses. Click 'Add New' to add one.";
strings_["address_book_exists"] = "Address already exists in book";
strings_["address_book_title"] = "Address Book";
strings_["address_book_update_failed"] = "Failed to update - address may be duplicate";
strings_["address_book_updated"] = "Address updated";
// --- Backup Dialog ---
strings_["backup_backing_up"] = "Backing up...";
strings_["backup_create"] = "Create Backup";
strings_["backup_created"] = "Wallet backup created";
strings_["backup_description"] = "Create a backup of your wallet.dat file. This file contains all your private keys and transaction history. Store the backup in a secure location.";
strings_["backup_destination"] = "Backup destination:";
strings_["backup_warn"] = "This file holds all your private keys \xE2\x80\x94 keep it somewhere safe.";
strings_["backup_overwrite_confirm"] = "A file already exists there \xE2\x80\x94 Save again to overwrite it.";
strings_["backup_tip_external"] = "Store backups on external drives or cloud storage";
strings_["backup_tip_multiple"] = "Create multiple backups in different locations";
strings_["backup_tip_test"] = "Test restoring from backup periodically";
strings_["backup_tips"] = "Tips:";
strings_["backup_title"] = "Backup Wallet";
strings_["backup_wallet_not_found"] = "Warning: wallet.dat not found at expected location";
// --- Block Info Dialog ---
strings_["block_bits"] = "Bits:";
strings_["block_click_next"] = "Click to view next block";
strings_["block_click_prev"] = "Click to view previous block";
strings_["block_get_info"] = "Get Block Info";
strings_["block_hash"] = "Block Hash:";
strings_["block_height"] = "Block Height:";
strings_["block_info_title"] = "Block Information";
strings_["block_merkle_root"] = "Merkle Root:";
strings_["block_nav_next"] = "Next >>";
strings_["block_nav_prev"] = "<< Previous";
strings_["block_next"] = "Next Block:";
strings_["block_previous"] = "Previous Block:";
strings_["block_size"] = "Size:";
strings_["block_timestamp"] = "Timestamp:";
strings_["block_transactions"] = "Transactions:";
// --- Console Tab ---
strings_["console_auto_scroll"] = "Auto-scroll";
strings_["console_available_commands"] = "Available commands:";
strings_["console_quit_note"] = "'quit'/'exit' aren't needed here — just close the window.";
strings_["lite_console_help_passthrough"] = "Any other input runs as a lite-wallet console command.";
strings_["lite_console_backend_commands"] = "Backend commands:";
strings_["console_no_output"] = "(no output)";
strings_["console_backend_unavailable"] = "No backend";
strings_["console_last_error"] = "Last error:";
strings_["console_not_connected_lite"] = "Error: no wallet open";
strings_["console_stop_confirm_node"] = "'stop' will shut down the node and disconnect the wallet. Type 'stop' again to confirm.";
strings_["console_capturing_output"] = "Capturing daemon output...";
strings_["console_clear"] = "Clear";
strings_["console_clear_console"] = "Clear Console";
strings_["console_cleared"] = "Console cleared";
strings_["console_click_commands"] = "Click commands above to insert them";
strings_["console_click_insert"] = "Click to insert";
strings_["console_click_insert_params"] = "Click to insert with parameters";
strings_["console_close"] = "Close";
strings_["console_commands"] = "Commands";
strings_["console_common_rpc"] = "Common RPC commands:";
strings_["console_completions"] = "Completions:";
strings_["console_connected"] = "Connected to daemon";
strings_["console_copy_all"] = "Copy All";
strings_["console_copy_selected"] = "Copy";
strings_["console_daemon"] = "Daemon";
strings_["console_daemon_error"] = "Daemon error!";
strings_["console_daemon_started"] = "Daemon started";
strings_["console_daemon_stopped"] = "Daemon stopped";
strings_["daemon_version"] = "Daemon";
strings_["console_disconnected"] = "Disconnected from daemon";
strings_["console_errors"] = "Errors";
strings_["console_filter_hint"] = "Filter output...";
strings_["console_help_clear"] = " clear - Clear the console";
strings_["console_help_getbalance"] = " getbalance - Show transparent balance";
strings_["console_help_getblockcount"] = " getblockcount - Show current block height";
strings_["console_help_getinfo"] = " getinfo - Show node information";
strings_["console_help_getmininginfo"] = " getmininginfo - Show mining status";
strings_["console_help_getpeerinfo"] = " getpeerinfo - Show connected peers";
strings_["console_help_gettotalbalance"] = " gettotalbalance - Show total balance";
strings_["console_help_help"] = " help - Show this help message";
strings_["console_help_setgenerate"] = " setgenerate - Control mining";
strings_["console_help_stop"] = " stop - Stop the daemon";
strings_["console_line_count"] = "%zu lines";
strings_["console_matches"] = "matches";
strings_["console_copy_value"] = "Copy";
strings_["console_new_lines"] = "%d new lines";
strings_["console_no_daemon"] = "No daemon";
strings_["console_not_connected"] = "Error: Not connected to daemon";
strings_["console_rpc_reference"] = "RPC Command Reference";
strings_["console_backend_reference"] = "Backend Command Reference";
strings_["console_rpc_trace"] = "RPC";
strings_["console_app"] = "App";
strings_["console_show_app_output"] = "Show [app] wallet log lines";
strings_["console_search_commands"] = "Search commands...";
strings_["console_select_all"] = "Select All";
strings_["console_show_daemon_output"] = "Show daemon output";
strings_["console_show_errors_only"] = "Show errors only";
strings_["console_show_rpc_ref"] = "Show RPC command reference";
strings_["console_show_backend_ref"] = "Show backend command reference";
strings_["console_show_rpc_trace"] = "Show app RPC calls";
strings_["console_showing_lines"] = "Showing %zu of %zu lines";
strings_["console_starting_node"] = "Starting node...";
strings_["console_status_error"] = "Error";
strings_["console_status_running"] = "Running";
strings_["console_status_starting"] = "Starting";
strings_["console_status_stopped"] = "Stopped";
strings_["console_status_stopping"] = "Stopping";
strings_["console_status_unknown"] = "Unknown";
strings_["console_tab_completion"] = "Tab for completion";
strings_["console_type_help"] = "Type 'help' for available commands";
strings_["console_welcome"] = "Welcome to ObsidianDragon Console";
strings_["console_zoom_in"] = "Zoom in";
strings_["console_zoom_out"] = "Zoom out";
strings_["console_toggle_accents"] = "Toggle line color accents";
strings_["console_toggle_text_color"] = "Toggle line text colors";
strings_["console_accents"] = "Color accents";
strings_["console_text_colors"] = "Text colors";
strings_["console_cat_control"] = "Control";
strings_["console_cat_network"] = "Network";
strings_["console_cat_blockchain"] = "Blockchain";
strings_["console_cat_mining"] = "Mining";
strings_["console_cat_wallet"] = "Wallet";
strings_["console_cat_raw_transactions"] = "Raw Transactions";
strings_["console_cat_utility"] = "Utility";
strings_["console_cat_sync"] = "Sync";
strings_["console_cat_send"] = "Send";
strings_["console_cat_keys"] = "Keys & Security";
strings_["console_cat_advanced"] = "Advanced";
strings_["console_ref_search_hint"] = "Search by name or task\xE2\x80\xA6";
strings_["console_ref_parameters"] = "Parameters";
strings_["console_ref_no_params"] = "Takes no parameters.";
strings_["console_ref_optional"] = "optional";
strings_["console_ref_value"] = "value";
strings_["console_ref_example"] = "Example";
strings_["console_ref_builds"] = "Builds";
strings_["console_ref_destructive"] = "Consequential";
strings_["console_ref_run_confirm"] = "Run %s now? This is a consequential command.";
strings_["console_ref_cancel"] = "Cancel";
strings_["console_ref_run"] = "Run";
strings_["console_ref_insert"] = "Insert into console";
strings_["console_ref_insert_run"] = "Insert & run";
strings_["console_ref_select_hint"] = "Select a command to see what it does.";
strings_["console_ref_no_match"] = "No commands match.";
// --- Export All Keys Dialog ---
strings_["export_keys_btn"] = "Export Keys";
strings_["export_keys_danger"] = "DANGER: This will export ALL private keys from your wallet! Anyone with access to this file can steal your funds. Store it securely and delete after use.";
strings_["export_keys_include_t"] = "Include T-addresses (transparent)";
strings_["export_keys_include_z"] = "Include Z-addresses (shielded)";
strings_["export_keys_options"] = "Export options:";
strings_["export_keys_success"] = "Keys exported successfully";
strings_["export_keys_select_type"] = "Select at least one address type";
strings_["export_keys_not_connected"] = "Not connected to the daemon";
strings_["export_keys_none_addrs"] = "No addresses to export";
strings_["export_keys_none_result"] = "No keys exported (0 of %d) \xE2\x80\x94 unlock the wallet and try again.";
strings_["export_keys_none_toast"] = "No keys could be exported \xE2\x80\x94 is the wallet unlocked?";
strings_["export_keys_write_fail"] = "Failed to write the key file.";
strings_["export_keys_partial"] = "Exported %d of %d keys \xE2\x80\x94 incomplete (some had no spending key, or the wallet is locked).";
strings_["export_keys_partial_toast"] = "Partial export: %d of %d keys";
strings_["export_keys_title"] = "Export All Private Keys";
// --- Export Transactions Dialog ---
strings_["export_tx_count"] = "Export %zu transactions to CSV file.";
strings_["export_tx_file_fail"] = "Failed to create CSV file";
strings_["export_tx_none"] = "No transactions to export";
strings_["export_tx_success"] = "Transactions exported successfully";
strings_["export_tx_title"] = "Export Transactions to CSV";
// --- Import Key Dialog ---
strings_["import_key_btn"] = "Import Key(s)";
strings_["import_key_formats"] = "Supported key formats:";
strings_["import_key_full_rescan"] = "(0 = full rescan)";
strings_["import_key_label"] = "Private Key(s):";
strings_["import_key_no_valid"] = "No valid keys found in input";
strings_["import_key_rescan"] = "Rescan blockchain after import";
strings_["import_key_start_height"] = "Start height:";
strings_["import_key_success"] = "Keys imported successfully";
strings_["import_key_t_format"] = "T-address WIF private keys";
strings_["import_key_title"] = "Import Private Key";
strings_["import_key_tooltip"] = "Enter one or more private keys, one per line.\nSupports both z-address and t-address keys.\nLines starting with # are treated as comments.";
strings_["import_key_warning"] = "Warning: Never share your private keys! Importing keys from untrusted sources can compromise your wallet.";
strings_["import_key_z_format"] = "Z-address spending keys (secret-extended-key-...)";
strings_["import_key_warn"] = "Only import a key you own \xE2\x80\x94 it grants access to its funds.";
strings_["import_key_need_node"] = "Connect a running node to import a key.";
strings_["import_key_field"] = "Key";
strings_["import_key_reveal_tip"] = "Show/hide the key";
strings_["import_key_type_tkey"] = "Transparent private key";
strings_["import_key_type_zspend"] = "Shielded spending key";
strings_["import_key_type_zview"] = "Shielded viewing key (watch-only)";
strings_["import_key_type_unknown"] = "Unrecognized key format";
strings_["import_key_rescanning"] = "Importing & rescanning \xE2\x80\x94 this can take several minutes";
strings_["import_key_done"] = "Imported. Wallet is rescanning.";
strings_["import_key_address"] = "Address:";
strings_["import_key_import"] = "Import";
// Viewing-key (watch-only) import — separate button + dialog mode.
strings_["import_viewkey_title"] = "Import Viewing Key";
strings_["import_viewkey_note"] = "Watch-only: a viewing key reveals an address's balance and transactions but cannot spend its funds.";
strings_["import_viewkey_field"] = "Viewing key";
strings_["import_key_wrong_type"] = "This looks like a viewing key. Use \"Import Viewing Key\" instead.";
strings_["import_viewkey_wrong_type"] = "This looks like a spending key. Use \"Import Private Key\" instead.";
strings_["import_scan_label"] = "Scan from block height (optional)";
strings_["import_scan_hint"] = "0 = rescan from the start";
strings_["import_scan_transparent"] = "Transparent keys always rescan fully";
strings_["import_scan_tip"] = "current height";
strings_["paste_clip_empty"] = "Clipboard is empty";
// Sweep (import a spending key, then move all its funds to your own address).
strings_["sweep_toggle"] = "Sweep to my wallet (don't keep the key)";
strings_["sweep_caveat"] = "Imports the key to sign one transaction moving all its funds to your address. The key stays in your wallet with an empty balance.";
strings_["sweep_dest_label"] = "Send swept funds to";
strings_["sweep_dest_new"] = "New shielded address (recommended)";
strings_["sweep_button"] = "Sweep";
strings_["sweep_done"] = "Done \xE2\x80\x94 funds swept to your address.";
strings_["sweep_to"] = "Swept to:";
strings_["sweep_tx"] = "Transaction:";
// --- Key Export Dialog ---
strings_["key_export_fetching"] = "Fetching key from wallet...";
strings_["key_export_failed"] = "Couldn't export the key \xE2\x80\x94 unlock the wallet (if encrypted) and try again.";
strings_["key_export_private_key"] = "Private Key:";
strings_["key_export_private_warning"] = "Keep this key SECRET! Anyone with this key can spend your funds. Never share it online or with untrusted parties.";
strings_["key_export_reveal"] = "Reveal Key";
strings_["key_export_viewing_key"] = "Viewing Key:";
strings_["key_export_viewing_warning"] = "This viewing key allows others to see your incoming transactions and balance, but NOT spend your funds. Share only with trusted parties.";
// --- Market Tab ---
strings_["market_12h"] = "12h";
strings_["market_18h"] = "18h";
strings_["market_24h"] = "24h";
strings_["market_col_name"] = "Name";
strings_["market_col_value"] = "Value";
strings_["market_col_trend"] = "Trend";
strings_["market_24h_volume"] = "24H VOLUME";
strings_["market_6h"] = "6h";
strings_["market_iv_live"] = "Live";
strings_["market_iv_1h"] = "1H";
strings_["market_iv_1d"] = "1D";
strings_["market_iv_1w"] = "1W";
strings_["market_iv_1m"] = "1M";
strings_["market_updated"] = "\xc2\xb7 Updated %s";
strings_["market_vol_short"] = "Vol";
strings_["market_cap_short"] = "Cap";
strings_["market_attribution"] = "Price data from CoinGecko";
strings_["market_btc_price"] = "BTC PRICE";
strings_["market_no_history"] = "No price history available";
strings_["market_chart_loading"] = "Loading price history";
strings_["market_style_line"] = "Switch to line chart";
strings_["market_style_candle"] = "Switch to candlesticks";
strings_["market_style_line_label"] = "Line";
strings_["market_style_candle_label"] = "Candlestick";
strings_["market_settings_title"] = "Market settings";
strings_["market_settings_tip"] = "Market options";
strings_["market_opt_chart_style"] = "Chart style";
strings_["market_no_price"] = "No price data";
strings_["market_now"] = "Now";
strings_["market_pct_shielded"] = "%.0f%% Shielded";
strings_["market_portfolio"] = "PORTFOLIO";
strings_["portfolio_all_funds"] = "All funds";
strings_["portfolio_manage"] = "Manage\xE2\x80\xA6";
strings_["portfolio_icon"] = "Icon";
strings_["portfolio_color"] = "Color";
strings_["portfolio_no_icon"] = "None";
strings_["portfolio_custom_color"] = "Custom color\xE2\x80\xA6";
strings_["portfolio_outline_opacity"] = "Outline opacity";
strings_["portfolio_price"] = "Price";
strings_["portfolio_price_usd"] = "Market \xC2\xB7 USD";
strings_["portfolio_price_btc"] = "Market \xC2\xB7 BTC";
strings_["portfolio_price_drgx"] = "DRGX only";
strings_["portfolio_price_manual"] = "Manual";
strings_["portfolio_manual_price"] = "Price / DRGX";
strings_["portfolio_currency"] = "Currency";
strings_["portfolio_show"] = "Show:";
strings_["portfolio_show_value"] = "Value";
strings_["portfolio_show_24h"] = "24h";
strings_["portfolio_show_sparkline"] = "Sparkline";
strings_["portfolio_spark_min"] = "Minute";
strings_["portfolio_spark_hour"] = "Hour";
strings_["portfolio_spark_day"] = "Day";
strings_["portfolio_spark_week"] = "Week";
strings_["portfolio_spark_month"] = "Month";
strings_["portfolio_appearance"] = "Appearance";
strings_["portfolio_addresses_hdr"] = "Addresses";
strings_["portfolio_search"] = "Search addresses\xE2\x80\xA6";
strings_["portfolio_search_icons"] = "Search icons\xE2\x80\xA6";
strings_["portfolio_funded"] = "Funded";
strings_["portfolio_select_all"] = "All";
strings_["portfolio_select_shown"] = "Select all";
strings_["portfolio_group_name"] = "Group name";
strings_["portfolio_no_addr_match"] = "No addresses match";
strings_["portfolio_manage_title"] = "Manage portfolio";
strings_["portfolio_add_entry"] = "Add entry";
strings_["portfolio_wallet_loading"] = "Wait until the wallet finishes loading to add a group.";
strings_["portfolio_new_entry"] = "New entry";
strings_["portfolio_label"] = "Label";
strings_["portfolio_addresses_sel"] = "%d selected";
strings_["portfolio_all_shielded"] = "All shielded";
strings_["portfolio_all_transparent"] = "All transparent";
strings_["portfolio_clear_sel"] = "Clear";
strings_["portfolio_no_entries"] = "No custom entries yet. Add one to track a group of addresses.";
strings_["portfolio_style_label"] = "Portfolio style";
strings_["portfolio_style_compact"] = "Table";
strings_["portfolio_style_detailed"] = "Cards";
strings_["portfolio_style_featured"] = "Spotlight";
strings_["portfolio_edit"] = "Edit";
strings_["portfolio_delete"] = "Delete";
strings_["portfolio_save"] = "Save";
strings_["portfolio_cancel"] = "Cancel";
strings_["portfolio_revert"] = "Revert";
strings_["portfolio_close"] = "Close";
strings_["portfolio_save_need_name"] = "Enter a name to save this group.";
strings_["portfolio_save_need_address"] = "Add at least one address to save.";
strings_["portfolio_save_need_price"] = "Enter a manual price above 0 to save.";
strings_["portfolio_untitled"] = "Untitled";
strings_["portfolio_detail_empty"] = "Select a group on the left, or add one, to edit it.";
strings_["portfolio_add_to"] = "Add to portfolio";
strings_["portfolio_remove_from"] = "Remove from portfolio";
strings_["market_24h_change"] = "24h";
strings_["market_price_loading"] = "Loading price data...";
strings_["market_price_unavailable"] = "Price data unavailable";
strings_["market_refresh_price"] = "Refresh price data";
strings_["market_trade_on"] = "Trade on %s";
// --- Mining Tab ---
strings_["mining_active"] = "Active";
strings_["mining_address_copied"] = "Mining address copied";
strings_["mining_all_time"] = "All Time";
strings_["mining_already_saved"] = "Pool URL already saved";
strings_["mining_block_copied"] = "Block hash copied";
strings_["mining_chart_1m_ago"] = "1m ago";
strings_["mining_chart_5m_ago"] = "5m ago";
strings_["mining_chart_now"] = "Now";
strings_["mining_chart_start"] = "Start";
strings_["mining_click"] = "Click";
strings_["mining_click_copy_address"] = "Click to copy address";
strings_["mining_click_copy_block"] = "Click to copy block hash";
strings_["mining_click_copy_difficulty"] = "Click to copy difficulty";
strings_["mining_connected"] = "Connected";
strings_["mining_connecting"] = "Connecting...";
strings_["mining_difficulty_copied"] = "Difficulty copied";
strings_["mining_est_block"] = "Est. Block";
strings_["mining_est_daily"] = "Est. Daily";
strings_["mining_filter_all"] = "All";
strings_["mining_filter_tip_all"] = "Show all earnings";
strings_["mining_filter_tip_pool"] = "Show pool earnings only";
strings_["mining_filter_tip_solo"] = "Show solo earnings only";
strings_["mining_idle_off_tooltip"] = "Enable idle mining";
strings_["mining_idle_on_tooltip"] = "Disable idle mining";
strings_["mining_idle_scale_on_tooltip"] = "Thread scaling: ON\nClick to switch to start/stop mode";
strings_["mining_idle_scale_off_tooltip"] = "Start/stop mode: ON\nClick to switch to thread scaling mode";
strings_["mining_idle_gpu_on_tooltip"] = "GPU-aware: ON\nGPU activity (video, games) prevents idle mining\nClick for unrestricted mode";
strings_["mining_idle_gpu_off_tooltip"] = "Unrestricted: ON\nOnly keyboard/mouse input determines idle state\nClick to enable GPU-aware detection";
strings_["mining_idle_threads_active_tooltip"] = "Threads when user is active";
strings_["mining_idle_threads_idle_tooltip"] = "Threads when system is idle";
strings_["mining_local_hashrate"] = "Local Hashrate";
strings_["mining_mine"] = "Mine";
strings_["mining_mining_addr"] = "Mining Addr";
strings_["mining_network"] = "Network";
strings_["mining_no_blocks_yet"] = "No blocks found yet";
strings_["mining_no_payouts_yet"] = "No pool payouts yet";
strings_["mining_no_saved_addresses"] = "No saved addresses";
strings_["mining_no_saved_pools"] = "No saved pools";
strings_["mining_open_in_explorer"] = "Open in explorer";
strings_["mining_payout_address"] = "Payout Address";
strings_["mining_payout_tooltip"] = "Address to receive mining rewards";
strings_["mining_generate_z_address_hint"] = "Generate a Z address in the Receive tab to use as your payout address";
strings_["mining_pool"] = "Pool";
strings_["mining_payout_foreign"] = "⚠ This payout address isn't in your current wallet — mined rewards would go to a different wallet. Update it if you switched wallets.";
strings_["mining_pool_hashrate"] = "Pool Hashrate";
strings_["mining_pool_url"] = "Pool URL";
// Pool selection mode + auto-balance (mining tab).
strings_["mining_select_manual"] = "Manual";
strings_["mining_select_auto"] = "Auto-balance";
strings_["mining_manual_desc"] = "Manual: mine to the pool you pick from the list below.";
strings_["mining_auto_balance_desc"] = "Spreads miners across the official pools by hashrate to help decentralize the network. Checks each pool periodically.";
strings_["mining_suggested_pools"] = "Suggested pools";
strings_["mining_pools_header"] = "POOLS";
strings_["mining_pool_fee"] = "Fee";
strings_["mining_mining_here"] = "mining here";
strings_["mining_refresh"] = "Refresh";
strings_["mining_auto_balanced_to"] = "Auto-balanced mining to";
strings_["mining_recent_blocks"] = "RECENT BLOCKS";
strings_["mining_recent_payouts"] = "RECENT POOL PAYOUTS";
strings_["mining_remove"] = "Remove";
strings_["mining_reset_defaults"] = "Reset Defaults";
strings_["mining_benchmark_tooltip"] = "Find optimal thread count for this CPU";
strings_["mining_benchmark_testing"] = "Testing";
strings_["mining_benchmark_cooling"] = "Cooling";
strings_["mining_benchmark_stabilizing"] = "Stabilizing";
strings_["mining_benchmark_cancel"] = "Cancel benchmark";
strings_["mining_benchmark_result"] = "Optimal";
strings_["mining_benchmark_dismiss"] = "Dismiss";
strings_["mining_save_payout_address"] = "Save payout address";
strings_["mining_save_pool_url"] = "Save pool URL";
strings_["mining_saved_addresses"] = "Saved Addresses:";
strings_["mining_saved_pools"] = "Saved Pools:";
strings_["mining_shares"] = "Shares";
strings_["mining_show_chart"] = "Chart";
strings_["mining_show_log"] = "Log";
strings_["mining_solo"] = "Solo";
strings_["mining_starting"] = "Starting...";
strings_["mining_starting_tooltip"] = "Miner is starting...";
strings_["mining_stop"] = "Stop";
strings_["mining_stop_solo_for_pool"] = "Stop solo mining before starting pool mining";
strings_["mining_stop_solo_for_pool_settings"] = "Stop solo mining to change pool settings";
strings_["mining_stopping"] = "Stopping...";
strings_["mining_stopping_tooltip"] = "Miner is stopping...";
strings_["mining_syncing_tooltip"] = "Blockchain is syncing...";
strings_["mining_to_save"] = "to save";
strings_["mining_today"] = "Today";
strings_["mining_uptime"] = "Uptime";
strings_["mining_yesterday"] = "Yesterday";
// --- Miner (xmrig) updater ---
strings_["xmrig_update_button"] = "Update miner…";
strings_["xmrig_update_short"] = "Update";
strings_["xmrig_current"] = "Current:";
strings_["xmrig_none"] = "none";
strings_["xmrig_update_title"] = "Update Miner";
strings_["xmrig_stop_mining_first"] = "Stop mining before updating the miner.";
strings_["xmrig_checking"] = "Checking for the latest miner…";
strings_["xmrig_unavailable_title"] = "Miner updates unavailable";
strings_["xmrig_unavailable_body"] = "No miner build is available for this platform.";
strings_["xmrig_update_available"] = "A new miner is available";
strings_["xmrig_up_to_date"] = "The miner is up to date";
strings_["xmrig_latest"] = "Latest:";
strings_["xmrig_installed"] = "Installed:";
strings_["xmrig_version"] = "Version:";
strings_["xmrig_verify_note"] = "The download is checked against the release's published SHA-256 checksum before install.";
strings_["xmrig_download_install"] = "Download & install";
strings_["xmrig_reinstall"] = "Reinstall";
strings_["xmrig_downloading"] = "Downloading…";
strings_["xmrig_verifying"] = "Verifying…";
strings_["xmrig_installing"] = "Installing…";
strings_["xmrig_installed_ok"] = "Miner installed";
strings_["xmrig_update_failed"] = "Update failed";
strings_["xmrig_unknown_error"] = "Unknown error.";
strings_["xmrig_browse_releases"] = "Browse all releases…";
strings_["xmrig_loading_releases"] = "Loading releases…";
strings_["xmrig_latest_badge"] = "latest";
strings_["xmrig_status_current"] = "This version is installed";
strings_["xmrig_status_latest"] = "Latest version";
strings_["xmrig_status_older"] = "Older than your installed version";
strings_["xmrig_released"] = "Released:";
strings_["xmrig_no_notes"] = "No release notes for this version.";
strings_["xmrig_install_this"] = "Install this version";
strings_["xmrig_downgrade_note"] = "Installing a different miner version replaces the current one; stop mining first, then it takes effect on the next start.";
strings_["xmrig_active_tt"] = "The currently installed (active) miner";
strings_["xmrig_latest_tt"] = "Newest available version";
strings_["xmrig_prerelease_tt"] = "Pre-release / testing build";
// --- Shared release picker ("Browse all releases") ---
strings_["upd_select_version"] = "Select a version to install";
strings_["upd_install"] = "Install";
strings_["upd_reinstall"] = "Reinstall";
strings_["upd_prerelease"] = "pre-release";
strings_["upd_installed_badge"] = "installed";
strings_["upd_no_build_platform"] = "No build for this platform";
strings_["upd_back"] = "Back";
// --- Daemon (full node) updater — Settings → daemon binary panel ---
strings_["daemon_update_check"] = "Check for updates…";
strings_["tt_daemon_update_check"] = "Download and verify the latest dragonxd full node from the project Gitea, then restart to apply";
strings_["daemon_update_title"] = "Update Node";
strings_["daemon_update_checking"] = "Checking for the latest node…";
strings_["daemon_update_unavailable_title"]= "Node updates unavailable";
strings_["daemon_update_unavailable_body"] = "No node build is available for this platform.";
strings_["daemon_update_available"] = "A new node version is available";
strings_["daemon_update_up_to_date"] = "The node is up to date";
strings_["daemon_update_latest"] = "Latest:";
strings_["daemon_update_installed"] = "Installed:";
strings_["daemon_update_version"] = "Version:";
strings_["daemon_update_verify_note"] = "The download is verified against the release's published SHA-256 and a pinned ed25519 signature before install.";
strings_["daemon_update_download_install"] = "Download & install";
strings_["daemon_update_reinstall"] = "Reinstall";
strings_["daemon_update_downloading"] = "Downloading…";
strings_["daemon_update_verifying"] = "Verifying…";
strings_["daemon_update_installing"] = "Installing…";
strings_["daemon_update_installed_ok"] = "Node installed";
strings_["daemon_update_restart_note"] = "Restart the daemon to start running the new version.";
strings_["daemon_update_restart_now"] = "Restart daemon now";
strings_["daemon_update_later"] = "Later";
strings_["daemon_update_failed"] = "Update failed";
strings_["daemon_update_unknown_error"] = "Unknown error.";
strings_["daemon_update_browse"] = "Browse all releases…";
strings_["daemon_update_loading"] = "Loading releases…";
strings_["daemon_update_downgrade_note"] = "Older versions may be incompatible with your current chain data. Installing a different version takes effect after a daemon restart.";
strings_["daemon_update_latest_badge"] = "latest";
strings_["daemon_update_status_current"] = "This version is installed";
strings_["daemon_update_status_latest"] = "Latest version";
strings_["daemon_update_status_older"] = "Older than your installed version";
strings_["daemon_update_released"] = "Released:";
strings_["daemon_update_no_notes"] = "No release notes for this version.";
strings_["daemon_update_install_this"] = "Install this version";
strings_["daemon_update_active_tt"] = "The currently installed (active) node";
strings_["daemon_update_latest_tt"] = "Newest available version";
strings_["daemon_update_prerelease_tt"] = "Pre-release / testing build";
// --- Lite Network tab (server browser) ---
strings_["lite_net_title"] = "Lite Servers";
strings_["lite_net_intro"] = "Pick a server to use, or let the wallet choose one at random. Changes apply immediately.";
strings_["lite_net_use_random"] = "Use a random server each time";
strings_["lite_net_random_active"] = "Random server selection is active.";
strings_["lite_net_refresh"] = "Refresh";
strings_["lite_net_add"] = "Add";
strings_["lite_net_add_url_hint"] = "https://your-lite-server";
strings_["lite_net_add_label_hint"] = "Label (optional)";
strings_["lite_net_invalid_url"] = "Enter a valid http(s):// URL.";
strings_["lite_net_official"] = "Official";
strings_["lite_net_custom"] = "Custom";
strings_["lite_net_in_use"] = "In use";
strings_["lite_net_offline"] = "offline";
strings_["lite_net_checking"] = "checking…";
strings_["lite_net_hide"] = "Hide";
strings_["lite_net_unhide"] = "Unhide";
strings_["lite_net_show_hidden"] = "Show hidden servers";
strings_["lite_net_hidden_section"] = "Hidden servers";
strings_["lite_net_connected"] = "Connected";
strings_["lite_net_connecting"] = "Connecting";
strings_["lite_net_disconnected"] = "Not connected";
strings_["lite_net_syncing"] = "Syncing";
strings_["lite_net_synced"] = "Synced";
strings_["lite_net_random_server"] = "Random server";
strings_["lite_net_sync_label"] = "Sync";
strings_["lite_net_no_wallet"] = "No wallet open";
// --- Peers Tab ---
strings_["peers_avg_ping"] = "Avg Ping";
strings_["peers_ban_24h"] = "Ban Peer 24h";
strings_["peers_ban_score"] = "Ban Score: %d";
strings_["peers_banned"] = "Banned";
strings_["peers_banned_count"] = "Banned: %d";
strings_["peers_best_block"] = "Best Block";
strings_["peers_blockchain"] = "BLOCKCHAIN";
strings_["peers_blocks"] = "Blocks";
strings_["peers_blocks_left"] = "%d blocks left";
strings_["peers_clear_all_bans"] = "Clear All Bans";
strings_["peers_click_copy"] = "Click to copy";
strings_["peers_connected"] = "Connected";
strings_["peers_connected_count"] = "Connected: %d";
strings_["peers_copy_ip"] = "Copy IP";
strings_["peers_dir_in"] = "In";
strings_["peers_dir_out"] = "Out";
strings_["peers_hash_copied"] = "Hash copied";
strings_["peers_hashrate"] = "Hashrate";
strings_["peers_in_out"] = "In/Out";
strings_["peers_longest"] = "Longest";
strings_["peers_longest_chain"] = "Longest Chain";
strings_["peers_memory"] = "Memory";
strings_["peers_no_banned"] = "No banned peers";
strings_["peers_no_connected"] = "No connected peers";
strings_["peers_no_tls"] = "No TLS";
strings_["peers_notarized"] = "Notarized";
strings_["peers_p2p_port"] = "P2P Port";
strings_["peers_protocol"] = "Protocol";
strings_["peers_received"] = "Received";
strings_["peers_refresh"] = "Refresh";
strings_["peers_refresh_tooltip"] = "Refresh peer list";
strings_["peers_refreshing"] = "Refreshing...";
strings_["peers_sent"] = "Sent";
strings_["peers_tt_id"] = "ID: %d";
strings_["peers_tt_received"] = "Received: %s";
strings_["peers_tt_sent"] = "Sent: %s";
strings_["peers_tt_services"] = "Services: %s";
strings_["peers_tt_start_height"] = "Start Height: %d";
strings_["peers_tt_synced"] = "Synced H/B: %d/%d";
strings_["peers_tt_tls_cipher"] = "TLS: %s";
strings_["peers_unban"] = "Unban";
strings_["peers_upper"] = "PEERS";
strings_["peers_version"] = "Version";
// --- QR Popup Dialog ---
strings_["qr_failed"] = "Failed to generate QR code";
strings_["qr_title"] = "QR Code";
// --- Receive Tab ---
strings_["click_copy_address"] = "Click to copy address";
strings_["click_copy_uri"] = "Click to copy URI";
strings_["generating"] = "Generating";
strings_["failed_create_shielded"] = "Failed to create shielded address";
strings_["failed_create_transparent"] = "Failed to create transparent address";
strings_["new_shielded_created"] = "New shielded address created";
strings_["new_transparent_created"] = "New transparent address created";
strings_["payment_request_copied"] = "Payment request copied";
strings_["payment_uri_copied"] = "Payment URI copied";
// --- Request Payment Dialog ---
strings_["request_amount"] = "Amount (optional):";
strings_["request_copy_uri"] = "Copy URI";
strings_["request_description"] = "Generate a payment request that others can scan or copy. The QR code contains your address and optional amount/memo.";
strings_["request_label"] = "Label (optional):";
strings_["request_memo"] = "Memo (optional):";
strings_["request_payment_uri"] = "Payment URI:";
strings_["request_receive_address"] = "Receive Address:";
strings_["request_select_address"] = "Select address...";
strings_["request_shielded_addrs"] = "-- Shielded Addresses --";
strings_["request_title"] = "Request Payment";
strings_["request_transparent_addrs"] = "-- Transparent Addresses --";
strings_["request_uri_copied"] = "Payment URI copied to clipboard";
// --- Send Tab ---
strings_["send_amount"] = "Amount";
strings_["send_amount_details"] = "AMOUNT DETAILS";
strings_["send_amount_upper"] = "AMOUNT";
strings_["send_clear_fields"] = "Clear all form fields?";
strings_["send_copy_error"] = "Copy Error";
strings_["send_dismiss"] = "Dismiss";
strings_["send_error_copied"] = "Error copied to clipboard";
strings_["send_error_prefix"] = "Error: %s";
strings_["send_exceeds_available"] = "Exceeds available (%.8f)";
strings_["send_fee"] = "Fee";
strings_["send_fee_high"] = "High";
strings_["send_fee_low"] = "Low";
strings_["send_fee_normal"] = "Normal";
strings_["send_form_restored"] = "Form restored";
strings_["send_go_to_receive"] = "Go to Receive";
strings_["send_keep"] = "Keep";
strings_["send_network_fee"] = "NETWORK FEE";
strings_["send_no_balance"] = "No balance";
strings_["send_no_recent"] = "No recent sends";
strings_["send_recent_sends"] = "RECENT SENDS";
strings_["send_recipient"] = "RECIPIENT";
strings_["send_select_source"] = "Select a source address...";
strings_["send_sending_from"] = "SENDING FROM";
strings_["send_submitting"] = "Submitting transaction...";
strings_["send_switch_to_receive"] = "Switch to Receive to get your address and start receiving funds.";
strings_["send_tooltip_enter_amount"] = "Enter an amount to send";
strings_["send_tooltip_exceeds_balance"] = "Amount exceeds available balance";
strings_["send_tooltip_in_progress"] = "Transaction already in progress";
strings_["send_tooltip_invalid_address"] = "Enter a valid recipient address";
strings_["send_tooltip_not_connected"] = "Not connected to daemon";
strings_["send_tooltip_select_source"] = "Select a source address first";
strings_["send_tooltip_syncing"] = "Wait for blockchain to sync";
strings_["send_total"] = "Total";
strings_["send_tx_failed"] = "Transaction failed";
strings_["send_tx_sent"] = "Transaction sent!";
strings_["send_cannot_send_now"] = "Cannot send now — check connection, sync, and available balance.";
strings_["send_tx_success"] = "Transaction sent successfully!";
strings_["send_status_unconfirmed"] = "Transaction status could not be confirmed";
strings_["send_err_needs_rescan"] = "Your wallet's shielded note data is out of date with the blockchain (this happens after a bootstrap or reindex). Run a full rescan via Settings -> Rescan Blockchain and let it finish completely, then try sending again.";
strings_["send_txid_copied"] = "TxID copied to clipboard";
strings_["send_txid_label"] = "TxID: %s";
strings_["send_valid_shielded"] = "Valid shielded address";
strings_["send_valid_transparent"] = "Valid transparent address";
strings_["send_wallet_empty"] = "Your wallet is empty";
strings_["send_yes_clear"] = "Yes, Clear";
// --- Shield Dialog ---
strings_["shield_check_status"] = "Check Status";
strings_["shield_completed"] = "Operation completed successfully!";
strings_["shield_description"] = "Shield your mining rewards by sending coinbase outputs from transparent addresses to a shielded address. This improves privacy by hiding your mining income.";
strings_["shield_from_address"] = "From Address:";
strings_["shield_funds"] = "Shield Funds";
strings_["shield_in_progress"] = "Operation in progress...";
strings_["shield_max_utxos"] = "Max UTXOs per operation";
strings_["shield_merge_done"] = "Shield/merge completed!";
strings_["shield_select_z"] = "Select z-address...";
strings_["shield_no_zaddr_hint"] = "No shielded (z) address yet — create one on the Receive tab first.";
strings_["shield_started"] = "Shield operation started";
strings_["shield_title"] = "Shield Coinbase Rewards";
strings_["shield_to_address"] = "To Address (Shielded):";
strings_["shield_utxo_limit"] = "UTXO Limit:";
strings_["shield_wildcard_hint"] = "Use '*' to shield from all transparent addresses";
strings_["shield_submitting"] = "Submitting operation...";
strings_["shield_op_submitted"] = "Operation submitted: ";
strings_["shield_op_failed"] = "Operation failed: ";
strings_["shield_error_prefix"] = "Error: ";
strings_["shield_status_label"] = "Status: ";
strings_["shield_status_check_error"] = "Error checking status: ";
strings_["shield_unknown_error"] = "Unknown error";
strings_["shield_send_failed"] = "Shield failed: ";
strings_["merge_send_failed"] = "Merge failed: ";
strings_["merge_description"] = "Merge multiple UTXOs into a single shielded address. This can help reduce wallet size and improve privacy.";
strings_["merge_funds"] = "Merge Funds";
strings_["merge_started"] = "Merge operation started";
strings_["merge_title"] = "Merge to Address";
// --- Transaction Details Dialog ---
strings_["tx_confirmations"] = "%d confirmations";
strings_["tx_details_title"] = "Transaction Details";
strings_["tx_from_address"] = "From Address:";
strings_["tx_id_label"] = "Transaction ID:";
strings_["tx_immature"] = "IMMATURE";
strings_["tx_mined"] = "MINED";
strings_["tx_received"] = "RECEIVED";
strings_["tx_sent"] = "SENT";
strings_["tx_to_address"] = "To Address:";
strings_["tx_view_explorer"] = "View on Explorer";
// --- Validate Address Dialog ---
strings_["validate_btn"] = "Validate";
strings_["validate_description"] = "Enter a DragonX address to check if it's valid and whether it belongs to this wallet.";
strings_["validate_invalid"] = "INVALID";
strings_["validate_is_mine"] = "This wallet owns this address";
strings_["validate_not_mine"] = "Not owned by this wallet";
strings_["validate_ownership"] = "Ownership:";
strings_["validate_results"] = "Results:";
strings_["validate_shielded_type"] = "Shielded (z-address)";
strings_["validate_status"] = "Status:";
strings_["validate_title"] = "Validate Address";
strings_["validate_transparent_type"] = "Transparent (t-address)";
strings_["validate_type"] = "Type:";
strings_["validate_valid"] = "VALID";
// Misc dialog/tab strings
strings_["ram_wallet_gb"] = "Wallet: %.1f GB";
strings_["ram_wallet_mb"] = "Wallet: %.0f MB";
strings_["ram_daemon_gb"] = "Daemon: %.1f GB (%s)";
strings_["ram_daemon_mb"] = "Daemon: %.0f MB (%s)";
strings_["ram_system_gb"] = "System: %.1f / %.0f GB";
strings_["shield_operation_id"] = "Operation ID: %s";
strings_["peers_peer_label"] = "Peer: %s";
strings_["error_format"] = "Error: %s";
strings_["key_export_click_retrieve"] = "Click to retrieve the key from your wallet";
strings_["key_export_viewing_keys_zonly"] = "Viewing keys are only available for shielded (z) addresses";
strings_["backup_source"] = "Source: %s";
strings_["export_keys_progress"] = "Exporting %d/%d...";
strings_["import_key_progress"] = "Importing %d/%d...";
strings_["click_to_copy"] = "Click to copy";
strings_["block_hash_copied"] = "Block hash copied";
// Explorer tab
strings_["explorer"] = "Explorer";
strings_["explorer_search"] = "Search";
strings_["explorer_chain_stats"] = "Chain";
strings_["explorer_mempool"] = "Mempool";
strings_["explorer_mempool_txs"] = "Transactions";
strings_["explorer_mempool_size"] = "Size";
strings_["explorer_recent_blocks"] = "Recent Blocks";
strings_["explorer_block_detail"] = "Block";
strings_["explorer_block_height"] = "Height";
strings_["explorer_block_hash"] = "Hash";
strings_["explorer_block_txs"] = "Transactions";
strings_["explorer_block_size"] = "Size";
strings_["explorer_block_time"] = "Time";
strings_["explorer_block_merkle"] = "Merkle Root";
strings_["explorer_tx_outputs"] = "Outputs";
strings_["explorer_tx_size"] = "Size";
strings_["explorer_txid"] = "TxID:";
strings_["explorer_prev_block"] = "Previous block";
strings_["explorer_next_block"] = "Next block";
// --- Antivirus (Windows Defender) help dialog (Windows-only) ---
strings_["av_title"] = "Windows Defender Blocked Miner";
strings_["av_intro"] = "Mining software is often flagged as potentially unwanted. Follow these steps to enable pool mining:";
strings_["av_step1"] = "Step 1: Add Exclusion";
strings_["av_step1_b1"] = "Open Windows Security > Virus & threat protection";
strings_["av_step1_b2"] = "Click Manage settings > Exclusions > Add or remove";
strings_["av_step1_b3"] = "Add folder: %APPDATA%\\ObsidianDragon\\";
strings_["av_step2"] = "Step 2: Restore from Quarantine (if needed)";
strings_["av_step2_b1"] = "Windows Security > Protection history";
strings_["av_step2_b2"] = "Find xmrig.exe and click Restore";
strings_["av_step3"] = "Step 3: Restart wallet and try again";
strings_["av_open_security"] = "Open Windows Security";
strings_["explorer_invalid_query"] = "Enter a block height or 64-character hash";
strings_["explorer_invalid_response"] = "Invalid response from daemon";
strings_["explorer_hash_not_found"] = "No block or transaction found for this hash";
strings_["explorer_not_connected"] = "Not connected to daemon — cannot look up a block or transaction hash";
strings_["explorer_no_results"] = "No matching cached blocks";
}
const char* I18n::translate(const char* key) const
{
if (!key) return "";
auto it = strings_.find(key);
if (it != strings_.end()) {
return it->second.c_str();
}
// Return key if translation not found
return key;
}
void I18n::registerLanguage(const std::string& code, const std::string& name)
{
// Check if already registered
for (const auto& lang : available_languages_) {
if (lang.first == code) return;
}
available_languages_.emplace_back(code, name);
}
} // namespace util
} // namespace dragonx