build method
Initialize a Notifier.
It is safe to use Ref.watch or Ref.listen inside this method.
If a dependency of this Notifier (when using Ref.watch) changes,
then build will be re-executed. On the other hand, the Notifier
will not be recreated. Its instance will be preserved between
executions of build.
If this method throws, reading this provider will rethrow the error.
Implementation
@override
AsyncValue<SyncStatus> build() {
// PER-BUILD RESET (M1): Riverpod REUSES the notifier instance across a
// `walletSessionProvider` rebuild (session close/reopen, onboarding flip) and
// fires `ref.onDispose` (→ `_teardown`, which sets `_disposed = true`) BEFORE
// re-running `build()`. Without this reset the instance fields are stale on
// the rebuild — most dangerously `_disposed` stays `true`, so the reconnect
// machinery early-returns forever and the reopened wallet NEVER syncs; the
// carried-over `_backoff`/`_wasPaused`/`_subDelivered` would likewise corrupt
// the fresh stream. The build is the single "(re)start" entry point, so it
// re-initializes the lifecycle from scratch (matching `SwapStatusNotifier`).
_disposed = false;
_wasPaused = false;
_subDelivered = false;
_backoff = minBackoff;
_sub = null;
_reconnect = null;
final session = ref.watch(walletSessionProvider);
ref.onDispose(_teardown);
// Riverpod disposes the previous `ref.listen` registration before re-running
// `build()`, so re-registering here on every rebuild does NOT accumulate.
ref.listen<AppLifecycleState>(appLifecycleProvider, (_, next) {
_onLifecycle(next);
});
if (session == null) {
// No wallet provisioned — the screen renders the not-set-up state and
// does not watch this provider. A neutral loading is the honest value.
return const AsyncValue<SyncStatus>.loading();
}
// Born-backgrounded cold start (Android push-trampoline): do not open
// the stream while paused — the next real resume subscribes.
if (ref.read(appLifecycleProvider) == AppLifecycleState.paused) {
_wasPaused = true;
} else {
_subscribe(session);
}
return const AsyncValue<SyncStatus>.loading();
}