85 lines
2.3 KiB
Dart
85 lines
2.3 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:logger/logger.dart';
|
|
|
|
import 'app_paths.dart';
|
|
|
|
class WalletCacheRecovery {
|
|
WalletCacheRecovery({required Logger logger}) : _logger = logger;
|
|
|
|
final Logger _logger;
|
|
|
|
Future<void> markOpenAttempt(String walletPath) async {
|
|
final marker = await _markerFile();
|
|
final payload = jsonEncode({
|
|
'path': walletPath,
|
|
'timestamp': DateTime.now().toIso8601String(),
|
|
});
|
|
await marker.writeAsString(payload);
|
|
}
|
|
|
|
Future<void> clearOpenAttempt() async {
|
|
for (final marker in await _markerFiles()) {
|
|
if (await marker.exists()) {
|
|
await marker.delete();
|
|
}
|
|
}
|
|
}
|
|
|
|
Future<bool> recoverIfNeeded(String walletPath) async {
|
|
for (final marker in await _markerFiles()) {
|
|
if (!await marker.exists()) {
|
|
continue;
|
|
}
|
|
final pendingPath = await _readPendingPath(marker);
|
|
if (pendingPath == null || pendingPath != walletPath) {
|
|
continue;
|
|
}
|
|
final recovered = await _rebuildCache(walletPath);
|
|
await clearOpenAttempt();
|
|
return recovered;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
Future<File> _markerFile() async {
|
|
return AppPaths.walletOpenMarkerFile();
|
|
}
|
|
|
|
Future<List<File>> _markerFiles() async {
|
|
final files = <File>[await _markerFile()];
|
|
files.addAll(await AppPaths.legacyWalletOpenMarkerFiles());
|
|
return files;
|
|
}
|
|
|
|
Future<String?> _readPendingPath(File marker) async {
|
|
try {
|
|
final raw = await marker.readAsString();
|
|
final json = jsonDecode(raw) as Map<String, dynamic>;
|
|
final path = json['path'];
|
|
return path is String ? path : null;
|
|
} catch (error) {
|
|
_logger.w('Failed to read wallet open marker: $error');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
Future<bool> _rebuildCache(String walletPath) async {
|
|
final walletFile = File(walletPath);
|
|
final keysFile = File('$walletPath.keys');
|
|
if (!await walletFile.exists()) {
|
|
return false;
|
|
}
|
|
if (!await keysFile.exists()) {
|
|
_logger.w('Wallet keys not found for recovery: $walletPath');
|
|
return false;
|
|
}
|
|
final backupPath =
|
|
'${walletFile.path}.cache.bak.${DateTime.now().millisecondsSinceEpoch}';
|
|
await walletFile.rename(backupPath);
|
|
_logger.w('Wallet cache moved to $backupPath');
|
|
return true;
|
|
}
|
|
}
|