Replace the JavaScript mobile app with a native Swift iOS wallet

This commit is contained in:
2026-09-19 13:33:11 +08:00
parent d80b58b704
commit 3e1a39d4d7
79 changed files with 25482 additions and 4023 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,311 @@
/**
* Copyright (c) woodser
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Parts of this file are originally copyright (c) 2014-2019, The Monero Project
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* All rights reserved.
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
*/
#pragma once
#include <boost/optional.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/condition_variable.hpp>
#include <atomic>
#include "monero_wallet.h"
#include "wallet/wallet2.h"
/**
* Implements a monero_wallet.h by wrapping monero-project's wallet2.
*/
namespace monero {
// -------------------------------- LISTENERS -------------------------------
// forward declaration of internal wallet2 listener
struct wallet2_listener;
// --------------------------- STATIC WALLET UTILS --------------------------
/**
* Monero wallet implementation which uses monero-project's wallet2.
*/
class monero_wallet_full : public monero_wallet {
public:
/**
* Indicates if a wallet exists at the given path.
*
* @param path is the path to check for a wallet
* @return true if a wallet exists at the given path, false otherwise
*/
static bool wallet_exists(const std::string& path);
/**
* Open an existing wallet from disk.
*
* @param path is the path to the wallet file to open
* @param password is the password of the wallet file to open
* @param network_type is the wallet's network type
* @param regtest enable regtest
* @return a pointer to the wallet instance
*/
static monero_wallet_full* open_wallet(const std::string& path, const std::string& password, const monero_network_type network_type, bool regtest = false);
/**
* Open an in-memory wallet from existing data buffers.
*
* @param password is the password of the wallet file to open
* @param network_type is the wallet's network type
* @param keys_data contains the contents of the ".keys" file
* @param cache_data contains the contents of the wallet cache file (no extension)
* @param daemon_connection is connection information to a daemon (default = an unconnected wallet)
* @param http_client_factory allows use of custom http clients
* @param regtest enable regtest
* @return a pointer to the wallet instance
*/
static monero_wallet_full* open_wallet_data(const std::string& password, const monero_network_type, const std::string& keys_data, const std::string& cache_data, const std::shared_ptr<monero_rpc_connection>& daemon_connection = std::make_shared<monero_rpc_connection>(), std::unique_ptr<epee::net_utils::http::http_client_factory> http_client_factory = nullptr, bool regtest = false);
/**
* Create a new wallet with the given configuration.
*
* @param config is the wallet configuration
* @param http_client_factory allows use of custom http clients
* @return a pointer to the wallet instance
*/
static monero_wallet_full* create_wallet(const monero_wallet_config& config, std::unique_ptr<epee::net_utils::http::http_client_factory> http_client_factory = nullptr);
/**
* Get a list of available languages for the wallet's seed.
*
* @return the available languages for the wallet's seed
*/
static std::vector<std::string> get_seed_languages();
// ----------------------------- WALLET METHODS -----------------------------
/**
* Destruct the wallet.
*/
~monero_wallet_full();
/**
* Supported wallet methods.
*/
bool is_view_only() const override { return m_w2->watch_only(); }
void set_daemon_connection(const std::string& uri, const std::string& username = "", const std::string& password = "", const std::string& proxy_uri = "", const boost::optional<bool>& is_trusted = boost::none) override;
void set_daemon_connection(const std::shared_ptr<monero_rpc_connection>& connection, const boost::optional<bool>& is_trusted = boost::none) override;
std::shared_ptr<monero_rpc_connection> get_daemon_connection() const override;
bool is_connected_to_daemon() const override;
bool is_daemon_synced() const override;
bool is_daemon_trusted() const override;
bool is_synced() const override;
monero_version get_version() const override;
std::string get_path() const override;
monero_network_type get_network_type() const override;
std::string get_seed() const override;
std::string get_seed_language() const override;
std::string get_public_view_key() const override;
std::string get_private_view_key() const override;
std::string get_public_spend_key() const override;
std::string get_private_spend_key() const override;
std::string get_address(const uint32_t account_idx, const uint32_t subaddress_idx) const override;
monero_subaddress get_address_index(const std::string& address) const override;
monero_integrated_address get_integrated_address(const std::string& standard_address = "", const std::string& payment_id = "") const override;
monero_integrated_address decode_integrated_address(const std::string& integrated_address) const override;
uint64_t get_height() const override;
uint64_t get_restore_height() const override;
void set_restore_height(uint64_t restore_height) override;
uint64_t get_daemon_height() const override;
uint64_t get_daemon_max_peer_height() const override;
uint64_t get_height_by_date(uint16_t year, uint8_t month, uint8_t day) const override;
void add_listener(monero_wallet_listener& listener) override;
void remove_listener(monero_wallet_listener& listener) override;
std::set<monero_wallet_listener*> get_listeners() override;
monero_sync_result sync() override;
monero_sync_result sync(monero_wallet_listener& listener) override;
monero_sync_result sync(uint64_t start_height) override;
monero_sync_result sync(uint64_t start_height, monero_wallet_listener& listener) override;
void start_syncing(uint64_t sync_period_in_ms) override;
void stop_syncing() override;
void scan_txs(const std::vector<std::string>& tx_hashes) override;
void rescan_spent() override;
void rescan_blockchain() override;
uint64_t get_balance() const override;
uint64_t get_balance(uint32_t account_idx) const override;
uint64_t get_balance(uint32_t account_idx, uint32_t subaddress_idx) const override;
uint64_t get_unlocked_balance() const override;
uint64_t get_unlocked_balance(uint32_t account_idx) const override;
uint64_t get_unlocked_balance(uint32_t account_idx, uint32_t subaddress_idx) const override;
std::vector<monero_account> get_accounts(bool include_subaddresses, const std::string& tag) const override;
monero_account get_account(const uint32_t account_idx, bool include_subaddresses) const override;
monero_account create_account(const std::string& label = "") override;
std::vector<monero_subaddress> get_subaddresses(const uint32_t account_idx, const std::vector<uint32_t>& subaddress_indices) const override;
monero_subaddress create_subaddress(uint32_t account_idx, const std::string& label = "") override;
void set_subaddress_label(uint32_t account_idx, uint32_t subaddress_idx, const std::string& label = "") override;
std::vector<std::shared_ptr<monero_tx_wallet>> get_txs() const override;
std::vector<std::shared_ptr<monero_tx_wallet>> get_txs(const monero_tx_query& query) const override;
std::vector<std::shared_ptr<monero_transfer>> get_transfers(const monero_transfer_query& query) const override;
std::vector<std::shared_ptr<monero_output_wallet>> get_outputs(const monero_output_query& query) const override;
std::string export_outputs(bool all = false) const override;
int import_outputs(const std::string& outputs_hex) override;
std::shared_ptr<monero_key_image_export_result> export_key_images(bool all = false) const override;
std::shared_ptr<monero_key_image_import_result> import_key_images(const std::vector<std::shared_ptr<monero_key_image>>& key_images, uint64_t offset = 0) override;
void freeze_output(const std::string& key_image) override;
void thaw_output(const std::string& key_image) override;
bool is_output_frozen(const std::string& key_image) override;
monero_tx_priority get_default_fee_priority() const override;
std::vector<std::shared_ptr<monero_tx_wallet>> create_txs(const monero_tx_config& config) override;
std::vector<std::shared_ptr<monero_tx_wallet>> sweep_unlocked(const monero_tx_config& config) override;
std::shared_ptr<monero_tx_wallet> sweep_output(const monero_tx_config& config) override;
std::vector<std::shared_ptr<monero_tx_wallet>> sweep_dust(bool relay = false) override;
std::vector<std::string> relay_txs(const std::vector<std::string>& tx_metadatas) override;
monero_tx_set describe_tx_set(const monero_tx_set& tx_set) override;
monero_tx_set sign_txs(const std::string& unsigned_tx_hex) override;
std::vector<std::string> submit_txs(const std::string& signed_tx_hex) override;
std::string sign_message(const std::string& msg, monero_message_signature_type signature_type, uint32_t account_idx = 0, uint32_t subaddress_idx = 0) const override;
monero_message_signature_result verify_message(const std::string& msg, const std::string& address, const std::string& signature) const override;
std::string get_tx_key(const std::string& tx_hash) const override;
std::shared_ptr<monero_check_tx> check_tx_key(const std::string& tx_hash, const std::string& txKey, const std::string& address) const override;
std::string get_tx_proof(const std::string& tx_hash, const std::string& address, const std::string& message) const override;
std::shared_ptr<monero_check_tx> check_tx_proof(const std::string& tx_hash, const std::string& address, const std::string& message, const std::string& signature) const override;
std::string get_spend_proof(const std::string& tx_hash, const std::string& message) const override;
bool check_spend_proof(const std::string& tx_hash, const std::string& message, const std::string& signature) const override;
std::string get_reserve_proof_wallet(const std::string& message) const override;
std::string get_reserve_proof_account(uint32_t account_idx, uint64_t amount, const std::string& message) const override;
std::shared_ptr<monero_check_reserve> check_reserve_proof(const std::string& address, const std::string& message, const std::string& signature) const override;
std::string get_tx_note(const std::string& tx_hash) const override;
std::vector<std::string> get_tx_notes(const std::vector<std::string>& tx_hashes) const override;
void set_tx_note(const std::string& tx_hash, const std::string& note) override;
void set_tx_notes(const std::vector<std::string>& tx_hashes, const std::vector<std::string>& notes) override;
std::vector<monero_address_book_entry> get_address_book_entries(const std::vector<uint64_t>& indices) const override;
uint64_t add_address_book_entry(const std::string& address, const std::string& description) override;
void edit_address_book_entry(uint64_t index, bool set_address, const std::string& address, bool set_description, const std::string& description) override;
void delete_address_book_entry(uint64_t index) override;
std::string get_payment_uri(const monero_tx_config& config) const override;
std::shared_ptr<monero_tx_config> parse_payment_uri(const std::string& uri) const override;
bool get_attribute(const std::string& key, std::string& value) const override;
void set_attribute(const std::string& key, const std::string& val) override;
void start_mining(boost::optional<uint64_t> num_threads, boost::optional<bool> background_mining, boost::optional<bool> ignore_battery) override;
void stop_mining() override;
uint64_t wait_for_next_block() override;
bool is_multisig_import_needed() const override;
monero_multisig_info get_multisig_info() const override;
std::string prepare_multisig() override;
std::string make_multisig(const std::vector<std::string>& multisig_hexes, int threshold, const std::string& password) override;
monero_multisig_init_result exchange_multisig_keys(const std::vector<std::string>& multisig_hexes, const std::string& password) override;
std::string export_multisig_hex() override;
int import_multisig_hex(const std::vector<std::string>& multisig_hexes, const bool refresh_after_import = true) override;
monero_multisig_sign_result sign_multisig_tx_hex(const std::string& multisig_tx_hex) override;
std::vector<std::string> submit_multisig_tx_hex(const std::string& signed_multisig_tx_hex) override;
void change_password(const std::string& old_password, const std::string& new_password) override;
void move_to(const std::string& path, const std::string& password) override;
void save() override;
void close(bool save = false) override;
bool is_closed() const override { return m_is_closed; }
/**
* Wallet import and export using buffers and not the file system.
*/
std::string get_keys_file_buffer(const epee::wipeable_string& password, bool view_only) const;
std::string get_cache_file_buffer() const;
// --------------------------------- PROTECTED --------------------------------
protected:
std::unique_ptr<tools::wallet2> m_w2; // internal wallet implementation
void init_common();
// ---------------------------------- PRIVATE ---------------------------------
private:
friend struct wallet2_listener;
std::unique_ptr<wallet2_listener> m_w2_listener; // internal wallet implementation listener
std::set<monero_wallet_listener*> m_listeners; // external wallet listeners
std::atomic<bool> m_is_closed;
static monero_wallet_full* create_wallet_from_seed(monero_wallet_config& config, std::unique_ptr<epee::net_utils::http::http_client_factory> http_client_factory);
static monero_wallet_full* create_wallet_from_keys(monero_wallet_config& config, std::unique_ptr<epee::net_utils::http::http_client_factory> http_client_factory);
static monero_wallet_full* create_wallet_random(monero_wallet_config& config, std::unique_ptr<epee::net_utils::http::http_client_factory> http_client_factory);
std::vector<monero_subaddress> get_subaddresses_aux(uint32_t account_idx, const std::vector<uint32_t>& subaddress_indices, const std::vector<tools::wallet2::transfer_details>& transfers) const;
std::vector<std::shared_ptr<monero_transfer>> get_transfers_aux(const monero_transfer_query& query) const;
std::vector<std::shared_ptr<monero_output_wallet>> get_outputs_aux(const monero_output_query& query) const;
std::vector<std::shared_ptr<monero_tx_wallet>> sweep_account(const monero_tx_config& config); // sweeps unlocked funds within an account; private helper to sweep_unlocked()
void assert_not_closed() const;
// serializes a wallet operation with background sync: pauses the sync loop, interrupts background refresh, and locks m_sync_mutex
struct sync_op_lock {
sync_op_lock(const monero_wallet_full& wallet);
sync_op_lock(const sync_op_lock&) = delete;
~sync_op_lock();
const monero_wallet_full& m_wallet;
};
// blockchain sync management
mutable std::atomic<bool> m_is_synced; // whether or not wallet is synced
mutable std::atomic<bool> m_is_connected; // cache connection status to avoid unecessary RPC calls
boost::condition_variable m_sync_cv; // to make sync threads woke
mutable boost::mutex m_sync_mutex; // synchronize sync and other wallet operations
mutable std::atomic<uint32_t> m_num_sync_pauses; // number of operations pausing background sync
std::atomic<bool> m_background_syncing; // whether or not a background sync pass is in progress
std::atomic<bool> m_rescan_on_sync; // whether or not to rescan on sync
std::atomic<bool> m_syncing_enabled; // whether or not auto sync is enabled
std::atomic<bool> m_sync_loop_running; // whether or not the syncing thread is shut down
std::atomic<int> m_syncing_interval; // auto sync loop interval in milliseconds
boost::thread m_syncing_thread; // thread for auto sync loop
boost::mutex m_syncing_mutex; // synchronize auto sync loop
void run_sync_loop(); // run the sync loop in a thread
monero_sync_result lock_and_sync(boost::optional<uint64_t> start_height = boost::none, bool background = false); // internal function to synchronize request to sync and rescan
monero_sync_result sync_aux(boost::optional<uint64_t> start_height = boost::none); // internal function to immediately block, sync, and report progress
};
}
@@ -0,0 +1,320 @@
/**
* Copyright (c) woodser
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Parts of this file are originally copyright (c) 2014-2019, The Monero Project
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* All rights reserved.
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
*/
#include "monero_wallet_keys.h"
#include "utils/monero_utils.h"
#include <chrono>
#include <iostream>
#include "mnemonics/electrum-words.h"
#include "mnemonics/english.h"
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "cryptonote_basic/cryptonote_basic_impl.h"
#include "string_tools.h"
#include "device/device.hpp"
using namespace epee;
using namespace tools;
using namespace crypto;
/**
* Public library interface.
*/
namespace monero {
// ---------------------------- WALLET MANAGEMENT ---------------------------
monero_wallet_keys* monero_wallet_keys::create_wallet_random(const monero_wallet_config& config) {
// validate and normalize config
monero_wallet_config config_normalized = config.copy();
if (config_normalized.m_network_type == boost::none) throw std::runtime_error("Must provide wallet network type");
if (config_normalized.m_language == boost::none || config_normalized.m_language.get().empty()) config_normalized.m_language = "English";
if (!monero_utils::is_valid_language(config_normalized.m_language.get())) throw std::runtime_error("Unknown language: " + config_normalized.m_language.get());
// initialize random wallet account
monero_wallet_keys* wallet = new monero_wallet_keys();
crypto::secret_key spend_key_sk = wallet->m_account.generate();
// initialize remaining wallet
wallet->m_network_type = config_normalized.m_network_type.get();
wallet->m_language = config_normalized.m_language.get();
epee::wipeable_string wipeable_mnemonic;
if (!crypto::ElectrumWords::bytes_to_words(spend_key_sk, wipeable_mnemonic, wallet->m_language)) {
throw std::runtime_error("Failed to create mnemonic from private spend key for language: " + std::string(wallet->m_language));
}
wallet->m_seed = std::string(wipeable_mnemonic.data(), wipeable_mnemonic.size());
wallet->init_common();
return wallet;
}
monero_wallet_keys* monero_wallet_keys::create_wallet_from_seed(const monero_wallet_config& config) {
// validate config
if (config.m_is_multisig != boost::none && config.m_is_multisig.get()) throw std::runtime_error("Restoring from multisig seed not supported");
if (config.m_network_type == boost::none) throw std::runtime_error("Must provide wallet network type");
if (config.m_seed == boost::none || config.m_seed.get().empty()) throw std::runtime_error("Must provide wallet seed");
// validate mnemonic and get recovery key and language
crypto::secret_key spend_key_sk;
std::string language;
bool is_valid = crypto::ElectrumWords::words_to_bytes(config.m_seed.get(), spend_key_sk, language);
if (!is_valid) throw std::runtime_error("Invalid mnemonic");
if (language == crypto::ElectrumWords::old_language_name) language = Language::English().get_language_name();
// apply offset if given
if (config.m_seed_offset != boost::none && !config.m_seed_offset.get().empty()) spend_key_sk = cryptonote::decrypt_key(spend_key_sk, config.m_seed_offset.get());
// initialize wallet account
monero_wallet_keys* wallet = new monero_wallet_keys();
wallet->m_account = cryptonote::account_base{};
wallet->m_account.generate(spend_key_sk, true, false);
// initialize remaining wallet
wallet->m_network_type = config.m_network_type.get();
wallet->m_language = language;
epee::wipeable_string wipeable_mnemonic;
if (!crypto::ElectrumWords::bytes_to_words(spend_key_sk, wipeable_mnemonic, wallet->m_language)) {
throw std::runtime_error("Failed to create mnemonic from private spend key for language: " + std::string(wallet->m_language));
}
wallet->m_seed = std::string(wipeable_mnemonic.data(), wipeable_mnemonic.size());
wallet->init_common();
return wallet;
}
monero_wallet_keys* monero_wallet_keys::create_wallet_from_keys(const monero_wallet_config& config) {
// validate and normalize config
monero_wallet_config config_normalized = config.copy();
if (config.m_network_type == boost::none) throw std::runtime_error("Must provide wallet network type");
if (config.m_language == boost::none || config_normalized.m_language.get().empty()) config_normalized.m_language = "English";
if (config.m_private_spend_key == boost::none) config_normalized.m_private_spend_key = std::string("");
if (config.m_private_view_key == boost::none) config_normalized.m_private_view_key = std::string("");
if (!monero_utils::is_valid_language(config_normalized.m_language.get())) throw std::runtime_error("Unknown language: " + config_normalized.m_language.get());
// parse and validate private spend key
crypto::secret_key spend_key_sk;
bool has_spend_key = false;
if (!config_normalized.m_private_spend_key.get().empty()) {
cryptonote::blobdata spend_key_data;
if (!epee::string_tools::parse_hexstr_to_binbuff(config.m_private_spend_key.get(), spend_key_data) || spend_key_data.size() != sizeof(crypto::secret_key)) {
throw std::runtime_error("failed to parse secret spend key");
}
has_spend_key = true;
spend_key_sk = *reinterpret_cast<const crypto::secret_key*>(spend_key_data.data());
}
// parse and validate private view key
bool has_view_key = true;
crypto::secret_key view_key_sk;
if (config_normalized.m_private_view_key.get().empty()) {
if (has_spend_key) has_view_key = false;
else throw std::runtime_error("Neither spend key nor view key supplied");
}
if (has_view_key) {
cryptonote::blobdata view_key_data;
if (!epee::string_tools::parse_hexstr_to_binbuff(config_normalized.m_private_view_key.get(), view_key_data) || view_key_data.size() != sizeof(crypto::secret_key)) {
throw std::runtime_error("failed to parse secret view key");
}
view_key_sk = *reinterpret_cast<const crypto::secret_key*>(view_key_data.data());
}
// parse and validate address
cryptonote::address_parse_info address_info;
if (config_normalized.m_primary_address.get().empty()) {
if (has_view_key) throw std::runtime_error("must provide address if providing private view key");
} else {
if (!get_account_address_from_str(address_info, static_cast<cryptonote::network_type>(config_normalized.m_network_type.get()), config_normalized.m_primary_address.get())) throw std::runtime_error("failed to parse address");
// check the spend and view keys match the given address
crypto::public_key pkey;
if (has_spend_key) {
if (!crypto::secret_key_to_public_key(spend_key_sk, pkey)) throw std::runtime_error("failed to verify secret spend key");
if (address_info.address.m_spend_public_key != pkey) throw std::runtime_error("spend key does not match address");
}
if (has_view_key) {
if (!crypto::secret_key_to_public_key(view_key_sk, pkey)) throw std::runtime_error("failed to verify secret view key");
if (address_info.address.m_view_public_key != pkey) throw std::runtime_error("view key does not match address");
}
}
// initialize wallet account
monero_wallet_keys* wallet = new monero_wallet_keys();
if (has_spend_key && has_view_key) {
wallet->m_account.create_from_keys(address_info.address, spend_key_sk, view_key_sk);
} else if (has_spend_key) {
wallet->m_account.generate(spend_key_sk, true, false);
} else {
wallet->m_account.create_from_viewkey(address_info.address, view_key_sk);
}
// initialize remaining wallet
wallet->m_is_view_only = !has_spend_key;
wallet->m_network_type = config_normalized.m_network_type.get();
if (!config_normalized.m_private_spend_key.get().empty()) {
wallet->m_language = config_normalized.m_language.get();
epee::wipeable_string wipeable_mnemonic;
if (!crypto::ElectrumWords::bytes_to_words(spend_key_sk, wipeable_mnemonic, wallet->m_language)) {
throw std::runtime_error("Failed to create mnemonic from private spend key for language: " + std::string(wallet->m_language));
}
wallet->m_seed = std::string(wipeable_mnemonic.data(), wipeable_mnemonic.size());
}
wallet->init_common();
return wallet;
}
std::vector<std::string> monero_wallet_keys::get_seed_languages() {
std::vector<std::string> languages;
crypto::ElectrumWords::get_language_list(languages, true); // TODO: support getting names in language
return languages;
}
// ----------------------------- WALLET METHODS -----------------------------
monero_wallet_keys::~monero_wallet_keys() {
MTRACE("~monero_wallet_keys()");
close();
}
monero_version monero_wallet_keys::get_version() const {
monero_version version;
version.m_number = 65552; // same as monero-wallet-rpc v0.15.0.1 release
version.m_is_release = false; // TODO: could pull from MONERO_VERSION_IS_RELEASE in version.cpp
return version;
}
std::string monero_wallet_keys::get_address(uint32_t account_idx, uint32_t subaddress_idx) const {
hw::device &hwdev = m_account.get_device();
cryptonote::subaddress_index index{account_idx, subaddress_idx};
cryptonote::account_public_address address = hwdev.get_subaddress(m_account.get_keys(), index);
return cryptonote::get_account_address_as_str(static_cast<cryptonote::network_type>(m_network_type), !index.is_zero(), address);
}
monero_integrated_address monero_wallet_keys::get_integrated_address(const std::string& standard_address, const std::string& payment_id) const {
MTRACE("monero_wallet_keys::get_integrated_address()");
throw std::runtime_error("monero_wallet_keys::get_integrated_address() not implemented");
}
monero_integrated_address monero_wallet_keys::decode_integrated_address(const std::string& integrated_address) const {
MTRACE("monero_wallet_keys::decode_integrated_address()");
throw std::runtime_error("monero_wallet_keys::decode_integrated_address() not implemented");
}
monero_account monero_wallet_keys::get_account(uint32_t account_idx, bool include_subaddresses) const {
MTRACE("monero_wallet_keys::get_account()");
if (include_subaddresses) {
std::string err = "monero_wallet_keys::get_account(account_idx, include_subaddresses) include_subaddresses must be false";
MERROR(err);
throw std::runtime_error(err);
}
// build and return account
monero_account account;
account.m_index = account_idx;
account.m_primary_address = get_address(account_idx, 0);
return account;
}
std::vector<monero_subaddress> monero_wallet_keys::get_subaddresses(const uint32_t account_idx, const std::vector<uint32_t>& subaddress_indices) const {
// must provide subaddress indices
if (subaddress_indices.empty()) {
std::string err = "Keys-only wallet does not have enumerable set of subaddresses; specific specific subaddresses";
MERROR(err);
throw std::runtime_error(err);
}
// initialize subaddresses at indices
std::vector<monero_subaddress> subaddresses;
for (uint32_t subaddressIndicesIdx = 0; subaddressIndicesIdx < subaddress_indices.size(); subaddressIndicesIdx++) {
monero_subaddress subaddress;
subaddress.m_account_index = account_idx;
uint32_t subaddress_idx = subaddress_indices.at(subaddressIndicesIdx);
subaddress.m_index = subaddress_idx;
subaddress.m_address = get_address(account_idx, subaddress_idx);
subaddresses.push_back(subaddress);
}
return subaddresses;
}
std::string monero_wallet_keys::sign_message(const std::string& msg, monero_message_signature_type signature_type, uint32_t account_idx, uint32_t subaddress_idx) const {
MTRACE("monero_wallet_keys::sign_message()");
throw std::runtime_error("monero_wallet_keys::sign_message() not implemented");
}
monero_message_signature_result monero_wallet_keys::verify_message(const std::string& msg, const std::string& address, const std::string& signature) const {
MTRACE("monero_wallet_keys::verify_message()");
throw std::runtime_error("monero_wallet_keys::verify_message() not implemented");
}
void monero_wallet_keys::close(bool save) {
if (save) throw std::runtime_error("MoneroWalletKeys does not support saving");
// no pointers to destroy
}
// ------------------------------- PRIVATE HELPERS ----------------------------
void monero_wallet_keys::init_common() {
m_primary_address = m_account.get_public_address_str(static_cast<cryptonote::network_type>(m_network_type));
const cryptonote::account_keys& keys = m_account.get_keys();
m_pub_view_key = epee::string_tools::pod_to_hex(keys.m_account_address.m_view_public_key);
m_prv_view_key = epee::string_tools::pod_to_hex(unwrap(unwrap(keys.m_view_secret_key)));
m_pub_spend_key = epee::string_tools::pod_to_hex(keys.m_account_address.m_spend_public_key);
m_prv_spend_key = epee::string_tools::pod_to_hex(unwrap(unwrap(keys.m_spend_secret_key)));
if (m_prv_spend_key == "0000000000000000000000000000000000000000000000000000000000000000") m_prv_spend_key = "";
}
}
@@ -0,0 +1,147 @@
/**
* Copyright (c) woodser
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Parts of this file are originally copyright (c) 2014-2019, The Monero Project
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* All rights reserved.
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
*/
#pragma once
#include "monero_wallet.h"
#include "cryptonote_basic/account.h"
using namespace monero;
/**
* Public library interface.
*/
namespace monero {
/**
* Implements a Monero wallet to provide basic key management.
*/
class monero_wallet_keys : public monero_wallet {
public:
// --------------------------- STATIC WALLET UTILS --------------------------
/**
* Create a new wallet with a randomly generated seed.
*
* @param config is the wallet configuration (network type and language)
*/
static monero_wallet_keys* create_wallet_random(const monero_wallet_config& config);
/**
* Create a wallet from an existing mnemonic phrase or seed.
*
* @param config is the wallet configuration (network type, seed, seed offset, isMultisig)
*/
static monero_wallet_keys* create_wallet_from_seed(const monero_wallet_config& config);
/**
* Create a wallet from an address, view key, and spend key.
*
* @param config is the wallet configuration (network type, address, view key, spend key, language)
*/
static monero_wallet_keys* create_wallet_from_keys(const monero_wallet_config& config);
/**
* Get a list of available languages for the wallet's seed.
*
* @return the available languages for the wallet's seed
*/
static std::vector<std::string> get_seed_languages();
// ----------------------------- WALLET METHODS -----------------------------
/**
* Destruct the wallet.
*/
~monero_wallet_keys();
/**
* Supported wallet methods.
*/
bool is_view_only() const override { return m_is_view_only; }
monero_version get_version() const override;
monero_network_type get_network_type() const override { return m_network_type; }
std::string get_seed() const override { return m_seed; }
std::string get_seed_language() const override { return m_language; }
std::string get_private_view_key() const override { return m_prv_view_key; }
std::string get_private_spend_key() const override { return m_prv_spend_key; }
std::string get_public_view_key() const override { return m_pub_view_key; }
std::string get_public_spend_key() const override { return m_pub_spend_key; }
std::string get_primary_address() const override { return m_primary_address; }
std::string get_address(const uint32_t account_idx, const uint32_t subaddress_idx) const override;
monero_integrated_address get_integrated_address(const std::string& standard_address = "", const std::string& payment_id = "") const override;
monero_integrated_address decode_integrated_address(const std::string& integrated_address) const override;
monero_account get_account(const uint32_t account_idx, bool include_subaddresses) const override;
std::vector<monero_subaddress> get_subaddresses(const uint32_t account_idx, const std::vector<uint32_t>& subaddress_indices) const override;
std::string sign_message(const std::string& msg, monero_message_signature_type signature_type, uint32_t account_idx = 0, uint32_t subaddress_idx = 0) const override;
monero_message_signature_result verify_message(const std::string& msg, const std::string& address, const std::string& signature) const override;
void close(bool save = false) override;
// --------------------------------- PRIVATE --------------------------------
private:
bool m_is_view_only;
monero_network_type m_network_type;
cryptonote::account_base m_account;
std::string m_seed;
std::string m_language;
std::string m_pub_view_key;
std::string m_prv_view_key;
std::string m_pub_spend_key;
std::string m_prv_spend_key;
std::string m_primary_address;
void init_common();
};
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,609 @@
/**
* Copyright (c) woodser
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Parts of this file are originally copyright (c) 2014-2019, The Monero Project
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* All rights reserved.
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
*/
#pragma once
#include "common/monero_rpc_connection.h"
#include "daemon/monero_daemon_model.h"
using namespace monero;
/**
* Public library interface.
*/
namespace monero {
/**
* Configures a wallet to create.
*/
struct monero_wallet_config : public serializable_struct {
boost::optional<std::string> m_path;
boost::optional<std::string> m_password;
boost::optional<monero_network_type> m_network_type;
std::shared_ptr<monero_rpc_connection> m_server;
boost::optional<bool> m_is_trusted_daemon;
boost::optional<std::string> m_seed;
boost::optional<std::string> m_seed_offset;
boost::optional<std::string> m_primary_address;
boost::optional<std::string> m_private_view_key;
boost::optional<std::string> m_private_spend_key;
boost::optional<uint64_t> m_restore_height;
boost::optional<std::string> m_language;
boost::optional<bool> m_save_current;
boost::optional<uint64_t> m_account_lookahead;
boost::optional<uint64_t> m_subaddress_lookahead;
boost::optional<bool> m_is_multisig;
boost::optional<bool> m_regtest;
monero_wallet_config() {}
monero_wallet_config(const monero_wallet_config& config);
monero_wallet_config copy() const;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static std::shared_ptr<monero_wallet_config> deserialize(const std::string& config_json);
};
/**
* Models a result of syncing a wallet.
*/
struct monero_sync_result : public serializable_struct {
uint64_t m_num_blocks_fetched;
bool m_received_money;
monero_sync_result() {}
monero_sync_result(const uint64_t num_blocks_fetched, const bool received_money) : m_num_blocks_fetched(num_blocks_fetched), m_received_money(received_money) {}
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
};
/**
* Models a Monero subaddress.
*/
struct monero_subaddress : public serializable_struct {
boost::optional<uint32_t> m_account_index;
boost::optional<uint32_t> m_index;
boost::optional<std::string> m_address;
boost::optional<std::string> m_label;
boost::optional<uint64_t> m_balance;
boost::optional<uint64_t> m_unlocked_balance;
boost::optional<uint64_t> m_num_unspent_outputs;
boost::optional<bool> m_is_used;
boost::optional<uint64_t> m_num_blocks_to_unlock;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_subaddress>& subaddress);
};
/**
* Models a Monero account.
*/
struct monero_account : public serializable_struct {
boost::optional<uint32_t> m_index;
boost::optional<std::string> m_primary_address;
boost::optional<uint64_t> m_balance;
boost::optional<uint64_t> m_unlocked_balance;
boost::optional<std::string> m_tag;
std::vector<monero_subaddress> m_subaddresses;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_account>& account);
};
/**
* Models an outgoing transfer destination.
*/
struct monero_destination : public serializable_struct {
boost::optional<std::string> m_address;
boost::optional<uint64_t> m_amount;
monero_destination(boost::optional<std::string> address = boost::none, boost::optional<uint64_t> amount = boost::none) : m_address(address), m_amount(amount) {}
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_destination>& destination);
std::shared_ptr<monero_destination> copy(const std::shared_ptr<monero_destination>& src, const std::shared_ptr<monero_destination>& tgt) const;
};
// forward declarations
struct monero_tx_config;
struct monero_tx_wallet;
struct monero_tx_query;
struct monero_tx_set;
/**
* Models a base transfer of funds to or from the wallet.
*
* TODO: m_is_incoming for api consistency
*/
struct monero_transfer : public serializable_struct {
std::shared_ptr<monero_tx_wallet> m_tx;
boost::optional<uint64_t> m_amount;
boost::optional<uint32_t> m_account_index;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_transfer>& transfer);
virtual boost::optional<bool> is_incoming() const = 0; // derived class must implement
std::shared_ptr<monero_transfer> copy(const std::shared_ptr<monero_transfer>& src, const std::shared_ptr<monero_transfer>& tgt) const;
boost::optional<bool> is_outgoing() const {
if (is_incoming() == boost::none) return boost::none;
return !(*is_incoming());
}
void merge(const std::shared_ptr<monero_transfer>& self, const std::shared_ptr<monero_transfer>& other);
};
/**
* Models an incoming transfer of funds to the wallet.
*/
struct monero_incoming_transfer : public monero_transfer {
boost::optional<uint32_t> m_subaddress_index;
boost::optional<std::string> m_address;
boost::optional<uint64_t> m_num_suggested_confirmations;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
std::shared_ptr<monero_incoming_transfer> copy(const std::shared_ptr<monero_transfer>& src, const std::shared_ptr<monero_transfer>& tgt) const;
std::shared_ptr<monero_incoming_transfer> copy(const std::shared_ptr<monero_incoming_transfer>& src, const std::shared_ptr<monero_incoming_transfer>& tgt) const;
boost::optional<bool> is_incoming() const;
void merge(const std::shared_ptr<monero_transfer>& self, const std::shared_ptr<monero_transfer>& other);
void merge(const std::shared_ptr<monero_incoming_transfer>& self, const std::shared_ptr<monero_incoming_transfer>& other);
};
/**
* Models an outgoing transfer of funds from the wallet.
*/
struct monero_outgoing_transfer : public monero_transfer {
std::vector<uint32_t> m_subaddress_indices;
std::vector<std::string> m_addresses;
std::vector<std::shared_ptr<monero_destination>> m_destinations;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
std::shared_ptr<monero_outgoing_transfer> copy(const std::shared_ptr<monero_transfer>& src, const std::shared_ptr<monero_transfer>& tgt) const;
std::shared_ptr<monero_outgoing_transfer> copy(const std::shared_ptr<monero_outgoing_transfer>& src, const std::shared_ptr<monero_outgoing_transfer>& tgt) const;
boost::optional<bool> is_incoming() const;
void merge(const std::shared_ptr<monero_transfer>& self, const std::shared_ptr<monero_transfer>& other);
void merge(const std::shared_ptr<monero_outgoing_transfer>& self, const std::shared_ptr<monero_outgoing_transfer>& other);
};
/**
* Configures a query to retrieve transfers.
*
* All transfers are returned except those that do not meet the criteria defined in this query.
*/
struct monero_transfer_query : public monero_transfer {
boost::optional<bool> m_is_incoming;
boost::optional<std::string> m_address;
std::vector<std::string> m_addresses;
boost::optional<uint32_t> m_subaddress_index;
std::vector<uint32_t> m_subaddress_indices;
std::vector<std::shared_ptr<monero_destination>> m_destinations;
boost::optional<bool> m_has_destinations;
std::shared_ptr<monero_tx_query> m_tx_query;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_transfer_query>& transfer_query);
static std::shared_ptr<monero_transfer_query> deserialize_from_block(const std::string& transfer_query_json);
static bool is_contextual(const monero_transfer_query& query);
std::shared_ptr<monero_transfer_query> copy(const std::shared_ptr<monero_transfer>& src, const std::shared_ptr<monero_transfer>& tgt) const;
std::shared_ptr<monero_transfer_query> copy(const std::shared_ptr<monero_transfer_query>& src, const std::shared_ptr<monero_transfer_query>& tgt) const;
boost::optional<bool> is_incoming() const;
bool meets_criteria(monero_transfer* transfer, bool query_parent = true) const;
};
/**
* Models a Monero output with wallet extensions.
*/
struct monero_output_wallet : public monero_output {
boost::optional<uint32_t> m_account_index;
boost::optional<uint32_t> m_subaddress_index;
boost::optional<bool> m_is_spent;
boost::optional<bool> m_is_frozen;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_output_wallet>& output_wallet);
std::shared_ptr<monero_output_wallet> copy(const std::shared_ptr<monero_output>& src, const std::shared_ptr<monero_output>& tgt) const;
std::shared_ptr<monero_output_wallet> copy(const std::shared_ptr<monero_output_wallet>& src, const std::shared_ptr<monero_output_wallet>& tgt) const;
void merge(const std::shared_ptr<monero_output>& self, const std::shared_ptr<monero_output>& other);
void merge(const std::shared_ptr<monero_output_wallet>& self, const std::shared_ptr<monero_output_wallet>& other);
};
/**
* Configures a query to retrieve wallet outputs (i.e. outputs that the wallet has or had the
* ability to spend).
*
* All outputs are returned except those that do not meet the criteria defined in this query.
*/
struct monero_output_query : public monero_output_wallet {
std::vector<uint32_t> m_subaddress_indices;
boost::optional<uint64_t> m_min_amount;
boost::optional<uint64_t> m_max_amount;
std::shared_ptr<monero_tx_query> m_tx_query;
//boost::property_tree::ptree to_property_tree() const;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_output_query>& output_query);
static std::shared_ptr<monero_output_query> deserialize_from_block(const std::string& output_query_json);
static bool is_contextual(const monero_output_query& query);
std::shared_ptr<monero_output_query> copy(const std::shared_ptr<monero_output>& src, const std::shared_ptr<monero_output>& tgt) const;
std::shared_ptr<monero_output_query> copy(const std::shared_ptr<monero_output_wallet>& src, const std::shared_ptr<monero_output_wallet>& tgt) const; // TODO: necessary to override all super classes?
std::shared_ptr<monero_output_query> copy(const std::shared_ptr<monero_output_query>& src, const std::shared_ptr<monero_output_query>& tgt) const;
bool meets_criteria(monero_output_wallet* output, bool query_parent = true) const;
};
/**
* Models a Monero transaction in the context of a wallet.
*/
struct monero_tx_wallet : public monero_tx {
std::shared_ptr<monero_tx_set> m_tx_set;
boost::optional<bool> m_is_incoming;
boost::optional<bool> m_is_outgoing;
std::vector<std::shared_ptr<monero_incoming_transfer>> m_incoming_transfers;
std::shared_ptr<monero_outgoing_transfer> m_outgoing_transfer;
boost::optional<std::string> m_note;
boost::optional<bool> m_is_locked;
boost::optional<uint64_t> m_input_sum;
boost::optional<uint64_t> m_output_sum;
boost::optional<std::string> m_change_address;
boost::optional<uint64_t> m_change_amount;
boost::optional<uint32_t> m_num_dummy_outputs;
boost::optional<std::string> m_extra_hex;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_tx_wallet>& tx_wallet);
std::shared_ptr<monero_tx_wallet> copy(const std::shared_ptr<monero_tx>& src, const std::shared_ptr<monero_tx>& tgt) const;
std::shared_ptr<monero_tx_wallet> copy(const std::shared_ptr<monero_tx_wallet>& src, const std::shared_ptr<monero_tx_wallet>& tgt) const;
void merge(const std::shared_ptr<monero_tx>& self, const std::shared_ptr<monero_tx>& other);
void merge(const std::shared_ptr<monero_tx_wallet>& self, const std::shared_ptr<monero_tx_wallet>& other);
std::vector<std::shared_ptr<monero_transfer>> get_transfers() const;
std::vector<std::shared_ptr<monero_transfer>> get_transfers(const monero_transfer_query& query) const;
std::vector<std::shared_ptr<monero_transfer>> filter_transfers(const monero_transfer_query& query);
std::vector<std::shared_ptr<monero_output_wallet>> get_outputs_wallet() const;
std::vector<std::shared_ptr<monero_output_wallet>> get_outputs_wallet(const monero_output_query& query) const;
std::vector<std::shared_ptr<monero_output_wallet>> filter_outputs_wallet(const monero_output_query& query);
};
/**
* Configures a query to retrieve transactions.
*
* All transactions are returned except those that do not meet the criteria defined in this query.
*/
struct monero_tx_query : public monero_tx_wallet {
boost::optional<bool> m_is_outgoing;
boost::optional<bool> m_is_incoming;
std::vector<std::string> m_hashes;
boost::optional<bool> m_has_payment_id;
std::vector<std::string> m_payment_ids;
boost::optional<uint64_t> m_height;
boost::optional<uint64_t> m_min_height;
boost::optional<uint64_t> m_max_height;
boost::optional<uint64_t> m_include_outputs;
std::shared_ptr<monero_transfer_query> m_transfer_query;
std::shared_ptr<monero_output_query> m_input_query;
std::shared_ptr<monero_output_query> m_output_query;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_tx_query>& tx_query);
static std::shared_ptr<monero_tx_query> deserialize_from_block(const std::string& tx_query_json);
/**
* Remove query criteria which require looking up other transfers/outputs to
* fulfill query.
*
* @param query the query to decontextualize
* @return a reference to the query for convenience
*/
static std::shared_ptr<monero_tx_query> decontextualize(std::shared_ptr<monero_tx_query> query);
std::shared_ptr<monero_tx_query> copy(const std::shared_ptr<monero_tx>& src, const std::shared_ptr<monero_tx>& tgt) const;
std::shared_ptr<monero_tx_query> copy(const std::shared_ptr<monero_tx_wallet>& src, const std::shared_ptr<monero_tx_wallet>& tgt) const; // TODO: necessary to override all super classes?
std::shared_ptr<monero_tx_query> copy(const std::shared_ptr<monero_tx_query>& src, const std::shared_ptr<monero_tx_query>& tgt) const;
bool meets_criteria(monero_tx_wallet* tx, bool query_children = true) const;
};
/**
* Groups transactions who share common hex data which is needed in order to
* sign and submit the transactions.
*
* For example, multisig transactions created from create_txs() share a common
* hex string which is needed in order to sign and submit the multisig
* transactions.
*/
struct monero_tx_set : public serializable_struct {
std::vector<std::shared_ptr<monero_tx_wallet>> m_txs;
boost::optional<std::string> m_signed_tx_hex;
boost::optional<std::string> m_unsigned_tx_hex;
boost::optional<std::string> m_multisig_tx_hex;
//boost::property_tree::ptree to_property_tree() const;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_tx_set>& set);
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static monero_tx_set deserialize(const std::string& tx_set_json);
};
/**
* Monero integrated address model.
*/
struct monero_integrated_address : public serializable_struct {
std::string m_standard_address;
std::string m_payment_id;
std::string m_integrated_address;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_integrated_address>& subaddress);
};
/**
* Enumerates Monero network types.
*/
enum monero_tx_priority : uint8_t {
DEFAULT = 0,
UNIMPORTANT,
NORMAL,
ELEVATED
};
/**
* Configures a transaction to send, sweep, or create a payment URI.
*/
struct monero_tx_config : public serializable_struct {
boost::optional<std::string> m_address;
boost::optional<uint64_t> m_amount;
std::vector<std::shared_ptr<monero_destination>> m_destinations;
std::vector<uint32_t> m_subtract_fee_from;
boost::optional<std::string> m_payment_id;
boost::optional<monero_tx_priority> m_priority;
boost::optional<uint32_t> m_ring_size;
boost::optional<uint64_t> m_fee;
boost::optional<uint32_t> m_account_index;
std::vector<uint32_t> m_subaddress_indices;
boost::optional<bool> m_can_split;
boost::optional<bool> m_relay;
boost::optional<std::string> m_note;
boost::optional<std::string> m_recipient_name;
boost::optional<uint64_t> m_below_amount;
boost::optional<bool> m_sweep_each_subaddress;
boost::optional<std::string> m_key_image;
monero_tx_config() {}
monero_tx_config(const monero_tx_config& config);
monero_tx_config copy() const;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static std::shared_ptr<monero_tx_config> deserialize(const std::string& config_json);
std::vector<std::shared_ptr<monero_destination>> get_normalized_destinations() const;
};
/**
* Models results from exporting signed key images.
*/
struct monero_key_image_export_result : public serializable_struct {
boost::optional<uint64_t> m_offset;
std::vector<std::shared_ptr<monero_key_image>> m_key_images;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static std::shared_ptr<monero_key_image_export_result> deserialize(const std::string& result_json);
};
/**
* Models results from importing key images.
*/
struct monero_key_image_import_result : public serializable_struct {
boost::optional<uint64_t> m_height;
boost::optional<uint64_t> m_spent_amount;
boost::optional<uint64_t> m_unspent_amount;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_key_image_import_result>& result);
};
/**
* Enumerates message verification results.
*/
enum monero_message_signature_type : uint8_t {
SIGN_WITH_SPEND_KEY = 0,
SIGN_WITH_VIEW_KEY
};
/**
* Models results from message verification.
*/
struct monero_message_signature_result : public serializable_struct {
bool m_is_good;
uint32_t m_version;
bool m_is_old;
monero_message_signature_type m_signature_type;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_message_signature_result> result);
};
/**
* Base class for results from checking a transaction or reserve proof.
*/
struct monero_check : public serializable_struct {
bool m_is_good;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
};
/**
* Results from checking a transaction key.
*/
struct monero_check_tx : public monero_check {
boost::optional<bool> m_in_tx_pool;
boost::optional<uint64_t> m_num_confirmations;
boost::optional<uint64_t> m_received_amount;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_check_tx>& check);
};
/**
* Results from checking a reserve proof.
*/
struct monero_check_reserve : public monero_check {
boost::optional<uint64_t> m_total_amount;
boost::optional<uint64_t> m_unconfirmed_spent_amount;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_check_reserve>& check);
};
/**
* Models information about a multisig wallet.
*/
struct monero_multisig_info : public serializable_struct {
bool m_is_multisig;
bool m_is_ready;
uint32_t m_threshold;
uint32_t m_num_participants;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_multisig_info>& info);
};
/**
* Models the result of initializing a multisig wallet which results in the
* multisig wallet's address xor another multisig hex to share with
* participants to create the wallet.
*/
struct monero_multisig_init_result : public serializable_struct {
boost::optional<std::string> m_address;
boost::optional<std::string> m_multisig_hex;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_multisig_init_result>& res);
};
/**
* Models the result of signing multisig tx hex.
*/
struct monero_multisig_sign_result : public serializable_struct {
boost::optional<std::string> m_signed_multisig_tx_hex;
std::vector<std::string> m_tx_hashes;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_multisig_sign_result>& res);
};
/**
* Monero address book entry model.
*/
struct monero_address_book_entry : public serializable_struct {
boost::optional<uint64_t> m_index; // TODO: not boost::optional
boost::optional<std::string> m_address;
boost::optional<std::string> m_description;
boost::optional<std::string> m_payment_id;
monero_address_book_entry() {}
monero_address_book_entry(uint64_t index, const std::string& address, const std::string& description) : m_index(index), m_address(address), m_description(description) {}
monero_address_book_entry(uint64_t index, const std::string& address, const std::string& description, const std::string& payment_id) : m_index(index), m_address(address), m_description(description), m_payment_id(payment_id) {}
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_address_book_entry>& entry);
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const;
};
/**
* Models a Monero address type.
*/
enum monero_address_type : uint8_t {
PRIMARY_ADDRESS = 0,
INTEGRATED_ADDRESS,
SUBADDRESS
};
/**
* Compares two transactions by their height.
*/
struct monero_tx_height_comparator {
bool operator()(const std::shared_ptr<monero_tx>& tx1, const std::shared_ptr<monero_tx>& tx2) const;
};
/**
* Compares two transfers by ascending account and subaddress indices.
*/
struct monero_incoming_transfer_comparator {
bool operator()(const std::shared_ptr<monero_incoming_transfer>& t1, const std::shared_ptr<monero_incoming_transfer>& t2) const;
bool operator()(const monero_incoming_transfer& t1, const monero_incoming_transfer& t2) const;
};
/**
* Compares two outputs by ascending account and subaddress indices.
*/
struct monero_output_comparator {
bool operator()(const monero_output_wallet& o1, const monero_output_wallet& o2) const;
};
/**
* Maintains metadata for a decoded address.
*/
struct monero_decoded_address : public serializable_struct {
std::string m_address;
monero_address_type m_address_type;
monero_network_type m_network_type;
monero_decoded_address(const std::string& address, monero_address_type address_type, monero_network_type network_type);
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
/**
* Represents an account tag.
*/
struct monero_account_tag : public serializable_struct {
boost::optional<std::string> m_tag;
boost::optional<std::string> m_label;
std::vector<uint32_t> m_account_indices;
monero_account_tag() { }
monero_account_tag(const std::string& tag, const std::string& label): m_tag(tag), m_label(label) { }
monero_account_tag(const std::string& tag, const std::string& label, const std::vector<uint32_t>& account_indices): m_tag(tag), m_label(label), m_account_indices(account_indices) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_account_tag>& account_tag);
};
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,282 @@
/**
* Copyright (c) everoddandeven
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Parts of this file are originally copyright (c) 2025-2026 woodser
*
* Parts of this file are originally copyright (c) 2014-2019, The Monero Project
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* All rights reserved.
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
*/
#pragma once
#include "monero_wallet.h"
/**
* Implements a monero_wallet.h by wrapping monero-project's monero-wallet-rpc.
*/
namespace monero {
// forward declaration of internal wallet poller
class monero_wallet_poller;
/**
* Implements a Monero wallet using monero-wallet-rpc.
*/
class monero_wallet_rpc : public monero_wallet {
public:
/**
* Destruct the wallet.
*/
~monero_wallet_rpc();
monero_wallet_rpc(const std::shared_ptr<monero_rpc_connection>& rpc_connection);
monero_wallet_rpc(const std::string& uri = "", const std::string& username = "", const std::string& password = "", const std::string& proxy_uri = "", const std::string& zmq_uri = "", const boost::optional<uint32_t>& timeout = boost::none);
/**
* Set the wallet poll period.
*
* @param period_ms poll period in milliseconds.
*/
void set_poll_period_in_ms(uint64_t period_ms);
/**
* Open an existing wallet from rpc server.
*
* @param config is the wallet configuration
* @return a pointer to the wallet instance
*/
monero_wallet_rpc* open_wallet(const std::shared_ptr<monero_wallet_config> &config);
/**
* Open an existing wallet from rpc server.
*
* @param name is the wallet's name to open
* @param password is the password of the wallet file to open
* @return a pointer to the wallet instance
*/
monero_wallet_rpc* open_wallet(const std::string& name, const std::string& password);
/**
* Create a new wallet with the given configuration.
*
* @param config is the wallet configuration
* @return a pointer to the wallet instance
*/
monero_wallet_rpc* create_wallet(const std::shared_ptr<monero_wallet_config> &config);
/**
* Get the wallet's RPC connection.
*
* @return the wallet's rpc connection
*/
std::shared_ptr<monero_rpc_connection> get_rpc_connection() const { return m_rpc; }
/**
* Get a list of available languages for the wallet's seed.
*
* @return the available languages for the wallet's seed
*/
std::vector<std::string> get_seed_languages() const;
/**
* Save and close the current wallet and stop the RPC server.
*/
void stop();
/**
* Supported wallet methods.
*/
void add_listener(monero_wallet_listener& listener) override;
void remove_listener(monero_wallet_listener& listener) override;
std::set<monero_wallet_listener*> get_listeners() override;
bool is_view_only() const override;
std::shared_ptr<monero_rpc_connection> get_daemon_connection() const override;
void set_daemon_connection(const std::shared_ptr<monero_rpc_connection>& connection, bool is_trusted, const boost::optional<ssl_options>& ssl_options);
void set_daemon_connection(const std::shared_ptr<monero_rpc_connection>& connection, const boost::optional<bool>& is_trusted = boost::none) override;
void set_daemon_connection(const std::string& uri, const std::string& username = "", const std::string& password = "", const std::string& proxy_uri = "", const boost::optional<bool>& is_trusted = boost::none) override;
bool is_connected_to_daemon() const override;
monero_version get_version() const override;
std::string get_path() const override;
std::string get_seed() const override;
std::string get_seed_language() const override;
std::string get_public_view_key() const override;
std::string get_private_view_key() const override;
std::string get_public_spend_key() const override;
std::string get_private_spend_key() const override;
std::string get_address(const uint32_t account_idx, const uint32_t subaddress_idx) const override;
monero_subaddress get_address_index(const std::string& address) const override;
monero_integrated_address get_integrated_address(const std::string& standard_address = "", const std::string& payment_id = "") const override;
monero_integrated_address decode_integrated_address(const std::string& integrated_address) const override;
uint64_t get_height() const override;
uint64_t get_daemon_height() const override;
uint64_t get_height_by_date(uint16_t year, uint8_t month, uint8_t day) const override;
monero_sync_result sync() override;
monero_sync_result sync(monero_wallet_listener& listener) override;
monero_sync_result sync(uint64_t start_height, monero_wallet_listener& listener) override;
monero_sync_result sync(uint64_t start_height) override;
void start_syncing(uint64_t sync_period_in_ms = 10000) override;
void stop_syncing() override;
void scan_txs(const std::vector<std::string>& tx_hashes) override;
void rescan_spent() override;
void rescan_blockchain() override;
uint64_t get_balance() const override;
uint64_t get_balance(uint32_t account_index) const override;
uint64_t get_balance(uint32_t account_idx, uint32_t subaddress_idx) const override;
uint64_t get_unlocked_balance() const override;
uint64_t get_unlocked_balance(uint32_t account_index) const override;
uint64_t get_unlocked_balance(uint32_t account_idx, uint32_t subaddress_idx) const override;
monero_account get_account(const uint32_t account_idx, bool include_subaddresses) const override;
monero_account get_account(const uint32_t account_idx, bool include_subaddresses, bool skip_balances) const;
std::vector<monero_account> get_accounts(bool include_subaddresses, const std::string& tag) const override;
std::vector<monero_account> get_accounts(bool include_subaddresses, const std::string& tag, bool skip_balances) const;
monero_account create_account(const std::string& label = "") override;
std::vector<monero_subaddress> get_subaddresses(const uint32_t account_idx, const std::vector<uint32_t>& subaddress_indices, bool skip_balances) const;
std::vector<monero_subaddress> get_subaddresses(uint32_t account_idx, const std::vector<uint32_t>& subaddress_indices) const override;
std::vector<monero_subaddress> get_subaddresses(const uint32_t account_idx) const override;
monero_subaddress get_subaddress(const uint32_t account_idx, const uint32_t subaddress_idx) const override;
monero_subaddress create_subaddress(uint32_t account_idx, const std::string& label = "") override;
void set_subaddress_label(uint32_t account_idx, uint32_t subaddress_idx, const std::string& label = "") override;
std::vector<std::shared_ptr<monero_tx_wallet>> get_txs() const override;
std::vector<std::shared_ptr<monero_tx_wallet>> get_txs(const monero_tx_query& query) const override;
std::vector<std::shared_ptr<monero_transfer>> get_transfers(const monero_transfer_query& query) const override;
std::vector<std::shared_ptr<monero_output_wallet>> get_outputs(const monero_output_query& query) const override;
std::string export_outputs(bool all = false) const override;
int import_outputs(const std::string& outputs_hex) override;
std::shared_ptr<monero_key_image_export_result> export_key_images(bool all = false) const override;
std::shared_ptr<monero_key_image_import_result> import_key_images(const std::vector<std::shared_ptr<monero_key_image>>& key_images, uint64_t offset = 0) override;
void freeze_output(const std::string& key_image) override;
void thaw_output(const std::string& key_image) override;
bool is_output_frozen(const std::string& key_image) override;
monero_tx_priority get_default_fee_priority() const override;
std::vector<std::shared_ptr<monero_tx_wallet>> create_txs(const monero_tx_config& conf) override;
std::shared_ptr<monero_tx_wallet> sweep_output(const monero_tx_config& config) override;
std::vector<std::shared_ptr<monero_tx_wallet>> sweep_dust(bool relay = false) override;
std::vector<std::shared_ptr<monero_tx_wallet>> sweep_unlocked(const monero_tx_config& config) override;
std::vector<std::string> relay_txs(const std::vector<std::string>& tx_metadatas) override;
monero_tx_set describe_tx_set(const monero_tx_set& tx_set) override;
monero_tx_set sign_txs(const std::string& unsigned_tx_hex) override;
std::vector<std::string> submit_txs(const std::string& signed_tx_hex) override;
std::string sign_message(const std::string& msg, monero_message_signature_type signature_type, uint32_t account_idx = 0, uint32_t subaddress_idx = 0) const override;
monero_message_signature_result verify_message(const std::string& msg, const std::string& address, const std::string& signature) const override;
std::string get_tx_key(const std::string& tx_hash) const override;
std::shared_ptr<monero_check_tx> check_tx_key(const std::string& tx_hash, const std::string& tx_key, const std::string& address) const override;
std::string get_tx_proof(const std::string& tx_hash, const std::string& address, const std::string& message) const override;
std::shared_ptr<monero_check_tx> check_tx_proof(const std::string& tx_hash, const std::string& address, const std::string& message, const std::string& signature) const override;
std::string get_spend_proof(const std::string& tx_hash, const std::string& message) const override;
bool check_spend_proof(const std::string& tx_hash, const std::string& message, const std::string& signature) const override;
std::string get_reserve_proof_wallet(const std::string& message) const override;
std::string get_reserve_proof_account(uint32_t account_idx, uint64_t amount, const std::string& message) const override;
std::shared_ptr<monero_check_reserve> check_reserve_proof(const std::string& address, const std::string& message, const std::string& signature) const override;
std::string get_tx_note(const std::string& tx_hash) const override;
std::vector<std::string> get_tx_notes(const std::vector<std::string>& tx_hashes) const override;
void set_tx_note(const std::string& tx_hashes, const std::string& notes) override;
void set_tx_notes(const std::vector<std::string>& tx_hashes, const std::vector<std::string>& notes) override;
std::vector<monero_address_book_entry> get_address_book_entries(const std::vector<uint64_t>& indices) const override;
uint64_t add_address_book_entry(const std::string& address, const std::string& description) override;
void edit_address_book_entry(uint64_t index, bool set_address, const std::string& address, bool set_description, const std::string& description) override;
void delete_address_book_entry(uint64_t index) override;
void tag_accounts(const std::string& tag, const std::vector<uint32_t>& account_indices) override;
void untag_accounts(const std::vector<uint32_t>& account_indices) override;
std::vector<std::shared_ptr<monero_account_tag>> get_account_tags() const override;
void set_account_tag_label(const std::string& tag, const std::string& label) override;
std::string get_payment_uri(const monero_tx_config& config) const override;
std::shared_ptr<monero_tx_config> parse_payment_uri(const std::string& uri) const override;
void set_attribute(const std::string& key, const std::string& val) override;
bool get_attribute(const std::string& key, std::string& value) const override;
void start_mining(boost::optional<uint64_t> num_threads, boost::optional<bool> background_mining, boost::optional<bool> ignore_battery) override;
void stop_mining() override;
bool is_multisig_import_needed() const override;
monero_multisig_info get_multisig_info() const override;
std::string prepare_multisig() override;
std::string make_multisig(const std::vector<std::string>& multisig_hexes, int threshold, const std::string& password) override;
monero_multisig_init_result exchange_multisig_keys(const std::vector<std::string>& multisig_hexes, const std::string& password) override;
std::string export_multisig_hex() override;
int import_multisig_hex(const std::vector<std::string>& multisig_hexes, const bool refresh_after_import = true) override;
monero_multisig_sign_result sign_multisig_tx_hex(const std::string& multisig_tx_hex) override;
std::vector<std::string> submit_multisig_tx_hex(const std::string& signed_multisig_tx_hex) override;
void change_password(const std::string& old_password, const std::string& new_password) override;
void save() override;
bool is_closed() const override;
void close(bool save = false) override;
std::shared_ptr<monero_subaddress> get_balances(const boost::optional<uint32_t>& account_idx, const boost::optional<uint32_t>& subaddress_idx) const;
// --------------------------------- PRIVATE --------------------------------
private:
friend class monero_wallet_poller;
boost::optional<uint64_t> m_sync_period_in_ms;
std::string m_path = "";
std::shared_ptr<monero_rpc_connection> m_rpc;
std::shared_ptr<monero_rpc_connection> m_daemon_connection;
mutable boost::recursive_mutex m_listeners_mutex;
std::set<monero_wallet_listener*> m_listeners;
mutable boost::recursive_mutex m_sync_mutex;
mutable boost::mutex m_address_cache_mutex;
mutable std::unordered_map<uint32_t, std::unordered_map<uint32_t, std::string>> m_address_cache;
boost::mutex m_poller_mutex;
std::unique_ptr<monero_wallet_poller> m_poller;
monero_wallet_rpc* create_wallet_random(const std::shared_ptr<monero_wallet_config> &config);
monero_wallet_rpc* create_wallet_from_seed(const std::shared_ptr<monero_wallet_config> &config);
monero_wallet_rpc* create_wallet_from_keys(const std::shared_ptr<monero_wallet_config> &config);
monero_sync_result refresh(const std::shared_ptr<serializable_struct>& params);
std::map<uint32_t, std::vector<uint32_t>> get_account_indices(bool get_subaddress_indices) const;
std::vector<uint32_t> get_subaddress_indices(uint32_t account_idx) const;
std::vector<std::shared_ptr<monero_output_wallet>> get_outputs_aux(const monero_output_query& query) const;
std::vector<std::shared_ptr<monero_transfer>> get_transfers_aux(const monero_transfer_query& query) const;
std::string query_key(const std::string& key_type) const;
std::vector<std::shared_ptr<monero_tx_wallet>> sweep_account(const monero_tx_config &conf);
void clear_address_cache();
void refresh_listening();
void wait_for_listener_callbacks_idle();
void poll();
void clear();
};
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,500 @@
/**
* Copyright (c) everoddandeven
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Parts of this file are originally copyright (c) 2025-2026 woodser
*
* Parts of this file are originally copyright (c) 2014-2019, The Monero Project
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* All rights reserved.
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
*/
#pragma once
#include "daemon/monero_daemon_rpc_model.h"
#include "monero_wallet_model.h"
/**
* Internal data model for monero_wallet_rpc.
*/
namespace monero {
/**
* key-value struct which can be serialized.
*/
struct key_value : public serializable_struct {
boost::optional<std::string> m_key;
boost::optional<std::string> m_value;
key_value() { }
key_value(const std::string& key): m_key(key) { }
key_value(const std::string& key, const std::string& value): m_key(key), m_value(value) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<key_value>& attributes);
};
/**
* Models a RPC Monero key image.
*/
struct monero_rpc_key_image : public monero_key_image {
monero_rpc_key_image(const std::shared_ptr<monero_key_image> &key_image);
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
// ------------------------------ JSON-RPC Params ---------------------------------
struct monero_query_key_params : public serializable_struct {
boost::optional<std::string> m_key_type;
monero_query_key_params(const std::string& key_type): m_key_type(key_type) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_query_output_params : public serializable_struct {
boost::optional<std::string> m_key_image;
monero_query_output_params(const std::string& key_image): m_key_image(key_image) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_get_address_params : public serializable_struct {
boost::optional<std::string> m_address;
boost::optional<uint32_t> m_account_index;
std::vector<uint32_t> m_subaddress_indices;
monero_get_address_params(const std::string& address): m_address(address) { }
monero_get_address_params(uint32_t account_index): m_account_index(account_index) { }
monero_get_address_params(uint32_t account_index, const std::vector<uint32_t>& subaddress_indices): m_account_index(account_index), m_subaddress_indices(subaddress_indices) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_integrated_address_params : public serializable_struct {
boost::optional<std::string> m_integrated_address;
boost::optional<std::string> m_standard_address;
boost::optional<std::string> m_payment_id;
monero_integrated_address_params(const std::string& integrated_address): m_integrated_address(integrated_address) {}
monero_integrated_address_params(const std::string& standard_address, const std::string& payment_id): m_standard_address(standard_address), m_payment_id(payment_id) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_multisig_params : public serializable_struct {
// TODO monero-docs document this parameter
boost::optional<bool> m_enable_multisig_experimental;
boost::optional<bool> m_refresh_after_import;
std::vector<std::string> m_multisig_info;
std::vector<std::string> m_multisig_hexes;
boost::optional<std::string> m_multisig_tx_hex;
boost::optional<int> m_threshold;
boost::optional<std::string> m_password;
monero_multisig_params(bool enable_multisig_experimental = true): m_enable_multisig_experimental(enable_multisig_experimental) { }
monero_multisig_params(const std::vector<std::string>& multisig_hexes, const std::string& password): m_multisig_info(multisig_hexes), m_password(password) { }
monero_multisig_params(const std::vector<std::string>& multisig_hexes, const char* password): monero_multisig_params(multisig_hexes, std::string(password)) { }
monero_multisig_params(const std::vector<std::string>& multisig_hexes, int threshold, const std::string& password): m_multisig_info(multisig_hexes), m_threshold(threshold), m_password(password) { }
monero_multisig_params(const std::vector<std::string>& multisig_hexes, const bool refresh_after_import): m_multisig_hexes(multisig_hexes), m_refresh_after_import(refresh_after_import) { }
monero_multisig_params(const std::string& multisig_tx_hex): m_multisig_tx_hex(multisig_tx_hex) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_payment_uri_params : public serializable_struct {
boost::optional<std::string> m_uri;
boost::optional<std::string> m_address;
boost::optional<uint64_t> m_amount;
boost::optional<std::string> m_payment_id;
boost::optional<std::string> m_recipient_name;
boost::optional<std::string> m_tx_description;
monero_payment_uri_params() { }
monero_payment_uri_params(const std::string& uri): m_uri(uri) { }
monero_payment_uri_params(const monero_tx_config& config);
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_get_balance_params : public serializable_struct {
boost::optional<uint32_t> m_account_idx;
std::vector<uint32_t> m_address_indices;
boost::optional<bool> m_all_accounts;
boost::optional<bool> m_strict;
monero_get_balance_params(bool all_accounts, bool strict = false): m_all_accounts(all_accounts), m_strict(strict) { }
monero_get_balance_params(uint32_t account_idx, const std::vector<uint32_t>& address_indices, bool all_accounts = false, bool strict = false): m_account_idx(account_idx), m_address_indices(address_indices), m_all_accounts(all_accounts), m_strict(strict) { }
monero_get_balance_params(uint32_t account_idx, boost::optional<uint32_t> address_idx, bool all_accounts = false, bool strict = false);
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_close_wallet_params : public serializable_struct {
boost::optional<bool> m_save;
monero_close_wallet_params(bool save = false): m_save(save) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_change_wallet_password_params : public serializable_struct {
boost::optional<std::string> m_old_password;
boost::optional<std::string> m_new_password;
monero_change_wallet_password_params(const std::string& old_password, const std::string& new_password): m_old_password(old_password), m_new_password(new_password) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_set_daemon_params : public serializable_struct {
boost::optional<std::string> m_address;
boost::optional<std::string> m_username;
boost::optional<std::string> m_password;
boost::optional<std::string> m_proxy;
boost::optional<bool> m_trusted;
boost::optional<std::string> m_ssl_support;
boost::optional<ssl_options> m_ssl_options;
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_account_tag_params : public serializable_struct {
std::vector<uint32_t> m_account_indices;
boost::optional<std::string> m_tag;
boost::optional<std::string> m_label;
boost::optional<std::string> m_description;
monero_account_tag_params() {}
monero_account_tag_params(const std::string& tag, const std::string& description = ""): m_tag(tag), m_description(description) { }
monero_account_tag_params(const std::vector<uint32_t>& account_indices): m_account_indices(account_indices) { }
monero_account_tag_params(const std::string& tag, const std::vector<uint32_t>& account_indices): m_tag(tag), m_account_indices(account_indices) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_tx_notes_params : public serializable_struct {
std::vector<std::string> m_tx_hashes;
std::vector<std::string> m_notes;
monero_tx_notes_params(const std::vector<std::string>& tx_hashes): m_tx_hashes(tx_hashes) { }
monero_tx_notes_params(const std::vector<std::string>& tx_hashes, const std::vector<std::string>& notes): m_tx_hashes(tx_hashes), m_notes(notes) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_address_book_entry_params : public serializable_struct {
boost::optional<uint64_t> m_index; // TODO: not boost::optional
boost::optional<bool> m_set_address;
boost::optional<std::string> m_address;
boost::optional<bool> m_set_description;
boost::optional<std::string> m_description;
std::vector<uint64_t> m_entries;
monero_address_book_entry_params(uint64_t index): m_index(index) { }
monero_address_book_entry_params(const std::vector<uint64_t>& entries): m_entries(entries) { }
monero_address_book_entry_params(uint64_t index, bool set_address, const std::string& address, bool set_description, const std::string& description): m_index(index), m_set_address(set_address), m_address(address), m_set_description(set_description), m_description(description) { }
monero_address_book_entry_params(const std::string& address, const std::string& description): m_address(address), m_description(description) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_verify_sign_message_params : public serializable_struct {
boost::optional<std::string> m_data;
boost::optional<std::string> m_address;
boost::optional<std::string> m_signature;
boost::optional<monero_message_signature_type> m_signature_type;
boost::optional<uint32_t> m_account_index;
boost::optional<uint32_t> m_address_index;
monero_verify_sign_message_params(const std::string &data, const std::string &address, const std::string& signature): m_data(data), m_address(address), m_signature(signature) { }
monero_verify_sign_message_params(const std::string &data, monero_message_signature_type signature_type, uint32_t account_index, uint32_t address_index): m_data(data), m_signature_type(signature_type), m_account_index(account_index), m_address_index(address_index) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_check_tx_key_params : public serializable_struct {
boost::optional<std::string> m_tx_hash;
boost::optional<std::string> m_address;
boost::optional<std::string> m_tx_key;
monero_check_tx_key_params(const std::string &tx_hash): m_tx_hash(tx_hash) { }
monero_check_tx_key_params(const std::string &tx_hash, const std::string &tx_key, const std::string &address): m_tx_hash(tx_hash), m_tx_key(tx_key), m_address(address) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_sign_describe_transfer_params : public serializable_struct {
boost::optional<std::string> m_unsigned_txset;
boost::optional<std::string> m_multisig_txset;
boost::optional<bool> m_export_raw;
boost::optional<bool> m_get_tx_keys;
monero_sign_describe_transfer_params() { }
monero_sign_describe_transfer_params(const std::string &unsigned_txset) : m_unsigned_txset(unsigned_txset) { }
monero_sign_describe_transfer_params(const std::string &unsigned_txset, const std::string &multisig_txset) : m_unsigned_txset(unsigned_txset), m_multisig_txset(multisig_txset) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_wallet_relay_tx_params : public serializable_struct {
boost::optional<std::string> m_hex;
boost::optional<std::string> m_signed_tx_hex;
monero_wallet_relay_tx_params() {}
monero_wallet_relay_tx_params(const std::string &hex): m_hex(hex) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_sweep_params : public serializable_struct {
boost::optional<std::string> m_address;
boost::optional<uint32_t> m_account_index;
std::vector<uint32_t> m_subaddr_indices;
boost::optional<std::string> m_key_image;
boost::optional<bool> m_relay;
boost::optional<monero_tx_priority> m_priority;
boost::optional<std::string> m_payment_id;
boost::optional<uint64_t> m_below_amount;
boost::optional<bool> m_get_tx_key;
boost::optional<bool> m_get_tx_keys;
boost::optional<bool> m_get_tx_hex;
boost::optional<bool> m_get_tx_metadata;
monero_sweep_params(bool relay = false): m_relay(relay) { }
monero_sweep_params(const monero_tx_config& config);
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_create_edit_subaddress_params : public serializable_struct {
boost::optional<std::string> m_label;
boost::optional<uint32_t> m_account_index;
boost::optional<uint32_t> m_subaddress_index;
monero_create_edit_subaddress_params(uint32_t account_idx, const std::string& label): m_account_index(account_idx), m_label(label) { }
monero_create_edit_subaddress_params(uint32_t account_idx, uint32_t subaddress_idx, const std::string& label): m_account_index(account_idx), m_subaddress_index(subaddress_idx), m_label(label) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_wallet_data_params : public serializable_struct {
boost::optional<bool> m_all;
std::vector<std::shared_ptr<monero_key_image>> m_key_images;
boost::optional<uint64_t> m_offset;
boost::optional<std::string> m_outputs_hex;
monero_wallet_data_params(const std::vector<std::shared_ptr<monero_key_image>> &key_images, uint64_t offset): m_key_images(key_images), m_offset(offset) { };
monero_wallet_data_params(bool all): m_all(all) { }
monero_wallet_data_params(const std::string& outputs_hex): m_outputs_hex(outputs_hex) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_create_open_wallet_params : public serializable_struct {
boost::optional<std::string> m_filename;
boost::optional<std::string> m_password;
boost::optional<std::string> m_language;
boost::optional<std::string> m_seed;
boost::optional<std::string> m_seed_offset;
boost::optional<uint64_t> m_restore_height;
boost::optional<bool> m_autosave_current;
boost::optional<bool> m_enable_multisig_experimental;
boost::optional<std::string> m_address;
boost::optional<std::string> m_view_key;
boost::optional<std::string> m_spend_key;
monero_create_open_wallet_params(const boost::optional<std::string>& filename, const boost::optional<std::string> &password): m_filename(filename), m_password(password), m_autosave_current(false) { }
monero_create_open_wallet_params(const boost::optional<std::string>& filename, const boost::optional<std::string> &password, const boost::optional<std::string> &language): m_filename(filename), m_password(password), m_language(language), m_autosave_current(false) { }
monero_create_open_wallet_params(const boost::optional<std::string>& filename, const boost::optional<std::string> &password, const boost::optional<std::string> &seed, const boost::optional<std::string> &seed_offset, const boost::optional<uint64_t> &restore_height, const boost::optional<std::string> &language, const boost::optional<bool> &autosave_current, const boost::optional<bool> &enable_multisig_experimental): m_filename(filename), m_password(password), m_seed(seed), m_seed_offset(seed_offset), m_restore_height(restore_height), m_language(language), m_autosave_current(autosave_current), m_enable_multisig_experimental(enable_multisig_experimental) { }
monero_create_open_wallet_params(const boost::optional<std::string>& filename, const boost::optional<std::string> &password, const boost::optional<std::string> &address, const boost::optional<std::string> &view_key, const boost::optional<std::string> &spend_key, const boost::optional<uint64_t> &restore_height, const boost::optional<bool> &autosave_current): m_filename(filename), m_password(password), m_address(address), m_view_key(view_key), m_spend_key(spend_key), m_restore_height(restore_height), m_autosave_current(autosave_current) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_reserve_proof_params : public serializable_struct {
boost::optional<bool> m_all;
boost::optional<std::string> m_message;
boost::optional<std::string> m_tx_hash;
boost::optional<uint32_t> m_account_index;
boost::optional<uint64_t> m_amount;
boost::optional<std::string> m_address;
boost::optional<std::string> m_signature;
monero_reserve_proof_params(const std::string &message, bool all = true): m_all(all), m_message(message) { }
monero_reserve_proof_params(const std::string &address, const std::string &message, const std::string &signature): m_address(address), m_message(message), m_signature(signature) { }
monero_reserve_proof_params(const std::string &tx_hash, const std::string &address, const std::string &message, const std::string &signature): m_tx_hash(tx_hash), m_address(address), m_message(message), m_signature(signature) { }
monero_reserve_proof_params(const std::string &tx_hash, const std::string &message): m_tx_hash(tx_hash), m_message(message) { }
monero_reserve_proof_params(uint32_t account_index, uint64_t amount, const std::string &message): m_account_index(account_index), m_amount(amount), m_message(message) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_wallet_refresh_params : public serializable_struct {
boost::optional<bool> m_enable;
boost::optional<uint64_t> m_period;
boost::optional<uint64_t> m_start_height;
monero_wallet_refresh_params() { }
monero_wallet_refresh_params(bool enable): m_enable(enable) { }
monero_wallet_refresh_params(bool enable, uint64_t period): m_enable(enable), m_period(period) { }
monero_wallet_refresh_params(uint64_t start_height): m_start_height(start_height) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_transfer_params : public serializable_struct {
std::vector<uint32_t> m_subtract_fee_from_outputs;
boost::optional<uint32_t> m_account_index;
std::vector<uint32_t> m_subaddress_indices;
boost::optional<std::string> m_payment_id;
boost::optional<bool> m_do_not_relay;
boost::optional<int> m_priority;
boost::optional<bool> m_get_tx_hex;
boost::optional<bool> m_get_tx_metadata;
boost::optional<bool> m_get_tx_keys;
boost::optional<bool> m_get_tx_key;
std::vector<std::shared_ptr<monero_destination>> m_destinations;
monero_transfer_params(const monero_tx_config &config);
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_get_transfers_params : public serializable_struct {
boost::optional<bool> m_in;
boost::optional<bool> m_out;
boost::optional<bool> m_pool;
boost::optional<bool> m_pending;
boost::optional<bool> m_failed;
boost::optional<uint64_t> m_min_height;
boost::optional<uint64_t> m_max_height;
boost::optional<bool> m_all_accounts;
boost::optional<uint32_t> m_account_index;
std::vector<uint32_t> m_subaddr_indices;
bool filter_by_height() const { return m_min_height != boost::none || m_max_height != boost::none; }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
struct monero_get_incoming_transfers_params : public serializable_struct {
boost::optional<std::string> m_transfer_type;
boost::optional<bool> m_verbose;
boost::optional<uint32_t> m_account_index;
std::vector<uint32_t> m_subaddr_indices;
monero_get_incoming_transfers_params(const std::string& transfer_type, bool verbose = true): m_transfer_type(transfer_type), m_verbose(verbose) { }
rapidjson::Value to_rapidjson_val(rapidjson::Document::AllocatorType& allocator) const override;
};
// ------------------------------ JSON-RPC Response ---------------------------------
struct monero_multisig_response {
boost::optional<int> m_num_outputs;
boost::optional<std::string> m_multisig_info;
std::vector<std::string> m_tx_hashes;
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_multisig_response>& response);
};
struct monero_get_balance_response {
boost::optional<uint64_t> m_balance;
boost::optional<uint64_t> m_unlocked_balance;
boost::optional<bool> m_multisig_import_needed;
boost::optional<uint64_t> m_time_to_unlock;
boost::optional<uint64_t> m_blocks_to_unlock;
std::vector<std::shared_ptr<monero_subaddress>> m_per_subaddress;
monero_get_balance_response(): m_balance(0), m_unlocked_balance(0) { }
static void from_property_tree(const boost::property_tree::ptree& node, const std::shared_ptr<monero_get_balance_response>& response);
};
// ------------------------------ RPC Deserialization ---------------------------------
void deserialize_subaddress(const boost::property_tree::ptree& node, const std::shared_ptr<monero_subaddress>& subaddress);
void deserialize_subaddresses(const boost::property_tree::ptree& node, std::vector<std::shared_ptr<monero_subaddress>>& subaddresses);
void deserialize_account(const boost::property_tree::ptree& node, monero_account& account);
void deserialize_accounts(const boost::property_tree::ptree& node, std::vector<monero_account>& accounts);
void init_sent_tx(const monero_tx_config &config, std::shared_ptr<monero_tx_wallet> &tx, bool copy_destinations);
void deserialize_tx_with_transfer_and_merge(const boost::property_tree::ptree& node, std::map<std::string, std::shared_ptr<monero_tx_wallet>>& tx_map, std::map<uint64_t, std::shared_ptr<monero_block>>& block_map);
void deserialize_tx_with_output_and_merge(const boost::property_tree::ptree& node, std::map<std::string, std::shared_ptr<monero_tx_wallet>>& tx_map, std::map<uint64_t, std::shared_ptr<monero_block>>& block_map);
void deserialize_tx_set(const boost::property_tree::ptree& node, const std::shared_ptr<monero_tx_set>& set);
void deserialize_tx_set(const boost::property_tree::ptree& node, const std::shared_ptr<monero_tx_set>& set, const std::shared_ptr<monero_tx_wallet> &tx, bool is_outgoing, const monero_tx_config &config);
void deserialize_sent_tx_set(const boost::property_tree::ptree& node, const std::shared_ptr<monero_tx_set>& set);
void deserialize_sent_tx_set(const boost::property_tree::ptree& node, const std::shared_ptr<monero_tx_set>& set, std::vector<std::shared_ptr<monero_tx_wallet>> &txs, const boost::optional<monero_tx_config> &conf);
void deserialize_described_tx_set(const boost::property_tree::ptree& node, const std::shared_ptr<monero_tx_set>& set);
void deserialize_submitted_tx_hashes(const boost::property_tree::ptree& node, std::vector<std::string>& tx_hashes);
void deserialize_relayed_tx_hash(const boost::property_tree::ptree& node, std::vector<std::string>& tx_hashes);
int deserialize_num_created_txs(const boost::property_tree::ptree& node, bool can_split);
std::string deserialize_tx_key(const boost::property_tree::ptree& node);
void deserialize_tx_notes(const boost::property_tree::ptree& node, std::vector<std::string>& tx_notes);
void deserialize_integrated_address(const boost::property_tree::ptree& node, monero_integrated_address& subaddress);
void deserialize_key_image_export_result(const boost::property_tree::ptree& node, const std::shared_ptr<monero_key_image_export_result>& result);
void deserialize_key_image_import_result(const boost::property_tree::ptree& node, const std::shared_ptr<monero_key_image_import_result>& result);
void deserialize_message_signature_result(const boost::property_tree::ptree& node, monero_message_signature_result& result);
void deserialize_check_tx(const boost::property_tree::ptree& node, const std::shared_ptr<monero_check_tx>& check);
void deserialize_check_reserve(const boost::property_tree::ptree& node, const std::shared_ptr<monero_check_reserve>& check);
void deserialize_multisig_info(const boost::property_tree::ptree& node, monero_multisig_info& info);
void deserialize_multisig_init_result(const boost::property_tree::ptree& node, monero_multisig_init_result& res);
void deserialize_multisig_sign_result(const boost::property_tree::ptree& node, monero_multisig_sign_result& res);
void deserialize_address_book_entries(const boost::property_tree::ptree& node, std::vector<monero_address_book_entry>& entries);
void deserialize_seed_languages(const boost::property_tree::ptree& node, std::vector<std::string>& languages);
uint64_t deserialize_address_book_index(const boost::property_tree::ptree& node);
void deserialize_account_tags(const boost::property_tree::ptree& node, std::vector<std::shared_ptr<monero_account_tag>>& account_tags);
std::string deserialize_signature(const boost::property_tree::ptree& node);
std::string deserialize_exported_outputs(const boost::property_tree::ptree& node);
uint64_t deserialize_block_height(const boost::property_tree::ptree& node);
int deserialize_num_imported_outputs(const boost::property_tree::ptree& node);
bool deserialize_frozen_output_info(const boost::property_tree::ptree& node);
monero_tx_priority deserialize_tx_priority(const boost::property_tree::ptree& node);
std::string deserialize_payment_uri(const boost::property_tree::ptree& node);
void deserialize_payment_uri(const boost::property_tree::ptree& node, const std::shared_ptr<monero_tx_config>& tx_config);
void deserialize_sync_result(const boost::property_tree::ptree& node, monero_sync_result& sync_result);
}