diff --git a/cw_bitcoin/lib/bitcoin_wallet.dart b/cw_bitcoin/lib/bitcoin_wallet.dart index 1d29307ca..94fe2b7bf 100644 --- a/cw_bitcoin/lib/bitcoin_wallet.dart +++ b/cw_bitcoin/lib/bitcoin_wallet.dart @@ -47,10 +47,8 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store { initialBalance: initialBalance, seedBytes: seedBytes, 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!; - String sideDerivationPath = derivationPath.substring(0, derivationPath.length - 1) + "1"; + String derivationPath = walletInfo.derivationInfo!.derivationPath! + "/0"; + String sideDerivationPath = walletInfo.derivationInfo!.derivationPath! + "/1"; final hd = bitcoin.HDWallet.fromSeed(seedBytes, network: networkType); walletAddresses = BitcoinWalletAddresses( walletInfo, diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart index 6a566aaf0..008744a05 100644 --- a/lib/bitcoin/cw_bitcoin.dart +++ b/lib/bitcoin/cw_bitcoin.dart @@ -287,6 +287,18 @@ class CWBitcoin extends Bitcoin { }) async { List list = []; + // var types = await compareDerivationMethods(mnemonic: mnemonic, node: node); + // if (types.length == 1 && types.first == DerivationType.electrum) { + // return [ + // DerivationInfo( + // derivationType: DerivationType.electrum, + // derivationPath: "m/0'/0", + // description: "Electrum", + // scriptType: "p2wpkh", + // ) + // ]; + // } + final electrumClient = ElectrumClient(); await electrumClient.connectToUri(node.uri); @@ -322,20 +334,18 @@ class CWBitcoin extends Bitcoin { ); String rootPath = dInfoCopy.derivationPath!; - int rootDepth = _countOccurrences(rootPath, "/"); - String pathForAccount0Index0 = rootPath; - - // for BIP44/BIP49, we need to specify the index 0 for the first address: - if (rootDepth == 3) { - pathForAccount0Index0 += "/0/0"; + int depth = _countOccurrences(rootPath, "/"); + String pathForIndex0 = rootPath; + if (depth == 3) { + pathForIndex0 = rootPath + "/0/0"; } else { - pathForAccount0Index0 += "/0"; + pathForIndex0 = rootPath + "/0"; } final hd = btc.HDWallet.fromSeed( seedBytes, network: networkType, - ).derivePath(pathForAccount0Index0); + ).derivePath(pathForIndex0); String? address; switch (dInfoCopy.scriptType) { @@ -359,7 +369,6 @@ class CWBitcoin extends Bitcoin { dInfoCopy.balance = balance.entries.first.value.toString(); dInfoCopy.address = address; dInfoCopy.transactionsCount = history.length; - dInfoCopy.derivationPath = pathForAccount0Index0; list.add(dInfoCopy); } catch (e) { diff --git a/lib/nano/cw_nano.dart b/lib/nano/cw_nano.dart index f434a36d8..088b858b1 100644 --- a/lib/nano/cw_nano.dart +++ b/lib/nano/cw_nano.dart @@ -106,7 +106,6 @@ class CWNano extends Nano { required String mnemonic, required DerivationType derivationType, }) { - if (mnemonic.split(" ").length == 12) { derivationType = DerivationType.bip39; } @@ -126,7 +125,6 @@ class CWNano extends Nano { required String seedKey, required DerivationType derivationType, }) { - if (seedKey.length == 128) { derivationType = DerivationType.bip39; } @@ -192,7 +190,6 @@ class CWNano extends Nano { } class CWNanoUtil extends NanoUtil { - @override bool isValidBip39Seed(String seed) { return NanoDerivations.isValidBip39Seed(seed); @@ -346,4 +343,54 @@ class CWNanoUtil extends NanoUtil { return [DerivationType.nano, DerivationType.bip39]; } } + + @override + Future> getDerivationsFromMnemonic({ + String? mnemonic, + String? seedKey, + required Node node, + }) async { + List list = []; + + List possibleDerivationTypes = await compareDerivationMethods( + mnemonic: mnemonic, + privateKey: seedKey, + node: node, + ); + if (possibleDerivationTypes.length == 1) { + return [DerivationInfo(derivationType: possibleDerivationTypes.first)]; + } + + AccountInfoResponse? bip39Info = await nanoUtil!.getInfoFromSeedOrMnemonic( + DerivationType.bip39, + mnemonic: mnemonic, + seedKey: seedKey, + node: node, + ); + AccountInfoResponse? standardInfo = await nanoUtil!.getInfoFromSeedOrMnemonic( + DerivationType.nano, + mnemonic: mnemonic, + seedKey: seedKey, + node: node, + ); + + if (standardInfo?.confirmationHeight != null && standardInfo!.confirmationHeight > 0) { + list.add(DerivationInfo( + derivationType: DerivationType.nano, + balance: nanoUtil!.getRawAsUsableString(standardInfo.balance, nanoUtil!.rawPerNano), + address: standardInfo.address!, + transactionsCount: standardInfo.confirmationHeight, + )); + } + + if (bip39Info?.confirmationHeight != null && bip39Info!.confirmationHeight > 0) { + list.add(DerivationInfo( + derivationType: DerivationType.bip39, + balance: nanoUtil!.getRawAsUsableString(bip39Info.balance, nanoUtil!.rawPerNano), + address: bip39Info.address!, + transactionsCount: bip39Info.confirmationHeight, + )); + } + return list; + } } diff --git a/lib/src/screens/restore/wallet_restore_page.dart b/lib/src/screens/restore/wallet_restore_page.dart index c3594ec43..415ae1e90 100644 --- a/lib/src/screens/restore/wallet_restore_page.dart +++ b/lib/src/screens/restore/wallet_restore_page.dart @@ -355,49 +355,39 @@ class WalletRestorePage extends BasePage { walletRestoreViewModel.state = IsExecutingState(); - List derivationTypes = - await walletRestoreViewModel.getDerivationTypes(_credentials()); DerivationInfo? dInfo; - if (derivationTypes.length > 1) { - // push screen to choose the derivation type: - List derivations = - await walletRestoreViewModel.getDerivationInfo(_credentials()); + // get info about the different derivations: + List derivations = + await walletRestoreViewModel.getDerivationInfo(_credentials()); - int derivationsWithHistory = 0; - int derivationWithHistoryIndex = 0; - for (int i = 0; i < derivations.length; i++) { - if (derivations[i].transactionsCount > 0) { - derivationsWithHistory++; - derivationWithHistoryIndex = i; - } + int derivationsWithHistory = 0; + int derivationWithHistoryIndex = 0; + for (int i = 0; i < derivations.length; i++) { + if (derivations[i].transactionsCount > 0) { + derivationsWithHistory++; + derivationWithHistoryIndex = i; } - - // dInfo = await Navigator.of(context).pushNamed(Routes.restoreWalletChooseDerivation, - // arguments: derivations) as DerivationInfo?; - - if (derivationsWithHistory > 1) { - dInfo = await Navigator.of(context).pushNamed(Routes.restoreWalletChooseDerivation, - arguments: derivations) as DerivationInfo?; - } else if (derivationsWithHistory == 1) { - dInfo = derivations[derivationWithHistoryIndex]; - } else if (derivationsWithHistory == 0 && derivations.isNotEmpty) { - dInfo = DerivationInfo( - derivationType: DerivationType.bip39, - derivationPath: "m/84'/0'/0'/0", - description: "Standard BIP84 native segwit", - scriptType: "p2wpkh", - ); - } - - if (dInfo == null) { - walletRestoreViewModel.state = InitialExecutionState(); - return; - } - - this.derivationInfo = dInfo; } + if (derivationsWithHistory > 1) { + dInfo = await Navigator.of(context).pushNamed( + Routes.restoreWalletChooseDerivation, + arguments: derivations, + ) as DerivationInfo?; + } else if (derivationsWithHistory == 1) { + dInfo = derivations[derivationWithHistoryIndex]; + } else if (derivationsWithHistory == 0 && derivations.isNotEmpty) { + dInfo = derivations.first; + } + + if (dInfo == null) { + walletRestoreViewModel.state = InitialExecutionState(); + return; + } + + this.derivationInfo = dInfo; + // get the default derivation for this wallet type: if (this.derivationInfo == null) { this.derivationInfo = walletRestoreViewModel.getDefaultDerivation(); diff --git a/lib/view_model/wallet_restore_view_model.dart b/lib/view_model/wallet_restore_view_model.dart index 97c672682..06d86bb3d 100644 --- a/lib/view_model/wallet_restore_view_model.dart +++ b/lib/view_model/wallet_restore_view_model.dart @@ -212,65 +212,17 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store { case WalletType.nano: String? mnemonic = credentials['seed'] as String?; String? seedKey = credentials['private_key'] as String?; - AccountInfoResponse? bip39Info = await nanoUtil!.getInfoFromSeedOrMnemonic( - DerivationType.bip39, - mnemonic: mnemonic, - seedKey: seedKey, - node: node); - AccountInfoResponse? standardInfo = await nanoUtil!.getInfoFromSeedOrMnemonic( - DerivationType.nano, + return nanoUtil!.getDerivationsFromMnemonic( mnemonic: mnemonic, seedKey: seedKey, node: node, ); - - if (standardInfo?.balance != null) { - list.add(DerivationInfo( - derivationType: DerivationType.nano, - balance: nanoUtil!.getRawAsUsableString(standardInfo!.balance, nanoUtil!.rawPerNano), - address: standardInfo.address!, - transactionsCount: standardInfo.confirmationHeight, - )); - } - - if (bip39Info?.balance != null) { - list.add(DerivationInfo( - derivationType: DerivationType.bip39, - balance: nanoUtil!.getRawAsUsableString(bip39Info!.balance, nanoUtil!.rawPerNano), - address: bip39Info.address!, - transactionsCount: bip39Info.confirmationHeight, - )); - } - break; default: break; } return list; } - Future> getDerivationTypes(dynamic options) async { - final seedKey = options['private_key'] as String?; - final mnemonic = options['seed'] as String?; - WalletType walletType = options['walletType'] as WalletType; - var appStore = getIt.get(); - var node = appStore.settingsStore.getCurrentNode(walletType); - - switch (type) { - case WalletType.bitcoin: - case WalletType.litecoin: - return bitcoin!.compareDerivationMethods(mnemonic: mnemonic!, node: node); - case WalletType.nano: - return nanoUtil!.compareDerivationMethods( - mnemonic: mnemonic, - privateKey: seedKey, - node: node, - ); - default: - break; - } - return [DerivationType.def]; - } - @override Future process(WalletCredentials credentials) async { if (mode == WalletRestoreMode.keys) { diff --git a/tool/configure.dart b/tool/configure.dart index 78d725253..f025d71ef 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -914,6 +914,11 @@ abstract class NanoUtil { String? privateKey, required Node node, }); + Future> getDerivationsFromMnemonic({ + String? mnemonic, + String? seedKey, + required Node node, + }); } """;