qml: change wizard passphrase flow
This commit is contained in:
72
electrum/gui/qml/components/wizard/WCConfirmExt.qml
Normal file
72
electrum/gui/qml/components/wizard/WCConfirmExt.qml
Normal file
@@ -0,0 +1,72 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
|
||||
import org.electrum 1.0
|
||||
|
||||
import "../controls"
|
||||
|
||||
WizardComponent {
|
||||
id: root
|
||||
securePage: true
|
||||
|
||||
valid: false
|
||||
|
||||
property int cosigner: 0
|
||||
|
||||
function checkValid() {
|
||||
valid = false
|
||||
var input = customwordstext.text
|
||||
if (input == '') {
|
||||
return
|
||||
}
|
||||
|
||||
if (cosigner) {
|
||||
// multisig cosigner
|
||||
if (input != wizard_data['multisig_cosigner_data'][cosigner.toString()]['seed_extra_words']) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if (input != wizard_data['seed_extra_words']) {
|
||||
return
|
||||
}
|
||||
}
|
||||
valid = true
|
||||
}
|
||||
|
||||
Flickable {
|
||||
anchors.fill: parent
|
||||
contentHeight: mainLayout.height
|
||||
clip: true
|
||||
interactive: height < contentHeight
|
||||
|
||||
ColumnLayout {
|
||||
id: mainLayout
|
||||
width: parent.width
|
||||
spacing: constants.paddingLarge
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.Wrap
|
||||
text: qsTr('Please enter your custom word(s) a second time:')
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: customwordstext
|
||||
Layout.fillWidth: true
|
||||
Layout.columnSpan: 2
|
||||
placeholderText: qsTr('Enter your custom word(s) here')
|
||||
inputMethodHints: Qt.ImhSensitiveData | Qt.ImhNoPredictiveText | Qt.ImhNoAutoUppercase
|
||||
onTextChanged: checkValid()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (wizard_data['wallet_type'] == 'multisig') {
|
||||
if ('multisig_current_cosigner' in wizard_data)
|
||||
cosigner = wizard_data['multisig_current_cosigner']
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,7 @@ WizardComponent {
|
||||
|
||||
function checkValid() {
|
||||
var seedvalid = wizard.wiz.isMatchingSeed(wizard_data['seed'], confirm.text)
|
||||
var customwordsvalid = customwordstext.text == wizard_data['seed_extra_words']
|
||||
valid = seedvalid && (wizard_data['seed_extend'] ? customwordsvalid : true)
|
||||
valid = seedvalid
|
||||
}
|
||||
|
||||
Flickable {
|
||||
@@ -46,19 +45,6 @@ WizardComponent {
|
||||
placeholderText: qsTr('Enter your seed')
|
||||
onTextChanged: checkValid()
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: customwordstext
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr('Enter your custom word(s)')
|
||||
inputMethodHints: Qt.ImhNoPredictiveText
|
||||
|
||||
onTextChanged: checkValid()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
customwordstext.visible = wizard_data['seed_extend']
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,13 +9,12 @@ import "../controls"
|
||||
WizardComponent {
|
||||
securePage: true
|
||||
|
||||
valid: seedtext.text != '' && extendcb.checked ? customwordstext.text != '' : true
|
||||
valid: seedtext.text != ''
|
||||
|
||||
function apply() {
|
||||
wizard_data['seed'] = seedtext.text
|
||||
wizard_data['seed_variant'] = 'electrum' // generated seed always electrum variant
|
||||
wizard_data['seed_extend'] = extendcb.checked
|
||||
wizard_data['seed_extra_words'] = extendcb.checked ? customwordstext.text : ''
|
||||
wizard_data['seed_extend'] = true // true so we get forwarded to the passphrase page
|
||||
}
|
||||
|
||||
function setWarningText(numwords) {
|
||||
@@ -70,20 +69,6 @@ WizardComponent {
|
||||
}
|
||||
}
|
||||
|
||||
ElCheckBox {
|
||||
id: extendcb
|
||||
Layout.fillWidth: true
|
||||
text: qsTr('Extend seed with custom words')
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: customwordstext
|
||||
visible: extendcb.checked
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr('Enter your custom word(s)')
|
||||
inputMethodHints: Qt.ImhNoPredictiveText
|
||||
}
|
||||
|
||||
Component.onCompleted : {
|
||||
setWarningText(12)
|
||||
}
|
||||
|
||||
119
electrum/gui/qml/components/wizard/WCEnterExt.qml
Normal file
119
electrum/gui/qml/components/wizard/WCEnterExt.qml
Normal file
@@ -0,0 +1,119 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
|
||||
import org.electrum 1.0
|
||||
|
||||
import "../controls"
|
||||
|
||||
WizardComponent {
|
||||
id: root
|
||||
securePage: true
|
||||
|
||||
valid: true
|
||||
|
||||
property int cosigner: 0
|
||||
|
||||
function apply() {
|
||||
var seed_extend = extendcb.checked
|
||||
if (cosigner) {
|
||||
wizard_data['multisig_cosigner_data'][cosigner.toString()]['seed_extend'] = seed_extend
|
||||
wizard_data['multisig_cosigner_data'][cosigner.toString()]['seed_extra_words'] = seed_extend ? customwordstext.text : ''
|
||||
} else {
|
||||
wizard_data['seed_extend'] = seed_extend
|
||||
wizard_data['seed_extra_words'] = seed_extend ? customwordstext.text : ''
|
||||
}
|
||||
}
|
||||
|
||||
function checkValid() {
|
||||
valid = false
|
||||
validationtext.text = ''
|
||||
|
||||
if (extendcb.checked && customwordstext.text == '') {
|
||||
return
|
||||
} else {
|
||||
// passphrase is either disabled or filled with text
|
||||
apply()
|
||||
if (cosigner && wizard_data['multisig_cosigner_data'][cosigner.toString()]['seed_variant'] == 'electrum') {
|
||||
// check if master keys are not duplicated after entering passphrase
|
||||
if (wiz.hasDuplicateMasterKeys(wizard_data)) {
|
||||
validationtext.text = qsTr('Error: duplicate master public key')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
valid = true
|
||||
}
|
||||
|
||||
Flickable {
|
||||
anchors.fill: parent
|
||||
contentHeight: mainLayout.height
|
||||
clip: true
|
||||
interactive: height < contentHeight
|
||||
|
||||
ColumnLayout {
|
||||
id: mainLayout
|
||||
width: parent.width
|
||||
spacing: constants.paddingLarge
|
||||
|
||||
InfoTextArea {
|
||||
id: validationtext
|
||||
Layout.fillWidth: true
|
||||
Layout.columnSpan: 2
|
||||
visible: text
|
||||
iconStyle: InfoTextArea.IconStyle.Error
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.Wrap
|
||||
text: [
|
||||
qsTr('You may extend your seed with custom words.'),
|
||||
qsTr('Your seed extension must be saved together with your seed.'),
|
||||
qsTr('Note that this is NOT your encryption password.'),
|
||||
'<br/>',
|
||||
qsTr('Do not enable it unless you know what it does!'),
|
||||
].join(' ')
|
||||
}
|
||||
|
||||
ElCheckBox {
|
||||
id: extendcb
|
||||
Layout.columnSpan: 2
|
||||
Layout.fillWidth: true
|
||||
text: qsTr('Extend seed with custom words')
|
||||
onCheckedChanged: checkValid()
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: customwordstext
|
||||
enabled: extendcb.checked
|
||||
Layout.fillWidth: true
|
||||
Layout.columnSpan: 2
|
||||
placeholderText: qsTr('Enter your custom word(s)')
|
||||
inputMethodHints: Qt.ImhSensitiveData | Qt.ImhNoPredictiveText | Qt.ImhNoAutoUppercase
|
||||
onTextChanged: startValidationTimer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function startValidationTimer() {
|
||||
valid = false
|
||||
validationTimer.restart()
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: validationTimer
|
||||
interval: 250
|
||||
repeat: false
|
||||
onTriggered: checkValid()
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (wizard_data['wallet_type'] == 'multisig') {
|
||||
if ('multisig_current_cosigner' in wizard_data)
|
||||
cosigner = wizard_data['multisig_current_cosigner']
|
||||
}
|
||||
checkValid()
|
||||
}
|
||||
}
|
||||
@@ -24,19 +24,16 @@ WizardComponent {
|
||||
property bool _seedValid
|
||||
|
||||
function apply() {
|
||||
var seed_extend = extendcb.checked && _canPassphrase
|
||||
if (cosigner) {
|
||||
wizard_data['multisig_cosigner_data'][cosigner.toString()]['seed'] = seedtext.text
|
||||
wizard_data['multisig_cosigner_data'][cosigner.toString()]['seed_variant'] = seed_variant_cb.currentValue
|
||||
wizard_data['multisig_cosigner_data'][cosigner.toString()]['seed_type'] = _seedType
|
||||
wizard_data['multisig_cosigner_data'][cosigner.toString()]['seed_extend'] = seed_extend
|
||||
wizard_data['multisig_cosigner_data'][cosigner.toString()]['seed_extra_words'] = seed_extend ? customwordstext.text : ''
|
||||
wizard_data['multisig_cosigner_data'][cosigner.toString()]['seed_extend'] = _canPassphrase
|
||||
} else {
|
||||
wizard_data['seed'] = seedtext.text
|
||||
wizard_data['seed_variant'] = seed_variant_cb.currentValue
|
||||
wizard_data['seed_type'] = _seedType
|
||||
wizard_data['seed_extend'] = seed_extend
|
||||
wizard_data['seed_extra_words'] = seed_extend ? customwordstext.text : ''
|
||||
wizard_data['seed_extend'] = _canPassphrase
|
||||
|
||||
// determine script type from electrum seed type
|
||||
// (used to limit script type options for bip39 cosigners)
|
||||
@@ -52,22 +49,20 @@ WizardComponent {
|
||||
function setSeedTypeHelpText() {
|
||||
var t = {
|
||||
'electrum': [
|
||||
// not shown as electrum is the default seed type anyways and the name is self-explanatory
|
||||
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': [
|
||||
qsTr('BIP39 seeds can be imported in Electrum, so that users can access funds locked in other wallets.'),
|
||||
'<br/><br/>',
|
||||
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.')
|
||||
qsTr('BIP39 seeds do not include a version number, which compromises compatibility with future software.'),
|
||||
].join(' '),
|
||||
'slip39': [
|
||||
qsTr('SLIP39 seeds can be imported in Electrum, so that users can access funds locked in other wallets.'),
|
||||
'<br/><br/>',
|
||||
qsTr('However, we do not generate SLIP39 seeds.')
|
||||
].join(' ')
|
||||
}
|
||||
infotext.text = t[seed_variant_cb.currentValue]
|
||||
infotext.visible = !cosigner && !is2fa && seed_variant_cb.currentValue != 'electrum'
|
||||
}
|
||||
|
||||
function checkValid() {
|
||||
@@ -100,11 +95,6 @@ WizardComponent {
|
||||
}
|
||||
}
|
||||
|
||||
if (_canPassphrase && extendcb.checked && customwordstext.text == '') {
|
||||
valid = false
|
||||
return
|
||||
}
|
||||
|
||||
valid = _seedValid
|
||||
}
|
||||
|
||||
@@ -196,7 +186,6 @@ WizardComponent {
|
||||
|
||||
InfoTextArea {
|
||||
id: infotext
|
||||
visible: !cosigner && !is2fa
|
||||
Layout.fillWidth: true
|
||||
Layout.columnSpan: 2
|
||||
Layout.bottomMargin: constants.paddingLarge
|
||||
@@ -221,26 +210,6 @@ WizardComponent {
|
||||
startValidationTimer()
|
||||
}
|
||||
}
|
||||
|
||||
ElCheckBox {
|
||||
id: extendcb
|
||||
Layout.columnSpan: 2
|
||||
Layout.fillWidth: true
|
||||
visible: _canPassphrase
|
||||
text: qsTr('Extend seed with custom words')
|
||||
onCheckedChanged: startValidationTimer()
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: customwordstext
|
||||
visible: extendcb.checked && extendcb.visible
|
||||
Layout.fillWidth: true
|
||||
Layout.columnSpan: 2
|
||||
placeholderText: qsTr('Enter your custom word(s)')
|
||||
inputMethodHints: Qt.ImhNoPredictiveText
|
||||
|
||||
onTextChanged: startValidationTimer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,14 +68,18 @@ class QENewWalletWizard(NewWalletWizard, QEAbstractWizard):
|
||||
'wallet_type': {'gui': 'WCWalletType'},
|
||||
'keystore_type': {'gui': 'WCKeystoreType'},
|
||||
'create_seed': {'gui': 'WCCreateSeed'},
|
||||
'create_ext': {'gui': 'WCEnterExt'},
|
||||
'confirm_seed': {'gui': 'WCConfirmSeed'},
|
||||
'confirm_ext': {'gui': 'WCConfirmExt'},
|
||||
'have_seed': {'gui': 'WCHaveSeed'},
|
||||
'have_ext': {'gui': 'WCEnterExt'},
|
||||
'script_and_derivation': {'gui': 'WCScriptAndDerivation'},
|
||||
'have_master_key': {'gui': 'WCHaveMasterKey'},
|
||||
'multisig': {'gui': 'WCMultisig'},
|
||||
'multisig_cosigner_keystore': {'gui': 'WCCosignerKeystore'},
|
||||
'multisig_cosigner_key': {'gui': 'WCHaveMasterKey'},
|
||||
'multisig_cosigner_seed': {'gui': 'WCHaveSeed'},
|
||||
'multisig_cosigner_have_ext': {'gui': 'WCEnterExt'},
|
||||
'multisig_cosigner_script_and_derivation': {'gui': 'WCScriptAndDerivation'},
|
||||
'imported': {'gui': 'WCImport'},
|
||||
'wallet_password': {'gui': 'WCWalletPassword'}
|
||||
|
||||
@@ -333,7 +333,7 @@ class KeystoreWizard(AbstractWizard):
|
||||
|
||||
def keystore_from_data(self, wallet_type: str, data: dict):
|
||||
if data['keystore_type'] in ['createseed', 'haveseed'] and 'seed' in data:
|
||||
seed_extension = data['seed_extra_words'] if data['seed_extend'] else ''
|
||||
seed_extension = data.get('seed_extra_words', '')
|
||||
if data['seed_variant'] == 'electrum':
|
||||
for_multisig = wallet_type in ['multisig']
|
||||
return keystore.from_seed(data['seed'], passphrase=seed_extension, for_multisig=for_multisig)
|
||||
|
||||
Reference in New Issue
Block a user