What happened?
While QA-testing transfer to spending for PR #1039, the session used a Trezor funding source, but the observed balance path is not hardware-specific. After:
- funding Spending with a first LSP channel,
- coop close to Savings for the full channel amount,
- a second transfer to Spending that opens a new channel,
the Spending balance on Home briefly showed the closed-channel amount plus the new channel (e.g. ₿ 1,593,281 = ~1,531,123 + ~62,158), and the total header was inflated accordingly (~₿ 3,311,656). After a few regtest blocks mined, balances returned to normal (Spending ~62,158, Savings ~1,531,123).
Reproduced once in session; subsequent attempts did not reproduce (timing-sensitive).
The bug is not believed to be hardware-wallet-specific. The same DeriveBalanceStateUseCase path is used for any coop close plus new channel while LDK still lists the coop-close funds in Lightning.
Expected behavior
After coop-close funds appear in Savings (on-chain), they should not also count toward Spending (totalLightningSats) until LDK clears the coop-close claimable entry. Opening a second Spending channel should only add the new channel balance to Spending.
Steps to Reproduce
- Regtest wallet with LSP channel(s).
- Fund Spending with a large first channel from Savings or any available funding source.
- Transfer to Savings by coop-closing the full Spending channel. Confirm the Savings balance updates on Home.
- Immediately start another transfer to Spending to open a second channel. Do not wait several minutes or many blocks.
- Complete funding until the second channel is ready (
ChannelReady).
- Open Home and compare Spending plus the total header.
Tip: The window is narrow (~few blocks on regtest while ClaimableAwaitingConfirmations remains in LDK after the close transaction is detected on-chain). Slowing block production after coop close may widen the window.
Logs / Screenshots / Recordings
Logs:
bitkit_logs_2026-06-24_08-27-21.zip
Screenshots
| State |
Screenshot |
Notes |
| Inflated spending / total |
 |
Spending ~₿ 1,593,281; total header ~₿ 3,311,656 (closed-channel amount + new second channel). |
| Corrected |
 |
Spending ~₿ 62,158; total ~₿ 1,780,533 after the coop-close claimable cleared (~few blocks). |
Log signature when bug is visible:
DeriveBalanceStateUseCase: totalOnchainSats ≈ coop-close amount; totalLightningSats ≈ coop-close + new channel; balanceInTransferToSavings = 0; Active transfers: []
- LDK
lightningBalances: ClaimableAwaitingConfirmations (source: COOP_CLOSE) + new channel ClaimableOnChannelClose
- Example inflated
totalLightningSats: 1,593,281 at block height ~136343; corrected to 62,158 after height ~136348
Bitkit Version
2.3.0 (182)
Device / OS
Samsung Galaxy S22, Android 16
Reproducibility
Rarely (once or twice)
Additional context
What happened?
While QA-testing transfer to spending for PR #1039, the session used a Trezor funding source, but the observed balance path is not hardware-specific. After:
the Spending balance on Home briefly showed the closed-channel amount plus the new channel (e.g. ₿ 1,593,281 = ~1,531,123 + ~62,158), and the total header was inflated accordingly (~₿ 3,311,656). After a few regtest blocks mined, balances returned to normal (Spending ~62,158, Savings ~1,531,123).
Reproduced once in session; subsequent attempts did not reproduce (timing-sensitive).
The bug is not believed to be hardware-wallet-specific. The same
DeriveBalanceStateUseCasepath is used for any coop close plus new channel while LDK still lists the coop-close funds in Lightning.Expected behavior
After coop-close funds appear in Savings (on-chain), they should not also count toward Spending (
totalLightningSats) until LDK clears the coop-close claimable entry. Opening a second Spending channel should only add the new channel balance to Spending.Steps to Reproduce
ChannelReady).Tip: The window is narrow (~few blocks on regtest while
ClaimableAwaitingConfirmationsremains in LDK after the close transaction is detected on-chain). Slowing block production after coop close may widen the window.Logs / Screenshots / Recordings
Logs:
bitkit_logs_2026-06-24_08-27-21.zip
Screenshots
Log signature when bug is visible:
DeriveBalanceStateUseCase:totalOnchainSats≈ coop-close amount;totalLightningSats≈ coop-close + new channel;balanceInTransferToSavings= 0;Active transfers: []lightningBalances:ClaimableAwaitingConfirmations(source: COOP_CLOSE) + new channelClaimableOnChannelClosetotalLightningSats: 1,593,281 at block height ~136343; corrected to 62,158 after height ~136348Bitkit Version
2.3.0 (182)
Device / OS
Samsung Galaxy S22, Android 16
Reproducibility
Rarely (once or twice)
Additional context
TransferReposettles theCOOP_CLOSEtransfer when the close is detected on-chain. In the captured window, the active transfer is gone, but LDK still includes aClaimableAwaitingConfirmations(source: COOP_CLOSE)entry intotalLightningBalanceSats. When a second channel becomes ready during that window, Android displays the closed-channel claimable plus the new channel as Spending.COOP_CLOSEclaimables from displayed Lightning when the channel is no longer in the local channel list and no active to-savings transfer owns it. Keep active cooperative-close handling and force-close handling separate.