commit
90d1a00c10
|
@ -78,7 +78,6 @@ namespace hw {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class device {
|
class device {
|
||||||
protected:
|
protected:
|
||||||
std::string name;
|
std::string name;
|
||||||
|
@ -96,6 +95,12 @@ namespace hw {
|
||||||
TRANSACTION_CREATE_FAKE,
|
TRANSACTION_CREATE_FAKE,
|
||||||
TRANSACTION_PARSE
|
TRANSACTION_PARSE
|
||||||
};
|
};
|
||||||
|
enum device_type
|
||||||
|
{
|
||||||
|
SOFTWARE = 0,
|
||||||
|
LEDGER = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
/* SETUP/TEARDOWN */
|
/* SETUP/TEARDOWN */
|
||||||
|
@ -109,7 +114,9 @@ namespace hw {
|
||||||
virtual bool connect(void) = 0;
|
virtual bool connect(void) = 0;
|
||||||
virtual bool disconnect(void) = 0;
|
virtual bool disconnect(void) = 0;
|
||||||
|
|
||||||
virtual bool set_mode(device_mode mode) = 0;
|
virtual bool set_mode(device_mode mode) = 0;
|
||||||
|
|
||||||
|
virtual device_type get_type() const = 0;
|
||||||
|
|
||||||
|
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
|
|
|
@ -61,6 +61,8 @@ namespace hw {
|
||||||
|
|
||||||
bool set_mode(device_mode mode) override;
|
bool set_mode(device_mode mode) override;
|
||||||
|
|
||||||
|
device_type get_type() const {return device_type::SOFTWARE;};
|
||||||
|
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
/* LOCKER */
|
/* LOCKER */
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
|
|
|
@ -142,7 +142,9 @@ namespace hw {
|
||||||
bool connect(void) override;
|
bool connect(void) override;
|
||||||
bool disconnect() override;
|
bool disconnect() override;
|
||||||
|
|
||||||
bool set_mode(device_mode mode) override;
|
bool set_mode(device_mode mode) override;
|
||||||
|
|
||||||
|
device_type get_type() const {return device_type::LEDGER;};
|
||||||
|
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
/* LOCKER */
|
/* LOCKER */
|
||||||
|
|
|
@ -639,6 +639,11 @@ bool WalletImpl::recoverFromDevice(const std::string &path, const std::string &p
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Wallet::Device WalletImpl::getDeviceType() const
|
||||||
|
{
|
||||||
|
return static_cast<Wallet::Device>(m_wallet->get_device_type());
|
||||||
|
}
|
||||||
|
|
||||||
bool WalletImpl::open(const std::string &path, const std::string &password)
|
bool WalletImpl::open(const std::string &path, const std::string &password)
|
||||||
{
|
{
|
||||||
clearStatus();
|
clearStatus();
|
||||||
|
|
|
@ -79,6 +79,7 @@ public:
|
||||||
bool recoverFromDevice(const std::string &path,
|
bool recoverFromDevice(const std::string &path,
|
||||||
const std::string &password,
|
const std::string &password,
|
||||||
const std::string &device_name);
|
const std::string &device_name);
|
||||||
|
Device getDeviceType() const;
|
||||||
bool close(bool store = true);
|
bool close(bool store = true);
|
||||||
std::string seed() const override;
|
std::string seed() const override;
|
||||||
std::string getSeedLanguage() const override;
|
std::string getSeedLanguage() const override;
|
||||||
|
|
|
@ -373,6 +373,10 @@ struct WalletListener
|
||||||
*/
|
*/
|
||||||
struct Wallet
|
struct Wallet
|
||||||
{
|
{
|
||||||
|
enum Device {
|
||||||
|
Device_Software = 0,
|
||||||
|
Device_Ledger = 1
|
||||||
|
};
|
||||||
|
|
||||||
enum Status {
|
enum Status {
|
||||||
Status_Ok,
|
Status_Ok,
|
||||||
|
@ -911,6 +915,12 @@ struct Wallet
|
||||||
virtual bool unlockKeysFile() = 0;
|
virtual bool unlockKeysFile() = 0;
|
||||||
//! returns true if the keys file is locked
|
//! returns true if the keys file is locked
|
||||||
virtual bool isKeysFileLocked() = 0;
|
virtual bool isKeysFileLocked() = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Queries backing device for wallet keys
|
||||||
|
* \return Device they are on
|
||||||
|
*/
|
||||||
|
virtual Device getDeviceType() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1096,6 +1106,18 @@ struct WalletManager
|
||||||
*/
|
*/
|
||||||
virtual bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const = 0;
|
virtual bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief determine the key storage for the specified wallet file
|
||||||
|
* \param device_type (OUT) wallet backend as enumerated in Wallet::Device
|
||||||
|
* \param keys_file_name Keys file to verify password for
|
||||||
|
* \param password Password to verify
|
||||||
|
* \return true if password correct, else false
|
||||||
|
*
|
||||||
|
* for verification only - determines key storage hardware
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtual bool queryWalletDevice(Wallet::Device& device_type, const std::string &keys_file_name, const std::string &password, uint64_t kdf_rounds = 1) const = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief findWallets - searches for the wallet files by given path name recursively
|
* \brief findWallets - searches for the wallet files by given path name recursively
|
||||||
* \param path - starting point to search
|
* \param path - starting point to search
|
||||||
|
|
|
@ -167,6 +167,14 @@ bool WalletManagerImpl::verifyWalletPassword(const std::string &keys_file_name,
|
||||||
return tools::wallet2::verify_password(keys_file_name, password, no_spend_key, hw::get_device("default"), kdf_rounds);
|
return tools::wallet2::verify_password(keys_file_name, password, no_spend_key, hw::get_device("default"), kdf_rounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WalletManagerImpl::queryWalletDevice(Wallet::Device& device_type, const std::string &keys_file_name, const std::string &password, uint64_t kdf_rounds) const
|
||||||
|
{
|
||||||
|
hw::device::device_type type;
|
||||||
|
bool r = tools::wallet2::query_device(type, keys_file_name, password, kdf_rounds);
|
||||||
|
device_type = static_cast<Wallet::Device>(type);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> WalletManagerImpl::findWallets(const std::string &path)
|
std::vector<std::string> WalletManagerImpl::findWallets(const std::string &path)
|
||||||
{
|
{
|
||||||
std::vector<std::string> result;
|
std::vector<std::string> result;
|
||||||
|
|
|
@ -76,6 +76,7 @@ public:
|
||||||
virtual bool closeWallet(Wallet *wallet, bool store = true) override;
|
virtual bool closeWallet(Wallet *wallet, bool store = true) override;
|
||||||
bool walletExists(const std::string &path) override;
|
bool walletExists(const std::string &path) override;
|
||||||
bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const override;
|
bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const override;
|
||||||
|
bool queryWalletDevice(Wallet::Device& device_type, const std::string &keys_file_name, const std::string &password, uint64_t kdf_rounds = 1) const;
|
||||||
std::vector<std::string> findWallets(const std::string &path) override;
|
std::vector<std::string> findWallets(const std::string &path) override;
|
||||||
std::string errorString() const override;
|
std::string errorString() const override;
|
||||||
void setDaemonAddress(const std::string &address) override;
|
void setDaemonAddress(const std::string &address) override;
|
||||||
|
|
|
@ -794,7 +794,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended):
|
||||||
m_light_wallet_connected(false),
|
m_light_wallet_connected(false),
|
||||||
m_light_wallet_balance(0),
|
m_light_wallet_balance(0),
|
||||||
m_light_wallet_unlocked_balance(0),
|
m_light_wallet_unlocked_balance(0),
|
||||||
m_key_on_device(false),
|
m_key_device_type(hw::device::device_type::SOFTWARE),
|
||||||
m_ring_history_saved(false),
|
m_ring_history_saved(false),
|
||||||
m_ringdb(),
|
m_ringdb(),
|
||||||
m_last_block_reward(0),
|
m_last_block_reward(0),
|
||||||
|
@ -2908,7 +2908,7 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable
|
||||||
|
|
||||||
rapidjson::Value value2(rapidjson::kNumberType);
|
rapidjson::Value value2(rapidjson::kNumberType);
|
||||||
|
|
||||||
value2.SetInt(m_key_on_device?1:0);
|
value2.SetInt(m_key_device_type);
|
||||||
json.AddMember("key_on_device", value2, json.GetAllocator());
|
json.AddMember("key_on_device", value2, json.GetAllocator());
|
||||||
|
|
||||||
value2.SetInt(watch_only ? 1 :0); // WTF ? JSON has different true and false types, and not boolean ??
|
value2.SetInt(watch_only ? 1 :0); // WTF ? JSON has different true and false types, and not boolean ??
|
||||||
|
@ -3121,7 +3121,7 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
|
||||||
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_device_name = "";
|
||||||
m_key_on_device = false;
|
m_key_device_type = hw::device::device_type::SOFTWARE;
|
||||||
encrypted_secret_keys = false;
|
encrypted_secret_keys = false;
|
||||||
}
|
}
|
||||||
else if(json.IsObject())
|
else if(json.IsObject())
|
||||||
|
@ -3141,8 +3141,8 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
|
||||||
|
|
||||||
if (json.HasMember("key_on_device"))
|
if (json.HasMember("key_on_device"))
|
||||||
{
|
{
|
||||||
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, key_on_device, int, Int, false, false);
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, key_on_device, int, Int, false, hw::device::device_type::SOFTWARE);
|
||||||
m_key_on_device = field_key_on_device;
|
m_key_device_type = static_cast<hw::device::device_type>(field_key_on_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, seed_language, std::string, String, false, std::string());
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, seed_language, std::string, String, false, std::string());
|
||||||
|
@ -3269,7 +3269,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) {
|
THROW_WALLET_EXCEPTION_IF(!r, error::invalid_password);
|
||||||
|
if (m_key_device_type == hw::device::device_type::LEDGER) {
|
||||||
LOG_PRINT_L0("Account on device. Initing device...");
|
LOG_PRINT_L0("Account on device. Initing device...");
|
||||||
hw::device &hwdev = hw::get_device(m_device_name);
|
hw::device &hwdev = hw::get_device(m_device_name);
|
||||||
hwdev.set_name(m_device_name);
|
hwdev.set_name(m_device_name);
|
||||||
|
@ -3277,6 +3278,8 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
|
||||||
hwdev.connect();
|
hwdev.connect();
|
||||||
m_account.set_device(hwdev);
|
m_account.set_device(hwdev);
|
||||||
LOG_PRINT_L0("Device inited...");
|
LOG_PRINT_L0("Device inited...");
|
||||||
|
} else if (key_on_device()) {
|
||||||
|
THROW_WALLET_EXCEPTION(error::wallet_internal_error, "hardware device not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r)
|
if (r)
|
||||||
|
@ -3444,6 +3447,59 @@ void wallet2::create_keys_file(const std::string &wallet_, bool watch_only, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief determine the key storage for the specified wallet file
|
||||||
|
* \param device_type (OUT) wallet backend as enumerated in hw::device::device_type
|
||||||
|
* \param keys_file_name Keys file to verify password for
|
||||||
|
* \param password Password to verify
|
||||||
|
* \return true if password correct, else false
|
||||||
|
*
|
||||||
|
* for verification only - determines key storage hardware
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool wallet2::query_device(hw::device::device_type& device_type, const std::string& keys_file_name, const epee::wipeable_string& password, uint64_t kdf_rounds)
|
||||||
|
{
|
||||||
|
rapidjson::Document json;
|
||||||
|
wallet2::keys_file_data keys_file_data;
|
||||||
|
std::string buf;
|
||||||
|
bool r = epee::file_io_utils::load_file_to_string(keys_file_name, buf);
|
||||||
|
THROW_WALLET_EXCEPTION_IF(!r, error::file_read_error, keys_file_name);
|
||||||
|
|
||||||
|
// Decrypt the contents
|
||||||
|
r = ::serialization::parse_binary(buf, keys_file_data);
|
||||||
|
THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "internal error: failed to deserialize \"" + keys_file_name + '\"');
|
||||||
|
crypto::chacha_key key;
|
||||||
|
crypto::generate_chacha_key(password.data(), password.size(), key, kdf_rounds);
|
||||||
|
std::string account_data;
|
||||||
|
account_data.resize(keys_file_data.account_data.size());
|
||||||
|
crypto::chacha20(keys_file_data.account_data.data(), keys_file_data.account_data.size(), key, keys_file_data.iv, &account_data[0]);
|
||||||
|
if (json.Parse(account_data.c_str()).HasParseError() || !json.IsObject())
|
||||||
|
crypto::chacha8(keys_file_data.account_data.data(), keys_file_data.account_data.size(), key, keys_file_data.iv, &account_data[0]);
|
||||||
|
|
||||||
|
// The contents should be JSON if the wallet follows the new format.
|
||||||
|
if (json.Parse(account_data.c_str()).HasParseError())
|
||||||
|
{
|
||||||
|
// old format before JSON wallet key file format
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
account_data = std::string(json["key_data"].GetString(), json["key_data"].GetString() +
|
||||||
|
json["key_data"].GetStringLength());
|
||||||
|
|
||||||
|
if (json.HasMember("key_on_device"))
|
||||||
|
{
|
||||||
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, key_on_device, int, Int, false, hw::device::device_type::SOFTWARE);
|
||||||
|
device_type = static_cast<hw::device::device_type>(field_key_on_device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cryptonote::account_base account_data_check;
|
||||||
|
|
||||||
|
r = epee::serialization::load_t_from_binary(account_data_check, account_data);
|
||||||
|
if (!r) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Generates a wallet or restores one.
|
* \brief Generates a wallet or restores one.
|
||||||
* \param wallet_ Name of wallet file
|
* \param wallet_ Name of wallet file
|
||||||
|
@ -3518,7 +3574,7 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string&
|
||||||
m_multisig = true;
|
m_multisig = true;
|
||||||
m_multisig_threshold = threshold;
|
m_multisig_threshold = threshold;
|
||||||
m_multisig_signers = multisig_signers;
|
m_multisig_signers = multisig_signers;
|
||||||
m_key_on_device = false;
|
m_key_device_type = hw::device::device_type::SOFTWARE;
|
||||||
setup_keys(password);
|
setup_keys(password);
|
||||||
|
|
||||||
create_keys_file(wallet_, false, password, m_nettype != MAINNET || create_address_file);
|
create_keys_file(wallet_, false, password, m_nettype != MAINNET || create_address_file);
|
||||||
|
@ -3558,7 +3614,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip
|
||||||
m_multisig = false;
|
m_multisig = false;
|
||||||
m_multisig_threshold = 0;
|
m_multisig_threshold = 0;
|
||||||
m_multisig_signers.clear();
|
m_multisig_signers.clear();
|
||||||
m_key_on_device = false;
|
m_key_device_type = hw::device::device_type::SOFTWARE;
|
||||||
setup_keys(password);
|
setup_keys(password);
|
||||||
|
|
||||||
// calculate a starting refresh height
|
// calculate a starting refresh height
|
||||||
|
@ -3646,7 +3702,7 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string&
|
||||||
m_multisig = false;
|
m_multisig = false;
|
||||||
m_multisig_threshold = 0;
|
m_multisig_threshold = 0;
|
||||||
m_multisig_signers.clear();
|
m_multisig_signers.clear();
|
||||||
m_key_on_device = false;
|
m_key_device_type = hw::device::device_type::SOFTWARE;
|
||||||
setup_keys(password);
|
setup_keys(password);
|
||||||
|
|
||||||
create_keys_file(wallet_, true, password, m_nettype != MAINNET || create_address_file);
|
create_keys_file(wallet_, true, password, m_nettype != MAINNET || create_address_file);
|
||||||
|
@ -3686,7 +3742,7 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string&
|
||||||
m_multisig = false;
|
m_multisig = false;
|
||||||
m_multisig_threshold = 0;
|
m_multisig_threshold = 0;
|
||||||
m_multisig_signers.clear();
|
m_multisig_signers.clear();
|
||||||
m_key_on_device = false;
|
m_key_device_type = hw::device::device_type::SOFTWARE;
|
||||||
setup_keys(password);
|
setup_keys(password);
|
||||||
|
|
||||||
create_keys_file(wallet_, false, password, create_address_file);
|
create_keys_file(wallet_, false, password, create_address_file);
|
||||||
|
@ -3713,12 +3769,12 @@ void wallet2::restore(const std::string& wallet_, const epee::wipeable_string& p
|
||||||
THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_wallet_file, ignored_ec), error::file_exists, m_wallet_file);
|
THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_wallet_file, ignored_ec), error::file_exists, m_wallet_file);
|
||||||
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;
|
|
||||||
|
|
||||||
auto &hwdev = hw::get_device(device_name);
|
auto &hwdev = hw::get_device(device_name);
|
||||||
hwdev.set_name(device_name);
|
hwdev.set_name(device_name);
|
||||||
|
|
||||||
m_account.create_from_device(hwdev);
|
m_account.create_from_device(hwdev);
|
||||||
|
m_key_device_type = m_account.get_device().get_type();
|
||||||
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;
|
||||||
|
@ -3815,7 +3871,7 @@ std::string wallet2::make_multisig(const epee::wipeable_string &password,
|
||||||
m_watch_only = false;
|
m_watch_only = false;
|
||||||
m_multisig = true;
|
m_multisig = true;
|
||||||
m_multisig_threshold = threshold;
|
m_multisig_threshold = threshold;
|
||||||
m_key_on_device = false;
|
m_key_device_type = hw::device::device_type::SOFTWARE;
|
||||||
|
|
||||||
if (threshold == spend_keys.size() + 1)
|
if (threshold == spend_keys.size() + 1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -189,6 +189,7 @@ namespace tools
|
||||||
static std::unique_ptr<wallet2> make_dummy(const boost::program_options::variables_map& vm, bool unattended, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter);
|
static std::unique_ptr<wallet2> make_dummy(const boost::program_options::variables_map& vm, bool unattended, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter);
|
||||||
|
|
||||||
static bool verify_password(const std::string& keys_file_name, const epee::wipeable_string& password, bool no_spend_key, hw::device &hwdev, uint64_t kdf_rounds);
|
static bool verify_password(const std::string& keys_file_name, const epee::wipeable_string& password, bool no_spend_key, hw::device &hwdev, uint64_t kdf_rounds);
|
||||||
|
static bool query_device(hw::device::device_type& device_type, const std::string& keys_file_name, const epee::wipeable_string& password, uint64_t kdf_rounds = 1);
|
||||||
|
|
||||||
wallet2(cryptonote::network_type nettype = cryptonote::MAINNET, uint64_t kdf_rounds = 1, bool unattended = false);
|
wallet2(cryptonote::network_type nettype = cryptonote::MAINNET, uint64_t kdf_rounds = 1, bool unattended = false);
|
||||||
~wallet2();
|
~wallet2();
|
||||||
|
@ -709,7 +710,8 @@ namespace tools
|
||||||
bool has_multisig_partial_key_images() const;
|
bool has_multisig_partial_key_images() const;
|
||||||
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 get_device_type() != hw::device::device_type::SOFTWARE; }
|
||||||
|
hw::device::device_type get_device_type() const { return m_key_device_type; }
|
||||||
bool reconnect_device();
|
bool reconnect_device();
|
||||||
|
|
||||||
// locked & unlocked balance of given or current subaddress account
|
// locked & unlocked balance of given or current subaddress account
|
||||||
|
@ -1284,7 +1286,7 @@ namespace tools
|
||||||
|
|
||||||
bool m_trusted_daemon;
|
bool m_trusted_daemon;
|
||||||
i_wallet2_callback* m_callback;
|
i_wallet2_callback* m_callback;
|
||||||
bool m_key_on_device;
|
hw::device::device_type m_key_device_type;
|
||||||
cryptonote::network_type m_nettype;
|
cryptonote::network_type m_nettype;
|
||||||
uint64_t m_kdf_rounds;
|
uint64_t m_kdf_rounds;
|
||||||
std::string seed_language; /*!< Language of the mnemonics (seed). */
|
std::string seed_language; /*!< Language of the mnemonics (seed). */
|
||||||
|
|
Loading…
Reference in New Issue