Browse Source

wizard: make wizard.keystore_from_data more robust;

- always store 'keystore_type' in cosigner data and use same types as main
- dont share 'hardware_device' in root of dict, but store for each cosigner
- properly return hardware keystore for hardware cosigners
master
Sander van Grieken 2 years ago
parent
commit
2caa8f13cf
  1. 8
      electrum/gui/qml/components/wizard/WCCosignerKeystore.qml
  2. 28
      electrum/gui/qt/wizard/wallet.py
  3. 10
      electrum/wizard.py

8
electrum/gui/qml/components/wizard/WCCosignerKeystore.qml

@ -19,7 +19,9 @@ WizardComponent {
function apply() {
wizard_data['cosigner_keystore_type'] = keystoregroup.checkedButton.keystoretype
wizard_data['multisig_current_cosigner'] = cosigner
wizard_data['multisig_cosigner_data'][cosigner.toString()] = {}
wizard_data['multisig_cosigner_data'][cosigner.toString()] = {
'keystore_type': keystoregroup.checkedButton.keystoretype
}
}
ButtonGroup {
@ -80,13 +82,13 @@ WizardComponent {
}
ElRadioButton {
ButtonGroup.group: keystoregroup
property string keystoretype: 'key'
property string keystoretype: 'masterkey'
checked: true
text: qsTr('Cosigner key')
}
ElRadioButton {
ButtonGroup.group: keystoregroup
property string keystoretype: 'seed'
property string keystoretype: 'haveseed'
text: qsTr('Cosigner seed')
}
}

28
electrum/gui/qt/wizard/wallet.py

@ -769,8 +769,8 @@ class WCCosignerKeystore(WizardComponent):
message = _('Add a cosigner to your multi-sig wallet')
choices = [
('key', _('Enter cosigner key')),
('seed', _('Enter cosigner seed')),
('masterkey', _('Enter cosigner key')),
('haveseed', _('Enter cosigner seed')),
('hardware', _('Cosign with hardware device'))
]
@ -806,7 +806,9 @@ class WCCosignerKeystore(WizardComponent):
def apply(self):
self.wizard_data['cosigner_keystore_type'] = self.choice_w.selected_item[0]
self.wizard_data['multisig_current_cosigner'] = self.cosigner
self.wizard_data['multisig_cosigner_data'][str(self.cosigner)] = {}
self.wizard_data['multisig_cosigner_data'][str(self.cosigner)] = {
'keystore_type': self.choice_w.selected_item[0]
}
class WCHaveMasterKey(WizardComponent):
@ -1214,8 +1216,8 @@ class WCChooseHWDevice(WizardComponent, Logger):
def apply(self):
if self.choice_w:
# TODO: data is not (de)serializable yet, wizard_data cannot be persisted
self.wizard_data['hardware_device'] = self.choice_w.selected_item[0]
cosigner_data = self.wizard.current_cosigner(self.wizard_data)
cosigner_data['hardware_device'] = self.choice_w.selected_item[0]
class WCWalletPasswordHardware(WizardComponent):
@ -1307,7 +1309,8 @@ class WCHWXPub(WizardComponent, Logger):
self.layout().addWidget(self.ok_l)
def on_ready(self):
_name, _info = self.wizard_data['hardware_device']
cosigner_data = self.wizard.current_cosigner(self.wizard_data)
_name, _info = cosigner_data['hardware_device']
self.plugin = self.plugins.get_plugin(_info.plugin_name)
self.title = _('Retrieving extended public key from {} ({})').format(_info.model_name, _info.label)
@ -1316,9 +1319,8 @@ class WCHWXPub(WizardComponent, Logger):
if not client.handler:
client.handler = self.plugin.create_handler(self.wizard)
cosigner = self.wizard.current_cosigner(self.wizard_data)
xtype = cosigner['script_type']
derivation = cosigner['derivation_path']
xtype = cosigner_data['script_type']
derivation = cosigner_data['derivation_path']
def get_xpub_task(client, derivation, xtype):
try:
@ -1340,7 +1342,8 @@ class WCHWXPub(WizardComponent, Logger):
t.start()
def get_xpub_from_client(self, client, derivation, xtype): # override for HWW specific client if needed
_name, _info = self.wizard_data['hardware_device']
cosigner_data = self.wizard.current_cosigner(self.wizard_data)
_name, _info = cosigner_data['hardware_device']
if xtype not in self.plugin.SUPPORTED_XTYPES:
raise ScriptTypeNotSupported(_('This type of script is not supported with {}').format(_info.model_name))
return client.get_xpub(derivation, xtype)
@ -1362,8 +1365,8 @@ class WCHWXPub(WizardComponent, Logger):
self.wizard.requestNext.emit() # via signal, so it triggers Next/Finish on GUI thread after on_updated()
def apply(self):
_name, _info = self.wizard_data['hardware_device']
cosigner_data = self.wizard.current_cosigner(self.wizard_data)
_name, _info = cosigner_data['hardware_device']
cosigner_data['hw_type'] = _info.plugin_name
cosigner_data['master_key'] = self.xpub
cosigner_data['root_fingerprint'] = self.root_fingerprint
@ -1376,7 +1379,8 @@ class WCHWUninitialized(WizardComponent):
WizardComponent.__init__(self, parent, wizard, title=_('Hardware not initialized'))
def on_ready(self):
_name, _info = self.wizard_data['hardware_device']
cosigner_data = self.wizard.current_cosigner(self.wizard_data)
_name, _info = cosigner_data['hardware_device']
label = WWLabel(_('This {} is not initialized. Use manufacturer tooling to initialize the device.').format(_info.model_name))
label.setAlignment(Qt.AlignCenter)
self.layout().addWidget(label)

10
electrum/wizard.py

@ -338,8 +338,8 @@ class NewWalletWizard(AbstractWizard):
def on_cosigner_keystore_type(self, wizard_data: dict) -> str:
t = wizard_data['cosigner_keystore_type']
return {
'key': 'multisig_cosigner_key',
'seed': 'multisig_cosigner_seed',
'masterkey': 'multisig_cosigner_key',
'haveseed': 'multisig_cosigner_seed',
'hardware': 'multisig_cosigner_hardware'
}.get(t)
@ -396,7 +396,7 @@ class NewWalletWizard(AbstractWizard):
return False
def keystore_from_data(self, wallet_type: str, data: dict):
if 'seed' in data:
if data['keystore_type'] in ['createseed', 'haveseed'] and 'seed' in data:
if data['seed_variant'] == 'electrum':
return keystore.from_seed(data['seed'], data['seed_extra_words'], True)
elif data['seed_variant'] == 'bip39':
@ -417,8 +417,10 @@ class NewWalletWizard(AbstractWizard):
return keystore.from_bip43_rootseed(root_seed, derivation, xtype=script)
else:
raise Exception('Unsupported seed variant %s' % data['seed_variant'])
elif 'master_key' in data:
elif data['keystore_type'] == 'masterkey' and 'master_key' in data:
return keystore.from_master_key(data['master_key'])
elif data['keystore_type'] == 'hardware':
return self.hw_keystore(data)
else:
raise Exception('no seed or master_key in data')

Loading…
Cancel
Save