From dd58455ea6d2629eb1a28991e40bf6f9953d41d3 Mon Sep 17 00:00:00 2001 From: Omar Hatem Date: Fri, 18 Sep 2026 00:33:16 +0200 Subject: [PATCH] Revert "fix: unify encryption across platforms (#3470)" (#3634) This reverts commit 90e25afc11f8e32a997d62abe5b8bed5428924b1. --- cw_core/lib/encryption_file_utils.dart | 47 ++- cw_core/lib/key.dart | 27 ++ cw_core/lib/utils/file.dart | 141 +------ cw_core/lib/wallet_service.dart | 32 +- cw_core/pubspec.yaml | 3 +- cw_core/test/encryption_file_utils_test.dart | 380 ------------------ .../dashboard/dashboard_view_model.dart | 5 +- pubspec.lock | 4 +- pubspec_base.yaml | 4 +- pubspec_overrides.yaml | 2 +- 10 files changed, 88 insertions(+), 557 deletions(-) delete mode 100644 cw_core/test/encryption_file_utils_test.dart diff --git a/cw_core/lib/encryption_file_utils.dart b/cw_core/lib/encryption_file_utils.dart index 54729b735..72a601bc3 100644 --- a/cw_core/lib/encryption_file_utils.dart +++ b/cw_core/lib/encryption_file_utils.dart @@ -1,34 +1,41 @@ +import 'dart:io'; +import 'dart:typed_data'; import 'package:cw_core/utils/file.dart' as file; +import 'package:cake_backup/backup.dart' as cwb; -EncryptionFileUtils encryptionFileUtilsFor(bool isDirect) => - XChaCha20MigratingEncryptionFileUtils(isDirect: isDirect); +EncryptionFileUtils encryptionFileUtilsFor(bool direct) => + direct ? XChaCha20EncryptionFileUtils() : Salsa20EncryhptionFileUtils(); abstract class EncryptionFileUtils { Future write({required String path, required String password, required String data}); Future read({required String path, required String password}); } -class XChaCha20MigratingEncryptionFileUtils extends EncryptionFileUtils { - XChaCha20MigratingEncryptionFileUtils({required this.isDirect}); - - final bool isDirect; - +class Salsa20EncryhptionFileUtils extends EncryptionFileUtils { + // Requires legacy complex key + iv as password @override - Future write({required String path, required String password, required String data}) { - return file.write( - path: path, - password: password, - data: data, - highEntropyPassphrase: !isDirect, - ); + Future write( + {required String path, required String password, required String data}) async => + await file.write(path: path, password: password, data: data); + + // Requires legacy complex key + iv as password + @override + Future read({required String path, required String password}) async => + await file.read(path: path, password: password); +} + +class XChaCha20EncryptionFileUtils extends EncryptionFileUtils { + @override + Future 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 read({required String path, required String password}) { - return file.read( - path: path, - password: password, - highEntropyPassphrase: !isDirect, - ); + Future 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); } } diff --git a/cw_core/lib/key.dart b/cw_core/lib/key.dart index 99570bc7f..383cbfffe 100644 --- a/cw_core/lib/key.dart +++ b/cw_core/lib/key.dart @@ -1,8 +1,35 @@ import 'package:encrypt/encrypt.dart' as encrypt; +const ivEncodedStringLength = 12; + String generateKey() { final key = encrypt.Key.fromSecureRandom(512); final iv = encrypt.IV.fromSecureRandom(8); return key.base64 + iv.base64; } + +List extractKeys(String key) { + final _key = key.substring(0, key.length - ivEncodedStringLength); + final iv = key.substring(key.length - ivEncodedStringLength); + + return [_key, iv]; +} + +Future encode( + {required encrypt.Key key, required encrypt.IV iv, required String data}) async { + final encrypter = encrypt.Encrypter(encrypt.Salsa20(key)); + final encrypted = encrypter.encrypt(data, iv: iv); + + return encrypted.base64; +} + +Future decode({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 encrypter = encrypt.Encrypter(encrypt.Salsa20(key)); + final encrypted = encrypter.decrypt64(data, iv: iv); + + return encrypted; +} diff --git a/cw_core/lib/utils/file.dart b/cw_core/lib/utils/file.dart index 3ad3165d6..72fc94859 100644 --- a/cw_core/lib/utils/file.dart +++ b/cw_core/lib/utils/file.dart @@ -1,84 +1,21 @@ -import 'dart:convert'; import 'dart:io'; -import 'dart:typed_data'; - -import 'package:cake_backup/backup.dart' as cwb; +import 'package:cw_core/key.dart'; import 'package:encrypt/encrypt.dart' as encrypt; -const _ivEncodedStringLength = 12; +Future write({required String path, required String password, required String data}) async => + writeData(path: path, password: password, data: data); -Future write({ - required String path, - required String password, - required String data, - bool? highEntropyPassphrase, -}) async { - await _writeXChaCha20( - path: path, - password: password, - data: data, - highEntropyPassphrase: highEntropyPassphrase ?? !Platform.isLinux, - ); +Future 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 read({ - required String path, - required String password, - bool? highEntropyPassphrase, -}) async { - final useHighEntropy = highEntropyPassphrase ?? !Platform.isLinux; - try { - return await _readXChaCha20(path: path, password: password); - } catch (e) { - final encrypted = await File(path).readAsBytes(); - if (encrypted.isNotEmpty && - (encrypted[0] == cwb.lowEntropyVersion || encrypted[0] == cwb.highEntropyVersion)) { - rethrow; - } - - final String data; - try { - data = await _readLegacy(path: path, password: password); - } catch (_) { - throw Exception('Failed to decrypt legacy file: invalid password or corrupted data'); - } - if (data.isEmpty) { - throw Exception('Failed to read data'); - } - - // Salsa20 is unauthenticated, so a wrong password decrypts to garbage instead of - // failing. Every payload written here is a JSON object with at least one key, so a - // correctly decrypted file always starts with '{"' and anything else is a bad - // password. - // There's 1 in 2^16 chance that this will be a false positive, but check later - // prevents any damage to the file caused by re-encryption. - if (!data.startsWith('{"')) { - throw Exception('Failed to decrypt legacy file: invalid password or corrupted data'); - } - - if (_isJson(data)) { - await _writeXChaCha20( - path: path, - password: password, - data: data, - highEntropyPassphrase: useHighEntropy, - ); - } - - return data; - } -} - -bool _isJson(String data) { - try { - json.decode(data); - return true; - } catch (_) { - return false; - } -} - -Future _readLegacy({required String path, required String password}) async { +Future read({required String path, required String password}) async { final file = File(path); if (!file.existsSync()) { @@ -87,57 +24,5 @@ Future _readLegacy({required String path, required String password}) asy final encrypted = file.readAsStringSync(); - return _decode(password: password, data: encrypted); -} - -Future _writeXChaCha20({ - required String path, - required String password, - required String data, - required bool highEntropyPassphrase, -}) async { - final encrypted = await cwb.encrypt( - password, - Uint8List.fromList(utf8.encode(data)), - highEntropyPassphrase: highEntropyPassphrase, - ); - - final tmpFile = File('$path.tmp'); - tmpFile.writeAsBytesSync(encrypted, flush: true); - tmpFile.renameSync(path); -} - -Future _readXChaCha20({ - required String path, - required String password, -}) async { - final encrypted = await File(path).readAsBytes(); - final bytes = await cwb.decrypt(password, encrypted); - return _decodeUtf8(bytes); -} - -// Linux wallets written by the old XChaCha20EncryptionFileUtils stored one byte per -// UTF-16 code unit, so bytes above 0x7F in those files are Latin-1 rather than UTF-8. -String _decodeUtf8(Uint8List bytes) { - try { - return utf8.decode(bytes); - } on FormatException { - return String.fromCharCodes(bytes); - } -} - -List _extractKeys(String key) { - final k = key.substring(0, key.length - _ivEncodedStringLength); - final iv = key.substring(key.length - _ivEncodedStringLength); - - return [k, iv]; -} - -Future _decode({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 encrypter = encrypt.Encrypter(encrypt.Salsa20(key)); - - return encrypter.decrypt64(data, iv: iv); + return decode(password: password, data: encrypted); } diff --git a/cw_core/lib/wallet_service.dart b/cw_core/lib/wallet_service.dart index d69300d17..72ea98a97 100644 --- a/cw_core/lib/wallet_service.dart +++ b/cw_core/lib/wallet_service.dart @@ -1,18 +1,17 @@ import "dart:convert"; import "dart:io"; -import 'package:cw_core/encryption_file_utils.dart'; -import 'package:cw_core/imported_nft.dart'; -import 'package:cw_core/pathForWallet.dart'; -import 'package:cw_core/spl_token.dart'; -import 'package:cw_core/tron_token.dart'; -import 'package:cw_core/utils/print_verbose.dart'; -import 'package:cw_core/wallet_keys_file.dart'; -import 'package:cw_core/wallet_base.dart'; -import 'package:cw_core/wallet_credentials.dart'; -import 'package:cw_core/wallet_info.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:path/path.dart' as p; +import "package:cw_core/imported_nft.dart"; +import "package:cw_core/pathForWallet.dart"; +import "package:cw_core/spl_token.dart"; +import "package:cw_core/tron_token.dart"; +import "package:cw_core/utils/file.dart"; +import "package:cw_core/utils/print_verbose.dart"; +import "package:cw_core/wallet_base.dart"; +import "package:cw_core/wallet_credentials.dart"; +import "package:cw_core/wallet_info.dart"; +import "package:cw_core/wallet_type.dart"; +import "package:path/path.dart" as p; abstract class WalletService { @@ -96,15 +95,8 @@ abstract class WalletService getSeeds(String name, String password, WalletType type) async { try { - final encryption = encryptionFileUtilsFor(Platform.isLinux); - - if (await WalletKeysFile.hasKeysFile(name, type)) { - final keysData = await WalletKeysFile.readKeysFile(name, type, password, encryption); - return keysData.mnemonic ?? keysData.altMnemonic ?? keysData.privateKey ?? ''; - } - final path = await pathForWallet(name: name, type: type); - final jsonSource = await encryption.read(path: path, password: password); + final jsonSource = await read(path: path, password: password); try { final data = json.decode(jsonSource) as Map; return data["mnemonic"] as String? ?? ""; diff --git a/cw_core/pubspec.yaml b/cw_core/pubspec.yaml index b7843f4b1..38a4e9a41 100644 --- a/cw_core/pubspec.yaml +++ b/cw_core/pubspec.yaml @@ -22,7 +22,8 @@ dependencies: cake_backup: git: url: https://github.com/cake-tech/cake_backup.git - ref: b5d86a2a21e1c186cd0baa4df1f3a4f3f9413056 + ref: main + version: 1.0.0 socks5_proxy: git: url: https://github.com/LacticWhale/socks_dart diff --git a/cw_core/test/encryption_file_utils_test.dart b/cw_core/test/encryption_file_utils_test.dart deleted file mode 100644 index bfd840f01..000000000 --- a/cw_core/test/encryption_file_utils_test.dart +++ /dev/null @@ -1,380 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; -import 'dart:typed_data'; - -import 'package:cake_backup/backup.dart' as cwb; -import 'package:cw_core/encryption_file_utils.dart'; -import 'package:cw_core/key.dart'; -import 'package:cw_core/utils/file.dart' as encrypted_file; -import 'package:cw_core/wallet_keys_file.dart'; -import 'package:encrypt/encrypt.dart' as encrypt; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - late Directory tmpDir; - - setUp(() { - tmpDir = Directory.systemTemp.createTempSync('cw_enc_'); - }); - - tearDown(() { - if (tmpDir.existsSync()) { - tmpDir.deleteSync(recursive: true); - } - }); - - String path([String name = 'wallet.json']) => '${tmpDir.path}/$name'; - - const walletJson = '{"mnemonic":"abandon ability able","privateKey":null}'; - - group('XChaCha20 round-trip', () { - test('writes and reads JSON with a generated high-entropy password', () async { - final password = generateKey(); - await encrypted_file.write( - path: path(), - password: password, - data: walletJson, - highEntropyPassphrase: true, - ); - - expect(await encrypted_file.read(path: path(), password: password), walletJson); - expect(File('${path()}.tmp').existsSync(), isFalse); - }); - - test('uses high-entropy (v3) vs low-entropy (v2) version bytes', () async { - final password = generateKey(); - - await encrypted_file.write( - path: path('high'), - password: password, - data: walletJson, - highEntropyPassphrase: true, - ); - expect(File(path('high')).readAsBytesSync().first, cwb.highEntropyVersion); - - await encrypted_file.write( - path: path('low'), - password: password, - data: walletJson, - highEntropyPassphrase: false, - ); - expect(File(path('low')).readAsBytesSync().first, cwb.lowEntropyVersion); - - expect(await encrypted_file.read(path: path('high'), password: password), walletJson); - expect(await encrypted_file.read(path: path('low'), password: password), walletJson); - }); - - test('read ignores highEntropyPassphrase because version is in the file', () async { - final password = generateKey(); - await encrypted_file.write( - path: path(), - password: password, - data: walletJson, - highEntropyPassphrase: true, - ); - - expect( - await encrypted_file.read( - path: path(), - password: password, - highEntropyPassphrase: false, - ), - walletJson, - ); - }); - - test('round-trips UTF-8 JSON with non-ASCII characters', () async { - final password = generateKey(); - const data = '{"name":"Café","mnemonic":"abandon"}'; - await encrypted_file.write( - path: path(), - password: password, - data: data, - highEntropyPassphrase: true, - ); - - expect(await encrypted_file.read(path: path(), password: password), data); - }); - - test('wrong password does not fall back to Salsa20 or rewrite the file', () async { - final password = generateKey(); - await encrypted_file.write( - path: path(), - password: password, - data: walletJson, - highEntropyPassphrase: true, - ); - final before = File(path()).readAsBytesSync(); - - await expectLater( - encrypted_file.read(path: path(), password: generateKey()), - throwsA(anything), - ); - expect(File(path()).readAsBytesSync(), before); - }); - - test('corrupt XChaCha20 blob is not treated as a legacy Salsa20 file', () async { - final password = generateKey(); - await encrypted_file.write( - path: path(), - password: password, - data: walletJson, - highEntropyPassphrase: true, - ); - final bytes = File(path()).readAsBytesSync(); - bytes[bytes.length - 1] = bytes[bytes.length - 1] ^ 0xFF; - File(path()).writeAsBytesSync(bytes); - - await expectLater( - encrypted_file.read(path: path(), password: password), - throwsA(anything), - ); - expect(File(path()).readAsBytesSync().first, cwb.highEntropyVersion); - }); - }); - - group('encryptionFileUtilsFor', () { - test('isDirect=false (generated password) writes high-entropy v3', () async { - final password = generateKey(); - final encryption = encryptionFileUtilsFor(false); - await encryption.write(path: path(), password: password, data: walletJson); - - expect(File(path()).readAsBytesSync().first, cwb.highEntropyVersion); - expect(await encryption.read(path: path(), password: password), walletJson); - }); - - test('isDirect=true (user password) writes low-entropy v2', () async { - const password = 'user-chosen-passphrase'; - final encryption = encryptionFileUtilsFor(true); - await encryption.write(path: path(), password: password, data: walletJson); - - expect(File(path()).readAsBytesSync().first, cwb.lowEntropyVersion); - expect(await encryption.read(path: path(), password: password), walletJson); - }); - - test('WalletKeysData JSON survives a write/read used by getSeeds', () async { - final password = generateKey(); - final keys = WalletKeysData( - mnemonic: 'abandon ability able about above absent absorb abstract', - privateKey: 'deadbeef', - ); - final encryption = encryptionFileUtilsFor(false); - await encryption.write(path: path(), password: password, data: keys.toJSON()); - - final decoded = json.decode(await encryption.read(path: path(), password: password)) - as Map; - final restored = WalletKeysData.fromJSON(decoded); - expect(restored.mnemonic, keys.mnemonic); - expect(restored.privateKey, keys.privateKey); - }); - }); - - group('legacy Salsa20 migration', () { - test('reads a Salsa20 wallet file and re-encrypts it as XChaCha20', () async { - final password = generateKey(); - File(path()).writeAsStringSync(_salsa20Encrypt(password, walletJson)); - expect(File(path()).readAsBytesSync().first, isNot(cwb.lowEntropyVersion)); - expect(File(path()).readAsBytesSync().first, isNot(cwb.highEntropyVersion)); - - final result = await encrypted_file.read( - path: path(), - password: password, - highEntropyPassphrase: true, - ); - - expect(result, walletJson); - expect(File(path()).readAsBytesSync().first, cwb.highEntropyVersion); - expect(await encrypted_file.read(path: path(), password: password), walletJson); - }); - - test('migrated file can be opened with EncryptionFileUtils', () async { - final password = generateKey(); - File(path()).writeAsStringSync(_salsa20Encrypt(password, walletJson)); - - final encryption = encryptionFileUtilsFor(false); - expect(await encryption.read(path: path(), password: password), walletJson); - expect(await encryption.read(path: path(), password: password), walletJson); - }); - - test('wrong password does not rewrite the Salsa20 file', () async { - final password = generateKey(); - final salsa = _salsa20Encrypt(password, walletJson); - File(path()).writeAsStringSync(salsa); - - await expectLater( - encrypted_file.read(path: path(), password: generateKey()), - throwsLegacyDecryptError, - ); - expect(File(path()).readAsStringSync(), salsa); - }); - - test('short or malformed password does not leak _readLegacy errors', () async { - final password = generateKey(); - final salsa = _salsa20Encrypt(password, walletJson); - File(path()).writeAsStringSync(salsa); - - await expectLater( - encrypted_file.read(path: path(), password: 'user-pass'), - throwsLegacyDecryptError, - ); - expect(File(path()).readAsStringSync(), salsa); - }); - - test('corrupt non-base64 file does not leak _readLegacy errors', () async { - File(path()).writeAsStringSync('not-valid-base64!!!'); - - await expectLater( - encrypted_file.read(path: path(), password: generateKey()), - throwsLegacyDecryptError, - ); - expect(File(path()).readAsStringSync(), 'not-valid-base64!!!'); - }); - - test('invalid UTF-8 legacy bytes do not leak _readLegacy errors', () async { - File(path()).writeAsBytesSync(const [0x00, 0xFF, 0xFE, 0x01]); - - await expectLater( - encrypted_file.read(path: path(), password: generateKey()), - throwsLegacyDecryptError, - ); - expect(File(path()).readAsBytesSync(), const [0x00, 0xFF, 0xFE, 0x01]); - }); - - test('rejects Salsa20 plaintext that does not start with {"', () async { - final password = generateKey(); - File(path()).writeAsStringSync(_salsa20Encrypt(password, 'not-json-payload')); - - await expectLater( - encrypted_file.read(path: path(), password: password), - throwsLegacyDecryptError, - ); - expect(File(path()).readAsBytesSync().first, isNot(cwb.highEntropyVersion)); - expect(File(path()).readAsBytesSync().first, isNot(cwb.lowEntropyVersion)); - }); - - test('does not re-encrypt Salsa20 data that starts with {" but is not JSON', () async { - final password = generateKey(); - const garbage = '{"not valid json'; - File(path()).writeAsStringSync(_salsa20Encrypt(password, garbage)); - - expect(await encrypted_file.read(path: path(), password: password), garbage); - expect(File(path()).readAsBytesSync().first, isNot(cwb.highEntropyVersion)); - expect(File(path()).readAsBytesSync().first, isNot(cwb.lowEntropyVersion)); - }); - - test( - 'wrong password that decrypts to {" does not rewrite the file', - () async { - final password = generateKey(); - final salsa = _salsa20Encrypt(password, walletJson); - File(path()).writeAsStringSync(salsa); - - final collision = _findWrongPasswordWithJsonObjectPrefix(salsa); - expect(collision, isNot(password)); - expect(_salsa20Decrypt(collision, salsa).startsWith('{"'), isTrue); - expect(() => json.decode(_salsa20Decrypt(collision, salsa)), throwsA(anything)); - - final result = await encrypted_file.read(path: path(), password: collision); - - expect(result.startsWith('{"'), isTrue); - expect(result, isNot(walletJson)); - expect(File(path()).readAsStringSync(), salsa); - }, - ); - }); - - group('legacy Linux XChaCha20 Latin-1 payloads', () { - test('decodes files stored as one byte per UTF-16 code unit', () async { - final password = generateKey(); - const data = '{"name":"Café","mnemonic":"abandon"}'; - // Old XChaCha20EncryptionFileUtils used String.codeUnits instead of utf8.encode. - final encrypted = await cwb.encrypt( - password, - Uint8List.fromList(data.codeUnits), - highEntropyPassphrase: true, - ); - File(path()).writeAsBytesSync(encrypted); - - expect(await encrypted_file.read(path: path(), password: password), data); - }); - }); - - group('generateKey', () { - test('produces unique passwords that still encrypt and decrypt', () async { - final a = generateKey(); - final b = generateKey(); - expect(a, isNot(b)); - expect(a.length, greaterThan(12)); - - await encrypted_file.write( - path: path(), - password: a, - data: walletJson, - highEntropyPassphrase: true, - ); - expect(await encrypted_file.read(path: path(), password: a), walletJson); - }); - }); -} - -final throwsLegacyDecryptError = throwsA( - isA().having( - (e) => e.toString(), - 'message', - contains('Failed to decrypt legacy file'), - ), -); - -({encrypt.Key key, encrypt.IV iv}) _salsa20Keys(String password) { - const ivEncodedStringLength = 12; - return ( - key: encrypt.Key.fromBase64(password.substring(0, password.length - ivEncodedStringLength)), - iv: encrypt.IV.fromBase64(password.substring(password.length - ivEncodedStringLength)), - ); -} - -encrypt.Encrypter _salsa20(String password) { - final keys = _salsa20Keys(password); - return encrypt.Encrypter(encrypt.Salsa20(keys.key)); -} - -String _salsa20Encrypt(String password, String data) { - final keys = _salsa20Keys(password); - return _salsa20(password).encrypt(data, iv: keys.iv).base64; -} - -String _salsa20Decrypt(String password, String data) { - final keys = _salsa20Keys(password); - return _salsa20(password).decrypt64(data, iv: keys.iv); -} - -List _salsa20DecryptBytes(String password, String data) { - final keys = _salsa20Keys(password); - return _salsa20(password).decryptBytes(encrypt.Encrypted.fromBase64(data), iv: keys.iv); -} - -String _passwordFromNonce(int nonce) { - final ivBytes = Uint8List(8); - ivBytes.buffer.asByteData().setUint64(0, nonce, Endian.little); - return encrypt.Key(Uint8List(32)).base64 + encrypt.IV(ivBytes).base64; -} - -/// Salsa20 has no MAC, so a wrong key decrypts to garbage. The first two bytes -/// are `{"` about once in 2^16 tries; keep going until that happens, then skip -/// the much rarer case where the garbage is also valid JSON (that would rewrite). -String _findWrongPasswordWithJsonObjectPrefix(String ciphertext) { - const maxAttempts = 1 << 20; - for (var nonce = 0; nonce < maxAttempts; nonce++) { - final candidate = _passwordFromNonce(nonce); - final bytes = _salsa20DecryptBytes(candidate, ciphertext); - if (bytes.length < 2 || bytes[0] != 0x7b || bytes[1] != 0x22) { - continue; - } - try { - json.decode(_salsa20Decrypt(candidate, ciphertext)); - } catch (_) { - return candidate; - } - } - fail('no Salsa20 {" prefix collision in $maxAttempts attempts'); -} diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index 1c71ce11e..f428b354d 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -55,7 +55,7 @@ import 'package:cw_core/pathForWallet.dart'; import 'package:cw_core/sync_status.dart'; import 'package:cw_core/transaction_history.dart'; import 'package:cw_core/transaction_info.dart'; -import 'package:cw_core/encryption_file_utils.dart'; +import 'package:cw_core/utils/file.dart'; import 'package:cw_core/utils/print_verbose.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_info.dart'; @@ -1515,8 +1515,7 @@ abstract class DashboardViewModelBase with Store { if (walletInfo.type == WalletType.bitcoin) { final password = await keyService.getWalletPassword(walletName: walletInfo.name); final path = await pathForWallet(name: walletInfo.name, type: walletInfo.type); - final encryption = encryptionFileUtilsFor(SettingsStoreBase.walletPasswordDirectInput); - final jsonSource = await encryption.read(path: path, password: password); + final jsonSource = await read(path: path, password: password); final data = json.decode(jsonSource) as Map; final mnemonic = data['mnemonic'] as String?; diff --git a/pubspec.lock b/pubspec.lock index 4cd50bf71..f37ff20e8 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -388,8 +388,8 @@ packages: dependency: "direct main" description: path: "." - ref: b5d86a2a21e1c186cd0baa4df1f3a4f3f9413056 - resolved-ref: b5d86a2a21e1c186cd0baa4df1f3a4f3f9413056 + ref: "3aba867dcab6737f6707782f5db15d71f303db38" + resolved-ref: "3aba867dcab6737f6707782f5db15d71f303db38" url: "https://github.com/cake-tech/cake_backup.git" source: git version: "1.0.0+1" diff --git a/pubspec_base.yaml b/pubspec_base.yaml index 52a41ad6f..e8c75f95e 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -85,7 +85,7 @@ dependencies: cake_backup: git: url: https://github.com/cake-tech/cake_backup.git - ref: b5d86a2a21e1c186cd0baa4df1f3a4f3f9413056 + ref: 3aba867dcab6737f6707782f5db15d71f303db38 flutter_plugin_android_lifecycle: 2.0.23 path_provider_android: ^2.2.1 shared_preferences_android: ^2.4.8 @@ -247,7 +247,7 @@ dev_dependencies: # cake_backup: # git: # url: https://github.com/cake-tech/cake_backup.git -# ref: b5d86a2a21e1c186cd0baa4df1f3a4f3f9413056 +# ref: 3aba867dcab6737f6707782f5db15d71f303db38 flutter_icons: image_path: "assets/images/app_logo.png" diff --git a/pubspec_overrides.yaml b/pubspec_overrides.yaml index 2bf9d2ce1..15910a4f2 100644 --- a/pubspec_overrides.yaml +++ b/pubspec_overrides.yaml @@ -174,7 +174,7 @@ dependency_overrides: cake_backup: git: url: https://github.com/cake-tech/cake_backup.git - ref: b5d86a2a21e1c186cd0baa4df1f3a4f3f9413056 + ref: 3aba867dcab6737f6707782f5db15d71f303db38 characters: git: url: https://github.com/dart-lang/core