resolveWalletDbDir function

Future<String> resolveWalletDbDir()

The wallet onboarding COMPOSITION ROOT (spec §3.2g iii-B-2-b): the one place that wires the production adapters into the onboarding seams. Building the provisioner, the store, and the screen-security adapter TOGETHER (with the co-wiring assertion below) is what makes them impossible to wire apart — a refactor cannot ship the seed-revealing provisioner without the screenshot protection on a platform that supports it (crypto audit H2). Resolve the wallet data directory to a PLAIN, already-created path — call this in main(), fold it into the host's WalletConfig (the reference buildWalletConfig does this), and pass that config to walletOnboardingOverrides BEFORE building the ProviderScope. This is a REFERENCE helper (it picks a per-network leaf under the app support dir and wires iOS backup-exclusion); a host with its own data-dir convention resolves its own path and puts it on its WalletConfig.dbDir. It must NOT be recomputed inside a provider build(): an async re-resolve on every rebuild would spawn a fresh provisioner mid-flight and risk a double-create (the footgun the port and controller both warn about).

Uses the app SUPPORT directory (not Documents — on iOS Documents is user-visible in the Files app). Backup-exclusion is wired on BOTH platforms: Android off app-wide (allowBackup=false), iOS via BackupExclusion on this dir (set below). Excluding the DB matters because its key is a ThisDeviceOnly Secure-Enclave key that never migrates — a backed-up DB restored onto a new device can't be opened (the needsRecovery trap), so excluding it routes a device-restore to the clean Welcome → Restore flow instead.

Implementation

/// Resolve the wallet data directory to a PLAIN, already-created path — call
/// this in `main()`, fold it into the host's [WalletConfig] (the reference
/// [buildWalletConfig] does this), and pass that config to
/// [walletOnboardingOverrides] BEFORE building the `ProviderScope`. This is a
/// REFERENCE helper (it picks a per-network leaf under the app support dir and
/// wires iOS backup-exclusion); a host with its own data-dir convention
/// resolves its own path and puts it on its `WalletConfig.dbDir`. It must NOT
/// be recomputed inside a provider
/// `build()`: an async re-resolve on every rebuild would spawn a fresh
/// provisioner mid-flight and risk a double-create (the footgun the port and
/// controller both warn about).
///
/// Uses the app SUPPORT directory (not Documents — on iOS Documents is
/// user-visible in the Files app). Backup-exclusion is wired on BOTH platforms:
/// Android off app-wide (`allowBackup=false`), iOS via [BackupExclusion] on this
/// dir (set below). Excluding the DB matters because its key is a `ThisDeviceOnly`
/// Secure-Enclave key that never migrates — a backed-up DB restored onto a new
/// device can't be opened (the needsRecovery trap), so excluding it routes a
/// device-restore to the clean Welcome → Restore flow instead.
Future<String> resolveWalletDbDir() async {
  final support = await getApplicationSupportDirectory();
  // Per-network leaf (`zec_wallet` mainnet / `zec_wallet_testnet` testnet): a
  // v-5c testnet-proof build lives BESIDE a mainnet wallet, never over it — the
  // SDK would refuse the mismatched DB anyway (NetworkMismatch), but the leaf
  // makes the define switch non-destructive in both directions.
  final dir = Directory('${support.path}/${referenceDbDirLeaf()}');
  // The lock-free existence PROBE does not create the dir (a missing dir just
  // reads "no wallet"); create/open DO create it at lock acquisition. Still
  // pre-create it here so the backup-exclusion flag below lands on a real
  // directory before any wallet files exist inside it.
  await dir.create(recursive: true);
  // iOS: exclude the wallet DB from device/iCloud backup (best-effort; never blocks
  // boot). Set AFTER the dir exists; the flag applies to the whole subtree, so all
  // DB files created inside it later are excluded too. (Android: allowBackup=false.)
  await const BackupExclusion().exclude(dir.path);
  return dir.path;
}