@vbyte/btc-dev
Version:
Batteries-included toolset for plebian bitcoin development
50 lines (49 loc) • 1.52 kB
JavaScript
import { Buff } from '@vbyte/buff';
import { encode_tapbranch } from './encode.js';
export function get_merkle_root(leaves) {
return merkleize(leaves)[0];
}
export function merkleize(taptree, target, path = []) {
const leaves = [];
const tree = [];
if (taptree.length < 1) {
throw new Error('Tree is empty!');
}
for (let i = 0; i < taptree.length; i++) {
const bytes = taptree[i];
if (Array.isArray(bytes)) {
let [tapleaf, new_target, branches] = merkleize(bytes, target);
target = new_target;
leaves.push(tapleaf);
for (const branch of branches) {
path.push(branch);
}
}
else {
const leaf = Buff.bytes(bytes).hex;
leaves.push(leaf);
}
}
if (leaves.length === 1) {
return [leaves[0], target, path];
}
leaves.sort();
if (leaves.length % 2 !== 0) {
leaves.push(leaves[leaves.length - 1]);
}
for (let i = 0; i < leaves.length - 1; i += 2) {
const branch = encode_tapbranch(leaves[i], leaves[i + 1]).hex;
tree.push(branch);
if (typeof target === 'string') {
if (target === leaves[i]) {
path.push(leaves[i + 1]);
target = branch;
}
else if (target === leaves[i + 1]) {
path.push(leaves[i]);
target = branch;
}
}
}
return merkleize(tree, target, path);
}