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>
163 lines
5.2 KiB
C++
163 lines
5.2 KiB
C++
#pragma once
|
|
|
|
#include "lite_client_bridge.h"
|
|
#include "lite_connection_service.h"
|
|
#include "lite_result_parsers.h"
|
|
#include "lite_sync_service.h"
|
|
#include "wallet_backend.h"
|
|
#include "wallet_capabilities.h"
|
|
|
|
#include <cstddef>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace dragonx::wallet {
|
|
|
|
enum class LiteWalletGatewayCommand {
|
|
Info,
|
|
Height,
|
|
Balance,
|
|
Addresses,
|
|
Notes,
|
|
List,
|
|
};
|
|
|
|
enum class LiteWalletGatewayAvailability {
|
|
Ready,
|
|
UnsupportedBuild,
|
|
BackendUnavailable,
|
|
BridgeUnavailable,
|
|
BridgeCallsDisabled,
|
|
NoUsableServer,
|
|
};
|
|
|
|
struct LiteWalletGatewayRequest {
|
|
LiteWalletGatewayCommand command = LiteWalletGatewayCommand::Info;
|
|
std::string serverUrl;
|
|
};
|
|
|
|
struct LiteWalletGatewayPlan {
|
|
bool ok = false;
|
|
LiteWalletGatewayCommand command = LiteWalletGatewayCommand::Info;
|
|
LiteServerEndpoint server;
|
|
std::size_t serverIndex = 0;
|
|
bool customServer = false;
|
|
bool bridgeExecutionAllowed = false;
|
|
std::string commandName;
|
|
std::string args;
|
|
std::string error;
|
|
};
|
|
|
|
struct LiteWalletGatewayCommandResult {
|
|
bool ok = false;
|
|
bool attempted = false;
|
|
bool bridgeAccepted = false;
|
|
LiteWalletGatewayPlan plan;
|
|
LiteResultParserError parserError = LiteResultParserError::None;
|
|
WalletBackendStatus status;
|
|
std::string bridgeResponseRedacted = "<empty>";
|
|
std::string error;
|
|
|
|
LiteInfoResponse info;
|
|
LiteHeightResponse height;
|
|
LiteBalanceResponse balance;
|
|
LiteAddressesResponse addresses;
|
|
LiteNotesResponse notes;
|
|
LiteTransactionsResponse transactions;
|
|
};
|
|
|
|
struct LiteWalletRefreshRequest {
|
|
std::string serverUrl;
|
|
bool includeInfo = true;
|
|
bool includeHeight = true;
|
|
bool includeBalance = true;
|
|
bool includeAddresses = true;
|
|
bool includeNotes = true;
|
|
bool includeTransactions = true;
|
|
bool haveSyncStatus = false;
|
|
LiteSyncStatusResponse syncStatus;
|
|
};
|
|
|
|
struct LiteWalletRefreshPlan {
|
|
bool ok = false;
|
|
std::vector<LiteWalletGatewayPlan> commands;
|
|
std::string error;
|
|
};
|
|
|
|
struct LiteWalletRefreshBundle {
|
|
bool hasInfo = false;
|
|
bool hasHeight = false;
|
|
bool hasBalance = false;
|
|
bool hasAddresses = false;
|
|
bool hasNotes = false;
|
|
bool hasTransactions = false;
|
|
bool hasSyncStatus = false;
|
|
bool complete = false;
|
|
std::size_t successfulCommandCount = 0;
|
|
|
|
LiteInfoResponse info;
|
|
LiteHeightResponse height;
|
|
LiteBalanceResponse balance;
|
|
LiteAddressesResponse addresses;
|
|
LiteNotesResponse notes;
|
|
LiteTransactionsResponse transactions;
|
|
LiteSyncStatusResponse syncStatus;
|
|
};
|
|
|
|
struct LiteWalletRefreshResult {
|
|
bool ok = false;
|
|
bool attempted = false;
|
|
LiteWalletRefreshPlan plan;
|
|
std::vector<LiteWalletGatewayCommandResult> commandResults;
|
|
LiteWalletRefreshBundle bundle;
|
|
WalletBackendStatus status;
|
|
std::string error;
|
|
};
|
|
|
|
struct LiteWalletGatewayOptions {
|
|
bool allowBridgeCalls = false;
|
|
};
|
|
|
|
const char* liteWalletGatewayCommandName(LiteWalletGatewayCommand command);
|
|
const char* liteWalletGatewayAvailabilityName(LiteWalletGatewayAvailability availability);
|
|
|
|
std::vector<LiteWalletGatewayCommand> liteWalletRefreshCommands(const LiteWalletRefreshRequest& request);
|
|
LiteWalletRefreshBundle assembleLiteWalletRefreshBundle(const std::vector<LiteWalletGatewayCommandResult>& results,
|
|
const LiteWalletRefreshRequest& request);
|
|
|
|
class LiteWalletGateway {
|
|
public:
|
|
LiteWalletGateway(WalletCapabilities capabilities,
|
|
LiteConnectionSettings connectionSettings,
|
|
LiteClientBridge* bridge,
|
|
LiteWalletGatewayOptions options = {});
|
|
|
|
const WalletCapabilities& capabilities() const { return capabilities_; }
|
|
const LiteConnectionSettings& connectionSettings() const { return connectionSettings_; }
|
|
const LiteWalletGatewayOptions& options() const { return options_; }
|
|
|
|
LiteWalletGatewayAvailability availability() const;
|
|
WalletBackendStatus status() const;
|
|
|
|
LiteWalletGatewayPlan planCommand(const LiteWalletGatewayRequest& request) const;
|
|
LiteWalletRefreshPlan planRefresh(const LiteWalletRefreshRequest& request) const;
|
|
LiteWalletGatewayCommandResult fetchCommand(const LiteWalletGatewayRequest& request);
|
|
LiteWalletRefreshResult refresh(const LiteWalletRefreshRequest& request);
|
|
|
|
private:
|
|
LiteServerSelectionResult selectServerForRequest(const std::string& serverUrl) const;
|
|
WalletBackendStatus statusFor(LiteWalletGatewayAvailability availability,
|
|
const std::string& detail = {}) const;
|
|
LiteWalletGatewayCommandResult blockedCommandResult(const LiteWalletGatewayPlan& plan,
|
|
const WalletBackendStatus& blockedStatus) const;
|
|
LiteWalletGatewayCommandResult executePlannedCommand(const LiteWalletGatewayPlan& plan);
|
|
LiteWalletGatewayCommandResult parseBridgeResponse(const LiteWalletGatewayPlan& plan,
|
|
const std::string& response) const;
|
|
|
|
WalletCapabilities capabilities_;
|
|
LiteConnectionSettings connectionSettings_;
|
|
LiteClientBridge* bridge_ = nullptr; // non-owning; owned by LiteWalletController
|
|
LiteWalletGatewayOptions options_;
|
|
};
|
|
|
|
} // namespace dragonx::wallet
|