From fac4003354bcbbfdeba027a50279d03177d1738a Mon Sep 17 00:00:00 2001 From: Sander van Grieken Date: Mon, 24 Oct 2022 12:42:45 +0200 Subject: [PATCH] qml: fix wizard_data not available to 'last' check on have seed wizard page also refactor seed verification, split off seed_variant from seed_type (partial disambiguation), fix bip39 wallet creation --- .../qml/components/wizard/WCBIP39Refine.qml | 4 +-- .../gui/qml/components/wizard/WCHaveSeed.qml | 29 ++++++++++--------- electrum/gui/qml/qebitcoin.py | 22 ++++++-------- electrum/wizard.py | 2 +- 4 files changed, 28 insertions(+), 29 deletions(-) diff --git a/electrum/gui/qml/components/wizard/WCBIP39Refine.qml b/electrum/gui/qml/components/wizard/WCBIP39Refine.qml index 27cb36dd4..cef0d198d 100644 --- a/electrum/gui/qml/components/wizard/WCBIP39Refine.qml +++ b/electrum/gui/qml/components/wizard/WCBIP39Refine.qml @@ -51,10 +51,9 @@ WizardComponent { clip:true interactive: height < contentHeight - GridLayout { + ColumnLayout { id: mainLayout width: parent.width - columns: 1 Label { text: qsTr('Script type and Derivation path') } Button { @@ -79,6 +78,7 @@ WizardComponent { text: qsTr('native segwit (p2wpkh)') } InfoTextArea { + Layout.preferredWidth: parent.width text: qsTr('You can override the suggested derivation path.') + ' ' + qsTr('If you are not sure what this is, leave this field unchanged.') } diff --git a/electrum/gui/qml/components/wizard/WCHaveSeed.qml b/electrum/gui/qml/components/wizard/WCHaveSeed.qml index 527de82a1..2d140f98d 100644 --- a/electrum/gui/qml/components/wizard/WCHaveSeed.qml +++ b/electrum/gui/qml/components/wizard/WCHaveSeed.qml @@ -14,38 +14,37 @@ WizardComponent { property bool is2fa: false - onAccept: { + function apply() { wizard_data['seed'] = seedtext.text + wizard_data['seed_variant'] = seed_variant.currentValue wizard_data['seed_type'] = bitcoin.seed_type wizard_data['seed_extend'] = extendcb.checked wizard_data['seed_extra_words'] = extendcb.checked ? customwordstext.text : '' - wizard_data['seed_bip39'] = seed_type.getTypeCode() == 'BIP39' - wizard_data['seed_slip39'] = seed_type.getTypeCode() == 'SLIP39' } function setSeedTypeHelpText() { var t = { - 'Electrum': [ + 'electrum': [ qsTr('Electrum seeds are the default seed type.'), qsTr('If you are restoring from a seed previously created by Electrum, choose this option') ].join(' '), - 'BIP39': [ + 'bip39': [ qsTr('BIP39 seeds can be imported in Electrum, so that users can access funds locked in other wallets.'), '

', qsTr('However, we do not generate BIP39 seeds, because they do not meet our safety standard.'), qsTr('BIP39 seeds do not include a version number, which compromises compatibility with future software.') ].join(' '), - 'SLIP39': [ + 'slip39': [ qsTr('SLIP39 seeds can be imported in Electrum, so that users can access funds locked in other wallets.'), '

', qsTr('However, we do not generate SLIP39 seeds.') ].join(' ') } - infotext.text = t[seed_type.currentText] + infotext.text = t[seed_variant.currentValue] } function checkValid() { - bitcoin.verify_seed(seedtext.text, seed_type.getTypeCode() == 'BIP39', seed_type.getTypeCode() == 'SLIP39', wizard_data['wallet_type']) + bitcoin.verify_seed(seedtext.text, seed_variant.currentValue, wizard_data['wallet_type']) } Flickable { @@ -65,16 +64,20 @@ WizardComponent { Layout.fillWidth: true } ComboBox { - id: seed_type + id: seed_variant visible: !is2fa - model: ['Electrum', 'BIP39'/*, 'SLIP39'*/] + + textRole: 'text' + valueRole: 'value' + model: [ + { text: qsTr('Electrum'), value: 'electrum' }, + { text: qsTr('BIP39'), value: 'bip39' } + ] onActivated: { setSeedTypeHelpText() + checkIsLast() checkValid() } - function getTypeCode() { - return currentText - } } InfoTextArea { id: infotext diff --git a/electrum/gui/qml/qebitcoin.py b/electrum/gui/qml/qebitcoin.py index 4d37d1206..70dd6437f 100644 --- a/electrum/gui/qml/qebitcoin.py +++ b/electrum/gui/qml/qebitcoin.py @@ -68,23 +68,18 @@ class QEBitcoin(QObject): asyncio.run_coroutine_threadsafe(co_gen_seed(seed_type, language), get_asyncio_loop()) - @pyqtSlot(str) - @pyqtSlot(str,bool,bool) - @pyqtSlot(str,bool,bool,str) - @pyqtSlot(str,bool,bool,str,str) - def verify_seed(self, seed, bip39=False, slip39=False, wallet_type='standard', language='en'): - self._logger.debug('bip39 ' + str(bip39)) - self._logger.debug('slip39 ' + str(slip39)) - + @pyqtSlot(str,str) + @pyqtSlot(str,str,str) + def verify_seed(self, seed, seed_variant, wallet_type='standard'): seed_type = '' seed_valid = False self.validationMessage = '' - if not (bip39 or slip39): + if seed_variant == 'electrum': seed_type = mnemonic.seed_type(seed) if seed_type != '': seed_valid = True - elif bip39: + elif seed_variant == 'bip39': is_checksum, is_wordlist = keystore.bip39_is_checksum_valid(seed) status = ('checksum: ' + ('ok' if is_checksum else 'failed')) if is_wordlist else 'unknown wordlist' self.validationMessage = 'BIP39 (%s)' % status @@ -92,8 +87,7 @@ class QEBitcoin(QObject): if is_checksum: seed_type = 'bip39' seed_valid = True - - elif slip39: # TODO: incomplete impl, this code only validates a single share. + elif seed_variant == 'slip39': # TODO: incomplete impl, this code only validates a single share. try: share = decode_mnemonic(seed) seed_type = 'slip39' @@ -101,11 +95,13 @@ class QEBitcoin(QObject): except Slip39Error as e: self.validationMessage = 'SLIP39: %s' % str(e) seed_valid = False # for now + else: + raise Exception(f'unknown seed variant {seed_variant}') # check if seed matches wallet type if wallet_type == '2fa' and not is_any_2fa_seed_type(seed_type): seed_valid = False - elif wallet_type == 'standard' and seed_type not in ['old', 'standard', 'segwit']: + elif wallet_type == 'standard' and seed_type not in ['old', 'standard', 'segwit', 'bip39']: seed_valid = False self.seedType = seed_type diff --git a/electrum/wizard.py b/electrum/wizard.py index c8bd7b2f3..8f8d6378c 100644 --- a/electrum/wizard.py +++ b/electrum/wizard.py @@ -182,7 +182,7 @@ class NewWalletWizard(AbstractWizard): raise NotImplementedError() def last_if_single_password_and_not_bip39(self, view, wizard_data): - return self.last_if_single_password(view, wizard_data) and not wizard_data['seed_type'] == 'bip39' + return self.last_if_single_password(view, wizard_data) and not wizard_data['seed_variant'] == 'bip39' def on_wallet_type(self, wizard_data): t = wizard_data['wallet_type']