Better support for USB devices
Benefits of this rewrite include: - support of disconnecting / reconnecting a device without having to close the wallet, even in a different USB socket - support of multiple keepkey / trezor devices, both during wallet creation and general use - wallet is watching-only dynamically according to whether the associated device is currently plugged in or not
This commit is contained in:
@@ -73,7 +73,7 @@ class Plugins(DaemonThread):
|
||||
self.print_error("loaded", name)
|
||||
return plugin
|
||||
except Exception:
|
||||
print_msg(_("Error: cannot initialize plugin"), name)
|
||||
self.print_error("cannot initialize plugin", name)
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
return None
|
||||
|
||||
@@ -106,16 +106,17 @@ class Plugins(DaemonThread):
|
||||
return not requires or w.wallet_type in requires
|
||||
|
||||
def hardware_wallets(self, action):
|
||||
result = []
|
||||
wallet_types, descs = [], []
|
||||
for name, (gui_good, details) in self.hw_wallets.items():
|
||||
if gui_good:
|
||||
try:
|
||||
p = self.wallet_plugin_loader(name)
|
||||
if action == 'restore' or p.is_enabled():
|
||||
result.append((details[1], details[2]))
|
||||
wallet_types.append(details[1])
|
||||
descs.append(details[2])
|
||||
except:
|
||||
self.print_error("cannot load plugin for:", name)
|
||||
return result
|
||||
return wallet_types, descs
|
||||
|
||||
def register_plugin_wallet(self, name, gui_good, details):
|
||||
def dynamic_constructor(storage):
|
||||
|
||||
@@ -205,6 +205,9 @@ class Abstract_Wallet(PrintError):
|
||||
def diagnostic_name(self):
|
||||
return self.basename()
|
||||
|
||||
def __str__(self):
|
||||
return self.basename()
|
||||
|
||||
def set_use_encryption(self, use_encryption):
|
||||
self.use_encryption = use_encryption
|
||||
self.storage.put('use_encryption', use_encryption)
|
||||
@@ -1718,18 +1721,25 @@ class BIP44_Wallet(BIP32_HD_Wallet):
|
||||
def can_create_accounts(self):
|
||||
return not self.is_watching_only()
|
||||
|
||||
@classmethod
|
||||
def prefix(self):
|
||||
return "/".join(self.root_derivation.split("/")[1:])
|
||||
|
||||
@classmethod
|
||||
def account_derivation(self, account_id):
|
||||
return self.prefix() + "/" + account_id + "'"
|
||||
|
||||
def address_id(self, address):
|
||||
acc_id, (change, address_index) = self.get_address_index(address)
|
||||
account_derivation = self.account_derivation(acc_id)
|
||||
@classmethod
|
||||
def address_derivation(self, account_id, change, address_index):
|
||||
account_derivation = self.account_derivation(account_id)
|
||||
return "%s/%d/%d" % (account_derivation, change, address_index)
|
||||
|
||||
def mnemonic_to_seed(self, mnemonic, passphrase):
|
||||
def address_id(self, address):
|
||||
acc_id, (change, address_index) = self.get_address_index(address)
|
||||
return self.address_derivation(acc_id, change, address_index)
|
||||
|
||||
@staticmethod
|
||||
def mnemonic_to_seed(mnemonic, passphrase):
|
||||
# See BIP39
|
||||
import pbkdf2, hashlib, hmac
|
||||
PBKDF2_ROUNDS = 2048
|
||||
|
||||
@@ -76,11 +76,9 @@ class WizardBase(PrintError):
|
||||
string like "2of3". Action is 'create' or 'restore'."""
|
||||
raise NotImplementedError
|
||||
|
||||
def query_hardware(self, choices, action):
|
||||
"""Asks the user what kind of hardware wallet they want from the given
|
||||
choices. choices is a list of (wallet_type, translated
|
||||
description) tuples. Action is 'create' or 'restore'. Return
|
||||
the wallet type chosen."""
|
||||
def query_choice(self, msg, choices):
|
||||
"""Asks the user which of several choices they would like.
|
||||
Return the index of the choice."""
|
||||
raise NotImplementedError
|
||||
|
||||
def show_and_verify_seed(self, seed):
|
||||
@@ -205,8 +203,13 @@ class WizardBase(PrintError):
|
||||
if kind == 'multisig':
|
||||
wallet_type = self.query_multisig(action)
|
||||
elif kind == 'hardware':
|
||||
choices = self.plugins.hardware_wallets(action)
|
||||
wallet_type = self.query_hardware(choices, action)
|
||||
wallet_types, choices = self.plugins.hardware_wallets(action)
|
||||
if action == 'create':
|
||||
msg = _('Select the hardware wallet to create')
|
||||
else:
|
||||
msg = _('Select the hardware wallet to restore')
|
||||
choice = self.query_choice(msg, choices)
|
||||
wallet_type = wallet_types[choice]
|
||||
elif kind == 'twofactor':
|
||||
wallet_type = '2fa'
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user