commit 3a735d40acecbcee689e13e5d6dbef9d10c01584
parent 9580cd62f61865553de0802af39bfd6edcca1fa8
Author: Neil Booth <kyuupichan@gmail.com>
Date: Sun, 24 Jan 2016 10:39:04 +0900
Keepkey/Trezor: fix 2 issues
1: In KeepKey recovery we let the user type a fifth
letter which causes the firmware to abort the
protocol. Only allow 4 letters.
2: Handle exceptions thrown during device initialization
properly
Diffstat:
2 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/plugins/trezor/plugin.py b/plugins/trezor/plugin.py
@@ -323,18 +323,21 @@ class TrezorCompatiblePlugin(BasePlugin, ThreadJob):
pin = pin_protection # It's the pin, not a boolean
client.load_device_by_xprv(item, pin, passphrase_protection,
label, language)
+ # After successful initialization create accounts
+ wallet.create_hd_account(None)
return initialize_method
- def setup_device(self, wallet, on_done):
+ def setup_device(self, wallet, on_done, on_error):
'''Called when creating a new wallet. Select the device to use. If
the device is uninitialized, go through the intialization
process. Then create the wallet accounts.'''
- create_hd_task = partial(wallet.create_hd_account, None)
initialized = self.select_device(wallet)
- if not initialized:
- wallet.thread.add(self.initialize_device(wallet))
- wallet.thread.add(create_hd_task, on_done=on_done)
+ if initialized:
+ task = partial(wallet.create_hd_account, None)
+ else:
+ task = self.initialize_device(wallet)
+ wallet.thread.add(task, on_done=on_done, on_error=on_error)
def unpaired_devices(self, handler):
'''Returns all connected, unpaired devices as a list of clients and a
diff --git a/plugins/trezor/qt_generic.py b/plugins/trezor/qt_generic.py
@@ -29,8 +29,8 @@ PASSPHRASE_NOT_PIN = _(
"Only change this if you are sure you understand it.")
CHARACTER_RECOVERY = (
"Use the recovery cipher shown on your device to input your seed words. "
- "The cipher updates with every letter. After at most 4 letters the "
- "device will auto-complete each word.\n"
+ "The cipher changes with every keypress.\n"
+ "After at most 4 letters the device will auto-complete a word.\n"
"Press SPACE or the Accept Word button to accept the device's auto-"
"completed word and advance to the next one.\n"
"Press BACKSPACE to go back a character or word.\n"
@@ -93,17 +93,24 @@ class CharacterDialog(WindowModalDialog):
if n == self.character_pos:
button.setFocus()
+ def is_valid_alpha_space(self, key):
+ # Auto-completion requires at least 3 characters
+ if key == ord(' ') and self.character_pos >= 3:
+ return True
+ # Firmware aborts protocol if the 5th character is non-space
+ if self.character_pos >= 4:
+ return False
+ return (key >= ord('a') and key <= ord('z')
+ or (key >= ord('A') and key <= ord('Z')))
+
def process_key(self, key):
self.data = None
if key == Qt.Key_Return and self.finished_button.isEnabled():
self.data = {'done': True}
elif key == Qt.Key_Backspace and (self.word_pos or self.character_pos):
self.data = {'delete': True}
- elif ((key >= ord('a') and key <= ord('z'))
- or (key >= ord('A') and key <= ord('Z'))
- or (key == ord(' ') and self.character_pos >= 3)):
- char = chr(key).lower()
- self.data = {'character': char}
+ elif self.is_valid_alpha_space(key):
+ self.data = {'character': chr(key).lower()}
if self.data:
self.loop.exit(0)
@@ -368,8 +375,14 @@ def qt_plugin_class(base_plugin_class):
wallet.thread = TaskThread(wizard, wizard.on_error)
# Setup device and create accounts in separate thread; wait until done
loop = QEventLoop()
- self.setup_device(wallet, loop.quit)
+ exc_info = []
+ self.setup_device(wallet, on_done=loop.quit,
+ on_error=lambda info: exc_info.extend(info))
loop.exec_()
+ # If an exception was thrown, show to user and exit install wizard
+ if exc_info:
+ wizard.on_error(exc_info)
+ raise UserCancelled
@hook
def receive_menu(self, menu, addrs, wallet):