mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-06-28 12:29:51 +00:00
Cw 688 avoid wallet file corruption (#1582)
* CW-688 Store Seed and keys in .keys file * CW-688 Open wallet from keys in .keys file and migrate wallets using the old file * CW-688 Open wallet from keys in .keys file and migrate wallets using the old file * CW-688 Restore .keys file from .keys.backup * CW-688 Restore .keys file from .keys.backup * CW-688 Move saving .keys files into the save function instead of the service * CW-688 Handle corrupt wallets * CW-688 Handle corrupt wallets * CW-688 Remove code duplication * CW-688 Reduce cache dependency * wrap any file reading/writing function with try/catch [skip ci] --------- Co-authored-by: Konstantin Ullrich <konstantinullrich12@gmail.com>
This commit is contained in:
parent
8e4082d680
commit
fb33a6f23d
18 changed files with 433 additions and 144 deletions
|
@ -16,6 +16,7 @@ import 'package:cw_core/transaction_priority.dart';
|
|||
import 'package:cw_core/wallet_addresses.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/wallet_keys_file.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cw_tron/default_tron_tokens.dart';
|
||||
import 'package:cw_tron/file.dart';
|
||||
|
@ -37,7 +38,8 @@ part 'tron_wallet.g.dart';
|
|||
class TronWallet = TronWalletBase with _$TronWallet;
|
||||
|
||||
abstract class TronWalletBase
|
||||
extends WalletBase<TronBalance, TronTransactionHistory, TronTransactionInfo> with Store {
|
||||
extends WalletBase<TronBalance, TronTransactionHistory, TronTransactionInfo>
|
||||
with Store, WalletKeysFile {
|
||||
TronWalletBase({
|
||||
required WalletInfo walletInfo,
|
||||
String? mnemonic,
|
||||
|
@ -124,18 +126,36 @@ abstract class TronWalletBase
|
|||
required String password,
|
||||
required WalletInfo walletInfo,
|
||||
}) async {
|
||||
final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
|
||||
final path = await pathForWallet(name: name, type: walletInfo.type);
|
||||
final jsonSource = await read(path: path, password: password);
|
||||
final data = json.decode(jsonSource) as Map;
|
||||
final mnemonic = data['mnemonic'] as String?;
|
||||
final privateKey = data['private_key'] as String?;
|
||||
final balance = TronBalance.fromJSON(data['balance'] as String) ?? TronBalance(BigInt.zero);
|
||||
|
||||
Map<String, dynamic>? data;
|
||||
try {
|
||||
final jsonSource = await read(path: path, password: password);
|
||||
|
||||
data = json.decode(jsonSource) as Map<String, dynamic>;
|
||||
} catch (e) {
|
||||
if (!hasKeysFile) rethrow;
|
||||
}
|
||||
|
||||
final balance = TronBalance.fromJSON(data?['balance'] as String) ?? TronBalance(BigInt.zero);
|
||||
|
||||
final WalletKeysData keysData;
|
||||
// Migrate wallet from the old scheme to then new .keys file scheme
|
||||
if (!hasKeysFile) {
|
||||
final mnemonic = data!['mnemonic'] as String?;
|
||||
final privateKey = data['private_key'] as String?;
|
||||
|
||||
keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey);
|
||||
} else {
|
||||
keysData = await WalletKeysFile.readKeysFile(name, walletInfo.type, password);
|
||||
}
|
||||
|
||||
return TronWallet(
|
||||
walletInfo: walletInfo,
|
||||
password: password,
|
||||
mnemonic: mnemonic,
|
||||
privateKey: privateKey,
|
||||
mnemonic: keysData.mnemonic,
|
||||
privateKey: keysData.privateKey,
|
||||
initialBalance: balance,
|
||||
);
|
||||
}
|
||||
|
@ -163,9 +183,7 @@ abstract class TronWalletBase
|
|||
}) async {
|
||||
assert(mnemonic != null || privateKey != null);
|
||||
|
||||
if (privateKey != null) {
|
||||
return TronPrivateKey(privateKey);
|
||||
}
|
||||
if (privateKey != null) return TronPrivateKey(privateKey);
|
||||
|
||||
final seed = bip39.mnemonicToSeed(mnemonic!);
|
||||
|
||||
|
@ -181,14 +199,10 @@ abstract class TronWalletBase
|
|||
int calculateEstimatedFee(TransactionPriority priority, int? amount) => 0;
|
||||
|
||||
@override
|
||||
Future<void> changePassword(String password) {
|
||||
throw UnimplementedError("changePassword");
|
||||
}
|
||||
Future<void> changePassword(String password) => throw UnimplementedError("changePassword");
|
||||
|
||||
@override
|
||||
void close() {
|
||||
_transactionsUpdateTimer?.cancel();
|
||||
}
|
||||
void close() => _transactionsUpdateTimer?.cancel();
|
||||
|
||||
@action
|
||||
@override
|
||||
|
@ -406,12 +420,15 @@ abstract class TronWalletBase
|
|||
Object get keys => throw UnimplementedError("keys");
|
||||
|
||||
@override
|
||||
Future<void> rescan({required int height}) {
|
||||
throw UnimplementedError("rescan");
|
||||
}
|
||||
Future<void> rescan({required int height}) => throw UnimplementedError("rescan");
|
||||
|
||||
@override
|
||||
Future<void> save() async {
|
||||
if (!(await WalletKeysFile.hasKeysFile(walletInfo.name, walletInfo.type))) {
|
||||
await saveKeysFile(_password);
|
||||
saveKeysFile(_password, true);
|
||||
}
|
||||
|
||||
await walletAddresses.updateAddressesInBox();
|
||||
final path = await makePath();
|
||||
await write(path: path, password: _password, data: toJSON());
|
||||
|
@ -424,7 +441,8 @@ abstract class TronWalletBase
|
|||
@override
|
||||
String get privateKey => _tronPrivateKey.toHex();
|
||||
|
||||
Future<String> makePath() async => pathForWallet(name: walletInfo.name, type: walletInfo.type);
|
||||
@override
|
||||
WalletKeysData get walletKeysData => WalletKeysData(mnemonic: _mnemonic, privateKey: privateKey);
|
||||
|
||||
String toJSON() => json.encode({
|
||||
'mnemonic': _mnemonic,
|
||||
|
@ -512,7 +530,7 @@ abstract class TronWalletBase
|
|||
|
||||
@override
|
||||
Future<void> renameWalletFiles(String newWalletName) async {
|
||||
String transactionHistoryFileNameForWallet = 'tron_transactions.json';
|
||||
const transactionHistoryFileNameForWallet = 'tron_transactions.json';
|
||||
|
||||
final currentWalletPath = await pathForWallet(name: walletInfo.name, type: type);
|
||||
final currentWalletFile = File(currentWalletPath);
|
||||
|
@ -550,9 +568,7 @@ abstract class TronWalletBase
|
|||
Future<String> signMessage(String message, {String? address}) async =>
|
||||
_tronPrivateKey.signPersonalMessage(ascii.encode(message));
|
||||
|
||||
String getTronBase58AddressFromHex(String hexAddress) {
|
||||
return TronAddress(hexAddress).toAddress();
|
||||
}
|
||||
String getTronBase58AddressFromHex(String hexAddress) => TronAddress(hexAddress).toAddress();
|
||||
|
||||
void updateScanProviderUsageState(bool isEnabled) {
|
||||
if (isEnabled) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:bip39/bip39.dart' as bip39;
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:cw_core/balance.dart';
|
||||
import 'package:cw_core/pathForWallet.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
|
@ -14,7 +15,6 @@ import 'package:cw_tron/tron_exception.dart';
|
|||
import 'package:cw_tron/tron_wallet.dart';
|
||||
import 'package:cw_tron/tron_wallet_creation_credentials.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
class TronWalletService extends WalletService<
|
||||
TronNewWalletCredentials,
|
||||
|
@ -153,7 +153,8 @@ class TronWalletService extends WalletService<
|
|||
}
|
||||
|
||||
@override
|
||||
Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>> restoreFromHardwareWallet(TronNewWalletCredentials credentials) {
|
||||
Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>>
|
||||
restoreFromHardwareWallet(TronNewWalletCredentials credentials) {
|
||||
// TODO: implement restoreFromHardwareWallet
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue