commit 87363c8301acc0689c0e0a4c59219fdd40b16a07
parent 13154d4ce765aa7c30707081ad0a9b5b66d7dc9e
Author: Neil Booth <kyuupichan@gmail.com>
Date: Sun, 3 Jan 2016 13:32:33 +0900
Trezor: Implement resetting a device
Diffstat:
5 files changed, 89 insertions(+), 13 deletions(-)
diff --git a/gui/qt/installwizard.py b/gui/qt/installwizard.py
@@ -384,3 +384,55 @@ class InstallWizard(WindowModalDialog, WizardBase):
self.set_layout(vbox)
if not self.exec_():
raise UserCancelled
+
+ def request_trezor_reset_settings(self, device):
+ vbox = QVBoxLayout()
+
+ main_label = QLabel(_("Choose how to initialize your %s device:")
+ % device)
+ vbox.addWidget(main_label)
+
+ msg = _("Select your seed length and strength:")
+ choices = [
+ _("12 words (low)"),
+ _("18 words (medium)"),
+ _("24 words (high)"),
+ ]
+ gb = QGroupBox(msg)
+ vbox1 = QVBoxLayout()
+ gb.setLayout(vbox1)
+ bg = QButtonGroup()
+ for i, choice in enumerate(choices):
+ rb = QRadioButton(gb)
+ rb.setText(choice)
+ bg.addButton(rb)
+ bg.setId(rb, i)
+ vbox1.addWidget(rb)
+ rb.setChecked(True)
+ vbox.addWidget(gb)
+
+ label = QLabel(_("Enter a label to name your device:"))
+ name = QLineEdit()
+ hl = QHBoxLayout()
+ hl.addWidget(label)
+ hl.addWidget(name)
+ hl.addStretch(2)
+ vbox.addLayout(hl)
+
+ cb_pin = QCheckBox(_('Enable PIN protection'))
+ cb_pin.setChecked(True)
+ vbox.addWidget(cb_pin)
+
+ cb_phrase = QCheckBox(_('Enable Passphrase protection'))
+ cb_phrase.setChecked(False)
+ vbox.addWidget(cb_phrase)
+
+ vbox.addStretch(1)
+ vbox.addLayout(Buttons(CancelButton(self), OkButton(self, _('Next'))))
+ self.set_layout(vbox)
+
+ if not self.exec_():
+ raise UserCancelled
+
+ return (bg.checkedId(), unicode(name.text()),
+ cb_pin.isChecked(), cb_phrase.isChecked())
diff --git a/lib/wizard.py b/lib/wizard.py
@@ -103,6 +103,16 @@ class WizardBase(PrintError):
dynamic feedback. If not provided, Wallet.is_any is used."""
raise NotImplementedError
+ def request_trezor_reset_settings(self, device):
+ """Ask the user how they want to initialize a trezor compatible
+ device. device is the device kind, e.g. "Keepkey", to be used
+ in dialog messages. Returns a 4-tuple: (strength, label,
+ pinprotection, passphraseprotection). Strength is 0, 1 or 2
+ for a 12, 18 or 24 word seed, respectively. Label is a name
+ to give the device. PIN protection and passphrase protection
+ are booleans and should default to True and False respectively."""
+ raise NotImplementedError
+
def request_many(self, n, xpub_hot=None):
"""If xpub_hot is provided, a new wallet is being created. Request N
master public keys for cosigners; xpub_hot is the master xpub
diff --git a/plugins/trezor/client.py b/plugins/trezor/client.py
@@ -154,8 +154,8 @@ def trezor_client_class(protocol_mixin, base_client, proto):
cls = TrezorClient
for method in ['apply_settings', 'change_pin', 'get_address',
- 'get_public_node', 'sign_message', 'sign_tx',
- 'wipe_device']:
+ 'get_public_node', 'reset_device', 'sign_message',
+ 'sign_tx', 'wipe_device']:
setattr(cls, method, wrapper(getattr(cls, method)))
return cls
diff --git a/plugins/trezor/plugin.py b/plugins/trezor/plugin.py
@@ -220,19 +220,32 @@ class TrezorCompatiblePlugin(BasePlugin):
self.print_error("clear session:", client)
client.clear_session()
+ def initialize_device(self, wallet, wizard):
+ (strength, label, pin_protection, passphrase_protection) \
+ = wizard.request_trezor_reset_settings(self.device)
+
+ assert strength in range(0, 3)
+ strength = 64 * (strength + 2) # 128, 192 or 256
+ language = ''
+
+ client = self.client(wallet)
+ client.reset_device(True, strength, passphrase_protection,
+ pin_protection, label, language)
+
+
def select_device(self, wallet, wizard):
- '''Called when creating a new wallet. Select the device
- to use.'''
+ '''Called when creating a new wallet. Select the device to use. If
+ the device is uninitialized, go through the intialization
+ process.'''
clients = list(self.clients)
- if not len(clients):
- return
- if len(clients) > 1:
- labels = [client.label() for client in clients]
- msg = _("Please select which %s device to use:") % self.device
- client = clients[wizard.query_choice(msg, labels)]
- else:
- client = clients[0]
+ suffixes = [_("An unnamed device (wiped)"), _(" (initialized)")]
+ labels = [client.label() + suffixes[client.is_initialized()]
+ for client in clients]
+ msg = _("Please select which %s device to use:") % self.device
+ client = clients[wizard.query_choice(msg, labels)]
self.pair_wallet(wallet, client)
+ if not client.is_initialized():
+ self.initialize_device(wallet, wizard)
def pair_wallet(self, wallet, client):
self.print_error("pairing wallet %s to device %s" % (wallet, client))
diff --git a/plugins/trezor/qt_generic.py b/plugins/trezor/qt_generic.py
@@ -59,7 +59,8 @@ class QtHandler(PrintError):
return self.passphrase
def pin_dialog(self, msg):
- # Needed e.g. when renaming label and haven't entered PIN
+ # Needed e.g. when resetting a device
+ self.clear_dialog()
dialog = WindowModalDialog(self.window_stack[-1], _("Enter PIN"))
matrix = self.pin_matrix_widget_class()
vbox = QVBoxLayout()