1
0

Merge pull request #9606 from f321x/jit-improve-qml

Handle just in time channels in qml request creation
This commit is contained in:
ThomasV
2025-03-14 08:35:37 +01:00
committed by GitHub
4 changed files with 69 additions and 10 deletions

View File

@@ -106,10 +106,42 @@ ElDialog {
}
FlatButton {
Layout.fillWidth: true
enabled: Daemon.currentWallet.isLightning && Daemon.currentWallet.lightningCanReceive.satsInt > amountBtc.textAsSats.satsInt
enabled: Daemon.currentWallet.isLightning && (Daemon.currentWallet.lightningCanReceive.satsInt
> amountBtc.textAsSats.satsInt || Daemon.currentWallet.canGetZeroconfChannel)
text: qsTr('Lightning')
icon.source: '../../icons/lightning.png'
onClicked: { dialog.isLightning = true; doAccept() }
onClicked: {
if (Daemon.currentWallet.lightningCanReceive.satsInt > amountBtc.textAsSats.satsInt) {
// can receive on existing channel
dialog.isLightning = true
doAccept()
} else if (Daemon.currentWallet.canGetZeroconfChannel && amountBtc.textAsSats.satsInt
>= Daemon.currentWallet.minChannelFunding.satsInt) {
// ask for confirmation of zeroconf channel to prevent fee surprise
var confirmdialog = app.messageDialog.createObject(dialog, {
title: qsTr('Confirm just-in-time channel'),
text: [qsTr('Receiving this payment will purchase a Lightning channel from your service provider.'),
qsTr('Fees will be deducted from the payment.'),
qsTr('Do you want to continue?')].join(' '),
yesno: true
})
confirmdialog.accepted.connect(function () {
dialog.isLightning = true
doAccept()
})
confirmdialog.open()
} else {
// show error that amnt > 200k is neccessary to get zeroconf channel
var confirmdialog = app.messageDialog.createObject(dialog, {
title: qsTr("Amount too low"),
text: [qsTr("You don't have channels with enough inbound liquidity to receive this payment."),
qsTr("Request at least %1 to open a channel just-in-time.").arg(
Config.formatSats(Daemon.currentWallet.minChannelFunding.satsInt, true))].join(' ')
})
confirmdialog.open()
}
// can't get zeroconf channel and doesn't have enough inbound liquidity
}
}
}
}

View File

@@ -6,6 +6,7 @@ from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject, QTimer, py
from electrum.logging import get_logger
from electrum.invoices import (PR_UNPAID, PR_EXPIRED, PR_UNKNOWN, PR_PAID, PR_INFLIGHT,
PR_FAILED, PR_ROUTING, PR_UNCONFIRMED, LN_EXPIRY_NEVER)
from electrum.lnutil import MIN_FUNDING_SAT
from .qewallet import QEWallet
from .qetypes import QEAmount
@@ -118,9 +119,13 @@ class QERequestDetails(QObject, QtEventListener):
@pyqtProperty(str, notify=detailsChanged)
def bolt11(self):
can_receive = self._wallet.wallet.lnworker.num_sats_can_receive() if self._wallet.wallet.lnworker else 0
if self._req and can_receive > 0 and (self._req.get_amount_sat() or 0) <= can_receive:
bolt11 = self._wallet.wallet.get_bolt11_invoice(self._req)
wallet = self._wallet.wallet
amount_sat = self._req.get_amount_sat() or 0 if self._req else 0
can_receive = wallet.lnworker.num_sats_can_receive() if wallet.lnworker else 0
will_req_zeroconf = wallet.lnworker.receive_requires_jit_channel(amount_msat=amount_sat*1000)
if self._req and ((can_receive > 0 and amount_sat <= can_receive)
or (will_req_zeroconf and amount_sat >= MIN_FUNDING_SAT)):
bolt11 = wallet.get_bolt11_invoice(self._req)
else:
return ''
# encode lightning invoices as uppercase so QR encoding can use

View File

@@ -15,6 +15,7 @@ from electrum.network import TxBroadcastError, BestEffortRequestFailed
from electrum.transaction import PartialTransaction, Transaction
from electrum.util import InvalidPassword, event_listener, AddTransactionException, get_asyncio_loop, NotEnoughFunds, \
NoDynamicFeeEstimates
from electrum.lnutil import MIN_FUNDING_SAT
from electrum.plugin import run_hook
from electrum.wallet import Multisig_Wallet
from electrum.crypto import pw_decode_with_version_and_mac
@@ -26,6 +27,7 @@ from .qeinvoicelistmodel import QEInvoiceListModel, QERequestListModel
from .qetransactionlistmodel import QETransactionListModel
from .qetypes import QEAmount
from .util import QtEventListener, qt_event_listener
from ...lntransport import extract_nodeid
from ...fee_policy import FeePolicy
if TYPE_CHECKING:
@@ -101,6 +103,7 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
self._frozenbalance = QEAmount()
self._totalbalance = QEAmount()
self._lightningcanreceive = QEAmount()
self._minchannelfunding = QEAmount(amount_sat=int(MIN_FUNDING_SAT))
self._lightningcansend = QEAmount()
self._lightningbalancefrozen = QEAmount()
@@ -459,6 +462,11 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
def canSignMessage(self):
return not isinstance(self.wallet, Multisig_Wallet) and not self.wallet.is_watching_only()
canGetZeroconfChannelChanged = pyqtSignal()
@pyqtProperty(bool, notify=canGetZeroconfChannelChanged)
def canGetZeroconfChannel(self) -> bool:
return self.wallet.lnworker and self.wallet.lnworker.can_get_zeroconf_channel()
@pyqtProperty(QEAmount, notify=balanceChanged)
def frozenBalance(self):
c, u, x = self.wallet.get_frozen_balance()
@@ -506,6 +514,10 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
self._lightningcanreceive.satsInt = int(self.wallet.lnworker.num_sats_can_receive())
return self._lightningcanreceive
@pyqtProperty(QEAmount, notify=dataChanged)
def minChannelFunding(self):
return self._minchannelfunding
@pyqtProperty(int, notify=peersUpdated)
def lightningNumPeers(self):
if self.isLightning: