From 418adb785790a42c1ecfb9ba0e29cf67bfb67c92 Mon Sep 17 00:00:00 2001 From: who asks? Date: Wed, 17 Jul 2024 20:09:55 -0600 Subject: [PATCH 01/18] add endpoints: export_encrypted_key_images and import_encrypted_key_images --- src/wallet/wallet_rpc_server.cpp | 96 + src/wallet/wallet_rpc_server.h | 6 +- src/wallet/wallet_rpc_server_commands_defs.h | 4367 +++++++++--------- 3 files changed, 2311 insertions(+), 2158 deletions(-) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 376c58f89a..7de53371c6 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -2952,6 +2952,102 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_export_encrypted_key_images(const wallet_rpc::COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx) + { + if (!m_wallet) return not_open(er); + try + { + std::pair>> ski = m_wallet->export_key_images(req.all); + res.offset = ski.first; + + // Serialize the key images and signatures into a single blob + std::string data; + data.reserve(ski.second.size() * (sizeof(crypto::key_image) + sizeof(crypto::signature))); + for (const auto &item : ski.second) + { + data += std::string((const char *)&item.first, sizeof(crypto::key_image)); + data += std::string((const char *)&item.second, sizeof(crypto::signature)); + } + + // Encrypt the serialized data + std::string ciphertext = m_wallet->encrypt_with_view_secret_key(data); + + // Encode the encrypted data as hex + res.encrypted_key_images_blob = epee::string_tools::buff_to_hex_nodelimer(ciphertext); + } + catch (const std::exception& e) + { + handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR); + return false; + } + + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_import_encrypted_key_images(const wallet_rpc::COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx) + { + if (!m_wallet) return not_open(er); + if (m_restricted) + { + er.code = WALLET_RPC_ERROR_CODE_DENIED; + er.message = "Command unavailable in restricted mode."; + return false; + } + if (!m_wallet->is_trusted_daemon()) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = "This command requires a trusted daemon."; + return false; + } + try + { + // Decode the hex-encoded encrypted blob + std::string ciphertext; + if (!epee::string_tools::parse_hexstr_to_binbuff(req.encrypted_key_images_blob, ciphertext)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE; + er.message = "Failed to parse encrypted key images blob"; + return false; + } + + // Decrypt the ciphertext + std::string decrypted_data = m_wallet->decrypt_with_view_secret_key(ciphertext); + + // Deserialize the decrypted data into key images and signatures + std::vector> ski; + const size_t record_size = sizeof(crypto::key_image) + sizeof(crypto::signature); + if (decrypted_data.size() % record_size != 0) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE; + er.message = "Decrypted data size is not a multiple of the record size"; + return false; + } + size_t num_records = decrypted_data.size() / record_size; + ski.reserve(num_records); + for (size_t i = 0; i < num_records; ++i) + { + crypto::key_image ki; + crypto::signature sig; + memcpy(&ki, &decrypted_data[i * record_size], sizeof(crypto::key_image)); + memcpy(&sig, &decrypted_data[i * record_size + sizeof(crypto::key_image)], sizeof(crypto::signature)); + ski.emplace_back(ki, sig); + } + + uint64_t spent = 0, unspent = 0; + uint64_t height = m_wallet->import_key_images(ski, req.offset, spent, unspent); + res.height = height; + res.spent = spent; + res.unspent = unspent; + } + catch (const std::exception& e) + { + handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR); + return false; + } + + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_make_uri(const wallet_rpc::COMMAND_RPC_MAKE_URI::request& req, wallet_rpc::COMMAND_RPC_MAKE_URI::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index bfb7013e25..246fe7c273 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -124,7 +124,9 @@ namespace tools MAP_JON_RPC_WE("export_outputs", on_export_outputs, wallet_rpc::COMMAND_RPC_EXPORT_OUTPUTS) MAP_JON_RPC_WE("import_outputs", on_import_outputs, wallet_rpc::COMMAND_RPC_IMPORT_OUTPUTS) MAP_JON_RPC_WE("export_key_images", on_export_key_images, wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES) - MAP_JON_RPC_WE("import_key_images", on_import_key_images, wallet_rpc::COMMAND_RPC_IMPORT_KEY_IMAGES) + MAP_JON_RPC_WE("import_key_images", on_import_key_images, wallet_rpc::COMMAND_RPC_IMPORT_KEY_IMAGES) + MAP_JON_RPC_WE("export_encrypted_key_images", on_export_encrypted_key_images, wallet_rpc::COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES) + MAP_JON_RPC_WE("import_encrypted_key_images", on_import_encrypted_key_images, wallet_rpc::COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES) MAP_JON_RPC_WE("make_uri", on_make_uri, wallet_rpc::COMMAND_RPC_MAKE_URI) MAP_JON_RPC_WE("parse_uri", on_parse_uri, wallet_rpc::COMMAND_RPC_PARSE_URI) MAP_JON_RPC_WE("get_address_book", on_get_address_book, wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY) @@ -216,6 +218,8 @@ namespace tools bool on_import_outputs(const wallet_rpc::COMMAND_RPC_IMPORT_OUTPUTS::request& req, wallet_rpc::COMMAND_RPC_IMPORT_OUTPUTS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_export_key_images(const wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_EXPORT_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_import_key_images(const wallet_rpc::COMMAND_RPC_IMPORT_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_IMPORT_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_export_encrypted_key_images(const wallet_rpc::COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_import_encrypted_key_images(const wallet_rpc::COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_make_uri(const wallet_rpc::COMMAND_RPC_MAKE_URI::request& req, wallet_rpc::COMMAND_RPC_MAKE_URI::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_parse_uri(const wallet_rpc::COMMAND_RPC_PARSE_URI::request& req, wallet_rpc::COMMAND_RPC_PARSE_URI::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_get_address_book(const wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::request& req, wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index 2173f5b6e9..42b43a26be 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -52,2653 +52,2706 @@ #define WALLET_RPC_VERSION MAKE_WALLET_RPC_VERSION(WALLET_RPC_VERSION_MAJOR, WALLET_RPC_VERSION_MINOR) namespace tools { -namespace wallet_rpc -{ + namespace wallet_rpc + { #define WALLET_RPC_STATUS_OK "OK" #define WALLET_RPC_STATUS_BUSY "BUSY" - struct COMMAND_RPC_GET_BALANCE - { - struct request_t - { - uint32_t account_index; - std::set address_indices; - bool all_accounts; - bool strict; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(account_index) - KV_SERIALIZE(address_indices) - KV_SERIALIZE_OPT(all_accounts, false) - KV_SERIALIZE_OPT(strict, false) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct per_subaddress_info + struct COMMAND_RPC_GET_BALANCE { - uint32_t account_index; - uint32_t address_index; - std::string address; - uint64_t balance; - uint64_t unlocked_balance; - std::string label; - uint64_t num_unspent_outputs; - uint64_t blocks_to_unlock; - uint64_t time_to_unlock; + struct request_t + { + uint32_t account_index; + std::set address_indices; + bool all_accounts; + bool strict; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(account_index) + KV_SERIALIZE(address_indices) + KV_SERIALIZE_OPT(all_accounts, false) + KV_SERIALIZE_OPT(strict, false) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(account_index) - KV_SERIALIZE(address_index) - KV_SERIALIZE(address) - KV_SERIALIZE(balance) - KV_SERIALIZE(unlocked_balance) - KV_SERIALIZE(label) - KV_SERIALIZE(num_unspent_outputs) - KV_SERIALIZE(blocks_to_unlock) - KV_SERIALIZE(time_to_unlock) - END_KV_SERIALIZE_MAP() - }; - - struct response_t - { - uint64_t balance; - uint64_t unlocked_balance; - bool multisig_import_needed; - std::vector per_subaddress; - uint64_t blocks_to_unlock; - uint64_t time_to_unlock; + struct per_subaddress_info + { + uint32_t account_index; + uint32_t address_index; + std::string address; + uint64_t balance; + uint64_t unlocked_balance; + std::string label; + uint64_t num_unspent_outputs; + uint64_t blocks_to_unlock; + uint64_t time_to_unlock; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(account_index) + KV_SERIALIZE(address_index) + KV_SERIALIZE(address) + KV_SERIALIZE(balance) + KV_SERIALIZE(unlocked_balance) + KV_SERIALIZE(label) + KV_SERIALIZE(num_unspent_outputs) + KV_SERIALIZE(blocks_to_unlock) + KV_SERIALIZE(time_to_unlock) + END_KV_SERIALIZE_MAP() + }; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(balance) - KV_SERIALIZE(unlocked_balance) - KV_SERIALIZE(multisig_import_needed) - KV_SERIALIZE(per_subaddress) - KV_SERIALIZE(blocks_to_unlock) - KV_SERIALIZE(time_to_unlock) - END_KV_SERIALIZE_MAP() + struct response_t + { + uint64_t balance; + uint64_t unlocked_balance; + bool multisig_import_needed; + std::vector per_subaddress; + uint64_t blocks_to_unlock; + uint64_t time_to_unlock; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(balance) + KV_SERIALIZE(unlocked_balance) + KV_SERIALIZE(multisig_import_needed) + KV_SERIALIZE(per_subaddress) + KV_SERIALIZE(blocks_to_unlock) + KV_SERIALIZE(time_to_unlock) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; struct COMMAND_RPC_GET_ADDRESS - { - struct request_t - { - uint32_t account_index; - std::vector address_index; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(account_index) - KV_SERIALIZE(address_index) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct address_info { - std::string address; - std::string label; - uint32_t address_index; - bool used; + struct request_t + { + uint32_t account_index; + std::vector address_index; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(account_index) + KV_SERIALIZE(address_index) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(label) - KV_SERIALIZE(address_index) - KV_SERIALIZE(used) - END_KV_SERIALIZE_MAP() - }; + struct address_info + { + std::string address; + std::string label; + uint32_t address_index; + bool used; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE(label) + KV_SERIALIZE(address_index) + KV_SERIALIZE(used) + END_KV_SERIALIZE_MAP() + }; - struct response_t - { - std::string address; // to remain compatible with older RPC format - std::vector addresses; + struct response_t + { + std::string address; // to remain compatible with older RPC format + std::vector addresses; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(addresses) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE(addresses) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_GET_ADDRESS_INDEX - { - struct request_t + struct COMMAND_RPC_GET_ADDRESS_INDEX { - std::string address; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + struct request_t + { + std::string address; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct response_t - { - cryptonote::subaddress_index index; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(index) - END_KV_SERIALIZE_MAP() + struct response_t + { + cryptonote::subaddress_index index; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(index) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_CREATE_ADDRESS - { - struct request_t + struct COMMAND_RPC_CREATE_ADDRESS { - uint32_t account_index; - uint32_t count; - std::string label; + struct request_t + { + uint32_t account_index; + uint32_t count; + std::string label; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(account_index) + KV_SERIALIZE_OPT(count, 1U) + KV_SERIALIZE(label) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(account_index) - KV_SERIALIZE_OPT(count, 1U) - KV_SERIALIZE(label) - END_KV_SERIALIZE_MAP() + struct response_t + { + std::string address; + uint32_t address_index; + std::vector addresses; + std::vector address_indices; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE(address_index) + KV_SERIALIZE(addresses) + KV_SERIALIZE(address_indices) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_LABEL_ADDRESS { - std::string address; - uint32_t address_index; - std::vector addresses; - std::vector address_indices; + struct request_t + { + cryptonote::subaddress_index index; + std::string label; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(address_index) - KV_SERIALIZE(addresses) - KV_SERIALIZE(address_indices) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(index) + KV_SERIALIZE(label) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; + + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_LABEL_ADDRESS - { - struct request_t + struct COMMAND_RPC_GET_ACCOUNTS { - cryptonote::subaddress_index index; - std::string label; + struct request_t + { + std::string tag; // all accounts if empty, otherwise those accounts with this tag + bool strict_balances; + bool regexp; // allow regular expression filters if set to true + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(tag) + KV_SERIALIZE_OPT(strict_balances, false) + KV_SERIALIZE_OPT(regexp, false) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(index) - KV_SERIALIZE(label) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + struct subaddress_account_info + { + uint32_t account_index; + std::string base_address; + uint64_t balance; + uint64_t unlocked_balance; + std::string label; + std::string tag; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(account_index) + KV_SERIALIZE(base_address) + KV_SERIALIZE(balance) + KV_SERIALIZE(unlocked_balance) + KV_SERIALIZE(label) + KV_SERIALIZE(tag) + END_KV_SERIALIZE_MAP() + }; - struct response_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + struct response_t + { + uint64_t total_balance; + uint64_t total_unlocked_balance; + std::vector subaddress_accounts; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(total_balance) + KV_SERIALIZE(total_unlocked_balance) + KV_SERIALIZE(subaddress_accounts) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_GET_ACCOUNTS - { - struct request_t + struct COMMAND_RPC_CREATE_ACCOUNT { - std::string tag; // all accounts if empty, otherwise those accounts with this tag - bool strict_balances; - bool regexp; // allow regular expression filters if set to true + struct request_t + { + std::string label; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(label) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tag) - KV_SERIALIZE_OPT(strict_balances, false) - KV_SERIALIZE_OPT(regexp, false) - END_KV_SERIALIZE_MAP() + struct response_t + { + uint32_t account_index; + std::string address; // the 0-th address for convenience + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(account_index) + KV_SERIALIZE(address) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct subaddress_account_info + struct COMMAND_RPC_LABEL_ACCOUNT { - uint32_t account_index; - std::string base_address; - uint64_t balance; - uint64_t unlocked_balance; - std::string label; - std::string tag; + struct request_t + { + uint32_t account_index; + std::string label; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(account_index) - KV_SERIALIZE(base_address) - KV_SERIALIZE(balance) - KV_SERIALIZE(unlocked_balance) - KV_SERIALIZE(label) - KV_SERIALIZE(tag) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(account_index) + KV_SERIALIZE(label) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; + + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - struct response_t + struct COMMAND_RPC_GET_ACCOUNT_TAGS { - uint64_t total_balance; - uint64_t total_unlocked_balance; - std::vector subaddress_accounts; + struct request_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(total_balance) - KV_SERIALIZE(total_unlocked_balance) - KV_SERIALIZE(subaddress_accounts) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + struct account_tag_info + { + std::string tag; + std::string label; + std::vector accounts; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(tag) + KV_SERIALIZE(label) + KV_SERIALIZE(accounts) + END_KV_SERIALIZE_MAP() + }; - struct COMMAND_RPC_CREATE_ACCOUNT - { - struct request_t - { - std::string label; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(label) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + struct response_t + { + std::vector account_tags; - struct response_t - { - uint32_t account_index; - std::string address; // the 0-th address for convenience - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(account_index) - KV_SERIALIZE(address) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(account_tags) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_LABEL_ACCOUNT - { - struct request_t + struct COMMAND_RPC_TAG_ACCOUNTS { - uint32_t account_index; - std::string label; + struct request_t + { + std::string tag; + std::set accounts; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(account_index) - KV_SERIALIZE(label) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(tag) + KV_SERIALIZE(accounts) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct response_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_GET_ACCOUNT_TAGS - { - struct request_t + struct COMMAND_RPC_UNTAG_ACCOUNTS { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + struct request_t + { + std::set accounts; - struct account_tag_info - { - std::string tag; - std::string label; - std::vector accounts; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(accounts) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tag) - KV_SERIALIZE(label) - KV_SERIALIZE(accounts) - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - struct response_t + struct COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION { - std::vector account_tags; + struct request_t + { + std::string tag; + std::string description; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(account_tags) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(tag) + KV_SERIALIZE(description) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; + + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_TAG_ACCOUNTS - { - struct request_t + struct COMMAND_RPC_GET_HEIGHT { - std::string tag; - std::set accounts; + struct request_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tag) - KV_SERIALIZE(accounts) - END_KV_SERIALIZE_MAP() + struct response_t + { + uint64_t height; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(height) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct transfer_destination { + uint64_t amount; + std::string address; BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + KV_SERIALIZE(amount) + KV_SERIALIZE(address) + END_KV_SERIALIZE_MAP() }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_UNTAG_ACCOUNTS - { - struct request_t + struct COMMAND_RPC_FREEZE { - std::set accounts; + struct request_t + { + std::string key_image; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(accounts) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(key_image) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct response_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION - { - struct request_t + struct COMMAND_RPC_THAW { - std::string tag; - std::string description; + struct request_t + { + std::string key_image; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tag) - KV_SERIALIZE(description) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(key_image) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct response_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_GET_HEIGHT + struct COMMAND_RPC_FROZEN { struct request_t { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + std::string key_image; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(key_image) + END_KV_SERIALIZE_MAP() }; typedef epee::misc_utils::struct_init request; struct response_t { - uint64_t height; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(height) - END_KV_SERIALIZE_MAP() + bool frozen; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(frozen) + END_KV_SERIALIZE_MAP() }; typedef epee::misc_utils::struct_init response; }; - struct transfer_destination - { - uint64_t amount; - std::string address; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount) - KV_SERIALIZE(address) - END_KV_SERIALIZE_MAP() - }; - - struct COMMAND_RPC_FREEZE - { - struct request_t + struct key_image_list { - std::string key_image; + std::list key_images; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(key_image) - END_KV_SERIALIZE_MAP() + KV_SERIALIZE(key_images) + END_KV_SERIALIZE_MAP() }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct amounts_list { + std::list amounts; + + bool operator==(const amounts_list& other) const { return amounts == other.amounts; } + BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + KV_SERIALIZE(amounts) + END_KV_SERIALIZE_MAP() }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_THAW - { - struct request_t + struct single_transfer_response { - std::string key_image; + std::string tx_hash; + std::string tx_key; + uint64_t amount; + amounts_list amounts_by_dest; + uint64_t fee; + uint64_t weight; + std::string tx_blob; + std::string tx_metadata; + std::string multisig_txset; + std::string unsigned_txset; + key_image_list spent_key_images; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(key_image) - END_KV_SERIALIZE_MAP() + KV_SERIALIZE(tx_hash) + KV_SERIALIZE(tx_key) + KV_SERIALIZE(amount) + KV_SERIALIZE_OPT(amounts_by_dest, decltype(amounts_by_dest)()) + KV_SERIALIZE(fee) + KV_SERIALIZE(weight) + KV_SERIALIZE(tx_blob) + KV_SERIALIZE(tx_metadata) + KV_SERIALIZE(multisig_txset) + KV_SERIALIZE(unsigned_txset) + KV_SERIALIZE(spent_key_images) + END_KV_SERIALIZE_MAP() }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_TRANSFER { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + struct request_t + { + std::list destinations; + uint32_t account_index; + std::set subaddr_indices; + std::set subtract_fee_from_outputs; + uint32_t priority; + uint64_t ring_size; + uint64_t unlock_time; + std::string payment_id; + bool get_tx_key; + bool do_not_relay; + bool get_tx_hex; + bool get_tx_metadata; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(destinations) + KV_SERIALIZE(account_index) + KV_SERIALIZE(subaddr_indices) + KV_SERIALIZE_OPT(subtract_fee_from_outputs, decltype(subtract_fee_from_outputs)()) + KV_SERIALIZE(priority) + KV_SERIALIZE_OPT(ring_size, (uint64_t)0) + KV_SERIALIZE(unlock_time) + KV_SERIALIZE(payment_id) + KV_SERIALIZE(get_tx_key) + KV_SERIALIZE_OPT(do_not_relay, false) + KV_SERIALIZE_OPT(get_tx_hex, false) + KV_SERIALIZE_OPT(get_tx_metadata, false) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; + + typedef single_transfer_response response_t; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_FROZEN - { - struct request_t + struct split_transfer_response { - std::string key_image; + std::list tx_hash_list; + std::list tx_key_list; + std::list amount_list; + std::list amounts_by_dest_list; + std::list fee_list; + std::list weight_list; + std::list tx_blob_list; + std::list tx_metadata_list; + std::string multisig_txset; + std::string unsigned_txset; + std::list spent_key_images_list; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(key_image) - END_KV_SERIALIZE_MAP() + KV_SERIALIZE(tx_hash_list) + KV_SERIALIZE(tx_key_list) + KV_SERIALIZE(amount_list) + KV_SERIALIZE_OPT(amounts_by_dest_list, decltype(amounts_by_dest_list)()) + KV_SERIALIZE(fee_list) + KV_SERIALIZE(weight_list) + KV_SERIALIZE(tx_blob_list) + KV_SERIALIZE(tx_metadata_list) + KV_SERIALIZE(multisig_txset) + KV_SERIALIZE(unsigned_txset) + KV_SERIALIZE(spent_key_images_list) + END_KV_SERIALIZE_MAP() }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_TRANSFER_SPLIT { - bool frozen; + struct request_t + { + std::list destinations; + uint32_t account_index; + std::set subaddr_indices; + uint32_t priority; + uint64_t ring_size; + uint64_t unlock_time; + std::string payment_id; + bool get_tx_keys; + bool do_not_relay; + bool get_tx_hex; + bool get_tx_metadata; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(destinations) + KV_SERIALIZE(account_index) + KV_SERIALIZE(subaddr_indices) + KV_SERIALIZE(priority) + KV_SERIALIZE_OPT(ring_size, (uint64_t)0) + KV_SERIALIZE(unlock_time) + KV_SERIALIZE(payment_id) + KV_SERIALIZE(get_tx_keys) + KV_SERIALIZE_OPT(do_not_relay, false) + KV_SERIALIZE_OPT(get_tx_hex, false) + KV_SERIALIZE_OPT(get_tx_metadata, false) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(frozen) - END_KV_SERIALIZE_MAP() + typedef split_transfer_response response_t; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct key_image_list - { - std::list key_images; + struct COMMAND_RPC_DESCRIBE_TRANSFER + { + struct recipient + { + std::string address; + uint64_t amount; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(key_images) - END_KV_SERIALIZE_MAP() - }; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE(amount) + END_KV_SERIALIZE_MAP() + }; - struct amounts_list - { - std::list amounts; + struct transfer_description + { + uint64_t amount_in; + uint64_t amount_out; + uint32_t ring_size; + uint64_t unlock_time; + std::list recipients; + std::string payment_id; + uint64_t change_amount; + std::string change_address; + uint64_t fee; + uint32_t dummy_outputs; + std::string extra; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(amount_in) + KV_SERIALIZE(amount_out) + KV_SERIALIZE(ring_size) + KV_SERIALIZE(unlock_time) + KV_SERIALIZE(recipients) + KV_SERIALIZE(payment_id) + KV_SERIALIZE(change_amount) + KV_SERIALIZE(change_address) + KV_SERIALIZE(fee) + KV_SERIALIZE(dummy_outputs) + KV_SERIALIZE(extra) + END_KV_SERIALIZE_MAP() + }; - bool operator==(const amounts_list& other) const { return amounts == other.amounts; } + struct txset_summary + { + uint64_t amount_in; + uint64_t amount_out; + std::list recipients; + uint64_t change_amount; + std::string change_address; + uint64_t fee; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(amount_in) + KV_SERIALIZE(amount_out) + KV_SERIALIZE(recipients) + KV_SERIALIZE(change_amount) + KV_SERIALIZE(change_address) + KV_SERIALIZE(fee) + END_KV_SERIALIZE_MAP() + }; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amounts) - END_KV_SERIALIZE_MAP() - }; + struct request_t + { + std::string unsigned_txset; + std::string multisig_txset; - struct single_transfer_response - { - std::string tx_hash; - std::string tx_key; - uint64_t amount; - amounts_list amounts_by_dest; - uint64_t fee; - uint64_t weight; - std::string tx_blob; - std::string tx_metadata; - std::string multisig_txset; - std::string unsigned_txset; - key_image_list spent_key_images; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_hash) - KV_SERIALIZE(tx_key) - KV_SERIALIZE(amount) - KV_SERIALIZE_OPT(amounts_by_dest, decltype(amounts_by_dest)()) - KV_SERIALIZE(fee) - KV_SERIALIZE(weight) - KV_SERIALIZE(tx_blob) - KV_SERIALIZE(tx_metadata) - KV_SERIALIZE(multisig_txset) - KV_SERIALIZE(unsigned_txset) - KV_SERIALIZE(spent_key_images) - END_KV_SERIALIZE_MAP() - }; - - struct COMMAND_RPC_TRANSFER - { - struct request_t - { - std::list destinations; - uint32_t account_index; - std::set subaddr_indices; - std::set subtract_fee_from_outputs; - uint32_t priority; - uint64_t ring_size; - uint64_t unlock_time; - std::string payment_id; - bool get_tx_key; - bool do_not_relay; - bool get_tx_hex; - bool get_tx_metadata; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(destinations) - KV_SERIALIZE(account_index) - KV_SERIALIZE(subaddr_indices) - KV_SERIALIZE_OPT(subtract_fee_from_outputs, decltype(subtract_fee_from_outputs)()) - KV_SERIALIZE(priority) - KV_SERIALIZE_OPT(ring_size, (uint64_t)0) - KV_SERIALIZE(unlock_time) - KV_SERIALIZE(payment_id) - KV_SERIALIZE(get_tx_key) - KV_SERIALIZE_OPT(do_not_relay, false) - KV_SERIALIZE_OPT(get_tx_hex, false) - KV_SERIALIZE_OPT(get_tx_metadata, false) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - typedef single_transfer_response response_t; - typedef epee::misc_utils::struct_init response; - }; - - struct split_transfer_response - { - std::list tx_hash_list; - std::list tx_key_list; - std::list amount_list; - std::list amounts_by_dest_list; - std::list fee_list; - std::list weight_list; - std::list tx_blob_list; - std::list tx_metadata_list; - std::string multisig_txset; - std::string unsigned_txset; - std::list spent_key_images_list; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_hash_list) - KV_SERIALIZE(tx_key_list) - KV_SERIALIZE(amount_list) - KV_SERIALIZE_OPT(amounts_by_dest_list, decltype(amounts_by_dest_list)()) - KV_SERIALIZE(fee_list) - KV_SERIALIZE(weight_list) - KV_SERIALIZE(tx_blob_list) - KV_SERIALIZE(tx_metadata_list) - KV_SERIALIZE(multisig_txset) - KV_SERIALIZE(unsigned_txset) - KV_SERIALIZE(spent_key_images_list) - END_KV_SERIALIZE_MAP() - }; - - struct COMMAND_RPC_TRANSFER_SPLIT - { - struct request_t - { - std::list destinations; - uint32_t account_index; - std::set subaddr_indices; - uint32_t priority; - uint64_t ring_size; - uint64_t unlock_time; - std::string payment_id; - bool get_tx_keys; - bool do_not_relay; - bool get_tx_hex; - bool get_tx_metadata; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(unsigned_txset) + KV_SERIALIZE(multisig_txset) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(destinations) - KV_SERIALIZE(account_index) - KV_SERIALIZE(subaddr_indices) - KV_SERIALIZE(priority) - KV_SERIALIZE_OPT(ring_size, (uint64_t)0) - KV_SERIALIZE(unlock_time) - KV_SERIALIZE(payment_id) - KV_SERIALIZE(get_tx_keys) - KV_SERIALIZE_OPT(do_not_relay, false) - KV_SERIALIZE_OPT(get_tx_hex, false) - KV_SERIALIZE_OPT(get_tx_metadata, false) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - typedef split_transfer_response response_t; - typedef epee::misc_utils::struct_init response; - }; - - struct COMMAND_RPC_DESCRIBE_TRANSFER - { - struct recipient - { - std::string address; - uint64_t amount; + struct response_t + { + std::list desc; + struct txset_summary summary; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(amount) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(summary) + KV_SERIALIZE(desc) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - struct transfer_description + struct COMMAND_RPC_SIGN_TRANSFER { - uint64_t amount_in; - uint64_t amount_out; - uint32_t ring_size; - uint64_t unlock_time; - std::list recipients; - std::string payment_id; - uint64_t change_amount; - std::string change_address; - uint64_t fee; - uint32_t dummy_outputs; - std::string extra; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount_in) - KV_SERIALIZE(amount_out) - KV_SERIALIZE(ring_size) - KV_SERIALIZE(unlock_time) - KV_SERIALIZE(recipients) - KV_SERIALIZE(payment_id) - KV_SERIALIZE(change_amount) - KV_SERIALIZE(change_address) - KV_SERIALIZE(fee) - KV_SERIALIZE(dummy_outputs) - KV_SERIALIZE(extra) - END_KV_SERIALIZE_MAP() - }; - - struct txset_summary - { - uint64_t amount_in; - uint64_t amount_out; - std::list recipients; - uint64_t change_amount; - std::string change_address; - uint64_t fee; + struct request_t + { + std::string unsigned_txset; + bool export_raw; + bool get_tx_keys; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(unsigned_txset) + KV_SERIALIZE_OPT(export_raw, false) + KV_SERIALIZE_OPT(get_tx_keys, false) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount_in) - KV_SERIALIZE(amount_out) - KV_SERIALIZE(recipients) - KV_SERIALIZE(change_amount) - KV_SERIALIZE(change_address) - KV_SERIALIZE(fee) - END_KV_SERIALIZE_MAP() + struct response_t + { + std::string signed_txset; + std::list tx_hash_list; + std::list tx_raw_list; + std::list tx_key_list; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(signed_txset) + KV_SERIALIZE(tx_hash_list) + KV_SERIALIZE(tx_raw_list) + KV_SERIALIZE(tx_key_list) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - struct request_t + struct COMMAND_RPC_SUBMIT_TRANSFER { - std::string unsigned_txset; - std::string multisig_txset; + struct request_t + { + std::string tx_data_hex; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(unsigned_txset) - KV_SERIALIZE(multisig_txset) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(tx_data_hex) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct response_t - { - std::list desc; - struct txset_summary summary; + struct response_t + { + std::list tx_hash_list; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(summary) - KV_SERIALIZE(desc) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(tx_hash_list) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_SIGN_TRANSFER - { - struct request_t + struct COMMAND_RPC_SWEEP_DUST { - std::string unsigned_txset; - bool export_raw; - bool get_tx_keys; + struct request_t + { + bool get_tx_keys; + bool do_not_relay; + bool get_tx_hex; + bool get_tx_metadata; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(get_tx_keys) + KV_SERIALIZE_OPT(do_not_relay, false) + KV_SERIALIZE_OPT(get_tx_hex, false) + KV_SERIALIZE_OPT(get_tx_metadata, false) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(unsigned_txset) - KV_SERIALIZE_OPT(export_raw, false) - KV_SERIALIZE_OPT(get_tx_keys, false) - END_KV_SERIALIZE_MAP() + typedef split_transfer_response response_t; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_SWEEP_ALL { - std::string signed_txset; - std::list tx_hash_list; - std::list tx_raw_list; - std::list tx_key_list; + struct request_t + { + std::string address; + uint32_t account_index; + std::set subaddr_indices; + bool subaddr_indices_all; + uint32_t priority; + uint64_t ring_size; + uint64_t outputs; + uint64_t unlock_time; + std::string payment_id; + bool get_tx_keys; + uint64_t below_amount; + bool do_not_relay; + bool get_tx_hex; + bool get_tx_metadata; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE(account_index) + KV_SERIALIZE(subaddr_indices) + KV_SERIALIZE_OPT(subaddr_indices_all, false) + KV_SERIALIZE(priority) + KV_SERIALIZE_OPT(ring_size, (uint64_t)0) + KV_SERIALIZE_OPT(outputs, (uint64_t)1) + KV_SERIALIZE(unlock_time) + KV_SERIALIZE(payment_id) + KV_SERIALIZE(get_tx_keys) + KV_SERIALIZE(below_amount) + KV_SERIALIZE_OPT(do_not_relay, false) + KV_SERIALIZE_OPT(get_tx_hex, false) + KV_SERIALIZE_OPT(get_tx_metadata, false) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(signed_txset) - KV_SERIALIZE(tx_hash_list) - KV_SERIALIZE(tx_raw_list) - KV_SERIALIZE(tx_key_list) - END_KV_SERIALIZE_MAP() + typedef split_transfer_response response_t; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_SUBMIT_TRANSFER - { - struct request_t + struct COMMAND_RPC_SWEEP_SINGLE { - std::string tx_data_hex; + struct request_t + { + std::string address; + uint32_t priority; + uint64_t ring_size; + uint64_t outputs; + uint64_t unlock_time; + std::string payment_id; + bool get_tx_key; + std::string key_image; + bool do_not_relay; + bool get_tx_hex; + bool get_tx_metadata; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE(priority) + KV_SERIALIZE_OPT(ring_size, (uint64_t)0) + KV_SERIALIZE_OPT(outputs, (uint64_t)1) + KV_SERIALIZE(unlock_time) + KV_SERIALIZE(payment_id) + KV_SERIALIZE(get_tx_key) + KV_SERIALIZE(key_image) + KV_SERIALIZE_OPT(do_not_relay, false) + KV_SERIALIZE_OPT(get_tx_hex, false) + KV_SERIALIZE_OPT(get_tx_metadata, false) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_data_hex) - END_KV_SERIALIZE_MAP() + typedef single_transfer_response response_t; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_RELAY_TX { - std::list tx_hash_list; + struct request_t + { + std::string hex; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_hash_list) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(hex) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; + + struct response_t + { + std::string tx_hash; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(tx_hash) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_SWEEP_DUST - { - struct request_t + struct COMMAND_RPC_STORE { - bool get_tx_keys; - bool do_not_relay; - bool get_tx_hex; - bool get_tx_metadata; + struct request_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(get_tx_keys) - KV_SERIALIZE_OPT(do_not_relay, false) - KV_SERIALIZE_OPT(get_tx_hex, false) - KV_SERIALIZE_OPT(get_tx_metadata, false) - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - typedef split_transfer_response response_t; - typedef epee::misc_utils::struct_init response; - }; - - struct COMMAND_RPC_SWEEP_ALL - { - struct request_t + struct payment_details { - std::string address; - uint32_t account_index; - std::set subaddr_indices; - bool subaddr_indices_all; - uint32_t priority; - uint64_t ring_size; - uint64_t outputs; - uint64_t unlock_time; std::string payment_id; - bool get_tx_keys; - uint64_t below_amount; - bool do_not_relay; - bool get_tx_hex; - bool get_tx_metadata; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(account_index) - KV_SERIALIZE(subaddr_indices) - KV_SERIALIZE_OPT(subaddr_indices_all, false) - KV_SERIALIZE(priority) - KV_SERIALIZE_OPT(ring_size, (uint64_t)0) - KV_SERIALIZE_OPT(outputs, (uint64_t)1) - KV_SERIALIZE(unlock_time) - KV_SERIALIZE(payment_id) - KV_SERIALIZE(get_tx_keys) - KV_SERIALIZE(below_amount) - KV_SERIALIZE_OPT(do_not_relay, false) - KV_SERIALIZE_OPT(get_tx_hex, false) - KV_SERIALIZE_OPT(get_tx_metadata, false) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - typedef split_transfer_response response_t; - typedef epee::misc_utils::struct_init response; - }; - - struct COMMAND_RPC_SWEEP_SINGLE - { - struct request_t - { - std::string address; - uint32_t priority; - uint64_t ring_size; - uint64_t outputs; + std::string tx_hash; + uint64_t amount; + uint64_t block_height; uint64_t unlock_time; - std::string payment_id; - bool get_tx_key; - std::string key_image; - bool do_not_relay; - bool get_tx_hex; - bool get_tx_metadata; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(priority) - KV_SERIALIZE_OPT(ring_size, (uint64_t)0) - KV_SERIALIZE_OPT(outputs, (uint64_t)1) - KV_SERIALIZE(unlock_time) - KV_SERIALIZE(payment_id) - KV_SERIALIZE(get_tx_key) - KV_SERIALIZE(key_image) - KV_SERIALIZE_OPT(do_not_relay, false) - KV_SERIALIZE_OPT(get_tx_hex, false) - KV_SERIALIZE_OPT(get_tx_metadata, false) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - typedef single_transfer_response response_t; - typedef epee::misc_utils::struct_init response; - }; - - struct COMMAND_RPC_RELAY_TX - { - struct request_t - { - std::string hex; + bool locked; + cryptonote::subaddress_index subaddr_index; + std::string address; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(hex) - END_KV_SERIALIZE_MAP() + KV_SERIALIZE(payment_id) + KV_SERIALIZE(tx_hash) + KV_SERIALIZE(amount) + KV_SERIALIZE(block_height) + KV_SERIALIZE(unlock_time) + KV_SERIALIZE(locked) + KV_SERIALIZE(subaddr_index) + KV_SERIALIZE(address) + END_KV_SERIALIZE_MAP() }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_GET_PAYMENTS { - std::string tx_hash; + struct request_t + { + std::string payment_id; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_hash) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(payment_id) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct COMMAND_RPC_STORE - { - struct request_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + struct response_t + { + std::list payments; - struct response_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(payments) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct payment_details - { - std::string payment_id; - std::string tx_hash; - uint64_t amount; - uint64_t block_height; - uint64_t unlock_time; - bool locked; - cryptonote::subaddress_index subaddr_index; - std::string address; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(payment_id) - KV_SERIALIZE(tx_hash) - KV_SERIALIZE(amount) - KV_SERIALIZE(block_height) - KV_SERIALIZE(unlock_time) - KV_SERIALIZE(locked) - KV_SERIALIZE(subaddr_index) - KV_SERIALIZE(address) - END_KV_SERIALIZE_MAP() - }; - - struct COMMAND_RPC_GET_PAYMENTS - { - struct request_t + struct COMMAND_RPC_GET_BULK_PAYMENTS { - std::string payment_id; + struct request_t + { + std::vector payment_ids; + uint64_t min_block_height; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(payment_id) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(payment_ids) + KV_SERIALIZE(min_block_height) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct response_t - { - std::list payments; + struct response_t + { + std::list payments; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(payments) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(payments) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_GET_BULK_PAYMENTS - { - struct request_t + struct transfer_details { - std::vector payment_ids; - uint64_t min_block_height; + uint64_t amount; + bool spent; + uint64_t global_index; + std::string tx_hash; + cryptonote::subaddress_index subaddr_index; + std::string key_image; + std::string pubkey; // owned output public key found + uint64_t block_height; + bool frozen; + bool unlocked; BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(payment_ids) - KV_SERIALIZE(min_block_height) - END_KV_SERIALIZE_MAP() + KV_SERIALIZE(amount) + KV_SERIALIZE(spent) + KV_SERIALIZE(global_index) + KV_SERIALIZE(tx_hash) + KV_SERIALIZE(subaddr_index) + KV_SERIALIZE(key_image) + KV_SERIALIZE(pubkey) + KV_SERIALIZE(block_height) + KV_SERIALIZE(frozen) + KV_SERIALIZE(unlocked) + END_KV_SERIALIZE_MAP() }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_INCOMING_TRANSFERS { - std::list payments; + struct request_t + { + std::string transfer_type; + uint32_t account_index; + std::set subaddr_indices; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(transfer_type) + KV_SERIALIZE(account_index) + KV_SERIALIZE(subaddr_indices) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(payments) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - - struct transfer_details - { - uint64_t amount; - bool spent; - uint64_t global_index; - std::string tx_hash; - cryptonote::subaddress_index subaddr_index; - std::string key_image; - std::string pubkey; // owned output public key found - uint64_t block_height; - bool frozen; - bool unlocked; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(amount) - KV_SERIALIZE(spent) - KV_SERIALIZE(global_index) - KV_SERIALIZE(tx_hash) - KV_SERIALIZE(subaddr_index) - KV_SERIALIZE(key_image) - KV_SERIALIZE(pubkey) - KV_SERIALIZE(block_height) - KV_SERIALIZE(frozen) - KV_SERIALIZE(unlocked) - END_KV_SERIALIZE_MAP() - }; - - struct COMMAND_RPC_INCOMING_TRANSFERS - { - struct request_t - { - std::string transfer_type; - uint32_t account_index; - std::set subaddr_indices; + struct response_t + { + std::list transfers; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(transfer_type) - KV_SERIALIZE(account_index) - KV_SERIALIZE(subaddr_indices) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(transfers) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + //JSON RPC V2 + struct COMMAND_RPC_QUERY_KEY { - std::list transfers; + struct request_t + { + std::string key_type; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(transfers) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(key_type) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - //JSON RPC V2 - struct COMMAND_RPC_QUERY_KEY - { - struct request_t - { - std::string key_type; + struct response_t + { + std::string key; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(key_type) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(key) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_MAKE_INTEGRATED_ADDRESS { - std::string key; + struct request_t + { + std::string standard_address; + std::string payment_id; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(key) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(standard_address) + KV_SERIALIZE(payment_id) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct COMMAND_RPC_MAKE_INTEGRATED_ADDRESS - { - struct request_t - { - std::string standard_address; - std::string payment_id; + struct response_t + { + std::string integrated_address; + std::string payment_id; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(standard_address) - KV_SERIALIZE(payment_id) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(integrated_address) + KV_SERIALIZE(payment_id) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS { - std::string integrated_address; - std::string payment_id; + struct request_t + { + std::string integrated_address; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(integrated_address) - KV_SERIALIZE(payment_id) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(integrated_address) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; + + struct response_t + { + std::string standard_address; + std::string payment_id; + bool is_subaddress; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(standard_address) + KV_SERIALIZE(payment_id) + KV_SERIALIZE(is_subaddress) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS - { - struct request_t + struct COMMAND_RPC_STOP_WALLET { - std::string integrated_address; + struct request_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(integrated_address) - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_RESCAN_BLOCKCHAIN { - std::string standard_address; - std::string payment_id; - bool is_subaddress; + struct request_t + { + bool hard; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(standard_address) - KV_SERIALIZE(payment_id) - KV_SERIALIZE(is_subaddress) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_OPT(hard, false) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct COMMAND_RPC_STOP_WALLET - { - struct request_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_SET_TX_NOTES { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + struct request_t + { + std::list txids; + std::list notes; - struct COMMAND_RPC_RESCAN_BLOCKCHAIN - { - struct request_t - { - bool hard; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(txids) + KV_SERIALIZE(notes) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_OPT(hard, false) - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_GET_TX_NOTES { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + struct request_t + { + std::list txids; - struct COMMAND_RPC_SET_TX_NOTES - { - struct request_t - { - std::list txids; - std::list notes; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(txids) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(txids) - KV_SERIALIZE(notes) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + struct response_t + { + std::list notes; - struct response_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(notes) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_GET_TX_NOTES - { - struct request_t + struct COMMAND_RPC_SET_ATTRIBUTE { - std::list txids; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(txids) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct response_t - { - std::list notes; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(notes) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - - struct COMMAND_RPC_SET_ATTRIBUTE - { - struct request_t - { - std::string key; - std::string value; + struct request_t + { + std::string key; + std::string value; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(key) - KV_SERIALIZE(value) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(key) + KV_SERIALIZE(value) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct response_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_GET_ATTRIBUTE - { - struct request_t + struct COMMAND_RPC_GET_ATTRIBUTE { + struct request_t + { - std::string key; + std::string key; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(key) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(key) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct response_t - { - std::string value; + struct response_t + { + std::string value; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(value) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(value) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_GET_TX_KEY - { - struct request_t + struct COMMAND_RPC_GET_TX_KEY { - std::string txid; + struct request_t + { + std::string txid; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(txid) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(txid) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct response_t - { - std::string tx_key; + struct response_t + { + std::string tx_key; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_key) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(tx_key) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_CHECK_TX_KEY - { - struct request_t + struct COMMAND_RPC_CHECK_TX_KEY { - std::string txid; - std::string tx_key; - std::string address; + struct request_t + { + std::string txid; + std::string tx_key; + std::string address; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(txid) + KV_SERIALIZE(tx_key) + KV_SERIALIZE(address) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(txid) - KV_SERIALIZE(tx_key) - KV_SERIALIZE(address) - END_KV_SERIALIZE_MAP() + struct response_t + { + uint64_t received; + bool in_pool; + uint64_t confirmations; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(received) + KV_SERIALIZE(in_pool) + KV_SERIALIZE(confirmations) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_GET_TX_PROOF { - uint64_t received; - bool in_pool; - uint64_t confirmations; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(received) - KV_SERIALIZE(in_pool) - KV_SERIALIZE(confirmations) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + struct request_t + { + std::string txid; + std::string address; + std::string message; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(txid) + KV_SERIALIZE(address) + KV_SERIALIZE(message) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct COMMAND_RPC_GET_TX_PROOF - { - struct request_t - { - std::string txid; - std::string address; - std::string message; + struct response_t + { + std::string signature; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(txid) - KV_SERIALIZE(address) - KV_SERIALIZE(message) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(signature) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_CHECK_TX_PROOF { - std::string signature; + struct request_t + { + std::string txid; + std::string address; + std::string message; + std::string signature; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(txid) + KV_SERIALIZE(address) + KV_SERIALIZE(message) + KV_SERIALIZE(signature) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(signature) - END_KV_SERIALIZE_MAP() + struct response_t + { + bool good; + uint64_t received; + bool in_pool; + uint64_t confirmations; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(good) + KV_SERIALIZE(received) + KV_SERIALIZE(in_pool) + KV_SERIALIZE(confirmations) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_CHECK_TX_PROOF - { - struct request_t + typedef std::vector amounts_container; + struct transfer_entry { std::string txid; + std::string payment_id; + uint64_t height; + uint64_t timestamp; + uint64_t amount; + amounts_container amounts; + uint64_t fee; + std::string note; + std::list destinations; + std::string type; + uint64_t unlock_time; + bool locked; + cryptonote::subaddress_index subaddr_index; + std::vector subaddr_indices; std::string address; - std::string message; - std::string signature; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(txid) - KV_SERIALIZE(address) - KV_SERIALIZE(message) - KV_SERIALIZE(signature) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct response_t - { - bool good; - uint64_t received; - bool in_pool; + bool double_spend_seen; uint64_t confirmations; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(good) - KV_SERIALIZE(received) - KV_SERIALIZE(in_pool) - KV_SERIALIZE(confirmations) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - - typedef std::vector amounts_container; - struct transfer_entry - { - std::string txid; - std::string payment_id; - uint64_t height; - uint64_t timestamp; - uint64_t amount; - amounts_container amounts; - uint64_t fee; - std::string note; - std::list destinations; - std::string type; - uint64_t unlock_time; - bool locked; - cryptonote::subaddress_index subaddr_index; - std::vector subaddr_indices; - std::string address; - bool double_spend_seen; - uint64_t confirmations; - uint64_t suggested_confirmations_threshold; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(txid) - KV_SERIALIZE(payment_id) - KV_SERIALIZE(height) - KV_SERIALIZE(timestamp) - KV_SERIALIZE(amount) - KV_SERIALIZE(amounts) - KV_SERIALIZE(fee) - KV_SERIALIZE(note) - KV_SERIALIZE(destinations) - KV_SERIALIZE(type) - KV_SERIALIZE(unlock_time) - KV_SERIALIZE(locked) - KV_SERIALIZE(subaddr_index) - KV_SERIALIZE(subaddr_indices) - KV_SERIALIZE(address) - KV_SERIALIZE(double_spend_seen) - KV_SERIALIZE_OPT(confirmations, (uint64_t)0) - KV_SERIALIZE_OPT(suggested_confirmations_threshold, (uint64_t)0) - END_KV_SERIALIZE_MAP() - }; - - struct COMMAND_RPC_GET_SPEND_PROOF - { - struct request_t - { - std::string txid; - std::string message; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(txid) - KV_SERIALIZE(message) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct response_t - { - std::string signature; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(signature) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - - struct COMMAND_RPC_CHECK_SPEND_PROOF - { - struct request_t - { - std::string txid; - std::string message; - std::string signature; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(txid) - KV_SERIALIZE(message) - KV_SERIALIZE(signature) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct response_t - { - bool good; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(good) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - - struct COMMAND_RPC_GET_RESERVE_PROOF - { - struct request_t - { - bool all; - uint32_t account_index; // ignored when `all` is true - uint64_t amount; // ignored when `all` is true - std::string message; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(all) - KV_SERIALIZE(account_index) - KV_SERIALIZE(amount) - KV_SERIALIZE(message) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct response_t + uint64_t suggested_confirmations_threshold; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(txid) + KV_SERIALIZE(payment_id) + KV_SERIALIZE(height) + KV_SERIALIZE(timestamp) + KV_SERIALIZE(amount) + KV_SERIALIZE(amounts) + KV_SERIALIZE(fee) + KV_SERIALIZE(note) + KV_SERIALIZE(destinations) + KV_SERIALIZE(type) + KV_SERIALIZE(unlock_time) + KV_SERIALIZE(locked) + KV_SERIALIZE(subaddr_index) + KV_SERIALIZE(subaddr_indices) + KV_SERIALIZE(address) + KV_SERIALIZE(double_spend_seen) + KV_SERIALIZE_OPT(confirmations, (uint64_t)0) + KV_SERIALIZE_OPT(suggested_confirmations_threshold, (uint64_t)0) + END_KV_SERIALIZE_MAP() + }; + + struct COMMAND_RPC_GET_SPEND_PROOF { - std::string signature; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(signature) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - - struct COMMAND_RPC_CHECK_RESERVE_PROOF - { - struct request_t - { - std::string address; - std::string message; - std::string signature; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(message) - KV_SERIALIZE(signature) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct response_t - { - bool good; - uint64_t total; - uint64_t spent; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(good) - KV_SERIALIZE(total) - KV_SERIALIZE(spent) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - - struct COMMAND_RPC_GET_TRANSFERS - { - struct request_t - { - bool in; - bool out; - bool pending; - bool failed; - bool pool; - - bool filter_by_height; - uint64_t min_height; - uint64_t max_height; - uint32_t account_index; - std::set subaddr_indices; - bool all_accounts; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(in) - KV_SERIALIZE(out) - KV_SERIALIZE(pending) - KV_SERIALIZE(failed) - KV_SERIALIZE(pool) - KV_SERIALIZE(filter_by_height) - KV_SERIALIZE(min_height) - KV_SERIALIZE_OPT(max_height, (uint64_t)CRYPTONOTE_MAX_BLOCK_NUMBER) - KV_SERIALIZE(account_index) - KV_SERIALIZE(subaddr_indices) - KV_SERIALIZE_OPT(all_accounts, false) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct response_t - { - std::list in; - std::list out; - std::list pending; - std::list failed; - std::list pool; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(in) - KV_SERIALIZE(out) - KV_SERIALIZE(pending) - KV_SERIALIZE(failed) - KV_SERIALIZE(pool) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - - struct COMMAND_RPC_GET_TRANSFER_BY_TXID - { - struct request_t - { - std::string txid; - uint32_t account_index; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(txid) - KV_SERIALIZE_OPT(account_index, (uint32_t)0) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct response_t - { - transfer_entry transfer; - std::list transfers; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(transfer) - KV_SERIALIZE(transfers) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - - struct COMMAND_RPC_SIGN - { - struct request_t - { - std::string data; - uint32_t account_index; - uint32_t address_index; - std::string signature_type; + struct request_t + { + std::string txid; + std::string message; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(data) - KV_SERIALIZE_OPT(account_index, 0u) - KV_SERIALIZE_OPT(address_index, 0u) - KV_SERIALIZE(signature_type) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(txid) + KV_SERIALIZE(message) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct response_t - { - std::string signature; + struct response_t + { + std::string signature; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(signature) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(signature) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_VERIFY - { - struct request_t + struct COMMAND_RPC_CHECK_SPEND_PROOF { - std::string data; - std::string address; - std::string signature; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(data) - KV_SERIALIZE(address) - KV_SERIALIZE(signature) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + struct request_t + { + std::string txid; + std::string message; + std::string signature; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(txid) + KV_SERIALIZE(message) + KV_SERIALIZE(signature) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct response_t - { - bool good; - unsigned version; - bool old; - std::string signature_type; + struct response_t + { + bool good; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(good) - KV_SERIALIZE(version) - KV_SERIALIZE(old) - KV_SERIALIZE(signature_type) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(good) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_EXPORT_OUTPUTS - { - struct request_t + struct COMMAND_RPC_GET_RESERVE_PROOF { - bool all; - uint32_t start; - uint32_t count; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(all) - KV_SERIALIZE_OPT(start, 0u) - KV_SERIALIZE_OPT(count, 0xffffffffu) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + struct request_t + { + bool all; + uint32_t account_index; // ignored when `all` is true + uint64_t amount; // ignored when `all` is true + std::string message; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(all) + KV_SERIALIZE(account_index) + KV_SERIALIZE(amount) + KV_SERIALIZE(message) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct response_t - { - std::string outputs_data_hex; + struct response_t + { + std::string signature; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(outputs_data_hex) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(signature) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_IMPORT_OUTPUTS - { - struct request_t + struct COMMAND_RPC_CHECK_RESERVE_PROOF { - std::string outputs_data_hex; + struct request_t + { + std::string address; + std::string message; + std::string signature; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE(message) + KV_SERIALIZE(signature) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(outputs_data_hex) - END_KV_SERIALIZE_MAP() + struct response_t + { + bool good; + uint64_t total; + uint64_t spent; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(good) + KV_SERIALIZE(total) + KV_SERIALIZE(spent) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_GET_TRANSFERS { - uint64_t num_imported; + struct request_t + { + bool in; + bool out; + bool pending; + bool failed; + bool pool; + + bool filter_by_height; + uint64_t min_height; + uint64_t max_height; + uint32_t account_index; + std::set subaddr_indices; + bool all_accounts; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(in) + KV_SERIALIZE(out) + KV_SERIALIZE(pending) + KV_SERIALIZE(failed) + KV_SERIALIZE(pool) + KV_SERIALIZE(filter_by_height) + KV_SERIALIZE(min_height) + KV_SERIALIZE_OPT(max_height, (uint64_t)CRYPTONOTE_MAX_BLOCK_NUMBER) + KV_SERIALIZE(account_index) + KV_SERIALIZE(subaddr_indices) + KV_SERIALIZE_OPT(all_accounts, false) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(num_imported) - END_KV_SERIALIZE_MAP() + struct response_t + { + std::list in; + std::list out; + std::list pending; + std::list failed; + std::list pool; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(in) + KV_SERIALIZE(out) + KV_SERIALIZE(pending) + KV_SERIALIZE(failed) + KV_SERIALIZE(pool) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_EXPORT_KEY_IMAGES - { - struct request_t + struct COMMAND_RPC_GET_TRANSFER_BY_TXID { - bool all; + struct request_t + { + std::string txid; + uint32_t account_index; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_OPT(all, false) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(txid) + KV_SERIALIZE_OPT(account_index, (uint32_t)0) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct signed_key_image - { - std::string key_image; - std::string signature; + struct response_t + { + transfer_entry transfer; + std::list transfers; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(key_image) - KV_SERIALIZE(signature) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(transfer) + KV_SERIALIZE(transfers) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - struct response_t + struct COMMAND_RPC_SIGN { - uint32_t offset; - std::vector signed_key_images; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(offset) - KV_SERIALIZE(signed_key_images) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + struct request_t + { + std::string data; + uint32_t account_index; + uint32_t address_index; + std::string signature_type; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(data) + KV_SERIALIZE_OPT(account_index, 0u) + KV_SERIALIZE_OPT(address_index, 0u) + KV_SERIALIZE(signature_type) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct COMMAND_RPC_IMPORT_KEY_IMAGES - { - struct signed_key_image - { - std::string key_image; - std::string signature; + struct response_t + { + std::string signature; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(key_image) - KV_SERIALIZE(signature) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(signature) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - struct request_t + struct COMMAND_RPC_VERIFY { - uint32_t offset; - std::vector signed_key_images; + struct request_t + { + std::string data; + std::string address; + std::string signature; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(data) + KV_SERIALIZE(address) + KV_SERIALIZE(signature) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_OPT(offset, (uint32_t)0) - KV_SERIALIZE(signed_key_images) - END_KV_SERIALIZE_MAP() + struct response_t + { + bool good; + unsigned version; + bool old; + std::string signature_type; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(good) + KV_SERIALIZE(version) + KV_SERIALIZE(old) + KV_SERIALIZE(signature_type) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_EXPORT_OUTPUTS { - uint64_t height; - uint64_t spent; - uint64_t unspent; + struct request_t + { + bool all; + uint32_t start; + uint32_t count; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(all) + KV_SERIALIZE_OPT(start, 0u) + KV_SERIALIZE_OPT(count, 0xffffffffu) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(height) - KV_SERIALIZE(spent) - KV_SERIALIZE(unspent) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + struct response_t + { + std::string outputs_data_hex; - struct uri_spec - { - std::string address; - std::string payment_id; - uint64_t amount; - std::string tx_description; - std::string recipient_name; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(payment_id) - KV_SERIALIZE(amount) - KV_SERIALIZE(tx_description) - KV_SERIALIZE(recipient_name) - END_KV_SERIALIZE_MAP() - }; - - struct COMMAND_RPC_MAKE_URI - { - struct request_t: public uri_spec - { + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(outputs_data_hex) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_IMPORT_OUTPUTS { - std::string uri; + struct request_t + { + std::string outputs_data_hex; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(uri) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(outputs_data_hex) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct COMMAND_RPC_PARSE_URI - { - struct request_t - { - std::string uri; + struct response_t + { + uint64_t num_imported; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(uri) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(num_imported) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_EXPORT_KEY_IMAGES { - uri_spec uri; - std::vector unknown_parameters; + struct request_t + { + bool all; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(uri) - KV_SERIALIZE(unknown_parameters) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_OPT(all, false) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct COMMAND_RPC_ADD_ADDRESS_BOOK_ENTRY - { - struct request_t - { - std::string address; - std::string description; + struct signed_key_image + { + std::string key_image; + std::string signature; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(description) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(key_image) + KV_SERIALIZE(signature) + END_KV_SERIALIZE_MAP() + }; - struct response_t - { - uint64_t index; + struct response_t + { + uint32_t offset; + std::vector signed_key_images; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(index) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(offset) + KV_SERIALIZE(signed_key_images) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_EDIT_ADDRESS_BOOK_ENTRY - { - struct request_t + struct COMMAND_RPC_IMPORT_KEY_IMAGES { - uint64_t index; - bool set_address; - std::string address; - bool set_description; - std::string description; + struct signed_key_image + { + std::string key_image; + std::string signature; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(index) - KV_SERIALIZE(set_address) - KV_SERIALIZE(address) - KV_SERIALIZE(set_description) - KV_SERIALIZE(description) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(key_image) + KV_SERIALIZE(signature) + END_KV_SERIALIZE_MAP() + }; - struct response_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + struct request_t + { + uint32_t offset; + std::vector signed_key_images; - struct COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY - { - struct request_t - { - std::list entries; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_OPT(offset, (uint32_t)0) + KV_SERIALIZE(signed_key_images) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(entries) - END_KV_SERIALIZE_MAP() + struct response_t + { + uint64_t height; + uint64_t spent; + uint64_t unspent; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(height) + KV_SERIALIZE(spent) + KV_SERIALIZE(unspent) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - - struct entry + struct COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES { - uint64_t index; - std::string address; - std::string description; + struct request_t + { + bool all; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(index) - KV_SERIALIZE(address) - KV_SERIALIZE(description) - END_KV_SERIALIZE_MAP() - }; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_OPT(all, false) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct response_t - { - std::vector entries; + struct response_t + { + uint32_t offset; + std::string encrypted_key_images_blob; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(entries) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(offset) + KV_SERIALIZE(encrypted_key_images_blob) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_DELETE_ADDRESS_BOOK_ENTRY - { - struct request_t + struct COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES { - uint64_t index; + struct request_t + { + uint32_t offset; + std::string encrypted_key_images_blob; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(index) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_OPT(offset, (uint32_t)0) + KV_SERIALIZE(encrypted_key_images_blob) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct response_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + struct response_t + { + uint64_t height; + uint64_t spent; + uint64_t unspent; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(height) + KV_SERIALIZE(spent) + KV_SERIALIZE(unspent) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_RESCAN_SPENT - { - struct request_t + struct uri_spec { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + std::string address; + std::string payment_id; + uint64_t amount; + std::string tx_description; + std::string recipient_name; - struct response_t - { BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE(payment_id) + KV_SERIALIZE(amount) + KV_SERIALIZE(tx_description) + KV_SERIALIZE(recipient_name) + END_KV_SERIALIZE_MAP() }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_REFRESH - { - struct request_t + struct COMMAND_RPC_MAKE_URI { - uint64_t start_height; + struct request_t: public uri_spec + { + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_OPT(start_height, (uint64_t) 0) - END_KV_SERIALIZE_MAP() + struct response_t + { + std::string uri; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(uri) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_PARSE_URI { - uint64_t blocks_fetched; - bool received_money; + struct request_t + { + std::string uri; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(blocks_fetched) - KV_SERIALIZE(received_money) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(uri) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct COMMAND_RPC_AUTO_REFRESH - { - struct request_t - { - bool enable; - uint32_t period; // seconds + struct response_t + { + uri_spec uri; + std::vector unknown_parameters; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_OPT(enable, true) - KV_SERIALIZE_OPT(period, (uint32_t)0) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(uri) + KV_SERIALIZE(unknown_parameters) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_ADD_ADDRESS_BOOK_ENTRY { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + struct request_t + { + std::string address; + std::string description; - struct COMMAND_RPC_SCAN_TX - { - struct request_t - { - std::list txids; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE(description) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(txids) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + struct response_t + { + uint64_t index; - struct response_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(index) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_START_MINING - { - struct request_t + struct COMMAND_RPC_EDIT_ADDRESS_BOOK_ENTRY { - uint64_t threads_count; - bool do_background_mining; - bool ignore_battery; + struct request_t + { + uint64_t index; + bool set_address; + std::string address; + bool set_description; + std::string description; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(index) + KV_SERIALIZE(set_address) + KV_SERIALIZE(address) + KV_SERIALIZE(set_description) + KV_SERIALIZE(description) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(threads_count) - KV_SERIALIZE(do_background_mining) - KV_SERIALIZE(ignore_battery) - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + struct request_t + { + std::list entries; - struct COMMAND_RPC_STOP_MINING - { - struct request_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(entries) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct response_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + struct entry + { + uint64_t index; + std::string address; + std::string description; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(index) + KV_SERIALIZE(address) + KV_SERIALIZE(description) + END_KV_SERIALIZE_MAP() + }; - struct COMMAND_RPC_GET_LANGUAGES - { - struct request_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + struct response_t + { + std::vector entries; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(entries) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_DELETE_ADDRESS_BOOK_ENTRY { - std::vector languages; - std::vector languages_local; + struct request_t + { + uint64_t index; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(languages) - KV_SERIALIZE(languages_local) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(index) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; + + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_CREATE_WALLET - { - struct request_t + struct COMMAND_RPC_RESCAN_SPENT { - std::string filename; - std::string password; - std::string language; + struct request_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(filename) - KV_SERIALIZE(password) - KV_SERIALIZE(language) - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_REFRESH { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + struct request_t + { + uint64_t start_height; - struct COMMAND_RPC_OPEN_WALLET - { - struct request_t - { - std::string filename; - std::string password; - bool autosave_current; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_OPT(start_height, (uint64_t) 0) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(filename) - KV_SERIALIZE(password) - KV_SERIALIZE_OPT(autosave_current, true) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + struct response_t + { + uint64_t blocks_fetched; + bool received_money; - struct response_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(blocks_fetched) + KV_SERIALIZE(received_money) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_CLOSE_WALLET - { - struct request_t + struct COMMAND_RPC_AUTO_REFRESH { - bool autosave_current; + struct request_t + { + bool enable; + uint32_t period; // seconds - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_OPT(autosave_current, true) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_OPT(enable, true) + KV_SERIALIZE_OPT(period, (uint32_t)0) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct response_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_CHANGE_WALLET_PASSWORD - { - struct request_t + struct COMMAND_RPC_SCAN_TX { - std::string old_password; - std::string new_password; + struct request_t + { + std::list txids; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(old_password) - KV_SERIALIZE(new_password) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(txids) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct response_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_GENERATE_FROM_KEYS - { - struct request + struct COMMAND_RPC_START_MINING { - uint64_t restore_height; - std::string filename; - std::string address; - std::string spendkey; - std::string viewkey; - std::string password; - bool autosave_current; - std::string language; + struct request_t + { + uint64_t threads_count; + bool do_background_mining; + bool ignore_battery; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(threads_count) + KV_SERIALIZE(do_background_mining) + KV_SERIALIZE(ignore_battery) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_OPT(restore_height, (uint64_t)0) - KV_SERIALIZE(filename) - KV_SERIALIZE(address) - KV_SERIALIZE(spendkey) - KV_SERIALIZE(viewkey) - KV_SERIALIZE(password) - KV_SERIALIZE_OPT(autosave_current, true) - KV_SERIALIZE(language) - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - struct response + struct COMMAND_RPC_STOP_MINING { - std::string address; - std::string info; + struct request_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(info) - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - }; - struct COMMAND_RPC_RESTORE_DETERMINISTIC_WALLET - { - struct request_t + struct COMMAND_RPC_GET_LANGUAGES { - uint64_t restore_height; - std::string filename; - std::string seed; - std::string seed_offset; - std::string password; - std::string language; - bool autosave_current; - bool enable_multisig_experimental; + struct request_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_OPT(restore_height, (uint64_t)0) - KV_SERIALIZE(filename) - KV_SERIALIZE(seed) - KV_SERIALIZE(seed_offset) - KV_SERIALIZE(password) - KV_SERIALIZE(language) - KV_SERIALIZE_OPT(autosave_current, true) - KV_SERIALIZE_OPT(enable_multisig_experimental, false) - END_KV_SERIALIZE_MAP() + struct response_t + { + std::vector languages; + std::vector languages_local; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(languages) + KV_SERIALIZE(languages_local) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_CREATE_WALLET { - std::string address; - std::string seed; - std::string info; - bool was_deprecated; + struct request_t + { + std::string filename; + std::string password; + std::string language; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(filename) + KV_SERIALIZE(password) + KV_SERIALIZE(language) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(seed) - KV_SERIALIZE(info) - KV_SERIALIZE(was_deprecated) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; - - struct COMMAND_RPC_IS_MULTISIG - { - struct request_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_OPEN_WALLET { - bool multisig; - bool kex_is_done; - bool ready; - uint32_t threshold; - uint32_t total; + struct request_t + { + std::string filename; + std::string password; + bool autosave_current; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(filename) + KV_SERIALIZE(password) + KV_SERIALIZE_OPT(autosave_current, true) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(multisig) - KV_SERIALIZE(kex_is_done) - KV_SERIALIZE(ready) - KV_SERIALIZE(threshold) - KV_SERIALIZE(total) - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_PREPARE_MULTISIG - { - struct request_t + struct COMMAND_RPC_CLOSE_WALLET { - bool enable_multisig_experimental; + struct request_t + { + bool autosave_current; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE_OPT(enable_multisig_experimental, false) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_OPT(autosave_current, true) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; + + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_CHANGE_WALLET_PASSWORD { - std::string multisig_info; + struct request_t + { + std::string old_password; + std::string new_password; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(multisig_info) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(old_password) + KV_SERIALIZE(new_password) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; + + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_MAKE_MULTISIG - { - struct request_t + struct COMMAND_RPC_GENERATE_FROM_KEYS { - std::vector multisig_info; - uint32_t threshold; - std::string password; + struct request + { + uint64_t restore_height; + std::string filename; + std::string address; + std::string spendkey; + std::string viewkey; + std::string password; + bool autosave_current; + std::string language; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_OPT(restore_height, (uint64_t)0) + KV_SERIALIZE(filename) + KV_SERIALIZE(address) + KV_SERIALIZE(spendkey) + KV_SERIALIZE(viewkey) + KV_SERIALIZE(password) + KV_SERIALIZE_OPT(autosave_current, true) + KV_SERIALIZE(language) + END_KV_SERIALIZE_MAP() + }; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(multisig_info) - KV_SERIALIZE(threshold) - KV_SERIALIZE(password) - END_KV_SERIALIZE_MAP() + struct response + { + std::string address; + std::string info; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE(info) + END_KV_SERIALIZE_MAP() + }; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_RESTORE_DETERMINISTIC_WALLET { - std::string address; - std::string multisig_info; + struct request_t + { + uint64_t restore_height; + std::string filename; + std::string seed; + std::string seed_offset; + std::string password; + std::string language; + bool autosave_current; + bool enable_multisig_experimental; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_OPT(restore_height, (uint64_t)0) + KV_SERIALIZE(filename) + KV_SERIALIZE(seed) + KV_SERIALIZE(seed_offset) + KV_SERIALIZE(password) + KV_SERIALIZE(language) + KV_SERIALIZE_OPT(autosave_current, true) + KV_SERIALIZE_OPT(enable_multisig_experimental, false) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(multisig_info) - END_KV_SERIALIZE_MAP() + struct response_t + { + std::string address; + std::string seed; + std::string info; + bool was_deprecated; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE(seed) + KV_SERIALIZE(info) + KV_SERIALIZE(was_deprecated) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_EXPORT_MULTISIG - { - struct request_t + struct COMMAND_RPC_IS_MULTISIG { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + struct request_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; + + struct response_t + { + bool multisig; + bool kex_is_done; + bool ready; + uint32_t threshold; + uint32_t total; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(multisig) + KV_SERIALIZE(kex_is_done) + KV_SERIALIZE(ready) + KV_SERIALIZE(threshold) + KV_SERIALIZE(total) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_PREPARE_MULTISIG { - std::string info; + struct request_t + { + bool enable_multisig_experimental; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(info) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_OPT(enable_multisig_experimental, false) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct COMMAND_RPC_IMPORT_MULTISIG - { - struct request_t - { - std::vector info; + struct response_t + { + std::string multisig_info; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(info) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(multisig_info) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_MAKE_MULTISIG { - uint64_t n_outputs; + struct request_t + { + std::vector multisig_info; + uint32_t threshold; + std::string password; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(multisig_info) + KV_SERIALIZE(threshold) + KV_SERIALIZE(password) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(n_outputs) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + struct response_t + { + std::string address; + std::string multisig_info; - struct COMMAND_RPC_FINALIZE_MULTISIG - { - // NOP - struct request_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE(multisig_info) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_EXPORT_MULTISIG { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + struct request_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct COMMAND_RPC_EXCHANGE_MULTISIG_KEYS - { - struct request_t - { - std::string password; - std::vector multisig_info; - bool force_update_use_with_caution; + struct response_t + { + std::string info; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(password) - KV_SERIALIZE(multisig_info) - KV_SERIALIZE_OPT(force_update_use_with_caution, false) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(info) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_IMPORT_MULTISIG { - std::string address; - std::string multisig_info; + struct request_t + { + std::vector info; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(multisig_info) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(info) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct COMMAND_RPC_SIGN_MULTISIG - { - struct request_t - { - std::string tx_data_hex; + struct response_t + { + uint64_t n_outputs; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_data_hex) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(n_outputs) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_FINALIZE_MULTISIG { - std::string tx_data_hex; - std::list tx_hash_list; + // NOP + struct request_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_data_hex) - KV_SERIALIZE(tx_hash_list) - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_SUBMIT_MULTISIG - { - struct request_t + struct COMMAND_RPC_EXCHANGE_MULTISIG_KEYS { - std::string tx_data_hex; + struct request_t + { + std::string password; + std::vector multisig_info; + bool force_update_use_with_caution; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(password) + KV_SERIALIZE(multisig_info) + KV_SERIALIZE_OPT(force_update_use_with_caution, false) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_data_hex) - END_KV_SERIALIZE_MAP() + struct response_t + { + std::string address; + std::string multisig_info; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE(multisig_info) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_SIGN_MULTISIG { - std::list tx_hash_list; + struct request_t + { + std::string tx_data_hex; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_hash_list) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(tx_data_hex) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct COMMAND_RPC_GET_VERSION - { - struct request_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + struct response_t + { + std::string tx_data_hex; + std::list tx_hash_list; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(tx_data_hex) + KV_SERIALIZE(tx_hash_list) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_SUBMIT_MULTISIG { - uint32_t version; - bool release; + struct request_t + { + std::string tx_data_hex; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(version) - KV_SERIALIZE(release) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(tx_data_hex) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct COMMAND_RPC_VALIDATE_ADDRESS - { - struct request_t - { - std::string address; - bool any_net_type; - bool allow_openalias; + struct response_t + { + std::list tx_hash_list; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE_OPT(any_net_type, false) - KV_SERIALIZE_OPT(allow_openalias, false) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(tx_hash_list) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_GET_VERSION { - bool valid; - bool integrated; - bool subaddress; - std::string nettype; - std::string openalias_address; + struct request_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(valid) - KV_SERIALIZE(integrated) - KV_SERIALIZE(subaddress) - KV_SERIALIZE(nettype) - KV_SERIALIZE(openalias_address) - END_KV_SERIALIZE_MAP() + struct response_t + { + uint32_t version; + bool release; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(version) + KV_SERIALIZE(release) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_SET_DAEMON - { - struct request_t + struct COMMAND_RPC_VALIDATE_ADDRESS { - std::string address; - std::string username; - std::string password; - bool trusted; - std::string ssl_support; // disabled, enabled, autodetect - std::string ssl_private_key_path; - std::string ssl_certificate_path; - std::string ssl_ca_file; - std::vector ssl_allowed_fingerprints; - bool ssl_allow_any_cert; - std::string proxy; + struct request_t + { + std::string address; + bool any_net_type; + bool allow_openalias; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE_OPT(any_net_type, false) + KV_SERIALIZE_OPT(allow_openalias, false) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(address) - KV_SERIALIZE(username) - KV_SERIALIZE(password) - KV_SERIALIZE_OPT(trusted, false) - KV_SERIALIZE_OPT(ssl_support, (std::string)"autodetect") - KV_SERIALIZE(ssl_private_key_path) - KV_SERIALIZE(ssl_certificate_path) - KV_SERIALIZE(ssl_ca_file) - KV_SERIALIZE(ssl_allowed_fingerprints) - KV_SERIALIZE_OPT(ssl_allow_any_cert, false) - KV_SERIALIZE_OPT(proxy, (std::string)"") - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init request; - - struct response_t - { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() + struct response_t + { + bool valid; + bool integrated; + bool subaddress; + std::string nettype; + std::string openalias_address; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(valid) + KV_SERIALIZE(integrated) + KV_SERIALIZE(subaddress) + KV_SERIALIZE(nettype) + KV_SERIALIZE(openalias_address) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; - struct COMMAND_RPC_SET_LOG_LEVEL - { - struct request_t + struct COMMAND_RPC_SET_DAEMON { - int8_t level; + struct request_t + { + std::string address; + std::string username; + std::string password; + bool trusted; + std::string ssl_support; // disabled, enabled, autodetect + std::string ssl_private_key_path; + std::string ssl_certificate_path; + std::string ssl_ca_file; + std::vector ssl_allowed_fingerprints; + bool ssl_allow_any_cert; + std::string proxy; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE(username) + KV_SERIALIZE(password) + KV_SERIALIZE_OPT(trusted, false) + KV_SERIALIZE_OPT(ssl_support, (std::string)"autodetect") + KV_SERIALIZE(ssl_private_key_path) + KV_SERIALIZE(ssl_certificate_path) + KV_SERIALIZE(ssl_ca_file) + KV_SERIALIZE(ssl_allowed_fingerprints) + KV_SERIALIZE_OPT(ssl_allow_any_cert, false) + KV_SERIALIZE_OPT(proxy, (std::string)"") + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(level) - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_SET_LOG_LEVEL { - BEGIN_KV_SERIALIZE_MAP() - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + struct request_t + { + int8_t level; - struct COMMAND_RPC_SET_LOG_CATEGORIES - { - struct request_t - { - std::string categories; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(level) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(categories) - END_KV_SERIALIZE_MAP() + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_SET_LOG_CATEGORIES { - std::string categories; + struct request_t + { + std::string categories; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(categories) - END_KV_SERIALIZE_MAP() - }; - typedef epee::misc_utils::struct_init response; - }; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(categories) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - struct COMMAND_RPC_ESTIMATE_TX_SIZE_AND_WEIGHT - { - struct request_t - { - uint32_t n_inputs; - uint32_t n_outputs; - uint32_t ring_size; - bool rct; + struct response_t + { + std::string categories; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(n_inputs) - KV_SERIALIZE(n_outputs) - KV_SERIALIZE_OPT(ring_size, 0u) - KV_SERIALIZE_OPT(rct, true) - END_KV_SERIALIZE_MAP() + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(categories) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init request; - struct response_t + struct COMMAND_RPC_ESTIMATE_TX_SIZE_AND_WEIGHT { - uint64_t size; - uint64_t weight; + struct request_t + { + uint32_t n_inputs; + uint32_t n_outputs; + uint32_t ring_size; + bool rct; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(n_inputs) + KV_SERIALIZE(n_outputs) + KV_SERIALIZE_OPT(ring_size, 0u) + KV_SERIALIZE_OPT(rct, true) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(size) - KV_SERIALIZE(weight) - END_KV_SERIALIZE_MAP() + struct response_t + { + uint64_t size; + uint64_t weight; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(size) + KV_SERIALIZE(weight) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; }; - typedef epee::misc_utils::struct_init response; - }; -} + } } From 54dab2e1219412ce631f5d7f46bcad94b7a180cd Mon Sep 17 00:00:00 2001 From: who asks? Date: Thu, 18 Jul 2024 15:36:57 -0600 Subject: [PATCH 02/18] add magic --- src/wallet/wallet_rpc_server.cpp | 190 +++++++++++++++++++------------ 1 file changed, 120 insertions(+), 70 deletions(-) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 7de53371c6..3de051376b 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -56,6 +56,8 @@ using namespace epee; #include "rpc/core_rpc_server_commands_defs.h" #include "daemonizer/daemonizer.h" +#define KEY_IMAGE_EXPORT_FILE_MAGIC "Monero key image export\003" + #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "wallet.rpc" @@ -2951,102 +2953,150 @@ namespace tools return true; } - //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_export_encrypted_key_images(const wallet_rpc::COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx) + /bool wallet_rpc_server::on_export_encrypted_key_images(const wallet_rpc::COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx) +{ + if (!m_wallet) return not_open(er); + try { - if (!m_wallet) return not_open(er); - try - { - std::pair>> ski = m_wallet->export_key_images(req.all); - res.offset = ski.first; + std::pair>> ski = m_wallet->export_key_images(req.all); + res.offset = ski.first; - // Serialize the key images and signatures into a single blob - std::string data; - data.reserve(ski.second.size() * (sizeof(crypto::key_image) + sizeof(crypto::signature))); - for (const auto &item : ski.second) - { - data += std::string((const char *)&item.first, sizeof(crypto::key_image)); - data += std::string((const char *)&item.second, sizeof(crypto::signature)); - } + std::string data; + const cryptonote::account_public_address &keys = m_wallet->get_account().get_keys().m_account_address; + + data.reserve(4 + sizeof(crypto::public_key) * 2 + ski.second.size() * (sizeof(crypto::key_image) + sizeof(crypto::signature))); + + data.resize(4); + data[0] = res.offset & 0xff; + data[1] = (res.offset >> 8) & 0xff; + data[2] = (res.offset >> 16) & 0xff; + data[3] = (res.offset >> 24) & 0xff; - // Encrypt the serialized data - std::string ciphertext = m_wallet->encrypt_with_view_secret_key(data); + data += std::string((const char *)&keys.m_spend_public_key, sizeof(crypto::public_key)); + data += std::string((const char *)&keys.m_view_public_key, sizeof(crypto::public_key)); - // Encode the encrypted data as hex - res.encrypted_key_images_blob = epee::string_tools::buff_to_hex_nodelimer(ciphertext); - } - catch (const std::exception& e) + for (const auto &item : ski.second) { - handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR); - return false; + data += std::string((const char *)&item.first, sizeof(crypto::key_image)); + data += std::string((const char *)&item.second, sizeof(crypto::signature)); } - return true; + std::string ciphertext = m_wallet->encrypt_with_view_secret_key(data); + + std::string magic(KEY_IMAGE_EXPORT_FILE_MAGIC, strlen(KEY_IMAGE_EXPORT_FILE_MAGIC)); + res.encrypted_key_images_blob = epee::string_tools::buff_to_hex_nodelimer(magic + ciphertext); } - //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::on_import_encrypted_key_images(const wallet_rpc::COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx) + catch (const std::exception& e) { - if (!m_wallet) return not_open(er); - if (m_restricted) + handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR); + return false; + } + + return true; +}/------------------------------------------------------------------------------------------------------------------------------ + /bool wallet_rpc_server::on_import_encrypted_key_images(const wallet_rpc::COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx) +{ + if (!m_wallet) return not_open(er); + if (m_restricted) + { + er.code = WALLET_RPC_ERROR_CODE_DENIED; + er.message = "Command unavailable in restricted mode."; + return false; + } + if (!m_wallet->is_trusted_daemon()) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = "This command requires a trusted daemon."; + return false; + } + try + { + std::string data; + if (!epee::string_tools::parse_hexstr_to_binbuff(req.encrypted_key_images_blob, data)) { - er.code = WALLET_RPC_ERROR_CODE_DENIED; - er.message = "Command unavailable in restricted mode."; + er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE; + er.message = "Failed to parse encrypted key images blob"; return false; } - if (!m_wallet->is_trusted_daemon()) + + const size_t magiclen = strlen(KEY_IMAGE_EXPORT_FILE_MAGIC); + if (data.size() < magiclen || memcmp(data.data(), KEY_IMAGE_EXPORT_FILE_MAGIC, magiclen)) { - er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; - er.message = "This command requires a trusted daemon."; + er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE; + er.message = "Bad key image export file magic in blob"; return false; } + try { - // Decode the hex-encoded encrypted blob - std::string ciphertext; - if (!epee::string_tools::parse_hexstr_to_binbuff(req.encrypted_key_images_blob, ciphertext)) - { - er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE; - er.message = "Failed to parse encrypted key images blob"; - return false; - } + data = m_wallet->decrypt_with_view_secret_key(std::string(data, magiclen)); + } + catch (const std::exception& e) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE; + er.message = "Failed to decrypt blob"; + return false; + } - // Decrypt the ciphertext - std::string decrypted_data = m_wallet->decrypt_with_view_secret_key(ciphertext); + const size_t headerlen = 4 + 2 * sizeof(crypto::public_key); + if (data.size() < headerlen) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE; + er.message = "Bad data size from file"; + return false; + } - // Deserialize the decrypted data into key images and signatures - std::vector> ski; - const size_t record_size = sizeof(crypto::key_image) + sizeof(crypto::signature); - if (decrypted_data.size() % record_size != 0) - { - er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE; - er.message = "Decrypted data size is not a multiple of the record size"; - return false; - } - size_t num_records = decrypted_data.size() / record_size; - ski.reserve(num_records); - for (size_t i = 0; i < num_records; ++i) - { - crypto::key_image ki; - crypto::signature sig; - memcpy(&ki, &decrypted_data[i * record_size], sizeof(crypto::key_image)); - memcpy(&sig, &decrypted_data[i * record_size + sizeof(crypto::key_image)], sizeof(crypto::signature)); - ski.emplace_back(ki, sig); - } + uint32_t offset = (uint8_t)data[0] | (((uint8_t)data[1]) << 8) | (((uint8_t)data[2]) << 16) | (((uint8_t)data[3]) << 24); + if (offset > m_wallet->get_num_transfer_details()) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE; + er.message = "Offset larger than known outputs"; + return false; + } - uint64_t spent = 0, unspent = 0; - uint64_t height = m_wallet->import_key_images(ski, req.offset, spent, unspent); - res.height = height; - res.spent = spent; - res.unspent = unspent; + const crypto::public_key &public_spend_key = *(const crypto::public_key*)&data[4]; + const crypto::public_key &public_view_key = *(const crypto::public_key*)&data[4 + sizeof(crypto::public_key)]; + const cryptonote::account_public_address &keys = m_wallet->get_account().get_keys().m_account_address; + if (public_spend_key != keys.m_spend_public_key || public_view_key != keys.m_view_public_key) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE; + er.message = "Key images from different account"; + return false; } - catch (const std::exception& e) + + const size_t record_size = sizeof(crypto::key_image) + sizeof(crypto::signature); + if ((data.size() - headerlen) % record_size) { - handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR); + er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE; + er.message = "Bad data size from file"; return false; } + size_t nki = (data.size() - headerlen) / record_size; - return true; + std::vector> ski; + ski.reserve(nki); + for (size_t n = 0; n < nki; ++n) + { + crypto::key_image key_image = *reinterpret_cast(&data[headerlen + n * record_size]); + crypto::signature signature = *reinterpret_cast(&data[headerlen + n * record_size + sizeof(crypto::key_image)]); + + ski.push_back(std::make_pair(key_image, signature)); + } + + uint64_t spent = 0, unspent = 0; + uint64_t height = m_wallet->import_key_images(ski, offset, spent, unspent); + res.height = height; + res.spent = spent; + res.unspent = unspent; } + catch (const std::exception& e) + { + handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR); + return false; + } + + return true; +}/------------------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_make_uri(const wallet_rpc::COMMAND_RPC_MAKE_URI::request& req, wallet_rpc::COMMAND_RPC_MAKE_URI::response& res, epee::json_rpc::error& er, const connection_context *ctx) { From 86ba8e2776713fe1a1dd9e1e5ff1facfb1e8d5c3 Mon Sep 17 00:00:00 2001 From: who asks? Date: Thu, 18 Jul 2024 15:48:20 -0600 Subject: [PATCH 03/18] fix / --- src/wallet/wallet_rpc_server.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 3de051376b..1db55d85f2 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -2993,8 +2993,9 @@ namespace tools } return true; -}/------------------------------------------------------------------------------------------------------------------------------ - /bool wallet_rpc_server::on_import_encrypted_key_images(const wallet_rpc::COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx) +} +//------------------------------------------------------------------------------------------------------------------------------ +bool wallet_rpc_server::on_import_encrypted_key_images(const wallet_rpc::COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_IMPORT_ENCRYPTED_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); if (m_restricted) @@ -3096,7 +3097,7 @@ namespace tools } return true; -}/------------------------------------------------------------------------------------------------------------------------------ +} //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_make_uri(const wallet_rpc::COMMAND_RPC_MAKE_URI::request& req, wallet_rpc::COMMAND_RPC_MAKE_URI::response& res, epee::json_rpc::error& er, const connection_context *ctx) { From 9b6499ccaf914efab073d9080d114d99f91780a2 Mon Sep 17 00:00:00 2001 From: who asks? Date: Thu, 18 Jul 2024 15:50:35 -0600 Subject: [PATCH 04/18] fix / --- src/wallet/wallet_rpc_server.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 1db55d85f2..7976cb7afa 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -2953,7 +2953,8 @@ namespace tools return true; } - /bool wallet_rpc_server::on_export_encrypted_key_images(const wallet_rpc::COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx) + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_export_encrypted_key_images(const wallet_rpc::COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES::request& req, wallet_rpc::COMMAND_RPC_EXPORT_ENCRYPTED_KEY_IMAGES::response& res, epee::json_rpc::error& er, const connection_context *ctx) { if (!m_wallet) return not_open(er); try From d2e3cff9f5ea82dc2998afae05e94c28282c4395 Mon Sep 17 00:00:00 2001 From: who asks? Date: Thu, 18 Jul 2024 17:28:04 -0600 Subject: [PATCH 05/18] change to hex_to_pod --- src/wallet/wallet_rpc_server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 7976cb7afa..7251beb4a5 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -3014,7 +3014,7 @@ bool wallet_rpc_server::on_import_encrypted_key_images(const wallet_rpc::COMMAND try { std::string data; - if (!epee::string_tools::parse_hexstr_to_binbuff(req.encrypted_key_images_blob, data)) + if (!epee::string_tools::hex_to_pod(req.encrypted_key_images_blob, data)) { er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE; er.message = "Failed to parse encrypted key images blob"; From 5722f42423644122602e7166f61585783f1d3ad6 Mon Sep 17 00:00:00 2001 From: who asks? Date: Thu, 18 Jul 2024 17:51:10 -0600 Subject: [PATCH 06/18] change back and add debug code --- src/wallet/wallet_rpc_server.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 7251beb4a5..d8e3c778e5 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -3014,14 +3014,24 @@ bool wallet_rpc_server::on_import_encrypted_key_images(const wallet_rpc::COMMAND try { std::string data; - if (!epee::string_tools::hex_to_pod(req.encrypted_key_images_blob, data)) + if (!epee::string_tools::parse_hexstr_to_binbuff(req.encrypted_key_images_blob, data)) { er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE; er.message = "Failed to parse encrypted key images blob"; return false; } + + // Debug: Print the first few bytes of the decoded data + std::cout << "First 32 bytes of decoded data: "; + for (size_t i = 0; i < std::min(data.size(), size_t(32)); ++i) { + std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)(unsigned char)data[i]; + } + std::cout << std::endl; + const size_t magiclen = strlen(KEY_IMAGE_EXPORT_FILE_MAGIC); + std::cout << "Magic length: " << magiclen << std::endl; + std::cout << "Expected magic: "; if (data.size() < magiclen || memcmp(data.data(), KEY_IMAGE_EXPORT_FILE_MAGIC, magiclen)) { er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE; From 67e634e734980cd02590bde4295729fe6c892274 Mon Sep 17 00:00:00 2001 From: who asks? Date: Thu, 18 Jul 2024 18:35:15 -0600 Subject: [PATCH 07/18] more debug code --- src/wallet/wallet_rpc_server.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index d8e3c778e5..f04a145476 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -3022,6 +3022,8 @@ bool wallet_rpc_server::on_import_encrypted_key_images(const wallet_rpc::COMMAND } + std::out << "encrypted_key_images_blob: " << req.encrypted_key_images_blob; + std::out << "data: " << data; // Debug: Print the first few bytes of the decoded data std::cout << "First 32 bytes of decoded data: "; for (size_t i = 0; i < std::min(data.size(), size_t(32)); ++i) { From 26913952a60a510ba3bfdc8f83e555687ad62a26 Mon Sep 17 00:00:00 2001 From: who asks? Date: Thu, 18 Jul 2024 18:38:54 -0600 Subject: [PATCH 08/18] more debug code --- src/wallet/wallet_rpc_server.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index f04a145476..fd2b823834 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -3022,8 +3022,8 @@ bool wallet_rpc_server::on_import_encrypted_key_images(const wallet_rpc::COMMAND } - std::out << "encrypted_key_images_blob: " << req.encrypted_key_images_blob; - std::out << "data: " << data; + std::cout << "encrypted_key_images_blob: " << req.encrypted_key_images_blob; + std::cout << "data: " << data; // Debug: Print the first few bytes of the decoded data std::cout << "First 32 bytes of decoded data: "; for (size_t i = 0; i < std::min(data.size(), size_t(32)); ++i) { From c5822d77ce232906da5c89cb5a97830e17d70bc8 Mon Sep 17 00:00:00 2001 From: who asks? Date: Thu, 18 Jul 2024 19:02:08 -0600 Subject: [PATCH 09/18] more debug code --- src/wallet/wallet_rpc_server.cpp | 4 ++-- src/wallet/wallet_rpc_server_commands_defs.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index fd2b823834..5c553aa71c 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -3022,8 +3022,8 @@ bool wallet_rpc_server::on_import_encrypted_key_images(const wallet_rpc::COMMAND } - std::cout << "encrypted_key_images_blob: " << req.encrypted_key_images_blob; - std::cout << "data: " << data; + std::cout << "encrypted_key_images_blob: " << req.encrypted_key_images_blob << std::endl; + std::cout << "data: " << data << std::endl; // Debug: Print the first few bytes of the decoded data std::cout << "First 32 bytes of decoded data: "; for (size_t i = 0; i < std::min(data.size(), size_t(32)); ++i) { diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index 42b43a26be..85866307f2 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -1858,7 +1858,7 @@ namespace tools BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE_OPT(offset, (uint32_t)0) - KV_SERIALIZE(encrypted_key_images_blob) + KV_SERIALIZE_OPT(encrypted_key_images_blob, "WTF") END_KV_SERIALIZE_MAP() }; typedef epee::misc_utils::struct_init request; From 75c14c8b4589f9d919624b14a43c34d0c604ed85 Mon Sep 17 00:00:00 2001 From: who asks? Date: Thu, 18 Jul 2024 21:18:56 -0600 Subject: [PATCH 10/18] final modifications to adding endpoints import_encrypted_key_images and export_encrypted_key_images --- src/wallet/wallet_rpc_server.cpp | 12 ------------ src/wallet/wallet_rpc_server_commands_defs.h | 2 +- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 5c553aa71c..7976cb7afa 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -3021,19 +3021,7 @@ bool wallet_rpc_server::on_import_encrypted_key_images(const wallet_rpc::COMMAND return false; } - - std::cout << "encrypted_key_images_blob: " << req.encrypted_key_images_blob << std::endl; - std::cout << "data: " << data << std::endl; - // Debug: Print the first few bytes of the decoded data - std::cout << "First 32 bytes of decoded data: "; - for (size_t i = 0; i < std::min(data.size(), size_t(32)); ++i) { - std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)(unsigned char)data[i]; - } - std::cout << std::endl; - const size_t magiclen = strlen(KEY_IMAGE_EXPORT_FILE_MAGIC); - std::cout << "Magic length: " << magiclen << std::endl; - std::cout << "Expected magic: "; if (data.size() < magiclen || memcmp(data.data(), KEY_IMAGE_EXPORT_FILE_MAGIC, magiclen)) { er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE; diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index 85866307f2..42b43a26be 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -1858,7 +1858,7 @@ namespace tools BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE_OPT(offset, (uint32_t)0) - KV_SERIALIZE_OPT(encrypted_key_images_blob, "WTF") + KV_SERIALIZE(encrypted_key_images_blob) END_KV_SERIALIZE_MAP() }; typedef epee::misc_utils::struct_init request; From 5e7c23446205145da9ad5a78585d4a60f1251788 Mon Sep 17 00:00:00 2001 From: who asks? Date: Tue, 20 Aug 2024 22:16:05 -0600 Subject: [PATCH 11/18] .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 9f62575e5a..4387e1c9dc 100644 --- a/.gitignore +++ b/.gitignore @@ -120,3 +120,5 @@ nbproject __pycache__/ *.pyc *.log +.gitignore +/dist/ From 25b09501e3c831d855bb01f1038a95e7d0ca48b2 Mon Sep 17 00:00:00 2001 From: who asks? Date: Tue, 20 Aug 2024 23:32:13 -0600 Subject: [PATCH 12/18] remove whitespace --- src/wallet/wallet_rpc_server.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 5dcc8e47d5..e95ff1b059 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -3117,9 +3117,9 @@ namespace tools std::string data; const cryptonote::account_public_address &keys = m_wallet->get_account().get_keys().m_account_address; - + data.reserve(4 + sizeof(crypto::public_key) * 2 + ski.second.size() * (sizeof(crypto::key_image) + sizeof(crypto::signature))); - + data.resize(4); data[0] = res.offset & 0xff; data[1] = (res.offset >> 8) & 0xff; @@ -3237,7 +3237,7 @@ bool wallet_rpc_server::on_import_encrypted_key_images(const wallet_rpc::COMMAND ski.push_back(std::make_pair(key_image, signature)); } - + uint64_t spent = 0, unspent = 0; uint64_t height = m_wallet->import_key_images(ski, offset, spent, unspent); res.height = height; From 84f402b47a6edfb72fae52b5fa8858294841660e Mon Sep 17 00:00:00 2001 From: DiosDelRayo Date: Fri, 27 Sep 2024 01:29:05 -0600 Subject: [PATCH 13/18] Modifications to enable Offline Signing in monero-gui and possible other projects via UR or other mediums of exchange. Added the following signatures in the mention files: wallet/wallet2.h + std::string export_key_images_string(bool all = false) const; + uint64_t import_key_images_string(const std::string &data, uint64_t &spent, uint64_t &unspent); M bool wallet2::export_key_images(const std::string &filename, bool all) const wallet/api/pending_transaction.h + std::string commit_string() override; wallet/api/unsigned_transaction.h + std::string signAsString() override; wallet/api/wallet.h: + bool submitTransactionFromString(const std::string &fileName) override; + virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) override; + std::string exportKeyImagesAsString(bool all = false) override; + bool importKeyImagesFromString(const std::string &data) override; + std::string exportOutputsAsString(bool all = false) override; + bool importOutputsFromString(const std::string &data) override; wallet/api/wallet2_api.h + virtual std::string commit_string() = 0; + virtual std::string signAsString() = 0; + virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) = 0; + virtual bool submitTransactionFromString(const std::string &fileName) = 0; + virtual bool importKeyImagesFromString(const std::string &data) = 0; + virtual std::string exportOutputsAsString(bool all = false) = 0; + virtual bool importOutputsFromString(const std::string &data) = 0; + uint64_t import_key_images_string(const std::string &data, uint64_t &spent, uint64_t &unspent); And the implementations in: wallet/wallet2.cpp wallet/api/pending_transaction.cpp wallet/api/unsigned_transaction.cpp wallet/api/wallet.cpp The method `bool wallet2::export_key_images(const std::string &filename, bool all) const` is modified to use `std::string export_key_images_string(bool all = false) const;` to get the string to write to the file. IMO that would be the perfect way to do it everywhere, but in the other methods it would require more modifications, so the other I duplicated and removed the part writing to the file and return instead a std::string, or use a std::string for the actual payload instead of a file path. One thing to mention is I remove in one or two log messages the filename, and the other is in `export_key_images` probably(almost sure) is now the performance messed up. This modifications was done to get all the necessary data for offline signing via UR or any other channel not using files as medium. IMO it had been better to not implement the filehandling direct in wallet2 or in the wallet api but rather in monero-wallet-cli and monero-gui itself, but it is like it is. --- src/wallet/api/pending_transaction.cpp | 38 +++++++ src/wallet/api/pending_transaction.h | 1 + src/wallet/api/unsigned_transaction.cpp | 22 ++++ src/wallet/api/unsigned_transaction.h | 1 + src/wallet/api/wallet.cpp | 137 ++++++++++++++++++++++++ src/wallet/api/wallet.h | 6 ++ src/wallet/api/wallet2_api.h | 49 ++++++++- src/wallet/wallet2.cpp | 28 +++-- src/wallet/wallet2.h | 2 + 9 files changed, 274 insertions(+), 10 deletions(-) diff --git a/src/wallet/api/pending_transaction.cpp b/src/wallet/api/pending_transaction.cpp index 9783da5bcd..ba84a37333 100644 --- a/src/wallet/api/pending_transaction.cpp +++ b/src/wallet/api/pending_transaction.cpp @@ -162,6 +162,44 @@ bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite) return m_status == Status_Ok; } +std::string PendingTransactionImpl::commit_string() +{ + + std::string tx; + LOG_PRINT_L3("m_pending_tx size: " << m_pending_tx.size()); + + try { + tx = m_wallet.m_wallet->dump_tx_to_str(m_pending_tx); + m_status = Status_Ok; + } catch (const tools::error::daemon_busy&) { + // TODO: make it translatable with "tr"? + m_errorString = tr("daemon is busy. Please try again later."); + m_status = Status_Error; + } catch (const tools::error::no_connection_to_daemon&) { + m_errorString = tr("no connection to daemon. Please make sure daemon is running."); + m_status = Status_Error; + } catch (const tools::error::tx_rejected& e) { + std::ostringstream writer(m_errorString); + writer << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status(); + std::string reason = e.reason(); + m_status = Status_Error; + m_errorString = writer.str(); + if (!reason.empty()) + m_errorString += string(tr(". Reason: ")) + reason; + } catch (const std::exception &e) { + m_errorString = string(tr("Unknown exception: ")) + e.what(); + m_status = Status_Error; + } catch (...) { + m_errorString = tr("Unhandled exception"); + LOG_ERROR(m_errorString); + m_status = Status_Error; + } + m_wallet.startRefresh(); + if (m_status != Status_Ok) + return ""; + return tx; +} + uint64_t PendingTransactionImpl::amount() const { uint64_t result = 0; diff --git a/src/wallet/api/pending_transaction.h b/src/wallet/api/pending_transaction.h index 9d8d754c0c..0b9b09eced 100644 --- a/src/wallet/api/pending_transaction.h +++ b/src/wallet/api/pending_transaction.h @@ -45,6 +45,7 @@ class PendingTransactionImpl : public PendingTransaction ~PendingTransactionImpl(); int status() const override; std::string errorString() const override; + std::string commit_string() override; bool commit(const std::string &filename = "", bool overwrite = false) override; uint64_t amount() const override; uint64_t dust() const override; diff --git a/src/wallet/api/unsigned_transaction.cpp b/src/wallet/api/unsigned_transaction.cpp index c549539e5b..378e1886f2 100644 --- a/src/wallet/api/unsigned_transaction.cpp +++ b/src/wallet/api/unsigned_transaction.cpp @@ -96,6 +96,28 @@ bool UnsignedTransactionImpl::sign(const std::string &signedFileName) return true; } +std::string UnsignedTransactionImpl::signAsString() +{ + if(m_wallet.watchOnly()) + { + m_errorString = tr("This is a watch only wallet"); + m_status = Status_Error; + return ""; + } + tools::wallet2::signed_tx_set signed_txes; + std::vector ptx; + try + { + return m_wallet.m_wallet->sign_tx_dump_to_str(m_unsigned_tx_set, ptx, signed_txes); + } + catch (const std::exception &e) + { + m_errorString = string(tr("Failed to sign transaction")) + e.what(); + m_status = Status_Error; + return ""; + } +} + //---------------------------------------------------------------------------------------------------- bool UnsignedTransactionImpl::checkLoadedTx(const std::function get_num_txes, const std::function &get_tx, const std::string &extra_message) { diff --git a/src/wallet/api/unsigned_transaction.h b/src/wallet/api/unsigned_transaction.h index b07d43fb11..6a4d87b530 100644 --- a/src/wallet/api/unsigned_transaction.h +++ b/src/wallet/api/unsigned_transaction.h @@ -53,6 +53,7 @@ class UnsignedTransactionImpl : public UnsignedTransaction uint64_t txCount() const override; // sign txs and save to file bool sign(const std::string &signedFileName) override; + std::string signAsString() override; std::string confirmationMessage() const override {return m_confirmationMessage;} uint64_t minMixinCount() const override; diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index c8257919dd..44b386f3d0 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -1134,6 +1134,27 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file return transaction; } +UnsignedTransaction *WalletImpl::loadUnsignedTxFromString(const std::string &data) { + clearStatus(); + UnsignedTransactionImpl * transaction = new UnsignedTransactionImpl(*this); + if (checkBackgroundSync("cannot load tx") || !m_wallet->parse_unsigned_tx_from_str(data, transaction->m_unsigned_tx_set)){ + setStatusError(tr("Failed to load unsigned transactions")); + transaction->m_status = UnsignedTransaction::Status::Status_Error; + transaction->m_errorString = errorString(); + + return transaction; + } + + // Check tx data and construct confirmation message + std::string extra_message; + if (!std::get<2>(transaction->m_unsigned_tx_set.transfers).empty()) + extra_message = (boost::format("%u outputs to import. ") % (unsigned)std::get<2>(transaction->m_unsigned_tx_set.transfers).size()).str(); + transaction->checkLoadedTx([&transaction](){return transaction->m_unsigned_tx_set.txes.size();}, [&transaction](size_t n)->const tools::wallet2::tx_construction_data&{return transaction->m_unsigned_tx_set.txes[n];}, extra_message); + setStatus(transaction->status(), transaction->errorString()); + + return transaction; +} + bool WalletImpl::submitTransaction(const string &fileName) { clearStatus(); if (checkBackgroundSync("cannot submit tx")) @@ -1154,6 +1175,48 @@ bool WalletImpl::submitTransaction(const string &fileName) { return true; } +bool WalletImpl::submitTransactionFromString(const string &data) { + clearStatus(); + if (checkBackgroundSync("cannot submit tx")) + return false; + std::unique_ptr transaction(new PendingTransactionImpl(*this)); + + bool r = m_wallet->parse_tx_from_str(data, transaction->m_pending_tx, NULL); + if (!r) { + setStatus(Status_Ok, tr("Failed to load transaction from string")); + return false; + } + + if(!transaction->commit()) { + setStatusError(transaction->m_errorString); + return false; + } + + return true; +} + +std::string WalletImpl::exportKeyImagesAsString(bool all) +{ + if (m_wallet->watch_only()) + { + setStatusError(tr("Wallet is view only")); + return ""; + } + if (checkBackgroundSync("cannot export key images")) + return ""; + + try + { + return m_wallet->export_key_images_string(all); + } + catch (const std::exception &e) + { + LOG_ERROR("Error exporting key images: " << e.what()); + setStatusError(e.what()); + return ""; + } +} + bool WalletImpl::exportKeyImages(const string &filename, bool all) { if (m_wallet->watch_only()) @@ -1181,6 +1244,31 @@ bool WalletImpl::exportKeyImages(const string &filename, bool all) return true; } +bool WalletImpl::importKeyImagesFromString(const std::string &data) +{ + if (checkBackgroundSync("cannot import key images")) + return false; + if (!trustedDaemon()) { + setStatusError(tr("Key images can only be imported with a trusted daemon")); + return false; + } + try + { + uint64_t spent = 0, unspent = 0; + uint64_t height = m_wallet->import_key_images_string(data, spent, unspent); + LOG_PRINT_L2("Signed key images imported to height " << height << ", " + << print_money(spent) << " spent, " << print_money(unspent) << " unspent"); + } + catch (const std::exception &e) + { + LOG_ERROR("Error exporting key images: " << e.what()); + setStatusError(string(tr("Failed to import key images: ")) + e.what()); + return false; + } + + return true; +} + bool WalletImpl::importKeyImages(const string &filename) { if (checkBackgroundSync("cannot import key images")) @@ -1206,6 +1294,29 @@ bool WalletImpl::importKeyImages(const string &filename) return true; } +std::string WalletImpl::exportOutputsAsString(bool all) +{ + if (checkBackgroundSync("cannot export outputs")) + return ""; + if (m_wallet->key_on_device()) + { + setStatusError(string(tr("Not supported on HW wallets."))); + return ""; + } + + try + { + return m_wallet->export_outputs_to_str(all); + } + catch (const std::exception &e) + { + LOG_ERROR("Error exporting outputs: " << e.what()); + setStatusError(string(tr("Error exporting outputs: ")) + e.what()); + return ""; + } + return ""; +} + bool WalletImpl::exportOutputs(const string &filename, bool all) { if (checkBackgroundSync("cannot export outputs")) @@ -1238,6 +1349,32 @@ bool WalletImpl::exportOutputs(const string &filename, bool all) return true; } +bool WalletImpl::importOutputsFromString(const std::string &data) +{ + if (checkBackgroundSync("cannot import outputs")) + return false; + if (m_wallet->key_on_device()) + { + setStatusError(string(tr("Not supported on HW wallets."))); + return false; + } + + + try + { + size_t n_outputs = m_wallet->import_outputs_from_str(data); + LOG_PRINT_L2(std::to_string(n_outputs) << " outputs imported"); + } + catch (const std::exception &e) + { + LOG_ERROR("Failed to import outputs: " << e.what()); + setStatusError(string(tr("Failed to import outputs: ")) + e.what()); + return false; + } + + return true; +} + bool WalletImpl::importOutputs(const string &filename) { if (checkBackgroundSync("cannot import outputs")) diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index d48d7f130e..2364f07419 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -166,10 +166,16 @@ class WalletImpl : public Wallet std::set subaddr_indices = {}) override; virtual PendingTransaction * createSweepUnmixableTransaction() override; bool submitTransaction(const std::string &fileName) override; + bool submitTransactionFromString(const std::string &fileName) override; virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) override; + virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) override; + std::string exportKeyImagesAsString(bool all = false) override; bool exportKeyImages(const std::string &filename, bool all = false) override; + bool importKeyImagesFromString(const std::string &data) override; bool importKeyImages(const std::string &filename) override; + std::string exportOutputsAsString(bool all = false) override; bool exportOutputs(const std::string &filename, bool all = false) override; + bool importOutputsFromString(const std::string &data) override; bool importOutputs(const std::string &filename) override; bool scanTransactions(const std::vector &txids) override; diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index c374d1574b..cd4206e6cf 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -89,6 +89,8 @@ struct PendingTransaction virtual ~PendingTransaction() = 0; virtual int status() const = 0; virtual std::string errorString() const = 0; + // return string of transaction gives the same content which would be saved to file with commit(filename) + virtual std::string commit_string() = 0; // commit transaction or save to file if filename is provided. virtual bool commit(const std::string &filename = "", bool overwrite = false) = 0; virtual uint64_t amount() const = 0; @@ -161,6 +163,11 @@ struct UnsignedTransaction * return - true on success */ virtual bool sign(const std::string &signedFileName) = 0; + /*! + * @brief sign - Sign txs and return as string + * return - true on success + */ + virtual std::string signAsString() = 0; }; /** @@ -895,11 +902,24 @@ struct Wallet */ virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) = 0; + /*! + * \brief loadUnsignedTxFromString - creates transaction from unsigned tx string + * \return - UnsignedTransaction object. caller is responsible to check UnsignedTransaction::status() + * after object returned + */ + virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) = 0; + /*! * \brief submitTransaction - submits transaction in signed tx file * \return - true on success */ virtual bool submitTransaction(const std::string &fileName) = 0; + + /*! + * \brief submitTransactionFromString - submits transaction in signed tx file + * \return - true on success + */ + virtual bool submitTransactionFromString(const std::string &fileName) = 0; /*! @@ -916,6 +936,13 @@ struct Wallet virtual uint64_t estimateTransactionFee(const std::vector> &destinations, PendingTransaction::Priority priority) const = 0; + /*! + * \brief exportKeyImages - exports key images as string + * \param all - export all key images or only those that have not yet been exported + * \return - key images as std::string + */ + virtual std::string exportKeyImagesAsString(bool all = false) = 0; + /*! * \brief exportKeyImages - exports key images to file * \param filename @@ -923,6 +950,13 @@ struct Wallet * \return - true on success */ virtual bool exportKeyImages(const std::string &filename, bool all = false) = 0; + + /*! + * \brief importKeyImagesFromString - imports key images from string for UR use. + * \param data + * \return - true on success + */ + virtual bool importKeyImagesFromString(const std::string &data) = 0; /*! * \brief importKeyImages - imports key images from file @@ -932,12 +966,25 @@ struct Wallet virtual bool importKeyImages(const std::string &filename) = 0; /*! - * \brief importOutputs - exports outputs to file + * \brief exportOutputsAsString - exports outputs to a string for UR + * \return - true on success + */ + virtual std::string exportOutputsAsString(bool all = false) = 0; + + /*! + * \brief exportOutputs - exports outputs to file * \param filename * \return - true on success */ virtual bool exportOutputs(const std::string &filename, bool all = false) = 0; + /*! + * \brief importOutputsFromString - imports outputs from string for UR + * \param filename + * \return - true on success + */ + virtual bool importOutputsFromString(const std::string &data) = 0; + /*! * \brief importOutputs - imports outputs from file * \param filename diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index fa9c51bb27..0bf3ff8c13 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -13262,9 +13262,8 @@ crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::walle return tx_pub_key; } -bool wallet2::export_key_images(const std::string &filename, bool all) const +std::string wallet2::export_key_images_string(bool all) const { - PERF_TIMER(export_key_images); std::pair>> ski = export_key_images(all); std::string magic(KEY_IMAGE_EXPORT_FILE_MAGIC, strlen(KEY_IMAGE_EXPORT_FILE_MAGIC)); const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address; @@ -13287,8 +13286,13 @@ bool wallet2::export_key_images(const std::string &filename, bool all) const // encrypt data, keep magic plaintext PERF_TIMER(export_key_images_encrypt); - std::string ciphertext = encrypt_with_view_secret_key(data); - return save_to_file(filename, magic + ciphertext); + return magic + encrypt_with_view_secret_key(data); +} + +bool wallet2::export_key_images(const std::string &filename, bool all) const +{ + PERF_TIMER(export_key_images); + return save_to_file(filename, export_key_images_string(all)); } //---------------------------------------------------------------------------------------------------- @@ -13353,10 +13357,16 @@ uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, std::string(tr("failed to read file ")) + filename); + return import_key_images_string(data, spent, unspent); +} + +uint64_t wallet2::import_key_images_string(const std::string &keyImages, uint64_t &spent, uint64_t &unspent) +{ + std::string data = keyImages; const size_t magiclen = strlen(KEY_IMAGE_EXPORT_FILE_MAGIC); if (data.size() < magiclen || memcmp(data.data(), KEY_IMAGE_EXPORT_FILE_MAGIC, magiclen)) { - THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Bad key image export file magic in ") + filename); + THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Bad key image export file magic")); } try @@ -13366,24 +13376,24 @@ uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent } catch (const std::exception &e) { - THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Failed to decrypt ") + filename + ": " + e.what()); + THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Failed to decrypt: ") + e.what()); } const size_t headerlen = 4 + 2 * sizeof(crypto::public_key); - THROW_WALLET_EXCEPTION_IF(data.size() < headerlen, error::wallet_internal_error, std::string("Bad data size from file ") + filename); + THROW_WALLET_EXCEPTION_IF(data.size() < headerlen, error::wallet_internal_error, std::string("Bad data size")); const uint32_t offset = (uint8_t)data[0] | (((uint8_t)data[1]) << 8) | (((uint8_t)data[2]) << 16) | (((uint8_t)data[3]) << 24); const crypto::public_key &public_spend_key = *(const crypto::public_key*)&data[4]; const crypto::public_key &public_view_key = *(const crypto::public_key*)&data[4 + sizeof(crypto::public_key)]; const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address; if (public_spend_key != keys.m_spend_public_key || public_view_key != keys.m_view_public_key) { - THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string( "Key images from ") + filename + " are for a different account"); + THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string( "Key images are from a different account" )); } THROW_WALLET_EXCEPTION_IF(offset > m_transfers.size(), error::wallet_internal_error, "Offset larger than known outputs"); const size_t record_size = sizeof(crypto::key_image) + sizeof(crypto::signature); THROW_WALLET_EXCEPTION_IF((data.size() - headerlen) % record_size, - error::wallet_internal_error, std::string("Bad data size from file ") + filename); + error::wallet_internal_error, std::string("Bad data size")); size_t nki = (data.size() - headerlen) / record_size; std::vector> ski; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 7228f19077..1da82e734f 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1630,10 +1630,12 @@ namespace tools void import_payments_out(const std::list> &confirmed_payments); std::tuple> export_blockchain() const; void import_blockchain(const std::tuple> &bc); + std::string export_key_images_string(bool all = false) const; bool export_key_images(const std::string &filename, bool all = false) const; std::pair>> export_key_images(bool all = false) const; uint64_t import_key_images(const std::vector> &signed_key_images, size_t offset, uint64_t &spent, uint64_t &unspent, bool check_spent = true); uint64_t import_key_images(const std::string &filename, uint64_t &spent, uint64_t &unspent); + uint64_t import_key_images_string(const std::string &data, uint64_t &spent, uint64_t &unspent); bool import_key_images(std::vector key_images, size_t offset=0, boost::optional> selected_transfers=boost::none); bool import_key_images(signed_tx_set & signed_tx, size_t offset=0, bool only_selected_transfers=false); crypto::public_key get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const; From 2bc362d9e60957f13981d3a2b10ad97b9da6c869 Mon Sep 17 00:00:00 2001 From: DiosDelRayo Date: Fri, 27 Sep 2024 01:29:05 -0600 Subject: [PATCH 14/18] Modifications to enable Offline Signing in monero-gui and possible other projects via UR or other mediums of exchange. Added the following signatures in the mention files: wallet/wallet2.h + std::string export_key_images_string(bool all = false) const; + uint64_t import_key_images_string(const std::string &data, uint64_t &spent, uint64_t &unspent); M bool wallet2::export_key_images(const std::string &filename, bool all) const wallet/api/pending_transaction.h + std::string commit_string() override; wallet/api/unsigned_transaction.h + std::string signAsString() override; wallet/api/wallet.h: + bool submitTransactionFromString(const std::string &fileName) override; + virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) override; + std::string exportKeyImagesAsString(bool all = false) override; + bool importKeyImagesFromString(const std::string &data) override; + std::string exportOutputsAsString(bool all = false) override; + bool importOutputsFromString(const std::string &data) override; wallet/api/wallet2_api.h + virtual std::string commit_string() = 0; + virtual std::string signAsString() = 0; + virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) = 0; + virtual bool submitTransactionFromString(const std::string &fileName) = 0; + virtual bool importKeyImagesFromString(const std::string &data) = 0; + virtual std::string exportOutputsAsString(bool all = false) = 0; + virtual bool importOutputsFromString(const std::string &data) = 0; + uint64_t import_key_images_string(const std::string &data, uint64_t &spent, uint64_t &unspent); And the implementations in: wallet/wallet2.cpp wallet/api/pending_transaction.cpp wallet/api/unsigned_transaction.cpp wallet/api/wallet.cpp The method `bool wallet2::export_key_images(const std::string &filename, bool all) const` is modified to use `std::string export_key_images_string(bool all = false) const;` to get the string to write to the file. IMO that would be the perfect way to do it everywhere, but in the other methods it would require more modifications, so the other I duplicated and removed the part writing to the file and return instead a std::string, or use a std::string for the actual payload instead of a file path. One thing to mention is I remove in one or two log messages the filename, and the other is in `export_key_images` probably(almost sure) is now the performance messed up. This modifications was done to get all the necessary data for offline signing via UR or any other channel not using files as medium. IMO it had been better to not implement the filehandling direct in wallet2 or in the wallet api but rather in monero-wallet-cli and monero-gui itself, but it is like it is. --- src/wallet/api/pending_transaction.cpp | 38 +++++++ src/wallet/api/pending_transaction.h | 1 + src/wallet/api/unsigned_transaction.cpp | 22 ++++ src/wallet/api/unsigned_transaction.h | 1 + src/wallet/api/wallet.cpp | 137 ++++++++++++++++++++++++ src/wallet/api/wallet.h | 6 ++ src/wallet/api/wallet2_api.h | 49 ++++++++- src/wallet/wallet2.cpp | 28 +++-- src/wallet/wallet2.h | 2 + 9 files changed, 274 insertions(+), 10 deletions(-) diff --git a/src/wallet/api/pending_transaction.cpp b/src/wallet/api/pending_transaction.cpp index 9783da5bcd..ba84a37333 100644 --- a/src/wallet/api/pending_transaction.cpp +++ b/src/wallet/api/pending_transaction.cpp @@ -162,6 +162,44 @@ bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite) return m_status == Status_Ok; } +std::string PendingTransactionImpl::commit_string() +{ + + std::string tx; + LOG_PRINT_L3("m_pending_tx size: " << m_pending_tx.size()); + + try { + tx = m_wallet.m_wallet->dump_tx_to_str(m_pending_tx); + m_status = Status_Ok; + } catch (const tools::error::daemon_busy&) { + // TODO: make it translatable with "tr"? + m_errorString = tr("daemon is busy. Please try again later."); + m_status = Status_Error; + } catch (const tools::error::no_connection_to_daemon&) { + m_errorString = tr("no connection to daemon. Please make sure daemon is running."); + m_status = Status_Error; + } catch (const tools::error::tx_rejected& e) { + std::ostringstream writer(m_errorString); + writer << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status(); + std::string reason = e.reason(); + m_status = Status_Error; + m_errorString = writer.str(); + if (!reason.empty()) + m_errorString += string(tr(". Reason: ")) + reason; + } catch (const std::exception &e) { + m_errorString = string(tr("Unknown exception: ")) + e.what(); + m_status = Status_Error; + } catch (...) { + m_errorString = tr("Unhandled exception"); + LOG_ERROR(m_errorString); + m_status = Status_Error; + } + m_wallet.startRefresh(); + if (m_status != Status_Ok) + return ""; + return tx; +} + uint64_t PendingTransactionImpl::amount() const { uint64_t result = 0; diff --git a/src/wallet/api/pending_transaction.h b/src/wallet/api/pending_transaction.h index 9d8d754c0c..0b9b09eced 100644 --- a/src/wallet/api/pending_transaction.h +++ b/src/wallet/api/pending_transaction.h @@ -45,6 +45,7 @@ class PendingTransactionImpl : public PendingTransaction ~PendingTransactionImpl(); int status() const override; std::string errorString() const override; + std::string commit_string() override; bool commit(const std::string &filename = "", bool overwrite = false) override; uint64_t amount() const override; uint64_t dust() const override; diff --git a/src/wallet/api/unsigned_transaction.cpp b/src/wallet/api/unsigned_transaction.cpp index c549539e5b..378e1886f2 100644 --- a/src/wallet/api/unsigned_transaction.cpp +++ b/src/wallet/api/unsigned_transaction.cpp @@ -96,6 +96,28 @@ bool UnsignedTransactionImpl::sign(const std::string &signedFileName) return true; } +std::string UnsignedTransactionImpl::signAsString() +{ + if(m_wallet.watchOnly()) + { + m_errorString = tr("This is a watch only wallet"); + m_status = Status_Error; + return ""; + } + tools::wallet2::signed_tx_set signed_txes; + std::vector ptx; + try + { + return m_wallet.m_wallet->sign_tx_dump_to_str(m_unsigned_tx_set, ptx, signed_txes); + } + catch (const std::exception &e) + { + m_errorString = string(tr("Failed to sign transaction")) + e.what(); + m_status = Status_Error; + return ""; + } +} + //---------------------------------------------------------------------------------------------------- bool UnsignedTransactionImpl::checkLoadedTx(const std::function get_num_txes, const std::function &get_tx, const std::string &extra_message) { diff --git a/src/wallet/api/unsigned_transaction.h b/src/wallet/api/unsigned_transaction.h index b07d43fb11..6a4d87b530 100644 --- a/src/wallet/api/unsigned_transaction.h +++ b/src/wallet/api/unsigned_transaction.h @@ -53,6 +53,7 @@ class UnsignedTransactionImpl : public UnsignedTransaction uint64_t txCount() const override; // sign txs and save to file bool sign(const std::string &signedFileName) override; + std::string signAsString() override; std::string confirmationMessage() const override {return m_confirmationMessage;} uint64_t minMixinCount() const override; diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index c8257919dd..44b386f3d0 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -1134,6 +1134,27 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file return transaction; } +UnsignedTransaction *WalletImpl::loadUnsignedTxFromString(const std::string &data) { + clearStatus(); + UnsignedTransactionImpl * transaction = new UnsignedTransactionImpl(*this); + if (checkBackgroundSync("cannot load tx") || !m_wallet->parse_unsigned_tx_from_str(data, transaction->m_unsigned_tx_set)){ + setStatusError(tr("Failed to load unsigned transactions")); + transaction->m_status = UnsignedTransaction::Status::Status_Error; + transaction->m_errorString = errorString(); + + return transaction; + } + + // Check tx data and construct confirmation message + std::string extra_message; + if (!std::get<2>(transaction->m_unsigned_tx_set.transfers).empty()) + extra_message = (boost::format("%u outputs to import. ") % (unsigned)std::get<2>(transaction->m_unsigned_tx_set.transfers).size()).str(); + transaction->checkLoadedTx([&transaction](){return transaction->m_unsigned_tx_set.txes.size();}, [&transaction](size_t n)->const tools::wallet2::tx_construction_data&{return transaction->m_unsigned_tx_set.txes[n];}, extra_message); + setStatus(transaction->status(), transaction->errorString()); + + return transaction; +} + bool WalletImpl::submitTransaction(const string &fileName) { clearStatus(); if (checkBackgroundSync("cannot submit tx")) @@ -1154,6 +1175,48 @@ bool WalletImpl::submitTransaction(const string &fileName) { return true; } +bool WalletImpl::submitTransactionFromString(const string &data) { + clearStatus(); + if (checkBackgroundSync("cannot submit tx")) + return false; + std::unique_ptr transaction(new PendingTransactionImpl(*this)); + + bool r = m_wallet->parse_tx_from_str(data, transaction->m_pending_tx, NULL); + if (!r) { + setStatus(Status_Ok, tr("Failed to load transaction from string")); + return false; + } + + if(!transaction->commit()) { + setStatusError(transaction->m_errorString); + return false; + } + + return true; +} + +std::string WalletImpl::exportKeyImagesAsString(bool all) +{ + if (m_wallet->watch_only()) + { + setStatusError(tr("Wallet is view only")); + return ""; + } + if (checkBackgroundSync("cannot export key images")) + return ""; + + try + { + return m_wallet->export_key_images_string(all); + } + catch (const std::exception &e) + { + LOG_ERROR("Error exporting key images: " << e.what()); + setStatusError(e.what()); + return ""; + } +} + bool WalletImpl::exportKeyImages(const string &filename, bool all) { if (m_wallet->watch_only()) @@ -1181,6 +1244,31 @@ bool WalletImpl::exportKeyImages(const string &filename, bool all) return true; } +bool WalletImpl::importKeyImagesFromString(const std::string &data) +{ + if (checkBackgroundSync("cannot import key images")) + return false; + if (!trustedDaemon()) { + setStatusError(tr("Key images can only be imported with a trusted daemon")); + return false; + } + try + { + uint64_t spent = 0, unspent = 0; + uint64_t height = m_wallet->import_key_images_string(data, spent, unspent); + LOG_PRINT_L2("Signed key images imported to height " << height << ", " + << print_money(spent) << " spent, " << print_money(unspent) << " unspent"); + } + catch (const std::exception &e) + { + LOG_ERROR("Error exporting key images: " << e.what()); + setStatusError(string(tr("Failed to import key images: ")) + e.what()); + return false; + } + + return true; +} + bool WalletImpl::importKeyImages(const string &filename) { if (checkBackgroundSync("cannot import key images")) @@ -1206,6 +1294,29 @@ bool WalletImpl::importKeyImages(const string &filename) return true; } +std::string WalletImpl::exportOutputsAsString(bool all) +{ + if (checkBackgroundSync("cannot export outputs")) + return ""; + if (m_wallet->key_on_device()) + { + setStatusError(string(tr("Not supported on HW wallets."))); + return ""; + } + + try + { + return m_wallet->export_outputs_to_str(all); + } + catch (const std::exception &e) + { + LOG_ERROR("Error exporting outputs: " << e.what()); + setStatusError(string(tr("Error exporting outputs: ")) + e.what()); + return ""; + } + return ""; +} + bool WalletImpl::exportOutputs(const string &filename, bool all) { if (checkBackgroundSync("cannot export outputs")) @@ -1238,6 +1349,32 @@ bool WalletImpl::exportOutputs(const string &filename, bool all) return true; } +bool WalletImpl::importOutputsFromString(const std::string &data) +{ + if (checkBackgroundSync("cannot import outputs")) + return false; + if (m_wallet->key_on_device()) + { + setStatusError(string(tr("Not supported on HW wallets."))); + return false; + } + + + try + { + size_t n_outputs = m_wallet->import_outputs_from_str(data); + LOG_PRINT_L2(std::to_string(n_outputs) << " outputs imported"); + } + catch (const std::exception &e) + { + LOG_ERROR("Failed to import outputs: " << e.what()); + setStatusError(string(tr("Failed to import outputs: ")) + e.what()); + return false; + } + + return true; +} + bool WalletImpl::importOutputs(const string &filename) { if (checkBackgroundSync("cannot import outputs")) diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index d48d7f130e..2364f07419 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -166,10 +166,16 @@ class WalletImpl : public Wallet std::set subaddr_indices = {}) override; virtual PendingTransaction * createSweepUnmixableTransaction() override; bool submitTransaction(const std::string &fileName) override; + bool submitTransactionFromString(const std::string &fileName) override; virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) override; + virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) override; + std::string exportKeyImagesAsString(bool all = false) override; bool exportKeyImages(const std::string &filename, bool all = false) override; + bool importKeyImagesFromString(const std::string &data) override; bool importKeyImages(const std::string &filename) override; + std::string exportOutputsAsString(bool all = false) override; bool exportOutputs(const std::string &filename, bool all = false) override; + bool importOutputsFromString(const std::string &data) override; bool importOutputs(const std::string &filename) override; bool scanTransactions(const std::vector &txids) override; diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index c374d1574b..cd4206e6cf 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -89,6 +89,8 @@ struct PendingTransaction virtual ~PendingTransaction() = 0; virtual int status() const = 0; virtual std::string errorString() const = 0; + // return string of transaction gives the same content which would be saved to file with commit(filename) + virtual std::string commit_string() = 0; // commit transaction or save to file if filename is provided. virtual bool commit(const std::string &filename = "", bool overwrite = false) = 0; virtual uint64_t amount() const = 0; @@ -161,6 +163,11 @@ struct UnsignedTransaction * return - true on success */ virtual bool sign(const std::string &signedFileName) = 0; + /*! + * @brief sign - Sign txs and return as string + * return - true on success + */ + virtual std::string signAsString() = 0; }; /** @@ -895,11 +902,24 @@ struct Wallet */ virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) = 0; + /*! + * \brief loadUnsignedTxFromString - creates transaction from unsigned tx string + * \return - UnsignedTransaction object. caller is responsible to check UnsignedTransaction::status() + * after object returned + */ + virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) = 0; + /*! * \brief submitTransaction - submits transaction in signed tx file * \return - true on success */ virtual bool submitTransaction(const std::string &fileName) = 0; + + /*! + * \brief submitTransactionFromString - submits transaction in signed tx file + * \return - true on success + */ + virtual bool submitTransactionFromString(const std::string &fileName) = 0; /*! @@ -916,6 +936,13 @@ struct Wallet virtual uint64_t estimateTransactionFee(const std::vector> &destinations, PendingTransaction::Priority priority) const = 0; + /*! + * \brief exportKeyImages - exports key images as string + * \param all - export all key images or only those that have not yet been exported + * \return - key images as std::string + */ + virtual std::string exportKeyImagesAsString(bool all = false) = 0; + /*! * \brief exportKeyImages - exports key images to file * \param filename @@ -923,6 +950,13 @@ struct Wallet * \return - true on success */ virtual bool exportKeyImages(const std::string &filename, bool all = false) = 0; + + /*! + * \brief importKeyImagesFromString - imports key images from string for UR use. + * \param data + * \return - true on success + */ + virtual bool importKeyImagesFromString(const std::string &data) = 0; /*! * \brief importKeyImages - imports key images from file @@ -932,12 +966,25 @@ struct Wallet virtual bool importKeyImages(const std::string &filename) = 0; /*! - * \brief importOutputs - exports outputs to file + * \brief exportOutputsAsString - exports outputs to a string for UR + * \return - true on success + */ + virtual std::string exportOutputsAsString(bool all = false) = 0; + + /*! + * \brief exportOutputs - exports outputs to file * \param filename * \return - true on success */ virtual bool exportOutputs(const std::string &filename, bool all = false) = 0; + /*! + * \brief importOutputsFromString - imports outputs from string for UR + * \param filename + * \return - true on success + */ + virtual bool importOutputsFromString(const std::string &data) = 0; + /*! * \brief importOutputs - imports outputs from file * \param filename diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index fa9c51bb27..0bf3ff8c13 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -13262,9 +13262,8 @@ crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::walle return tx_pub_key; } -bool wallet2::export_key_images(const std::string &filename, bool all) const +std::string wallet2::export_key_images_string(bool all) const { - PERF_TIMER(export_key_images); std::pair>> ski = export_key_images(all); std::string magic(KEY_IMAGE_EXPORT_FILE_MAGIC, strlen(KEY_IMAGE_EXPORT_FILE_MAGIC)); const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address; @@ -13287,8 +13286,13 @@ bool wallet2::export_key_images(const std::string &filename, bool all) const // encrypt data, keep magic plaintext PERF_TIMER(export_key_images_encrypt); - std::string ciphertext = encrypt_with_view_secret_key(data); - return save_to_file(filename, magic + ciphertext); + return magic + encrypt_with_view_secret_key(data); +} + +bool wallet2::export_key_images(const std::string &filename, bool all) const +{ + PERF_TIMER(export_key_images); + return save_to_file(filename, export_key_images_string(all)); } //---------------------------------------------------------------------------------------------------- @@ -13353,10 +13357,16 @@ uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, std::string(tr("failed to read file ")) + filename); + return import_key_images_string(data, spent, unspent); +} + +uint64_t wallet2::import_key_images_string(const std::string &keyImages, uint64_t &spent, uint64_t &unspent) +{ + std::string data = keyImages; const size_t magiclen = strlen(KEY_IMAGE_EXPORT_FILE_MAGIC); if (data.size() < magiclen || memcmp(data.data(), KEY_IMAGE_EXPORT_FILE_MAGIC, magiclen)) { - THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Bad key image export file magic in ") + filename); + THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Bad key image export file magic")); } try @@ -13366,24 +13376,24 @@ uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent } catch (const std::exception &e) { - THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Failed to decrypt ") + filename + ": " + e.what()); + THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Failed to decrypt: ") + e.what()); } const size_t headerlen = 4 + 2 * sizeof(crypto::public_key); - THROW_WALLET_EXCEPTION_IF(data.size() < headerlen, error::wallet_internal_error, std::string("Bad data size from file ") + filename); + THROW_WALLET_EXCEPTION_IF(data.size() < headerlen, error::wallet_internal_error, std::string("Bad data size")); const uint32_t offset = (uint8_t)data[0] | (((uint8_t)data[1]) << 8) | (((uint8_t)data[2]) << 16) | (((uint8_t)data[3]) << 24); const crypto::public_key &public_spend_key = *(const crypto::public_key*)&data[4]; const crypto::public_key &public_view_key = *(const crypto::public_key*)&data[4 + sizeof(crypto::public_key)]; const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address; if (public_spend_key != keys.m_spend_public_key || public_view_key != keys.m_view_public_key) { - THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string( "Key images from ") + filename + " are for a different account"); + THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string( "Key images are from a different account" )); } THROW_WALLET_EXCEPTION_IF(offset > m_transfers.size(), error::wallet_internal_error, "Offset larger than known outputs"); const size_t record_size = sizeof(crypto::key_image) + sizeof(crypto::signature); THROW_WALLET_EXCEPTION_IF((data.size() - headerlen) % record_size, - error::wallet_internal_error, std::string("Bad data size from file ") + filename); + error::wallet_internal_error, std::string("Bad data size")); size_t nki = (data.size() - headerlen) / record_size; std::vector> ski; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 7228f19077..1da82e734f 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1630,10 +1630,12 @@ namespace tools void import_payments_out(const std::list> &confirmed_payments); std::tuple> export_blockchain() const; void import_blockchain(const std::tuple> &bc); + std::string export_key_images_string(bool all = false) const; bool export_key_images(const std::string &filename, bool all = false) const; std::pair>> export_key_images(bool all = false) const; uint64_t import_key_images(const std::vector> &signed_key_images, size_t offset, uint64_t &spent, uint64_t &unspent, bool check_spent = true); uint64_t import_key_images(const std::string &filename, uint64_t &spent, uint64_t &unspent); + uint64_t import_key_images_string(const std::string &data, uint64_t &spent, uint64_t &unspent); bool import_key_images(std::vector key_images, size_t offset=0, boost::optional> selected_transfers=boost::none); bool import_key_images(signed_tx_set & signed_tx, size_t offset=0, bool only_selected_transfers=false); crypto::public_key get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const; From 23d893473e570437c9423d429b468bdc00f9e012 Mon Sep 17 00:00:00 2001 From: DiosDelRayo Date: Wed, 20 Nov 2024 08:47:52 -0600 Subject: [PATCH 15/18] https://github.com/monero-project/monero/pull/9492#pullrequestreview-2358265221 --- src/wallet/api/pending_transaction.cpp | 2 +- src/wallet/api/pending_transaction.h | 2 +- src/wallet/api/wallet2_api.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/api/pending_transaction.cpp b/src/wallet/api/pending_transaction.cpp index ba84a37333..a84a1de487 100644 --- a/src/wallet/api/pending_transaction.cpp +++ b/src/wallet/api/pending_transaction.cpp @@ -162,7 +162,7 @@ bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite) return m_status == Status_Ok; } -std::string PendingTransactionImpl::commit_string() +std::string PendingTransactionImpl::commitToString() { std::string tx; diff --git a/src/wallet/api/pending_transaction.h b/src/wallet/api/pending_transaction.h index 0b9b09eced..e1c3cc678e 100644 --- a/src/wallet/api/pending_transaction.h +++ b/src/wallet/api/pending_transaction.h @@ -45,7 +45,7 @@ class PendingTransactionImpl : public PendingTransaction ~PendingTransactionImpl(); int status() const override; std::string errorString() const override; - std::string commit_string() override; + std::string commitToString() override; bool commit(const std::string &filename = "", bool overwrite = false) override; uint64_t amount() const override; uint64_t dust() const override; diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index cd4206e6cf..981e561ec7 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -90,7 +90,7 @@ struct PendingTransaction virtual int status() const = 0; virtual std::string errorString() const = 0; // return string of transaction gives the same content which would be saved to file with commit(filename) - virtual std::string commit_string() = 0; + virtual std::string commitToString() = 0; // commit transaction or save to file if filename is provided. virtual bool commit(const std::string &filename = "", bool overwrite = false) = 0; virtual uint64_t amount() const = 0; From 744bf8d9e1f6b81983a77403495665108ab6027d Mon Sep 17 00:00:00 2001 From: DiosDelRayo Date: Wed, 20 Nov 2024 09:07:21 -0600 Subject: [PATCH 16/18] https://github.com/monero-project/monero/pull/9492#pullrequestreview-2358265221 --- src/wallet/api/pending_transaction.cpp | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/src/wallet/api/pending_transaction.cpp b/src/wallet/api/pending_transaction.cpp index a84a1de487..a13959806c 100644 --- a/src/wallet/api/pending_transaction.cpp +++ b/src/wallet/api/pending_transaction.cpp @@ -171,21 +171,10 @@ std::string PendingTransactionImpl::commitToString() try { tx = m_wallet.m_wallet->dump_tx_to_str(m_pending_tx); m_status = Status_Ok; - } catch (const tools::error::daemon_busy&) { - // TODO: make it translatable with "tr"? - m_errorString = tr("daemon is busy. Please try again later."); - m_status = Status_Error; - } catch (const tools::error::no_connection_to_daemon&) { - m_errorString = tr("no connection to daemon. Please make sure daemon is running."); + return tx; + } catch (const tools::error::wallet_internal_error&) { + m_errorString = tr("Wallet internal eror."); m_status = Status_Error; - } catch (const tools::error::tx_rejected& e) { - std::ostringstream writer(m_errorString); - writer << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status(); - std::string reason = e.reason(); - m_status = Status_Error; - m_errorString = writer.str(); - if (!reason.empty()) - m_errorString += string(tr(". Reason: ")) + reason; } catch (const std::exception &e) { m_errorString = string(tr("Unknown exception: ")) + e.what(); m_status = Status_Error; @@ -194,10 +183,7 @@ std::string PendingTransactionImpl::commitToString() LOG_ERROR(m_errorString); m_status = Status_Error; } - m_wallet.startRefresh(); - if (m_status != Status_Ok) - return ""; - return tx; + return ""; // m_status != Status_Ok } uint64_t PendingTransactionImpl::amount() const From bc76da9a93ae4fd2e2370862615c430c63551e76 Mon Sep 17 00:00:00 2001 From: DiosDelRayo Date: Wed, 20 Nov 2024 10:03:51 -0600 Subject: [PATCH 17/18] https://github.com/monero-project/monero/pull/9492#pullrequestreview-2358265221 --- src/wallet/api/wallet.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 44b386f3d0..9df2420503 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -1136,13 +1136,13 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file UnsignedTransaction *WalletImpl::loadUnsignedTxFromString(const std::string &data) { clearStatus(); - UnsignedTransactionImpl * transaction = new UnsignedTransactionImpl(*this); + std::unique_ptr transaction(new UnsignedTransactionImpl(*this)); if (checkBackgroundSync("cannot load tx") || !m_wallet->parse_unsigned_tx_from_str(data, transaction->m_unsigned_tx_set)){ setStatusError(tr("Failed to load unsigned transactions")); transaction->m_status = UnsignedTransaction::Status::Status_Error; transaction->m_errorString = errorString(); - return transaction; + return transaction.release(); } // Check tx data and construct confirmation message @@ -1152,7 +1152,7 @@ UnsignedTransaction *WalletImpl::loadUnsignedTxFromString(const std::string &dat transaction->checkLoadedTx([&transaction](){return transaction->m_unsigned_tx_set.txes.size();}, [&transaction](size_t n)->const tools::wallet2::tx_construction_data&{return transaction->m_unsigned_tx_set.txes[n];}, extra_message); setStatus(transaction->status(), transaction->errorString()); - return transaction; + return transaction.release(); } bool WalletImpl::submitTransaction(const string &fileName) { From c399de283f21d88960faf7e870a768a8eebc316b Mon Sep 17 00:00:00 2001 From: DiosDelRayo Date: Thu, 21 Nov 2024 13:26:39 -0600 Subject: [PATCH 18/18] https://github.com/monero-project/monero/pull/9492#pullrequestreview-2358265221 --- src/wallet/api/wallet.cpp | 37 ++++++++++++++++++------------------ src/wallet/api/wallet.h | 4 ++-- src/wallet/api/wallet2_api.h | 10 +++++----- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 9df2420503..0fa464a8dd 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -1183,7 +1183,7 @@ bool WalletImpl::submitTransactionFromString(const string &data) { bool r = m_wallet->parse_tx_from_str(data, transaction->m_pending_tx, NULL); if (!r) { - setStatus(Status_Ok, tr("Failed to load transaction from string")); + setStatusError(Status_Ok, tr("Failed to load transaction from string")); return false; } @@ -1197,24 +1197,24 @@ bool WalletImpl::submitTransactionFromString(const string &data) { std::string WalletImpl::exportKeyImagesAsString(bool all) { - if (m_wallet->watch_only()) - { - setStatusError(tr("Wallet is view only")); - return ""; - } - if (checkBackgroundSync("cannot export key images")) - return ""; + if (m_wallet->watch_only()) + { + setStatusError(tr("Wallet is view only")); + return ""; + } + if (checkBackgroundSync("cannot export key images")) + return ""; - try - { + try + { return m_wallet->export_key_images_string(all); - } - catch (const std::exception &e) - { - LOG_ERROR("Error exporting key images: " << e.what()); - setStatusError(e.what()); - return ""; - } + } + catch (const std::exception &e) + { + LOG_ERROR("Error exporting key images: " << e.what()); + setStatusError(e.what()); + return ""; + } } bool WalletImpl::exportKeyImages(const string &filename, bool all) @@ -1248,7 +1248,8 @@ bool WalletImpl::importKeyImagesFromString(const std::string &data) { if (checkBackgroundSync("cannot import key images")) return false; - if (!trustedDaemon()) { + if (!trustedDaemon()) + { setStatusError(tr("Key images can only be imported with a trusted daemon")); return false; } diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index 2364f07419..89de247b1f 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -166,9 +166,9 @@ class WalletImpl : public Wallet std::set subaddr_indices = {}) override; virtual PendingTransaction * createSweepUnmixableTransaction() override; bool submitTransaction(const std::string &fileName) override; - bool submitTransactionFromString(const std::string &fileName) override; + bool submitTransactionFromString(const std::string &data) override; virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) override; - virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) override; + virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &data) override; std::string exportKeyImagesAsString(bool all = false) override; bool exportKeyImages(const std::string &filename, bool all = false) override; bool importKeyImagesFromString(const std::string &data) override; diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index 981e561ec7..ed483476c3 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -164,8 +164,8 @@ struct UnsignedTransaction */ virtual bool sign(const std::string &signedFileName) = 0; /*! - * @brief sign - Sign txs and return as string - * return - true on success + * @brief signAsString - Sign txs and return as string + * return - signed tx as string on success */ virtual std::string signAsString() = 0; }; @@ -907,7 +907,7 @@ struct Wallet * \return - UnsignedTransaction object. caller is responsible to check UnsignedTransaction::status() * after object returned */ - virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &unsigned_filename) = 0; + virtual UnsignedTransaction * loadUnsignedTxFromString(const std::string &data) = 0; /*! * \brief submitTransaction - submits transaction in signed tx file @@ -916,10 +916,10 @@ struct Wallet virtual bool submitTransaction(const std::string &fileName) = 0; /*! - * \brief submitTransactionFromString - submits transaction in signed tx file + * \brief submitTransactionFromString - submits transaction provided as string * \return - true on success */ - virtual bool submitTransactionFromString(const std::string &fileName) = 0; + virtual bool submitTransactionFromString(const std::string &data) = 0; /*!