aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/wallet2.cpp119
-rw-r--r--src/wallet/wallet2.h52
-rw-r--r--src/wallet/wallet_errors.h23
-rw-r--r--src/wallet/wallet_rpc_server.cpp49
-rw-r--r--src/wallet/wallet_rpc_server.h10
-rw-r--r--src/wallet/wallet_rpc_server_commans_defs.h35
-rw-r--r--src/wallet/wallet_rpc_server_error_codes.h3
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