From 63741d82644944f236c93e9f44cb988a38df1993 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Thu, 11 Jun 2015 09:44:13 +0100 Subject: [PATCH 1/4] Integrated addresses (standard address plus payment id) --- src/cryptonote_config.h | 2 + src/cryptonote_core/account.cpp | 6 ++ src/cryptonote_core/account.h | 1 + src/cryptonote_core/cryptonote_basic_impl.cpp | 75 ++++++++++++++++++- src/cryptonote_core/cryptonote_basic_impl.h | 22 ++++++ src/simplewallet/simplewallet.cpp | 64 +++++++++++++++- src/simplewallet/simplewallet.h | 1 + src/wallet/wallet_rpc_server.cpp | 18 ++++- 8 files changed, 181 insertions(+), 8 deletions(-) diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index e5df844e7..c6aa064cf 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -121,6 +121,7 @@ namespace config std::string const P2P_REMOTE_DEBUG_TRUSTED_PUB_KEY = "0000000000000000000000000000000000000000000000000000000000000000"; uint64_t const CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = 18; + uint64_t const CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX = 19; uint16_t const P2P_DEFAULT_PORT = 18080; uint16_t const RPC_DEFAULT_PORT = 18081; boost::uuids::uuid const NETWORK_ID = { { @@ -132,6 +133,7 @@ namespace config namespace testnet { uint64_t const CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = 53; + uint64_t const CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX = 54; uint16_t const P2P_DEFAULT_PORT = 28080; uint16_t const RPC_DEFAULT_PORT = 28081; boost::uuids::uuid const NETWORK_ID = { { diff --git a/src/cryptonote_core/account.cpp b/src/cryptonote_core/account.cpp index 55e368836..b68103dda 100644 --- a/src/cryptonote_core/account.cpp +++ b/src/cryptonote_core/account.cpp @@ -104,4 +104,10 @@ DISABLE_VS_WARNINGS(4244 4345) return get_account_address_as_str(testnet, m_keys.m_account_address); } //----------------------------------------------------------------- + std::string account_base::get_public_integrated_address_str(const crypto::hash &payment_id, bool testnet) + { + //TODO: change this code into base 58 + return get_account_integrated_address_as_str(testnet, m_keys.m_account_address, payment_id); + } + //----------------------------------------------------------------- } diff --git a/src/cryptonote_core/account.h b/src/cryptonote_core/account.h index dcfd9e8d9..0f36029b5 100644 --- a/src/cryptonote_core/account.h +++ b/src/cryptonote_core/account.h @@ -60,6 +60,7 @@ namespace cryptonote crypto::secret_key generate(const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false, bool two_random = false); const account_keys& get_keys() const; std::string get_public_address_str(bool testnet); + std::string get_public_integrated_address_str(const crypto::hash &payment_id, bool testnet); uint64_t get_createtime() const { return m_creation_timestamp; } void set_createtime(uint64_t val) { m_creation_timestamp = val; } diff --git a/src/cryptonote_core/cryptonote_basic_impl.cpp b/src/cryptonote_core/cryptonote_basic_impl.cpp index f2d862e57..839c6ad1e 100644 --- a/src/cryptonote_core/cryptonote_basic_impl.cpp +++ b/src/cryptonote_core/cryptonote_basic_impl.cpp @@ -44,6 +44,21 @@ using namespace epee; namespace cryptonote { + struct integrated_address { + account_public_address adr; + crypto::hash payment_id; + + BEGIN_SERIALIZE_OBJECT() + FIELD(adr) + FIELD(payment_id) + END_SERIALIZE() + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(adr) + KV_SERIALIZE(payment_id) + END_KV_SERIALIZE_MAP() + }; + /************************************************************************/ /* Cryptonote helper functions */ /************************************************************************/ @@ -106,6 +121,16 @@ namespace cryptonote { return summ; } + //------------------------------------------------------------------------------------ + uint8_t get_account_integrated_address_checksum(const public_integrated_address_outer_blob& bl) + { + const unsigned char* pbuf = reinterpret_cast(&bl); + uint8_t summ = 0; + for(size_t i = 0; i!= sizeof(public_integrated_address_outer_blob)-1; i++) + summ += pbuf[i]; + + return summ; + } //----------------------------------------------------------------------- std::string get_account_address_as_str( bool testnet @@ -118,6 +143,21 @@ namespace cryptonote { return tools::base58::encode_addr(address_prefix, t_serializable_object_to_blob(adr)); } //----------------------------------------------------------------------- + std::string get_account_integrated_address_as_str( + bool testnet + , account_public_address const & adr + , crypto::hash const & payment_id + ) + { + uint64_t integrated_address_prefix = testnet ? + config::testnet::CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX : config::CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX; + + integrated_address iadr = { + adr, payment_id + }; + return tools::base58::encode_addr(integrated_address_prefix, t_serializable_object_to_blob(iadr)); + } + //----------------------------------------------------------------------- bool is_coinbase(const transaction& tx) { if(tx.vin.size() != 1) @@ -129,14 +169,18 @@ namespace cryptonote { return true; } //----------------------------------------------------------------------- - bool get_account_address_from_str( + bool get_account_integrated_address_from_str( account_public_address& adr + , bool& has_payment_id + , crypto::hash& payment_id , bool testnet , std::string const & str ) { uint64_t address_prefix = testnet ? config::testnet::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX : config::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX; + uint64_t integrated_address_prefix = testnet ? + config::testnet::CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX : config::CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX; if (2 * sizeof(public_address_outer_blob) != str.size()) { @@ -148,18 +192,29 @@ namespace cryptonote { return false; } - if (address_prefix != prefix) + if (integrated_address_prefix == prefix) { - LOG_PRINT_L1("Wrong address prefix: " << prefix << ", expected " << address_prefix); + has_payment_id = true; + } + else if (address_prefix == prefix) + { + has_payment_id = false; + } + else { + LOG_PRINT_L1("Wrong address prefix: " << prefix << ", expected " << address_prefix << " or " << integrated_address_prefix); return false; } - if (!::serialization::parse_binary(data, adr)) + integrated_address iadr; + if (!::serialization::parse_binary(data, iadr)) { LOG_PRINT_L1("Account public address keys can't be parsed"); return false; } + adr = iadr.adr; + payment_id = iadr.payment_id; + if (!crypto::check_key(adr.m_spend_public_key) || !crypto::check_key(adr.m_view_public_key)) { LOG_PRINT_L1("Failed to validate address keys"); @@ -196,10 +251,22 @@ namespace cryptonote { //we success adr = blob.m_address; + has_payment_id = false; } return true; } + //----------------------------------------------------------------------- + bool get_account_address_from_str( + account_public_address& adr + , bool testnet + , std::string const & str + ) + { + bool has_payment_id; + crypto::hash payment_id; + return get_account_integrated_address_from_str(adr, has_payment_id, payment_id, testnet, str); + } bool operator ==(const cryptonote::transaction& a, const cryptonote::transaction& b) { return cryptonote::get_transaction_hash(a) == cryptonote::get_transaction_hash(b); diff --git a/src/cryptonote_core/cryptonote_basic_impl.h b/src/cryptonote_core/cryptonote_basic_impl.h index 5c773c4e1..87d6f1024 100644 --- a/src/cryptonote_core/cryptonote_basic_impl.h +++ b/src/cryptonote_core/cryptonote_basic_impl.h @@ -56,6 +56,13 @@ namespace cryptonote { account_public_address m_address; uint8_t check_sum; }; + struct public_integrated_address_outer_blob + { + uint8_t m_ver; + account_public_address m_address; + crypto::hash payment_id; + uint8_t check_sum; + }; #pragma pack (pop) @@ -66,12 +73,27 @@ namespace cryptonote { size_t get_max_tx_size(); bool get_block_reward(size_t median_size, size_t current_block_size, uint64_t already_generated_coins, uint64_t &reward); uint8_t get_account_address_checksum(const public_address_outer_blob& bl); + uint8_t get_account_integrated_address_checksum(const public_integrated_address_outer_blob& bl); std::string get_account_address_as_str( bool testnet , const account_public_address& adr ); + std::string get_account_integrated_address_as_str( + bool testnet + , const account_public_address& adr + , const crypto::hash& payment_id + ); + + bool get_account_integrated_address_from_str( + account_public_address& adr + , bool& has_payment_id + , crypto::hash& payment_id + , bool testnet + , const std::string& str + ); + bool get_account_address_from_str( account_public_address& adr , bool testnet diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 3159e85d4..c40e3f0ae 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -298,6 +298,7 @@ simple_wallet::simple_wallet() m_cmd_binder.set_handler("sweep_dust", boost::bind(&simple_wallet::sweep_dust, this, _1), "Send all dust outputs to the same address with mixin 0"); m_cmd_binder.set_handler("set_log", boost::bind(&simple_wallet::set_log, this, _1), "set_log - Change current log detalization level, is a number 0-4"); m_cmd_binder.set_handler("address", boost::bind(&simple_wallet::print_address, this, _1), "Show current wallet public address"); + m_cmd_binder.set_handler("integrated_address", boost::bind(&simple_wallet::print_integrated_address, this, _1), "Show an integrated address for the current wallet public address and a payment id"); m_cmd_binder.set_handler("save", boost::bind(&simple_wallet::save, this, _1), "Save wallet synchronized data"); m_cmd_binder.set_handler("save_watch_only", boost::bind(&simple_wallet::save_watch_only, this, _1), "Save watch only keys file"); m_cmd_binder.set_handler("viewkey", boost::bind(&simple_wallet::viewkey, this, _1), "Get viewkey"); @@ -1137,6 +1138,7 @@ bool simple_wallet::transfer(const std::vector &args_) } std::vector extra; + bool payment_id_seen = false; if (1 == local_args.size() % 2) { std::string payment_id_str = local_args.back(); @@ -1156,13 +1158,17 @@ bool simple_wallet::transfer(const std::vector &args_) fail_msg_writer() << "payment id has invalid format: \"" << payment_id_str << "\", expected 64-character string"; return true; } + payment_id_seen = true; } vector dsts; + crypto::hash payment_id = null_hash; for (size_t i = 0; i < local_args.size(); i += 2) { cryptonote::tx_destination_entry de; - if(!get_account_address_from_str(de.addr, m_wallet->testnet(), local_args[i])) + bool has_payment_id; + crypto::hash new_payment_id; + if(!get_account_integrated_address_from_str(de.addr, has_payment_id, new_payment_id, m_wallet->testnet(), local_args[i])) { // if treating as an address fails, try as url bool dnssec_ok = false; @@ -1174,7 +1180,7 @@ bool simple_wallet::transfer(const std::vector &args_) // for now, move on only if one address found if (addresses_from_dns.size() == 1) { - if (get_account_address_from_str(de.addr, m_wallet->testnet(), addresses_from_dns[0])) + if (get_account_integrated_address_from_str(de.addr, has_payment_id, new_payment_id, m_wallet->testnet(), addresses_from_dns[0])) { // if it was an address, prompt user for confirmation. // inform user of DNSSEC validation status as well. @@ -1221,6 +1227,26 @@ bool simple_wallet::transfer(const std::vector &args_) } } + if (has_payment_id) { + if (payment_id_seen && payment_id != new_payment_id) { + fail_msg_writer() << "A single transaction cannot use more than one payment id: " << local_args[i]; + return true; + } + + if (!payment_id_seen) + { + std::string extra_nonce; + set_payment_id_to_tx_extra_nonce(extra_nonce, new_payment_id); + bool r = add_extra_nonce_to_tx_extra(extra, extra_nonce); + if(!r) + { + fail_msg_writer() << "Failed to set up payment id, though it was decoded correctly"; + return true; + } + payment_id = new_payment_id; + } + } + bool ok = cryptonote::parse_amount(de.amount, local_args[i + 1]); if(!ok || 0 == de.amount) { @@ -1491,6 +1517,40 @@ bool simple_wallet::print_address(const std::vector &args/* = std:: return true; } //---------------------------------------------------------------------------------------------------- +bool simple_wallet::print_integrated_address(const std::vector &args/* = std::vector()*/) +{ + if (args.size() != 1) + { + fail_msg_writer() << "Missing payment id or address"; + return true; + } + crypto::hash payment_id; + if(tools::wallet2::parse_payment_id(args.back(), payment_id)) + { + success_msg_writer() << m_wallet->get_account().get_public_integrated_address_str(payment_id, m_wallet->testnet()); + return true; + } + else { + bool has_payment_id; + crypto::hash payment_id; + account_public_address addr; + if(get_account_integrated_address_from_str(addr, has_payment_id, payment_id, m_wallet->testnet(), args.back())) + { + if (has_payment_id) + { + success_msg_writer() << "Integrated address: account " << get_account_address_as_str(m_wallet->testnet(),addr) << ", payment id " << payment_id; + } + else + { + success_msg_writer() << "Standard address: account " << get_account_address_as_str(m_wallet->testnet(),addr); + } + return true; + } + } + fail_msg_writer() << "Failed to parse payment id or address"; + return true; +} +//---------------------------------------------------------------------------------------------------- bool simple_wallet::process_command(const std::vector &args) { return m_cmd_binder.process_command_vec(args); diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index fa16fd386..bc100f507 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -108,6 +108,7 @@ namespace cryptonote std::vector dsts, size_t num_splits ); bool print_address(const std::vector &args = std::vector()); + bool print_integrated_address(const std::vector &args = std::vector()); bool save(const std::vector &args); bool save_watch_only(const std::vector &args); bool set_variable(const std::vector &args); diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 9ef19f739..8bef8cdec 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -117,12 +117,15 @@ namespace tools } //------------------------------------------------------------------------------------------------------------------------------ - bool wallet_rpc_server::validate_transfer(const std::list destinations, const std::string payment_id, std::vector& dsts, std::vector& extra, epee::json_rpc::error& er) + bool wallet_rpc_server::validate_transfer(const std::list destinations, std::string payment_id, std::vector& dsts, std::vector& extra, epee::json_rpc::error& er) { + crypto::hash integrated_payment_id = cryptonote::null_hash; for (auto it = destinations.begin(); it != destinations.end(); it++) { cryptonote::tx_destination_entry de; - if(!get_account_address_from_str(de.addr, m_wallet.testnet(), it->address)) + bool has_payment_id; + crypto::hash new_payment_id; + if(!get_account_integrated_address_from_str(de.addr, has_payment_id, new_payment_id, m_wallet.testnet(), it->address)) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + it->address; @@ -130,6 +133,17 @@ namespace tools } de.amount = it->amount; dsts.push_back(de); + + if (has_payment_id) + { + if (!payment_id.empty() || integrated_payment_id != cryptonote::null_hash) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID; + er.message = "A single payment id is allowed per transaction"; + return false; + } + integrated_payment_id = new_payment_id; + } } if (!payment_id.empty()) From 7bd6efe3130bd8637601091251d455eba5981a8f Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Thu, 11 Jun 2015 21:51:14 +0100 Subject: [PATCH 2/4] account: add a couple consts --- src/cryptonote_core/account.cpp | 4 ++-- src/cryptonote_core/account.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cryptonote_core/account.cpp b/src/cryptonote_core/account.cpp index b68103dda..313d803a5 100644 --- a/src/cryptonote_core/account.cpp +++ b/src/cryptonote_core/account.cpp @@ -98,13 +98,13 @@ DISABLE_VS_WARNINGS(4244 4345) return m_keys; } //----------------------------------------------------------------- - std::string account_base::get_public_address_str(bool testnet) + std::string account_base::get_public_address_str(bool testnet) const { //TODO: change this code into base 58 return get_account_address_as_str(testnet, m_keys.m_account_address); } //----------------------------------------------------------------- - std::string account_base::get_public_integrated_address_str(const crypto::hash &payment_id, bool testnet) + std::string account_base::get_public_integrated_address_str(const crypto::hash &payment_id, bool testnet) const { //TODO: change this code into base 58 return get_account_integrated_address_as_str(testnet, m_keys.m_account_address, payment_id); diff --git a/src/cryptonote_core/account.h b/src/cryptonote_core/account.h index 0f36029b5..909fa7ef6 100644 --- a/src/cryptonote_core/account.h +++ b/src/cryptonote_core/account.h @@ -59,8 +59,8 @@ namespace cryptonote account_base(); crypto::secret_key generate(const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false, bool two_random = false); const account_keys& get_keys() const; - std::string get_public_address_str(bool testnet); - std::string get_public_integrated_address_str(const crypto::hash &payment_id, bool testnet); + std::string get_public_address_str(bool testnet) const; + std::string get_public_integrated_address_str(const crypto::hash &payment_id, bool testnet) const; uint64_t get_createtime() const { return m_creation_timestamp; } void set_createtime(uint64_t val) { m_creation_timestamp = val; } From 67be2e4b3a911cc3b06d1df494fc4d2a047ed03a Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Thu, 11 Jun 2015 23:25:12 +0100 Subject: [PATCH 3/4] simplewallet: allow integrated_address to generate a random payment id --- src/simplewallet/simplewallet.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index c40e3f0ae..6ed7bdcda 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -298,7 +298,7 @@ simple_wallet::simple_wallet() m_cmd_binder.set_handler("sweep_dust", boost::bind(&simple_wallet::sweep_dust, this, _1), "Send all dust outputs to the same address with mixin 0"); m_cmd_binder.set_handler("set_log", boost::bind(&simple_wallet::set_log, this, _1), "set_log - Change current log detalization level, is a number 0-4"); m_cmd_binder.set_handler("address", boost::bind(&simple_wallet::print_address, this, _1), "Show current wallet public address"); - m_cmd_binder.set_handler("integrated_address", boost::bind(&simple_wallet::print_integrated_address, this, _1), "Show an integrated address for the current wallet public address and a payment id"); + m_cmd_binder.set_handler("integrated_address", boost::bind(&simple_wallet::print_integrated_address, this, _1), "Convert a payment ID to an integrated address for the current wallet public address (no arguments use a random payment ID), or display standard addres and payment ID corresponding to an integrated addres"); m_cmd_binder.set_handler("save", boost::bind(&simple_wallet::save, this, _1), "Save wallet synchronized data"); m_cmd_binder.set_handler("save_watch_only", boost::bind(&simple_wallet::save_watch_only, this, _1), "Save watch only keys file"); m_cmd_binder.set_handler("viewkey", boost::bind(&simple_wallet::viewkey, this, _1), "Get viewkey"); @@ -1519,12 +1519,19 @@ bool simple_wallet::print_address(const std::vector &args/* = std:: //---------------------------------------------------------------------------------------------------- bool simple_wallet::print_integrated_address(const std::vector &args/* = std::vector()*/) { - if (args.size() != 1) + crypto::hash payment_id; + if (args.size() > 1) { - fail_msg_writer() << "Missing payment id or address"; + fail_msg_writer() << "integrated_address only takes one or zero arguments"; + return true; + } + if (args.size() == 0) + { + crypto::generate_random_bytes(32, payment_id.data); + success_msg_writer() << "Random payment ID: " << payment_id; + success_msg_writer() << "Matching integrated address: " << m_wallet->get_account().get_public_integrated_address_str(payment_id, m_wallet->testnet()); return true; } - crypto::hash payment_id; if(tools::wallet2::parse_payment_id(args.back(), payment_id)) { success_msg_writer() << m_wallet->get_account().get_public_integrated_address_str(payment_id, m_wallet->testnet()); From 6f8a6dcb6c8113f6a37784e713cd5c5ba1806d94 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 13 Jun 2015 16:08:00 +0100 Subject: [PATCH 4/4] Add RPC commands to manipulate integrated addresses --- src/wallet/wallet_rpc_server.cpp | 64 ++++++++++++++++++++ src/wallet/wallet_rpc_server.h | 4 ++ src/wallet/wallet_rpc_server_commands_defs.h | 45 ++++++++++++++ 3 files changed, 113 insertions(+) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 8bef8cdec..7c82e69f8 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -331,6 +331,70 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_make_integrated_address(const wallet_rpc::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS::response& res, epee::json_rpc::error& er) + { + try + { + crypto::hash payment_id; + if (req.payment_id.empty()) + { + crypto::generate_random_bytes(32, payment_id.data); + } + else + { + if (!tools::wallet2::parse_payment_id(req.payment_id,payment_id)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID; + er.message = "Invalid payment ID"; + return false; + } + } + + res.integrated_address = m_wallet.get_account().get_public_integrated_address_str(payment_id, m_wallet.testnet()); + return true; + } + catch (std::exception &e) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = e.what(); + return false; + } + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_split_integrated_address(const wallet_rpc::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS::response& res, epee::json_rpc::error& er) + { + try + { + cryptonote::account_public_address address; + crypto::hash payment_id; + bool has_payment_id; + + if(!get_account_integrated_address_from_str(address, has_payment_id, payment_id, m_wallet.testnet(), req.integrated_address)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; + er.message = "Invalid address"; + return false; + } + if(!has_payment_id) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; + er.message = "Address is not an integrated address"; + return false; + } + res.standard_address = get_account_address_as_str(m_wallet.testnet(),address); + res.payment_id = boost::lexical_cast(payment_id); + return true; + } + catch (std::exception &e) + { + er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; + er.message = e.what(); + return false; + } + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_store(const wallet_rpc::COMMAND_RPC_STORE::request& req, wallet_rpc::COMMAND_RPC_STORE::response& res, epee::json_rpc::error& er) { if (m_wallet.restricted()) diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index 8538eed2b..73411a98d 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -71,6 +71,8 @@ namespace tools MAP_JON_RPC_WE("get_bulk_payments", on_get_bulk_payments, wallet_rpc::COMMAND_RPC_GET_BULK_PAYMENTS) MAP_JON_RPC_WE("incoming_transfers", on_incoming_transfers, wallet_rpc::COMMAND_RPC_INCOMING_TRANSFERS) MAP_JON_RPC_WE("query_key", on_query_key, wallet_rpc::COMMAND_RPC_QUERY_KEY) + MAP_JON_RPC_WE("make_integrated_address", on_make_integrated_address, wallet_rpc::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS) + MAP_JON_RPC_WE("split_integrated_address", on_split_integrated_address, wallet_rpc::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS) END_JSON_RPC_MAP() END_URI_MAP2() @@ -81,6 +83,8 @@ namespace tools bool on_transfer(const wallet_rpc::COMMAND_RPC_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_TRANSFER::response& res, epee::json_rpc::error& er); bool on_transfer_split(const wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::request& req, wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::response& res, epee::json_rpc::error& er); bool on_sweep_dust(const wallet_rpc::COMMAND_RPC_SWEEP_DUST::request& req, wallet_rpc::COMMAND_RPC_SWEEP_DUST::response& res, epee::json_rpc::error& er); + bool on_make_integrated_address(const wallet_rpc::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS::response& res, epee::json_rpc::error& er); + bool on_split_integrated_address(const wallet_rpc::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS::response& res, epee::json_rpc::error& er); bool on_store(const wallet_rpc::COMMAND_RPC_STORE::request& req, wallet_rpc::COMMAND_RPC_STORE::response& res, epee::json_rpc::error& er); 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); bool on_get_bulk_payments(const wallet_rpc::COMMAND_RPC_GET_BULK_PAYMENTS::request& req, wallet_rpc::COMMAND_RPC_GET_BULK_PAYMENTS::response& res, epee::json_rpc::error& er); diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index ecb3cc5e9..bff2cbf93 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -299,6 +299,51 @@ namespace wallet_rpc END_KV_SERIALIZE_MAP() }; }; + + struct COMMAND_RPC_MAKE_INTEGRATED_ADDRESS + { + struct request + { + std::string payment_id; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(payment_id) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string integrated_address; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(integrated_address) + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS + { + struct request + { + std::string integrated_address; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(integrated_address) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string standard_address; + std::string payment_id; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(standard_address) + KV_SERIALIZE(payment_id) + END_KV_SERIALIZE_MAP() + }; + }; + } }