Fixes for backups for monero.com app
M committed
Feb 2, 2022 at 14:40 UTC
05c4d26634a780339486a28472dd4eda976d1a17
8 files changed
+65
-16
lib/core/backup_service.dart
+40
-2
@@ -14,6 +14,7 @@ import 'package:cake_wallet/entities/preferences_key.dart';
14
import 'package:cake_wallet/entities/secret_store_key.dart';
15
import 'package:cw_core/wallet_info.dart';
16
import 'package:cake_wallet/.secrets.g.dart' as secrets;
17
+import 'package:cake_wallet/wallet_types.g.dart';
18
19
class BackupService {
20
BackupService(this._flutterSecureStorage, this._walletInfoSource,
@@ -29,6 +30,7 @@ class BackupService {
30
final SharedPreferences _sharedPreferences;
31
final Box<WalletInfo> _walletInfoSource;
32
final KeyService _keyService;
33
+ List<WalletInfo> _correctWallets;
34
35
Future<void> importBackup(Uint8List data, String password,
36
{String nonce = secrets.backupSalt}) async {
@@ -118,10 +120,35 @@ class BackupService {
120
}
121
});
122
123
+ await _verifyWallets();
124
await _importKeychainDump(password, nonce: nonce);
125
await _importPreferencesDump();
126
}
127
128
+ Future<void> _verifyWallets() async {
129
+ final walletInfoSource = await _reloadHiveWalletInfoBox();
130
+ _correctWallets = walletInfoSource
131
+ .values
132
+ .where((info) => availableWalletTypes.contains(info.type))
133
+ .toList();
134
+
135
+ if (_correctWallets.isEmpty) {
136
+ throw Exception('Correct wallets not detected');
137
+ }
138
+ }
139
+
140
+ Future<Box<WalletInfo>> _reloadHiveWalletInfoBox() async {
141
+ final appDir = await getApplicationDocumentsDirectory();
142
+ await Hive.close();
143
+ Hive.init(appDir.path);
144
+
145
+ if (!Hive.isAdapterRegistered(WalletInfo.typeId)) {
146
+ Hive.registerAdapter(WalletInfoAdapter());
147
+ }
148
+
149
+ return await Hive.openBox<WalletInfo>(WalletInfo.boxName);
150
+ }
151
+
152
Future<void> _importPreferencesDump() async {
153
final appDir = await getApplicationDocumentsDirectory();
154
final preferencesFile = File('${appDir.path}/~_preferences_dump');
@@ -132,15 +159,26 @@ class BackupService {
159
160
final data =
161
json.decode(preferencesFile.readAsStringSync()) as Map<String, Object>;
162
+ String currentWalletName = data[PreferencesKey.currentWalletName] as String;
163
+ int currentWalletType = data[PreferencesKey.currentWalletType] as int;
164
+
165
+ final isCorrentCurrentWallet = _correctWallets
166
+ .any((info) => info.name == currentWalletName &&
167
+ info.type.index == currentWalletType);
168
+
169
+ if (!isCorrentCurrentWallet) {
170
+ currentWalletName = _correctWallets.first.name;
171
+ currentWalletType = _correctWallets.first.type.index;
172
+ }
173
174
await _sharedPreferences.setString(PreferencesKey.currentWalletName,
137
- data[PreferencesKey.currentWalletName] as String);
175
+ currentWalletName);
176
await _sharedPreferences.setInt(PreferencesKey.currentNodeIdKey,
177
data[PreferencesKey.currentNodeIdKey] as int);
178
await _sharedPreferences.setInt(PreferencesKey.currentBalanceDisplayModeKey,
179
data[PreferencesKey.currentBalanceDisplayModeKey] as int);
180
await _sharedPreferences.setInt(PreferencesKey.currentWalletType,
143
- data[PreferencesKey.currentWalletType] as int);
181
+ currentWalletType);
182
await _sharedPreferences.setString(PreferencesKey.currentFiatCurrencyKey,
183
data[PreferencesKey.currentFiatCurrencyKey] as String);
184
await _sharedPreferences.setBool(
lib/src/screens/dashboard/wallet_menu.dart
-1
@@ -52,7 +52,6 @@ class WalletMenu {
52
image: Image.asset('assets/images/open_book_menu.png',
53
height: 16, width: 16),
54
handler: () => Navigator.of(context).pushNamed(Routes.addressBook)),
55
- if(!isMoneroOnly)
55
WalletMenuItem(
56
title: S.current.backup,
57
image: Image.asset('assets/images/restore_wallet.png',
lib/src/screens/wallet_list/wallet_list_page.dart
+4
-2
@@ -80,7 +80,7 @@ class WalletListBodyState extends State<WalletListBody> {
80
: Theme.of(context).backgroundColor;
81
final row = GestureDetector(
82
onTap: () async {
83
- if (wallet.isCurrent) {
83
+ if (wallet.isCurrent || !wallet.isEnabled) {
84
return;
85
}
86
@@ -132,7 +132,9 @@ class WalletListBodyState extends State<WalletListBody> {
132
crossAxisAlignment:
133
CrossAxisAlignment.center,
134
children: <Widget>[
135
- _imageFor(type: wallet.type),
135
+ wallet.isEnabled
136
+ ? _imageFor(type: wallet.type)
137
+ : nonWalletTypeIcon,
138
SizedBox(width: 10),
139
Text(
140
wallet.name,
lib/src/screens/welcome/welcome_page.dart
+2
-7
@@ -161,13 +161,8 @@ class WelcomePage extends BasePage {
161
padding: EdgeInsets.only(top: 10),
162
child: PrimaryImageButton(
163
onPressed: () {
164
- if (isMoneroOnly) {
165
- Navigator.of(context).pushNamed(Routes.moneroRestoreWalletFromWelcome);
166
- } else {
167
- Navigator.pushNamed(context,
168
- Routes.restoreOptions);
169
- }
170
- },
164
+ Navigator.pushNamed(context, Routes.restoreOptions);
165
+ },
166
image: restoreWalletImage,
167
text: S
168
.of(context)
lib/view_model/backup_view_model.dart
+4
-2
@@ -7,6 +7,7 @@ import 'package:flutter/foundation.dart';
7
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
8
import 'package:mobx/mobx.dart';
9
import 'package:intl/intl.dart';
10
+import 'package:cake_wallet/wallet_type_utils.dart';
11
12
part 'backup_view_model.g.dart';
13
@@ -58,9 +59,10 @@ abstract class BackupViewModelBase with Store {
59
state = ExecutedSuccessfullyState();
60
final now = DateTime.now();
61
final formatter = DateFormat('yyyy-MM-dd_Hm');
62
+ final snakeAppName = approximatedAppName.replaceAll(' ', '_').toLowerCase();
63
+ final fileName = '${snakeAppName}_backup_${formatter.format(now)}';
64
62
- return BackupExportFile(backupContent.toList(),
63
- name: 'cake_wallet_backup_${formatter.format(now)}');
65
+ return BackupExportFile(backupContent.toList(), name: fileName);
66
} catch (e) {
67
print(e.toString());
68
state = FailureState(e.toString());
lib/view_model/wallet_list/wallet_list_item.dart
+6
-1
@@ -3,10 +3,15 @@ import 'package:cw_core/wallet_type.dart';
3
4
class WalletListItem {
5
const WalletListItem(
6
- {@required this.name, @required this.type, @required this.key, this.isCurrent = false});
6
+ {@required this.name,
7
+ @required this.type,
8
+ @required this.key,
9
+ this.isCurrent = false,
10
+ this.isEnabled = true});
11
12
final String name;
13
final WalletType type;
14
final bool isCurrent;
15
final dynamic key;
16
+ final bool isEnabled;
17
}
lib/view_model/wallet_list/wallet_list_view_model.dart
+3
-1
@@ -8,6 +8,7 @@ import 'package:cw_core/wallet_service.dart';
8
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
9
import 'package:cw_core/wallet_info.dart';
10
import 'package:cw_core/wallet_type.dart';
11
+import 'package:cake_wallet/wallet_types.g.dart';
12
13
part 'wallet_list_view_model.g.dart';
14
@@ -55,6 +56,7 @@ abstract class WalletListViewModelBase with Store {
56
type: info.type,
57
key: info.key,
58
isCurrent: info.name == _appStore.wallet.name &&
58
- info.type == _appStore.wallet.type)));
59
+ info.type == _appStore.wallet.type,
60
+ isEnabled: availableWalletTypes.contains(info.type))));
61
}
62
}
lib/wallet_type_utils.dart
+6
@@ -4,4 +4,10 @@ import 'package:cake_wallet/wallet_types.g.dart';
4
bool get isMoneroOnly {
5
return availableWalletTypes.length == 1
6
&& availableWalletTypes.first == WalletType.monero;
7
+}
8
+
9
+String get approximatedAppName {
10
+ return isMoneroOnly
11
+ ? 'Monero.com'
12
+ : 'Cake Wallet';
13
}
\ No newline at end of file