URI: 
       tlnbase: derive keys from wallet keystore - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 96544b8b580149d808fd46bb574d7497f8ae70c6
   DIR parent bdec72dd4b7afb133c259de65070eafa09dbb02b
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Tue, 24 Apr 2018 09:55:29 +0200
       
       lnbase: derive keys from wallet keystore
       
       Diffstat:
         M electrum/keystore.py                |       5 ++++-
         M lib/lnbase.py                       |      58 ++++++++++++++-----------------
         M lib/tests/test_lnbase_online.py     |       3 ++-
       
       3 files changed, 33 insertions(+), 33 deletions(-)
       ---
   DIR diff --git a/electrum/keystore.py b/electrum/keystore.py
       t@@ -383,7 +383,10 @@ class BIP32_KeyStore(Deterministic_KeyStore, Xpub):
                pk = node.eckey.get_secret_bytes()
                return pk, True
        
       -
       +    def get_keypair(self, sequence, password):
       +        k, _ = self.get_private_key(sequence, password)
       +        K, cK = get_pubkeys_from_secret(k)
       +        return cK, k
        
        class Old_KeyStore(Deterministic_KeyStore):
        
   DIR diff --git a/lib/lnbase.py b/lib/lnbase.py
       t@@ -36,7 +36,6 @@ from collections import namedtuple, defaultdict
        # hardcoded nodes
        node_list = [
            ('ecdsa.net', '9735', '038370f0e7a03eded3e1d41dc081084a87f0afa1c5b22090b4f3abb391eb15d8ff'),
       -    ('77.58.162.148', '9735', '022bb78ab9df617aeaaf37f6644609abb7295fad0c20327bccd41f8d69173ccb49')
        ]
        
        
       t@@ -292,15 +291,6 @@ LocalState = namedtuple("LocalState", ["ctn", "per_commitment_secret_seed", "amo
        ChannelConstraints = namedtuple("ChannelConstraints", ["feerate", "capacity", "is_initiator"])
        OpenChannel = namedtuple("OpenChannel", ["channel_id", "funding_outpoint", "local_config", "remote_config", "remote_state", "local_state", "constraints"])
        
       -class KeypairGenerator:
       -    def __init__(self, seed):
       -        self.xprv, xpub = bitcoin.bip32_root(seed, "p2wpkh")
       -    def get(self, keyfamily, index):
       -        childxprv, childxpub = bitcoin.bip32_private_derivation(self.xprv, "m/", "m/42'/{keyfamily}'/{index}'".format(keyfamily=keyfamily, index=index))
       -        _, _, _, _, child_c, child_cK = bitcoin.deserialize_xpub(childxpub)
       -        _, _, _, _, _, k = bitcoin.deserialize_xprv(childxprv)
       -        assert len(k) == 32
       -        return Keypair(pubkey=child_cK, privkey=k)
        
        def aiosafe(f):
            async def f2(*args, **kwargs):
       t@@ -526,10 +516,10 @@ def make_commitment(ctn, local_funding_pubkey, remote_funding_pubkey, remote_pay
        
        
        class Peer(PrintError):
       -    def __init__(self, host, port, pubkey, request_initial_sync=False, network=None):
       +    def __init__(self, host, port, pubkey, privkey, request_initial_sync=False, network=None):
                self.host = host
                self.port = port
       -        self.privkey = os.urandom(32) + b"\x01"
       +        self.privkey = privkey
                self.pubkey = pubkey
                self.network = network
                self.read_buffer = b''
       t@@ -744,10 +734,8 @@ class Peer(PrintError):
                self.writer.close()
        
            @aiosafe
       -    async def channel_establishment_flow(self, wallet, config, funding_sat, push_msat, temp_channel_id, keypair_generator=None):
       +    async def channel_establishment_flow(self, wallet, config, password, funding_sat, push_msat, temp_channel_id):
                await self.initialized
       -        if keypair_generator is None:
       -            keypair_generator = KeypairGenerator(b"testseed")
                # see lnd/keychain/derivation.go
                keyfamilymultisig = 0
                keyfamilyrevocationbase = 1
       t@@ -763,12 +751,13 @@ class Peer(PrintError):
                local_max_htlc_value_in_flight_msat = 500000 * 1000
                local_max_accepted_htlcs = 5
                # key derivation
       +        keypair_generator = lambda family, i: Keypair(*wallet.keystore.get_keypair([family, i], password))
                local_config=ChannelConfig(
       -            payment_basepoint=keypair_generator.get(keyfamilypaymentbase, 0),
       -            multisig_key=keypair_generator.get(keyfamilymultisig, 0),
       -            htlc_basepoint=keypair_generator.get(keyfamilyhtlcbase, 0),
       -            delayed_basepoint=keypair_generator.get(keyfamilydelaybase, 0),
       -            revocation_basepoint=keypair_generator.get(keyfamilyrevocationbase, 0),
       +            payment_basepoint=keypair_generator(keyfamilypaymentbase, 0),
       +            multisig_key=keypair_generator(keyfamilymultisig, 0),
       +            htlc_basepoint=keypair_generator(keyfamilyhtlcbase, 0),
       +            delayed_basepoint=keypair_generator(keyfamilydelaybase, 0),
       +            revocation_basepoint=keypair_generator(keyfamilyrevocationbase, 0),
                    to_self_delay=to_self_delay,
                    dust_limit_sat=dust_limit_sat,
                    max_htlc_value_in_flight_msat=local_max_htlc_value_in_flight_msat,
       t@@ -1101,23 +1090,30 @@ class Peer(PrintError):
                self.revoke_and_ack[channel_id].set_result(payload)
        
        
       -
        # replacement for lightningCall
        class LNWorker:
        
            def __init__(self, wallet, network):
       +        self.privkey = bitcoin.sha256('1234567890')
                self.wallet = wallet
                self.network = network
       -        host, port, pubkey = network.config.get('lightning_peer', node_list[0])
       -        pubkey = binascii.unhexlify(pubkey)
       -        port = int(port)
       -        self.peer = Peer(host, port, pubkey)
       -        self.network.futures.append(asyncio.run_coroutine_threadsafe(self.peer.main_loop(), asyncio.get_event_loop()))
       -
       -    def openchannel(self):
       -        # todo: get utxo from wallet
       -        # submit coro to asyncio main loop
       -        self.peer.open_channel()
       +        self.config = network.config
       +        self.peers = {}
       +        self.channels = {}
       +        peer_list = network.config.get('lightning_peers', node_list)
       +        for host, port, pubkey in peer_list:
       +            self.add_peer(host, port, pubkey)
       +
       +    def add_peer(self, host, port, pubkey):
       +        peer = Peer(host, int(port), binascii.unhexlify(pubkey), self.privkey)
       +        self.network.futures.append(asyncio.run_coroutine_threadsafe(peer.main_loop(), asyncio.get_event_loop()))
       +        self.peers[pubkey] = peer
       +
       +    def open_channel(self, pubkey, amount, push_msat, password):
       +        keystore = self.wallet.keystore
       +        peer = self.peers.get(pubkey)
       +        coro = peer.channel_establishment_flow(self.wallet, self.config, password, amount, push_msat, temp_channel_id=os.urandom(32))
       +        fut = asyncio.run_coroutine_threadsafe(coro, self.network.asyncio_loop)
        
        
        class ChannelInfo(PrintError):
   DIR diff --git a/lib/tests/test_lnbase_online.py b/lib/tests/test_lnbase_online.py
       t@@ -41,7 +41,8 @@ if __name__ == "__main__":
            wallet = Wallet(storage)
            wallet.start_threads(network)
            # start peer
       -    peer = Peer(host, port, pubkey, request_initial_sync=False, network=network)
       +    privkey = sha256('1234567890')
       +    peer = Peer(host, port, pubkey, privkey, request_initial_sync=False, network=network)
            network.futures.append(asyncio.run_coroutine_threadsafe(peer.main_loop(), network.asyncio_loop))
        
            funding_satoshis = 1000000