lnsocket-monitor

Core Lightning · commando · JSON lines

lnsocket-monitor.

Your Lightning node as a stream of events. Payments, forwards, deposits and channel changes, printed the moment the node records them, from anywhere it's reachable on the Lightning port.

cargo install --git https://github.com/jb55/lnsocket-monitor
lnsocket-monitor -n mynode
$ lnsocket-monitor -n mynode | jq -c

Illustrative output, trimmed. Real lines carry more fields.

events

Everything worth a glance, one JSON object per line

Every line has type, node and time, with amounts in msat. Pipe it into jq, a bot, a log, or the notifier below. --replay N prints the last N of each kind at startup, so you can see output before anything happens.

invoicesinvoice_paid

Someone paid you. The description holds the zap request when it's a zap.

sendpayspayment_sent

A payment you made completed: amount, fee, destination alias, parts.

forwardsforward_settled

You routed a payment. In and out peers by alias, and the fee you earned.

chainmovesonchain_deposit

Coins confirmed in your on-chain wallet, with the txid.

chainmoveschannel_opened

A channel's funding locked in: peer, capacity, your side, who opened it.

chainmoveschannel_closed

A channel's funding was spent: peer, capacity, what came back to you.

networkevents, --peerspeer_connected

A channel peer came online. Gossip-only peers are left out.

networkevents, --peerspeer_disconnected

A channel peer went away, with the reason when the node has one.

how it works

Nothing is polled

Core Lightning's wait RPC blocks until a subsystem's index moves. The monitor keeps one waiting per subsystem, then reads exactly what changed from the last index it saw.

  • A connection per wait

    A commando connection answers nothing else while a command runs on it, so each blocking wait gets a socket of its own. The list* calls never queue behind one.

  • Catch up from the last index

    When a wait returns, the monitor lists from the last index it reported, not the one returned. A dropped connection never skips an event.

  • Channels from the chain

    Opens and closes come from chain moves, recorded when the funding locks in and when it's spent, so there's no channel list to diff.

  • Notices a dead link

    Every wait connection pings the node each minute and reconnects when it stops hearing back. Everything it sends is read-only and safe to resend.

contrib/nudge

Notifications from your node, not from a script

contrib/nudge/lnsocket-nudge runs the monitor and posts each event with nudge. It's one Python file with no dependencies.

Mock-ups. Names, amounts and notes are made up.

Zaps with a face

A zap invoice carries the zap request. The zapper's profile and the zapped note are looked up on a local nostr relay (notedeck's, ws://127.0.0.1:6677), so the notification shows who it was, their picture and what they zapped.

Click to open

Clicking a zap runs nd call open nostr:note1… through nudge's actions.json, opening the note in notedeck, or the profile for a profile zap. Chain events open the transaction on mempool.space.

Your node's icon

Everything else wears a bolt icon with the node's alias as the sender, so it never looks like a generic script notification.

Keeps running

The monitor is restarted if it exits. --skip forward_settled drops kinds you don't want, and --dry-run prints instead of posting.

setup

Four steps from rune to notification

The monitor reads the same config as lnrpc, so a node you already call by name works as is.

01 · on the node

Make a read-only rune

Lists, gets and wait, and nothing that spends.

$ lightning-cli createrune restrictions='[["method^list","method^get","method=wait"],["method/listdatastore"]]'
02 · on your machine

Save the node

Kept in ~/.config/lnrpc/config.toml, mode 0600. The first node is the default.

$ lnrpc config add mynode 02a1…c3f9 ln.example.com <rune>
03

Install and watch

Replay a few old events to see the shape of the output.

$ cargo install --git https://github.com/jb55/lnsocket-monitor
$ lnsocket-monitor --replay 3
04 · macOS

Turn on notifications

Install nudge, then run the notifier from a checkout.

$ brew install --cask jb55/nudge/nudge && nudge --authorize
$ git clone https://github.com/jb55/lnsocket-monitor
$ lnsocket-monitor/contrib/nudge/lnsocket-nudge