feat(lite): real backend integration — controller, M0-M2a wiring, smoke tool, tests

- LiteWalletController (src/wallet/lite_wallet_controller.*): App-owned; runs real
  create/open/restore via the linked SDXL bridge with allowBridgeCalls=true; wipes
  seed/passphrase with sodium_memzero; persists on a ready wallet. M2a:
  applyLiteRefreshModelToWalletState maps a parsed refresh bundle into WalletState
  (zatoshi->DRGX, z/t split, tx typing + confirmations, sync progress).
- App wiring: liteWallet() accessor + init() construction when supportsLiteBackend();
  persist -> settings save.
- settings_page: "Validate" reroutes to the controller for real execution (validation-
  only fallback otherwise); wipes UI secret buffers after submit.
- chain name default -> "main" with load-time migration of legacy "DRAGONX"
  (settings.cpp), preventing the backend "Unknown chain" panic.
- M0: build.sh --lite-backend flag; lite_smoke real-backend tool + CMake targets;
  tests/fake_lite_backend.h deterministic harness.
- Tests (test_phase4): injectable-fake bridge, controller lifecycle, chain-name
  migration, refresh->WalletState mapping; plus the lite test-suite churn-cleanup rewrite.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-04 21:15:44 -05:00
parent 863d015628
commit 5586f334a4
12 changed files with 3597 additions and 121 deletions

67
tools/lite_smoke.cpp Normal file
View File

@@ -0,0 +1,67 @@
// DragonX Wallet - ImGui Edition
// Copyright 2024-2026 The Hush Developers
// Released under the GPLv3
//
// Real-backend smoke harness for the lite wallet bridge. Links the actual SDXL
// litelib_* backend (via the same imported CMake target the app uses) and exercises
// LiteClientBridge against a real lightwalletd server. This is the "real backend smoke
// test" the implementation plan gates behind passing fake-backend tests.
//
// lite_smoke [server-url] [--create]
//
// Read-only by default (available / checkServerOnline / walletExists). Pass --create to
// also attempt a real litelib_initialize_new (writes wallet state — run with an isolated
// HOME, e.g. HOME=/tmp/lite_smoke env, so it cannot clobber a real wallet).
#include "wallet/lite_client_bridge.h"
#include "wallet/lite_connection_service.h"
#include <cstdio>
#include <string>
int main(int argc, char** argv)
{
using namespace dragonx::wallet;
std::string server = "https://lite.dragonx.is";
bool doCreate = false;
for (int i = 1; i < argc; ++i) {
const std::string arg = argv[i];
if (arg == "--create") doCreate = true;
else server = arg;
}
std::printf("[lite-smoke] server = %s\n", server.c_str());
auto bridge = LiteClientBridge::linkedSdxl();
std::printf("[lite-smoke] available() = %s\n", bridge.available() ? "true" : "false");
if (!bridge.available()) {
std::printf("[lite-smoke] reason = %s\n", bridge.unavailableReason().c_str());
std::printf("[lite-smoke] FAIL: backend not linked\n");
return 2;
}
const bool walletExists = bridge.walletExists(kDragonXLiteChainName);
std::printf("[lite-smoke] walletExists(%s) = %s\n", kDragonXLiteChainName, walletExists ? "true" : "false");
const bool online = bridge.checkServerOnline(server);
std::printf("[lite-smoke] checkServerOnline() = %s\n", online ? "true" : "false");
if (doCreate) {
std::printf("[lite-smoke] initializeNew() ... (real network + writes wallet state)\n");
auto result = bridge.initializeNew(false, server);
std::printf("[lite-smoke] initializeNew ok = %s\n", result.ok ? "true" : "false");
if (result.ok) {
// The response is the new wallet's SEED PHRASE — never print it. Report only
// that a well-formed, non-empty response came back.
std::printf("[lite-smoke] wallet created; response len = %zu (seed redacted)\n",
result.value.size());
} else {
std::printf("[lite-smoke] error = %s\n", result.error.c_str());
}
}
bridge.shutdown();
std::printf("[lite-smoke] done (real litelib_* symbols are callable; results above are live)\n");
return 0;
}