|
|
|
@ -161,6 +161,7 @@ struct options {
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const command_line::arg_descriptor<uint64_t> kdf_rounds = {"kdf-rounds", tools::wallet2::tr("Number of rounds for the key derivation function"), 1};
|
|
|
|
|
const command_line::arg_descriptor<std::string> hw_device = {"hw-device", tools::wallet2::tr("HW device to use"), ""};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void do_prepare_file_names(const std::string& file_path, std::string& keys_file, std::string& wallet_file)
|
|
|
|
@ -211,6 +212,7 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
|
|
|
|
|
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);
|
|
|
|
|
auto device_name = command_line::get_arg(vm, opts.hw_device);
|
|
|
|
|
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(!daemon_address.empty() && !daemon_host.empty() && 0 != daemon_port,
|
|
|
|
|
tools::error::wallet_internal_error, tools::wallet2::tr("can't specify daemon host or port more than once"));
|
|
|
|
@ -265,6 +267,7 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
|
|
|
|
|
wallet->init(unattended, std::move(daemon_address), std::move(login), 0, false, *trusted_daemon);
|
|
|
|
|
boost::filesystem::path ringdb_path = command_line::get_arg(vm, opts.shared_ringdb_dir);
|
|
|
|
|
wallet->set_ring_database(ringdb_path.string());
|
|
|
|
|
wallet->device_name(device_name);
|
|
|
|
|
return wallet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -814,6 +817,11 @@ bool wallet2::has_stagenet_option(const boost::program_options::variables_map& v
|
|
|
|
|
return command_line::get_arg(vm, options().stagenet);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string wallet2::device_name_option(const boost::program_options::variables_map& vm)
|
|
|
|
|
{
|
|
|
|
|
return command_line::get_arg(vm, options().hw_device);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void wallet2::init_options(boost::program_options::options_description& desc_params)
|
|
|
|
|
{
|
|
|
|
|
const options opts{};
|
|
|
|
@ -829,6 +837,7 @@ void wallet2::init_options(boost::program_options::options_description& desc_par
|
|
|
|
|
command_line::add_arg(desc_params, opts.stagenet);
|
|
|
|
|
command_line::add_arg(desc_params, opts.shared_ringdb_dir);
|
|
|
|
|
command_line::add_arg(desc_params, opts.kdf_rounds);
|
|
|
|
|
command_line::add_arg(desc_params, opts.hw_device);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<wallet2> wallet2::make_from_json(const boost::program_options::variables_map& vm, bool unattended, const std::string& json_file, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
|
|
|
|
@ -984,6 +993,27 @@ bool wallet2::get_multisig_seed(epee::wipeable_string& seed, const epee::wipeabl
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
|
bool wallet2::reconnect_device()
|
|
|
|
|
{
|
|
|
|
|
bool r = true;
|
|
|
|
|
hw::device &hwdev = hw::get_device(m_device_name);
|
|
|
|
|
hwdev.set_name(m_device_name);
|
|
|
|
|
r = hwdev.init();
|
|
|
|
|
if (!r){
|
|
|
|
|
LOG_PRINT_L2("Could not init device");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r = hwdev.connect();
|
|
|
|
|
if (!r){
|
|
|
|
|
LOG_PRINT_L2("Could not connect to the device");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_account.set_device(hwdev);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
|
/*!
|
|
|
|
|
* \brief Gets the seed language
|
|
|
|
|
*/
|
|
|
|
@ -2980,6 +3010,9 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable
|
|
|
|
|
value2.SetUint(1);
|
|
|
|
|
json.AddMember("encrypted_secret_keys", value2, json.GetAllocator());
|
|
|
|
|
|
|
|
|
|
value.SetString(m_device_name.c_str(), m_device_name.size());
|
|
|
|
|
json.AddMember("device_name", value, json.GetAllocator());
|
|
|
|
|
|
|
|
|
|
// Serialize the JSON object
|
|
|
|
|
rapidjson::StringBuffer buffer;
|
|
|
|
|
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
|
|
|
@ -3088,6 +3121,7 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
|
|
|
|
|
m_ignore_fractional_outputs = true;
|
|
|
|
|
m_subaddress_lookahead_major = SUBADDRESS_LOOKAHEAD_MAJOR;
|
|
|
|
|
m_subaddress_lookahead_minor = SUBADDRESS_LOOKAHEAD_MINOR;
|
|
|
|
|
m_device_name = "";
|
|
|
|
|
m_key_on_device = false;
|
|
|
|
|
encrypted_secret_keys = false;
|
|
|
|
|
}
|
|
|
|
@ -3219,8 +3253,15 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
|
|
|
|
|
m_subaddress_lookahead_major = field_subaddress_lookahead_major;
|
|
|
|
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, subaddress_lookahead_minor, uint32_t, Uint, false, SUBADDRESS_LOOKAHEAD_MINOR);
|
|
|
|
|
m_subaddress_lookahead_minor = field_subaddress_lookahead_minor;
|
|
|
|
|
|
|
|
|
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, encrypted_secret_keys, uint32_t, Uint, false, false);
|
|
|
|
|
encrypted_secret_keys = field_encrypted_secret_keys;
|
|
|
|
|
|
|
|
|
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, device_name, std::string, String, false, std::string());
|
|
|
|
|
if (m_device_name.empty() && field_device_name_found)
|
|
|
|
|
{
|
|
|
|
|
m_device_name = field_device_name;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -3231,7 +3272,8 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
|
|
|
|
|
r = epee::serialization::load_t_from_binary(m_account, account_data);
|
|
|
|
|
if (r && m_key_on_device) {
|
|
|
|
|
LOG_PRINT_L0("Account on device. Initing device...");
|
|
|
|
|
hw::device &hwdev = hw::get_device("Ledger");
|
|
|
|
|
hw::device &hwdev = hw::get_device(m_device_name);
|
|
|
|
|
hwdev.set_name(m_device_name);
|
|
|
|
|
hwdev.init();
|
|
|
|
|
hwdev.connect();
|
|
|
|
|
m_account.set_device(hwdev);
|
|
|
|
@ -3673,13 +3715,18 @@ void wallet2::restore(const std::string& wallet_, const epee::wipeable_string& p
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_keys_file, ignored_ec), error::file_exists, m_keys_file);
|
|
|
|
|
}
|
|
|
|
|
m_key_on_device = true;
|
|
|
|
|
m_account.create_from_device(device_name);
|
|
|
|
|
|
|
|
|
|
auto &hwdev = hw::get_device(device_name);
|
|
|
|
|
hwdev.set_name(device_name);
|
|
|
|
|
|
|
|
|
|
m_account.create_from_device(hwdev);
|
|
|
|
|
m_account_public_address = m_account.get_keys().m_account_address;
|
|
|
|
|
m_watch_only = false;
|
|
|
|
|
m_multisig = false;
|
|
|
|
|
m_multisig_threshold = 0;
|
|
|
|
|
m_multisig_signers.clear();
|
|
|
|
|
setup_keys(password);
|
|
|
|
|
m_device_name = device_name;
|
|
|
|
|
|
|
|
|
|
create_keys_file(wallet_, false, password, m_nettype != MAINNET || create_address_file);
|
|
|
|
|
if (m_subaddress_lookahead_major == SUBADDRESS_LOOKAHEAD_MAJOR && m_subaddress_lookahead_minor == SUBADDRESS_LOOKAHEAD_MINOR)
|
|
|
|
|