Merge pull request 'fix(wallet): refetch balance and history on resume' (#164) from fix/wallet-resume-refetch into dev
Reviewed-on: #164
This commit is contained in:
commit
586698259a
1 changed files with 72 additions and 34 deletions
|
|
@ -437,6 +437,39 @@ export class WalletWebSocketService extends BaseService {
|
|||
// Resume polling if we were using fallback
|
||||
this.schedulePolling()
|
||||
}
|
||||
|
||||
// Reconnecting is not enough on its own — see below.
|
||||
await this.reconcileMissedActivity()
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-sync balance and history after the app was backgrounded.
|
||||
*
|
||||
* `onPause` closes the socket to save battery, and the LNbits websocket
|
||||
* only pushes on live events — it replays nothing on reconnect. So any
|
||||
* payment that settled while we were away produced a notification that
|
||||
* reached no one: the balance and the transaction list both stayed at
|
||||
* their pre-pause values until the user hit Refresh by hand.
|
||||
*
|
||||
* Reconnecting therefore has to be paired with an explicit refetch. Both
|
||||
* halves are needed: the balance comes from PaymentService, the rows come
|
||||
* from WalletService, and neither implies the other.
|
||||
*
|
||||
* `allSettled` so a failure in one does not leave the other un-refreshed.
|
||||
*/
|
||||
private async reconcileMissedActivity(): Promise<void> {
|
||||
console.log('WalletWebSocketService: Reconciling activity missed while paused')
|
||||
|
||||
const results = await Promise.allSettled([
|
||||
this.fetchAndUpdateBalance(),
|
||||
this.walletService?.refresh?.()
|
||||
])
|
||||
|
||||
results
|
||||
.filter((r): r is PromiseRejectedResult => r.status === 'rejected')
|
||||
.forEach(r =>
|
||||
console.error('WalletWebSocketService: Resume reconciliation failed', r.reason)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -556,46 +589,51 @@ export class WalletWebSocketService extends BaseService {
|
|||
*/
|
||||
private async performPollingUpdate(): Promise<void> {
|
||||
try {
|
||||
const wallet = this.paymentService?.getPreferredWallet?.()
|
||||
if (!wallet?.inkey) {
|
||||
console.log('WalletWebSocketService: No wallet available for polling')
|
||||
this.schedulePolling() // Continue polling
|
||||
return
|
||||
}
|
||||
|
||||
// Fetch balance from LNbits API
|
||||
const baseUrl = import.meta.env.VITE_LNBITS_BASE_URL || 'http://localhost:5000'
|
||||
const response = await fetch(`${baseUrl}/api/v1/wallet`, {
|
||||
headers: {
|
||||
'X-Api-Key': wallet.inkey
|
||||
}
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
console.error('WalletWebSocketService: Polling failed', response.status, response.statusText)
|
||||
this.schedulePolling() // Continue polling despite error
|
||||
return
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
if (data.balance !== undefined) {
|
||||
// LNbits API returns balance in millisats
|
||||
const balanceMsat = parseInt(data.balance)
|
||||
console.log('WalletWebSocketService: Polling update - balance:', balanceMsat, 'msat')
|
||||
|
||||
// Update balance via PaymentService
|
||||
if (this.paymentService?.updateWalletBalance) {
|
||||
this.paymentService.updateWalletBalance(balanceMsat, wallet.id)
|
||||
}
|
||||
}
|
||||
|
||||
// Schedule next polling
|
||||
this.schedulePolling()
|
||||
|
||||
await this.fetchAndUpdateBalance()
|
||||
} catch (error) {
|
||||
console.error('WalletWebSocketService: Polling error', error)
|
||||
this.schedulePolling() // Continue polling despite error
|
||||
} finally {
|
||||
// Keep polling regardless of the outcome of this round.
|
||||
this.schedulePolling()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the authoritative wallet balance from LNbits and push it into
|
||||
* PaymentService. Shared by the polling fallback and by resume
|
||||
* reconciliation.
|
||||
*/
|
||||
private async fetchAndUpdateBalance(): Promise<void> {
|
||||
const wallet = this.paymentService?.getPreferredWallet?.()
|
||||
if (!wallet?.inkey) {
|
||||
console.log('WalletWebSocketService: No wallet available for balance fetch')
|
||||
return
|
||||
}
|
||||
|
||||
const baseUrl = import.meta.env.VITE_LNBITS_BASE_URL || 'http://localhost:5000'
|
||||
const response = await fetch(`${baseUrl}/api/v1/wallet`, {
|
||||
headers: {
|
||||
'X-Api-Key': wallet.inkey
|
||||
}
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
console.error(
|
||||
'WalletWebSocketService: Balance fetch failed',
|
||||
response.status,
|
||||
response.statusText
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
if (data.balance !== undefined) {
|
||||
// LNbits API returns balance in millisats
|
||||
const balanceMsat = parseInt(data.balance)
|
||||
console.log('WalletWebSocketService: Balance fetch -', balanceMsat, 'msat')
|
||||
if (this.paymentService?.updateWalletBalance) {
|
||||
this.paymentService.updateWalletBalance(balanceMsat, wallet.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue