LCOV - code coverage report
Current view: top level - crypto/utxo/utils - derivation.dart (source / functions) Coverage Total Hit
Test: lcov.info Lines: 88.9 % 63 56
Test Date: 2025-06-07 01:20:49 Functions: - 0 0

            Line data    Source code
       1              : import 'dart:typed_data';
       2              : import 'package:bip32/bip32.dart' as bip32;
       3              : import 'package:walletkit_dart/src/crypto/utxo/utils/pubkey_to_address.dart';
       4              : import 'package:bs58check/bs58check.dart' as bs58check;
       5              : import 'package:walletkit_dart/src/utils/var_uint.dart';
       6              : import 'package:walletkit_dart/walletkit_dart.dart';
       7              : 
       8              : typedef BipNode = bip32.BIP32;
       9              : 
      10            2 : String deriveExtendedPubKey({
      11              :   required Uint8List seed,
      12              :   required HDWalletPath walletPurpose,
      13              :   UTXONetworkType? type,
      14              : }) {
      15              :   ///
      16              :   /// Walletkit Compatibility
      17              :   ///
      18            2 :   if (type == LitecoinNetwork) {
      19            2 :     final depth1MasterNode = deriveMasterNodeFromSeed(
      20              :       seed: seed,
      21              :       networkType: type,
      22              :       walletPath: bitcoinBip44HDPath, // TODO: Check if still valid
      23              :     );
      24              : 
      25            2 :     final parentFingerprint = depth1MasterNode.parentFingerprint;
      26              : 
      27            2 :     final masterNode = deriveMasterNodeFromSeed(
      28              :       seed: seed,
      29              :       networkType: type,
      30              :       walletPath: walletPurpose,
      31              :     );
      32            4 :     return masterNode.neutered().toBase58wkCompatibility(parentFingerprint, 1);
      33              :   }
      34              : 
      35            1 :   final masterNode = deriveMasterNodeFromSeed(
      36              :     seed: seed,
      37              :     networkType: type,
      38              :     walletPath: walletPurpose,
      39              :   );
      40            2 :   return masterNode.neutered().toBase58();
      41              : }
      42              : 
      43           10 : BipNode deriveMasterNodeFromSeed({
      44              :   required Uint8List seed,
      45              :   required HDWalletPath walletPath,
      46              :   UTXONetworkType? networkType,
      47              : }) {
      48           21 :   final bipNetworkType = networkType?.networkBIP.getForWalletType(walletPath.purpose);
      49              : 
      50           10 :   final parentNode = BipNode.fromSeed(seed, bipNetworkType);
      51           10 :   final derivationPath = switch (walletPath.basePath) {
      52           12 :     "m/44'/2'" => walletPath.account0Path,
      53           20 :     _ => walletPath.purpose.string,
      54              :   };
      55           10 :   final node = parentNode.derivePath(derivationPath); // TODO: Use base Path with Account
      56              : 
      57              :   return node;
      58              : }
      59              : 
      60            6 : BipNode deriveMasterNodeFromExtendedKeyWithCheck({
      61              :   required String ePubKey,
      62              :   required UTXONetworkType networkType,
      63              :   required HDWalletPurpose purpose,
      64              : }) {
      65            6 :   final (node, version) = deriveMasterNodeFromExtendedKey(
      66              :     ePubKey,
      67              :     networkType: networkType,
      68              :     purpose: purpose,
      69              :   );
      70              : 
      71           48 :   if (version != node.network.bip32.private && version != node.network.bip32.public) {
      72            0 :     throw ArgumentError(
      73            0 :       "Version mismatch. Extracted Version: $version. Expected: ${node.network.bip32.private} or ${node.network.bip32.public}",
      74              :     );
      75              :   }
      76              : 
      77              :   return node;
      78              : }
      79              : 
      80            7 : (BipNode node, int version) deriveMasterNodeFromExtendedKey(
      81              :   String ePubKey, {
      82              :   UTXONetworkType? networkType,
      83              :   HDWalletPurpose? purpose,
      84              : }) {
      85            7 :   final buffer = bs58check.decode(ePubKey);
      86              : 
      87           14 :   if (buffer.length != 78) {
      88            0 :     throw UnsupportedError("invalid ePubKey");
      89              :   }
      90              : 
      91           14 :   final version = buffer.bytes.getUint32(0);
      92              : 
      93            7 :   final node = BipNode.fromBase58(
      94              :     ePubKey,
      95              :     switch ((networkType, purpose)) {
      96           13 :       (UTXONetworkType network, HDWalletPurpose purpose) =>
      97           12 :         network.networkBIP.getForWalletType(purpose),
      98            1 :       _ => bip32.NetworkType(
      99              :           wif: 0x80,
     100            1 :           bip32: bip32.Bip32Type(
     101              :             private: 0x0488ADE4,
     102              :             public: 0x0488B21E,
     103              :           ),
     104              :         ),
     105              :     },
     106              :   );
     107              : 
     108              :   return (node, version);
     109              : }
     110              : 
     111            9 : NodeWithAddress deriveChildNode({
     112              :   required BipNode masterNode,
     113              :   required int chainIndex,
     114              :   required int index,
     115              :   required UTXONetworkType networkType,
     116              :   required Iterable<AddressType> addressTypes,
     117              :   required HDWalletPurpose? walletPurpose,
     118              : }) {
     119            9 :   if (index < 0) {
     120            0 :     throw UnsupportedError("index must not be negative");
     121              :   }
     122           18 :   if (chainIndex != EXTERNAL_CHAIN_INDEX && chainIndex != INTERNAL_CHAIN_INDEX) {
     123            0 :     throw UnsupportedError("unexpected chainIndex");
     124              :   }
     125              : 
     126            9 :   final childDerivationPath = "$chainIndex/$index";
     127              : 
     128            9 :   final node = masterNode.derivePath(childDerivationPath);
     129              : 
     130            9 :   final publicKey = node.publicKey;
     131              : 
     132            9 :   final addressMap = {
     133            9 :     for (final addressType in addressTypes)
     134           18 :       addressType: pubKeyToAddress(publicKey, addressType, networkType),
     135              :   };
     136              : 
     137           18 :   final mainAddress = addressMap[addressTypes.first]!;
     138              : 
     139            9 :   return NodeWithAddress.fromChainIndex(
     140              :     node: node,
     141              :     address: mainAddress,
     142              :     chainIndex: chainIndex,
     143              :     derivationPath: childDerivationPath,
     144              :     addresses: addressMap,
     145              :     walletPurpose: walletPurpose,
     146              :   );
     147              : }
     148              : 
     149            1 : bip32.BIP32 deriveChildNodeFromPath({
     150              :   required Uint8List seed,
     151              :   required String childDerivationPath,
     152              :   required HDWalletPath walletPath,
     153              :   UTXONetworkType? networkType,
     154              : }) {
     155            1 :   final masterNode = deriveMasterNodeFromSeed(
     156              :     seed: seed,
     157              :     networkType: networkType,
     158              :     walletPath: walletPath,
     159              :   );
     160              : 
     161            1 :   final node = masterNode.derivePath(childDerivationPath);
     162              : 
     163              :   return node;
     164              : }
     165              : 
     166              : extension on BipNode {
     167            2 :   String toBase58wkCompatibility(int parentFingerprint, int depth) {
     168            8 :     final version = (!isNeutered()) ? network.bip32.private : network.bip32.public;
     169            2 :     Uint8List buffer = new Uint8List(78);
     170            4 :     ByteData bytes = buffer.buffer.asByteData();
     171            2 :     bytes.setUint32(0, version);
     172            2 :     bytes.setUint8(4, depth);
     173            2 :     bytes.setUint32(5, parentFingerprint);
     174            4 :     bytes.setUint32(9, index);
     175            4 :     buffer.setRange(13, 45, chainCode);
     176            2 :     if (!isNeutered()) {
     177            0 :       bytes.setUint8(45, 0);
     178            0 :       buffer.setRange(46, 78, privateKey!);
     179              :     } else {
     180            4 :       buffer.setRange(45, 78, publicKey);
     181              :     }
     182              : 
     183            2 :     return bs58check.encode(buffer);
     184              :   }
     185              : }
     186              : 
     187            2 : BipNode deriveNode(Uint8List seed, String path) {
     188            2 :   final node = bip32.BIP32.fromSeed(seed);
     189            2 :   return node.derivePath(path);
     190              : }
        

Generated by: LCOV version 2.0-1