qml: skip multisig_show_masterpubkey view and instead present master pub key on every
cosigner key/seed import page.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import QtQuick 2.6
|
import QtQuick 2.6
|
||||||
import QtQuick.Layouts 1.0
|
import QtQuick.Layouts 1.0
|
||||||
import QtQuick.Controls 2.1
|
import QtQuick.Controls 2.1
|
||||||
|
import QtQuick.Controls.Material 2.0
|
||||||
|
|
||||||
import org.electrum 1.0
|
import org.electrum 1.0
|
||||||
|
|
||||||
@@ -13,6 +14,7 @@ WizardComponent {
|
|||||||
|
|
||||||
property int cosigner: 0
|
property int cosigner: 0
|
||||||
property int participants: 0
|
property int participants: 0
|
||||||
|
property string multisigMasterPubkey: wizard_data['multisig_master_pubkey']
|
||||||
|
|
||||||
function apply() {
|
function apply() {
|
||||||
wizard_data['cosigner_keystore_type'] = keystoregroup.checkedButton.keystoretype
|
wizard_data['cosigner_keystore_type'] = keystoregroup.checkedButton.keystoretype
|
||||||
@@ -25,6 +27,52 @@ WizardComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
Label {
|
||||||
|
visible: cosigner
|
||||||
|
text: qsTr('Here is your master public key. Please share it with your cosigners')
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
|
||||||
|
TextHighlightPane {
|
||||||
|
visible: cosigner
|
||||||
|
Layout.fillWidth: true
|
||||||
|
padding: 0
|
||||||
|
leftPadding: constants.paddingSmall
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
width: parent.width
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: multisigMasterPubkey
|
||||||
|
font.pixelSize: constants.fontSizeMedium
|
||||||
|
font.family: FixedFont
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
ToolButton {
|
||||||
|
icon.source: '../../../icons/share.png'
|
||||||
|
icon.color: 'transparent'
|
||||||
|
onClicked: {
|
||||||
|
var dialog = app.genericShareDialog.createObject(app,
|
||||||
|
{ title: qsTr('Master public key'), text: multisigMasterPubkey }
|
||||||
|
)
|
||||||
|
dialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.preferredWidth: parent.width
|
||||||
|
Layout.preferredHeight: 1
|
||||||
|
Layout.topMargin: constants.paddingLarge
|
||||||
|
Layout.bottomMargin: constants.paddingLarge
|
||||||
|
visible: cosigner
|
||||||
|
color: Material.accentColor
|
||||||
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: qsTr('Add cosigner #%1 of %2 to your multi-sig wallet').arg(cosigner).arg(participants)
|
text: qsTr('Add cosigner #%1 of %2 to your multi-sig wallet').arg(cosigner).arg(participants)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import QtQuick 2.6
|
import QtQuick 2.6
|
||||||
import QtQuick.Layouts 1.0
|
import QtQuick.Layouts 1.0
|
||||||
import QtQuick.Controls 2.1
|
import QtQuick.Controls 2.1
|
||||||
|
import QtQuick.Controls.Material 2.0
|
||||||
|
|
||||||
import org.electrum 1.0
|
import org.electrum 1.0
|
||||||
|
|
||||||
@@ -13,6 +14,7 @@ WizardComponent {
|
|||||||
|
|
||||||
property int cosigner: 0
|
property int cosigner: 0
|
||||||
property int participants: 0
|
property int participants: 0
|
||||||
|
property string multisigMasterPubkey: wizard_data['multisig_master_pubkey']
|
||||||
|
|
||||||
function apply() {
|
function apply() {
|
||||||
if (cosigner) {
|
if (cosigner) {
|
||||||
@@ -45,6 +47,50 @@ WizardComponent {
|
|||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
|
Label {
|
||||||
|
visible: cosigner
|
||||||
|
text: qsTr('Here is your master public key. Please share it with your cosigners')
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
|
||||||
|
TextHighlightPane {
|
||||||
|
visible: cosigner
|
||||||
|
Layout.fillWidth: true
|
||||||
|
padding: 0
|
||||||
|
leftPadding: constants.paddingSmall
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
width: parent.width
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: multisigMasterPubkey
|
||||||
|
font.pixelSize: constants.fontSizeMedium
|
||||||
|
font.family: FixedFont
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
ToolButton {
|
||||||
|
icon.source: '../../../icons/share.png'
|
||||||
|
icon.color: 'transparent'
|
||||||
|
onClicked: {
|
||||||
|
var dialog = app.genericShareDialog.createObject(app,
|
||||||
|
{ title: qsTr('Master public key'), text: multisigMasterPubkey }
|
||||||
|
)
|
||||||
|
dialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.preferredWidth: parent.width
|
||||||
|
Layout.preferredHeight: 1
|
||||||
|
Layout.topMargin: constants.paddingLarge
|
||||||
|
Layout.bottomMargin: constants.paddingLarge
|
||||||
|
visible: cosigner
|
||||||
|
color: Material.accentColor
|
||||||
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: qsTr('Cosigner #%1 of %2').arg(cosigner).arg(participants)
|
text: qsTr('Cosigner #%1 of %2').arg(cosigner).arg(participants)
|
||||||
visible: cosigner
|
visible: cosigner
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ WizardComponent {
|
|||||||
property bool is2fa: false
|
property bool is2fa: false
|
||||||
property int cosigner: 0
|
property int cosigner: 0
|
||||||
property int participants: 0
|
property int participants: 0
|
||||||
|
property string multisigMasterPubkey: wizard_data['multisig_master_pubkey']
|
||||||
|
|
||||||
function apply() {
|
function apply() {
|
||||||
if (cosigner) {
|
if (cosigner) {
|
||||||
@@ -85,14 +86,61 @@ WizardComponent {
|
|||||||
|
|
||||||
Label {
|
Label {
|
||||||
Layout.columnSpan: 2
|
Layout.columnSpan: 2
|
||||||
text: qsTr('Cosigner #%1 of %2').arg(cosigner).arg(participants)
|
Layout.fillWidth: true
|
||||||
visible: cosigner
|
visible: cosigner
|
||||||
|
text: qsTr('Here is your master public key. Please share it with your cosigners')
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
|
||||||
|
TextHighlightPane {
|
||||||
|
visible: cosigner
|
||||||
|
Layout.columnSpan: 2
|
||||||
|
Layout.fillWidth: true
|
||||||
|
padding: 0
|
||||||
|
leftPadding: constants.paddingSmall
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
width: parent.width
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: multisigMasterPubkey
|
||||||
|
font.pixelSize: constants.fontSizeMedium
|
||||||
|
font.family: FixedFont
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
ToolButton {
|
||||||
|
icon.source: '../../../icons/share.png'
|
||||||
|
icon.color: 'transparent'
|
||||||
|
onClicked: {
|
||||||
|
var dialog = app.genericShareDialog.createObject(app,
|
||||||
|
{ title: qsTr('Master public key'), text: multisigMasterPubkey }
|
||||||
|
)
|
||||||
|
dialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.columnSpan: 2
|
||||||
|
Layout.preferredWidth: parent.width
|
||||||
|
Layout.preferredHeight: 1
|
||||||
|
Layout.topMargin: constants.paddingLarge
|
||||||
|
Layout.bottomMargin: constants.paddingLarge
|
||||||
|
visible: cosigner
|
||||||
|
color: Material.accentColor
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
|
Layout.columnSpan: 2
|
||||||
|
visible: cosigner
|
||||||
|
text: qsTr('Cosigner #%1 of %2').arg(cosigner).arg(participants)
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
visible: !is2fa
|
visible: !is2fa
|
||||||
text: qsTr('Seed Type')
|
text: qsTr('Seed Type')
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
}
|
||||||
ComboBox {
|
ComboBox {
|
||||||
id: seed_variant_cb
|
id: seed_variant_cb
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import "../controls"
|
|||||||
WizardComponent {
|
WizardComponent {
|
||||||
valid: true
|
valid: true
|
||||||
|
|
||||||
property string masterPubkey: ''
|
property string masterPubkey: wizard_data['multisig_master_pubkey']
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -48,17 +48,4 @@ WizardComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitcoin {
|
|
||||||
id: bitcoin
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
if ('master_key' in wizard_data) {
|
|
||||||
masterPubkey = bitcoin.getMultisigMasterPubkeyFromKey(wizard_data['master_key'])
|
|
||||||
} else if (wizard_data['seed_variant'] == 'electrum') {
|
|
||||||
masterPubkey = bitcoin.getMultisigMasterPubkeyFromSeed(wizard_data['seed_variant'], wizard_data['seed'], wizard_data['seed_extra_words'])
|
|
||||||
} else {
|
|
||||||
masterPubkey = bitcoin.getMultisigMasterPubkeyFromSeed(wizard_data['seed_variant'], wizard_data['seed'], wizard_data['seed_extra_words'], wizard_data['derivation_path'])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,21 +165,3 @@ class QEBitcoin(QObject):
|
|||||||
@pyqtSlot(str, result=bool)
|
@pyqtSlot(str, result=bool)
|
||||||
def isPrivateKeyList(self, csv: str):
|
def isPrivateKeyList(self, csv: str):
|
||||||
return keystore.is_private_key_list(csv)
|
return keystore.is_private_key_list(csv)
|
||||||
|
|
||||||
@pyqtSlot(str, result=str)
|
|
||||||
def getMultisigMasterPubkeyFromKey(self, key):
|
|
||||||
return keystore.from_master_key(key).get_master_public_key()
|
|
||||||
|
|
||||||
@pyqtSlot(str, str, str, result=str)
|
|
||||||
@pyqtSlot(str, str, str, str, result=str)
|
|
||||||
def getMultisigMasterPubkeyFromSeed(self, seed_variant, seed, seed_extra_words, derivation_path = None):
|
|
||||||
if seed_variant == 'electrum':
|
|
||||||
k = keystore.from_seed(seed, seed_extra_words, True)
|
|
||||||
elif seed_variant == 'bip39':
|
|
||||||
root_seed = keystore.bip39_to_seed(seed, seed_extra_words)
|
|
||||||
derivation = normalize_bip32_derivation(derivation_path)
|
|
||||||
k = keystore.from_bip43_rootseed(root_seed, derivation, xtype='p2wsh')
|
|
||||||
else:
|
|
||||||
raise Exception(f'Unsupported seed variant {seed_variant}')
|
|
||||||
|
|
||||||
return k.get_master_public_key()
|
|
||||||
|
|||||||
@@ -510,8 +510,6 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
|
|||||||
def broadcast(self, tx):
|
def broadcast(self, tx):
|
||||||
assert tx.is_complete()
|
assert tx.is_complete()
|
||||||
|
|
||||||
# network = self.wallet.network # TODO not always defined?
|
|
||||||
|
|
||||||
def broadcast_thread():
|
def broadcast_thread():
|
||||||
try:
|
try:
|
||||||
self._logger.info('running broadcast in thread')
|
self._logger.info('running broadcast in thread')
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class QENewWalletWizard(NewWalletWizard, QEAbstractWizard):
|
|||||||
'bip39_refine': { 'gui': 'WCBIP39Refine' },
|
'bip39_refine': { 'gui': 'WCBIP39Refine' },
|
||||||
'have_master_key': { 'gui': 'WCHaveMasterKey' },
|
'have_master_key': { 'gui': 'WCHaveMasterKey' },
|
||||||
'multisig': { 'gui': 'WCMultisig' },
|
'multisig': { 'gui': 'WCMultisig' },
|
||||||
'multisig_show_masterpubkey': { 'gui': 'WCShowMasterPubkey' },
|
# 'multisig_show_masterpubkey': { 'gui': 'WCShowMasterPubkey' },
|
||||||
'multisig_cosigner_keystore': { 'gui': 'WCCosignerKeystore' },
|
'multisig_cosigner_keystore': { 'gui': 'WCCosignerKeystore' },
|
||||||
'multisig_cosigner_key': { 'gui': 'WCHaveMasterKey' },
|
'multisig_cosigner_key': { 'gui': 'WCHaveMasterKey' },
|
||||||
'multisig_cosigner_seed': { 'gui': 'WCHaveSeed' },
|
'multisig_cosigner_seed': { 'gui': 'WCHaveSeed' },
|
||||||
|
|||||||
@@ -149,26 +149,30 @@ 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',
|
||||||
|
'accept': self.maybe_master_pubkey,
|
||||||
'last': lambda v,d: self.is_single_password() and not self.is_multisig(d)
|
'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,
|
||||||
|
'accept': self.maybe_master_pubkey,
|
||||||
'last': lambda v,d: self.is_single_password() and not self.is_bip39_seed(d) and not self.is_multisig(d)
|
'last': lambda v,d: self.is_single_password() and not self.is_bip39_seed(d) and not self.is_multisig(d)
|
||||||
},
|
},
|
||||||
'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',
|
||||||
|
'accept': self.maybe_master_pubkey,
|
||||||
'last': lambda v,d: self.is_single_password() and not self.is_multisig(d)
|
'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',
|
||||||
|
'accept': self.maybe_master_pubkey,
|
||||||
'last': lambda v,d: self.is_single_password() and not self.is_multisig(d)
|
'last': lambda v,d: self.is_single_password() and not self.is_multisig(d)
|
||||||
},
|
},
|
||||||
'multisig': {
|
'multisig': {
|
||||||
'next': 'keystore_type'
|
'next': 'keystore_type'
|
||||||
},
|
},
|
||||||
'multisig_show_masterpubkey': {
|
# 'multisig_show_masterpubkey': {
|
||||||
'next': 'multisig_cosigner_keystore'
|
# 'next': 'multisig_cosigner_keystore'
|
||||||
},
|
# },
|
||||||
'multisig_cosigner_keystore': { # this view should set 'multisig_current_cosigner'
|
'multisig_cosigner_keystore': { # this view should set 'multisig_current_cosigner'
|
||||||
'next': self.on_cosigner_keystore_type
|
'next': self.on_cosigner_keystore_type
|
||||||
},
|
},
|
||||||
@@ -229,10 +233,18 @@ class NewWalletWizard(AbstractWizard):
|
|||||||
if self.is_bip39_seed(wizard_data):
|
if self.is_bip39_seed(wizard_data):
|
||||||
return 'bip39_refine'
|
return 'bip39_refine'
|
||||||
elif self.is_multisig(wizard_data):
|
elif self.is_multisig(wizard_data):
|
||||||
return 'multisig_show_masterpubkey'
|
return 'multisig_cosigner_keystore'
|
||||||
else:
|
else:
|
||||||
return 'wallet_password'
|
return 'wallet_password'
|
||||||
|
|
||||||
|
def maybe_master_pubkey(self, wizard_data):
|
||||||
|
self._logger.info('maybe_master_pubkey')
|
||||||
|
if self.is_bip39_seed(wizard_data) and 'derivation_path' not in wizard_data:
|
||||||
|
self._logger.info('maybe_master_pubkey2')
|
||||||
|
return
|
||||||
|
|
||||||
|
wizard_data['multisig_master_pubkey'] = self.keystore_from_data(wizard_data).get_master_public_key()
|
||||||
|
|
||||||
def on_cosigner_keystore_type(self, wizard_data):
|
def on_cosigner_keystore_type(self, wizard_data):
|
||||||
t = wizard_data['cosigner_keystore_type']
|
t = wizard_data['cosigner_keystore_type']
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user