Files
ObsidianDragon/src/wallet/lite_connection_service.h
DanS dcd09dc542 refactor(audit): batch 7 — RPC/settings/lite/effects mechanical dedups
Six behavior-preserving consolidations from the audit:

- RPCClient::call() overloads share a private performCall() (payload dump +
  curl_easy_perform + http code) and a static parseRpcResult() (error->RpcError
  extraction). The timeout overload restores the prior timeout in both the
  success and catch paths, exactly as before.
- The six UnifiedCallback methods delegate to one splitUnified() that builds
  the (Callback, ErrorCallback) pair once (null-check preserved).
- One liteTrimCopy() in lite_connection_service replaces 5 file-local
  trim-copy helpers across the lite slice.
- lite_wallet_controller's inline height JSON parse now routes through the
  tested parseLiteHeightResponse().
- theme_effects.cpp: unpackRGB()/scaledAlpha() replace 14 RGB-unpack + 5
  alpha-scale copy-paste blocks.
- settings.cpp load() uses loadScalar()/loadClamped() helpers for ~44 scalar
  fields. Besides removing boilerplate this HARDENS loading: ~44 fields that
  previously only checked contains() now also verify the JSON type, so a
  malformed value in settings.json falls back to the default instead of
  throwing/misreading. Custom cases (enum parses, legacy migrations, arrays)
  stay inline; save() is unchanged.

Full-node + Lite build clean; ctest 1/1; hygiene clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:56:54 -05:00

127 lines
3.8 KiB
C++

// DragonX Wallet - ImGui Edition
// Copyright 2024-2026 The Hush Developers
// Released under the GPLv3
#pragma once
#include "lite_client_bridge.h"
#include "wallet_backend.h"
#include "wallet_capabilities.h"
#include <cstddef>
#include <string>
#include <vector>
namespace dragonx {
namespace wallet {
// The SDXL litelib backend identifies the production chain as "main" (its mainnet
// module carries DragonX's coin params). It hard-panics on any other chain name, so
// this MUST be one of {"main","test","regtest"} — not the coin ticker.
constexpr const char* kDragonXLiteChainName = "main";
constexpr const char* kDefaultDragonXLiteServer = "https://lite.dragonx.is";
enum class LiteServerSelectionMode {
Sticky,
Random
};
enum class LiteConnectionAvailability {
Ready,
UnsupportedBuild,
BackendUnavailable,
BridgeUnavailable,
NoUsableServer
};
struct LiteServerEndpoint {
std::string url;
std::string label;
bool enabled = true;
};
struct LiteConnectionSettings {
std::vector<LiteServerEndpoint> servers;
LiteServerSelectionMode selectionMode = LiteServerSelectionMode::Sticky;
std::string stickyServerUrl = kDefaultDragonXLiteServer;
std::string chainName = kDragonXLiteChainName;
std::size_t randomSelectionSeed = 0;
};
struct LiteServerSelectionResult {
bool ok = false;
LiteServerEndpoint server;
std::size_t serverIndex = 0;
bool customServer = false;
std::string error;
};
struct LiteWalletExistsRequest {
std::string chainName = kDragonXLiteChainName;
};
struct LiteServerHealthRequest {
LiteServerEndpoint server;
std::size_t serverIndex = 0;
bool customServer = false;
};
struct LiteWalletExistsCheckResult {
bool ok = false;
bool attempted = false;
bool walletExists = false;
LiteWalletExistsRequest request;
WalletBackendStatus status;
std::string error;
};
struct LiteServerHealthCheckResult {
bool ok = false;
bool attempted = false;
bool serverOnline = false;
LiteServerHealthRequest request;
WalletBackendStatus status;
std::string error;
};
// Trims leading/trailing whitespace, returning a copy. Shared across the lite slice.
std::string liteTrimCopy(const std::string& value);
std::vector<LiteServerEndpoint> defaultDragonXLiteServers();
LiteConnectionSettings defaultLiteConnectionSettings();
bool isLiteServerUrlUsable(const std::string& serverUrl);
// True if the URL is one of the built-in official DragonX lite servers (gets a glowing outline).
bool isOfficialLiteServer(const std::string& serverUrl);
const char* liteServerSelectionModeName(LiteServerSelectionMode mode);
const char* liteConnectionAvailabilityName(LiteConnectionAvailability availability);
LiteServerSelectionResult selectLiteServer(const LiteConnectionSettings& settings);
class LiteConnectionService {
public:
LiteConnectionService(WalletCapabilities capabilities,
LiteConnectionSettings settings,
LiteClientBridge bridge);
const LiteConnectionSettings& settings() const { return settings_; }
const WalletCapabilities& capabilities() const { return capabilities_; }
LiteConnectionAvailability availability() const;
WalletBackendStatus status() const;
LiteServerSelectionResult selectedServer() const;
LiteWalletExistsRequest walletExistsRequest() const;
LiteServerHealthRequest serverHealthRequest() const;
LiteWalletExistsCheckResult checkWalletExists();
LiteServerHealthCheckResult checkSelectedServerHealth();
private:
WalletBackendStatus statusFor(LiteConnectionAvailability availability,
const std::string& detail = {}) const;
WalletBackendStatus bridgeReadinessStatus() const;
WalletCapabilities capabilities_;
LiteConnectionSettings settings_;
LiteClientBridge bridge_;
};
} // namespace wallet
} // namespace dragonx