Skip to content

Add offline-capable balance display using cached data #810

Description

@Mystery-CLI

Background

Mobile users of the FuTuRe platform frequently check their account balance while in environments with intermittent or absent internet connectivity — on public transport, in buildings with poor signal, or while travelling internationally. Currently, when the application cannot reach the Stellar Horizon API, the balance display shows an error or empty state with no indication of the last known value. This creates unnecessary anxiety for users who simply want to confirm their balance before initiating a transaction.

Problem

The current behaviour of the balance display component when offline provides a poor user experience in several ways:

  • No fallback information. When offline, users see either an error message or a blank balance field. The previous balance, which was accurate moments ago, is discarded rather than shown.
  • No cache indicator. Even if cached data were shown, users need to know that it may be stale — but today there is no mechanism for showing a cached-data indicator at all.
  • Unnecessary alarm. An empty balance field in a financial application causes immediate concern. Users cannot distinguish between "I am offline" and "there is a problem with my account."
  • Inconsistent with native app expectations. Native banking apps universally show the last-known balance when offline, with a timestamp or indicator. Users expect this behaviour and are frustrated by its absence.
  • Wasted re-fetches. Without a cached value, the application may attempt multiple network requests in quick succession while offline, degrading battery life and cluttering error logs.

Proposed Solution

Integrate an IndexedDB cache layer for the account balance response, populated whenever a successful Horizon API response is received. When the application detects that it is offline (via the navigator.onLine API and a failed fetch), display the most recently cached balance alongside a clearly styled "Cached — last updated [timestamp]" indicator rather than an error or blank state.

The implementation should:

  1. Store the balance response in an IndexedDB object store keyed by account public key whenever a successful fetch completes.
  2. On balance component mount, attempt a live fetch. If the fetch fails due to network unavailability, fall back to the IndexedDB cached value.
  3. Render the cached balance with a visual indicator — e.g. a small clock or info icon — communicating that the displayed value is from the cache, not a live read.
  4. Include the human-readable timestamp of the last successful fetch in the indicator tooltip or subtitle.
  5. Suppress error states that would normally appear for network failures when a valid cache entry exists.
  6. Clear the cache entry when the user logs out to prevent showing another user's balance.

Implementation Steps

  1. Create a frontend/src/cache/balanceCache.js module wrapping IndexedDB reads and writes.
  2. Update the balance-fetching logic to write to the cache on every successful Horizon response.
  3. Update the error-handling path to check for a cache entry before rendering an error state.
  4. Add the "Cached" indicator UI to the balance display component.
  5. Write unit tests for the cache module and update the balance component tests to cover the offline fallback path.
  6. Test the offline scenario manually in Chrome DevTools using the "Offline" network throttle preset.

Acceptance Criteria

  • When the network is unavailable, the last known balance is displayed rather than an error or empty state.
  • The cached balance is accompanied by a clearly visible "Cached" indicator and timestamp.
  • The cache is updated on every successful live balance fetch.
  • The cache is cleared on logout.
  • No cached balance from a previous user session is shown to a different user.
  • Existing online balance display behaviour is unchanged.

Notes

The cache TTL should not auto-expire the displayed value — a balance cached hours ago is still better than a blank. The indicator's staleness message will communicate age to the user. If the application comes back online mid-session, the balance should update automatically and the cached indicator should disappear.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions