mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-11-16 17:27:37 +00:00
CW-599-Extract-Secure-Storage (#1353)
* feat: Modify app to depend on secure storage abstraction instead of the direct package * chore: Revert command * Update configure.dart [skip ci] * Update configure.dart * Fix conflicts * clean up and fixes * minor fix --------- Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
This commit is contained in:
parent
c35929f28e
commit
bfb78eded9
23 changed files with 259 additions and 199 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -156,6 +156,7 @@ assets/images/app_logo.png
|
||||||
macos/Runner/Info.plist
|
macos/Runner/Info.plist
|
||||||
macos/Runner/DebugProfile.entitlements
|
macos/Runner/DebugProfile.entitlements
|
||||||
macos/Runner/Release.entitlements
|
macos/Runner/Release.entitlements
|
||||||
|
lib/core/secure_storage.dart
|
||||||
|
|
||||||
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
|
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
|
||||||
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
|
macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:cake_wallet/core/secure_storage.dart';
|
import 'package:cake_wallet/core/secure_storage.dart';
|
||||||
import 'package:cake_wallet/core/totp_request_details.dart';
|
import 'package:cake_wallet/core/totp_request_details.dart';
|
||||||
|
@ -7,7 +6,6 @@ import 'package:cake_wallet/routes.dart';
|
||||||
import 'package:cake_wallet/src/screens/auth/auth_page.dart';
|
import 'package:cake_wallet/src/screens/auth/auth_page.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:cake_wallet/entities/preferences_key.dart';
|
import 'package:cake_wallet/entities/preferences_key.dart';
|
||||||
import 'package:cake_wallet/entities/secret_store_key.dart';
|
import 'package:cake_wallet/entities/secret_store_key.dart';
|
||||||
|
@ -35,14 +33,14 @@ class AuthService with Store {
|
||||||
Routes.restoreOptions,
|
Routes.restoreOptions,
|
||||||
];
|
];
|
||||||
|
|
||||||
final FlutterSecureStorage secureStorage;
|
final SecureStorage secureStorage;
|
||||||
final SharedPreferences sharedPreferences;
|
final SharedPreferences sharedPreferences;
|
||||||
final SettingsStore settingsStore;
|
final SettingsStore settingsStore;
|
||||||
|
|
||||||
Future<void> setPassword(String password) async {
|
Future<void> setPassword(String password) async {
|
||||||
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
|
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
|
||||||
final encodedPassword = encodedPinCode(pin: password);
|
final encodedPassword = encodedPinCode(pin: password);
|
||||||
await writeSecureStorage(secureStorage, key: key, value: encodedPassword);
|
await secureStorage.write(key: key, value: encodedPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> canAuthenticate() async {
|
Future<bool> canAuthenticate() async {
|
||||||
|
@ -61,7 +59,7 @@ class AuthService with Store {
|
||||||
|
|
||||||
Future<bool> authenticate(String pin) async {
|
Future<bool> authenticate(String pin) async {
|
||||||
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
|
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
|
||||||
final encodedPin = await readSecureStorage(secureStorage, key);
|
final encodedPin = await secureStorage.read(key: key);
|
||||||
final decodedPin = decodedPinCode(pin: encodedPin!);
|
final decodedPin = decodedPinCode(pin: encodedPin!);
|
||||||
|
|
||||||
return decodedPin == pin;
|
return decodedPin == pin;
|
||||||
|
@ -69,11 +67,7 @@ class AuthService with Store {
|
||||||
|
|
||||||
void saveLastAuthTime() {
|
void saveLastAuthTime() {
|
||||||
int timestamp = DateTime.now().millisecondsSinceEpoch;
|
int timestamp = DateTime.now().millisecondsSinceEpoch;
|
||||||
writeSecureStorage(
|
secureStorage.write(key: SecureKey.lastAuthTimeMilliseconds, value: timestamp.toString());
|
||||||
secureStorage,
|
|
||||||
key: SecureKey.lastAuthTimeMilliseconds,
|
|
||||||
value: timestamp.toString(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> requireAuth() async {
|
Future<bool> requireAuth() async {
|
||||||
|
|
|
@ -7,7 +7,6 @@ import 'package:cake_wallet/utils/device_info.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:cryptography/cryptography.dart';
|
import 'package:cryptography/cryptography.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
@ -25,7 +24,7 @@ import 'package:cake_backup/backup.dart' as cake_backup;
|
||||||
|
|
||||||
class BackupService {
|
class BackupService {
|
||||||
BackupService(
|
BackupService(
|
||||||
this._flutterSecureStorage, this._walletInfoSource, this._keyService, this._sharedPreferences)
|
this._secureStorage, this._walletInfoSource, this._keyService, this._sharedPreferences)
|
||||||
: _cipher = Cryptography.instance.chacha20Poly1305Aead(),
|
: _cipher = Cryptography.instance.chacha20Poly1305Aead(),
|
||||||
_correctWallets = <WalletInfo>[];
|
_correctWallets = <WalletInfo>[];
|
||||||
|
|
||||||
|
@ -35,7 +34,7 @@ class BackupService {
|
||||||
static const _v2 = 2;
|
static const _v2 = 2;
|
||||||
|
|
||||||
final Cipher _cipher;
|
final Cipher _cipher;
|
||||||
final FlutterSecureStorage _flutterSecureStorage;
|
final SecureStorage _secureStorage;
|
||||||
final SharedPreferences _sharedPreferences;
|
final SharedPreferences _sharedPreferences;
|
||||||
final Box<WalletInfo> _walletInfoSource;
|
final Box<WalletInfo> _walletInfoSource;
|
||||||
final KeyService _keyService;
|
final KeyService _keyService;
|
||||||
|
@ -374,15 +373,14 @@ class BackupService {
|
||||||
final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
|
final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
|
||||||
final backupPassword = keychainJSON[backupPasswordKey] as String;
|
final backupPassword = keychainJSON[backupPasswordKey] as String;
|
||||||
|
|
||||||
await writeSecureStorage(_flutterSecureStorage, key: backupPasswordKey, value: backupPassword);
|
await _secureStorage.write(key: backupPasswordKey, value: backupPassword);
|
||||||
|
|
||||||
keychainWalletsInfo.forEach((dynamic rawInfo) async {
|
keychainWalletsInfo.forEach((dynamic rawInfo) async {
|
||||||
final info = rawInfo as Map<String, dynamic>;
|
final info = rawInfo as Map<String, dynamic>;
|
||||||
await importWalletKeychainInfo(info);
|
await importWalletKeychainInfo(info);
|
||||||
});
|
});
|
||||||
|
|
||||||
await writeSecureStorage(_flutterSecureStorage,
|
await _secureStorage.write(key: pinCodeKey, value: encodedPinCode(pin: decodedPin));
|
||||||
key: pinCodeKey, value: encodedPinCode(pin: decodedPin));
|
|
||||||
|
|
||||||
keychainDumpFile.deleteSync();
|
keychainDumpFile.deleteSync();
|
||||||
}
|
}
|
||||||
|
@ -401,15 +399,14 @@ class BackupService {
|
||||||
final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
|
final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
|
||||||
final backupPassword = keychainJSON[backupPasswordKey] as String;
|
final backupPassword = keychainJSON[backupPasswordKey] as String;
|
||||||
|
|
||||||
await writeSecureStorage(_flutterSecureStorage, key: backupPasswordKey, value: backupPassword);
|
await _secureStorage.write(key: backupPasswordKey, value: backupPassword);
|
||||||
|
|
||||||
keychainWalletsInfo.forEach((dynamic rawInfo) async {
|
keychainWalletsInfo.forEach((dynamic rawInfo) async {
|
||||||
final info = rawInfo as Map<String, dynamic>;
|
final info = rawInfo as Map<String, dynamic>;
|
||||||
await importWalletKeychainInfo(info);
|
await importWalletKeychainInfo(info);
|
||||||
});
|
});
|
||||||
|
|
||||||
await writeSecureStorage(_flutterSecureStorage,
|
await _secureStorage.write(key: pinCodeKey, value: encodedPinCode(pin: decodedPin));
|
||||||
key: pinCodeKey, value: encodedPinCode(pin: decodedPin));
|
|
||||||
|
|
||||||
keychainDumpFile.deleteSync();
|
keychainDumpFile.deleteSync();
|
||||||
}
|
}
|
||||||
|
@ -429,7 +426,7 @@ class BackupService {
|
||||||
Future<Uint8List> _exportKeychainDumpV2(String password,
|
Future<Uint8List> _exportKeychainDumpV2(String password,
|
||||||
{String keychainSalt = secrets.backupKeychainSalt}) async {
|
{String keychainSalt = secrets.backupKeychainSalt}) async {
|
||||||
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
|
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
|
||||||
final encodedPin = await _flutterSecureStorage.read(key: key);
|
final encodedPin = await _secureStorage.read(key: key);
|
||||||
final decodedPin = decodedPinCode(pin: encodedPin!);
|
final decodedPin = decodedPinCode(pin: encodedPin!);
|
||||||
final wallets = await Future.wait(_walletInfoSource.values.map((walletInfo) async {
|
final wallets = await Future.wait(_walletInfoSource.values.map((walletInfo) async {
|
||||||
return {
|
return {
|
||||||
|
@ -439,7 +436,7 @@ class BackupService {
|
||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
|
final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
|
||||||
final backupPassword = await _flutterSecureStorage.read(key: backupPasswordKey);
|
final backupPassword = await _secureStorage.read(key: backupPasswordKey);
|
||||||
final data = utf8.encode(
|
final data = utf8.encode(
|
||||||
json.encode({'pin': decodedPin, 'wallets': wallets, backupPasswordKey: backupPassword}));
|
json.encode({'pin': decodedPin, 'wallets': wallets, backupPasswordKey: backupPassword}));
|
||||||
final encrypted = await _encryptV2(Uint8List.fromList(data), '$keychainSalt$password');
|
final encrypted = await _encryptV2(Uint8List.fromList(data), '$keychainSalt$password');
|
||||||
|
|
|
@ -1,31 +1,30 @@
|
||||||
import 'package:cake_wallet/core/secure_storage.dart';
|
import 'package:cake_wallet/core/secure_storage.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
||||||
import 'package:cake_wallet/entities/secret_store_key.dart';
|
import 'package:cake_wallet/entities/secret_store_key.dart';
|
||||||
import 'package:cake_wallet/entities/encrypt.dart';
|
import 'package:cake_wallet/entities/encrypt.dart';
|
||||||
|
|
||||||
class KeyService {
|
class KeyService {
|
||||||
KeyService(this._secureStorage);
|
KeyService(this._secureStorage);
|
||||||
|
|
||||||
final FlutterSecureStorage _secureStorage;
|
final SecureStorage _secureStorage;
|
||||||
|
|
||||||
Future<String> getWalletPassword({required String walletName}) async {
|
Future<String> getWalletPassword({required String walletName}) async {
|
||||||
final key = generateStoreKeyFor(
|
final key =
|
||||||
key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
|
generateStoreKeyFor(key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
|
||||||
final encodedPassword = await readSecureStorage(_secureStorage, key);
|
final encodedPassword = await _secureStorage.read(key: key);
|
||||||
return decodeWalletPassword(password: encodedPassword!);
|
return decodeWalletPassword(password: encodedPassword!);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> saveWalletPassword({required String walletName, required String password}) async {
|
Future<void> saveWalletPassword({required String walletName, required String password}) async {
|
||||||
final key = generateStoreKeyFor(
|
final key =
|
||||||
key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
|
generateStoreKeyFor(key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
|
||||||
final encodedPassword = encodeWalletPassword(password: password);
|
final encodedPassword = encodeWalletPassword(password: password);
|
||||||
|
|
||||||
await writeSecureStorage(_secureStorage, key: key, value: encodedPassword);
|
await _secureStorage.write(key: key, value: encodedPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteWalletPassword({required String walletName}) async {
|
Future<void> deleteWalletPassword({required String walletName}) async {
|
||||||
final key = generateStoreKeyFor(
|
final key =
|
||||||
key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
|
generateStoreKeyFor(key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
|
||||||
|
|
||||||
await _secureStorage.delete(key: key);
|
await _secureStorage.delete(key: key);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
import 'dart:async';
|
|
||||||
import 'dart:io';
|
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
||||||
// For now, we can create a utility function to handle this.
|
|
||||||
//
|
|
||||||
// However, we could look into abstracting the entire FlutterSecureStorage package
|
|
||||||
// so the app doesn't depend on the package directly but an absraction.
|
|
||||||
// It'll make these kind of modifications to read/write come from a single point.
|
|
||||||
|
|
||||||
Future<String?> readSecureStorage(FlutterSecureStorage secureStorage, String key) async {
|
|
||||||
String? result;
|
|
||||||
const maxWait = Duration(seconds: 3);
|
|
||||||
const checkInterval = Duration(milliseconds: 200);
|
|
||||||
|
|
||||||
DateTime start = DateTime.now();
|
|
||||||
|
|
||||||
while (result == null && DateTime.now().difference(start) < maxWait) {
|
|
||||||
result = await secureStorage.read(key: key);
|
|
||||||
|
|
||||||
if (result != null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
await Future.delayed(checkInterval);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> writeSecureStorage(FlutterSecureStorage secureStorage,
|
|
||||||
{required String key, required String value}) async {
|
|
||||||
// delete the value before writing on macOS because of a weird bug
|
|
||||||
// https://github.com/mogol/flutter_secure_storage/issues/581
|
|
||||||
if (Platform.isMacOS) {
|
|
||||||
await secureStorage.delete(key: key);
|
|
||||||
}
|
|
||||||
await secureStorage.write(key: key, value: value);
|
|
||||||
}
|
|
|
@ -1,8 +1,8 @@
|
||||||
|
import 'package:cake_wallet/core/secure_storage.dart';
|
||||||
import 'package:cake_wallet/di.dart';
|
import 'package:cake_wallet/di.dart';
|
||||||
import 'package:cake_wallet/store/settings_store.dart';
|
import 'package:cake_wallet/store/settings_store.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:cake_wallet/entities/preferences_key.dart';
|
import 'package:cake_wallet/entities/preferences_key.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:cake_wallet/core/key_service.dart';
|
import 'package:cake_wallet/core/key_service.dart';
|
||||||
|
@ -25,7 +25,7 @@ class WalletCreationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
WalletType type;
|
WalletType type;
|
||||||
final FlutterSecureStorage secureStorage;
|
final SecureStorage secureStorage;
|
||||||
final SharedPreferences sharedPreferences;
|
final SharedPreferences sharedPreferences;
|
||||||
final SettingsStore settingsStore;
|
final SettingsStore settingsStore;
|
||||||
final KeyService keyService;
|
final KeyService keyService;
|
||||||
|
|
50
lib/di.dart
50
lib/di.dart
|
@ -236,6 +236,32 @@ import 'package:get_it/get_it.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:cake_wallet/core/secure_storage.dart';
|
||||||
|
import 'package:cake_wallet/core/wallet_creation_service.dart';
|
||||||
|
import 'package:cake_wallet/store/app_store.dart';
|
||||||
|
import 'package:cw_core/wallet_type.dart';
|
||||||
|
import 'package:cake_wallet/view_model/wallet_new_vm.dart';
|
||||||
|
import 'package:cake_wallet/store/authentication_store.dart';
|
||||||
|
import 'package:cake_wallet/store/dashboard/trades_store.dart';
|
||||||
|
import 'package:cake_wallet/store/dashboard/trade_filter_store.dart';
|
||||||
|
import 'package:cake_wallet/store/dashboard/transaction_filter_store.dart';
|
||||||
|
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
|
||||||
|
import 'package:cake_wallet/store/templates/send_template_store.dart';
|
||||||
|
import 'package:cake_wallet/store/templates/exchange_template_store.dart';
|
||||||
|
import 'package:cake_wallet/entities/template.dart';
|
||||||
|
import 'package:cake_wallet/exchange/exchange_template.dart';
|
||||||
|
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||||
|
import 'package:cake_wallet/src/screens/dashboard/pages/address_page.dart';
|
||||||
|
import 'package:cake_wallet/anypay/anypay_api.dart';
|
||||||
|
import 'package:cake_wallet/view_model/ionia/ionia_gift_card_details_view_model.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/ionia/cards/ionia_payment_status_page.dart';
|
||||||
|
import 'package:cake_wallet/view_model/ionia/ionia_payment_status_view_model.dart';
|
||||||
|
import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart';
|
||||||
|
import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/receive/fullscreen_qr_page.dart';
|
||||||
|
import 'package:cake_wallet/core/wallet_loading_service.dart';
|
||||||
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
|
import 'package:cake_wallet/entities/qr_view_data.dart';
|
||||||
|
|
||||||
import 'buy/dfx/dfx_buy_provider.dart';
|
import 'buy/dfx/dfx_buy_provider.dart';
|
||||||
import 'core/totp_request_details.dart';
|
import 'core/totp_request_details.dart';
|
||||||
|
@ -268,7 +294,7 @@ Future<void> setup({
|
||||||
required Box<Order> ordersSource,
|
required Box<Order> ordersSource,
|
||||||
required Box<UnspentCoinsInfo> unspentCoinsInfoSource,
|
required Box<UnspentCoinsInfo> unspentCoinsInfoSource,
|
||||||
required Box<AnonpayInvoiceInfo> anonpayInvoiceInfoSource,
|
required Box<AnonpayInvoiceInfo> anonpayInvoiceInfoSource,
|
||||||
required FlutterSecureStorage secureStorage,
|
required SecureStorage secureStorage,
|
||||||
required GlobalKey<NavigatorState> navigatorKey,
|
required GlobalKey<NavigatorState> navigatorKey,
|
||||||
}) async {
|
}) async {
|
||||||
_walletInfoSource = walletInfoSource;
|
_walletInfoSource = walletInfoSource;
|
||||||
|
@ -285,7 +311,7 @@ Future<void> setup({
|
||||||
|
|
||||||
if (!_isSetupFinished) {
|
if (!_isSetupFinished) {
|
||||||
getIt.registerSingletonAsync<SharedPreferences>(() => SharedPreferences.getInstance());
|
getIt.registerSingletonAsync<SharedPreferences>(() => SharedPreferences.getInstance());
|
||||||
getIt.registerSingleton<FlutterSecureStorage>(secureStorage);
|
getIt.registerSingleton<SecureStorage>(secureStorage);
|
||||||
}
|
}
|
||||||
if (!_isSetupFinished) {
|
if (!_isSetupFinished) {
|
||||||
getIt.registerFactory(() => BackgroundTasks());
|
getIt.registerFactory(() => BackgroundTasks());
|
||||||
|
@ -333,22 +359,22 @@ Future<void> setup({
|
||||||
getIt.registerSingleton<ExchangeTemplateStore>(
|
getIt.registerSingleton<ExchangeTemplateStore>(
|
||||||
ExchangeTemplateStore(templateSource: _exchangeTemplates));
|
ExchangeTemplateStore(templateSource: _exchangeTemplates));
|
||||||
getIt.registerSingleton<YatStore>(
|
getIt.registerSingleton<YatStore>(
|
||||||
YatStore(appStore: getIt.get<AppStore>(), secureStorage: getIt.get<FlutterSecureStorage>())
|
YatStore(appStore: getIt.get<AppStore>(), secureStorage: getIt.get<SecureStorage>())
|
||||||
..init());
|
..init());
|
||||||
getIt.registerSingleton<AnonpayTransactionsStore>(
|
getIt.registerSingleton<AnonpayTransactionsStore>(
|
||||||
AnonpayTransactionsStore(anonpayInvoiceInfoSource: _anonpayInvoiceInfoSource));
|
AnonpayTransactionsStore(anonpayInvoiceInfoSource: _anonpayInvoiceInfoSource));
|
||||||
|
|
||||||
final secretStore = await SecretStoreBase.load(getIt.get<FlutterSecureStorage>());
|
final secretStore = await SecretStoreBase.load(getIt.get<SecureStorage>());
|
||||||
|
|
||||||
getIt.registerSingleton<SecretStore>(secretStore);
|
getIt.registerSingleton<SecretStore>(secretStore);
|
||||||
|
|
||||||
getIt.registerFactory<KeyService>(() => KeyService(getIt.get<FlutterSecureStorage>()));
|
getIt.registerFactory<KeyService>(() => KeyService(getIt.get<SecureStorage>()));
|
||||||
|
|
||||||
getIt.registerFactoryParam<WalletCreationService, WalletType, void>((type, _) =>
|
getIt.registerFactoryParam<WalletCreationService, WalletType, void>((type, _) =>
|
||||||
WalletCreationService(
|
WalletCreationService(
|
||||||
initialType: type,
|
initialType: type,
|
||||||
keyService: getIt.get<KeyService>(),
|
keyService: getIt.get<KeyService>(),
|
||||||
secureStorage: getIt.get<FlutterSecureStorage>(),
|
secureStorage: getIt.get<SecureStorage>(),
|
||||||
sharedPreferences: getIt.get<SharedPreferences>(),
|
sharedPreferences: getIt.get<SharedPreferences>(),
|
||||||
settingsStore: getIt.get<SettingsStore>(),
|
settingsStore: getIt.get<SettingsStore>(),
|
||||||
walletInfoSource: _walletInfoSource));
|
walletInfoSource: _walletInfoSource));
|
||||||
|
@ -403,7 +429,7 @@ Future<void> setup({
|
||||||
|
|
||||||
getIt.registerFactory<AuthService>(
|
getIt.registerFactory<AuthService>(
|
||||||
() => AuthService(
|
() => AuthService(
|
||||||
secureStorage: getIt.get<FlutterSecureStorage>(),
|
secureStorage: getIt.get<SecureStorage>(),
|
||||||
sharedPreferences: getIt.get<SharedPreferences>(),
|
sharedPreferences: getIt.get<SharedPreferences>(),
|
||||||
settingsStore: getIt.get<SettingsStore>(),
|
settingsStore: getIt.get<SettingsStore>(),
|
||||||
),
|
),
|
||||||
|
@ -980,16 +1006,16 @@ Future<void> setup({
|
||||||
trades: _tradesSource,
|
trades: _tradesSource,
|
||||||
settingsStore: getIt.get<SettingsStore>()));
|
settingsStore: getIt.get<SettingsStore>()));
|
||||||
|
|
||||||
getIt.registerFactory(() => BackupService(getIt.get<FlutterSecureStorage>(), _walletInfoSource,
|
getIt.registerFactory(() => BackupService(getIt.get<SecureStorage>(), _walletInfoSource,
|
||||||
getIt.get<KeyService>(), getIt.get<SharedPreferences>()));
|
getIt.get<KeyService>(), getIt.get<SharedPreferences>()));
|
||||||
|
|
||||||
getIt.registerFactory(() => BackupViewModel(
|
getIt.registerFactory(() => BackupViewModel(
|
||||||
getIt.get<FlutterSecureStorage>(), getIt.get<SecretStore>(), getIt.get<BackupService>()));
|
getIt.get<SecureStorage>(), getIt.get<SecretStore>(), getIt.get<BackupService>()));
|
||||||
|
|
||||||
getIt.registerFactory(() => BackupPage(getIt.get<BackupViewModel>()));
|
getIt.registerFactory(() => BackupPage(getIt.get<BackupViewModel>()));
|
||||||
|
|
||||||
getIt.registerFactory(() =>
|
getIt.registerFactory(() =>
|
||||||
EditBackupPasswordViewModel(getIt.get<FlutterSecureStorage>(), getIt.get<SecretStore>()));
|
EditBackupPasswordViewModel(getIt.get<SecureStorage>(), getIt.get<SecretStore>()));
|
||||||
|
|
||||||
getIt.registerFactory(() => EditBackupPasswordPage(getIt.get<EditBackupPasswordViewModel>()));
|
getIt.registerFactory(() => EditBackupPasswordPage(getIt.get<EditBackupPasswordViewModel>()));
|
||||||
|
|
||||||
|
@ -1038,7 +1064,7 @@ Future<void> setup({
|
||||||
getIt.registerFactory(() => SupportPage(getIt.get<SupportViewModel>()));
|
getIt.registerFactory(() => SupportPage(getIt.get<SupportViewModel>()));
|
||||||
|
|
||||||
getIt.registerFactory(() => SupportChatPage(getIt.get<SupportViewModel>(),
|
getIt.registerFactory(() => SupportChatPage(getIt.get<SupportViewModel>(),
|
||||||
secureStorage: getIt.get<FlutterSecureStorage>()));
|
secureStorage: getIt.get<SecureStorage>()));
|
||||||
|
|
||||||
getIt.registerFactory(() => SupportOtherLinksPage(getIt.get<SupportViewModel>()));
|
getIt.registerFactory(() => SupportOtherLinksPage(getIt.get<SupportViewModel>()));
|
||||||
|
|
||||||
|
@ -1080,7 +1106,7 @@ Future<void> setup({
|
||||||
getIt.registerFactory(() => AnyPayApi());
|
getIt.registerFactory(() => AnyPayApi());
|
||||||
|
|
||||||
getIt.registerFactory<IoniaService>(
|
getIt.registerFactory<IoniaService>(
|
||||||
() => IoniaService(getIt.get<FlutterSecureStorage>(), getIt.get<IoniaApi>()));
|
() => IoniaService(getIt.get<SecureStorage>(), getIt.get<IoniaApi>()));
|
||||||
|
|
||||||
getIt.registerFactory<IoniaAnyPay>(() => IoniaAnyPay(
|
getIt.registerFactory<IoniaAnyPay>(() => IoniaAnyPay(
|
||||||
getIt.get<IoniaService>(), getIt.get<AnyPayApi>(), getIt.get<AppStore>().wallet!));
|
getIt.get<IoniaService>(), getIt.get<AnyPayApi>(), getIt.get<AppStore>().wallet!));
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
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/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: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:flutter_secure_storage/flutter_secure_storage.dart';
|
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
@ -42,7 +42,7 @@ const newCakeWalletBitcoinUri = 'btc-electrum.cakewallet.com:50002';
|
||||||
Future<void> defaultSettingsMigration(
|
Future<void> defaultSettingsMigration(
|
||||||
{required int version,
|
{required int version,
|
||||||
required SharedPreferences sharedPreferences,
|
required SharedPreferences sharedPreferences,
|
||||||
required FlutterSecureStorage secureStorage,
|
required SecureStorage secureStorage,
|
||||||
required Box<Node> nodes,
|
required Box<Node> nodes,
|
||||||
required Box<Node> powNodes,
|
required Box<Node> powNodes,
|
||||||
required Box<WalletInfo> walletInfoSource,
|
required Box<WalletInfo> walletInfoSource,
|
||||||
|
@ -485,7 +485,7 @@ Node? getTronDefaultNode({required Box<Node> nodes}) {
|
||||||
|
|
||||||
Future<void> insecureStorageMigration({
|
Future<void> insecureStorageMigration({
|
||||||
required SharedPreferences sharedPreferences,
|
required SharedPreferences sharedPreferences,
|
||||||
required FlutterSecureStorage secureStorage,
|
required SecureStorage secureStorage,
|
||||||
}) async {
|
}) async {
|
||||||
bool? allowBiometricalAuthentication =
|
bool? allowBiometricalAuthentication =
|
||||||
sharedPreferences.getBool(SecureKey.allowBiometricalAuthenticationKey);
|
sharedPreferences.getBool(SecureKey.allowBiometricalAuthenticationKey);
|
||||||
|
@ -559,7 +559,7 @@ Future<void> insecureStorageMigration({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> rewriteSecureStoragePin({required FlutterSecureStorage secureStorage}) async {
|
Future<void> rewriteSecureStoragePin({required SecureStorage secureStorage}) async {
|
||||||
// the bug only affects ios/mac:
|
// the bug only affects ios/mac:
|
||||||
if (!Platform.isIOS && !Platform.isMacOS) {
|
if (!Platform.isIOS && !Platform.isMacOS) {
|
||||||
return;
|
return;
|
||||||
|
@ -585,8 +585,9 @@ Future<void> rewriteSecureStoragePin({required FlutterSecureStorage secureStorag
|
||||||
await secureStorage.write(
|
await secureStorage.write(
|
||||||
key: keyForPinCode,
|
key: keyForPinCode,
|
||||||
value: encodedPin,
|
value: encodedPin,
|
||||||
iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock),
|
// TODO: find a way to add those with the generated secure storage
|
||||||
mOptions: MacOsOptions(accessibility: KeychainAccessibility.first_unlock),
|
// iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock),
|
||||||
|
// mOptions: MacOsOptions(accessibility: KeychainAccessibility.first_unlock),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -720,7 +721,7 @@ Future<void> updateDisplayModes(SharedPreferences sharedPreferences) async {
|
||||||
await sharedPreferences.setInt(PreferencesKey.currentBalanceDisplayModeKey, balanceDisplayMode);
|
await sharedPreferences.setInt(PreferencesKey.currentBalanceDisplayModeKey, balanceDisplayMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> generateBackupPassword(FlutterSecureStorage secureStorage) async {
|
Future<void> generateBackupPassword(SecureStorage secureStorage) async {
|
||||||
final key = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
|
final key = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
|
||||||
|
|
||||||
if ((await secureStorage.read(key: key))?.isNotEmpty ?? false) {
|
if ((await secureStorage.read(key: key))?.isNotEmpty ?? false) {
|
||||||
|
|
|
@ -2,7 +2,6 @@ import 'dart:io';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:cake_wallet/core/secure_storage.dart';
|
import 'package:cake_wallet/core/secure_storage.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
@ -11,8 +10,7 @@ import 'package:cake_wallet/entities/contact.dart';
|
||||||
import 'package:cw_core/crypto_currency.dart';
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
import 'package:cake_wallet/entities/encrypt.dart';
|
import 'package:cake_wallet/entities/encrypt.dart';
|
||||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||||
import 'package:cake_wallet/entities/ios_legacy_helper.dart'
|
import 'package:cake_wallet/entities/ios_legacy_helper.dart' as ios_legacy_helper;
|
||||||
as ios_legacy_helper;
|
|
||||||
import 'package:cake_wallet/entities/preferences_key.dart';
|
import 'package:cake_wallet/entities/preferences_key.dart';
|
||||||
import 'package:cake_wallet/entities/secret_store_key.dart';
|
import 'package:cake_wallet/entities/secret_store_key.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
|
@ -30,8 +28,8 @@ Future<void> migrate_android_v1() async {
|
||||||
await android_migrate_wallets(appDocDir: appDocDir);
|
await android_migrate_wallets(appDocDir: appDocDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> ios_migrate_v1(Box<WalletInfo> walletInfoSource,
|
Future<void> ios_migrate_v1(
|
||||||
Box<Trade> tradeSource, Box<Contact> contactSource) async {
|
Box<WalletInfo> walletInfoSource, Box<Trade> tradeSource, Box<Contact> contactSource) async {
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
|
||||||
if (prefs.getBool('ios_migration_v1_completed') ?? false) {
|
if (prefs.getBool('ios_migration_v1_completed') ?? false) {
|
||||||
|
@ -67,10 +65,7 @@ Future<void> ios_migrate_user_defaults() async {
|
||||||
if (activeCurrency != null) {
|
if (activeCurrency != null) {
|
||||||
final convertedCurrency = convertFiatLegacy(activeCurrency);
|
final convertedCurrency = convertFiatLegacy(activeCurrency);
|
||||||
|
|
||||||
if (convertedCurrency != null) {
|
await prefs.setString('current_fiat_currency', convertedCurrency.serialize());
|
||||||
await prefs.setString(
|
|
||||||
'current_fiat_currency', convertedCurrency.serialize());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//translate fee priority
|
//translate fee priority
|
||||||
|
@ -81,24 +76,21 @@ Future<void> ios_migrate_user_defaults() async {
|
||||||
}
|
}
|
||||||
|
|
||||||
//translate current balance mode
|
//translate current balance mode
|
||||||
final currentBalanceMode =
|
final currentBalanceMode = await ios_legacy_helper.getInt('display_balance_mode');
|
||||||
await ios_legacy_helper.getInt('display_balance_mode');
|
|
||||||
if (currentBalanceMode != null) {
|
if (currentBalanceMode != null) {
|
||||||
await prefs.setInt('current_balance_display_mode', currentBalanceMode);
|
await prefs.setInt('current_balance_display_mode', currentBalanceMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
//translate should save recipient address
|
//translate should save recipient address
|
||||||
final shouldSave =
|
final shouldSave = await ios_legacy_helper.getBool('should_save_recipient_address');
|
||||||
await ios_legacy_helper.getBool('should_save_recipient_address');
|
|
||||||
|
|
||||||
if (shouldSave != null) {
|
if (shouldSave != null) {
|
||||||
await prefs.setBool('save_recipient_address', shouldSave);
|
await prefs.setBool('save_recipient_address', shouldSave);
|
||||||
}
|
}
|
||||||
|
|
||||||
//translate biometric
|
//translate biometric
|
||||||
final biometricOn =
|
final biometricOn = await ios_legacy_helper.getBool('biometric_authentication_on');
|
||||||
await ios_legacy_helper.getBool('biometric_authentication_on');
|
|
||||||
|
|
||||||
if (biometricOn != null) {
|
if (biometricOn != null) {
|
||||||
await prefs.setBool('allow_biometrical_authentication', biometricOn);
|
await prefs.setBool('allow_biometrical_authentication', biometricOn);
|
||||||
}
|
}
|
||||||
|
@ -137,9 +129,8 @@ Future<void> ios_migrate_pin() async {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final flutterSecureStorage = FlutterSecureStorage();
|
final flutterSecureStorage = secureStorageShared;
|
||||||
final pinPassword = await flutterSecureStorage.read(
|
final pinPassword = await flutterSecureStorage.readNoIOptions(key: 'pin_password');
|
||||||
key: 'pin_password', iOptions: IOSOptions());
|
|
||||||
// No pin
|
// No pin
|
||||||
if (pinPassword == null) {
|
if (pinPassword == null) {
|
||||||
await prefs.setBool('ios_migration_pin_completed', true);
|
await prefs.setBool('ios_migration_pin_completed', true);
|
||||||
|
@ -148,7 +139,7 @@ Future<void> ios_migrate_pin() async {
|
||||||
|
|
||||||
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
|
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
|
||||||
final encodedPassword = encodedPinCode(pin: pinPassword);
|
final encodedPassword = encodedPinCode(pin: pinPassword);
|
||||||
await writeSecureStorage(flutterSecureStorage, key: key, value: encodedPassword);
|
await flutterSecureStorage.write(key: key, value: encodedPassword);
|
||||||
|
|
||||||
await prefs.setBool('ios_migration_pin_completed', true);
|
await prefs.setBool('ios_migration_pin_completed', true);
|
||||||
}
|
}
|
||||||
|
@ -161,7 +152,7 @@ Future<void> ios_migrate_wallet_passwords() async {
|
||||||
}
|
}
|
||||||
|
|
||||||
final appDocDir = await getApplicationDocumentsDirectory();
|
final appDocDir = await getApplicationDocumentsDirectory();
|
||||||
final flutterSecureStorage = FlutterSecureStorage();
|
final flutterSecureStorage = secureStorageShared;
|
||||||
final keyService = KeyService(flutterSecureStorage);
|
final keyService = KeyService(flutterSecureStorage);
|
||||||
final walletsDir = Directory('${appDocDir.path}/wallets');
|
final walletsDir = Directory('${appDocDir.path}/wallets');
|
||||||
final moneroWalletsDir = Directory('${walletsDir.path}/monero');
|
final moneroWalletsDir = Directory('${walletsDir.path}/monero');
|
||||||
|
@ -176,10 +167,8 @@ Future<void> ios_migrate_wallet_passwords() async {
|
||||||
if (item is Directory) {
|
if (item is Directory) {
|
||||||
final name = item.path.split('/').last;
|
final name = item.path.split('/').last;
|
||||||
final oldKey = 'wallet_monero_' + name + '_password';
|
final oldKey = 'wallet_monero_' + name + '_password';
|
||||||
final password = await flutterSecureStorage.read(
|
final password = await flutterSecureStorage.readNoIOptions(key: oldKey);
|
||||||
key: oldKey, iOptions: IOSOptions());
|
await keyService.saveWalletPassword(walletName: name, password: password!);
|
||||||
await keyService.saveWalletPassword(
|
|
||||||
walletName: name, password: password!);
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
print(e.toString());
|
||||||
|
@ -311,18 +300,14 @@ Future<void> ios_migrate_wallet_info(Box<WalletInfo> walletsInfoSource) async {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final config = json.decode(configFile.readAsStringSync())
|
final config = json.decode(configFile.readAsStringSync()) as Map<String, dynamic>;
|
||||||
as Map<String, dynamic>;
|
final isRecovery = config['isRecovery'] as bool? ?? false;
|
||||||
final isRecovery = config['isRecovery'] as bool ?? false;
|
|
||||||
final dateAsDouble = config['date'] as double;
|
final dateAsDouble = config['date'] as double;
|
||||||
final timestamp = dateAsDouble.toInt() * 1000;
|
final timestamp = dateAsDouble.toInt() * 1000;
|
||||||
final date = DateTime.fromMillisecondsSinceEpoch(timestamp);
|
final date = DateTime.fromMillisecondsSinceEpoch(timestamp);
|
||||||
final id = walletTypeToString(WalletType.monero).toLowerCase() +
|
final id = walletTypeToString(WalletType.monero).toLowerCase() + '_' + name;
|
||||||
'_' +
|
final exist = walletsInfoSource.values.firstWhereOrNull((el) => el.id == id) != null;
|
||||||
name;
|
|
||||||
final exist = walletsInfoSource.values
|
|
||||||
.firstWhereOrNull((el) => el.id == id) != null;
|
|
||||||
|
|
||||||
if (exist) {
|
if (exist) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -373,12 +358,10 @@ Future<void> ios_migrate_trades_list(Box<Trade> tradeSource) async {
|
||||||
}
|
}
|
||||||
|
|
||||||
final content = file.readAsBytesSync();
|
final content = file.readAsBytesSync();
|
||||||
final flutterSecureStorage = FlutterSecureStorage();
|
final flutterSecureStorage = secureStorageShared;
|
||||||
final masterPassword = await flutterSecureStorage.read(
|
final masterPassword = await flutterSecureStorage.readNoIOptions(key: 'master_password');
|
||||||
key: 'master_password', iOptions: IOSOptions());
|
|
||||||
final key = masterPassword!.replaceAll('-', '');
|
final key = masterPassword!.replaceAll('-', '');
|
||||||
final decoded =
|
final decoded = await ios_legacy_helper.decrypt(content, key: key, salt: secrets.salt);
|
||||||
await ios_legacy_helper.decrypt(content, key: key, salt: secrets.salt);
|
|
||||||
final decodedJson = json.decode(decoded) as List<dynamic>;
|
final decodedJson = json.decode(decoded) as List<dynamic>;
|
||||||
final trades = decodedJson.map((dynamic el) {
|
final trades = decodedJson.map((dynamic el) {
|
||||||
final elAsMap = el as Map<String, dynamic>;
|
final elAsMap = el as Map<String, dynamic>;
|
||||||
|
@ -441,8 +424,7 @@ Future<void> ios_migrate_address_book(Box<Contact> contactSource) async {
|
||||||
final address = _item["address"] as String;
|
final address = _item["address"] as String;
|
||||||
final name = _item["name"] as String;
|
final name = _item["name"] as String;
|
||||||
|
|
||||||
return Contact(
|
return Contact(address: address, name: name, type: CryptoCurrency.fromString(type));
|
||||||
address: address, name: name, type: CryptoCurrency.fromString(type));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await contactSource.addAll(contacts);
|
await contactSource.addAll(contacts);
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import 'package:cake_wallet/core/secure_storage.dart';
|
import 'package:cake_wallet/core/secure_storage.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
||||||
import 'package:cw_core/cake_hive.dart';
|
import 'package:cw_core/cake_hive.dart';
|
||||||
|
|
||||||
Future<List<int>> getEncryptionKey(
|
Future<List<int>> getEncryptionKey(
|
||||||
{required String forKey, required FlutterSecureStorage secureStorage}) async {
|
{required String forKey, required SecureStorage secureStorage}) async {
|
||||||
final stringifiedKey = await secureStorage.read(key: 'transactionDescriptionsBoxKey');
|
final stringifiedKey = await secureStorage.read(key: 'transactionDescriptionsBoxKey');
|
||||||
List<int> key;
|
List<int> key;
|
||||||
|
|
||||||
|
@ -11,7 +10,7 @@ Future<List<int>> getEncryptionKey(
|
||||||
key = CakeHive.generateSecureKey();
|
key = CakeHive.generateSecureKey();
|
||||||
final keyStringified = key.join(',');
|
final keyStringified = key.join(',');
|
||||||
String storageKey = 'transactionDescriptionsBoxKey';
|
String storageKey = 'transactionDescriptionsBoxKey';
|
||||||
await writeSecureStorage(secureStorage, key: storageKey, value: keyStringified);
|
await secureStorage.write(key: storageKey, value: keyStringified);
|
||||||
} else {
|
} else {
|
||||||
key = stringifiedKey.split(',').map((i) => int.parse(i)).toList();
|
key = stringifiedKey.split(',').map((i) => int.parse(i)).toList();
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,9 +61,9 @@ class PreferencesKey {
|
||||||
static const defaultBananoRep = 'default_banano_representative';
|
static const defaultBananoRep = 'default_banano_representative';
|
||||||
static const lookupsTwitter = 'looks_up_twitter';
|
static const lookupsTwitter = 'looks_up_twitter';
|
||||||
static const lookupsMastodon = 'looks_up_mastodon';
|
static const lookupsMastodon = 'looks_up_mastodon';
|
||||||
static const lookupsYatService = 'looks_up_mastodon';
|
static const lookupsYatService = 'looks_up_yat';
|
||||||
static const lookupsUnstoppableDomains = 'looks_up_mastodon';
|
static const lookupsUnstoppableDomains = 'looks_up_unstoppable_domain';
|
||||||
static const lookupsOpenAlias = 'looks_up_mastodon';
|
static const lookupsOpenAlias = 'looks_up_open_alias';
|
||||||
static const lookupsENS = 'looks_up_ens';
|
static const lookupsENS = 'looks_up_ens';
|
||||||
|
|
||||||
static String moneroWalletUpdateV1Key(String name) =>
|
static String moneroWalletUpdateV1Key(String name) =>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:cake_wallet/core/secure_storage.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
enum SecretStoreKey { moneroWalletPassword, pinCodePassword, backupPassword }
|
enum SecretStoreKey { moneroWalletPassword, pinCodePassword, backupPassword }
|
||||||
|
@ -66,7 +66,7 @@ class SecureKey {
|
||||||
static const lastAuthTimeMilliseconds = 'last_auth_time_milliseconds';
|
static const lastAuthTimeMilliseconds = 'last_auth_time_milliseconds';
|
||||||
|
|
||||||
static Future<int?> getInt({
|
static Future<int?> getInt({
|
||||||
required FlutterSecureStorage secureStorage,
|
required SecureStorage secureStorage,
|
||||||
required SharedPreferences sharedPreferences,
|
required SharedPreferences sharedPreferences,
|
||||||
required String key,
|
required String key,
|
||||||
}) async {
|
}) async {
|
||||||
|
@ -76,7 +76,7 @@ class SecureKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<bool?> getBool({
|
static Future<bool?> getBool({
|
||||||
required FlutterSecureStorage secureStorage,
|
required SecureStorage secureStorage,
|
||||||
required SharedPreferences sharedPreferences,
|
required SharedPreferences sharedPreferences,
|
||||||
required String key,
|
required String key,
|
||||||
}) async {
|
}) async {
|
||||||
|
@ -91,7 +91,7 @@ class SecureKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<String?> getString({
|
static Future<String?> getString({
|
||||||
required FlutterSecureStorage secureStorage,
|
required SecureStorage secureStorage,
|
||||||
required SharedPreferences sharedPreferences,
|
required SharedPreferences sharedPreferences,
|
||||||
required String key,
|
required String key,
|
||||||
}) async {
|
}) async {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
import 'package:cake_wallet/core/secure_storage.dart';
|
||||||
import 'package:cake_wallet/ionia/ionia_merchant.dart';
|
import 'package:cake_wallet/ionia/ionia_merchant.dart';
|
||||||
import 'package:cake_wallet/ionia/ionia_order.dart';
|
import 'package:cake_wallet/ionia/ionia_order.dart';
|
||||||
import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
|
import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
||||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||||
import 'package:cake_wallet/ionia/ionia_api.dart';
|
import 'package:cake_wallet/ionia/ionia_api.dart';
|
||||||
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
|
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
|
||||||
|
@ -16,7 +16,7 @@ class IoniaService {
|
||||||
|
|
||||||
static String get clientId => secrets.ioniaClientId;
|
static String get clientId => secrets.ioniaClientId;
|
||||||
|
|
||||||
final FlutterSecureStorage secureStorage;
|
final SecureStorage secureStorage;
|
||||||
final IoniaApi ioniaApi;
|
final IoniaApi ioniaApi;
|
||||||
|
|
||||||
// Create user
|
// Create user
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
|
import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
|
||||||
import 'package:cake_wallet/core/auth_service.dart';
|
import 'package:cake_wallet/core/auth_service.dart';
|
||||||
|
import 'package:cake_wallet/core/secure_storage.dart';
|
||||||
import 'package:cake_wallet/entities/language_service.dart';
|
import 'package:cake_wallet/entities/language_service.dart';
|
||||||
import 'package:cake_wallet/buy/order.dart';
|
import 'package:cake_wallet/buy/order.dart';
|
||||||
import 'package:cake_wallet/locales/locale.dart';
|
import 'package:cake_wallet/locales/locale.dart';
|
||||||
|
@ -18,7 +19,6 @@ import 'package:hive/hive.dart';
|
||||||
import 'package:cake_wallet/di.dart';
|
import 'package:cake_wallet/di.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
||||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||||
import 'package:cake_wallet/themes/theme_base.dart';
|
import 'package:cake_wallet/themes/theme_base.dart';
|
||||||
import 'package:cake_wallet/router.dart' as Router;
|
import 'package:cake_wallet/router.dart' as Router;
|
||||||
|
@ -138,9 +138,8 @@ Future<void> initializeAppConfigs() async {
|
||||||
CakeHive.registerAdapter(AnonpayInvoiceInfoAdapter());
|
CakeHive.registerAdapter(AnonpayInvoiceInfoAdapter());
|
||||||
}
|
}
|
||||||
|
|
||||||
final secureStorage = FlutterSecureStorage(
|
final secureStorage = secureStorageShared;
|
||||||
iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock),
|
|
||||||
);
|
|
||||||
final transactionDescriptionsBoxKey =
|
final transactionDescriptionsBoxKey =
|
||||||
await getEncryptionKey(secureStorage: secureStorage, forKey: TransactionDescription.boxKey);
|
await getEncryptionKey(secureStorage: secureStorage, forKey: TransactionDescription.boxKey);
|
||||||
final tradesBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: Trade.boxKey);
|
final tradesBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: Trade.boxKey);
|
||||||
|
@ -191,7 +190,7 @@ Future<void> initialSetup(
|
||||||
required Box<Template> templates,
|
required Box<Template> templates,
|
||||||
required Box<ExchangeTemplate> exchangeTemplates,
|
required Box<ExchangeTemplate> exchangeTemplates,
|
||||||
required Box<TransactionDescription> transactionDescriptions,
|
required Box<TransactionDescription> transactionDescriptions,
|
||||||
required FlutterSecureStorage secureStorage,
|
required SecureStorage secureStorage,
|
||||||
required Box<AnonpayInvoiceInfo> anonpayInvoiceInfo,
|
required Box<AnonpayInvoiceInfo> anonpayInvoiceInfo,
|
||||||
required Box<UnspentCoinsInfo> unspentCoinsInfoSource,
|
required Box<UnspentCoinsInfo> unspentCoinsInfoSource,
|
||||||
int initialMigrationVersion = 15}) async {
|
int initialMigrationVersion = 15}) async {
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
|
import 'package:cake_wallet/core/secure_storage.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/support_chat/widgets/chatwoot_widget.dart';
|
import 'package:cake_wallet/src/screens/support_chat/widgets/chatwoot_widget.dart';
|
||||||
import 'package:cake_wallet/view_model/support_view_model.dart';
|
import 'package:cake_wallet/view_model/support_view_model.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
||||||
|
|
||||||
|
|
||||||
class SupportChatPage extends BasePage {
|
class SupportChatPage extends BasePage {
|
||||||
SupportChatPage(this.supportViewModel, {required this.secureStorage});
|
SupportChatPage(this.supportViewModel, {required this.secureStorage});
|
||||||
|
|
||||||
final SupportViewModel supportViewModel;
|
final SupportViewModel supportViewModel;
|
||||||
final FlutterSecureStorage secureStorage;
|
final SecureStorage secureStorage;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get title => S.current.settings_support;
|
String get title => S.current.settings_support;
|
||||||
|
|
|
@ -3,14 +3,13 @@ import 'dart:convert';
|
||||||
import 'package:cake_wallet/core/secure_storage.dart';
|
import 'package:cake_wallet/core/secure_storage.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
||||||
|
|
||||||
const COOKIE_KEY = 'chatwootCookie';
|
const COOKIE_KEY = 'chatwootCookie';
|
||||||
|
|
||||||
class ChatwootWidget extends StatefulWidget {
|
class ChatwootWidget extends StatefulWidget {
|
||||||
ChatwootWidget(this.secureStorage, {required this.supportUrl});
|
ChatwootWidget(this.secureStorage, {required this.supportUrl});
|
||||||
|
|
||||||
final FlutterSecureStorage secureStorage;
|
final SecureStorage secureStorage;
|
||||||
final String supportUrl;
|
final String supportUrl;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -59,6 +58,6 @@ class ChatwootWidgetState extends State<ChatwootWidget> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> storeCookie(String value) async {
|
Future<void> storeCookie(String value) async {
|
||||||
await writeSecureStorage(widget.secureStorage, key: COOKIE_KEY, value: value);
|
await widget.secureStorage.write(key: COOKIE_KEY, value: value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
|
import 'package:cake_wallet/core/secure_storage.dart';
|
||||||
import 'package:cake_wallet/entities/secret_store_key.dart';
|
import 'package:cake_wallet/entities/secret_store_key.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
|
|
||||||
part 'secret_store.g.dart';
|
part 'secret_store.g.dart';
|
||||||
|
@ -8,7 +7,7 @@ part 'secret_store.g.dart';
|
||||||
class SecretStore = SecretStoreBase with _$SecretStore;
|
class SecretStore = SecretStoreBase with _$SecretStore;
|
||||||
|
|
||||||
abstract class SecretStoreBase with Store {
|
abstract class SecretStoreBase with Store {
|
||||||
static Future<SecretStore> load(FlutterSecureStorage storage) async {
|
static Future<SecretStore> load(SecureStorage storage) async {
|
||||||
final secretStore = SecretStore();
|
final secretStore = SecretStore();
|
||||||
final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
|
final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
|
||||||
final backupPassword = await storage.read(key: backupPasswordKey);
|
final backupPassword = await storage.read(key: backupPasswordKey);
|
||||||
|
|
|
@ -26,7 +26,6 @@ import 'package:cake_wallet/themes/theme_base.dart';
|
||||||
import 'package:cake_wallet/themes/theme_list.dart';
|
import 'package:cake_wallet/themes/theme_list.dart';
|
||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:package_info/package_info.dart';
|
import 'package:package_info/package_info.dart';
|
||||||
|
@ -48,7 +47,7 @@ class SettingsStore = SettingsStoreBase with _$SettingsStore;
|
||||||
|
|
||||||
abstract class SettingsStoreBase with Store {
|
abstract class SettingsStoreBase with Store {
|
||||||
SettingsStoreBase(
|
SettingsStoreBase(
|
||||||
{required FlutterSecureStorage secureStorage,
|
{required SecureStorage secureStorage,
|
||||||
required BackgroundTasks backgroundTasks,
|
required BackgroundTasks backgroundTasks,
|
||||||
required SharedPreferences sharedPreferences,
|
required SharedPreferences sharedPreferences,
|
||||||
required bool initialShouldShowMarketPlaceInDashboard,
|
required bool initialShouldShowMarketPlaceInDashboard,
|
||||||
|
@ -398,10 +397,8 @@ abstract class SettingsStoreBase with Store {
|
||||||
(bool usePolygonScan) =>
|
(bool usePolygonScan) =>
|
||||||
_sharedPreferences.setBool(PreferencesKey.usePolygonScan, usePolygonScan));
|
_sharedPreferences.setBool(PreferencesKey.usePolygonScan, usePolygonScan));
|
||||||
|
|
||||||
reaction(
|
reaction((_) => useTronGrid,
|
||||||
(_) => useTronGrid,
|
(bool useTronGrid) => _sharedPreferences.setBool(PreferencesKey.useTronGrid, useTronGrid));
|
||||||
(bool useTronGrid) =>
|
|
||||||
_sharedPreferences.setBool(PreferencesKey.useTronGrid, useTronGrid));
|
|
||||||
|
|
||||||
reaction((_) => defaultNanoRep,
|
reaction((_) => defaultNanoRep,
|
||||||
(String nanoRep) => _sharedPreferences.setString(PreferencesKey.defaultNanoRep, nanoRep));
|
(String nanoRep) => _sharedPreferences.setString(PreferencesKey.defaultNanoRep, nanoRep));
|
||||||
|
@ -441,83 +438,79 @@ abstract class SettingsStoreBase with Store {
|
||||||
// secure storage keys:
|
// secure storage keys:
|
||||||
reaction(
|
reaction(
|
||||||
(_) => allowBiometricalAuthentication,
|
(_) => allowBiometricalAuthentication,
|
||||||
(bool biometricalAuthentication) => writeSecureStorage(secureStorage,
|
(bool biometricalAuthentication) => secureStorage.write(
|
||||||
key: SecureKey.allowBiometricalAuthenticationKey,
|
key: SecureKey.allowBiometricalAuthenticationKey,
|
||||||
value: biometricalAuthentication.toString()));
|
value: biometricalAuthentication.toString()));
|
||||||
|
|
||||||
reaction(
|
reaction(
|
||||||
(_) => selectedCake2FAPreset,
|
(_) => selectedCake2FAPreset,
|
||||||
(Cake2FAPresetsOptions selectedCake2FAPreset) => writeSecureStorage(secureStorage,
|
(Cake2FAPresetsOptions selectedCake2FAPreset) => secureStorage.write(
|
||||||
key: SecureKey.selectedCake2FAPreset,
|
key: SecureKey.selectedCake2FAPreset,
|
||||||
value: selectedCake2FAPreset.serialize().toString()));
|
value: selectedCake2FAPreset.serialize().toString()));
|
||||||
|
|
||||||
reaction(
|
reaction(
|
||||||
(_) => shouldRequireTOTP2FAForAccessingWallet,
|
(_) => shouldRequireTOTP2FAForAccessingWallet,
|
||||||
(bool requireTOTP2FAForAccessingWallet) => writeSecureStorage(secureStorage,
|
(bool requireTOTP2FAForAccessingWallet) => secureStorage.write(
|
||||||
key: SecureKey.shouldRequireTOTP2FAForAccessingWallet,
|
key: SecureKey.shouldRequireTOTP2FAForAccessingWallet,
|
||||||
value: requireTOTP2FAForAccessingWallet.toString()));
|
value: requireTOTP2FAForAccessingWallet.toString()));
|
||||||
|
|
||||||
reaction(
|
reaction(
|
||||||
(_) => shouldRequireTOTP2FAForSendsToContact,
|
(_) => shouldRequireTOTP2FAForSendsToContact,
|
||||||
(bool requireTOTP2FAForSendsToContact) => writeSecureStorage(secureStorage,
|
(bool requireTOTP2FAForSendsToContact) => secureStorage.write(
|
||||||
key: SecureKey.shouldRequireTOTP2FAForSendsToContact,
|
key: SecureKey.shouldRequireTOTP2FAForSendsToContact,
|
||||||
value: requireTOTP2FAForSendsToContact.toString()));
|
value: requireTOTP2FAForSendsToContact.toString()));
|
||||||
|
|
||||||
reaction(
|
reaction(
|
||||||
(_) => shouldRequireTOTP2FAForSendsToNonContact,
|
(_) => shouldRequireTOTP2FAForSendsToNonContact,
|
||||||
(bool requireTOTP2FAForSendsToNonContact) => writeSecureStorage(secureStorage,
|
(bool requireTOTP2FAForSendsToNonContact) => secureStorage.write(
|
||||||
key: SecureKey.shouldRequireTOTP2FAForSendsToNonContact,
|
key: SecureKey.shouldRequireTOTP2FAForSendsToNonContact,
|
||||||
value: requireTOTP2FAForSendsToNonContact.toString()));
|
value: requireTOTP2FAForSendsToNonContact.toString()));
|
||||||
|
|
||||||
reaction(
|
reaction(
|
||||||
(_) => shouldRequireTOTP2FAForSendsToInternalWallets,
|
(_) => shouldRequireTOTP2FAForSendsToInternalWallets,
|
||||||
(bool requireTOTP2FAForSendsToInternalWallets) => writeSecureStorage(secureStorage,
|
(bool requireTOTP2FAForSendsToInternalWallets) => secureStorage.write(
|
||||||
key: SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets,
|
key: SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets,
|
||||||
value: requireTOTP2FAForSendsToInternalWallets.toString()));
|
value: requireTOTP2FAForSendsToInternalWallets.toString()));
|
||||||
|
|
||||||
reaction(
|
reaction(
|
||||||
(_) => shouldRequireTOTP2FAForExchangesToInternalWallets,
|
(_) => shouldRequireTOTP2FAForExchangesToInternalWallets,
|
||||||
(bool requireTOTP2FAForExchangesToInternalWallets) => writeSecureStorage(secureStorage,
|
(bool requireTOTP2FAForExchangesToInternalWallets) => secureStorage.write(
|
||||||
key: SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets,
|
key: SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets,
|
||||||
value: requireTOTP2FAForExchangesToInternalWallets.toString()));
|
value: requireTOTP2FAForExchangesToInternalWallets.toString()));
|
||||||
|
|
||||||
reaction(
|
reaction(
|
||||||
(_) => shouldRequireTOTP2FAForExchangesToExternalWallets,
|
(_) => shouldRequireTOTP2FAForExchangesToExternalWallets,
|
||||||
(bool requireTOTP2FAForExchangesToExternalWallets) => writeSecureStorage(secureStorage,
|
(bool requireTOTP2FAForExchangesToExternalWallets) => secureStorage.write(
|
||||||
key: SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets,
|
key: SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets,
|
||||||
value: requireTOTP2FAForExchangesToExternalWallets.toString()));
|
value: requireTOTP2FAForExchangesToExternalWallets.toString()));
|
||||||
|
|
||||||
reaction(
|
reaction(
|
||||||
(_) => shouldRequireTOTP2FAForAddingContacts,
|
(_) => shouldRequireTOTP2FAForAddingContacts,
|
||||||
(bool requireTOTP2FAForAddingContacts) => writeSecureStorage(secureStorage,
|
(bool requireTOTP2FAForAddingContacts) => secureStorage.write(
|
||||||
key: SecureKey.shouldRequireTOTP2FAForAddingContacts,
|
key: SecureKey.shouldRequireTOTP2FAForAddingContacts,
|
||||||
value: requireTOTP2FAForAddingContacts.toString()));
|
value: requireTOTP2FAForAddingContacts.toString()));
|
||||||
|
|
||||||
reaction(
|
reaction(
|
||||||
(_) => shouldRequireTOTP2FAForCreatingNewWallets,
|
(_) => shouldRequireTOTP2FAForCreatingNewWallets,
|
||||||
(bool requireTOTP2FAForCreatingNewWallets) => writeSecureStorage(secureStorage,
|
(bool requireTOTP2FAForCreatingNewWallets) => secureStorage.write(
|
||||||
key: SecureKey.shouldRequireTOTP2FAForCreatingNewWallets,
|
key: SecureKey.shouldRequireTOTP2FAForCreatingNewWallets,
|
||||||
value: requireTOTP2FAForCreatingNewWallets.toString()));
|
value: requireTOTP2FAForCreatingNewWallets.toString()));
|
||||||
|
|
||||||
reaction(
|
reaction(
|
||||||
(_) => shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
|
(_) => shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
|
||||||
(bool requireTOTP2FAForAllSecurityAndBackupSettings) => writeSecureStorage(secureStorage,
|
(bool requireTOTP2FAForAllSecurityAndBackupSettings) => secureStorage.write(
|
||||||
key: SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
|
key: SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
|
||||||
value: requireTOTP2FAForAllSecurityAndBackupSettings.toString()));
|
value: requireTOTP2FAForAllSecurityAndBackupSettings.toString()));
|
||||||
|
|
||||||
reaction(
|
reaction((_) => useTOTP2FA,
|
||||||
(_) => useTOTP2FA,
|
(bool use) => secureStorage.write(key: SecureKey.useTOTP2FA, value: use.toString()));
|
||||||
(bool use) =>
|
|
||||||
writeSecureStorage(secureStorage, key: SecureKey.useTOTP2FA, value: use.toString()));
|
|
||||||
|
|
||||||
reaction(
|
reaction((_) => totpSecretKey,
|
||||||
(_) => totpSecretKey,
|
(String totpKey) => secureStorage.write(key: SecureKey.totpSecretKey, value: totpKey));
|
||||||
(String totpKey) =>
|
|
||||||
writeSecureStorage(secureStorage, key: SecureKey.totpSecretKey, value: totpKey));
|
|
||||||
|
|
||||||
reaction(
|
reaction(
|
||||||
(_) => pinTimeOutDuration,
|
(_) => pinTimeOutDuration,
|
||||||
(PinCodeRequiredDuration pinCodeInterval) => writeSecureStorage(secureStorage,
|
(PinCodeRequiredDuration pinCodeInterval) => secureStorage.write(
|
||||||
key: SecureKey.pinTimeOutDuration, value: pinCodeInterval.value.toString()));
|
key: SecureKey.pinTimeOutDuration, value: pinCodeInterval.value.toString()));
|
||||||
|
|
||||||
reaction(
|
reaction(
|
||||||
|
@ -720,7 +713,7 @@ abstract class SettingsStoreBase with Store {
|
||||||
@observable
|
@observable
|
||||||
int customBitcoinFeeRate;
|
int customBitcoinFeeRate;
|
||||||
|
|
||||||
final FlutterSecureStorage _secureStorage;
|
final SecureStorage _secureStorage;
|
||||||
final SharedPreferences _sharedPreferences;
|
final SharedPreferences _sharedPreferences;
|
||||||
final BackgroundTasks _backgroundTasks;
|
final BackgroundTasks _backgroundTasks;
|
||||||
|
|
||||||
|
@ -763,7 +756,7 @@ abstract class SettingsStoreBase with Store {
|
||||||
BalanceDisplayMode initialBalanceDisplayMode = BalanceDisplayMode.availableBalance,
|
BalanceDisplayMode initialBalanceDisplayMode = BalanceDisplayMode.availableBalance,
|
||||||
ThemeBase? initialTheme}) async {
|
ThemeBase? initialTheme}) async {
|
||||||
final sharedPreferences = await getIt.getAsync<SharedPreferences>();
|
final sharedPreferences = await getIt.getAsync<SharedPreferences>();
|
||||||
final secureStorage = await getIt.get<FlutterSecureStorage>();
|
final secureStorage = await getIt.get<SecureStorage>();
|
||||||
final backgroundTasks = getIt.get<BackgroundTasks>();
|
final backgroundTasks = getIt.get<BackgroundTasks>();
|
||||||
final currentFiatCurrency = FiatCurrency.deserialize(
|
final currentFiatCurrency = FiatCurrency.deserialize(
|
||||||
raw: sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey)!);
|
raw: sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey)!);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:cake_wallet/core/secure_storage.dart';
|
||||||
import 'package:cw_core/transaction_history.dart';
|
import 'package:cw_core/transaction_history.dart';
|
||||||
import 'package:cw_core/wallet_base.dart';
|
import 'package:cw_core/wallet_base.dart';
|
||||||
import 'package:cw_core/balance.dart';
|
import 'package:cw_core/balance.dart';
|
||||||
|
@ -10,7 +11,6 @@ import 'dart:convert';
|
||||||
import 'package:cake_wallet/store/yat/yat_exception.dart';
|
import 'package:cake_wallet/store/yat/yat_exception.dart';
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
||||||
|
|
||||||
part 'yat_store.g.dart';
|
part 'yat_store.g.dart';
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ abstract class YatStoreBase with Store {
|
||||||
|
|
||||||
AppStore appStore;
|
AppStore appStore;
|
||||||
|
|
||||||
FlutterSecureStorage secureStorage;
|
SecureStorage secureStorage;
|
||||||
|
|
||||||
@observable
|
@observable
|
||||||
String emoji;
|
String emoji;
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:cake_wallet/core/backup_service.dart';
|
import 'package:cake_wallet/core/backup_service.dart';
|
||||||
import 'package:cake_wallet/core/execution_state.dart';
|
import 'package:cake_wallet/core/execution_state.dart';
|
||||||
|
import 'package:cake_wallet/core/secure_storage.dart';
|
||||||
import 'package:cake_wallet/entities/secret_store_key.dart';
|
import 'package:cake_wallet/entities/secret_store_key.dart';
|
||||||
import 'package:cake_wallet/store/secret_store.dart';
|
import 'package:cake_wallet/store/secret_store.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:cake_wallet/wallet_type_utils.dart';
|
import 'package:cake_wallet/wallet_type_utils.dart';
|
||||||
|
@ -34,7 +33,7 @@ abstract class BackupViewModelBase with Store {
|
||||||
}, fireImmediately: true);
|
}, fireImmediately: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
final FlutterSecureStorage secureStorage;
|
final SecureStorage secureStorage;
|
||||||
final SecretStore secretStore;
|
final SecretStore secretStore;
|
||||||
final BackupService backupService;
|
final BackupService backupService;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import 'package:cake_wallet/core/secure_storage.dart';
|
import 'package:cake_wallet/core/secure_storage.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
||||||
import 'package:cake_wallet/entities/secret_store_key.dart';
|
import 'package:cake_wallet/entities/secret_store_key.dart';
|
||||||
import 'package:cake_wallet/store/secret_store.dart';
|
import 'package:cake_wallet/store/secret_store.dart';
|
||||||
|
|
||||||
|
@ -14,7 +13,7 @@ abstract class EditBackupPasswordViewModelBase with Store {
|
||||||
: backupPassword = secretStore.read(generateStoreKeyFor(key: SecretStoreKey.backupPassword)),
|
: backupPassword = secretStore.read(generateStoreKeyFor(key: SecretStoreKey.backupPassword)),
|
||||||
_originalPassword = '';
|
_originalPassword = '';
|
||||||
|
|
||||||
final FlutterSecureStorage secureStorage;
|
final SecureStorage secureStorage;
|
||||||
final SecretStore secretStore;
|
final SecretStore secretStore;
|
||||||
|
|
||||||
@observable
|
@observable
|
||||||
|
@ -38,7 +37,7 @@ abstract class EditBackupPasswordViewModelBase with Store {
|
||||||
@action
|
@action
|
||||||
Future<void> save() async {
|
Future<void> save() async {
|
||||||
final key = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
|
final key = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
|
||||||
await writeSecureStorage(secureStorage, key: key, value: backupPassword);
|
await secureStorage.write(key: key, value: backupPassword);
|
||||||
secretStore.write(key: key, value: backupPassword);
|
secretStore.write(key: key, value: backupPassword);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,12 +11,6 @@ dependencies:
|
||||||
ref: cake-4.0.2
|
ref: cake-4.0.2
|
||||||
version: 4.0.2
|
version: 4.0.2
|
||||||
shared_preferences: ^2.0.15
|
shared_preferences: ^2.0.15
|
||||||
flutter_secure_storage:
|
|
||||||
git:
|
|
||||||
url: https://github.com/cake-tech/flutter_secure_storage.git
|
|
||||||
path: flutter_secure_storage
|
|
||||||
ref: cake-9.0.0
|
|
||||||
version: 9.0.0
|
|
||||||
# provider: ^6.0.3
|
# provider: ^6.0.3
|
||||||
rxdart: ^0.27.4
|
rxdart: ^0.27.4
|
||||||
yaml: ^3.1.1
|
yaml: ^3.1.1
|
||||||
|
|
|
@ -10,6 +10,7 @@ const polygonOutputPath = 'lib/polygon/polygon.dart';
|
||||||
const solanaOutputPath = 'lib/solana/solana.dart';
|
const solanaOutputPath = 'lib/solana/solana.dart';
|
||||||
const tronOutputPath = 'lib/tron/tron.dart';
|
const tronOutputPath = 'lib/tron/tron.dart';
|
||||||
const walletTypesPath = 'lib/wallet_types.g.dart';
|
const walletTypesPath = 'lib/wallet_types.g.dart';
|
||||||
|
const secureStoragePath = 'lib/core/secure_storage.dart';
|
||||||
const pubspecDefaultPath = 'pubspec_default.yaml';
|
const pubspecDefaultPath = 'pubspec_default.yaml';
|
||||||
const pubspecOutputPath = 'pubspec.yaml';
|
const pubspecOutputPath = 'pubspec.yaml';
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ Future<void> main(List<String> args) async {
|
||||||
final hasPolygon = args.contains('${prefix}polygon');
|
final hasPolygon = args.contains('${prefix}polygon');
|
||||||
final hasSolana = args.contains('${prefix}solana');
|
final hasSolana = args.contains('${prefix}solana');
|
||||||
final hasTron = args.contains('${prefix}tron');
|
final hasTron = args.contains('${prefix}tron');
|
||||||
|
final excludeFlutterSecureStorage = args.contains('${prefix}excludeFlutterSecureStorage');
|
||||||
|
|
||||||
await generateBitcoin(hasBitcoin);
|
await generateBitcoin(hasBitcoin);
|
||||||
await generateMonero(hasMonero);
|
await generateMonero(hasMonero);
|
||||||
|
@ -45,6 +47,7 @@ Future<void> main(List<String> args) async {
|
||||||
hasNano: hasNano,
|
hasNano: hasNano,
|
||||||
hasBanano: hasBanano,
|
hasBanano: hasBanano,
|
||||||
hasBitcoinCash: hasBitcoinCash,
|
hasBitcoinCash: hasBitcoinCash,
|
||||||
|
hasFlutterSecureStorage: !excludeFlutterSecureStorage,
|
||||||
hasPolygon: hasPolygon,
|
hasPolygon: hasPolygon,
|
||||||
hasSolana: hasSolana,
|
hasSolana: hasSolana,
|
||||||
hasTron: hasTron,
|
hasTron: hasTron,
|
||||||
|
@ -61,6 +64,7 @@ Future<void> main(List<String> args) async {
|
||||||
hasSolana: hasSolana,
|
hasSolana: hasSolana,
|
||||||
hasTron: hasTron,
|
hasTron: hasTron,
|
||||||
);
|
);
|
||||||
|
await injectSecureStorage(!excludeFlutterSecureStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> generateBitcoin(bool hasImplementation) async {
|
Future<void> generateBitcoin(bool hasImplementation) async {
|
||||||
|
@ -1142,6 +1146,7 @@ Future<void> generatePubspec(
|
||||||
required bool hasNano,
|
required bool hasNano,
|
||||||
required bool hasBanano,
|
required bool hasBanano,
|
||||||
required bool hasBitcoinCash,
|
required bool hasBitcoinCash,
|
||||||
|
required bool hasFlutterSecureStorage,
|
||||||
required bool hasPolygon,
|
required bool hasPolygon,
|
||||||
required bool hasSolana,
|
required bool hasSolana,
|
||||||
required bool hasTron}) async {
|
required bool hasTron}) async {
|
||||||
|
@ -1165,6 +1170,14 @@ Future<void> generatePubspec(
|
||||||
cw_shared_external:
|
cw_shared_external:
|
||||||
path: ./cw_shared_external
|
path: ./cw_shared_external
|
||||||
""";
|
""";
|
||||||
|
const flutterSecureStorage = """
|
||||||
|
flutter_secure_storage:
|
||||||
|
git:
|
||||||
|
url: https://github.com/cake-tech/flutter_secure_storage.git
|
||||||
|
path: flutter_secure_storage
|
||||||
|
ref: cake-9.0.0
|
||||||
|
version: 9.0.0
|
||||||
|
""";
|
||||||
const cwEthereum = """
|
const cwEthereum = """
|
||||||
cw_ethereum:
|
cw_ethereum:
|
||||||
path: ./cw_ethereum
|
path: ./cw_ethereum
|
||||||
|
@ -1246,6 +1259,10 @@ Future<void> generatePubspec(
|
||||||
output += '\n$cwHaven';
|
output += '\n$cwHaven';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasFlutterSecureStorage) {
|
||||||
|
output += '\n$flutterSecureStorage\n';
|
||||||
|
}
|
||||||
|
|
||||||
if (hasEthereum || hasPolygon) {
|
if (hasEthereum || hasPolygon) {
|
||||||
output += '\n$cwEVM';
|
output += '\n$cwEVM';
|
||||||
}
|
}
|
||||||
|
@ -1330,3 +1347,103 @@ Future<void> generateWalletTypes(
|
||||||
outputContent += '];\n';
|
outputContent += '];\n';
|
||||||
await walletTypesFile.writeAsString(outputContent);
|
await walletTypesFile.writeAsString(outputContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> injectSecureStorage(bool hasFlutterSecureStorage) async {
|
||||||
|
const flutterSecureStorageHeader = """
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
|
""";
|
||||||
|
const abstractSecureStorage = """
|
||||||
|
abstract class SecureStorage {
|
||||||
|
Future<String?> read({required String key});
|
||||||
|
Future<void> write({required String key, required String? value});
|
||||||
|
Future<void> delete({required String key});
|
||||||
|
// Legacy
|
||||||
|
Future<String?> readNoIOptions({required String key});
|
||||||
|
}""";
|
||||||
|
const defaultSecureStorage = """
|
||||||
|
class DefaultSecureStorage extends SecureStorage {
|
||||||
|
DefaultSecureStorage._(this._secureStorage);
|
||||||
|
|
||||||
|
factory DefaultSecureStorage() => _instance;
|
||||||
|
|
||||||
|
static final _instance = DefaultSecureStorage._(FlutterSecureStorage(
|
||||||
|
iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock),
|
||||||
|
));
|
||||||
|
|
||||||
|
final FlutterSecureStorage _secureStorage;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<String?> read({required String key}) async => await _readInternal(key, false);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> write({required String key, required String? value}) async {
|
||||||
|
// delete the value before writing on macOS because of a weird bug
|
||||||
|
// https://github.com/mogol/flutter_secure_storage/issues/581
|
||||||
|
if (Platform.isMacOS) {
|
||||||
|
await _secureStorage.delete(key: key);
|
||||||
|
}
|
||||||
|
await _secureStorage.write(key: key, value: value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> delete({required String key}) async => _secureStorage.delete(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<String?> readNoIOptions({required String key}) async => await _readInternal(key, true);
|
||||||
|
|
||||||
|
Future<String?> _readInternal(String key, bool useNoIOptions) async {
|
||||||
|
String? result;
|
||||||
|
|
||||||
|
const maxWait = Duration(seconds: 3);
|
||||||
|
const checkInterval = Duration(milliseconds: 200);
|
||||||
|
|
||||||
|
DateTime start = DateTime.now();
|
||||||
|
|
||||||
|
while (result == null && DateTime.now().difference(start) < maxWait) {
|
||||||
|
result = await _secureStorage.read(
|
||||||
|
key: key,
|
||||||
|
iOptions: useNoIOptions ? IOSOptions() : null,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result != null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Future.delayed(checkInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}""";
|
||||||
|
const fakeSecureStorage = """
|
||||||
|
class FakeSecureStorage extends SecureStorage {
|
||||||
|
@override
|
||||||
|
Future<String?> read({required String key}) async => null;
|
||||||
|
@override
|
||||||
|
Future<void> write({required String key, required String? value}) async {}
|
||||||
|
@override
|
||||||
|
Future<void> delete({required String key}) async {}
|
||||||
|
@override
|
||||||
|
Future<String?> readNoIOptions({required String key}) async => null;
|
||||||
|
}""";
|
||||||
|
final outputFile = File(secureStoragePath);
|
||||||
|
final header = hasFlutterSecureStorage
|
||||||
|
? '${flutterSecureStorageHeader}\n\nfinal SecureStorage secureStorageShared = DefaultSecureStorage();\n'
|
||||||
|
: 'final SecureStorage secureStorageShared = FakeSecureStorage();\n';
|
||||||
|
var output = '';
|
||||||
|
if (outputFile.existsSync()) {
|
||||||
|
await outputFile.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
output += '${header}\n${abstractSecureStorage}\n\n';
|
||||||
|
|
||||||
|
if (hasFlutterSecureStorage) {
|
||||||
|
output += '${defaultSecureStorage}\n';
|
||||||
|
} else {
|
||||||
|
output += '${fakeSecureStorage}\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
await outputFile.writeAsString(output);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue