Merge branch 'main' of https://github.com/cake-tech/cake_wallet into CW-519-tor

This commit is contained in:
fosse 2024-01-22 23:34:24 -05:00
commit 6e0c20ba75
39 changed files with 547 additions and 327 deletions

View file

@ -46,6 +46,8 @@ class DFXBuyProvider extends BuyProvider {
return 'XMR';
case WalletType.ethereum:
return 'ETH';
case WalletType.polygon:
return 'MATIC';
default:
throw Exception("WalletType is not available for DFX ${wallet.type}");
}
@ -61,6 +63,8 @@ class DFXBuyProvider extends BuyProvider {
return 'Monero';
case WalletType.ethereum:
return 'Ethereum';
case WalletType.polygon:
return 'Polygon';
default:
throw Exception("WalletType is not available for DFX ${wallet.type}");
}
@ -141,6 +145,7 @@ class DFXBuyProvider extends BuyProvider {
String getSignature(String message) {
switch (wallet.type) {
case WalletType.ethereum:
case WalletType.polygon:
return wallet.signMessage(message);
case WalletType.monero:
case WalletType.litecoin:

View file

@ -72,11 +72,11 @@ class AuthService with Store {
void saveLastAuthTime() {
int timestamp = DateTime.now().millisecondsSinceEpoch;
sharedPreferences.setInt(PreferencesKey.lastAuthTimeMilliseconds, timestamp);
secureStorage.write(key: SecureKey.lastAuthTimeMilliseconds, value: timestamp.toString());
}
bool requireAuth() {
final timestamp = sharedPreferences.getInt(PreferencesKey.lastAuthTimeMilliseconds);
Future<bool> requireAuth() async {
final timestamp = int.tryParse(await secureStorage.read(key: SecureKey.lastAuthTimeMilliseconds) ?? '0');
final duration = _durationToRequireAuth(timestamp ?? 0);
final requiredPinInterval = settingsStore.pinTimeOutDuration;
@ -100,7 +100,7 @@ class AuthService with Store {
'Either route or onAuthSuccess param must be passed.');
if (!conditionToDetermineIfToUse2FA) {
if (!requireAuth() && !_alwaysAuthenticateRoutes.contains(route)) {
if (!(await requireAuth()) && !_alwaysAuthenticateRoutes.contains(route)) {
if (onAuthSuccess != null) {
onAuthSuccess(true);
} else {

View file

@ -213,8 +213,6 @@ class BackupService {
final defaultBuyProvider = data[PreferencesKey.defaultBuyProvider] as int?;
final currentTransactionPriorityKeyLegacy =
data[PreferencesKey.currentTransactionPriorityKeyLegacy] as int?;
final allowBiometricalAuthentication =
data[PreferencesKey.allowBiometricalAuthenticationKey] as bool?;
final currentBitcoinElectrumSererId =
data[PreferencesKey.currentBitcoinElectrumSererIdKey] as int?;
final currentLanguageCode = data[PreferencesKey.currentLanguageCode] as String?;
@ -229,23 +227,6 @@ class BackupService {
data[PreferencesKey.currentDefaultSettingsMigrationVersion] as int?;
final moneroTransactionPriority = data[PreferencesKey.moneroTransactionPriority] as int?;
final bitcoinTransactionPriority = data[PreferencesKey.bitcoinTransactionPriority] as int?;
final selectedCake2FAPreset = data[PreferencesKey.selectedCake2FAPreset] as int?;
final shouldRequireTOTP2FAForAccessingWallet =
data[PreferencesKey.shouldRequireTOTP2FAForAccessingWallet] as bool?;
final shouldRequireTOTP2FAForSendsToContact =
data[PreferencesKey.shouldRequireTOTP2FAForSendsToContact] as bool?;
final shouldRequireTOTP2FAForSendsToNonContact =
data[PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact] as bool?;
final shouldRequireTOTP2FAForSendsToInternalWallets =
data[PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets] as bool?;
final shouldRequireTOTP2FAForExchangesToInternalWallets =
data[PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets] as bool?;
final shouldRequireTOTP2FAForAddingContacts =
data[PreferencesKey.shouldRequireTOTP2FAForAddingContacts] as bool?;
final shouldRequireTOTP2FAForCreatingNewWallets =
data[PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets] as bool?;
final shouldRequireTOTP2FAForAllSecurityAndBackupSettings =
data[PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings] as bool?;
final sortBalanceTokensBy = data[PreferencesKey.sortBalanceBy] as int?;
final pinNativeTokenAtTop = data[PreferencesKey.pinNativeTokenAtTop] as bool?;
final useEtherscan = data[PreferencesKey.useEtherscan] as bool?;
@ -296,14 +277,7 @@ class BackupService {
if (currentTransactionPriorityKeyLegacy != null)
await _sharedPreferences.setInt(
PreferencesKey.currentTransactionPriorityKeyLegacy, currentTransactionPriorityKeyLegacy);
if (DeviceInfo.instance.isDesktop) {
await _sharedPreferences.setBool(PreferencesKey.allowBiometricalAuthenticationKey, false);
} else if (allowBiometricalAuthentication != null) {
await _sharedPreferences.setBool(
PreferencesKey.allowBiometricalAuthenticationKey, allowBiometricalAuthentication);
}
if (currentBitcoinElectrumSererId != null)
await _sharedPreferences.setInt(
PreferencesKey.currentBitcoinElectrumSererIdKey, currentBitcoinElectrumSererId);
@ -354,43 +328,6 @@ class BackupService {
await _sharedPreferences.setInt(
PreferencesKey.bitcoinTransactionPriority, bitcoinTransactionPriority);
if (selectedCake2FAPreset != null)
await _sharedPreferences.setInt(PreferencesKey.selectedCake2FAPreset, selectedCake2FAPreset);
if (shouldRequireTOTP2FAForAccessingWallet != null)
await _sharedPreferences.setBool(PreferencesKey.shouldRequireTOTP2FAForAccessingWallet,
shouldRequireTOTP2FAForAccessingWallet);
if (shouldRequireTOTP2FAForSendsToContact != null)
await _sharedPreferences.setBool(PreferencesKey.shouldRequireTOTP2FAForSendsToContact,
shouldRequireTOTP2FAForSendsToContact);
if (shouldRequireTOTP2FAForSendsToNonContact != null)
await _sharedPreferences.setBool(PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact,
shouldRequireTOTP2FAForSendsToNonContact);
if (shouldRequireTOTP2FAForSendsToInternalWallets != null)
await _sharedPreferences.setBool(PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets,
shouldRequireTOTP2FAForSendsToInternalWallets);
if (shouldRequireTOTP2FAForExchangesToInternalWallets != null)
await _sharedPreferences.setBool(
PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets,
shouldRequireTOTP2FAForExchangesToInternalWallets);
if (shouldRequireTOTP2FAForAddingContacts != null)
await _sharedPreferences.setBool(PreferencesKey.shouldRequireTOTP2FAForAddingContacts,
shouldRequireTOTP2FAForAddingContacts);
if (shouldRequireTOTP2FAForCreatingNewWallets != null)
await _sharedPreferences.setBool(PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets,
shouldRequireTOTP2FAForCreatingNewWallets);
if (shouldRequireTOTP2FAForAllSecurityAndBackupSettings != null)
await _sharedPreferences.setBool(
PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
shouldRequireTOTP2FAForAllSecurityAndBackupSettings);
if (sortBalanceTokensBy != null)
await _sharedPreferences.setInt(PreferencesKey.sortBalanceBy, sortBalanceTokensBy);
@ -542,8 +479,6 @@ class BackupService {
PreferencesKey.currentPinLength: _sharedPreferences.getInt(PreferencesKey.currentPinLength),
PreferencesKey.currentTransactionPriorityKeyLegacy:
_sharedPreferences.getInt(PreferencesKey.currentTransactionPriorityKeyLegacy),
PreferencesKey.allowBiometricalAuthenticationKey:
_sharedPreferences.getBool(PreferencesKey.allowBiometricalAuthenticationKey),
PreferencesKey.currentBitcoinElectrumSererIdKey:
_sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey),
PreferencesKey.currentLanguageCode:
@ -564,24 +499,6 @@ class BackupService {
_sharedPreferences.getInt(PreferencesKey.currentTorConnectionModeKey),
PreferencesKey.shouldStartTorOnLaunch:
_sharedPreferences.getBool(PreferencesKey.shouldStartTorOnLaunch),
PreferencesKey.selectedCake2FAPreset:
_sharedPreferences.getInt(PreferencesKey.selectedCake2FAPreset),
PreferencesKey.shouldRequireTOTP2FAForAccessingWallet:
_sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForAccessingWallet),
PreferencesKey.shouldRequireTOTP2FAForSendsToContact:
_sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToContact),
PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact:
_sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact),
PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets:
_sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets),
PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets: _sharedPreferences
.getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets),
PreferencesKey.shouldRequireTOTP2FAForAddingContacts:
_sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForAddingContacts),
PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets:
_sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets),
PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings: _sharedPreferences
.getBool(PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings),
PreferencesKey.sortBalanceBy: _sharedPreferences.getInt(PreferencesKey.sortBalanceBy),
PreferencesKey.pinNativeTokenAtTop:
_sharedPreferences.getBool(PreferencesKey.pinNativeTokenAtTop),

View file

@ -278,6 +278,7 @@ Future<void> setup({
if (!_isSetupFinished) {
getIt.registerSingletonAsync<SharedPreferences>(() => SharedPreferences.getInstance());
getIt.registerSingleton<FlutterSecureStorage>(secureStorage);
}
if (!_isSetupFinished) {
getIt.registerFactory(() => BackgroundTasks());
@ -304,7 +305,6 @@ Future<void> setup({
getIt.registerFactory<Box<Node>>(() => _nodeSource);
getIt.registerFactory<Box<Node>>(() => _powNodeSource, instanceName: Node.boxName + "pow");
getIt.registerSingleton<FlutterSecureStorage>(secureStorage);
getIt.registerSingleton(AuthenticationStore());
getIt.registerSingleton<WalletListStore>(WalletListStore());
getIt.registerSingleton(NodeListStoreBase.instance);
@ -727,7 +727,7 @@ Future<void> setup({
getIt.registerSingleton(TorViewModel(getIt.get<SettingsStore>()));
getIt.registerSingleton(ProxyWrapper(settingsStore: getIt.get<SettingsStore>()));
if (DeviceInfo.instance.isMobile && settingsStore.shouldStartTorOnLaunch) {
getIt.get<TorViewModel>().startTor();
}

View file

@ -186,6 +186,10 @@ Future<void> defaultSettingsMigration(
await rewriteSecureStoragePin(secureStorage: secureStorage);
break;
case 26:
await insecureStorageMigration(
secureStorage: secureStorage, sharedPreferences: sharedPreferences);
break;
case 27:
await migrateTorPreferences(sharedPreferences: sharedPreferences);
break;
default:
@ -382,7 +386,6 @@ Node getMoneroDefaultNode({required Box<Node> nodes}) {
}
Future<void> migrateTorPreferences({required SharedPreferences sharedPreferences}) async {
if (sharedPreferences.getInt(PreferencesKey.currentFiatApiModeKey) == 1) {
await sharedPreferences.setInt(PreferencesKey.currentFiatApiModeKey, 0);
}
@ -390,7 +393,82 @@ Future<void> migrateTorPreferences({required SharedPreferences sharedPreferences
if (sharedPreferences.getInt(PreferencesKey.exchangeStatusKey) == 1) {
await sharedPreferences.setInt(PreferencesKey.exchangeStatusKey, 0);
}
}
Future<void> insecureStorageMigration({
required SharedPreferences sharedPreferences,
required FlutterSecureStorage secureStorage,
}) async {
bool? allowBiometricalAuthentication =
sharedPreferences.getBool(SecureKey.allowBiometricalAuthenticationKey);
bool? useTOTP2FA = sharedPreferences.getBool(SecureKey.useTOTP2FA);
bool? shouldRequireTOTP2FAForAccessingWallet =
sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForAccessingWallet);
bool? shouldRequireTOTP2FAForSendsToContact =
sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForSendsToContact);
bool? shouldRequireTOTP2FAForSendsToNonContact =
sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForSendsToNonContact);
bool? shouldRequireTOTP2FAForSendsToInternalWallets =
sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets);
bool? shouldRequireTOTP2FAForExchangesToInternalWallets =
sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets);
bool? shouldRequireTOTP2FAForExchangesToExternalWallets =
sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets);
bool? shouldRequireTOTP2FAForAddingContacts =
sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForAddingContacts);
bool? shouldRequireTOTP2FAForCreatingNewWallets =
sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForCreatingNewWallets);
bool? shouldRequireTOTP2FAForAllSecurityAndBackupSettings =
sharedPreferences.getBool(SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings);
int? selectedCake2FAPreset = sharedPreferences.getInt(SecureKey.selectedCake2FAPreset);
String? totpSecretKey = sharedPreferences.getString(SecureKey.totpSecretKey);
int? pinTimeOutDuration = sharedPreferences.getInt(SecureKey.pinTimeOutDuration);
int? lastAuthTimeMilliseconds = sharedPreferences.getInt(SecureKey.lastAuthTimeMilliseconds);
try {
await secureStorage.write(
key: SecureKey.allowBiometricalAuthenticationKey,
value: allowBiometricalAuthentication.toString());
await secureStorage.write(key: SecureKey.useTOTP2FA, value: useTOTP2FA.toString());
await secureStorage.write(
key: SecureKey.shouldRequireTOTP2FAForAccessingWallet,
value: shouldRequireTOTP2FAForAccessingWallet.toString());
await secureStorage.write(
key: SecureKey.shouldRequireTOTP2FAForSendsToContact,
value: shouldRequireTOTP2FAForSendsToContact.toString());
await secureStorage.write(
key: SecureKey.shouldRequireTOTP2FAForSendsToNonContact,
value: shouldRequireTOTP2FAForSendsToNonContact.toString());
await secureStorage.write(
key: SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets,
value: shouldRequireTOTP2FAForSendsToInternalWallets.toString());
await secureStorage.write(
key: SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets,
value: shouldRequireTOTP2FAForExchangesToInternalWallets.toString());
await secureStorage.write(
key: SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets,
value: shouldRequireTOTP2FAForExchangesToExternalWallets.toString());
await secureStorage.write(
key: SecureKey.shouldRequireTOTP2FAForAddingContacts,
value: shouldRequireTOTP2FAForAddingContacts.toString());
await secureStorage.write(
key: SecureKey.shouldRequireTOTP2FAForCreatingNewWallets,
value: shouldRequireTOTP2FAForCreatingNewWallets.toString());
await secureStorage.write(
key: SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
value: shouldRequireTOTP2FAForAllSecurityAndBackupSettings.toString());
await secureStorage.write(
key: SecureKey.selectedCake2FAPreset, value: selectedCake2FAPreset.toString());
await secureStorage.write(key: SecureKey.totpSecretKey, value: totpSecretKey.toString());
await secureStorage.write(
key: SecureKey.pinTimeOutDuration, value: pinTimeOutDuration.toString());
await secureStorage.write(
key: SecureKey.lastAuthTimeMilliseconds, value: lastAuthTimeMilliseconds.toString());
} catch (e) {
print("Error migrating shared preferences to secure storage!: $e");
// this actually shouldn't be that big of a problem since we don't delete the old keys in this update
// and we read and write to the new locations when loading storage, the migration is just for extra safety
}
}
Future<void> rewriteSecureStoragePin({required FlutterSecureStorage secureStorage}) async {

View file

@ -24,8 +24,7 @@ class PreferencesKey {
static const walletListAscending = 'wallet_list_ascending';
static const currentFiatApiModeKey = 'current_fiat_api_mode';
static const shouldStartTorOnLaunch = 'start_tor_on_launch';
static const allowBiometricalAuthenticationKey = 'allow_biometrical_authentication';
static const useTOTP2FA = 'use_totp_2fa';
static const currentTorConnectionModeKey = 'current_tor_connection_mode';
static const failedTotpTokenTrials = 'failed_token_trials';
static const disableExchangeKey = 'disable_exchange';
static const exchangeStatusKey = 'exchange_status';
@ -34,6 +33,7 @@ class PreferencesKey {
static const displayActionListModeKey = 'display_list_mode';
static const currentPinLength = 'current_pin_length';
static const currentLanguageCode = 'language_code';
static const currentSeedPhraseLength = 'current_seed_phrase_length';
static const currentDefaultSettingsMigrationVersion =
'current_default_settings_migration_version';
static const moneroTransactionPriority = 'current_fee_priority_monero';
@ -48,9 +48,6 @@ class PreferencesKey {
static const moneroWalletPasswordUpdateV1Base = 'monero_wallet_update_v1';
static const syncModeKey = 'sync_mode';
static const syncAllKey = 'sync_all';
static const currentTorConnectionModeKey = 'current_tor_connection_mode';
static const pinTimeOutDuration = 'pin_timeout_duration';
static const lastAuthTimeMilliseconds = 'last_auth_time_milliseconds';
static const lastPopupDate = 'last_popup_date';
static const lastAppReviewDate = 'last_app_review_date';
static const sortBalanceBy = 'sort_balance_by';
@ -77,25 +74,4 @@ class PreferencesKey {
static const lastSeenAppVersion = 'last_seen_app_version';
static const shouldShowMarketPlaceInDashboard = 'should_show_marketplace_in_dashboard';
static const isNewInstall = 'is_new_install';
static const shouldRequireTOTP2FAForAccessingWallet =
'should_require_totp_2fa_for_accessing_wallets';
static const shouldRequireTOTP2FAForSendsToContact =
'should_require_totp_2fa_for_sends_to_contact';
static const shouldRequireTOTP2FAForSendsToNonContact =
'should_require_totp_2fa_for_sends_to_non_contact';
static const shouldRequireTOTP2FAForSendsToInternalWallets =
'should_require_totp_2fa_for_sends_to_internal_wallets';
static const shouldRequireTOTP2FAForExchangesToInternalWallets =
'should_require_totp_2fa_for_exchanges_to_internal_wallets';
static const shouldRequireTOTP2FAForExchangesToExternalWallets =
'should_require_totp_2fa_for_exchanges_to_external_wallets';
static const shouldRequireTOTP2FAForAddingContacts =
'should_require_totp_2fa_for_adding_contacts';
static const shouldRequireTOTP2FAForCreatingNewWallets =
'should_require_totp_2fa_for_creating_new_wallets';
static const shouldRequireTOTP2FAForAllSecurityAndBackupSettings =
'should_require_totp_2fa_for_all_security_and_backup_settings';
static const selectedCake2FAPreset = 'selected_cake_2fa_preset';
static const totpSecretKey = 'totp_secret_key';
static const currentSeedPhraseLength = 'current_seed_phrase_length';
}

View file

@ -65,9 +65,10 @@ class ProvidersHelper {
case WalletType.litecoin:
case WalletType.bitcoinCash:
return [ProviderType.askEachTime, ProviderType.onramper, ProviderType.robinhood];
case WalletType.polygon:
return [ProviderType.askEachTime, ProviderType.dfx];
case WalletType.none:
case WalletType.haven:
case WalletType.polygon:
return [];
}
}
@ -76,17 +77,22 @@ class ProvidersHelper {
switch (walletType) {
case WalletType.bitcoin:
case WalletType.ethereum:
return [ProviderType.askEachTime, ProviderType.onramper,
ProviderType.moonpaySell, ProviderType.dfx];
return [
ProviderType.askEachTime,
ProviderType.onramper,
ProviderType.moonpaySell,
ProviderType.dfx,
];
case WalletType.litecoin:
case WalletType.bitcoinCash:
return [ProviderType.askEachTime, ProviderType.moonpaySell];
case WalletType.polygon:
return [ProviderType.askEachTime, ProviderType.dfx];
case WalletType.monero:
case WalletType.nano:
case WalletType.banano:
case WalletType.none:
case WalletType.haven:
case WalletType.polygon:
return [];
}
}

View file

@ -1,3 +1,6 @@
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:shared_preferences/shared_preferences.dart';
enum SecretStoreKey { moneroWalletPassword, pinCodePassword, backupPassword }
const moneroWalletPassword = "MONERO_WALLET_PASSWORD";
@ -35,3 +38,65 @@ String generateStoreKeyFor({
return _key;
}
class SecureKey {
static const allowBiometricalAuthenticationKey = 'allow_biometrical_authentication';
static const useTOTP2FA = 'use_totp_2fa';
static const shouldRequireTOTP2FAForAccessingWallet =
'should_require_totp_2fa_for_accessing_wallets';
static const shouldRequireTOTP2FAForSendsToContact =
'should_require_totp_2fa_for_sends_to_contact';
static const shouldRequireTOTP2FAForSendsToNonContact =
'should_require_totp_2fa_for_sends_to_non_contact';
static const shouldRequireTOTP2FAForSendsToInternalWallets =
'should_require_totp_2fa_for_sends_to_internal_wallets';
static const shouldRequireTOTP2FAForExchangesToInternalWallets =
'should_require_totp_2fa_for_exchanges_to_internal_wallets';
static const shouldRequireTOTP2FAForExchangesToExternalWallets =
'should_require_totp_2fa_for_exchanges_to_external_wallets';
static const shouldRequireTOTP2FAForAddingContacts =
'should_require_totp_2fa_for_adding_contacts';
static const shouldRequireTOTP2FAForCreatingNewWallets =
'should_require_totp_2fa_for_creating_new_wallets';
static const shouldRequireTOTP2FAForAllSecurityAndBackupSettings =
'should_require_totp_2fa_for_all_security_and_backup_settings';
static const selectedCake2FAPreset = 'selected_cake_2fa_preset';
static const totpSecretKey = 'totp_secret_key';
static const pinTimeOutDuration = 'pin_timeout_duration';
static const lastAuthTimeMilliseconds = 'last_auth_time_milliseconds';
static Future<int?> getInt({
required FlutterSecureStorage secureStorage,
required SharedPreferences sharedPreferences,
required String key,
}) async {
int? value = int.tryParse((await secureStorage.read(key: key) ?? ''));
value ??= sharedPreferences.getInt(key);
return value;
}
static Future<bool?> getBool({
required FlutterSecureStorage secureStorage,
required SharedPreferences sharedPreferences,
required String key,
}) async {
String? value = (await secureStorage.read(key: key) ?? '');
if (value.toLowerCase() == "true") {
return true;
} else if (value.toLowerCase() == "false") {
return false;
} else {
return sharedPreferences.getBool(key);
}
}
static Future<String?> getString({
required FlutterSecureStorage secureStorage,
required SharedPreferences sharedPreferences,
required String key,
}) async {
String? value = await secureStorage.read(key: key);
value ??= sharedPreferences.getString(key);
return value;
}
}

View file

@ -1,12 +1,14 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
import 'package:cake_wallet/src/screens/setup_2fa/widgets/popup_cancellable_alert.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/src/widgets/search_bar_widget.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/wallet_types.g.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
@ -70,7 +72,8 @@ class WalletTypeFormState extends State<WalletTypeForm> {
Widget build(BuildContext context) {
return Center(
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
constraints:
BoxConstraints(maxWidth: ResponsiveLayoutUtilBase.kDesktopMaxWidthConstraint),
child: Column(
children: [
Padding(
@ -128,6 +131,19 @@ class WalletTypeFormState extends State<WalletTypeForm> {
throw Exception('Wallet Type is not selected yet.');
}
if (selected == WalletType.haven) {
return await showPopUp<void>(
context: context,
builder: (BuildContext context) {
return PopUpCancellableAlertDialog(
contentText: S.of(context).pause_wallet_creation,
actionButtonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop(),
);
},
);
}
widget.onTypeSelected(context, selected!);
}
}

View file

@ -53,13 +53,17 @@ class RootState extends State<Root> with WidgetsBindingObserver {
@override
void initState() {
_requestAuth = widget.authService.requireAuth();
WidgetsBinding.instance.addPostFrameCallback((_) async {
bool value = await widget.authService.requireAuth();
setState(() {
_requestAuth = value;
});
});
_isInactiveController = StreamController<bool>.broadcast();
_isInactive = false;
_postFrameCallback = false;
WidgetsBinding.instance.addObserver(this);
super.initState();
if (DeviceInfo.instance.isMobile) {
initUniLinks();
}
@ -105,8 +109,10 @@ class RootState extends State<Root> with WidgetsBindingObserver {
break;
case AppLifecycleState.resumed:
setState(() {
_requestAuth = widget.authService.requireAuth();
widget.authService.requireAuth().then((value) {
setState(() {
_requestAuth = value;
});
});
break;
default:

View file

@ -10,6 +10,7 @@ import 'package:cake_wallet/entities/background_tasks.dart';
import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cake_wallet/entities/pin_code_required_duration.dart';
import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cake_wallet/entities/secret_store_key.dart';
import 'package:cake_wallet/entities/seed_phrase_length.dart';
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/entities/sort_balance_types.dart';
@ -26,6 +27,7 @@ import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/themes/theme_list.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
import 'package:package_info/package_info.dart';
@ -47,7 +49,8 @@ class SettingsStore = SettingsStoreBase with _$SettingsStore;
abstract class SettingsStoreBase with Store {
SettingsStoreBase(
{required BackgroundTasks backgroundTasks,
{required FlutterSecureStorage secureStorage,
required BackgroundTasks backgroundTasks,
required SharedPreferences sharedPreferences,
required bool initialShouldShowMarketPlaceInDashboard,
required FiatCurrency initialFiatCurrency,
@ -114,6 +117,7 @@ abstract class SettingsStoreBase with Store {
TransactionPriority? initialBitcoinCashTransactionPriority})
: nodes = ObservableMap<WalletType, Node>.of(nodes),
powNodes = ObservableMap<WalletType, Node>.of(powNodes),
_secureStorage = secureStorage,
_sharedPreferences = sharedPreferences,
_backgroundTasks = backgroundTasks,
fiatCurrency = initialFiatCurrency,
@ -328,74 +332,6 @@ abstract class SettingsStoreBase with Store {
reaction((_) => currentTheme,
(ThemeBase theme) => sharedPreferences.setInt(PreferencesKey.currentTheme, theme.raw));
reaction(
(_) => allowBiometricalAuthentication,
(bool biometricalAuthentication) => sharedPreferences.setBool(
PreferencesKey.allowBiometricalAuthenticationKey, biometricalAuthentication));
reaction(
(_) => selectedCake2FAPreset,
(Cake2FAPresetsOptions selectedCake2FAPreset) => sharedPreferences.setInt(
PreferencesKey.selectedCake2FAPreset, selectedCake2FAPreset.serialize()));
reaction(
(_) => shouldRequireTOTP2FAForAccessingWallet,
(bool requireTOTP2FAForAccessingWallet) => sharedPreferences.setBool(
PreferencesKey.shouldRequireTOTP2FAForAccessingWallet,
requireTOTP2FAForAccessingWallet));
reaction(
(_) => shouldRequireTOTP2FAForSendsToContact,
(bool requireTOTP2FAForSendsToContact) => sharedPreferences.setBool(
PreferencesKey.shouldRequireTOTP2FAForSendsToContact, requireTOTP2FAForSendsToContact));
reaction(
(_) => shouldRequireTOTP2FAForSendsToNonContact,
(bool requireTOTP2FAForSendsToNonContact) => sharedPreferences.setBool(
PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact,
requireTOTP2FAForSendsToNonContact));
reaction(
(_) => shouldRequireTOTP2FAForSendsToInternalWallets,
(bool requireTOTP2FAForSendsToInternalWallets) => sharedPreferences.setBool(
PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets,
requireTOTP2FAForSendsToInternalWallets));
reaction(
(_) => shouldRequireTOTP2FAForExchangesToInternalWallets,
(bool requireTOTP2FAForExchangesToInternalWallets) => sharedPreferences.setBool(
PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets,
requireTOTP2FAForExchangesToInternalWallets));
reaction(
(_) => shouldRequireTOTP2FAForExchangesToExternalWallets,
(bool requireTOTP2FAForExchangesToExternalWallets) => sharedPreferences.setBool(
PreferencesKey.shouldRequireTOTP2FAForExchangesToExternalWallets,
requireTOTP2FAForExchangesToExternalWallets));
reaction(
(_) => shouldRequireTOTP2FAForAddingContacts,
(bool requireTOTP2FAForAddingContacts) => sharedPreferences.setBool(
PreferencesKey.shouldRequireTOTP2FAForAddingContacts, requireTOTP2FAForAddingContacts));
reaction(
(_) => shouldRequireTOTP2FAForCreatingNewWallets,
(bool requireTOTP2FAForCreatingNewWallets) => sharedPreferences.setBool(
PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets,
requireTOTP2FAForCreatingNewWallets));
reaction(
(_) => shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
(bool requireTOTP2FAForAllSecurityAndBackupSettings) => sharedPreferences.setBool(
PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
requireTOTP2FAForAllSecurityAndBackupSettings));
reaction(
(_) => useTOTP2FA, (bool use) => sharedPreferences.setBool(PreferencesKey.useTOTP2FA, use));
reaction((_) => totpSecretKey,
(String totpKey) => sharedPreferences.setString(PreferencesKey.totpSecretKey, totpKey));
reaction(
(_) => numberOfFailedTokenTrials,
(int failedTokenTrail) =>
@ -419,11 +355,6 @@ abstract class SettingsStoreBase with Store {
(SeedPhraseLength seedPhraseWordCount) => sharedPreferences.setInt(
PreferencesKey.currentSeedPhraseLength, seedPhraseWordCount.value));
reaction(
(_) => pinTimeOutDuration,
(PinCodeRequiredDuration pinCodeInterval) =>
sharedPreferences.setInt(PreferencesKey.pinTimeOutDuration, pinCodeInterval.value));
reaction(
(_) => balanceDisplayMode,
(BalanceDisplayMode mode) => sharedPreferences.setInt(
@ -501,6 +432,84 @@ abstract class SettingsStoreBase with Store {
reaction((_) => lookupsENS,
(bool looksUpENS) => _sharedPreferences.setBool(PreferencesKey.lookupsENS, looksUpENS));
// secure storage keys:
reaction(
(_) => allowBiometricalAuthentication,
(bool biometricalAuthentication) => secureStorage.write(
key: SecureKey.allowBiometricalAuthenticationKey,
value: biometricalAuthentication.toString()));
reaction(
(_) => selectedCake2FAPreset,
(Cake2FAPresetsOptions selectedCake2FAPreset) => secureStorage.write(
key: SecureKey.selectedCake2FAPreset,
value: selectedCake2FAPreset.serialize().toString()));
reaction(
(_) => shouldRequireTOTP2FAForAccessingWallet,
(bool requireTOTP2FAForAccessingWallet) => secureStorage.write(
key: SecureKey.shouldRequireTOTP2FAForAccessingWallet,
value: requireTOTP2FAForAccessingWallet.toString()));
reaction(
(_) => shouldRequireTOTP2FAForSendsToContact,
(bool requireTOTP2FAForSendsToContact) => secureStorage.write(
key: SecureKey.shouldRequireTOTP2FAForSendsToContact,
value: requireTOTP2FAForSendsToContact.toString()));
reaction(
(_) => shouldRequireTOTP2FAForSendsToNonContact,
(bool requireTOTP2FAForSendsToNonContact) => secureStorage.write(
key: SecureKey.shouldRequireTOTP2FAForSendsToNonContact,
value: requireTOTP2FAForSendsToNonContact.toString()));
reaction(
(_) => shouldRequireTOTP2FAForSendsToInternalWallets,
(bool requireTOTP2FAForSendsToInternalWallets) => secureStorage.write(
key: SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets,
value: requireTOTP2FAForSendsToInternalWallets.toString()));
reaction(
(_) => shouldRequireTOTP2FAForExchangesToInternalWallets,
(bool requireTOTP2FAForExchangesToInternalWallets) => secureStorage.write(
key: SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets,
value: requireTOTP2FAForExchangesToInternalWallets.toString()));
reaction(
(_) => shouldRequireTOTP2FAForExchangesToExternalWallets,
(bool requireTOTP2FAForExchangesToExternalWallets) => secureStorage.write(
key: SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets,
value: requireTOTP2FAForExchangesToExternalWallets.toString()));
reaction(
(_) => shouldRequireTOTP2FAForAddingContacts,
(bool requireTOTP2FAForAddingContacts) => secureStorage.write(
key: SecureKey.shouldRequireTOTP2FAForAddingContacts,
value: requireTOTP2FAForAddingContacts.toString()));
reaction(
(_) => shouldRequireTOTP2FAForCreatingNewWallets,
(bool requireTOTP2FAForCreatingNewWallets) => secureStorage.write(
key: SecureKey.shouldRequireTOTP2FAForCreatingNewWallets,
value: requireTOTP2FAForCreatingNewWallets.toString()));
reaction(
(_) => shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
(bool requireTOTP2FAForAllSecurityAndBackupSettings) => secureStorage.write(
key: SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
value: requireTOTP2FAForAllSecurityAndBackupSettings.toString()));
reaction((_) => useTOTP2FA,
(bool use) => secureStorage.write(key: SecureKey.useTOTP2FA, value: use.toString()));
reaction((_) => totpSecretKey,
(String totpKey) => secureStorage.write(key: SecureKey.totpSecretKey, value: totpKey));
reaction(
(_) => pinTimeOutDuration,
(PinCodeRequiredDuration pinCodeInterval) => secureStorage.write(
key: SecureKey.pinTimeOutDuration, value: pinCodeInterval.value.toString()));
this.nodes.observe((change) {
if (change.newValue != null && change.key != null) {
_saveCurrentNode(change.newValue!, change.key!);
@ -690,6 +699,7 @@ abstract class SettingsStoreBase with Store {
String deviceName;
final FlutterSecureStorage _secureStorage;
final SharedPreferences _sharedPreferences;
final BackgroundTasks _backgroundTasks;
@ -732,6 +742,7 @@ abstract class SettingsStoreBase with Store {
BalanceDisplayMode initialBalanceDisplayMode = BalanceDisplayMode.availableBalance,
ThemeBase? initialTheme}) async {
final sharedPreferences = await getIt.getAsync<SharedPreferences>();
final secureStorage = await getIt.get<FlutterSecureStorage>();
final backgroundTasks = getIt.get<BackgroundTasks>();
final currentFiatCurrency = FiatCurrency.deserialize(
raw: sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey)!);
@ -797,36 +808,6 @@ abstract class SettingsStoreBase with Store {
TorConnectionMode.disabled.raw);
final shouldStartTorOnLaunch =
sharedPreferences.getBool(PreferencesKey.shouldStartTorOnLaunch) ?? false;
final allowBiometricalAuthentication =
sharedPreferences.getBool(PreferencesKey.allowBiometricalAuthenticationKey) ?? false;
final selectedCake2FAPreset = Cake2FAPresetsOptions.deserialize(
raw: sharedPreferences.getInt(PreferencesKey.selectedCake2FAPreset) ??
Cake2FAPresetsOptions.normal.raw);
final shouldRequireTOTP2FAForAccessingWallet =
sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForAccessingWallet) ?? false;
final shouldRequireTOTP2FAForSendsToContact =
sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToContact) ?? false;
final shouldRequireTOTP2FAForSendsToNonContact =
sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact) ?? false;
final shouldRequireTOTP2FAForSendsToInternalWallets =
sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets) ??
false;
final shouldRequireTOTP2FAForExchangesToInternalWallets = sharedPreferences
.getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets) ??
false;
final shouldRequireTOTP2FAForExchangesToExternalWallets = sharedPreferences
.getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToExternalWallets) ??
false;
final shouldRequireTOTP2FAForAddingContacts =
sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForAddingContacts) ?? false;
final shouldRequireTOTP2FAForCreatingNewWallets =
sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets) ??
false;
final shouldRequireTOTP2FAForAllSecurityAndBackupSettings = sharedPreferences
.getBool(PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings) ??
false;
final useTOTP2FA = sharedPreferences.getBool(PreferencesKey.useTOTP2FA) ?? false;
final totpSecretKey = sharedPreferences.getString(PreferencesKey.totpSecretKey) ?? '';
final tokenTrialNumber = sharedPreferences.getInt(PreferencesKey.failedTotpTokenTrials) ?? 0;
final shouldShowMarketPlaceInDashboard =
sharedPreferences.getBool(PreferencesKey.shouldShowMarketPlaceInDashboard) ?? true;
@ -843,18 +824,14 @@ abstract class SettingsStoreBase with Store {
actionListDisplayMode.addAll(deserializeActionlistDisplayModes(
sharedPreferences.getInt(PreferencesKey.displayActionListModeKey) ?? defaultActionsMode));
var pinLength = sharedPreferences.getInt(PreferencesKey.currentPinLength);
final timeOutDuration = sharedPreferences.getInt(PreferencesKey.pinTimeOutDuration);
final seedPhraseCount = sharedPreferences.getInt(PreferencesKey.currentSeedPhraseLength);
final pinCodeTimeOutDuration = timeOutDuration != null
? PinCodeRequiredDuration.deserialize(raw: timeOutDuration)
: defaultPinCodeTimeOutDuration;
final seedPhraseWordCount = seedPhraseCount != null
? SeedPhraseLength.deserialize(raw: seedPhraseCount)
: defaultSeedPhraseLength;
final sortBalanceBy =
SortBalanceBy.values[sharedPreferences.getInt(PreferencesKey.sortBalanceBy) ?? 0];
final pinNativeTokenAtTop =
sharedPreferences.getBool(PreferencesKey.pinNativeTokenAtTop) ?? true;
final seedPhraseCount = sharedPreferences.getInt(PreferencesKey.currentSeedPhraseLength);
final seedPhraseWordCount = seedPhraseCount != null
? SeedPhraseLength.deserialize(raw: seedPhraseCount)
: defaultSeedPhraseLength;
final useEtherscan = sharedPreferences.getBool(PreferencesKey.useEtherscan) ?? true;
final usePolygonScan = sharedPreferences.getBool(PreferencesKey.usePolygonScan) ?? true;
final defaultNanoRep = sharedPreferences.getString(PreferencesKey.defaultNanoRep) ?? "";
@ -956,7 +933,101 @@ abstract class SettingsStoreBase with Store {
});
final savedSyncAll = sharedPreferences.getBool(PreferencesKey.syncAllKey) ?? true;
// migrated to secure:
final timeOutDuration = await SecureKey.getInt(
secureStorage: secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.pinTimeOutDuration,
);
final pinCodeTimeOutDuration = timeOutDuration != null
? PinCodeRequiredDuration.deserialize(raw: timeOutDuration)
: defaultPinCodeTimeOutDuration;
final allowBiometricalAuthentication = await SecureKey.getBool(
secureStorage: secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.pinTimeOutDuration,
) ??
false;
final selectedCake2FAPreset = Cake2FAPresetsOptions.deserialize(
raw: await SecureKey.getInt(
secureStorage: secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.selectedCake2FAPreset,
) ??
Cake2FAPresetsOptions.normal.raw);
final shouldRequireTOTP2FAForAccessingWallet = await SecureKey.getBool(
secureStorage: secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.shouldRequireTOTP2FAForAccessingWallet,
) ??
false;
final shouldRequireTOTP2FAForSendsToContact = await SecureKey.getBool(
secureStorage: secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.shouldRequireTOTP2FAForSendsToContact,
) ??
false;
final shouldRequireTOTP2FAForSendsToNonContact = await SecureKey.getBool(
secureStorage: secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.shouldRequireTOTP2FAForSendsToNonContact,
) ??
false;
final shouldRequireTOTP2FAForSendsToInternalWallets = await SecureKey.getBool(
secureStorage: secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets,
) ??
false;
final shouldRequireTOTP2FAForExchangesToInternalWallets = await SecureKey.getBool(
secureStorage: secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets,
) ??
false;
final shouldRequireTOTP2FAForExchangesToExternalWallets = await SecureKey.getBool(
secureStorage: secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets,
) ??
false;
final shouldRequireTOTP2FAForAddingContacts = await SecureKey.getBool(
secureStorage: secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.shouldRequireTOTP2FAForAddingContacts,
) ??
false;
final shouldRequireTOTP2FAForCreatingNewWallets = await SecureKey.getBool(
secureStorage: secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.shouldRequireTOTP2FAForCreatingNewWallets,
) ??
false;
final shouldRequireTOTP2FAForAllSecurityAndBackupSettings = await SecureKey.getBool(
secureStorage: secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
) ??
false;
final useTOTP2FA = await SecureKey.getBool(
secureStorage: secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.useTOTP2FA,
) ??
false;
final totpSecretKey = await SecureKey.getString(
secureStorage: secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.useTOTP2FA,
) ??
'';
return SettingsStore(
secureStorage: secureStorage,
sharedPreferences: sharedPreferences,
initialShouldShowMarketPlaceInDashboard: shouldShowMarketPlaceInDashboard,
nodes: nodes,
@ -1084,8 +1155,6 @@ abstract class SettingsStoreBase with Store {
shouldSaveRecipientAddress =
sharedPreferences.getBool(PreferencesKey.shouldSaveRecipientAddressKey) ??
shouldSaveRecipientAddress;
useTOTP2FA = sharedPreferences.getBool(PreferencesKey.useTOTP2FA) ?? useTOTP2FA;
totpSecretKey = sharedPreferences.getString(PreferencesKey.totpSecretKey) ?? totpSecretKey;
numberOfFailedTokenTrials =
sharedPreferences.getInt(PreferencesKey.failedTotpTokenTrials) ?? numberOfFailedTokenTrials;
isAppSecure = sharedPreferences.getBool(PreferencesKey.isAppSecureKey) ?? isAppSecure;
@ -1094,41 +1163,10 @@ abstract class SettingsStoreBase with Store {
walletListOrder =
WalletListOrderType.values[sharedPreferences.getInt(PreferencesKey.walletListOrder) ?? 0];
walletListAscending = sharedPreferences.getBool(PreferencesKey.walletListAscending) ?? true;
allowBiometricalAuthentication =
sharedPreferences.getBool(PreferencesKey.allowBiometricalAuthenticationKey) ??
allowBiometricalAuthentication;
selectedCake2FAPreset = Cake2FAPresetsOptions.deserialize(
raw: sharedPreferences.getInt(PreferencesKey.selectedCake2FAPreset) ??
Cake2FAPresetsOptions.normal.raw);
shouldRequireTOTP2FAForAccessingWallet =
sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForAccessingWallet) ?? false;
shouldRequireTOTP2FAForSendsToContact =
sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToContact) ?? false;
shouldRequireTOTP2FAForSendsToNonContact =
sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToNonContact) ?? false;
shouldRequireTOTP2FAForSendsToInternalWallets =
sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForSendsToInternalWallets) ??
false;
shouldRequireTOTP2FAForExchangesToInternalWallets = sharedPreferences
.getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToInternalWallets) ??
false;
shouldRequireTOTP2FAForExchangesToExternalWallets = sharedPreferences
.getBool(PreferencesKey.shouldRequireTOTP2FAForExchangesToExternalWallets) ??
false;
shouldRequireTOTP2FAForAddingContacts =
sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForAddingContacts) ?? false;
shouldRequireTOTP2FAForCreatingNewWallets =
sharedPreferences.getBool(PreferencesKey.shouldRequireTOTP2FAForCreatingNewWallets) ??
false;
shouldRequireTOTP2FAForAllSecurityAndBackupSettings = sharedPreferences
.getBool(PreferencesKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings) ??
false;
shouldShowMarketPlaceInDashboard =
sharedPreferences.getBool(PreferencesKey.shouldShowMarketPlaceInDashboard) ??
shouldShowMarketPlaceInDashboard;
selectedCake2FAPreset = Cake2FAPresetsOptions.deserialize(
raw: sharedPreferences.getInt(PreferencesKey.selectedCake2FAPreset) ??
Cake2FAPresetsOptions.narrow.raw);
exchangeStatus = ExchangeApiMode.deserialize(
raw: sharedPreferences.getInt(PreferencesKey.exchangeStatusKey) ??
ExchangeApiMode.enabled.raw);
@ -1217,6 +1255,93 @@ abstract class SettingsStoreBase with Store {
if (nanoNode != null) {
nodes[WalletType.nano] = nanoNode;
}
// MIGRATED:
useTOTP2FA = await SecureKey.getBool(
secureStorage: _secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.useTOTP2FA,
) ??
useTOTP2FA;
totpSecretKey = await SecureKey.getString(
secureStorage: _secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.useTOTP2FA,
) ??
totpSecretKey;
allowBiometricalAuthentication = await SecureKey.getBool(
secureStorage: _secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.allowBiometricalAuthenticationKey,
) ??
allowBiometricalAuthentication;
selectedCake2FAPreset = Cake2FAPresetsOptions.deserialize(
raw: await SecureKey.getInt(
secureStorage: _secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.selectedCake2FAPreset,
) ??
Cake2FAPresetsOptions.normal.raw);
shouldRequireTOTP2FAForAccessingWallet = await SecureKey.getBool(
secureStorage: _secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.shouldRequireTOTP2FAForAccessingWallet,
) ??
false;
shouldRequireTOTP2FAForSendsToContact = await SecureKey.getBool(
secureStorage: _secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.shouldRequireTOTP2FAForSendsToContact,
) ??
false;
shouldRequireTOTP2FAForSendsToNonContact = await SecureKey.getBool(
secureStorage: _secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.shouldRequireTOTP2FAForSendsToNonContact,
) ??
false;
shouldRequireTOTP2FAForSendsToInternalWallets = await SecureKey.getBool(
secureStorage: _secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.shouldRequireTOTP2FAForSendsToInternalWallets,
) ??
false;
shouldRequireTOTP2FAForExchangesToInternalWallets = await SecureKey.getBool(
secureStorage: _secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.shouldRequireTOTP2FAForExchangesToInternalWallets,
) ??
false;
shouldRequireTOTP2FAForExchangesToExternalWallets = await SecureKey.getBool(
secureStorage: _secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.shouldRequireTOTP2FAForExchangesToExternalWallets,
) ??
false;
shouldRequireTOTP2FAForAddingContacts = await SecureKey.getBool(
secureStorage: _secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.shouldRequireTOTP2FAForAddingContacts,
) ??
false;
shouldRequireTOTP2FAForCreatingNewWallets = await SecureKey.getBool(
secureStorage: _secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.shouldRequireTOTP2FAForCreatingNewWallets,
) ??
false;
shouldRequireTOTP2FAForAllSecurityAndBackupSettings = await SecureKey.getBool(
secureStorage: _secureStorage,
sharedPreferences: sharedPreferences,
key: SecureKey.shouldRequireTOTP2FAForAllSecurityAndBackupSettings,
) ??
false;
}
Future<void> _saveCurrentNode(Node node, WalletType walletType) async {

View file

@ -44,5 +44,5 @@ abstract class SecuritySettingsViewModelBase with Store {
setPinCodeRequiredDuration(PinCodeRequiredDuration duration) =>
_settingsStore.pinTimeOutDuration = duration;
bool checkPinCodeRiquired() => _authService.requireAuth();
Future<bool> checkPinCodeRiquired() => _authService.requireAuth();
}

View file

@ -161,7 +161,7 @@ abstract class WalletListViewModelBase with Store {
}
}
bool checkIfAuthRequired() {
Future<bool> checkIfAuthRequired() async {
return _authService.requireAuth();
}
}

View file

@ -756,7 +756,7 @@
"dfx_option_description": "ﺎﺑﻭﺭﻭﺃ ﻲﻓ ﺕﺎﻛﺮﺸﻟﺍﻭ ﺔﺋﺰﺠﺘﻟﺍ ءﻼﻤﻌﻟ .ﻲﻓﺎﺿﺇ KYC ﻥﻭﺪﺑ ﻭﺭﻮﻳ 990 ﻰﻟﺇ ﻞﺼﻳ ﺎﻣ .ﻱﺮﺴﻳﻮﺴﻟﺍ",
"polygonscan_history": "ﻥﺎﻜﺴﻧﻮﺠﻴﻟﻮﺑ ﺦﻳﺭﺎﺗ",
"wallet_seed_legacy": "بذرة محفظة قديمة",
"default_sell_provider": " ﻲﺿﺍﺮﺘﻓﻻﺍ ﻊﻴﺒﻟﺍ ﺩﻭﺰﻣ",
"default_sell_provider": "ﻲﺿﺍﺮﺘﻓﻻﺍ ﻊﻴﺒﻟﺍ ﺩﻭﺰﻣ",
"select_sell_provider_notice": ".ﻖﻴﺒﻄﺘﻟﺍ ﺕﺍﺩﺍﺪﻋﺇ ﻲﻓ ﻚﺑ ﺹﺎﺨﻟﺍ ﻲﺿﺍﺮﺘﻓﻻﺍ ﻊﻴﺒﻟﺍ ﺩﻭﺰﻣ ﻦﻴﻴﻌﺗ ﻖﻳﺮﻃ ﻦﻋ ﺔﺷﺎﺸﻟﺍ ﻩﺬﻫ ﻲﻄﺨﺗ",
"custom_drag": "مخصص (عقد وسحب)",
"switchToEVMCompatibleWallet": " (Ethereum، Polygon) ﻯﺮﺧﺃ ﺓﺮﻣ ﺔﻟﻭﺎﺤﻤﻟﺍﻭ EVM ﻊﻣ ﺔﻘﻓﺍﻮﺘﻣ ﺔﻈﻔﺤﻣ ﻰﻟﺇ ﻞﻳﺪﺒﺘﻟﺍ ﻰﺟﺮﻳ",
@ -768,5 +768,6 @@
"connecting": "توصيل",
"receivable_balance": "التوازن القادم",
"confirmed_tx": "مؤكد",
"transaction_details_source_address": "عنوان المصدر"
}
"transaction_details_source_address": "عنوان المصدر",
"pause_wallet_creation": ".ﺎﻴًﻟﺎﺣ ﺎﺘًﻗﺆﻣ ﺔﻔﻗﻮﺘﻣ Haven Wallet ءﺎﺸﻧﺇ ﻰﻠﻋ ﺓﺭﺪﻘﻟﺍ"
}

View file

@ -764,5 +764,6 @@
"connecting": "Свързване",
"receivable_balance": "Баланс за вземания",
"confirmed_tx": "Потвърдено",
"transaction_details_source_address": "Адрес на източника"
}
"transaction_details_source_address": "Адрес на източника",
"pause_wallet_creation": "Възможността за създаване на Haven Wallet в момента е на пауза."
}

View file

@ -764,5 +764,6 @@
"connecting": "Spojovací",
"receivable_balance": "Zůstatek pohledávek",
"confirmed_tx": "Potvrzeno",
"transaction_details_source_address": "Zdrojová adresa"
}
"transaction_details_source_address": "Zdrojová adresa",
"pause_wallet_creation": "Možnost vytvářet Haven Wallet je momentálně pozastavena."
}

View file

@ -772,5 +772,6 @@
"connecting": "Verbinden",
"receivable_balance": "Forderungsbilanz",
"confirmed_tx": "Bestätigt",
"transaction_details_source_address": "Quelladresse"
}
"transaction_details_source_address": "Quelladresse",
"pause_wallet_creation": "Die Möglichkeit, Haven Wallet zu erstellen, ist derzeit pausiert."
}

View file

@ -773,5 +773,6 @@
"connecting": "Connecting",
"receivable_balance": "Receivable Balance",
"confirmed_tx": "Confirmed",
"transaction_details_source_address": "Source address"
}
"transaction_details_source_address": "Source address",
"pause_wallet_creation": "Ability to create Haven Wallet is currently paused."
}

View file

@ -772,5 +772,6 @@
"connecting": "Conexión",
"receivable_balance": "Saldo de cuentas por cobrar",
"confirmed_tx": "Confirmado",
"transaction_details_source_address": "Dirección de la fuente"
}
"transaction_details_source_address": "Dirección de la fuente",
"pause_wallet_creation": "La capacidad para crear Haven Wallet está actualmente pausada."
}

View file

@ -772,5 +772,6 @@
"connecting": "De liaison",
"receivable_balance": "Solde de créances",
"confirmed_tx": "Confirmé",
"transaction_details_source_address": "Adresse source"
}
"transaction_details_source_address": "Adresse source",
"pause_wallet_creation": "La possibilité de créer Haven Wallet est actuellement suspendue."
}

View file

@ -754,5 +754,6 @@
"connecting": "Haɗa",
"receivable_balance": "Daidaituwa da daidaituwa",
"confirmed_tx": "Tabbatar",
"transaction_details_source_address": "Adireshin Incord"
}
"transaction_details_source_address": "Adireshin Incord",
"pause_wallet_creation": "A halin yanzu an dakatar da ikon ƙirƙirar Haven Wallet."
}

View file

@ -772,5 +772,6 @@
"connecting": "कनेक्ट",
"receivable_balance": "प्राप्य शेष",
"confirmed_tx": "की पुष्टि",
"transaction_details_source_address": "स्रोत पता"
}
"transaction_details_source_address": "स्रोत पता",
"pause_wallet_creation": "हेवन वॉलेट बनाने की क्षमता फिलहाल रुकी हुई है।"
}

View file

@ -770,5 +770,6 @@
"connecting": "Spoj",
"receivable_balance": "Stanje potraživanja",
"confirmed_tx": "Potvrđen",
"transaction_details_source_address": "Adresa izvora"
}
"transaction_details_source_address": "Adresa izvora",
"pause_wallet_creation": "Mogućnost stvaranja novčanika Haven trenutno je pauzirana."
}

View file

@ -760,5 +760,6 @@
"connecting": "Menghubungkan",
"receivable_balance": "Saldo piutang",
"confirmed_tx": "Dikonfirmasi",
"transaction_details_source_address": "Alamat sumber"
}
"transaction_details_source_address": "Alamat sumber",
"pause_wallet_creation": "Kemampuan untuk membuat Haven Wallet saat ini dijeda."
}

View file

@ -772,5 +772,6 @@
"connecting": "Connessione",
"receivable_balance": "Bilanciamento creditizio",
"confirmed_tx": "Confermato",
"transaction_details_source_address": "Indirizzo di partenza"
}
"transaction_details_source_address": "Indirizzo di partenza",
"pause_wallet_creation": "La possibilità di creare Haven Wallet è attualmente sospesa."
}

View file

@ -772,5 +772,6 @@
"connecting": "接続",
"receivable_balance": "売掛金残高",
"confirmed_tx": "確認済み",
"transaction_details_source_address": "ソースアドレス"
}
"transaction_details_source_address": "ソースアドレス",
"pause_wallet_creation": "Haven Wallet を作成する機能は現在一時停止されています。"
}

View file

@ -770,5 +770,6 @@
"connecting": "연결",
"receivable_balance": "채권 잔액",
"confirmed_tx": "확인",
"transaction_details_source_address": "소스 주소"
}
"transaction_details_source_address": "소스 주소",
"pause_wallet_creation": "Haven Wallet 생성 기능이 현재 일시 중지되었습니다."
}

View file

@ -770,5 +770,6 @@
"connecting": "ချိတ်ဆက်",
"receivable_balance": "လက်ကျန်ငွေ",
"confirmed_tx": "အတည်ပြုသည်",
"transaction_details_source_address": "အရင်းအမြစ်လိပ်စာ"
}
"transaction_details_source_address": "အရင်းအမြစ်လိပ်စာ",
"pause_wallet_creation": "Haven Wallet ဖန်တီးနိုင်မှုကို လောလောဆယ် ခေတ္တရပ်ထားသည်။"
}

View file

@ -772,5 +772,6 @@
"connecting": "Verbinden",
"receivable_balance": "Het saldo",
"confirmed_tx": "Bevestigd",
"transaction_details_source_address": "Bron adres"
}
"transaction_details_source_address": "Bron adres",
"pause_wallet_creation": "De mogelijkheid om Haven Wallet te maken is momenteel onderbroken."
}

View file

@ -772,5 +772,6 @@
"connecting": "Złączony",
"receivable_balance": "Saldo należności",
"confirmed_tx": "Potwierdzony",
"transaction_details_source_address": "Adres źródłowy"
}
"transaction_details_source_address": "Adres źródłowy",
"pause_wallet_creation": "Możliwość utworzenia Portfela Haven jest obecnie wstrzymana."
}

View file

@ -771,5 +771,6 @@
"connecting": "Conectando",
"receivable_balance": "Saldo a receber",
"confirmed_tx": "Confirmado",
"transaction_details_source_address": "Endereço de Origem"
}
"transaction_details_source_address": "Endereço de Origem",
"pause_wallet_creation": "A capacidade de criar a Haven Wallet está atualmente pausada."
}

View file

@ -772,5 +772,6 @@
"connecting": "Соединение",
"receivable_balance": "Баланс дебиторской задолженности",
"confirmed_tx": "Подтвержденный",
"transaction_details_source_address": "Адрес источника"
}
"transaction_details_source_address": "Адрес источника",
"pause_wallet_creation": "Возможность создания Haven Wallet в настоящее время приостановлена."
}

View file

@ -770,5 +770,6 @@
"connecting": "การเชื่อมต่อ",
"receivable_balance": "ยอดลูกหนี้",
"confirmed_tx": "ซึ่งยืนยันแล้ว",
"transaction_details_source_address": "ที่อยู่แหล่งกำเนิด"
}
"transaction_details_source_address": "ที่อยู่แหล่งกำเนิด",
"pause_wallet_creation": "ขณะนี้ความสามารถในการสร้าง Haven Wallet ถูกหยุดชั่วคราว"
}

View file

@ -766,5 +766,6 @@
"connecting": "Pagkonekta",
"receivable_balance": "Natatanggap na balanse",
"confirmed_tx": "Nakumpirma",
"transaction_details_source_address": "SOURCE ADDRESS"
}
"transaction_details_source_address": "SOURCE ADDRESS",
"pause_wallet_creation": "Kasalukuyang naka-pause ang kakayahang gumawa ng Haven Wallet."
}

View file

@ -770,5 +770,6 @@
"connecting": "Bağlanıyor",
"receivable_balance": "Alacak bakiyesi",
"confirmed_tx": "Onaylanmış",
"transaction_details_source_address": "Kaynak adresi"
}
"transaction_details_source_address": "Kaynak adresi",
"pause_wallet_creation": "Haven Cüzdanı oluşturma yeteneği şu anda duraklatıldı."
}

View file

@ -772,5 +772,6 @@
"connecting": "З'єднання",
"receivable_balance": "Баланс дебіторської заборгованості",
"confirmed_tx": "Підтверджений",
"transaction_details_source_address": "Адреса джерела"
}
"transaction_details_source_address": "Адреса джерела",
"pause_wallet_creation": "Можливість створення гаманця Haven зараз призупинено."
}

View file

@ -764,5 +764,6 @@
"connecting": "رابطہ قائم کرنا",
"receivable_balance": "قابل وصول توازن",
"confirmed_tx": "تصدیق",
"transaction_details_source_address": "ماخذ ایڈریس"
}
"transaction_details_source_address": "ماخذ ایڈریس",
"pause_wallet_creation": "Haven Wallet ۔ﮯﮨ ﻑﻮﻗﻮﻣ ﻝﺎﺤﻟﺍ ﯽﻓ ﺖﯿﻠﮨﺍ ﯽﮐ ﮯﻧﺎﻨﺑ"
}

View file

@ -766,5 +766,6 @@
"connecting": "Asopọ",
"receivable_balance": "Iwontunws.funfun ti o gba",
"confirmed_tx": "Jẹrisi",
"transaction_details_source_address": "Adirẹsi orisun"
}
"transaction_details_source_address": "Adirẹsi orisun",
"pause_wallet_creation": "Agbara lati ṣẹda Haven Wallet ti wa ni idaduro lọwọlọwọ."
}

View file

@ -771,5 +771,6 @@
"connecting": "连接",
"receivable_balance": "应收余额",
"confirmed_tx": "确认的",
"transaction_details_source_address": "源地址"
}
"transaction_details_source_address": "源地址",
"pause_wallet_creation": "创建 Haven 钱包的功能当前已暂停。"
}