diff --git a/cw_core/lib/db/sqlite.dart b/cw_core/lib/db/sqlite.dart index 0deffab8e..b6e0dd23e 100644 --- a/cw_core/lib/db/sqlite.dart +++ b/cw_core/lib/db/sqlite.dart @@ -63,7 +63,7 @@ Future _initDb({String? pathOverride}) async { } } await db?.close(); - db = await openDatabase(dbFile.path, version: 10, + db = await openDatabase(dbFile.path, version: 11, onUpgrade: (Database db, int oldVersion, int newVersion) async { printV("migrating: $oldVersion, $newVersion"); if (oldVersion <= 1) { @@ -152,6 +152,14 @@ CREATE TABLE IF NOT EXISTS BalanceCardStyleSettings ( await _createSplTokenTable(db); await _createTronTokenTable(db); } + if (oldVersion <= 10) { + await _addColumnIfNotExists( + db, + table: 'WalletInfo', + column: 'showSeedBackupReminder', + definition: 'BOOLEAN DEFAULT FALSE', + ); + } }, onCreate: (Database db, int version) async { await db.execute(''' CREATE TABLE WalletInfo ( @@ -178,7 +186,8 @@ CREATE TABLE WalletInfo ( sortOrder INTEGER DEFAULT (0) NOT NULL, receiveInfoboxDismissed BOOLEAN DEFAULT FALSE, showCombinedBalance BOOLEAN DEFAULT TRUE, - favoriteTokenAddress TEXT DEFAULT NULL + favoriteTokenAddress TEXT DEFAULT NULL, + showSeedBackupReminder BOOLEAN DEFAULT FALSE ); '''); diff --git a/cw_core/lib/wallet_info.dart b/cw_core/lib/wallet_info.dart index 585ce3b3a..61b62780f 100644 --- a/cw_core/lib/wallet_info.dart +++ b/cw_core/lib/wallet_info.dart @@ -349,7 +349,8 @@ class WalletInfo { this.addressPageType, this.receiveInfoboxDismissed, this.showCombinedBalance, - this.favoriteTokenAddress) + this.favoriteTokenAddress, + this.showSeedBackupReminder) : _yatLastUsedAddressController = StreamController.broadcast(); factory WalletInfo.external( @@ -397,7 +398,8 @@ class WalletInfo { null, receiveInfoboxDismissed ?? false, showCombinedBalance ?? true, - favoriteTokenAddress); + favoriteTokenAddress, + false); } static String get tableName => 'walletInfo'; @@ -418,6 +420,7 @@ class WalletInfo { bool receiveInfoboxDismissed; bool showCombinedBalance; String? favoriteTokenAddress; + bool showSeedBackupReminder; Future> getAddresses() async { final list = await WalletInfoAddressMap.selectList(internalId); @@ -587,6 +590,7 @@ class WalletInfo { "receiveInfoboxDismissed": receiveInfoboxDismissed ? 1 : 0, "showCombinedBalance": showCombinedBalance ? 1 : 0, "favoriteTokenAddress": favoriteTokenAddress, + "showSeedBackupReminder": showSeedBackupReminder ? 1 : 0, "network": network, }; @@ -616,7 +620,8 @@ class WalletInfo { json['addressPageType'] as String? ?? null, json['receiveInfoboxDismissed'] != 0, json["showCombinedBalance"] != 0, - json["favoriteTokenAddress"] as String? ?? null); + json["favoriteTokenAddress"] as String? ?? null, + json['showSeedBackupReminder'] == 1); info.network = json['network'] as String?; return info; } @@ -664,4 +669,14 @@ class WalletInfo { restoreHeight = height; await save(); } + + Future updateShowSeedBackupReminder(bool show) async { + showSeedBackupReminder = show; + + try { + await save(); + } catch (e) { + printV("Failed to save the seed backup reminder flag: $e"); + } + } } diff --git a/cw_core/lib/wallet_info_legacy.dart b/cw_core/lib/wallet_info_legacy.dart index 2dadbf2ab..6f9ff9c94 100644 --- a/cw_core/lib/wallet_info_legacy.dart +++ b/cw_core/lib/wallet_info_legacy.dart @@ -274,7 +274,8 @@ class WalletInfo extends HiveObject { addressPageType, false, true, - null) + null, + false) ..network = network; final wiId = await walletInfo.save(); for (final address in usedAddresses ?? []) { diff --git a/lib/core/auth_service.dart b/lib/core/auth_service.dart index 487192916..1057b6237 100644 --- a/lib/core/auth_service.dart +++ b/lib/core/auth_service.dart @@ -36,6 +36,7 @@ class AuthService with Store { static const List _alwaysAuthenticateRoutes = [ Routes.showKeys, + Routes.seed, Routes.backup, Routes.setupPin, Routes.setup_2faPage, diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index 994121a90..4b83c8089 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -107,6 +107,7 @@ abstract class DashboardViewModelBase with Store { wallet = appStore.wallet! { showDecredInfoCard = wallet.type == WalletType.decred && (sharedPreferences.getBool(PreferencesKey.showDecredInfoCard) ?? true); + showSeedBackupReminder = wallet.walletInfo.showSeedBackupReminder; name = wallet.name; type = wallet.type; @@ -207,6 +208,7 @@ abstract class DashboardViewModelBase with Store { loadCardDesigns(); showDecredInfoCard = wallet?.type == WalletType.decred && sharedPreferences.getBool(PreferencesKey.showDecredInfoCard) != false; + loadSeedBackupReminder(); tradeMonitor.stopTradeMonitoring(); tradeMonitor.monitorActiveTrades(wallet!.id); @@ -892,6 +894,22 @@ abstract class DashboardViewModelBase with Store { @observable late bool showDecredInfoCard; + @observable + late bool showSeedBackupReminder; + + @computed + bool get hasBalance => wallet.balance.values.any( + (balance) => + !balance.available.isZero || + !balance.unavailable.isZero || + !(balance.secondAvailable?.isZero ?? true) || + !(balance.secondUnavailable?.isZero ?? true) || + !(balance.frozen?.isZero ?? true), + ); + + @computed + bool get shouldShowSeedBackupReminder => showSeedBackupReminder && hasBalance; + @computed bool get showPayjoinCard => wallet.type == WalletType.bitcoin && @@ -1121,6 +1139,17 @@ abstract class DashboardViewModelBase with Store { sharedPreferences.setBool(PreferencesKey.showDecredInfoCard, false); } + @action + void loadSeedBackupReminder() { + showSeedBackupReminder = wallet.walletInfo.showSeedBackupReminder; + } + + @action + Future dismissSeedBackupReminder() async { + showSeedBackupReminder = false; + await wallet.walletInfo.updateShowSeedBackupReminder(false); + } + @action void dismissPayjoin() { settingsStore.showPayjoinCard = false; diff --git a/lib/view_model/wallet_seed_view_model.dart b/lib/view_model/wallet_seed_view_model.dart index 4d3ee97d7..9894dc48b 100644 --- a/lib/view_model/wallet_seed_view_model.dart +++ b/lib/view_model/wallet_seed_view_model.dart @@ -1,7 +1,9 @@ +import 'dart:async'; import 'dart:math'; import 'package:cake_wallet/utils/feature_flag.dart'; import 'package:cw_core/utils/print_verbose.dart'; +import 'package:cw_core/wallet_info.dart'; import 'package:flutter/foundation.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:mobx/mobx.dart'; @@ -16,11 +18,14 @@ abstract class WalletSeedViewModelBase with Store { : name = wallet.name, seed = wallet.seed!, walletType = wallet.type, + _walletInfo = wallet.walletInfo, currentOptions = ObservableList(), verificationIndices = ObservableList() { setupSeedVerification(); } + final WalletInfo _walletInfo; + @observable String name; @@ -133,6 +138,7 @@ abstract class WalletSeedViewModelBase with Store { } else { // All verification steps completed isVerificationComplete = true; + unawaited(markSeedVerified()); } return true; @@ -141,4 +147,12 @@ abstract class WalletSeedViewModelBase with Store { return false; } } + + Future markSeedVerified() async { + if (!_walletInfo.showSeedBackupReminder) { + return; + } + + await _walletInfo.updateShowSeedBackupReminder(false); + } }