qml: add initial sign and broadcast feature to TxDetails/qetxdetails
This commit is contained in:
@@ -277,6 +277,7 @@ Pane {
|
|||||||
ToolButton {
|
ToolButton {
|
||||||
icon.source: '../../icons/share.png'
|
icon.source: '../../icons/share.png'
|
||||||
icon.color: 'transparent'
|
icon.color: 'transparent'
|
||||||
|
enabled: root.txid
|
||||||
onClicked: {
|
onClicked: {
|
||||||
var dialog = app.genericShareDialog.createObject(root,
|
var dialog = app.genericShareDialog.createObject(root,
|
||||||
{ title: qsTr('Transaction ID'), text: root.txid }
|
{ 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_save_as_local = False
|
||||||
_can_remove = False
|
_can_remove = False
|
||||||
_is_unrelated = False
|
_is_unrelated = False
|
||||||
|
_is_complete = False
|
||||||
|
|
||||||
_is_mined = False
|
_is_mined = False
|
||||||
|
|
||||||
@@ -184,6 +185,10 @@ class QETxDetails(QObject):
|
|||||||
def isUnrelated(self):
|
def isUnrelated(self):
|
||||||
return self._is_unrelated
|
return self._is_unrelated
|
||||||
|
|
||||||
|
@pyqtProperty(bool, notify=detailsChanged)
|
||||||
|
def isComplete(self):
|
||||||
|
return self._is_complete
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
if self._wallet is None:
|
if self._wallet is None:
|
||||||
self._logger.error('wallet undefined')
|
self._logger.error('wallet undefined')
|
||||||
@@ -230,6 +235,7 @@ class QETxDetails(QObject):
|
|||||||
else:
|
else:
|
||||||
self._lnamount.satsInt = 0
|
self._lnamount.satsInt = 0
|
||||||
|
|
||||||
|
self._is_complete = self._tx.is_complete()
|
||||||
self._is_unrelated = txinfo.amount is None and self._lnamount.isEmpty
|
self._is_unrelated = txinfo.amount is None and self._lnamount.isEmpty
|
||||||
self._is_lightning_funding_tx = txinfo.is_lightning_funding_tx
|
self._is_lightning_funding_tx = txinfo.is_lightning_funding_tx
|
||||||
self._can_bump = txinfo.can_bump
|
self._can_bump = txinfo.can_bump
|
||||||
@@ -252,3 +258,28 @@ class QETxDetails(QObject):
|
|||||||
self._confirmations = tx_mined_info.conf
|
self._confirmations = tx_mined_info.conf
|
||||||
self._txpos = tx_mined_info.txpos
|
self._txpos = tx_mined_info.txpos
|
||||||
self._header_hash = tx_mined_info.header_hash
|
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'])
|
paymentSucceeded = pyqtSignal([str], arguments=['key'])
|
||||||
paymentFailed = pyqtSignal([str,str], arguments=['key','reason'])
|
paymentFailed = pyqtSignal([str,str], arguments=['key','reason'])
|
||||||
requestNewPassword = pyqtSignal()
|
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)
|
_network_signal = pyqtSignal(str, object)
|
||||||
|
|
||||||
@@ -399,17 +402,31 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
|
|||||||
|
|
||||||
use_rbf = bool(self.wallet.config.get('use_rbf', True))
|
use_rbf = bool(self.wallet.config.get('use_rbf', True))
|
||||||
tx.set_rbf(use_rbf)
|
tx.set_rbf(use_rbf)
|
||||||
self.sign_and_broadcast(tx)
|
self.sign(tx, broadcast=True)
|
||||||
|
|
||||||
@auth_protect
|
@auth_protect
|
||||||
def sign_and_broadcast(self, tx):
|
def sign(self, tx, *, broadcast: bool = False):
|
||||||
def cb(result):
|
|
||||||
self._logger.info('signing was succesful? %s' % str(result))
|
|
||||||
tx = self.wallet.sign_transaction(tx, None)
|
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():
|
if not tx.is_complete():
|
||||||
self._logger.info('tx not complete')
|
self._logger.info('tx not complete')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if broadcast:
|
||||||
|
self.broadcast(tx)
|
||||||
|
|
||||||
|
def broadcast(self, tx):
|
||||||
|
assert tx.is_complete()
|
||||||
|
|
||||||
self.network = self.wallet.network # TODO not always defined?
|
self.network = self.wallet.network # TODO not always defined?
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -417,13 +434,14 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
|
|||||||
self.network.run_from_another_thread(self.network.broadcast_transaction(tx))
|
self.network.run_from_another_thread(self.network.broadcast_transaction(tx))
|
||||||
self._logger.info('broadcast submit done')
|
self._logger.info('broadcast submit done')
|
||||||
except TxBroadcastError as e:
|
except TxBroadcastError as e:
|
||||||
self._logger.info(e)
|
self.broadcastFailed.emit(tx.txid(),'',repr(e))
|
||||||
return
|
self._logger.error(e)
|
||||||
except BestEffortRequestFailed as e:
|
except BestEffortRequestFailed as e:
|
||||||
self._logger.info(e)
|
self.broadcastFailed.emit(tx.txid(),'',repr(e))
|
||||||
return
|
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()
|
paymentAuthRejected = pyqtSignal()
|
||||||
def ln_auth_rejected(self):
|
def ln_auth_rejected(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user