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
This commit is contained in:
Konstantin Ullrich 2023-12-02 02:02:55 +01:00 committed by GitHub
parent 3760285a64
commit 3b7f9a297c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 52 additions and 32 deletions

View file

@ -1,10 +1,11 @@
import 'dart:convert'; import 'dart:convert';
import 'package:cw_bitcoin/electrum_transaction_info.dart';
import 'package:cw_core/pathForWallet.dart'; import 'package:cw_core/pathForWallet.dart';
import 'package:cw_core/transaction_history.dart';
import 'package:cw_core/utils/file.dart';
import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_info.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:cw_core/transaction_history.dart';
import 'package:cw_bitcoin/file.dart';
import 'package:cw_bitcoin/electrum_transaction_info.dart';
part 'electrum_transaction_history.g.dart'; part 'electrum_transaction_history.g.dart';

View file

@ -18,7 +18,6 @@ import 'package:cw_bitcoin/electrum_balance.dart';
import 'package:cw_bitcoin/electrum_transaction_history.dart'; import 'package:cw_bitcoin/electrum_transaction_history.dart';
import 'package:cw_bitcoin/electrum_transaction_info.dart'; import 'package:cw_bitcoin/electrum_transaction_info.dart';
import 'package:cw_bitcoin/electrum_wallet_addresses.dart'; import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
import 'package:cw_bitcoin/file.dart';
import 'package:cw_bitcoin/pending_bitcoin_transaction.dart'; import 'package:cw_bitcoin/pending_bitcoin_transaction.dart';
import 'package:cw_bitcoin/script_hash.dart'; import 'package:cw_bitcoin/script_hash.dart';
import 'package:cw_bitcoin/utils.dart'; import 'package:cw_bitcoin/utils.dart';
@ -30,6 +29,7 @@ import 'package:cw_core/sync_status.dart';
import 'package:cw_core/transaction_direction.dart'; import 'package:cw_core/transaction_direction.dart';
import 'package:cw_core/transaction_priority.dart'; import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/unspent_coins_info.dart'; import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/utils/file.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_info.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';

View file

@ -1,8 +1,8 @@
import 'dart:convert'; import 'dart:convert';
import 'package:cw_bitcoin/bitcoin_address_record.dart'; import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/electrum_balance.dart'; import 'package:cw_bitcoin/electrum_balance.dart';
import 'package:cw_bitcoin/file.dart';
import 'package:cw_core/pathForWallet.dart'; import 'package:cw_core/pathForWallet.dart';
import 'package:cw_core/utils/file.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
class ElectrumWallletSnapshot { class ElectrumWallletSnapshot {
@ -56,4 +56,4 @@ class ElectrumWallletSnapshot {
regularAddressIndex: regularAddressIndex, regularAddressIndex: regularAddressIndex,
changeAddressIndex: changeAddressIndex); changeAddressIndex: changeAddressIndex);
} }
} }

View file

@ -30,7 +30,6 @@ dependencies:
rxdart: ^0.27.5 rxdart: ^0.27.5
unorm_dart: ^0.2.0 unorm_dart: ^0.2.0
cryptography: ^2.0.5 cryptography: ^2.0.5
encrypt: ^5.0.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View file

@ -118,7 +118,10 @@ final dates = {
"2023-6": 2898234, "2023-6": 2898234,
"2023-7": 2919771, "2023-7": 2919771,
"2023-8": 2942045, "2023-8": 2942045,
"2023-9": 2964280 "2023-9": 2964280,
"2023-10": 2985937,
"2023-11": 3008178,
"2023-12": 3029759
}; };
int getMoneroHeigthByDate({required DateTime date}) { int getMoneroHeigthByDate({required DateTime date}) {

View file

@ -2,17 +2,8 @@ import 'dart:io';
import 'package:cw_core/key.dart'; import 'package:cw_core/key.dart';
import 'package:encrypt/encrypt.dart' as encrypt; import 'package:encrypt/encrypt.dart' as encrypt;
Future<void> write( Future<void> write({required String path, required String password, required String data}) async =>
{required String path, writeData(path: path, password: password, data: data);
required String password,
required String data}) async {
final keys = extractKeys(password);
final key = encrypt.Key.fromBase64(keys.first);
final iv = encrypt.IV.fromBase64(keys.last);
final encrypted = await encode(key: key, iv: iv, data: data);
final f = File(path);
f.writeAsStringSync(encrypted);
}
Future<void> writeData( Future<void> writeData(
{required String path, {required String path,

View file

@ -385,6 +385,9 @@ extern "C"
(uint64_t)restoreHeight, (uint64_t)restoreHeight,
std::string(spendKey)); std::string(spendKey));
// Cache Raw to support Polyseed
wallet->setCacheAttribute("cakewallet.seed", std::string(seed));
int status; int status;
std::string errorString; std::string errorString;
@ -396,9 +399,6 @@ extern "C"
return false; return false;
} }
// Cache Raw to support Polyseed
wallet->setCacheAttribute("cakewallet.seed", std::string(seed));
change_current_wallet(wallet); change_current_wallet(wallet);
return true; return true;
} }

View file

@ -97,7 +97,8 @@ abstract class MoneroWalletBase
ObservableMap<CryptoCurrency, MoneroBalance> balance; ObservableMap<CryptoCurrency, MoneroBalance> balance;
@override @override
String get seed => monero_wallet.getSeed(); String get seed => _seed;
String _seed = monero_wallet.getSeed();
@override @override
MoneroWalletKeys get keys => MoneroWalletKeys( MoneroWalletKeys get keys => MoneroWalletKeys(
@ -113,7 +114,11 @@ abstract class MoneroWalletBase
Timer? _autoSaveTimer; Timer? _autoSaveTimer;
List<MoneroUnspent> unspentCoins; List<MoneroUnspent> unspentCoins;
Future<void> init() async { Future<void> init({String seedFallback = ""}) async {
if (_seed.isEmpty) {
_seed = seedFallback;
}
await walletAddresses.init(); await walletAddresses.init();
balance = ObservableMap<CryptoCurrency, MoneroBalance>.of(<CryptoCurrency, MoneroBalance>{ balance = ObservableMap<CryptoCurrency, MoneroBalance>.of(<CryptoCurrency, MoneroBalance>{
currency: MoneroBalance( currency: MoneroBalance(

View file

@ -2,6 +2,7 @@ import 'dart:io';
import 'package:cw_core/monero_wallet_utils.dart'; import 'package:cw_core/monero_wallet_utils.dart';
import 'package:cw_core/pathForWallet.dart'; import 'package:cw_core/pathForWallet.dart';
import 'package:cw_core/unspent_coins_info.dart'; import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/utils/file.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_credentials.dart'; import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_info.dart';
@ -77,8 +78,12 @@ class MoneroWalletService extends WalletService<
final polyseed = Polyseed.create(); final polyseed = Polyseed.create();
final lang = PolyseedLang.getByEnglishName(credentials.language); final lang = PolyseedLang.getByEnglishName(credentials.language);
final heightOverride =
getMoneroHeigthByDate(date: DateTime.now().subtract(Duration(days: 2)));
return _restoreFromPolyseed( return _restoreFromPolyseed(
path, credentials.password!, polyseed, credentials.walletInfo!, lang); path, credentials.password!, polyseed, credentials.walletInfo!, lang,
overrideHeight: heightOverride);
} }
await monero_wallet_manager.createWallet( await monero_wallet_manager.createWallet(
@ -129,7 +134,12 @@ class MoneroWalletService extends WalletService<
return openWallet(name, password); return openWallet(name, password);
} }
await wallet.init(); if (wallet.seed.isEmpty) {
final seedFallback = await _getSeedBackup(path, password);
await wallet.init(seedFallback: seedFallback);
} else {
await wallet.init();
}
return wallet; return wallet;
} catch (e) { } catch (e) {
@ -268,10 +278,11 @@ class MoneroWalletService extends WalletService<
Future<MoneroWallet> _restoreFromPolyseed(String path, String password, Polyseed polyseed, Future<MoneroWallet> _restoreFromPolyseed(String path, String password, Polyseed polyseed,
WalletInfo walletInfo, PolyseedLang lang, WalletInfo walletInfo, PolyseedLang lang,
{PolyseedCoin coin = PolyseedCoin.POLYSEED_MONERO}) async { {PolyseedCoin coin = PolyseedCoin.POLYSEED_MONERO, int? overrideHeight}) async {
final height = getMoneroHeigthByDate( final height = overrideHeight ?? getMoneroHeigthByDate(
date: DateTime.fromMillisecondsSinceEpoch(polyseed.birthday * 1000)); date: DateTime.fromMillisecondsSinceEpoch(polyseed.birthday * 1000));
final spendKey = keyToHexString(polyseed.generateKey(coin, 32)); final spendKey = keyToHexString(polyseed.generateKey(coin, 32));
final seed = polyseed.encode(lang, coin);
walletInfo.isRecovery = true; walletInfo.isRecovery = true;
walletInfo.restoreHeight = height; walletInfo.restoreHeight = height;
@ -279,10 +290,13 @@ class MoneroWalletService extends WalletService<
await monero_wallet_manager.restoreFromSpendKey( await monero_wallet_manager.restoreFromSpendKey(
path: path, path: path,
password: password, password: password,
seed: polyseed.encode(lang, coin), seed: seed,
language: lang.nameEnglish, language: lang.nameEnglish,
restoreHeight: height, restoreHeight: height,
spendKey: spendKey); spendKey: spendKey);
await writeData(path: "$path.seed", password: password, data: seed);
final wallet = MoneroWallet( final wallet = MoneroWallet(
walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource); walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource);
await wallet.init(); await wallet.init();
@ -290,6 +304,13 @@ class MoneroWalletService extends WalletService<
return wallet; return wallet;
} }
Future<String> _getSeedBackup(String path, String password) async {
final seedFilePath = "$path.seed";
final seedFile = File(seedFilePath);
if (!seedFile.existsSync()) return "";
return read(path: seedFilePath, password: password);
}
Future<void> repairOldAndroidWallet(String name) async { Future<void> repairOldAndroidWallet(String name) async {
try { try {
if (!Platform.isAndroid) { if (!Platform.isAndroid) {

View file

@ -385,6 +385,9 @@ extern "C"
(uint64_t)restoreHeight, (uint64_t)restoreHeight,
std::string(spendKey)); std::string(spendKey));
// Cache Raw to support Polyseed
wallet->setCacheAttribute("cakewallet.seed", std::string(seed));
int status; int status;
std::string errorString; std::string errorString;
@ -396,9 +399,6 @@ extern "C"
return false; return false;
} }
// Cache Raw to support Polyseed
wallet->setCacheAttribute("cakewallet.seed", std::string(seed));
change_current_wallet(wallet); change_current_wallet(wallet);
return true; return true;
} }