qml: add plumbing for duplicate master pubkey check, fix multisig end conditions
This commit is contained in:
@@ -4,7 +4,6 @@ import QtQuick.Controls 2.1
|
|||||||
|
|
||||||
import org.electrum 1.0
|
import org.electrum 1.0
|
||||||
|
|
||||||
import ".."
|
|
||||||
import "../controls"
|
import "../controls"
|
||||||
|
|
||||||
WizardComponent {
|
WizardComponent {
|
||||||
@@ -77,7 +76,7 @@ WizardComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
bitcoin.generate_seed(wizard_data['seed_type'])
|
bitcoin.generateSeed(wizard_data['seed_type'])
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitcoin {
|
Bitcoin {
|
||||||
|
|||||||
@@ -23,7 +23,21 @@ WizardComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function verifyMasterKey(key) {
|
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 {
|
ColumnLayout {
|
||||||
@@ -76,8 +90,7 @@ WizardComponent {
|
|||||||
|
|
||||||
TextArea {
|
TextArea {
|
||||||
id: validationtext
|
id: validationtext
|
||||||
text: bitcoin.validationMessage
|
visible: text
|
||||||
visible: bitcoin.validationMessage
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
readOnly: true
|
readOnly: true
|
||||||
wrapMode: TextInput.WordWrap
|
wrapMode: TextInput.WordWrap
|
||||||
@@ -108,6 +121,7 @@ WizardComponent {
|
|||||||
|
|
||||||
Bitcoin {
|
Bitcoin {
|
||||||
id: bitcoin
|
id: bitcoin
|
||||||
|
onValidationMessageChanged: validationtext.text = validationMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
|||||||
@@ -54,7 +54,22 @@ WizardComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function checkValid() {
|
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 {
|
Flickable {
|
||||||
@@ -130,8 +145,7 @@ WizardComponent {
|
|||||||
}
|
}
|
||||||
TextArea {
|
TextArea {
|
||||||
id: validationtext
|
id: validationtext
|
||||||
text: bitcoin.validationMessage
|
visible: text
|
||||||
visible: bitcoin.validationMessage
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
readOnly: true
|
readOnly: true
|
||||||
wrapMode: TextInput.WordWrap
|
wrapMode: TextInput.WordWrap
|
||||||
@@ -151,6 +165,9 @@ WizardComponent {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.columnSpan: 2
|
Layout.columnSpan: 2
|
||||||
placeholderText: qsTr('Enter your custom word(s)')
|
placeholderText: qsTr('Enter your custom word(s)')
|
||||||
|
onTextChanged: {
|
||||||
|
validationTimer.restart()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,7 +175,7 @@ WizardComponent {
|
|||||||
Bitcoin {
|
Bitcoin {
|
||||||
id: bitcoin
|
id: bitcoin
|
||||||
onSeedTypeChanged: contentText.text = bitcoin.seed_type
|
onSeedTypeChanged: contentText.text = bitcoin.seed_type
|
||||||
onSeedValidChanged: root.valid = bitcoin.seed_valid
|
onValidationMessageChanged: validationtext.text = validationMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ Item {
|
|||||||
property var wizard_data : ({})
|
property var wizard_data : ({})
|
||||||
property bool valid
|
property bool valid
|
||||||
property bool last: false
|
property bool last: false
|
||||||
property bool ready: false
|
|
||||||
property string title: ''
|
property string title: ''
|
||||||
|
|
||||||
onAccept: {
|
onAccept: {
|
||||||
|
|||||||
@@ -24,9 +24,6 @@ class QEBitcoin(QObject):
|
|||||||
generatedSeedChanged = pyqtSignal()
|
generatedSeedChanged = pyqtSignal()
|
||||||
generatedSeed = ''
|
generatedSeed = ''
|
||||||
|
|
||||||
seedValidChanged = pyqtSignal()
|
|
||||||
seedValid = False
|
|
||||||
|
|
||||||
seedTypeChanged = pyqtSignal()
|
seedTypeChanged = pyqtSignal()
|
||||||
seedType = ''
|
seedType = ''
|
||||||
|
|
||||||
@@ -37,10 +34,6 @@ class QEBitcoin(QObject):
|
|||||||
def generated_seed(self):
|
def generated_seed(self):
|
||||||
return self.generatedSeed
|
return self.generatedSeed
|
||||||
|
|
||||||
@pyqtProperty(bool, notify=seedValidChanged)
|
|
||||||
def seed_valid(self):
|
|
||||||
return self.seedValid
|
|
||||||
|
|
||||||
@pyqtProperty('QString', notify=seedTypeChanged)
|
@pyqtProperty('QString', notify=seedTypeChanged)
|
||||||
def seed_type(self):
|
def seed_type(self):
|
||||||
return self.seedType
|
return self.seedType
|
||||||
@@ -58,7 +51,7 @@ class QEBitcoin(QObject):
|
|||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
@pyqtSlot(str,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))
|
self._logger.debug('generating seed of type ' + str(seed_type))
|
||||||
|
|
||||||
async def co_gen_seed(seed_type, language):
|
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())
|
asyncio.run_coroutine_threadsafe(co_gen_seed(seed_type, language), get_asyncio_loop())
|
||||||
|
|
||||||
@pyqtSlot(str,str)
|
@pyqtSlot(str,str,str, result=bool)
|
||||||
@pyqtSlot(str,str,str)
|
|
||||||
def verifySeed(self, seed, seed_variant, wallet_type='standard'):
|
def verifySeed(self, seed, seed_variant, wallet_type='standard'):
|
||||||
seed_type = ''
|
seed_type = ''
|
||||||
seed_valid = False
|
seed_valid = False
|
||||||
@@ -109,12 +101,10 @@ class QEBitcoin(QObject):
|
|||||||
self.seedType = seed_type
|
self.seedType = seed_type
|
||||||
self.seedTypeChanged.emit()
|
self.seedTypeChanged.emit()
|
||||||
|
|
||||||
if self.seedValid != seed_valid:
|
|
||||||
self.seedValid = seed_valid
|
|
||||||
self.seedValidChanged.emit()
|
|
||||||
|
|
||||||
self._logger.debug('seed verified: ' + str(seed_valid))
|
self._logger.debug('seed verified: ' + str(seed_valid))
|
||||||
|
|
||||||
|
return seed_valid
|
||||||
|
|
||||||
@pyqtSlot(str, str, result=bool)
|
@pyqtSlot(str, str, result=bool)
|
||||||
def verifyMasterKey(self, key, wallet_type='standard'):
|
def verifyMasterKey(self, key, wallet_type='standard'):
|
||||||
self.validationMessage = ''
|
self.validationMessage = ''
|
||||||
|
|||||||
@@ -82,6 +82,12 @@ class QENewWalletWizard(NewWalletWizard, QEAbstractWizard):
|
|||||||
def is_single_password(self):
|
def is_single_password(self):
|
||||||
return self._daemon.singlePasswordEnabled
|
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)
|
@pyqtSlot('QJSValue', bool, str)
|
||||||
def createStorage(self, js_data, single_password_enabled, single_password):
|
def createStorage(self, js_data, single_password_enabled, single_password):
|
||||||
self._logger.info('Creating wallet from wizard data')
|
self._logger.info('Creating wallet from wizard data')
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ class NewWalletWizard(AbstractWizard):
|
|||||||
},
|
},
|
||||||
'confirm_seed': {
|
'confirm_seed': {
|
||||||
'next': lambda d: 'wallet_password' if not self.is_multisig(d) else 'multisig_show_masterpubkey',
|
'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': {
|
'have_seed': {
|
||||||
'next': self.on_have_seed,
|
'next': self.on_have_seed,
|
||||||
@@ -157,11 +157,11 @@ class NewWalletWizard(AbstractWizard):
|
|||||||
},
|
},
|
||||||
'bip39_refine': {
|
'bip39_refine': {
|
||||||
'next': lambda d: 'wallet_password' if not self.is_multisig(d) else 'multisig_show_masterpubkey',
|
'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': {
|
'have_master_key': {
|
||||||
'next': lambda d: 'wallet_password' if not self.is_multisig(d) else 'multisig_show_masterpubkey',
|
'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': {
|
'multisig': {
|
||||||
'next': 'keystore_type'
|
'next': 'keystore_type'
|
||||||
@@ -261,12 +261,16 @@ class NewWalletWizard(AbstractWizard):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def has_duplicate_keys(self, wizard_data):
|
||||||
|
# TODO
|
||||||
|
return False
|
||||||
|
|
||||||
def finished(self, wizard_data):
|
def finished(self, wizard_data):
|
||||||
self._logger.debug('finished')
|
self._logger.debug('finished')
|
||||||
# override
|
# override
|
||||||
|
|
||||||
def create_storage(self, path, data):
|
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']
|
assert data['wallet_type'] in ['standard', '2fa', 'imported']
|
||||||
|
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
|
|||||||
Reference in New Issue
Block a user