|
|
@ -16,7 +16,7 @@ from electrum.util import bh2u |
|
|
|
from ..hw_wallet.qt import QtHandlerBase, QtPluginBase |
|
|
|
from ..hw_wallet.plugin import only_hook_if_libraries_available |
|
|
|
from .trezor import (TrezorPlugin, TIM_NEW, TIM_RECOVER, TrezorInitSettings, |
|
|
|
RECOVERY_TYPE_SCRAMBLED_WORDS, RECOVERY_TYPE_MATRIX) |
|
|
|
Capability, BackupType, RecoveryDeviceType) |
|
|
|
|
|
|
|
|
|
|
|
PASSPHRASE_HELP_SHORT =_( |
|
|
@ -199,6 +199,8 @@ class QtPlugin(QtPluginBase): |
|
|
|
raise Exception(_("The device was disconnected.")) |
|
|
|
model = client.get_trezor_model() |
|
|
|
fw_version = client.client.version |
|
|
|
capabilities = client.client.features.capabilities |
|
|
|
have_shamir = Capability.Shamir in capabilities |
|
|
|
|
|
|
|
# label |
|
|
|
label = QLabel(_("Enter a label to name your device:")) |
|
|
@ -209,22 +211,87 @@ class QtPlugin(QtPluginBase): |
|
|
|
hl.addStretch(1) |
|
|
|
vbox.addLayout(hl) |
|
|
|
|
|
|
|
# Backup type |
|
|
|
gb_backuptype = QGroupBox() |
|
|
|
hbox_backuptype = QHBoxLayout() |
|
|
|
gb_backuptype.setLayout(hbox_backuptype) |
|
|
|
vbox.addWidget(gb_backuptype) |
|
|
|
gb_backuptype.setTitle(_('Select backup type:')) |
|
|
|
bg_backuptype = QButtonGroup() |
|
|
|
|
|
|
|
rb_single = QRadioButton(gb_backuptype) |
|
|
|
rb_single.setText(_('Single seed (BIP39)')) |
|
|
|
bg_backuptype.addButton(rb_single) |
|
|
|
bg_backuptype.setId(rb_single, BackupType.Bip39) |
|
|
|
hbox_backuptype.addWidget(rb_single) |
|
|
|
rb_single.setChecked(not have_shamir) |
|
|
|
|
|
|
|
rb_shamir = QRadioButton(gb_backuptype) |
|
|
|
rb_shamir.setText(_('Shamir')) |
|
|
|
bg_backuptype.addButton(rb_shamir) |
|
|
|
bg_backuptype.setId(rb_shamir, BackupType.Slip39_Basic) |
|
|
|
hbox_backuptype.addWidget(rb_shamir) |
|
|
|
rb_shamir.setChecked(have_shamir) |
|
|
|
rb_shamir.setEnabled(Capability.Shamir in capabilities) |
|
|
|
|
|
|
|
rb_shamir_groups = QRadioButton(gb_backuptype) |
|
|
|
rb_shamir_groups.setText(_('Super Shamir')) |
|
|
|
bg_backuptype.addButton(rb_shamir_groups) |
|
|
|
bg_backuptype.setId(rb_shamir_groups, BackupType.Slip39_Advanced) |
|
|
|
hbox_backuptype.addWidget(rb_shamir_groups) |
|
|
|
rb_shamir_groups.setEnabled(Capability.ShamirGroups in capabilities) |
|
|
|
|
|
|
|
# word count |
|
|
|
gb = QGroupBox() |
|
|
|
word_count_buttons = {} |
|
|
|
|
|
|
|
gb_numwords = QGroupBox() |
|
|
|
hbox1 = QHBoxLayout() |
|
|
|
gb.setLayout(hbox1) |
|
|
|
vbox.addWidget(gb) |
|
|
|
gb.setTitle(_("Select your seed length:")) |
|
|
|
gb_numwords.setLayout(hbox1) |
|
|
|
vbox.addWidget(gb_numwords) |
|
|
|
gb_numwords.setTitle(_("Select seed/share length:")) |
|
|
|
bg_numwords = QButtonGroup() |
|
|
|
word_counts = (12, 18, 24) |
|
|
|
for i, count in enumerate(word_counts): |
|
|
|
rb = QRadioButton(gb) |
|
|
|
for count in (12, 18, 20, 24, 33): |
|
|
|
rb = QRadioButton(gb_numwords) |
|
|
|
word_count_buttons[count] = rb |
|
|
|
rb.setText(_("{:d} words").format(count)) |
|
|
|
bg_numwords.addButton(rb) |
|
|
|
bg_numwords.setId(rb, i) |
|
|
|
bg_numwords.setId(rb, count) |
|
|
|
hbox1.addWidget(rb) |
|
|
|
rb.setChecked(True) |
|
|
|
|
|
|
|
def configure_word_counts(): |
|
|
|
if model == "1": |
|
|
|
checked_wordcount = 24 |
|
|
|
else: |
|
|
|
checked_wordcount = 12 |
|
|
|
|
|
|
|
if method == TIM_RECOVER: |
|
|
|
if have_shamir: |
|
|
|
valid_word_counts = (12, 18, 20, 24, 33) |
|
|
|
else: |
|
|
|
valid_word_counts = (12, 18, 24) |
|
|
|
elif rb_single.isChecked(): |
|
|
|
valid_word_counts = (12, 18, 24) |
|
|
|
gb_numwords.setTitle(_('Select seed length:')) |
|
|
|
else: |
|
|
|
valid_word_counts = (20, 33) |
|
|
|
checked_wordcount = 20 |
|
|
|
gb_numwords.setTitle(_('Select share length:')) |
|
|
|
|
|
|
|
word_count_buttons[checked_wordcount].setChecked(True) |
|
|
|
for c, btn in word_count_buttons.items(): |
|
|
|
btn.setVisible(c in valid_word_counts) |
|
|
|
|
|
|
|
bg_backuptype.buttonClicked.connect(configure_word_counts) |
|
|
|
configure_word_counts() |
|
|
|
|
|
|
|
# set up conditional visibility: |
|
|
|
# 1. backup_type is only visible when creating new seed |
|
|
|
gb_backuptype.setVisible(method == TIM_NEW) |
|
|
|
# 2. word_count is not visible when recovering on TT |
|
|
|
if method == TIM_RECOVER and model != "1": |
|
|
|
gb_numwords.setVisible(False) |
|
|
|
|
|
|
|
# PIN |
|
|
|
cb_pin = QCheckBox(_('Enable PIN protection')) |
|
|
|
cb_pin.setChecked(True) |
|
|
@ -255,7 +322,7 @@ class QtPlugin(QtPluginBase): |
|
|
|
|
|
|
|
# ask for recovery type (random word order OR matrix) |
|
|
|
bg_rectype = None |
|
|
|
if method == TIM_RECOVER and not model == 'T': |
|
|
|
if method == TIM_RECOVER and model == '1': |
|
|
|
gb_rectype = QGroupBox() |
|
|
|
hbox_rectype = QHBoxLayout() |
|
|
|
gb_rectype.setLayout(hbox_rectype) |
|
|
@ -266,14 +333,14 @@ class QtPlugin(QtPluginBase): |
|
|
|
rb1 = QRadioButton(gb_rectype) |
|
|
|
rb1.setText(_('Scrambled words')) |
|
|
|
bg_rectype.addButton(rb1) |
|
|
|
bg_rectype.setId(rb1, RECOVERY_TYPE_SCRAMBLED_WORDS) |
|
|
|
bg_rectype.setId(rb1, RecoveryDeviceType.ScrambledWords) |
|
|
|
hbox_rectype.addWidget(rb1) |
|
|
|
rb1.setChecked(True) |
|
|
|
|
|
|
|
rb2 = QRadioButton(gb_rectype) |
|
|
|
rb2.setText(_('Matrix')) |
|
|
|
bg_rectype.addButton(rb2) |
|
|
|
bg_rectype.setId(rb2, RECOVERY_TYPE_MATRIX) |
|
|
|
bg_rectype.setId(rb2, RecoveryDeviceType.Matrix) |
|
|
|
hbox_rectype.addWidget(rb2) |
|
|
|
|
|
|
|
# no backup |
|
|
@ -293,11 +360,12 @@ class QtPlugin(QtPluginBase): |
|
|
|
wizard.exec_layout(vbox, next_enabled=next_enabled) |
|
|
|
|
|
|
|
return TrezorInitSettings( |
|
|
|
word_count=word_counts[bg_numwords.checkedId()], |
|
|
|
word_count=bg_numwords.checkedId(), |
|
|
|
label=name.text(), |
|
|
|
pin_enabled=cb_pin.isChecked(), |
|
|
|
passphrase_enabled=cb_phrase.isChecked(), |
|
|
|
recovery_type=bg_rectype.checkedId() if bg_rectype else None, |
|
|
|
backup_type=bg_backuptype.checkedId(), |
|
|
|
no_backup=cb_no_backup.isChecked() if cb_no_backup else False, |
|
|
|
) |
|
|
|
|
|
|
|