fix(wallet): refetch balance and history on resume #164

Merged
padreug merged 1 commit from fix/wallet-resume-refetch into dev 2026-09-22 21:06:19 +00:00
Owner

A payment that settled while the app was backgrounded stayed invisible until the user pressed Refresh by hand.

onPause closes the socket to save battery, and the LNbits websocket only pushes on live events. It replays nothing on reconnect. onResume reconnected the socket and stopped there, so the notification for anything that settled in between reached no one, and both the balance and the transaction list sat at their pre-pause values.

Fix

onResume now pairs reconnection with an explicit refetch of both: the balance via PaymentService and the rows via WalletService. Neither implies the other, so both are needed. allSettled keeps a failure in one from leaving the other un-refreshed.

The balance fetch is extracted out of the polling fallback rather than duplicated, so the two paths cannot drift apart.

Verification

Ran a real internal payment against the live LNbits on this machine:

socket closed (backgrounded)
paid a 33-sat invoice, waited 5s so the notification task fired
reconnected -> nothing arrived in 8s; the 33 sats were invisible
REST refetch -> 283633 sat, a 33 sat delta the UI had missed

Worth recording: a first attempt reconnected immediately and did receive a message, which looked like a replay. It was a test artifact. LNbits dispatches the notification from an async task, and reconnecting within milliseconds meant the task found the new socket. The delay above is what a backgrounded app actually looks like, and with it the message is genuinely lost.

vue-tsc --noEmit is clean.

A payment that settled while the app was backgrounded stayed invisible until the user pressed Refresh by hand. `onPause` closes the socket to save battery, and the LNbits websocket only pushes on live events. It replays nothing on reconnect. `onResume` reconnected the socket and stopped there, so the notification for anything that settled in between reached no one, and both the balance and the transaction list sat at their pre-pause values. ## Fix `onResume` now pairs reconnection with an explicit refetch of both: the balance via PaymentService and the rows via WalletService. Neither implies the other, so both are needed. `allSettled` keeps a failure in one from leaving the other un-refreshed. The balance fetch is extracted out of the polling fallback rather than duplicated, so the two paths cannot drift apart. ## Verification Ran a real internal payment against the live LNbits on this machine: ``` socket closed (backgrounded) paid a 33-sat invoice, waited 5s so the notification task fired reconnected -> nothing arrived in 8s; the 33 sats were invisible REST refetch -> 283633 sat, a 33 sat delta the UI had missed ``` Worth recording: a first attempt reconnected immediately and *did* receive a message, which looked like a replay. It was a test artifact. LNbits dispatches the notification from an async task, and reconnecting within milliseconds meant the task found the new socket. The delay above is what a backgrounded app actually looks like, and with it the message is genuinely lost. `vue-tsc --noEmit` is clean.
A payment that settled while the app was backgrounded stayed invisible
until the user pressed Refresh by hand.

`onPause` closes the socket to save battery, and the LNbits websocket
only pushes on live events — it replays nothing on reconnect. `onResume`
reconnected the socket and stopped there, so the notification for
anything that settled in between reached no one. Balance and the
transaction list both sat at their pre-pause values.

`onResume` now pairs reconnection with an explicit refetch of both: the
balance via PaymentService and the rows via WalletService. Neither
implies the other, so both are needed. `allSettled` keeps a failure in
one from leaving the other un-refreshed.

The balance fetch is extracted from the polling fallback rather than
duplicated, so the two paths cannot drift.

Verified against the live LNbits with a real internal payment:

  socket closed (backgrounded)
  paid a 33-sat invoice, waited 5s so the notification task fired
  reconnected -> nothing arrived in 8s; the 33 sats were invisible
  REST refetch -> 283633 sat, a 33 sat delta the UI had missed

A first attempt reconnected immediately and did see a message. That was
a test artifact, not a replay: LNbits dispatches the notification from
an async task, which found the new socket. Hence the deliberate delay
above, which is what a backgrounded app actually looks like.
padreug deleted branch fix/wallet-resume-refetch 2026-09-22 21:06:19 +00:00
Sign in to join this conversation.
No description provided.