- Improve code for backup cache (#2216)
* - Improve code for backup cache - Backup all Cached values without manually adding each one * Exclude some cache keys from backup [skip ci] * Exclude some cache keys from backup [skip ci]
Omar Hatem committed
Apr 19, 2025 at 01:13 UTC
e09d9aadfa58be8fc734800bbfec1cb64fb3b72b
1 file changed
+37
-204
lib/core/backup_service.dart
+37
-204
@@ -1,6 +1,5 @@
1
import 'dart:convert';
2
import 'dart:io';
3
-import 'dart:typed_data';
3
import 'package:cake_wallet/core/secure_storage.dart';
4
import 'package:cake_wallet/entities/get_encryption_key.dart';
5
import 'package:cake_wallet/entities/transaction_description.dart';
@@ -164,6 +163,31 @@ class $BackupService {
163
}
164
165
final data = json.decode(preferencesFile.readAsStringSync()) as Map<String, dynamic>;
166
+
167
+ try { // shouldn't throw an error but just in case, so it doesn't stop the backup restore
168
+ for (var entry in data.entries) {
169
+ String key = entry.key;
170
+ dynamic value = entry.value;
171
+
172
+ // Check the type of the value and save accordingly
173
+ if (value is String) {
174
+ await sharedPreferences.setString(key, value);
175
+ } else if (value is int) {
176
+ await sharedPreferences.setInt(key, value);
177
+ } else if (value is double) {
178
+ await sharedPreferences.setDouble(key, value);
179
+ } else if (value is bool) {
180
+ await sharedPreferences.setBool(key, value);
181
+ } else if (value is List<String>) {
182
+ await sharedPreferences.setStringList(key, value);
183
+ } else {
184
+ if (kDebugMode) {
185
+ printV('Skipping individual save for key "$key": Unsupported type (${value.runtimeType}). Value: $value');
186
+ }
187
+ }
188
+ }
189
+ } catch (_) {}
190
+
191
String currentWalletName = data[PreferencesKey.currentWalletName] as String;
192
int currentWalletType = data[PreferencesKey.currentWalletType] as int;
193
@@ -175,151 +199,10 @@ class $BackupService {
199
currentWalletType = serializeToInt(correctWallets.first.type);
200
}
201
178
- final currentNodeId = data[PreferencesKey.currentNodeIdKey] as int?;
179
- final currentBalanceDisplayMode = data[PreferencesKey.currentBalanceDisplayModeKey] as int?;
180
- final currentFiatCurrency = data[PreferencesKey.currentFiatCurrencyKey] as String?;
181
- final shouldSaveRecipientAddress = data[PreferencesKey.shouldSaveRecipientAddressKey] as bool?;
182
- final isAppSecure = data[PreferencesKey.isAppSecureKey] as bool?;
183
- final disableTradeOption = data[PreferencesKey.disableTradeOption] as bool?;
184
- final currentTransactionPriorityKeyLegacy =
185
- data[PreferencesKey.currentTransactionPriorityKeyLegacy] as int?;
186
- final currentBitcoinElectrumSererId =
187
- data[PreferencesKey.currentBitcoinElectrumSererIdKey] as int?;
188
- final currentLanguageCode = data[PreferencesKey.currentLanguageCode] as String?;
189
- final displayActionListMode = data[PreferencesKey.displayActionListModeKey] as int?;
190
- final fiatApiMode = data[PreferencesKey.currentFiatApiModeKey] as int?;
191
- final currentTheme = data[PreferencesKey.currentTheme] as int?;
192
- final exchangeStatus = data[PreferencesKey.exchangeStatusKey] as int?;
193
- final currentDefaultSettingsMigrationVersion =
194
- data[PreferencesKey.currentDefaultSettingsMigrationVersion] as int?;
195
- final moneroTransactionPriority = data[PreferencesKey.moneroTransactionPriority] as int?;
196
- final bitcoinTransactionPriority = data[PreferencesKey.bitcoinTransactionPriority] as int?;
197
- final sortBalanceTokensBy = data[PreferencesKey.sortBalanceBy] as int?;
198
- final pinNativeTokenAtTop = data[PreferencesKey.pinNativeTokenAtTop] as bool?;
199
- final useEtherscan = data[PreferencesKey.useEtherscan] as bool?;
200
- final defaultNanoRep = data[PreferencesKey.defaultNanoRep] as String?;
201
- final defaultBananoRep = data[PreferencesKey.defaultBananoRep] as String?;
202
- final lookupsTwitter = data[PreferencesKey.lookupsTwitter] as bool?;
203
- final lookupsMastodon = data[PreferencesKey.lookupsMastodon] as bool?;
204
- final lookupsYatService = data[PreferencesKey.lookupsYatService] as bool?;
205
- final lookupsUnstoppableDomains = data[PreferencesKey.lookupsUnstoppableDomains] as bool?;
206
- final lookupsOpenAlias = data[PreferencesKey.lookupsOpenAlias] as bool?;
207
- final lookupsENS = data[PreferencesKey.lookupsENS] as bool?;
208
- final lookupsWellKnown = data[PreferencesKey.lookupsWellKnown] as bool?;
209
- final syncAll = data[PreferencesKey.syncAllKey] as bool?;
210
- final syncMode = data[PreferencesKey.syncModeKey] as int?;
211
- final autoGenerateSubaddressStatus =
212
- data[PreferencesKey.autoGenerateSubaddressStatusKey] as int?;
213
-
214
- await sharedPreferences.setString(PreferencesKey.currentWalletName, currentWalletName);
215
-
216
- if (currentNodeId != null)
217
- await sharedPreferences.setInt(PreferencesKey.currentNodeIdKey, currentNodeId);
218
-
219
- if (currentBalanceDisplayMode != null)
220
- await sharedPreferences.setInt(
221
- PreferencesKey.currentBalanceDisplayModeKey, currentBalanceDisplayMode);
222
-
223
- await sharedPreferences.setInt(PreferencesKey.currentWalletType, currentWalletType);
224
-
225
- if (currentFiatCurrency != null)
226
- await sharedPreferences.setString(
227
- PreferencesKey.currentFiatCurrencyKey, currentFiatCurrency);
228
-
229
- if (shouldSaveRecipientAddress != null)
230
- await sharedPreferences.setBool(
231
- PreferencesKey.shouldSaveRecipientAddressKey, shouldSaveRecipientAddress);
232
-
233
- if (isAppSecure != null)
234
- await sharedPreferences.setBool(PreferencesKey.isAppSecureKey, isAppSecure);
235
-
236
- if (disableTradeOption != null)
237
- await sharedPreferences.setBool(PreferencesKey.disableTradeOption, disableTradeOption);
238
-
239
- if (currentTransactionPriorityKeyLegacy != null)
240
- await sharedPreferences.setInt(
241
- PreferencesKey.currentTransactionPriorityKeyLegacy, currentTransactionPriorityKeyLegacy);
242
-
243
- if (currentBitcoinElectrumSererId != null)
244
- await sharedPreferences.setInt(
245
- PreferencesKey.currentBitcoinElectrumSererIdKey, currentBitcoinElectrumSererId);
246
-
247
- if (currentLanguageCode != null)
248
- await sharedPreferences.setString(PreferencesKey.currentLanguageCode, currentLanguageCode);
249
-
250
- if (displayActionListMode != null)
251
- await sharedPreferences.setInt(
252
- PreferencesKey.displayActionListModeKey, displayActionListMode);
253
-
254
- if (fiatApiMode != null)
255
- await sharedPreferences.setInt(PreferencesKey.currentFiatApiModeKey, fiatApiMode);
256
- if (autoGenerateSubaddressStatus != null)
257
- await sharedPreferences.setInt(
258
- PreferencesKey.autoGenerateSubaddressStatusKey, autoGenerateSubaddressStatus);
259
-
260
- if (currentTheme != null && DeviceInfo.instance.isMobile) {
261
- await sharedPreferences.setInt(PreferencesKey.currentTheme, currentTheme);
262
- // enforce dark theme on desktop platforms until the design is ready:
263
- } else if (DeviceInfo.instance.isDesktop) {
202
+ if (DeviceInfo.instance.isDesktop) {
203
await sharedPreferences.setInt(PreferencesKey.currentTheme, ThemeList.darkTheme.raw);
204
}
205
267
- if (exchangeStatus != null)
268
- await sharedPreferences.setInt(PreferencesKey.exchangeStatusKey, exchangeStatus);
269
-
270
- if (currentDefaultSettingsMigrationVersion != null)
271
- await sharedPreferences.setInt(PreferencesKey.currentDefaultSettingsMigrationVersion,
272
- currentDefaultSettingsMigrationVersion);
273
-
274
- if (moneroTransactionPriority != null)
275
- await sharedPreferences.setInt(
276
- PreferencesKey.moneroTransactionPriority, moneroTransactionPriority);
277
-
278
- if (bitcoinTransactionPriority != null)
279
- await sharedPreferences.setInt(
280
- PreferencesKey.bitcoinTransactionPriority, bitcoinTransactionPriority);
281
-
282
- if (sortBalanceTokensBy != null)
283
- await sharedPreferences.setInt(PreferencesKey.sortBalanceBy, sortBalanceTokensBy);
284
-
285
- if (pinNativeTokenAtTop != null)
286
- await sharedPreferences.setBool(PreferencesKey.pinNativeTokenAtTop, pinNativeTokenAtTop);
287
-
288
- if (useEtherscan != null)
289
- await sharedPreferences.setBool(PreferencesKey.useEtherscan, useEtherscan);
290
-
291
- if (defaultNanoRep != null)
292
- await sharedPreferences.setString(PreferencesKey.defaultNanoRep, defaultNanoRep);
293
-
294
- if (defaultBananoRep != null)
295
- await sharedPreferences.setString(PreferencesKey.defaultBananoRep, defaultBananoRep);
296
-
297
- if (syncAll != null) await sharedPreferences.setBool(PreferencesKey.syncAllKey, syncAll);
298
- if (lookupsTwitter != null)
299
- await sharedPreferences.setBool(PreferencesKey.lookupsTwitter, lookupsTwitter);
300
-
301
- if (lookupsMastodon != null)
302
- await sharedPreferences.setBool(PreferencesKey.lookupsMastodon, lookupsMastodon);
303
-
304
- if (lookupsYatService != null)
305
- await sharedPreferences.setBool(PreferencesKey.lookupsYatService, lookupsYatService);
306
-
307
- if (lookupsUnstoppableDomains != null)
308
- await sharedPreferences.setBool(
309
- PreferencesKey.lookupsUnstoppableDomains, lookupsUnstoppableDomains);
310
-
311
- if (lookupsOpenAlias != null)
312
- await sharedPreferences.setBool(PreferencesKey.lookupsOpenAlias, lookupsOpenAlias);
313
-
314
- if (lookupsENS != null) await sharedPreferences.setBool(PreferencesKey.lookupsENS, lookupsENS);
315
-
316
- if (lookupsWellKnown != null)
317
- await sharedPreferences.setBool(PreferencesKey.lookupsWellKnown, lookupsWellKnown);
318
-
319
- if (syncAll != null) await sharedPreferences.setBool(PreferencesKey.syncAllKey, syncAll);
320
-
321
- if (syncMode != null) await sharedPreferences.setInt(PreferencesKey.syncModeKey, syncMode);
322
-
206
await preferencesFile.delete();
207
}
208
@@ -378,11 +261,6 @@ class $BackupService {
261
await keyService.saveWalletPassword(walletName: name, password: password);
262
}
263
381
- @Deprecated('Use v2 instead')
382
- Future<Uint8List> _exportKeychainDumpV1(String password,
383
- {required String nonce, String keychainSalt = secrets.backupKeychainSalt}) async =>
384
- throw Exception('Deprecated');
385
-
264
Future<Uint8List> exportKeychainDumpV2(String password,
265
{String keychainSalt = secrets.backupKeychainSalt}) async {
266
final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
@@ -402,59 +280,18 @@ class $BackupService {
280
return encrypted;
281
}
282
283
+ static const List<String> _excludedPrefsKeys = [
284
+ PreferencesKey.currentPinLength,
285
+ PreferencesKey.showCameraConsent,
286
+ PreferencesKey.lastSeenAppVersion,
287
+ PreferencesKey.failedTotpTokenTrials,
288
+ ];
289
+
290
Future<String> exportPreferencesJSON() async {
406
- final preferences = <String, dynamic>{
407
- PreferencesKey.currentWalletName:
408
- sharedPreferences.getString(PreferencesKey.currentWalletName),
409
- PreferencesKey.currentNodeIdKey: sharedPreferences.getInt(PreferencesKey.currentNodeIdKey),
410
- PreferencesKey.currentBalanceDisplayModeKey:
411
- sharedPreferences.getInt(PreferencesKey.currentBalanceDisplayModeKey),
412
- PreferencesKey.currentWalletType: sharedPreferences.getInt(PreferencesKey.currentWalletType),
413
- PreferencesKey.currentFiatCurrencyKey:
414
- sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey),
415
- PreferencesKey.shouldSaveRecipientAddressKey:
416
- sharedPreferences.getBool(PreferencesKey.shouldSaveRecipientAddressKey),
417
- PreferencesKey.disableTradeOption: sharedPreferences.getBool(PreferencesKey.disableTradeOption),
418
- PreferencesKey.currentTransactionPriorityKeyLegacy:
419
- sharedPreferences.getInt(PreferencesKey.currentTransactionPriorityKeyLegacy),
420
- PreferencesKey.currentBitcoinElectrumSererIdKey:
421
- sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey),
422
- PreferencesKey.currentLanguageCode:
423
- sharedPreferences.getString(PreferencesKey.currentLanguageCode),
424
- PreferencesKey.displayActionListModeKey:
425
- sharedPreferences.getInt(PreferencesKey.displayActionListModeKey),
426
- PreferencesKey.currentTheme: sharedPreferences.getInt(PreferencesKey.currentTheme),
427
- PreferencesKey.exchangeStatusKey: sharedPreferences.getInt(PreferencesKey.exchangeStatusKey),
428
- PreferencesKey.currentDefaultSettingsMigrationVersion:
429
- sharedPreferences.getInt(PreferencesKey.currentDefaultSettingsMigrationVersion),
430
- PreferencesKey.bitcoinTransactionPriority:
431
- sharedPreferences.getInt(PreferencesKey.bitcoinTransactionPriority),
432
- PreferencesKey.moneroTransactionPriority:
433
- sharedPreferences.getInt(PreferencesKey.moneroTransactionPriority),
434
- PreferencesKey.currentFiatApiModeKey:
435
- sharedPreferences.getInt(PreferencesKey.currentFiatApiModeKey),
436
- PreferencesKey.sortBalanceBy: sharedPreferences.getInt(PreferencesKey.sortBalanceBy),
437
- PreferencesKey.pinNativeTokenAtTop:
438
- sharedPreferences.getBool(PreferencesKey.pinNativeTokenAtTop),
439
- PreferencesKey.useEtherscan: sharedPreferences.getBool(PreferencesKey.useEtherscan),
440
- PreferencesKey.defaultNanoRep: sharedPreferences.getString(PreferencesKey.defaultNanoRep),
441
- PreferencesKey.defaultBananoRep:
442
- sharedPreferences.getString(PreferencesKey.defaultBananoRep),
443
- PreferencesKey.lookupsTwitter: sharedPreferences.getBool(PreferencesKey.lookupsTwitter),
444
- PreferencesKey.lookupsMastodon: sharedPreferences.getBool(PreferencesKey.lookupsMastodon),
445
- PreferencesKey.lookupsYatService:
446
- sharedPreferences.getBool(PreferencesKey.lookupsYatService),
447
- PreferencesKey.lookupsUnstoppableDomains:
448
- sharedPreferences.getBool(PreferencesKey.lookupsUnstoppableDomains),
449
- PreferencesKey.lookupsOpenAlias: sharedPreferences.getBool(PreferencesKey.lookupsOpenAlias),
450
- PreferencesKey.lookupsENS: sharedPreferences.getBool(PreferencesKey.lookupsENS),
451
- PreferencesKey.lookupsWellKnown:
452
- sharedPreferences.getBool(PreferencesKey.lookupsWellKnown),
453
- PreferencesKey.syncModeKey: sharedPreferences.getInt(PreferencesKey.syncModeKey),
454
- PreferencesKey.syncAllKey: sharedPreferences.getBool(PreferencesKey.syncAllKey),
455
- PreferencesKey.autoGenerateSubaddressStatusKey:
456
- sharedPreferences.getInt(PreferencesKey.autoGenerateSubaddressStatusKey),
457
- };
291
+ final preferences = <String, dynamic>{};
292
+ sharedPreferences.getKeys().forEach((key) => preferences[key] = sharedPreferences.get(key));
293
+
294
+ _excludedPrefsKeys.forEach((key) => preferences.remove(key));
295
296
return json.encode(preferences);
297
}
@@ -466,10 +303,6 @@ class $BackupService {
303
return Uint8List.fromList(bytes);
304
}
305
469
- @Deprecated('Use v2 instead')
470
- Future<Uint8List> _encryptV1(Uint8List data, String secretKeySource, String nonceBase64) async =>
471
- throw Exception('Deprecated');
472
-
306
Future<Uint8List> _decryptV1(Uint8List data, String secretKeySource, String nonceBase64,
307
{int macLength = 16}) async {
308
final secretKeyHash = await Cryptography.instance.sha256().hash(utf8.encode(secretKeySource));