qml: add initial sign and broadcast feature to TxDetails/qetxdetails
This commit is contained in:
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user