// 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 "wallet/lite_result_parsers.h" #include #include int main(int argc, char** argv) { using namespace dragonx::wallet; std::setvbuf(stdout, nullptr, _IONBF, 0); // unbuffered so output survives a timeout kill std::string server = "https://lite.dragonx.is"; bool doCreate = false; bool doRefresh = false; bool doFull = false; for (int i = 1; i < argc; ++i) { const std::string arg = argv[i]; if (arg == "--create") doCreate = true; else if (arg == "--refresh") doRefresh = true; else if (arg == "--full") doFull = 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()); } } if (doRefresh) { // Run each refresh command through the real parser to verify the LIVE backend's // JSON shapes match what the gateway expects. Prints flags/counts only (no secrets, // addresses, or amounts). std::printf("[lite-smoke] --- refresh shape check (real backend output -> parsers) ---\n"); { auto r = bridge.execute("info", ""); auto p = parseLiteInfoResponse(r.value); std::printf("[lite-smoke] info bridge_ok=%d parse_ok=%d err=%s\n", r.ok, p.ok, liteResultParserErrorName(p.error)); } { auto r = bridge.execute("syncstatus", ""); auto p = parseLiteSyncStatusResponse(r.value); std::printf("[lite-smoke] syncstatus bridge_ok=%d parse_ok=%d err=%s synced=%llu/%llu\n", r.ok, p.ok, liteResultParserErrorName(p.error), (unsigned long long)p.syncStatus.syncedBlocks, (unsigned long long)p.syncStatus.totalBlocks); std::printf("[lite-smoke] syncstatus RAW = %.200s\n", r.value.c_str()); } // The data commands below trigger a blocking full-chain sync on a fresh wallet; // gate them behind --full so the shape check stays fast by default. if (!doFull) { bridge.shutdown(); std::printf("[lite-smoke] (skipping balance/addresses/list; pass --full)\n"); return 0; } { auto r = bridge.execute("balance", ""); auto p = parseLiteBalanceResponse(r.value); std::printf("[lite-smoke] balance bridge_ok=%d parse_ok=%d err=%s\n", r.ok, p.ok, liteResultParserErrorName(p.error)); } { auto r = bridge.execute("addresses", ""); auto p = parseLiteAddressesResponse(r.value); std::printf("[lite-smoke] addresses bridge_ok=%d parse_ok=%d err=%s z=%zu t=%zu\n", r.ok, p.ok, liteResultParserErrorName(p.error), p.addresses.zAddresses.size(), p.addresses.tAddresses.size()); } { auto r = bridge.execute("list", ""); auto p = parseLiteTransactionsResponse(r.value); std::printf("[lite-smoke] list bridge_ok=%d parse_ok=%d err=%s count=%zu\n", r.ok, p.ok, liteResultParserErrorName(p.error), p.transactions.transactions.size()); } } bridge.shutdown(); std::printf("[lite-smoke] done (real litelib_* symbols are callable; results above are live)\n"); return 0; }