Qt: move open_channel_dialog code in separate module
(no functional change in this commit)
This commit is contained in:
@@ -15,9 +15,8 @@ from electrum.util import bh2u, NotEnoughFunds, NoDynamicFeeEstimates
|
||||
from electrum.i18n import _
|
||||
from electrum.lnchannel import AbstractChannel, PeerState, ChannelBackup, Channel, ChannelState
|
||||
from electrum.wallet import Abstract_Wallet
|
||||
from electrum.lnutil import LOCAL, REMOTE, format_short_channel_id, LN_MAX_FUNDING_SAT
|
||||
from electrum.lnutil import LOCAL, REMOTE, format_short_channel_id
|
||||
from electrum.lnworker import LNWallet
|
||||
from electrum import ecc
|
||||
from electrum.gui import messages
|
||||
|
||||
from .util import (MyTreeView, WindowModalDialog, Buttons, OkButton, CancelButton,
|
||||
@@ -384,105 +383,9 @@ class ChannelsList(MyTreeView):
|
||||
d.exec_()
|
||||
|
||||
def new_channel_dialog(self, *, amount_sat=None):
|
||||
lnworker = self.parent.wallet.lnworker
|
||||
d = WindowModalDialog(self.parent, _('Open Channel'))
|
||||
vbox = QVBoxLayout(d)
|
||||
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
|
||||
vbox.addWidget(QLabel(_('Choose a trampoline node to open a channel with')))
|
||||
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)
|
||||
amount_e.setAmount(amount_sat)
|
||||
# max button
|
||||
def spend_max():
|
||||
amount_e.setFrozen(max_button.isChecked())
|
||||
if not max_button.isChecked():
|
||||
return
|
||||
dummy_nodeid = ecc.GENERATOR.get_public_key_bytes(compressed=True)
|
||||
make_tx = self.parent.mktx_for_open_channel(funding_sat='!', node_id=dummy_nodeid)
|
||||
try:
|
||||
tx = make_tx(None)
|
||||
except (NotEnoughFunds, NoDynamicFeeEstimates) as e:
|
||||
max_button.setChecked(False)
|
||||
amount_e.setFrozen(False)
|
||||
self.main_window.show_error(str(e))
|
||||
return
|
||||
amount = tx.output_value()
|
||||
amount = min(amount, LN_MAX_FUNDING_SAT)
|
||||
amount_e.setAmount(amount)
|
||||
max_button = EnterButton(_("Max"), spend_max)
|
||||
max_button.setFixedWidth(100)
|
||||
max_button.setCheckable(True)
|
||||
|
||||
clear_button = QPushButton(d, text=_('Clear'))
|
||||
def on_clear():
|
||||
amount_e.setText('')
|
||||
amount_e.setFrozen(False)
|
||||
amount_e.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()
|
||||
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')), 0, 0)
|
||||
h.addWidget(trampoline_combo, 0, 1, 1, 4)
|
||||
|
||||
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)
|
||||
vbox.addStretch()
|
||||
ok_button = OkButton(d)
|
||||
ok_button.setDefault(True)
|
||||
vbox.addLayout(Buttons(CancelButton(d), ok_button))
|
||||
if not d.exec_():
|
||||
return
|
||||
if max_button.isChecked() and amount_e.get_amount() < LN_MAX_FUNDING_SAT:
|
||||
# if 'max' enabled and amount is strictly less than max allowed,
|
||||
# that means we have fewer coins than max allowed, and hence we can
|
||||
# spend all coins
|
||||
funding_sat = '!'
|
||||
else:
|
||||
funding_sat = amount_e.get_amount()
|
||||
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)
|
||||
return True
|
||||
from .new_channel_dialog import NewChannelDialog
|
||||
d = NewChannelDialog(self.parent, amount_sat)
|
||||
return d.run()
|
||||
|
||||
def swap_dialog(self):
|
||||
from .swap_dialog import SwapDialog
|
||||
|
||||
126
electrum/gui/qt/new_channel_dialog.py
Normal file
126
electrum/gui/qt/new_channel_dialog.py
Normal file
@@ -0,0 +1,126 @@
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from PyQt5.QtWidgets import QLabel, QVBoxLayout, QGridLayout, QPushButton, QComboBox, QLineEdit
|
||||
|
||||
from electrum.i18n import _
|
||||
from electrum.transaction import PartialTxOutput, PartialTransaction
|
||||
from electrum.lnutil import LN_MAX_FUNDING_SAT
|
||||
from electrum.lnworker import hardcoded_trampoline_nodes
|
||||
from electrum import ecc
|
||||
|
||||
|
||||
from .util import (WindowModalDialog, Buttons, OkButton, CancelButton,
|
||||
EnterButton, ColorScheme, WWLabel, read_QIcon, IconLabel)
|
||||
from .amountedit import BTCAmountEdit
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .main_window import ElectrumWindow
|
||||
|
||||
|
||||
|
||||
class NewChannelDialog(WindowModalDialog):
|
||||
|
||||
def __init__(self, window: 'ElectrumWindow', amount_sat: Optional[int] = None):
|
||||
WindowModalDialog.__init__(self, window, _('Open Channel'))
|
||||
self.window = window
|
||||
self.network = window.network
|
||||
self.config = window.config
|
||||
self.lnworker = self.window.wallet.lnworker
|
||||
self.trampolines = hardcoded_trampoline_nodes()
|
||||
self.trampoline_names = list(self.trampolines.keys())
|
||||
vbox = QVBoxLayout(self)
|
||||
if self.network.channel_db:
|
||||
vbox.addWidget(QLabel(_('Enter Remote Node ID or connection string or invoice')))
|
||||
self.remote_nodeid = QLineEdit()
|
||||
self.remote_nodeid.setMinimumWidth(700)
|
||||
self.suggest_button = QPushButton(self, text=_('Suggest Peer'))
|
||||
self.suggest_button.clicked.connect(self.on_suggest)
|
||||
else:
|
||||
vbox.addWidget(QLabel(_('Choose a trampoline node to open a channel with')))
|
||||
self.trampoline_combo = QComboBox()
|
||||
self.trampoline_combo.addItems(self.trampoline_names)
|
||||
self.trampoline_combo.setCurrentIndex(1)
|
||||
self.amount_e = BTCAmountEdit(self.window.get_decimal_point)
|
||||
self.amount_e.setAmount(amount_sat)
|
||||
self.max_button = EnterButton(_("Max"), self.spend_max)
|
||||
self.max_button.setFixedWidth(100)
|
||||
self.max_button.setCheckable(True)
|
||||
self.clear_button = QPushButton(self, text=_('Clear'))
|
||||
self.clear_button.clicked.connect(self.on_clear)
|
||||
self.clear_button.setFixedWidth(100)
|
||||
h = QGridLayout()
|
||||
if self.network.channel_db:
|
||||
h.addWidget(QLabel(_('Remote Node ID')), 0, 0)
|
||||
h.addWidget(self.remote_nodeid, 0, 1, 1, 4)
|
||||
h.addWidget(self.suggest_button, 0, 5)
|
||||
else:
|
||||
h.addWidget(QLabel(_('Trampoline')), 0, 0)
|
||||
h.addWidget(self.trampoline_combo, 0, 1, 1, 4)
|
||||
h.addWidget(QLabel('Amount'), 2, 0)
|
||||
h.addWidget(self.amount_e, 2, 1)
|
||||
h.addWidget(self.max_button, 2, 2)
|
||||
h.addWidget(self.clear_button, 2, 3)
|
||||
vbox.addLayout(h)
|
||||
vbox.addStretch()
|
||||
ok_button = OkButton(self)
|
||||
ok_button.setDefault(True)
|
||||
vbox.addLayout(Buttons(CancelButton(self), ok_button))
|
||||
|
||||
def on_suggest(self):
|
||||
self.network.start_gossip()
|
||||
nodeid = self.lnworker.suggest_peer().hex() or ''
|
||||
if not nodeid:
|
||||
self.remote_nodeid.setText("")
|
||||
self.remote_nodeid.setPlaceholderText(
|
||||
"Please wait until the graph is synchronized to 30%, and then try again.")
|
||||
else:
|
||||
self.remote_nodeid.setText(nodeid)
|
||||
self.remote_nodeid.repaint() # macOS hack for #6269
|
||||
|
||||
def on_clear(self):
|
||||
self.amount_e.setText('')
|
||||
self.amount_e.setFrozen(False)
|
||||
self.amount_e.repaint() # macOS hack for #6269
|
||||
if self.network.channel_db:
|
||||
remote_nodeid.setText('')
|
||||
remote_nodeid.repaint() # macOS hack for #6269
|
||||
self.max_button.setChecked(False)
|
||||
self.max_button.repaint() # macOS hack for #6269
|
||||
|
||||
def spend_max(self):
|
||||
self.amount_e.setFrozen(self.max_button.isChecked())
|
||||
if not self.max_button.isChecked():
|
||||
return
|
||||
dummy_nodeid = ecc.GENERATOR.get_public_key_bytes(compressed=True)
|
||||
make_tx = self.window.mktx_for_open_channel(funding_sat='!', node_id=dummy_nodeid)
|
||||
try:
|
||||
tx = make_tx(None)
|
||||
except (NotEnoughFunds, NoDynamicFeeEstimates) as e:
|
||||
max_button.setChecked(False)
|
||||
self.amount_e.setFrozen(False)
|
||||
self.main_window.show_error(str(e))
|
||||
return
|
||||
amount = tx.output_value()
|
||||
amount = min(amount, LN_MAX_FUNDING_SAT)
|
||||
self.amount_e.setAmount(amount)
|
||||
|
||||
def run(self):
|
||||
if not self.exec_():
|
||||
return
|
||||
if self.max_button.isChecked() and self.amount_e.get_amount() < LN_MAX_FUNDING_SAT:
|
||||
# if 'max' enabled and amount is strictly less than max allowed,
|
||||
# that means we have fewer coins than max allowed, and hence we can
|
||||
# spend all coins
|
||||
funding_sat = '!'
|
||||
else:
|
||||
funding_sat = self.amount_e.get_amount()
|
||||
if self.network.channel_db:
|
||||
connect_str = str(self.remote_nodeid.text()).strip()
|
||||
else:
|
||||
name = self.trampoline_names[self.trampoline_combo.currentIndex()]
|
||||
connect_str = str(self.trampolines[name])
|
||||
if not connect_str or not funding_sat:
|
||||
return
|
||||
self.window.open_channel(connect_str, funding_sat, 0)
|
||||
return True
|
||||
Reference in New Issue
Block a user