feat(lite): M2b-1/2 — shared-bridge refactor + sync/refresh into WalletState
Shared-bridge refactor (litelib is a global singleton; every LiteClientBridge calls litelib_shutdown() on destruction, so services must not each own one): - LiteWalletLifecycleService, LiteWalletGateway, LiteSyncService now take a non-owning LiteClientBridge*; LiteWalletController owns the single bridge and passes &bridge_. Sync + controller refresh: - LiteSyncService::startSync executes the real "sync" command (was a stub). - LiteWalletController: startSync() (auto-fires when a wallet becomes ready) and refreshWalletState(WalletState&) — polls syncstatus, runs gateway.refresh(), maps the bundle, applies balances/addresses/transactions/sync into WalletState. Tests: - fake_lite_backend.h returns command-shaped JSON (per tests/fixtures/lite/result_parsers.json). - testLiteWalletControllerRefreshPopulatesState drives the full path against the fake. - Surfaced + worked around a real integration issue: parseLiteInfoResponse requires latest_block_height and the gateway aborts the whole refresh on the first command's parse failure (fragile vs partial backend responses; hardening tracked for M2b-3). Verified: ctest green; lite+backend, full-node, lite-no-backend apps + lite_smoke build clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -94,10 +94,13 @@ LiteWalletController::LiteWalletController(WalletCapabilities capabilities,
|
||||
LiteConnectionSettings connectionSettings,
|
||||
LiteClientBridge bridge,
|
||||
LiteWalletControllerOptions options)
|
||||
: lifecycle_(capabilities,
|
||||
std::move(connectionSettings),
|
||||
std::move(bridge),
|
||||
LiteWalletLifecycleOptions{options.allowBridgeCalls})
|
||||
: bridge_(std::move(bridge)),
|
||||
lifecycle_(capabilities, connectionSettings, &bridge_,
|
||||
LiteWalletLifecycleOptions{options.allowBridgeCalls}),
|
||||
gateway_(capabilities, connectionSettings, &bridge_,
|
||||
LiteWalletGatewayOptions{options.allowBridgeCalls}),
|
||||
sync_(capabilities, connectionSettings, &bridge_,
|
||||
LiteSyncServiceOptions{options.allowBridgeCalls})
|
||||
{
|
||||
status_ = lifecycle_.status();
|
||||
}
|
||||
@@ -119,9 +122,46 @@ void LiteWalletController::onLifecycleResult(const LiteWalletLifecycleResult& re
|
||||
if (result.walletReady) {
|
||||
walletOpen_ = true;
|
||||
if (persist_) persist_();
|
||||
startSync(); // begin background sync now that a wallet is ready
|
||||
}
|
||||
}
|
||||
|
||||
LiteSyncStartResult LiteWalletController::startSync()
|
||||
{
|
||||
auto result = sync_.startSync(LiteSyncStartRequest{});
|
||||
if (result.syncStarted) syncStarted_ = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool LiteWalletController::refreshWalletState(dragonx::WalletState& state)
|
||||
{
|
||||
if (!walletOpen_) return false;
|
||||
|
||||
// Poll sync status first so the refresh bundle (and the mapped sync model) carries it.
|
||||
LiteWalletRefreshRequest request;
|
||||
const auto syncResult = sync_.pollSyncStatus(LiteSyncStatusRequest{});
|
||||
if (syncResult.ok) {
|
||||
request.haveSyncStatus = true;
|
||||
request.syncStatus = syncResult.syncStatus;
|
||||
}
|
||||
|
||||
const auto refreshResult = gateway_.refresh(request);
|
||||
if (refreshResult.bundle.successfulCommandCount == 0 && !request.haveSyncStatus) {
|
||||
status_ = refreshResult.status;
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto mapped = mapLiteWalletRefreshResult(refreshResult);
|
||||
if (!mapped.ok) {
|
||||
status_ = refreshResult.status;
|
||||
return false;
|
||||
}
|
||||
|
||||
applyLiteRefreshModelToWalletState(mapped.model, state);
|
||||
status_ = refreshResult.status;
|
||||
return true;
|
||||
}
|
||||
|
||||
LiteWalletLifecycleResult LiteWalletController::createWallet(LiteWalletCreateRequest request)
|
||||
{
|
||||
auto result = lifecycle_.createWallet(request);
|
||||
|
||||
Reference in New Issue
Block a user