From 428ba209f4299f277ea792a9a7726f6497dfbee7 Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Tue, 8 Nov 2022 17:43:42 +0100 Subject: [PATCH] qml: multisig wizard; cosigner w. electrum seed --- .../components/wizard/WCCosignerKeystore.qml | 17 +++++++++++- .../qml/components/wizard/WCCosignerSeed.qml | 26 ++++++++++++++----- .../gui/qml/components/wizard/WCHaveSeed.qml | 25 ++++++++++++++---- .../gui/qml/components/wizard/WCMultisig.qml | 1 + electrum/gui/qml/qewizard.py | 24 +++++++++++++++-- electrum/wizard.py | 9 +++++-- 6 files changed, 86 insertions(+), 16 deletions(-) diff --git a/electrum/gui/qml/components/wizard/WCCosignerKeystore.qml b/electrum/gui/qml/components/wizard/WCCosignerKeystore.qml index 0ca30c297..df686819b 100644 --- a/electrum/gui/qml/components/wizard/WCCosignerKeystore.qml +++ b/electrum/gui/qml/components/wizard/WCCosignerKeystore.qml @@ -11,8 +11,12 @@ WizardComponent { valid: keystoregroup.checkedButton !== null + property int cosigner: 0 + property int participants: 0 + function apply() { wizard_data['cosigner_keystore_type'] = keystoregroup.checkedButton.keystoretype + wizard_data['multisig_current_cosigner'] = cosigner } ButtonGroup { @@ -21,7 +25,7 @@ WizardComponent { ColumnLayout { Label { - text: qsTr('Add a cosigner to your multi-sig wallet') + text: qsTr('Add cosigner #%1 of %2 to your multi-sig wallet').arg(cosigner).arg(participants) } RadioButton { ButtonGroup.group: keystoregroup @@ -35,5 +39,16 @@ WizardComponent { text: qsTr('Cosigner seed') } } + + onReadyChanged: { + if (!ready) + return + + participants = wizard_data['multisig_participants'] + + // cosigner index is determined here and put on the wizard_data dict in apply() + // as this page is the start for each additional cosigner + cosigner = 2 + Object.keys(wizard_data['multisig_cosigner_data']).length + } } diff --git a/electrum/gui/qml/components/wizard/WCCosignerSeed.qml b/electrum/gui/qml/components/wizard/WCCosignerSeed.qml index b4c2ac240..9ecfb63e5 100644 --- a/electrum/gui/qml/components/wizard/WCCosignerSeed.qml +++ b/electrum/gui/qml/components/wizard/WCCosignerSeed.qml @@ -6,14 +6,28 @@ import org.electrum 1.0 import "../controls" -WizardComponent { +WCHaveSeed { id: root - valid: false + headingtext: qsTr('Cosigner #%1 of %2').arg(cosigner).arg(participants) - ColumnLayout { - Label { - text: qsTr('TODO: Cosigner seed entry') - } + property int cosigner: 0 + property int participants: 0 + + function apply() { + console.log('apply fn called') + wizard_data['cosigner_seed'] = seed + wizard_data['cosigner_seed_variant'] = seed_variant + wizard_data['cosigner_seed_type'] = seed_type + wizard_data['cosigner_seed_extend'] = seed_extend + wizard_data['cosigner_seed_extra_words'] = seed_extra_words + } + + onReadyChanged: { + if (!ready) + return + + participants = wizard_data['multisig_participants'] + cosigner = wizard_data['multisig_current_cosigner'] } } diff --git a/electrum/gui/qml/components/wizard/WCHaveSeed.qml b/electrum/gui/qml/components/wizard/WCHaveSeed.qml index 2d140f98d..582b5cc31 100644 --- a/electrum/gui/qml/components/wizard/WCHaveSeed.qml +++ b/electrum/gui/qml/components/wizard/WCHaveSeed.qml @@ -5,7 +5,6 @@ import QtQuick.Controls.Material 2.0 import org.electrum 1.0 -import ".." import "../controls" WizardComponent { @@ -14,9 +13,19 @@ WizardComponent { property bool is2fa: false + property string headingtext + + // expose for WCCosignerSeed 'subclass' + property alias seed: seedtext.text + property alias seed_variant: seed_variant_cb.currentValue + property alias seed_type: bitcoin.seed_type + property alias seed_extend: extendcb.checked + property string seed_extra_words: extendcb.checked ? customwordstext.text : '' + function apply() { + console.log('apply fn called (WCHaveSeed)') wizard_data['seed'] = seedtext.text - wizard_data['seed_variant'] = seed_variant.currentValue + wizard_data['seed_variant'] = seed_variant_cb.currentValue wizard_data['seed_type'] = bitcoin.seed_type wizard_data['seed_extend'] = extendcb.checked wizard_data['seed_extra_words'] = extendcb.checked ? customwordstext.text : '' @@ -40,11 +49,11 @@ WizardComponent { qsTr('However, we do not generate SLIP39 seeds.') ].join(' ') } - infotext.text = t[seed_variant.currentValue] + infotext.text = t[seed_variant_cb.currentValue] } function checkValid() { - bitcoin.verify_seed(seedtext.text, seed_variant.currentValue, wizard_data['wallet_type']) + bitcoin.verify_seed(seedtext.text, seed_variant_cb.currentValue, wizard_data['wallet_type']) } Flickable { @@ -58,13 +67,19 @@ WizardComponent { width: parent.width columns: 2 + Label { + Layout.columnSpan: 2 + visible: headingtext + text: headingtext + } + Label { visible: !is2fa text: qsTr('Seed Type') Layout.fillWidth: true } ComboBox { - id: seed_variant + id: seed_variant_cb visible: !is2fa textRole: 'text' diff --git a/electrum/gui/qml/components/wizard/WCMultisig.qml b/electrum/gui/qml/components/wizard/WCMultisig.qml index 6d08c7848..c6aa1a212 100644 --- a/electrum/gui/qml/components/wizard/WCMultisig.qml +++ b/electrum/gui/qml/components/wizard/WCMultisig.qml @@ -90,6 +90,7 @@ WizardComponent { stepSize: 1 from: 1 to: participants + value: signatures onValueChanged: { if (activeFocus) signatures = value diff --git a/electrum/gui/qml/qewizard.py b/electrum/gui/qml/qewizard.py index a1017ecd9..8c7514bf8 100644 --- a/electrum/gui/qml/qewizard.py +++ b/electrum/gui/qml/qewizard.py @@ -49,7 +49,7 @@ class QENewWalletWizard(NewWalletWizard, QEAbstractWizard): QEAbstractWizard.__init__(self, parent) self._daemon = daemon - # attach view names + # attach view names and accept handlers self.navmap_merge({ 'wallet_name': { 'gui': 'WCWalletName' }, 'wallet_type': { 'gui': 'WCWalletType' }, @@ -63,7 +63,12 @@ class QENewWalletWizard(NewWalletWizard, QEAbstractWizard): 'multisig_show_masterpubkey': { 'gui': 'WCShowMasterPubkey' }, 'multisig_cosigner_keystore': { 'gui': 'WCCosignerKeystore' }, 'multisig_cosigner_key': { 'gui': 'WCCosignerKey' }, - 'multisig_cosigner_seed': { 'gui': 'WCCosignerSeed' }, + 'multisig_cosigner_seed': { 'gui': 'WCCosignerSeed', + 'accept': self.accept_cosigner_seed + }, + 'multisig_cosigner_bip39_refine': { 'gui': 'WCBIP39Refine', + 'accept': self.accept_cosigner_bip39refine + }, 'imported': { 'gui': 'WCImport' }, 'wallet_password': { 'gui': 'WCWalletPassword' } }) @@ -81,6 +86,21 @@ class QENewWalletWizard(NewWalletWizard, QEAbstractWizard): def is_single_password(self): return self._daemon.singlePasswordEnabled + def accept_cosigner_seed(self, wizard_data): + self._logger.debug('accept_cosigner_seed') + cosigner = wizard_data['multisig_current_cosigner'] if 'multisig_current_cosigner' in wizard_data else 2 + wizard_data['multisig_cosigner_data'][str(cosigner)] = { + 'seed': wizard_data['cosigner_seed'], + 'seed_variant': wizard_data['cosigner_seed_variant'], + 'seed_type': wizard_data['cosigner_seed_type'], + 'seed_extend': wizard_data['cosigner_seed_extend'], + 'seed_extra_words': wizard_data['cosigner_seed_extra_words'] + } + + def accept_cosigner_bip39refine(self, wizard_data): + pass # TODO + + @pyqtSlot('QJSValue', bool, str) def createStorage(self, js_data, single_password_enabled, single_password): self._logger.info('Creating wallet from wizard data') diff --git a/electrum/wizard.py b/electrum/wizard.py index 73960efa9..1440e8a1e 100644 --- a/electrum/wizard.py +++ b/electrum/wizard.py @@ -173,10 +173,12 @@ class NewWalletWizard(AbstractWizard): 'next': self.on_cosigner_keystore_type }, 'multisig_cosigner_key': { - 'next': 'multisig_cosigner_keystore' # TODO + 'next': lambda d: 'multisig_cosigner_keystore' if self.has_all_cosigner_data(d) else 'wallet_password', + 'last': lambda v,d: self.is_single_password() and self.has_all_cosigner_data(d) }, 'multisig_cosigner_seed': { - 'next': 'multisig_cosigner_keystore' # TODO + 'next': lambda d: 'multisig_cosigner_keystore' if self.has_all_cosigner_data(d) else 'wallet_password', + 'last': lambda v,d: self.is_single_password() and self.has_all_cosigner_data(d) }, 'imported': { 'next': 'wallet_password', @@ -234,6 +236,9 @@ class NewWalletWizard(AbstractWizard): 'seed': 'multisig_cosigner_seed' }.get(t) + def has_all_cosigner_data(self, wizard_data): + return len(wizard_data['multisig_cosigner_data']) < (wizard_data['multisig_participants'] - 1) + def finished(self, wizard_data): self._logger.debug('finished') # override