diff options
author | Lee Clagett <code@leeclagett.com> | 2016-11-08 22:55:41 -0500 |
---|---|---|
committer | Lee Clagett <code@leeclagett.com> | 2016-11-10 16:39:27 -0500 |
commit | 358e068e878892eb3cc0f333215708390e51f0c3 (patch) | |
tree | 6fda7493c79996da048bac8f969574e4715c4ced | |
parent | Merge pull request #1312 (diff) | |
download | monero-358e068e878892eb3cc0f333215708390e51f0c3.tar.xz |
Created monero-wallet-rpc, moving functionality from monero-wallet-cli
Diffstat (limited to '')
-rw-r--r-- | src/simplewallet/CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 762 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.h | 21 | ||||
-rw-r--r-- | src/wallet/CMakeLists.txt | 39 | ||||
-rw-r--r-- | src/wallet/password_container.cpp (renamed from src/simplewallet/password_container.cpp) | 0 | ||||
-rw-r--r-- | src/wallet/password_container.h (renamed from src/simplewallet/password_container.h) | 0 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 344 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 19 | ||||
-rw-r--r-- | src/wallet/wallet_args.cpp | 185 | ||||
-rw-r--r-- | src/wallet/wallet_args.h | 53 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.cpp | 127 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.h | 9 | ||||
-rw-r--r-- | translations/monero.ts | 1796 |
13 files changed, 2299 insertions, 1062 deletions
diff --git a/src/simplewallet/CMakeLists.txt b/src/simplewallet/CMakeLists.txt index cb9ba2b7c..259008ac5 100644 --- a/src/simplewallet/CMakeLists.txt +++ b/src/simplewallet/CMakeLists.txt @@ -27,14 +27,12 @@ # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. set(simplewallet_sources - simplewallet.cpp - password_container.cpp) + simplewallet.cpp) set(simplewallet_headers) set(simplewallet_private_headers - simplewallet.h - password_container.h) + simplewallet.h) monero_private_headers(simplewallet ${simplewallet_private_headers}) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index ce1dac71a..a2b9405c8 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -52,25 +52,19 @@ #include "cryptonote_core/cryptonote_format_utils.h" #include "storages/http_abstract_invoke.h" #include "rpc/core_rpc_server_commands_defs.h" -#include "wallet/wallet_rpc_server.h" -#include "version.h" #include "crypto/crypto.h" // for crypto::secret_key definition #include "mnemonics/electrum-words.h" #include "rapidjson/document.h" #include "common/json_util.h" #include "ringct/rctSigs.h" +#include "wallet/wallet_args.h" #include <stdexcept> -#if defined(WIN32) -#include <crtdbg.h> -#endif - using namespace std; using namespace epee; using namespace cryptonote; using boost::lexical_cast; namespace po = boost::program_options; -namespace bf = boost::filesystem; typedef cryptonote::simple_wallet sw; #define EXTENDED_LOGS_FILE "wallet_details.log" @@ -80,13 +74,6 @@ typedef cryptonote::simple_wallet sw; #define KEY_IMAGE_EXPORT_FILE_MAGIC "Monero key image export\002" #define OUTPUT_EXPORT_FILE_MAGIC "Monero output export\002" -// workaround for a suspected bug in pthread/kernel on MacOS X -#ifdef __APPLE__ -#define DEFAULT_MAX_CONCURRENCY 1 -#else -#define DEFAULT_MAX_CONCURRENCY 0 -#endif - #define LOCK_IDLE_SCOPE() \ bool auto_refresh_enabled = m_auto_refresh_enabled.load(std::memory_order_relaxed); \ m_auto_refresh_enabled.store(false, std::memory_order_relaxed); \ @@ -111,24 +98,14 @@ enum TransferType { namespace { - const command_line::arg_descriptor<std::string> arg_wallet_file = {"wallet-file", sw::tr("Use wallet <arg>"), ""}; + const auto arg_wallet_file = wallet_args::arg_wallet_file(); const command_line::arg_descriptor<std::string> arg_generate_new_wallet = {"generate-new-wallet", sw::tr("Generate new wallet and save it to <arg>"), ""}; const command_line::arg_descriptor<std::string> arg_generate_from_view_key = {"generate-from-view-key", sw::tr("Generate incoming-only wallet from view key"), ""}; const command_line::arg_descriptor<std::string> arg_generate_from_keys = {"generate-from-keys", sw::tr("Generate wallet from private keys"), ""}; - const command_line::arg_descriptor<std::string> arg_generate_from_json = {"generate-from-json", sw::tr("Generate wallet from JSON format file"), ""}; - const command_line::arg_descriptor<std::string> arg_daemon_address = {"daemon-address", sw::tr("Use daemon instance at <host>:<port>"), ""}; - const command_line::arg_descriptor<std::string> arg_daemon_host = {"daemon-host", sw::tr("Use daemon instance at host <arg> instead of localhost"), ""}; - const command_line::arg_descriptor<std::string> arg_password = {"password", sw::tr("Wallet password"), "", true}; - const command_line::arg_descriptor<std::string> arg_password_file = {"password-file", sw::tr("Wallet password file"), "", true}; + const auto arg_generate_from_json = wallet_args::arg_generate_from_json(); const command_line::arg_descriptor<std::string> arg_electrum_seed = {"electrum-seed", sw::tr("Specify Electrum seed for wallet recovery/creation"), ""}; const command_line::arg_descriptor<bool> arg_restore_deterministic_wallet = {"restore-deterministic-wallet", sw::tr("Recover wallet using Electrum-style mnemonic seed"), false}; const command_line::arg_descriptor<bool> arg_non_deterministic = {"non-deterministic", sw::tr("Create non-deterministic view and spend keys"), false}; - const command_line::arg_descriptor<int> arg_daemon_port = {"daemon-port", sw::tr("Use daemon instance at port <arg> instead of 18081"), 0}; - const command_line::arg_descriptor<uint32_t> arg_log_level = {"log-level", "", LOG_LEVEL_0}; - const command_line::arg_descriptor<uint32_t> arg_max_concurrency = {"max-concurrency", "Max number of threads to use for a parallel job", DEFAULT_MAX_CONCURRENCY}; - const command_line::arg_descriptor<std::string> arg_log_file = {"log-file", sw::tr("Specify log file"), ""}; - const command_line::arg_descriptor<bool> arg_testnet = {"testnet", sw::tr("For testnet. Daemon must also be launched with --testnet flag"), false}; - const command_line::arg_descriptor<bool> arg_restricted = {"restricted-rpc", sw::tr("Restricts RPC to view-only commands"), false}; const command_line::arg_descriptor<bool> arg_trusted_daemon = {"trusted-daemon", sw::tr("Enable commands which rely on a trusted daemon"), false}; const command_line::arg_descriptor<bool> arg_allow_mismatched_daemon_version = {"allow-mismatched-daemon-version", sw::tr("Allow communicating with a daemon that uses a different RPC version"), false}; const command_line::arg_descriptor<uint64_t> arg_restore_height = {"restore-height", sw::tr("Restore from specific blockchain height"), 0}; @@ -272,7 +249,7 @@ namespace return true; } } - fail_msg_writer() << tr("failed to parse refresh type"); + fail_msg_writer() << cryptonote::simple_wallet::tr("failed to parse refresh type"); return false; } @@ -661,7 +638,6 @@ bool simple_wallet::help(const std::vector<std::string> &args/* = std::vector<st simple_wallet::simple_wallet() : m_allow_mismatched_daemon_version(false) - , m_daemon_port(0) , m_refresh_progress_reporter(*this) , m_idle_run(true) , m_auto_refresh_enabled(false) @@ -966,303 +942,12 @@ void simple_wallet::print_seed(std::string seed) // don't log std::cout << seed << std::endl; } - -//---------------------------------------------------------------------------------------------------- -bool simple_wallet::get_password(const boost::program_options::variables_map& vm, bool allow_entry, tools::password_container &pwd_container) -{ - // has_arg returns true even when the parameter is not passed ?? - const std::string gfj = command_line::get_arg(vm, arg_generate_from_json); - if (!gfj.empty()) { - // will be in the json file, if any - return true; - } - - if (has_arg(vm, arg_password) && has_arg(vm, arg_password_file)) - { - fail_msg_writer() << tr("can't specify more than one of --password and --password-file"); - return false; - } - - if (command_line::has_arg(vm, arg_password)) - { - pwd_container.password(command_line::get_arg(vm, arg_password)); - return true; - } - - if (command_line::has_arg(vm, arg_password_file)) - { - std::string password; - bool r = epee::file_io_utils::load_file_to_string(command_line::get_arg(vm, arg_password_file), - password); - if (!r) - { - fail_msg_writer() << tr("the password file specified could not be read"); - return false; - } - - // Remove line breaks the user might have inserted - password.erase(std::remove(password.begin() - 1, password.end(), '\n'), password.end()); - password.erase(std::remove(password.end() - 1, password.end(), '\r'), password.end()); - pwd_container.password(password.c_str()); - return true; - } - - if (allow_entry) - { - //vm is already part of the password container class. just need to check vm for an already existing wallet - //here need to pass in variable map. This will indicate if the wallet already exists to the read password function - bool r = pwd_container.read_password(); - if (!r) - { - fail_msg_writer() << tr("failed to read wallet password"); - return false; - } - return true; - } - - fail_msg_writer() << tr("Wallet password not set."); - return false; -} - -//---------------------------------------------------------------------------------------------------- -bool simple_wallet::generate_from_json(const boost::program_options::variables_map& vm, std::string &wallet_file, std::string &password) -{ - bool testnet = command_line::get_arg(vm, arg_testnet); - - std::string buf; - bool r = epee::file_io_utils::load_file_to_string(m_generate_from_json, buf); - if (!r) { - fail_msg_writer() << tr("Failed to load file ") << m_generate_from_json; - return false; - } - - rapidjson::Document json; - if (json.Parse(buf.c_str()).HasParseError()) { - fail_msg_writer() << tr("Failed to parse JSON"); - return false; - } - - GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, version, unsigned, Uint, true, 0); - const int current_version = 1; - if (field_version > current_version) { - fail_msg_writer() << boost::format(tr("Version %u too new, we can only grok up to %u")) % field_version % current_version; - return false; - } - - GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, filename, std::string, String, true, std::string()); - - GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, scan_from_height, uint64_t, Uint64, false, 0); - bool recover = field_scan_from_height_found; - - GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, password, std::string, String, false, std::string()); - password = field_password; - - GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, viewkey, std::string, String, false, std::string()); - crypto::secret_key viewkey; - if (field_viewkey_found) - { - cryptonote::blobdata viewkey_data; - if(!epee::string_tools::parse_hexstr_to_binbuff(field_viewkey, viewkey_data)) - { - fail_msg_writer() << tr("failed to parse view key secret key"); - return false; - } - viewkey = *reinterpret_cast<const crypto::secret_key*>(viewkey_data.data()); - crypto::public_key pkey; - if (!crypto::secret_key_to_public_key(viewkey, pkey)) { - fail_msg_writer() << tr("failed to verify view key secret key"); - return false; - } - } - - GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, spendkey, std::string, String, false, std::string()); - crypto::secret_key spendkey; - if (field_spendkey_found) - { - cryptonote::blobdata spendkey_data; - if(!epee::string_tools::parse_hexstr_to_binbuff(field_spendkey, spendkey_data)) - { - fail_msg_writer() << tr("failed to parse spend key secret key"); - return false; - } - spendkey = *reinterpret_cast<const crypto::secret_key*>(spendkey_data.data()); - crypto::public_key pkey; - if (!crypto::secret_key_to_public_key(spendkey, pkey)) { - fail_msg_writer() << tr("failed to verify spend key secret key"); - return false; - } - } - - GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, seed, std::string, String, false, std::string()); - std::string old_language; - if (field_seed_found) - { - if (!crypto::ElectrumWords::words_to_bytes(field_seed, m_recovery_key, old_language)) - { - fail_msg_writer() << tr("Electrum-style word list failed verification"); - return false; - } - m_electrum_seed = field_seed; - m_restore_deterministic_wallet = true; - } - - GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, address, std::string, String, false, std::string()); - - // compatibility checks - if (!field_seed_found && !field_viewkey_found) - { - fail_msg_writer() << tr("At least one of Electrum-style word list and private view key must be specified"); - return false; - } - if (field_seed_found && (field_viewkey_found || field_spendkey_found)) - { - fail_msg_writer() << tr("Both Electrum-style word list and private key(s) specified"); - return false; - } - - // if an address was given, we check keys against it, and deduce the spend - // public key if it was not given - if (field_address_found) - { - cryptonote::account_public_address address; - bool has_payment_id; - crypto::hash8 new_payment_id; - if(!get_account_integrated_address_from_str(address, has_payment_id, new_payment_id, testnet, field_address)) - { - fail_msg_writer() << tr("invalid address"); - return false; - } - if (field_viewkey_found) - { - crypto::public_key pkey; - if (!crypto::secret_key_to_public_key(viewkey, pkey)) { - fail_msg_writer() << tr("failed to verify view key secret key"); - return false; - } - if (address.m_view_public_key != pkey) { - fail_msg_writer() << tr("view key does not match standard address"); - return false; - } - } - if (field_spendkey_found) - { - crypto::public_key pkey; - if (!crypto::secret_key_to_public_key(spendkey, pkey)) { - fail_msg_writer() << tr("failed to verify spend key secret key"); - return false; - } - if (address.m_spend_public_key != pkey) { - fail_msg_writer() << tr("spend key does not match standard address"); - return false; - } - } - } - - m_wallet_file=field_filename; - - bool was_deprecated_wallet = m_restore_deterministic_wallet && ((old_language == crypto::ElectrumWords::old_language_name) || - crypto::ElectrumWords::get_is_old_style_seed(m_electrum_seed)); - if (was_deprecated_wallet) { - fail_msg_writer() << tr("Cannot create deprecated wallets from JSON"); - return false; - } - - m_wallet.reset(new tools::wallet2(testnet)); - m_wallet->callback(this); - m_wallet->set_refresh_from_block_height(field_scan_from_height); - - try - { - if (!field_seed.empty()) - { - m_wallet->generate(m_wallet_file, password, m_recovery_key, recover, false); - } - else - { - cryptonote::account_public_address address; - if (!crypto::secret_key_to_public_key(viewkey, address.m_view_public_key)) { - fail_msg_writer() << tr("failed to verify view key secret key"); - return false; - } - - if (field_spendkey.empty()) - { - // if we have an addres but no spend key, we can deduce the spend public key - // from the address - if (field_address_found) - { - cryptonote::account_public_address address2; - bool has_payment_id; - crypto::hash8 new_payment_id; - get_account_integrated_address_from_str(address2, has_payment_id, new_payment_id, testnet, field_address); - address.m_spend_public_key = address2.m_spend_public_key; - } - m_wallet->generate(m_wallet_file, password, address, viewkey); - } - else - { - if (!crypto::secret_key_to_public_key(spendkey, address.m_spend_public_key)) { - fail_msg_writer() << tr("failed to verify spend key secret key"); - return false; - } - m_wallet->generate(m_wallet_file, password, address, spendkey, viewkey); - } - } - } - catch (const std::exception& e) - { - fail_msg_writer() << tr("failed to generate new wallet: ") << e.what(); - return false; - } - - wallet_file = m_wallet_file; - - return r; -} - -static bool is_local_daemon(const std::string &address) -{ - // extract host - epee::net_utils::http::url_content u_c; - if (!epee::net_utils::parse_url(address, u_c)) - { - LOG_PRINT_L1("Failed to determine whether daemon is local, assuming not"); - return false; - } - if (u_c.host.empty()) - { - LOG_PRINT_L1("Failed to determine whether daemon is local, assuming not"); - return false; - } - - // resolve to IP - boost::asio::io_service io_service; - boost::asio::ip::tcp::resolver resolver(io_service); - boost::asio::ip::tcp::resolver::query query(u_c.host, ""); - boost::asio::ip::tcp::resolver::iterator i = resolver.resolve(query); - while (i != boost::asio::ip::tcp::resolver::iterator()) - { - const boost::asio::ip::tcp::endpoint &ep = *i; - if (ep.address().is_loopback()) - return true; - ++i; - } - - return false; -} - //---------------------------------------------------------------------------------------------------- bool simple_wallet::init(const boost::program_options::variables_map& vm) { if (!handle_command_line(vm)) return false; - if (!m_daemon_address.empty() && !m_daemon_host.empty() && 0 != m_daemon_port) - { - fail_msg_writer() << tr("can't specify daemon host or port more than once"); - 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_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-json=\"jsonfilename\" and --generate-from-keys=\"wallet_name\""); @@ -1273,37 +958,8 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) if(!ask_wallet_create_if_needed()) return false; } - bool testnet = command_line::get_arg(vm, arg_testnet); - - if (m_daemon_host.empty()) - m_daemon_host = "localhost"; - - if (!m_daemon_port) - { - m_daemon_port = testnet ? config::testnet::RPC_DEFAULT_PORT : config::RPC_DEFAULT_PORT; - } - - if (m_daemon_address.empty()) - m_daemon_address = std::string("http://") + m_daemon_host + ":" + std::to_string(m_daemon_port); - - // set --trusted-daemon if local - try - { - if (is_local_daemon(m_daemon_address)) - { - LOG_PRINT_L1(tr("Daemon is local, assuming trusted")); - m_trusted_daemon = true; - } - } - catch (const std::exception &e) { } - tools::password_container pwd_container(m_wallet_file.empty()); //m_wallet_file will be empty at this point for new wallets - if (!cryptonote::simple_wallet::get_password(vm, true, pwd_container)) - return false; - if (!m_generate_new.empty() || m_restoring) { - if (m_wallet_file.empty()) m_wallet_file = m_generate_new; // alias for simplicity later - std::string old_language; // check for recover flag. if present, require electrum word list (only recovery option for now). if (m_restore_deterministic_wallet) @@ -1350,6 +1006,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) } if (!m_generate_from_view_key.empty()) { + m_wallet_file = m_generate_from_view_key; // parse address std::string address_string = command_line::input_line("Standard address: "); if (std::cin.eof()) @@ -1361,7 +1018,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) cryptonote::account_public_address address; bool has_payment_id; crypto::hash8 new_payment_id; - if(!get_account_integrated_address_from_str(address, has_payment_id, new_payment_id, testnet, address_string)) + if(!get_account_integrated_address_from_str(address, has_payment_id, new_payment_id, tools::wallet2::has_testnet_option(vm), address_string)) { fail_msg_writer() << tr("failed to parse address"); return false; @@ -1396,11 +1053,12 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) return false; } - bool r = new_wallet(m_wallet_file, pwd_container.password(), address, viewkey, testnet); + bool r = new_wallet(vm, address, boost::none, viewkey); CHECK_AND_ASSERT_MES(r, false, tr("account creation failed")); } else if (!m_generate_from_keys.empty()) { + m_wallet_file = m_generate_from_keys; // parse address std::string address_string = command_line::input_line("Standard address: "); if (std::cin.eof()) @@ -1412,7 +1070,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) cryptonote::account_public_address address; bool has_payment_id; crypto::hash8 new_payment_id; - if(!get_account_integrated_address_from_str(address, has_payment_id, new_payment_id, testnet, address_string)) + if(!get_account_integrated_address_from_str(address, has_payment_id, new_payment_id, tools::wallet2::has_testnet_option(vm), address_string)) { fail_msg_writer() << tr("failed to parse address"); return false; @@ -1470,29 +1128,30 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) fail_msg_writer() << tr("view key does not match standard address"); return false; } - - bool r = new_wallet(m_wallet_file, pwd_container.password(), address, spendkey, viewkey, testnet); + bool r = new_wallet(vm, address, spendkey, viewkey); CHECK_AND_ASSERT_MES(r, false, tr("account creation failed")); } else if (!m_generate_from_json.empty()) { - std::string wallet_file, password; // we don't need to remember them - if (!generate_from_json(vm, wallet_file, password)) + m_wallet_file = m_generate_from_json; + if (!tools::wallet2::make_from_json(vm, m_wallet_file)) return false; } else { - bool r = new_wallet(m_wallet_file, pwd_container.password(), m_recovery_key, m_restore_deterministic_wallet, - m_non_deterministic, testnet, old_language); + m_wallet_file = m_generate_new; + bool r = new_wallet(vm, m_recovery_key, m_restore_deterministic_wallet, m_non_deterministic, old_language); CHECK_AND_ASSERT_MES(r, false, tr("account creation failed")); } } else { - bool r = open_wallet(m_wallet_file, pwd_container.password(), testnet); + assert(!m_wallet_file.empty()); + bool r = open_wallet(vm); CHECK_AND_ASSERT_MES(r, false, tr("failed to open account")); } - + assert(m_wallet); + m_wallet->callback(this); return true; } //---------------------------------------------------------------------------------------------------- @@ -1511,9 +1170,6 @@ bool simple_wallet::handle_command_line(const boost::program_options::variables_ m_generate_from_view_key = command_line::get_arg(vm, arg_generate_from_view_key); m_generate_from_keys = command_line::get_arg(vm, arg_generate_from_keys); m_generate_from_json = command_line::get_arg(vm, arg_generate_from_json); - m_daemon_address = command_line::get_arg(vm, arg_daemon_address); - m_daemon_host = command_line::get_arg(vm, arg_daemon_host); - m_daemon_port = command_line::get_arg(vm, arg_daemon_port); m_electrum_seed = command_line::get_arg(vm, arg_electrum_seed); m_restore_deterministic_wallet = command_line::get_arg(vm, arg_restore_deterministic_wallet); m_non_deterministic = command_line::get_arg(vm, arg_non_deterministic); @@ -1534,7 +1190,7 @@ bool simple_wallet::try_connect_to_daemon(bool silent) if (!m_wallet->check_connection(&same_version)) { if (!silent) - fail_msg_writer() << tr("wallet failed to connect to daemon: ") << m_daemon_address << ". " << + fail_msg_writer() << tr("wallet failed to connect to daemon: ") << m_wallet->get_daemon_address() << ". " << tr("Daemon either is not started or wrong port was passed. " "Please make sure daemon is running or restart the wallet with the correct daemon address."); return false; @@ -1542,7 +1198,7 @@ bool simple_wallet::try_connect_to_daemon(bool silent) if (!m_allow_mismatched_daemon_version && !same_version) { if (!silent) - fail_msg_writer() << tr("Daemon uses a different RPC version that the wallet: ") << m_daemon_address << ". " << + fail_msg_writer() << tr("Daemon uses a different RPC version that the wallet: ") << m_wallet->get_daemon_address() << ". " << tr("Either update one of them, or use --allow-mismatched-daemon-version."); return false; } @@ -1592,9 +1248,16 @@ std::string simple_wallet::get_mnemonic_language() } //---------------------------------------------------------------------------------------------------- -bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string& password, const crypto::secret_key& recovery_key, - bool recover, bool two_random, bool testnet, const std::string &old_language) +bool simple_wallet::new_wallet(const boost::program_options::variables_map& vm, + const crypto::secret_key& recovery_key, bool recover, bool two_random, const std::string &old_language) { + auto rc = tools::wallet2::make_new(vm); + m_wallet = std::move(rc.first); + if (!m_wallet) + { + return false; + } + bool was_deprecated_wallet = m_restore_deterministic_wallet && ((old_language == crypto::ElectrumWords::old_language_name) || crypto::ElectrumWords::get_is_old_style_seed(m_electrum_seed)); @@ -1616,11 +1279,6 @@ bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string return false; } - - m_wallet_file=wallet_file; - - m_wallet.reset(new tools::wallet2(testnet)); - m_wallet->callback(this); m_wallet->set_seed_language(mnemonic_language); // for a totally new account, we don't care about older blocks. @@ -1636,7 +1294,7 @@ bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string crypto::secret_key recovery_val; try { - recovery_val = m_wallet->generate(wallet_file, password, recovery_key, recover, two_random); + recovery_val = m_wallet->generate(m_wallet_file, std::move(rc.second).password(), recovery_key, recover, two_random); message_writer(epee::log_space::console_color_white, true) << tr("Generated new wallet: ") << m_wallet->get_account().get_public_address_str(m_wallet->testnet()); std::cout << tr("View key: ") << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_view_secret_key) << ENDL; @@ -1647,8 +1305,6 @@ bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string return false; } - m_wallet->init(m_daemon_address); - // convert rng value to electrum-style word list std::string electrum_words; @@ -1673,47 +1329,29 @@ bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string return true; } //---------------------------------------------------------------------------------------------------- -bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string& password, const cryptonote::account_public_address& address, - const crypto::secret_key& viewkey, bool testnet) +bool simple_wallet::new_wallet(const boost::program_options::variables_map& vm, + const cryptonote::account_public_address& address, const boost::optional<crypto::secret_key>& spendkey, + const crypto::secret_key& viewkey) { - m_wallet_file=wallet_file; - - m_wallet.reset(new tools::wallet2(testnet)); - m_wallet->callback(this); - if (m_restore_height) - m_wallet->set_refresh_from_block_height(m_restore_height); - - try + auto rc = tools::wallet2::make_new(vm); + m_wallet = std::move(rc.first); + if (!m_wallet) { - m_wallet->generate(wallet_file, password, address, viewkey); - message_writer(epee::log_space::console_color_white, true) << tr("Generated new watch-only wallet: ") - << m_wallet->get_account().get_public_address_str(m_wallet->testnet()); - std::cout << tr("View key: ") << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_view_secret_key) << ENDL; - } - catch (const std::exception& e) - { - fail_msg_writer() << tr("failed to generate new wallet: ") << e.what(); return false; } - - m_wallet->init(m_daemon_address); - - return true; -} -//---------------------------------------------------------------------------------------------------- -bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string& password, const cryptonote::account_public_address& address, - const crypto::secret_key& spendkey, const crypto::secret_key& viewkey, bool testnet) -{ - m_wallet_file=wallet_file; - - m_wallet.reset(new tools::wallet2(testnet)); - m_wallet->callback(this); if (m_restore_height) m_wallet->set_refresh_from_block_height(m_restore_height); try { - m_wallet->generate(wallet_file, password, address, spendkey, viewkey); + if (spendkey) + { + m_wallet->generate(m_wallet_file, std::move(rc.second).password(), address, *spendkey, viewkey); + } + else + { + m_wallet->generate(m_wallet_file, std::move(rc.second).password(), address, viewkey); + } message_writer(epee::log_space::console_color_white, true) << tr("Generated new wallet: ") << m_wallet->get_account().get_public_address_str(m_wallet->testnet()); } @@ -1723,26 +1361,28 @@ bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string return false; } - m_wallet->init(m_daemon_address); return true; } //---------------------------------------------------------------------------------------------------- -bool simple_wallet::open_wallet(const string &wallet_file, const std::string& password, bool testnet) +bool simple_wallet::open_wallet(const boost::program_options::variables_map& vm) { - if (!tools::wallet2::wallet_valid_path_format(wallet_file)) + if (!tools::wallet2::wallet_valid_path_format(m_wallet_file)) { - fail_msg_writer() << tr("wallet file path not valid: ") << wallet_file; + fail_msg_writer() << tr("wallet file path not valid: ") << m_wallet_file; return false; } - - m_wallet_file=wallet_file; - m_wallet.reset(new tools::wallet2(testnet)); - m_wallet->callback(this); - + std::string password; try { - m_wallet->load(m_wallet_file, password); + auto rc = tools::wallet2::make_from_file(vm, m_wallet_file); + m_wallet = std::move(rc.first); + password = std::move(rc.second).password(); + if (!m_wallet) + { + return false; + } + message_writer(epee::log_space::console_color_white, true) << (m_wallet->watch_only() ? tr("Opened watch-only wallet") : tr("Opened wallet")) << ": " << m_wallet->get_account().get_public_address_str(m_wallet->testnet()); @@ -1770,7 +1410,7 @@ bool simple_wallet::open_wallet(const string &wallet_file, const std::string& pa { message_writer(epee::log_space::console_color_green, false) << "\n" << tr("You had been using " "a deprecated version of the wallet. Your wallet file format is being upgraded now.\n"); - m_wallet->rewrite(m_wallet_file, password); + m_wallet->rewrite(m_wallet_file, password); } } } @@ -1778,13 +1418,10 @@ bool simple_wallet::open_wallet(const string &wallet_file, const std::string& pa { fail_msg_writer() << tr("failed to load wallet: ") << e.what(); // only suggest removing cache if the password was actually correct - if (m_wallet->verify_password(password)) - fail_msg_writer() << boost::format(tr("You may want to remove the file \"%s\" and try again")) % wallet_file; + if (m_wallet && m_wallet->verify_password(password)) + fail_msg_writer() << boost::format(tr("You may want to remove the file \"%s\" and try again")) % m_wallet_file; return false; } - - m_wallet->init(m_daemon_address); - success_msg_writer() << "**********************************************************************\n" << tr("Use \"help\" command to see the list of available commands.\n") << @@ -1881,6 +1518,7 @@ bool simple_wallet::start_mining(const std::vector<std::string>& args) if (!try_connect_to_daemon()) return true; + assert(m_wallet); COMMAND_RPC_START_MINING::request req; req.miner_address = m_wallet->get_account().get_public_address_str(m_wallet->testnet()); @@ -1910,7 +1548,7 @@ bool simple_wallet::start_mining(const std::vector<std::string>& args) } COMMAND_RPC_START_MINING::response res; - bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/start_mining", req, res, m_http_client); + bool r = net_utils::invoke_http_json_remote_command2(m_wallet->get_daemon_address() + "/start_mining", req, res, m_http_client); std::string err = interpret_rpc_response(r, res.status); if (err.empty()) success_msg_writer() << tr("Mining started in daemon"); @@ -1924,9 +1562,10 @@ bool simple_wallet::stop_mining(const std::vector<std::string>& args) if (!try_connect_to_daemon()) return true; + assert(m_wallet); COMMAND_RPC_STOP_MINING::request req; COMMAND_RPC_STOP_MINING::response res; - bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/stop_mining", req, res, m_http_client); + bool r = net_utils::invoke_http_json_remote_command2(m_wallet->get_daemon_address() + "/stop_mining", req, res, m_http_client); std::string err = interpret_rpc_response(r, res.status); if (err.empty()) success_msg_writer() << tr("Mining stopped in daemon"); @@ -1940,9 +1579,10 @@ bool simple_wallet::save_bc(const std::vector<std::string>& args) if (!try_connect_to_daemon()) return true; + assert(m_wallet); COMMAND_RPC_SAVE_BC::request req; COMMAND_RPC_SAVE_BC::response res; - bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/save_bc", req, res, m_http_client); + bool r = net_utils::invoke_http_json_remote_command2(m_wallet->get_daemon_address() + "/save_bc", req, res, m_http_client); std::string err = interpret_rpc_response(r, res.status); if (err.empty()) success_msg_writer() << tr("Blockchain saved"); @@ -2207,9 +1847,14 @@ bool simple_wallet::show_payments(const std::vector<std::string> &args) //---------------------------------------------------------------------------------------------------- uint64_t simple_wallet::get_daemon_blockchain_height(std::string& err) { + if (!m_wallet) + { + throw std::runtime_error("simple_wallet null wallet"); + } + COMMAND_RPC_GET_HEIGHT::request req; COMMAND_RPC_GET_HEIGHT::response res = boost::value_initialized<COMMAND_RPC_GET_HEIGHT::response>(); - bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/getheight", req, res, m_http_client); + bool r = net_utils::invoke_http_json_remote_command2(m_wallet->get_daemon_address() + "/getheight", req, res, m_http_client); err = interpret_rpc_response(r, res.status); return res.height; } @@ -3418,6 +3063,7 @@ bool simple_wallet::check_tx_key(const std::vector<std::string> &args_) if (!try_connect_to_daemon()) return true; + assert(m_wallet); cryptonote::blobdata txid_data; if(!epee::string_tools::parse_hexstr_to_binbuff(local_args[0], txid_data)) { @@ -3454,7 +3100,7 @@ bool simple_wallet::check_tx_key(const std::vector<std::string> &args_) COMMAND_RPC_GET_TRANSACTIONS::request req; COMMAND_RPC_GET_TRANSACTIONS::response res; req.txs_hashes.push_back(epee::string_tools::pod_to_hex(txid)); - if (!net_utils::invoke_http_json_remote_command2(m_daemon_address + "/gettransactions", req, res, m_http_client) || + if (!net_utils::invoke_http_json_remote_command2(m_wallet->get_daemon_address() + "/gettransactions", req, res, m_http_client) || (res.txs.size() != 1 && res.txs_as_hex.size() != 1)) { fail_msg_writer() << tr("failed to get transaction from daemon"); @@ -4261,258 +3907,68 @@ void simple_wallet::interrupt() //---------------------------------------------------------------------------------------------------- int main(int argc, char* argv[]) { -#ifdef WIN32 - _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); -#endif - - //TRY_ENTRY(); - - std::string lang = i18n_get_language(); - tools::sanitize_locale(); - tools::set_strict_default_file_permissions(true); - - string_tools::set_module_name_and_folder(argv[0]); - - po::options_description desc_general(sw::tr("General options")); - command_line::add_arg(desc_general, command_line::arg_help); - command_line::add_arg(desc_general, command_line::arg_version); - - po::options_description desc_params(sw::tr("Wallet options")); + po::options_description desc_params(wallet_args::tr("Wallet options")); + tools::wallet2::init_options(desc_params); 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_keys); command_line::add_arg(desc_params, arg_generate_from_json); - command_line::add_arg(desc_params, arg_password); - command_line::add_arg(desc_params, arg_password_file); - command_line::add_arg(desc_params, arg_daemon_address); - command_line::add_arg(desc_params, arg_daemon_host); - command_line::add_arg(desc_params, arg_daemon_port); command_line::add_arg(desc_params, arg_command); - command_line::add_arg(desc_params, arg_log_level); - command_line::add_arg(desc_params, arg_max_concurrency); - - bf::path default_log {log_space::log_singletone::get_default_log_folder()}; - std::string log_file_name = log_space::log_singletone::get_default_log_file(); - if (log_file_name.empty()) - { - // Sanity check: File path should also be empty if file name is. If not, - // this would be a problem in epee's discovery of current process's file - // path. - if (! default_log.empty()) - { - fail_msg_writer() << sw::tr("unexpected empty log file name in presence of non-empty file path"); - return false; - } - // epee didn't find path to executable from argv[0], so use this default file name. - log_file_name = "monero-wallet-cli.log"; - // The full path will use cwd because epee also returned an empty default log folder. - } - default_log /= log_file_name; - - command_line::add_arg(desc_params, arg_log_file, default_log.string()); command_line::add_arg(desc_params, arg_restore_deterministic_wallet ); command_line::add_arg(desc_params, arg_non_deterministic ); command_line::add_arg(desc_params, arg_electrum_seed ); - command_line::add_arg(desc_params, arg_testnet); - command_line::add_arg(desc_params, arg_restricted); command_line::add_arg(desc_params, arg_trusted_daemon); command_line::add_arg(desc_params, arg_allow_mismatched_daemon_version); command_line::add_arg(desc_params, arg_restore_height); - tools::wallet_rpc_server::init_options(desc_params); po::positional_options_description positional_options; positional_options.add(arg_command.name, -1); - i18n_set_language("translations", "monero", lang); + const auto vm = wallet_args::main( + argc, argv, + "monero-wallet-cli [--wallet-file=<file>|--generate-new-wallet=<file>] [<COMMAND>]", + desc_params, + positional_options + ); - po::options_description desc_all; - desc_all.add(desc_general).add(desc_params); - cryptonote::simple_wallet w; - po::variables_map vm; - bool r = command_line::handle_error_helper(desc_all, [&]() + if (!vm) { - po::store(command_line::parse_command_line(argc, argv, desc_general, true), vm); - - if (command_line::get_arg(vm, command_line::arg_help)) - { - success_msg_writer() << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"; - success_msg_writer() << sw::tr("Usage:") << " monero-wallet-cli [--wallet-file=<file>|--generate-new-wallet=<file>] [--daemon-address=<host>:<port>] [<COMMAND>]"; - success_msg_writer() << desc_all; - return false; - } - else if (command_line::get_arg(vm, command_line::arg_version)) - { - success_msg_writer() << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"; - return false; - } - - auto parser = po::command_line_parser(argc, argv).options(desc_params).positional(positional_options); - po::store(parser.run(), vm); - po::notify(vm); - return true; - }); - if (!r) - return 0; - - // log_file_path - // default: < argv[0] directory >/monero-wallet-cli.log - // so if ran as "monero-wallet-cli" (no path), log file will be in cwd - // - // if log-file argument given: - // absolute path - // relative path: relative to cwd - - // Set log file - bf::path log_file_path {bf::absolute(command_line::get_arg(vm, arg_log_file))}; - - // Set up logging options - int log_level = LOG_LEVEL_2; - log_space::get_set_log_detalisation_level(true, log_level); - //log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL, LOG_LEVEL_0); - log_space::log_singletone::add_logger(LOGGER_FILE, - log_file_path.filename().string().c_str(), - log_file_path.parent_path().string().c_str(), - LOG_LEVEL_4 - ); - - if(command_line::has_arg(vm, arg_max_concurrency)) - tools::set_max_concurrency(command_line::get_arg(vm, arg_max_concurrency)); - - message_writer(epee::log_space::console_color_white, true) << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"; - - if(command_line::has_arg(vm, arg_log_level)) - log_level = command_line::get_arg(vm, arg_log_level); - LOG_PRINT_L0("Setting log level = " << log_level); - LOG_PRINT_L0(sw::tr("default_log: ") << default_log.string()); - message_writer(epee::log_space::console_color_white, true) << boost::format(sw::tr("Logging at log level %d to %s")) % - log_level % log_file_path.string(); - log_space::get_set_log_detalisation_level(true, log_level); - - if(command_line::has_arg(vm, tools::wallet_rpc_server::arg_rpc_bind_port)) - { - log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL, LOG_LEVEL_2); - //runs wallet with rpc interface - if(!command_line::has_arg(vm, arg_wallet_file) ) - { - LOG_ERROR(sw::tr("Wallet file not set.")); - return 1; - } - if(!command_line::has_arg(vm, arg_daemon_address) ) - { - LOG_ERROR(sw::tr("Daemon address not set.")); - return 1; - } + return 1; + } - bool testnet = command_line::get_arg(vm, arg_testnet); - bool restricted = command_line::get_arg(vm, arg_restricted); - std::string wallet_file = command_line::get_arg(vm, arg_wallet_file); - - tools::password_container pwd_container(wallet_file.empty()); - if (!cryptonote::simple_wallet::get_password(vm, false, pwd_container)) - return 1; - std::string daemon_address = command_line::get_arg(vm, arg_daemon_address); - std::string daemon_host = command_line::get_arg(vm, arg_daemon_host); - int daemon_port = command_line::get_arg(vm, arg_daemon_port); - if (daemon_host.empty()) - daemon_host = "localhost"; - if (!daemon_port) - daemon_port = testnet ? config::testnet::RPC_DEFAULT_PORT : config::RPC_DEFAULT_PORT; - if (daemon_address.empty()) - daemon_address = std::string("http://") + daemon_host + ":" + std::to_string(daemon_port); - - std::string password; - const std::string gfj = command_line::get_arg(vm, arg_generate_from_json); - if (!gfj.empty()) { - if (!w.generate_from_json(vm, wallet_file, password)) - return 1; - } - else { - password = pwd_container.password(); - } + cryptonote::simple_wallet w; + const bool r = w.init(*vm); + CHECK_AND_ASSERT_MES(r, 1, sw::tr("Failed to initialize wallet")); - tools::wallet2 wal(testnet,restricted); - bool quit = false; - tools::signal_handler::install([&wal, &quit](int) { - quit = true; - wal.stop(); - }); - try - { - LOG_PRINT_L0(sw::tr("Loading wallet...")); - wal.load(wallet_file, password); - wal.init(daemon_address); - wal.refresh(); - // if we ^C during potentially length load/refresh, there's no server loop yet - if (quit) - { - LOG_PRINT_L0(sw::tr("Storing wallet...")); - wal.store(); - LOG_PRINT_GREEN(sw::tr("Stored ok"), LOG_LEVEL_0); - return 1; - } - LOG_PRINT_GREEN(sw::tr("Loaded ok"), LOG_LEVEL_0); - } - catch (const std::exception& e) - { - LOG_ERROR(sw::tr("Wallet initialization failed: ") << e.what()); - return 1; - } - tools::wallet_rpc_server wrpc(wal); - bool r = wrpc.init(vm); - CHECK_AND_ASSERT_MES(r, 1, sw::tr("Failed to initialize wallet rpc server")); - tools::signal_handler::install([&wrpc, &wal](int) { - wrpc.send_stop_signal(); - }); - LOG_PRINT_L0(sw::tr("Starting wallet rpc server")); - wrpc.run(); - LOG_PRINT_L0(sw::tr("Stopped wallet rpc server")); - try - { - LOG_PRINT_L0(sw::tr("Storing wallet...")); - wal.store(); - LOG_PRINT_GREEN(sw::tr("Stored ok"), LOG_LEVEL_0); - } - catch (const std::exception& e) - { - LOG_ERROR(sw::tr("Failed to store wallet: ") << e.what()); - return 1; - } - }else + std::vector<std::string> command = command_line::get_arg(*vm, arg_command); + if (!command.empty()) { - //runs wallet with console interface - r = w.init(vm); - CHECK_AND_ASSERT_MES(r, 1, sw::tr("Failed to initialize wallet")); - - std::vector<std::string> command = command_line::get_arg(vm, arg_command); - if (!command.empty()) - { - w.process_command(command); - w.stop(); - w.deinit(); - } - else - { - tools::signal_handler::install([&w](int type) { + w.process_command(command); + w.stop(); + w.deinit(); + } + else + { + tools::signal_handler::install([&w](int type) { #ifdef WIN32 - if (type == CTRL_C_EVENT) + if (type == CTRL_C_EVENT) #else - if (type == SIGINT) + if (type == SIGINT) #endif - { - // if we're pressing ^C when refreshing, just stop refreshing - w.interrupt(); - } - else - { - w.stop(); - } - }); - w.run(); + { + // if we're pressing ^C when refreshing, just stop refreshing + w.interrupt(); + } + else + { + w.stop(); + } + }); + w.run(); - w.deinit(); - } + w.deinit(); } return 0; //CATCH_ENTRY_L0("main", 1); diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index fcc77ff69..4fe1b0417 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -37,13 +37,14 @@ #include <memory> +#include <boost/optional/optional.hpp> #include <boost/program_options/variables_map.hpp> #include "cryptonote_core/account.h" #include "cryptonote_core/cryptonote_basic_impl.h" #include "wallet/wallet2.h" #include "console_handler.h" -#include "password_container.h" +#include "wallet/password_container.h" #include "crypto/crypto.h" // for definition of crypto::secret_key /*! @@ -58,7 +59,6 @@ namespace cryptonote class simple_wallet : public tools::i_wallet2_callback { public: - static bool get_password(const boost::program_options::variables_map& vm, bool allow_entry, tools::password_container &pwd_container); static const char *tr(const char *str) { return i18n_translate(str, "cryptonote::simple_wallet"); } public: @@ -70,7 +70,6 @@ namespace cryptonote bool run(); void stop(); void interrupt(); - bool generate_from_json(const boost::program_options::variables_map& vm, std::string &wallet_file, std::string &password); //wallet *create_wallet(); bool process_command(const std::vector<std::string> &args); @@ -82,13 +81,11 @@ namespace cryptonote void wallet_idle_thread(); - bool new_wallet(const std::string &wallet_file, const std::string& password, const crypto::secret_key& recovery_key, - bool recover, bool two_random, bool testnet, const std::string &old_language); - bool new_wallet(const std::string &wallet_file, const std::string& password, const cryptonote::account_public_address& address, - const crypto::secret_key& spendkey, const crypto::secret_key& viewkey, bool testnet); - bool new_wallet(const std::string &wallet_file, const std::string& password, const cryptonote::account_public_address& address, - const crypto::secret_key& viewkey, bool testnet); - bool open_wallet(const std::string &wallet_file, const std::string& password, bool testnet); + bool new_wallet(const boost::program_options::variables_map& vm, const crypto::secret_key& recovery_key, + bool recover, bool two_random, const std::string &old_language); + bool new_wallet(const boost::program_options::variables_map& vm, const cryptonote::account_public_address& address, + const boost::optional<crypto::secret_key>& spendkey, const crypto::secret_key& viewkey); + bool open_wallet(const boost::program_options::variables_map& vm); bool close_wallet(); bool viewkey(const std::vector<std::string> &args = std::vector<std::string>()); @@ -256,10 +253,6 @@ namespace cryptonote bool m_restoring; // are we restoring, by whatever method? uint64_t m_restore_height; // optional - std::string m_daemon_address; - std::string m_daemon_host; - int m_daemon_port; - epee::console_handlers_binder m_cmd_binder; std::unique_ptr<tools::wallet2> m_wallet; diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt index 4f82b3c82..e287d9927 100644 --- a/src/wallet/CMakeLists.txt +++ b/src/wallet/CMakeLists.txt @@ -31,7 +31,9 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(wallet_sources + password_container.cpp wallet2.cpp + wallet_args.cpp wallet_rpc_server.cpp api/wallet.cpp api/wallet_manager.cpp @@ -45,7 +47,9 @@ set(wallet_api_headers set(wallet_private_headers + password_container.h wallet2.h + wallet_args.h wallet_errors.h wallet_rpc_server.h wallet_rpc_server_commands_defs.h @@ -77,6 +81,41 @@ target_link_libraries(wallet PRIVATE ${EXTRA_LIBRARIES}) +set(wallet_rpc_sources + wallet_rpc_server.cpp) + +set(wallet_rpc_headers) + +set(wallet_rpc_private_headers + wallet_rpc_server.h) + +monero_private_headers(wallet_rpc_server + ${wallet_rpc_private_headers}) +monero_add_executable(wallet_rpc_server + ${wallet_rpc_sources} + ${wallet_rpc_headers} + ${wallet_rpc_private_headers}) + +target_link_libraries(wallet_rpc_server + PRIVATE + wallet + rpc + cryptonote_core + crypto + common + ${Boost_CHRONO_LIBRARY} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${Boost_FILESYSTEM_LIBRARY} + ${Boost_THREAD_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${EXTRA_LIBRARIES}) +add_dependencies(wallet_rpc_server version) +set_property(TARGET wallet_rpc_server + PROPERTY + OUTPUT_NAME "monero-wallet-rpc") +install(TARGETS wallet_rpc_server DESTINATION bin) + + # build and install libwallet_merged only if we building for GUI if (BUILD_GUI_DEPS) set(libs_to_merge wallet cryptonote_core mnemonics common crypto ringct) diff --git a/src/simplewallet/password_container.cpp b/src/wallet/password_container.cpp index 480d132e7..480d132e7 100644 --- a/src/simplewallet/password_container.cpp +++ b/src/wallet/password_container.cpp diff --git a/src/simplewallet/password_container.h b/src/wallet/password_container.h index 62f43aa37..62f43aa37 100644 --- a/src/simplewallet/password_container.h +++ b/src/wallet/password_container.h diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index ac8802ca4..1ed44ee98 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -32,23 +32,27 @@ #include <tuple> #include <boost/archive/binary_oarchive.hpp> #include <boost/archive/binary_iarchive.hpp> - +#include <boost/format.hpp> +#include <boost/optional/optional.hpp> #include <boost/utility/value_init.hpp> #include "include_base_utils.h" using namespace epee; #include "cryptonote_config.h" #include "wallet2.h" +#include "wallet2_api.h" #include "cryptonote_core/cryptonote_format_utils.h" #include "rpc/core_rpc_server_commands_defs.h" #include "misc_language.h" #include "cryptonote_core/cryptonote_basic_impl.h" #include "common/boost_serialization_helper.h" +#include "common/command_line.h" #include "profile_tools.h" #include "crypto/crypto.h" #include "serialization/binary_utils.h" #include "cryptonote_protocol/blobdatatype.h" #include "mnemonics/electrum-words.h" +#include "common/i18n.h" #include "common/dns_utils.h" #include "common/util.h" #include "rapidjson/document.h" @@ -56,6 +60,7 @@ using namespace epee; #include "rapidjson/stringbuffer.h" #include "common/json_util.h" #include "common/base58.h" +#include "common/scoped_message_writer.h" #include "ringct/rctSigs.h" extern "C" @@ -92,6 +97,17 @@ using namespace cryptonote; namespace { +// Create on-demand to prevent static initialization order fiasco issues. +struct options { + const command_line::arg_descriptor<std::string> daemon_address = {"daemon-address", tools::wallet2::tr("Use daemon instance at <host>:<port>"), ""}; + const command_line::arg_descriptor<std::string> daemon_host = {"daemon-host", tools::wallet2::tr("Use daemon instance at host <arg> instead of localhost"), ""}; + const command_line::arg_descriptor<std::string> password = {"password", tools::wallet2::tr("Wallet password"), "", true}; + const command_line::arg_descriptor<std::string> password_file = {"password-file", tools::wallet2::tr("Wallet password file"), "", true}; + const command_line::arg_descriptor<int> daemon_port = {"daemon-port", tools::wallet2::tr("Use daemon instance at port <arg> instead of 18081"), 0}; + const command_line::arg_descriptor<bool> testnet = {"testnet", tools::wallet2::tr("For testnet. Daemon must also be launched with --testnet flag"), false}; + const command_line::arg_descriptor<bool> restricted = {"restricted-rpc", tools::wallet2::tr("Restricts to view-only commands"), false}; +}; + void do_prepare_file_names(const std::string& file_path, std::string& keys_file, std::string& wallet_file) { keys_file = file_path; @@ -117,6 +133,279 @@ uint64_t calculate_fee(uint64_t fee_per_kb, const cryptonote::blobdata &blob, ui return calculate_fee(fee_per_kb, blob.size(), fee_multiplier); } +std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variables_map& vm, const options& opts) +{ + const bool testnet = command_line::get_arg(vm, opts.testnet); + const bool restricted = command_line::get_arg(vm, opts.restricted); + + auto daemon_address = command_line::get_arg(vm, opts.daemon_address); + auto daemon_host = command_line::get_arg(vm, opts.daemon_host); + auto daemon_port = command_line::get_arg(vm, opts.daemon_port); + + if (!daemon_address.empty() && !daemon_host.empty() && 0 != daemon_port) + { + tools::fail_msg_writer() << tools::wallet2::tr("can't specify daemon host or port more than once"); + return nullptr; + } + + if (daemon_host.empty()) + daemon_host = "localhost"; + + if (!daemon_port) + { + daemon_port = testnet ? config::testnet::RPC_DEFAULT_PORT : config::RPC_DEFAULT_PORT; + } + + if (daemon_address.empty()) + daemon_address = std::string("http://") + daemon_host + ":" + std::to_string(daemon_port); + + std::unique_ptr<tools::wallet2> wallet(new tools::wallet2(testnet, restricted)); + wallet->init(daemon_address); + return wallet; +} + +boost::optional<tools::password_container> get_password(const boost::program_options::variables_map& vm, const options& opts, const bool verify) +{ + if (command_line::has_arg(vm, opts.password) && command_line::has_arg(vm, opts.password_file)) + { + tools::fail_msg_writer() << tools::wallet2::tr("can't specify more than one of --password and --password-file"); + return boost::none; + } + + if (command_line::has_arg(vm, opts.password)) + { + tools::password_container pwd(false); + pwd.password(command_line::get_arg(vm, opts.password)); + return {std::move(pwd)}; + } + + if (command_line::has_arg(vm, opts.password_file)) + { + std::string password; + bool r = epee::file_io_utils::load_file_to_string(command_line::get_arg(vm, opts.password_file), + password); + if (!r) + { + tools::fail_msg_writer() << tools::wallet2::tr("the password file specified could not be read"); + return boost::none; + } + + // Remove line breaks the user might have inserted + password.erase(std::remove(password.begin() - 1, password.end(), '\n'), password.end()); + password.erase(std::remove(password.end() - 1, password.end(), '\r'), password.end()); + return {tools::password_container(std::move(password))}; + } + + //vm is already part of the password container class. just need to check vm for an already existing wallet + //here need to pass in variable map. This will indicate if the wallet already exists to the read password function + tools::password_container pwd(verify); + if (pwd.read_password()) + { + return {std::move(pwd)}; + } + + tools::fail_msg_writer() << tools::wallet2::tr("failed to read wallet password"); + return boost::none; +} + +std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, bool testnet, bool restricted) +{ + /* GET_FIELD_FROM_JSON_RETURN_ON_ERROR Is a generic macro that can return + false. Gcc will coerce this into unique_ptr(nullptr), but clang correctly + fails. This large wrapper is for the use of that macro */ + std::unique_ptr<tools::wallet2> wallet; + const auto do_generate = [&]() -> bool { + std::string buf; + if (!epee::file_io_utils::load_file_to_string(json_file, buf)) { + tools::fail_msg_writer() << tools::wallet2::tr("Failed to load file ") << json_file; + return false; + } + + rapidjson::Document json; + if (json.Parse(buf.c_str()).HasParseError()) { + tools::fail_msg_writer() << tools::wallet2::tr("Failed to parse JSON"); + return false; + } + + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, version, unsigned, Uint, true, 0); + const int current_version = 1; + if (field_version > current_version) { + tools::fail_msg_writer() << boost::format(tools::wallet2::tr("Version %u too new, we can only grok up to %u")) % field_version % current_version; + return false; + } + + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, filename, std::string, String, true, std::string()); + + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, scan_from_height, uint64_t, Uint64, false, 0); + const bool recover = field_scan_from_height_found; + + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, password, std::string, String, false, std::string()); + + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, viewkey, std::string, String, false, std::string()); + crypto::secret_key viewkey; + if (field_viewkey_found) + { + cryptonote::blobdata viewkey_data; + if(!epee::string_tools::parse_hexstr_to_binbuff(field_viewkey, viewkey_data)) + { + tools::fail_msg_writer() << tools::wallet2::tr("failed to parse view key secret key"); + return false; + } + viewkey = *reinterpret_cast<const crypto::secret_key*>(viewkey_data.data()); + crypto::public_key pkey; + if (!crypto::secret_key_to_public_key(viewkey, pkey)) { + tools::fail_msg_writer() << tools::wallet2::tr("failed to verify view key secret key"); + return false; + } + } + + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, spendkey, std::string, String, false, std::string()); + crypto::secret_key spendkey; + if (field_spendkey_found) + { + cryptonote::blobdata spendkey_data; + if(!epee::string_tools::parse_hexstr_to_binbuff(field_spendkey, spendkey_data)) + { + tools::fail_msg_writer() << tools::wallet2::tr("failed to parse spend key secret key"); + return false; + } + spendkey = *reinterpret_cast<const crypto::secret_key*>(spendkey_data.data()); + crypto::public_key pkey; + if (!crypto::secret_key_to_public_key(spendkey, pkey)) { + tools::fail_msg_writer() << tools::wallet2::tr("failed to verify spend key secret key"); + return false; + } + } + + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, seed, std::string, String, false, std::string()); + std::string old_language; + crypto::secret_key recovery_key; + bool restore_deterministic_wallet = false; + if (field_seed_found) + { + if (!crypto::ElectrumWords::words_to_bytes(field_seed, recovery_key, old_language)) + { + tools::fail_msg_writer() << tools::wallet2::tr("Electrum-style word list failed verification"); + return false; + } + restore_deterministic_wallet = true; + } + + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, address, std::string, String, false, std::string()); + + // compatibility checks + if (!field_seed_found && !field_viewkey_found) + { + tools::fail_msg_writer() << tools::wallet2::tr("At least one of Electrum-style word list and private view key must be specified"); + return false; + } + if (field_seed_found && (field_viewkey_found || field_spendkey_found)) + { + tools::fail_msg_writer() << tools::wallet2::tr("Both Electrum-style word list and private key(s) specified"); + return false; + } + + // if an address was given, we check keys against it, and deduce the spend + // public key if it was not given + if (field_address_found) + { + cryptonote::account_public_address address; + bool has_payment_id; + crypto::hash8 new_payment_id; + if(!get_account_integrated_address_from_str(address, has_payment_id, new_payment_id, testnet, field_address)) + { + tools::fail_msg_writer() << tools::wallet2::tr("invalid address"); + return false; + } + if (field_viewkey_found) + { + crypto::public_key pkey; + if (!crypto::secret_key_to_public_key(viewkey, pkey)) { + tools::fail_msg_writer() << tools::wallet2::tr("failed to verify view key secret key"); + return false; + } + if (address.m_view_public_key != pkey) { + tools::fail_msg_writer() << tools::wallet2::tr("view key does not match standard address"); + return false; + } + } + if (field_spendkey_found) + { + crypto::public_key pkey; + if (!crypto::secret_key_to_public_key(spendkey, pkey)) { + tools::fail_msg_writer() << tools::wallet2::tr("failed to verify spend key secret key"); + return false; + } + if (address.m_spend_public_key != pkey) { + tools::fail_msg_writer() << tools::wallet2::tr("spend key does not match standard address"); + return false; + } + } + } + + const bool deprecated_wallet = restore_deterministic_wallet && ((old_language == crypto::ElectrumWords::old_language_name) || + crypto::ElectrumWords::get_is_old_style_seed(field_seed)); + if (deprecated_wallet) { + tools::fail_msg_writer() << tools::wallet2::tr("Cannot create deprecated wallets from JSON"); + return false; + } + + wallet.reset(new tools::wallet2(testnet, restricted)); + wallet->set_refresh_from_block_height(field_scan_from_height); + + try + { + if (!field_seed.empty()) + { + wallet->generate(field_filename, field_password, recovery_key, recover, false); + } + else + { + cryptonote::account_public_address address; + if (!crypto::secret_key_to_public_key(viewkey, address.m_view_public_key)) { + tools::fail_msg_writer() << tools::wallet2::tr("failed to verify view key secret key"); + return false; + } + + if (field_spendkey.empty()) + { + // if we have an addres but no spend key, we can deduce the spend public key + // from the address + if (field_address_found) + { + cryptonote::account_public_address address2; + bool has_payment_id; + crypto::hash8 new_payment_id; + get_account_integrated_address_from_str(address2, has_payment_id, new_payment_id, testnet, field_address); + address.m_spend_public_key = address2.m_spend_public_key; + } + wallet->generate(field_filename, field_password, address, viewkey); + } + else + { + if (!crypto::secret_key_to_public_key(spendkey, address.m_spend_public_key)) { + tools::fail_msg_writer() << tools::wallet2::tr("failed to verify spend key secret key"); + return false; + } + wallet->generate(field_filename, field_password, address, spendkey, viewkey); + } + } + } + catch (const std::exception& e) + { + tools::fail_msg_writer() << tools::wallet2::tr("failed to generate new wallet: ") << e.what(); + return false; + } + return true; + }; + + if (do_generate()) + { + return wallet; + } + return nullptr; +} + } //namespace namespace tools @@ -124,6 +413,59 @@ namespace tools // for now, limit to 30 attempts. TODO: discuss a good number to limit to. const size_t MAX_SPLIT_ATTEMPTS = 30; +const char* wallet2::tr(const char* str) { return i18n_translate(str, "tools::wallet2"); } + +bool wallet2::has_testnet_option(const boost::program_options::variables_map& vm) +{ + return command_line::get_arg(vm, options().testnet); +} + +void wallet2::init_options(boost::program_options::options_description& desc_params) +{ + const options opts{}; + command_line::add_arg(desc_params, opts.daemon_address); + command_line::add_arg(desc_params, opts.daemon_host); + command_line::add_arg(desc_params, opts.password); + command_line::add_arg(desc_params, opts.password_file); + command_line::add_arg(desc_params, opts.daemon_port); + command_line::add_arg(desc_params, opts.testnet); + command_line::add_arg(desc_params, opts.restricted); +} + +std::unique_ptr<wallet2> wallet2::make_from_json(const boost::program_options::variables_map& vm, const std::string& json_file) +{ + const options opts{}; + return generate_from_json(json_file, command_line::get_arg(vm, opts.testnet), command_line::get_arg(vm, opts.restricted)); +} + +std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_from_file( + const boost::program_options::variables_map& vm, const std::string& wallet_file) +{ + const options opts{}; + auto pwd = get_password(vm, opts, false); + if (!pwd) + { + return {nullptr, password_container(false)}; + } + auto wallet = make_basic(vm, opts); + if (wallet) + { + wallet->load(wallet_file, pwd->password()); + } + return {std::move(wallet), std::move(*pwd)}; +} + +std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_new(const boost::program_options::variables_map& vm) +{ + const options opts{}; + auto pwd = get_password(vm, opts, true); + if (!pwd) + { + return {nullptr, password_container(false)}; + } + return {make_basic(vm, opts), std::move(*pwd)}; +} + //---------------------------------------------------------------------------------------------------- void wallet2::init(const std::string& daemon_address, uint64_t upper_transaction_size_limit) { diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 3c4b1015f..d42385caf 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -32,6 +32,9 @@ #include <memory> #include <boost/archive/binary_iarchive.hpp> + +#include <boost/program_options/options_description.hpp> +#include <boost/program_options/variables_map.hpp> #include <boost/serialization/list.hpp> #include <boost/serialization/vector.hpp> #include <atomic> @@ -51,6 +54,7 @@ #include "ringct/rctOps.h" #include "wallet_errors.h" +#include "password_container.h" #include <iostream> #define WALLET_RCP_CONNECTION_TIMEOUT 200000 @@ -95,6 +99,21 @@ namespace tools wallet2(const wallet2&) : m_run(true), m_callback(0), m_testnet(false), m_always_confirm_transfers(true), m_store_tx_info(true), m_default_mixin(0), m_default_priority(0), m_refresh_type(RefreshOptimizeCoinbase), m_auto_refresh(true), m_refresh_from_block_height(0), m_confirm_missing_payment_id(true) {} public: + static const char* tr(const char* str);// { return i18n_translate(str, "cryptonote::simple_wallet"); } + + static bool has_testnet_option(const boost::program_options::variables_map& vm); + static void init_options(boost::program_options::options_description& desc_params); + + //! Uses stdin and stdout. Returns a wallet2 if no errors. + static std::unique_ptr<wallet2> make_from_json(const boost::program_options::variables_map& vm, const std::string& json_file); + + //! Uses stdin and stdout. Returns a wallet2 and password for `wallet_file` if no errors. + static std::pair<std::unique_ptr<wallet2>, password_container> + make_from_file(const boost::program_options::variables_map& vm, const std::string& wallet_file); + + //! Uses stdin and stdout. Returns a wallet2 and password for wallet with no file if no errors. + static std::pair<std::unique_ptr<wallet2>, password_container> make_new(const boost::program_options::variables_map& vm); + wallet2(bool testnet = false, bool restricted = false) : m_run(true), m_callback(0), m_testnet(testnet), m_always_confirm_transfers(true), m_store_tx_info(true), m_default_mixin(0), m_default_priority(0), m_refresh_type(RefreshOptimizeCoinbase), m_auto_refresh(true), m_refresh_from_block_height(0), m_confirm_missing_payment_id(true), m_restricted(restricted), is_old_file_format(false) {} struct transfer_details { diff --git a/src/wallet/wallet_args.cpp b/src/wallet/wallet_args.cpp new file mode 100644 index 000000000..f7eec8cfc --- /dev/null +++ b/src/wallet/wallet_args.cpp @@ -0,0 +1,185 @@ +// Copyright (c) 2014-2016, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 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. +#include "wallet/wallet_args.h" + +#include <boost/filesystem/path.hpp> +#include <boost/format.hpp> +#include "common/i18n.h" +#include "common/scoped_message_writer.h" +#include "common/util.h" +#include "misc_log_ex.h" +#include "string_tools.h" +#include "version.h" + +#if defined(WIN32) +#include <crtdbg.h> +#endif + +// workaround for a suspected bug in pthread/kernel on MacOS X +#ifdef __APPLE__ +#define DEFAULT_MAX_CONCURRENCY 1 +#else +#define DEFAULT_MAX_CONCURRENCY 0 +#endif + + +namespace wallet_args +{ + // Create on-demand to prevent static initialization order fiasco issues. + command_line::arg_descriptor<std::string> arg_generate_from_json() + { + return {"generate-from-json", wallet_args::tr("Generate wallet from JSON format file"), ""}; + } + command_line::arg_descriptor<std::string> arg_wallet_file() + { + return {"wallet-file", wallet_args::tr("Use wallet <arg>"), ""}; + } + + const char* tr(const char* str) + { + return i18n_translate(str, "wallet_args"); + } + + boost::optional<boost::program_options::variables_map> main( + int argc, char** argv, + const char* const usage, + boost::program_options::options_description desc_params, + const boost::program_options::positional_options_description& positional_options) + + { + namespace bf = boost::filesystem; + namespace po = boost::program_options; +#ifdef WIN32 + _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); +#endif + + const command_line::arg_descriptor<uint32_t> arg_log_level = {"log-level", "", LOG_LEVEL_0}; + const command_line::arg_descriptor<uint32_t> arg_max_concurrency = {"max-concurrency", wallet_args::tr("Max number of threads to use for a parallel job"), DEFAULT_MAX_CONCURRENCY}; + const command_line::arg_descriptor<std::string> arg_log_file = {"log-file", wallet_args::tr("Specify log file"), ""}; + + + std::string lang = i18n_get_language(); + tools::sanitize_locale(); + tools::set_strict_default_file_permissions(true); + + epee::string_tools::set_module_name_and_folder(argv[0]); + + po::options_description desc_general(wallet_args::tr("General options")); + command_line::add_arg(desc_general, command_line::arg_help); + command_line::add_arg(desc_general, command_line::arg_version); + + + bf::path default_log {epee::log_space::log_singletone::get_default_log_folder()}; + std::string log_file_name = epee::log_space::log_singletone::get_default_log_file(); + if (log_file_name.empty()) + { + // Sanity check: File path should also be empty if file name is. If not, + // this would be a problem in epee's discovery of current process's file + // path. + if (! default_log.empty()) + { + tools::fail_msg_writer() << wallet_args::tr("unexpected empty log file name in presence of non-empty file path"); + return boost::none; + } + // epee didn't find path to executable from argv[0], so use this default file name. + log_file_name = "monero-wallet-cli.log"; + // The full path will use cwd because epee also returned an empty default log folder. + } + default_log /= log_file_name; + + command_line::add_arg(desc_params, arg_log_file, default_log.string()); + command_line::add_arg(desc_params, arg_log_level); + command_line::add_arg(desc_params, arg_max_concurrency); + + i18n_set_language("translations", "monero", lang); + + po::options_description desc_all; + desc_all.add(desc_general).add(desc_params); + po::variables_map vm; + bool r = command_line::handle_error_helper(desc_all, [&]() + { + po::store(command_line::parse_command_line(argc, argv, desc_general, true), vm); + + if (command_line::get_arg(vm, command_line::arg_help)) + { + tools::msg_writer() << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"; + tools::msg_writer() << wallet_args::tr("Usage:") << ' ' << usage; + tools::msg_writer() << desc_all; + return false; + } + else if (command_line::get_arg(vm, command_line::arg_version)) + { + tools::msg_writer() << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"; + return false; + } + + auto parser = po::command_line_parser(argc, argv).options(desc_params).positional(positional_options); + po::store(parser.run(), vm); + po::notify(vm); + return true; + }); + if (!r) + return boost::none; + + // log_file_path + // default: < argv[0] directory >/monero-wallet-cli.log + // so if ran as "monero-wallet-cli" (no path), log file will be in cwd + // + // if log-file argument given: + // absolute path + // relative path: relative to cwd + + // Set log file + bf::path log_file_path {bf::absolute(command_line::get_arg(vm, arg_log_file))}; + + // Set up logging options + int log_level = LOG_LEVEL_2; + epee::log_space::get_set_log_detalisation_level(true, log_level); + //epee::log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL, LOG_LEVEL_0); + epee::log_space::log_singletone::add_logger(LOGGER_FILE, + log_file_path.filename().string().c_str(), + log_file_path.parent_path().string().c_str(), + LOG_LEVEL_4 + ); + + if(command_line::has_arg(vm, arg_max_concurrency)) + tools::set_max_concurrency(command_line::get_arg(vm, arg_max_concurrency)); + + tools::scoped_message_writer(epee::log_space::console_color_white, true) << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"; + + if(command_line::has_arg(vm, arg_log_level)) + log_level = command_line::get_arg(vm, arg_log_level); + LOG_PRINT_L0("Setting log level = " << log_level); + LOG_PRINT_L0(wallet_args::tr("default_log: ") << default_log.string()); + tools::scoped_message_writer(epee::log_space::console_color_white, true) << boost::format(wallet_args::tr("Logging at log level %d to %s")) % + log_level % log_file_path.string(); + epee::log_space::get_set_log_detalisation_level(true, log_level); + + return {std::move(vm)}; + } +} diff --git a/src/wallet/wallet_args.h b/src/wallet/wallet_args.h new file mode 100644 index 000000000..17446abf3 --- /dev/null +++ b/src/wallet/wallet_args.h @@ -0,0 +1,53 @@ +// Copyright (c) 2014-2016, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 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. +#include <boost/optional/optional.hpp> +#include <boost/program_options/options_description.hpp> +#include <boost/program_options/positional_options.hpp> +#include <boost/program_options/variables_map.hpp> + +#include "common/command_line.h" + +namespace wallet_args +{ + command_line::arg_descriptor<std::string> arg_generate_from_json(); + command_line::arg_descriptor<std::string> arg_wallet_file(); + + const char* tr(const char* str); + + /*! Processes command line arguments (`argc` and `argv`) using `desc_params` + and `positional_options`, while adding parameters for log files and + concurrency. Log file and concurrency arguments are handled, along with basic + global init for the wallet process. + + \return The list of parsed options, iff there are no errors.*/ + boost::optional<boost::program_options::variables_map> main( + int argc, char** argv, + const char* const usage, + boost::program_options::options_description desc_params, + const boost::program_options::positional_options_description& positional_options); +} diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index faa40e166..92ad65c5b 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -27,12 +27,14 @@ // 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 <cstdint> #include "include_base_utils.h" using namespace epee; #include "wallet_rpc_server.h" +#include "wallet/wallet_args.h" #include "common/command_line.h" +#include "common/i18n.h" #include "cryptonote_core/cryptonote_format_utils.h" #include "cryptonote_core/account.h" #include "wallet_rpc_server_commands_defs.h" @@ -40,19 +42,20 @@ using namespace epee; #include "string_tools.h" #include "crypto/hash.h" -namespace tools +namespace { - //----------------------------------------------------------------------------------- - const command_line::arg_descriptor<std::string> wallet_rpc_server::arg_rpc_bind_port = {"rpc-bind-port", "Starts wallet as rpc server for wallet operations, sets bind port for server", "", true}; - const command_line::arg_descriptor<std::string> wallet_rpc_server::arg_rpc_bind_ip = {"rpc-bind-ip", "Specify ip to bind rpc server", "127.0.0.1"}; - const command_line::arg_descriptor<std::string> wallet_rpc_server::arg_user_agent = {"user-agent", "Restrict RPC to clients using this user agent", ""}; + const command_line::arg_descriptor<std::string, true> arg_rpc_bind_port = {"rpc-bind-port", "Sets bind port for server"}; + const command_line::arg_descriptor<std::string> arg_rpc_bind_ip = {"rpc-bind-ip", "Specify ip to bind rpc server", "127.0.0.1"}; + const command_line::arg_descriptor<std::string> arg_user_agent = {"user-agent", "Restrict RPC to clients using this user agent", ""}; +} - void wallet_rpc_server::init_options(boost::program_options::options_description& desc) +namespace tools +{ + const char* wallet_rpc_server::tr(const char* str) { - command_line::add_arg(desc, arg_rpc_bind_ip); - command_line::add_arg(desc, arg_rpc_bind_port); - command_line::add_arg(desc, arg_user_agent); + return i18n_translate(str, "tools::wallet_rpc_server"); } + //------------------------------------------------------------------------------------------------------------------------------ wallet_rpc_server::wallet_rpc_server(wallet2& w):m_wallet(w) {} @@ -1070,3 +1073,107 @@ namespace tools //------------------------------------------------------------------------------------------------------------------------------ } +int main(int argc, char** argv) { + namespace po = boost::program_options; + + const auto arg_wallet_file = wallet_args::arg_wallet_file(); + const auto arg_from_json = wallet_args::arg_generate_from_json(); + + po::options_description desc_params(wallet_args::tr("Wallet options")); + tools::wallet2::init_options(desc_params); + command_line::add_arg(desc_params, arg_rpc_bind_ip); + command_line::add_arg(desc_params, arg_rpc_bind_port); + command_line::add_arg(desc_params, arg_user_agent); + command_line::add_arg(desc_params, arg_wallet_file); + command_line::add_arg(desc_params, arg_from_json); + + const auto vm = wallet_args::main( + argc, argv, + "monero-wallet-rpc [--wallet-file=<file>|--generate-from-json=<file>] [--rpc-bind-port=<port>]", + desc_params, + po::positional_options_description() + ); + if (!vm) + { + return 1; + } + + epee::log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL, LOG_LEVEL_2); + + std::unique_ptr<tools::wallet2> wal; + try + { + const auto wallet_file = command_line::get_arg(*vm, arg_wallet_file); + const auto from_json = command_line::get_arg(*vm, arg_from_json); + + if(!wallet_file.empty() && !from_json.empty()) + { + LOG_ERROR(tools::wallet_rpc_server::tr("Can't specify more than one of --wallet-file and --generate-from-json")); + return 1; + } + + if (wallet_file.empty() && from_json.empty()) + { + LOG_ERROR(tools::wallet_rpc_server::tr("Must specify --wallet-file or --generate-from-json")); + return 1; + } + + LOG_PRINT_L0(tools::wallet_rpc_server::tr("Loading wallet...")); + if(!wallet_file.empty()) + { + wal = tools::wallet2::make_from_file(*vm, wallet_file).first; + } + else + { + wal = tools::wallet2::make_from_json(*vm, from_json); + } + if (!wal) + { + return 1; + } + + bool quit = false; + tools::signal_handler::install([&wal, &quit](int) { + assert(wal); + quit = true; + wal->stop(); + }); + + wal->refresh(); + // if we ^C during potentially length load/refresh, there's no server loop yet + if (quit) + { + LOG_PRINT_L0(tools::wallet_rpc_server::tr("Storing wallet...")); + wal->store(); + LOG_PRINT_GREEN(tools::wallet_rpc_server::tr("Stored ok"), LOG_LEVEL_0); + return 1; + } + LOG_PRINT_GREEN(tools::wallet_rpc_server::tr("Loaded ok"), LOG_LEVEL_0); + } + catch (const std::exception& e) + { + LOG_ERROR(tools::wallet_rpc_server::tr("Wallet initialization failed: ") << e.what()); + return 1; + } + tools::wallet_rpc_server wrpc(*wal); + bool r = wrpc.init(*vm); + CHECK_AND_ASSERT_MES(r, 1, tools::wallet_rpc_server::tr("Failed to initialize wallet rpc server")); + tools::signal_handler::install([&wrpc, &wal](int) { + wrpc.send_stop_signal(); + }); + LOG_PRINT_L0(tools::wallet_rpc_server::tr("Starting wallet rpc server")); + wrpc.run(); + LOG_PRINT_L0(tools::wallet_rpc_server::tr("Stopped wallet rpc server")); + try + { + LOG_PRINT_L0(tools::wallet_rpc_server::tr("Storing wallet...")); + wal->store(); + LOG_PRINT_GREEN(tools::wallet_rpc_server::tr("Stored ok"), LOG_LEVEL_0); + } + catch (const std::exception& e) + { + LOG_ERROR(tools::wallet_rpc_server::tr("Failed to store wallet: ") << e.what()); + return 1; + } + return 0; +} diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index b3e95c18a..4eceb1d55 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -35,7 +35,6 @@ #include "net/http_server_impl_base.h" #include "wallet_rpc_server_commands_defs.h" #include "wallet2.h" -#include "common/command_line.h" namespace tools { /************************************************************************/ @@ -46,14 +45,10 @@ namespace tools public: typedef epee::net_utils::connection_context_base connection_context; - wallet_rpc_server(wallet2& cr); - - const static command_line::arg_descriptor<std::string> arg_rpc_bind_port; - const static command_line::arg_descriptor<std::string> arg_rpc_bind_ip; - const static command_line::arg_descriptor<std::string> arg_user_agent; + static const char* tr(const char* str); + wallet_rpc_server(wallet2& cr); - static void init_options(boost::program_options::options_description& desc); bool init(const boost::program_options::variables_map& vm); bool run(); private: diff --git a/translations/monero.ts b/translations/monero.ts index 018b4f1f0..5f154944b 100644 --- a/translations/monero.ts +++ b/translations/monero.ts @@ -2,1011 +2,2061 @@ <!DOCTYPE TS> <TS version="2.0"> <context> - <name>cryptonote::simple_wallet</name> + <name>Bitmonero::PendingTransactionImpl</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="217"/> - <source>Commands: </source> + <location filename="../src/wallet/api/pending_transaction.cpp" line="95"/> + <source>daemon is busy. Please try again later.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="248"/> - <source>This wallet is watch-only and cannot have a seed.</source> + <location filename="../src/wallet/api/pending_transaction.cpp" line="98"/> + <source>no connection to daemon. Please make sure daemon is running.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="268"/> - <source>The wallet is non-deterministic. Cannot display seed.</source> + <location filename="../src/wallet/api/pending_transaction.cpp" line="102"/> + <source>transaction %s was rejected by daemon with status: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="278"/> - <source>This wallet is watch-only and doesn't have a seed.</source> + <location filename="../src/wallet/api/pending_transaction.cpp" line="105"/> + <source>Unknown exception: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="283"/> - <source>This wallet is non-deterministic and doesn't have a seed.</source> + <location filename="../src/wallet/api/pending_transaction.cpp" line="108"/> + <source>Unhandled exception</source> <translation type="unfinished"></translation> </message> +</context> +<context> + <name>Bitmonero::WalletImpl</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="290"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="320"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="554"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="916"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="923"/> - <source>failed to read wallet password</source> + <location filename="../src/wallet/api/wallet.cpp" line="593"/> + <source>payment id has invalid format, expected 16 or 64 character hex string: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="298"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="328"/> - <source>invalid password</source> + <location filename="../src/wallet/api/wallet.cpp" line="609"/> + <location filename="../src/wallet/api/wallet.cpp" line="703"/> + <source>daemon is busy. Please try again later.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="313"/> - <source>This wallet is watch-only and cannot transfer.</source> + <location filename="../src/wallet/api/wallet.cpp" line="612"/> + <location filename="../src/wallet/api/wallet.cpp" line="706"/> + <source>no connection to daemon. Please make sure daemon is running.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="347"/> - <source>start_mining [<number_of_threads>] - Start mining in daemon</source> + <location filename="../src/wallet/api/wallet.cpp" line="615"/> + <location filename="../src/wallet/api/wallet.cpp" line="709"/> + <source>RPC error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="348"/> - <source>Stop mining in daemon</source> + <location filename="../src/wallet/api/wallet.cpp" line="618"/> + <location filename="../src/wallet/api/wallet.cpp" line="712"/> + <source>failed to get random outputs to mix</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="349"/> - <source>Save current blockchain data</source> + <location filename="../src/wallet/api/wallet.cpp" line="625"/> + <location filename="../src/wallet/api/wallet.cpp" line="719"/> + <source>not enough money to transfer, available only %s, sent amount %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="350"/> - <source>Resynchronize transactions and balance</source> + <location filename="../src/wallet/api/wallet.cpp" line="634"/> + <location filename="../src/wallet/api/wallet.cpp" line="728"/> + <source>not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="351"/> - <source>Show current wallet balance</source> + <location filename="../src/wallet/api/wallet.cpp" line="643"/> + <location filename="../src/wallet/api/wallet.cpp" line="737"/> + <source>not enough outputs for specified mixin_count</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="352"/> - <source>incoming_transfers [available|unavailable] - Show incoming transfers - all of them or filter them by availability</source> + <location filename="../src/wallet/api/wallet.cpp" line="645"/> + <location filename="../src/wallet/api/wallet.cpp" line="739"/> + <source>output amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="353"/> - <source>payments <payment_id_1> [<payment_id_2> ... <payment_id_N>] - Show payments <payment_id_1>, ... <payment_id_N></source> + <location filename="../src/wallet/api/wallet.cpp" line="645"/> + <location filename="../src/wallet/api/wallet.cpp" line="739"/> + <source>found outputs to mix</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="354"/> - <source>Show blockchain height</source> + <location filename="../src/wallet/api/wallet.cpp" line="650"/> + <location filename="../src/wallet/api/wallet.cpp" line="744"/> + <source>transaction was not constructed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="355"/> - <source>transfer [<mixin_count>] <addr_1> <amount_1> [<addr_2> <amount_2> ... <addr_N> <amount_N>] [payment_id] - Transfer <amount_1>,... <amount_N> to <address_1>,... <address_N>, respectively. <mixin_count> is the number of transactions yours is indistinguishable from (from 2 to maximum available)</source> + <location filename="../src/wallet/api/wallet.cpp" line="654"/> + <location filename="../src/wallet/api/wallet.cpp" line="748"/> + <source>transaction %s was rejected by daemon with status: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="356"/> - <source>Send all dust outputs to the same address with mixin 0</source> + <location filename="../src/wallet/api/wallet.cpp" line="661"/> + <location filename="../src/wallet/api/wallet.cpp" line="755"/> + <source>one of destinations is zero</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="357"/> - <source>set_log <level> - Change current log detalization level, <level> is a number 0-4</source> + <location filename="../src/wallet/api/wallet.cpp" line="664"/> + <location filename="../src/wallet/api/wallet.cpp" line="758"/> + <source>failed to find a suitable way to split transactions</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="358"/> - <source>Show current wallet public address</source> + <location filename="../src/wallet/api/wallet.cpp" line="667"/> + <location filename="../src/wallet/api/wallet.cpp" line="761"/> + <source>unknown transfer error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="359"/> - <source>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</source> + <location filename="../src/wallet/api/wallet.cpp" line="670"/> + <location filename="../src/wallet/api/wallet.cpp" line="764"/> + <source>internal error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="360"/> - <source>Save wallet synchronized data</source> + <location filename="../src/wallet/api/wallet.cpp" line="673"/> + <location filename="../src/wallet/api/wallet.cpp" line="767"/> + <source>unexpected error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="361"/> - <source>Save watch only keys file</source> + <location filename="../src/wallet/api/wallet.cpp" line="676"/> + <location filename="../src/wallet/api/wallet.cpp" line="770"/> + <source>unknown error</source> <translation type="unfinished"></translation> </message> +</context> +<context> + <name>Bitmonero::WalletManagerImpl</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="362"/> - <source>Get viewkey</source> + <location filename="../src/wallet/api/wallet_manager.cpp" line="144"/> + <source>failed to parse txid</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="363"/> - <source>Get spendkey</source> + <location filename="../src/wallet/api/wallet_manager.cpp" line="151"/> + <location filename="../src/wallet/api/wallet_manager.cpp" line="158"/> + <source>failed to parse tx key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="364"/> - <source>Get deterministic seed</source> + <location filename="../src/wallet/api/wallet_manager.cpp" line="169"/> + <source>failed to parse address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="366"/> - <source>Show this help</source> + <location filename="../src/wallet/api/wallet_manager.cpp" line="180"/> + <source>failed to get transaction from daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="365"/> - <source>available options: seed language - Set wallet seed langage; always-confirm-transfers <1|0> - whether to confirm unsplit txes</source> + <location filename="../src/wallet/api/wallet_manager.cpp" line="191"/> + <source>failed to parse transaction from daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="373"/> - <source>set: needs an argument. available options: seed, always-confirm-transfers</source> + <location filename="../src/wallet/api/wallet_manager.cpp" line="198"/> + <source>failed to validate transaction from daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="382"/> - <source>set seed: needs an argument. available options: language</source> + <location filename="../src/wallet/api/wallet_manager.cpp" line="203"/> + <source>failed to get the right transaction from daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="397"/> - <source>set always-confirm-transfers: needs an argument (0 or 1)</source> + <location filename="../src/wallet/api/wallet_manager.cpp" line="210"/> + <source>failed to generate key derivation from supplied parameters</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="409"/> - <source>set: unrecognized argument(s)</source> + <location filename="../src/wallet/api/wallet_manager.cpp" line="266"/> + <source>error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="417"/> - <source>use: set_log <log_level_number_0-4></source> + <location filename="../src/wallet/api/wallet_manager.cpp" line="272"/> + <source>received</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="423"/> - <source>wrong number format, use: set_log <log_level_number_0-4></source> + <location filename="../src/wallet/api/wallet_manager.cpp" line="272"/> + <source>in txid</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="428"/> - <source>wrong number range, use: set_log <log_level_number_0-4></source> + <location filename="../src/wallet/api/wallet_manager.cpp" line="276"/> + <source>received nothing in txid</source> <translation type="unfinished"></translation> </message> +</context> +<context> + <name>cryptonote::simple_wallet</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="443"/> - <source>Specify wallet file name (e.g., wallet.bin). If the wallet doesn't exist, it will be created. -Wallet file name: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="276"/> + <source>Commands: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="449"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="815"/> - <source>wallet file path not valid: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="352"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="379"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="409"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="455"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="517"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="590"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="620"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1491"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1498"/> + <source>failed to read wallet password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="468"/> - <source>Attempting to generate or restore wallet, but specified file(s) exist. Exiting to not risk overwriting.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="360"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="387"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="417"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="463"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="525"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="561"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="598"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="628"/> + <source>invalid password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="482"/> - <source>The wallet doesn't exist, generating new one</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="651"/> + <source>start_mining [<number_of_threads>] - Start mining in daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="487"/> - <source>Keys file wasn't found: failed to open wallet: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="652"/> + <source>Stop mining in daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="501"/> - <source>PLEASE NOTE: the following 25 words can be used to recover access to your wallet. Please write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. -</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="653"/> + <source>Save current blockchain data</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="517"/> - <source>you can't specify daemon host or port several times</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="655"/> + <source>Show current wallet balance</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="523"/> - <source>Specifying more than one of --generate-new-wallet="wallet_name", --wallet-file="wallet_name" and --generate-from-keys doesn't make sense!</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="658"/> + <source>Show blockchain height</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="569"/> - <source>Cannot specify both --restore-deterministic-wallet and --non-deterministic</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="667"/> + <source>Show current wallet public address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="578"/> - <source>specify a recovery parameter with the --electrum-seed="words list here"</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="689"/> + <source>Show this help</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="585"/> - <source>electrum-style word list failed verification</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="712"/> + <source>set seed: needs an argument. available options: language</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="596"/> - <source>--generate-from-view-key needs a address:viewkey:filename triple</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="727"/> + <source>set always-confirm-transfers: needs an argument (0 or 1)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="606"/> - <source>Failed to parse address</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="830"/> + <source>set: unrecognized argument(s)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="614"/> - <source>Failed to parse view key secret key</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="845"/> + <source>wrong number format, use: set_log <log_level_number_0-4></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="668"/> - <source>wallet failed to connect to daemon: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="850"/> + <source>wrong number range, use: set_log <log_level_number_0-4></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="669"/> - <source>Daemon either is not started or passed wrong port. Please, make sure that daemon is running or restart the wallet with correct daemon address.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1374"/> + <source>wallet file path not valid: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="689"/> - <source>List of available languages for your wallet's seed:</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="892"/> + <source>Attempting to generate or restore wallet, but specified file(s) exist. Exiting to not risk overwriting.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="698"/> - <source>Enter the number corresponding to the language of your choice: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="941"/> + <source>PLEASE NOTE: the following 25 words can be used to recover access to your wallet. Please write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. +</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="705"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="710"/> - <source>Invalid language choice passed. Please try again. -</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="986"/> + <source>specify a recovery parameter with the --electrum-seed="words list here"</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="733"/> - <source>You had been using a deprecated version of the wallet. Please use the new seed that we provide. -</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1195"/> + <source>wallet failed to connect to daemon: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="749"/> - <source>Generated new wallet: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1223"/> + <source>List of available languages for your wallet's seed:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="751"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="798"/> - <source>view key: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1232"/> + <source>Enter the number corresponding to the language of your choice: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="755"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="802"/> - <source>failed to generate new wallet: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1276"/> + <source>You had been using a deprecated version of the wallet. Please use the new seed that we provide. +</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="768"/> - <source>Your wallet has been generated. -To start synchronizing with the daemon use "refresh" command. -Use "help" command to see the list of available commands. -Always use "exit" command when closing monero-wallet-cli to save -current session's state. Otherwise, you will possibly need to synchronize -your wallet again. Your wallet key is NOT under risk anyway. -</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1300"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1357"/> + <source>Generated new wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="796"/> - <source>Generated new watch-only wallet: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1306"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1362"/> + <source>failed to generate new wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="827"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1389"/> <source>Opened watch-only wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="827"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1389"/> <source>Opened wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="836"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1398"/> <source>You had been using a deprecated version of the wallet. Please proceed to upgrade your wallet. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="849"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1413"/> <source>You had been using a deprecated version of the wallet. Your wallet file format is being upgraded now. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="857"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1421"/> <source>failed to load wallet: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="866"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1429"/> <source>Use "help" command to see the list of available commands. </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="876"/> - <source>failed to deinit wallet</source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="898"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1473"/> <source>Wallet data saved</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="913"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1488"/> <source>Password for the new watch-only wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="920"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1495"/> <source>Enter new password again</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="928"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1503"/> <source>passwords do not match</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="965"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1547"/> <source>invalid arguments. Please use start_mining [<number_of_threads>], <number_of_threads> should be from 1 to </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="974"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1556"/> <source>Mining started in daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="976"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1558"/> <source>mining has NOT been started: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="990"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1573"/> <source>Mining stopped in daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="992"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1575"/> <source>mining has NOT been stopped: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1006"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1590"/> <source>Blockchain saved</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1008"/> - <source>Blockchain can't be saved: </source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1020"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1029"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1038"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1605"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1617"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1629"/> <source>Height </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1021"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1030"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1039"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1606"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1618"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1630"/> <source>transaction </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1022"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1607"/> <source>received </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1031"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1619"/> <source>spent </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1040"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1631"/> <source>unsupported transaction format</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1049"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1648"/> <source>Starting refresh...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1072"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1661"/> <source>Refresh done, blocks received: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1077"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1451"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1588"/> - <source>daemon is busy. Please try later</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1970"/> + <source>you have cancelled the transfer request</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1081"/> - <source>no connection to daemon. Please, make sure daemon is running</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1976"/> + <source>failed to get a Monero address from: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1086"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1460"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1597"/> - <source>RPC error: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1982"/> + <source>not yet supported: Multiple Monero addresses found for given URL: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1091"/> - <source>Error refreshing: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="1987"/> + <source>wrong address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1096"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1511"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1648"/> - <source>internal error: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2055"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2555"/> + <source>payment id has invalid format, expected 16 or 64 character hex string: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1101"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1516"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1653"/> - <source>unexpected error: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2070"/> + <source>bad locked_blocks parameter:</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1106"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1521"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1658"/> - <source>unknown error</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2075"/> + <source>Locked blocks too high, max 1000000 (˜4 yrs)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1111"/> - <source>refresh failed: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2094"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2577"/> + <source>a single transaction cannot use more than one payment id: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1111"/> - <source>Blocks received: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2103"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2586"/> + <source>failed to set up payment id, though it was decoded correctly</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1119"/> - <source>balance: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2123"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2595"/> + <source>No payment id is included with this transaction. Is this okay? (Y/Yes/N/No)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1120"/> - <source>unlocked balance: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2128"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2207"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2386"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2600"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2645"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2918"/> + <source>transaction cancelled.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1121"/> - <source>including unlocked dust: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="2183"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2899"/> + <source>Your transaction needs to be split into %llu transactions. This will result in a transaction fee being applied to each transaction, for a total fee of %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1153"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1193"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2189"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2905"/> + <source>The transaction fee is %s</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2192"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2908"/> + <source>, of which %s is dust from change</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2193"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2200"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2909"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2911"/> + <source>.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2193"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2909"/> + <source>A total of %s from dust change will be sent to dust address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2198"/> + <source>. +This transaction will unlock on block %llu, in approximately %s days (assuming 2 minutes per block)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2200"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2911"/> + <source>Is this okay? (Y/Yes/N/No)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2221"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2399"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2658"/> + <source>Failed to write transaction(s) to file</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2225"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2403"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2662"/> + <source>Unsigned transaction(s) successfully written to file: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2260"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2438"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2697"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2959"/> + <source>Not enough money in unlocked balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2269"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2447"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2706"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2968"/> + <source>Failed to find a way to create transactions. This is usually due to dust which is so small it cannot pay for itself in fees, or trying to send more money than the unlocked balance, or not leaving enough for fees</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2289"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2467"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2726"/> + <source>Reason: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2301"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2479"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2738"/> + <source>failed to find a suitable way to split transactions</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2356"/> + <source>No unmixable outputs found</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2563"/> + <source>No address given</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2615"/> + <source>No outputs found</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2797"/> + <source>Claimed change does not go to a paid address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2802"/> + <source>Claimed change is larger than payment to the change address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2814"/> + <source>sending %s to %s</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2820"/> + <source>with no destinations</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2823"/> + <source>Loaded %lu transactions, for %s, fee %s, change %s, %s, with min mixin %lu. Is this okay? (Y/Yes/N/No)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2851"/> + <source>Failed to sign transaction</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2857"/> + <source>Failed to sign transaction: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2861"/> + <source>Transaction successfully signed to file: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2876"/> + <source>Failed to load transaction from file</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2939"/> + <source>daemon is busy. Please try later</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1675"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1909"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2249"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2427"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2686"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2948"/> + <source>RPC error: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1685"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2311"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2489"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2748"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3007"/> + <source>internal error: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1690"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1914"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2316"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2494"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2753"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3012"/> + <source>unexpected error: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1695"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1919"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2321"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2499"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2758"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3017"/> + <source>unknown error</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1700"/> + <source>refresh failed: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1700"/> + <source>Blocks received: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1725"/> + <source>unlocked balance: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1766"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1810"/> <source>amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1153"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1766"/> <source>spent</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1153"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1766"/> <source>global index</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1153"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1766"/> <source>tx id</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1169"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1784"/> <source>No incoming transfers</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1173"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1788"/> <source>No incoming available transfers</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1177"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1792"/> <source>No incoming unavailable transfers</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1188"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1803"/> <source>expected at least one payment_id</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1193"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1810"/> <source>payment</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1193"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1810"/> <source>transaction</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1193"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1810"/> <source>height</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1193"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1810"/> <source>unlock time</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1205"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1822"/> <source>No payments with id </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1226"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1306"/> - <source>payment id has invalid format, expected 64-character string: </source> - <translation type="unfinished"></translation> - </message> - <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1252"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1874"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2148"/> <source>failed to get blockchain height: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1278"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2021"/> <source>wrong number of arguments</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1284"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1535"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2842"/> <source>This is a watch only wallet</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1339"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1947"/> <source>DNSSEC validation passed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1343"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="256"/> + <source>failed to parse refresh type</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="307"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="339"/> + <source>wallet is watch-only and has no seed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="329"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="344"/> + <source>wallet is non-deterministic and has no seed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="401"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="431"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="489"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="613"/> + <source>wallet is watch-only and cannot transfer</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="438"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="444"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="473"/> + <source>mixin must be an integer >= 2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="478"/> + <source>could not change default mixin</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="496"/> + <source>priority must be 0, 1, 2, or 3 </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="508"/> + <source>priority must be 0, 1, 2, or 3</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="535"/> + <source>priority must be 0, 1, 2 or 3</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="540"/> + <source>could not change default priority</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="654"/> + <source>Synchronize transactions and balance</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="656"/> + <source>incoming_transfers [available|unavailable] - Show incoming transfers, all or filtered by availability</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="657"/> + <source>payments <PID_1> [<PID_2> ... <PID_N>] - Show payments for given payment ID[s]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="659"/> + <source>transfer [<mixin_count>] <addr_1> <amount_1> [<addr_2> <amount_2> ... <addr_N> <amount_N>] [payment_id] - Transfer <amount_1>,... <amount_N> to <address_1>,... <address_N>, respectively. <mixin_count> is the number of extra inputs to include for untraceability (from 2 to maximum available)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="660"/> + <source>Same as transfer_original, but using a new transaction building algorithm</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="661"/> + <source>locked_transfer [<mixin_count>] <addr> <amount> <lockblocks>(Number of blocks to lock the transaction for, max 1000000) [<payment_id>]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="662"/> + <source>Send all unmixable outputs to yourself with mixin 0</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="663"/> + <source>sweep_all [mixin] address [payment_id] - Send all unlocked balance an address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="664"/> + <source>Sign a transaction from a file</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="665"/> + <source>Submit a signed transaction from a file</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="666"/> + <source>set_log <level> - Change current log detail level, <0-4></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="668"/> + <source>integrated_address [PID] - Encode a payment ID into an integrated address for the current wallet public address (no argument uses a random payment ID), or decode an integrated address to standard address and payment ID</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="669"/> + <source>Save wallet data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="670"/> + <source>Save a watch-only keys file</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="671"/> + <source>Display private view key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="672"/> + <source>Display private spend key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="673"/> + <source>Display Electrum-style mnemonic seed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="674"/> + <source>Available options: seed language - set wallet seed language; always-confirm-transfers <1|0> - whether to confirm unsplit txes; store-tx-info <1|0> - whether to store outgoing tx info (destination address, payment ID, tx secret key) for future reference; default-mixin <n> - set default mixin (default is 4); auto-refresh <1|0> - whether to automatically sync new blocks from the daemon; refresh-type <full|optimize-coinbase|no-coinbase|default> - set wallet refresh behaviour; priority [1|2|3] - normal/elevated/priority fee; confirm-missing-payment-id <1|0></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="675"/> + <source>Rescan blockchain for spent outputs</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="676"/> + <source>Get transaction key (r) for a given <txid></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="677"/> + <source>Check amount going to <address> in <txid></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="678"/> + <source>show_transfers [in|out] [<min_height> [<max_height>]] - Show incoming/outgoing transfers within an optional height range</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="679"/> + <source>Rescan blockchain from scratch</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="680"/> + <source>Set an arbitrary string note for a txid</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="681"/> + <source>Get a string note for a txid</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="682"/> + <source>Show wallet status information</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="683"/> + <source>Sign the contents of a file</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="684"/> + <source>Verify a signature on the contents of a file</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="685"/> + <source>Export a signed set of key images</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="686"/> + <source>Import signed key images list and verify their spent status</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="687"/> + <source>Export a set of outputs owned by this wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="688"/> + <source>Import set of outputs owned by this wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="742"/> + <source>set store-tx-info: needs an argument (0 or 1)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="757"/> + <source>set default-mixin: needs an argument (integer >= 2)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="772"/> + <source>set auto-refresh: needs an argument (0 or 1)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="787"/> + <source>set refresh-type: needs an argument:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="788"/> + <source>full (slowest, no assumptions); optimize-coinbase (fast, assumes the whole coinbase is paid to a single address); no-coinbase (fastest, assumes we receive no coinbase transaction), default (same as optimize-coinbase)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="803"/> + <source>set priority: needs an argument: 0, 1, 2, or 3</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="818"/> + <source>set confirm-missing-payment-id: needs an argument (0 or 1)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="839"/> + <source>usage: set_log <log_level_number_0-4></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="870"/> + <source>Specify wallet file name (e.g., MyWallet). If the wallet doesn't exist, it will be created. +Wallet file name (or Ctrl-C to quit): </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="880"/> + <source>Wallet name not valid. Please try again or use Ctrl-C to quit.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="897"/> + <source>Wallet and key files found, loading...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="903"/> + <source>Key file found but not wallet file. Regenerating...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="909"/> + <source>Key file not found. Failed to open wallet: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="914"/> + <source>No wallet/key file found with that name. Confirm creation of new wallet named: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="915"/> + <source>(y)es/(n)o: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="923"/> + <source>Generating new wallet...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="957"/> + <source>can't specify more than one of --generate-new-wallet="wallet_name", --wallet-file="wallet_name", --generate-from-view-key="wallet_name", --generate-from-json="jsonfilename" and --generate-from-keys="wallet_name"</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="975"/> + <source>can't specify both --restore-deterministic-wallet and --non-deterministic</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="993"/> + <source>Electrum-style word list failed verification</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1008"/> + <source>bad m_restore_height parameter:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1020"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1037"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1071"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1088"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1104"/> + <source>No data supplied, cancelled</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1028"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1079"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3098"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3636"/> + <source>failed to parse address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1043"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1110"/> + <source>failed to parse view key secret key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1053"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1128"/> + <source>failed to verify view key secret key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1057"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1132"/> + <source>view key does not match standard address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1062"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1136"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1146"/> + <source>account creation failed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1094"/> + <source>failed to parse spend key secret key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1120"/> + <source>failed to verify spend key secret key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1124"/> + <source>spend key does not match standard address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1153"/> + <source>failed to open account</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1196"/> + <source>Daemon either is not started or wrong port was passed. Please make sure daemon is running or restart the wallet with the correct daemon address.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1203"/> + <source>Daemon uses a different RPC version that the wallet: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1204"/> + <source>Either update one of them, or use --allow-mismatched-daemon-version.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1241"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1246"/> + <source>invalid language choice passed. Please try again. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1302"/> + <source>View key: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1317"/> + <source>Your wallet has been generated! +To start synchronizing with the daemon, use "refresh" command. +Use "help" command to see the list of available commands. +Always use "exit" command when closing monero-wallet-cli to save your +current session's state. Otherwise, you might need to synchronize +your wallet again (your wallet keys are NOT at risk in any case). +</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1424"/> + <source>You may want to remove the file "%s" and try again</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1450"/> + <source>failed to deinitialize wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1516"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1882"/> + <source>this command requires a trusted daemon. Enable with --trusted-daemon</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1592"/> + <source>blockchain can't be saved: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1666"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1896"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2240"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2418"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2677"/> + <source>daemon is busy. Please try again later.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1670"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1900"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2244"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2422"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2681"/> + <source>no connection to daemon. Please make sure daemon is running.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1680"/> + <source>refresh error: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1724"/> + <source>Balance: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1766"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1773"/> + <source>unlocked</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1766"/> + <source>ringct</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1772"/> + <source>T</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1772"/> + <source>F</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1773"/> + <source>locked</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1774"/> + <source>RingCT</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1774"/> + <source>-</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1843"/> + <source>payment ID has invalid format, expected 16 or 64 character hex string: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1904"/> + <source>failed to get spent status</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="1951"/> <source>WARNING: DNSSEC validation was unsuccessful, this address may not be correct!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1346"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1954"/> <source>For URL: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1348"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1956"/> <source> Monero Address = </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1350"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1958"/> <source>Is this OK? (Y/n) </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1356"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1968"/> <source>yes</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1356"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="1968"/> <source>no</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1358"/> - <source>You have cancelled the transfer request</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3474"/> + <source>usage: integrated_address [payment ID]</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1364"/> - <source>Failed to get a Monero address from: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3497"/> + <source>Integrated address: account %s, payment ID %s</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1370"/> - <source>Not yet supported: Multiple Monero addresses found for given URL: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3502"/> + <source>Standard address: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1374"/> - <source>Wrong address: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3507"/> + <source>failed to parse payment ID or address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1381"/> - <source>A single transaction cannot use more than one payment id: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3515"/> + <source>usage: set_tx_note [txid] free text note</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1392"/> - <source>Failed to set up payment id, though it was decoded correctly</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3543"/> + <source>usage: get_tx_note [txid]</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1402"/> - <source>amount is wrong: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3591"/> + <source>usage: sign <filename></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1403"/> - <source>expected number from 0 to </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3596"/> + <source>wallet is watch-only and cannot sign</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1424"/> - <source>Your transaction needs to be split into %llu transactions. This will result in a transaction fee being applied to each transaction, for a total fee of %s. Is this okay? (Y/Yes/N/No)</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3604"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3627"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3714"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3837"/> + <source>failed to read file </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1430"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1568"/> - <source>Transaction cancelled.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3616"/> + <source>usage: verify <filename> <address> <signature></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1443"/> - <source>Money successfully sent, transaction </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3643"/> + <source>Bad signature from </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1455"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1592"/> - <source>no connection to daemon. Please, make sure daemon is running.</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3647"/> + <source>Good signature from </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1464"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1601"/> - <source>failed to get random outputs to mix</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3656"/> + <source>usage: export_key_images <filename></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1468"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1605"/> - <source>not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3661"/> + <source>wallet is watch-only and cannot export key images</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3686"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3809"/> + <source>failed to save file </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3697"/> + <source>Signed key images exported to </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3705"/> + <source>usage: import_key_images <filename></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1477"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1614"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3787"/> + <source>usage: export_outputs <filename></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3820"/> + <source>Outputs exported to </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3828"/> + <source>usage: import_outputs <filename></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2112"/> + <source>amount is wrong: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2113"/> + <source>expected number from 0 to </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2232"/> + <source>Money successfully sent, transaction </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2943"/> + <source>no connection to daemon. Please, make sure daemon is running.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2253"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2431"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2690"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2952"/> + <source>failed to get random outputs to mix</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="2274"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2452"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2711"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2973"/> <source>not enough outputs for specified mixin_count</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1480"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1617"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2277"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2455"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2714"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2976"/> <source>output amount</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1480"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1617"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2277"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2455"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2714"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2976"/> <source>found outputs to mix</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1485"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1622"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2282"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2460"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2719"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2981"/> <source>transaction was not constructed</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1489"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1626"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2286"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2464"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2723"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2985"/> <source>transaction %s was rejected by daemon with status: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1497"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1634"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2297"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2475"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2734"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2993"/> <source>one of destinations is zero</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1501"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1638"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2997"/> <source>Failed to find a suitable way to split transactions</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1506"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1643"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2306"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2484"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2743"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3002"/> <source>unknown transfer error: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1553"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2369"/> <source>Sweeping </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1555"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2371"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2630"/> <source>Sweeping %s in %llu transactions for a total fee of %s. Is this okay? (Y/Yes/N/No)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1561"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2377"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2636"/> <source>Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No)</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1580"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2410"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2669"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="2931"/> <source>Money successfully sent, transaction: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1667"/> - <source>wallet</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3028"/> + <source>usage: get_tx_key <txid></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1687"/> - <source>integrated_address only takes one or zero arguments</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3035"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3072"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3522"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3550"/> + <source>failed to parse txid</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1693"/> - <source>Random payment ID: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3046"/> + <source>Tx key: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1694"/> - <source>Matching integrated address: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3051"/> + <source>no tx keys found for this txid</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3061"/> + <source>usage: check_tx_key <txid> <txkey> <address></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3081"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3088"/> + <source>failed to parse tx key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3108"/> + <source>failed to get transaction from daemon</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3119"/> + <source>failed to parse transaction from daemon</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3126"/> + <source>failed to validate transaction from daemon</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3131"/> + <source>failed to get the right transaction from daemon</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3138"/> + <source>failed to generate key derivation from supplied parameters</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3194"/> + <source>error: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3200"/> + <source>received</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3200"/> + <source>in txid</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3204"/> + <source>received nothing in txid</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3208"/> + <source>WARNING: this transaction is not yet included in the blockchain!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1710"/> - <source>Integrated address: account %s, payment id %s</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3217"/> + <source>This transaction has %u confirmations</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1715"/> - <source>Standard address: account: </source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3221"/> + <source>WARNING: failed to determine number of confirmations!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1720"/> - <source>Failed to parse payment id or address</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3261"/> + <source>usage: show_transfers [in|out|all|pending|failed] [<min_height> [<max_height>]]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3300"/> + <source>bad min_height parameter:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3312"/> + <source>bad max_height parameter:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3358"/> + <source>in</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3358"/> + <location filename="../src/simplewallet/simplewallet.cpp" line="3396"/> + <source>out</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3396"/> + <source>failed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3396"/> + <source>pending</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3449"/> + <source>wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3480"/> + <source>Random payment ID: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="3481"/> + <source>Matching integrated address: </source> <translation type="unfinished"></translation> </message> </context> <context> <name>sw</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="81"/> - <source>Use wallet <arg></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="106"/> + <source>Generate new wallet and save it to <arg></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="107"/> + <source>Generate incoming-only wallet from view key</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="108"/> + <source>Generate wallet from private keys</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="110"/> + <source>Specify Electrum seed for wallet recovery/creation</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="111"/> + <source>Recover wallet using Electrum-style mnemonic seed</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="112"/> + <source>Create non-deterministic view and spend keys</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="113"/> + <source>Enable commands which rely on a trusted daemon</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="82"/> - <source>Generate new wallet and save it to <arg> or <address>.wallet by default</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="114"/> + <source>Allow communicating with a daemon that uses a different RPC version</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="115"/> + <source>Restore from specific blockchain height</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="126"/> + <source>daemon is busy. Please try again later.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="135"/> + <source>possibly lost connection to daemon</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="216"/> + <source>Error: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/simplewallet/simplewallet.cpp" line="228"/> + <source>yes</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="83"/> - <source>Generate wallet from (address:viewkey:filename) and save it to <filename></source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3945"/> + <source>Failed to initialize wallet</source> <translation type="unfinished"></translation> </message> +</context> +<context> + <name>tools::wallet2</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="84"/> + <location filename="../src/wallet/wallet2.cpp" line="102"/> <source>Use daemon instance at <host>:<port></source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="85"/> + <location filename="../src/wallet/wallet2.cpp" line="103"/> <source>Use daemon instance at host <arg> instead of localhost</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="86"/> + <location filename="../src/wallet/wallet2.cpp" line="104"/> <source>Wallet password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="87"/> - <source>Specify electrum seed for wallet recovery/creation</source> + <location filename="../src/wallet/wallet2.cpp" line="105"/> + <source>Wallet password file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="88"/> - <source>Recover wallet using electrum-style mnemonic</source> + <location filename="../src/wallet/wallet2.cpp" line="106"/> + <source>Use daemon instance at port <arg> instead of 18081</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="89"/> - <source>creates non-deterministic view and spend keys</source> + <location filename="../src/wallet/wallet2.cpp" line="107"/> + <source>For testnet. Daemon must also be launched with --testnet flag</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="90"/> - <source>Use daemon instance at port <arg> instead of 8081</source> + <location filename="../src/wallet/wallet2.cpp" line="108"/> + <source>Restricts to view-only commands</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="92"/> - <source>Specify log file</source> + <location filename="../src/wallet/wallet2.cpp" line="147"/> + <source>can't specify daemon host or port more than once</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="93"/> - <source>Used to deploy test nets. The daemon must be launched with --testnet flag</source> + <location filename="../src/wallet/wallet2.cpp" line="171"/> + <source>can't specify more than one of --password and --password-file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="94"/> - <source>Restricts RPC to view only commands</source> + <location filename="../src/wallet/wallet2.cpp" line="189"/> + <source>the password file specified could not be read</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="105"/> - <source>daemon is busy. Please try later</source> + <location filename="../src/wallet/wallet2.cpp" line="207"/> + <source>failed to read wallet password</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="114"/> - <source>possible lost connection to daemon</source> + <location filename="../src/wallet/wallet2.cpp" line="215"/> + <source>Failed to load file </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="195"/> - <source>Error: </source> + <location filename="../src/wallet/wallet2.cpp" line="221"/> + <source>Failed to parse JSON</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="207"/> - <source>yes</source> + <location filename="../src/wallet/wallet2.cpp" line="228"/> + <source>Version %u too new, we can only grok up to %u</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1739"/> - <source>General options</source> + <location filename="../src/wallet/wallet2.cpp" line="246"/> + <source>failed to parse view key secret key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1743"/> - <source>Wallet options</source> + <location filename="../src/wallet/wallet2.cpp" line="252"/> + <location filename="../src/wallet/wallet2.cpp" line="319"/> + <location filename="../src/wallet/wallet2.cpp" line="361"/> + <source>failed to verify view key secret key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1756"/> - <source>default_log: </source> + <location filename="../src/wallet/wallet2.cpp" line="264"/> + <source>failed to parse spend key secret key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1781"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1788"/> - <location filename="../src/simplewallet/simplewallet.cpp" line="1819"/> - <source>wallet</source> + <location filename="../src/wallet/wallet2.cpp" line="270"/> + <location filename="../src/wallet/wallet2.cpp" line="331"/> + <location filename="../src/wallet/wallet2.cpp" line="382"/> + <source>failed to verify spend key secret key</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1782"/> - <source>Usage:</source> + <location filename="../src/wallet/wallet2.cpp" line="283"/> + <source>Electrum-style word list failed verification</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1824"/> - <source>Logging at log level %d to %s</source> + <location filename="../src/wallet/wallet2.cpp" line="294"/> + <source>At least one of Electrum-style word list and private view key must be specified</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="299"/> + <source>Both Electrum-style word list and private key(s) specified</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="312"/> + <source>invalid address</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet2.cpp" line="323"/> + <source>view key does not match standard address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1834"/> - <source>Wallet file not set.</source> + <location filename="../src/wallet/wallet2.cpp" line="335"/> + <source>spend key does not match standard address</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1839"/> - <source>Daemon address not set.</source> + <location filename="../src/wallet/wallet2.cpp" line="344"/> + <source>Cannot create deprecated wallets from JSON</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1844"/> - <source>Wallet password not set.</source> + <location filename="../src/wallet/wallet2.cpp" line="391"/> + <source>failed to generate new wallet: </source> <translation type="unfinished"></translation> </message> +</context> +<context> + <name>tools::wallet_rpc_server</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1865"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1111"/> + <source>Can't specify more than one of --wallet-file and --generate-from-json</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1117"/> + <source>Must specify --wallet-file or --generate-from-json</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1121"/> <source>Loading wallet...</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1869"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1146"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1169"/> + <source>Storing wallet...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1148"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1171"/> + <source>Stored ok</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1151"/> <source>Loaded ok</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1873"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1155"/> <source>Wallet initialization failed: </source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1878"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1160"/> <source>Failed to initialize wallet rpc server</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1884"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1164"/> <source>Starting wallet rpc server</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1886"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1166"/> <source>Stopped wallet rpc server</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1889"/> - <source>Storing wallet...</source> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1175"/> + <source>Failed to store wallet: </source> <translation type="unfinished"></translation> </message> +</context> +<context> + <name>wallet_args</name> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1891"/> - <source>Stored ok</source> + <location filename="../src/simplewallet/simplewallet.cpp" line="3912"/> + <location filename="../src/wallet/wallet_rpc_server.cpp" line="1082"/> + <source>Wallet options</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1895"/> - <source>Failed to store wallet: </source> + <location filename="../src/wallet/wallet_args.cpp" line="25"/> + <source>Generate wallet from JSON format file</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../src/simplewallet/simplewallet.cpp" line="1902"/> - <source>Failed to initialize wallet</source> + <location filename="../src/wallet/wallet_args.cpp" line="29"/> + <source>Use wallet <arg></source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="51"/> + <source>Max number of threads to use for a parallel job</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="52"/> + <source>Specify log file</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="61"/> + <source>General options</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="75"/> + <source>unexpected empty log file name in presence of non-empty file path</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="100"/> + <source>Usage:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="147"/> + <source>default_log: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../src/wallet/wallet_args.cpp" line="148"/> + <source>Logging at log level %d to %s</source> <translation type="unfinished"></translation> </message> </context> |