Merge branch spesmilo/pr/10016' into 202507_pr10016_qml_wizard_passphrase
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'}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
},
|
||||
|
||||
@@ -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': {
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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)
|
||||
},
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user