From 4baab13bddd13a36f931be089c0f6c3b6c1d101b Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Wed, 10 Jun 2026 15:16:20 -0400 Subject: [PATCH] update api --- CMakeLists.txt | 1 - flake.nix | 2 +- metadata.json | 7 +- src/i_logos_execution_zone_wallet_module.h | 107 ---- src/logos_execution_zone_wallet_module.cpp | 593 +++++++++++---------- src/logos_execution_zone_wallet_module.h | 164 ++---- tests/test_execution_zone.cpp | 200 ++++--- tests/test_execution_zone_integration.cpp | 14 +- 8 files changed, 466 insertions(+), 622 deletions(-) delete mode 100644 src/i_logos_execution_zone_wallet_module.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a74fcca..3e6bae5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,6 @@ logos_module( SOURCES src/logos_execution_zone_wallet_module.h src/logos_execution_zone_wallet_module.cpp - src/i_logos_execution_zone_wallet_module.h EXTERNAL_LIBS wallet_ffi ) diff --git a/flake.nix b/flake.nix index c2e2bf6..3675d04 100644 --- a/flake.nix +++ b/flake.nix @@ -1,5 +1,5 @@ { - description = "Logos Execution Zone Wallet Module - Qt6 Plugin"; + description = "Logos Execution Zone Wallet Module"; inputs = { logos-module-builder.url = "github:logos-co/logos-module-builder"; diff --git a/metadata.json b/metadata.json index a3994d1..09ae8bc 100644 --- a/metadata.json +++ b/metadata.json @@ -5,6 +5,11 @@ "author": "Logos Blockchain Team", "type": "core", "category": "blockchain", + "interface": "universal", + "codegen": { + "impl_header": "src/logos_execution_zone_wallet_module.h", + "impl_class": "LogosExecutionZoneWalletModule" + }, "main": "logos_execution_zone_plugin", "dependencies": [], "capabilities": [], @@ -13,7 +18,7 @@ "nix": { "packages": { "build": [], - "runtime": [] + "runtime": ["nlohmann_json"] }, "external_libraries": [ { diff --git a/src/i_logos_execution_zone_wallet_module.h b/src/i_logos_execution_zone_wallet_module.h deleted file mode 100644 index def8a41..0000000 --- a/src/i_logos_execution_zone_wallet_module.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef I_LOGOS_EXECUTION_ZONE_WALLET_MODULE_H -#define I_LOGOS_EXECUTION_ZONE_WALLET_MODULE_H - -#include - -class ILogosExecutionZoneWalletModule { -public: - virtual ~ILogosExecutionZoneWalletModule() = default; - - // === Logos Core === - - virtual void initLogos(LogosAPI* logosApiInstance) = 0; - - // === Logos Execution Zone Wallet === - - // Account Management - virtual QString create_account_public() = 0; - virtual QString create_account_private() = 0; - virtual QJsonArray list_accounts() = 0; - - // Account Queries - virtual QString get_balance(const QString& account_id_hex, bool is_public) = 0; - virtual QString get_account_public(const QString& account_id_hex) = 0; - virtual QString get_account_private(const QString& account_id_hex) = 0; - virtual QString get_public_account_key(const QString& account_id_hex) = 0; - virtual QString get_private_account_keys(const QString& account_id_hex) = 0; - - // Account Encoding - virtual QString account_id_to_base58(const QString& account_id_hex) = 0; - virtual QString account_id_from_base58(const QString& base58_str) = 0; - - // Blockchain Synchronisation - virtual int sync_to_block(uint64_t block_id) = 0; - virtual int sync_to_block(const QString& block_id_str) = 0; - virtual int get_last_synced_block() = 0; - virtual int get_current_block_height() = 0; - - // Pinata - virtual QString claim_pinata( - const QString& pinata_account_id_hex, - const QString& winner_account_id_hex, - const QString& solution_le16_hex - ) = 0; - virtual QString claim_pinata_private_owned_already_initialized( - const QString& pinata_account_id_hex, - const QString& winner_account_id_hex, - const QString& solution_le16_hex, - uint64_t winner_proof_index, - const QString& winner_proof_siblings_json - ) = 0; - virtual QString claim_pinata_private_owned_not_initialized( - const QString& pinata_account_id_hex, - const QString& winner_account_id_hex, - const QString& solution_le16_hex - ) = 0; - - // Operations - virtual QString transfer_public( - const QString& from_hex, - const QString& to_hex, - const QString& amount_le16_hex - ) = 0; - virtual QString transfer_shielded( - const QString& from_hex, - const QString& to_keys_json, - const QString& amount_le16_hex - ) = 0; - virtual QString transfer_deshielded( - const QString& from_hex, - const QString& to_hex, - const QString& amount_le16_hex - ) = 0; - virtual QString transfer_private( - const QString& from_hex, - const QString& to_keys_json, - const QString& amount_le16_hex - ) = 0; - virtual QString transfer_shielded_owned( - const QString& from_hex, - const QString& to_hex, - const QString& amount_le16_hex - ) = 0; - virtual QString transfer_private_owned( - const QString& from_hex, - const QString& to_hex, - const QString& amount_le16_hex - ) = 0; - virtual QString register_public_account(const QString& account_id_hex) = 0; - virtual QString register_private_account(const QString& account_id_hex) = 0; - - // Wallet Lifecycle - virtual int create_new( - const QString& config_path, - const QString& storage_path, - const QString& password - ) = 0; - virtual int open(const QString& config_path, const QString& storage_path) = 0; - virtual int save() = 0; - - // Configuration & Metadata - virtual QString get_sequencer_addr() = 0; -}; - -#define ILogosExecutionZoneWalletModule_iid "org.logos.ilogosexecutionzonewalletmodule" -Q_DECLARE_INTERFACE(ILogosExecutionZoneWalletModule, ILogosExecutionZoneWalletModule_iid) - -#endif diff --git a/src/logos_execution_zone_wallet_module.cpp b/src/logos_execution_zone_wallet_module.cpp index aed6c09..b235590 100644 --- a/src/logos_execution_zone_wallet_module.cpp +++ b/src/logos_execution_zone_wallet_module.cpp @@ -1,26 +1,35 @@ #include "logos_execution_zone_wallet_module.h" #include -#include -#include -#include -#include -#include +#include +#include +#include +#include -static QString bytesToHex(const uint8_t* data, const size_t length) { - const QByteArray bytearray(reinterpret_cast(data), static_cast(length)); - return QString::fromLatin1(bytearray.toHex()); +#include + +namespace { + +std::string bytesToHex(const uint8_t* data, const size_t length) { + static const char hexChars[] = "0123456789abcdef"; + std::string out; + out.reserve(length * 2); + for (size_t i = 0; i < length; ++i) { + out.push_back(hexChars[(data[i] >> 4) & 0xF]); + out.push_back(hexChars[data[i] & 0xF]); + } + return out; } // Balance from wallet_ffi_get_balance is 16 bytes little-endian (u128). Convert to decimal string for UI. // Requires __uint128_t (GCC/Clang on 64-bit). -static QString balanceLe16ToDecimalString(const uint8_t* data) { +std::string balanceLe16ToDecimalString(const uint8_t* data) { #if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ >= 16 __uint128_t v = 0; for (int i = 0; i < 16; ++i) v |= static_cast<__uint128_t>(data[i]) << (i * 8); if (v == 0) - return QStringLiteral("0"); + return "0"; char buf[40]; int i = 0; while (v) { @@ -28,122 +37,151 @@ static QString balanceLe16ToDecimalString(const uint8_t* data) { v /= 10; } std::reverse(buf, buf + i); - return QString::fromLatin1(buf, i); + return std::string(buf, i); #else #error "balanceLe16ToDecimalString requires __uint128_t; build with GCC or Clang on 64-bit" #endif } namespace JsonKeys { -static constexpr auto TxHash = "tx_hash"; -static constexpr auto Success = "success"; -static constexpr auto Error = "error"; -static constexpr auto ProgramOwner = "program_owner"; -static constexpr auto Balance = "balance"; -static constexpr auto Nonce = "nonce"; -static constexpr auto Data = "data"; -static constexpr auto NullifierPublicKey = "nullifier_public_key"; -static constexpr auto ViewingPublicKey = "viewing_public_key"; -static constexpr auto AccountId = "account_id"; -static constexpr auto IsPublic = "is_public"; +constexpr auto TxHash = "tx_hash"; +constexpr auto Success = "success"; +constexpr auto Error = "error"; +constexpr auto ProgramOwner = "program_owner"; +constexpr auto Balance = "balance"; +constexpr auto Nonce = "nonce"; +constexpr auto Data = "data"; +constexpr auto NullifierPublicKey = "nullifier_public_key"; +constexpr auto ViewingPublicKey = "viewing_public_key"; +constexpr auto AccountId = "account_id"; +constexpr auto IsPublic = "is_public"; } // namespace JsonKeys -static bool hexToBytes(const QString& hex, QByteArray& output_bytes, int expectedLength = -1) { - QString trimmed_hex = hex.trimmed(); - if (trimmed_hex.startsWith("0x", Qt::CaseInsensitive)) - trimmed_hex = trimmed_hex.mid(2); - if (trimmed_hex.size() % 2 != 0) +bool hexToBytes(const std::string& hex, std::vector& output_bytes, int expectedLength = -1) { + // Trim whitespace. + size_t start = hex.find_first_not_of(" \t\n\r\f\v"); + if (start == std::string::npos) { + output_bytes.clear(); + return expectedLength == -1 || expectedLength == 0; + } + size_t end = hex.find_last_not_of(" \t\n\r\f\v"); + std::string trimmed = hex.substr(start, end - start + 1); + + if (trimmed.size() >= 2 && trimmed[0] == '0' && (trimmed[1] == 'x' || trimmed[1] == 'X')) + trimmed = trimmed.substr(2); + + if (trimmed.size() % 2 != 0) return false; - const QByteArray decoded = QByteArray::fromHex(trimmed_hex.toLatin1()); - if (expectedLength != -1 && decoded.size() != expectedLength) + + std::vector decoded; + decoded.reserve(trimmed.size() / 2); + auto nibble = [](char c, int& out) -> bool { + if (c >= '0' && c <= '9') { out = c - '0'; return true; } + if (c >= 'a' && c <= 'f') { out = c - 'a' + 10; return true; } + if (c >= 'A' && c <= 'F') { out = c - 'A' + 10; return true; } return false; - output_bytes = decoded; + }; + for (size_t i = 0; i < trimmed.size(); i += 2) { + int hi = 0, lo = 0; + if (!nibble(trimmed[i], hi) || !nibble(trimmed[i + 1], lo)) + return false; + decoded.push_back(static_cast((hi << 4) | lo)); + } + + if (expectedLength != -1 && static_cast(decoded.size()) != expectedLength) + return false; + + output_bytes = std::move(decoded); return true; } -static bool hexToU128(const QString& hex, uint8_t (*output)[16]) { - QByteArray buffer; +bool hexToU128(const std::string& hex, uint8_t (*output)[16]) { + std::vector buffer; if (!hexToBytes(hex, buffer, 16)) return false; - memcpy(output, buffer.constData(), 16); + memcpy(output, buffer.data(), 16); return true; } -static QString bytes32ToHex(const FfiBytes32& bytes) { +std::string bytes32ToHex(const FfiBytes32& bytes) { return bytesToHex(bytes.data, 32); } -static bool hexToBytes32(const QString& hex, FfiBytes32* output_bytes) { +bool hexToBytes32(const std::string& hex, FfiBytes32* output_bytes) { if (output_bytes == nullptr) return false; - QByteArray buffer; + std::vector buffer; if (!hexToBytes(hex, buffer, 32)) return false; - memcpy(output_bytes->data, buffer.constData(), 32); + memcpy(output_bytes->data, buffer.data(), 32); return true; } // Builds JSON { success, tx_hash, error } for both success (result + empty error) and failure (nullptr + errorMessage). -static QString transferResultToJson(const FfiTransferResult* result, const QString& errorMessage) { - QVariantMap map; - const bool isError = !errorMessage.isEmpty(); - map[JsonKeys::Success] = !isError && result && result->success; - map[JsonKeys::TxHash] = (!isError && result && result->tx_hash) ? QString::fromUtf8(result->tx_hash) : QString(); - map[JsonKeys::Error] = errorMessage; - return QJsonDocument(QJsonObject::fromVariantMap(map)).toJson(QJsonDocument::Compact); +std::string transferResultToJson(const FfiTransferResult* result, const std::string& errorMessage) { + nlohmann::json obj = nlohmann::json::object(); + const bool isError = !errorMessage.empty(); + obj[JsonKeys::Success] = !isError && result && result->success; + obj[JsonKeys::TxHash] = (!isError && result && result->tx_hash) ? std::string(result->tx_hash) : std::string(); + obj[JsonKeys::Error] = errorMessage; + return obj.dump(); } -static QString ffiAccountToJson(const FfiAccount& account) { - QVariantMap map; - map[JsonKeys::ProgramOwner] = bytesToHex(reinterpret_cast(account.program_owner.data), 32); - map[JsonKeys::Balance] = bytesToHex(account.balance.data, 16); - map[JsonKeys::Nonce] = bytesToHex(account.nonce.data, 16); +std::string ffiAccountToJson(const FfiAccount& account) { + nlohmann::json obj = nlohmann::json::object(); + obj[JsonKeys::ProgramOwner] = bytesToHex(reinterpret_cast(account.program_owner.data), 32); + obj[JsonKeys::Balance] = bytesToHex(account.balance.data, 16); + obj[JsonKeys::Nonce] = bytesToHex(account.nonce.data, 16); if (account.data && account.data_len > 0) { - map[JsonKeys::Data] = bytesToHex(account.data, account.data_len); + obj[JsonKeys::Data] = bytesToHex(account.data, account.data_len); } else { - map[JsonKeys::Data] = QString(); + obj[JsonKeys::Data] = ""; } - return QJsonDocument(QJsonObject::fromVariantMap(map)).toJson(QJsonDocument::Compact); + return obj.dump(); } -static QJsonObject ffiAccountListEntryToJson(const FfiAccountListEntry& entry) { - QVariantMap map; - map[JsonKeys::AccountId] = bytes32ToHex(entry.account_id); - map[JsonKeys::IsPublic] = entry.is_public; - return QJsonObject::fromVariantMap(map); +nlohmann::json ffiAccountListEntryToJson(const FfiAccountListEntry& entry) { + nlohmann::json obj = nlohmann::json::object(); + obj[JsonKeys::AccountId] = bytes32ToHex(entry.account_id); + obj[JsonKeys::IsPublic] = entry.is_public; + return obj; } -static QString ffiPrivateAccountKeysToJson(const FfiPrivateAccountKeys& keys) { - QVariantMap map; - map[JsonKeys::NullifierPublicKey] = bytes32ToHex(keys.nullifier_public_key); +std::string ffiPrivateAccountKeysToJson(const FfiPrivateAccountKeys& keys) { + nlohmann::json obj = nlohmann::json::object(); + obj[JsonKeys::NullifierPublicKey] = bytes32ToHex(keys.nullifier_public_key); if (keys.viewing_public_key && keys.viewing_public_key_len > 0) { - map[JsonKeys::ViewingPublicKey] = bytesToHex(keys.viewing_public_key, keys.viewing_public_key_len); + obj[JsonKeys::ViewingPublicKey] = bytesToHex(keys.viewing_public_key, keys.viewing_public_key_len); } else { - map[JsonKeys::ViewingPublicKey] = QString(); + obj[JsonKeys::ViewingPublicKey] = ""; } - return QJsonDocument(QJsonObject::fromVariantMap(map)).toJson(QJsonDocument::Compact); + return obj.dump(); } -static bool jsonToFfiPrivateAccountKeys(const QString& json, FfiPrivateAccountKeys* output_keys) { - QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8()); - if (!doc.isObject()) +bool jsonToFfiPrivateAccountKeys(const std::string& json, FfiPrivateAccountKeys* output_keys) { + nlohmann::json doc = nlohmann::json::parse(json, nullptr, false); + if (doc.is_discarded() || !doc.is_object()) return false; - const QVariantMap map = doc.object().toVariantMap(); - if (map.contains(JsonKeys::NullifierPublicKey)) { - if (!hexToBytes32(map[JsonKeys::NullifierPublicKey].toString(), &output_keys->nullifier_public_key)) + if (doc.contains(JsonKeys::NullifierPublicKey) && doc[JsonKeys::NullifierPublicKey].is_string()) { + if (!hexToBytes32(doc[JsonKeys::NullifierPublicKey].get(), &output_keys->nullifier_public_key)) return false; } - if (map.contains(JsonKeys::ViewingPublicKey)) { - QByteArray buffer; - if (!hexToBytes(map[JsonKeys::ViewingPublicKey].toString(), buffer)) + if (doc.contains(JsonKeys::ViewingPublicKey) && doc[JsonKeys::ViewingPublicKey].is_string()) { + std::vector buffer; + if (!hexToBytes(doc[JsonKeys::ViewingPublicKey].get(), buffer)) return false; - uint8_t* data = static_cast(malloc(buffer.size())); - memcpy(data, buffer.constData(), buffer.size()); - output_keys->viewing_public_key = data; - output_keys->viewing_public_key_len = buffer.size(); + if (buffer.empty()) { + output_keys->viewing_public_key = nullptr; + output_keys->viewing_public_key_len = 0; + } else { + auto* data = static_cast(malloc(buffer.size())); + memcpy(data, buffer.data(), buffer.size()); + output_keys->viewing_public_key = data; + output_keys->viewing_public_key_len = buffer.size(); + } } else { output_keys->viewing_public_key = nullptr; output_keys->viewing_public_key_len = 0; @@ -154,29 +192,28 @@ static bool jsonToFfiPrivateAccountKeys(const QString& json, FfiPrivateAccountKe // Parses a JSON array of 32-byte hex strings into a contiguous byte buffer of siblings. // Returns true on success, with out_len set to the number of siblings and out_bytes sized to out_len*32. -static bool jsonArrayHexToSiblings32(const QString& json_array_str, QByteArray& out_bytes, uintptr_t& out_len) { - QJsonDocument doc = QJsonDocument::fromJson(json_array_str.toUtf8()); - if (!doc.isArray()) { +bool jsonArrayHexToSiblings32(const std::string& json_array_str, std::vector& out_bytes, uintptr_t& out_len) { + nlohmann::json doc = nlohmann::json::parse(json_array_str, nullptr, false); + if (doc.is_discarded() || !doc.is_array()) return false; - } - const QJsonArray arr = doc.array(); - out_len = static_cast(arr.size()); - out_bytes.clear(); - out_bytes.reserve(static_cast(out_len * 32)); - for (const QJsonValue& v : arr) { - if (!v.isString()) { + out_len = static_cast(doc.size()); + out_bytes.clear(); + out_bytes.reserve(out_len * 32); + + for (const auto& v : doc) { + if (!v.is_string()) return false; - } - QByteArray bytes; - if (!hexToBytes(v.toString(), bytes, 32)) { + std::vector bytes; + if (!hexToBytes(v.get(), bytes, 32)) return false; - } - out_bytes.append(bytes); + out_bytes.insert(out_bytes.end(), bytes.begin(), bytes.end()); } return true; } +} // namespace + LogosExecutionZoneWalletModule::LogosExecutionZoneWalletModule() = default; LogosExecutionZoneWalletModule::~LogosExecutionZoneWalletModule() { @@ -186,54 +223,46 @@ LogosExecutionZoneWalletModule::~LogosExecutionZoneWalletModule() { } } -// === Plugin Interface === - -QString LogosExecutionZoneWalletModule::name() const { +std::string LogosExecutionZoneWalletModule::name() const { return "logos_execution_zone"; } -QString LogosExecutionZoneWalletModule::version() const { +std::string LogosExecutionZoneWalletModule::version() const { return "1.0.0"; } -// === Logos Core === - -void LogosExecutionZoneWalletModule::initLogos(LogosAPI* logosApiInstance) { - logosAPI = logosApiInstance; -} - // === Account Management === -QString LogosExecutionZoneWalletModule::create_account_public() { +std::string LogosExecutionZoneWalletModule::create_account_public() { FfiBytes32 id{}; const WalletFfiError error = wallet_ffi_create_account_public(walletHandle, &id); if (error != SUCCESS) { - qWarning() << "create_account_public: wallet FFI error" << error; + fprintf(stderr, "create_account_public: wallet FFI error %d\n", error); return {}; } return bytes32ToHex(id); } -QString LogosExecutionZoneWalletModule::create_account_private() { +std::string LogosExecutionZoneWalletModule::create_account_private() { FfiBytes32 id{}; const WalletFfiError error = wallet_ffi_create_account_private(walletHandle, &id); if (error != SUCCESS) { - qWarning() << "create_account_private: wallet FFI error" << error; + fprintf(stderr, "create_account_private: wallet FFI error %d\n", error); return {}; } return bytes32ToHex(id); } -QJsonArray LogosExecutionZoneWalletModule::list_accounts() { +LogosList LogosExecutionZoneWalletModule::list_accounts() { + LogosList result = nlohmann::json::array(); FfiAccountList list{}; const WalletFfiError error = wallet_ffi_list_accounts(walletHandle, &list); if (error != SUCCESS) { - qWarning() << "list_accounts: wallet FFI error" << error; - return {}; + fprintf(stderr, "list_accounts: wallet FFI error %d\n", error); + return result; } - QJsonArray result; for (uintptr_t i = 0; i < list.count; ++i) { - result.append(ffiAccountListEntryToJson(list.entries[i])); + result.push_back(ffiAccountListEntryToJson(list.entries[i])); } wallet_ffi_free_account_list(&list); return result; @@ -241,120 +270,114 @@ QJsonArray LogosExecutionZoneWalletModule::list_accounts() { // === Account Queries === -QString LogosExecutionZoneWalletModule::get_balance(const QString& account_id_hex, const bool is_public) { +std::string LogosExecutionZoneWalletModule::get_balance(const std::string& account_id_hex, const bool is_public) { FfiBytes32 id{}; if (!hexToBytes32(account_id_hex, &id)) { - qWarning() << "get_balance: invalid account_id_hex"; + fprintf(stderr, "get_balance: invalid account_id_hex\n"); return {}; } uint8_t balance[16] = {0}; const WalletFfiError error = wallet_ffi_get_balance(walletHandle, &id, is_public, &balance); if (error != SUCCESS) { - qWarning() << "get_balance: wallet FFI error" << error; + fprintf(stderr, "get_balance: wallet FFI error %d\n", error); return {}; } // Return decimal string for UI display (balance is 16-byte little-endian u128). return balanceLe16ToDecimalString(balance); } -QString LogosExecutionZoneWalletModule::get_balance(const QString& account_id_hex, const QString& is_public_str) { - const bool is_public = (is_public_str == QStringLiteral("true") - || is_public_str == QStringLiteral("1") - || is_public_str.compare(QStringLiteral("yes"), Qt::CaseInsensitive) == 0); - return get_balance(account_id_hex, is_public); -} - -QString LogosExecutionZoneWalletModule::get_account_public(const QString& account_id_hex) { +std::string LogosExecutionZoneWalletModule::get_account_public(const std::string& account_id_hex) { FfiBytes32 id{}; if (!hexToBytes32(account_id_hex, &id)) { - qWarning() << "get_account_public: invalid account_id_hex"; + fprintf(stderr, "get_account_public: invalid account_id_hex\n"); return {}; } FfiAccount account{}; const WalletFfiError error = wallet_ffi_get_account_public(walletHandle, &id, &account); if (error != SUCCESS) { - qWarning() << "get_account_public: wallet FFI error" << error; + fprintf(stderr, "get_account_public: wallet FFI error %d\n", error); return {}; } - QString result = ffiAccountToJson(account); + std::string result = ffiAccountToJson(account); wallet_ffi_free_account_data(&account); return result; } -QString LogosExecutionZoneWalletModule::get_account_private(const QString& account_id_hex) { +std::string LogosExecutionZoneWalletModule::get_account_private(const std::string& account_id_hex) { FfiBytes32 id{}; if (!hexToBytes32(account_id_hex, &id)) { - qWarning() << "get_account_private: invalid account_id_hex"; + fprintf(stderr, "get_account_private: invalid account_id_hex\n"); return {}; } FfiAccount account{}; const WalletFfiError error = wallet_ffi_get_account_private(walletHandle, &id, &account); if (error != SUCCESS) { - qWarning() << "get_account_private: wallet FFI error" << error; + fprintf(stderr, "get_account_private: wallet FFI error %d\n", error); return {}; } - QString result = ffiAccountToJson(account); + std::string result = ffiAccountToJson(account); wallet_ffi_free_account_data(&account); return result; } -QString LogosExecutionZoneWalletModule::get_public_account_key(const QString& account_id_hex) { +std::string LogosExecutionZoneWalletModule::get_public_account_key(const std::string& account_id_hex) { FfiBytes32 id{}; if (!hexToBytes32(account_id_hex, &id)) { - qWarning() << "get_public_account_key: invalid account_id_hex"; + fprintf(stderr, "get_public_account_key: invalid account_id_hex\n"); return {}; } FfiPublicAccountKey key{}; const WalletFfiError error = wallet_ffi_get_public_account_key(walletHandle, &id, &key); if (error != SUCCESS) { - qWarning() << "get_public_account_key: wallet FFI error" << error; + fprintf(stderr, "get_public_account_key: wallet FFI error %d\n", error); return {}; } return bytes32ToHex(key.public_key); } -QString LogosExecutionZoneWalletModule::get_private_account_keys(const QString& account_id_hex) { +std::string LogosExecutionZoneWalletModule::get_private_account_keys(const std::string& account_id_hex) { FfiBytes32 id{}; if (!hexToBytes32(account_id_hex, &id)) { - qWarning() << "get_private_account_keys: invalid account_id_hex"; + fprintf(stderr, "get_private_account_keys: invalid account_id_hex\n"); return {}; } FfiPrivateAccountKeys keys{}; const WalletFfiError error = wallet_ffi_get_private_account_keys(walletHandle, &id, &keys); if (error != SUCCESS) { - qWarning() << "get_private_account_keys: wallet FFI error" << error; + fprintf(stderr, "get_private_account_keys: wallet FFI error %d\n", error); return {}; } - QString result = ffiPrivateAccountKeysToJson(keys); + std::string result = ffiPrivateAccountKeysToJson(keys); wallet_ffi_free_private_account_keys(&keys); return result; } // === Account Encoding === -QString LogosExecutionZoneWalletModule::account_id_to_base58(const QString& account_id_hex) { +std::string LogosExecutionZoneWalletModule::account_id_to_base58(const std::string& account_id_hex) { FfiBytes32 id{}; if (!hexToBytes32(account_id_hex, &id)) { + fprintf(stderr, "account_id_to_base58: invalid account_id_hex\n"); return {}; } char* str = wallet_ffi_account_id_to_base58(&id); if (!str) { + fprintf(stderr, "account_id_to_base58: wallet_ffi returned null\n"); return {}; } - QString result = QString::fromUtf8(str); + std::string value(str); wallet_ffi_free_string(str); - return result; + return value; } -QString LogosExecutionZoneWalletModule::account_id_from_base58(const QString& base58_str) { +std::string LogosExecutionZoneWalletModule::account_id_from_base58(const std::string& base58_str) { FfiBytes32 id{}; - const QByteArray utf8 = base58_str.toUtf8(); - const WalletFfiError error = wallet_ffi_account_id_from_base58(utf8.constData(), &id); + const WalletFfiError error = wallet_ffi_account_id_from_base58(base58_str.c_str(), &id); if (error != SUCCESS) { - qWarning() << "account_id_from_base58: wallet FFI error" << error; + fprintf(stderr, "account_id_from_base58: wallet FFI error %d\n", error); return {}; } return bytes32ToHex(id); @@ -362,96 +385,86 @@ QString LogosExecutionZoneWalletModule::account_id_from_base58(const QString& ba // === Blockchain Synchronisation === -int LogosExecutionZoneWalletModule::sync_to_block(const uint64_t block_id) { - return wallet_ffi_sync_to_block(walletHandle, block_id); +int64_t LogosExecutionZoneWalletModule::sync_to_block(const int64_t block_id) { + return wallet_ffi_sync_to_block(walletHandle, static_cast(block_id)); } -int LogosExecutionZoneWalletModule::sync_to_block(const QString& block_id_str) { - bool ok = false; - const uint64_t block_id = block_id_str.trimmed().toULongLong(&ok); - if (!ok) { - qWarning() << "sync_to_block: invalid block id string:" << block_id_str; - return -1; - } - return sync_to_block(block_id); -} - -int LogosExecutionZoneWalletModule::get_last_synced_block() { +int64_t LogosExecutionZoneWalletModule::get_last_synced_block() { uint64_t block_id = 0; const WalletFfiError error = wallet_ffi_get_last_synced_block(walletHandle, &block_id); if (error != SUCCESS) { - qWarning() << "get_last_synced_block: wallet FFI error" << error; + fprintf(stderr, "get_last_synced_block: wallet FFI error %d\n", error); return 0; } - return static_cast(block_id); + return static_cast(block_id); } -int LogosExecutionZoneWalletModule::get_current_block_height() { +int64_t LogosExecutionZoneWalletModule::get_current_block_height() { uint64_t block_height = 0; const WalletFfiError error = wallet_ffi_get_current_block_height(walletHandle, &block_height); if (error != SUCCESS) { - qWarning() << "get_current_block_height: wallet FFI error" << error; + fprintf(stderr, "get_current_block_height: wallet FFI error %d\n", error); return 0; } - return static_cast(block_height); + return static_cast(block_height); } // === Pinata claiming === -QString LogosExecutionZoneWalletModule::claim_pinata( - const QString& pinata_account_id_hex, - const QString& winner_account_id_hex, - const QString& solution_le16_hex +std::string LogosExecutionZoneWalletModule::claim_pinata( + const std::string& pinata_account_id_hex, + const std::string& winner_account_id_hex, + const std::string& solution_le16_hex ) { FfiBytes32 pinataId{}, winnerId{}; if (!hexToBytes32(pinata_account_id_hex, &pinataId) || !hexToBytes32(winner_account_id_hex, &winnerId)) { - qWarning() << "claim_pinata: invalid account id hex"; + fprintf(stderr, "claim_pinata: invalid account id hex\n"); return {}; } uint8_t solution[16]; if (!hexToU128(solution_le16_hex, &solution)) { - qWarning() << "claim_pinata: solution_le16_hex must be 32 hex characters (16 bytes)"; + fprintf(stderr, "claim_pinata: solution_le16_hex must be 32 hex characters (16 bytes)\n"); return {}; } FfiTransferResult result{}; const WalletFfiError error = wallet_ffi_claim_pinata(walletHandle, &pinataId, &winnerId, &solution, &result); if (error != SUCCESS) { - qWarning() << "claim_pinata: wallet FFI error" << error; + fprintf(stderr, "claim_pinata: wallet FFI error %d\n", error); return {}; } - QString resultJson = transferResultToJson(&result, QString()); + std::string resultJson = transferResultToJson(&result, std::string()); wallet_ffi_free_transfer_result(&result); return resultJson; } -QString LogosExecutionZoneWalletModule::claim_pinata_private_owned_already_initialized( - const QString& pinata_account_id_hex, - const QString& winner_account_id_hex, - const QString& solution_le16_hex, - uint64_t winner_proof_index, - const QString& winner_proof_siblings_json +std::string LogosExecutionZoneWalletModule::claim_pinata_private_owned_already_initialized( + const std::string& pinata_account_id_hex, + const std::string& winner_account_id_hex, + const std::string& solution_le16_hex, + int64_t winner_proof_index, + const std::string& winner_proof_siblings_json ) { FfiBytes32 pinataId{}, winnerId{}; if (!hexToBytes32(pinata_account_id_hex, &pinataId) || !hexToBytes32(winner_account_id_hex, &winnerId)) { - qWarning() << "claim_pinata_private_owned_already_initialized: invalid account id hex"; + fprintf(stderr, "claim_pinata_private_owned_already_initialized: invalid account id hex\n"); return {}; } uint8_t solution[16]; if (!hexToU128(solution_le16_hex, &solution)) { - qWarning() << "claim_pinata_private_owned_already_initialized: solution_le16_hex must be 32 hex characters (16 bytes)"; + fprintf(stderr, "claim_pinata_private_owned_already_initialized: solution_le16_hex must be 32 hex characters (16 bytes)\n"); return {}; } - QByteArray siblings_bytes; + std::vector siblings_bytes; uintptr_t siblings_len = 0; if (!jsonArrayHexToSiblings32(winner_proof_siblings_json, siblings_bytes, siblings_len)) { - qWarning() << "claim_pinata_private_owned_already_initialized: failed to parse winner_proof_siblings_json"; + fprintf(stderr, "claim_pinata_private_owned_already_initialized: failed to parse winner_proof_siblings_json\n"); return {}; } const uint8_t (*siblings_ptr)[32] = nullptr; if (siblings_len > 0) { - siblings_ptr = reinterpret_cast(siblings_bytes.constData()); + siblings_ptr = reinterpret_cast(siblings_bytes.data()); } FfiTransferResult result{}; @@ -466,27 +479,27 @@ QString LogosExecutionZoneWalletModule::claim_pinata_private_owned_already_initi &result ); if (error != SUCCESS) { - qWarning() << "claim_pinata_private_owned_already_initialized: wallet FFI error" << error; + fprintf(stderr, "claim_pinata_private_owned_already_initialized: wallet FFI error %d\n", error); return {}; } - QString resultJson = transferResultToJson(&result, QString()); + std::string resultJson = transferResultToJson(&result, std::string()); wallet_ffi_free_transfer_result(&result); return resultJson; } -QString LogosExecutionZoneWalletModule::claim_pinata_private_owned_not_initialized( - const QString& pinata_account_id_hex, - const QString& winner_account_id_hex, - const QString& solution_le16_hex +std::string LogosExecutionZoneWalletModule::claim_pinata_private_owned_not_initialized( + const std::string& pinata_account_id_hex, + const std::string& winner_account_id_hex, + const std::string& solution_le16_hex ) { FfiBytes32 pinataId{}, winnerId{}; if (!hexToBytes32(pinata_account_id_hex, &pinataId) || !hexToBytes32(winner_account_id_hex, &winnerId)) { - qWarning() << "claim_pinata_private_owned_not_initialized: invalid account id hex"; + fprintf(stderr, "claim_pinata_private_owned_not_initialized: invalid account id hex\n"); return {}; } uint8_t solution[16]; if (!hexToU128(solution_le16_hex, &solution)) { - qWarning() << "claim_pinata_private_owned_not_initialized: solution_le16_hex must be 32 hex characters (16 bytes)"; + fprintf(stderr, "claim_pinata_private_owned_not_initialized: solution_le16_hex must be 32 hex characters (16 bytes)\n"); return {}; } FfiTransferResult result{}; @@ -498,290 +511,284 @@ QString LogosExecutionZoneWalletModule::claim_pinata_private_owned_not_initializ &result ); if (error != SUCCESS) { - qWarning() << "claim_pinata_private_owned_not_initialized: wallet FFI error" << error; + fprintf(stderr, "claim_pinata_private_owned_not_initialized: wallet FFI error %d\n", error); return {}; } - QString resultJson = transferResultToJson(&result, QString()); + std::string resultJson = transferResultToJson(&result, std::string()); wallet_ffi_free_transfer_result(&result); return resultJson; } // === Operations === -QString LogosExecutionZoneWalletModule::transfer_public( - const QString& from_hex, - const QString& to_hex, - const QString& amount_le16_hex +std::string LogosExecutionZoneWalletModule::transfer_public( + const std::string& from_hex, + const std::string& to_hex, + const std::string& amount_le16_hex ) { FfiBytes32 fromId{}, toId{}; if (!hexToBytes32(from_hex, &fromId) || !hexToBytes32(to_hex, &toId)) { - qWarning() << "transfer_public: invalid account id hex"; - return transferResultToJson(nullptr, QStringLiteral("transfer_public: invalid account id hex")); + fprintf(stderr, "transfer_public: invalid account id hex\n"); + return transferResultToJson(nullptr, "transfer_public: invalid account id hex"); } uint8_t amount[16]; if (!hexToU128(amount_le16_hex, &amount)) { - qWarning() << "transfer_public: amount_le16_hex must be 32 hex characters (16 bytes)"; - return transferResultToJson(nullptr, QStringLiteral("transfer_public: amount_le16_hex must be 32 hex characters (16 bytes)")); + fprintf(stderr, "transfer_public: amount_le16_hex must be 32 hex characters (16 bytes)\n"); + return transferResultToJson(nullptr, "transfer_public: amount_le16_hex must be 32 hex characters (16 bytes)"); } FfiTransferResult result{}; const WalletFfiError error = wallet_ffi_transfer_public(walletHandle, &fromId, &toId, &amount, &result); if (error != SUCCESS) { - qWarning() << "transfer_public: wallet FFI error" << error; - return transferResultToJson(nullptr, QStringLiteral("transfer_public: wallet FFI error ") + QString::number(error)); + fprintf(stderr, "transfer_public: wallet FFI error %d\n", error); + return transferResultToJson(nullptr, "transfer_public: wallet FFI error " + std::to_string(error)); } - QString resultJson = transferResultToJson(&result, QString()); + std::string resultJson = transferResultToJson(&result, std::string()); wallet_ffi_free_transfer_result(&result); return resultJson; } -QString LogosExecutionZoneWalletModule::transfer_shielded( - const QString& from_hex, - const QString& to_keys_json, - const QString& amount_le16_hex +std::string LogosExecutionZoneWalletModule::transfer_shielded( + const std::string& from_hex, + const std::string& to_keys_json, + const std::string& amount_le16_hex ) { FfiBytes32 fromId{}; if (!hexToBytes32(from_hex, &fromId)) { - qWarning() << "transfer_shielded: invalid from account id hex"; - return transferResultToJson(nullptr, QStringLiteral("transfer_shielded: invalid from account id hex")); + fprintf(stderr, "transfer_shielded: invalid from account id hex\n"); + return transferResultToJson(nullptr, "transfer_shielded: invalid from account id hex"); } FfiPrivateAccountKeys toKeys{}; if (!jsonToFfiPrivateAccountKeys(to_keys_json, &toKeys)) { - qWarning() << "transfer_shielded: failed to parse to_keys_json"; - return transferResultToJson(nullptr, QStringLiteral("transfer_shielded: failed to parse to_keys_json")); + fprintf(stderr, "transfer_shielded: failed to parse to_keys_json\n"); + return transferResultToJson(nullptr, "transfer_shielded: failed to parse to_keys_json"); } uint8_t amount[16]; if (!hexToU128(amount_le16_hex, &amount)) { - qWarning() << "transfer_shielded: amount_le16_hex must be 32 hex characters (16 bytes)"; + fprintf(stderr, "transfer_shielded: amount_le16_hex must be 32 hex characters (16 bytes)\n"); free(const_cast(toKeys.viewing_public_key)); - return transferResultToJson(nullptr, QStringLiteral("transfer_shielded: amount_le16_hex must be 32 hex characters (16 bytes)")); + return transferResultToJson(nullptr, "transfer_shielded: amount_le16_hex must be 32 hex characters (16 bytes)"); } FfiTransferResult result{}; const WalletFfiError error = wallet_ffi_transfer_shielded(walletHandle, &fromId, &toKeys, &amount, &result); free(const_cast(toKeys.viewing_public_key)); if (error != SUCCESS) { - qWarning() << "transfer_shielded: wallet FFI error" << error; - return transferResultToJson(nullptr, QStringLiteral("transfer_shielded: wallet FFI error ") + QString::number(error)); + fprintf(stderr, "transfer_shielded: wallet FFI error %d\n", error); + return transferResultToJson(nullptr, "transfer_shielded: wallet FFI error " + std::to_string(error)); } - QString resultJson = transferResultToJson(&result, QString()); + std::string resultJson = transferResultToJson(&result, std::string()); wallet_ffi_free_transfer_result(&result); return resultJson; } -QString LogosExecutionZoneWalletModule::transfer_deshielded( - const QString& from_hex, - const QString& to_hex, - const QString& amount_le16_hex +std::string LogosExecutionZoneWalletModule::transfer_deshielded( + const std::string& from_hex, + const std::string& to_hex, + const std::string& amount_le16_hex ) { FfiBytes32 fromId{}, toId{}; if (!hexToBytes32(from_hex, &fromId) || !hexToBytes32(to_hex, &toId)) { - qWarning() << "transfer_deshielded: invalid account id hex"; - return transferResultToJson(nullptr, QStringLiteral("transfer_deshielded: invalid account id hex")); + fprintf(stderr, "transfer_deshielded: invalid account id hex\n"); + return transferResultToJson(nullptr, "transfer_deshielded: invalid account id hex"); } uint8_t amount[16]; if (!hexToU128(amount_le16_hex, &amount)) { - qWarning() << "transfer_deshielded: amount_le16_hex must be 32 hex characters (16 bytes)"; - return transferResultToJson(nullptr, QStringLiteral("transfer_deshielded: amount_le16_hex must be 32 hex characters (16 bytes)")); + fprintf(stderr, "transfer_deshielded: amount_le16_hex must be 32 hex characters (16 bytes)\n"); + return transferResultToJson(nullptr, "transfer_deshielded: amount_le16_hex must be 32 hex characters (16 bytes)"); } FfiTransferResult result{}; const WalletFfiError error = wallet_ffi_transfer_deshielded(walletHandle, &fromId, &toId, &amount, &result); if (error != SUCCESS) { - qWarning() << "transfer_deshielded: wallet FFI error" << error; - return transferResultToJson(nullptr, QStringLiteral("transfer_deshielded: wallet FFI error ") + QString::number(error)); + fprintf(stderr, "transfer_deshielded: wallet FFI error %d\n", error); + return transferResultToJson(nullptr, "transfer_deshielded: wallet FFI error " + std::to_string(error)); } - QString resultJson = transferResultToJson(&result, QString()); + std::string resultJson = transferResultToJson(&result, std::string()); wallet_ffi_free_transfer_result(&result); return resultJson; } -QString LogosExecutionZoneWalletModule::transfer_private( - const QString& from_hex, - const QString& to_keys_json, - const QString& amount_le16_hex +std::string LogosExecutionZoneWalletModule::transfer_private( + const std::string& from_hex, + const std::string& to_keys_json, + const std::string& amount_le16_hex ) { FfiBytes32 fromId{}; if (!hexToBytes32(from_hex, &fromId)) { - qWarning() << "transfer_private: invalid from account id hex"; - return transferResultToJson(nullptr, QStringLiteral("transfer_private: invalid from account id hex")); + fprintf(stderr, "transfer_private: invalid from account id hex\n"); + return transferResultToJson(nullptr, "transfer_private: invalid from account id hex"); } FfiPrivateAccountKeys toKeys{}; if (!jsonToFfiPrivateAccountKeys(to_keys_json, &toKeys)) { - qWarning() << "transfer_private: failed to parse to_keys_json"; - return transferResultToJson(nullptr, QStringLiteral("transfer_private: failed to parse to_keys_json")); + fprintf(stderr, "transfer_private: failed to parse to_keys_json\n"); + return transferResultToJson(nullptr, "transfer_private: failed to parse to_keys_json"); } uint8_t amount[16]; if (!hexToU128(amount_le16_hex, &amount)) { - qWarning() << "transfer_private: amount_le16_hex must be 32 hex characters (16 bytes)"; + fprintf(stderr, "transfer_private: amount_le16_hex must be 32 hex characters (16 bytes)\n"); free(const_cast(toKeys.viewing_public_key)); - return transferResultToJson(nullptr, QStringLiteral("transfer_private: amount_le16_hex must be 32 hex characters (16 bytes)")); + return transferResultToJson(nullptr, "transfer_private: amount_le16_hex must be 32 hex characters (16 bytes)"); } FfiTransferResult result{}; const WalletFfiError error = wallet_ffi_transfer_private(walletHandle, &fromId, &toKeys, &amount, &result); free(const_cast(toKeys.viewing_public_key)); if (error != SUCCESS) { - qWarning() << "transfer_private: wallet FFI error" << error; - return transferResultToJson(nullptr, QStringLiteral("transfer_private: wallet FFI error ") + QString::number(error)); + fprintf(stderr, "transfer_private: wallet FFI error %d\n", error); + return transferResultToJson(nullptr, "transfer_private: wallet FFI error " + std::to_string(error)); } - QString resultJson = transferResultToJson(&result, QString()); + std::string resultJson = transferResultToJson(&result, std::string()); wallet_ffi_free_transfer_result(&result); return resultJson; } -QString LogosExecutionZoneWalletModule::transfer_shielded_owned( - const QString& from_hex, - const QString& to_hex, - const QString& amount_le16_hex +std::string LogosExecutionZoneWalletModule::transfer_shielded_owned( + const std::string& from_hex, + const std::string& to_hex, + const std::string& amount_le16_hex ) { FfiBytes32 fromId{}, toId{}; if (!hexToBytes32(from_hex, &fromId) || !hexToBytes32(to_hex, &toId)) { - qWarning() << "transfer_shielded_owned: invalid account id hex"; - return transferResultToJson(nullptr, QStringLiteral("transfer_shielded_owned: invalid account id hex")); + fprintf(stderr, "transfer_shielded_owned: invalid account id hex\n"); + return transferResultToJson(nullptr, "transfer_shielded_owned: invalid account id hex"); } uint8_t amount[16]; if (!hexToU128(amount_le16_hex, &amount)) { - qWarning() << "transfer_shielded_owned: amount_le16_hex must be 32 hex characters (16 bytes)"; - return transferResultToJson(nullptr, QStringLiteral("transfer_shielded_owned: amount_le16_hex must be 32 hex characters (16 bytes)")); + fprintf(stderr, "transfer_shielded_owned: amount_le16_hex must be 32 hex characters (16 bytes)\n"); + return transferResultToJson(nullptr, "transfer_shielded_owned: amount_le16_hex must be 32 hex characters (16 bytes)"); } FfiTransferResult result{}; const WalletFfiError error = wallet_ffi_transfer_shielded_owned(walletHandle, &fromId, &toId, &amount, &result); if (error != SUCCESS) { - qWarning() << "transfer_shielded_owned: wallet FFI error" << error; - return transferResultToJson(nullptr, QStringLiteral("transfer_shielded_owned: wallet FFI error ") + QString::number(error)); + fprintf(stderr, "transfer_shielded_owned: wallet FFI error %d\n", error); + return transferResultToJson(nullptr, "transfer_shielded_owned: wallet FFI error " + std::to_string(error)); } - QString resultJson = transferResultToJson(&result, QString()); + std::string resultJson = transferResultToJson(&result, std::string()); wallet_ffi_free_transfer_result(&result); return resultJson; } -QString LogosExecutionZoneWalletModule::transfer_private_owned( - const QString& from_hex, - const QString& to_hex, - const QString& amount_le16_hex +std::string LogosExecutionZoneWalletModule::transfer_private_owned( + const std::string& from_hex, + const std::string& to_hex, + const std::string& amount_le16_hex ) { FfiBytes32 fromId{}, toId{}; if (!hexToBytes32(from_hex, &fromId) || !hexToBytes32(to_hex, &toId)) { - qWarning() << "transfer_private_owned: invalid account id hex"; - return transferResultToJson(nullptr, QStringLiteral("transfer_private_owned: invalid account id hex")); + fprintf(stderr, "transfer_private_owned: invalid account id hex\n"); + return transferResultToJson(nullptr, "transfer_private_owned: invalid account id hex"); } uint8_t amount[16]; if (!hexToU128(amount_le16_hex, &amount)) { - qWarning() << "transfer_private_owned: amount_le16_hex must be 32 hex characters (16 bytes)"; - return transferResultToJson(nullptr, QStringLiteral("transfer_private_owned: amount_le16_hex must be 32 hex characters (16 bytes)")); + fprintf(stderr, "transfer_private_owned: amount_le16_hex must be 32 hex characters (16 bytes)\n"); + return transferResultToJson(nullptr, "transfer_private_owned: amount_le16_hex must be 32 hex characters (16 bytes)"); } FfiTransferResult result{}; const WalletFfiError error = wallet_ffi_transfer_private_owned(walletHandle, &fromId, &toId, &amount, &result); if (error != SUCCESS) { - qWarning() << "transfer_private_owned: wallet FFI error" << error; - return transferResultToJson(nullptr, QStringLiteral("transfer_private_owned: wallet FFI error ") + QString::number(error)); + fprintf(stderr, "transfer_private_owned: wallet FFI error %d\n", error); + return transferResultToJson(nullptr, "transfer_private_owned: wallet FFI error " + std::to_string(error)); } - QString resultJson = transferResultToJson(&result, QString()); + std::string resultJson = transferResultToJson(&result, std::string()); wallet_ffi_free_transfer_result(&result); return resultJson; } -QString LogosExecutionZoneWalletModule::register_public_account(const QString& account_id_hex) { +std::string LogosExecutionZoneWalletModule::register_public_account(const std::string& account_id_hex) { FfiBytes32 id{}; if (!hexToBytes32(account_id_hex, &id)) { - qWarning() << "register_public_account: invalid account_id_hex"; - return transferResultToJson(nullptr, QStringLiteral("register_public_account: invalid account_id_hex")); + fprintf(stderr, "register_public_account: invalid account_id_hex\n"); + return transferResultToJson(nullptr, "register_public_account: invalid account_id_hex"); } FfiTransferResult result{}; const WalletFfiError error = wallet_ffi_register_public_account(walletHandle, &id, &result); if (error != SUCCESS) { - qWarning() << "register_public_account: wallet FFI error" << error; - return transferResultToJson(nullptr, QStringLiteral("register_public_account: wallet FFI error ") + QString::number(error)); + fprintf(stderr, "register_public_account: wallet FFI error %d\n", error); + return transferResultToJson(nullptr, "register_public_account: wallet FFI error " + std::to_string(error)); } - QString resultJson = transferResultToJson(&result, QString()); + std::string resultJson = transferResultToJson(&result, std::string()); wallet_ffi_free_transfer_result(&result); return resultJson; } -QString LogosExecutionZoneWalletModule::register_private_account(const QString& account_id_hex) { +std::string LogosExecutionZoneWalletModule::register_private_account(const std::string& account_id_hex) { FfiBytes32 id{}; if (!hexToBytes32(account_id_hex, &id)) { - qWarning() << "register_private_account: invalid account_id_hex"; - return transferResultToJson(nullptr, QStringLiteral("register_private_account: invalid account_id_hex")); + fprintf(stderr, "register_private_account: invalid account_id_hex\n"); + return transferResultToJson(nullptr, "register_private_account: invalid account_id_hex"); } FfiTransferResult result{}; const WalletFfiError error = wallet_ffi_register_private_account(walletHandle, &id, &result); if (error != SUCCESS) { - qWarning() << "register_private_account: wallet FFI error" << error; - return transferResultToJson(nullptr, QStringLiteral("register_private_account: wallet FFI error ") + QString::number(error)); + fprintf(stderr, "register_private_account: wallet FFI error %d\n", error); + return transferResultToJson(nullptr, "register_private_account: wallet FFI error " + std::to_string(error)); } - QString resultJson = transferResultToJson(&result, QString()); + std::string resultJson = transferResultToJson(&result, std::string()); wallet_ffi_free_transfer_result(&result); return resultJson; } // === Wallet Lifecycle === -int LogosExecutionZoneWalletModule::create_new( - const QString& config_path, - const QString& storage_path, - const QString& password +int64_t LogosExecutionZoneWalletModule::create_new( + const std::string& config_path, + const std::string& storage_path, + const std::string& password ) { if (walletHandle) { - qWarning() << "create_new: wallet is already open"; + fprintf(stderr, "create_new: wallet is already open\n"); return INTERNAL_ERROR; } - const QByteArray config_utf8 = config_path.toUtf8(); - const QByteArray storage_utf8 = storage_path.toUtf8(); - const QByteArray password_utf8 = password.toUtf8(); - - walletHandle = wallet_ffi_create_new(config_utf8.constData(), storage_utf8.constData(), password_utf8.constData()); + walletHandle = wallet_ffi_create_new(config_path.c_str(), storage_path.c_str(), password.c_str()); if (!walletHandle) { - qWarning() << "create_new: wallet_ffi_create_new returned null"; + fprintf(stderr, "create_new: wallet_ffi_create_new returned null\n"); return INTERNAL_ERROR; } return SUCCESS; } -int LogosExecutionZoneWalletModule::open(const QString& config_path, const QString& storage_path) { +int64_t LogosExecutionZoneWalletModule::open(const std::string& config_path, const std::string& storage_path) { if (walletHandle) { - qWarning() << "open: wallet is already open"; + fprintf(stderr, "open: wallet is already open\n"); return INTERNAL_ERROR; } - const QByteArray config_utf8 = config_path.toUtf8(); - const QByteArray storage_utf8 = storage_path.toUtf8(); - - walletHandle = wallet_ffi_open(config_utf8.constData(), storage_utf8.constData()); + walletHandle = wallet_ffi_open(config_path.c_str(), storage_path.c_str()); if (!walletHandle) { - qWarning() << "open: wallet_ffi_open returned null"; + fprintf(stderr, "open: wallet_ffi_open returned null\n"); return INTERNAL_ERROR; } return SUCCESS; } -int LogosExecutionZoneWalletModule::save() { +int64_t LogosExecutionZoneWalletModule::save() { return wallet_ffi_save(walletHandle); } // === Configuration === -QString LogosExecutionZoneWalletModule::get_sequencer_addr() { +std::string LogosExecutionZoneWalletModule::get_sequencer_addr() { char* addr = wallet_ffi_get_sequencer_addr(walletHandle); if (!addr) { + fprintf(stderr, "get_sequencer_addr: wallet_ffi returned null\n"); return {}; } - QString result = QString::fromUtf8(addr); + std::string value(addr); wallet_ffi_free_string(addr); - return result; + return value; } diff --git a/src/logos_execution_zone_wallet_module.h b/src/logos_execution_zone_wallet_module.h index bf30074..23f201a 100644 --- a/src/logos_execution_zone_wallet_module.h +++ b/src/logos_execution_zone_wallet_module.h @@ -1,130 +1,80 @@ #ifndef LOGOS_EXECUTION_ZONE_WALLET_MODULE_H #define LOGOS_EXECUTION_ZONE_WALLET_MODULE_H -#include "i_logos_execution_zone_wallet_module.h" +#include +#include + +#include -#ifdef __cplusplus extern "C" { -#endif #include -#ifdef __cplusplus } -#endif - -#include -#include -#include -#include - -class LogosExecutionZoneWalletModule : public QObject, public PluginInterface, public ILogosExecutionZoneWalletModule { - Q_OBJECT - Q_PLUGIN_METADATA(IID ILogosExecutionZoneWalletModule_iid FILE "metadata.json") - Q_INTERFACES(PluginInterface ILogosExecutionZoneWalletModule) - -private: - LogosAPI* logosApi = nullptr; - WalletHandle* walletHandle = nullptr; +// Universal (Qt-free) execution-zone wallet module. The Qt glue (provider +// object + plugin) is generated from this header by logos-cpp-generator, which +// maps the std return types below to the Qt signatures callers invoke: +// std::string -> QString, int64_t -> int, LogosList -> QVariantList. +// +// NOTE: the generator parses this header line-by-line and only recognises a +// method when its declaration ends with ';' on a single line. Keep every +// method declaration on ONE line — multi-line signatures are silently dropped. +class LogosExecutionZoneWalletModule { public: LogosExecutionZoneWalletModule(); - ~LogosExecutionZoneWalletModule() override; + ~LogosExecutionZoneWalletModule(); - // === Plugin Interface === - [[nodiscard]] QString name() const override; - [[nodiscard]] QString version() const override; + LogosExecutionZoneWalletModule(const LogosExecutionZoneWalletModule&) = delete; + LogosExecutionZoneWalletModule& operator=(const LogosExecutionZoneWalletModule&) = delete; - // === Logos Core === + std::string name() const; + std::string version() const; - Q_INVOKABLE void initLogos(LogosAPI* logosApiInstance) override; + // === Wallet Lifecycle === + int64_t create_new(const std::string& config_path, const std::string& storage_path, const std::string& password); + int64_t open(const std::string& config_path, const std::string& storage_path); + int64_t save(); - // === Logos Execution Zone Wallet === + // === Account Management === + std::string create_account_public(); + std::string create_account_private(); + LogosList list_accounts(); - // Pinata claiming - Q_INVOKABLE QString claim_pinata( - const QString& pinata_account_id_hex, - const QString& winner_account_id_hex, - const QString& solution_le16_hex - ) override; - Q_INVOKABLE QString claim_pinata_private_owned_already_initialized( - const QString& pinata_account_id_hex, - const QString& winner_account_id_hex, - const QString& solution_le16_hex, - uint64_t winner_proof_index, - const QString& winner_proof_siblings_json - ) override; - Q_INVOKABLE QString claim_pinata_private_owned_not_initialized( - const QString& pinata_account_id_hex, - const QString& winner_account_id_hex, - const QString& solution_le16_hex - ) override; + // === Account Queries === + std::string get_balance(const std::string& account_id_hex, bool is_public); + std::string get_account_public(const std::string& account_id_hex); + std::string get_account_private(const std::string& account_id_hex); + std::string get_public_account_key(const std::string& account_id_hex); + std::string get_private_account_keys(const std::string& account_id_hex); - // Account Management - Q_INVOKABLE QString create_account_public() override; - Q_INVOKABLE QString create_account_private() override; - Q_INVOKABLE QJsonArray list_accounts() override; + // === Account Encoding === + std::string account_id_to_base58(const std::string& account_id_hex); + std::string account_id_from_base58(const std::string& base58_str); - // Account Queries - Q_INVOKABLE QString get_balance(const QString& account_id_hex, bool is_public) override; - Q_INVOKABLE QString get_balance(const QString& account_id_hex, const QString& is_public_str); - Q_INVOKABLE QString get_account_public(const QString& account_id_hex) override; - Q_INVOKABLE QString get_account_private(const QString& account_id_hex) override; - Q_INVOKABLE QString get_public_account_key(const QString& account_id_hex) override; - Q_INVOKABLE QString get_private_account_keys(const QString& account_id_hex) override; + // === Blockchain Synchronisation === + int64_t sync_to_block(int64_t block_id); + int64_t get_last_synced_block(); + int64_t get_current_block_height(); - // Account Encoding - Q_INVOKABLE QString account_id_to_base58(const QString& account_id_hex) override; - Q_INVOKABLE QString account_id_from_base58(const QString& base58_str) override; + // === Pinata claiming === + std::string claim_pinata(const std::string& pinata_account_id_hex, const std::string& winner_account_id_hex, const std::string& solution_le16_hex); + std::string claim_pinata_private_owned_already_initialized(const std::string& pinata_account_id_hex, const std::string& winner_account_id_hex, const std::string& solution_le16_hex, int64_t winner_proof_index, const std::string& winner_proof_siblings_json); + std::string claim_pinata_private_owned_not_initialized(const std::string& pinata_account_id_hex, const std::string& winner_account_id_hex, const std::string& solution_le16_hex); - // Blockchain Synchronisation - Q_INVOKABLE int sync_to_block(uint64_t block_id) override; - Q_INVOKABLE int sync_to_block(const QString& block_id_str) override; - Q_INVOKABLE int get_last_synced_block() override; - Q_INVOKABLE int get_current_block_height() override; + // === Operations === + std::string transfer_public(const std::string& from_hex, const std::string& to_hex, const std::string& amount_le16_hex); + std::string transfer_shielded(const std::string& from_hex, const std::string& to_keys_json, const std::string& amount_le16_hex); + std::string transfer_deshielded(const std::string& from_hex, const std::string& to_hex, const std::string& amount_le16_hex); + std::string transfer_private(const std::string& from_hex, const std::string& to_keys_json, const std::string& amount_le16_hex); + std::string transfer_shielded_owned(const std::string& from_hex, const std::string& to_hex, const std::string& amount_le16_hex); + std::string transfer_private_owned(const std::string& from_hex, const std::string& to_hex, const std::string& amount_le16_hex); + std::string register_public_account(const std::string& account_id_hex); + std::string register_private_account(const std::string& account_id_hex); - // Operations - Q_INVOKABLE QString transfer_public( - const QString& from_hex, - const QString& to_hex, - const QString& amount_le16_hex - ) override; - Q_INVOKABLE QString transfer_shielded( - const QString& from_hex, - const QString& to_keys_json, - const QString& amount_le16_hex - ) override; - Q_INVOKABLE QString transfer_deshielded( - const QString& from_hex, - const QString& to_hex, - const QString& amount_le16_hex - ) override; - Q_INVOKABLE QString transfer_private( - const QString& from_hex, - const QString& to_keys_json, - const QString& amount_le16_hex - ) override; - Q_INVOKABLE QString transfer_shielded_owned( - const QString& from_hex, - const QString& to_hex, - const QString& amount_le16_hex - ) override; - Q_INVOKABLE QString transfer_private_owned( - const QString& from_hex, - const QString& to_hex, - const QString& amount_le16_hex - ) override; - Q_INVOKABLE QString register_public_account(const QString& account_id_hex) override; - Q_INVOKABLE QString register_private_account(const QString& account_id_hex) override; + // === Configuration === + std::string get_sequencer_addr(); - // Wallet Lifecycle - Q_INVOKABLE int create_new(const QString& config_path, const QString& storage_path, const QString& password) override; - Q_INVOKABLE int open(const QString& config_path, const QString& storage_path) override; - Q_INVOKABLE int save() override; - - // Configuration - Q_INVOKABLE QString get_sequencer_addr() override; - -signals: - void eventResponse(const QString& eventName, const QVariantList& data); +private: + WalletHandle* walletHandle = nullptr; }; -#endif +#endif // LOGOS_EXECUTION_ZONE_WALLET_MODULE_H diff --git a/tests/test_execution_zone.cpp b/tests/test_execution_zone.cpp index b51191b..4eca948 100644 --- a/tests/test_execution_zone.cpp +++ b/tests/test_execution_zone.cpp @@ -4,19 +4,20 @@ #include #include "logos_execution_zone_wallet_module.h" -#include -#include -#include -#include +#include + +#include // 64-char hex string = 32 bytes (valid account id). -static const QString VALID_ID = QString(64, 'a'); -static const QString VALID_ID_2 = QString(64, 'b'); +static const std::string VALID_ID = std::string(64, 'a'); +static const std::string VALID_ID_2 = std::string(64, 'b'); // 32-char hex string = 16 bytes (valid amount / solution). -static const QString VALID_U128 = QString(32, '1'); +static const std::string VALID_U128 = std::string(32, '1'); -static QJsonObject parseObject(const QString& json) { - return QJsonDocument::fromJson(json.toUtf8()).object(); +// The impl returns serialized JSON strings (Qt-free). Parse them here so tests +// can assert on individual fields. +static nlohmann::json parseObject(const std::string& json) { + return nlohmann::json::parse(json, nullptr, false); } // ============================================================================ @@ -25,8 +26,8 @@ static QJsonObject parseObject(const QString& json) { LOGOS_TEST(name_and_version) { LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_EQ(module.name(), QStringLiteral("logos_execution_zone")); - LOGOS_ASSERT_EQ(module.version(), QStringLiteral("1.0.0")); + LOGOS_ASSERT_EQ(module.name(), std::string("logos_execution_zone")); + LOGOS_ASSERT_EQ(module.version(), std::string("1.0.0")); } // ============================================================================ @@ -37,10 +38,12 @@ LOGOS_TEST(create_account_public_returns_hex_on_success) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - const QString id = module.create_account_public(); + const std::string id = module.create_account_public(); LOGOS_ASSERT(t.cFunctionCalled("wallet_ffi_create_account_public")); // Mock fills the id with 0xAB bytes -> 64 hex chars ("ab" x 32). - LOGOS_ASSERT_EQ(id, QString("ab").repeated(32)); + std::string expected; + for (int i = 0; i < 32; ++i) expected += "ab"; + LOGOS_ASSERT_EQ(id, expected); } LOGOS_TEST(create_account_public_returns_empty_on_error) { @@ -48,16 +51,18 @@ LOGOS_TEST(create_account_public_returns_empty_on_error) { t.mockCFunction("wallet_ffi_create_account_public").returns(static_cast(INTERNAL_ERROR)); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_TRUE(module.create_account_public().isEmpty()); + LOGOS_ASSERT_TRUE(module.create_account_public().empty()); } LOGOS_TEST(create_account_private_returns_hex_on_success) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - const QString id = module.create_account_private(); + const std::string id = module.create_account_private(); LOGOS_ASSERT(t.cFunctionCalled("wallet_ffi_create_account_private")); - LOGOS_ASSERT_EQ(id, QString("cd").repeated(32)); + std::string expected; + for (int i = 0; i < 32; ++i) expected += "cd"; + LOGOS_ASSERT_EQ(id, expected); } LOGOS_TEST(list_accounts_maps_entries) { @@ -65,17 +70,16 @@ LOGOS_TEST(list_accounts_maps_entries) { t.mockCFunction("list_accounts_count").returns(3); LogosExecutionZoneWalletModule module; - const QJsonArray accounts = module.list_accounts(); + const LogosList accounts = module.list_accounts(); LOGOS_ASSERT(t.cFunctionCalled("wallet_ffi_list_accounts")); - LOGOS_ASSERT_EQ(accounts.size(), 3); + LOGOS_ASSERT_EQ(static_cast(accounts.size()), 3); - // list_accounts appends JSON objects (ffiAccountListEntryToJson returns a - // QJsonObject); entry 0 is public, entry 1 is private. - const QJsonObject e0 = accounts[0].toObject(); - LOGOS_ASSERT_TRUE(e0["is_public"].toBool()); - LOGOS_ASSERT_EQ(e0["account_id"].toString(), QString("10").repeated(32)); - const QJsonObject e1 = accounts[1].toObject(); - LOGOS_ASSERT_FALSE(e1["is_public"].toBool()); + // entry 0 is public, entry 1 is private. + std::string expectedId0; + for (int i = 0; i < 32; ++i) expectedId0 += "10"; + LOGOS_ASSERT_TRUE(accounts[0]["is_public"].get()); + LOGOS_ASSERT_EQ(accounts[0]["account_id"].get(), expectedId0); + LOGOS_ASSERT_FALSE(accounts[1]["is_public"].get()); } LOGOS_TEST(list_accounts_empty_on_error) { @@ -83,7 +87,7 @@ LOGOS_TEST(list_accounts_empty_on_error) { t.mockCFunction("wallet_ffi_list_accounts").returns(static_cast(INTERNAL_ERROR)); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_EQ(module.list_accounts().size(), 0); + LOGOS_ASSERT_EQ(static_cast(module.list_accounts().size()), 0); } // ============================================================================ @@ -94,7 +98,7 @@ LOGOS_TEST(get_balance_invalid_hex_returns_empty) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_TRUE(module.get_balance(QStringLiteral("not-hex"), true).isEmpty()); + LOGOS_ASSERT_TRUE(module.get_balance("not-hex", true).empty()); LOGOS_ASSERT_FALSE(t.cFunctionCalled("wallet_ffi_get_balance")); } @@ -103,9 +107,9 @@ LOGOS_TEST(get_balance_returns_decimal_string) { t.mockCFunction("get_balance_value").returns(123456789); LogosExecutionZoneWalletModule module; - const QString balance = module.get_balance(VALID_ID, true); + const std::string balance = module.get_balance(VALID_ID, true); LOGOS_ASSERT(t.cFunctionCalled("wallet_ffi_get_balance")); - LOGOS_ASSERT_EQ(balance, QStringLiteral("123456789")); + LOGOS_ASSERT_EQ(balance, std::string("123456789")); } LOGOS_TEST(get_balance_zero) { @@ -113,35 +117,26 @@ LOGOS_TEST(get_balance_zero) { t.mockCFunction("get_balance_value").returns(0); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_EQ(module.get_balance(VALID_ID, false), QStringLiteral("0")); -} - -LOGOS_TEST(get_balance_string_overload_parses_bool) { - auto t = LogosTestContext("logos_execution_zone"); - t.mockCFunction("get_balance_value").returns(42); - LogosExecutionZoneWalletModule module; - - LOGOS_ASSERT_EQ(module.get_balance(VALID_ID, QStringLiteral("true")), QStringLiteral("42")); - LOGOS_ASSERT_EQ(module.get_balance(VALID_ID, QStringLiteral("1")), QStringLiteral("42")); - LOGOS_ASSERT_EQ(module.get_balance(VALID_ID, QStringLiteral("yes")), QStringLiteral("42")); + LOGOS_ASSERT_EQ(module.get_balance(VALID_ID, false), std::string("0")); } LOGOS_TEST(get_account_public_returns_json) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - const QString json = module.get_account_public(VALID_ID); + const nlohmann::json obj = parseObject(module.get_account_public(VALID_ID)); LOGOS_ASSERT(t.cFunctionCalled("wallet_ffi_get_account_public")); - const QJsonObject obj = parseObject(json); // program_owner mocked to 0xAA bytes. - LOGOS_ASSERT_EQ(obj["program_owner"].toString(), QString("aa").repeated(32)); + std::string expectedOwner; + for (int i = 0; i < 32; ++i) expectedOwner += "aa"; + LOGOS_ASSERT_EQ(obj["program_owner"].get(), expectedOwner); } LOGOS_TEST(get_account_public_invalid_hex_returns_empty) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_TRUE(module.get_account_public(QStringLiteral("zz")).isEmpty()); + LOGOS_ASSERT_TRUE(module.get_account_public("zz").empty()); LOGOS_ASSERT_FALSE(t.cFunctionCalled("wallet_ffi_get_account_public")); } @@ -149,15 +144,19 @@ LOGOS_TEST(get_public_account_key_returns_hex) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_EQ(module.get_public_account_key(VALID_ID), QString("be").repeated(32)); + std::string expected; + for (int i = 0; i < 32; ++i) expected += "be"; + LOGOS_ASSERT_EQ(module.get_public_account_key(VALID_ID), expected); } LOGOS_TEST(get_private_account_keys_returns_json) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - const QJsonObject obj = parseObject(module.get_private_account_keys(VALID_ID)); - LOGOS_ASSERT_EQ(obj["nullifier_public_key"].toString(), QString("ef").repeated(32)); + const nlohmann::json obj = parseObject(module.get_private_account_keys(VALID_ID)); + std::string expected; + for (int i = 0; i < 32; ++i) expected += "ef"; + LOGOS_ASSERT_EQ(obj["nullifier_public_key"].get(), expected); } // ============================================================================ @@ -168,7 +167,7 @@ LOGOS_TEST(account_id_to_base58_invalid_hex_returns_empty) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_TRUE(module.account_id_to_base58(QStringLiteral("xyz")).isEmpty()); + LOGOS_ASSERT_TRUE(module.account_id_to_base58("xyz").empty()); } LOGOS_TEST(account_id_to_base58_returns_string) { @@ -176,14 +175,16 @@ LOGOS_TEST(account_id_to_base58_returns_string) { t.mockCFunction("wallet_ffi_account_id_to_base58").returns("SomeBase58Value"); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_EQ(module.account_id_to_base58(VALID_ID), QStringLiteral("SomeBase58Value")); + LOGOS_ASSERT_EQ(module.account_id_to_base58(VALID_ID), std::string("SomeBase58Value")); } LOGOS_TEST(account_id_from_base58_returns_hex) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_EQ(module.account_id_from_base58(QStringLiteral("anything")), QString("5a").repeated(32)); + std::string expected; + for (int i = 0; i < 32; ++i) expected += "5a"; + LOGOS_ASSERT_EQ(module.account_id_from_base58("anything"), expected); } LOGOS_TEST(account_id_from_base58_error_returns_empty) { @@ -191,27 +192,19 @@ LOGOS_TEST(account_id_from_base58_error_returns_empty) { t.mockCFunction("wallet_ffi_account_id_from_base58").returns(static_cast(INTERNAL_ERROR)); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_TRUE(module.account_id_from_base58(QStringLiteral("anything")).isEmpty()); + LOGOS_ASSERT_TRUE(module.account_id_from_base58("anything").empty()); } // ============================================================================ // Blockchain synchronisation // ============================================================================ -LOGOS_TEST(sync_to_block_string_invalid_returns_negative_one) { - auto t = LogosTestContext("logos_execution_zone"); - LogosExecutionZoneWalletModule module; - - LOGOS_ASSERT_EQ(module.sync_to_block(QStringLiteral("notnum")), -1); - LOGOS_ASSERT_FALSE(t.cFunctionCalled("wallet_ffi_sync_to_block")); -} - -LOGOS_TEST(sync_to_block_string_valid_forwards) { +LOGOS_TEST(sync_to_block_forwards_value) { auto t = LogosTestContext("logos_execution_zone"); t.mockCFunction("wallet_ffi_sync_to_block").returns(7); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_EQ(module.sync_to_block(QStringLiteral("100")), 7); + LOGOS_ASSERT_EQ(module.sync_to_block(100), static_cast(7)); LOGOS_ASSERT(t.cFunctionCalled("wallet_ffi_sync_to_block")); } @@ -220,7 +213,7 @@ LOGOS_TEST(get_last_synced_block_returns_value) { t.mockCFunction("last_synced_block_value").returns(55); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_EQ(module.get_last_synced_block(), 55); + LOGOS_ASSERT_EQ(module.get_last_synced_block(), static_cast(55)); } LOGOS_TEST(get_last_synced_block_error_returns_zero) { @@ -228,7 +221,7 @@ LOGOS_TEST(get_last_synced_block_error_returns_zero) { t.mockCFunction("wallet_ffi_get_last_synced_block").returns(static_cast(INTERNAL_ERROR)); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_EQ(module.get_last_synced_block(), 0); + LOGOS_ASSERT_EQ(module.get_last_synced_block(), static_cast(0)); } LOGOS_TEST(get_current_block_height_returns_value) { @@ -236,7 +229,7 @@ LOGOS_TEST(get_current_block_height_returns_value) { t.mockCFunction("current_block_height_value").returns(999); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_EQ(module.get_current_block_height(), 999); + LOGOS_ASSERT_EQ(module.get_current_block_height(), static_cast(999)); } // ============================================================================ @@ -247,20 +240,20 @@ LOGOS_TEST(transfer_public_success_json) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - const QJsonObject obj = parseObject(module.transfer_public(VALID_ID, VALID_ID_2, VALID_U128)); + const nlohmann::json obj = parseObject(module.transfer_public(VALID_ID, VALID_ID_2, VALID_U128)); LOGOS_ASSERT(t.cFunctionCalled("wallet_ffi_transfer_public")); - LOGOS_ASSERT_TRUE(obj["success"].toBool()); - LOGOS_ASSERT_EQ(obj["tx_hash"].toString(), QStringLiteral("0xmocktxhash")); - LOGOS_ASSERT_TRUE(obj["error"].toString().isEmpty()); + LOGOS_ASSERT_TRUE(obj["success"].get()); + LOGOS_ASSERT_EQ(obj["tx_hash"].get(), std::string("0xmocktxhash")); + LOGOS_ASSERT_TRUE(obj["error"].get().empty()); } LOGOS_TEST(transfer_public_invalid_hex_error_json) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - const QJsonObject obj = parseObject(module.transfer_public(QStringLiteral("bad"), VALID_ID_2, VALID_U128)); - LOGOS_ASSERT_FALSE(obj["success"].toBool()); - LOGOS_ASSERT_FALSE(obj["error"].toString().isEmpty()); + const nlohmann::json obj = parseObject(module.transfer_public("bad", VALID_ID_2, VALID_U128)); + LOGOS_ASSERT_FALSE(obj["success"].get()); + LOGOS_ASSERT_FALSE(obj["error"].get().empty()); LOGOS_ASSERT_FALSE(t.cFunctionCalled("wallet_ffi_transfer_public")); } @@ -268,9 +261,9 @@ LOGOS_TEST(transfer_public_invalid_amount_error_json) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - const QJsonObject obj = parseObject(module.transfer_public(VALID_ID, VALID_ID_2, QStringLiteral("ff"))); - LOGOS_ASSERT_FALSE(obj["success"].toBool()); - LOGOS_ASSERT_CONTAINS(obj["error"].toString().toStdString(), std::string("amount")); + const nlohmann::json obj = parseObject(module.transfer_public(VALID_ID, VALID_ID_2, "ff")); + LOGOS_ASSERT_FALSE(obj["success"].get()); + LOGOS_ASSERT_CONTAINS(obj["error"].get(), std::string("amount")); } LOGOS_TEST(transfer_public_ffi_error_json) { @@ -278,9 +271,9 @@ LOGOS_TEST(transfer_public_ffi_error_json) { t.mockCFunction("wallet_ffi_transfer_public").returns(static_cast(INTERNAL_ERROR)); LogosExecutionZoneWalletModule module; - const QJsonObject obj = parseObject(module.transfer_public(VALID_ID, VALID_ID_2, VALID_U128)); - LOGOS_ASSERT_FALSE(obj["success"].toBool()); - LOGOS_ASSERT_FALSE(obj["error"].toString().isEmpty()); + const nlohmann::json obj = parseObject(module.transfer_public(VALID_ID, VALID_ID_2, VALID_U128)); + LOGOS_ASSERT_FALSE(obj["success"].get()); + LOGOS_ASSERT_FALSE(obj["error"].get().empty()); } LOGOS_TEST(transfer_shielded_invalid_keys_json_error) { @@ -288,8 +281,8 @@ LOGOS_TEST(transfer_shielded_invalid_keys_json_error) { LogosExecutionZoneWalletModule module; // to_keys_json is not valid JSON object -> parse failure. - const QJsonObject obj = parseObject(module.transfer_shielded(VALID_ID, QStringLiteral("not-json"), VALID_U128)); - LOGOS_ASSERT_FALSE(obj["success"].toBool()); + const nlohmann::json obj = parseObject(module.transfer_shielded(VALID_ID, "not-json", VALID_U128)); + LOGOS_ASSERT_FALSE(obj["success"].get()); LOGOS_ASSERT_FALSE(t.cFunctionCalled("wallet_ffi_transfer_shielded")); } @@ -297,18 +290,18 @@ LOGOS_TEST(transfer_shielded_success_json) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - const QString keysJson = QStringLiteral("{\"nullifier_public_key\":\"") + QString(64, 'a') + QStringLiteral("\"}"); - const QJsonObject obj = parseObject(module.transfer_shielded(VALID_ID, keysJson, VALID_U128)); + const std::string keysJson = std::string("{\"nullifier_public_key\":\"") + std::string(64, 'a') + std::string("\"}"); + const nlohmann::json obj = parseObject(module.transfer_shielded(VALID_ID, keysJson, VALID_U128)); LOGOS_ASSERT(t.cFunctionCalled("wallet_ffi_transfer_shielded")); - LOGOS_ASSERT_TRUE(obj["success"].toBool()); + LOGOS_ASSERT_TRUE(obj["success"].get()); } LOGOS_TEST(register_public_account_invalid_hex_error_json) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - const QJsonObject obj = parseObject(module.register_public_account(QStringLiteral("bad"))); - LOGOS_ASSERT_FALSE(obj["success"].toBool()); + const nlohmann::json obj = parseObject(module.register_public_account("bad")); + LOGOS_ASSERT_FALSE(obj["success"].get()); LOGOS_ASSERT_FALSE(t.cFunctionCalled("wallet_ffi_register_public_account")); } @@ -316,9 +309,9 @@ LOGOS_TEST(register_private_account_success_json) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - const QJsonObject obj = parseObject(module.register_private_account(VALID_ID)); + const nlohmann::json obj = parseObject(module.register_private_account(VALID_ID)); LOGOS_ASSERT(t.cFunctionCalled("wallet_ffi_register_private_account")); - LOGOS_ASSERT_TRUE(obj["success"].toBool()); + LOGOS_ASSERT_TRUE(obj["success"].get()); } // ============================================================================ @@ -329,7 +322,7 @@ LOGOS_TEST(claim_pinata_invalid_hex_returns_empty) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_TRUE(module.claim_pinata(QStringLiteral("bad"), VALID_ID_2, VALID_U128).isEmpty()); + LOGOS_ASSERT_TRUE(module.claim_pinata("bad", VALID_ID_2, VALID_U128).empty()); LOGOS_ASSERT_FALSE(t.cFunctionCalled("wallet_ffi_claim_pinata")); } @@ -337,7 +330,7 @@ LOGOS_TEST(claim_pinata_invalid_solution_returns_empty) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_TRUE(module.claim_pinata(VALID_ID, VALID_ID_2, QStringLiteral("ab")).isEmpty()); + LOGOS_ASSERT_TRUE(module.claim_pinata(VALID_ID, VALID_ID_2, "ab").empty()); LOGOS_ASSERT_FALSE(t.cFunctionCalled("wallet_ffi_claim_pinata")); } @@ -345,9 +338,9 @@ LOGOS_TEST(claim_pinata_success_json) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - const QJsonObject obj = parseObject(module.claim_pinata(VALID_ID, VALID_ID_2, VALID_U128)); + const nlohmann::json obj = parseObject(module.claim_pinata(VALID_ID, VALID_ID_2, VALID_U128)); LOGOS_ASSERT(t.cFunctionCalled("wallet_ffi_claim_pinata")); - LOGOS_ASSERT_TRUE(obj["success"].toBool()); + LOGOS_ASSERT_TRUE(obj["success"].get()); } LOGOS_TEST(claim_pinata_already_initialized_invalid_siblings_returns_empty) { @@ -355,9 +348,9 @@ LOGOS_TEST(claim_pinata_already_initialized_invalid_siblings_returns_empty) { LogosExecutionZoneWalletModule module; // siblings json is not an array -> parse failure. - const QString result = module.claim_pinata_private_owned_already_initialized( - VALID_ID, VALID_ID_2, VALID_U128, 0, QStringLiteral("not-an-array")); - LOGOS_ASSERT_TRUE(result.isEmpty()); + const std::string result = module.claim_pinata_private_owned_already_initialized( + VALID_ID, VALID_ID_2, VALID_U128, 0, "not-an-array"); + LOGOS_ASSERT_TRUE(result.empty()); LOGOS_ASSERT_FALSE(t.cFunctionCalled("wallet_ffi_claim_pinata_private_owned_already_initialized")); } @@ -365,11 +358,11 @@ LOGOS_TEST(claim_pinata_already_initialized_success_json) { auto t = LogosTestContext("logos_execution_zone"); LogosExecutionZoneWalletModule module; - const QString siblings = QStringLiteral("[\"") + QString(64, 'a') + QStringLiteral("\",\"") + QString(64, 'b') + QStringLiteral("\"]"); - const QJsonObject obj = parseObject(module.claim_pinata_private_owned_already_initialized( + const std::string siblings = std::string("[\"") + std::string(64, 'a') + std::string("\",\"") + std::string(64, 'b') + std::string("\"]"); + const nlohmann::json obj = parseObject(module.claim_pinata_private_owned_already_initialized( VALID_ID, VALID_ID_2, VALID_U128, 1, siblings)); LOGOS_ASSERT(t.cFunctionCalled("wallet_ffi_claim_pinata_private_owned_already_initialized")); - LOGOS_ASSERT_TRUE(obj["success"].toBool()); + LOGOS_ASSERT_TRUE(obj["success"].get()); } // ============================================================================ @@ -381,12 +374,10 @@ LOGOS_TEST(create_new_success_then_double_open_fails) { t.mockCFunction("wallet_ffi_create_new").returns(1); // non-null handle LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_EQ(module.create_new(QStringLiteral("/cfg"), QStringLiteral("/store"), QStringLiteral("pw")), - static_cast(SUCCESS)); + LOGOS_ASSERT_EQ(module.create_new("/cfg", "/store", "pw"), static_cast(SUCCESS)); LOGOS_ASSERT(t.cFunctionCalled("wallet_ffi_create_new")); // Second attempt: already open. - LOGOS_ASSERT_EQ(module.create_new(QStringLiteral("/cfg"), QStringLiteral("/store"), QStringLiteral("pw")), - static_cast(INTERNAL_ERROR)); + LOGOS_ASSERT_EQ(module.create_new("/cfg", "/store", "pw"), static_cast(INTERNAL_ERROR)); } LOGOS_TEST(create_new_null_handle_returns_internal_error) { @@ -394,8 +385,7 @@ LOGOS_TEST(create_new_null_handle_returns_internal_error) { t.mockCFunction("wallet_ffi_create_new").returns(0); // null handle LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_EQ(module.create_new(QStringLiteral("/cfg"), QStringLiteral("/store"), QStringLiteral("pw")), - static_cast(INTERNAL_ERROR)); + LOGOS_ASSERT_EQ(module.create_new("/cfg", "/store", "pw"), static_cast(INTERNAL_ERROR)); } LOGOS_TEST(open_success) { @@ -403,7 +393,7 @@ LOGOS_TEST(open_success) { t.mockCFunction("wallet_ffi_open").returns(1); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_EQ(module.open(QStringLiteral("/cfg"), QStringLiteral("/store")), static_cast(SUCCESS)); + LOGOS_ASSERT_EQ(module.open("/cfg", "/store"), static_cast(SUCCESS)); LOGOS_ASSERT(t.cFunctionCalled("wallet_ffi_open")); } @@ -412,7 +402,7 @@ LOGOS_TEST(save_forwards_return_code) { t.mockCFunction("wallet_ffi_save").returns(static_cast(SUCCESS)); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_EQ(module.save(), static_cast(SUCCESS)); + LOGOS_ASSERT_EQ(module.save(), static_cast(SUCCESS)); LOGOS_ASSERT(t.cFunctionCalled("wallet_ffi_save")); } @@ -425,5 +415,5 @@ LOGOS_TEST(get_sequencer_addr_returns_string) { t.mockCFunction("wallet_ffi_get_sequencer_addr").returns("10.0.0.1:9000"); LogosExecutionZoneWalletModule module; - LOGOS_ASSERT_EQ(module.get_sequencer_addr(), QStringLiteral("10.0.0.1:9000")); + LOGOS_ASSERT_EQ(module.get_sequencer_addr(), std::string("10.0.0.1:9000")); } diff --git a/tests/test_execution_zone_integration.cpp b/tests/test_execution_zone_integration.cpp index e49c180..861a2ed 100644 --- a/tests/test_execution_zone_integration.cpp +++ b/tests/test_execution_zone_integration.cpp @@ -8,20 +8,20 @@ #include #include "logos_execution_zone_wallet_module.h" -#include +#include // account_id_to_base58 and account_id_from_base58 are pure encoding helpers that // do not require an open wallet, so they can be exercised against the real lib. LOGOS_TEST(integration_account_id_base58_round_trip) { LogosExecutionZoneWalletModule module; - const QString idHex = QString(64, 'a'); + const std::string idHex = std::string(64, 'a'); - const QString base58 = module.account_id_to_base58(idHex); - LOGOS_ASSERT_FALSE(base58.isEmpty()); + const std::string base58 = module.account_id_to_base58(idHex); + LOGOS_ASSERT_FALSE(base58.empty()); - const QString decodedHex = module.account_id_from_base58(base58); - LOGOS_ASSERT_FALSE(decodedHex.isEmpty()); + const std::string decodedHex = module.account_id_from_base58(base58); + LOGOS_ASSERT_FALSE(decodedHex.empty()); LOGOS_ASSERT_EQ(decodedHex, idHex); } @@ -29,5 +29,5 @@ LOGOS_TEST(integration_account_id_from_base58_rejects_garbage) { LogosExecutionZoneWalletModule module; // Clearly invalid base58 input should not decode to a valid id. - LOGOS_ASSERT_TRUE(module.account_id_from_base58(QStringLiteral("!!!not-base58!!!")).isEmpty()); + LOGOS_ASSERT_TRUE(module.account_id_from_base58("!!!not-base58!!!").empty()); }