diff --git a/electrum/gui/qml/components/wizard/WCCreateSeed.qml b/electrum/gui/qml/components/wizard/WCCreateSeed.qml index 65b7e1d77..e42c613e1 100644 --- a/electrum/gui/qml/components/wizard/WCCreateSeed.qml +++ b/electrum/gui/qml/components/wizard/WCCreateSeed.qml @@ -4,7 +4,6 @@ import QtQuick.Controls 2.1 import org.electrum 1.0 -import ".." import "../controls" WizardComponent { @@ -77,7 +76,7 @@ WizardComponent { } Component.onCompleted: { - bitcoin.generate_seed(wizard_data['seed_type']) + bitcoin.generateSeed(wizard_data['seed_type']) } Bitcoin { diff --git a/electrum/gui/qml/components/wizard/WCHaveMasterKey.qml b/electrum/gui/qml/components/wizard/WCHaveMasterKey.qml index 62947e56b..1407dacbd 100644 --- a/electrum/gui/qml/components/wizard/WCHaveMasterKey.qml +++ b/electrum/gui/qml/components/wizard/WCHaveMasterKey.qml @@ -23,7 +23,21 @@ WizardComponent { } function verifyMasterKey(key) { - return valid = bitcoin.verifyMasterKey(key.trim(), wizard_data['wallet_type']) + valid = false + validationtext.text = '' + + if (!bitcoin.verifyMasterKey(key.trim(), wizard_data['wallet_type'])) + return false + + if (cosigner) { + apply() + if (wiz.hasDuplicateKeys(wizard_data)) { + validationtext.text = qsTr('Error: duplicate master public key') + return false + } + } + + return valid = true } ColumnLayout { @@ -76,8 +90,7 @@ WizardComponent { TextArea { id: validationtext - text: bitcoin.validationMessage - visible: bitcoin.validationMessage + visible: text Layout.fillWidth: true readOnly: true wrapMode: TextInput.WordWrap @@ -108,6 +121,7 @@ WizardComponent { Bitcoin { id: bitcoin + onValidationMessageChanged: validationtext.text = validationMessage } Component.onCompleted: { diff --git a/electrum/gui/qml/components/wizard/WCHaveSeed.qml b/electrum/gui/qml/components/wizard/WCHaveSeed.qml index 6710d3c7a..8f27dcb25 100644 --- a/electrum/gui/qml/components/wizard/WCHaveSeed.qml +++ b/electrum/gui/qml/components/wizard/WCHaveSeed.qml @@ -54,7 +54,22 @@ WizardComponent { } function checkValid() { - bitcoin.verifySeed(seedtext.text, seed_variant_cb.currentValue, wizard_data['wallet_type']) + valid = false + validationtext.text = '' + + var validSeed = bitcoin.verifySeed(seedtext.text, seed_variant_cb.currentValue, wizard_data['wallet_type']) + if (!cosigner || !validSeed) { + valid = validSeed + return + } else { + apply() + if (wiz.hasDuplicateKeys(wizard_data)) { + validationtext.text = qsTr('Error: duplicate master public key') + return + } else { + valid = true + } + } } Flickable { @@ -130,8 +145,7 @@ WizardComponent { } TextArea { id: validationtext - text: bitcoin.validationMessage - visible: bitcoin.validationMessage + visible: text Layout.fillWidth: true readOnly: true wrapMode: TextInput.WordWrap @@ -151,6 +165,9 @@ WizardComponent { Layout.fillWidth: true Layout.columnSpan: 2 placeholderText: qsTr('Enter your custom word(s)') + onTextChanged: { + validationTimer.restart() + } } } } @@ -158,7 +175,7 @@ WizardComponent { Bitcoin { id: bitcoin onSeedTypeChanged: contentText.text = bitcoin.seed_type - onSeedValidChanged: root.valid = bitcoin.seed_valid + onValidationMessageChanged: validationtext.text = validationMessage } Timer { diff --git a/electrum/gui/qml/components/wizard/WizardComponent.qml b/electrum/gui/qml/components/wizard/WizardComponent.qml index 9e29251c5..5a04bba3d 100644 --- a/electrum/gui/qml/components/wizard/WizardComponent.qml +++ b/electrum/gui/qml/components/wizard/WizardComponent.qml @@ -7,7 +7,6 @@ Item { property var wizard_data : ({}) property bool valid property bool last: false - property bool ready: false property string title: '' onAccept: { diff --git a/electrum/gui/qml/qebitcoin.py b/electrum/gui/qml/qebitcoin.py index d327b1081..4e0f69739 100644 --- a/electrum/gui/qml/qebitcoin.py +++ b/electrum/gui/qml/qebitcoin.py @@ -24,9 +24,6 @@ class QEBitcoin(QObject): generatedSeedChanged = pyqtSignal() generatedSeed = '' - seedValidChanged = pyqtSignal() - seedValid = False - seedTypeChanged = pyqtSignal() seedType = '' @@ -37,10 +34,6 @@ class QEBitcoin(QObject): def generated_seed(self): return self.generatedSeed - @pyqtProperty(bool, notify=seedValidChanged) - def seed_valid(self): - return self.seedValid - @pyqtProperty('QString', notify=seedTypeChanged) def seed_type(self): return self.seedType @@ -58,7 +51,7 @@ class QEBitcoin(QObject): @pyqtSlot() @pyqtSlot(str) @pyqtSlot(str,str) - def generate_seed(self, seed_type='segwit', language='en'): + def generateSeed(self, seed_type='segwit', language='en'): self._logger.debug('generating seed of type ' + str(seed_type)) async def co_gen_seed(seed_type, language): @@ -68,8 +61,7 @@ class QEBitcoin(QObject): asyncio.run_coroutine_threadsafe(co_gen_seed(seed_type, language), get_asyncio_loop()) - @pyqtSlot(str,str) - @pyqtSlot(str,str,str) + @pyqtSlot(str,str,str, result=bool) def verifySeed(self, seed, seed_variant, wallet_type='standard'): seed_type = '' seed_valid = False @@ -109,12 +101,10 @@ class QEBitcoin(QObject): self.seedType = seed_type self.seedTypeChanged.emit() - if self.seedValid != seed_valid: - self.seedValid = seed_valid - self.seedValidChanged.emit() - self._logger.debug('seed verified: ' + str(seed_valid)) + return seed_valid + @pyqtSlot(str, str, result=bool) def verifyMasterKey(self, key, wallet_type='standard'): self.validationMessage = '' diff --git a/electrum/gui/qml/qewizard.py b/electrum/gui/qml/qewizard.py index bd0f26661..aa863c49c 100644 --- a/electrum/gui/qml/qewizard.py +++ b/electrum/gui/qml/qewizard.py @@ -82,6 +82,12 @@ class QENewWalletWizard(NewWalletWizard, QEAbstractWizard): def is_single_password(self): return self._daemon.singlePasswordEnabled + @pyqtSlot('QJSValue', result=bool) + def hasDuplicateKeys(self, js_data): + self._logger.info('Checking for duplicate keys') + data = js_data.toVariant() + return self.has_duplicate_keys(data) + @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 a58a209d4..cfb0743b7 100644 --- a/electrum/wizard.py +++ b/electrum/wizard.py @@ -149,7 +149,7 @@ class NewWalletWizard(AbstractWizard): }, 'confirm_seed': { 'next': lambda d: 'wallet_password' if not self.is_multisig(d) else 'multisig_show_masterpubkey', - 'last': lambda v,d: self.is_single_password() + 'last': lambda v,d: self.is_single_password() and not self.is_multisig(d) }, 'have_seed': { 'next': self.on_have_seed, @@ -157,11 +157,11 @@ class NewWalletWizard(AbstractWizard): }, 'bip39_refine': { 'next': lambda d: 'wallet_password' if not self.is_multisig(d) else 'multisig_show_masterpubkey', - 'last': lambda v,d: self.is_single_password() + 'last': lambda v,d: self.is_single_password() and not self.is_multisig(d) }, 'have_master_key': { 'next': lambda d: 'wallet_password' if not self.is_multisig(d) else 'multisig_show_masterpubkey', - 'last': lambda v,d: self.is_single_password() + 'last': lambda v,d: self.is_single_password() and not self.is_multisig(d) }, 'multisig': { 'next': 'keystore_type' @@ -261,12 +261,16 @@ class NewWalletWizard(AbstractWizard): return True + def has_duplicate_keys(self, wizard_data): + # TODO + return False + def finished(self, wizard_data): self._logger.debug('finished') # override def create_storage(self, path, data): - # only standard and 2fa wallets for now + # only standard, 2fa and imported wallets for now assert data['wallet_type'] in ['standard', '2fa', 'imported'] if os.path.exists(path):