feat(recovery): bundle & embed the offline wallet-rebuild helper in every release

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>
This commit is contained in:
2026-08-10 22:10:57 -05:00
co-authored by Claude Opus 4.8
parent ac49f44f84
commit 393f3d147e
3 changed files with 127 additions and 9 deletions
+7
View File
@@ -55,6 +55,12 @@ BundledDaemonInfo getBundledDaemonInfo();
// caller should stop the daemon first. Returns true if all present resources were written.
bool reextractBundledDaemon();
// Ensure the embedded offline wallet-rebuild recovery helper is extracted to the daemon dir, and
// return its path ("" if not embedded in this build or extraction failed). Idempotent — extracts only
// when missing. Unlike the first-run extractEmbeddedResources() (gated on needsParamsExtraction()),
// this runs on demand so recovery works from a self-contained exe on ANY run, not just the first.
std::string ensureWalletRebuildHelperExtracted();
// Resource names
constexpr const char* RESOURCE_SAPLING_SPEND = "sapling-spend.params";
constexpr const char* RESOURCE_SAPLING_OUTPUT = "sapling-output.params";
@@ -62,6 +68,7 @@ constexpr const char* RESOURCE_ASMAP = "asmap.dat";
constexpr const char* RESOURCE_DRAGONXD = "dragonxd.exe";
constexpr const char* RESOURCE_DRAGONX_CLI = "dragonx-cli.exe";
constexpr const char* RESOURCE_DRAGONX_TX = "dragonx-tx.exe";
constexpr const char* RESOURCE_DRAGONX_WALLET_REBUILD = "dragonx-wallet-rebuild.exe";
constexpr const char* RESOURCE_XMRIG = "xmrig.exe";
constexpr const char* RESOURCE_DARK_GRADIENT = "dark_gradient.png";
constexpr const char* RESOURCE_LOGO = "logo_ObsidianDragon_dark.png";