On Linux and macOS the Lite data dir (~/.silentdragonxlite) was created
with create_dir_all (0755 under the default umask) on every
get_zcash_data_path() call, even by the startup wallet_exists() probe.
do_save wrote the wallet through File::create (0644) and renamed it into
place, and fs::copy gave the .bak the same mode, so any local account
could read the wallet file, and the plaintext seed with it when the
wallet was not encrypted. The debug log was 0644 and its roller pattern
was relative, so rolled logs landed in the process's working directory.
A crash-leftover .dat.tmp was truncated and reused: an fd another
account had opened on it read the next wallet. And after encrypt(), the
first save copied the previous, plaintext wallet to .bak, where the seed
stayed until the next save, or for good if the app quit right away.
- New helpers, each an item-level #[cfg(unix)] / #[cfg(not(unix))]
pair: create_private_dir_all (0700 components), tighten (strips only
the group/other bits of an existing dir or file, keeps the owner bits,
never follows a symlink), create_private_file_new (unlinks a stale
file, then create_new with 0600), and a once-per-process warning when
a chmod fails (drvfs, FAT, NFS).
- get_zcash_data_path creates the default data dir 0700 and tightens an
existing one (for test/regtest also its parent). A caller-supplied
data_dir is created as before and never chmodded, and the params dir
is left alone.
- do_save writes a fresh 0600 temp file and tightens the .bak after the
copy. At the plaintext -> encrypted transition (the wallet is
encrypted and the on-disk header says plaintext) the .bak is copied
from the new, encrypted file. wallet_header_encrypted reads the flag
byte for versions 4 and 6-9 only (v5 is gzip) and returns None when it
cannot tell, which keeps the old behaviour.
- read_from_disk tightens a wallet restored from .bak, and the wallet
and .bak after every successful read.
- get_log_config pre-creates the log 0600 on unix and anchors the
roller in the data dir; a data path containing "{}" keeps the old
relative pattern. log4rs re-creates the log with the umask mode after
a 5 MB roll, so the 0700 data dir is the lasting control.
Flagged behaviour changes:
- on unix, the data dir is 0700 and existing files lose their
group/other bits (owner bits kept, symlinks and a caller-supplied
data_dir untouched); a shared group or a backup user under another uid
loses read access;
- a fresh 0600 temp file is used;
- the first encrypted save backs up the encrypted file;
- the log rolls inside the data dir (old rolled logs in former working
directories are not cleaned up).
On Windows the file modes are unchanged; the encrypted first .bak and
the log-roll location apply there too. Wallet format v9 is unchanged;
no ABI or symbol change.
Tests: the wallet and .bak are 0600 after every save and after an open
from 0644, and a wallet restored from a loose .bak is 0600, while the
caller's 0755 data dir is unchanged; a stale 0644 .dat.tmp is replaced
by a new inode and an fd held on it still reads the stale bytes; tighten
keeps owner bits (0555 -> 0500), ignores the other kind and symlinks,
create_private_dir_all makes every component 0700, and
create_private_file_new never reuses or follows a stale file or link;
after encrypt the first save's .bak is encrypted, byte-identical to the
wallet and unlocks to the seed; the header probe answers only for v4 and
v6-v9; the log is 0600, the roller pattern and a real roll stay in the
data dir, and a "{}" path falls back. An opt-in test
(DRAGONX_LITE_SCRATCH_HOME=1, temp HOME) checks the default data dir,
its testnet parent, a symlinked data dir and the params dir.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ObsidianDragon - DragonX Wallet
A lightweight, portable full-node cryptocurrency wallet for DragonX (DRGX), built with Dear ImGui.
Current pre-release: 1.2.0-rc1.
Features
- Full Node Support: Connects to dragonxd for complete blockchain verification
- Shielded Transactions: Full z-address support with encrypted memos
- Address Management: Labels, icons, favorites, hidden addresses, and address-to-address transfers
- Integrated Mining: Solo CPU mining plus pool mining through xmrig, with idle-mining controls
- Explorer Tools: Block/transaction lookup and bootstrap snapshot download
- Market Data: Real-time price charts from CoinGecko
- QR Codes: Generate and display QR codes for receiving addresses
- Multi-language: i18n support for English, German, Spanish, French, Japanese, Korean, Portuguese, Russian, and Chinese
- CJK Fonts: Bundled CJK subset font for translated interfaces
- Lightweight: ~5-10MB binary vs ~50MB+ for Qt version
- Fast Builds: Compiles in seconds, not minutes
Screenshots
Building
Quick Setup
The setup script detects your OS, installs all build dependencies, and validates your environment:
./setup.sh # Install core build deps (interactive)
./setup.sh --check # Just report what's missing
./setup.sh --all # Core + Windows/macOS cross-compile + Sapling params
./setup.sh --win # Also install mingw-w64 + libsodium-win
Manual Prerequisites
Click to expand manual install commands
Linux (Ubuntu/Debian):
sudo apt install build-essential cmake git pkg-config
sudo apt install libgl1-mesa-dev libx11-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev
sudo apt install libsodium-dev libcurl4-openssl-dev
Linux (Arch):
sudo pacman -S base-devel cmake git pkg-config mesa libx11 libxcursor libxrandr libxinerama libxi libsodium curl
macOS:
xcode-select --install
brew install cmake
Windows:
- Visual Studio 2019+ with C++ workload
- CMake 3.20+
Binaries
Download linux and windows binaries of latest releases and place in binary directories:
DragonX daemon (https://git.dragonx.is/DragonX/dragonx):
- prebuilt-binaries/dragonxd-linux/
- prebuilt-binaries/dragonxd-win/
- prebuilt-binaries/dragonxd-mac/
DRG-XMRig fork (https://git.dragonx.is/DragonX/drg-xmrig):
- prebuilt-binaries/drg-xmrig/
Build Steps
### Clone repository (if not already)
git clone https://git.dragonx.is/dragonx/ObsidianDragon.git
cd ObsidianDragon/
Windows Build
./build.sh --win-release
Release Build
./build.sh --linux-release # Linux release + AppImage
./build.sh --win-release # Windows cross-compile
./build.sh --mac-release # macOS .app bundle + DMG
./build.sh --clean --linux-release # Clean + Release
Running
-
Start dragonxd (if not using embedded daemon):
dragonxd -daemon -
Run the wallet:
cd build/bin ./ObsidianDragon
The wallet will automatically connect to the daemon using credentials from ~/.hush/DRAGONX/DRAGONX.conf.
Using Custom Node Binaries
The wallet checks its own directory first when looking for DragonX node binaries. This means you can test new or different branch builds of hush-arrakis-chain/hushd without waiting for a new wallet release:
- Build or download the node binaries you want to test
- Place them in the same directory as the wallet executable (e.g.
build/bin/) - Launch the wallet — it will use the local binaries instead of the bundled ones
Search order:
- Wallet executable directory (highest priority)
- Embedded/extracted daemon (app data directory)
- System-wide locations (
/usr/local/bin,~/dragonx/src, etc.)
This is useful for testing new branches or hotfixes to the node software before they are bundled into a wallet release.
Configuration
Configuration is stored in ~/.hush/DRAGONX/DRAGONX.conf:
rpcuser=your_rpc_user
rpcpassword=your_rpc_password
rpcport=21769
Project Structure
ObsidianDragon/
├── src/
│ ├── main.cpp # Entry point, SDL/ImGui setup
│ ├── app.cpp/h # Main application class
│ ├── data/ # WalletState, address book, exchange info
│ ├── config/ # Settings persistence and committed/generated version.h
│ ├── ui/
│ │ ├── schema/ # TOML UI schema and skin manager
│ │ ├── material/ # Material components, typography, layout
│ │ ├── windows/ # Tabs and dialogs
│ │ └── pages/ # Multi-page screens such as Settings
│ ├── rpc/
│ │ ├── rpc_client.cpp # JSON-RPC client
│ │ └── connection.cpp # Daemon connection
│ ├── resources/ # Embedded resource extraction
│ ├── platform/ # Windows DX11/backdrop helpers
│ ├── util/
│ │ ├── i18n.cpp # Internationalization
│ │ └── ...
│ └── daemon/
│ └── embedded_daemon.cpp
├── res/
│ ├── fonts/ # Ubuntu, icon, and CJK fonts
│ └── lang/ # Translation files
├── libs/
│ └── qrcode/ # QR code generation
├── CMakeLists.txt
├── build.sh # Release/cross-platform build script
└── scripts/create-appimage.sh # AppImage packaging
Dependencies
Fetched or discovered by CMake:
- SDL3 — Cross-platform windowing/input
- nlohmann/json — JSON parsing
- toml++ — TOML parsing (UI schema/themes)
- libcurl — HTTP/HTTPS transport for daemon RPC and network calls (system on Linux/macOS, fetched on Windows)
Bundled in libs/:
- Dear ImGui — Immediate mode GUI
- libsodium — Cryptographic operations (system on Linux or fetched by
scripts/fetch-libsodium.sh) - QR-Code-generator — QR code rendering
- miniz — ZIP compression
- GLAD — OpenGL loader (Linux/macOS)
- stb_image — Image loading
- incbin — Binary resource embedding (Windows builds)
Keyboard Shortcuts
| Shortcut | Action |
|---|---|
| Ctrl+, | Settings |
| F5 | Refresh |
| Alt+F4 | Exit |
Translation
Current language files live in res/lang/ as de, es, fr, ja, ko, pt, ru, and zh JSON files, with built-in English fallbacks.
To add a new language:
- Copy
res/lang/es.jsontores/lang/<code>.json - Translate all strings
- The language will appear in Settings automatically
License
This project is licensed under the GNU General Public License v3 (GPLv3).
Credits
- The Hush Developers
- DragonX Community
- Dear ImGui by Omar Cornut
- SDL by Sam Lantinga
Links
- Website: https://dragonx.is
- Explorer: https://explorer.dragonx.is
- Source: https://git.dragonx.is/dragonx/ObsidianDragon








