lite_bridge_runtime.{cpp,h} was ~25k lines of dry-dispatch / dynamic-loader
scaffolding that the shipping wallet never used: 0 of its 122 public types
reached the app binary. The only live code on the bridge path was the
owned-string memory-safety helper — LiteClientBridge::linkedSdxl() already
loads the backend via direct litelib_* externs in lite_client_bridge.cpp.
- Extract LiteBridgeOwnedString + liteBridgeRuntimeTakeOwnedString into
src/wallet/lite_owned_string.{h,cpp} (the copy-before-free / free-once /
wipe / "Error:"-classify boundary), with the runtime-friend coupling removed.
- Point lite_client_bridge.cpp at the new header.
- Delete lite_bridge_runtime.{cpp,h} and the 16 runtime-only tests +
their fixtures/aliases in test_phase4.cpp; keep the 5 owned-string tests
(retargeted) and restore testGeneratedResourceBehavior, which had been
caught in the runtime-test line range.
- Swap the CMake source/header references.
Both variants build; full test suite passes; source-hygiene check clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
186 lines
5.5 KiB
C++
186 lines
5.5 KiB
C++
// DragonX Wallet - ImGui Edition
|
|
// Copyright 2024-2026 The Hush Developers
|
|
// Released under the GPLv3
|
|
|
|
#include "lite_client_bridge.h"
|
|
#include "lite_owned_string.h"
|
|
|
|
#ifndef DRAGONX_ENABLE_LITE_BACKEND
|
|
#define DRAGONX_ENABLE_LITE_BACKEND 0
|
|
#endif
|
|
|
|
#if DRAGONX_ENABLE_LITE_BACKEND
|
|
extern "C" {
|
|
bool litelib_wallet_exists(const char* chain_name);
|
|
char* litelib_initialize_new(bool dangerous, const char* server);
|
|
char* litelib_initialize_new_from_phrase(bool dangerous,
|
|
const char* server,
|
|
const char* seed,
|
|
unsigned long long birthday,
|
|
unsigned long long number,
|
|
bool overwrite);
|
|
char* litelib_initialize_existing(bool dangerous, const char* server);
|
|
char* litelib_execute(const char* command, const char* args);
|
|
void litelib_rust_free_string(char* value);
|
|
bool litelib_check_server_online(const char* server);
|
|
void litelib_shutdown();
|
|
}
|
|
#endif
|
|
|
|
#include <utility>
|
|
|
|
namespace dragonx {
|
|
namespace wallet {
|
|
|
|
namespace {
|
|
|
|
bool hasRequiredApi(const LiteClientBridgeApi& api)
|
|
{
|
|
return api.walletExists &&
|
|
api.initializeNew &&
|
|
api.initializeNewFromPhrase &&
|
|
api.initializeExisting &&
|
|
api.execute &&
|
|
api.freeString &&
|
|
api.checkServerOnline &&
|
|
api.shutdown;
|
|
}
|
|
|
|
#if DRAGONX_ENABLE_LITE_BACKEND
|
|
LiteClientBridgeApi linkedSdxlApi()
|
|
{
|
|
return LiteClientBridgeApi{
|
|
&litelib_wallet_exists,
|
|
&litelib_initialize_new,
|
|
&litelib_initialize_new_from_phrase,
|
|
&litelib_initialize_existing,
|
|
&litelib_execute,
|
|
&litelib_rust_free_string,
|
|
&litelib_check_server_online,
|
|
&litelib_shutdown
|
|
};
|
|
}
|
|
#endif
|
|
|
|
} // namespace
|
|
|
|
LiteClientBridge::LiteClientBridge(LiteClientBridgeApi api, std::string unavailableReason)
|
|
: api_(api), unavailableReason_(std::move(unavailableReason))
|
|
{
|
|
}
|
|
|
|
LiteClientBridge LiteClientBridge::unavailable(std::string reason)
|
|
{
|
|
return LiteClientBridge({}, std::move(reason));
|
|
}
|
|
|
|
LiteClientBridge LiteClientBridge::fromApi(LiteClientBridgeApi api)
|
|
{
|
|
if (!hasRequiredApi(api)) {
|
|
return unavailable("lite client bridge API is incomplete");
|
|
}
|
|
return LiteClientBridge(api, {});
|
|
}
|
|
|
|
LiteClientBridge LiteClientBridge::linkedSdxl()
|
|
{
|
|
#if DRAGONX_ENABLE_LITE_BACKEND
|
|
return fromApi(linkedSdxlApi());
|
|
#else
|
|
return unavailable("lite backend is not linked");
|
|
#endif
|
|
}
|
|
|
|
LiteClientBridge::LiteClientBridge(LiteClientBridge&& other) noexcept
|
|
: api_(other.api_),
|
|
unavailableReason_(std::move(other.unavailableReason_)),
|
|
shutdownCalled_(other.shutdownCalled_)
|
|
{
|
|
other.api_ = {};
|
|
other.shutdownCalled_ = true;
|
|
}
|
|
|
|
LiteClientBridge& LiteClientBridge::operator=(LiteClientBridge&& other) noexcept
|
|
{
|
|
if (this == &other) return *this;
|
|
shutdown();
|
|
api_ = other.api_;
|
|
unavailableReason_ = std::move(other.unavailableReason_);
|
|
shutdownCalled_ = other.shutdownCalled_;
|
|
other.api_ = {};
|
|
other.shutdownCalled_ = true;
|
|
return *this;
|
|
}
|
|
|
|
LiteClientBridge::~LiteClientBridge()
|
|
{
|
|
shutdown();
|
|
}
|
|
|
|
bool LiteClientBridge::available() const
|
|
{
|
|
return hasRequiredApi(api_);
|
|
}
|
|
|
|
bool LiteClientBridge::walletExists(const std::string& chainName) const
|
|
{
|
|
if (!available()) return false;
|
|
return api_.walletExists(chainName.c_str());
|
|
}
|
|
|
|
bool LiteClientBridge::checkServerOnline(const std::string& server) const
|
|
{
|
|
if (!available()) return false;
|
|
return api_.checkServerOnline(server.c_str());
|
|
}
|
|
|
|
LiteBridgeStringResult LiteClientBridge::initializeNew(bool dangerous, const std::string& server)
|
|
{
|
|
if (!available()) return unavailableResult();
|
|
return takeOwnedString(api_.initializeNew(dangerous, server.c_str()));
|
|
}
|
|
|
|
LiteBridgeStringResult LiteClientBridge::initializeNewFromPhrase(bool dangerous,
|
|
const std::string& server,
|
|
const std::string& seed,
|
|
unsigned long long birthday,
|
|
unsigned long long account,
|
|
bool overwrite)
|
|
{
|
|
if (!available()) return unavailableResult();
|
|
return takeOwnedString(api_.initializeNewFromPhrase(
|
|
dangerous, server.c_str(), seed.c_str(), birthday, account, overwrite));
|
|
}
|
|
|
|
LiteBridgeStringResult LiteClientBridge::initializeExisting(bool dangerous, const std::string& server)
|
|
{
|
|
if (!available()) return unavailableResult();
|
|
return takeOwnedString(api_.initializeExisting(dangerous, server.c_str()));
|
|
}
|
|
|
|
LiteBridgeStringResult LiteClientBridge::execute(const std::string& command, const std::string& args)
|
|
{
|
|
if (!available()) return unavailableResult();
|
|
if (command.empty()) return {false, {}, "lite command is empty"};
|
|
return takeOwnedString(api_.execute(command.c_str(), args.c_str()));
|
|
}
|
|
|
|
void LiteClientBridge::shutdown()
|
|
{
|
|
if (shutdownCalled_) return;
|
|
shutdownCalled_ = true;
|
|
if (available()) api_.shutdown();
|
|
}
|
|
|
|
LiteBridgeStringResult LiteClientBridge::unavailableResult() const
|
|
{
|
|
return {false, {}, unavailableReason_.empty() ? "lite backend is unavailable" : unavailableReason_};
|
|
}
|
|
|
|
LiteBridgeStringResult LiteClientBridge::takeOwnedString(char* rawValue) const
|
|
{
|
|
return liteBridgeRuntimeTakeOwnedString(rawValue, api_.freeString);
|
|
}
|
|
|
|
} // namespace wallet
|
|
} // namespace dragonx
|