diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/wallet2.cpp | 119 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 52 | ||||
-rw-r--r-- | src/wallet/wallet_errors.h | 23 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.cpp | 49 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.h | 10 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server_commans_defs.h | 35 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server_error_codes.h | 3 |
7 files changed, 216 insertions, 75 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 9bd487997..e8d67eec2 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -22,6 +22,23 @@ using namespace epee; using namespace cryptonote; +namespace +{ +void do_prepare_file_names(const std::string& file_path, std::string& keys_file, std::string& wallet_file) +{ + keys_file = file_path; + wallet_file = file_path; + boost::system::error_code e; + if(string_tools::get_extension(keys_file) == "keys") + {//provided keys file name + wallet_file = string_tools::cut_off_extension(wallet_file); + }else + {//provided wallet file name + keys_file += ".keys"; + } +} +} //namespace + namespace tools { //---------------------------------------------------------------------------------------------------- @@ -36,17 +53,25 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_ process_unconfirmed(tx); std::vector<size_t> outs; uint64_t tx_money_got_in_outs = 0; - crypto::public_key tx_pub_key = null_pkey; - bool r = parse_and_validate_tx_extra(tx, tx_pub_key); - - // Temporarily disabled due to messed up tx_extra from someone - // screwing around with MMing. 2014-04-30 - // THROW_WALLET_EXCEPTION_IF(!r, error::tx_extra_parse_error, tx); - - // We don't know how to handle this weird tx, so return - if (!r) return; - - r = lookup_acc_outs(m_account.get_keys(), tx, tx_pub_key, outs, tx_money_got_in_outs); + + std::vector<tx_extra_field> tx_extra_fields; + if(!parse_tx_extra(tx.extra, tx_extra_fields)) + { + // Extra may only be partially parsed, it's OK if tx_extra_fields contains public key + LOG_PRINT_L0("Transaction extra has unsupported format: " << get_transaction_hash(tx)); + } + + tx_extra_pub_key pub_key_field; + if(!find_tx_extra_field_by_type(tx_extra_fields, pub_key_field)) + { + LOG_PRINT_L0("Public key wasn't found in the transaction extra. Skipping transaction " << get_transaction_hash(tx)); + if(0 != m_callback) + m_callback->on_skip_transaction(height, tx); + return; + } + + crypto::public_key tx_pub_key = pub_key_field.pub_key; + bool r = lookup_acc_outs(m_account.get_keys(), tx, tx_pub_key, outs, tx_money_got_in_outs); THROW_WALLET_EXCEPTION_IF(!r, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys()); if(!outs.empty() && tx_money_got_in_outs) @@ -87,6 +112,8 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_ m_callback->on_money_received(height, td.m_tx, td.m_internal_output_index); } } + + uint64_t tx_money_spent_in_ins = 0; // check all outputs for spending (compare key images) BOOST_FOREACH(auto& in, tx.vin) { @@ -96,12 +123,33 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_ if(it != m_key_images.end()) { LOG_PRINT_L0("Spent money: " << print_money(boost::get<cryptonote::txin_to_key>(in).amount) << ", with tx: " << get_transaction_hash(tx)); + tx_money_spent_in_ins += boost::get<cryptonote::txin_to_key>(in).amount; transfer_details& td = m_transfers[it->second]; td.m_spent = true; if (0 != m_callback) m_callback->on_money_spent(height, td.m_tx, td.m_internal_output_index, tx); } } + + tx_extra_nonce extra_nonce; + if (find_tx_extra_field_by_type(tx_extra_fields, extra_nonce)) + { + crypto::hash payment_id; + if(get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id)) + { + uint64_t received = (tx_money_spent_in_ins < tx_money_got_in_outs) ? tx_money_got_in_outs - tx_money_spent_in_ins : 0; + if (0 < received && null_hash != payment_id) + { + payment_details payment; + payment.m_tx_hash = cryptonote::get_transaction_hash(tx); + payment.m_amount = received; + payment.m_block_height = height; + payment.m_unlock_time = tx.unlock_time; + m_payments.emplace(payment_id, payment); + LOG_PRINT_L2("Payment found: " << payment_id << " / " << payment.m_tx_hash << " / " << payment.m_amount); + } + } + } } //---------------------------------------------------------------------------------------------------- void wallet2::process_unconfirmed(const cryptonote::transaction& tx) @@ -203,7 +251,7 @@ void wallet2::pull_blocks(size_t& blocks_added) { //split detected here !!! THROW_WALLET_EXCEPTION_IF(current_index == res.start_height, error::wallet_internal_error, - "wrong daemon response: split starts from the first block in response " + string_tools::pod_to_hex(bl_id) + + "wrong daemon response: split starts from the first block in response " + string_tools::pod_to_hex(bl_id) + " (height " + std::to_string(res.start_height) + "), local block id at this height: " + string_tools::pod_to_hex(m_blockchain[current_index])); @@ -304,6 +352,14 @@ void wallet2::detach_blockchain(uint64_t height) m_blockchain.erase(m_blockchain.begin()+height, m_blockchain.end()); m_local_bc_height -= blocks_detached; + for (auto it = m_payments.begin(); it != m_payments.end(); ) + { + if(height <= it->second.m_block_height) + it = m_payments.erase(it); + else + ++it; + } + LOG_PRINT_L0("Detached blockchain on height " << height << ", transfers detached " << transfers_detached << ", blocks detached " << blocks_detached); } //---------------------------------------------------------------------------------------------------- @@ -399,18 +455,19 @@ void wallet2::generate(const std::string& wallet_, const std::string& password) store(); } //---------------------------------------------------------------------------------------------------- +void wallet2::wallet_exists(const std::string& file_path, bool& keys_file_exists, bool& wallet_file_exitst) +{ + std::string keys_file, wallet_file; + do_prepare_file_names(file_path, keys_file, wallet_file); + + boost::system::error_code ignore; + keys_file_exists = boost::filesystem::exists(keys_file, ignore); + wallet_file_exitst = boost::filesystem::exists(wallet_file, ignore); +} +//---------------------------------------------------------------------------------------------------- bool wallet2::prepare_file_names(const std::string& file_path) { - m_keys_file = file_path; - m_wallet_file = file_path; - boost::system::error_code e; - if(string_tools::get_extension(m_keys_file) == "keys") - {//provided keys file name - m_wallet_file = string_tools::cut_off_extension(m_wallet_file); - }else - {//provided wallet file name - m_keys_file += ".keys"; - } + do_prepare_file_names(file_path, m_keys_file, m_wallet_file); return true; } //---------------------------------------------------------------------------------------------------- @@ -422,7 +479,7 @@ bool wallet2::check_connection() net_utils::http::url_content u; net_utils::parse_url(m_daemon_address, u); if(!u.port) - u.port = RPC_DEFAULT_PORT; + u.port = RPC_DEFAULT_PORT; return m_http_client.connect(u.host, std::to_string(u.port), WALLET_RCP_CONNECTION_TIMEOUT); } //---------------------------------------------------------------------------------------------------- @@ -497,6 +554,14 @@ void wallet2::get_transfers(wallet2::transfer_container& incoming_transfers) con incoming_transfers = m_transfers; } //---------------------------------------------------------------------------------------------------- +void wallet2::get_payments(const crypto::hash& payment_id, std::list<wallet2::payment_details>& payments) const +{ + auto range = m_payments.equal_range(payment_id); + std::for_each(range.first, range.second, [&payments](const payment_container::value_type& x) { + payments.push_back(x.second); + }); +} +//---------------------------------------------------------------------------------------------------- bool wallet2::is_transfer_unlocked(const transfer_details& td) const { if(!is_tx_spendtime_unlocked(td.m_tx.unlock_time)) @@ -596,16 +661,16 @@ void wallet2::add_unconfirmed_tx(const cryptonote::transaction& tx, uint64_t cha } //---------------------------------------------------------------------------------------------------- void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, - uint64_t unlock_time, uint64_t fee, cryptonote::transaction& tx) + uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx) { - transfer(dsts, fake_outputs_count, unlock_time, fee, detail::digit_split_strategy, tx_dust_policy(fee), tx); + transfer(dsts, fake_outputs_count, unlock_time, fee, extra, detail::digit_split_strategy, tx_dust_policy(fee), tx); } //---------------------------------------------------------------------------------------------------- void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, - uint64_t unlock_time, uint64_t fee) + uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra) { cryptonote::transaction tx; - transfer(dsts, fake_outputs_count, unlock_time, fee, tx); + transfer(dsts, fake_outputs_count, unlock_time, fee, extra, tx); } //---------------------------------------------------------------------------------------------------- } diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 221f3d25c..edbf31f2d 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -34,6 +34,7 @@ namespace tools virtual void on_new_block(uint64_t height, const cryptonote::block& block) {} virtual void on_money_received(uint64_t height, const cryptonote::transaction& tx, size_t out_index) {} virtual void on_money_spent(uint64_t height, const cryptonote::transaction& in_tx, size_t out_index, const cryptonote::transaction& spend_tx) {} + virtual void on_skip_transaction(uint64_t height, const cryptonote::transaction& tx) {} }; struct tx_dust_policy @@ -67,14 +68,23 @@ namespace tools uint64_t amount() const { return m_tx.vout[m_internal_output_index].amount; } }; + struct payment_details + { + crypto::hash m_tx_hash; + uint64_t m_amount; + uint64_t m_block_height; + uint64_t m_unlock_time; + }; + struct unconfirmed_transfer_details { cryptonote::transaction m_tx; uint64_t m_change; - time_t m_sent_time; + time_t m_sent_time; }; typedef std::vector<transfer_details> transfer_container; + typedef std::unordered_multimap<crypto::hash, payment_details> payment_container; struct keys_file_data { @@ -108,13 +118,14 @@ namespace tools uint64_t balance(); uint64_t unlocked_balance(); template<typename T> - void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, T destination_split_strategy, const tx_dust_policy& dust_policy); + void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy); template<typename T> - void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction &tx); - void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee); - void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, cryptonote::transaction& tx); + void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction &tx); + void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra); + void transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, cryptonote::transaction& tx); bool check_connection(); void get_transfers(wallet2::transfer_container& incoming_transfers) const; + void get_payments(const crypto::hash& payment_id, std::list<wallet2::payment_details>& payments) const; uint64_t get_blockchain_current_height() const { return m_local_bc_height; } template <class t_archive> inline void serialize(t_archive &a, const unsigned int ver) @@ -128,8 +139,13 @@ namespace tools if(ver < 6) return; a & m_unconfirmed_txs; + if(ver < 7) + return; + a & m_payments; } + static void wallet_exists(const std::string& file_path, bool& keys_file_exists, bool& wallet_file_exitst); + private: bool store_keys(const std::string& keys_file_name, const std::string& password); void load_keys(const std::string& keys_file_name, const std::string& password); @@ -152,10 +168,11 @@ namespace tools std::string m_keys_file; epee::net_utils::http::http_simple_client m_http_client; std::vector<crypto::hash> m_blockchain; - std::atomic<uint64_t> m_local_bc_height; //temporary workaround + std::atomic<uint64_t> m_local_bc_height; //temporary workaround std::unordered_map<crypto::hash, unconfirmed_transfer_details> m_unconfirmed_txs; transfer_container m_transfers; + payment_container m_payments; std::unordered_map<crypto::key_image, size_t> m_key_images; cryptonote::account_public_address m_account_public_address; uint64_t m_upper_transaction_size_limit; //TODO: auto-calc this value or request from daemon, now use some fixed value @@ -165,7 +182,7 @@ namespace tools i_wallet2_callback* m_callback; }; } -BOOST_CLASS_VERSION(tools::wallet2, 6) +BOOST_CLASS_VERSION(tools::wallet2, 7) namespace boost { @@ -190,7 +207,14 @@ namespace boost a & x.m_tx; } - + template <class Archive> + inline void serialize(Archive& a, tools::wallet2::payment_details& x, const boost::serialization::version_type ver) + { + a & x.m_tx_hash; + a & x.m_amount; + a & x.m_block_height; + a & x.m_unlock_time; + } } } @@ -261,15 +285,15 @@ namespace tools //---------------------------------------------------------------------------------------------------- template<typename T> void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, - uint64_t unlock_time, uint64_t fee, T destination_split_strategy, const tx_dust_policy& dust_policy) + uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy) { cryptonote::transaction tx; - transfer(dsts, fake_outputs_count, unlock_time, fee, destination_split_strategy, dust_policy, tx); + transfer(dsts, fake_outputs_count, unlock_time, fee, extra, destination_split_strategy, dust_policy, tx); } template<typename T> void wallet2::transfer(const std::vector<cryptonote::tx_destination_entry>& dsts, size_t fake_outputs_count, - uint64_t unlock_time, uint64_t fee, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction &tx) + uint64_t unlock_time, uint64_t fee, const std::vector<uint8_t>& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction &tx) { using namespace cryptonote; THROW_WALLET_EXCEPTION_IF(dsts.empty(), error::zero_destination); @@ -320,7 +344,7 @@ namespace tools } THROW_WALLET_EXCEPTION_IF(!scanty_outs.empty(), error::not_enough_outs_to_mix, scanty_outs, fake_outputs_count); } - + //prepare inputs size_t i = 0; std::vector<cryptonote::tx_source_entry> sources; @@ -381,7 +405,7 @@ namespace tools splitted_dsts.push_back(cryptonote::tx_destination_entry(dust, dust_policy.addr_for_dust)); } - bool r = cryptonote::construct_tx(m_account.get_keys(), sources, splitted_dsts, tx, unlock_time); + bool r = cryptonote::construct_tx(m_account.get_keys(), sources, splitted_dsts, extra, tx, unlock_time); THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, splitted_dsts, unlock_time); THROW_WALLET_EXCEPTION_IF(m_upper_transaction_size_limit <= get_object_blobsize(tx), error::tx_too_big, tx, m_upper_transaction_size_limit); @@ -409,7 +433,7 @@ namespace tools BOOST_FOREACH(transfer_container::iterator it, selected_transfers) it->m_spent = true; - LOG_PRINT_L0("Transaction successfully sent. <" << get_transaction_hash(tx) << ">" << ENDL + LOG_PRINT_L0("Transaction successfully sent. <" << get_transaction_hash(tx) << ">" << ENDL << "Commission: " << print_money(fee+dust) << " (dust: " << print_money(dust) << ")" << ENDL << "Balance: " << print_money(balance()) << ENDL << "Unlocked: " << print_money(unlocked_balance()) << ENDL diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index b2a863436..0d42dbaf4 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -34,7 +34,6 @@ namespace tools // block_parse_error // get_blocks_error // get_out_indexes_error - // tx_extra_parse_error // tx_parse_error // transfer_error * // get_random_outs_general_error @@ -248,28 +247,6 @@ namespace tools //---------------------------------------------------------------------------------------------------- typedef failed_rpc_request<refresh_error, get_out_indices_error_message_index> get_out_indices_error; //---------------------------------------------------------------------------------------------------- - struct tx_extra_parse_error : public refresh_error - { - explicit tx_extra_parse_error(std::string&& loc, const cryptonote::transaction& tx) - : refresh_error(std::move(loc), "transaction extra parse error") - , m_tx(tx) - { - } - - const cryptonote::transaction& tx() const { return m_tx; } - - std::string to_string() const - { - std::ostringstream ss; - cryptonote::transaction tx = m_tx; - ss << refresh_error::to_string() << ", tx: " << cryptonote::obj_to_json_str(tx); - return ss.str(); - } - - private: - const cryptonote::transaction m_tx; - }; - //---------------------------------------------------------------------------------------------------- struct tx_parse_error : public refresh_error { explicit tx_parse_error(std::string&& loc, const cryptonote::blobdata& tx_blob) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index a89cc4e72..f1766c3b4 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -11,6 +11,7 @@ using namespace epee; #include "cryptonote_core/cryptonote_format_utils.h" #include "cryptonote_core/account.h" #include "misc_language.h" +#include "string_tools.h" #include "crypto/hash.h" namespace tools @@ -74,7 +75,7 @@ namespace tools { std::vector<cryptonote::tx_destination_entry> dsts; - for (auto it = req.destinations.begin(); it != req.destinations.end(); it++) + for (auto it = req.destinations.begin(); it != req.destinations.end(); it++) { cryptonote::tx_destination_entry de; if(!get_account_address_from_str(de.addr, it->address)) @@ -89,7 +90,7 @@ namespace tools try { cryptonote::transaction tx; - m_wallet.transfer(dsts, req.mixin, req.unlock_time, req.fee, tx); + m_wallet.transfer(dsts, req.mixin, req.unlock_time, req.fee, std::vector<uint8_t>(), tx); res.tx_hash = boost::lexical_cast<std::string>(cryptonote::get_transaction_hash(tx)); return true; } @@ -97,19 +98,19 @@ namespace tools { er.code = WALLET_RPC_ERROR_CODE_DAEMON_IS_BUSY; er.message = e.what(); - return false; + return false; } catch (const std::exception& e) { er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR; er.message = e.what(); - return false; + return false; } catch (...) { er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; er.message = "WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR"; - return false; + return false; } return true; } @@ -129,4 +130,40 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ -}
\ No newline at end of file + bool wallet_rpc_server::on_get_payments(const wallet_rpc::COMMAND_RPC_GET_PAYMENTS::request& req, wallet_rpc::COMMAND_RPC_GET_PAYMENTS::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + crypto::hash payment_id; + cryptonote::blobdata payment_id_blob; + if(!epee::string_tools::parse_hexstr_to_binbuff(req.payment_id, payment_id_blob)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID; + er.message = "Payment ID has invald format"; + return false; + } + + if(sizeof(payment_id) != payment_id_blob.size()) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID; + er.message = "Payment ID has invalid size"; + return false; + } + + payment_id = *reinterpret_cast<const crypto::hash*>(payment_id_blob.data()); + + res.payments.clear(); + std::list<wallet2::payment_details> payment_list; + m_wallet.get_payments(payment_id, payment_list); + for (auto payment : payment_list) + { + wallet_rpc::payment_details rpc_payment; + rpc_payment.tx_hash = epee::string_tools::pod_to_hex(payment.m_tx_hash); + rpc_payment.amount = payment.m_amount; + rpc_payment.block_height = payment.m_block_height; + rpc_payment.unlock_time = payment.m_unlock_time; + res.payments.push_back(rpc_payment); + } + + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ +} diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index 418f055d9..db49df574 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -2,7 +2,7 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#pragma once +#pragma once #include <boost/program_options/options_description.hpp> #include <boost/program_options/variables_map.hpp> @@ -35,9 +35,10 @@ namespace tools BEGIN_URI_MAP2() BEGIN_JSON_RPC_MAP("/json_rpc") - MAP_JON_RPC_WE("getbalance", on_getbalance, wallet_rpc::COMMAND_RPC_GET_BALANCE) - MAP_JON_RPC_WE("transfer", on_transfer, wallet_rpc::COMMAND_RPC_TRANSFER) - MAP_JON_RPC_WE("store", on_store, wallet_rpc::COMMAND_RPC_STORE) + MAP_JON_RPC_WE("getbalance", on_getbalance, wallet_rpc::COMMAND_RPC_GET_BALANCE) + MAP_JON_RPC_WE("transfer", on_transfer, wallet_rpc::COMMAND_RPC_TRANSFER) + MAP_JON_RPC_WE("store", on_store, wallet_rpc::COMMAND_RPC_STORE) + MAP_JON_RPC_WE("get_payments", on_get_payments, wallet_rpc::COMMAND_RPC_GET_PAYMENTS) END_JSON_RPC_MAP() END_URI_MAP2() @@ -45,6 +46,7 @@ namespace tools bool on_getbalance(const wallet_rpc::COMMAND_RPC_GET_BALANCE::request& req, wallet_rpc::COMMAND_RPC_GET_BALANCE::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_transfer(const wallet_rpc::COMMAND_RPC_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_TRANSFER::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_store(const wallet_rpc::COMMAND_RPC_STORE::request& req, wallet_rpc::COMMAND_RPC_STORE::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_get_payments(const wallet_rpc::COMMAND_RPC_GET_PAYMENTS::request& req, wallet_rpc::COMMAND_RPC_GET_PAYMENTS::response& res, epee::json_rpc::error& er, connection_context& cntx); bool handle_command_line(const boost::program_options::variables_map& vm); diff --git a/src/wallet/wallet_rpc_server_commans_defs.h b/src/wallet/wallet_rpc_server_commans_defs.h index a94ce36b0..b99d92ca2 100644 --- a/src/wallet/wallet_rpc_server_commans_defs.h +++ b/src/wallet/wallet_rpc_server_commans_defs.h @@ -86,6 +86,41 @@ namespace wallet_rpc }; }; + struct payment_details + { + std::string tx_hash; + uint64_t amount; + uint64_t block_height; + uint64_t unlock_time; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(tx_hash) + KV_SERIALIZE(amount) + KV_SERIALIZE(block_height) + KV_SERIALIZE(unlock_time) + END_KV_SERIALIZE_MAP() + }; + + struct COMMAND_RPC_GET_PAYMENTS + { + struct request + { + std::string payment_id; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(payment_id) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::list<payment_details> payments; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(payments) + END_KV_SERIALIZE_MAP() + }; + }; } } diff --git a/src/wallet/wallet_rpc_server_error_codes.h b/src/wallet/wallet_rpc_server_error_codes.h index 415abf406..7fa536dac 100644 --- a/src/wallet/wallet_rpc_server_error_codes.h +++ b/src/wallet/wallet_rpc_server_error_codes.h @@ -2,10 +2,11 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#pragma once +#pragma once #define WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR -1 #define WALLET_RPC_ERROR_CODE_WRONG_ADDRESS -2 #define WALLET_RPC_ERROR_CODE_DAEMON_IS_BUSY -3 #define WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR -4 +#define WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID -5 |