From ad96c478b1cd03bd3efc03ea8fb26c1177a3c778 Mon Sep 17 00:00:00 2001 From: stoffu Date: Tue, 10 Oct 2017 08:31:46 +0900 Subject: [PATCH] wallet-cli: added --generate-from-spend-key option --- src/simplewallet/simplewallet.cpp | 29 ++++++++++++++++++++++++++--- src/simplewallet/simplewallet.h | 1 + src/wallet/wallet2.cpp | 13 +++++++++++-- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index c936f481e..03b280acf 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -111,6 +111,7 @@ namespace const auto arg_wallet_file = wallet_args::arg_wallet_file(); const command_line::arg_descriptor arg_generate_new_wallet = {"generate-new-wallet", sw::tr("Generate new wallet and save it to "), ""}; const command_line::arg_descriptor arg_generate_from_view_key = {"generate-from-view-key", sw::tr("Generate incoming-only wallet from view key"), ""}; + const command_line::arg_descriptor arg_generate_from_spend_key = {"generate-from-spend-key", sw::tr("Generate deterministic wallet from spend key"), ""}; const command_line::arg_descriptor arg_generate_from_keys = {"generate-from-keys", sw::tr("Generate wallet from private keys"), ""}; const command_line::arg_descriptor arg_generate_from_multisig_keys = {"generate-from-multisig-keys", sw::tr("Generate a master wallet from multisig wallet keys"), ""}; const auto arg_generate_from_json = wallet_args::arg_generate_from_json(); @@ -1077,12 +1078,12 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) if (!handle_command_line(vm)) return false; - if((!m_generate_new.empty()) + (!m_wallet_file.empty()) + (!m_generate_from_view_key.empty()) + (!m_generate_from_keys.empty()) + (!m_generate_from_multisig_keys.empty()) + (!m_generate_from_json.empty()) > 1) + if((!m_generate_new.empty()) + (!m_wallet_file.empty()) + (!m_generate_from_view_key.empty()) + (!m_generate_from_spend_key.empty()) + (!m_generate_from_keys.empty()) + (!m_generate_from_multisig_keys.empty()) + (!m_generate_from_json.empty()) > 1) { - fail_msg_writer() << tr("can't specify more than one of --generate-new-wallet=\"wallet_name\", --wallet-file=\"wallet_name\", --generate-from-view-key=\"wallet_name\", --generate-from-keys=\"wallet_name\", --generate-from-multisig-keys=\"wallet_name\" and --generate-from-json=\"jsonfilename\""); + fail_msg_writer() << tr("can't specify more than one of --generate-new-wallet=\"wallet_name\", --wallet-file=\"wallet_name\", --generate-from-view-key=\"wallet_name\", --generate-from-spend-key=\"wallet_name\", --generate-from-keys=\"wallet_name\", --generate-from-multisig-keys=\"wallet_name\" and --generate-from-json=\"jsonfilename\""); return false; } - else if (m_generate_new.empty() && m_wallet_file.empty() && m_generate_from_view_key.empty() && m_generate_from_keys.empty() && m_generate_from_multisig_keys.empty() && m_generate_from_json.empty()) + else if (m_generate_new.empty() && m_wallet_file.empty() && m_generate_from_view_key.empty() && m_generate_from_spend_key.empty() && m_generate_from_keys.empty() && m_generate_from_multisig_keys.empty() && m_generate_from_json.empty()) { if(!ask_wallet_create_if_needed()) return false; } @@ -1190,6 +1191,25 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) bool r = new_wallet(vm, info.address, boost::none, viewkey); CHECK_AND_ASSERT_MES(r, false, tr("account creation failed")); } + else if (!m_generate_from_spend_key.empty()) + { + m_wallet_file = m_generate_from_spend_key; + // parse spend secret key + std::string spendkey_string = command_line::input_line("Secret spend key: "); + if (std::cin.eof()) + return false; + if (spendkey_string.empty()) { + fail_msg_writer() << tr("No data supplied, cancelled"); + return false; + } + if (!epee::string_tools::hex_to_pod(spendkey_string, m_recovery_key)) + { + fail_msg_writer() << tr("failed to parse spend key secret key"); + return false; + } + bool r = new_wallet(vm, m_recovery_key, true, false, ""); + CHECK_AND_ASSERT_MES(r, false, tr("account creation failed")); + } else if (!m_generate_from_keys.empty()) { m_wallet_file = m_generate_from_keys; @@ -1531,6 +1551,7 @@ bool simple_wallet::handle_command_line(const boost::program_options::variables_ m_wallet_file = command_line::get_arg(vm, arg_wallet_file); m_generate_new = command_line::get_arg(vm, arg_generate_new_wallet); m_generate_from_view_key = command_line::get_arg(vm, arg_generate_from_view_key); + m_generate_from_spend_key = command_line::get_arg(vm, arg_generate_from_spend_key); m_generate_from_keys = command_line::get_arg(vm, arg_generate_from_keys); m_generate_from_multisig_keys = command_line::get_arg(vm, arg_generate_from_multisig_keys); m_generate_from_json = command_line::get_arg(vm, arg_generate_from_json); @@ -1543,6 +1564,7 @@ bool simple_wallet::handle_command_line(const boost::program_options::variables_ m_restore_height = command_line::get_arg(vm, arg_restore_height); m_do_not_relay = command_line::get_arg(vm, arg_do_not_relay); m_restoring = !m_generate_from_view_key.empty() || + !m_generate_from_spend_key.empty() || !m_generate_from_keys.empty() || !m_generate_from_multisig_keys.empty() || !m_generate_from_json.empty() || @@ -5546,6 +5568,7 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_params, arg_wallet_file); command_line::add_arg(desc_params, arg_generate_new_wallet); command_line::add_arg(desc_params, arg_generate_from_view_key); + command_line::add_arg(desc_params, arg_generate_from_spend_key); command_line::add_arg(desc_params, arg_generate_from_keys); command_line::add_arg(desc_params, arg_generate_from_multisig_keys); command_line::add_arg(desc_params, arg_generate_from_json); diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 639cee642..8100fda55 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -281,6 +281,7 @@ namespace cryptonote std::string m_wallet_file; std::string m_generate_new; std::string m_generate_from_view_key; + std::string m_generate_from_spend_key; std::string m_generate_from_keys; std::string m_generate_from_multisig_keys; std::string m_generate_from_json; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index a87803206..54ec73692 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -305,9 +305,9 @@ std::unique_ptr generate_from_json(const std::string& json_file, GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, address, std::string, String, false, std::string()); // compatibility checks - if (!field_seed_found && !field_viewkey_found) + if (!field_seed_found && !field_viewkey_found && !field_spendkey_found) { - tools::fail_msg_writer() << tools::wallet2::tr("At least one of Electrum-style word list and private view key must be specified"); + tools::fail_msg_writer() << tools::wallet2::tr("At least one of Electrum-style word list and private view key and private spend key must be specified"); return false; } if (field_seed_found && (field_viewkey_found || field_spendkey_found)) @@ -368,6 +368,10 @@ std::unique_ptr generate_from_json(const std::string& json_file, { wallet->generate(field_filename, field_password, recovery_key, recover, false); } + else if (field_viewkey.empty() && !field_spendkey.empty()) + { + wallet->generate(field_filename, field_password, spendkey, recover, false); + } else { cryptonote::account_public_address address; @@ -390,6 +394,11 @@ std::unique_ptr generate_from_json(const std::string& json_file, } address.m_spend_public_key = info.address.m_spend_public_key; } + else + { + tools::fail_msg_writer() << tools::wallet2::tr("Address must be specified in order to create watch-only wallet"); + return false; + } wallet->generate(field_filename, field_password, address, viewkey); } else