mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-17 05:41:29 +02:00
* Add psbt rpcs * Only build arm64 * Rebuild protos * Update proto * Add psbt create rpc * Restore wallet stuff * more stuff * more stuff * more stuff * Fix open wallet * Fix mweb enabled * Start of buildPsbt * Update proto * Psbt add recipients * fixes * slightly better * more fixes * decode ur * add more commit code * Update proto * use new proto * Don't eat psbt rpc errors * Use unix domain socket for mwebd * add gitignore * Undo build only arm64 * fix pure mweb txns * fix mweb txids * fix ci * fix blank pegin address * chore: update cw_mweb dependencies chore: remove cw_core as dependency from cw_mweb * fix: Ltub restore * fix: address review crashes, fix non-mweb view only wallets * minor fixes --------- Co-authored-by: Hector Chu <hectorchu@gmail.com> Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
126 lines
4.5 KiB
Dart
126 lines
4.5 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?,
|
|
);
|
|
}
|