refactor to use one less /0 working on both electrum and bip39 derivations

This commit is contained in:
Matthew Fosse 2024-04-29 16:48:14 -07:00
parent fcb9f0d77e
commit 765689c551
7 changed files with 49 additions and 54 deletions

View file

@ -33,33 +33,32 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
Map<String, int>? initialChangeAddressIndex, Map<String, int>? initialChangeAddressIndex,
String? passphrase, String? passphrase,
}) : super( }) : super(
mnemonic: mnemonic, mnemonic: mnemonic,
passphrase: passphrase, passphrase: passphrase,
password: password, password: password,
walletInfo: walletInfo, walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfo, unspentCoinsInfo: unspentCoinsInfo,
networkType: networkParam == null networkType: networkParam == null
? bitcoin.bitcoin ? bitcoin.bitcoin
: networkParam == BitcoinNetwork.mainnet : networkParam == BitcoinNetwork.mainnet
? bitcoin.bitcoin ? bitcoin.bitcoin
: bitcoin.testnet, : bitcoin.testnet,
initialAddresses: initialAddresses, initialAddresses: initialAddresses,
initialBalance: initialBalance, initialBalance: initialBalance,
seedBytes: seedBytes, seedBytes: seedBytes,
currency: CryptoCurrency.btc) { currency: CryptoCurrency.btc,
// 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) String derivationPath = walletInfo.derivationInfo!.derivationPath! + "/0";
String derivationPath = walletInfo.derivationInfo!.derivationPath!; String sideDerivationPath = walletInfo.derivationInfo!.derivationPath! + "/1";
String sideDerivationPath = derivationPath.substring(0, derivationPath.length - 1) + "1"; final hd2 = bitcoin.HDWallet.fromSeed(seedBytes, network: networkType);
final hd = bitcoin.HDWallet.fromSeed(seedBytes, network: networkType);
walletAddresses = BitcoinWalletAddresses( walletAddresses = BitcoinWalletAddresses(
walletInfo, walletInfo,
electrumClient: electrumClient, electrumClient: electrumClient,
initialAddresses: initialAddresses, initialAddresses: initialAddresses,
initialRegularAddressIndex: initialRegularAddressIndex, initialRegularAddressIndex: initialRegularAddressIndex,
initialChangeAddressIndex: initialChangeAddressIndex, initialChangeAddressIndex: initialChangeAddressIndex,
mainHd: hd.derivePath(derivationPath), mainHd: hd2.derivePath(derivationPath),
sideHd: hd.derivePath(sideDerivationPath), sideHd: hd2.derivePath(sideDerivationPath),
network: networkParam ?? network, network: networkParam ?? network,
); );
autorun((_) { autorun((_) {
@ -127,7 +126,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
); );
// set the default if not present: // set the default if not present:
walletInfo.derivationInfo!.derivationPath = snp.derivationPath ?? "m/0'/1"; walletInfo.derivationInfo!.derivationPath = snp.derivationPath ?? "m/0'";
late Uint8List seedBytes; late Uint8List seedBytes;

View file

@ -4,7 +4,7 @@ Map<DerivationType, List<DerivationInfo>> electrum_derivations = {
DerivationType.electrum: [ DerivationType.electrum: [
DerivationInfo( DerivationInfo(
derivationType: DerivationType.electrum, derivationType: DerivationType.electrum,
derivationPath: "m/0'/0", derivationPath: "m/0'",
description: "Electrum", description: "Electrum",
scriptType: "p2wpkh", scriptType: "p2wpkh",
), ),

View file

@ -63,7 +63,7 @@ abstract class ElectrumWalletBase
: hd = currency == CryptoCurrency.bch : hd = currency == CryptoCurrency.bch
? bitcoinCashHDWallet(seedBytes) ? bitcoinCashHDWallet(seedBytes)
: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType) : bitcoin.HDWallet.fromSeed(seedBytes, network: networkType)
.derivePath(walletInfo.derivationInfo?.derivationPath ?? "m/0'/0"), .derivePath(walletInfo.derivationInfo?.derivationPath ?? "m/0'"),
syncStatus = NotConnectedSyncStatus(), syncStatus = NotConnectedSyncStatus(),
_password = password, _password = password,
_feeRates = <int>[], _feeRates = <int>[],

View file

@ -56,7 +56,7 @@ class ElectrumWalletSnapshot {
final derivationType = final derivationType =
DerivationType.values[(data['derivationTypeIndex'] as int?) ?? DerivationType.electrum.index]; DerivationType.values[(data['derivationTypeIndex'] as int?) ?? DerivationType.electrum.index];
final derivationPath = data['derivationPath'] as String? ?? "m/0'/0"; final derivationPath = data['derivationPath'] as String? ?? "m/0'";
try { try {
regularAddressIndexByType = { regularAddressIndexByType = {

View file

@ -33,23 +33,27 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
Map<String, int>? initialRegularAddressIndex, Map<String, int>? initialRegularAddressIndex,
Map<String, int>? initialChangeAddressIndex, Map<String, int>? initialChangeAddressIndex,
}) : super( }) : super(
mnemonic: mnemonic, mnemonic: mnemonic,
password: password, password: password,
walletInfo: walletInfo, walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfo, unspentCoinsInfo: unspentCoinsInfo,
networkType: litecoinNetwork, networkType: litecoinNetwork,
initialAddresses: initialAddresses, initialAddresses: initialAddresses,
initialBalance: initialBalance, initialBalance: initialBalance,
seedBytes: seedBytes, seedBytes: seedBytes,
currency: CryptoCurrency.ltc) { currency: CryptoCurrency.ltc,
) {
String derivationPath = walletInfo.derivationInfo!.derivationPath! + "/0";
String sideDerivationPath = walletInfo.derivationInfo!.derivationPath! + "/1";
final hd2 = bitcoin.HDWallet.fromSeed(seedBytes, network: networkType);
walletAddresses = LitecoinWalletAddresses( walletAddresses = LitecoinWalletAddresses(
walletInfo, walletInfo,
electrumClient: electrumClient, electrumClient: electrumClient,
initialAddresses: initialAddresses, initialAddresses: initialAddresses,
initialRegularAddressIndex: initialRegularAddressIndex, initialRegularAddressIndex: initialRegularAddressIndex,
initialChangeAddressIndex: initialChangeAddressIndex, initialChangeAddressIndex: initialChangeAddressIndex,
mainHd: hd, mainHd: hd2.derivePath(derivationPath),
sideHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType).derivePath("m/0'/1"), sideHd: hd2.derivePath(sideDerivationPath),
network: network, network: network,
); );
autorun((_) { autorun((_) {

View file

@ -292,7 +292,7 @@ class CWBitcoin extends Bitcoin {
return [ return [
DerivationInfo( DerivationInfo(
derivationType: DerivationType.electrum, derivationType: DerivationType.electrum,
derivationPath: "m/0'/0", derivationPath: "m/0'",
description: "Electrum", description: "Electrum",
scriptType: "p2wpkh", scriptType: "p2wpkh",
) )
@ -333,27 +333,19 @@ class CWBitcoin extends Bitcoin {
scriptType: dInfo.scriptType, scriptType: dInfo.scriptType,
); );
String derivationPath = dInfoCopy.derivationPath!; String rootPath = dInfoCopy.derivationPath!;
int derivationDepth = _countOccurrences(derivationPath, "/"); int depth = _countOccurrences(rootPath, "/");
String pathForIndex0 = rootPath;
// the correct derivation depth is dependant on the derivation type: if (depth == 3) {
// the derivation paths defined in electrum_derivations are at the ROOT level, i.e.: pathForIndex0 = rootPath + "/0/0";
// electrum's format doesn't specify subaddresses, just subaccounts: } else {
pathForIndex0 = rootPath + "/0";
// for BIP44
if (derivationDepth == 3) {
// we add "/0/0" so that we generate account 0, index 0 and correctly get balance
derivationPath += "/0/0";
// we don't support sub-ACCOUNTS in bitcoin like we do monero, and so the path dInfoCopy
// expects should be ACCOUNT 0, index unspecified:
dInfoCopy.derivationPath = dInfoCopy.derivationPath! + "/0";
} }
// var hd = bip32.BIP32.fromSeed(seedBytes).derivePath(derivationPath);
final hd = btc.HDWallet.fromSeed( final hd = btc.HDWallet.fromSeed(
seedBytes, seedBytes,
network: networkType, network: networkType,
).derivePath(derivationPath); ).derivePath(pathForIndex0);
String? address; String? address;
switch (dInfoCopy.scriptType) { switch (dInfoCopy.scriptType) {

View file

@ -99,7 +99,7 @@ abstract class WalletCreationVMBase with Store {
case WalletType.litecoin: case WalletType.litecoin:
return DerivationInfo( return DerivationInfo(
derivationType: DerivationType.electrum, derivationType: DerivationType.electrum,
derivationPath: "m/0'/0", derivationPath: "m/0'",
); );
default: default:
return null; return null;