qml: accept raw tx from send page paste/qrscan and show TxDetails
This commit is contained in:
@@ -63,7 +63,16 @@ Pane {
|
||||
icon.source: '../../icons/paste.png'
|
||||
icon.height: constants.iconSizeMedium
|
||||
icon.width: constants.iconSizeMedium
|
||||
onClicked: invoice.recipient = AppController.clipboardToText()
|
||||
onClicked: {
|
||||
var text = AppController.clipboardToText()
|
||||
if (bitcoin.verify_raw_tx(text)) {
|
||||
app.stack.push(Qt.resolvedUrl('TxDetails.qml'),
|
||||
{ rawtx: text }
|
||||
)
|
||||
} else {
|
||||
invoice.recipient = text
|
||||
}
|
||||
}
|
||||
}
|
||||
ToolButton {
|
||||
icon.source: '../../icons/qrcode.png'
|
||||
@@ -73,7 +82,14 @@ Pane {
|
||||
onClicked: {
|
||||
var page = app.stack.push(Qt.resolvedUrl('Scan.qml'))
|
||||
page.onFound.connect(function() {
|
||||
invoice.recipient = page.scanData
|
||||
var text = page.scanData
|
||||
if (bitcoin.verify_raw_tx(text)) {
|
||||
app.stack.push(Qt.resolvedUrl('TxDetails.qml'),
|
||||
{ rawtx: text }
|
||||
)
|
||||
} else {
|
||||
invoice.recipient = text
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -379,4 +395,7 @@ Pane {
|
||||
}
|
||||
}
|
||||
|
||||
Bitcoin {
|
||||
id: bitcoin
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ Pane {
|
||||
property string title: qsTr("Transaction details")
|
||||
|
||||
property string txid
|
||||
property string rawtx
|
||||
|
||||
property alias label: txdetails.label
|
||||
|
||||
@@ -50,9 +51,24 @@ Pane {
|
||||
width: parent.width
|
||||
columns: 2
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.columnSpan: 2
|
||||
visible: txdetails.isUnrelated
|
||||
Image {
|
||||
source: '../../icons/warning.png'
|
||||
Layout.preferredWidth: constants.iconSizeSmall
|
||||
Layout.preferredHeight: constants.iconSizeSmall
|
||||
}
|
||||
Label {
|
||||
text: qsTr('Transaction is unrelated to this wallet')
|
||||
color: Material.accentColor
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
visible: txdetails.lnAmount.satsInt == 0
|
||||
visible: !txdetails.isUnrelated && txdetails.lnAmount.satsInt == 0
|
||||
text: txdetails.amount.satsInt > 0
|
||||
? qsTr('Amount received')
|
||||
: qsTr('Amount sent')
|
||||
@@ -61,7 +77,7 @@ Pane {
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
visible: txdetails.lnAmount.satsInt != 0
|
||||
visible: !txdetails.isUnrelated && txdetails.lnAmount.satsInt != 0
|
||||
text: txdetails.lnAmount.satsInt > 0
|
||||
? qsTr('Amount received in channels')
|
||||
: qsTr('Amount withdrawn from channels')
|
||||
@@ -70,6 +86,7 @@ Pane {
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
visible: !txdetails.isUnrelated
|
||||
Layout.fillWidth: true
|
||||
Label {
|
||||
visible: txdetails.lnAmount.satsInt == 0
|
||||
@@ -88,30 +105,30 @@ Pane {
|
||||
}
|
||||
|
||||
Item {
|
||||
visible: Daemon.fx.enabled; Layout.preferredWidth: 1; Layout.preferredHeight: 1
|
||||
visible: !txdetails.isUnrelated && Daemon.fx.enabled; Layout.preferredWidth: 1; Layout.preferredHeight: 1
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: Daemon.fx.enabled && txdetails.lnAmount.satsInt == 0
|
||||
visible: !txdetails.isUnrelated && Daemon.fx.enabled && txdetails.lnAmount.satsInt == 0
|
||||
text: Daemon.fx.fiatValue(txdetails.amount, false) + ' ' + Daemon.fx.fiatCurrency
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: Daemon.fx.enabled && txdetails.lnAmount.satsInt != 0
|
||||
visible: !txdetails.isUnrelated && Daemon.fx.enabled && txdetails.lnAmount.satsInt != 0
|
||||
text: Daemon.fx.fiatValue(txdetails.lnAmount, false) + ' ' + Daemon.fx.fiatCurrency
|
||||
}
|
||||
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
visible: txdetails.amount.satsInt < 0
|
||||
visible: txdetails.fee.satsInt != 0
|
||||
text: qsTr('Transaction fee')
|
||||
color: Material.accentColor
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
visible: txdetails.amount.satsInt < 0
|
||||
visible: txdetails.fee.satsInt != 0
|
||||
Label {
|
||||
text: Config.formatSats(txdetails.fee)
|
||||
font.family: FixedFont
|
||||
@@ -135,12 +152,12 @@ Pane {
|
||||
Label {
|
||||
text: qsTr('Mempool depth')
|
||||
color: Material.accentColor
|
||||
visible: !txdetails.isMined
|
||||
visible: !txdetails.isMined && txdetails.canBroadcast
|
||||
}
|
||||
|
||||
Label {
|
||||
text: txdetails.mempoolDepth
|
||||
visible: !txdetails.isMined
|
||||
visible: !txdetails.isMined && txdetails.canBroadcast
|
||||
}
|
||||
|
||||
Label {
|
||||
@@ -314,6 +331,7 @@ Pane {
|
||||
id: txdetails
|
||||
wallet: Daemon.currentWallet
|
||||
txid: root.txid
|
||||
rawtx: root.rawtx
|
||||
onLabelChanged: root.detailsChanged()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,9 @@ from electrum.bip32 import is_bip32_derivation, xpub_type
|
||||
from electrum.logging import get_logger
|
||||
from electrum.slip39 import decode_mnemonic, Slip39Error
|
||||
from electrum.util import parse_URI, create_bip21_uri, InvalidBitcoinURI, get_asyncio_loop
|
||||
from .qetypes import QEAmount
|
||||
from electrum.transaction import tx_from_any
|
||||
|
||||
from .qetypes import QEAmount
|
||||
|
||||
class QEBitcoin(QObject):
|
||||
def __init__(self, config, parent=None):
|
||||
@@ -152,3 +153,11 @@ class QEBitcoin(QObject):
|
||||
extra_params['exp'] = str(expiry)
|
||||
|
||||
return create_bip21_uri(address, satoshis.satsInt, message, extra_query_params=extra_params)
|
||||
|
||||
@pyqtSlot(str, result=bool)
|
||||
def verify_raw_tx(self, rawtx):
|
||||
try:
|
||||
tx_from_any(rawtx)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
@@ -2,6 +2,7 @@ from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject
|
||||
|
||||
from electrum.logging import get_logger
|
||||
from electrum.util import format_time
|
||||
from electrum.transaction import tx_from_any
|
||||
|
||||
from .qewallet import QEWallet
|
||||
from .qetypes import QEAmount
|
||||
@@ -13,9 +14,12 @@ class QETxDetails(QObject):
|
||||
_logger = get_logger(__name__)
|
||||
|
||||
_wallet = None
|
||||
_txid = None
|
||||
_txid = ''
|
||||
_rawtx = ''
|
||||
_label = ''
|
||||
|
||||
_tx = None
|
||||
|
||||
_status = ''
|
||||
_amount = QEAmount(amount_sat=0)
|
||||
_lnamount = QEAmount(amount_sat=0)
|
||||
@@ -30,6 +34,7 @@ class QETxDetails(QObject):
|
||||
_can_cpfp = False
|
||||
_can_save_as_local = False
|
||||
_can_remove = False
|
||||
_is_unrelated = False
|
||||
|
||||
_is_mined = False
|
||||
|
||||
@@ -67,6 +72,22 @@ class QETxDetails(QObject):
|
||||
self.txidChanged.emit()
|
||||
self.update()
|
||||
|
||||
@pyqtProperty(str, notify=detailsChanged)
|
||||
def rawtx(self):
|
||||
return self._rawtx
|
||||
|
||||
@rawtx.setter
|
||||
def rawtx(self, rawtx: str):
|
||||
if self._rawtx != rawtx:
|
||||
self._logger.debug('rawtx set -> %s' % rawtx)
|
||||
self._rawtx = rawtx
|
||||
try:
|
||||
self._tx = tx_from_any(rawtx, deserialize=True)
|
||||
self._logger.debug('tx type is %s' % str(type(self._tx)))
|
||||
self.txid = self._tx.txid() # triggers update()
|
||||
except Exception as e:
|
||||
self._logger.error(repr(e))
|
||||
|
||||
labelChanged = pyqtSignal()
|
||||
@pyqtProperty(str, notify=labelChanged)
|
||||
def label(self):
|
||||
@@ -159,24 +180,29 @@ class QETxDetails(QObject):
|
||||
def canRemove(self):
|
||||
return self._can_remove
|
||||
|
||||
@pyqtProperty(bool, notify=detailsChanged)
|
||||
def isUnrelated(self):
|
||||
return self._is_unrelated
|
||||
|
||||
def update(self):
|
||||
if self._wallet is None:
|
||||
self._logger.error('wallet undefined')
|
||||
return
|
||||
|
||||
# abusing get_input_tx to get tx from txid
|
||||
tx = self._wallet.wallet.get_input_tx(self._txid)
|
||||
if not self._rawtx:
|
||||
# abusing get_input_tx to get tx from txid
|
||||
self._tx = self._wallet.wallet.get_input_tx(self._txid)
|
||||
|
||||
#self._logger.debug(repr(tx.to_json()))
|
||||
#self._logger.debug(repr(self._tx.to_json()))
|
||||
|
||||
self._inputs = list(map(lambda x: x.to_json(), tx.inputs()))
|
||||
self._inputs = list(map(lambda x: x.to_json(), self._tx.inputs()))
|
||||
self._outputs = list(map(lambda x: {
|
||||
'address': x.get_ui_address_str(),
|
||||
'value': QEAmount(amount_sat=x.value),
|
||||
'is_mine': self._wallet.wallet.is_mine(x.get_ui_address_str())
|
||||
}, tx.outputs()))
|
||||
}, self._tx.outputs()))
|
||||
|
||||
txinfo = self._wallet.wallet.get_tx_info(tx)
|
||||
txinfo = self._wallet.wallet.get_tx_info(self._tx)
|
||||
|
||||
#self._logger.debug(repr(txinfo))
|
||||
|
||||
@@ -204,6 +230,7 @@ class QETxDetails(QObject):
|
||||
else:
|
||||
self._lnamount.satsInt = 0
|
||||
|
||||
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
|
||||
self._can_dscancel = txinfo.can_dscancel
|
||||
|
||||
Reference in New Issue
Block a user