update to v0.17.0.1 Oxygen Orion

import libwallet-crypto.a
sign and verify messages with spend or view key and subaddress
factor out confirmation and suggested confirmations calculations
This commit is contained in:
woodser
2020-09-29 12:54:36 -04:00
parent c5ef7959e8
commit bde25003da
10 changed files with 141 additions and 67 deletions
+8 -1
View File
@@ -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
+1 -1
View File
@@ -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.
+3 -3
View File
@@ -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 ../../
+12 -9
View File
@@ -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");
}
+56 -35
View File
@@ -116,7 +116,26 @@ namespace monero {
return opt_val == boost::none ? false : val == *opt_val;
}
std::shared_ptr<monero_tx_wallet> 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<monero_tx_wallet>& tx, uint64_t blockchain_height) {
std::shared_ptr<monero_block>& 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<monero_incoming_transfer>& 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<monero_tx_wallet> 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<monero_block> block = std::make_shared<monero_block>();
@@ -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<monero_incoming_transfer> incoming_transfer = std::make_shared<monero_incoming_transfer>();
@@ -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<monero_tx_wallet> 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<monero_tx_wallet> 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<monero_block> block = std::make_shared<monero_block>();
@@ -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<monero_outgoing_transfer> outgoing_transfer = std::make_shared<monero_outgoing_transfer>();
@@ -238,7 +245,7 @@ namespace monero {
return tx;
}
std::shared_ptr<monero_tx_wallet> 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<monero_tx_wallet> 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<monero_tx_wallet> build_tx_with_vout(const tools::wallet2& m_w2, const tools::wallet2::transfer_details& td) {
std::shared_ptr<monero_tx_wallet> build_tx_with_vout(tools::wallet2& m_w2, const tools::wallet2::transfer_details& td) {
// construct block
std::shared_ptr<monero_block> block = std::make_shared<monero_block>();
@@ -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<false> 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<std::string> &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<std::pair<crypto::hash, tools::wallet2::pool_payment_details>> payments;
m_w2->get_unconfirmed_payments(payments, account_index, subaddress_indices);
for (std::list<std::pair<crypto::hash, tools::wallet2::pool_payment_details>>::const_iterator i = payments.begin(); i != payments.end(); ++i) {
std::shared_ptr<monero_tx_wallet> tx = build_tx_with_incoming_transfer_unconfirmed(*m_w2, i->first, i->second);
std::shared_ptr<monero_tx_wallet> tx = build_tx_with_incoming_transfer_unconfirmed(*m_w2, height, i->first, i->second);
merge_tx(tx, tx_map, block_map, false);
}
}
+2 -2
View File
@@ -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<std::string> 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<monero_check_tx> 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;
+2 -2
View File
@@ -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");
}
+2 -2
View File
@@ -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<monero_subaddress> get_subaddresses(const uint32_t account_idx, const std::vector<uint32_t>& 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 --------------------------------
+35 -12
View File
@@ -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);
+20
View File
@@ -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.
*/