LCOV - code coverage report
Current view: top level - crypto/utxo/utils - derivation.dart (source / functions) Coverage Total Hit
Test: lcov.info Lines: 89.2 % 65 58
Test Date: 2025-01-30 01:10:00 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              :   final bipNetworkType =
      49           21 :       networkType?.networkBIP.getForWalletType(walletPath.purpose);
      50              : 
      51           10 :   final parentNode = BipNode.fromSeed(seed, bipNetworkType);
      52           10 :   final derivationPath = switch (walletPath.basePath) {
      53           12 :     "m/44'/2'" => walletPath.account0Path,
      54           20 :     _ => walletPath.purpose.string,
      55              :   };
      56              :   final node =
      57           10 :       parentNode.derivePath(derivationPath); // TODO: Use base Path with Account
      58              : 
      59              :   return node;
      60              : }
      61              : 
      62            6 : BipNode deriveMasterNodeFromExtendedKeyWithCheck({
      63              :   required String ePubKey,
      64              :   required UTXONetworkType networkType,
      65              :   required HDWalletPurpose purpose,
      66              : }) {
      67            6 :   final (node, version) = deriveMasterNodeFromExtendedKey(
      68              :     ePubKey,
      69              :     networkType: networkType,
      70              :     purpose: purpose,
      71              :   );
      72              : 
      73           24 :   if (version != node.network.bip32.private &&
      74           24 :       version != node.network.bip32.public) {
      75            0 :     throw ArgumentError(
      76            0 :       "Version mismatch. Extracted Version: $version. Expected: ${node.network.bip32.private} or ${node.network.bip32.public}",
      77              :     );
      78              :   }
      79              : 
      80              :   return node;
      81              : }
      82              : 
      83            7 : (BipNode node, int version) deriveMasterNodeFromExtendedKey(
      84              :   String ePubKey, {
      85              :   UTXONetworkType? networkType,
      86              :   HDWalletPurpose? purpose,
      87              : }) {
      88            7 :   final buffer = bs58check.decode(ePubKey);
      89              : 
      90           14 :   if (buffer.length != 78) {
      91            0 :     throw UnsupportedError("invalid ePubKey");
      92              :   }
      93              : 
      94           14 :   final version = buffer.bytes.getUint32(0);
      95              : 
      96            7 :   final node = BipNode.fromBase58(
      97              :     ePubKey,
      98              :     switch ((networkType, purpose)) {
      99           13 :       (UTXONetworkType network, HDWalletPurpose purpose) =>
     100           12 :         network.networkBIP.getForWalletType(purpose),
     101            1 :       _ => bip32.NetworkType(
     102              :           wif: 0x80,
     103            1 :           bip32: bip32.Bip32Type(
     104              :             private: 0x0488ADE4,
     105              :             public: 0x0488B21E,
     106              :           ),
     107              :         ),
     108              :     },
     109              :   );
     110              : 
     111              :   return (node, version);
     112              : }
     113              : 
     114            9 : NodeWithAddress deriveChildNode({
     115              :   required BipNode masterNode,
     116              :   required int chainIndex,
     117              :   required int index,
     118              :   required UTXONetworkType networkType,
     119              :   required Iterable<AddressType> addressTypes,
     120              :   required HDWalletPurpose? walletPurpose,
     121              : }) {
     122            9 :   if (index < 0) {
     123            0 :     throw UnsupportedError("index must not be negative");
     124              :   }
     125            9 :   if (chainIndex != EXTERNAL_CHAIN_INDEX &&
     126            9 :       chainIndex != INTERNAL_CHAIN_INDEX) {
     127            0 :     throw UnsupportedError("unexpected chainIndex");
     128              :   }
     129              : 
     130            9 :   final childDerivationPath = "$chainIndex/$index";
     131              : 
     132            9 :   final node = masterNode.derivePath(childDerivationPath);
     133              : 
     134            9 :   final publicKey = node.publicKey;
     135              : 
     136            9 :   final addressMap = {
     137            9 :     for (final addressType in addressTypes)
     138           18 :       addressType: pubKeyToAddress(publicKey, addressType, networkType),
     139              :   };
     140              : 
     141           18 :   final mainAddress = addressMap[addressTypes.first]!;
     142              : 
     143            9 :   return NodeWithAddress.fromChainIndex(
     144              :     node: node,
     145              :     address: mainAddress,
     146              :     chainIndex: chainIndex,
     147              :     derivationPath: childDerivationPath,
     148              :     addresses: addressMap,
     149              :     walletPurpose: walletPurpose,
     150              :   );
     151              : }
     152              : 
     153            1 : bip32.BIP32 deriveChildNodeFromPath({
     154              :   required Uint8List seed,
     155              :   required String childDerivationPath,
     156              :   required HDWalletPath walletPath,
     157              :   UTXONetworkType? networkType,
     158              : }) {
     159            1 :   final masterNode = deriveMasterNodeFromSeed(
     160              :     seed: seed,
     161              :     networkType: networkType,
     162              :     walletPath: walletPath,
     163              :   );
     164              : 
     165            1 :   final node = masterNode.derivePath(childDerivationPath);
     166              : 
     167              :   return node;
     168              : }
     169              : 
     170              : extension on BipNode {
     171            2 :   String toBase58wkCompatibility(int parentFingerprint, int depth) {
     172              :     final version =
     173            8 :         (!isNeutered()) ? network.bip32.private : network.bip32.public;
     174            2 :     Uint8List buffer = new Uint8List(78);
     175            4 :     ByteData bytes = buffer.buffer.asByteData();
     176            2 :     bytes.setUint32(0, version);
     177            2 :     bytes.setUint8(4, depth);
     178            2 :     bytes.setUint32(5, parentFingerprint);
     179            4 :     bytes.setUint32(9, index);
     180            4 :     buffer.setRange(13, 45, chainCode);
     181            2 :     if (!isNeutered()) {
     182            0 :       bytes.setUint8(45, 0);
     183            0 :       buffer.setRange(46, 78, privateKey!);
     184              :     } else {
     185            4 :       buffer.setRange(45, 78, publicKey);
     186              :     }
     187              : 
     188            2 :     return bs58check.encode(buffer);
     189              :   }
     190              : }
     191              : 
     192            2 : BipNode deriveNode(Uint8List seed, String path) {
     193            2 :   final node = bip32.BIP32.fromSeed(seed);
     194            2 :   return node.derivePath(path);
     195              : }
        

Generated by: LCOV version 2.0-1