diff --git a/cw_bitcoin/lib/bitcoin_wallet.dart b/cw_bitcoin/lib/bitcoin_wallet.dart index 2c89b8d49..bdf195ab0 100644 --- a/cw_bitcoin/lib/bitcoin_wallet.dart +++ b/cw_bitcoin/lib/bitcoin_wallet.dart @@ -1,5 +1,5 @@ import 'package:cw_bitcoin/bitcoin_mnemonic.dart'; -import 'package:cw_bitcoin/encryption_file_utils.dart'; +import 'package:cw_core/encryption_file_utils.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/unspent_coins_info.dart'; import 'package:hive/hive.dart'; diff --git a/cw_bitcoin/lib/bitcoin_wallet_service.dart b/cw_bitcoin/lib/bitcoin_wallet_service.dart index 2674f3eeb..af091dd97 100644 --- a/cw_bitcoin/lib/bitcoin_wallet_service.dart +++ b/cw_bitcoin/lib/bitcoin_wallet_service.dart @@ -2,7 +2,7 @@ import 'dart:io'; import 'package:cw_bitcoin/bitcoin_mnemonic.dart'; import 'package:cw_bitcoin/bitcoin_mnemonic_is_incorrect_exception.dart'; import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart'; -import 'package:cw_bitcoin/encryption_file_utils.dart'; +import 'package:cw_core/encryption_file_utils.dart'; import 'package:cw_core/unspent_coins_info.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_service.dart'; diff --git a/cw_bitcoin/lib/electrum_transaction_history.dart b/cw_bitcoin/lib/electrum_transaction_history.dart index 7b59b7ecb..f3135a447 100644 --- a/cw_bitcoin/lib/electrum_transaction_history.dart +++ b/cw_bitcoin/lib/electrum_transaction_history.dart @@ -1,5 +1,5 @@ import 'dart:convert'; -import 'package:cw_bitcoin/encryption_file_utils.dart'; +import 'package:cw_core/encryption_file_utils.dart'; import 'package:cw_core/pathForWallet.dart'; import 'package:cw_core/wallet_info.dart'; import 'package:mobx/mobx.dart'; diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index 710e7807f..6123def64 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -2,8 +2,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'dart:math'; -import 'dart:typed_data'; -import 'package:cw_bitcoin/encryption_file_utils.dart'; +import 'package:cw_core/encryption_file_utils.dart'; import 'package:cw_core/unspent_coins_info.dart'; import 'package:hive/hive.dart'; import 'package:cw_bitcoin/electrum_wallet_addresses.dart'; diff --git a/cw_bitcoin/lib/electrum_wallet_snapshot.dart b/cw_bitcoin/lib/electrum_wallet_snapshot.dart index 191832b4e..bc14b4c21 100644 --- a/cw_bitcoin/lib/electrum_wallet_snapshot.dart +++ b/cw_bitcoin/lib/electrum_wallet_snapshot.dart @@ -1,7 +1,7 @@ import 'dart:convert'; import 'package:cw_bitcoin/bitcoin_address_record.dart'; import 'package:cw_bitcoin/electrum_balance.dart'; -import 'package:cw_bitcoin/encryption_file_utils.dart'; +import 'package:cw_core/encryption_file_utils.dart'; import 'package:cw_core/pathForWallet.dart'; import 'package:cw_core/wallet_type.dart'; diff --git a/cw_bitcoin/lib/file.dart b/cw_bitcoin/lib/file.dart deleted file mode 100644 index 49b7d895e..000000000 --- a/cw_bitcoin/lib/file.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'dart:io'; -import 'package:cw_core/key.dart'; -import 'package:encrypt/encrypt.dart' as encrypt; - -// Do not use directly, move to Salsa20EncryhptionFile -Future<void> write( - {required String path, - required String password, - required String data}) async { - final keys = extractKeys(password); - final key = encrypt.Key.fromBase64(keys.first); - final iv = encrypt.IV.fromBase64(keys.last); - final encrypted = await encode(key: key, iv: iv, data: data); - final f = File(path); - f.writeAsStringSync(encrypted); -} - -Future<void> writeData( - {required String path, - required String password, - required String data}) async { - final keys = extractKeys(password); - final key = encrypt.Key.fromBase64(keys.first); - final iv = encrypt.IV.fromBase64(keys.last); - final encrypted = await encode(key: key, iv: iv, data: data); - final f = File(path); - f.writeAsStringSync(encrypted); -} - -Future<String> read({required String path, required String password}) async { - final file = File(path); - - if (!file.existsSync()) { - file.createSync(); - } - - final encrypted = file.readAsStringSync(); - - return decode(password: password, data: encrypted); -} diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart index 6d5171fd7..80327b5f1 100644 --- a/cw_bitcoin/lib/litecoin_wallet.dart +++ b/cw_bitcoin/lib/litecoin_wallet.dart @@ -1,6 +1,6 @@ import 'package:cw_bitcoin/bitcoin_mnemonic.dart'; import 'package:cw_bitcoin/bitcoin_transaction_priority.dart'; -import 'package:cw_bitcoin/encryption_file_utils.dart'; +import 'package:cw_core/encryption_file_utils.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/unspent_coins_info.dart'; import 'package:cw_bitcoin/litecoin_wallet_addresses.dart'; diff --git a/cw_bitcoin/lib/litecoin_wallet_service.dart b/cw_bitcoin/lib/litecoin_wallet_service.dart index cb33df800..5a8e9cf4f 100644 --- a/cw_bitcoin/lib/litecoin_wallet_service.dart +++ b/cw_bitcoin/lib/litecoin_wallet_service.dart @@ -1,5 +1,5 @@ import 'dart:io'; -import 'package:cw_bitcoin/encryption_file_utils.dart'; +import 'package:cw_core/encryption_file_utils.dart'; import 'package:cw_core/unspent_coins_info.dart'; import 'package:hive/hive.dart'; import 'package:cw_bitcoin/bitcoin_mnemonic.dart'; diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock index fe8b55acd..0e2d7b88c 100644 --- a/cw_bitcoin/pubspec.lock +++ b/cw_bitcoin/pubspec.lock @@ -156,7 +156,7 @@ packages: source: hosted version: "8.4.4" cake_backup: - dependency: "direct main" + dependency: transitive description: path: "." ref: main diff --git a/cw_bitcoin/pubspec.yaml b/cw_bitcoin/pubspec.yaml index e0f5dad67..dae0af39b 100644 --- a/cw_bitcoin/pubspec.yaml +++ b/cw_bitcoin/pubspec.yaml @@ -27,11 +27,6 @@ dependencies: unorm_dart: ^0.2.0 cryptography: ^2.0.5 encrypt: ^5.0.1 - cake_backup: - git: - url: https://github.com/cake-tech/cake_backup.git - ref: main - version: 1.0.0 dev_dependencies: flutter_test: diff --git a/cw_bitcoin/lib/encryption_file_utils.dart b/cw_core/lib/encryption_file_utils.dart similarity index 89% rename from cw_bitcoin/lib/encryption_file_utils.dart rename to cw_core/lib/encryption_file_utils.dart index 95f000f04..0852aeda7 100644 --- a/cw_bitcoin/lib/encryption_file_utils.dart +++ b/cw_core/lib/encryption_file_utils.dart @@ -1,6 +1,6 @@ import 'dart:io'; import 'dart:typed_data'; -import 'package:cw_bitcoin/file.dart' as bf; +import 'package:cw_core/file.dart' as file; import 'package:cake_backup/backup.dart' as cwb; EncryptionFileUtils encryptionFileUtilsFor(bool direct) @@ -17,12 +17,12 @@ class Salsa20EncryhptionFileUtils extends EncryptionFileUtils { // Requires legacy complex key + iv as password @override Future<void> write({required String path, required String password, required String data}) async - => await bf.write(path: path, password: password, data: data); + => await file.write(path: path, password: password, data: data); // Requires legacy complex key + iv as password @override Future<String> read({required String path, required String password}) async - => await bf.read(path: path, password: password); + => await file.read(path: path, password: password); } class XChaCha20EncryptionFileUtils extends EncryptionFileUtils { diff --git a/cw_ethereum/lib/file.dart b/cw_core/lib/file.dart similarity index 100% rename from cw_ethereum/lib/file.dart rename to cw_core/lib/file.dart diff --git a/cw_core/pubspec.lock b/cw_core/pubspec.lock index e399526fd..014bd34fa 100644 --- a/cw_core/pubspec.lock +++ b/cw_core/pubspec.lock @@ -113,6 +113,15 @@ packages: url: "https://pub.dev" source: hosted version: "8.4.3" + cake_backup: + dependency: "direct main" + description: + path: "." + ref: main + resolved-ref: "3aba867dcab6737f6707782f5db15d71f303db38" + url: "https://github.com/cake-tech/cake_backup.git" + source: git + version: "1.0.0+1" characters: dependency: transitive description: @@ -169,6 +178,22 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.2" + cryptography: + dependency: transitive + description: + name: cryptography + sha256: df156c5109286340817d21fa7b62f9140f17915077127dd70f8bd7a2a0997a35 + url: "https://pub.dev" + source: hosted + version: "2.5.0" + cupertino_icons: + dependency: transitive + description: + name: cupertino_icons + sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d + url: "https://pub.dev" + source: hosted + version: "1.0.6" dart_style: dependency: transitive description: @@ -608,6 +633,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" + tuple: + dependency: transitive + description: + name: tuple + sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151 + url: "https://pub.dev" + source: hosted + version: "2.0.2" typed_data: dependency: transitive description: diff --git a/cw_core/pubspec.yaml b/cw_core/pubspec.yaml index 9dcb7eaba..b6665a9f2 100644 --- a/cw_core/pubspec.yaml +++ b/cw_core/pubspec.yaml @@ -19,6 +19,11 @@ dependencies: flutter_mobx: ^2.0.6+1 intl: ^0.18.0 encrypt: ^5.0.1 + cake_backup: + git: + url: https://github.com/cake-tech/cake_backup.git + ref: main + version: 1.0.0 dev_dependencies: flutter_test: diff --git a/cw_ethereum/lib/encryption_file_utils.dart b/cw_ethereum/lib/encryption_file_utils.dart deleted file mode 100644 index 4644b8cfb..000000000 --- a/cw_ethereum/lib/encryption_file_utils.dart +++ /dev/null @@ -1,42 +0,0 @@ -import 'dart:io'; -import 'dart:typed_data'; -import 'package:cw_ethereum/file.dart' as ef; -import 'package:cake_backup/backup.dart' as cwb; - -EncryptionFileUtils encryptionFileUtilsFor(bool direct) - => direct - ? XChaCha20EncryptionFileUtils() - : Salsa20EncryhptionFileUtils(); - -abstract class EncryptionFileUtils { - Future<void> write({required String path, required String password, required String data}); - Future<String> read({required String path, required String password}); -} - -class Salsa20EncryhptionFileUtils extends EncryptionFileUtils { - // Requires legacy complex key + iv as password - @override - Future<void> write({required String path, required String password, required String data}) async - => await ef.write(path: path, password: password, data: data); - - // Requires legacy complex key + iv as password - @override - Future<String> read({required String path, required String password}) async - => await ef.read(path: path, password: password); -} - -class XChaCha20EncryptionFileUtils extends EncryptionFileUtils { - @override - Future<void> write({required String path, required String password, required String data}) async { - final encrypted = await cwb.encrypt(password, Uint8List.fromList(data.codeUnits)); - await File(path).writeAsBytes(encrypted); - } - - @override - Future<String> read({required String path, required String password}) async { - final file = File(path); - final encrypted = await file.readAsBytes(); - final bytes = await cwb.decrypt(password, encrypted); - return String.fromCharCodes(bytes); - } -} \ No newline at end of file diff --git a/cw_ethereum/lib/ethereum_transaction_history.dart b/cw_ethereum/lib/ethereum_transaction_history.dart index 397625f05..a4229ac72 100644 --- a/cw_ethereum/lib/ethereum_transaction_history.dart +++ b/cw_ethereum/lib/ethereum_transaction_history.dart @@ -2,7 +2,7 @@ import 'dart:convert'; import 'dart:core'; import 'package:cw_core/pathForWallet.dart'; import 'package:cw_core/wallet_info.dart'; -import 'package:cw_ethereum/encryption_file_utils.dart'; +import 'package:cw_core/encryption_file_utils.dart'; import 'package:mobx/mobx.dart'; import 'package:cw_core/transaction_history.dart'; import 'package:cw_ethereum/ethereum_transaction_info.dart'; diff --git a/cw_ethereum/lib/ethereum_wallet.dart b/cw_ethereum/lib/ethereum_wallet.dart index c476405a4..d2e7423d0 100644 --- a/cw_ethereum/lib/ethereum_wallet.dart +++ b/cw_ethereum/lib/ethereum_wallet.dart @@ -15,7 +15,7 @@ import 'package:cw_core/wallet_addresses.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_info.dart'; import 'package:cw_ethereum/default_erc20_tokens.dart'; -import 'package:cw_ethereum/encryption_file_utils.dart'; +import 'package:cw_core/encryption_file_utils.dart'; import 'package:cw_ethereum/erc20_balance.dart'; import 'package:cw_ethereum/ethereum_client.dart'; import 'package:cw_ethereum/ethereum_exceptions.dart'; diff --git a/cw_ethereum/lib/ethereum_wallet_service.dart b/cw_ethereum/lib/ethereum_wallet_service.dart index 289e7d25b..cdff5812f 100644 --- a/cw_ethereum/lib/ethereum_wallet_service.dart +++ b/cw_ethereum/lib/ethereum_wallet_service.dart @@ -5,7 +5,7 @@ import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_service.dart'; import 'package:cw_core/wallet_type.dart'; -import 'package:cw_ethereum/encryption_file_utils.dart'; +import 'package:cw_core/encryption_file_utils.dart'; import 'package:cw_ethereum/ethereum_mnemonics.dart'; import 'package:cw_ethereum/ethereum_wallet.dart'; import 'package:cw_ethereum/ethereum_wallet_creation_credentials.dart'; diff --git a/cw_ethereum/pubspec.yaml b/cw_ethereum/pubspec.yaml index 6b324aa7b..5d19589f3 100644 --- a/cw_ethereum/pubspec.yaml +++ b/cw_ethereum/pubspec.yaml @@ -23,11 +23,6 @@ dependencies: shared_preferences: ^2.0.15 cw_core: path: ../cw_core - cake_backup: - git: - url: https://github.com/cake-tech/cake_backup.git - ref: main - version: 1.0.0 dev_dependencies: flutter_test: diff --git a/cw_haven/pubspec.lock b/cw_haven/pubspec.lock index a63aa3237..40f2bbe3b 100644 --- a/cw_haven/pubspec.lock +++ b/cw_haven/pubspec.lock @@ -113,6 +113,15 @@ packages: url: "https://pub.dev" source: hosted version: "8.4.3" + cake_backup: + dependency: transitive + description: + path: "." + ref: main + resolved-ref: "3aba867dcab6737f6707782f5db15d71f303db38" + url: "https://github.com/cake-tech/cake_backup.git" + source: git + version: "1.0.0+1" characters: dependency: transitive description: @@ -169,6 +178,22 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.2" + cryptography: + dependency: transitive + description: + name: cryptography + sha256: df156c5109286340817d21fa7b62f9140f17915077127dd70f8bd7a2a0997a35 + url: "https://pub.dev" + source: hosted + version: "2.5.0" + cupertino_icons: + dependency: transitive + description: + name: cupertino_icons + sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d + url: "https://pub.dev" + source: hosted + version: "1.0.6" cw_core: dependency: "direct main" description: @@ -615,6 +640,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" + tuple: + dependency: transitive + description: + name: tuple + sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151 + url: "https://pub.dev" + source: hosted + version: "2.0.2" typed_data: dependency: transitive description: diff --git a/cw_monero/example/pubspec.lock b/cw_monero/example/pubspec.lock index 1aae6b0c9..3b4d65636 100644 --- a/cw_monero/example/pubspec.lock +++ b/cw_monero/example/pubspec.lock @@ -33,6 +33,15 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + cake_backup: + dependency: transitive + description: + path: "." + ref: main + resolved-ref: "3aba867dcab6737f6707782f5db15d71f303db38" + url: "https://github.com/cake-tech/cake_backup.git" + source: git + version: "1.0.0+1" characters: dependency: transitive description: @@ -73,6 +82,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.2" + cryptography: + dependency: transitive + description: + name: cryptography + sha256: df156c5109286340817d21fa7b62f9140f17915077127dd70f8bd7a2a0997a35 + url: "https://pub.dev" + source: hosted + version: "2.5.0" cupertino_icons: dependency: "direct main" description: @@ -366,6 +383,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.1" + tuple: + dependency: transitive + description: + name: tuple + sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151 + url: "https://pub.dev" + source: hosted + version: "2.0.2" typed_data: dependency: transitive description: diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock index 37e08e7ca..ac20e1606 100644 --- a/cw_monero/pubspec.lock +++ b/cw_monero/pubspec.lock @@ -113,6 +113,15 @@ packages: url: "https://pub.dev" source: hosted version: "8.4.3" + cake_backup: + dependency: transitive + description: + path: "." + ref: main + resolved-ref: "3aba867dcab6737f6707782f5db15d71f303db38" + url: "https://github.com/cake-tech/cake_backup.git" + source: git + version: "1.0.0+1" characters: dependency: transitive description: @@ -169,6 +178,22 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.2" + cryptography: + dependency: transitive + description: + name: cryptography + sha256: df156c5109286340817d21fa7b62f9140f17915077127dd70f8bd7a2a0997a35 + url: "https://pub.dev" + source: hosted + version: "2.5.0" + cupertino_icons: + dependency: transitive + description: + name: cupertino_icons + sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d + url: "https://pub.dev" + source: hosted + version: "1.0.6" cw_core: dependency: "direct main" description: @@ -615,6 +640,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" + tuple: + dependency: transitive + description: + name: tuple + sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151 + url: "https://pub.dev" + source: hosted + version: "2.0.2" typed_data: dependency: transitive description: diff --git a/cw_nano/lib/nano_transaction_history.dart b/cw_nano/lib/nano_transaction_history.dart index dadd353c4..44d64f7d4 100644 --- a/cw_nano/lib/nano_transaction_history.dart +++ b/cw_nano/lib/nano_transaction_history.dart @@ -2,24 +2,29 @@ import 'dart:convert'; import 'dart:core'; import 'package:cw_core/pathForWallet.dart'; import 'package:cw_core/wallet_info.dart'; -import 'package:cw_nano/file.dart'; +import 'package:cw_core/encryption_file_utils.dart'; import 'package:mobx/mobx.dart'; import 'package:cw_core/transaction_history.dart'; import 'package:cw_nano/nano_transaction_info.dart'; part 'nano_transaction_history.g.dart'; + const transactionsHistoryFileName = 'transactions.json'; class NanoTransactionHistory = NanoTransactionHistoryBase with _$NanoTransactionHistory; -abstract class NanoTransactionHistoryBase - extends TransactionHistoryBase<NanoTransactionInfo> with Store { - NanoTransactionHistoryBase({required this.walletInfo, required String password}) - : _password = password { +abstract class NanoTransactionHistoryBase extends TransactionHistoryBase<NanoTransactionInfo> + with Store { + NanoTransactionHistoryBase({ + required this.walletInfo, + required String password, + required this.encryptionFileUtils, + }) : _password = password { transactions = ObservableMap<String, NanoTransactionInfo>(); } final WalletInfo walletInfo; + final EncryptionFileUtils encryptionFileUtils; String _password; Future<void> init() async => await _load(); @@ -30,7 +35,7 @@ abstract class NanoTransactionHistoryBase final dirPath = await pathForWalletDir(name: walletInfo.name, type: walletInfo.type); final path = '$dirPath/$transactionsHistoryFileName'; final data = json.encode({'transactions': transactions}); - await writeData(path: path, password: _password, data: data); + await encryptionFileUtils.write(path: path, password: _password, data: data); } catch (e) { print('Error while save nano transaction history: ${e.toString()}'); } @@ -46,7 +51,10 @@ abstract class NanoTransactionHistoryBase Future<Map<String, dynamic>> _read() async { final dirPath = await pathForWalletDir(name: walletInfo.name, type: walletInfo.type); final path = '$dirPath/$transactionsHistoryFileName'; - final content = await read(path: path, password: _password); + final content = await encryptionFileUtils.read(path: path, password: _password); + if (content.isEmpty) { + return {}; + } return json.decode(content) as Map<String, dynamic>; } diff --git a/cw_nano/lib/nano_wallet.dart b/cw_nano/lib/nano_wallet.dart index da50f4ebb..a26cd89a8 100644 --- a/cw_nano/lib/nano_wallet.dart +++ b/cw_nano/lib/nano_wallet.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:cw_core/cake_hive.dart'; import 'package:cw_core/crypto_currency.dart'; +import 'package:cw_core/encryption_file_utils.dart'; import 'package:cw_core/nano_account_info_response.dart'; import 'package:cw_core/node.dart'; import 'package:cw_core/pathForWallet.dart'; @@ -11,7 +12,6 @@ import 'package:cw_core/sync_status.dart'; import 'package:cw_core/transaction_direction.dart'; import 'package:cw_core/transaction_priority.dart'; import 'package:cw_core/wallet_info.dart'; -import 'package:cw_nano/file.dart'; import 'package:cw_core/nano_account.dart'; import 'package:cw_nano/nano_balance.dart'; import 'package:cw_nano/nano_client.dart'; @@ -39,11 +39,13 @@ abstract class NanoWalletBase required String mnemonic, required String password, NanoBalance? initialBalance, + required EncryptionFileUtils encryptionFileUtils, }) : syncStatus = NotConnectedSyncStatus(), _password = password, _mnemonic = mnemonic, _derivationType = walletInfo.derivationType!, _isTransactionUpdating = false, + _encryptionFileUtils = encryptionFileUtils, _client = NanoClient(), walletAddresses = NanoWalletAddresses(walletInfo), balance = ObservableMap<CryptoCurrency, NanoBalance>.of({ @@ -52,7 +54,11 @@ abstract class NanoWalletBase }), super(walletInfo) { this.walletInfo = walletInfo; - transactionHistory = NanoTransactionHistory(walletInfo: walletInfo, password: password); + transactionHistory = NanoTransactionHistory( + walletInfo: walletInfo, + password: password, + encryptionFileUtils: encryptionFileUtils, + ); if (!CakeHive.isAdapterRegistered(NanoAccount.typeId)) { CakeHive.registerAdapter(NanoAccountAdapter()); } @@ -62,6 +68,8 @@ abstract class NanoWalletBase final String _password; final DerivationType _derivationType; + final EncryptionFileUtils _encryptionFileUtils; + String? _privateKey; String? _publicAddress; String? _seedKey; @@ -83,6 +91,9 @@ abstract class NanoWalletBase @observable late ObservableMap<CryptoCurrency, NanoBalance> balance; + @override + String get password => _password; + // initialize the different forms of private / public key we'll need: Future<void> init() async { final String type = (_derivationType == DerivationType.nano) ? "standard" : "hd"; @@ -290,7 +301,7 @@ abstract class NanoWalletBase Future<void> save() async { await walletAddresses.updateAddressesInBox(); final path = await makePath(); - await write(path: path, password: _password, data: toJSON()); + await _encryptionFileUtils.write(path: path, password: _password, data: toJSON()); await transactionHistory.save(); } @@ -339,9 +350,10 @@ abstract class NanoWalletBase required String name, required String password, required WalletInfo walletInfo, + required EncryptionFileUtils encryptionFileUtils, }) async { final path = await pathForWallet(name: name, type: walletInfo.type); - final jsonSource = await read(path: path, password: password); + final jsonSource = await encryptionFileUtils.read(path: path, password: password); final data = json.decode(jsonSource) as Map; final mnemonic = data['mnemonic'] as String; @@ -361,6 +373,7 @@ abstract class NanoWalletBase password: password, mnemonic: mnemonic, initialBalance: balance, + encryptionFileUtils: encryptionFileUtils, ); // init() should always be run after this! } diff --git a/cw_nano/lib/nano_wallet_service.dart b/cw_nano/lib/nano_wallet_service.dart index 2f183d1cc..6c7ee549b 100644 --- a/cw_nano/lib/nano_wallet_service.dart +++ b/cw_nano/lib/nano_wallet_service.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:cw_core/pathForWallet.dart'; +import 'package:cw_core/encryption_file_utils.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_service.dart'; @@ -15,9 +16,10 @@ import 'package:nanodart/nanodart.dart'; class NanoWalletService extends WalletService<NanoNewWalletCredentials, NanoRestoreWalletFromSeedCredentials, NanoRestoreWalletFromKeysCredentials> { - NanoWalletService(this.walletInfoSource); + NanoWalletService(this.walletInfoSource, this.isDirect); final Box<WalletInfo> walletInfoSource; + final bool isDirect; static bool walletFilesExist(String path) => !File(path).existsSync() && !File('$path.keys').existsSync(); @@ -38,6 +40,7 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials, walletInfo: credentials.walletInfo!, mnemonic: mnemonic, password: credentials.password!, + encryptionFileUtils: encryptionFileUtilsFor(isDirect), ); wallet.init(); return wallet; @@ -65,8 +68,12 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials, String randomWords = (List<String>.from(nm.NanoMnemomics.WORDLIST)..shuffle()).take(24).join(' '); - final currentWallet = - NanoWallet(walletInfo: currentWalletInfo, password: password, mnemonic: randomWords); + final currentWallet = NanoWallet( + walletInfo: currentWalletInfo, + password: password, + mnemonic: randomWords, + encryptionFileUtils: encryptionFileUtilsFor(isDirect), + ); await currentWallet.renameWalletFiles(newName); @@ -105,6 +112,7 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials, password: credentials.password!, mnemonic: mnemonic ?? credentials.seedKey, walletInfo: credentials.walletInfo!, + encryptionFileUtils: encryptionFileUtilsFor(isDirect), ); await wallet.init(); await wallet.save(); @@ -135,6 +143,7 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials, password: credentials.password!, mnemonic: credentials.mnemonic, walletInfo: credentials.walletInfo!, + encryptionFileUtils: encryptionFileUtilsFor(isDirect), ); await wallet.init(); @@ -154,6 +163,7 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials, name: name, password: password, walletInfo: walletInfo, + encryptionFileUtils: encryptionFileUtilsFor(isDirect), ); await wallet.init(); diff --git a/cw_nano/pubspec.lock b/cw_nano/pubspec.lock index ea932baee..9bcc6695c 100644 --- a/cw_nano/pubspec.lock +++ b/cw_nano/pubspec.lock @@ -137,6 +137,15 @@ packages: url: "https://pub.dev" source: hosted version: "8.6.1" + cake_backup: + dependency: transitive + description: + path: "." + ref: main + resolved-ref: "3aba867dcab6737f6707782f5db15d71f303db38" + url: "https://github.com/cake-tech/cake_backup.git" + source: git + version: "1.0.0+1" characters: dependency: transitive description: @@ -193,6 +202,22 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.3" + cryptography: + dependency: transitive + description: + name: cryptography + sha256: df156c5109286340817d21fa7b62f9140f17915077127dd70f8bd7a2a0997a35 + url: "https://pub.dev" + source: hosted + version: "2.5.0" + cupertino_icons: + dependency: transitive + description: + name: cupertino_icons + sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d + url: "https://pub.dev" + source: hosted + version: "1.0.6" cw_core: dependency: "direct main" description: @@ -695,6 +720,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" + tuple: + dependency: transitive + description: + name: tuple + sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151 + url: "https://pub.dev" + source: hosted + version: "2.0.2" typed_data: dependency: transitive description: diff --git a/lib/di.dart b/lib/di.dart index f8b455fd0..270bb77e4 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -1,4 +1,3 @@ - import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart'; import 'package:cake_wallet/core/yat_service.dart'; import 'package:cake_wallet/entities/parse_address_from_domain.dart'; @@ -327,8 +326,7 @@ Future<void> setup({ getIt.registerSingleton<ExchangeTemplateStore>( ExchangeTemplateStore(templateSource: _exchangeTemplates)); getIt.registerSingleton<YatStore>( - YatStore(appStore: getIt.get<AppStore>(), secureStorage: getIt.get<SecureStorage>()) - ..init()); + YatStore(appStore: getIt.get<AppStore>(), secureStorage: getIt.get<SecureStorage>())..init()); getIt.registerSingleton<AnonpayTransactionsStore>( AnonpayTransactionsStore(anonpayInvoiceInfoSource: _anonpayInvoiceInfoSource)); @@ -849,7 +847,8 @@ Future<void> setup({ return ethereum!.createEthereumWalletService( _walletInfoSource, SettingsStoreBase.walletPasswordDirectInput); case WalletType.nano: - return nano!.createNanoWalletService(_walletInfoSource, SettingsStoreBase.walletPasswordDirectInput); + return nano!.createNanoWalletService( + _walletInfoSource, SettingsStoreBase.walletPasswordDirectInput); default: throw Exception('Unexpected token: ${param1.toString()} for generating of WalletService'); } @@ -913,19 +912,16 @@ Future<void> setup({ trades: _tradesSource, settingsStore: getIt.get<SettingsStore>())); - getIt.registerFactory(() => BackupService( - getIt.get<SecureStorage>(), - _walletInfoSource, - getIt.get<KeyService>(), - getIt.get<SharedPreferences>())); + getIt.registerFactory(() => BackupService(getIt.get<SecureStorage>(), _walletInfoSource, + getIt.get<KeyService>(), getIt.get<SharedPreferences>())); getIt.registerFactory(() => BackupViewModel( getIt.get<SecureStorage>(), getIt.get<SecretStore>(), getIt.get<BackupService>())); getIt.registerFactory(() => BackupPage(getIt.get<BackupViewModel>())); - getIt.registerFactory(() => - EditBackupPasswordViewModel(getIt.get<SecureStorage>(), getIt.get<SecretStore>())); + getIt.registerFactory( + () => EditBackupPasswordViewModel(getIt.get<SecureStorage>(), getIt.get<SecretStore>())); getIt.registerFactory(() => EditBackupPasswordPage(getIt.get<EditBackupPasswordViewModel>())); @@ -972,8 +968,8 @@ Future<void> setup({ getIt.registerFactory(() => SupportPage(getIt.get<SupportViewModel>())); - getIt.registerFactory(() => SupportChatPage(getIt.get<SupportViewModel>(), - secureStorage: getIt.get<SecureStorage>())); + getIt.registerFactory(() => + SupportChatPage(getIt.get<SupportViewModel>(), secureStorage: getIt.get<SecureStorage>())); getIt.registerFactory(() => SupportOtherLinksPage(getIt.get<SupportViewModel>())); @@ -1156,62 +1152,52 @@ Future<void> setup({ (type, _) => AdvancedPrivacySettingsViewModel(type, getIt.get<SettingsStore>())); getIt.registerFactoryParam<WalletUnlockLoadableViewModel, WalletUnlockArguments, void>((args, _) { - final currentWalletName = getIt - .get<SharedPreferences>() - .getString(PreferencesKey.currentWalletName) ?? ''; + final currentWalletName = + getIt.get<SharedPreferences>().getString(PreferencesKey.currentWalletName) ?? ''; final currentWalletTypeRaw = - getIt.get<SharedPreferences>() - .getInt(PreferencesKey.currentWalletType) ?? 0; + getIt.get<SharedPreferences>().getInt(PreferencesKey.currentWalletType) ?? 0; final currentWalletType = deserializeFromInt(currentWalletTypeRaw); - return WalletUnlockLoadableViewModel( - getIt.get<AppStore>(), - getIt.get<WalletLoadingService>(), - walletName: args.walletName ?? currentWalletName, - walletType: args.walletType ?? currentWalletType); + return WalletUnlockLoadableViewModel(getIt.get<AppStore>(), getIt.get<WalletLoadingService>(), + walletName: args.walletName ?? currentWalletName, + walletType: args.walletType ?? currentWalletType); }); - getIt.registerFactoryParam<WalletUnlockVerifiableViewModel, WalletUnlockArguments, void>((args, _) { - final currentWalletName = getIt - .get<SharedPreferences>() - .getString(PreferencesKey.currentWalletName) ?? ''; + getIt.registerFactoryParam<WalletUnlockVerifiableViewModel, WalletUnlockArguments, void>( + (args, _) { + final currentWalletName = + getIt.get<SharedPreferences>().getString(PreferencesKey.currentWalletName) ?? ''; final currentWalletTypeRaw = - getIt.get<SharedPreferences>() - .getInt(PreferencesKey.currentWalletType) ?? 0; + getIt.get<SharedPreferences>().getInt(PreferencesKey.currentWalletType) ?? 0; final currentWalletType = deserializeFromInt(currentWalletTypeRaw); - return WalletUnlockVerifiableViewModel( - getIt.get<AppStore>(), - walletName: args.walletName ?? currentWalletName, - walletType: args.walletType ?? currentWalletType); + return WalletUnlockVerifiableViewModel(getIt.get<AppStore>(), + walletName: args.walletName ?? currentWalletName, + walletType: args.walletType ?? currentWalletType); }); getIt.registerFactoryParam<WalletUnlockPage, WalletUnlockArguments, bool>((args, closable) { - return WalletUnlockPage( - getIt.get<WalletUnlockLoadableViewModel>(param1: args), - args.callback, - args.authPasswordHandler, - closable: closable); + return WalletUnlockPage(getIt.get<WalletUnlockLoadableViewModel>(param1: args), args.callback, + args.authPasswordHandler, + closable: closable); }, instanceName: 'wallet_unlock_loadable'); getIt.registerFactoryParam<WalletUnlockPage, WalletUnlockArguments, bool>((args, closable) { - return WalletUnlockPage( - getIt.get<WalletUnlockVerifiableViewModel>(param1: args), - args.callback, - args.authPasswordHandler, - closable: closable); + return WalletUnlockPage(getIt.get<WalletUnlockVerifiableViewModel>(param1: args), args.callback, + args.authPasswordHandler, + closable: closable); }, instanceName: 'wallet_unlock_verifiable'); getIt.registerFactory<WalletUnlockPage>( () => getIt.get<WalletUnlockPage>( - param1: WalletUnlockArguments( - callback: (bool successful, _) { + param1: WalletUnlockArguments(callback: (bool successful, _) { if (successful) { final authStore = getIt.get<AuthenticationStore>(); authStore.allowed(); - }}), - param2: false, - instanceName: 'wallet_unlock_loadable'), + } + }), + param2: false, + instanceName: 'wallet_unlock_loadable'), instanceName: 'wallet_password_login'); getIt.registerFactoryParam<HomeSettingsPage, BalanceViewModel, void>((balanceViewModel, _) => diff --git a/lib/nano/cw_nano.dart b/lib/nano/cw_nano.dart index 0c52a24d6..dd10817a9 100644 --- a/lib/nano/cw_nano.dart +++ b/lib/nano/cw_nano.dart @@ -75,8 +75,8 @@ class CWNano extends Nano { } @override - WalletService createNanoWalletService(Box<WalletInfo> walletInfoSource) { - return NanoWalletService(walletInfoSource); + WalletService createNanoWalletService(Box<WalletInfo> walletInfoSource, bool isDirect) { + return NanoWalletService(walletInfoSource, isDirect); } @override diff --git a/lib/view_model/wallet_new_vm.dart b/lib/view_model/wallet_new_vm.dart index 6a544fcaa..560c87020 100644 --- a/lib/view_model/wallet_new_vm.dart +++ b/lib/view_model/wallet_new_vm.dart @@ -1,6 +1,4 @@ -import 'package:cake_wallet/view_model/restore/restore_wallet.dart'; import 'package:cake_wallet/ethereum/ethereum.dart'; -import 'package:flutter/foundation.dart'; import 'package:hive/hive.dart'; import 'package:mobx/mobx.dart'; import 'package:cake_wallet/monero/monero.dart'; @@ -49,7 +47,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store { case WalletType.nano: return nano!.createNanoNewWalletCredentials(name: name, password: walletPassword); default: - throw Exception('Unexpected type: ${type.toString()}');; + throw Exception('Unexpected type: ${type.toString()}'); } } diff --git a/tool/configure.dart b/tool/configure.dart index 2ee8d3e77..235b2fcd1 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -616,11 +616,11 @@ abstract class Nano { void setCurrentAccount(Object wallet, int id, String label, String? balance); - WalletService createNanoWalletService(Box<WalletInfo> walletInfoSource); + WalletService createNanoWalletService(Box<WalletInfo> walletInfoSource, bool isDirect); WalletCredentials createNanoNewWalletCredentials({ required String name, - String password, + String? password, }); WalletCredentials createNanoRestoreWalletFromSeedCredentials({