From 1e3b53d2cf2dcaf3f2786d430d2497dcb25a2637 Mon Sep 17 00:00:00 2001 From: M Date: Tue, 6 Jul 2021 13:51:54 +0300 Subject: [PATCH] Added backups for monero wallet files. --- lib/monero/monero_wallet.dart | 2 + lib/monero/monero_wallet_service.dart | 16 ++--- lib/monero/monero_wallet_utils.dart | 88 +++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 12 deletions(-) create mode 100644 lib/monero/monero_wallet_utils.dart diff --git a/lib/monero/monero_wallet.dart b/lib/monero/monero_wallet.dart index e902f1080..4105e5de2 100644 --- a/lib/monero/monero_wallet.dart +++ b/lib/monero/monero_wallet.dart @@ -3,6 +3,7 @@ import 'package:cake_wallet/entities/transaction_priority.dart'; import 'package:cake_wallet/monero/monero_amount_format.dart'; import 'package:cake_wallet/monero/monero_transaction_creation_exception.dart'; import 'package:cake_wallet/monero/monero_transaction_info.dart'; +import 'package:cake_wallet/monero/monero_wallet_utils.dart'; import 'package:flutter/foundation.dart'; import 'package:mobx/mobx.dart'; import 'package:cw_monero/transaction_history.dart' @@ -246,6 +247,7 @@ abstract class MoneroWalletBase extends WalletBase getNodeHeight() async => monero_wallet.getNodeHeight(); diff --git a/lib/monero/monero_wallet_service.dart b/lib/monero/monero_wallet_service.dart index 7795b8700..824daf41a 100644 --- a/lib/monero/monero_wallet_service.dart +++ b/lib/monero/monero_wallet_service.dart @@ -1,5 +1,6 @@ import 'dart:io'; import 'package:cake_wallet/core/wallet_base.dart'; +import 'package:cake_wallet/monero/monero_wallet_utils.dart'; import 'package:hive/hive.dart'; import 'package:cw_monero/wallet_manager.dart' as monero_wallet_manager; import 'package:cw_monero/wallet.dart' as monero_wallet; @@ -55,16 +56,7 @@ class MoneroWalletService extends WalletService< MoneroWalletService(this.walletInfoSource); final Box walletInfoSource; - - static Future _removeCache(String name) async { - final path = await pathForWallet(name: name, type: WalletType.monero); - final cacheFile = File(path); - - if (cacheFile.existsSync()) { - cacheFile.deleteSync(); - } - } - + static bool walletFilesExist(String path) => !File(path).existsSync() && !File('$path.keys').existsSync(); @@ -120,7 +112,7 @@ class MoneroWalletService extends WalletService< final isValid = wallet.validate(); if (!isValid) { - await _removeCache(name); + await restoreOrResetWalletFiles(name); wallet.close(); return openWallet(name, password); } @@ -135,7 +127,7 @@ class MoneroWalletService extends WalletService< (e is WalletOpeningException && (e.message == 'std::bad_alloc' || e.message.contains('bad_alloc')))) { - await _removeCache(name); + await restoreOrResetWalletFiles(name); return openWallet(name, password); } diff --git a/lib/monero/monero_wallet_utils.dart b/lib/monero/monero_wallet_utils.dart new file mode 100644 index 000000000..b0e509085 --- /dev/null +++ b/lib/monero/monero_wallet_utils.dart @@ -0,0 +1,88 @@ +import 'dart:io'; +import 'package:cake_wallet/entities/pathForWallet.dart'; +import 'package:cake_wallet/entities/wallet_type.dart'; + +String backupFileName(String originalPath) { + final pathParts = originalPath.split('/'); + final newName = '#_${pathParts.last}'; + pathParts.removeLast(); + pathParts.add(newName); + return pathParts.join('/'); +} + +Future backupWalletFiles(String name) async { + final path = await pathForWallet(name: name, type: WalletType.monero); + final cacheFile = File(path); + final keysFile = File('$path.keys'); + final addressListFile = File('$path.address.txt'); + final newCacheFilePath = backupFileName(cacheFile.path); + final newKeysFilePath = backupFileName(keysFile.path); + final newAddressListFilePath = backupFileName(addressListFile.path); + + if (cacheFile.existsSync()) { + await cacheFile.copy(newCacheFilePath); + } + + if (keysFile.existsSync()) { + await keysFile.copy(newKeysFilePath); + } + + if (addressListFile.existsSync()) { + await addressListFile.copy(newAddressListFilePath); + } +} + +Future restoreWalletFiles(String name) async { + final walletDirPath = await pathForWalletDir(name: name, type: WalletType.monero); + final cacheFilePath = '$walletDirPath/$name'; + final keysFilePath = '$walletDirPath/$name.keys'; + final addressListFilePath = '$walletDirPath/$name.address.txt'; + final backupCacheFile = File(backupFileName(cacheFilePath)); + final backupKeysFile = File(backupFileName(keysFilePath)); + final backupAddressListFile = File(backupFileName(addressListFilePath)); + + if (backupCacheFile.existsSync()) { + await backupCacheFile.copy(cacheFilePath); + } + + if (backupKeysFile.existsSync()) { + await backupKeysFile.copy(keysFilePath); + } + + if (backupAddressListFile.existsSync()) { + await backupAddressListFile.copy(addressListFilePath); + } +} + +Future backupWalletFilesExists(String name) async { + final walletDirPath = await pathForWalletDir(name: name, type: WalletType.monero); + final cacheFilePath = '$walletDirPath/$name'; + final keysFilePath = '$walletDirPath/$name.keys'; + final addressListFilePath = '$walletDirPath/$name.address.txt'; + final backupCacheFile = File(backupFileName(cacheFilePath)); + final backupKeysFile = File(backupFileName(keysFilePath)); + final backupAddressListFile = File(backupFileName(addressListFilePath)); + + return backupCacheFile.existsSync() + && backupKeysFile.existsSync() + && backupAddressListFile.existsSync(); +} + +Future removeCache(String name) async { + final path = await pathForWallet(name: name, type: WalletType.monero); + final cacheFile = File(path); + + if (cacheFile.existsSync()) { + cacheFile.deleteSync(); + } +} + +Future restoreOrResetWalletFiles(String name) async { + final backupsExists = await backupWalletFilesExists(name); + + if (backupsExists) { + await restoreWalletFiles(name); + } + + removeCache(name); +} \ No newline at end of file