From 36a03b98ad1c6f1a3937dcf8aebe6f7e13304d77 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Mon, 8 Jul 2024 10:41:01 +0200 Subject: [PATCH] haven: backup seeds --- lib/entities/default_settings_migration.dart | 25 +++++++++++++++++++- lib/entities/haven_seed_store.dart | 19 +++++++++++++++ lib/main.dart | 20 +++++++++++++--- 3 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 lib/entities/haven_seed_store.dart diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart index 3aad38179..2fbd7a2b4 100644 --- a/lib/entities/default_settings_migration.dart +++ b/lib/entities/default_settings_migration.dart @@ -1,11 +1,15 @@ import 'dart:io' show Directory, File, Platform; import 'package:cake_wallet/bitcoin/bitcoin.dart'; +import 'package:cake_wallet/core/key_service.dart'; import 'package:cake_wallet/core/secure_storage.dart'; import 'package:cake_wallet/entities/exchange_api_mode.dart'; import 'package:cake_wallet/entities/fiat_api_mode.dart'; +import 'package:cake_wallet/entities/haven_seed_store.dart'; +import 'package:cw_core/cake_hive.dart'; import 'package:cw_core/pathForWallet.dart'; import 'package:cake_wallet/entities/secret_store_key.dart'; import 'package:cw_core/root_dir.dart'; +import 'package:cw_haven/haven_wallet_service.dart'; import 'package:hive/hive.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:cake_wallet/entities/preferences_key.dart'; @@ -49,7 +53,8 @@ Future defaultSettingsMigration( required Box powNodes, required Box walletInfoSource, required Box tradeSource, - required Box contactSource}) async { + required Box contactSource, + required Box havenSeedStore}) async { if (Platform.isIOS) { await ios_migrate_v1(walletInfoSource, tradeSource, contactSource); } @@ -245,6 +250,9 @@ Future defaultSettingsMigration( _fixNodesUseSSLFlag(nodes); await changeDefaultNanoNode(nodes, sharedPreferences); break; + case 40: + await _backupHavenSeeds(havenSeedStore); + default: break; } @@ -259,6 +267,21 @@ Future defaultSettingsMigration( await sharedPreferences.setInt(PreferencesKey.currentDefaultSettingsMigrationVersion, version); } +Future _backupHavenSeeds(Box havenSeedStore) async { + final walletInfoSource = await CakeHive.openBox(WalletInfo.boxName); + final wallets = walletInfoSource.values + .where((element) => element.type == WalletType.haven); + for (var w in wallets) { + final walletService = HavenWalletService(walletInfoSource); + final flutterSecureStorage = secureStorageShared; + final keyService = KeyService(flutterSecureStorage); + final password = await keyService.getWalletPassword(walletName: w.name); + final wallet = await walletService.openWallet(w.name, password); + havenSeedStore.add(HavenSeedStore(id: wallet.id, seed: wallet.seed)); + wallet.close(); + } +} + void _fixNodesUseSSLFlag(Box nodes) { for (Node node in nodes.values) { switch (node.uriRaw) { diff --git a/lib/entities/haven_seed_store.dart b/lib/entities/haven_seed_store.dart new file mode 100644 index 000000000..52a156b6e --- /dev/null +++ b/lib/entities/haven_seed_store.dart @@ -0,0 +1,19 @@ +import 'package:cw_core/hive_type_ids.dart'; +import 'package:hive/hive.dart'; + +part 'haven_seed_store.g.dart'; + +@HiveType(typeId: HavenSeedStore.typeId) +class HavenSeedStore extends HiveObject { + HavenSeedStore({required this.id, this.seed}); + + static const typeId = TRANSACTION_TYPE_ID; + static const boxName = 'HavenSeedStore'; + static const boxKey = 'havenSeedStoreKey'; + + @HiveField(0, defaultValue: '') + String id; + + @HiveField(2) + String? seed; +} diff --git a/lib/main.dart b/lib/main.dart index 014d5f011..9e3214ac9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,6 +7,7 @@ import 'package:cake_wallet/entities/contact.dart'; import 'package:cake_wallet/entities/default_settings_migration.dart'; import 'package:cake_wallet/entities/get_encryption_key.dart'; import 'package:cake_wallet/core/secure_storage.dart'; +import 'package:cake_wallet/entities/haven_seed_store.dart'; import 'package:cake_wallet/entities/language_service.dart'; import 'package:cake_wallet/entities/template.dart'; import 'package:cake_wallet/entities/transaction_description.dart'; @@ -167,6 +168,10 @@ Future initializeAppConfigs() async { CakeHive.registerAdapter(AnonpayInvoiceInfoAdapter()); } + if (!CakeHive.isAdapterRegistered(HavenSeedStore.typeId)) { + CakeHive.registerAdapter(HavenSeedStoreAdapter()); + } + final secureStorage = secureStorageShared; final transactionDescriptionsBoxKey = @@ -188,6 +193,12 @@ Future initializeAppConfigs() async { final anonpayInvoiceInfo = await CakeHive.openBox(AnonpayInvoiceInfo.boxName); final unspentCoinsInfoSource = await CakeHive.openBox(UnspentCoinsInfo.boxName); + final havenSeedStoreBoxKey = + await getEncryptionKey(secureStorage: secureStorage, forKey: HavenSeedStore.boxKey); + final havenSeedStore = await CakeHive.openBox( + HavenSeedStore.boxName, + encryptionKey: havenSeedStoreBoxKey); + await initialSetup( sharedPreferences: await SharedPreferences.getInstance(), nodes: nodes, @@ -203,7 +214,8 @@ Future initializeAppConfigs() async { transactionDescriptions: transactionDescriptions, secureStorage: secureStorage, anonpayInvoiceInfo: anonpayInvoiceInfo, - initialMigrationVersion: 39, + havenSeedStore: havenSeedStore, + initialMigrationVersion: 40, ); } @@ -222,7 +234,8 @@ Future initialSetup( required SecureStorage secureStorage, required Box anonpayInvoiceInfo, required Box unspentCoinsInfoSource, - int initialMigrationVersion = 15}) async { + required Box havenSeedStore, + int initialMigrationVersion = 15, }) async { LanguageService.loadLocaleList(); await defaultSettingsMigration( secureStorage: secureStorage, @@ -232,7 +245,8 @@ Future initialSetup( contactSource: contactSource, tradeSource: tradesSource, nodes: nodes, - powNodes: powNodes); + powNodes: powNodes, + havenSeedStore: havenSeedStore); await setup( walletInfoSource: walletInfoSource, nodeSource: nodes,