Merge pull request #4299
f9b22a7b
hw_device: support for multiple devices added [for review] (Dusan Klinec)
This commit is contained in:
commit
b4a9ebad6c
|
@ -197,10 +197,14 @@ DISABLE_VS_WARNINGS(4244 4345)
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
void account_base::create_from_device(const std::string &device_name)
|
void account_base::create_from_device(const std::string &device_name)
|
||||||
{
|
{
|
||||||
|
|
||||||
hw::device &hwdev = hw::get_device(device_name);
|
hw::device &hwdev = hw::get_device(device_name);
|
||||||
m_keys.set_device(hwdev);
|
|
||||||
hwdev.set_name(device_name);
|
hwdev.set_name(device_name);
|
||||||
|
create_from_device(hwdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void account_base::create_from_device(hw::device &hwdev)
|
||||||
|
{
|
||||||
|
m_keys.set_device(hwdev);
|
||||||
MCDEBUG("ledger", "device type: "<<typeid(hwdev).name());
|
MCDEBUG("ledger", "device type: "<<typeid(hwdev).name());
|
||||||
hwdev.init();
|
hwdev.init();
|
||||||
hwdev.connect();
|
hwdev.connect();
|
||||||
|
|
|
@ -77,7 +77,8 @@ namespace cryptonote
|
||||||
public:
|
public:
|
||||||
account_base();
|
account_base();
|
||||||
crypto::secret_key generate(const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false, bool two_random = false);
|
crypto::secret_key generate(const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false, bool two_random = false);
|
||||||
void create_from_device(const std::string &device_name) ;
|
void create_from_device(const std::string &device_name);
|
||||||
|
void create_from_device(hw::device &hwdev);
|
||||||
void create_from_keys(const cryptonote::account_public_address& address, const crypto::secret_key& spendkey, const crypto::secret_key& viewkey);
|
void create_from_keys(const cryptonote::account_public_address& address, const crypto::secret_key& spendkey, const crypto::secret_key& viewkey);
|
||||||
void create_from_viewkey(const cryptonote::account_public_address& address, const crypto::secret_key& viewkey);
|
void create_from_viewkey(const cryptonote::account_public_address& address, const crypto::secret_key& viewkey);
|
||||||
bool make_multisig(const crypto::secret_key &view_secret_key, const crypto::secret_key &spend_secret_key, const crypto::public_key &spend_public_key, const std::vector<crypto::secret_key> &multisig_keys);
|
bool make_multisig(const crypto::secret_key &view_secret_key, const crypto::secret_key &spend_secret_key, const crypto::public_key &spend_public_key, const std::vector<crypto::secret_key> &multisig_keys);
|
||||||
|
|
|
@ -40,31 +40,59 @@ namespace hw {
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
/* SETUP */
|
/* SETUP */
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
device& get_device(const std::string device_descriptor) {
|
|
||||||
|
|
||||||
struct s_devices {
|
static std::unique_ptr<device_registry> registry;
|
||||||
std::map<std::string, std::unique_ptr<device>> registry;
|
|
||||||
s_devices() : registry() {
|
device_registry::device_registry(){
|
||||||
hw::core::register_all(registry);
|
hw::core::register_all(registry);
|
||||||
#ifdef HAVE_PCSC
|
#ifdef HAVE_PCSC
|
||||||
hw::ledger::register_all(registry);
|
hw::ledger::register_all(registry);
|
||||||
#endif
|
#endif
|
||||||
};
|
}
|
||||||
};
|
|
||||||
|
|
||||||
static const s_devices devices;
|
bool device_registry::register_device(const std::string & device_name, device * hw_device){
|
||||||
|
auto search = registry.find(device_name);
|
||||||
|
if (search != registry.end()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto device = devices.registry.find(device_descriptor);
|
registry.insert(std::make_pair(device_name, std::unique_ptr<device>(hw_device)));
|
||||||
if (device == devices.registry.end()) {
|
return true;
|
||||||
MERROR("device not found in registry: '" << device_descriptor << "'\n" <<
|
}
|
||||||
"known devices:");
|
|
||||||
|
|
||||||
for( const auto& sm_pair : devices.registry ) {
|
device& device_registry::get_device(const std::string & device_descriptor){
|
||||||
|
// Device descriptor can contain further specs after first :
|
||||||
|
auto delim = device_descriptor.find(':');
|
||||||
|
auto device_descriptor_lookup = device_descriptor;
|
||||||
|
if (delim != std::string::npos) {
|
||||||
|
device_descriptor_lookup = device_descriptor.substr(0, delim);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto device = registry.find(device_descriptor_lookup);
|
||||||
|
if (device == registry.end()) {
|
||||||
|
MERROR("Device not found in registry: '" << device_descriptor << "'. Known devices: ");
|
||||||
|
for( const auto& sm_pair : registry ) {
|
||||||
MERROR(" - " << sm_pair.first);
|
MERROR(" - " << sm_pair.first);
|
||||||
}
|
}
|
||||||
throw std::runtime_error("device not found: "+ device_descriptor);
|
throw std::runtime_error("device not found: " + device_descriptor);
|
||||||
}
|
}
|
||||||
return *device->second;
|
return *device->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
device& get_device(const std::string & device_descriptor) {
|
||||||
|
if (!registry){
|
||||||
|
registry.reset(new device_registry());
|
||||||
|
}
|
||||||
|
|
||||||
|
return registry->get_device(device_descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool register_device(const std::string & device_name, device * hw_device){
|
||||||
|
if (!registry){
|
||||||
|
registry.reset(new device_registry());
|
||||||
|
}
|
||||||
|
|
||||||
|
return registry->register_device(device_name, hw_device);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,6 +202,17 @@ namespace hw {
|
||||||
~reset_mode() { hwref.set_mode(hw::device::NONE);}
|
~reset_mode() { hwref.set_mode(hw::device::NONE);}
|
||||||
};
|
};
|
||||||
|
|
||||||
device& get_device(const std::string device_descriptor) ;
|
class device_registry {
|
||||||
|
private:
|
||||||
|
std::map<std::string, std::unique_ptr<device>> registry;
|
||||||
|
|
||||||
|
public:
|
||||||
|
device_registry();
|
||||||
|
bool register_device(const std::string & device_name, device * hw_device);
|
||||||
|
device& get_device(const std::string & device_descriptor);
|
||||||
|
};
|
||||||
|
|
||||||
|
device& get_device(const std::string & device_descriptor);
|
||||||
|
bool register_device(const std::string & device_name, device * hw_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2523,6 +2523,10 @@ simple_wallet::simple_wallet()
|
||||||
boost::bind(&simple_wallet::import_key_images, this, _1),
|
boost::bind(&simple_wallet::import_key_images, this, _1),
|
||||||
tr("import_key_images <file>"),
|
tr("import_key_images <file>"),
|
||||||
tr("Import a signed key images list and verify their spent status."));
|
tr("Import a signed key images list and verify their spent status."));
|
||||||
|
m_cmd_binder.set_handler("hw_reconnect",
|
||||||
|
boost::bind(&simple_wallet::hw_reconnect, this, _1),
|
||||||
|
tr("hw_reconnect"),
|
||||||
|
tr("Attempts to reconnect HW wallet."));
|
||||||
m_cmd_binder.set_handler("export_outputs",
|
m_cmd_binder.set_handler("export_outputs",
|
||||||
boost::bind(&simple_wallet::export_outputs, this, _1),
|
boost::bind(&simple_wallet::export_outputs, this, _1),
|
||||||
tr("export_outputs <file>"),
|
tr("export_outputs <file>"),
|
||||||
|
@ -2650,6 +2654,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
|
||||||
success_msg_writer() << "subaddress-lookahead = " << lookahead.first << ":" << lookahead.second;
|
success_msg_writer() << "subaddress-lookahead = " << lookahead.first << ":" << lookahead.second;
|
||||||
success_msg_writer() << "segregation-height = " << m_wallet->segregation_height();
|
success_msg_writer() << "segregation-height = " << m_wallet->segregation_height();
|
||||||
success_msg_writer() << "ignore-fractional-outputs = " << m_wallet->ignore_fractional_outputs();
|
success_msg_writer() << "ignore-fractional-outputs = " << m_wallet->ignore_fractional_outputs();
|
||||||
|
success_msg_writer() << "device_name = " << m_wallet->device_name();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3295,7 +3300,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
||||||
{
|
{
|
||||||
m_wallet_file = m_generate_from_device;
|
m_wallet_file = m_generate_from_device;
|
||||||
// create wallet
|
// create wallet
|
||||||
auto r = new_wallet(vm, "Ledger");
|
auto r = new_wallet(vm);
|
||||||
CHECK_AND_ASSERT_MES(r, false, tr("account creation failed"));
|
CHECK_AND_ASSERT_MES(r, false, tr("account creation failed"));
|
||||||
password = *r;
|
password = *r;
|
||||||
// if no block_height is specified, assume its a new account and start it "now"
|
// if no block_height is specified, assume its a new account and start it "now"
|
||||||
|
@ -3703,8 +3708,8 @@ boost::optional<epee::wipeable_string> simple_wallet::new_wallet(const boost::pr
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
boost::optional<epee::wipeable_string> simple_wallet::new_wallet(const boost::program_options::variables_map& vm,
|
boost::optional<epee::wipeable_string> simple_wallet::new_wallet(const boost::program_options::variables_map& vm)
|
||||||
const std::string &device_name) {
|
{
|
||||||
auto rc = tools::wallet2::make_new(vm, false, password_prompter);
|
auto rc = tools::wallet2::make_new(vm, false, password_prompter);
|
||||||
m_wallet = std::move(rc.first);
|
m_wallet = std::move(rc.first);
|
||||||
if (!m_wallet)
|
if (!m_wallet)
|
||||||
|
@ -3723,10 +3728,11 @@ boost::optional<epee::wipeable_string> simple_wallet::new_wallet(const boost::pr
|
||||||
if (m_restore_height)
|
if (m_restore_height)
|
||||||
m_wallet->set_refresh_from_block_height(m_restore_height);
|
m_wallet->set_refresh_from_block_height(m_restore_height);
|
||||||
|
|
||||||
|
auto device_desc = tools::wallet2::device_name_option(vm);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool create_address_file = command_line::get_arg(vm, arg_create_address_file);
|
bool create_address_file = command_line::get_arg(vm, arg_create_address_file);
|
||||||
m_wallet->restore(m_wallet_file, std::move(rc.second).password(), device_name, create_address_file);
|
m_wallet->restore(m_wallet_file, std::move(rc.second).password(), device_desc.empty() ? "Ledger" : device_desc, create_address_file);
|
||||||
message_writer(console_color_white, true) << tr("Generated new wallet on hw device: ")
|
message_writer(console_color_white, true) << tr("Generated new wallet on hw device: ")
|
||||||
<< m_wallet->get_account().get_public_address_str(m_wallet->nettype());
|
<< m_wallet->get_account().get_public_address_str(m_wallet->nettype());
|
||||||
}
|
}
|
||||||
|
@ -7745,6 +7751,31 @@ bool simple_wallet::import_key_images(const std::vector<std::string> &args)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
bool simple_wallet::hw_reconnect(const std::vector<std::string> &args)
|
||||||
|
{
|
||||||
|
if (!m_wallet->key_on_device())
|
||||||
|
{
|
||||||
|
fail_msg_writer() << tr("command only supported by HW wallet");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOCK_IDLE_SCOPE();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool r = m_wallet->reconnect_device();
|
||||||
|
if (!r){
|
||||||
|
fail_msg_writer() << tr("Failed to reconnect device");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
fail_msg_writer() << tr("Failed to reconnect device: ") << tr(e.what());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
bool simple_wallet::export_outputs(const std::vector<std::string> &args)
|
bool simple_wallet::export_outputs(const std::vector<std::string> &args)
|
||||||
{
|
{
|
||||||
if (m_wallet->key_on_device())
|
if (m_wallet->key_on_device())
|
||||||
|
|
|
@ -98,7 +98,7 @@ namespace cryptonote
|
||||||
const boost::optional<crypto::secret_key>& spendkey, const crypto::secret_key& viewkey);
|
const boost::optional<crypto::secret_key>& spendkey, const crypto::secret_key& viewkey);
|
||||||
boost::optional<epee::wipeable_string> new_wallet(const boost::program_options::variables_map& vm,
|
boost::optional<epee::wipeable_string> new_wallet(const boost::program_options::variables_map& vm,
|
||||||
const epee::wipeable_string &multisig_keys, const std::string &old_language);
|
const epee::wipeable_string &multisig_keys, const std::string &old_language);
|
||||||
boost::optional<epee::wipeable_string> new_wallet(const boost::program_options::variables_map& vm, const std::string& device_name);
|
boost::optional<epee::wipeable_string> new_wallet(const boost::program_options::variables_map& vm);
|
||||||
bool open_wallet(const boost::program_options::variables_map& vm);
|
bool open_wallet(const boost::program_options::variables_map& vm);
|
||||||
bool close_wallet();
|
bool close_wallet();
|
||||||
|
|
||||||
|
@ -201,6 +201,7 @@ namespace cryptonote
|
||||||
bool verify(const std::vector<std::string> &args);
|
bool verify(const std::vector<std::string> &args);
|
||||||
bool export_key_images(const std::vector<std::string> &args);
|
bool export_key_images(const std::vector<std::string> &args);
|
||||||
bool import_key_images(const std::vector<std::string> &args);
|
bool import_key_images(const std::vector<std::string> &args);
|
||||||
|
bool hw_reconnect(const std::vector<std::string> &args);
|
||||||
bool export_outputs(const std::vector<std::string> &args);
|
bool export_outputs(const std::vector<std::string> &args);
|
||||||
bool import_outputs(const std::vector<std::string> &args);
|
bool import_outputs(const std::vector<std::string> &args);
|
||||||
bool show_transfer(const std::vector<std::string> &args);
|
bool show_transfer(const std::vector<std::string> &args);
|
||||||
|
|
|
@ -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<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)
|
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_address = command_line::get_arg(vm, opts.daemon_address);
|
||||||
auto daemon_host = command_line::get_arg(vm, opts.daemon_host);
|
auto daemon_host = command_line::get_arg(vm, opts.daemon_host);
|
||||||
auto daemon_port = command_line::get_arg(vm, opts.daemon_port);
|
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,
|
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"));
|
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);
|
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);
|
boost::filesystem::path ringdb_path = command_line::get_arg(vm, opts.shared_ringdb_dir);
|
||||||
wallet->set_ring_database(ringdb_path.string());
|
wallet->set_ring_database(ringdb_path.string());
|
||||||
|
wallet->device_name(device_name);
|
||||||
return wallet;
|
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);
|
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)
|
void wallet2::init_options(boost::program_options::options_description& desc_params)
|
||||||
{
|
{
|
||||||
const options opts{};
|
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.stagenet);
|
||||||
command_line::add_arg(desc_params, opts.shared_ringdb_dir);
|
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.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)
|
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;
|
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
|
* \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);
|
value2.SetUint(1);
|
||||||
json.AddMember("encrypted_secret_keys", value2, json.GetAllocator());
|
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
|
// Serialize the JSON object
|
||||||
rapidjson::StringBuffer buffer;
|
rapidjson::StringBuffer buffer;
|
||||||
rapidjson::Writer<rapidjson::StringBuffer> writer(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_ignore_fractional_outputs = true;
|
||||||
m_subaddress_lookahead_major = SUBADDRESS_LOOKAHEAD_MAJOR;
|
m_subaddress_lookahead_major = SUBADDRESS_LOOKAHEAD_MAJOR;
|
||||||
m_subaddress_lookahead_minor = SUBADDRESS_LOOKAHEAD_MINOR;
|
m_subaddress_lookahead_minor = SUBADDRESS_LOOKAHEAD_MINOR;
|
||||||
|
m_device_name = "";
|
||||||
m_key_on_device = false;
|
m_key_on_device = false;
|
||||||
encrypted_secret_keys = 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;
|
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);
|
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;
|
m_subaddress_lookahead_minor = field_subaddress_lookahead_minor;
|
||||||
|
|
||||||
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, encrypted_secret_keys, uint32_t, Uint, false, false);
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, encrypted_secret_keys, uint32_t, Uint, false, false);
|
||||||
encrypted_secret_keys = field_encrypted_secret_keys;
|
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
|
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);
|
r = epee::serialization::load_t_from_binary(m_account, account_data);
|
||||||
if (r && m_key_on_device) {
|
if (r && m_key_on_device) {
|
||||||
LOG_PRINT_L0("Account on device. Initing 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.init();
|
||||||
hwdev.connect();
|
hwdev.connect();
|
||||||
m_account.set_device(hwdev);
|
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);
|
THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_keys_file, ignored_ec), error::file_exists, m_keys_file);
|
||||||
}
|
}
|
||||||
m_key_on_device = true;
|
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_account_public_address = m_account.get_keys().m_account_address;
|
||||||
m_watch_only = false;
|
m_watch_only = false;
|
||||||
m_multisig = false;
|
m_multisig = false;
|
||||||
m_multisig_threshold = 0;
|
m_multisig_threshold = 0;
|
||||||
m_multisig_signers.clear();
|
m_multisig_signers.clear();
|
||||||
setup_keys(password);
|
setup_keys(password);
|
||||||
|
m_device_name = device_name;
|
||||||
|
|
||||||
create_keys_file(wallet_, false, password, m_nettype != MAINNET || create_address_file);
|
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)
|
if (m_subaddress_lookahead_major == SUBADDRESS_LOOKAHEAD_MAJOR && m_subaddress_lookahead_minor == SUBADDRESS_LOOKAHEAD_MINOR)
|
||||||
|
|
|
@ -172,6 +172,7 @@ namespace tools
|
||||||
|
|
||||||
static bool has_testnet_option(const boost::program_options::variables_map& vm);
|
static bool has_testnet_option(const boost::program_options::variables_map& vm);
|
||||||
static bool has_stagenet_option(const boost::program_options::variables_map& vm);
|
static bool has_stagenet_option(const boost::program_options::variables_map& vm);
|
||||||
|
static std::string device_name_option(const boost::program_options::variables_map& vm);
|
||||||
static void init_options(boost::program_options::options_description& desc_params);
|
static void init_options(boost::program_options::options_description& desc_params);
|
||||||
|
|
||||||
//! Uses stdin and stdout. Returns a wallet2 if no errors.
|
//! Uses stdin and stdout. Returns a wallet2 if no errors.
|
||||||
|
@ -709,6 +710,7 @@ namespace tools
|
||||||
bool has_unknown_key_images() const;
|
bool has_unknown_key_images() const;
|
||||||
bool get_multisig_seed(epee::wipeable_string& seed, const epee::wipeable_string &passphrase = std::string(), bool raw = true) const;
|
bool get_multisig_seed(epee::wipeable_string& seed, const epee::wipeable_string &passphrase = std::string(), bool raw = true) const;
|
||||||
bool key_on_device() const { return m_key_on_device; }
|
bool key_on_device() const { return m_key_on_device; }
|
||||||
|
bool reconnect_device();
|
||||||
|
|
||||||
// locked & unlocked balance of given or current subaddress account
|
// locked & unlocked balance of given or current subaddress account
|
||||||
uint64_t balance(uint32_t subaddr_index_major) const;
|
uint64_t balance(uint32_t subaddr_index_major) const;
|
||||||
|
@ -938,6 +940,8 @@ namespace tools
|
||||||
void ignore_fractional_outputs(bool value) { m_ignore_fractional_outputs = value; }
|
void ignore_fractional_outputs(bool value) { m_ignore_fractional_outputs = value; }
|
||||||
bool confirm_non_default_ring_size() const { return m_confirm_non_default_ring_size; }
|
bool confirm_non_default_ring_size() const { return m_confirm_non_default_ring_size; }
|
||||||
void confirm_non_default_ring_size(bool always) { m_confirm_non_default_ring_size = always; }
|
void confirm_non_default_ring_size(bool always) { m_confirm_non_default_ring_size = always; }
|
||||||
|
const std::string & device_name() const { return m_device_name; }
|
||||||
|
void device_name(const std::string & device_name) { m_device_name = device_name; }
|
||||||
|
|
||||||
bool get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys) const;
|
bool get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys) const;
|
||||||
void set_tx_key(const crypto::hash &txid, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys);
|
void set_tx_key(const crypto::hash &txid, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys);
|
||||||
|
@ -1319,6 +1323,7 @@ namespace tools
|
||||||
NodeRPCProxy m_node_rpc_proxy;
|
NodeRPCProxy m_node_rpc_proxy;
|
||||||
std::unordered_set<crypto::hash> m_scanned_pool_txs[2];
|
std::unordered_set<crypto::hash> m_scanned_pool_txs[2];
|
||||||
size_t m_subaddress_lookahead_major, m_subaddress_lookahead_minor;
|
size_t m_subaddress_lookahead_major, m_subaddress_lookahead_minor;
|
||||||
|
std::string m_device_name;
|
||||||
|
|
||||||
// Light wallet
|
// Light wallet
|
||||||
bool m_light_wallet; /* sends view key to daemon for scanning */
|
bool m_light_wallet; /* sends view key to daemon for scanning */
|
||||||
|
|
Loading…
Reference in New Issue