j-bitcoin
Version:
Comprehensive JavaScript/TypeScript Bitcoin (BTC) wallet library with custodial and non-custodial support, hierarchical deterministic keys, threshold signatures, and advanced cryptographic features
282 lines (211 loc) • 40.1 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<title>src/core/taproot/merkle-tree.js - J-Bitcoin - Bitcoin Wallet Library</title>
<meta name="description" content="JavaScript/TypeScript Bitcoin wallet library with HD wallets, threshold signatures, and BIP compliance" />
<meta name="keywords" content="bitcoin, btc, cryptocurrency, wallet, javascript, typescript, threshold signatures, bip32, bip39" />
<meta name="keyword" content="bitcoin, btc, cryptocurrency, wallet, javascript, typescript, threshold signatures, bip32, bip39" />
<script src="scripts/prettify/prettify.js"></script>
<script src="scripts/prettify/lang-css.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
<script src="scripts/nav.js" defer></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger" class="navicon-button x">
<div class="navicon"></div>
</label>
<label for="nav-trigger" class="overlay"></label>
<nav class="wrap">
<input type="text" id="nav-search" placeholder="Search" />
<h2><a href="index.html">Home</a></h2><h2><a href="https://github.com/yfbsei/J-Bitcoin" target="_blank" class="menu-item home-link" id="home-link" >🏠 Home</a></h2><h2><a href="https://github.com/yfbsei/J-Bitcoin" target="_blank" class="menu-item github-link" id="github-link" >📚 GitHub</a></h2><h2><a href="https://www.npmjs.com/package/j-bitcoin" target="_blank" class="menu-item npm-link" id="npm-link" >📦 NPM</a></h2><h2><a href="https://github.com/yfbsei/J-Bitcoin/tree/main/examples" target="_blank" class="menu-item examples-link" id="examples-link" >🔧 Examples</a></h2><h2><a href="https://github.com/yfbsei/J-Bitcoin/blob/main/CHANGELOG.md" target="_blank" class="menu-item changelog-link" id="changelog-link" >📊 Changelog</a></h2><h3>Classes</h3><ul><li><a href="BIP143.html">BIP143</a><ul class='methods'><li data-type='method' style='display: none;'><a href="BIP143.html#.calculate">calculate</a></li><li data-type='method' style='display: none;'><a href="BIP143.html#.forP2WPKH">forP2WPKH</a></li><li data-type='method' style='display: none;'><a href="BIP143.html#.hashOutputs">hashOutputs</a></li><li data-type='method' style='display: none;'><a href="BIP143.html#.hashPrevouts">hashPrevouts</a></li><li data-type='method' style='display: none;'><a href="BIP143.html#.hashSequence">hashSequence</a></li></ul></li><li><a href="BIP322.html">BIP322</a><ul class='methods'><li data-type='method' style='display: none;'><a href="BIP322.html#.createToSign">createToSign</a></li><li data-type='method' style='display: none;'><a href="BIP322.html#.createToSpend">createToSpend</a></li><li data-type='method' style='display: none;'><a href="BIP322.html#.hashMessage">hashMessage</a></li><li data-type='method' style='display: none;'><a href="BIP322.html#.sign">sign</a></li><li data-type='method' style='display: none;'><a href="BIP322.html#.signLegacy">signLegacy</a></li><li data-type='method' style='display: none;'><a href="BIP322.html#.verify">verify</a></li><li data-type='method' style='display: none;'><a href="BIP322.html#.verifyLegacy">verifyLegacy</a></li></ul></li><li><a href="BIP322Error.html">BIP322Error</a></li><li><a href="BIP341.html">BIP341</a><ul class='methods'><li data-type='method' style='display: none;'><a href="BIP341.html#.calculate">calculate</a></li><li data-type='method' style='display: none;'><a href="BIP341.html#.forScriptPath">forScriptPath</a></li><li data-type='method' style='display: none;'><a href="BIP341.html#.shaAmounts">shaAmounts</a></li><li data-type='method' style='display: none;'><a href="BIP341.html#.shaOutputs">shaOutputs</a></li><li data-type='method' style='display: none;'><a href="BIP341.html#.shaPrevouts">shaPrevouts</a></li><li data-type='method' style='display: none;'><a href="BIP341.html#.shaScriptPubkeys">shaScriptPubkeys</a></li><li data-type='method' style='display: none;'><a href="BIP341.html#.shaSequences">shaSequences</a></li></ul></li><li><a href="BIP49.html">BIP49</a><ul class='methods'><li data-type='method' style='display: none;'><a href="BIP49.html#.createRedeemScript">createRedeemScript</a></li><li data-type='method' style='display: none;'><a href="BIP49.html#.createScriptPubKey">createScriptPubKey</a></li><li data-type='method' style='display: none;'><a href="BIP49.html#.getAccountPath">getAccountPath</a></li><li data-type='method' style='display: none;'><a href="BIP49.html#.getDerivationPath">getDerivationPath</a></li><li data-type='method' style='display: none;'><a href="BIP49.html#.toAddress">toAddress</a></li></ul></li><li><a href="CustodialWallet.html">CustodialWallet</a><ul class='methods'><li data-type='method' style='display: none;'><a href="CustodialWallet.html#canSign">canSign</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#clearCache">clearCache</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#createTransaction">createTransaction</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#deriveAddress">deriveAddress</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#destroy">destroy</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#exportWIF">exportWIF</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#getAddresses">getAddresses</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#getChangeAddress">getChangeAddress</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#getExtendedPrivateKey">getExtendedPrivateKey</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#getExtendedPublicKey">getExtendedPublicKey</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#getMnemonic">getMnemonic</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#getNetwork">getNetwork</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#getReceivingAddress">getReceivingAddress</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#signMessage">signMessage</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#signMessageBIP322">signMessageBIP322</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#signTransaction">signTransaction</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#toJSON">toJSON</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#verifyMessage">verifyMessage</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#.createNew">createNew</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#.fromExtendedKey">fromExtendedKey</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#.fromMnemonic">fromMnemonic</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#.fromSeed">fromSeed</a></li><li data-type='method' style='display: none;'><a href="CustodialWallet.html#.fromWIF">fromWIF</a></li></ul></li><li></li><li><a href="CustodialWalletError.html">CustodialWalletError</a></li><li></li><li><a href="DecodingError.html">DecodingError</a></li><li><a href="ECDSAError.html">ECDSAError</a></li><li></li><li><a href="EncodingError.html">EncodingError</a></li><li><a href="JVRSS.html">JVRSS</a><ul class='methods'><li data-type='method' style='display: none;'><a href="JVRSS.html#broadcastObfuscatedCoefficients">broadcastObfuscatedCoefficients</a></li><li data-type='method' style='display: none;'><a href="JVRSS.html#calculateSharedPublicKey">calculateSharedPublicKey</a></li><li data-type='method' style='display: none;'><a href="JVRSS.html#calculateShares">calculateShares</a></li><li data-type='method' style='display: none;'><a href="JVRSS.html#clear">clear</a></li><li data-type='method' style='display: none;'><a href="JVRSS.html#distributePolynomialPoints">distributePolynomialPoints</a></li><li data-type='method' style='display: none;'><a href="JVRSS.html#generatePolynomials">generatePolynomials</a></li><li data-type='method' style='display: none;'><a href="JVRSS.html#getParticipant">getParticipant</a></li><li data-type='method' style='display: none;'><a href="JVRSS.html#getSharesForInterpolation">getSharesForInterpolation</a></li><li data-type='method' style='display: none;'><a href="JVRSS.html#reconstructSecret">reconstructSecret</a></li><li data-type='method' style='display: none;'><a href="JVRSS.html#runProtocol">runProtocol</a></li><li data-type='method' style='display: none;'><a href="JVRSS.html#verifyAllShares">verifyAllShares</a></li></ul></li><li><a href="JVRSSError.html">JVRSSError</a></li><li><a href="LegacySighash.html">LegacySighash</a><ul class='methods'><li data-type='method' style='display: none;'><a href="LegacySighash.html#.calculate">calculate</a></li></ul></li><li><a href="MPCError.html">MPCError</a></li><li><a href="NonCustodialWallet.html">NonCustodialWallet</a><ul class='methods'><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#_exportShares">_exportShares</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#_reconstructPublicKey">_reconstructPublicKey</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#canSign">canSign</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#canSignHD">canSignHD</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#clear">clear</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#clearAddressCache">clearAddressCache</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#createTransaction">createTransaction</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#deriveAddress">deriveAddress</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#destroy">destroy</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#exportShares">exportShares</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#exportWIF">exportWIF</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#generateEphemeralKeys">generateEphemeralKeys</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#getAddress">getAddress</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#getAddressCount">getAddressCount</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#getAddresses">getAddresses</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#getChangeAddress">getChangeAddress</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#getExtendedPrivateKey">getExtendedPrivateKey</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#getExtendedPublicKey">getExtendedPublicKey</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#getMnemonic">getMnemonic</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#getNetwork">getNetwork</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#getPublicKey">getPublicKey</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#getReceivingAddress">getReceivingAddress</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#getShare">getShare</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#getShares">getShares</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#getThresholdConfig">getThresholdConfig</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#hasHD">hasHD</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#initialize">initialize</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#listAddresses">listAddresses</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#sign">sign</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#signMessage">signMessage</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#signMessageBIP322">signMessageBIP322</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#signMessageHD">signMessageHD</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#signTransaction">signTransaction</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#toJSON">toJSON</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#verify">verify</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#verifyMessageHD">verifyMessageHD</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#.createNew">createNew</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#.createNewHD">createNewHD</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#.fromExtendedKey">fromExtendedKey</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#.fromMnemonic">fromMnemonic</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#.fromSeed">fromSeed</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#.fromShares">fromShares</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#.fromWIF">fromWIF</a></li><li data-type='method' style='display: none;'><a href="NonCustodialWallet.html#.importShares">importShares</a></li></ul></li><li><a href="Participant.html">Participant</a><ul class='methods'><li data-type='method' style='display: none;'><a href="Participant.html#calculateKeyShare">calculateKeyShare</a></li><li data-type='method' style='display: none;'><a href="Participant.html#clear">clear</a></li><li data-type='method' style='display: none;'><a href="Participant.html#evaluateAt">evaluateAt</a></li><li data-type='method' style='display: none;'><a href="Participant.html#generatePolynomial">generatePolynomial</a></li><li data-type='method' style='display: none;'><a href="Participant.html#generateSignatureShare">generateSignatureShare</a></li><li data-type='method' style='display: none;'><a href="Participant.html#getBlindingShare">getBlindingShare</a></li><li data-type='method' style='display: none;'><a href="Participant.html#getKeyShare">getKeyShare</a></li><li data-type='method' style='display: none;'><a href="Participant.html#getKeySharePublicKey">getKeySharePublicKey</a></li><li data-type='method' style='display: none;'><a href="Participant.html#getNextEphemeralKey">getNextEphemeralKey</a></li><li data-type='method' style='display: none;'><a href="Participant.html#getObfuscatedCoefficients">getObfuscatedCoefficients</a></li><li data-type='method' style='display: none;'><a href="Participant.html#getPolynomialPointFor">getPolynomialPointFor</a></li><li data-type='method' style='display: none;'><a href="Participant.html#receivePolynomialPoint">receivePolynomialPoint</a></li><li data-type='method' style='display: none;'><a href="Participant.html#setBlindingShare">setBlindingShare</a></li><li data-type='method' style='display: none;'><a href="Participant.html#storeEphemeralKey">storeEphemeralKey</a></li><li data-type='method' style='display: none;'><a href="Participant.html#verifyPolynomialPoint">verifyPolynomialPoint</a></li></ul></li><li><a href="ParticipantError.html">ParticipantError</a></li><li><a href="ParticipantShare.html">ParticipantShare</a></li><li><a href="Polynomial.html">Polynomial</a><ul class='methods'><li data-type='method' style='display: none;'><a href="Polynomial.html#clear">clear</a></li><li data-type='method' style='display: none;'><a href="Polynomial.html#evaluate">evaluate</a></li><li data-type='method' style='display: none;'><a href="Polynomial.html#generateShares">generateShares</a></li><li data-type='method' style='display: none;'><a href="Polynomial.html#getCoefficients">getCoefficients</a></li><li data-type='method' style='display: none;'><a href="Polynomial.html#getSecret">getSecret</a></li><li data-type='method' style='display: none;'><a href="Polynomial.html#.interpolate">interpolate</a></li><li data-type='method' style='display: none;'><a href="Polynomial.html#.lagrangeCoefficient">lagrangeCoefficient</a></li><li data-type='method' style='display: none;'><a href="Polynomial.html#.reconstructSecret">reconstructSecret</a></li></ul></li><li><a href="PolynomialError.html">PolynomialError</a></li><li><a href="Schnorr.html">Schnorr</a><ul class='methods'><li data-type='method' style='display: none;'><a href="Schnorr.html#sign">sign</a></li></ul></li><li><a href="SchnorrError.html">SchnorrError</a></li><li></li><li><a href="ScriptBuilder.html">ScriptBuilder</a><ul class='methods'><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#addOp">addOp</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#build">build</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#pushData">pushData</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#pushNumber">pushNumber</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#reset">reset</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#.createCLTV">createCLTV</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#.createCSV">createCSV</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#.createMultisig">createMultisig</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#.createOpReturn">createOpReturn</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#.createP2PKH">createP2PKH</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#.createP2PKHFromPubkey">createP2PKHFromPubkey</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#.createP2PKHScriptSig">createP2PKHScriptSig</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#.createP2SH">createP2SH</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#.createP2SHScriptSig">createP2SHScriptSig</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#.createP2TR">createP2TR</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#.createP2WPKH">createP2WPKH</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#.createP2WPKHFromPubkey">createP2WPKHFromPubkey</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#.createP2WSH">createP2WSH</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#.detectType">detectType</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#.disassemble">disassemble</a></li><li data-type='method' style='display: none;'><a href="ScriptBuilder.html#.parse">parse</a></li></ul></li><li><a href="ScriptError.html">ScriptError</a></li><li><a href="SighashCalculator.html">SighashCalculator</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SighashCalculator.html#.calculate">calculate</a></li></ul></li><li><a href="SighashError.html">SighashError</a></li><li><a href="TaggedHash.html">TaggedHash</a><ul class='methods'><li data-type='method' style='display: none;'><a href="TaggedHash.html#.create">create</a></li></ul></li><li><a href="ThresholdSignatureError.html">ThresholdSignatureError</a></li><li><a href="ThresholdSignatureScheme.html">ThresholdSignatureScheme</a><ul class='methods'><li data-type='method' style='display: none;'><a href="ThresholdSignatureScheme.html#clear">clear</a></li><li data-type='method' style='display: none;'><a href="ThresholdSignatureScheme.html#generateEphemeralKeys">generateEphemeralKeys</a></li><li data-type='method' style='display: none;'><a href="ThresholdSignatureScheme.html#generateSharedPrivateKey">generateSharedPrivateKey</a></li><li data-type='method' style='display: none;'><a href="ThresholdSignatureScheme.html#getConfig">getConfig</a></li><li data-type='method' style='display: none;'><a href="ThresholdSignatureScheme.html#getNextEphemeralKey">getNextEphemeralKey</a></li><li data-type='method' style='display: none;'><a href="ThresholdSignatureScheme.html#getPublicKey">getPublicKey</a></li><li data-type='method' style='display: none;'><a href="ThresholdSignatureScheme.html#sign">sign</a></li><li data-type='method' style='display: none;'><a href="ThresholdSignatureScheme.html#signMessage">signMessage</a></li><li data-type='method' style='display: none;'><a href="ThresholdSignatureScheme.html#verify">verify</a></li></ul></li><li><a href="TransactionBuilder.html">TransactionBuilder</a><ul class='methods'><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#addInput">addInput</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#addOpReturn">addOpReturn</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#addOutput">addOutput</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#addWitness">addWitness</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#build">build</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#calculateFee">calculateFee</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#clone">clone</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#enableRBF">enableRBF</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#getTxid">getTxid</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#getVirtualSize">getVirtualSize</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#getWeight">getWeight</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#getWtxid">getWtxid</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#isFullySigned">isFullySigned</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#reset">reset</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#serialize">serialize</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#setInputSequence">setInputSequence</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#setLocktime">setLocktime</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#setVersion">setVersion</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#signAllInputs">signAllInputs</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#signInput">signInput</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#signInputs">signInputs</a></li><li data-type='method' style='display: none;'><a href="TransactionBuilder.html#toHex">toHex</a></li></ul></li><li></li><li><a href="TransactionBuilderError.html">TransactionBuilderError</a></li><li><a href="TransactionParseError.html">TransactionParseError</a></li><li><a href="TransactionParser.html">TransactionParser</a><ul class='methods'><li data-type='method' style='display: none;'><a href="TransactionParser.html#.fromBuffer">fromBuffer</a></li><li data-type='method' style='display: none;'><a href="TransactionParser.html#.fromHex">fromHex</a></li><li data-type='method' style='display: none;'><a href="TransactionParser.html#.getTxid">getTxid</a></li><li data-type='method' style='display: none;'><a href="TransactionParser.html#.serializeWithoutWitness">serializeWithoutWitness</a></li></ul></li><li><a href="ValidationError.html">ValidationError</a></li><li><a href="WitnessBuilder.html">WitnessBuilder</a><ul class='methods'><li data-type='method' style='display: none;'><a href="WitnessBuilder.html#.buildControlBlock">buildControlBlock</a></li><li data-type='method' style='display: none;'><a href="WitnessBuilder.html#.buildP2TRKeyPath">buildP2TRKeyPath</a></li><li data-type='method' style='display: none;'><a href="WitnessBuilder.html#.buildP2TRScriptPath">buildP2TRScriptPath</a></li><li data-type='method' style='display: none;'><a href="WitnessBuilder.html#.buildP2WPKH">buildP2WPKH</a></li><li data-type='method' style='display: none;'><a href="WitnessBuilder.html#.buildP2WSH">buildP2WSH</a></li><li data-type='method' style='display: none;'><a href="WitnessBuilder.html#.buildP2WSHMultisig">buildP2WSHMultisig</a></li><li data-type='method' style='display: none;'><a href="WitnessBuilder.html#.calculateTapbranchHash">calculateTapbranchHash</a></li><li data-type='method' style='display: none;'><a href="WitnessBuilder.html#.calculateTapleafHash">calculateTapleafHash</a></li><li data-type='method' style='display: none;'><a href="WitnessBuilder.html#.calculateTaptweak">calculateTaptweak</a></li><li data-type='method' style='display: none;'><a href="WitnessBuilder.html#.parse">parse</a></li><li data-type='method' style='display: none;'><a href="WitnessBuilder.html#.serialize">serialize</a></li><li data-type='method' style='display: none;'><a href="WitnessBuilder.html#.validate">validate</a></li></ul></li><li><a href="WitnessError.html">WitnessError</a></li></ul><h3>Namespaces</h3><ul><li><a href="BECH32.html">BECH32</a><ul class='methods'><li data-type='method' style='display: none;'><a href="BECH32.html#.decode">decode</a></li><li data-type='method' style='display: none;'><a href="BECH32.html#.getAddressType">getAddressType</a></li><li data-type='method' style='display: none;'><a href="BECH32.html#.getPrefix">getPrefix</a></li><li data-type='method' style='display: none;'><a href="BECH32.html#.to_P2TR">to_P2TR</a></li><li data-type='method' style='display: none;'><a href="BECH32.html#.to_P2WPKH">to_P2WPKH</a></li><li data-type='method' style='display: none;'><a href="BECH32.html#.to_P2WSH">to_P2WSH</a></li><li data-type='method' style='display: none;'><a href="BECH32.html#.validate">validate</a></li></ul></li><li><a href="BIP39.html">BIP39</a><ul class='methods'><li data-type='method' style='display: none;'><a href="BIP39.html#.deriveSeed">deriveSeed</a></li><li data-type='method' style='display: none;'><a href="BIP39.html#.generateMnemonic">generateMnemonic</a></li><li data-type='method' style='display: none;'><a href="BIP39.html#.getWordList">getWordList</a></li><li data-type='method' style='display: none;'><a href="BIP39.html#.mnemonicToEntropy">mnemonicToEntropy</a></li><li data-type='method' style='display: none;'><a href="BIP39.html#.validateChecksum">validateChecksum</a></li><li data-type='method' style='display: none;'><a href="BIP39.html#.validateMnemonic">validateMnemonic</a></li></ul></li><li><a href="ECDSA.html">ECDSA</a><ul class='methods'><li data-type='method' style='display: none;'><a href="ECDSA.html#.getPublicKey">getPublicKey</a></li><li data-type='method' style='display: none;'><a href="ECDSA.html#.recoverPublicKey">recoverPublicKey</a></li><li data-type='method' style='display: none;'><a href="ECDSA.html#.sign">sign</a></li><li data-type='method' style='display: none;'><a href="ECDSA.html#.signMessage">signMessage</a></li><li data-type='method' style='display: none;'><a href="ECDSA.html#.verify">verify</a></li><li data-type='method' style='display: none;'><a href="ECDSA.html#.verifyMessage">verifyMessage</a></li></ul></li></ul><h3>Global</h3><ul><li><a href="global.html#ADDRESS_FORMATS">ADDRESS_FORMATS</a></li><li><a href="global.html#ADDRESS_TYPE_PURPOSE">ADDRESS_TYPE_PURPOSE</a></li><li><a href="global.html#ADDSS">ADDSS</a></li><li><a href="global.html#BECH32_PREFIXES">BECH32_PREFIXES</a></li><li><a href="global.html#BIP322_CONSTANTS">BIP322_CONSTANTS</a></li><li><a href="global.html#BIP32_CONSTANTS">BIP32_CONSTANTS</a></li><li><a href="global.html#BIP340_CONSTANTS">BIP340_CONSTANTS</a></li><li><a href="global.html#BIP39_CONSTANTS">BIP39_CONSTANTS</a></li><li><a href="global.html#BIP44_CONSTANTS">BIP44_CONSTANTS</a></li><li><a href="global.html#BIP49_CONSTANTS">BIP49_CONSTANTS</a></li><li><a href="global.html#BIP_COMPLIANCE">BIP_COMPLIANCE</a></li><li><a href="global.html#BIP_PURPOSES">BIP_PURPOSES</a></li><li><a href="global.html#CRYPTO_CONSTANTS">CRYPTO_CONSTANTS</a></li><li><a href="global.html#CURVE_ORDER">CURVE_ORDER</a></li><li><a href="global.html#ENCODING_CONSTANTS">ENCODING_CONSTANTS</a></li><li><a href="global.html#FEATURES">FEATURES</a></li><li><a href="global.html#G">G</a></li><li><a href="global.html#HARDENED_OFFSET">HARDENED_OFFSET</a></li><li><a href="global.html#INVSS">INVSS</a></li><li><a href="global.html#LIBRARY_INFO">LIBRARY_INFO</a></li><li><a href="global.html#NETWORKS">NETWORKS</a></li><li><a href="global.html#NETWORK_VERSIONS">NETWORK_VERSIONS</a></li><li><a href="global.html#OPCODES">OPCODES</a></li><li><a href="global.html#PROSS">PROSS</a></li><li><a href="global.html#SECURITY_CONSTANTS">SECURITY_CONSTANTS</a></li><li><a href="global.html#SIGHASH">SIGHASH</a></li><li><a href="global.html#TAPROOT_CONSTANTS">TAPROOT_CONSTANTS</a></li><li><a href="global.html#THRESHOLD_CONSTANTS">THRESHOLD_CONSTANTS</a></li><li><a href="global.html#TRANSACTION_CONSTANTS">TRANSACTION_CONSTANTS</a></li><li><a href="global.html#TX_CONSTANTS">TX_CONSTANTS</a></li><li><a href="global.html#b58decode">b58decode</a></li><li><a href="global.html#b58encode">b58encode</a></li><li><a href="global.html#computeAdditiveShares">computeAdditiveShares</a></li><li><a href="global.html#computeMultiplicativeShares">computeMultiplicativeShares</a></li><li><a href="global.html#convertBits">convertBits</a></li><li><a href="global.html#createP2WPKHScriptCode">createP2WPKHScriptCode</a></li><li><a href="global.html#createThresholdScheme">createThresholdScheme</a></li><li><a href="global.html#decode">decode</a></li><li><a href="global.html#decodeAddress">decodeAddress</a></li><li><a href="global.html#decodeExtendedKey">decodeExtendedKey</a></li><li><a href="global.html#decodeLegacyAddress">decodeLegacyAddress</a></li><li><a href="global.html#decodeSegwit">decodeSegwit</a></li><li><a href="global.html#decodeSegwitAddress">decodeSegwitAddress</a></li><li><a href="global.html#decodeWIFPrivateKey">decodeWIFPrivateKey</a></li><li><a href="global.html#derive">derive</a></li><li><a href="global.html#deriveChildKey">deriveChildKey</a></li><li><a href="global.html#doubleHash256">doubleHash256</a></li><li><a href="global.html#encode">encode</a></li><li><a href="global.html#encodeAddress">encodeAddress</a></li><li><a href="global.html#encodeExtendedKey">encodeExtendedKey</a></li><li><a href="global.html#encodeP2PKH">encodeP2PKH</a></li><li><a href="global.html#encodeP2SH">encodeP2SH</a></li><li><a href="global.html#encodePush">encodePush</a></li><li><a href="global.html#encodeSegwit">encodeSegwit</a></li><li><a href="global.html#encodeVarInt">encodeVarInt</a></li><li><a href="global.html#encodeWIF">encodeWIF</a></li><li><a href="global.html#generateDerivationPath">generateDerivationPath</a></li><li><a href="global.html#generateEphemeralKeyShares">generateEphemeralKeyShares</a></li><li><a href="global.html#generateMasterKey">generateMasterKey</a></li><li><a href="global.html#generateSecureRandom">generateSecureRandom</a></li><li><a href="global.html#getFingerprint">getFingerprint</a></li><li><a href="global.html#hash160">hash160</a></li><li><a href="global.html#hash256">hash256</a></li><li><a href="global.html#normalizeUnicode">normalizeUnicode</a></li><li><a href="global.html#polymod">polymod</a></li><li><a href="global.html#rmd160">rmd160</a></li><li><a href="global.html#rotl">rotl</a></li><li><a href="global.html#runJVRSS">runJVRSS</a></li><li><a href="global.html#secureClear">secureClear</a></li><li><a href="global.html#sha256">sha256</a></li><li><a href="global.html#taggedHash">taggedHash</a></li><li><a href="global.html#validateAddress">validateAddress</a></li><li><a href="global.html#validateAndGetNetwork">validateAndGetNetwork</a></li><li><a href="global.html#validateBuffer">validateBuffer</a></li><li><a href="global.html#validateBufferLength">validateBufferLength</a></li><li><a href="global.html#validateChildKey">validateChildKey</a></li><li><a href="global.html#validateDerivationPath">validateDerivationPath</a></li><li><a href="global.html#validateEntropyQuality">validateEntropyQuality</a></li><li><a href="global.html#validateExtendedKey">validateExtendedKey</a></li><li><a href="global.html#validateHexString">validateHexString</a></li><li><a href="global.html#validateNumberRange">validateNumberRange</a></li><li><a href="global.html#validatePrivateKey">validatePrivateKey</a></li><li><a href="global.html#validatePublicKey">validatePublicKey</a></li><li><a href="global.html#validateSeed">validateSeed</a></li></ul>
</nav>
<div id="main">
<h1 class="page-title">src/core/taproot/merkle-tree.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>/**
* @fileoverview Taproot merkle tree implementation for script path spending
* @version 1.0.0
* @author yfbsei
* @license ISC
*/
import { createHash } from 'node:crypto';
class MerkleTreeError extends Error {
constructor(message, code, details = {}) {
super(message);
this.name = 'MerkleTreeError';
this.code = code;
this.details = details;
}
}
const MERKLE_CONSTANTS = {
HASH_SIZE: 32,
MAX_TREE_DEPTH: 128,
MAX_SCRIPT_SIZE: 10000,
MAX_LEAVES: 2 ** 16,
TAPLEAF_TAG: 'TapLeaf',
TAPBRANCH_TAG: 'TapBranch',
TAPTWEAK_TAG: 'TapTweak',
DEFAULT_LEAF_VERSION: 0xc0
};
class TaggedHash {
static create(tag, data) {
const tagHash = createHash('sha256').update(tag).digest();
const taggedData = Buffer.concat([tagHash, tagHash, data]);
return createHash('sha256').update(taggedData).digest();
}
static createTapLeaf(leafVersion, script) {
const data = Buffer.concat([
Buffer.from([leafVersion]),
Buffer.from([script.length]),
script
]);
return this.create(MERKLE_CONSTANTS.TAPLEAF_TAG, data);
}
static createTapBranch(left, right) {
const ordered = Buffer.compare(left, right) < 0
? Buffer.concat([left, right])
: Buffer.concat([right, left]);
return this.create(MERKLE_CONSTANTS.TAPBRANCH_TAG, ordered);
}
static createTapTweak(internalKey, merkleRoot = null) {
const data = merkleRoot
? Buffer.concat([internalKey, merkleRoot])
: internalKey;
return this.create(MERKLE_CONSTANTS.TAPTWEAK_TAG, data);
}
}
class TaprootMerkleTree {
constructor(scripts, leafVersion = MERKLE_CONSTANTS.DEFAULT_LEAF_VERSION) {
if (!Array.isArray(scripts) || scripts.length === 0) {
throw new MerkleTreeError('Scripts array is required', 'INVALID_SCRIPTS');
}
if (scripts.length > MERKLE_CONSTANTS.MAX_LEAVES) {
throw new MerkleTreeError('Too many scripts', 'TOO_MANY_LEAVES');
}
this.leafVersion = leafVersion;
this.scripts = scripts;
this.leaves = [];
this.tree = [];
this._buildTree();
}
_buildTree() {
this.leaves = this.scripts.map((script, index) => ({
script: Buffer.isBuffer(script) ? script : Buffer.from(script),
leafVersion: this.leafVersion,
hash: TaggedHash.createTapLeaf(
this.leafVersion,
Buffer.isBuffer(script) ? script : Buffer.from(script)
),
index
}));
if (this.leaves.length === 1) {
this.tree = [[this.leaves[0].hash]];
this.root = this.leaves[0].hash;
return;
}
let currentLevel = this.leaves.map(leaf => leaf.hash);
this.tree = [currentLevel];
while (currentLevel.length > 1) {
const nextLevel = [];
for (let i = 0; i < currentLevel.length; i += 2) {
if (i + 1 < currentLevel.length) {
const branch = TaggedHash.createTapBranch(currentLevel[i], currentLevel[i + 1]);
nextLevel.push(branch);
} else {
nextLevel.push(currentLevel[i]);
}
}
this.tree.push(nextLevel);
currentLevel = nextLevel;
}
this.root = currentLevel[0];
}
getRoot() {
return this.root;
}
getMerklePath(leafIndex) {
if (leafIndex < 0 || leafIndex >= this.leaves.length) {
throw new MerkleTreeError('Invalid leaf index', 'INVALID_INDEX');
}
const path = [];
let index = leafIndex;
for (let level = 0; level < this.tree.length - 1; level++) {
const currentLevel = this.tree[level];
const siblingIndex = index % 2 === 0 ? index + 1 : index - 1;
if (siblingIndex < currentLevel.length) {
path.push({
hash: currentLevel[siblingIndex],
position: index % 2 === 0 ? 'right' : 'left'
});
}
index = Math.floor(index / 2);
}
return {
leafIndex,
leafHash: this.leaves[leafIndex].hash,
hashes: path.map(p => p.hash),
positions: path.map(p => p.position)
};
}
verifyInclusion(leafIndex, leafHash) {
const path = this.getMerklePath(leafIndex);
let computedHash = leafHash;
for (let i = 0; i < path.hashes.length; i++) {
computedHash = TaggedHash.createTapBranch(computedHash, path.hashes[i]);
}
return computedHash.equals(this.root);
}
getLeaf(index) {
if (index < 0 || index >= this.leaves.length) {
throw new MerkleTreeError('Invalid leaf index', 'INVALID_INDEX');
}
return { ...this.leaves[index] };
}
getLeafCount() {
return this.leaves.length;
}
getTreeDepth() {
return this.tree.length;
}
toJSON() {
return {
root: this.root.toString('hex'),
leafVersion: this.leafVersion,
leafCount: this.leaves.length,
depth: this.tree.length,
leaves: this.leaves.map(leaf => ({
hash: leaf.hash.toString('hex'),
index: leaf.index
}))
};
}
}
export {
TaprootMerkleTree,
TaggedHash,
MerkleTreeError,
MERKLE_CONSTANTS
};
</code></pre>
</article>
</section>
</div>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Wed Dec 31 2025 22:27:40 GMT-0500 (Eastern Standard Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
</footer>
<script>prettyPrint();</script>
<script src="scripts/polyfill.js"></script>
<script src="scripts/linenumber.js"></script>
<script src="scripts/search.js" defer></script>
<script src="scripts/collapse.js" defer></script>
</body>
</html>