mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-23 03:59:23 +00:00
Merge branch 'main' of https://github.com/cake-tech/cake_wallet into CW-519-tor
This commit is contained in:
commit
6e0c20ba75
39 changed files with 547 additions and 327 deletions
|
@ -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:
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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 [];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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!);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -44,5 +44,5 @@ abstract class SecuritySettingsViewModelBase with Store {
|
|||
setPinCodeRequiredDuration(PinCodeRequiredDuration duration) =>
|
||||
_settingsStore.pinTimeOutDuration = duration;
|
||||
|
||||
bool checkPinCodeRiquired() => _authService.requireAuth();
|
||||
Future<bool> checkPinCodeRiquired() => _authService.requireAuth();
|
||||
}
|
||||
|
|
|
@ -161,7 +161,7 @@ abstract class WalletListViewModelBase with Store {
|
|||
}
|
||||
}
|
||||
|
||||
bool checkIfAuthRequired() {
|
||||
Future<bool> checkIfAuthRequired() async {
|
||||
return _authService.requireAuth();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 ءﺎﺸﻧﺇ ﻰﻠﻋ ﺓﺭﺪﻘﻟﺍ"
|
||||
}
|
||||
|
|
|
@ -764,5 +764,6 @@
|
|||
"connecting": "Свързване",
|
||||
"receivable_balance": "Баланс за вземания",
|
||||
"confirmed_tx": "Потвърдено",
|
||||
"transaction_details_source_address": "Адрес на източника"
|
||||
}
|
||||
"transaction_details_source_address": "Адрес на източника",
|
||||
"pause_wallet_creation": "Възможността за създаване на Haven Wallet в момента е на пауза."
|
||||
}
|
||||
|
|
|
@ -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."
|
||||
}
|
||||
|
|
|
@ -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."
|
||||
}
|
||||
|
|
|
@ -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."
|
||||
}
|
||||
|
|
|
@ -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."
|
||||
}
|
||||
|
|
|
@ -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."
|
||||
}
|
||||
|
|
|
@ -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."
|
||||
}
|
||||
|
|
|
@ -772,5 +772,6 @@
|
|||
"connecting": "कनेक्ट",
|
||||
"receivable_balance": "प्राप्य शेष",
|
||||
"confirmed_tx": "की पुष्टि",
|
||||
"transaction_details_source_address": "स्रोत पता"
|
||||
}
|
||||
"transaction_details_source_address": "स्रोत पता",
|
||||
"pause_wallet_creation": "हेवन वॉलेट बनाने की क्षमता फिलहाल रुकी हुई है।"
|
||||
}
|
||||
|
|
|
@ -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."
|
||||
}
|
||||
|
|
|
@ -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."
|
||||
}
|
||||
|
|
|
@ -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."
|
||||
}
|
||||
|
|
|
@ -772,5 +772,6 @@
|
|||
"connecting": "接続",
|
||||
"receivable_balance": "売掛金残高",
|
||||
"confirmed_tx": "確認済み",
|
||||
"transaction_details_source_address": "ソースアドレス"
|
||||
}
|
||||
"transaction_details_source_address": "ソースアドレス",
|
||||
"pause_wallet_creation": "Haven Wallet を作成する機能は現在一時停止されています。"
|
||||
}
|
||||
|
|
|
@ -770,5 +770,6 @@
|
|||
"connecting": "연결",
|
||||
"receivable_balance": "채권 잔액",
|
||||
"confirmed_tx": "확인",
|
||||
"transaction_details_source_address": "소스 주소"
|
||||
}
|
||||
"transaction_details_source_address": "소스 주소",
|
||||
"pause_wallet_creation": "Haven Wallet 생성 기능이 현재 일시 중지되었습니다."
|
||||
}
|
||||
|
|
|
@ -770,5 +770,6 @@
|
|||
"connecting": "ချိတ်ဆက်",
|
||||
"receivable_balance": "လက်ကျန်ငွေ",
|
||||
"confirmed_tx": "အတည်ပြုသည်",
|
||||
"transaction_details_source_address": "အရင်းအမြစ်လိပ်စာ"
|
||||
}
|
||||
"transaction_details_source_address": "အရင်းအမြစ်လိပ်စာ",
|
||||
"pause_wallet_creation": "Haven Wallet ဖန်တီးနိုင်မှုကို လောလောဆယ် ခေတ္တရပ်ထားသည်။"
|
||||
}
|
||||
|
|
|
@ -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."
|
||||
}
|
||||
|
|
|
@ -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."
|
||||
}
|
||||
|
|
|
@ -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."
|
||||
}
|
||||
|
|
|
@ -772,5 +772,6 @@
|
|||
"connecting": "Соединение",
|
||||
"receivable_balance": "Баланс дебиторской задолженности",
|
||||
"confirmed_tx": "Подтвержденный",
|
||||
"transaction_details_source_address": "Адрес источника"
|
||||
}
|
||||
"transaction_details_source_address": "Адрес источника",
|
||||
"pause_wallet_creation": "Возможность создания Haven Wallet в настоящее время приостановлена."
|
||||
}
|
||||
|
|
|
@ -770,5 +770,6 @@
|
|||
"connecting": "การเชื่อมต่อ",
|
||||
"receivable_balance": "ยอดลูกหนี้",
|
||||
"confirmed_tx": "ซึ่งยืนยันแล้ว",
|
||||
"transaction_details_source_address": "ที่อยู่แหล่งกำเนิด"
|
||||
}
|
||||
"transaction_details_source_address": "ที่อยู่แหล่งกำเนิด",
|
||||
"pause_wallet_creation": "ขณะนี้ความสามารถในการสร้าง Haven Wallet ถูกหยุดชั่วคราว"
|
||||
}
|
||||
|
|
|
@ -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."
|
||||
}
|
||||
|
|
|
@ -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ı."
|
||||
}
|
||||
|
|
|
@ -772,5 +772,6 @@
|
|||
"connecting": "З'єднання",
|
||||
"receivable_balance": "Баланс дебіторської заборгованості",
|
||||
"confirmed_tx": "Підтверджений",
|
||||
"transaction_details_source_address": "Адреса джерела"
|
||||
}
|
||||
"transaction_details_source_address": "Адреса джерела",
|
||||
"pause_wallet_creation": "Можливість створення гаманця Haven зараз призупинено."
|
||||
}
|
||||
|
|
|
@ -764,5 +764,6 @@
|
|||
"connecting": "رابطہ قائم کرنا",
|
||||
"receivable_balance": "قابل وصول توازن",
|
||||
"confirmed_tx": "تصدیق",
|
||||
"transaction_details_source_address": "ماخذ ایڈریس"
|
||||
}
|
||||
"transaction_details_source_address": "ماخذ ایڈریس",
|
||||
"pause_wallet_creation": "Haven Wallet ۔ﮯﮨ ﻑﻮﻗﻮﻣ ﻝﺎﺤﻟﺍ ﯽﻓ ﺖﯿﻠﮨﺍ ﯽﮐ ﮯﻧﺎﻨﺑ"
|
||||
}
|
||||
|
|
|
@ -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ọ."
|
||||
}
|
||||
|
|
|
@ -771,5 +771,6 @@
|
|||
"connecting": "连接",
|
||||
"receivable_balance": "应收余额",
|
||||
"confirmed_tx": "确认的",
|
||||
"transaction_details_source_address": "源地址"
|
||||
}
|
||||
"transaction_details_source_address": "源地址",
|
||||
"pause_wallet_creation": "创建 Haven 钱包的功能当前已暂停。"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue