Bug missing polyseed (#1214)
* Move file.dart * Add seedFallback for missing polyseeds * Remove unused dependency of cw_bitcoin * Minor fix MacOS * Add more blockheight-date matching * Scan only last 2 days for new Polyseed wallets
Konstantin Ullrich committed
Dec 2, 2023 at 02:02 UTC
3b7f9a297cbe5aa4eb7ce9656af7685626e12618
10 files changed
+52
-32
cw_bitcoin/lib/electrum_transaction_history.dart
+4
-3
@@ -1,10 +1,11 @@
1
import 'dart:convert';
2
+
3
+import 'package:cw_bitcoin/electrum_transaction_info.dart';
4
import 'package:cw_core/pathForWallet.dart';
5
+import 'package:cw_core/transaction_history.dart';
6
+import 'package:cw_core/utils/file.dart';
7
import 'package:cw_core/wallet_info.dart';
8
import 'package:mobx/mobx.dart';
5
-import 'package:cw_core/transaction_history.dart';
6
-import 'package:cw_bitcoin/file.dart';
7
-import 'package:cw_bitcoin/electrum_transaction_info.dart';
9
10
part 'electrum_transaction_history.g.dart';
11
cw_bitcoin/lib/electrum_wallet.dart
+1
-1
@@ -18,7 +18,6 @@ import 'package:cw_bitcoin/electrum_balance.dart';
18
import 'package:cw_bitcoin/electrum_transaction_history.dart';
19
import 'package:cw_bitcoin/electrum_transaction_info.dart';
20
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
21
-import 'package:cw_bitcoin/file.dart';
21
import 'package:cw_bitcoin/pending_bitcoin_transaction.dart';
22
import 'package:cw_bitcoin/script_hash.dart';
23
import 'package:cw_bitcoin/utils.dart';
@@ -30,6 +29,7 @@ import 'package:cw_core/sync_status.dart';
29
import 'package:cw_core/transaction_direction.dart';
30
import 'package:cw_core/transaction_priority.dart';
31
import 'package:cw_core/unspent_coins_info.dart';
32
+import 'package:cw_core/utils/file.dart';
33
import 'package:cw_core/wallet_base.dart';
34
import 'package:cw_core/wallet_info.dart';
35
import 'package:flutter/foundation.dart';
cw_bitcoin/lib/electrum_wallet_snapshot.dart
+2
-2
@@ -1,8 +1,8 @@
1
import 'dart:convert';
2
import 'package:cw_bitcoin/bitcoin_address_record.dart';
3
import 'package:cw_bitcoin/electrum_balance.dart';
4
-import 'package:cw_bitcoin/file.dart';
4
import 'package:cw_core/pathForWallet.dart';
5
+import 'package:cw_core/utils/file.dart';
6
import 'package:cw_core/wallet_type.dart';
7
8
class ElectrumWallletSnapshot {
@@ -56,4 +56,4 @@ class ElectrumWallletSnapshot {
56
regularAddressIndex: regularAddressIndex,
57
changeAddressIndex: changeAddressIndex);
58
}
59
-}
\ No newline at end of file
59
+}
cw_bitcoin/pubspec.yaml
-1
@@ -30,7 +30,6 @@ dependencies:
30
rxdart: ^0.27.5
31
unorm_dart: ^0.2.0
32
cryptography: ^2.0.5
33
- encrypt: ^5.0.1
33
34
dev_dependencies:
35
flutter_test:
cw_core/lib/get_height_by_date.dart
+4
-1
@@ -118,7 +118,10 @@ final dates = {
118
"2023-6": 2898234,
119
"2023-7": 2919771,
120
"2023-8": 2942045,
121
- "2023-9": 2964280
121
+ "2023-9": 2964280,
122
+ "2023-10": 2985937,
123
+ "2023-11": 3008178,
124
+ "2023-12": 3029759
125
};
126
127
int getMoneroHeigthByDate({required DateTime date}) {
cw_core/lib/utils/file.dart
renamed
+2
-11
@@ -2,17 +2,8 @@ import 'dart:io';
2
import 'package:cw_core/key.dart';
3
import 'package:encrypt/encrypt.dart' as encrypt;
4
5
-Future<void> write(
6
- {required String path,
7
- required String password,
8
- required String data}) async {
9
- final keys = extractKeys(password);
10
- final key = encrypt.Key.fromBase64(keys.first);
11
- final iv = encrypt.IV.fromBase64(keys.last);
12
- final encrypted = await encode(key: key, iv: iv, data: data);
13
- final f = File(path);
14
- f.writeAsStringSync(encrypted);
15
-}
5
+Future<void> write({required String path, required String password, required String data}) async =>
6
+ writeData(path: path, password: password, data: data);
7
8
Future<void> writeData(
9
{required String path,
cw_monero/ios/Classes/monero_api.cpp
+3
-3
@@ -385,6 +385,9 @@ extern "C"
385
(uint64_t)restoreHeight,
386
std::string(spendKey));
387
388
+ // Cache Raw to support Polyseed
389
+ wallet->setCacheAttribute("cakewallet.seed", std::string(seed));
390
+
391
int status;
392
std::string errorString;
393
@@ -396,9 +399,6 @@ extern "C"
399
return false;
400
}
401
399
- // Cache Raw to support Polyseed
400
- wallet->setCacheAttribute("cakewallet.seed", std::string(seed));
401
-
402
change_current_wallet(wallet);
403
return true;
404
}
cw_monero/lib/monero_wallet.dart
+7
-2
@@ -97,7 +97,8 @@ abstract class MoneroWalletBase
97
ObservableMap<CryptoCurrency, MoneroBalance> balance;
98
99
@override
100
- String get seed => monero_wallet.getSeed();
100
+ String get seed => _seed;
101
+ String _seed = monero_wallet.getSeed();
102
103
@override
104
MoneroWalletKeys get keys => MoneroWalletKeys(
@@ -113,7 +114,11 @@ abstract class MoneroWalletBase
114
Timer? _autoSaveTimer;
115
List<MoneroUnspent> unspentCoins;
116
116
- Future<void> init() async {
117
+ Future<void> init({String seedFallback = ""}) async {
118
+ if (_seed.isEmpty) {
119
+ _seed = seedFallback;
120
+ }
121
+
122
await walletAddresses.init();
123
balance = ObservableMap<CryptoCurrency, MoneroBalance>.of(<CryptoCurrency, MoneroBalance>{
124
currency: MoneroBalance(
cw_monero/lib/monero_wallet_service.dart
+26
-5
@@ -2,6 +2,7 @@ import 'dart:io';
2
import 'package:cw_core/monero_wallet_utils.dart';
3
import 'package:cw_core/pathForWallet.dart';
4
import 'package:cw_core/unspent_coins_info.dart';
5
+import 'package:cw_core/utils/file.dart';
6
import 'package:cw_core/wallet_base.dart';
7
import 'package:cw_core/wallet_credentials.dart';
8
import 'package:cw_core/wallet_info.dart';
@@ -77,8 +78,12 @@ class MoneroWalletService extends WalletService<
78
final polyseed = Polyseed.create();
79
final lang = PolyseedLang.getByEnglishName(credentials.language);
80
81
+ final heightOverride =
82
+ getMoneroHeigthByDate(date: DateTime.now().subtract(Duration(days: 2)));
83
+
84
return _restoreFromPolyseed(
81
- path, credentials.password!, polyseed, credentials.walletInfo!, lang);
85
+ path, credentials.password!, polyseed, credentials.walletInfo!, lang,
86
+ overrideHeight: heightOverride);
87
}
88
89
await monero_wallet_manager.createWallet(
@@ -129,7 +134,12 @@ class MoneroWalletService extends WalletService<
134
return openWallet(name, password);
135
}
136
132
- await wallet.init();
137
+ if (wallet.seed.isEmpty) {
138
+ final seedFallback = await _getSeedBackup(path, password);
139
+ await wallet.init(seedFallback: seedFallback);
140
+ } else {
141
+ await wallet.init();
142
+ }
143
144
return wallet;
145
} catch (e) {
@@ -268,10 +278,11 @@ class MoneroWalletService extends WalletService<
278
279
Future<MoneroWallet> _restoreFromPolyseed(String path, String password, Polyseed polyseed,
280
WalletInfo walletInfo, PolyseedLang lang,
271
- {PolyseedCoin coin = PolyseedCoin.POLYSEED_MONERO}) async {
272
- final height = getMoneroHeigthByDate(
281
+ {PolyseedCoin coin = PolyseedCoin.POLYSEED_MONERO, int? overrideHeight}) async {
282
+ final height = overrideHeight ?? getMoneroHeigthByDate(
283
date: DateTime.fromMillisecondsSinceEpoch(polyseed.birthday * 1000));
284
final spendKey = keyToHexString(polyseed.generateKey(coin, 32));
285
+ final seed = polyseed.encode(lang, coin);
286
287
walletInfo.isRecovery = true;
288
walletInfo.restoreHeight = height;
@@ -279,10 +290,13 @@ class MoneroWalletService extends WalletService<
290
await monero_wallet_manager.restoreFromSpendKey(
291
path: path,
292
password: password,
282
- seed: polyseed.encode(lang, coin),
293
+ seed: seed,
294
language: lang.nameEnglish,
295
restoreHeight: height,
296
spendKey: spendKey);
297
+
298
+ await writeData(path: "$path.seed", password: password, data: seed);
299
+
300
final wallet = MoneroWallet(
301
walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource);
302
await wallet.init();
@@ -290,6 +304,13 @@ class MoneroWalletService extends WalletService<
304
return wallet;
305
}
306
307
+ Future<String> _getSeedBackup(String path, String password) async {
308
+ final seedFilePath = "$path.seed";
309
+ final seedFile = File(seedFilePath);
310
+ if (!seedFile.existsSync()) return "";
311
+ return read(path: seedFilePath, password: password);
312
+ }
313
+
314
Future<void> repairOldAndroidWallet(String name) async {
315
try {
316
if (!Platform.isAndroid) {
cw_monero/macos/Classes/monero_api.cpp
+3
-3
@@ -385,6 +385,9 @@ extern "C"
385
(uint64_t)restoreHeight,
386
std::string(spendKey));
387
388
+ // Cache Raw to support Polyseed
389
+ wallet->setCacheAttribute("cakewallet.seed", std::string(seed));
390
+
391
int status;
392
std::string errorString;
393
@@ -396,9 +399,6 @@ extern "C"
399
return false;
400
}
401
399
- // Cache Raw to support Polyseed
400
- wallet->setCacheAttribute("cakewallet.seed", std::string(seed));
401
-
402
change_current_wallet(wallet);
403
return true;
404
}