diff --git a/CMakeLists.txt b/CMakeLists.txt index de0297e..44f37d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -154,11 +154,15 @@ message(STATUS MONERO_CORE_BUILD : ${MONERO_CORE_BUILD}) add_library(wallet_merged STATIC IMPORTED) set_target_properties(wallet_merged PROPERTIES IMPORTED_LOCATION ${MONERO_CORE_BUILD}/lib/libwallet_merged.a) - + add_library(wallet STATIC IMPORTED) set_target_properties(wallet PROPERTIES IMPORTED_LOCATION ${MONERO_CORE_BUILD}/lib/libwallet.a) +add_library(wallet_crypto STATIC IMPORTED) +set_target_properties(wallet_crypto PROPERTIES IMPORTED_LOCATION + ${MONERO_CORE_BUILD}/src/crypto/wallet/libwallet-crypto.a) + add_library(lmdb STATIC IMPORTED) set_target_properties(lmdb PROPERTIES IMPORTED_LOCATION ${MONERO_CORE_BUILD}/external/db_drivers/liblmdb/liblmdb.a) @@ -272,6 +276,7 @@ if (BUILD_LIBRARY) crypto wallet_merged + wallet_crypto #wallet_api wallet lmdb @@ -327,6 +332,7 @@ if (BUILD_SAMPLE) crypto wallet_merged + wallet_crypto #wallet_api wallet lmdb @@ -382,6 +388,7 @@ if (BUILD_SCRATCHPAD) crypto wallet_merged + wallet_crypto #wallet_api wallet lmdb diff --git a/README.md b/README.md index fc2b6b0..51a13ea 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Monero C++ Library -A C++ library for creating Monero applications using native bindings to [monero v0.16.0.3 'Nitrogen Nebula'](https://github.com/monero-project/monero/tree/v0.16.0.3). +A C++ library for creating Monero applications using native bindings to [monero v0.17.0.1 'Oxygen Orion'](https://github.com/monero-project/monero/tree/v0.17.0.1). * Supports fully client-side wallets by wrapping [wallet2.h](https://github.com/monero-project/monero/blob/master/src/wallet/wallet2.h). * Supports multisig, view-only, and offline wallets. diff --git a/bin/update_submodules.sh b/bin/update_submodules.sh index a870e40..34303d9 100755 --- a/bin/update_submodules.sh +++ b/bin/update_submodules.sh @@ -1,10 +1,10 @@ #!/usr/bin/env bash # initialize submodules recursively -git submodule update --init --recursive +git submodule update --init --force --recursive # update monero-core cd ./external/monero-core -git checkout tags/v0.16.0.3 -git pull --ff-only origin tags/v0.16.0.3 +git checkout tags/v0.17.0.1 +git pull --ff-only origin tags/v0.17.0.1 cd ../../ \ No newline at end of file diff --git a/src/wallet/monero_wallet.h b/src/wallet/monero_wallet.h index 7b207e3..8aecae3 100644 --- a/src/wallet/monero_wallet.h +++ b/src/wallet/monero_wallet.h @@ -913,22 +913,25 @@ namespace monero { /** * Sign a message. * - * @param msg is the message to sign - * @return the signature + * @param msg - the message to sign + * @param signature_type - sign with spend key or spend key + * @param account_idx - the account index of the message signature (default 0) + * @param subaddress_idx - the subaddress index of the message signature (default 0) + * @return the message signature */ - virtual std::string sign_message(const std::string& msg) const { + virtual std::string sign_message(const std::string& msg, monero_message_signature_type signature_type, uint32_t account_idx = 0, uint32_t subaddress_idx = 0) const { throw std::runtime_error("sign_message() not supported"); } /** - * Verify a signature on a message. + * Verify a message signature. * - * @param msg is the signed message - * @param address is the signing address - * @param signature is the signature - * @return true if the signature is good, false otherwise + * @param msg - the signed message + * @param address - signing address + * @param signature - signature + * @return the message signature result */ - virtual bool verify_message(const std::string& msg, const std::string& address, const std::string& signature) const { + virtual monero_message_signature_result verify_message(const std::string& msg, const std::string& address, const std::string& signature) const { throw std::runtime_error("verify_message() not supported"); } diff --git a/src/wallet/monero_wallet_core.cpp b/src/wallet/monero_wallet_core.cpp index b063147..7daca4d 100644 --- a/src/wallet/monero_wallet_core.cpp +++ b/src/wallet/monero_wallet_core.cpp @@ -116,7 +116,26 @@ namespace monero { return opt_val == boost::none ? false : val == *opt_val; } - std::shared_ptr build_tx_with_incoming_transfer(const tools::wallet2& m_w2, uint64_t height, const crypto::hash &payment_id, const tools::wallet2::payment_details &pd) { + // compute m_num_confirmations TODO monero core: this logic is based on wallet_rpc_server.cpp `set_confirmations` but it should be encapsulated in wallet2 + void set_num_confirmations(std::shared_ptr& tx, uint64_t blockchain_height) { + std::shared_ptr& block = tx->m_block.get(); + if (block->m_height.get() >= blockchain_height || (block->m_height.get() == 0 && !tx->m_in_tx_pool.get())) tx->m_num_confirmations = 0; + else tx->m_num_confirmations = blockchain_height - block->m_height.get(); + } + + // compute m_num_suggested_confirmations TODO monero core: this logic is based on wallet_rpc_server.cpp `set_confirmations` but it should be encapsulated in wallet2 + void set_num_suggested_confirmations(std::shared_ptr& incoming_transfer, uint64_t blockchain_height, uint64_t block_reward, uint64_t unlock_time) { + if (block_reward == 0) incoming_transfer->m_num_suggested_confirmations = 0; + else incoming_transfer->m_num_suggested_confirmations = (incoming_transfer->m_amount.get() + block_reward - 1) / block_reward; + if (unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER) { + if (unlock_time > blockchain_height) incoming_transfer->m_num_suggested_confirmations = std::max(incoming_transfer->m_num_suggested_confirmations.get(), unlock_time - blockchain_height); + } else { + const uint64_t now = time(NULL); + if (unlock_time > now) incoming_transfer->m_num_suggested_confirmations = std::max(incoming_transfer->m_num_suggested_confirmations.get(), (unlock_time - now + DIFFICULTY_TARGET_V2 - 1) / DIFFICULTY_TARGET_V2); + } + } + + std::shared_ptr build_tx_with_incoming_transfer(tools::wallet2& m_w2, uint64_t height, const crypto::hash &payment_id, const tools::wallet2::payment_details &pd) { // construct block std::shared_ptr block = std::make_shared(); @@ -144,11 +163,7 @@ namespace monero { tx->m_in_tx_pool = false; tx->m_relay = true; tx->m_is_double_spend_seen = false; - - // compute m_num_confirmations TODO monero core: this logic is based on wallet_rpc_server.cpp:87 but it should be encapsulated in wallet2 - // TODO: factor out this duplicate code with build_tx_with_outgoing_transfer() - if (*block->m_height >= height || (*block->m_height == 0 && !*tx->m_in_tx_pool)) tx->m_num_confirmations = 0; - else tx->m_num_confirmations = height - *block->m_height; + set_num_confirmations(tx, height); // construct transfer std::shared_ptr incoming_transfer = std::make_shared(); @@ -158,18 +173,13 @@ namespace monero { incoming_transfer->m_account_index = pd.m_subaddr_index.major; incoming_transfer->m_subaddress_index = pd.m_subaddr_index.minor; incoming_transfer->m_address = m_w2.get_subaddress_as_str(pd.m_subaddr_index); - - // compute m_num_suggested_confirmations TODO monero core: this logic is based on wallet_rpc_server.cpp:87 `set_confirmations` but it should be encapsulated in wallet2 - // TODO: factor out this duplicate code with build_tx_with_outgoing_transfer() - uint64_t block_reward = m_w2.get_last_block_reward(); - if (block_reward == 0) incoming_transfer->m_num_suggested_confirmations = 0; - else incoming_transfer->m_num_suggested_confirmations = (*incoming_transfer->m_amount + block_reward - 1) / block_reward; + set_num_suggested_confirmations(incoming_transfer, height, m_w2.get_last_block_reward(), pd.m_unlock_time); // return pointer to new tx return tx; } - std::shared_ptr build_tx_with_outgoing_transfer(const tools::wallet2& m_w2, uint64_t height, const crypto::hash &txid, const tools::wallet2::confirmed_transfer_details &pd) { + std::shared_ptr build_tx_with_outgoing_transfer(tools::wallet2& m_w2, uint64_t height, const crypto::hash &txid, const tools::wallet2::confirmed_transfer_details &pd) { // construct block std::shared_ptr block = std::make_shared(); @@ -197,10 +207,7 @@ namespace monero { tx->m_in_tx_pool = false; tx->m_relay = true; tx->m_is_double_spend_seen = false; - - // compute m_num_confirmations TODO monero core: this logic is based on wallet_rpc_server.cpp:87 but it should be encapsulated in wallet2 - if (*block->m_height >= height || (*block->m_height == 0 && !*tx->m_in_tx_pool)) tx->m_num_confirmations = 0; - else tx->m_num_confirmations = height - *block->m_height; + set_num_confirmations(tx, height); // construct transfer std::shared_ptr outgoing_transfer = std::make_shared(); @@ -238,7 +245,7 @@ namespace monero { return tx; } - std::shared_ptr build_tx_with_incoming_transfer_unconfirmed(const tools::wallet2& m_w2, const crypto::hash &payment_id, const tools::wallet2::pool_payment_details &ppd) { + std::shared_ptr build_tx_with_incoming_transfer_unconfirmed(const tools::wallet2& m_w2, uint64_t height, const crypto::hash &payment_id, const tools::wallet2::pool_payment_details &ppd) { // construct tx const tools::wallet2::payment_details &pd = ppd.m_pd; @@ -270,11 +277,7 @@ namespace monero { incoming_transfer->m_account_index = pd.m_subaddr_index.major; incoming_transfer->m_subaddress_index = pd.m_subaddr_index.minor; incoming_transfer->m_address = m_w2.get_subaddress_as_str(pd.m_subaddr_index); - - // compute m_num_suggested_confirmations TODO monero core: this logic is based on wallet_rpc_server.cpp:87 but it should be encapsulated in wallet2 - uint64_t block_reward = m_w2.get_last_block_reward(); - if (block_reward == 0) incoming_transfer->m_num_suggested_confirmations = 0; - else incoming_transfer->m_num_suggested_confirmations = (*incoming_transfer->m_amount + block_reward - 1) / block_reward; + set_num_suggested_confirmations(incoming_transfer, height, m_w2.get_last_block_reward(), pd.m_unlock_time); // return pointer to new tx return tx; @@ -338,7 +341,7 @@ namespace monero { return tx; } - std::shared_ptr build_tx_with_vout(const tools::wallet2& m_w2, const tools::wallet2::transfer_details& td) { + std::shared_ptr build_tx_with_vout(tools::wallet2& m_w2, const tools::wallet2::transfer_details& td) { // construct block std::shared_ptr block = std::make_shared(); @@ -2225,14 +2228,22 @@ namespace monero { } // deserialize tx + bool loaded = false; tools::wallet2::pending_tx ptx; try { std::istringstream iss(blob); - boost::archive::portable_binary_iarchive ar(iss); - ar >> ptx; - } catch (...) { - throw std::runtime_error("Failed to parse tx metadata"); + binary_archive ar(iss); + if (::serialization::serialize(ar, ptx)) loaded = true; + } catch (...) {} + if (!loaded) { + try { + std::istringstream iss(blob); + boost::archive::portable_binary_iarchive ar(iss); + ar >> ptx; + loaded = true; + } catch (...) {} } + if (!loaded) throw std::runtime_error("Failed to parse tx metadata"); // commit tx try { @@ -2455,15 +2466,17 @@ namespace monero { } } - std::string monero_wallet_core::sign_message(const std::string& msg) const { - return m_w2->sign(msg); + std::string monero_wallet_core::sign_message(const std::string& msg, monero_message_signature_type signature_type, uint32_t account_idx, uint32_t subaddress_idx) const { + cryptonote::subaddress_index index = {account_idx, subaddress_idx}; + tools::wallet2::message_signature_type_t signature_type_w2 = signature_type == monero_message_signature_type::SIGN_WITH_SPEND_KEY ? tools::wallet2::message_signature_type_t::sign_with_spend_key : tools::wallet2::message_signature_type_t::sign_with_view_key; + return m_w2->sign(msg, signature_type_w2, index); } - bool monero_wallet_core::verify_message(const std::string& msg, const std::string& address, const std::string& signature) const { + monero_message_signature_result monero_wallet_core::verify_message(const std::string& msg, const std::string& address, const std::string& signature) const { // validate and parse address or url cryptonote::address_parse_info info; - std::string err; + std::string err = "Invalid address"; if (!get_account_address_from_str_or_url(info, m_w2->nettype(), address, [&err](const std::string &url, const std::vector &addresses, bool dnssec_valid)->std::string { if (!dnssec_valid) { @@ -2480,8 +2493,16 @@ namespace monero { throw std::runtime_error(err); } - // verify and return result - return m_w2->verify(msg, info.address, signature); + // verify message + tools:wallet2::message_signature_result_t result_w2 = m_w2->verify(msg, info.address, signature); + + // translate result + monero_message_signature_result result; + result.m_is_good = result_w2.valid; + result.m_is_old = result_w2.old; + result.m_signature_type = result_w2.type == tools::wallet2::message_signature_type_t::sign_with_spend_key ? monero_message_signature_type::SIGN_WITH_SPEND_KEY : monero_message_signature_type::SIGN_WITH_VIEW_KEY; + result.m_version = result_w2.version; + return result; } std::string monero_wallet_core::get_tx_key(const std::string& tx_hash) const { @@ -3244,7 +3265,7 @@ namespace monero { std::list> payments; m_w2->get_unconfirmed_payments(payments, account_index, subaddress_indices); for (std::list>::const_iterator i = payments.begin(); i != payments.end(); ++i) { - std::shared_ptr tx = build_tx_with_incoming_transfer_unconfirmed(*m_w2, i->first, i->second); + std::shared_ptr tx = build_tx_with_incoming_transfer_unconfirmed(*m_w2, height, i->first, i->second); merge_tx(tx, tx_map, block_map, false); } } diff --git a/src/wallet/monero_wallet_core.h b/src/wallet/monero_wallet_core.h index a160591..95f4e09 100644 --- a/src/wallet/monero_wallet_core.h +++ b/src/wallet/monero_wallet_core.h @@ -236,8 +236,8 @@ namespace monero { monero_tx_set parse_tx_set(const monero_tx_set& tx_set) override; std::string sign_txs(const std::string& unsigned_tx_hex) override; std::vector submit_txs(const std::string& signed_tx_hex) override; - std::string sign_message(const std::string& msg) const override; - bool verify_message(const std::string& msg, const std::string& address, const std::string& signature) const override; + std::string sign_message(const std::string& msg, monero_message_signature_type signature_type, uint32_t account_idx = 0, uint32_t subaddress_idx = 0) const override; + monero_message_signature_result verify_message(const std::string& msg, const std::string& address, const std::string& signature) const override; std::string get_tx_key(const std::string& tx_hash) const override; std::shared_ptr check_tx_key(const std::string& tx_hash, const std::string& txKey, const std::string& address) const override; std::string get_tx_proof(const std::string& tx_hash, const std::string& address, const std::string& message) const override; diff --git a/src/wallet/monero_wallet_keys.cpp b/src/wallet/monero_wallet_keys.cpp index 2f76e68..93ee9f9 100644 --- a/src/wallet/monero_wallet_keys.cpp +++ b/src/wallet/monero_wallet_keys.cpp @@ -274,12 +274,12 @@ namespace monero { return subaddresses; } - std::string monero_wallet_keys::sign_message(const std::string& msg) const { + std::string monero_wallet_keys::sign_message(const std::string& msg, monero_message_signature_type signature_type, uint32_t account_idx, uint32_t subaddress_idx) const { std::cout << "monero_wallet_keys::sign_message()" << std::endl; throw std::runtime_error("monero_wallet_keys::sign_message() not implemented"); } - bool monero_wallet_keys::verify_message(const std::string& msg, const std::string& address, const std::string& signature) const { + monero_message_signature_result monero_wallet_keys::verify_message(const std::string& msg, const std::string& address, const std::string& signature) const { std::cout << "monero_wallet_keys::verify_message()" << std::endl; throw std::runtime_error("monero_wallet_keys::verify_message() not implemented"); } diff --git a/src/wallet/monero_wallet_keys.h b/src/wallet/monero_wallet_keys.h index 52d3167..cb3b989 100644 --- a/src/wallet/monero_wallet_keys.h +++ b/src/wallet/monero_wallet_keys.h @@ -130,8 +130,8 @@ namespace monero { monero_integrated_address decode_integrated_address(const std::string& integrated_address) const override; monero_account get_account(const uint32_t account_idx, bool include_subaddresses) const override; std::vector get_subaddresses(const uint32_t account_idx, const std::vector& subaddress_indices) const override; - std::string sign_message(const std::string& msg) const override; - bool verify_message(const std::string& msg, const std::string& address, const std::string& signature) const override; + std::string sign_message(const std::string& msg, monero_message_signature_type signature_type, uint32_t account_idx = 0, uint32_t subaddress_idx = 0) const override; + monero_message_signature_result verify_message(const std::string& msg, const std::string& address, const std::string& signature) const override; void close(bool save = false) override; // --------------------------------- PRIVATE -------------------------------- diff --git a/src/wallet/monero_wallet_model.cpp b/src/wallet/monero_wallet_model.cpp index c6b66cb..2f6cd92 100644 --- a/src/wallet/monero_wallet_model.cpp +++ b/src/wallet/monero_wallet_model.cpp @@ -121,7 +121,7 @@ namespace monero { if (m_balance != boost::none) monero_utils::addJsonMember("balance", m_balance.get(), allocator, root, value_num); if (m_unlocked_balance != boost::none) monero_utils::addJsonMember("unlockedBalance", m_unlocked_balance.get(), allocator, root, value_num); - // set std::string values + // set string values rapidjson::Value value_str(rapidjson::kStringType); if (m_primary_address != boost::none) monero_utils::addJsonMember("primaryAddress", m_primary_address.get(), allocator, root, value_str); if (m_tag != boost::none) monero_utils::addJsonMember("tag", m_tag.get(), allocator, root, value_str); @@ -149,7 +149,7 @@ namespace monero { if (m_num_unspent_outputs != boost::none) monero_utils::addJsonMember("numUnspentOutputs", m_num_unspent_outputs.get(), allocator, root, value_num); if (m_num_blocks_to_unlock) monero_utils::addJsonMember("numBlocksToUnlock", m_num_blocks_to_unlock.get(), allocator, root, value_num); - // set std::string values + // set string values rapidjson::Value value_str(rapidjson::kStringType); if (m_address != boost::none) monero_utils::addJsonMember("address", m_address.get(), allocator, root, value_str); if (m_label != boost::none) monero_utils::addJsonMember("label", m_label.get(), allocator, root, value_str); @@ -175,7 +175,7 @@ namespace monero { if (m_change_amount != boost::none) monero_utils::addJsonMember("changeAmount", m_change_amount.get(), allocator, root, value_num); if (m_num_dummy_outputs != boost::none) monero_utils::addJsonMember("numDummyOutputs", m_num_dummy_outputs.get(), allocator, root, value_num); - // set std::string values + // set string values rapidjson::Value value_str(rapidjson::kStringType); if (m_note != boost::none) monero_utils::addJsonMember("note", m_note.get(), allocator, root, value_str); if (m_change_address != boost::none) monero_utils::addJsonMember("changeAddress", m_change_address.get(), allocator, root, value_str); @@ -539,7 +539,7 @@ namespace monero { rapidjson::Value value_num(rapidjson::kNumberType); if (m_amount != boost::none) monero_utils::addJsonMember("amount", m_amount.get(), allocator, root, value_num); - // set std::string values + // set string values rapidjson::Value value_str(rapidjson::kStringType); if (m_address != boost::none) monero_utils::addJsonMember("address", m_address.get(), allocator, root, value_str); @@ -570,7 +570,7 @@ namespace monero { // create root rapidjson::Value root(rapidjson::kObjectType); - // set std::string values + // set string values rapidjson::Value value_str(rapidjson::kStringType); if (m_multisig_tx_hex != boost::none) monero_utils::addJsonMember("multisigTxHex", m_multisig_tx_hex.get(), allocator, root, value_str); if (m_unsigned_tx_hex != boost::none) monero_utils::addJsonMember("unsignedTxHex", m_unsigned_tx_hex.get(), allocator, root, value_str); @@ -676,7 +676,7 @@ namespace monero { if (m_subaddress_index != boost::none) monero_utils::addJsonMember("subaddressIndex", m_subaddress_index.get(), allocator, root, value_num); if (m_num_suggested_confirmations != boost::none) monero_utils::addJsonMember("numSuggestedConfirmations", m_num_suggested_confirmations.get(), allocator, root, value_num); - // set std::string values + // set string values rapidjson::Value value_str(rapidjson::kStringType); if (m_address != boost::none) monero_utils::addJsonMember("address", m_address.get(), allocator, root, value_str); @@ -761,7 +761,7 @@ namespace monero { if (m_is_incoming != boost::none) monero_utils::addJsonMember("isIncoming", m_is_incoming.get(), allocator, root); if (m_has_destinations != boost::none) monero_utils::addJsonMember("hasDestinations", m_has_destinations.get(), allocator, root); - // set std::string values + // set string values rapidjson::Value value_str(rapidjson::kStringType); if (m_address != boost::none) monero_utils::addJsonMember("address", m_address.get(), allocator, root, value_str); @@ -1143,7 +1143,7 @@ namespace monero { if (m_unlock_height != boost::none) monero_utils::addJsonMember("unlockHeight", m_unlock_height.get(), allocator, root, value_num); if (m_below_amount != boost::none) monero_utils::addJsonMember("belowAmount", m_below_amount.get(), allocator, root, value_num); - // set std::string values + // set string values rapidjson::Value value_str(rapidjson::kStringType); if (m_payment_id != boost::none) monero_utils::addJsonMember("paymentId", m_payment_id.get(), allocator, root, value_str); if (m_note != boost::none) monero_utils::addJsonMember("note", m_note.get(), allocator, root, value_str); @@ -1229,7 +1229,7 @@ namespace monero { // create root rapidjson::Value root(rapidjson::kObjectType); - // set std::string values + // set string values rapidjson::Value value_str(rapidjson::kStringType); monero_utils::addJsonMember("standardAddress", m_standard_address, allocator, root, value_str); monero_utils::addJsonMember("paymentId", m_payment_id, allocator, root, value_str); @@ -1256,6 +1256,29 @@ namespace monero { return root; } + // -------------------- MONERO MESSAGE SIGNATURE RESULT --------------------- + + rapidjson::Value monero_message_signature_result::to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const { + + // create root + rapidjson::Value root(rapidjson::kObjectType); + + // set bool values + monero_utils::addJsonMember("isGood", m_is_good, allocator, root); + monero_utils::addJsonMember("isOld", m_is_old, allocator, root); + + // set num values + rapidjson::Value value_num(rapidjson::kNumberType); + monero_utils::addJsonMember("version", m_version, allocator, root, value_num); + + // set string values + rapidjson::Value value_str(rapidjson::kStringType); + monero_utils::addJsonMember("signatureType", m_signature_type == monero_message_signature_type::SIGN_WITH_SPEND_KEY ? "spend" : "view", allocator, root, value_str); + + // return root + return root; + } + // ----------------------------- MONERO CHECK ------------------------------- rapidjson::Value monero_check::to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const { @@ -1330,7 +1353,7 @@ namespace monero { // create root rapidjson::Value root(rapidjson::kObjectType); - // set std::string values + // set string values rapidjson::Value value_str(rapidjson::kStringType); if (m_address != boost::none) monero_utils::addJsonMember("address", m_address.get(), allocator, root, value_str); if (m_multisig_hex != boost::none) monero_utils::addJsonMember("multisigHex", m_multisig_hex.get(), allocator, root, value_str); @@ -1343,7 +1366,7 @@ namespace monero { // create root rapidjson::Value root(rapidjson::kObjectType); - // set std::string values + // set string values rapidjson::Value value_str(rapidjson::kStringType); if (m_signed_multisig_tx_hex != boost::none) monero_utils::addJsonMember("signedMultisigTxHex", m_signed_multisig_tx_hex.get(), allocator, root, value_str); @@ -1365,7 +1388,7 @@ namespace monero { rapidjson::Value value_num(rapidjson::kNumberType); if (m_index != boost::none) monero_utils::addJsonMember("index", m_index.get(), allocator, root, value_num); - // set std::string values + // set string values rapidjson::Value value_str(rapidjson::kStringType); if (m_address != boost::none) monero_utils::addJsonMember("address", m_address.get(), allocator, root, value_str); if (m_description != boost::none) monero_utils::addJsonMember("description", m_description.get(), allocator, root, value_str); diff --git a/src/wallet/monero_wallet_model.h b/src/wallet/monero_wallet_model.h index 433998e..7d34e67 100644 --- a/src/wallet/monero_wallet_model.h +++ b/src/wallet/monero_wallet_model.h @@ -378,6 +378,26 @@ namespace monero { rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const; }; + /** + * Enumerates message verification results. + */ + enum monero_message_signature_type : uint8_t { + SIGN_WITH_SPEND_KEY = 0, + SIGN_WITH_VIEW_KEY + }; + + /** + * Enumerates message verification results. + */ + struct monero_message_signature_result : public serializable_struct { + bool m_is_good; + uint32_t m_version; + bool m_is_old; + monero_message_signature_type m_signature_type; + + rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const; + }; + /** * Base class for results from checking a transaction or reserve proof. */