11'use strict' ;
22Object . defineProperty ( exports , '__esModule' , { value : true } ) ;
33exports . checkTaprootInputForSigs =
4+ exports . createTapTreeUsingHuffmanConstructor =
45 exports . tapTreeFromList =
56 exports . tapTreeToList =
67 exports . tweakInternalPubKey =
@@ -18,6 +19,7 @@ const psbtutils_1 = require('./psbtutils');
1819const bip341_1 = require ( '../payments/bip341' ) ;
1920const payments_1 = require ( '../payments' ) ;
2021const psbtutils_2 = require ( './psbtutils' ) ;
22+ const sortutils_1 = require ( '../sortutils' ) ;
2123const toXOnly = pubKey => ( pubKey . length === 32 ? pubKey : pubKey . slice ( 1 , 33 ) ) ;
2224exports . toXOnly = toXOnly ;
2325/**
@@ -155,6 +157,35 @@ function tapTreeFromList(leaves = []) {
155157 return instertLeavesInTree ( leaves ) ;
156158}
157159exports . tapTreeFromList = tapTreeFromList ;
160+ /**
161+ * Construct a Taptree where the leaves with the highest likelihood of use are closer to the root.
162+ * @param nodes A list of nodes where each element contains a weight (likelihood of use) and
163+ * a node which could be a Tapleaf or a branch in a Taptree
164+ */
165+ function createTapTreeUsingHuffmanConstructor ( nodes ) {
166+ if ( nodes . length === 0 )
167+ throw new Error ( 'Cannot create taptree from empty list.' ) ;
168+ const compare = ( a , b ) => a . weight - b . weight ;
169+ const sortedNodes = [ ...nodes ] . sort ( compare ) ; // Sort array in ascending order of weight
170+ let newNode ;
171+ let nodeA , nodeB ;
172+ while ( sortedNodes . length > 1 ) {
173+ // Construct a new node from the two nodes with the least weight
174+ nodeA = sortedNodes . shift ( ) ; // There will always be an element to pop
175+ nodeB = sortedNodes . shift ( ) ; // because loop ends when length <= 1
176+ newNode = {
177+ weight : nodeA . weight + nodeB . weight ,
178+ node : [ nodeA . node , nodeB . node ] ,
179+ } ;
180+ // Place newNode back into array
181+ ( 0 , sortutils_1 . insertIntoSortedArray ) ( sortedNodes , newNode , compare ) ;
182+ }
183+ // Last node is the root node
184+ const root = sortedNodes . shift ( ) ;
185+ return root . node ;
186+ }
187+ exports . createTapTreeUsingHuffmanConstructor =
188+ createTapTreeUsingHuffmanConstructor ;
158189function checkTaprootInputForSigs ( input , action ) {
159190 const sigs = extractTaprootSigs ( input ) ;
160191 return sigs . some ( sig =>
0 commit comments