tkivy: port lightning ui to lnbase - electrum - Electrum Bitcoin wallet
 (HTM) git clone https://git.parazyd.org/electrum
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
       ---
 (DIR) commit 10e8a902242fd387f3539440cc8fc970e57b659f
 (DIR) parent 18963405eeb54259210a761aac23134b005dd40a
 (HTM) Author: Janus <ysangkok@gmail.com>
       Date:   Wed, 23 May 2018 19:08:46 +0200
       
       kivy: port lightning ui to lnbase
       
       Diffstat:
         M electrum/gui/qt/main_window.py      |       1 +
         M gui/kivy/uix/dialogs/lightning_cha… |      30 ++++++------------------------
         M gui/kivy/uix/dialogs/lightning_pay… |      41 +++++++++++++++++++------------
         M lib/lnbase.py                       |       3 +++
       
       4 files changed, 35 insertions(+), 40 deletions(-)
       ---
 (DIR) diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py
       t@@ -2100,6 +2100,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
                    'util': util,
                    '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))
                methods = {}
 (DIR) diff --git a/gui/kivy/uix/dialogs/lightning_channels.py b/gui/kivy/uix/dialogs/lightning_channels.py
       t@@ -3,16 +3,15 @@ from kivy.lang import Builder
        from kivy.factory import Factory
        from kivy.uix.popup import Popup
        from kivy.clock import Clock
       -import electrum.lightning as lightning
        from electrum_gui.kivy.uix.context_menu import ContextMenu
        
        Builder.load_string('''
        <LightningChannelItem@CardItem>
            details: {}
            active: False
       -    channelPoint: '<channelPoint not set>'
       +    channelId: '<channelId not set>'
            Label:
       -        text: root.channelPoint
       +        text: root.channelId
        
        <LightningChannelsDialog@Popup>:
            name: 'lightning_channels'
       t@@ -87,6 +86,7 @@ class LightningChannelsDialog(Factory.Popup):
                self.clocks = []
                self.app = app
                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):
                p = Factory.ChannelDetailsPopup()
       t@@ -94,8 +94,7 @@ class LightningChannelsDialog(Factory.Popup):
                p.open()
        
            def close_channel(self, obj):
       -        print("asked to close channel", obj.channelPoint)
       -        lightning.lightningCall(self.app.wallet.network.lightningrpc, "closechannel")(*([obj.channelPoint] + (["--force"] if not obj.active else [])))
       +        print("UNIMPLEMENTED asked to close channel", obj.channelId) # TODO
        
            def show_menu(self, obj):
                self.hide_menu()
       t@@ -108,24 +107,7 @@ class LightningChannelsDialog(Factory.Popup):
                    self.ids.box.remove_widget(self.context_menu)
                    self.context_menu = None
        
       -    def open(self, *args, **kwargs):
       -        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
       +    def rpc_result_handler(self, res):
                channel_cards = self.ids.lightning_channels_container
                channel_cards.clear_widgets()
                if "channels" in res:
       t@@ -133,7 +115,7 @@ class LightningChannelsDialog(Factory.Popup):
                    item = Factory.LightningChannelItem()
                    item.screen = self
                    print(i)
       -            item.channelPoint = i["channel_point"].split(":")[0]
       +            item.channelId = i["chan_id"]
                    item.active = i["active"]
                    item.details = i
                    channel_cards.add_widget(item)
 (DIR) diff --git a/gui/kivy/uix/dialogs/lightning_payer.py b/gui/kivy/uix/dialogs/lightning_payer.py
       t@@ -2,7 +2,7 @@ import binascii
        from kivy.lang import Builder
        from kivy.factory import Factory
        from electrum_gui.kivy.i18n import _
       -import electrum.lightning as lightning
       +from kivy.clock import mainthread
        from electrum.lightning_payencode.lnaddr import lndecode
        
        Builder.load_string('''
       t@@ -49,36 +49,45 @@ 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)
       -        class FakeQtSignal:
       -            def emit(self2, data):
       -                self.app.show_info(data)
       -        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 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 = 100000
       -        push_amt = 0
       -        lightning.lightningCall(self.app.wallet.network.lightningrpc, "openchannel")(hexpubkey, local_amt, push_amt)
       +        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):
       -        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):
                self.invoice_data = str(data)
 (DIR) diff --git a/lib/lnbase.py b/lib/lnbase.py
       t@@ -1434,6 +1434,9 @@ class LNWorker:
            def subscribe_invoice_added_from_other_thread(self, emit_function):
                pass
        
       +    def pay_invoice_from_other_thread(self, lnaddr):
       +        pass
       +
        class ChannelInfo(PrintError):
        
            def __init__(self, channel_announcement_payload):