wizard: scan hardware devices directly

This commit is contained in:
ThomasV 2016-08-23 13:40:11 +02:00
parent 0520eda628
commit 4781df9d21
5 changed files with 61 additions and 43 deletions

View File

@ -338,13 +338,13 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
self.show_message(msg)
@wizard_dialog
def confirm_dialog(self, msg, run_next):
self.confirm(msg)
def confirm_dialog(self, title, message, run_next):
self.confirm(message, title)
def confirm(self, msg):
def confirm(self, message, title):
vbox = QVBoxLayout()
vbox.addWidget(WWLabel(msg))
self.set_main_layout(vbox)
vbox.addWidget(WWLabel(message))
self.set_main_layout(vbox, title)
@wizard_dialog
def action_dialog(self, action, run_next):
@ -379,6 +379,13 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
self.set_main_layout(vbox, '')
return clayout.selected_index()
def get_passphrase(self, msg, confirm):
phrase = self.pw_layout(msg, PW_PASSPHRASE)
if phrase is None:
raise UserCancelled
return phrase
@wizard_dialog
def account_id_dialog(self, run_next):
message = '\n'.join([

View File

@ -117,12 +117,12 @@ class BaseWizard(object):
('create_seed', _('Create a new seed')),
('restore_seed', _('I already have a seed')),
('restore_from_key', _('Import keys')),
('choose_hw', _('Use hardware device')),
('choose_device', _('Use hardware device')),
]
else:
choices = [
('restore_from_key', _('Import cosigner key')),
('choose_hw', _('Cosign with hardware device')),
('choose_device', _('Cosign with hardware device')),
]
self.choice_dialog(title=title, message=message, choices=choices, run_next=self.run)
@ -165,46 +165,59 @@ class BaseWizard(object):
])
self.restore_keys_dialog(title=title, message=message, run_next=self.on_restore, is_valid=v)
def choose_hw(self):
hw_wallet_types, choices = self.plugins.hardware_wallets('create')
choices = zip(hw_wallet_types, choices)
def choose_device(self):
title = _('Hardware Keystore')
if choices:
msg = _('Select the type of device') + ':'
else:
msg = ' '.join([
# check available plugins
support = self.plugins.get_hardware_support()
if not support:
msg = '\n'.join([
_('No hardware wallet support found on your system.'),
_('Please install the relevant libraries (eg python-trezor for Trezor).'),
])
self.choice_dialog(title=title, message=msg, choices=choices, run_next=self.on_hardware)
self.confirm_dialog(title=title, message=msg, run_next= lambda x: self.choose_device())
return
# scan devices
devices = []
for name, description, plugin in support:
devmgr = plugin.device_manager()
try:
u = devmgr.unpaired_device_infos(self, plugin)
except:
print "error", name
continue
devices += map(lambda x: (name, x), u)
if not devices:
msg = '\n'.join([
_('No hardware device detected.'),
_('To trigger a rescan, press \'next\'.'),
])
self.confirm_dialog(title=title, message=msg, run_next= lambda x: self.choose_device())
return
# select device
self.devices = devices
choices = []
for name, device_info in devices:
choices.append( ((name, device_info), device_info.description) )
msg = _('Select a device') + ':'
self.choice_dialog(title=title, message=msg, choices=choices, run_next=self.on_device)
def on_hardware(self, hw_type):
self.hw_type = hw_type
title = _('Hardware wallet') + ' [%s]' % hw_type
message = _('Do you have a device, or do you want to restore a wallet using an existing seed?')
choices = [
('on_hardware_device', _('I have a %s device')%hw_type),
('on_hardware_seed', _('I have a %s seed')%hw_type),
]
self.choice_dialog(title=title, message=message, choices=choices, run_next=self.run)
def on_hardware_device(self):
f = lambda x: self.run('on_hardware_account_id', x)
def on_device(self, name, device_info):
f = lambda x: self.run('on_hardware_account_id', name, device_info, x)
self.account_id_dialog(run_next=f)
def on_hardware_account_id(self, account_id):
def on_hardware_account_id(self, hw_type, device_info, account_id):
from keystore import hardware_keystore, bip44_derivation
derivation = bip44_derivation(int(account_id))
plugin = self.plugins.get_plugin(self.hw_type)
xpub = plugin.setup_device(derivation, self)
plugin = self.plugins.get_plugin(hw_type)
xpub = plugin.setup_device(device_info, derivation, self)
# create keystore
d = {
'type': 'hardware',
'hw_type': self.hw_type,
'hw_type': hw_type,
'derivation': derivation,
'xpub': xpub,
}
k = hardware_keystore(self.hw_type, d)
k = hardware_keystore(hw_type, d)
self.on_keystore(k, None)
def on_hardware_seed(self):

View File

@ -139,19 +139,18 @@ class Plugins(DaemonThread):
requires = d.get('requires_wallet_type', [])
return not requires or w.wallet_type in requires
def hardware_wallets(self, action):
wallet_types, descs = [], []
def get_hardware_support(self):
out = []
for name, (gui_good, details) in self.hw_wallets.items():
if gui_good:
try:
p = self.get_plugin(name)
if action == 'restore' or p.is_enabled():
wallet_types.append(details[1])
descs.append(details[2])
if p.is_enabled():
out.append([name, details[2], p])
except:
traceback.print_exc()
self.print_error("cannot load plugin for:", name)
return wallet_types, descs
return out
def register_wallet_type(self, name, gui_good, wallet_type):
from wallet import register_wallet_type, register_constructor

View File

@ -199,13 +199,12 @@ class TrezorCompatiblePlugin(HW_PluginBase):
client.load_device_by_xprv(item, pin, passphrase_protection,
label, language)
def setup_device(self, derivation, wizard):
def setup_device(self, device_info, derivation, wizard):
'''Called when creating a new wallet. Select the device to use. If
the device is uninitialized, go through the intialization
process.'''
handler = self.create_handler(wizard)
handler = wizard
devmgr = self.device_manager()
device_info = devmgr.select_device(handler, self)
device_id = device_info.device.id_
if not device_info.initialized:
self.initialize_device(device_id, wizard, handler)

View File

@ -337,7 +337,7 @@ class TrustedCoinPlugin(BasePlugin):
def show_disclaimer(self, wizard):
wizard.set_icon(':icons/trustedcoin.png')
wizard.stack = []
wizard.confirm_dialog('\n\n'.join(DISCLAIMER), run_next = lambda x: wizard.run('choose_seed'))
wizard.confirm_dialog(title='Disclaimer', message='\n\n'.join(DISCLAIMER), run_next = lambda x: wizard.run('choose_seed'))
def choose_seed(self, wizard):
title = _('Create or restore')
@ -372,7 +372,7 @@ class TrustedCoinPlugin(BasePlugin):
]
msg = '\n\n'.join(msg)
wizard.stack = []
wizard.confirm_dialog(msg, run_next = lambda x: wizard.run('create_remote_key'))
wizard.confirm_dialog(title='', message=msg, run_next = lambda x: wizard.run('create_remote_key'))
def restore_wallet(self, wizard):
title = _("Restore two-factor Wallet")