-
Notifications
You must be signed in to change notification settings - Fork 129
Description
When restoring an ldk-node wallet from seed, the node starts syncing from the current chain tip. Any on-chain deposits made before the restore are never seen by synchronize_listeners, so the wallet balance shows zero even though funds exist on-chain.
This affects all seed restores, but pruned nodes are hit hardest: historical blocks are gone, so there is no workaround via rescan.
There is an existing TODO acknowledging this:
// TODO: Use a proper wallet birthday once BDK supports it.(src/builder.rs:1327)
Impact
- On-chain balance shows 0 after seed restore
- Cannot open Lightning channels (no visible funds)
- Funds are safe on-chain but inaccessible through ldk-node
- Mobile wallets (where reinstalls and data loss are common) are the primary use case
What we did
We hit this building Bitcoin Pocket Node, an Android app running bitcoind + ldk-node on GrapheneOS with pruned storage.
Our workaround overrides chain_tip_opt in the Builder when a birthday height is provided. Caller flow:
- User restores seed words
- App uses bitcoind
scantxoutsetto find UTXOs and their block heights (works on pruned nodes) - Sets birthday to
min(heights) - 10as safety margin - ldk-node syncs from there, balance appears with zero transaction fees
Working fork with the changes (~100 lines): FreeOnlineUser/ldk-node@upstream/wallet-birthday
Verified end-to-end on real hardware: seed restore, UTXO scan, birthday set, 110,628 sats recovered in seconds.
Upstream context
BDK is working on related pieces:
Once BDK ships native birthday support, ldk-node can use that directly (which is what the TODO anticipates). Our fork is a pragmatic solution in the meantime.
We are also the folks working on the watchtower improvements discussed in #813.