Browse Source

qml: support create & save transaction on watch-only wallet, refactor showExport and supply

relevant help text when sharing a transaction
master
Sander van Grieken 3 years ago
parent
commit
c08ca94591
  1. 9
      electrum/gui/qml/components/ExportTxDialog.qml
  2. 33
      electrum/gui/qml/components/TxDetails.qml
  3. 50
      electrum/gui/qml/components/WalletMainView.qml
  4. 7
      electrum/gui/qml/qetxdetails.py
  5. 21
      electrum/gui/qml/qetxfinalizer.py
  6. 13
      electrum/gui/qml/qewallet.py

9
electrum/gui/qml/components/ExportTxDialog.qml

@ -8,9 +8,7 @@ import "controls"
ElDialog {
id: dialog
property QtObject txdetails
property string text
required property string text
property string text_qr
// if text_qr is undefined text will be used
property string text_help
@ -97,9 +95,4 @@ ElDialog {
}
}
}
Component.onCompleted: {
text = dialog.txdetails.serializedTx(false)
text_qr = dialog.txdetails.serializedTx(true)
}
}

33
electrum/gui/qml/components/TxDetails.qml

@ -24,14 +24,6 @@ Pane {
app.stack.pop()
}
function showExport(helptext) {
var dialog = exportTxDialog.createObject(root, {
txdetails: txdetails,
text_help: helptext
})
dialog.open()
}
ColumnLayout {
anchors.fill: parent
spacing: 0
@ -378,9 +370,24 @@ Pane {
Layout.preferredWidth: 1
icon.source: '../../icons/qrcode_white.png'
text: qsTr('Share')
enabled: !txdetails.isUnrelated
onClicked: {
var dialog = exportTxDialog.createObject(root, { txdetails: txdetails })
dialog.open()
var msg = ''
if (txdetails.isComplete) {
// TODO: iff offline wallet?
// TODO: or also if just temporarily offline?
msg = qsTr('This transaction is complete. Please share it with an online device')
} else if (txdetails.wallet.isWatchOnly) {
msg = qsTr('This transaction should be signed. Present this QR code to the signing device')
} else if (txdetails.wallet.isMultisig && txdetails.wallet.walletType != '2fa') {
if (txdetails.canSign) {
msg = qsTr('Note: this wallet can sign, but has not signed this transaction yet')
} else {
msg = qsTr('Transaction is partially signed by this wallet. Present this QR code to the next co-signer')
}
}
app.stack.getRoot().showExport(txdetails.getSerializedTx(false), txdetails.getSerializedTx(true), msg)
}
}
@ -522,10 +529,4 @@ Pane {
}
}
Component {
id: exportTxDialog
ExportTxDialog {
onClosed: destroy()
}
}
}

50
electrum/gui/qml/components/WalletMainView.qml

@ -50,6 +50,19 @@ Item {
}
}
function showExportByTxid(txid, helptext) {
showExport(Daemon.currentWallet.getSerializedTx(txid, false), Daemon.currentWallet.getSerializedTx(txid, true), helptext)
}
function showExport(data, data_qr, helptext) {
var dialog = exportTxDialog.createObject(app, {
text: data,
text_qr: data_qr,
text_help: helptext
})
dialog.open()
}
property QtObject menu: Menu {
parent: Overlay.overlay
dim: true
@ -251,7 +264,7 @@ Item {
if (code == 'ln') {
var dialog = app.messageDialog.createObject(app, {text: error, yesno: true})
dialog.yesClicked.connect(function() {
createRequest(true, false)
createRequest(true, false)
})
} else if (code == 'reuse_addr') {
var dialog = app.messageDialog.createObject(app, {text: error, yesno: true})
@ -287,6 +300,8 @@ Item {
Component {
id: invoiceDialog
InvoiceDialog {
id: _invoiceDialog
width: parent.width
height: parent.height
@ -300,7 +315,11 @@ Item {
var canComplete = !Daemon.currentWallet.isWatchOnly && Daemon.currentWallet.canSignWithoutCosigner
dialog.txaccepted.connect(function() {
if (!canComplete) {
dialog.finalizer.signAndSave()
if (Daemon.currentWallet.isWatchOnly) {
dialog.finalizer.save()
} else {
dialog.finalizer.signAndSave()
}
} else {
dialog.finalizer.signAndSend()
}
@ -317,6 +336,13 @@ Item {
}
onClosed: destroy()
Connections {
target: Daemon.currentWallet
function onSaveTxSuccess(txid) {
_invoiceDialog.close()
}
}
}
}
@ -371,7 +397,7 @@ Item {
console.log('rejected')
}
onClosed: destroy()
}
}
}
Component {
@ -393,9 +419,13 @@ Item {
wallet: Daemon.currentWallet
canRbf: true
onFinishedSave: {
// tx was (partially) signed and saved. Show QR for co-signers or online wallet
var page = app.stack.push(Qt.resolvedUrl('TxDetails.qml'), { txid: txid })
page.showExport(qsTr('Transaction created and partially signed by this wallet. Present this QR code to the next co-signer'))
if (wallet.isWatchOnly) {
// tx was saved. Show QR for signer(s)
showExportByTxid(txid, qsTr('Transaction created. Present this QR code to the signing device'))
} else {
// tx was (partially) signed and saved. Show QR for co-signers or online wallet
showExportByTxid(txid, qsTr('Transaction created and partially signed by this wallet. Present this QR code to the next co-signer'))
}
_confirmPaymentDialog.destroy()
}
}
@ -432,5 +462,13 @@ Item {
onClosed: destroy()
}
}
Component {
id: exportTxDialog
ExportTxDialog {
onClosed: destroy()
}
}
}

7
electrum/gui/qml/qetxdetails.py

@ -393,8 +393,9 @@ class QETxDetails(QObject, QtEventListener):
@pyqtSlot(result=str)
@pyqtSlot(bool, result=str)
def serializedTx(self, for_qr=False):
def getSerializedTx(self, for_qr=False):
tx = self._tx
if for_qr:
return self._tx.to_qr_data()
return tx.to_qr_data()
else:
return str(self._tx)
return str(tx)

21
electrum/gui/qml/qetxfinalizer.py

@ -341,6 +341,15 @@ class QETxFinalizer(TxFeeSlider):
self._valid = True
self.validChanged.emit()
@pyqtSlot()
def save(self):
if not self._valid or not self._tx:
self._logger.debug('no valid tx')
return
if self._wallet.save_tx(self._tx):
self.finishedSave.emit(self._tx.txid())
@pyqtSlot()
def signAndSend(self):
if not self._valid or not self._tx:
@ -379,18 +388,10 @@ class QETxFinalizer(TxFeeSlider):
self._logger.debug('onSigned')
self._wallet.transactionSigned.disconnect(self.onSigned)
if not self._wallet.wallet.adb.add_transaction(self._tx):
if not self._wallet.save_tx(self._tx):
self._logger.error('Could not save tx')
self.finishedSave.emit(self._tx.txid())
@pyqtSlot(result=str)
@pyqtSlot(bool, result=str)
def serializedTx(self, for_qr=False):
if for_qr:
return self._tx.to_qr_data()
else:
return str(self._tx)
self.finishedSave.emit(self._tx.txid())
# mixin for watching an existing TX based on its txid for verified event
# requires self._wallet to contain a QEWallet instance

13
electrum/gui/qml/qewallet.py

@ -328,6 +328,10 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
def walletType(self):
return self.wallet.wallet_type
@pyqtProperty(bool, notify=dataChanged)
def isMultisig(self):
return isinstance(self.wallet, Multisig_Wallet)
@pyqtProperty(bool, notify=dataChanged)
def hasSeed(self):
return self.wallet.has_seed()
@ -723,3 +727,12 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
self._seed = ''
self.dataChanged.emit()
@pyqtSlot(str, result=str)
@pyqtSlot(str, bool, result=str)
def getSerializedTx(self, txid, for_qr=False):
tx = self.wallet.db.get_transaction(txid)
if for_qr:
return tx.to_qr_data()
else:
return str(tx)

Loading…
Cancel
Save