kivy: port lightning ui to lnbase
This commit is contained in:
@@ -2100,6 +2100,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
|
|||||||
'util': util,
|
'util': util,
|
||||||
'bitcoin': bitcoin,
|
'bitcoin': bitcoin,
|
||||||
})
|
})
|
||||||
|
if self.config.get('lnbase', False): console.updateNamespace({'lightning' : self.wallet.lnworker.console_interface})
|
||||||
|
|
||||||
c = commands.Commands(self.config, self.wallet, self.network, lambda: self.console.set_json(True))
|
c = commands.Commands(self.config, self.wallet, self.network, lambda: self.console.set_json(True))
|
||||||
methods = {}
|
methods = {}
|
||||||
|
|||||||
@@ -3,16 +3,15 @@ from kivy.lang import Builder
|
|||||||
from kivy.factory import Factory
|
from kivy.factory import Factory
|
||||||
from kivy.uix.popup import Popup
|
from kivy.uix.popup import Popup
|
||||||
from kivy.clock import Clock
|
from kivy.clock import Clock
|
||||||
import electrum.lightning as lightning
|
|
||||||
from electrum_gui.kivy.uix.context_menu import ContextMenu
|
from electrum_gui.kivy.uix.context_menu import ContextMenu
|
||||||
|
|
||||||
Builder.load_string('''
|
Builder.load_string('''
|
||||||
<LightningChannelItem@CardItem>
|
<LightningChannelItem@CardItem>
|
||||||
details: {}
|
details: {}
|
||||||
active: False
|
active: False
|
||||||
channelPoint: '<channelPoint not set>'
|
channelId: '<channelId not set>'
|
||||||
Label:
|
Label:
|
||||||
text: root.channelPoint
|
text: root.channelId
|
||||||
|
|
||||||
<LightningChannelsDialog@Popup>:
|
<LightningChannelsDialog@Popup>:
|
||||||
name: 'lightning_channels'
|
name: 'lightning_channels'
|
||||||
@@ -87,6 +86,7 @@ class LightningChannelsDialog(Factory.Popup):
|
|||||||
self.clocks = []
|
self.clocks = []
|
||||||
self.app = app
|
self.app = app
|
||||||
self.context_menu = None
|
self.context_menu = None
|
||||||
|
self.app.wallet.lnworker.subscribe_channel_list_updates_from_other_thread(self.rpc_result_handler)
|
||||||
|
|
||||||
def show_channel_details(self, obj):
|
def show_channel_details(self, obj):
|
||||||
p = Factory.ChannelDetailsPopup()
|
p = Factory.ChannelDetailsPopup()
|
||||||
@@ -94,8 +94,7 @@ class LightningChannelsDialog(Factory.Popup):
|
|||||||
p.open()
|
p.open()
|
||||||
|
|
||||||
def close_channel(self, obj):
|
def close_channel(self, obj):
|
||||||
print("asked to close channel", obj.channelPoint)
|
print("UNIMPLEMENTED asked to close channel", obj.channelId) # TODO
|
||||||
lightning.lightningCall(self.app.wallet.network.lightningrpc, "closechannel")(*([obj.channelPoint] + (["--force"] if not obj.active else [])))
|
|
||||||
|
|
||||||
def show_menu(self, obj):
|
def show_menu(self, obj):
|
||||||
self.hide_menu()
|
self.hide_menu()
|
||||||
@@ -108,24 +107,7 @@ class LightningChannelsDialog(Factory.Popup):
|
|||||||
self.ids.box.remove_widget(self.context_menu)
|
self.ids.box.remove_widget(self.context_menu)
|
||||||
self.context_menu = None
|
self.context_menu = None
|
||||||
|
|
||||||
def open(self, *args, **kwargs):
|
def rpc_result_handler(self, res):
|
||||||
super(LightningChannelsDialog, self).open(*args, **kwargs)
|
|
||||||
for i in self.clocks: i.cancel()
|
|
||||||
self.clocks.append(Clock.schedule_interval(self.fetch_channels, 10))
|
|
||||||
self.app.wallet.network.lightningrpc.subscribe(self.rpc_result_handler)
|
|
||||||
|
|
||||||
def dismiss(self, *args, **kwargs):
|
|
||||||
self.hide_menu()
|
|
||||||
super(LightningChannelsDialog, self).dismiss(*args, **kwargs)
|
|
||||||
self.app.wallet.network.lightningrpc.clearSubscribers()
|
|
||||||
|
|
||||||
def fetch_channels(self, dw):
|
|
||||||
lightning.lightningCall(self.app.wallet.network.lightningrpc, "listchannels")()
|
|
||||||
|
|
||||||
def rpc_result_handler(self, methodName, res):
|
|
||||||
print("got result", methodName)
|
|
||||||
if isinstance(res, Exception):
|
|
||||||
raise res
|
|
||||||
channel_cards = self.ids.lightning_channels_container
|
channel_cards = self.ids.lightning_channels_container
|
||||||
channel_cards.clear_widgets()
|
channel_cards.clear_widgets()
|
||||||
if "channels" in res:
|
if "channels" in res:
|
||||||
@@ -133,7 +115,7 @@ class LightningChannelsDialog(Factory.Popup):
|
|||||||
item = Factory.LightningChannelItem()
|
item = Factory.LightningChannelItem()
|
||||||
item.screen = self
|
item.screen = self
|
||||||
print(i)
|
print(i)
|
||||||
item.channelPoint = i["channel_point"].split(":")[0]
|
item.channelId = i["chan_id"]
|
||||||
item.active = i["active"]
|
item.active = i["active"]
|
||||||
item.details = i
|
item.details = i
|
||||||
channel_cards.add_widget(item)
|
channel_cards.add_widget(item)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import binascii
|
|||||||
from kivy.lang import Builder
|
from kivy.lang import Builder
|
||||||
from kivy.factory import Factory
|
from kivy.factory import Factory
|
||||||
from electrum_gui.kivy.i18n import _
|
from electrum_gui.kivy.i18n import _
|
||||||
import electrum.lightning as lightning
|
from kivy.clock import mainthread
|
||||||
from electrum.lightning_payencode.lnaddr import lndecode
|
from electrum.lightning_payencode.lnaddr import lndecode
|
||||||
|
|
||||||
Builder.load_string('''
|
Builder.load_string('''
|
||||||
@@ -49,36 +49,45 @@ class LightningPayerDialog(Factory.Popup):
|
|||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
super(LightningPayerDialog, self).__init__()
|
super(LightningPayerDialog, self).__init__()
|
||||||
self.app = app
|
self.app = app
|
||||||
def open(self, *args, **kwargs):
|
|
||||||
super(LightningPayerDialog, self).open(*args, **kwargs)
|
#def open(self, *args, **kwargs):
|
||||||
class FakeQtSignal:
|
# super(LightningPayerDialog, self).open(*args, **kwargs)
|
||||||
def emit(self2, data):
|
#def dismiss(self, *args, **kwargs):
|
||||||
self.app.show_info(data)
|
# super(LightningPayerDialog, self).dismiss(*args, **kwargs)
|
||||||
class MyConsole:
|
|
||||||
new_lightning_result = FakeQtSignal()
|
|
||||||
self.app.wallet.network.lightningrpc.setConsole(MyConsole())
|
|
||||||
def dismiss(self, *args, **kwargs):
|
|
||||||
super(LightningPayerDialog, self).dismiss(*args, **kwargs)
|
|
||||||
self.app.wallet.network.lightningrpc.setConsole(None)
|
|
||||||
def do_paste_xclip(self):
|
def do_paste_xclip(self):
|
||||||
import subprocess
|
import subprocess
|
||||||
proc = subprocess.run(["xclip","-sel","clipboard","-o"], stdout=subprocess.PIPE)
|
proc = subprocess.run(["xclip","-sel","clipboard","-o"], stdout=subprocess.PIPE)
|
||||||
self.invoice_data = proc.stdout.decode("ascii")
|
self.invoice_data = proc.stdout.decode("ascii")
|
||||||
|
|
||||||
def do_paste(self):
|
def do_paste(self):
|
||||||
contents = self.app._clipboard.paste()
|
contents = self.app._clipboard.paste()
|
||||||
if not contents:
|
if not contents:
|
||||||
self.app.show_info(_("Clipboard is empty"))
|
self.app.show_info(_("Clipboard is empty"))
|
||||||
return
|
return
|
||||||
self.invoice_data = contents
|
self.invoice_data = contents
|
||||||
|
|
||||||
def do_clear(self):
|
def do_clear(self):
|
||||||
self.invoice_data = ""
|
self.invoice_data = ""
|
||||||
|
|
||||||
def do_open_channel(self):
|
def do_open_channel(self):
|
||||||
compressed_pubkey_bytes = lndecode(self.invoice_data).pubkey.serialize()
|
compressed_pubkey_bytes = lndecode(self.invoice_data).pubkey.serialize()
|
||||||
hexpubkey = binascii.hexlify(compressed_pubkey_bytes).decode("ascii")
|
hexpubkey = binascii.hexlify(compressed_pubkey_bytes).decode("ascii")
|
||||||
local_amt = 100000
|
local_amt = 200000
|
||||||
push_amt = 0
|
push_amt = 100000
|
||||||
lightning.lightningCall(self.app.wallet.network.lightningrpc, "openchannel")(hexpubkey, local_amt, push_amt)
|
|
||||||
|
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):
|
def do_pay(self):
|
||||||
lightning.lightningCall(self.app.wallet.network.lightningrpc, "sendpayment")("--pay_req=" + self.invoice_data)
|
self.app.wallet.lnworker.pay_invoice_from_other_thread(self.invoice_data)
|
||||||
|
|
||||||
def on_lightning_qr(self, data):
|
def on_lightning_qr(self, data):
|
||||||
self.invoice_data = str(data)
|
self.invoice_data = str(data)
|
||||||
|
|||||||
@@ -1434,6 +1434,9 @@ class LNWorker:
|
|||||||
def subscribe_invoice_added_from_other_thread(self, emit_function):
|
def subscribe_invoice_added_from_other_thread(self, emit_function):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def pay_invoice_from_other_thread(self, lnaddr):
|
||||||
|
pass
|
||||||
|
|
||||||
class ChannelInfo(PrintError):
|
class ChannelInfo(PrintError):
|
||||||
|
|
||||||
def __init__(self, channel_announcement_payload):
|
def __init__(self, channel_announcement_payload):
|
||||||
|
|||||||
Reference in New Issue
Block a user