Move trezor-specific install wizard code to plugin
This commit is contained in:
parent
54cdd551fe
commit
3e8598c245
|
@ -418,88 +418,3 @@ class InstallWizard(WindowModalDialog, WizardBase):
|
|||
self.set_layout(vbox)
|
||||
if not self.exec_():
|
||||
raise UserCancelled
|
||||
|
||||
def request_trezor_init_settings(self, method, device):
|
||||
vbox = QVBoxLayout()
|
||||
|
||||
main_label = QLabel(_("Initialization settings for your %s:") % device)
|
||||
vbox.addWidget(main_label)
|
||||
|
||||
OK_button = OkButton(self, _('Next'))
|
||||
|
||||
if method in [self.TIM_NEW, self.TIM_RECOVER]:
|
||||
gb = QGroupBox()
|
||||
vbox1 = QVBoxLayout()
|
||||
gb.setLayout(vbox1)
|
||||
vbox.addWidget(gb)
|
||||
gb.setTitle(_("Select your seed length:"))
|
||||
choices = [
|
||||
_("12 words"),
|
||||
_("18 words"),
|
||||
_("24 words"),
|
||||
]
|
||||
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)
|
||||
cb_pin = QCheckBox(_('Enable PIN protection'))
|
||||
cb_pin.setChecked(True)
|
||||
else:
|
||||
text = QTextEdit()
|
||||
text.setMaximumHeight(60)
|
||||
if method == self.TIM_MNEMONIC:
|
||||
msg = _("Enter your BIP39 mnemonic:")
|
||||
else:
|
||||
msg = _("Enter the master private key beginning with xprv:")
|
||||
def set_enabled():
|
||||
OK_button.setEnabled(Wallet.is_xprv(
|
||||
self.get_seed_text(text)))
|
||||
text.textChanged.connect(set_enabled)
|
||||
OK_button.setEnabled(False)
|
||||
|
||||
vbox.addWidget(QLabel(msg))
|
||||
vbox.addWidget(text)
|
||||
pin = QLineEdit()
|
||||
pin.setValidator(QRegExpValidator(QRegExp('[1-9]{0,10}')))
|
||||
pin.setMaximumWidth(100)
|
||||
hbox_pin = QHBoxLayout()
|
||||
hbox_pin.addWidget(QLabel(_("Enter your PIN (digits 1-9):")))
|
||||
hbox_pin.addWidget(pin)
|
||||
hbox_pin.addStretch(1)
|
||||
|
||||
label = QLabel(_("Enter a label to name your device:"))
|
||||
name = QLineEdit()
|
||||
hl = QHBoxLayout()
|
||||
hl.addWidget(label)
|
||||
hl.addWidget(name)
|
||||
hl.addStretch(1)
|
||||
vbox.addLayout(hl)
|
||||
|
||||
if method in [self.TIM_NEW, self.TIM_RECOVER]:
|
||||
vbox.addWidget(cb_pin)
|
||||
else:
|
||||
vbox.addLayout(hbox_pin)
|
||||
|
||||
cb_phrase = QCheckBox(_('Enable Passphrase protection'))
|
||||
cb_phrase.setChecked(False)
|
||||
vbox.addWidget(cb_phrase)
|
||||
|
||||
vbox.addStretch(1)
|
||||
vbox.addLayout(Buttons(CancelButton(self), OK_button))
|
||||
self.set_layout(vbox)
|
||||
|
||||
if not self.exec_():
|
||||
raise UserCancelled
|
||||
|
||||
if method in [self.TIM_NEW, self.TIM_RECOVER]:
|
||||
item = bg.checkedId()
|
||||
pin = cb_pin.isChecked()
|
||||
else:
|
||||
item = ' '.join(str(self.get_seed_text(text)).split())
|
||||
pin = str(pin.text())
|
||||
|
||||
return (item, unicode(name.text()), pin, cb_phrase.isChecked())
|
||||
|
|
|
@ -48,7 +48,6 @@ class WizardBase(PrintError):
|
|||
('multisig', _("Multi-signature wallet")),
|
||||
('hardware', _("Hardware wallet")),
|
||||
]
|
||||
TIM_NEW, TIM_RECOVER, TIM_MNEMONIC, TIM_PRIVKEY = range(0, 4)
|
||||
|
||||
# Derived classes must set:
|
||||
# self.language_for_seed
|
||||
|
@ -103,23 +102,6 @@ class WizardBase(PrintError):
|
|||
dynamic feedback. If not provided, Wallet.is_any is used."""
|
||||
raise NotImplementedError
|
||||
|
||||
def request_trezor_init_settings(self, method, device):
|
||||
"""Ask the user for the information needed to initialize a trezor-
|
||||
compatible device. Method is one of the TIM_ trezor init
|
||||
method constants. TIM_NEW and TIM_RECOVER should ask how many
|
||||
seed words to use, and return 0, 1 or 2 for a 12, 18 or 24
|
||||
word seed respectively. TIM_MNEMONIC should ask for a
|
||||
mnemonic. TIM_PRIVKEY should ask for a master private key.
|
||||
All four methods should additionally ask for a name to label
|
||||
the device, PIN information and whether passphrase protection is
|
||||
to be enabled (True/False, default to False). For TIM_NEW and
|
||||
TIM_RECOVER, the pin information is whether pin protection
|
||||
is required (True/False, default to True); for TIM_MNEMONIC and
|
||||
TIM_PRIVKEY is is the pin as a string of digits 1-9.
|
||||
The result is a 4-tuple: (TIM specific data, label, pininfo,
|
||||
passphraseprotection)."""
|
||||
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
|
||||
|
|
|
@ -14,7 +14,9 @@ from electrum.transaction import (deserialize, is_extended_pubkey,
|
|||
from electrum.wallet import BIP32_HD_Wallet, BIP44_Wallet
|
||||
from electrum.util import ThreadJob
|
||||
from electrum.plugins import DeviceMgr
|
||||
from electrum.wizard import WizardBase
|
||||
|
||||
# Trezor initialization methods
|
||||
TIM_NEW, TIM_RECOVER, TIM_MNEMONIC, TIM_PRIVKEY = range(0, 4)
|
||||
|
||||
class DeviceDisconnectedError(Exception):
|
||||
pass
|
||||
|
@ -247,7 +249,7 @@ class TrezorCompatiblePlugin(BasePlugin, ThreadJob):
|
|||
if isinstance(wallet, self.wallet_class):
|
||||
self.device_manager().close_wallet(wallet)
|
||||
|
||||
def initialize_device(self, wallet, wizard):
|
||||
def initialize_device(self, wallet):
|
||||
# Prevent timeouts during initialization
|
||||
wallet.last_operation = self.prevent_timeout
|
||||
|
||||
|
@ -268,22 +270,22 @@ class TrezorCompatiblePlugin(BasePlugin, ThreadJob):
|
|||
_("Upload a master private key")
|
||||
]
|
||||
|
||||
method = wizard.query_choice(msg, methods)
|
||||
method = wallet.handler.query_choice(msg, methods)
|
||||
(item, label, pin_protection, passphrase_protection) \
|
||||
= wizard.request_trezor_init_settings(method, self.device)
|
||||
= wallet.handler.request_trezor_init_settings(method, self.device)
|
||||
|
||||
client = self.get_client(wallet)
|
||||
language = 'english'
|
||||
|
||||
if method == WizardBase.TIM_NEW:
|
||||
if method == TIM_NEW:
|
||||
strength = 64 * (item + 2) # 128, 192 or 256
|
||||
client.reset_device(True, strength, passphrase_protection,
|
||||
pin_protection, label, language)
|
||||
elif method == WizardBase.TIM_RECOVER:
|
||||
elif method == TIM_RECOVER:
|
||||
word_count = 6 * (item + 2) # 12, 18 or 24
|
||||
client.recovery_device(word_count, passphrase_protection,
|
||||
pin_protection, label, language)
|
||||
elif method == WizardBase.TIM_MNEMONIC:
|
||||
elif method == TIM_MNEMONIC:
|
||||
pin = pin_protection # It's the pin, not a boolean
|
||||
client.load_device_by_mnemonic(str(item), pin,
|
||||
passphrase_protection,
|
||||
|
@ -293,7 +295,7 @@ class TrezorCompatiblePlugin(BasePlugin, ThreadJob):
|
|||
client.load_device_by_xprv(item, pin, passphrase_protection,
|
||||
label, language)
|
||||
|
||||
def select_device(self, wallet, wizard):
|
||||
def select_device(self, wallet):
|
||||
'''Called when creating a new wallet. Select the device to use. If
|
||||
the device is uninitialized, go through the intialization
|
||||
process.'''
|
||||
|
@ -306,10 +308,10 @@ class TrezorCompatiblePlugin(BasePlugin, ThreadJob):
|
|||
labels = list(map(client_desc, clients))
|
||||
|
||||
msg = _("Please select which %s device to use:") % self.device
|
||||
client = clients[wizard.query_choice(msg, labels)]
|
||||
client = clients[wallet.handler.query_choice(msg, labels)]
|
||||
self.device_manager().pair_wallet(wallet, client)
|
||||
if not client.is_initialized():
|
||||
self.initialize_device(wallet, wizard)
|
||||
self.initialize_device(wallet)
|
||||
|
||||
def on_restore_wallet(self, wallet, wizard):
|
||||
assert isinstance(wallet, self.wallet_class)
|
||||
|
|
|
@ -8,12 +8,13 @@ from PyQt4.Qt import QVBoxLayout, QLabel, SIGNAL
|
|||
from electrum_gui.qt.main_window import StatusBarButton
|
||||
from electrum_gui.qt.password_dialog import PasswordDialog
|
||||
from electrum_gui.qt.util import *
|
||||
from plugin import TrezorCompatiblePlugin
|
||||
from .plugin import TrezorCompatiblePlugin, TIM_NEW, TIM_RECOVER, TIM_MNEMONIC
|
||||
|
||||
from electrum.i18n import _
|
||||
from electrum.plugins import hook, DeviceMgr
|
||||
from electrum.util import PrintError
|
||||
from electrum.wallet import BIP44_Wallet
|
||||
from electrum.wallet import Wallet, BIP44_Wallet
|
||||
from electrum.wizard import UserCancelled
|
||||
|
||||
|
||||
# By far the trickiest thing about this handler is the window stack;
|
||||
|
@ -134,6 +135,97 @@ class QtHandler(PrintError):
|
|||
finally:
|
||||
assert dialog == self.window_stack.pop()
|
||||
|
||||
def query_choice(self, msg, labels):
|
||||
return self.win.query_choice(msg, labels)
|
||||
|
||||
def request_trezor_init_settings(self, method, device):
|
||||
wizard = self.win
|
||||
|
||||
vbox = QVBoxLayout()
|
||||
main_label = QLabel(_("Initialization settings for your %s:") % device)
|
||||
vbox.addWidget(main_label)
|
||||
OK_button = OkButton(wizard, _('Next'))
|
||||
|
||||
def clean_text(widget):
|
||||
text = unicode(widget.toPlainText()).strip()
|
||||
return ' '.join(text.split())
|
||||
|
||||
if method in [TIM_NEW, TIM_RECOVER]:
|
||||
gb = QGroupBox()
|
||||
vbox1 = QVBoxLayout()
|
||||
gb.setLayout(vbox1)
|
||||
vbox.addWidget(gb)
|
||||
gb.setTitle(_("Select your seed length:"))
|
||||
choices = [
|
||||
_("12 words"),
|
||||
_("18 words"),
|
||||
_("24 words"),
|
||||
]
|
||||
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)
|
||||
cb_pin = QCheckBox(_('Enable PIN protection'))
|
||||
cb_pin.setChecked(True)
|
||||
else:
|
||||
text = QTextEdit()
|
||||
text.setMaximumHeight(60)
|
||||
if method == TIM_MNEMONIC:
|
||||
msg = _("Enter your BIP39 mnemonic:")
|
||||
else:
|
||||
msg = _("Enter the master private key beginning with xprv:")
|
||||
def set_enabled():
|
||||
OK_button.setEnabled(Wallet.is_xprv(clean_text(text)))
|
||||
text.textChanged.connect(set_enabled)
|
||||
OK_button.setEnabled(False)
|
||||
|
||||
vbox.addWidget(QLabel(msg))
|
||||
vbox.addWidget(text)
|
||||
pin = QLineEdit()
|
||||
pin.setValidator(QRegExpValidator(QRegExp('[1-9]{0,10}')))
|
||||
pin.setMaximumWidth(100)
|
||||
hbox_pin = QHBoxLayout()
|
||||
hbox_pin.addWidget(QLabel(_("Enter your PIN (digits 1-9):")))
|
||||
hbox_pin.addWidget(pin)
|
||||
hbox_pin.addStretch(1)
|
||||
|
||||
label = QLabel(_("Enter a label to name your device:"))
|
||||
name = QLineEdit()
|
||||
hl = QHBoxLayout()
|
||||
hl.addWidget(label)
|
||||
hl.addWidget(name)
|
||||
hl.addStretch(1)
|
||||
vbox.addLayout(hl)
|
||||
|
||||
if method in [TIM_NEW, TIM_RECOVER]:
|
||||
vbox.addWidget(cb_pin)
|
||||
else:
|
||||
vbox.addLayout(hbox_pin)
|
||||
|
||||
cb_phrase = QCheckBox(_('Enable Passphrase protection'))
|
||||
cb_phrase.setChecked(False)
|
||||
vbox.addWidget(cb_phrase)
|
||||
|
||||
vbox.addStretch(1)
|
||||
vbox.addLayout(Buttons(CancelButton(wizard), OK_button))
|
||||
|
||||
wizard.set_layout(vbox)
|
||||
if not wizard.exec_():
|
||||
raise UserCancelled
|
||||
|
||||
if method in [TIM_NEW, TIM_RECOVER]:
|
||||
item = bg.checkedId()
|
||||
pin = cb_pin.isChecked()
|
||||
else:
|
||||
item = ' '.join(str(clean_text(text)).split())
|
||||
pin = str(pin.text())
|
||||
|
||||
return (item, unicode(name.text()), pin, cb_phrase.isChecked())
|
||||
|
||||
|
||||
def qt_plugin_class(base_plugin_class):
|
||||
|
||||
|
@ -159,7 +251,7 @@ def qt_plugin_class(base_plugin_class):
|
|||
def on_create_wallet(self, wallet, wizard):
|
||||
assert type(wallet) == self.wallet_class
|
||||
wallet.handler = self.create_handler(wizard)
|
||||
self.select_device(wallet, wizard)
|
||||
self.select_device(wallet)
|
||||
wallet.create_hd_account(None)
|
||||
|
||||
@hook
|
||||
|
|
Loading…
Reference in New Issue