diff --git a/CLAUDE.md b/CLAUDE.md index 8a3776d..01632d1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -70,9 +70,9 @@ Guard full-node-only code paths with `#if DRAGONX_LITE_BUILD` / chat code with ` The Lite variant is **functionally complete and runtime-verified on Linux + Windows** (work lives on branch `cleanup/lite-plan-churn`, **local-only — not pushed yet**): - **Implemented:** lifecycle (create/open/restore + auto-open on startup), sync, refresh, send / shield / import / export / seed, persistence (the backend does *not* auto-save after sync/send/shield — the controller triggers `save` at those points), and passphrase **encryption** (encrypt/unlock/lock/decrypt + Settings UI + send-time & startup unlock; the backend locks immediately on `encrypt`). All controller-tested against the fake backend (`tests/fake_lite_backend.h`) and smoke-verified against the real SDXL backend via `tools/lite_smoke` (incl. a full sync). GUI is wired end-to-end with lite-appropriate wording; the full-node RPC connect loop / wizard / daemon strings are gated out of lite (lite "online" is derived from `lite_wallet_->walletOpen()`, not RPC). -- **Packaging (verified):** `./build.sh --lite-backend --linux-release` (zip + AppImage) and `--win-release` (cross-compiled `.exe`; first build the Windows backend artifact with `scripts/build-lite-backend-artifact.sh --platform windows`). Both correctly exclude full-node assets. +- **Packaging:** `./build.sh --lite-backend --linux-release` (zip + AppImage, **verified**) and `--win-release` (cross-compiled `.exe`, **verified**; first build the Windows backend artifact with `scripts/build-lite-backend-artifact.sh --platform windows`). macOS `--lite-backend --mac-release` is **wired but not yet verified on this Linux box** (needs macOS/osxcross): the `.app`/launcher/rpath/`CFBundleExecutable` follow `ObsidianDragonLite`, full-node assets are skipped, and the lite variant gets its own `CFBundleName` ("DragonX Wallet Lite"), bundle id (`is.hush.dragonx.lite`), and DMG name so it can coexist with the full-node app. All variants correctly exclude full-node assets. - **Rollout / kill-switch (implemented):** `wallet/lite_rollout_policy.{h,cpp}` is a pure, fail-open gate (local-only, no network) feeding `LiteWalletLifecycleService::availability()` (new `RolloutDisabled` reason). Inputs: the emergency env var `DRAGONX_LITE_KILL_SWITCH` (absolute — not even `force_on` bypasses it); a `lite_rollout` setting (`auto`/`force_on`/`force_off`); and an optional **locally-cached** manifest at `/lite_rollout.json` (`global_enabled`, `min_version`/`max_version`, `blocked_versions`, `rollout_permille`, `message`) keyed for staged rollout on a hashed, never-transmitted per-install id. A signed remote fetcher can populate that cache later without touching the policy. Resolved in `App::rebuildLiteWallet()`; the disable message surfaces via the lifecycle status. Unit-tested + runtime-verified (env / manifest / control). -- **Remaining (M5b):** macOS packaging, CI backend-artifact build + signing. +- **Remaining (M5b):** verify the wired macOS `--lite` packaging on a Mac/osxcross, CI backend-artifact build + signing. - **To publish:** rename branch → `feat/lite-wallet`, base the PR on `dev` (the full-node UX is already there), and handle the dormant gated-OFF HushChat content bundled in commit `af06b8b`. The detailed milestone plan and design history (the v2 plan, backend artifact/ABI/signing design docs, the v1 plan, chat specs, etc.) are kept **untracked** under `docs/_archive/`. diff --git a/build.sh b/build.sh index 07334be..6217ca3 100755 --- a/build.sh +++ b/build.sh @@ -80,6 +80,7 @@ Examples: $0 --linux-release # Linux release (zip + AppImage) $0 --win-release # Windows cross-compile $0 --mac-release # macOS bundle + DMG (native or osxcross) + $0 --lite-backend --mac-release # macOS ObsidianDragonLite.app + DMG (lite backend) $0 --clean --linux-release --win-release # Clean + both EOF exit 0 @@ -1045,26 +1046,34 @@ TOOLCHAIN # Fix the rpath so the binary finds SDL3 in Frameworks/ if $IS_CROSS; then local INSTALL_NAME_TOOL="${OSXCROSS}/target/bin/${OSXCROSS_TRIPLE}-install_name_tool" - [[ -x "$INSTALL_NAME_TOOL" ]] && "$INSTALL_NAME_TOOL" -change "@rpath/$sdl_name" "@executable_path/../Frameworks/$sdl_name" "$MACOS/ObsidianDragon" 2>/dev/null || true + [[ -x "$INSTALL_NAME_TOOL" ]] && "$INSTALL_NAME_TOOL" -change "@rpath/$sdl_name" "@executable_path/../Frameworks/$sdl_name" "$MACOS/${APP_BASENAME}" 2>/dev/null || true else - install_name_tool -change "@rpath/$sdl_name" "@executable_path/../Frameworks/$sdl_name" "$MACOS/ObsidianDragon" 2>/dev/null || true + install_name_tool -change "@rpath/$sdl_name" "@executable_path/../Frameworks/$sdl_name" "$MACOS/${APP_BASENAME}" 2>/dev/null || true fi info " Bundled $sdl_name" fi - # Launcher script (ensures working dir + dylib path) - mv "$MACOS/ObsidianDragon" "$MACOS/ObsidianDragon.bin" - cat > "$MACOS/ObsidianDragon" <<'LAUNCH' + # Launcher script (ensures working dir + dylib path). Uses ${APP_BASENAME} so the lite + # variant (ObsidianDragonLite) gets a correctly-named launcher + .bin pair. + mv "$MACOS/${APP_BASENAME}" "$MACOS/${APP_BASENAME}.bin" + cat > "$MACOS/${APP_BASENAME}" < "$CONTENTS/Info.plist" < CFBundleName - DragonX Wallet + ${APP_DISPLAY_NAME} CFBundleDisplayName - DragonX Wallet + ${APP_DISPLAY_NAME} CFBundleIdentifier - is.hush.dragonx + ${APP_BUNDLE_ID} CFBundleVersion ${VERSION} CFBundleShortVersionString ${VERSION} CFBundleExecutable - ObsidianDragon + ${APP_BASENAME} CFBundleIconFile ObsidianDragon CFBundlePackageType @@ -1151,13 +1160,15 @@ PLIST fi # ── Create DMG ─────────────────────────────────────────────────────────── - local DMG_NAME="DragonX_Wallet-${VERSION}-macOS-${MAC_ARCH}.dmg" + local DMG_BASENAME="DragonX_Wallet" + $DO_LITE && DMG_BASENAME="DragonX_Wallet_Lite" + local DMG_NAME="${DMG_BASENAME}-${VERSION}-macOS-${MAC_ARCH}.dmg" if command -v create-dmg &>/dev/null; then # create-dmg (works on macOS; also available on Linux via npm) info "Creating DMG with create-dmg ..." create-dmg \ - --volname "DragonX Wallet" \ + --volname "${APP_DISPLAY_NAME}" \ --volicon "$RESOURCES/ObsidianDragon.icns" \ --window-pos 200 120 \ --window-size 600 400 \ @@ -1177,7 +1188,7 @@ PLIST mkdir -p "$staging" cp -a "$APP" "$staging/" ln -s /Applications "$staging/Applications" - hdiutil create -volname "DragonX Wallet" \ + hdiutil create -volname "${APP_DISPLAY_NAME}" \ -srcfolder "$staging" \ -ov -format UDZO \ "$out/$DMG_NAME" 2>/dev/null && { @@ -1193,7 +1204,7 @@ PLIST cp -a "$APP" "$staging/" # Can't create a real symlink to /Applications in an ISO, but the .app # is the important part — users drag it to Applications manually. - genisoimage -V "DragonX Wallet" \ + genisoimage -V "${APP_DISPLAY_NAME}" \ -D -R -apple -no-pad \ -o "$out/$DMG_NAME" \ "$staging" 2>/dev/null && {