Browse Source

qml: add initial sign and broadcast feature to TxDetails/qetxdetails

patch-4
Sander van Grieken 2 years ago
parent
commit
742012aee3
  1. 15
      electrum/gui/qml/components/TxDetails.qml
  2. 31
      electrum/gui/qml/qetxdetails.py
  3. 36
      electrum/gui/qml/qewallet.py

15
electrum/gui/qml/components/TxDetails.qml

@ -277,6 +277,7 @@ Pane {
ToolButton {
icon.source: '../../icons/share.png'
icon.color: 'transparent'
enabled: root.txid
onClicked: {
var dialog = app.genericShareDialog.createObject(root,
{ title: qsTr('Transaction ID'), text: root.txid }
@ -324,6 +325,20 @@ Pane {
}
}
RowLayout {
visible: !txdetails.isMined && !txdetails.isUnrelated
Layout.columnSpan: 2
Button {
text: qsTr('Sign')
enabled: !txdetails.isComplete
onClicked: txdetails.sign()
}
Button {
text: qsTr('Broadcast')
enabled: txdetails.canBroadcast
onClicked: txdetails.broadcast()
}
}
}
}

31
electrum/gui/qml/qetxdetails.py

@ -35,6 +35,7 @@ class QETxDetails(QObject):
_can_save_as_local = False
_can_remove = False
_is_unrelated = False
_is_complete = False
_is_mined = False
@ -184,6 +185,10 @@ class QETxDetails(QObject):
def isUnrelated(self):
return self._is_unrelated
@pyqtProperty(bool, notify=detailsChanged)
def isComplete(self):
return self._is_complete
def update(self):
if self._wallet is None:
self._logger.error('wallet undefined')
@ -230,6 +235,7 @@ class QETxDetails(QObject):
else:
self._lnamount.satsInt = 0
self._is_complete = self._tx.is_complete()
self._is_unrelated = txinfo.amount is None and self._lnamount.isEmpty
self._is_lightning_funding_tx = txinfo.is_lightning_funding_tx
self._can_bump = txinfo.can_bump
@ -252,3 +258,28 @@ class QETxDetails(QObject):
self._confirmations = tx_mined_info.conf
self._txpos = tx_mined_info.txpos
self._header_hash = tx_mined_info.header_hash
@pyqtSlot()
def sign(self):
try:
self._wallet.transactionSigned.disconnect(self.onSigned)
except:
pass
self._wallet.transactionSigned.connect(self.onSigned)
self._wallet.sign(self._tx)
# side-effect: signing updates self._tx
# we rely on this for broadcast
@pyqtSlot(str)
def onSigned(self, txid):
if txid != self._txid:
return
self._logger.debug('onSigned')
self._wallet.transactionSigned.disconnect(self.onSigned)
self.update()
@pyqtSlot()
def broadcast(self):
assert self._tx.is_complete()
self._wallet.broadcast(self._tx)

36
electrum/gui/qml/qewallet.py

@ -59,6 +59,9 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
paymentSucceeded = pyqtSignal([str], arguments=['key'])
paymentFailed = pyqtSignal([str,str], arguments=['key','reason'])
requestNewPassword = pyqtSignal()
transactionSigned = pyqtSignal([str], arguments=['txid'])
#broadcastSucceeded = pyqtSignal([str], arguments=['txid'])
broadcastFailed = pyqtSignal([str,str,str], arguments=['txid','code','reason'])
_network_signal = pyqtSignal(str, object)
@ -399,17 +402,31 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
use_rbf = bool(self.wallet.config.get('use_rbf', True))
tx.set_rbf(use_rbf)
self.sign_and_broadcast(tx)
self.sign(tx, broadcast=True)
@auth_protect
def sign_and_broadcast(self, tx):
def cb(result):
self._logger.info('signing was succesful? %s' % str(result))
def sign(self, tx, *, broadcast: bool = False):
tx = self.wallet.sign_transaction(tx, None)
if tx is None:
self._logger.info('did not sign')
return
txid = tx.txid()
self._logger.debug(f'txid={txid}')
self.transactionSigned.emit(txid)
if not tx.is_complete():
self._logger.info('tx not complete')
return
if broadcast:
self.broadcast(tx)
def broadcast(self, tx):
assert tx.is_complete()
self.network = self.wallet.network # TODO not always defined?
try:
@ -417,13 +434,14 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
self.network.run_from_another_thread(self.network.broadcast_transaction(tx))
self._logger.info('broadcast submit done')
except TxBroadcastError as e:
self._logger.info(e)
return
self.broadcastFailed.emit(tx.txid(),'',repr(e))
self._logger.error(e)
except BestEffortRequestFailed as e:
self._logger.info(e)
return
self.broadcastFailed.emit(tx.txid(),'',repr(e))
self._logger.error(e)
return
#TODO: properly catch server side errors, e.g. bad-txns-inputs-missingorspent
#might need callback from network.py
paymentAuthRejected = pyqtSignal()
def ln_auth_rejected(self):

Loading…
Cancel
Save