diff --git a/lib/base_wizard.py b/lib/base_wizard.py index 716c0dc19..56642ed50 100644 --- a/lib/base_wizard.py +++ b/lib/base_wizard.py @@ -178,12 +178,13 @@ class BaseWizard(object): return # scan devices devices = [] + devmgr = self.plugins.device_manager for name, description, plugin in support: - devmgr = plugin.device_manager() try: - u = devmgr.unpaired_device_infos(self, plugin) + # FIXME: side-effect: unpaired_device_info sets client.handler + u = devmgr.unpaired_device_infos(None, plugin) except: - print "error", name + devmgr.print_error("error", name) continue devices += map(lambda x: (name, x), u) if not devices: @@ -209,6 +210,7 @@ class BaseWizard(object): from keystore import hardware_keystore, bip44_derivation derivation = bip44_derivation(int(account_id)) plugin = self.plugins.get_plugin(hw_type) + self.plugin = plugin xpub = plugin.setup_device(device_info, derivation, self) # create keystore d = { diff --git a/lib/plugins.py b/lib/plugins.py index 451dee894..53a940d8b 100644 --- a/lib/plugins.py +++ b/lib/plugins.py @@ -437,8 +437,6 @@ class DeviceMgr(ThreadJob, PrintError): if devices is None: devices = self.scan_devices() devices = [dev for dev in devices if not self.xpub_by_id(dev.id_)] - - states = [_("wiped"), _("initialized")] infos = [] for device in devices: if not device.product_key in plugin.DEVICE_IDS: @@ -446,7 +444,7 @@ class DeviceMgr(ThreadJob, PrintError): client = self.create_client(device, handler, plugin) if not client: continue - state = states[client.is_initialized()] + state = _("initialized") if client.is_initialized() else _("wiped") label = client.label() or _("An unnamed %s") % plugin.device descr = "%s (%s)" % (label, state) infos.append(DeviceInfo(device, descr, client.is_initialized())) diff --git a/plugins/trezor/plugin.py b/plugins/trezor/plugin.py index 48e856469..46c91f829 100644 --- a/plugins/trezor/plugin.py +++ b/plugins/trezor/plugin.py @@ -160,13 +160,12 @@ class TrezorCompatiblePlugin(HW_PluginBase): (TIM_MNEMONIC, _("Upload a BIP39 mnemonic to generate the seed")), (TIM_PRIVKEY, _("Upload a master private key")) ] - f = lambda x: self._initialize_device(x, device_id, handler) + f = lambda x: self._initialize_device(x, device_id, wizard, handler) wizard.choice_dialog(title=_('Initialize Device'), message=msg, choices=choices, run_next=f) - def _initialize_device(self, method, device_id, handler): + def _initialize_device(self, method, device_id, wizard, handler): (item, label, pin_protection, passphrase_protection) \ - = handler.request_trezor_init_settings(method, self.device) - + = self.request_trezor_init_settings(wizard, method, self.device) if method == TIM_RECOVER and self.device == 'TREZOR': # Warn user about firmware lameness handler.show_error(_( @@ -203,14 +202,18 @@ class TrezorCompatiblePlugin(HW_PluginBase): '''Called when creating a new wallet. Select the device to use. If the device is uninitialized, go through the intialization process.''' - handler = wizard devmgr = self.device_manager() device_id = device_info.device.id_ + client = devmgr.client_by_id(device_id) if not device_info.initialized: + handler = self.create_handler(wizard) + client.handler = handler self.initialize_device(device_id, wizard, handler) - client = devmgr.client_by_id(device_id) + + client.handler = wizard + xpub = client.get_xpub(derivation) client.used() - return client.get_xpub(derivation) + return xpub def sign_transaction(self, keystore, tx, prev_tx, xpub_path): self.prev_tx = prev_tx diff --git a/plugins/trezor/qt_generic.py b/plugins/trezor/qt_generic.py index 26b3d3e26..824ed5865 100644 --- a/plugins/trezor/qt_generic.py +++ b/plugins/trezor/qt_generic.py @@ -176,12 +176,57 @@ class QtHandler(QtHandlerBase): self.character_dialog.get_char(msg.word_pos, msg.character_pos) self.done.set() - def request_trezor_init_settings(self, method, device): - wizard = self.win - vbox = QVBoxLayout() - next_enabled=True +def qt_plugin_class(base_plugin_class): + + class QtPlugin(base_plugin_class): + # Derived classes must provide the following class-static variables: + # icon_file + # pin_matrix_widget_class + + def create_handler(self, window): + return QtHandler(window, self.pin_matrix_widget_class(), self.device) + + @hook + def load_wallet(self, wallet, window): + for keystore in wallet.get_keystores(): + if type(keystore) != self.keystore_class: + continue + button = StatusBarButton(QIcon(self.icon_file), self.device, + partial(self.settings_dialog, window)) + window.statusBar().addPermanentWidget(button) + keystore.handler = self.create_handler(window) + keystore.thread = TaskThread(window, window.on_error) + # Trigger a pairing + keystore.thread.add(partial(self.get_client, keystore)) + + @hook + def receive_menu(self, menu, addrs, wallet): + for keystore in wallet.get_keystores(): + if type(keystore) == self.keystore_class and len(addrs) == 1: + def show_address(): + keystore.thread.add(partial(self.show_address, wallet, addrs[0])) + menu.addAction(_("Show on %s") % self.device, show_address) + + def settings_dialog(self, window): + device_id = self.choose_device(window) + if device_id: + SettingsDialog(window, self, device_id).exec_() + + def choose_device(self, window): + '''This dialog box should be usable even if the user has + forgotten their PIN or it is in bootloader mode.''' + keystore = window.wallet.get_keystore() + device_id = self.device_manager().xpub_id(keystore.xpub) + if not device_id: + info = self.device_manager().select_device(keystore.handler, self) + device_id = info.device.id_ + return device_id + + def request_trezor_init_settings(self, wizard, method, device): + vbox = QVBoxLayout() + next_enabled = True label = QLabel(_("Enter a label to name your device:")) name = QLineEdit() hl = QHBoxLayout() @@ -260,54 +305,6 @@ class QtHandler(QtHandlerBase): return (item, unicode(name.text()), pin, cb_phrase.isChecked()) - -def qt_plugin_class(base_plugin_class): - - class QtPlugin(base_plugin_class): - # Derived classes must provide the following class-static variables: - # icon_file - # pin_matrix_widget_class - - def create_handler(self, window): - return QtHandler(window, self.pin_matrix_widget_class(), self.device) - - @hook - def load_wallet(self, wallet, window): - for keystore in wallet.get_keystores(): - if type(keystore) != self.keystore_class: - continue - button = StatusBarButton(QIcon(self.icon_file), self.device, - partial(self.settings_dialog, window)) - window.statusBar().addPermanentWidget(button) - keystore.handler = self.create_handler(window) - keystore.thread = TaskThread(window, window.on_error) - # Trigger a pairing - keystore.thread.add(partial(self.get_client, keystore)) - - @hook - def receive_menu(self, menu, addrs, wallet): - for keystore in wallet.get_keystores(): - if type(keystore) == self.keystore_class and len(addrs) == 1: - def show_address(): - keystore.thread.add(partial(self.show_address, wallet, addrs[0])) - menu.addAction(_("Show on %s") % self.device, show_address) - - def settings_dialog(self, window): - device_id = self.choose_device(window) - if device_id: - SettingsDialog(window, self, device_id).exec_() - - def choose_device(self, window): - '''This dialog box should be usable even if the user has - forgotten their PIN or it is in bootloader mode.''' - keystore = window.wallet.get_keystore() - device_id = self.device_manager().xpub_id(keystore.xpub) - if not device_id: - info = self.device_manager().select_device(keystore.handler, self) - device_id = info.device.id_ - return device_id - - return QtPlugin