dev
dart 131 lines 4.32 KB
Raw
1 import 'dart:io';
2
3 import 'package:bip39/bip39.dart';
4 import 'package:cw_bitcoin/bitcoin_mnemonics_bip39.dart';
5 import 'package:cw_bitcoin_cash/cw_bitcoin_cash.dart';
6 import 'package:cw_core/encryption_file_utils.dart';
7 import 'package:cw_core/pathForWallet.dart';
8 import 'package:cw_core/unspent_coins_info.dart';
9 import 'package:cw_core/wallet_info.dart';
10 import 'package:cw_core/wallet_service.dart';
11 import 'package:cw_core/wallet_type.dart';
12 import 'package:hive/hive.dart';
13
14 class BitcoinCashWalletService extends WalletService<
15 BitcoinCashNewWalletCredentials,
16 BitcoinCashRestoreWalletFromSeedCredentials,
17 BitcoinCashRestoreWalletFromWIFCredentials,
18 BitcoinCashNewWalletCredentials> {
19 BitcoinCashWalletService(this.unspentCoinsInfoSource, this.isDirect);
20
21 final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
22 final bool isDirect;
23
24 @override
25 WalletType getType() => WalletType.bitcoinCash;
26
27 @override
28 Future<bool> isWalletExit(String name) async =>
29 File(await pathForWallet(name: name, type: getType())).existsSync();
30
31 @override
32 Future<BitcoinCashWallet> create(credentials, {bool? isTestnet}) async {
33 final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
34
35 final wallet = await BitcoinCashWalletBase.create(
36 mnemonic: credentials.mnemonic ?? MnemonicBip39.generate(strength: strength),
37 password: credentials.password!,
38 walletInfo: credentials.walletInfo!,
39 unspentCoinsInfo: unspentCoinsInfoSource,
40 encryptionFileUtils: encryptionFileUtilsFor(isDirect),
41 passphrase: credentials.passphrase,
42 );
43 await wallet.save();
44 await wallet.init();
45
46 return wallet;
47 }
48
49 @override
50 Future<BitcoinCashWallet> openWallet(String name, String password) async {
51 final walletInfo = await WalletInfo.get(name, getType());
52 if (walletInfo == null) {
53 throw Exception('Wallet not found');
54 }
55
56 try {
57 final wallet = await BitcoinCashWalletBase.open(
58 password: password,
59 name: name,
60 walletInfo: walletInfo,
61 unspentCoinsInfo: unspentCoinsInfoSource,
62 encryptionFileUtils: encryptionFileUtilsFor(isDirect),
63 );
64 await wallet.init();
65 saveBackup(name);
66 return wallet;
67 } catch (_) {
68 await restoreWalletFilesFromBackup(name);
69 final wallet = await BitcoinCashWalletBase.open(
70 password: password,
71 name: name,
72 walletInfo: walletInfo,
73 unspentCoinsInfo: unspentCoinsInfoSource,
74 encryptionFileUtils: encryptionFileUtilsFor(isDirect),
75 );
76 await wallet.init();
77 return wallet;
78 }
79 }
80
81 @override
82 Future<void> remove(String wallet) async {
83 File(await pathForWalletDir(name: wallet, type: getType())).delete(recursive: true);
84 final walletInfo = await WalletInfo.get(wallet, getType());
85 if (walletInfo == null) {
86 throw Exception('Wallet not found');
87 }
88 await WalletInfo.delete(walletInfo);
89
90 final unspentCoinsToDelete = unspentCoinsInfoSource.values
91 .where((unspentCoin) => unspentCoin.walletId == walletInfo.id)
92 .toList();
93
94 final keysToDelete = unspentCoinsToDelete.map((unspentCoin) => unspentCoin.key).toList();
95
96 if (keysToDelete.isNotEmpty) {
97 await unspentCoinsInfoSource.deleteAll(keysToDelete);
98 }
99 }
100
101 @override
102 Future<BitcoinCashWallet> restoreFromHardwareWallet(BitcoinCashNewWalletCredentials credentials) {
103 throw UnimplementedError(
104 "Restoring a Bitcoin Cash wallet from a hardware wallet is not yet supported!");
105 }
106
107 @override
108 Future<BitcoinCashWallet> restoreFromKeys(credentials, {bool? isTestnet}) {
109 // TODO: implement restoreFromKeys
110 throw UnimplementedError('restoreFromKeys() is not implemented');
111 }
112
113 @override
114 Future<BitcoinCashWallet> restoreFromSeed(BitcoinCashRestoreWalletFromSeedCredentials credentials,
115 {bool? isTestnet}) async {
116 if (!validateMnemonic(credentials.mnemonic)) {
117 throw BitcoinCashMnemonicIsIncorrectException();
118 }
119
120 final wallet = await BitcoinCashWalletBase.create(
121 password: credentials.password!,
122 mnemonic: credentials.mnemonic,
123 walletInfo: credentials.walletInfo!,
124 unspentCoinsInfo: unspentCoinsInfoSource,
125 encryptionFileUtils: encryptionFileUtilsFor(isDirect),
126 passphrase: credentials.passphrase);
127 await wallet.save();
128 await wallet.init();
129 return wallet;
130 }
131 }