tkivy and qt: adapt open_channel dialogs to trampoline - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- DIR commit 0e23f33f59b3ae841eee89cfcccf05af8a56c60b DIR parent cf818fe08cdb1dcfc5651d9c2ea3edeee68c7e3e HTML Author: ThomasV <thomasv@electrum.org> Date: Thu, 11 Feb 2021 14:46:36 +0100 kivy and qt: adapt open_channel dialogs to trampoline Diffstat: M electrum/gui/kivy/uix/dialogs/ligh… | 41 ++++++++++++++++++++++--------- M electrum/gui/qt/channels_list.py | 67 ++++++++++++++++++++----------- 2 files changed, 72 insertions(+), 36 deletions(-) --- DIR diff --git a/electrum/gui/kivy/uix/dialogs/lightning_open_channel.py b/electrum/gui/kivy/uix/dialogs/lightning_open_channel.py t@@ -21,6 +21,7 @@ Builder.load_string(''' #:import KIVY_GUI_PATH electrum.gui.kivy.KIVY_GUI_PATH <LightningOpenChannelDialog@Popup> + use_gossip: False id: s name: 'lightning_open_channel' title: _('Open Lightning Channel') t@@ -45,8 +46,9 @@ Builder.load_string(''' size: '22dp', '22dp' pos_hint: {'center_y': .5} BlueButton: - text: s.pubkey if s.pubkey else _('Node ID') + text: s.pubkey if s.pubkey else (_('Node ID') if root.use_gossip else _('Trampoline node')) shorten: True + on_release: s.suggest_node() CardSeparator: color: blue_bottom.foreground_color BoxLayout: t@@ -61,7 +63,7 @@ Builder.load_string(''' text: s.amount if s.amount else _('Amount') on_release: app.amount_dialog(s, True) TopLabel: - text: _('Paste or scan a node ID, a connection string or a lightning invoice.') + text: _('Paste or scan a node ID, a connection string or a lightning invoice.') if root.use_gossip else _('Choose a trampoline node and the amount') BoxLayout: size_hint: 1, None height: '48dp' t@@ -107,14 +109,19 @@ class LightningOpenChannelDialog(Factory.Popup, Logger): d.open() def suggest_node(self): - suggested = self.app.wallet.lnworker.suggest_peer() - if suggested: - self.pubkey = suggested.hex() + if self.use_gossip: + suggested = self.app.wallet.lnworker.suggest_peer() + if suggested: + self.pubkey = suggested.hex() + else: + _, _, percent = self.app.wallet.network.lngossip.get_sync_progress_estimate() + if percent is None: + percent = "??" + self.pubkey = f"Please wait, graph is updating ({percent}% / 30% done)." else: - _, _, percent = self.app.wallet.network.lngossip.get_sync_progress_estimate() - if percent is None: - percent = "??" - self.pubkey = f"Please wait, graph is updating ({percent}% / 30% done)." + self.trampoline_index += 1 + self.trampoline_index = self.trampoline_index % len(self.trampoline_names) + self.pubkey = self.trampoline_names[self.trampoline_index] def __init__(self, app, lnaddr=None, msg=None): Factory.Popup.__init__(self) t@@ -122,6 +129,13 @@ class LightningOpenChannelDialog(Factory.Popup, Logger): self.app = app # type: ElectrumWindow self.lnaddr = lnaddr self.msg = msg + self.use_gossip = bool(self.app.network.channel_db) + if not self.use_gossip: + from electrum.lnworker import hardcoded_trampoline_nodes + self.trampolines = hardcoded_trampoline_nodes() + self.trampoline_names = list(self.trampolines.keys()) + self.trampoline_index = 0 + self.pubkey = '' def open(self, *args, **kwargs): super(LightningOpenChannelDialog, self).open(*args, **kwargs) t@@ -153,9 +167,12 @@ class LightningOpenChannelDialog(Factory.Popup, Logger): if not self.pubkey or not self.amount: self.app.show_info(_('All fields must be filled out')) return - conn_str = self.pubkey - if self.ipport: - conn_str += '@' + self.ipport.strip() + if self.use_gossip: + conn_str = self.pubkey + if self.ipport: + conn_str += '@' + self.ipport.strip() + else: + conn_str = str(self.trampolines[self.pubkey]) amount = '!' if self.is_max else self.app.get_amount(self.amount) self.app.protected('Create a new channel?', self.do_open_channel, (conn_str, amount)) self.dismiss() DIR diff --git a/electrum/gui/qt/channels_list.py b/electrum/gui/qt/channels_list.py t@@ -6,7 +6,7 @@ from typing import Sequence, Optional from PyQt5 import QtCore, QtGui from PyQt5.QtCore import Qt from PyQt5.QtWidgets import (QMenu, QHBoxLayout, QLabel, QVBoxLayout, QGridLayout, QLineEdit, - QPushButton, QAbstractItemView) + QPushButton, QAbstractItemView, QComboBox) from PyQt5.QtGui import QFont, QStandardItem, QBrush from electrum.util import bh2u, NotEnoughFunds, NoDynamicFeeEstimates t@@ -343,9 +343,30 @@ class ChannelsList(MyTreeView): lnworker = self.parent.wallet.lnworker d = WindowModalDialog(self.parent, _('Open Channel')) vbox = QVBoxLayout(d) - vbox.addWidget(QLabel(_('Enter Remote Node ID or connection string or invoice'))) - remote_nodeid = QLineEdit() - remote_nodeid.setMinimumWidth(700) + if self.parent.network.channel_db: + vbox.addWidget(QLabel(_('Enter Remote Node ID or connection string or invoice'))) + remote_nodeid = QLineEdit() + remote_nodeid.setMinimumWidth(700) + suggest_button = QPushButton(d, text=_('Suggest Peer')) + def on_suggest(): + self.parent.wallet.network.start_gossip() + nodeid = bh2u(lnworker.suggest_peer() or b'') + if not nodeid: + remote_nodeid.setText("") + remote_nodeid.setPlaceholderText( + "Please wait until the graph is synchronized to 30%, and then try again.") + else: + remote_nodeid.setText(nodeid) + remote_nodeid.repaint() # macOS hack for #6269 + suggest_button.clicked.connect(on_suggest) + else: + from electrum.lnworker import hardcoded_trampoline_nodes + trampolines = hardcoded_trampoline_nodes() + trampoline_names = list(trampolines.keys()) + trampoline_combo = QComboBox() + trampoline_combo.addItems(trampoline_names) + trampoline_combo.setCurrentIndex(1) + amount_e = BTCAmountEdit(self.parent.get_decimal_point) # max button def spend_max(): t@@ -367,37 +388,31 @@ class ChannelsList(MyTreeView): max_button.setFixedWidth(100) max_button.setCheckable(True) - suggest_button = QPushButton(d, text=_('Suggest Peer')) - def on_suggest(): - self.parent.wallet.network.start_gossip() - nodeid = bh2u(lnworker.suggest_peer() or b'') - if not nodeid: - remote_nodeid.setText("") - remote_nodeid.setPlaceholderText( - "Please wait until the graph is synchronized to 30%, and then try again.") - else: - remote_nodeid.setText(nodeid) - remote_nodeid.repaint() # macOS hack for #6269 - suggest_button.clicked.connect(on_suggest) - clear_button = QPushButton(d, text=_('Clear')) def on_clear(): amount_e.setText('') amount_e.setFrozen(False) amount_e.repaint() # macOS hack for #6269 - remote_nodeid.setText('') - remote_nodeid.repaint() # macOS hack for #6269 + if self.parent.network.channel_db: + remote_nodeid.setText('') + remote_nodeid.repaint() # macOS hack for #6269 max_button.setChecked(False) max_button.repaint() # macOS hack for #6269 clear_button.clicked.connect(on_clear) + clear_button.setFixedWidth(100) h = QGridLayout() - h.addWidget(QLabel(_('Remote Node ID')), 0, 0) - h.addWidget(remote_nodeid, 0, 1, 1, 3) - h.addWidget(suggest_button, 1, 1) - h.addWidget(clear_button, 1, 2) + if self.parent.network.channel_db: + h.addWidget(QLabel(_('Remote Node ID')), 0, 0) + h.addWidget(remote_nodeid, 0, 1, 1, 4) + h.addWidget(suggest_button, 0, 5) + else: + h.addWidget(QLabel(_('Trampoline Node')), 0, 0) + h.addWidget(trampoline_combo, 0, 1, 1, 3) + h.addWidget(QLabel('Amount'), 2, 0) h.addWidget(amount_e, 2, 1) h.addWidget(max_button, 2, 2) + h.addWidget(clear_button, 2, 3) vbox.addLayout(h) ok_button = OkButton(d) ok_button.setDefault(True) t@@ -411,7 +426,11 @@ class ChannelsList(MyTreeView): funding_sat = '!' else: funding_sat = amount_e.get_amount() - connect_str = str(remote_nodeid.text()).strip() + if self.parent.network.channel_db: + connect_str = str(remote_nodeid.text()).strip() + else: + name = trampoline_names[trampoline_combo.currentIndex()] + connect_str = str(trampolines[name]) if not connect_str or not funding_sat: return self.parent.open_channel(connect_str, funding_sat, 0)