cake_wallet/cw_bitcoin/lib/bitcoin_wallet.dart

130 lines
4.8 KiB
Dart
Raw Normal View History

import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
2022-10-12 17:09:57 +00:00
import 'package:cw_core/crypto_currency.dart';
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;
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,
int initialRegularAddressIndex = 0,
int initialChangeAddressIndex = 0})
: 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-09-12 14:33:15 +00:00
// in a standard BIP44 wallet, mainHd derivation path = m/84'/0'/0'/0 (account 0, index unspecified here)
// the sideHd derivation path = m/84'/0'/0'/1 (account 1, index unspecified here)
2023-08-25 15:59:24 +00:00
walletAddresses = BitcoinWalletAddresses(walletInfo,
electrumClient: electrumClient,
initialAddresses: initialAddresses,
initialRegularAddressIndex: initialRegularAddressIndex,
initialChangeAddressIndex: initialChangeAddressIndex,
2023-09-12 13:15:26 +00:00
mainHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType)
.derivePath(walletInfo.derivationInfo!.derivationPath!),
sideHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType).derivePath(walletInfo
.derivationInfo!.derivationPath!
.substring(0, walletInfo.derivationInfo!.derivationPath!.length - 1) +
"1"),
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 {
late Uint8List seedBytes;
2023-09-07 13:22:03 +00:00
switch (walletInfo.derivationInfo?.derivationType) {
2023-09-07 13:22:03 +00:00
case DerivationType.bip39:
seedBytes = await bip39.mnemonicToSeed(mnemonic);
break;
case DerivationType.electrum2:
default:
seedBytes = await mnemonicToSeedBytes(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);
}
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,
}) 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.derivationInfo ??= DerivationInfo(
derivationType: snp.derivationType ?? DerivationType.electrum2,
derivationPath: snp.derivationPath,
);
2023-08-24 22:06:58 +00:00
// set the default if not present:
walletInfo.derivationInfo!.derivationPath = snp.derivationPath ?? "m/0'/1";
2023-08-25 15:59:24 +00:00
late Uint8List seedBytes;
2023-09-07 13:22:03 +00:00
switch (walletInfo.derivationInfo!.derivationType) {
2023-09-07 13:22:03 +00:00
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
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,
initialRegularAddressIndex: snp.regularAddressIndex,
initialChangeAddressIndex: snp.changeAddressIndex);
}
}