qt: refactor SeedLayout/KeysLayout to SeedWidget/KeysWidget, remove the hacks left over from old to new wizard and
update validation in all cases (e.g. validate electrum seed when switching from bip39 to electrum in options dialog)
This commit is contained in:
@@ -69,66 +69,10 @@ def seed_warning_msg(seed):
|
||||
]).format(len(seed.split()))
|
||||
|
||||
|
||||
class SeedLayout(QVBoxLayout):
|
||||
class SeedWidget(QWidget):
|
||||
|
||||
updated = pyqtSignal()
|
||||
|
||||
def seed_options(self):
|
||||
dialog = QDialog()
|
||||
dialog.setWindowTitle(_("Seed Options"))
|
||||
vbox = QVBoxLayout(dialog)
|
||||
|
||||
seed_types = [
|
||||
(value, title) for value, title in (
|
||||
('electrum', _('Electrum')),
|
||||
('bip39', _('BIP39 seed')),
|
||||
('slip39', _('SLIP39 seed')),
|
||||
)
|
||||
if value in self.options or value == 'electrum'
|
||||
]
|
||||
|
||||
if 'ext' in self.options:
|
||||
cb_ext = QCheckBox(_('Extend this seed with custom words'))
|
||||
cb_ext.setChecked(self.is_ext)
|
||||
vbox.addWidget(cb_ext)
|
||||
|
||||
if len(seed_types) >= 2:
|
||||
def on_selected(idx):
|
||||
self.seed_type = seed_type_choice.selected_key
|
||||
self.is_seed = (lambda x: bool(x)) if self.seed_type != 'electrum' else self.saved_is_seed
|
||||
self.slip39_current_mnemonic_invalid = None
|
||||
self.seed_status.setText('')
|
||||
self.on_edit()
|
||||
if self.seed_type == 'bip39':
|
||||
msg = ' '.join([
|
||||
'<b>' + _('Warning') + ':</b> ',
|
||||
_('BIP39 seeds can be imported in Electrum, so that users can access funds locked in other wallets.'),
|
||||
_('However, we do not generate BIP39 seeds, because they do not meet our safety standard.'),
|
||||
_('BIP39 seeds do not include a version number, which compromises compatibility with future software.'),
|
||||
_('We do not guarantee that BIP39 imports will always be supported in Electrum.'),
|
||||
])
|
||||
elif self.seed_type == 'slip39':
|
||||
msg = ' '.join([
|
||||
'<b>' + _('Warning') + ':</b> ',
|
||||
_('SLIP39 seeds can be imported in Electrum, so that users can access funds locked in other wallets.'),
|
||||
_('However, we do not generate SLIP39 seeds.'),
|
||||
])
|
||||
else:
|
||||
msg = ''
|
||||
self.update_share_buttons()
|
||||
self.initialize_completer()
|
||||
self.seed_warning.setText(msg)
|
||||
|
||||
seed_type_choice = ChoiceWidget(message=_('Seed type'), choices=seed_types, selected=self.seed_type)
|
||||
seed_type_choice.itemSelected.connect(on_selected)
|
||||
vbox.addWidget(seed_type_choice)
|
||||
|
||||
vbox.addLayout(Buttons(OkButton(dialog)))
|
||||
if not dialog.exec():
|
||||
return None
|
||||
self.is_ext = cb_ext.isChecked() if 'ext' in self.options else False
|
||||
self.seed_type = seed_type_choice.selected_key if len(seed_types) >= 2 else 'electrum'
|
||||
self.updated.emit()
|
||||
validChanged = pyqtSignal([bool], arguments=['valid'])
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -137,20 +81,38 @@ class SeedLayout(QVBoxLayout):
|
||||
icon=True,
|
||||
msg=None,
|
||||
options=None,
|
||||
is_seed=None,
|
||||
is_seed=None, # only used for electrum seeds
|
||||
passphrase=None,
|
||||
parent=None,
|
||||
for_seed_words=True,
|
||||
*,
|
||||
config: 'SimpleConfig',
|
||||
):
|
||||
QVBoxLayout.__init__(self)
|
||||
self.parent = parent
|
||||
QWidget.__init__(self, parent)
|
||||
vbox = QVBoxLayout()
|
||||
self.setLayout(vbox)
|
||||
|
||||
self.options = options
|
||||
self.config = config
|
||||
self.seed_type = 'electrum'
|
||||
|
||||
if options:
|
||||
self.seed_types = [
|
||||
(value, title) for value, title in (
|
||||
('electrum', _('Electrum')),
|
||||
('bip39', _('BIP39 seed')),
|
||||
('slip39', _('SLIP39 seed')),
|
||||
)
|
||||
if value in self.options
|
||||
]
|
||||
assert len(self.seed_types)
|
||||
self.seed_type = self.seed_types[0][0]
|
||||
else:
|
||||
self.seed_type = 'electrum'
|
||||
|
||||
self.is_seed = is_seed
|
||||
|
||||
if title:
|
||||
self.addWidget(WWLabel(title))
|
||||
vbox.addWidget(WWLabel(title))
|
||||
if seed: # "read only", we already have the text
|
||||
if for_seed_words:
|
||||
self.seed_e = ButtonsTextEdit()
|
||||
@@ -162,8 +124,6 @@ class SeedLayout(QVBoxLayout):
|
||||
assert for_seed_words
|
||||
self.seed_e = CompletionTextEdit()
|
||||
self.seed_e.setTabChangesFocus(False) # so that tab auto-completes
|
||||
self.is_seed = is_seed
|
||||
self.saved_is_seed = self.is_seed
|
||||
self.seed_e.textChanged.connect(self.on_edit)
|
||||
self.initialize_completer()
|
||||
|
||||
@@ -176,7 +136,7 @@ class SeedLayout(QVBoxLayout):
|
||||
logo.setMaximumWidth(60)
|
||||
hbox.addWidget(logo)
|
||||
hbox.addWidget(self.seed_e)
|
||||
self.addLayout(hbox)
|
||||
vbox.addLayout(hbox)
|
||||
hbox = QHBoxLayout()
|
||||
hbox.addStretch(1)
|
||||
self.seed_type_label = QLabel('')
|
||||
@@ -187,7 +147,7 @@ class SeedLayout(QVBoxLayout):
|
||||
if options:
|
||||
opt_button = EnterButton(_('Options'), self.seed_options)
|
||||
hbox.addWidget(opt_button)
|
||||
self.addLayout(hbox)
|
||||
vbox.addLayout(hbox)
|
||||
if passphrase:
|
||||
hbox = QHBoxLayout()
|
||||
passphrase_e = QLineEdit()
|
||||
@@ -195,7 +155,7 @@ class SeedLayout(QVBoxLayout):
|
||||
passphrase_e.setReadOnly(True)
|
||||
hbox.addWidget(QLabel(_("Your seed extension is") + ':'))
|
||||
hbox.addWidget(passphrase_e)
|
||||
self.addLayout(hbox)
|
||||
vbox.addLayout(hbox)
|
||||
|
||||
# slip39 shares
|
||||
self.slip39_mnemonic_index = 0
|
||||
@@ -211,15 +171,75 @@ class SeedLayout(QVBoxLayout):
|
||||
self.next_share_btn.clicked.connect(self.on_next_share)
|
||||
hbox.addWidget(self.next_share_btn)
|
||||
self.update_share_buttons()
|
||||
self.addLayout(hbox)
|
||||
vbox.addLayout(hbox)
|
||||
|
||||
self.addStretch(1)
|
||||
vbox.addStretch(1)
|
||||
self.seed_status = WWLabel('')
|
||||
self.addWidget(self.seed_status)
|
||||
vbox.addWidget(self.seed_status)
|
||||
self.seed_warning = WWLabel('')
|
||||
if msg:
|
||||
self.seed_warning.setText(seed_warning_msg(seed))
|
||||
self.addWidget(self.seed_warning)
|
||||
else:
|
||||
self.update_seed_warning()
|
||||
|
||||
vbox.addWidget(self.seed_warning)
|
||||
|
||||
def seed_options(self):
|
||||
dialog = QDialog()
|
||||
dialog.setWindowTitle(_("Seed Options"))
|
||||
vbox = QVBoxLayout(dialog)
|
||||
|
||||
if 'ext' in self.options:
|
||||
cb_ext = QCheckBox(_('Extend this seed with custom words'))
|
||||
cb_ext.setChecked(self.is_ext)
|
||||
vbox.addWidget(cb_ext)
|
||||
|
||||
def on_selected(idx):
|
||||
self.seed_type = seed_type_choice.selected_key
|
||||
self.slip39_current_mnemonic_invalid = None
|
||||
self.seed_status.setText('')
|
||||
self.update_seed_warning()
|
||||
self.on_edit()
|
||||
self.update_share_buttons()
|
||||
self.initialize_completer()
|
||||
|
||||
if len(self.seed_types) > 1:
|
||||
seed_type_choice = ChoiceWidget(message=_('Seed type'), choices=self.seed_types, selected=self.seed_type)
|
||||
seed_type_choice.itemSelected.connect(on_selected)
|
||||
vbox.addWidget(seed_type_choice)
|
||||
|
||||
vbox.addLayout(Buttons(OkButton(dialog)))
|
||||
|
||||
if not dialog.exec():
|
||||
return None
|
||||
|
||||
if 'ext' in self.options:
|
||||
self.is_ext = cb_ext.isChecked()
|
||||
if len(self.seed_types) > 1:
|
||||
self.seed_type = seed_type_choice.selected_key
|
||||
|
||||
self.update_seed_warning()
|
||||
self.updated.emit()
|
||||
|
||||
def update_seed_warning(self):
|
||||
if self.seed_type == 'bip39':
|
||||
msg = ' '.join([
|
||||
'<b>' + _('Warning') + ':</b> ',
|
||||
_('BIP39 seeds can be imported in Electrum, so that users can access funds locked in other wallets.'),
|
||||
_('However, we do not generate BIP39 seeds, because they do not meet our safety standard.'),
|
||||
_('BIP39 seeds do not include a version number, which compromises compatibility with future software.'),
|
||||
_('We do not guarantee that BIP39 imports will always be supported in Electrum.'),
|
||||
])
|
||||
elif self.seed_type == 'slip39':
|
||||
msg = ' '.join([
|
||||
'<b>' + _('Warning') + ':</b> ',
|
||||
_('SLIP39 seeds can be imported in Electrum, so that users can access funds locked in other wallets.'),
|
||||
_('However, we do not generate SLIP39 seeds.'),
|
||||
])
|
||||
else:
|
||||
msg = ''
|
||||
|
||||
self.seed_warning.setText(msg)
|
||||
|
||||
def initialize_completer(self):
|
||||
if self.seed_type != 'slip39':
|
||||
@@ -261,12 +281,12 @@ class SeedLayout(QVBoxLayout):
|
||||
|
||||
def on_edit(self):
|
||||
s = ' '.join(self.get_seed_words())
|
||||
b = self.is_seed(s)
|
||||
if self.seed_type == 'bip39':
|
||||
from electrum.keystore import bip39_is_checksum_valid
|
||||
is_checksum, is_wordlist = bip39_is_checksum_valid(s)
|
||||
label = ''
|
||||
if bool(s):
|
||||
valid = bool(s)
|
||||
if valid:
|
||||
label = ('' if is_checksum else _('BIP39 checksum failed')) if is_wordlist else _('Unknown BIP39 wordlist')
|
||||
elif self.seed_type == 'slip39':
|
||||
self.slip39_mnemonics[self.slip39_mnemonic_index] = s
|
||||
@@ -287,15 +307,13 @@ class SeedLayout(QVBoxLayout):
|
||||
self.seed_status.setText(seed_status)
|
||||
self.slip39_current_mnemonic_invalid = current_mnemonic_invalid
|
||||
|
||||
b = self.slip39_seed is not None
|
||||
valid = self.slip39_seed is not None
|
||||
self.update_share_buttons()
|
||||
else:
|
||||
valid = self.is_seed(s)
|
||||
t = calc_seed_type(s)
|
||||
label = _('Seed Type') + ': ' + t if t else ''
|
||||
if t and not b: # electrum seed, but does not conform to dialog rules
|
||||
# FIXME we should just accept any electrum seed and "redirect" the wizard automatically.
|
||||
# i.e. if user selected wallet_type=="standard" but entered a 2fa seed, accept and redirect
|
||||
# if user selected wallet_type=="2fa" but entered a std electrum seed, accept and redirect
|
||||
if t and not valid: # electrum seed, but does not conform to dialog rules
|
||||
wiztype_fullname = _('Wallet with two-factor authentication') if is_any_2fa_seed_type(t) else _("Standard wallet")
|
||||
msg = ' '.join([
|
||||
'<b>' + _('Warning') + ':</b> ',
|
||||
@@ -307,7 +325,7 @@ class SeedLayout(QVBoxLayout):
|
||||
self.seed_warning.setText("")
|
||||
|
||||
self.seed_type_label.setText(label)
|
||||
self.parent.next_button.setEnabled(b)
|
||||
self.validChanged.emit(valid)
|
||||
|
||||
# disable suggestions if user already typed an unknown word
|
||||
for word in self.get_seed_words()[:-1]:
|
||||
@@ -354,7 +372,10 @@ class SeedLayout(QVBoxLayout):
|
||||
self.slip39_current_mnemonic_invalid = None
|
||||
|
||||
|
||||
class KeysLayout(QVBoxLayout):
|
||||
class KeysWidget(QWidget):
|
||||
|
||||
validChanged = pyqtSignal([bool], arguments=['valid'])
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
parent=None,
|
||||
@@ -364,29 +385,28 @@ class KeysLayout(QVBoxLayout):
|
||||
*,
|
||||
config: 'SimpleConfig',
|
||||
):
|
||||
QVBoxLayout.__init__(self)
|
||||
self.parent = parent
|
||||
QWidget.__init__(self, parent)
|
||||
vbox = QVBoxLayout()
|
||||
self.setLayout(vbox)
|
||||
|
||||
self.is_valid = is_valid
|
||||
self.text_e = ScanQRTextEdit(allow_multi=allow_multi, config=config)
|
||||
self.text_e.textChanged.connect(self.on_edit)
|
||||
if isinstance(header_layout, str):
|
||||
self.addWidget(WWLabel(header_layout))
|
||||
vbox.addWidget(WWLabel(header_layout))
|
||||
else:
|
||||
self.addLayout(header_layout)
|
||||
self.addWidget(self.text_e)
|
||||
vbox.addLayout(header_layout)
|
||||
vbox.addWidget(self.text_e)
|
||||
|
||||
def get_text(self):
|
||||
return self.text_e.text()
|
||||
|
||||
def on_edit(self):
|
||||
valid = False
|
||||
try:
|
||||
valid = self.is_valid(self.get_text())
|
||||
except Exception as e:
|
||||
self.parent.next_button.setToolTip(f'{_("Error")}: {str(e)}')
|
||||
else:
|
||||
self.parent.next_button.setToolTip('')
|
||||
self.parent.next_button.setEnabled(valid)
|
||||
valid = False
|
||||
self.validChanged.emit(valid)
|
||||
|
||||
|
||||
class SeedDialog(WindowModalDialog):
|
||||
@@ -395,13 +415,7 @@ class SeedDialog(WindowModalDialog):
|
||||
WindowModalDialog.__init__(self, parent, ('Electrum - ' + _('Seed')))
|
||||
self.setMinimumWidth(400)
|
||||
vbox = QVBoxLayout(self)
|
||||
title = _("Your wallet generation seed is:")
|
||||
slayout = SeedLayout(
|
||||
title=title,
|
||||
seed=seed,
|
||||
msg=True,
|
||||
passphrase=passphrase,
|
||||
config=config,
|
||||
)
|
||||
vbox.addLayout(slayout)
|
||||
title = _("Your wallet generation seed is:")
|
||||
seed_widget = SeedWidget(title=title, seed=seed, msg=True, passphrase=passphrase, config=config)
|
||||
vbox.addWidget(seed_widget)
|
||||
vbox.addLayout(Buttons(CloseButton(self)))
|
||||
|
||||
@@ -27,10 +27,9 @@ from electrum.wizard import NewWalletWizard
|
||||
|
||||
from electrum.gui.qt.bip39_recovery_dialog import Bip39RecoveryDialog
|
||||
from electrum.gui.qt.password_dialog import PasswordLayout, PW_NEW, MSG_ENTER_PASSWORD, PasswordLayoutForHW
|
||||
from electrum.gui.qt.seed_dialog import SeedLayout, MSG_PASSPHRASE_WARN_ISSUE4566, KeysLayout
|
||||
from electrum.gui.qt.seed_dialog import SeedWidget, MSG_PASSPHRASE_WARN_ISSUE4566, KeysWidget
|
||||
from electrum.gui.qt.util import (PasswordLineEdit, char_width_in_lineedit, WWLabel, InfoButton, font_height,
|
||||
ChoiceWidget, MessageBoxMixin, WindowModalDialog, CancelButton,
|
||||
Buttons, OkButton, icon_path)
|
||||
ChoiceWidget, MessageBoxMixin, icon_path)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from electrum.simple_config import SimpleConfig
|
||||
@@ -437,7 +436,7 @@ class WCCreateSeed(WalletWizardComponent):
|
||||
WalletWizardComponent.__init__(self, parent, wizard, title=_('Wallet Seed'))
|
||||
self._busy = True
|
||||
self.seed_type = 'standard' if self.wizard.config.WIZARD_DONT_CREATE_SEGWIT else 'segwit'
|
||||
self.slayout = None
|
||||
self.seed_widget = None
|
||||
self.seed = None
|
||||
|
||||
def on_ready(self):
|
||||
@@ -446,10 +445,10 @@ class WCCreateSeed(WalletWizardComponent):
|
||||
QTimer.singleShot(1, self.create_seed)
|
||||
|
||||
def apply(self):
|
||||
if self.slayout:
|
||||
if self.seed_widget:
|
||||
self.wizard_data['seed'] = self.seed
|
||||
self.wizard_data['seed_type'] = self.seed_type
|
||||
self.wizard_data['seed_extend'] = self.slayout.is_ext
|
||||
self.wizard_data['seed_extend'] = self.seed_widget.is_ext
|
||||
self.wizard_data['seed_variant'] = 'electrum'
|
||||
self.wizard_data['seed_extra_words'] = '' # empty default
|
||||
|
||||
@@ -457,15 +456,15 @@ class WCCreateSeed(WalletWizardComponent):
|
||||
self.busy = True
|
||||
self.seed = mnemonic.Mnemonic('en').make_seed(seed_type=self.seed_type)
|
||||
|
||||
self.slayout = SeedLayout(
|
||||
self.seed_widget = SeedWidget(
|
||||
title=_('Your wallet generation seed is:'),
|
||||
seed=self.seed,
|
||||
options=['ext'],
|
||||
options=['ext', 'electrum'],
|
||||
msg=True,
|
||||
parent=self,
|
||||
config=self.wizard.config,
|
||||
)
|
||||
self.layout().addLayout(self.slayout)
|
||||
self.layout().addWidget(self.seed_widget)
|
||||
self.layout().addStretch(1)
|
||||
self.busy = False
|
||||
self.valid = True
|
||||
@@ -482,19 +481,16 @@ class WCConfirmSeed(WalletWizardComponent):
|
||||
|
||||
self.layout().addWidget(WWLabel(message))
|
||||
|
||||
# TODO: SeedLayout assumes too much in parent, refactor SeedLayout
|
||||
# for now, fake parent.next_button.setEnabled
|
||||
class Hack:
|
||||
def setEnabled(self2, b):
|
||||
self.valid = b
|
||||
self.next_button = Hack()
|
||||
|
||||
self.slayout = SeedLayout(
|
||||
self.seed_widget = SeedWidget(
|
||||
is_seed=lambda x: x == self.wizard_data['seed'],
|
||||
parent=self,
|
||||
config=self.wizard.config,
|
||||
)
|
||||
self.layout().addLayout(self.slayout)
|
||||
|
||||
def seed_valid_changed(valid):
|
||||
self.valid = valid
|
||||
|
||||
self.seed_widget.validChanged.connect(seed_valid_changed)
|
||||
self.layout().addWidget(self.seed_widget)
|
||||
|
||||
wizard.app.clipboard().clear()
|
||||
|
||||
@@ -583,37 +579,39 @@ class WCHaveSeed(WalletWizardComponent, Logger):
|
||||
WalletWizardComponent.__init__(self, parent, wizard, title=_('Enter Seed'))
|
||||
Logger.__init__(self)
|
||||
|
||||
self.slayout = None
|
||||
|
||||
self.layout().addWidget(WWLabel(_('Please enter your seed phrase in order to restore your wallet.')))
|
||||
|
||||
# TODO: SeedLayout assumes too much in parent, refactor SeedLayout
|
||||
# for now, fake parent.next_button.setEnabled
|
||||
class Hack:
|
||||
def setEnabled(self2, b):
|
||||
if not b:
|
||||
self.valid = b
|
||||
else:
|
||||
self.validate()
|
||||
|
||||
self.next_button = Hack()
|
||||
|
||||
self.seed_widget = None
|
||||
self.can_passphrase = True
|
||||
|
||||
def on_ready(self):
|
||||
options = ['ext'] if self.wizard_data['wallet_type'] == '2fa' else ['ext', 'bip39', 'slip39']
|
||||
self.slayout = SeedLayout(
|
||||
options = ['ext', 'electrum', 'bip39', 'slip39']
|
||||
if self.wizard_data['wallet_type'] == '2fa':
|
||||
options = ['ext', 'electrum']
|
||||
else:
|
||||
if self.params and 'seed_options' in self.params:
|
||||
options = self.params['seed_options']
|
||||
|
||||
self.seed_widget = SeedWidget(
|
||||
is_seed=self.is_seed,
|
||||
options=options,
|
||||
parent=self,
|
||||
config=self.wizard.config,
|
||||
)
|
||||
self.slayout.updated.connect(self.validate)
|
||||
|
||||
self.layout().addLayout(self.slayout)
|
||||
def seed_valid_changed(valid):
|
||||
if not valid:
|
||||
self.valid = valid
|
||||
else:
|
||||
self.validate()
|
||||
|
||||
self.seed_widget.validChanged.connect(seed_valid_changed)
|
||||
self.seed_widget.updated.connect(self.validate)
|
||||
|
||||
self.layout().addWidget(self.seed_widget)
|
||||
self.layout().addStretch(1)
|
||||
|
||||
def is_seed(self, x):
|
||||
# really only used for electrum seeds. bip39 and slip39 are validated in SeedWidget
|
||||
t = mnemonic.calc_seed_type(x)
|
||||
if self.wizard_data['wallet_type'] == 'standard':
|
||||
return mnemonic.is_seed(x) and not mnemonic.is_any_2fa_seed_type(t)
|
||||
@@ -624,9 +622,9 @@ class WCHaveSeed(WalletWizardComponent, Logger):
|
||||
return t in ['standard', 'segwit']
|
||||
|
||||
def validate(self):
|
||||
# precond: only call when SeedLayout deems seed a valid seed
|
||||
seed = self.slayout.get_seed()
|
||||
seed_variant = self.slayout.seed_type
|
||||
# precond: only call when SeedWidget deems seed a valid seed
|
||||
seed = self.seed_widget.get_seed()
|
||||
seed_variant = self.seed_widget.seed_type
|
||||
wallet_type = self.wizard_data['wallet_type']
|
||||
seed_valid, seed_type, validation_message, self.can_passphrase = self.wizard.validate_seed(seed, seed_variant, wallet_type)
|
||||
|
||||
@@ -646,13 +644,13 @@ class WCHaveSeed(WalletWizardComponent, Logger):
|
||||
def apply(self):
|
||||
cosigner_data = self.wizard.current_cosigner(self.wizard_data)
|
||||
|
||||
cosigner_data['seed'] = self.slayout.get_seed()
|
||||
cosigner_data['seed_variant'] = self.slayout.seed_type
|
||||
if self.slayout.seed_type == 'electrum':
|
||||
cosigner_data['seed_type'] = mnemonic.calc_seed_type(self.slayout.get_seed())
|
||||
cosigner_data['seed'] = self.seed_widget.get_seed()
|
||||
cosigner_data['seed_variant'] = self.seed_widget.seed_type
|
||||
if self.seed_widget.seed_type == 'electrum':
|
||||
cosigner_data['seed_type'] = mnemonic.calc_seed_type(self.seed_widget.get_seed())
|
||||
else:
|
||||
cosigner_data['seed_type'] = self.slayout.seed_type
|
||||
cosigner_data['seed_extend'] = self.slayout.is_ext if self.can_passphrase else False
|
||||
cosigner_data['seed_type'] = self.seed_widget.seed_type
|
||||
cosigner_data['seed_extend'] = self.seed_widget.is_ext if self.can_passphrase else False
|
||||
cosigner_data['seed_extra_words'] = '' # empty default
|
||||
|
||||
|
||||
@@ -790,13 +788,13 @@ class WCCosignerKeystore(WalletWizardComponent):
|
||||
# different from old wizard: master public key for sharing is now shown on this page
|
||||
self.layout().addSpacing(20)
|
||||
self.layout().addWidget(WWLabel(_('Below is your master public key. Please share it with your cosigners')))
|
||||
slayout = SeedLayout(
|
||||
seed_widget = SeedWidget(
|
||||
self.wizard_data['multisig_master_pubkey'],
|
||||
icon=False,
|
||||
for_seed_words=False,
|
||||
config=self.wizard.config,
|
||||
)
|
||||
self.layout().addLayout(slayout)
|
||||
self.layout().addWidget(seed_widget)
|
||||
self.layout().addStretch(1)
|
||||
|
||||
def apply(self):
|
||||
@@ -811,7 +809,7 @@ class WCHaveMasterKey(WalletWizardComponent):
|
||||
def __init__(self, parent, wizard):
|
||||
WalletWizardComponent.__init__(self, parent, wizard, title=_('Create keystore from a master key'))
|
||||
|
||||
self.slayout = None
|
||||
self.keys_widget = None
|
||||
|
||||
self.message_create = ' '.join([
|
||||
_("To create a watching-only wallet, please enter your master public key (xpub/ypub/zpub)."),
|
||||
@@ -827,16 +825,6 @@ class WCHaveMasterKey(WalletWizardComponent):
|
||||
self.label.setMinimumWidth(400)
|
||||
self.header_layout.addWidget(self.label)
|
||||
|
||||
# TODO: KeysLayout assumes too much in parent, refactor KeysLayout
|
||||
# for now, fake parent.next_button.setEnabled
|
||||
class Hack:
|
||||
def setEnabled(self2, b):
|
||||
self.valid = b
|
||||
|
||||
def setToolTip(self2, b):
|
||||
pass
|
||||
self.next_button = Hack()
|
||||
|
||||
def on_ready(self):
|
||||
if self.wizard_data['wallet_type'] == 'standard':
|
||||
self.label.setText(self.message_create)
|
||||
@@ -860,12 +848,19 @@ class WCHaveMasterKey(WalletWizardComponent):
|
||||
return True
|
||||
else:
|
||||
raise Exception(f"unexpected wallet type: {self.wizard_data['wallet_type']}")
|
||||
self.slayout = KeysLayout(parent=self, header_layout=self.header_layout, is_valid=is_valid,
|
||||
allow_multi=False, config=self.wizard.config)
|
||||
self.layout().addLayout(self.slayout)
|
||||
|
||||
self.keys_widget = KeysWidget(parent=self, header_layout=self.header_layout, is_valid=is_valid,
|
||||
allow_multi=False, config=self.wizard.config)
|
||||
|
||||
def key_valid_changed(valid):
|
||||
self.valid = valid
|
||||
|
||||
self.keys_widget.validChanged.connect(key_valid_changed)
|
||||
|
||||
self.layout().addWidget(self.keys_widget)
|
||||
|
||||
def apply(self):
|
||||
text = self.slayout.get_text()
|
||||
text = self.keys_widget.get_text()
|
||||
cosigner_data = self.wizard.current_cosigner(self.wizard_data)
|
||||
cosigner_data['master_key'] = text
|
||||
|
||||
@@ -942,25 +937,20 @@ class WCImport(WalletWizardComponent):
|
||||
header_layout.addWidget(label)
|
||||
header_layout.addWidget(InfoButton(WIF_HELP_TEXT), alignment=Qt.AlignmentFlag.AlignRight)
|
||||
|
||||
# TODO: KeysLayout assumes too much in parent, refactor KeysLayout
|
||||
# for now, fake parent.next_button.setEnabled
|
||||
class Hack:
|
||||
def setEnabled(self2, b):
|
||||
self.valid = b
|
||||
|
||||
def setToolTip(self2, b):
|
||||
pass
|
||||
self.next_button = Hack()
|
||||
|
||||
def is_valid(x) -> bool:
|
||||
return keystore.is_address_list(x) or keystore.is_private_key_list(x, raise_on_error=True)
|
||||
|
||||
self.slayout = KeysLayout(parent=self, header_layout=header_layout, is_valid=is_valid,
|
||||
allow_multi=True, config=self.wizard.config)
|
||||
self.layout().addLayout(self.slayout)
|
||||
self.keys_widget = KeysWidget(header_layout=header_layout, is_valid=is_valid,
|
||||
allow_multi=True, config=self.wizard.config)
|
||||
|
||||
def key_valid_changed(valid):
|
||||
self.valid = valid
|
||||
|
||||
self.keys_widget.validChanged.connect(key_valid_changed)
|
||||
self.layout().addWidget(self.keys_widget)
|
||||
|
||||
def apply(self):
|
||||
text = self.slayout.get_text()
|
||||
text = self.keys_widget.get_text()
|
||||
if keystore.is_address_list(text):
|
||||
self.wizard_data['address_list'] = text
|
||||
elif keystore.is_private_key_list(text):
|
||||
|
||||
Reference in New Issue
Block a user