wallet: rejig to avoid prompting in wallet2
wallet2 is a library, and should not prompt for stdin. Instead, pass a function so simplewallet can prompt on stdin, and a GUI might display a window, etc.
This commit is contained in:
+18
-28
@@ -135,7 +135,7 @@ 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)
|
||||
std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variables_map& vm, const options& opts, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
|
||||
{
|
||||
const bool testnet = command_line::get_arg(vm, opts.testnet);
|
||||
const bool restricted = command_line::get_arg(vm, opts.restricted);
|
||||
@@ -154,7 +154,9 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
|
||||
if (command_line::has_arg(vm, opts.daemon_login))
|
||||
{
|
||||
auto parsed = tools::login::parse(
|
||||
command_line::get_arg(vm, opts.daemon_login), false, "Daemon client password"
|
||||
command_line::get_arg(vm, opts.daemon_login), false, [password_prompter](bool verify) {
|
||||
return password_prompter("Daemon client password", verify);
|
||||
}
|
||||
);
|
||||
if (!parsed)
|
||||
return nullptr;
|
||||
@@ -178,7 +180,7 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
|
||||
return wallet;
|
||||
}
|
||||
|
||||
boost::optional<tools::password_container> get_password(const boost::program_options::variables_map& vm, const options& opts, const bool verify)
|
||||
boost::optional<tools::password_container> get_password(const boost::program_options::variables_map& vm, const options& opts, const std::function<boost::optional<tools::password_container>(const char*, bool)> &password_prompter, const bool verify)
|
||||
{
|
||||
if (command_line::has_arg(vm, opts.password) && command_line::has_arg(vm, opts.password_file))
|
||||
{
|
||||
@@ -207,10 +209,10 @@ boost::optional<tools::password_container> get_password(const boost::program_opt
|
||||
return {tools::password_container{std::move(password)}};
|
||||
}
|
||||
|
||||
return tools::wallet2::password_prompt(verify);
|
||||
return password_prompter(verify ? tr("Enter new wallet password") : tr("Wallet password"), verify);
|
||||
}
|
||||
|
||||
std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, const boost::program_options::variables_map& vm, const options& opts)
|
||||
std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, const boost::program_options::variables_map& vm, const options& opts, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
|
||||
{
|
||||
const bool testnet = command_line::get_arg(vm, opts.testnet);
|
||||
|
||||
@@ -359,7 +361,7 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file,
|
||||
return false;
|
||||
}
|
||||
|
||||
wallet.reset(make_basic(vm, opts).release());
|
||||
wallet.reset(make_basic(vm, opts, password_prompter).release());
|
||||
wallet->set_refresh_from_block_height(field_scan_from_height);
|
||||
|
||||
try
|
||||
@@ -496,34 +498,22 @@ void wallet2::init_options(boost::program_options::options_description& desc_par
|
||||
command_line::add_arg(desc_params, opts.restricted);
|
||||
}
|
||||
|
||||
boost::optional<password_container> wallet2::password_prompt(const bool new_password)
|
||||
{
|
||||
auto pwd_container = tools::password_container::prompt(
|
||||
new_password, (new_password ? tr("Enter new wallet password") : tr("Wallet password"))
|
||||
);
|
||||
if (!pwd_container)
|
||||
{
|
||||
tools::fail_msg_writer() << tr("failed to read wallet password");
|
||||
}
|
||||
return pwd_container;
|
||||
}
|
||||
|
||||
std::unique_ptr<wallet2> wallet2::make_from_json(const boost::program_options::variables_map& vm, const std::string& json_file)
|
||||
std::unique_ptr<wallet2> wallet2::make_from_json(const boost::program_options::variables_map& vm, const std::string& json_file, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
|
||||
{
|
||||
const options opts{};
|
||||
return generate_from_json(json_file, vm, opts);
|
||||
return generate_from_json(json_file, vm, opts, password_prompter);
|
||||
}
|
||||
|
||||
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 boost::program_options::variables_map& vm, const std::string& wallet_file, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
|
||||
{
|
||||
const options opts{};
|
||||
auto pwd = get_password(vm, opts, false);
|
||||
auto pwd = get_password(vm, opts, password_prompter, false);
|
||||
if (!pwd)
|
||||
{
|
||||
return {nullptr, password_container{}};
|
||||
}
|
||||
auto wallet = make_basic(vm, opts);
|
||||
auto wallet = make_basic(vm, opts, password_prompter);
|
||||
if (wallet)
|
||||
{
|
||||
wallet->load(wallet_file, pwd->password());
|
||||
@@ -531,21 +521,21 @@ std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_from_file(
|
||||
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)
|
||||
std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_new(const boost::program_options::variables_map& vm, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter)
|
||||
{
|
||||
const options opts{};
|
||||
auto pwd = get_password(vm, opts, true);
|
||||
auto pwd = get_password(vm, opts, password_prompter, true);
|
||||
if (!pwd)
|
||||
{
|
||||
return {nullptr, password_container{}};
|
||||
}
|
||||
return {make_basic(vm, opts), std::move(*pwd)};
|
||||
return {make_basic(vm, opts, password_prompter), std::move(*pwd)};
|
||||
}
|
||||
|
||||
std::unique_ptr<wallet2> wallet2::make_dummy(const boost::program_options::variables_map& vm)
|
||||
std::unique_ptr<wallet2> wallet2::make_dummy(const boost::program_options::variables_map& vm, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
|
||||
{
|
||||
const options opts{};
|
||||
return make_basic(vm, opts);
|
||||
return make_basic(vm, opts, password_prompter);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -155,21 +155,18 @@ namespace tools
|
||||
static bool has_testnet_option(const boost::program_options::variables_map& vm);
|
||||
static void init_options(boost::program_options::options_description& desc_params);
|
||||
|
||||
//! \return Password retrieved from prompt. Logs error on failure.
|
||||
static boost::optional<password_container> password_prompt(const bool new_password);
|
||||
|
||||
//! 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);
|
||||
static std::unique_ptr<wallet2> make_from_json(const boost::program_options::variables_map& vm, const std::string& json_file, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter);
|
||||
|
||||
//! 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);
|
||||
make_from_file(const boost::program_options::variables_map& vm, const std::string& wallet_file, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter);
|
||||
|
||||
//! 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);
|
||||
static std::pair<std::unique_ptr<wallet2>, password_container> make_new(const boost::program_options::variables_map& vm, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter);
|
||||
|
||||
//! Just parses variables.
|
||||
static std::unique_ptr<wallet2> make_dummy(const boost::program_options::variables_map& vm);
|
||||
static std::unique_ptr<wallet2> make_dummy(const boost::program_options::variables_map& vm, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter);
|
||||
|
||||
static bool verify_password(const std::string& keys_file_name, const std::string& password, bool watch_only);
|
||||
|
||||
|
||||
@@ -60,6 +60,16 @@ namespace
|
||||
const command_line::arg_descriptor<std::string> arg_wallet_dir = {"wallet-dir", "Directory for newly created wallets"};
|
||||
|
||||
constexpr const char default_rpc_username[] = "monero";
|
||||
|
||||
boost::optional<tools::password_container> password_prompter(const char *prompt, bool verify)
|
||||
{
|
||||
auto pwd_container = tools::password_container::prompt(verify, prompt);
|
||||
if (!pwd_container)
|
||||
{
|
||||
MERROR("failed to read wallet password");
|
||||
}
|
||||
return pwd_container;
|
||||
}
|
||||
}
|
||||
|
||||
namespace tools
|
||||
@@ -131,7 +141,7 @@ namespace tools
|
||||
walvars = m_wallet;
|
||||
else
|
||||
{
|
||||
tmpwal = tools::wallet2::make_dummy(*m_vm);
|
||||
tmpwal = tools::wallet2::make_dummy(*m_vm, password_prompter);
|
||||
walvars = tmpwal.get();
|
||||
}
|
||||
boost::optional<epee::net_utils::http::login> http_login{};
|
||||
@@ -1798,7 +1808,7 @@ namespace tools
|
||||
command_line::add_arg(desc, arg_password);
|
||||
po::store(po::parse_command_line(argc, argv, desc), vm2);
|
||||
}
|
||||
std::unique_ptr<tools::wallet2> wal = tools::wallet2::make_new(vm2).first;
|
||||
std::unique_ptr<tools::wallet2> wal = tools::wallet2::make_new(vm2, password_prompter).first;
|
||||
if (!wal)
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
|
||||
@@ -1872,7 +1882,7 @@ namespace tools
|
||||
}
|
||||
std::unique_ptr<tools::wallet2> wal = nullptr;
|
||||
try {
|
||||
wal = tools::wallet2::make_from_file(vm2, wallet_file).first;
|
||||
wal = tools::wallet2::make_from_file(vm2, wallet_file, password_prompter).first;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@@ -2007,11 +2017,11 @@ int main(int argc, char** argv) {
|
||||
LOG_PRINT_L0(tools::wallet_rpc_server::tr("Loading wallet..."));
|
||||
if(!wallet_file.empty())
|
||||
{
|
||||
wal = tools::wallet2::make_from_file(*vm, wallet_file).first;
|
||||
wal = tools::wallet2::make_from_file(*vm, wallet_file, password_prompter).first;
|
||||
}
|
||||
else
|
||||
{
|
||||
wal = tools::wallet2::make_from_json(*vm, from_json);
|
||||
wal = tools::wallet2::make_from_json(*vm, from_json, password_prompter);
|
||||
}
|
||||
if (!wal)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user