def lndecode(invoice: str, *, verbose=False, net=None) -> LnAddr:
    if (net is None):
        net = constants.net
    decoded_bech32 = bech32_decode(invoice, ignore_long_length=True)
    hrp = decoded_bech32.hrp
    data = decoded_bech32.data
    if (decoded_bech32.encoding is None):
        raise LnDecodeException('Bad bech32 checksum')
    if (decoded_bech32.encoding != segwit_addr.Encoding.BECH32):
        raise LnDecodeException('Bad bech32 encoding: must be using vanilla BECH32')
    if (not hrp.startswith('ln')):
        raise LnDecodeException('Does not start with ln')
    if (not hrp[2:].startswith(net.BOLT11_HRP)):
        raise LnDecodeException(f'Wrong Lightning invoice HRP {hrp[2:]}, should be {net.BOLT11_HRP}')
    data = u5_to_bitarray(data)
    if (len(data) < (65 * 8)):
        raise LnDecodeException('Too short to contain signature')
    sigdecoded = data[((- 65) * 8):].tobytes()
    data = bitstring.ConstBitStream(data[:((- 65) * 8)])
    addr = LnAddr()
    addr.pubkey = None
    m = re.search('[^\\d]+', hrp[2:])
    if m:
        addr.net = BOLT11_HRP_INV_DICT[m.group(0)]
        amountstr = hrp[(2 + m.end()):]
        if (amountstr != ''):
            addr.amount = unshorten_amount(amountstr)
    addr.date = data.read(35).uint
    while (data.pos != data.len):
        (tag, tagdata, data) = pull_tagged(data)
        data_length = (len(tagdata) / 5)
        if (tag == 'r'):
            route = []
            s = bitstring.ConstBitStream(tagdata)
            while ((((((s.pos + 264) + 64) + 32) + 32) + 16) < s.len):
                route.append((s.read(264).tobytes(), s.read(64).tobytes(), s.read(32).uintbe, s.read(32).uintbe, s.read(16).uintbe))
            addr.tags.append(('r', route))
        elif (tag == 't'):
            s = bitstring.ConstBitStream(tagdata)
            e = (s.read(264).tobytes(), s.read(32).uintbe, s.read(32).uintbe, s.read(16).uintbe)
            addr.tags.append(('t', e))
        elif (tag == 'f'):
            fallback = parse_fallback(tagdata, addr.net)
            if fallback:
                addr.tags.append(('f', fallback))
            else:
                addr.unknown_tags.append((tag, tagdata))
                continue
        elif (tag == 'd'):
            addr.tags.append(('d', trim_to_bytes(tagdata).decode('utf-8')))
        elif (tag == 'h'):
            if (data_length != 52):
                addr.unknown_tags.append((tag, tagdata))
                continue
            addr.tags.append(('h', trim_to_bytes(tagdata)))
        elif (tag == 'x'):
            addr.tags.append(('x', tagdata.uint))
        elif (tag == 'p'):
            if (data_length != 52):
                addr.unknown_tags.append((tag, tagdata))
                continue
            addr.paymenthash = trim_to_bytes(tagdata)
        elif (tag == 's'):
            if (data_length != 52):
                addr.unknown_tags.append((tag, tagdata))
                continue
            addr.payment_secret = trim_to_bytes(tagdata)
        elif (tag == 'n'):
            if (data_length != 53):
                addr.unknown_tags.append((tag, tagdata))
                continue
            pubkeybytes = trim_to_bytes(tagdata)
            addr.pubkey = pubkeybytes
        elif (tag == 'c'):
            addr._min_final_cltv_expiry = tagdata.uint
        elif (tag == '9'):
            features = tagdata.uint
            addr.tags.append(('9', features))
            from .lnutil import validate_features
            validate_features(features)
        else:
            addr.unknown_tags.append((tag, tagdata))
    if verbose:
        print('hex of signature data (32 byte r, 32 byte s): {}'.format(hexlify(sigdecoded[0:64])))
        print('recovery flag: {}'.format(sigdecoded[64]))
        print('hex of data for signing: {}'.format(hexlify((hrp.encode('ascii') + data.tobytes()))))
        print('SHA256 of above: {}'.format(sha256((hrp.encode('ascii') + data.tobytes())).hexdigest()))
    addr.signature = sigdecoded[:65]
    hrp_hash = sha256((hrp.encode('ascii') + data.tobytes())).digest()
    if addr.pubkey:
        ecc.ECPubkey(addr.pubkey).verify_message_hash(sigdecoded[:64], hrp_hash)
        pubkey_copy = addr.pubkey

        class WrappedBytesKey():
            serialize = (lambda : pubkey_copy)
        addr.pubkey = WrappedBytesKey
    else:
        addr.pubkey = SerializableKey(ecc.ECPubkey.from_sig_string(sigdecoded[:64], sigdecoded[64], hrp_hash))
    return addr
def lndecode(invoice: str, *, verbose=False, net=None) -> LnAddr:
    if (net is None):
        net = constants.net
    decoded_bech32 = bech32_decode(invoice, ignore_long_length=True)
    hrp = decoded_bech32.hrp
    data = decoded_bech32.data
    if (decoded_bech32.encoding is None):
        raise LnDecodeException('Bad bech32 checksum')
    if (decoded_bech32.encoding != segwit_addr.Encoding.BECH32):
        raise LnDecodeException('Bad bech32 encoding: must be using vanilla BECH32')
    if (not hrp.startswith('ln')):
        raise LnDecodeException('Does not start with ln')
    if (not hrp[2:].startswith(net.BOLT11_HRP)):
        raise LnDecodeException(f'Wrong Lightning invoice HRP {hrp[2:]}, should be {net.BOLT11_HRP}')
    data = u5_to_bitarray(data)
    if (len(data) < (65 * 8)):
        raise LnDecodeException('Too short to contain signature')
    sigdecoded = data[((- 65) * 8):].tobytes()
    data = bitstring.ConstBitStream(data[:((- 65) * 8)])
    addr = LnAddr()
    addr.pubkey = None
    m = re.search('[^\\d]+', hrp[2:])
    if m:
        addr.net = BOLT11_HRP_INV_DICT[m.group(0)]
        amountstr = hrp[(2 + m.end()):]
        if (amountstr != ):
            addr.amount = unshorten_amount(amountstr)
    addr.date = data.read(35).uint
    while (data.pos != data.len):
        (tag, tagdata, data) = pull_tagged(data)
        data_length = (len(tagdata) / 5)
        if (tag == 'r'):
            route = []
            s = bitstring.ConstBitStream(tagdata)
            while ((((((s.pos + 264) + 64) + 32) + 32) + 16) < s.len):
                route.append((s.read(264).tobytes(), s.read(64).tobytes(), s.read(32).uintbe, s.read(32).uintbe, s.read(16).uintbe))
            addr.tags.append(('r', route))
        elif (tag == 't'):
            s = bitstring.ConstBitStream(tagdata)
            e = (s.read(264).tobytes(), s.read(32).uintbe, s.read(32).uintbe, s.read(16).uintbe)
            addr.tags.append(('t', e))
        elif (tag == 'f'):
            fallback = parse_fallback(tagdata, addr.net)
            if fallback:
                addr.tags.append(('f', fallback))
            else:
                addr.unknown_tags.append((tag, tagdata))
                continue
        elif (tag == 'd'):
            addr.tags.append(('d', trim_to_bytes(tagdata).decode('utf-8')))
        elif (tag == 'h'):
            if (data_length != 52):
                addr.unknown_tags.append((tag, tagdata))
                continue
            addr.tags.append(('h', trim_to_bytes(tagdata)))
        elif (tag == 'x'):
            addr.tags.append(('x', tagdata.uint))
        elif (tag == 'p'):
            if (data_length != 52):
                addr.unknown_tags.append((tag, tagdata))
                continue
            addr.paymenthash = trim_to_bytes(tagdata)
        elif (tag == 's'):
            if (data_length != 52):
                addr.unknown_tags.append((tag, tagdata))
                continue
            addr.payment_secret = trim_to_bytes(tagdata)
        elif (tag == 'n'):
            if (data_length != 53):
                addr.unknown_tags.append((tag, tagdata))
                continue
            pubkeybytes = trim_to_bytes(tagdata)
            addr.pubkey = pubkeybytes
        elif (tag == 'c'):
            addr._min_final_cltv_expiry = tagdata.uint
        elif (tag == '9'):
            features = tagdata.uint
            addr.tags.append(('9', features))
            from .lnutil import validate_features
            validate_features(features)
        else:
            addr.unknown_tags.append((tag, tagdata))
    if verbose:
        print('hex of signature data (32 byte r, 32 byte s): {}'.format(hexlify(sigdecoded[0:64])))
        print('recovery flag: {}'.format(sigdecoded[64]))
        print('hex of data for signing: {}'.format(hexlify((hrp.encode('ascii') + data.tobytes()))))
        print('SHA256 of above: {}'.format(sha256((hrp.encode('ascii') + data.tobytes())).hexdigest()))
    addr.signature = sigdecoded[:65]
    hrp_hash = sha256((hrp.encode('ascii') + data.tobytes())).digest()
    if addr.pubkey:
        ecc.ECPubkey(addr.pubkey).verify_message_hash(sigdecoded[:64], hrp_hash)
        pubkey_copy = addr.pubkey

        class WrappedBytesKey():
            serialize = (lambda : pubkey_copy)
        addr.pubkey = WrappedBytesKey
    else:
        addr.pubkey = SerializableKey(ecc.ECPubkey.from_sig_string(sigdecoded[:64], sigdecoded[64], hrp_hash))
    return addr