build method

  1. @override
AsyncValue<SyncStatus> build()

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();
}