1
0

qml: when opening channel, validate and show user feedback if amount outside acceptable range

This commit is contained in:
Sander van Grieken
2025-04-07 13:08:05 +02:00
parent 746c13b32d
commit 8b54f6445c
2 changed files with 47 additions and 22 deletions

View File

@@ -201,7 +201,6 @@ ElDialog {
if (activeFocus) {
channelopener.amount.isMax = checked
if (checked) {
maxAmountMessage.text = ''
channelopener.updateMaxAmount()
}
}
@@ -232,11 +231,12 @@ ElDialog {
Item { visible: Daemon.fx.enabled ; height: 1; width: 1 }
InfoTextArea {
id: warning
Layout.topMargin: constants.paddingMedium
Layout.fillWidth: true
Layout.columnSpan: 3
id: maxAmountMessage
visible: is_max.checked && text
text: channelopener.warning
visible: text
compact: true
}
@@ -321,9 +321,6 @@ ElDialog {
// TODO: handle incomplete TX
root.close()
}
onMaxAmountMessage: (message) => {
maxAmountMessage.text = message
}
}
FontMetrics {

View File

@@ -9,6 +9,7 @@ from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject
from electrum.i18n import _
from electrum.gui import messages
from electrum.util import bfh
from electrum.lnutil import MIN_FUNDING_SAT
from electrum.lntransport import extract_nodeid, ConnStringFormatError
from electrum.bitcoin import DummyAddress
from electrum.lnworker import hardcoded_trampoline_nodes
@@ -31,7 +32,6 @@ class QEChannelOpener(QObject, AuthMixin):
channelOpenError = pyqtSignal([str], arguments=['message'])
channelOpenSuccess = pyqtSignal([str, bool, int, bool],
arguments=['cid', 'has_onchain_backup', 'min_depth', 'tx_complete'])
maxAmountMessage = pyqtSignal([str], arguments=['message'])
dataChanged = pyqtSignal() # generic notify signal
@@ -44,6 +44,8 @@ class QEChannelOpener(QObject, AuthMixin):
self._valid = False
self._opentx = None
self._txdetails = None
self._warning = ''
self._determine_max_message = None
self._finalizer = None
self._node_pubkey = None
@@ -92,6 +94,21 @@ class QEChannelOpener(QObject, AuthMixin):
def valid(self):
return self._valid
def setValid(self, is_valid):
if self._valid != is_valid:
self._valid = is_valid
self.validChanged.emit()
warningChanged = pyqtSignal()
@pyqtProperty(str, notify=warningChanged)
def warning(self):
return self._warning
def setWarning(self, warning):
if self._warning != warning:
self._warning = warning
self.warningChanged.emit()
finalizerChanged = pyqtSignal()
@pyqtProperty(QETxFinalizer, notify=finalizerChanged)
def finalizer(self):
@@ -106,10 +123,9 @@ class QEChannelOpener(QObject, AuthMixin):
def trampolineNodeNames(self):
return list(hardcoded_trampoline_nodes().keys())
# FIXME min channel funding amount
# FIXME have requested funding amount
def validate(self):
"""side-effects: sets self._valid, self._node_pubkey, self._connect_str_resolved"""
"""side-effects: sets self._node_pubkey, self._connect_str_resolved"""
connect_str_valid = False
if self._connect_str:
self._logger.debug(f'checking if {self._connect_str=!r} is valid')
@@ -129,19 +145,36 @@ class QEChannelOpener(QObject, AuthMixin):
self._connect_str_resolved = self._connect_str
connect_str_valid = True
self.setWarning('')
if not connect_str_valid:
self._valid = False
self.validChanged.emit()
self.setValid(False)
return
self._logger.debug(f'amount={self._amount}')
if not self._amount or not (self._amount.satsInt > 0 or self._amount.isMax):
self._valid = False
self.validChanged.emit()
self.setValid(False)
return
self._valid = True
self.validChanged.emit()
# for MAX, estimate is assumed to be calculated and set in self._amount.satsInt
if self._amount.satsInt < MIN_FUNDING_SAT:
message = _('Minimum required amount: {}').format(
self._wallet.wallet.config.format_amount_and_units(MIN_FUNDING_SAT)
)
if self._amount.isMax and self._determine_max_message:
message += '\n' + self._determine_max_message
self.setWarning(message)
self.setValid(False)
return
if self._amount.satsInt > self._wallet.wallet.config.LIGHTNING_MAX_FUNDING_SAT:
self.setWarning(_('Amount is above maximum channel size: {}').format(
self._wallet.wallet.config.format_amount_and_units(self._wallet.wallet.config.LIGHTNING_MAX_FUNDING_SAT)
))
self.setValid(False)
return
self.setValid(True)
@pyqtSlot(str, result=bool)
def validateConnectString(self, connect_str):
@@ -252,13 +285,8 @@ class QEChannelOpener(QObject, AuthMixin):
node_id=dummy_nodeid,
fee_policy=fee_policy)
amount, message = self._wallet.determine_max(mktx=make_tx)
if amount is None:
self._amount.isMax = False
else:
self._amount.satsInt = amount
if message:
self.maxAmountMessage.emit(message)
amount, self._determine_max_message = self._wallet.determine_max(mktx=make_tx)
self._amount.satsInt = amount if amount else 0
finally:
self._updating_max = False
self.validate()