mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-09-03 12:30:07 +00:00
Kivy: open channel dialog
This commit is contained in:
parent
9c4fa7b251
commit
6e69c9ed1a
11 changed files with 203 additions and 121 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -20,6 +20,7 @@ bin/
|
|||
electrum/gui/qt/icons_rc.py
|
||||
electrum/gui/kivy/theming/light-0.png
|
||||
electrum/gui/kivy/theming/light.atlas
|
||||
electrum/gui/kivy/theming/light/network.png
|
||||
|
||||
# tests/tox
|
||||
.tox/
|
||||
|
|
|
@ -5,6 +5,7 @@ PYTHON = python3
|
|||
.PHONY: theming apk clean
|
||||
|
||||
theming:
|
||||
bash -c "convert -background none theming/light/network.{svg,png}"
|
||||
$(PYTHON) -m kivy.atlas theming/light 1024 theming/light/*.png
|
||||
prepare:
|
||||
# running pre build setup
|
||||
|
|
|
@ -451,12 +451,9 @@ BoxLayout:
|
|||
ActionOvrButton:
|
||||
name: 'network'
|
||||
text: _('Network')
|
||||
ActionOvrButton:
|
||||
name: 'lightning_payer_dialog'
|
||||
text: _('Pay Lightning Invoice')
|
||||
ActionOvrButton:
|
||||
name: 'lightning_channels_dialog'
|
||||
text: _('Lightning Channels')
|
||||
text: _('Channels')
|
||||
ActionOvrButton:
|
||||
name: 'settings'
|
||||
text: _('Settings')
|
||||
|
|
|
@ -74,7 +74,7 @@ from electrum.util import (base_units, NoDynamicFeeEstimates, decimal_point_to_b
|
|||
base_unit_name_to_decimal_point, NotEnoughFunds, UnknownBaseUnit,
|
||||
DECIMAL_POINT_DEFAULT)
|
||||
|
||||
from .uix.dialogs.lightning_payer import LightningPayerDialog
|
||||
from .uix.dialogs.lightning_open_channel import LightningOpenChannelDialog
|
||||
from .uix.dialogs.lightning_channels import LightningChannelsDialog
|
||||
|
||||
class ElectrumWindow(App):
|
||||
|
@ -615,8 +615,8 @@ class ElectrumWindow(App):
|
|||
self._settings_dialog.update()
|
||||
self._settings_dialog.open()
|
||||
|
||||
def lightning_payer_dialog(self):
|
||||
d = LightningPayerDialog(self)
|
||||
def lightning_open_channel_dialog(self):
|
||||
d = LightningOpenChannelDialog(self)
|
||||
d.open()
|
||||
|
||||
def lightning_channels_dialog(self):
|
||||
|
@ -753,7 +753,11 @@ class ElectrumWindow(App):
|
|||
inputs = self.wallet.get_spendable_coins(None, self.electrum_config)
|
||||
if not inputs:
|
||||
return ''
|
||||
addr = str(self.send_screen.screen.address) or self.wallet.dummy_address()
|
||||
addr = None
|
||||
if self.send_screen:
|
||||
addr = str(self.send_screen.screen.address)
|
||||
if not addr:
|
||||
addr = self.wallet.dummy_address()
|
||||
outputs = [TxOutput(TYPE_ADDRESS, addr, '!')]
|
||||
try:
|
||||
tx = self.wallet.make_unsigned_transaction(inputs, outputs, self.electrum_config)
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.4 KiB |
6
electrum/gui/kivy/theming/light/network.svg
Normal file
6
electrum/gui/kivy/theming/light/network.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="512" height="512" version="1.1" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<use transform="translate(-216 -252)" width="100%" height="100%" xlink:href="#path831"/>
|
||||
<path id="path831" d="m244.94 256.71c-14.934 1.4562-25.469 19.091-24.913 37.987-2.155 55.246-0.0543 91.614 0.17146 143.49 0.95499 15.061 13.656 34.066 35.042 34.181 6.5619 0.30953 16.143 0.34717 30.995 0.34717 27.995 0 41.291 0.77865 41.291 2.4214 0 1.3327-2.9613 5.3827-6.5786 9-5.0074 5.0074-8.6562 6.5787-15.298 6.5787-10.341 0-14.124 3.1317-14.124 11.698v6.3018h144v-6.3018c0-8.5666-3.7834-11.698-14.124-11.698-6.6413 0-10.29-1.5713-15.297-6.5787-3.6174-3.6173-6.5786-7.6673-6.5786-9 0-1.6428 13.297-2.4214 41.291-2.4214 15.112-7e-3 63.701 6.378 66.081-35.293 0.62209-11.405 0.62843-32.056 0.62843-72.708 0-39.56-7e-3 -60.178-0.58008-71.767-0.6711-12.6-1.8798-36.301-24.834-36.233h-118.59zm10.586 36h216v144h-216v-72z" fill="#fff"/>
|
||||
<path d="m110.41 469.11c-4.9443-1.8094-13.262-7.4832-18.485-12.608-15.863-15.568-16.401-19.038-16.401-105.69v-76.1h36v150.96l5.5228 5.5227c5.4382 5.4383 6.1188 5.5228 44.468 5.5228h38.945c3.4461 14.807 6.6856 24.504 14.871 36-30.131-0.82757-61.12 0.99452-90.818-1.2282-6.8699-0.53546-11.167-1.3039-14.104-2.3788z" fill="#fff"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -7,22 +7,35 @@ from kivy.clock import Clock
|
|||
from electrum.gui.kivy.uix.context_menu import ContextMenu
|
||||
from electrum.util import bh2u
|
||||
from electrum.lnutil import LOCAL, REMOTE
|
||||
from electrum.gui.kivy.i18n import _
|
||||
|
||||
Builder.load_string('''
|
||||
Builder.load_string(r'''
|
||||
<LightningChannelItem@CardItem>
|
||||
details: {}
|
||||
active: False
|
||||
channelId: '<channelId not set>'
|
||||
id: card
|
||||
_chan: None
|
||||
Label:
|
||||
color: (.5,.5,.5,1) if not card.active else (1,1,1,1)
|
||||
text: root.channelId
|
||||
Label:
|
||||
text: _('State:\n') + (card._chan.get_state() if card._chan else 'n/a')
|
||||
font_size: '10sp'
|
||||
|
||||
<LightningChannelsDialog@Popup>:
|
||||
name: 'lightning_channels'
|
||||
title: 'Lightning channels. Tap to select.'
|
||||
title: _('Lightning channels. Tap for options.')
|
||||
id: popup
|
||||
BoxLayout:
|
||||
id: box
|
||||
orientation: 'vertical'
|
||||
spacing: '1dp'
|
||||
Button:
|
||||
size_hint: 1, None
|
||||
height: '48dp'
|
||||
text: _('New channel...')
|
||||
on_press: popup.app.popup_dialog('lightning_open_channel_dialog')
|
||||
ScrollView:
|
||||
GridLayout:
|
||||
cols: 1
|
||||
|
@ -95,7 +108,7 @@ class LightningChannelsDialog(Factory.Popup):
|
|||
|
||||
def show_channel_details(self, obj):
|
||||
p = Factory.ChannelDetailsPopup()
|
||||
p.title = 'Lightning channels details for ' + self.presentable_chan_id(obj._chan)
|
||||
p.title = _('Details for channel ') + self.presentable_chan_id(obj._chan)
|
||||
p.data = [{'keyName': key, 'value': str(obj.details[key])} for key in obj.details.keys()]
|
||||
p.open()
|
||||
|
||||
|
@ -104,25 +117,28 @@ class LightningChannelsDialog(Factory.Popup):
|
|||
coro = asyncio.run_coroutine_threadsafe(self.app.wallet.lnworker.close_channel(obj._chan.channel_id), loop)
|
||||
try:
|
||||
coro.result(5)
|
||||
self.app.show_info('Channel closed')
|
||||
self.app.show_info(_('Channel closed'))
|
||||
except Exception as e:
|
||||
self.app.show_info('Could not close channel: ' + repr(e)) # repr because str(Exception()) == ''
|
||||
self.app.show_info(_('Could not close channel: ') + repr(e)) # repr because str(Exception()) == ''
|
||||
|
||||
def force_close_channel(self, obj):
|
||||
if obj._chan.get_state() == 'CLOSED':
|
||||
self.app.show_error(_('Channel already closed'))
|
||||
return
|
||||
loop = self.app.wallet.network.asyncio_loop
|
||||
coro = asyncio.run_coroutine_threadsafe(self.app.wallet.lnworker.force_close_channel(obj._chan.channel_id), loop)
|
||||
try:
|
||||
coro.result(1)
|
||||
self.app.show_info('Channel closed, you may need to wait at least ' + str(obj._chan.config[REMOTE].to_self_delay) + ' blocks, because of CSV delays')
|
||||
self.app.show_info(_('Channel closed, you may need to wait at least {} blocks, because of CSV delays'.format(obj._chan.config[REMOTE].to_self_delay)))
|
||||
except Exception as e:
|
||||
self.app.show_info('Could not force close channel: ' + repr(e)) # repr because str(Exception()) == ''
|
||||
self.app.show_info(_('Could not force close channel: ') + repr(e)) # repr because str(Exception()) == ''
|
||||
|
||||
def show_menu(self, obj):
|
||||
self.hide_menu()
|
||||
self.context_menu = ContextMenu(obj, [
|
||||
("Force close", self.force_close_channel),
|
||||
("Co-op close", self.close_channel),
|
||||
("Details", self.show_channel_details)])
|
||||
(_("Force close"), self.force_close_channel),
|
||||
(_("Co-op close"), self.close_channel),
|
||||
(_("Details"), self.show_channel_details)])
|
||||
self.ids.box.add_widget(self.context_menu)
|
||||
|
||||
def hide_menu(self):
|
||||
|
@ -136,6 +152,8 @@ class LightningChannelsDialog(Factory.Popup):
|
|||
def channels_update(self, evt):
|
||||
channel_cards = self.ids.lightning_channels_container
|
||||
channel_cards.clear_widgets()
|
||||
if not self.app.wallet:
|
||||
return
|
||||
lnworker = self.app.wallet.lnworker
|
||||
for i in lnworker.channels.values():
|
||||
item = Factory.LightningChannelItem()
|
||||
|
@ -147,10 +165,12 @@ class LightningChannelsDialog(Factory.Popup):
|
|||
channel_cards.add_widget(item)
|
||||
|
||||
def channel_details(self, chan):
|
||||
return {'Node ID': bh2u(chan.node_id),
|
||||
'Channel ID': bh2u(chan.channel_id),
|
||||
'Capacity': self.app.format_amount_and_units(chan.constraints.capacity),
|
||||
'Funding TXID': chan.funding_outpoint.txid,
|
||||
'Short Chan ID': bh2u(chan.short_channel_id) if chan.short_channel_id else 'Not available',
|
||||
'Available to spend': self.app.format_amount_and_units(chan.available_to_spend(LOCAL) // 1000),
|
||||
'State': chan.get_state()}
|
||||
return {_('Node ID'): bh2u(chan.node_id),
|
||||
_('Channel ID'): bh2u(chan.channel_id),
|
||||
_('Capacity'): self.app.format_amount_and_units(chan.constraints.capacity),
|
||||
_('Funding TXID'): chan.funding_outpoint.txid,
|
||||
_('Short Chan ID'): bh2u(chan.short_channel_id) if chan.short_channel_id else _('Not available'),
|
||||
_('Available to spend'): self.app.format_amount_and_units(chan.available_to_spend(LOCAL) // 1000),
|
||||
_('State'): chan.get_state(),
|
||||
_('Initiator'): 'Opened/funded by us' if chan.constraints.is_initiator else 'Opened/funded by remote party',
|
||||
_('Current feerate'): chan.constraints.feerate}
|
||||
|
|
141
electrum/gui/kivy/uix/dialogs/lightning_open_channel.py
Normal file
141
electrum/gui/kivy/uix/dialogs/lightning_open_channel.py
Normal file
|
@ -0,0 +1,141 @@
|
|||
from kivy.lang import Builder
|
||||
from kivy.factory import Factory
|
||||
from electrum.gui.kivy.i18n import _
|
||||
from electrum.lnaddr import lndecode
|
||||
from electrum.gui.kivy.uix.dialogs.choice_dialog import ChoiceDialog
|
||||
from electrum.util import bh2u
|
||||
from electrum.bitcoin import COIN
|
||||
import electrum.simple_config as config
|
||||
from .label_dialog import LabelDialog
|
||||
|
||||
Builder.load_string('''
|
||||
<LightningOpenChannelDialog@Popup>
|
||||
id: s
|
||||
name: 'lightning_open_channel'
|
||||
title: _('Open Lightning Channel')
|
||||
pubkey: ''
|
||||
amount: ''
|
||||
ipport: ''
|
||||
BoxLayout
|
||||
spacing: '12dp'
|
||||
padding: '12dp'
|
||||
orientation: 'vertical'
|
||||
SendReceiveBlueBottom:
|
||||
id: blue_bottom
|
||||
size_hint: 1, None
|
||||
height: self.minimum_height
|
||||
BoxLayout:
|
||||
size_hint: 1, None
|
||||
height: blue_bottom.item_height
|
||||
Image:
|
||||
source: 'atlas://electrum/gui/kivy/theming/light/globe'
|
||||
size_hint: None, None
|
||||
size: '22dp', '22dp'
|
||||
pos_hint: {'center_y': .5}
|
||||
BlueButton:
|
||||
text: s.pubkey if s.pubkey else _('Node ID, [pubkey]@[host]:[port]')
|
||||
shorten: True
|
||||
on_release: s.choose_node()
|
||||
IconButton:
|
||||
on_release: app.scan_qr(on_complete=s.on_pubkey)
|
||||
icon: 'atlas://electrum/gui/kivy/theming/light/camera'
|
||||
color: blue_bottom.foreground_color
|
||||
size: '22dp', '22dp'
|
||||
pos_hint: {'center_y': .5}
|
||||
size_hint: None, None
|
||||
CardSeparator:
|
||||
color: blue_bottom.foreground_color
|
||||
BoxLayout:
|
||||
size_hint: 1, None
|
||||
height: blue_bottom.item_height
|
||||
Image:
|
||||
source: 'atlas://electrum/gui/kivy/theming/light/network'
|
||||
size_hint: None, None
|
||||
size: '22dp', '22dp'
|
||||
pos_hint: {'center_y': .5}
|
||||
BlueButton:
|
||||
text: s.ipport if s.ipport else _('Auto-detect IP/port')
|
||||
on_release: s.ipport_dialog()
|
||||
CardSeparator:
|
||||
color: blue_bottom.foreground_color
|
||||
BoxLayout:
|
||||
size_hint: 1, None
|
||||
height: blue_bottom.item_height
|
||||
Image:
|
||||
source: 'atlas://electrum/gui/kivy/theming/light/calculator'
|
||||
size_hint: None, None
|
||||
size: '22dp', '22dp'
|
||||
pos_hint: {'center_y': .5}
|
||||
BlueButton:
|
||||
text: s.amount if s.amount else _('Channel capacity amount')
|
||||
on_release: app.amount_dialog(s, True)
|
||||
Button:
|
||||
size_hint: 1, None
|
||||
height: blue_bottom.item_height
|
||||
text: _('Paste')
|
||||
on_release: s.do_paste()
|
||||
Button:
|
||||
size_hint: 1, None
|
||||
height: blue_bottom.item_height
|
||||
text: _('Open Channel')
|
||||
on_release: s.do_open_channel()
|
||||
''')
|
||||
|
||||
class LightningOpenChannelDialog(Factory.Popup):
|
||||
def ipport_dialog(self):
|
||||
def callback(text):
|
||||
self.ipport = text
|
||||
d = LabelDialog(_('IP/port in format:\n[host]:[port]'), self.ipport, callback)
|
||||
d.open()
|
||||
|
||||
def on_pubkey(self, data):
|
||||
self.pubkey = data.replace('\n', '') # strip newlines if we choose from ChoiseDialog
|
||||
|
||||
def choose_node(self):
|
||||
lines = []
|
||||
suggested = self.app.wallet.lnworker.suggest_peer()
|
||||
if suggested:
|
||||
assert len(suggested) == 33
|
||||
for i in range(0, 34, 11):
|
||||
lines += [bh2u(suggested[i:i+11])]
|
||||
servers = ['\n'.join(lines)]
|
||||
ChoiceDialog(_('Choose node to connect to'), sorted(servers), self.pubkey, self.on_pubkey).open()
|
||||
|
||||
def __init__(self, app, lnaddr=None, msg=None):
|
||||
super(LightningOpenChannelDialog, self).__init__()
|
||||
self.app = app
|
||||
self.lnaddr = lnaddr
|
||||
self.msg = msg
|
||||
|
||||
def open(self, *args, **kwargs):
|
||||
super(LightningOpenChannelDialog, self).open(*args, **kwargs)
|
||||
if self.lnaddr:
|
||||
fee = self.app.electrum_config.fee_per_kb()
|
||||
if not fee:
|
||||
fee = config.FEERATE_FALLBACK_STATIC_FEE
|
||||
self.amount = self.app.format_amount_and_units(self.lnaddr.amount * COIN + fee * 2)
|
||||
self.pubkey = bh2u(self.lnaddr.pubkey.serialize())
|
||||
if self.msg:
|
||||
self.app.show_info(self.msg)
|
||||
|
||||
def do_paste(self):
|
||||
contents = self.app._clipboard.paste()
|
||||
if not contents:
|
||||
self.app.show_info(_("Clipboard is empty"))
|
||||
return
|
||||
self.pubkey = contents
|
||||
|
||||
def do_open_channel(self):
|
||||
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()
|
||||
try:
|
||||
node_id_hex = self.app.wallet.lnworker.open_channel(conn_str, self.app.get_amount(self.amount), 0)
|
||||
except Exception as e:
|
||||
self.app.show_error(_('Problem opening channel: ') + '\n' + repr(e))
|
||||
return
|
||||
self.app.show_info(_('Please wait for confirmation, channel is opening with node ') + node_id_hex[:16])
|
||||
self.dismiss()
|
|
@ -1,93 +0,0 @@
|
|||
import binascii
|
||||
from kivy.lang import Builder
|
||||
from kivy.factory import Factory
|
||||
from electrum.gui.kivy.i18n import _
|
||||
from kivy.clock import mainthread
|
||||
from electrum.lnaddr import lndecode
|
||||
|
||||
Builder.load_string('''
|
||||
<LightningPayerDialog@Popup>
|
||||
id: s
|
||||
name: 'lightning_payer'
|
||||
invoice_data: ''
|
||||
BoxLayout:
|
||||
orientation: "vertical"
|
||||
BlueButton:
|
||||
text: s.invoice_data if s.invoice_data else _('Lightning invoice')
|
||||
shorten: True
|
||||
on_release: Clock.schedule_once(lambda dt: app.show_info(_('Copy and paste the lightning invoice using the Paste button, or use the camera to scan a QR code.')))
|
||||
GridLayout:
|
||||
cols: 4
|
||||
size_hint: 1, None
|
||||
height: '48dp'
|
||||
IconButton:
|
||||
id: qr
|
||||
on_release: Clock.schedule_once(lambda dt: app.scan_qr(on_complete=s.on_lightning_qr))
|
||||
icon: 'atlas://gui/kivy/theming/light/camera'
|
||||
Button:
|
||||
text: _('Paste')
|
||||
on_release: s.do_paste()
|
||||
Button:
|
||||
text: _('Paste using xclip')
|
||||
on_release: s.do_paste_xclip()
|
||||
Button:
|
||||
text: _('Clear')
|
||||
on_release: s.do_clear()
|
||||
Button:
|
||||
size_hint: 1, None
|
||||
height: '48dp'
|
||||
text: _('Open channel to pubkey in invoice')
|
||||
on_release: s.do_open_channel()
|
||||
Button:
|
||||
size_hint: 1, None
|
||||
height: '48dp'
|
||||
text: _('Pay pasted/scanned invoice')
|
||||
on_release: s.do_pay()
|
||||
''')
|
||||
|
||||
class LightningPayerDialog(Factory.Popup):
|
||||
def __init__(self, app):
|
||||
super(LightningPayerDialog, self).__init__()
|
||||
self.app = app
|
||||
|
||||
#def open(self, *args, **kwargs):
|
||||
# super(LightningPayerDialog, self).open(*args, **kwargs)
|
||||
#def dismiss(self, *args, **kwargs):
|
||||
# super(LightningPayerDialog, self).dismiss(*args, **kwargs)
|
||||
|
||||
def do_paste_xclip(self):
|
||||
import subprocess
|
||||
proc = subprocess.run(["xclip","-sel","clipboard","-o"], stdout=subprocess.PIPE)
|
||||
self.invoice_data = proc.stdout.decode("ascii")
|
||||
|
||||
def do_paste(self):
|
||||
contents = self.app._clipboard.paste()
|
||||
if not contents:
|
||||
self.app.show_info(_("Clipboard is empty"))
|
||||
return
|
||||
self.invoice_data = contents
|
||||
|
||||
def do_clear(self):
|
||||
self.invoice_data = ""
|
||||
|
||||
def do_open_channel(self):
|
||||
compressed_pubkey_bytes = lndecode(self.invoice_data).pubkey.serialize()
|
||||
hexpubkey = binascii.hexlify(compressed_pubkey_bytes).decode("ascii")
|
||||
local_amt = 200000
|
||||
push_amt = 100000
|
||||
|
||||
def on_success(pw):
|
||||
# node_id, local_amt, push_amt, emit_function, get_password
|
||||
self.app.wallet.lnworker.open_channel_from_other_thread(hexpubkey, local_amt, push_amt, mainthread(lambda parent: self.app.show_info(_("Channel open, waiting for locking..."))), lambda: pw)
|
||||
|
||||
if self.app.wallet.has_keystore_encryption():
|
||||
# wallet, msg, on_success (Tuple[str, str] -> ()), on_failure (() -> ())
|
||||
self.app.password_dialog(self.app.wallet, _("Password needed for opening channel"), on_success, lambda: self.app.show_error(_("Failed getting password from you")))
|
||||
else:
|
||||
on_success("")
|
||||
|
||||
def do_pay(self):
|
||||
self.app.wallet.lnworker.pay_invoice_from_other_thread(self.invoice_data)
|
||||
|
||||
def on_lightning_qr(self, data):
|
||||
self.invoice_data = str(data)
|
|
@ -30,7 +30,7 @@ from electrum.lnaddr import lndecode
|
|||
from electrum.lnutil import RECEIVED, SENT
|
||||
|
||||
from .context_menu import ContextMenu
|
||||
|
||||
from .dialogs.lightning_open_channel import LightningOpenChannelDialog
|
||||
|
||||
from electrum.gui.kivy.i18n import _
|
||||
|
||||
|
@ -268,11 +268,13 @@ class SendScreen(CScreen):
|
|||
return
|
||||
invoice = self.screen.address
|
||||
amount_sat = self.app.get_amount(self.screen.amount)
|
||||
addr = self.app.wallet.lnworker._check_invoice(invoice, amount_sat)
|
||||
try:
|
||||
addr = self.app.wallet.lnworker._check_invoice(invoice, amount_sat)
|
||||
route = self.app.wallet.lnworker._create_route_from_invoice(decoded_invoice=addr)
|
||||
except Exception as e:
|
||||
self.app.show_error(_('Could not find path for payment. Check if you have open channels. Error details:') + ':\n' + repr(e))
|
||||
dia = LightningOpenChannelDialog(self.app, addr, str(e) + _(':\nYou can open a channel.'))
|
||||
dia.open()
|
||||
return
|
||||
self.app.network.register_callback(self.payment_completed_async_thread, ['ln_payment_completed'])
|
||||
_addr, _peer, coro = self.app.wallet.lnworker._pay(invoice, amount_sat)
|
||||
fut = asyncio.run_coroutine_threadsafe(coro, self.app.network.asyncio_loop)
|
||||
|
|
|
@ -240,6 +240,7 @@ class LNWorker(PrintError):
|
|||
if conf >= chan.constraints.funding_txn_minimum_depth > 0:
|
||||
chan.short_channel_id = chan.short_channel_id_predicted
|
||||
self.save_channel(chan)
|
||||
self.on_channels_updated()
|
||||
return True, conf
|
||||
return False, conf
|
||||
|
||||
|
@ -255,6 +256,7 @@ class LNWorker(PrintError):
|
|||
if is_spent:
|
||||
if chan.get_state() != 'FORCE_CLOSING':
|
||||
chan.set_state("CLOSED")
|
||||
self.on_channels_updated()
|
||||
self.channel_db.remove_channel(chan.short_channel_id)
|
||||
self.network.trigger_callback('channel', chan)
|
||||
|
||||
|
@ -543,6 +545,7 @@ class LNWorker(PrintError):
|
|||
tx = chan.force_close_tx()
|
||||
chan.set_state('FORCE_CLOSING')
|
||||
self.save_channel(chan)
|
||||
self.on_channels_updated()
|
||||
return await self.network.broadcast_transaction(tx)
|
||||
|
||||
def _get_next_peers_to_try(self) -> Sequence[LNPeerAddr]:
|
||||
|
|
Loading…
Add table
Reference in a new issue