Python 3 script to connect to an LND node via gRPC, cache daily routing economics in SQLite, and report monthly profit:
- Forwarding fee income
- Rebalancing fee costs
- Net routing profit (forwards - rebalances)
- Python 3.9+
- LND gRPC enabled and reachable from this host
- TLS cert and macaroon for your node
- Generated LND stubs present in this repo:
lightning_pb2.pyandlightning_pb2_grpc.py - Packages from
requirements.txt(protobuf + grpcio)
Recommended: use a virtual environment.
python3 -m venv .venv
source .venv/bin/activate # Windows PowerShell: .\.venv\Scripts\Activate.ps1
python3 -m pip install -r requirements.txtSet these before running. Recommended: create a .env file so you don't have to export variables every time.
LND_GRPC_HOST(e.g.127.0.0.1orlocalhost)LND_GRPC_PORT(e.g.10009)LND_TLS_CERT(path totls.cert)LND_MACAROON(path to macaroon, typically.../data/chain/bitcoin/mainnet/admin.macaroon)- Optional:
TZ(IANA timezone likeAmerica/Sao_Paulo; defaults to local time)
Create a .env file in the repo root (already in .gitignore) and run the script without exporting anything. The script loads .env automatically (uses python-dotenv if installed, otherwise a built-in minimal parser). Existing exported variables are not overridden.
Sample .env:
LND_GRPC_HOST=localhost
LND_GRPC_PORT=10009
LND_TLS_CERT="/home/admin/.lnd/tls.cert"
LND_MACAROON="/home/admin/.lnd/data/chain/bitcoin/mainnet/admin.macaroon"
# TZ=America/Sao_Paulo
Then just run:
python3 lnd_daily_fees.pyYou can set them directly in the shell (examples below).
Example (Linux/macOS):
export LND_GRPC_HOST=localhost
export LND_GRPC_PORT=10009
export LND_TLS_CERT="/home/admin/.lnd/tls.cert"
export LND_MACAROON="/home/admin/.lnd/data/chain/bitcoin/mainnet/admin.macaroon"
python3 lnd_daily_fees.pyPowerShell example:
$env:LND_GRPC_HOST = "name_machine"
$env:LND_GRPC_PORT = "10009"
$env:LND_TLS_CERT = "C:\Users\admin\.lnd\tls.cert"
$env:LND_MACAROON = "C:\Users\admin\.lnd\data\chain\bitcoin\mainnet\admin.macaroon"
python3 lnd_daily_fees.py- Default: backfill from the first day of the month that is
--monthsago up to yesterday (local time). Only days missing in the SQLite DB are fetched and stored. - Custom date range (inclusive, capped at yesterday):
python3 lnd_daily_fees.py --from 2025-12-01 --to 2025-12-03
- Override timezone:
python3 lnd_daily_fees.py --tz America/Sao_Paulo
- Choose database path (default:
lnd_fees.sqlite):python3 lnd_daily_fees.py --db-path /path/to/fees.sqlite
- Monthly report depth: show current month plus N previous months (default 3):
python3 lnd_daily_fees.py --months 6
The script prints:
- Which dates were inserted into the DB
- Node alias/pubkey (when connecting)
- Monthly revenue, rebalance costs, and profit for the current month plus
--monthsprevious months
ModuleNotFoundError: google: install protobuf viapip install -r requirements.txt.- TLS/macaroon path errors: verify the file paths set in environment variables.
- Connection errors: confirm
LND_GRPC_HOST:PORTis reachable and gRPC is enabled.