Skip to content

Wallet birthday height for seed recovery on pruned nodes #818

@FreeOnlineUser

Description

@FreeOnlineUser

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:

  1. User restores seed words
  2. App uses bitcoind scantxoutset to find UTXOs and their block heights (works on pruned nodes)
  3. Sets birthday to min(heights) - 10 as safety margin
  4. 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:

  • bdk#2126: Adding start_height to FilterIter::new
  • bdk#2050: Pruned node support via scantxoutset

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions