Skip to main content

A reusable parser for Lightning Network gossip messages format.

Project description

Ruff Code style: black Checked with mypy Uses: dataclasses Uses: typing

Commitizen friendly

lnhistoryclient

A Python client library to parse and handle raw Lightning Network gossip messages. Reusable, and production-tested on real-world data. For details about the gossip messages see the Lightning Network specifications BOLT #7 This python package is part of the ln-history project.


Installation

pip install lnhistoryclient

Usage

To parse a single raw Lightning Network gossip message, first extract the message type, then use the type to select the appropriate parser. This ensures correctness and avoids interpreting invalid data. The library accepts both bytes and io.BytesIO objects as input for maximum flexibility.

from lnhistoryclient.parser.common import get_message_type, strip_known_message_type
from lnhistoryclient.parser.parser_factory import get_parser_by_message_type


raw_hex = bytes.fromhex("0101...")  # Replace with actual raw hex (includes 2-byte type prefix)

msg_type = get_message_type_by_raw_hex(raw_hex)
if msg_type is not None:
    parser = get_parser_by_message_type(msg_type)
    result = parser(strip_known_message_type(raw_hex))  # Strip the type prefix
    print(result)
else:
    print("Unknown or unsupported message type.")

For convenience (and if you're confident the input is valid), a shortcut is also available:

from lnhistoryclient.parser.parser_factory import get_parser_from_raw_hex
from lnhistoryclient.parser.common import strip_known_message_type

raw_hex = bytes.fromhex("0101...")  # Replace with actual raw hex

parser = get_parser_from_raw_hex(raw_hex)
if parser:
    result = parser(strip_known_message_type(raw_hex))
    print(result)
else:
    print("Could not determine parser.")

You can also directly use individual parsers if you know the message type:

from lnhistoryclient.parser.channel_announcement_parser import parse_channel_announcement
from lnhistoryclient.parser.common import strip_known_message_type

result = parse_channel_announcement(strip_known_message_type(raw_hex))
print(result)

In case you have a file with multiple gossip messages there is also the read_gossip_file function available:

from lnhistoryclient.parser.gossip_file import read_gossip_file
from lnhistoryclient.parser.common import get_message_type_by_bytes, strip_known_message_type
from lnhistoryclient.parser.parser_map import PARSER_MAP

for msg in read_gossip_file("path/to/your/gossip-file"):
    msg_type = get_message_type_by_bytes(msg)
    parse_func = PARSER_MAP[msg_type]
    parsed_msg = parse_func(strip_known_message_type(msg))
    print(parsed_msg)

Please see the doc string of the read_gossip_file for detailed information about the type of the gossip-file. In short: Various file formats are supported and automatically detected.

Graph building & analytics

Graph construction, network analytics, and the API client live under optional submodules and require the analysis extra (the core parser stays dependency-free):

pip install "lnhistoryclient[analysis]"   # networkx, numpy, scipy, requests, pandas, matplotlib

Fetch a snapshot from the ln-history API and analyse it:

from datetime import datetime
from lnhistoryclient.api import LnhistoryRequester
from lnhistoryclient.graph import graph_stats
from lnhistoryclient.analysis import Metric, top_nodes_by, simulate_random_payments

with LnhistoryRequester(backend_url="http://localhost:5050") as client:
    # enrich_capacity=True adds on-chain capacity_sat via the bulk capacities endpoint
    G = client.get_snapshot(datetime(2021, 6, 1), with_updates=True, enrich_capacity=True)

print(graph_stats(G))                                        # nodes/channels/components

# Node ranking — one entry point, metric + optional weighting:
top_nodes_by(G, Metric.BETWEENNESS)                          # unweighted routing importance
top_nodes_by(G, Metric.STRENGTH, weight="capacity")         # most liquidity
top_nodes_by(G, Metric.BETWEENNESS, weight="fee")           # cheapest-path centrality

# Payment simulation (balance-agnostic — an upper bound on routability):
summary = simulate_random_payments(G, n=1000, amount_sat=100_000, seed=42)
print(summary.success_rate, summary.failure_reasons)

The canonical graph is a lossless networkx.MultiDiGraph (build_multidigraph); use to_directed_simple / to_undirected_simple to project it for routing or topology metrics. See examples/analyse_snapshot.py for a full showcase. Weighting conventions (fee cost, capacity inversion) live in lnhistoryclient.analysis.weights.

Model

The library provides python typing models for every gossip message. See in the project structure section below for details.

Project Structure

The function are grouped into different directories depending on their functionality. On the root level (.) the Lnhistoryrequester.py class is the only class you need to import, in case you want to query the ln-history platform and do not have your own data. The constants.py and common.py files contain constants of the Bitcoin Lightning Specification as well as helper functions. The model directory python typing models. The parser directory contains all functions to parse a gossip message (including core-lightning internal ones) from raw bytes or hex into something human readable (python typing models).

Requirements

Python >=3.9, <4.0

Dependencies

The core parser has no runtime dependencies. Graph/analytics/API features are opt-in via pip install "lnhistoryclient[analysis]", which pulls networkx, numpy, scipy, requests, pandas, and matplotlib.

Code Style, Linting etc.

The code has been formatted using ruff, black and mypy

Contributing

Pull requests, issues, and feature ideas are always welcome! Fork the repo Create a new branch Submit a PR with a clear description

This project is MIT licensed.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lnhistoryclient-4.0.0.tar.gz (46.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lnhistoryclient-4.0.0-py3-none-any.whl (55.0 kB view details)

Uploaded Python 3

File details

Details for the file lnhistoryclient-4.0.0.tar.gz.

File metadata

  • Download URL: lnhistoryclient-4.0.0.tar.gz
  • Upload date:
  • Size: 46.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for lnhistoryclient-4.0.0.tar.gz
Algorithm Hash digest
SHA256 2fa970f06b8350e24caf8dbd3acdc3ec8b327df2eb736af7ad581bc3f16772f3
MD5 751c9ece70c6b1974397b2d060cca643
BLAKE2b-256 72ecc0694a3cbe78ae1fb245a022b32c5d5cf3f16d4dc02424575ee0d7053907

See more details on using hashes here.

File details

Details for the file lnhistoryclient-4.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for lnhistoryclient-4.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 20d1e4532d78d912dd5087c09ba45bef5f40a11657da19da69b9ed519e310240
MD5 f45a0e6ed0073a3da2f1fd538d80def8
BLAKE2b-256 220a1b40527e678299cb0be79d6d6c4de8babc0b9a024f932fc1947809a1645f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page