The Missing Ledger
why your Lightning node needs a general ledger (and why I built one)
It’s April. You’re filing your taxes. You exported a CSV from Strike, another from River, a third from your Coinbase account you barely touch. Your LND node has been quietly routing payments all year; forwarding HTLCs, earning a few sats per hop, rebalancing channels when liquidity drifted. Somewhere in all of that is the answer to a simple question: how much Bitcoin did I actually acquire this year, and what did it cost me?
You don’t know. Not without a spreadsheet and a Saturday afternoon you don’t have.
I’ve been running a Lightning node on Umbrel for five years. I DCA through Strike and River. I hold a small position on Coinbase from before I went self-custody. My node routes payments and earns fees. Each of those pieces has its own interface, its own export format, its own version of the truth. None of them talk to each other. None of them give me the one number I actually want: my total Bitcoin position across everything, and what it cost me to build it.
So I built Satsbook; a general ledger for your Lightning node. It stitches together your node’s routing income, your exchange purchases, and your cost basis into one view, running entirely on your own hardware. I’m going to explain why this gap exists, why nobody has filled it, and what Satsbook does about it.
The three problems nobody’s solving
You can’t see your node’s ROI
ThunderHub shows forwarding events. RTL shows channel balances. Neither shows earnings over time. There’s no YTD view. No way to ask “how much did this channel earn relative to the capital I locked in it?” No comparison between what I spent on rebalancing and what I earned in routing fees. The data is there, it’s in the LND database, but nothing surfaces it in a way that answers the question a normal person would ask: is this node making money?
I found myself SSH’d into my Umbrel at 11pm, running SQL queries against the LND database to answer questions that should have been one click on a dashboard. That’s when I knew something was missing.
Your tax records are siloed across five tools
Strike has a CSV. River has a CSV. Coinbase has a statement. My LND node has on-chain transactions from channel opens and closes. I’ve got BTC that moved from an exchange into a Lightning channel that later got closed back on-chain, and none of these tools have any idea about the others.
The IRS treats every disposal of Bitcoin as a taxable event. That arguably includes every Lightning payment you make. If you can’t reconstruct the full history — what you bought, when you bought it, what you received as routing income, what you spent — you can’t file cleanly. You’re either overpaying, underpaying, or guessing. None of those options are good.
The cost basis problem is genuinely hard when your Bitcoin lives across five different systems and two different layers. It’s not that people are lazy about taxes. It’s that the infrastructure to do it correctly doesn’t exist for Lightning operators.
The tools that do exist aren’t built for you
I looked. Here’s what I found:
Amboss is excellent if you’re a professional routing operator running Lightning as a business. If you’re a home-lab operator running Umbrel on a Pi, it’s overkill in some ways and doesn’t cover the accounting side at all.
Koinly and CoinLedger handle crypto taxes, but they pretend Lightning doesn’t exist. No channel opens, no routing fees, no understanding of the HTLC lifecycle. They’re built for people trading on centralized exchanges, not people running infrastructure.
Cryptio and TRES are enterprise tools with enterprise pricing. They’re for companies with compliance departments, not for someone running a node in their closet.
ThunderHub and RTL are node management UIs. They’re indispensable for what they do — managing channels, monitoring liquidity, watching the mempool. But they’re not accounting tools. They don’t track cost basis. They don’t know about your exchange purchases. They show you what’s happening right now, not what happened over the last twelve months.
There’s a specific person who falls through all of these cracks. The sovereign operator running Umbrel at home. Real Bitcoin in channels. Real opinions about custody. A real need for clean financial records. And absolutely nothing that gives them a unified view of what their stack is doing.
That’s the whitespace. That’s who I built Satsbook for.
Why nobody built this
The gap is structural, not accidental. Four reasons:
The market is small and technical. There are maybe 20,000 people running Umbrel who care about routing fees and cost basis. You can’t raise a Series A for that. No VC is going to fund “a general ledger for home Lightning node operators.” The total addressable market makes investors’ eyes glaze over. So nobody with funding attempts it.
The integrations are unglamorous. LND’s gRPC API. Strike’s CSV format and its idiosyncrasies. River’s export layout. Coinbase’s transaction statements. Each one has its own edge cases, its own date formats, its own way of categorizing transactions. Stitching them together into a single coherent ledger is the kind of boring, detail-heavy work that nobody wants to do as a startup.
The tax treatment is uncertain. How do you account for a Lightning channel open? A splice? A circular rebalance? The IRS hasn’t issued clear guidance on any of it. Big players stay away from uncertainty because they can’t afford to build something that might be wrong. A side project doesn’t have that constraint — I can build what I think is right and update it when guidance comes.
The audience hates cloud tools. This is the catch-22. The people most likely to need this product are the most likely to refuse to upload their node data to a SaaS platform. Self-sovereign means self-sovereign. Which means the whole thing has to run locally, on their hardware, with no outbound connections they didn’t ask for. That’s harder to build and harder to monetize, which is why nobody attempts it.
These are exactly the reasons I was in a good position to build it. I’m in the audience. I already had LND integration experience from a prior side project. And I’m happy with a side-hustle-sized market that a VC would never touch.
What Satsbook actually looks like
I’ll show you instead of telling you.
This is the screen that made me realize the project was worth finishing. One number: your total net BTC position across every source. Node earnings, Strike purchases, River DCA, Coinbase holdings; all rolled up into a single figure with the USD equivalent at current price. Below it, the breakdown showing where each piece came from.
Before Satsbook, if someone asked me “how much Bitcoin do you actually have?” I’d have to open four tabs and do arithmetic in my head. Now it’s one number on one page, and I trust it because I can see where each component came from.
This is the strip I check every morning. Three numbers: what my node earned in routing fees this year, what I purchased through exchanges this year, and my net position change. One line that tells me whether my stack is growing and where the growth is coming from.
This is for the routing nerds. Daily fee income charted over time, with a per-channel breakdown underneath. You can finally see which channels are earning their keep and which ones are just sitting there consuming capital.
This is the unlock. Three tabs — Strike, River, Coinbase. Drop a CSV, hit upload. Satsbook parses it, deduplicates by content hash so you can re-upload safely, and folds those transactions into your unified ledger. Each vendor has a danger zone at the bottom if you need to clear and re-import. The whole cycle takes about thirty seconds.
How it’s built
For the readers who want to know what they’re running before they install it — and I respect that instinct completely.
Satsbook is a single Go binary. No CGO, no Python, no Node.js. It cross-compiles cleanly to linux/arm64, which means it runs natively on your Raspberry Pi without emulation. The binary is about 25 MB.
The database is SQLite, embedded via a pure-Go driver (modernc.org/sqlite). No separate database process. No Postgres. No Redis. Your data lives in a single file on your node.
The frontend is HTMX — server-rendered HTML with no JavaScript framework. Every request is visible in your browser’s network tab. There’s no client-side state, no build step, no npm. If you open the source, you can read every template.
All assets are embedded in the binary via Go’s embed.FS. There are no runtime file dependencies. The binary is the whole app.
Satsbook connects to your LND node using a read-only macaroon. It literally cannot sign transactions, send payments, or modify anything on your node. It reads forwarding history and channel balances. That’s it.
The only outbound connection is a single price lookup to CoinGecko for the current BTC/USD rate, used to display dollar equivalents on the dashboard. You can disable it.
Syncing is incremental. Satsbook maintains a cursor so it never re-fetches data it’s already stored. First sync pulls your full history; every sync after that picks up only new events.
If you want to audit it, it’s about 14,000 lines of Go. You can read the whole thing in an afternoon.
Free is real. Paid is coming.
I want to be transparent about the business model, because I think the Bitcoin community deserves that.
The free tier is the dashboard and exchange imports. Net BTC position, routing fee income, YTD summary, Strike/River/Coinbase CSV import, per-channel breakdown. Full stop. It’s not a trial. It’s not time-limited. It’s not a demo with the good features grayed out. It’s genuinely useful on its own, and it will stay free.
Pro ($9/mo) is the tier you’d pay for at tax time. Full history export, FIFO and LIFO cost basis calculations, Form 8949 output. If you’ve ever spent a Saturday afternoon in a spreadsheet trying to reconstruct your cost basis, this is the thing that makes that Saturday go away.
Power ($19/mo) is for the operators who want more. Monarch and YNAB sync, Telegram alerts, multi-node support. These features are under development.
Here’s the quiet part out loud: the free tier is the acquisition funnel. The paid tier is the sustainability model. I’m building this as a side business, not a VC-scale land grab, and the pricing reflects that. If the free tier is all you ever need, great — use it, tell your friends about it, file an issue when something breaks. That’s a win for me too.
Try it
Three things I’m asking:
Install it. If you’re on Umbrel, add the community app store and install Satsbook in about thirty seconds:
Umbrel → App Store → Community App Stores → Add Store
https://github.com/satsbook/umbrel-app-storeImport one CSV. Look at your dashboard. Tell me what surprised you.
Tell me what’s broken. I built this for my node. Your node is different. Your channels, your exchange history, your edge cases — I want to hear about them. The fastest way to help is a post in GitHub Discussions that says “this doesn’t match what I see in ThunderHub.” Those posts are gold.
Share it with someone who needs it. If you have a friend running a node who complains about tax season, or who’s been meaning to figure out what their routing fees actually add up to, point them at this post.
It’s MIT licensed. It runs on your hardware. It never phones home. I built it for myself, and I hope you find it as useful as I have.
Satsbook is open source at github.com/satsbook/satsbook. Built by BrewGator. Not financial or tax advice.





