CW-673: Save Haven seeds to show it to the user after Haven removal (#1518)

* haven: backup seeds

* haven backup fixes

* ci fix

* reorder build script

* disable haven

* properly call cw_haven code

* [skip ci] update PR

* Update evm_chain_transaction_history.dart

remove print

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
This commit is contained in:
cyan 2024-12-11 15:31:01 -05:00 committed by GitHub
parent 329a1fd6de
commit e2a1d865af
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 87 additions and 14 deletions

View file

@ -19,3 +19,4 @@ const DERIVATION_INFO_TYPE_ID = 17;
const TRON_TOKEN_TYPE_ID = 18; const TRON_TOKEN_TYPE_ID = 18;
const HARDWARE_WALLET_TYPE_TYPE_ID = 19; const HARDWARE_WALLET_TYPE_TYPE_ID = 19;
const MWEB_UTXO_TYPE_ID = 20; const MWEB_UTXO_TYPE_ID = 20;
const HAVEN_SEED_STORE_TYPE_ID = 21;

View file

@ -84,7 +84,6 @@ abstract class EVMChainTransactionHistoryBase
_update(tx); _update(tx);
} }
} }
print('doneee');
} catch (e) { } catch (e) {
log(e.toString()); log(e.toString());
} }

View file

@ -1,9 +1,13 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io' show Directory, File, Platform; import 'dart:io' show Directory, File, Platform;
import 'package:cake_wallet/bitcoin/bitcoin.dart'; 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/core/secure_storage.dart';
import 'package:cake_wallet/entities/exchange_api_mode.dart'; import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cake_wallet/entities/fiat_api_mode.dart'; import 'package:cake_wallet/entities/fiat_api_mode.dart';
import 'package:cake_wallet/entities/haven_seed_store.dart';
import 'package:cake_wallet/haven/haven.dart';
import 'package:cw_core/cake_hive.dart';
import 'package:cw_core/pathForWallet.dart'; import 'package:cw_core/pathForWallet.dart';
import 'package:cake_wallet/entities/secret_store_key.dart'; import 'package:cake_wallet/entities/secret_store_key.dart';
import 'package:cw_core/root_dir.dart'; import 'package:cw_core/root_dir.dart';
@ -52,7 +56,8 @@ Future<void> defaultSettingsMigration(
required Box<Node> powNodes, required Box<Node> powNodes,
required Box<WalletInfo> walletInfoSource, required Box<WalletInfo> walletInfoSource,
required Box<Trade> tradeSource, required Box<Trade> tradeSource,
required Box<Contact> contactSource}) async { required Box<Contact> contactSource,
required Box<HavenSeedStore> havenSeedStore}) async {
if (Platform.isIOS) { if (Platform.isIOS) {
await ios_migrate_v1(walletInfoSource, tradeSource, contactSource); await ios_migrate_v1(walletInfoSource, tradeSource, contactSource);
} }
@ -290,14 +295,16 @@ Future<void> defaultSettingsMigration(
); );
break; break;
case 45: case 45:
await updateWalletTypeNodesWithNewNode( await _backupHavenSeeds(havenSeedStore);
updateWalletTypeNodesWithNewNode(
newNodeUri: 'matic.nownodes.io', newNodeUri: 'matic.nownodes.io',
sharedPreferences: sharedPreferences, sharedPreferences: sharedPreferences,
nodes: nodes, nodes: nodes,
type: WalletType.polygon, type: WalletType.polygon,
useSSL: true, useSSL: true,
); );
await updateWalletTypeNodesWithNewNode( updateWalletTypeNodesWithNewNode(
newNodeUri: 'eth.nownodes.io', newNodeUri: 'eth.nownodes.io',
sharedPreferences: sharedPreferences, sharedPreferences: sharedPreferences,
nodes: nodes, nodes: nodes,
@ -318,6 +325,13 @@ Future<void> defaultSettingsMigration(
await sharedPreferences.setInt(PreferencesKey.currentDefaultSettingsMigrationVersion, version); await sharedPreferences.setInt(PreferencesKey.currentDefaultSettingsMigrationVersion, version);
} }
Future<void> _backupHavenSeeds(Box<HavenSeedStore> havenSeedStore) async {
final future = haven?.backupHavenSeeds(havenSeedStore);
if (future != null) {
await future;
}
return;
}
/// generic function for changing any wallet default node /// generic function for changing any wallet default node
/// instead of making a new function for each change /// instead of making a new function for each change
Future<void> _changeDefaultNode({ Future<void> _changeDefaultNode({

View file

@ -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 = HAVEN_SEED_STORE_TYPE_ID;
static const boxName = 'HavenSeedStore';
static const boxKey = 'havenSeedStoreKey';
@HiveField(0, defaultValue: '')
String id;
@HiveField(2)
String? seed;
}

View file

@ -307,6 +307,23 @@ class CWHaven extends Haven {
return havenTransactionInfo.accountIndex; return havenTransactionInfo.accountIndex;
} }
@override
Future<void> backupHavenSeeds(Box<HavenSeedStore> havenSeedStore) async {
final walletInfoSource = await CakeHive.openBox<WalletInfo>(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);
await havenSeedStore.add(HavenSeedStore(id: wallet.id, seed: wallet.seed));
wallet.close();
}
await havenSeedStore.flush();
}
@override @override
WalletService createHavenWalletService(Box<WalletInfo> walletInfoSource) { WalletService createHavenWalletService(Box<WalletInfo> walletInfoSource) {
return HavenWalletService(walletInfoSource); return HavenWalletService(walletInfoSource);

View file

@ -9,6 +9,7 @@ import 'package:cake_wallet/entities/contact.dart';
import 'package:cake_wallet/entities/default_settings_migration.dart'; import 'package:cake_wallet/entities/default_settings_migration.dart';
import 'package:cake_wallet/entities/get_encryption_key.dart'; import 'package:cake_wallet/entities/get_encryption_key.dart';
import 'package:cake_wallet/core/secure_storage.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/language_service.dart';
import 'package:cake_wallet/entities/template.dart'; import 'package:cake_wallet/entities/template.dart';
import 'package:cake_wallet/entities/transaction_description.dart'; import 'package:cake_wallet/entities/transaction_description.dart';
@ -164,6 +165,10 @@ Future<void> initializeAppConfigs() async {
CakeHive.registerAdapter(AnonpayInvoiceInfoAdapter()); CakeHive.registerAdapter(AnonpayInvoiceInfoAdapter());
} }
if (!CakeHive.isAdapterRegistered(HavenSeedStore.typeId)) {
CakeHive.registerAdapter(HavenSeedStoreAdapter());
}
if (!CakeHive.isAdapterRegistered(MwebUtxo.typeId)) { if (!CakeHive.isAdapterRegistered(MwebUtxo.typeId)) {
CakeHive.registerAdapter(MwebUtxoAdapter()); CakeHive.registerAdapter(MwebUtxoAdapter());
} }
@ -188,6 +193,12 @@ Future<void> initializeAppConfigs() async {
final anonpayInvoiceInfo = await CakeHive.openBox<AnonpayInvoiceInfo>(AnonpayInvoiceInfo.boxName); final anonpayInvoiceInfo = await CakeHive.openBox<AnonpayInvoiceInfo>(AnonpayInvoiceInfo.boxName);
final unspentCoinsInfoSource = await CakeHive.openBox<UnspentCoinsInfo>(UnspentCoinsInfo.boxName); final unspentCoinsInfoSource = await CakeHive.openBox<UnspentCoinsInfo>(UnspentCoinsInfo.boxName);
final havenSeedStoreBoxKey =
await getEncryptionKey(secureStorage: secureStorage, forKey: HavenSeedStore.boxKey);
final havenSeedStore = await CakeHive.openBox<HavenSeedStore>(
HavenSeedStore.boxName,
encryptionKey: havenSeedStoreBoxKey);
await initialSetup( await initialSetup(
sharedPreferences: await SharedPreferences.getInstance(), sharedPreferences: await SharedPreferences.getInstance(),
nodes: nodes, nodes: nodes,
@ -203,6 +214,7 @@ Future<void> initializeAppConfigs() async {
transactionDescriptions: transactionDescriptions, transactionDescriptions: transactionDescriptions,
secureStorage: secureStorage, secureStorage: secureStorage,
anonpayInvoiceInfo: anonpayInvoiceInfo, anonpayInvoiceInfo: anonpayInvoiceInfo,
havenSeedStore: havenSeedStore,
initialMigrationVersion: 45, initialMigrationVersion: 45,
); );
} }
@ -222,7 +234,8 @@ Future<void> initialSetup(
required SecureStorage secureStorage, required SecureStorage secureStorage,
required Box<AnonpayInvoiceInfo> anonpayInvoiceInfo, required Box<AnonpayInvoiceInfo> anonpayInvoiceInfo,
required Box<UnspentCoinsInfo> unspentCoinsInfoSource, required Box<UnspentCoinsInfo> unspentCoinsInfoSource,
int initialMigrationVersion = 15}) async { required Box<HavenSeedStore> havenSeedStore,
int initialMigrationVersion = 15, }) async {
LanguageService.loadLocaleList(); LanguageService.loadLocaleList();
await defaultSettingsMigration( await defaultSettingsMigration(
secureStorage: secureStorage, secureStorage: secureStorage,
@ -232,7 +245,8 @@ Future<void> initialSetup(
contactSource: contactSource, contactSource: contactSource,
tradeSource: tradesSource, tradeSource: tradesSource,
nodes: nodes, nodes: nodes,
powNodes: powNodes); powNodes: powNodes,
havenSeedStore: havenSeedStore);
await setup( await setup(
walletInfoSource: walletInfoSource, walletInfoSource: walletInfoSource,
nodeSource: nodes, nodeSource: nodes,

View file

@ -656,7 +656,14 @@ import 'package:cw_core/output_info.dart';
import 'package:cake_wallet/view_model/send/output.dart'; import 'package:cake_wallet/view_model/send/output.dart';
import 'package:cw_core/wallet_service.dart'; import 'package:cw_core/wallet_service.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:cw_core/crypto_currency.dart';"""; import 'package:cw_core/crypto_currency.dart';
import 'package:cake_wallet/core/key_service.dart';
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:cake_wallet/entities/haven_seed_store.dart';
import 'package:cw_core/cake_hive.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_type.dart';
""";
const havenCWHeaders = """ const havenCWHeaders = """
import 'package:cw_core/get_height_by_date.dart'; import 'package:cw_core/get_height_by_date.dart';
import 'package:cw_core/monero_amount_format.dart'; import 'package:cw_core/monero_amount_format.dart';
@ -679,6 +686,7 @@ import 'package:cw_haven/mnemonics/french.dart';
import 'package:cw_haven/mnemonics/italian.dart'; import 'package:cw_haven/mnemonics/italian.dart';
import 'package:cw_haven/haven_transaction_creation_credentials.dart'; import 'package:cw_haven/haven_transaction_creation_credentials.dart';
import 'package:cw_haven/api/balance_list.dart'; import 'package:cw_haven/api/balance_list.dart';
import 'package:cw_haven/haven_wallet_service.dart';
"""; """;
const havenCwPart = "part 'cw_haven.dart';"; const havenCwPart = "part 'cw_haven.dart';";
const havenContent = """ const havenContent = """
@ -779,6 +787,7 @@ abstract class Haven {
void onStartup(); void onStartup();
int getTransactionInfoAccountId(TransactionInfo tx); int getTransactionInfoAccountId(TransactionInfo tx);
WalletService createHavenWalletService(Box<WalletInfo> walletInfoSource); WalletService createHavenWalletService(Box<WalletInfo> walletInfoSource);
Future<void> backupHavenSeeds(Box<HavenSeedStore> havenSeedStore);
CryptoCurrency assetOfTransaction(TransactionInfo tx); CryptoCurrency assetOfTransaction(TransactionInfo tx);
List<AssetRate> getAssetRate(); List<AssetRate> getAssetRate();
} }