The screenshot sweep and the full UI sweep are dev tools. The full sweep
injects demo data into the live wallet state and the real data and
config dirs, and the tab sweep screenshots real balances and addresses.
Both were compiled into every build: the Settings buttons were
reachable in full-node releases, and the DRAGONX_FULL_SWEEP env hook
worked in every build, Lite releases included.
A default-OFF option alone would fail open: dev and release builds
share build/linux (and build/mac), so a release configured without
--clean would inherit a cached ON from the last dev configure.
- CMake: option(DRAGONX_ENABLE_UI_SWEEP ... OFF), passed to
ObsidianDragon and ObsidianDragonTests as a compile definition.
- build.sh passes it explicitly: ON in the dev build, OFF in every
release configure (Linux, Windows, macOS osxcross and native).
- Packaging guard: while the cache says ON, dragonx_release depends on
dragonx_release_sweep_guard, which fails, so a hand-configured ON
tree cannot package a release.
- startSweepImpl is a no-op unless the option is ON (an undefined macro
counts as 0, so it fails closed). The enabled branch logs the
sentinel "[Sweep] DRAGONX_UI_SWEEP_COMPILED_IN", so a release can be
checked with `strings <bin> | grep -c DRAGONX_UI_SWEEP_COMPILED_IN`
(must be 0).
- main.cpp: the DRAGONX_FULL_SWEEP hook is compiled out (autoSweep is
false). It must be: with the sweep a no-op, the hook would quit the
app once its warm-up frames ran out.
- Settings > Node > Debug options: both sweep buttons, open-dir, the
seed-demo-chat button and the current-theme checkbox are compiled only
into dev builds. The daemon debug categories are unchanged.
No i18n change: the existing strings stay in the tables.
Verified with an isolated release (DRAGONX_BUILD_ROOT/DRAGONX_RELEASE_ROOT
in a scratch dir) whose tree was first configured by hand with ON:
build.sh --linux-release without --clean leaves the cache OFF, and the
sentinel count is 0 in the built binary, the zip and the AppImage.
With the cache set back to ON by hand, --target dragonx_release fails
at the guard before compiling anything. Dev trees configured ON keep
the sweep (sentinel present; a one-surface DRAGONX_FULL_SWEEP run
against the fake daemon captured and exited cleanly).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both Windows zips shipped a loose xmrig.exe next to the wallet exe. The
exe already embeds xmrig (HAS_EMBEDDED_XMRIG), and getXmrigPath() uses,
and re-extracts when needed, the copy under %APPDATA%\<app>\dragonx; it
looks next to the exe only when that extraction fails.
build_release_win now copies it only when the generated header does not
define HAS_EMBEDDED_XMRIG, or there is no header.
Measured: each Windows zip loses exactly one entry, xmrig.exe; with the
ImGui demo stubs, the full-node zip went from 167,515,430 to 164,554,177
bytes.
The loose dragonxd, dragonx-cli, dragonx-tx, wallet-rebuild helper,
params and asmap stay in the full-node zip. The daemon copy under
%APPDATA% is written once and never refreshed, so without the loose copy
existing zip users would silently run their first-install daemon.
Dropping them needs a migration first.
Not verifiable here: mining from an unzipped Windows build without the
loose xmrig.exe.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Windows release embeds its resources into the exe through a
generated INCBIN header. The Lite build got the same param and asmap
entries as the full node, so ObsidianDragonLite.exe carried
sapling-spend.params, sapling-output.params and asmap.dat (about 53 MB)
that it never reads: the SDXL backend embeds its own copy of the params,
and Lite already skips extracting full-node-only resources.
build_release_win now writes the param and asmap INCBINs only for the
full node (should_bundle_full_node_assets). Lite gets null/zero stubs
for those three symbols and still embeds images, themes and xmrig. Two
fixes make that safe:
- getEmbeddedResource() stopped at the first table entry with null data,
so with the params stubbed out the Lite lookup ended before xmrig:
mining would report itself available but never find the embedded
binary. It now walks to the end of the table and skips null payloads.
This also fixes a full-node build without asmap, whose lookup ended at
the null asmap entry and hid the daemon and xmrig entries.
- full and Lite builds share build/windows. When the full-node build
cannot find the params, the generated header is now deleted, so a Lite
header left behind by an earlier Lite build is not compiled into it
(the node would then never start, because the startup job would take
the embedded-extraction path and never copy the loose params).
Measured on release builds:
- ObsidianDragonLite.exe: 159,788,544 -> 106,120,192 bytes (-53.7 MB, of
which about 0.28 MB is the ImGui demo stubs);
- the Lite header has no param or asmap INCBINs and the resource object
holds only the xmrig payload; a sample of sapling-spend.params occurs
once in the exe instead of twice (the remaining copy is the
backend's);
- the full-node header is byte-identical to before.
Not verifiable here (Windows runtime): the Lite exe starting without
embedded params, and mining through the embedded xmrig. Lite installs
from older versions may still hold about 53 MB of extracted params and
asmap in %APPDATA%\ObsidianDragonLite\dragonx; nothing deletes them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Release builds ran a plain `cmake --build .`, which builds `all`: on top
of the app and the wallet-rebuild helper, every --*-release run also
compiled HushChatFixtureCheck, ObsidianDragonTests where BUILD_TESTING
is on (Linux, macOS) and, in Lite backend trees, lite_smoke and
lite_send_smoke. None of them ship.
A new `dragonx_release` custom target depends on ObsidianDragon plus
dragonx-wallet-rebuild, copy_langs and copy_themes where those targets
exist, and the three release paths in build.sh build only that target.
The dev build (./build.sh) still builds `all`.
BUILD_TESTING is deliberately left alone: release and dev builds share
build/<platform>, and writing BUILD_TESTING=OFF into that cache would
leave ctest running a stale test binary.
Measured:
- a dry run of dragonx_release schedules none of the test, smoke-tool or
fixture-CLI builds that `all` schedules, in a full-node, a
Lite+backend and a mingw tree; the wallet-rebuild helper is still
built;
- all four release builds (Linux and Windows, full node and Lite) log
the dragonx_release target and no ObsidianDragonTests build, and the
Linux zip and AppImage file lists are unchanged.
Consequences: a release run no longer refreshes the test binary or the
lite smoke tools in build/<platform>/bin, so run ./build.sh or
`cmake --build` before ctest, and build the Windows smoke tools with
`--target lite_smoke lite_send_smoke`. If a release step starts copying
another CMake-built file out of bin/, its target must be added to
dragonx_release.
Not verifiable here: macOS --mac-release (the .app should still contain
the app, dragonx-wallet-rebuild and Contents/Resources/res).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The release functions always built in build/<platform> and wrote to
release/<platform>. On Linux and macOS build/<platform> is also the dev
build tree, so a release run reconfigures it (--linux-release turns a
Lite+backend dev tree into a full-node one), and building a baseline to
compare a change against meant overwriting the existing release/
artifacts.
build_release_linux, build_release_win and build_release_mac now take
their build and output roots from DRAGONX_BUILD_ROOT and
DRAGONX_RELEASE_ROOT, defaulting to build/ and release/ as before:
DRAGONX_BUILD_ROOT=/tmp/rel-build DRAGONX_RELEASE_ROOT=/tmp/rel \
./build.sh --win-release
With both unset nothing changes. The dev build (./build.sh) and the lite
backend artifact dir (build/lite-backend/<platform>) do not read them.
A full release set (Linux and Windows, full node and Lite) built into
override roots left the release/ listings (file sizes and timestamps)
and the dev tree's CMakeCache.txt unchanged (same checksums before and
after).
Known gaps:
- the end-of-run summary still prints release/ as the output dir;
- configuring a Windows build still writes res/ObsidianDragon.manifest
into the source tree, so the last configured variant's version ends up
there;
- a fresh build root re-downloads the FetchContent dependencies and
appimagetool, so it needs network access;
- the macOS paths changed the same way but were not run here.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The macOS release path hardcoded aarch64-apple-darwin for the wallet-rebuild
helper's static libdb and — unlike the Linux/Windows paths — never passed
-DBDB_INCLUDE_DIR/-DBDB_LIBRARY to CMake. So on an Intel Mac the helper either
couldn't find libdb, or picked up macOS's SDK stub /usr/include/db.h (a DB 1.85
shim with no db_create) and failed to compile.
- mac_bdb_dir(): map the target arch to the depends triple (x86_64 ->
x86_64-apple-darwin, arm64 -> aarch64-apple-darwin; universal / unknown falls
back to the host arch).
- Pass -DBDB_INCLUDE_DIR / -DBDB_LIBRARY (when the vendored libdb is present) in
BOTH the native and osxcross configures, so CMake uses our BDB 6.2 header
instead of the SDK stub. Full-node only (lite has no BDB wallet.dat).
- Use the derived triple in require_wallet_rebuild_helper's fix hint.
Verified end-to-end by building both ObsidianDragon 2.0.1 and ObsidianDragonLite
1.1.0 .dmg/.app on an Intel Mac (x86_64; built single-arch via DRAGONX_MAC_ARCHS
since the vendored deps are x86_64-only).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Linux and macOS release paths already strip the main binary (and the
Windows path even stripped the dragonx-wallet-rebuild helper), but the
Windows app exe was shipping unstripped — ~5 MB of symbols on the full
node, ~19 MB on the params-heavy lite build. Strip it right after the
Windows build, best-effort with a warning fallback.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The dragonx-wallet-rebuild helper is the only thing that repairs a genuinely
BDB-inconsistent wallet.dat — plain "Restore" just re-triggers the daemon's
salvage cascade — yet it was silently dropped from every packaged build:
- Linux zip/AppImage copied a hand-picked file list that omitted it.
- Windows bundled it only behind a soft `[[ -f ]]` guard (silent skip).
- macOS never wired Berkeley DB, never built it, never bundled it.
build.sh now HARD-REQUIRES the helper for full-node releases (fails the build if
the vendored Berkeley DB depends are missing, rather than shipping recovery-less),
and ships it in the Linux zip + AppImage, the Windows zip, and the macOS .app.
It also compiles the helper standalone for Windows and INCBINs it, and
embedded_resources gains ensureWalletRebuildHelperExtracted() to extract it on
demand — so a self-contained ObsidianDragon.exe carries recovery exactly like the
embedded daemon, even on a machine where first-run param extraction already ran.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Wires the wallet-rebuild recovery helper into the release pipeline so a shipped
build actually carries it (the app locates it next to dragonxd).
- CMakeLists: link the vendored STATIC Berkeley DB for the helper — add
Threads::Threads + dl (Linux) / ws2_32 (Windows) that the static libdb-6.2 needs
(the system shared lib pulled those in transitively; the static one doesn't).
- build.sh (Linux + Windows): pass BDB_INCLUDE_DIR/BDB_LIBRARY explicitly at
configure, pointing at external/dragonx/depends/<triple>/{include,lib/libdb-6.2.a}
— the same libdb the daemon links, so the helper's output is a v6.2 btree the
bundled dragonxd reads. Explicit paths bypass find_library (and the mingw
toolchain's sysroot-only find restriction). Guarded: no depends → helper simply
not built/bundled. Strip + copy the helper next to dragonxd(.exe) in both bundles.
Verified: Linux links the vendored libdb-6.2.a statically (no dynamic libdb) and
rebuilds the real broken wallet correctly; the helper cross-compiles cleanly with
mingw against the vendored Windows libdb-6.2.a to a PE32+ x64 exe. Full app +
helper build, suite green (1/1), build.sh syntax OK.
Remaining: macOS Berkeley DB (no in-tree depends artifact) + resource-embedding as
an alternative to side-by-side bundling.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- The macOS DMG filename used a separate hardcoded DMG_BASENAME ("DragonX_Wallet"),
so the export didn't match the .app/zip (ObsidianDragon). Derive it from
APP_BASENAME: full-node -> ObsidianDragon-*.dmg, lite -> ObsidianDragonLite-*.dmg.
The mounted volume + CFBundleName keep the "DragonX Wallet" display branding.
- build_release_mac did `rm -rf "$out"`, wiping all of release/mac on every build, so
building one variant destroyed the other's artifacts. Scope the cleanup to the
current variant's files (as the Linux/Windows release paths already do) so the
full-node and lite releases coexist.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The --mac-release path (full-node and --lite-backend) had never run on a real
Mac and broke on several Linux-only assumptions:
- build.sh version parser used GNU sed \+ (BSD sed reads it literally), so it
aborted before compiling — switched to POSIX [[:space:]][[:space:]]*.
- build.sh libsodium universal check used GNU grep \| — switched to grep -E.
- libwebp's cpu.cmake applies -mno-sse2 to its reference DSP files; under a
universal build (-arch arm64;x86_64) that lands on the x86_64 slice, where it
disables _Float16 and breaks the SDK 26 <math.h>. Added an idempotent
FetchContent PATCH_COMMAND (cmake/patch-libwebp-simd.cmake) to neutralize it.
- The SDXL lite backend static lib needs Security + CoreFoundation frameworks on
macOS; added them to the imported dragonx_lite_backend target for APPLE.
- Added a DRAGONX_MAC_ARCHS override plus auto-detect: with --lite-backend the
app is built for the arch(es) the backend .a actually provides (its pinned
ring 0.16.11 is x86_64-only), instead of failing to link a universal app.
- build-lite-backend-artifact.sh uses bash 4+ (mapfile); added a re-exec guard
for macOS's stock bash 3.2 and added bash to setup.sh's macOS core deps.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Point the miner build at DragonX/drg-xmrig and rename the prebuilt staging
dir xmrig-hac -> drg-xmrig across setup.sh, build.sh, the legacy Windows
script, .gitignore and README.
setup.sh now clones/builds the miner from git.dragonx.is/DragonX/drg-xmrig
(was dragonx/xmrig-hac), and the prebuilt staging dir is renamed
prebuilt-binaries/xmrig-hac -> prebuilt-binaries/drg-xmrig across build.sh, the
legacy Windows build script, .gitignore and README.
Also aligns setup.sh's section-8 directory list with section 7 (it previously
used a bare "xmrig" token, creating a stray empty prebuilt-binaries/xmrig/),
and updates the xmrig_manager.cpp header comment.
Co-Authored-By: Claude Opus 4.8 (1M context) <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>
The chat "Emoji style: Color" option renders the merged emoji in color (COLR/CPAL
Twemoji) instead of the monochrome NotoEmoji subset. This needs FreeType, which the
default stb_truetype rasterizer can't do for color glyphs.
- Vendor imgui_freetype (matches the bundled 1.92 ImFontLoader API) and embed a 1.4 MB
COLRv0 Twemoji font (no libpng/harfbuzz needed).
- CMake gains an optional FreeType path: native Linux/macOS use the system FreeType via
find_package; the mingw-w64 cross-compile has none, so build.sh --win-release now
cross-builds a minimal static FreeType (scripts/build-freetype-mingw.sh) and passes it
in. Absent FreeType => graceful monochrome fallback, so no build breaks.
- Typography selects the FreeType loader + the color font (LoadColor) when color emoji is
on, else the stb loader + mono subset; toggling reloads the atlas. Both the DX11 and
OpenGL backends already support the 1.92 RGBA dynamic atlas, so color glyphs render.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The wallet is meant to ship xmrig embedded (HAS_EMBEDDED_XMRIG -> getXmrigPath() extracts it
at runtime), but build.sh only embedded a flat prebuilt-binaries/xmrig-hac/xmrig.exe — while
the published DRG-XMRig archive ships the binary inside a versioned subdir
(drg-xmrig-6.25.3-win-x64/xmrig.exe). So xmrig.exe was never present, HAS_EMBEDDED_XMRIG stayed
undefined, and the Windows wallet ran with no miner: "xmrig binary not found", pool mining and
the thread benchmark both fail.
build.sh now extracts xmrig.exe (flattened) from the matching win-x64 zip when a raw binary
isn't already staged, so the existing embed step fires. (Checks the extracted file rather than
unzip's exit code, which is non-zero when a glob matches nothing.) Verified: --win-release now
logs "Extracted xmrig.exe", stages it (6.7M), and defines HAS_EMBEDDED_XMRIG=1.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The 1.3.0 lite-capability work gated isUsingEmbeddedDaemon() on the compile flag
DRAGONX_ENABLE_EMBEDDED_DAEMON (in 1.2.0 it was hardcoded true, so the daemon
always launched). The lite branch in CMakeLists set that flag OFF with
`CACHE BOOL ... FORCE`, which POISONS the build dir's cache: a later full-node
reconfigure of the same dir keeps the forced-OFF value (the full-node branch
never re-asserts it), so embeddedDaemonAvailable=false and the wallet extracts
dragonxd but never starts it — exactly the reported "unpacks dragonxd.exe but
does not start the daemon, manual start works."
Note the two gates are independent: the binary is EMBEDDED/extracted via build.sh
(HAS_EMBEDDED_DAEMON), while LAUNCHING is gated by DRAGONX_ENABLE_EMBEDDED_DAEMON
— so they diverged (extract yes, launch no).
The forced cache write was also pointless: makeWalletCapabilities() already
forces the embedded-daemon capability off for any lite build via
`fullNodeBuild && embeddedDaemonCompiled`, so lite never launches a daemon
regardless of the flag.
Fix:
- CMakeLists: remove the FORCE cache poisoning (the root cause).
- build.sh: set DRAGONX_ENABLE_EMBEDDED_DAEMON explicitly per variant (ON for
full-node, OFF for lite), mirroring the existing DRAGONX_BUILD_LITE handling,
so an already-poisoned build dir is HEALED on the next build rather than
silently keeping the stale OFF.
Verified: a poisoned Windows cache (=0) flips to =1 on reconfigure; full-node
builds define =1, lite =0; tests + hygiene green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The linux/windows release packaging did `rm -rf "$out"` on the whole output dir, so building
ObsidianDragonLite into release/<os>/ wiped the ObsidianDragon artifacts already there (both
variants share release/linux and release/windows). Remove only the CURRENT variant's prior
artifacts (by APP_BASENAME, which can't cross-match — "ObsidianDragon-*" excludes
"ObsidianDragonLite-*"), so full-node and lite releases coexist.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The full-node app and ObsidianDragonLite are now versioned separately:
- project() VERSION -> 1.3.0 (suffix cleared); DRAGONX_LITE_VERSION -> 1.0.0.
- A DRAGONX_APP_VERSION* set (resolved per variant in the lite/full block) feeds the generated
header (version.h.in), the Windows VERSIONINFO/.rc + manifest, and the build summary — so each
variant reports its own version. The .rc/manifest name fields also follow DRAGONX_APP_NAME so a
lite .exe's properties read "ObsidianDragonLite".
- build.sh resolves the release-filename version per variant by parsing CMakeLists (single source
of truth) instead of a hardcoded string.
Also fixes a latent variant-bleed: build.sh now passes DRAGONX_BUILD_LITE and
DRAGONX_ENABLE_LITE_BACKEND explicitly (ON *and* OFF), so switching variants in a shared build dir
can't reuse a stale cached value (a prior --lite build was making a subsequent full-node build
produce the lite name/version).
Both variants build + report the right version (full 1.3.0, lite 1.0.0); suite passes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The mac-release path was mostly ObsidianDragon-hardcoded, so `--lite --mac-release`
would produce a broken bundle. Make it variant-aware, mirroring the linux/win lite
handling that already keys off APP_BASENAME + should_bundle_full_node_assets:
- SDL3 rpath fix, the launcher script + its .bin pair, and CFBundleExecutable now
follow ${APP_BASENAME} (ObsidianDragonLite), so the bundle's executable resolves.
- Lite variant gets its own CFBundleName/CFBundleDisplayName ("DragonX Wallet Lite"),
CFBundleIdentifier (is.hush.dragonx.lite), DMG filename (DragonX_Wallet_Lite-…)
and volume name, so it can coexist with the full-node app.
- Full-node assets (daemon, Sapling params, asmap) were already gated out for lite;
the lite backend artifact is auto-selected for the macos platform by the existing
--lite-backend logic, and CMAKE_LITE_ARGS already reaches the mac configure.
Authored + validated on Linux (bash -n; launcher heredoc, plist, and DMG naming
render correctly for the lite variant) but NOT yet built/run — that needs macOS or
osxcross, neither available here. CLAUDE.md updated to reflect the wired-but-unverified
status; remaining M5b is verifying it on a Mac plus CI backend-artifact build + signing.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`build.sh --lite-backend --win-release` now cross-compiles a working
ObsidianDragonLite.exe with the real SDXL backend:
- Artifact platform follows the cross target: when only --win-release is
requested, auto-select build/lite-backend/windows/ (previously always the host
artifact, which would link a Linux .a into a Windows .exe).
- Link the Win32 system libs a Rust x86_64-pc-windows-gnu staticlib pulls in
(rustls/schannel, ring, dirs, std) via DRAGONX_LITE_BACKEND_EXTRA_LIBS. The set
is rustc's `--print native-static-libs` for the backend (winapi_* shims mapped
to real mingw import libs); all 21 exist in mingw-w64.
Verified end to end on Linux:
- scripts/build-lite-backend-artifact.sh --platform windows cross-builds the
backend to x86_64-pc-windows-gnu (~105 MB .a); rustls/ring cross-compile clean
(no openssl blocker); all required litelib_* symbols present.
- build.sh --lite-backend --win-release -> release/windows/ObsidianDragonLite-
<ver>.exe (PE32+ GUI x86-64, INCBIN-embedded, ~170 MB) + zip, with the same
full-node-asset exclusion as Linux.
Not yet done: running the .exe on real Windows (cross-compiled only). Plan
updated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add --lite build flow and ObsidianDragonLite target naming, hide full-node pages/features in lite mode, enforce pool-only mining in lite, and include chat port feasibility audit documentation.
s_dropTargetIdx was reset to -1 unconditionally each frame, including
the release frame. Since drop target detection runs in PASS 2 (after
the drop handler), the target was always -1 when checked. Only reset
while mouse button is held so the previous frame's value is preserved.
Also bump version to 1.2.0-rc1 and add release notes.
Instead of blocking the entire UI with "Activating best chain..." until
the daemon finishes warmup, treat warmup responses as a successful
connection. The wallet now:
- Sets connected=true + warming_up=true when daemon returns RPC -28
- Shows warmup status with block progress in the loading overlay
- Polls getinfo every few seconds to detect warmup completion
- Allows Console, Peers, Settings tabs during warmup
- Shows orange status indicator with warmup message in status bar
- Skips balance/tx/address refresh until warmup completes
- Triggers full data refresh once daemon is ready
Also: fix curl handle/header leak on reconnect, fill in empty
externalDetected error branch, bump version to v1.2.0 in build scripts.
- Set CMAKE_OSX_DEPLOYMENT_TARGET and CMAKE_OSX_ARCHITECTURES before
project() so they propagate to all FetchContent dependencies (SDL3, etc.)
- build.sh: native mac release builds universal binary, detects and
rebuilds single-arch libsodium, verifies with lipo, exports
MACOSX_DEPLOYMENT_TARGET; dev build uses correct build/mac directory
- fetch-libsodium.sh: build arm64 and x86_64 separately then merge with
lipo on native macOS; fix sha256sum unavailable on macOS (use shasum)
Build & setup:
- Fix setup.sh and build.sh for macOS (bundle daemon, xmrig, sapling params, asmap.dat into .app)
- Fix CMakeLists.txt libsodium linking for macOS
- Fix incbin.h to use __DATA,__const section on macOS
- Remove vendored libsodium-1.0.18 source tree (use fetch script instead)
- Remove prebuilt-binaries/xmrig (replaced by xmrig-hac)
- Add .DS_Store to .gitignore
Rendering & UI:
- Use GLSL #version 150 and OpenGL 3.2 Core Profile on macOS
- Force dpiScale=1.0 on macOS to fix Retina double-scaling
- Set default window/UI opacity to 100% on Mac/Linux
- Add scroll fade shader guard for macOS GL compatibility
- Add ImGui error recovery around render loop and mining tab
Daemon & bootstrap:
- Fix getDragonXDataDir() to return ~/Library/Application Support/Hush/DRAGONX/ on macOS
- Fix isPortInUse() with connect() fallback (no /proc/net/tcp on macOS)
- Increase daemon watchdog timeout from 3s to 15s
- Add daemon status indicator (colored dot + label) in wizard bootstrap phases
Mining tab:
- Fix EmbeddedDaemon::getMemoryUsageMB() crash on macOS (was using Linux /proc)
- Fix XmrigManager::getMemoryUsageMB() to use ps on macOS instead of /proc
- Restructure RenderMiningTab with wrapper pattern for exception safety
- Fix default pool URL to include port (pool.dragonx.is:3433)
- Linux --linux-release now produces both ObsidianDragon-Linux-x64.zip
(raw binaries) and ObsidianDragon.AppImage (single-file)
- Windows --win-release keeps standalone exe alongside zip with binaries
- Bundle sapling-spend.params and sapling-output.params in Linux release
Windows identity:
- Add VERSIONINFO resource (.rc) with ObsidianDragon file description
- Embed application manifest for DPI awareness and shell identity
- Patch libwinpthread/libpthread to remove competing VERSIONINFO
- Set AppUserModelID and HWND property store to override Task Manager cache
- Link patched pthread libs to eliminate "POSIX WinThreads" description
Address creation (+New button):
- Move z_getnewaddress/getnewaddress off UI thread to async worker
- Inject new address into state immediately for instant UI selection
- Trigger background refresh for balance updates
Mining tab:
- Add pool mining dropdown with saved URLs/workers and bookmarks
- Add solo mining log panel from daemon output with chart/log toggle
- Fix toggle button cursor (render after InputTextMultiline)
- Auto-restart miner on pool config change
- Migrate default pool URL to include stratum port
Transactions:
- Sort pending (0-conf) transactions to top of history
- Fall back to timereceived when timestamp is missing
Shutdown:
- Replace blocking sleep_for calls with 100ms polling loops
- Check shutting_down_ flag throughout daemon restart/bootstrap flows
- Reduce daemon stop timeout from 30s to 10s
Other:
- Fix market chart fill artifact (single concave polygon vs per-segment quads)
- Add bootstrap checksum verification state display
- Rename daemon client identifier to ObsidianDragon
- 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)