1
1
'use strict' ;
2
2
Object . defineProperty ( exports , '__esModule' , { value : true } ) ;
3
3
exports . checkTaprootInputForSigs =
4
+ exports . createTapTreeUsingHuffmanConstructor =
4
5
exports . tapTreeFromList =
5
6
exports . tapTreeToList =
6
7
exports . tweakInternalPubKey =
@@ -18,6 +19,7 @@ const psbtutils_1 = require('./psbtutils');
18
19
const bip341_1 = require ( '../payments/bip341' ) ;
19
20
const payments_1 = require ( '../payments' ) ;
20
21
const psbtutils_2 = require ( './psbtutils' ) ;
22
+ const sortutils_1 = require ( '../sortutils' ) ;
21
23
const toXOnly = pubKey => ( pubKey . length === 32 ? pubKey : pubKey . slice ( 1 , 33 ) ) ;
22
24
exports . toXOnly = toXOnly ;
23
25
/**
@@ -155,6 +157,35 @@ function tapTreeFromList(leaves = []) {
155
157
return instertLeavesInTree ( leaves ) ;
156
158
}
157
159
exports . 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 ;
158
189
function checkTaprootInputForSigs ( input , action ) {
159
190
const sigs = extractTaprootSigs ( input ) ;
160
191
return sigs . some ( sig =>
0 commit comments