expose more trampoline boilerplate
allow delegation of make_tx and accept/send
This commit is contained in:
@@ -23,8 +23,10 @@ Pane {
|
|||||||
text: qsTr('Node')
|
text: qsTr('Node')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gossip
|
||||||
TextArea {
|
TextArea {
|
||||||
id: node
|
id: node
|
||||||
|
visible: Config.useGossip
|
||||||
Layout.columnSpan: 2
|
Layout.columnSpan: 2
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
font.family: FixedFont
|
font.family: FixedFont
|
||||||
@@ -37,6 +39,7 @@ Pane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
visible: Config.useGossip
|
||||||
spacing: 0
|
spacing: 0
|
||||||
ToolButton {
|
ToolButton {
|
||||||
icon.source: '../../icons/paste.png'
|
icon.source: '../../icons/paste.png'
|
||||||
@@ -62,6 +65,18 @@ Pane {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// trampoline
|
||||||
|
ComboBox {
|
||||||
|
id: tnode
|
||||||
|
visible: !Config.useGossip
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
model: channelopener.trampolineNodeNames
|
||||||
|
onCurrentValueChanged: {
|
||||||
|
channelopener.nodeid = tnode.currentValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: qsTr('Amount')
|
text: qsTr('Amount')
|
||||||
}
|
}
|
||||||
@@ -85,9 +100,7 @@ Pane {
|
|||||||
id: is_max
|
id: is_max
|
||||||
text: qsTr('Max')
|
text: qsTr('Max')
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
if (checked) {
|
channelopener.amount = checked ? MAX : Config.unitsToSats(amount.text)
|
||||||
channelopener.amount = MAX
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,6 +105,22 @@ Pane {
|
|||||||
Daemon.fx.rateSource = currentValue
|
Daemon.fx.rateSource = currentValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr('Lightning Routing')
|
||||||
|
enabled: Daemon.currentWallet.isLightning
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox {
|
||||||
|
id: lnRoutingType
|
||||||
|
valueRole: 'key'
|
||||||
|
textRole: 'label'
|
||||||
|
enabled: Daemon.currentWallet.isLightning && false
|
||||||
|
model: ListModel {
|
||||||
|
ListElement { key: 'gossip'; label: qsTr('Gossip') }
|
||||||
|
ListElement { key: 'trampoline'; label: qsTr('Trampoline') }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -118,5 +134,6 @@ Pane {
|
|||||||
historicRates.checked = Daemon.fx.historicRates
|
historicRates.checked = Daemon.fx.historicRates
|
||||||
rateSources.currentIndex = rateSources.indexOfValue(Daemon.fx.rateSource)
|
rateSources.currentIndex = rateSources.indexOfValue(Daemon.fx.rateSource)
|
||||||
fiatEnable.checked = Daemon.fx.enabled
|
fiatEnable.checked = Daemon.fx.enabled
|
||||||
|
lnRoutingType.currentIndex = Config.useGossip ? 0 : 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject
|
|||||||
|
|
||||||
from electrum.logging import get_logger
|
from electrum.logging import get_logger
|
||||||
from electrum.util import format_time
|
from electrum.util import format_time
|
||||||
from electrum.lnutil import extract_nodeid, ConnStringFormatError
|
from electrum.lnutil import extract_nodeid, ConnStringFormatError, LNPeerAddr
|
||||||
|
from electrum.lnworker import hardcoded_trampoline_nodes
|
||||||
from electrum.gui import messages
|
from electrum.gui import messages
|
||||||
|
|
||||||
from .qewallet import QEWallet
|
from .qewallet import QEWallet
|
||||||
@@ -23,6 +24,8 @@ class QEChannelOpener(QObject):
|
|||||||
validationError = pyqtSignal([str,str], arguments=['code','message'])
|
validationError = pyqtSignal([str,str], arguments=['code','message'])
|
||||||
conflictingBackup = pyqtSignal([str], arguments=['message'])
|
conflictingBackup = pyqtSignal([str], arguments=['message'])
|
||||||
|
|
||||||
|
dataChanged = pyqtSignal() # generic notify signal
|
||||||
|
|
||||||
walletChanged = pyqtSignal()
|
walletChanged = pyqtSignal()
|
||||||
@pyqtProperty(QEWallet, notify=walletChanged)
|
@pyqtProperty(QEWallet, notify=walletChanged)
|
||||||
def wallet(self):
|
def wallet(self):
|
||||||
@@ -69,14 +72,28 @@ class QEChannelOpener(QObject):
|
|||||||
def openTx(self):
|
def openTx(self):
|
||||||
return self._opentx
|
return self._opentx
|
||||||
|
|
||||||
|
@pyqtProperty(list, notify=dataChanged)
|
||||||
|
def trampolineNodeNames(self):
|
||||||
|
return list(hardcoded_trampoline_nodes().keys())
|
||||||
|
|
||||||
|
# FIXME min channel funding amount
|
||||||
|
# FIXME have requested funding amount
|
||||||
def validate(self):
|
def validate(self):
|
||||||
nodeid_valid = False
|
nodeid_valid = False
|
||||||
if self._nodeid:
|
if self._nodeid:
|
||||||
try:
|
if not self._wallet.wallet.config.get('use_gossip', False):
|
||||||
self._node_pubkey, self._host_port = extract_nodeid(self._nodeid)
|
self._peer = hardcoded_trampoline_nodes()[self._nodeid]
|
||||||
nodeid_valid = True
|
nodeid_valid = True
|
||||||
except ConnStringFormatError as e:
|
else:
|
||||||
self.validationError.emit('invalid_nodeid', repr(e))
|
try:
|
||||||
|
node_pubkey, host_port = extract_nodeid(self._nodeid)
|
||||||
|
host, port = host_port.split(':',1)
|
||||||
|
self._peer = LNPeerAddr(host, int(port), node_pubkey)
|
||||||
|
nodeid_valid = True
|
||||||
|
except ConnStringFormatError as e:
|
||||||
|
self.validationError.emit('invalid_nodeid', repr(e))
|
||||||
|
except ValueError as e:
|
||||||
|
self.validationError.emit('invalid_nodeid', repr(e))
|
||||||
|
|
||||||
if not nodeid_valid:
|
if not nodeid_valid:
|
||||||
self._valid = False
|
self._valid = False
|
||||||
@@ -99,16 +116,12 @@ class QEChannelOpener(QObject):
|
|||||||
if not self.valid:
|
if not self.valid:
|
||||||
return
|
return
|
||||||
|
|
||||||
#if self.use_gossip:
|
self._logger.debug('Connect String: %s' % str(self._peer))
|
||||||
#conn_str = self.pubkey
|
|
||||||
#if self.ipport:
|
|
||||||
#conn_str += '@' + self.ipport.strip()
|
|
||||||
#else:
|
|
||||||
#conn_str = str(self.trampolines[self.pubkey])
|
|
||||||
amount = '!' if self._amount.isMax else self._amount.satsInt
|
amount = '!' if self._amount.isMax else self._amount.satsInt
|
||||||
|
|
||||||
lnworker = self._wallet.wallet.lnworker
|
lnworker = self._wallet.wallet.lnworker
|
||||||
if lnworker.has_conflicting_backup_with(node_pubkey) and not confirm_backup_conflict:
|
if lnworker.has_conflicting_backup_with(self._peer.pubkey) and not confirm_backup_conflict:
|
||||||
self.conflictingBackup.emit(messages.MGS_CONFLICTING_BACKUP_INSTANCE)
|
self.conflictingBackup.emit(messages.MGS_CONFLICTING_BACKUP_INSTANCE)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -117,7 +130,7 @@ class QEChannelOpener(QObject):
|
|||||||
make_tx = lambda rbf: lnworker.mktx_for_open_channel(
|
make_tx = lambda rbf: lnworker.mktx_for_open_channel(
|
||||||
coins=coins,
|
coins=coins,
|
||||||
funding_sat=amount,
|
funding_sat=amount,
|
||||||
node_id=self._node_pubkey,
|
node_id=self._peer.pubkey,
|
||||||
fee_est=None)
|
fee_est=None)
|
||||||
#on_pay = lambda tx: self.app.protected('Create a new channel?', self.do_open_channel, (tx, conn_str))
|
#on_pay = lambda tx: self.app.protected('Create a new channel?', self.do_open_channel, (tx, conn_str))
|
||||||
#d = ConfirmTxDialog(
|
#d = ConfirmTxDialog(
|
||||||
|
|||||||
@@ -70,6 +70,16 @@ class QEConfig(QObject):
|
|||||||
self.config.amt_add_thousands_sep = checked
|
self.config.amt_add_thousands_sep = checked
|
||||||
self.thousandsSeparatorChanged.emit()
|
self.thousandsSeparatorChanged.emit()
|
||||||
|
|
||||||
|
useGossipChanged = pyqtSignal()
|
||||||
|
@pyqtProperty(bool, notify=useGossipChanged)
|
||||||
|
def useGossip(self):
|
||||||
|
return self.config.get('use_gossip', False)
|
||||||
|
|
||||||
|
@useGossip.setter
|
||||||
|
def useGossip(self, gossip):
|
||||||
|
self.config.set_key('use_gossip', gossip)
|
||||||
|
self.useGossipChanged.emit()
|
||||||
|
|
||||||
@pyqtSlot('qint64', result=str)
|
@pyqtSlot('qint64', result=str)
|
||||||
@pyqtSlot('qint64', bool, result=str)
|
@pyqtSlot('qint64', bool, result=str)
|
||||||
@pyqtSlot(QEAmount, result=str)
|
@pyqtSlot(QEAmount, result=str)
|
||||||
|
|||||||
@@ -11,8 +11,10 @@ from .qewallet import QEWallet
|
|||||||
from .qetypes import QEAmount
|
from .qetypes import QEAmount
|
||||||
|
|
||||||
class QETxFinalizer(QObject):
|
class QETxFinalizer(QObject):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None, *, make_tx=None, accept=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
self.f_make_tx = make_tx
|
||||||
|
self.f_accept = accept
|
||||||
self._tx = None
|
self._tx = None
|
||||||
|
|
||||||
_logger = get_logger(__name__)
|
_logger = get_logger(__name__)
|
||||||
@@ -207,6 +209,11 @@ class QETxFinalizer(QObject):
|
|||||||
|
|
||||||
@profiler
|
@profiler
|
||||||
def make_tx(self):
|
def make_tx(self):
|
||||||
|
if self.f_make_tx:
|
||||||
|
tx = self.f_make_tx()
|
||||||
|
return tx
|
||||||
|
|
||||||
|
# default impl
|
||||||
coins = self._wallet.wallet.get_spendable_coins(None)
|
coins = self._wallet.wallet.get_spendable_coins(None)
|
||||||
outputs = [PartialTxOutput.from_address_and_value(self.address, self._amount.satsInt)]
|
outputs = [PartialTxOutput.from_address_and_value(self.address, self._amount.satsInt)]
|
||||||
tx = self._wallet.wallet.make_unsigned_transaction(coins=coins,outputs=outputs, fee=None,rbf=self._rbf)
|
tx = self._wallet.wallet.make_unsigned_transaction(coins=coins,outputs=outputs, fee=None,rbf=self._rbf)
|
||||||
@@ -268,4 +275,8 @@ class QETxFinalizer(QObject):
|
|||||||
self._logger.debug('no valid tx')
|
self._logger.debug('no valid tx')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if self.f_accept:
|
||||||
|
self.f_accept(self._tx)
|
||||||
|
return
|
||||||
|
|
||||||
self._wallet.sign_and_broadcast(self._tx)
|
self._wallet.sign_and_broadcast(self._tx)
|
||||||
|
|||||||
Reference in New Issue
Block a user