Finishes the transactions-export partial. The dialog now offers three scopes:
- All transactions (unchanged default; exported with no copy).
- Current History filter — the Transactions tab publishes a TxFilterSnapshot of
the visible legs (a merged autoshield row contributes both its send+receive
legs, so the CSV stays a per-leg record like an unfiltered export); the radio
is disabled with an explanation when no filter is active, and a snapshot that
predates the current tx list (revision mismatch) is refused rather than
silently exporting everything.
- Date range (YYYY-MM-DD, inclusive end-of-day; pending/dateless rows excluded
with a note; invalid/reversed dates blocked inline).
The live count reflects what will actually be exported. formatTransactionsCsv
and the atomic write are unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The transactions CSV export now sanitizes the typed filename (basename only,
illegal chars → '_', no leading dots/trailing dots-or-spaces, length-capped,
always .csv) so it can't be pointed outside the config dir, and the success
screen gets an "Open folder" button. (All-vs-filter / date-range export scope is
left for a follow-up — it needs tx-tab filter-snapshot plumbing.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Batch of safe, isolated fixes from the 10-surface UX audit:
- settings: Auto-shield / Save-z-transactions toggles now persist on change
(they discarded CB()'s return and relied on a Save button that only renders
on the About tab, so the choice was silently lost on relaunch).
- exports: show the resolved Platform::getConfigDir() instead of a hardcoded
~/.config path (wrong on Windows/macOS) in both the all-keys and CSV
dialogs; all-keys also reveals the file path on a partial export.
- notifications: error/warning toasts last 9s/7s (were 4s/3.5s) so failures
are readable.
- qr popup / tx-details: copy-to-clipboard now confirms with a toast.
- about: Escape-to-close + readable heading contrast via OnSurfaceMedium().
- sidebar: suppress single-key nav (J/K/arrows/[) while an overlay dialog or
ImGui popup is open, so it no longer switches the tab behind a modal.
- i18n: strip the stale hardcoded path out of file_save_location in i18n.cpp
and all eight res/lang/*.json locales (additive, one key each).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The transaction export streamed rows straight into an ofstream. A write
that failed partway, on a full disk or removable media, left a truncated
CSV on disk behind a success toast. The CSV formatting also lived inline
in the dialog with no test coverage.
- The CSV is now built in memory and written atomically (temp file plus
rename), so a write failure is reported with an error toast and leaves
no partial file.
- Formatting moves into a reusable helper, and the timestamp conversions
use the thread-safe localtime variants and tolerate a conversion
failure rather than dereferencing a null result.
Tests: field escaping neutralises formula-injection prefixes and quotes
special characters, and the full CSV has the expected header and rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Dev-branch audit (docs/_archive/security-audit-dev-2026-07-22.md) re-found the
master issues (absent on dev) plus new ones in dev-only code. Applied here;
full-node build + test suite green; the subtle fixes were adversarially re-verified.
Ported from the master remediation (adapted to dev's code):
- bootstrap: reject zip-slip / path-traversal archive members (isSafeArchivePath)
before writing (S2-1). (dev already fail-closes on a missing checksum.)
- xmrig updater: fail closed when a signature is required but no key is pinned (F1-1).
- http_download.httpGetString: 16 MiB hard cap + MAXFILESIZE on the shared
metadata/price fetch (F1-2 / caps the updater + exchange paths at one site).
- rpc_client: explicit SSL_VERIFYPEER/VERIFYHOST (F4-1) and a 256 MiB response
cap in WriteCallback (F4-3).
- lite_connection_service: reject remote http:// lite servers, loopback only (L1-1).
Loopback is matched by a strict dotted-decimal 127.0.0.0/8 check (not a
startsWith("127.") prefix, which would wrongly accept 127.0.0.1.evil.com), with
userinfo/fragment stripping.
- lite controller: propagate encrypt/decrypt save() failure instead of reporting
success (F7-1).
- xmrig_manager: chmod(0600) the pool config before writing secrets (F5-2).
- app: clear the copied secret from the OS clipboard on shutdown (F3b-1).
- export_transactions: neutralize CSV/spreadsheet formula injection (F13-1).
- build pipeline: build-from-source lite backend + remove the self-attested
CMake signature gate (F15-1); pinned+verified appimagetool (F15-3/4);
verified Sapling params in setup.sh (F15-6); build.sh exits 0 on success.
(F14-1 empty-quoted-arg and F8-2 NUL-termination were already fixed on dev.)
Dev-only findings:
- rpc_client.callRaw: scrub the raw buffer + parsed tree (templated scrubJsonSecrets
for ordered_json) so console dumpprivkey/z_exportkey keys don't linger in freed
heap (N1-1).
- seed_wallet_creator: wipe the exported mnemonic on the failure path so a discarded
failed result never carries a live seed (W1-2).
- export_all_keys: write the plaintext key dump 0600 + atomically via
writeFileAtomically (U1-2).
- chat_database: restrict chat_messages.sqlite and its WAL/SHM sidecars to owner-only (C3-1).
Not done (need a decision, documented in the report):
- Chat header metadata (cid/z/p) rides outside the AEAD (C1/C2) — binding it is a
wire-protocol change requiring SilentDragonXLite interop review.
- Bootstrap lacks an offline-rooted signature (S2-2 residual) — needs signing infra.
- Console scrollback retains console-typed key-export output in plaintext (N1-1
residual) — inherent to an echoing console; would need output redaction.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Phase 1 (first modal). Bring the CSV export dialog onto the key-import reference:
- Struct-form OverlayDialogSpec / BlurFloat (was the legacy positional overload).
- material::DialogActionFooter (centered TactileButton pair) replacing the
StyledButtons + the two ImGui::Separators.
- Full i18n: TR("close") and the success/error status now via TR (were hardcoded
English); on success the saved path shows in a widgets::AddressCopyField with a
green check.
- Add ExportTransactionsDialog::hide() + a modal-export-transactions sweep surface
so the dialog is captured (it wasn't before).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Address a cluster of low-severity robustness nits where an async
callback could be skipped (leaving a spinner spinning forever) or a
synchronous action could be re-fired mid-flight:
- app_network: add catch(...) fallbacks around the importPrivateKey and
submitZSendMany worker lambdas so a non-std throw can't escape the
worker and skip the main-thread callback (stuck "Importing…"/"Sending…").
- export_transactions: re-entrancy guard disabling Export while a write
is in flight.
- bootstrap_download: disable Cancel once clicked so the request is
visibly acknowledged and can't be re-fired before the worker stops.
- network_tab: give clear "already in list" feedback on a duplicate
server (keep the inputs, clear only the stale invalid-URL error) and
disable/relabel Refresh while a probe is in flight.
- key_export: offer Retry from the error branch (falls back to Reveal)
and guard against an empty/malformed address before dispatching.
- receive_tab: only enter the "generating…" state when a dispatch is
actually possible (guards a stuck spinner when disconnected).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
UI-standardization audit: the labeled single-line form field (a plain
ImGui::Text label above a fixed-width InputText/InputTextWithHint) was
open-coded across dialogs. Add material::LabeledInput(label, id, buf, size,
width=-1, hint=nullptr, flags=0) mirroring that idiom exactly — pixel-identical,
but a single chokepoint so input styling (label typography, frame, spacing) can
later evolve in one place. Returns the input's edited bool.
Adopt at the clean vertical (label-above) single-line sites: address-book
add/edit (label + address), shield from-address, export-all-keys + export-
transactions filename, validate-address input, request-payment label + URI.
Left as-is: horizontal label-beside-input rows (settings RPC host/port/user/
pass use Text + SameLine), multiline (InputTextMultiline), numeric (InputDouble),
combos, and hint-only inputs — none match the vertical single-line idiom.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Security (P0):
- Fix sidebar remaining interactive behind lock screen
- Extend auto-lock idle detection to include active widget interactions
- Distinguish missing PIN vault from wrong PIN; auto-switch to passphrase
Blocking UX (P1):
- Add 15s timeout for encryption state check to prevent indefinite loading
- Show restart reason in loading overlay after wallet encryption
- Add Force Quit button on shutdown screen after 10s
- Warn user if embedded daemon fails to start during wizard completion
Polish (P2):
- Use configured explorer URL in Receive tab instead of hardcoded URL
- Increase request memo buffer from 256 to 512 bytes to match Send tab
- Extend notification duration to 5s for critical operations (tx sent,
wallet encrypted, key import, backup, export)
- Add Reduce Motion accessibility setting (disables page fade + balance lerp)
- Show estimated remaining time during mining thread benchmark
- Add staleness indicator to market price data (warning after 5 min)
New i18n keys: incorrect_pin, incorrect_passphrase, pin_not_set,
restarting_after_encryption, force_quit, reduce_motion, tt_reduce_motion,
ago, wizard_daemon_start_failed
- Replace all hardcoded English strings with TR() translation keys across
every tab, dialog, and component (~20 UI files)
- Expand all 8 language files (de, es, fr, ja, ko, pt, ru, zh) with
complete translations (~37k lines added)
- Improve i18n loader with exe-relative path fallback and English base
fallback for missing keys
- Add pool-side hashrate polling via pool stats API in xmrig_manager
- Introduce Layout::beginFrame() per-frame caching and refresh balance
layout config only on schema generation change
- Offload daemon output parsing to worker thread
- Add CJK subset fallback font for Chinese/Japanese/Korean glyphs
- Fix z_importwallet to use full path instead of filename only
- Add rescanBlockchain() method that restarts daemon with -rescan flag
- Track rescan progress via daemon output parsing and getrescaninfo RPC
- Display rescan progress in status bar with animated indicator when starting
- Improve dark theme card contrast: lighter surface-variant, tinted borders, stronger rim-light
Full-node GUI wallet for DragonX cryptocurrency.
Built with Dear ImGui, SDL3, and OpenGL3/DX11.
Features:
- Send/receive shielded and transparent transactions
- Autoshield with merged transaction display
- Built-in CPU mining (xmrig)
- Peer management and network monitoring
- Wallet encryption with PIN lock
- QR code generation for receive addresses
- Transaction history with pagination
- Console for direct RPC commands
- Cross-platform (Linux, Windows)