mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-28 06:28:41 +01:00
Upstream reformatted its whole tree in 16ddc0837. Matching it removes
formatting from the conflict surface of this and every later sync.
133 lines
4.6 KiB
Dart
133 lines
4.6 KiB
Dart
import 'dart:convert';
|
|
import 'dart:developer' as dev;
|
|
import 'dart:io';
|
|
|
|
import 'package:cw_core/balance.dart';
|
|
import 'package:cw_core/encryption_file_utils.dart';
|
|
import 'package:cw_core/pathForWallet.dart';
|
|
import 'package:cw_core/transaction_history.dart';
|
|
import 'package:cw_core/transaction_info.dart';
|
|
import 'package:cw_core/wallet_base.dart';
|
|
import 'package:cw_core/wallet_type.dart';
|
|
|
|
mixin WalletKeysFile<BalanceType extends Balance, HistoryType extends TransactionHistoryBase,
|
|
TransactionType extends TransactionInfo>
|
|
on WalletBase<BalanceType, HistoryType, TransactionType> {
|
|
Future<String> makePath() => pathForWallet(name: walletInfo.name, type: walletInfo.type);
|
|
|
|
// this needs to be overridden
|
|
WalletKeysData get walletKeysData;
|
|
|
|
Future<String> makeKeysFilePath() async => "${await makePath()}.keys";
|
|
|
|
Future<void> saveKeysFile(String password, EncryptionFileUtils encryptionFileUtils,
|
|
[bool isBackup = false]) async {
|
|
try {
|
|
final rootPath = await makeKeysFilePath();
|
|
final path = "$rootPath${isBackup ? ".backup" : ""}";
|
|
dev.log("Saving .keys file '$path'");
|
|
await encryptionFileUtils.write(
|
|
path: path, password: password, data: walletKeysData.toJSON());
|
|
} catch (_) {}
|
|
}
|
|
|
|
static Future<void> createKeysFile(String name, WalletType type, String password,
|
|
WalletKeysData walletKeysData, EncryptionFileUtils encryptionFileUtils,
|
|
[bool withBackup = true]) async {
|
|
try {
|
|
final rootPath = await pathForWallet(name: name, type: type);
|
|
final path = "$rootPath.keys";
|
|
|
|
dev.log("Saving .keys file '$path'");
|
|
await encryptionFileUtils.write(
|
|
path: path, password: password, data: walletKeysData.toJSON());
|
|
|
|
if (withBackup) {
|
|
dev.log("Saving .keys.backup file '$path.backup'");
|
|
await encryptionFileUtils.write(
|
|
path: "$path.backup", password: password, data: walletKeysData.toJSON());
|
|
}
|
|
} catch (_) {}
|
|
}
|
|
|
|
static Future<bool> hasKeysFile(String name, WalletType type) async {
|
|
try {
|
|
final path = await pathForWallet(name: name, type: type);
|
|
return File("$path.keys").existsSync() || File("$path.keys.backup").existsSync();
|
|
} catch (_) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static Future<WalletKeysData> readKeysFile(
|
|
String name,
|
|
WalletType type,
|
|
String password,
|
|
EncryptionFileUtils encryptionFileUtils,
|
|
) async {
|
|
final path = await pathForWallet(name: name, type: type);
|
|
|
|
var readPath = "$path.keys";
|
|
try {
|
|
if (!File(readPath).existsSync()) throw Exception("No .keys file found for $name $type");
|
|
|
|
final jsonSource = await encryptionFileUtils.read(path: readPath, password: password);
|
|
final data = json.decode(jsonSource) as Map<String, dynamic>;
|
|
return WalletKeysData.fromJSON(data);
|
|
} catch (e) {
|
|
dev.log("Failed to read .keys file. Trying .keys.backup file...");
|
|
|
|
readPath = "$readPath.backup";
|
|
if (!File(readPath).existsSync())
|
|
throw Exception("No .keys nor a .keys.backup file found for $name $type");
|
|
|
|
final jsonSource = await encryptionFileUtils.read(path: readPath, password: password);
|
|
final data = json.decode(jsonSource) as Map<String, dynamic>;
|
|
final keysData = WalletKeysData.fromJSON(data);
|
|
|
|
dev.log("Restoring .keys from .keys.backup");
|
|
createKeysFile(name, type, password, keysData, encryptionFileUtils, false);
|
|
return keysData;
|
|
}
|
|
}
|
|
}
|
|
|
|
class WalletKeysData {
|
|
final String? privateKey;
|
|
final String? mnemonic;
|
|
final String? altMnemonic;
|
|
final String? passphrase;
|
|
final String? xPub;
|
|
final String? scanSecret;
|
|
final String? spendPubkey;
|
|
|
|
WalletKeysData(
|
|
{this.privateKey,
|
|
this.mnemonic,
|
|
this.altMnemonic,
|
|
this.passphrase,
|
|
this.xPub,
|
|
this.scanSecret,
|
|
this.spendPubkey});
|
|
|
|
String toJSON() => jsonEncode({
|
|
"privateKey": privateKey,
|
|
"mnemonic": mnemonic,
|
|
if (altMnemonic != null) "altMnemonic": altMnemonic,
|
|
if (passphrase != null) "passphrase": passphrase,
|
|
if (xPub != null) "xPub": xPub,
|
|
if (scanSecret != null) "scanSecret": scanSecret,
|
|
if (spendPubkey != null) "spendPubkey": spendPubkey,
|
|
});
|
|
|
|
static WalletKeysData fromJSON(Map<String, dynamic> json) => WalletKeysData(
|
|
privateKey: json["privateKey"] as String?,
|
|
mnemonic: json["mnemonic"] as String?,
|
|
altMnemonic: json["altMnemonic"] as String?,
|
|
passphrase: json["passphrase"] as String?,
|
|
xPub: json["xPub"] as String?,
|
|
scanSecret: json["scanSecret"] as String?,
|
|
spendPubkey: json["spendPubkey"] as String?,
|
|
);
|
|
}
|