2021-12-24 12:52:08 +00:00
|
|
|
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
|
2022-10-12 17:09:57 +00:00
|
|
|
import 'package:cw_core/crypto_currency.dart';
|
2021-12-24 12:52:08 +00:00
|
|
|
import 'package:cw_core/unspent_coins_info.dart';
|
|
|
|
import 'package:hive/hive.dart';
|
|
|
|
import 'package:mobx/mobx.dart';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
|
|
|
|
import 'package:cw_bitcoin/electrum_wallet_snapshot.dart';
|
|
|
|
import 'package:cw_bitcoin/electrum_wallet.dart';
|
|
|
|
import 'package:cw_core/wallet_info.dart';
|
|
|
|
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
|
|
|
import 'package:cw_bitcoin/electrum_balance.dart';
|
|
|
|
import 'package:cw_bitcoin/bitcoin_wallet_addresses.dart';
|
2023-09-07 13:22:03 +00:00
|
|
|
import 'package:bip39/bip39.dart' as bip39;
|
2021-12-24 12:52:08 +00:00
|
|
|
|
|
|
|
part 'bitcoin_wallet.g.dart';
|
|
|
|
|
|
|
|
class BitcoinWallet = BitcoinWalletBase with _$BitcoinWallet;
|
|
|
|
|
|
|
|
abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
|
|
|
BitcoinWalletBase(
|
2022-10-12 17:09:57 +00:00
|
|
|
{required String mnemonic,
|
|
|
|
required String password,
|
|
|
|
required WalletInfo walletInfo,
|
|
|
|
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
|
|
|
required Uint8List seedBytes,
|
|
|
|
List<BitcoinAddressRecord>? initialAddresses,
|
|
|
|
ElectrumBalance? initialBalance,
|
2022-01-18 16:27:33 +00:00
|
|
|
int initialRegularAddressIndex = 0,
|
|
|
|
int initialChangeAddressIndex = 0})
|
2021-12-24 12:52:08 +00:00
|
|
|
: super(
|
|
|
|
mnemonic: mnemonic,
|
|
|
|
password: password,
|
|
|
|
walletInfo: walletInfo,
|
|
|
|
unspentCoinsInfo: unspentCoinsInfo,
|
|
|
|
networkType: bitcoin.bitcoin,
|
|
|
|
initialAddresses: initialAddresses,
|
2022-10-12 17:09:57 +00:00
|
|
|
initialBalance: initialBalance,
|
|
|
|
seedBytes: seedBytes,
|
|
|
|
currency: CryptoCurrency.btc) {
|
2023-08-25 15:59:24 +00:00
|
|
|
walletAddresses = BitcoinWalletAddresses(walletInfo,
|
2022-01-18 16:27:33 +00:00
|
|
|
electrumClient: electrumClient,
|
2021-12-24 12:52:08 +00:00
|
|
|
initialAddresses: initialAddresses,
|
2022-01-18 16:27:33 +00:00
|
|
|
initialRegularAddressIndex: initialRegularAddressIndex,
|
|
|
|
initialChangeAddressIndex: initialChangeAddressIndex,
|
2021-12-24 12:52:08 +00:00
|
|
|
mainHd: hd,
|
2022-10-12 17:09:57 +00:00
|
|
|
sideHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType)
|
2023-08-25 15:59:24 +00:00
|
|
|
.derivePath(walletInfo.derivationPath!),
|
2021-12-24 12:52:08 +00:00
|
|
|
networkType: networkType);
|
|
|
|
}
|
|
|
|
|
2023-08-25 15:59:24 +00:00
|
|
|
static Future<BitcoinWallet> create(
|
|
|
|
{required String mnemonic,
|
|
|
|
required String password,
|
|
|
|
required WalletInfo walletInfo,
|
|
|
|
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
|
|
|
List<BitcoinAddressRecord>? initialAddresses,
|
|
|
|
ElectrumBalance? initialBalance,
|
|
|
|
int initialRegularAddressIndex = 0,
|
|
|
|
int initialChangeAddressIndex = 0}) async {
|
2023-09-07 13:22:03 +00:00
|
|
|
|
2023-08-25 15:59:24 +00:00
|
|
|
late Uint8List seedBytes;
|
2023-09-07 13:22:03 +00:00
|
|
|
|
|
|
|
switch (walletInfo.derivationType) {
|
|
|
|
case DerivationType.electrum2:
|
|
|
|
seedBytes = await mnemonicToSeedBytes(mnemonic);
|
|
|
|
break;
|
|
|
|
case DerivationType.bip39:
|
|
|
|
default:
|
|
|
|
seedBytes = await bip39.mnemonicToSeed(mnemonic);
|
|
|
|
break;
|
2023-08-25 15:59:24 +00:00
|
|
|
}
|
2023-09-07 13:22:03 +00:00
|
|
|
|
2022-10-12 17:09:57 +00:00
|
|
|
return BitcoinWallet(
|
|
|
|
mnemonic: mnemonic,
|
|
|
|
password: password,
|
|
|
|
walletInfo: walletInfo,
|
|
|
|
unspentCoinsInfo: unspentCoinsInfo,
|
|
|
|
initialAddresses: initialAddresses,
|
|
|
|
initialBalance: initialBalance,
|
2023-08-25 15:59:24 +00:00
|
|
|
seedBytes: seedBytes,
|
2022-10-12 17:09:57 +00:00
|
|
|
initialRegularAddressIndex: initialRegularAddressIndex,
|
|
|
|
initialChangeAddressIndex: initialChangeAddressIndex);
|
|
|
|
}
|
|
|
|
|
2021-12-24 12:52:08 +00:00
|
|
|
static Future<BitcoinWallet> open({
|
2022-10-12 17:09:57 +00:00
|
|
|
required String name,
|
|
|
|
required WalletInfo walletInfo,
|
|
|
|
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
|
|
|
required String password,
|
2021-12-24 12:52:08 +00:00
|
|
|
}) async {
|
2022-10-12 17:09:57 +00:00
|
|
|
final snp = await ElectrumWallletSnapshot.load(name, walletInfo.type, password);
|
2023-08-24 22:06:58 +00:00
|
|
|
|
|
|
|
walletInfo.derivationType = snp.derivationType;
|
|
|
|
walletInfo.derivationPath = snp.derivationPath;
|
|
|
|
|
|
|
|
// set the default if not present:
|
|
|
|
if (walletInfo.derivationPath == null) {
|
|
|
|
walletInfo.derivationPath = "m/0'/1";
|
|
|
|
}
|
2023-08-25 15:59:24 +00:00
|
|
|
if (walletInfo.derivationType == null) {
|
|
|
|
walletInfo.derivationType = DerivationType.electrum2;
|
|
|
|
}
|
|
|
|
|
|
|
|
late Uint8List seedBytes;
|
2023-09-07 13:22:03 +00:00
|
|
|
|
|
|
|
switch (walletInfo.derivationType) {
|
|
|
|
case DerivationType.electrum2:
|
|
|
|
seedBytes = await mnemonicToSeedBytes(snp.mnemonic);
|
|
|
|
break;
|
|
|
|
case DerivationType.bip39:
|
|
|
|
default:
|
|
|
|
seedBytes = await bip39.mnemonicToSeed(snp.mnemonic);
|
|
|
|
break;
|
2023-08-25 15:59:24 +00:00
|
|
|
}
|
2023-08-24 22:06:58 +00:00
|
|
|
|
2021-12-24 12:52:08 +00:00
|
|
|
return BitcoinWallet(
|
|
|
|
mnemonic: snp.mnemonic,
|
|
|
|
password: password,
|
|
|
|
walletInfo: walletInfo,
|
|
|
|
unspentCoinsInfo: unspentCoinsInfo,
|
|
|
|
initialAddresses: snp.addresses,
|
|
|
|
initialBalance: snp.balance,
|
2023-08-25 15:59:24 +00:00
|
|
|
seedBytes: seedBytes,
|
2022-01-18 16:27:33 +00:00
|
|
|
initialRegularAddressIndex: snp.regularAddressIndex,
|
|
|
|
initialChangeAddressIndex: snp.changeAddressIndex);
|
2021-12-24 12:52:08 +00:00
|
|
|
}
|
|
|
|
}
|