Add the code to enable removing Haven wallets (#2222)
Omar Hatem committed
Apr 23, 2025 at 12:19 UTC
698f0199d04166a855f706293b6a50529bac54a9
2 files changed
+47
-315
lib/di.dart
+3
-1
@@ -33,6 +33,7 @@ import 'package:cake_wallet/entities/exchange_api_mode.dart';
33
import 'package:cake_wallet/entities/hardware_wallet/require_hardware_wallet_connection.dart';
34
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
35
import 'package:cake_wallet/exchange/provider/trocador_exchange_provider.dart';
36
+import 'package:cake_wallet/haven/cw_haven.dart';
37
import 'package:cake_wallet/src/screens/dev/monero_background_sync.dart';
38
import 'package:cake_wallet/src/screens/dev/moneroc_call_profiler.dart';
39
import 'package:cake_wallet/src/screens/settings/background_sync_page.dart';
@@ -1115,8 +1116,9 @@ Future<void> setup({
1116
return zano!.createZanoWalletService(_walletInfoSource);
1117
case WalletType.decred:
1118
return decred!.createDecredWalletService(_walletInfoSource, _unspentCoinsInfoSource);
1118
- case WalletType.none:
1119
case WalletType.haven:
1120
+ return HavenWalletService(_walletInfoSource);
1121
+ case WalletType.none:
1122
throw Exception('Unexpected token: ${param1.toString()} for generating of WalletService');
1123
}
1124
});
lib/haven/cw_haven.dart
+44
-314
@@ -1,348 +1,78 @@
1
-part of 'haven.dart';
1
+import 'dart:io';
2
3
-class CWHavenAccountList extends HavenAccountList {
4
- CWHavenAccountList(this._wallet);
3
+import 'package:cw_core/balance.dart';
4
+import 'package:cw_core/pathForWallet.dart';
5
+import 'package:cw_core/transaction_history.dart';
6
+import 'package:cw_core/transaction_info.dart';
7
+import 'package:cw_core/wallet_base.dart';
8
+import 'package:cw_core/wallet_credentials.dart';
9
+import 'package:cw_core/wallet_info.dart';
10
+import 'package:cw_core/wallet_service.dart';
11
+import 'package:cw_core/wallet_type.dart';
12
+import 'package:hive/hive.dart';
13
6
- final Object _wallet;
14
+class HavenWalletService extends WalletService {
15
+ final Box<WalletInfo> walletInfoSource;
16
8
- @override
9
- @computed
10
- ObservableList<Account> get accounts {
11
- final havenWallet = _wallet as HavenWallet;
12
- final accounts = havenWallet.walletAddresses.accountList.accounts
13
- .map((acc) => Account(id: acc.id, label: acc.label))
14
- .toList();
15
- return ObservableList<Account>.of(accounts);
16
- }
17
-
18
- @override
19
- void update(Object wallet) {
20
- final havenWallet = wallet as HavenWallet;
21
- havenWallet.walletAddresses.accountList.update();
22
- }
23
-
24
- @override
25
- void refresh(Object wallet) {
26
- final havenWallet = wallet as HavenWallet;
27
- havenWallet.walletAddresses.accountList.refresh();
28
- }
29
-
30
- @override
31
- List<Account> getAll(Object wallet) {
32
- final havenWallet = wallet as HavenWallet;
33
- return havenWallet.walletAddresses.accountList
34
- .getAll()
35
- .map((acc) => Account(id: acc.id, label: acc.label))
36
- .toList();
37
- }
38
-
39
- @override
40
- Future<void> addAccount(Object wallet, {required String label}) async {
41
- final havenWallet = wallet as HavenWallet;
42
- await havenWallet.walletAddresses.accountList.addAccount(label: label);
43
- }
44
-
45
- @override
46
- Future<void> setLabelAccount(Object wallet,
47
- {required int accountIndex, required String label}) async {
48
- final havenWallet = wallet as HavenWallet;
49
- await havenWallet.walletAddresses.accountList
50
- .setLabelAccount(accountIndex: accountIndex, label: label);
51
- }
52
-}
53
-
54
-class CWHavenSubaddressList extends MoneroSubaddressList {
55
- CWHavenSubaddressList(this._wallet);
56
-
57
- final Object _wallet;
58
-
59
- @override
60
- @computed
61
- ObservableList<Subaddress> get subaddresses {
62
- final havenWallet = _wallet as HavenWallet;
63
- final subAddresses = havenWallet.walletAddresses.subaddressList.subaddresses
64
- .map((sub) => Subaddress(id: sub.id, address: sub.address, label: sub.label))
65
- .toList();
66
- return ObservableList<Subaddress>.of(subAddresses);
67
- }
68
-
69
- @override
70
- void update(Object wallet, {required int accountIndex}) {
71
- final havenWallet = wallet as HavenWallet;
72
- havenWallet.walletAddresses.subaddressList.update(accountIndex: accountIndex);
73
- }
74
-
75
- @override
76
- void refresh(Object wallet, {required int accountIndex}) {
77
- final havenWallet = wallet as HavenWallet;
78
- havenWallet.walletAddresses.subaddressList.refresh(accountIndex: accountIndex);
79
- }
80
-
81
- @override
82
- List<Subaddress> getAll(Object wallet) {
83
- final havenWallet = wallet as HavenWallet;
84
- return havenWallet.walletAddresses.subaddressList
85
- .getAll()
86
- .map((sub) => Subaddress(id: sub.id, label: sub.label, address: sub.address))
87
- .toList();
88
- }
89
-
90
- @override
91
- Future<void> addSubaddress(Object wallet,
92
- {required int accountIndex, required String label}) async {
93
- final havenWallet = wallet as HavenWallet;
94
- await havenWallet.walletAddresses.subaddressList
95
- .addSubaddress(accountIndex: accountIndex, label: label);
96
- }
97
-
98
- @override
99
- Future<void> setLabelSubaddress(Object wallet,
100
- {required int accountIndex, required int addressIndex, required String label}) async {
101
- final havenWallet = wallet as HavenWallet;
102
- await havenWallet.walletAddresses.subaddressList
103
- .setLabelSubaddress(accountIndex: accountIndex, addressIndex: addressIndex, label: label);
104
- }
105
-}
106
-
107
-class CWHavenWalletDetails extends HavenWalletDetails {
108
- CWHavenWalletDetails(this._wallet);
109
-
110
- final Object _wallet;
111
-
112
- @computed
113
- @override
114
- Account get account {
115
- final havenWallet = _wallet as HavenWallet;
116
- final acc = havenWallet.walletAddresses.account as monero_account.Account;
117
- return Account(id: acc.id, label: acc.label);
118
- }
119
-
120
- @computed
121
- @override
122
- HavenBalance get balance {
123
- final havenWallet = _wallet as HavenWallet;
124
- final balance = havenWallet.balance;
125
- throw Exception('Unimplemented');
126
- //return HavenBalance(
127
- // fullBalance: balance.fullBalance,
128
- // unlockedBalance: balance.unlockedBalance);
129
- }
130
-}
131
-
132
-class CWHaven extends Haven {
133
- @override
134
- HavenAccountList getAccountList(Object wallet) {
135
- return CWHavenAccountList(wallet);
136
- }
17
+ HavenWalletService(this.walletInfoSource);
18
19
@override
139
- MoneroSubaddressList getSubaddressList(Object wallet) {
140
- return CWHavenSubaddressList(wallet);
141
- }
20
+ WalletType getType() => WalletType.haven;
21
22
@override
144
- TransactionHistoryBase getTransactionHistory(Object wallet) {
145
- final havenWallet = wallet as HavenWallet;
146
- return havenWallet.transactionHistory;
147
- }
148
-
149
- @override
150
- HavenWalletDetails getMoneroWalletDetails(Object wallet) {
151
- return CWHavenWalletDetails(wallet);
152
- }
23
+ Future<void> remove(String wallet) async {
24
+ final path = await pathForWalletDir(name: wallet, type: WalletType.haven);
25
154
- @override
155
- int getHeightByDate({required DateTime date}) => getHavenHeightByDate(date: date);
156
-
157
- @override
158
- Future<int> getCurrentHeight() => getHavenCurrentHeight();
159
-
160
- @override
161
- TransactionPriority getDefaultTransactionPriority() {
162
- return MoneroTransactionPriority.automatic;
163
- }
26
+ final file = Directory(path);
27
+ final isExist = file.existsSync();
28
165
- @override
166
- TransactionPriority deserializeMoneroTransactionPriority({required int raw}) {
167
- return MoneroTransactionPriority.deserialize(raw: raw);
168
- }
169
-
170
- @override
171
- List<TransactionPriority> getTransactionPriorities() {
172
- return MoneroTransactionPriority.all;
173
- }
174
-
175
- @override
176
- List<String> getMoneroWordList(String language) {
177
- switch (language.toLowerCase()) {
178
- case 'english':
179
- return EnglishMnemonics.words;
180
- case 'chinese (simplified)':
181
- return ChineseSimplifiedMnemonics.words;
182
- case 'dutch':
183
- return DutchMnemonics.words;
184
- case 'german':
185
- return GermanMnemonics.words;
186
- case 'japanese':
187
- return JapaneseMnemonics.words;
188
- case 'portuguese':
189
- return PortugueseMnemonics.words;
190
- case 'russian':
191
- return RussianMnemonics.words;
192
- case 'spanish':
193
- return SpanishMnemonics.words;
194
- case 'french':
195
- return FrenchMnemonics.words;
196
- case 'italian':
197
- return ItalianMnemonics.words;
198
- default:
199
- return EnglishMnemonics.words;
29
+ if (isExist) {
30
+ await file.delete(recursive: true);
31
}
201
- }
202
-
203
- @override
204
- WalletCredentials createHavenRestoreWalletFromKeysCredentials(
205
- {required String name,
206
- required String spendKey,
207
- required String viewKey,
208
- required String address,
209
- required String password,
210
- required String language,
211
- required int height}) {
212
- return HavenRestoreWalletFromKeysCredentials(
213
- name: name,
214
- spendKey: spendKey,
215
- viewKey: viewKey,
216
- address: address,
217
- password: password,
218
- language: language,
219
- height: height);
220
- }
32
222
- @override
223
- WalletCredentials createHavenRestoreWalletFromSeedCredentials(
224
- {required String name,
225
- required String password,
226
- required int height,
227
- required String mnemonic}) {
228
- return HavenRestoreWalletFromSeedCredentials(
229
- name: name, password: password, height: height, mnemonic: mnemonic);
33
+ final walletInfo = walletInfoSource.values
34
+ .firstWhere((info) => info.id == WalletBase.idFor(wallet, getType()));
35
+ await walletInfoSource.delete(walletInfo.key);
36
}
37
38
@override
233
- WalletCredentials createHavenNewWalletCredentials(
234
- {required String name, required String language, String? password}) {
235
- return HavenNewWalletCredentials(name: name, password: password, language: language);
39
+ Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>> create(
40
+ WalletCredentials credentials,
41
+ {bool? isTestnet}) {
42
+ throw UnimplementedError();
43
}
44
45
@override
239
- Map<String, String> getKeys(Object wallet) {
240
- final havenWallet = wallet as HavenWallet;
241
- final keys = havenWallet.keys;
242
- return <String, String>{
243
- 'privateSpendKey': keys.privateSpendKey,
244
- 'privateViewKey': keys.privateViewKey,
245
- 'publicSpendKey': keys.publicSpendKey,
246
- 'publicViewKey': keys.publicViewKey
247
- };
46
+ Future<bool> isWalletExit(String name) {
47
+ throw UnimplementedError();
48
}
49
50
@override
251
- Object createHavenTransactionCreationCredentials(
252
- {required List<Output> outputs,
253
- required TransactionPriority priority,
254
- required String assetType}) {
255
- return HavenTransactionCreationCredentials(
256
- outputs: outputs
257
- .map((out) => OutputInfo(
258
- fiatAmount: out.fiatAmount,
259
- cryptoAmount: out.cryptoAmount,
260
- address: out.address,
261
- note: out.note,
262
- sendAll: out.sendAll,
263
- extractedAddress: out.extractedAddress,
264
- isParsedAddress: out.isParsedAddress,
265
- formattedCryptoAmount: out.formattedCryptoAmount))
266
- .toList(),
267
- priority: priority as MoneroTransactionPriority,
268
- assetType: assetType);
51
+ Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>> openWallet(
52
+ String name, String password) {
53
+ throw UnimplementedError();
54
}
55
56
@override
272
- String formatterMoneroAmountToString({required int amount}) {
273
- return moneroAmountToString(amount: amount);
57
+ Future<void> rename(String currentName, String password, String newName) {
58
+ throw UnimplementedError();
59
}
60
61
@override
277
- double formatterMoneroAmountToDouble({required int amount}) {
278
- return moneroAmountToDouble(amount: amount);
62
+ Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>>
63
+ restoreFromHardwareWallet(WalletCredentials credentials) {
64
+ throw UnimplementedError();
65
}
66
67
@override
282
- int formatterMoneroParseAmount({required String amount}) {
283
- return moneroParseAmount(amount: amount);
68
+ Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>>
69
+ restoreFromKeys(WalletCredentials credentials, {bool? isTestnet}) {
70
+ throw UnimplementedError();
71
}
72
73
@override
287
- Account getCurrentAccount(Object wallet) {
288
- final havenWallet = wallet as HavenWallet;
289
- final acc = havenWallet.walletAddresses.account as monero_account.Account;
290
- return Account(id: acc.id, label: acc.label);
74
+ Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>>
75
+ restoreFromSeed(WalletCredentials credentials, {bool? isTestnet}) {
76
+ throw UnimplementedError();
77
}
292
-
293
- @override
294
- void setCurrentAccount(Object wallet, int id, String label) {
295
- final havenWallet = wallet as HavenWallet;
296
- havenWallet.walletAddresses.account = monero_account.Account(id: id, label: label);
297
- }
298
-
299
- @override
300
- void onStartup() {
301
- monero_wallet_api.onStartup();
302
- }
303
-
304
- @override
305
- int getTransactionInfoAccountId(TransactionInfo tx) {
306
- final havenTransactionInfo = tx as HavenTransactionInfo;
307
- return havenTransactionInfo.accountIndex;
308
- }
309
-
310
- @override
311
- Future<void> backupHavenSeeds(Box<HavenSeedStore> havenSeedStore) async {
312
- final walletInfoSource = await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
313
- final wallets = walletInfoSource.values
314
- .where((element) => element.type == WalletType.haven);
315
- for (var w in wallets) {
316
- final walletService = HavenWalletService(walletInfoSource);
317
- final flutterSecureStorage = secureStorageShared;
318
- final keyService = KeyService(flutterSecureStorage);
319
- final password = await keyService.getWalletPassword(walletName: w.name);
320
- final wallet = await walletService.openWallet(w.name, password);
321
- await havenSeedStore.add(HavenSeedStore(id: wallet.id, seed: wallet.seed));
322
- wallet.close();
323
- }
324
- await havenSeedStore.flush();
325
- }
326
-
327
- @override
328
- WalletService createHavenWalletService(Box<WalletInfo> walletInfoSource) {
329
- return HavenWalletService(walletInfoSource);
330
- }
331
-
332
- @override
333
- String getTransactionAddress(Object wallet, int accountIndex, int addressIndex) {
334
- final havenWallet = wallet as HavenWallet;
335
- return havenWallet.getTransactionAddress(accountIndex, addressIndex);
336
- }
337
-
338
- @override
339
- CryptoCurrency assetOfTransaction(TransactionInfo tx) {
340
- final transaction = tx as HavenTransactionInfo;
341
- final asset = CryptoCurrency.fromString(transaction.assetType);
342
- return asset;
343
- }
344
-
345
- @override
346
- List<AssetRate> getAssetRate() =>
347
- getRate().map((rate) => AssetRate(rate.getAssetType(), rate.getRate())).toList();
78
}