Skip to content

perf: cut offline wallet startup from 60s+ to ~3s#4064

Draft
kaloudis wants to merge 7 commits into
masterfrom
perf-offline
Draft

perf: cut offline wallet startup from 60s+ to ~3s#4064
kaloudis wants to merge 7 commits into
masterfrom
perf-offline

Conversation

@kaloudis
Copy link
Copy Markdown
Contributor

@kaloudis kaloudis commented May 6, 2026

Description

When the device is offline, Zeus's LDK Node and Cashu init paths used to block on a series of internal HTTP timeouts — VSS dual-store build (30–60s), node.syncWallets() Esplora + RGS fetch (~30s+), and on a fresh recovery, the sequential Nostr relay loop (8 × 10s = up to 80s). End-to-end an offline cold-start could take 60s+ for an existing wallet and several minutes for a fresh recovery.

This PR seeds connectivityStore.isOffline before any wallet implementation init runs, then short-circuits the network-bound work that would otherwise stall on those internal timeouts. Online cold-start is unchanged apart from a one-time probe capped at ~1.5s.

Impact

Path Before After
Initial reachability probe ~5s probe budget ~1.5s
LDK VSS dual-store build (offline) ~30s existing / ~60s restore skipped
LDK syncWallets() (offline) ~30s+ Esplora + RGS fetch skipped
Cashu Nostr mint restore (fresh recovery, offline) up to ~80s sequential skipped
LDK VSS build timeout when online-but-VSS-slow 30s 10s
Offline cold-start, existing wallet ~60s+ ~3s
Offline cold-start, fresh recovery several minutes ~3s

Online cold-start regresses by at most the new ~1.5s checkNow() probe; when online, the same VSS build and sync paths run as before. As a secondary benefit, online Nostr mint restore now fans out across all relays in parallel instead of trying them one-at-a-time.

Behaviour notes / risks

  • VSS deferral while offline. A session built offline uses local-only SQLite. VSS resumes on the next launch once we're online; we do not currently rebuild the node mid-session on reconnect.
  • No alerts when offline. When VSS / sync / RGS are skipped because we're offline, vssError / esploraError / rgsError stay undefined, so Wallet.tsx doesn't surface alerts the user already understands. Online failures alert as before.
  • Tighter VSS budget. Existing-wallet VSS timeout drops from 30s → 10s. Users on slow connections may occasionally see a vssError alert where the previous 30s budget would have eventually succeeded. The graceful fallback (local-only build, retry on next launch) is unchanged.
  • Connectivity ownership. ConnectivityStore lifecycle (start/stop) is now owned by Wallet.fetchData() rather than CashuStore.initializeWallets(). Cashu still registers its reconnect callback via startConnectivityMonitoring.

Test plan

  • Offline cold-start, existing wallet — disable Wi-Fi/cellular, launch app; confirm UI is interactive within ~3s and no VSS / Esplora / RGS alerts surface.
  • Online cold-start, existing wallet — confirm startup time has not regressed beyond the ~1.5s probe.
  • Online → offline mid-session — confirm the running session keeps working off local state; on next cold-start, offline path is taken.
  • Offline → online reconnect — confirm connectivityStore.onReconnect fires and Cashu pending tokens sweep.
  • Fresh recovery, online — verify Nostr mint restore still finds the backup with parallel fan-out.
  • Fresh recovery, offline — verify we no longer hang on the relay loop and the wallet still loads (no mints, as expected).
  • VSS reachable but slow — confirm the new 10s budget falls back to local with a clear vssError alert.

PR Type

This pull request is categorized as a:

  • New feature
  • Bug fix
  • Code refactor
  • Configuration change
  • Locales update
  • Quality assurance
  • Other

Checklist

  • I’ve run yarn run tsc and made sure my code compiles correctly
  • I’ve run yarn run lint and made sure my code didn’t contain any problematic patterns
  • I’ve run yarn run prettier and made sure my code is formatted correctly
  • I’ve run yarn run test and made sure all of the tests pass

Testing

If you modified or added a utility file, did you add new unit tests?

  • No, I’m a fool
  • Yes
  • N/A

I have tested this PR on the following platforms (please specify OS version and phone model/VM):

  • Android
  • iOS

I have tested this PR with the following types of nodes (please specify node version and API version where appropriate):

On-device

  • LDK Node
  • Embedded LND

Remote

  • LND (REST)
  • LND (Lightning Node Connect)
  • Core Lightning (CLNRest)
  • Nostr Wallet Connect
  • LndHub

Locales

  • I’ve added new locale text that requires translations
  • I’m aware that new translations should be made on the ZEUS Transfix page and not directly to this repo

Third Party Dependencies and Packages

  • Contributors will need to run yarn after this PR is merged in
  • 3rd party dependencies have been modified:
    • verify that package.json and yarn.lock have been properly updated
    • verify that dependencies are installed for both iOS and Android platforms

Other:

  • Changes were made that require an update to the README
  • Changes were made that require an update to onboarding

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request optimizes the application's startup performance and offline behavior by introducing a fast connectivity probe and skipping network-dependent tasks like VSS synchronization, wallet syncing, and Nostr mint restoration when offline. Additionally, Nostr mint restoration was refactored to fetch from relays in parallel with a tighter timeout. Feedback suggests adding a guard to prevent redundant callback registrations in CashuStore and implementing error handling when executing reconnect callbacks in ConnectivityStore to ensure robustness.

Comment thread stores/CashuStore.ts
Comment thread stores/ConnectivityStore.ts Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant