diff --git a/electrum/gui/qml/components/wizard/WCConfirmExt.qml b/electrum/gui/qml/components/wizard/WCConfirmExt.qml
new file mode 100644
index 000000000..abcfc3130
--- /dev/null
+++ b/electrum/gui/qml/components/wizard/WCConfirmExt.qml
@@ -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']
+ }
+ }
+}
\ No newline at end of file
diff --git a/electrum/gui/qml/components/wizard/WCConfirmSeed.qml b/electrum/gui/qml/components/wizard/WCConfirmSeed.qml
index a5f27d8e0..a2b058e95 100644
--- a/electrum/gui/qml/components/wizard/WCConfirmSeed.qml
+++ b/electrum/gui/qml/components/wizard/WCConfirmSeed.qml
@@ -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']
- }
}
diff --git a/electrum/gui/qml/components/wizard/WCCreateSeed.qml b/electrum/gui/qml/components/wizard/WCCreateSeed.qml
index da087706a..efa4df90a 100644
--- a/electrum/gui/qml/components/wizard/WCCreateSeed.qml
+++ b/electrum/gui/qml/components/wizard/WCCreateSeed.qml
@@ -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)
}
diff --git a/electrum/gui/qml/components/wizard/WCEnterExt.qml b/electrum/gui/qml/components/wizard/WCEnterExt.qml
new file mode 100644
index 000000000..b804f09ab
--- /dev/null
+++ b/electrum/gui/qml/components/wizard/WCEnterExt.qml
@@ -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.'),
+ '
',
+ 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()
+ }
+}
diff --git a/electrum/gui/qml/components/wizard/WCHaveSeed.qml b/electrum/gui/qml/components/wizard/WCHaveSeed.qml
index 4afc638a7..3be2a29d5 100644
--- a/electrum/gui/qml/components/wizard/WCHaveSeed.qml
+++ b/electrum/gui/qml/components/wizard/WCHaveSeed.qml
@@ -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.'),
- '
',
- 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.'),
- '
',
- 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()
- }
}
}
diff --git a/electrum/gui/qml/qewizard.py b/electrum/gui/qml/qewizard.py
index 0a9d51fa1..cd45e9e57 100644
--- a/electrum/gui/qml/qewizard.py
+++ b/electrum/gui/qml/qewizard.py
@@ -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'}
diff --git a/electrum/gui/qt/wizard/wallet.py b/electrum/gui/qt/wizard/wallet.py
index e8e6bf0d5..6ba6aa0d4 100644
--- a/electrum/gui/qt/wizard/wallet.py
+++ b/electrum/gui/qt/wizard/wallet.py
@@ -94,8 +94,11 @@ class QENewWalletWizard(NewWalletWizard, QEAbstractWizard, MessageBoxMixin):
'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},
'choose_hardware_device': {'gui': WCChooseHWDevice},
'script_and_derivation': {'gui': WCScriptAndDerivation},
'have_master_key': {'gui': WCHaveMasterKey},
@@ -103,6 +106,7 @@ class QENewWalletWizard(NewWalletWizard, QEAbstractWizard, MessageBoxMixin):
'multisig_cosigner_keystore': {'gui': WCCosignerKeystore},
'multisig_cosigner_key': {'gui': WCHaveMasterKey},
'multisig_cosigner_seed': {'gui': WCHaveSeed},
+ 'multisig_cosigner_have_ext': {'gui': WCEnterExt},
'multisig_cosigner_hardware': {'gui': WCChooseHWDevice},
'multisig_cosigner_script_and_derivation': {'gui': WCScriptAndDerivation},
'imported': {'gui': WCImport},
@@ -122,47 +126,6 @@ class QENewWalletWizard(NewWalletWizard, QEAbstractWizard, MessageBoxMixin):
}
})
- # insert seed extension entry/confirm as separate views
- self.navmap_merge({
- 'create_seed': {
- 'next': lambda d: 'create_ext' if self.wants_ext(d) else 'confirm_seed'
- },
- 'create_ext': {
- 'next': 'confirm_seed',
- 'gui': WCEnterExt
- },
- 'confirm_seed': {
- 'next': lambda d: 'confirm_ext' if self.wants_ext(d) else self.on_have_or_confirm_seed(d),
- 'accept': lambda d: None if self.wants_ext(d) else self.maybe_master_pubkey(d)
- },
- 'confirm_ext': {
- 'next': self.on_have_or_confirm_seed,
- 'accept': self.maybe_master_pubkey,
- 'gui': WCConfirmExt
- },
- 'have_seed': {
- 'next': lambda d: 'have_ext' if self.wants_ext(d) else self.on_have_or_confirm_seed(d),
- 'accept': lambda d: None if self.wants_ext(d) else self.maybe_master_pubkey(d),
- 'last': lambda d: self.is_single_password() and not
- (self.needs_derivation_path(d) or self.is_multisig(d) or self.wants_ext(d))
- },
- 'have_ext': {
- 'next': self.on_have_or_confirm_seed,
- 'accept': self.maybe_master_pubkey,
- 'gui': WCEnterExt
- },
- 'multisig_cosigner_seed': {
- 'next': lambda d: 'multisig_cosigner_have_ext' if self.wants_ext(d) else self.on_have_cosigner_seed(d),
- 'last': lambda d: self.is_single_password() and self.last_cosigner(d) and not
- (self.needs_derivation_path(d) or self.wants_ext(d))
- },
- 'multisig_cosigner_have_ext': {
- 'next': self.on_have_cosigner_seed,
- 'last': lambda d: self.is_single_password() and self.last_cosigner(d) and not self.needs_derivation_path(d),
- 'gui': WCEnterExt
- },
- })
-
run_hook('init_wallet_wizard', self)
@property
diff --git a/electrum/plugins/trustedcoin/qml.py b/electrum/plugins/trustedcoin/qml.py
index aa93a1d91..f2e66dab1 100644
--- a/electrum/plugins/trustedcoin/qml.py
+++ b/electrum/plugins/trustedcoin/qml.py
@@ -69,12 +69,21 @@ class Plugin(TrustedCoinPlugin):
'trustedcoin_create_seed': {
'gui': 'WCCreateSeed',
},
+ 'trustedcoin_create_ext': {
+ 'gui': 'WCEnterExt',
+ },
'trustedcoin_confirm_seed': {
'gui': 'WCConfirmSeed',
},
+ 'trustedcoin_confirm_ext': {
+ 'gui': 'WCConfirmExt',
+ },
'trustedcoin_have_seed': {
'gui': 'WCHaveSeed',
},
+ 'trustedcoin_have_ext': {
+ 'gui': 'WCEnterExt',
+ },
'trustedcoin_keep_disable': {
'gui': '../../../../plugins/trustedcoin/qml/KeepDisable',
},
diff --git a/electrum/plugins/trustedcoin/qt.py b/electrum/plugins/trustedcoin/qt.py
index 8d32e04a5..93bca30b8 100644
--- a/electrum/plugins/trustedcoin/qt.py
+++ b/electrum/plugins/trustedcoin/qt.py
@@ -250,14 +250,26 @@ class Plugin(TrustedCoinPlugin):
'gui': WCCreateSeed,
'params': {'icon': self.icon_path('trustedcoin-wizard.png')},
},
+ 'trustedcoin_create_ext': {
+ 'gui': WCEnterExt,
+ 'params': {'icon': self.icon_path('trustedcoin-wizard.png')},
+ },
'trustedcoin_confirm_seed': {
'gui': WCConfirmSeed,
'params': {'icon': self.icon_path('trustedcoin-wizard.png')},
},
+ 'trustedcoin_confirm_ext': {
+ 'gui': WCConfirmExt,
+ 'params': {'icon': self.icon_path('trustedcoin-wizard.png')},
+ },
'trustedcoin_have_seed': {
'gui': WCHaveSeed,
'params': {'icon': self.icon_path('trustedcoin-wizard.png')},
},
+ 'trustedcoin_have_ext': {
+ 'gui': WCEnterExt,
+ 'params': {'icon': self.icon_path('trustedcoin-wizard.png')},
+ },
'trustedcoin_keep_disable': {
'gui': WCKeepDisable,
'params': {'icon': self.icon_path('trustedcoin-wizard.png')},
@@ -277,35 +289,6 @@ class Plugin(TrustedCoinPlugin):
}
wizard.navmap_merge(views)
- # modify default flow, insert seed extension entry/confirm as separate views
- ext = {
- 'trustedcoin_create_seed': {
- 'next': lambda d: 'trustedcoin_create_ext' if wizard.wants_ext(d) else 'trustedcoin_confirm_seed'
- },
- 'trustedcoin_create_ext': {
- 'gui': WCEnterExt,
- 'params': {'icon': self.icon_path('trustedcoin-wizard.png')},
- 'next': 'trustedcoin_confirm_seed',
- },
- 'trustedcoin_confirm_seed': {
- 'next': lambda d: 'trustedcoin_confirm_ext' if wizard.wants_ext(d) else 'trustedcoin_tos'
- },
- 'trustedcoin_confirm_ext': {
- 'gui': WCConfirmExt,
- 'params': {'icon': self.icon_path('trustedcoin-wizard.png')},
- 'next': 'trustedcoin_tos',
- },
- 'trustedcoin_have_seed': {
- 'next': lambda d: 'trustedcoin_have_ext' if wizard.wants_ext(d) else 'trustedcoin_keep_disable'
- },
- 'trustedcoin_have_ext': {
- 'gui': WCEnterExt,
- 'params': {'icon': self.icon_path('trustedcoin-wizard.png')},
- 'next': 'trustedcoin_keep_disable',
- },
- }
- wizard.navmap_merge(ext)
-
# insert page offering choice to go online or continue on another system
ext_online = {
'trustedcoin_continue_online': {
diff --git a/electrum/plugins/trustedcoin/trustedcoin.py b/electrum/plugins/trustedcoin/trustedcoin.py
index 4b9d6b7df..db1605c20 100644
--- a/electrum/plugins/trustedcoin/trustedcoin.py
+++ b/electrum/plugins/trustedcoin/trustedcoin.py
@@ -586,13 +586,22 @@ class TrustedCoinPlugin(BasePlugin):
else 'trustedcoin_have_seed'
},
'trustedcoin_create_seed': {
- 'next': 'trustedcoin_confirm_seed'
+ 'next': lambda d: 'trustedcoin_create_ext' if wizard.wants_ext(d) else 'trustedcoin_confirm_seed',
+ },
+ 'trustedcoin_create_ext': {
+ 'next': 'trustedcoin_confirm_seed',
},
'trustedcoin_confirm_seed': {
- 'next': 'trustedcoin_tos'
+ 'next': lambda d: 'trustedcoin_confirm_ext' if wizard.wants_ext(d) else 'trustedcoin_tos',
+ },
+ 'trustedcoin_confirm_ext': {
+ 'next': 'trustedcoin_tos',
},
'trustedcoin_have_seed': {
- 'next': 'trustedcoin_keep_disable'
+ 'next': lambda d: 'trustedcoin_have_ext' if wizard.wants_ext(d) else 'trustedcoin_keep_disable',
+ },
+ 'trustedcoin_have_ext': {
+ 'next': 'trustedcoin_keep_disable',
},
'trustedcoin_keep_disable': {
'next': lambda d: 'trustedcoin_tos' if d['trustedcoin_keepordisable'] != 'disable'
diff --git a/electrum/wizard.py b/electrum/wizard.py
index de79c12f3..9092e891f 100644
--- a/electrum/wizard.py
+++ b/electrum/wizard.py
@@ -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)
@@ -391,14 +391,28 @@ class NewWalletWizard(KeystoreWizard):
'next': self.on_keystore_type
},
'create_seed': {
- 'next': 'confirm_seed'
+ 'next': lambda d: 'create_ext' if self.wants_ext(d) else 'confirm_seed',
+ },
+ 'create_ext': {
+ 'next': 'confirm_seed',
},
'confirm_seed': {
+ 'next': lambda d: 'confirm_ext' if self.wants_ext(d) else self.on_have_or_confirm_seed(d),
+ 'accept': lambda d: None if self.wants_ext(d) else self.maybe_master_pubkey(d),
+ 'last': lambda d: self.is_single_password() and not self.is_multisig(d) and not self.wants_ext(d),
+ },
+ 'confirm_ext': {
'next': self.on_have_or_confirm_seed,
'accept': self.maybe_master_pubkey,
'last': lambda d: self.is_single_password() and not self.is_multisig(d)
},
'have_seed': {
+ 'next': lambda d: 'have_ext' if self.wants_ext(d) else self.on_have_or_confirm_seed(d),
+ 'accept': lambda d: None if self.wants_ext(d) else self.maybe_master_pubkey(d),
+ 'last': lambda d: self.is_single_password() and not
+ (self.needs_derivation_path(d) or self.is_multisig(d) or self.wants_ext(d)),
+ },
+ 'have_ext': {
'next': self.on_have_or_confirm_seed,
'accept': self.maybe_master_pubkey,
'last': lambda d: self.is_single_password() and not
@@ -428,6 +442,11 @@ class NewWalletWizard(KeystoreWizard):
'last': lambda d: self.is_single_password() and self.last_cosigner(d)
},
'multisig_cosigner_seed': {
+ 'next': lambda d: 'multisig_cosigner_have_ext' if self.wants_ext(d) else self.on_have_cosigner_seed(d),
+ 'last': lambda d: self.is_single_password() and self.last_cosigner(d) and not
+ (self.needs_derivation_path(d) or self.wants_ext(d)),
+ },
+ 'multisig_cosigner_have_ext': {
'next': self.on_have_cosigner_seed,
'last': lambda d: self.is_single_password() and self.last_cosigner(d) and not self.needs_derivation_path(d)
},
diff --git a/tests/test_wizard.py b/tests/test_wizard.py
index d6bc1633e..bb08399c1 100644
--- a/tests/test_wizard.py
+++ b/tests/test_wizard.py
@@ -164,6 +164,41 @@ class WalletWizardTestCase(WizardTestCase):
wallet = Daemon._load_wallet(wallet_path, password=None, config=self.config)
self.assertEqual("bc1qq2tmmcngng78nllq2pvrkchcdukemtj56uyue0", wallet.get_receiving_addresses()[0])
+ async def test_create_standard_wallet_newseed_passphrase(self):
+ w = self.wizard_for(name='test_standard_wallet', wallet_type='standard')
+ v = w._current
+ d = v.wizard_data
+ self.assertEqual('keystore_type', v.view)
+
+ d.update({'keystore_type': 'createseed'})
+ v = w.resolve_next(v.view, d)
+ self.assertEqual('create_seed', v.view)
+
+ d.update({'seed': '9dk', 'seed_type': 'segwit', 'seed_extend': True,
+ 'seed_variant': 'electrum',
+ 'seed_extra_words': False})
+
+ v = w.resolve_next(v.view, d)
+ self.assertEqual('create_ext', v.view)
+
+ v = w.resolve_next(v.view, d)
+ self.assertEqual('confirm_seed', v.view)
+
+ v = w.resolve_next(v.view, d)
+ self.assertEqual('confirm_ext', v.view)
+
+ v = w.resolve_next(v.view, d)
+ self.assertEqual('wallet_password', v.view)
+
+ d.update({'password': None, 'encrypt': False})
+ self.assertTrue(w.is_last_view(v.view, d))
+ v = w.resolve_next(v.view, d)
+
+ wallet_path = os.path.join(w._daemon.config.get_datadir_wallet_path(), d['wallet_name'])
+ w.create_storage(wallet_path, d)
+
+ self.assertTrue(os.path.exists(wallet_path))
+
async def test_create_standard_wallet_haveseed_electrum(self):
w = self.wizard_for(name='test_standard_wallet', wallet_type='standard')
v = w._current
@@ -190,6 +225,34 @@ class WalletWizardTestCase(WizardTestCase):
wallet = Daemon._load_wallet(wallet_path, password=None, config=self.config)
self.assertEqual("bc1qq2tmmcngng78nllq2pvrkchcdukemtj56uyue0", wallet.get_receiving_addresses()[0])
+ async def test_create_standard_wallet_haveseed_electrum_passphrase(self):
+ w = self.wizard_for(name='test_standard_wallet', wallet_type='standard')
+ v = w._current
+ d = v.wizard_data
+ self.assertEqual('keystore_type', v.view)
+
+ d.update({'keystore_type': 'haveseed'})
+ v = w.resolve_next(v.view, d)
+ self.assertEqual('have_seed', v.view)
+
+ d.update({'seed': '9dk', 'seed_type': 'segwit', 'seed_extend': True, 'seed_variant': 'electrum',
+ 'seed_extra_words': False})
+
+ v = w.resolve_next(v.view, d)
+ self.assertEqual('have_ext', v.view)
+
+ v = w.resolve_next(v.view, d)
+ self.assertEqual('wallet_password', v.view)
+
+ d.update({'password': None, 'encrypt': False})
+ self.assertTrue(w.is_last_view(v.view, d))
+ v = w.resolve_next(v.view, d)
+
+ wallet_path = os.path.join(w._daemon.config.get_datadir_wallet_path(), d['wallet_name'])
+ w.create_storage(wallet_path, d)
+
+ self.assertTrue(os.path.exists(wallet_path))
+
async def test_create_standard_wallet_haveseed_bip39(self):
w = self.wizard_for(name='test_standard_wallet', wallet_type='standard')
v = w._current
@@ -234,10 +297,12 @@ class WalletWizardTestCase(WizardTestCase):
self.assertEqual('trustedcoin_have_seed', v.view)
d.update({
'seed': 'oblige basket safe educate whale bacon celery demand novel slice various awkward',
- 'seed_type': '2fa', 'seed_extend': False, 'seed_variant': 'electrum',
+ 'seed_type': '2fa', 'seed_extend': True, 'seed_variant': 'electrum',
'seed_extra_words': False
})
v = w.resolve_next(v.view, d)
+ self.assertEqual('trustedcoin_have_ext', v.view)
+ v = w.resolve_next(v.view, d)
self.assertEqual('trustedcoin_keep_disable', v.view)
d.update({'trustedcoin_keepordisable': 'keep'})
v = w.resolve_next(v.view, d)