@babylonlabs-io/ts-sdk 0.26.1 → 0.26.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +0,0 @@
1
- "use strict";var Vt=Object.defineProperty;var Ft=(e,t,n)=>t in e?Vt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var P=(e,t,n)=>Ft(e,typeof t!="symbol"?t+"":t,n);const M=require("bitcoinjs-lib"),ot=require("buffer"),B=require("viem"),Kt=require("./signing-DHSXjhLM.cjs"),ut=require("@babylonlabs-io/babylon-tbv-rust-wasm"),R=require("./challengeAssert-X7V3Ik_Q.cjs"),k=require("./bitcoin-CNnPFU6Y.cjs"),ht=require("./validation-u8W7Lp2x.cjs"),$=require("./psbtInputFields-tnAR8tG5.cjs"),ft=require("./fundPeginTransaction-DxNOeyNI.cjs"),wt=require("./index-CIuXb72l.cjs"),O=require("./types-xU3SBcpH.cjs"),u=require("./buildAndBroadcastRefund-Mr3ck5ek.cjs");function Dt(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const n in e)if(n!=="default"){const s=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,s.get?s:{enumerable:!0,get:()=>e[n]})}}return t.default=e,Object.freeze(t)}const Mt=Dt(M),C={"0x04aabf33":"Vault already exists: This Bitcoin transaction has already been registered. Please select different UTXOs or use a different amount to create a unique transaction.","0x4fec082d":"Script mismatch: The Bitcoin transaction's taproot output does not match the expected vault script. This may be caused by incorrect vault participants or key configuration.","0x6cc363a5":"Invalid BTC proof of possession: The signature could not be verified. Please ensure you're signing with the correct Bitcoin wallet.","0x6c3f2bf6":"Invalid BTC public key: The Bitcoin public key format is invalid.","0x2c5211c6":"Invalid amount: The deposit amount is invalid or below the minimum required.","0x0405f772":"Application not registered: The application controller is not registered in the system.","0x24e165cc":"Invalid provider status: The vault provider is not in a valid state to accept deposits.","0xd92e233d":"Zero address: One of the required addresses is the zero address.","0x65aa7007":"BTC key mismatch: The Bitcoin public key does not match the expected key.","0x82b42900":"Unauthorized: You must be the depositor or vault provider to submit this transaction.","0x8baa579f":"Invalid signature: The BTC proof of possession signature could not be verified.","0x2f9d01e9":"Invalid BTC transaction: The Bitcoin transaction format is invalid.","0x5a3c6b3e":"Vault provider not registered: The selected vault provider is not registered.","0x979f4518":"Invalid pegin fee: The ETH fee sent does not match the required amount. This may indicate a fee rate change during the transaction.","0x5fad9694":"This pre-pegin output has already been used to activate another vault.","0x7ed061c9":"This pegin transaction has already been used to activate another vault."};function N(e){if(!e||typeof e!="object")return;const t=e;if(typeof t.data=="string"&&t.data.startsWith("0x"))return t.data;if(typeof t.details=="string"&&t.details.startsWith("0x"))return t.details;let n=t.cause,s=0;const o=5;for(;n&&typeof n=="object"&&s<o;){const a=n;if(typeof a.data=="string"&&a.data.startsWith("0x"))return a.data;n=a.cause,s++}const i=(typeof t.message=="string"?t.message:"").match(/\b(0x[a-fA-F0-9]{8})\b/);if(i)return i[1]}function Nt(e){const t=N(e);if(t){const n=t.substring(0,10);return C[t]??C[n]}}function Xt(e){const t=N(e);if(t===void 0)return!1;const n=t.substring(0,10);return t in C||n in C}function S(e){console.error("[Contract Error] Raw error:",e);const t=N(e);if(console.error("[Contract Error] Extracted error data:",t),t){const s=t.substring(0,10),o=C[t]??C[s];if(o)throw console.error("[Contract Error] Known error:",o),new Error(o)}const n=(e==null?void 0:e.message)||"";if(n.includes("gas limit too high")||n.includes("21000000")||n.includes("Internal JSON-RPC error")){const s=t?` (error code: ${t})`:"";throw console.error("[Contract Error] Transaction rejected. Error code:",t,"Message:",n),new Error(`Transaction failed: The contract rejected this transaction${s}. Possible causes: (1) Vault already exists for this transaction, (2) Invalid signature, (3) Unauthorized caller. Please check your transaction parameters and try again.`)}throw e instanceof Error?(console.error("[Contract Error] Unhandled error:",e.message),e):new Error(`Contract call failed: ${String(e)}`)}const qt=0,jt=/^0x[0-9a-f]+$/i,Gt=/^[0-9a-f]+$/i,zt=/^[A-Za-z0-9+/]+={0,2}$/;function W(e){if(typeof e!="string"||e.length===0)throw new Error("BTC wallet returned empty public key");return k.processPublicKeyToXOnly(e).toLowerCase()}function Zt(e){if(typeof e!="string"||e.length===0)throw new Error("BTC wallet returned empty BIP-322 signature");if(e.startsWith("0x")||e.startsWith("0X")){if(!jt.test(e)||e.length<4||e.length%2!==0)throw new Error("BTC wallet returned malformed hex BIP-322 signature");return e.toLowerCase()}if(Gt.test(e)){if(e.length%2!==0)throw new Error("BTC wallet returned malformed hex BIP-322 signature");return`0x${e.toLowerCase()}`}if(!zt.test(e)||e.length%4!==0)throw new Error("BTC wallet returned malformed base64 BIP-322 signature");const t=ot.Buffer.from(e,"base64");if(t.length===0||t.toString("base64")!==e)throw new Error("BTC wallet returned malformed base64 BIP-322 signature");return`0x${t.toString("hex")}`}function Yt(e,t,n,s){const o=n==null?void 0:n[`${e}:${t}`];return o?Promise.resolve({txid:e,vout:t,value:o.value,scriptPubKey:o.scriptPubKey}):wt.getUtxoInfo(e,t,s)}const dt=12e4;class Jt{constructor(t){P(this,"config");this.config=t}async preparePegin(t){const n=await this.config.btcWallet.getPublicKeyHex(),s=W(n),o=k.stripHexPrefix(t.vaultProviderBtcPubkey),r=t.vaultKeeperBtcPubkeys.map(k.stripHexPrefix),i=t.universalChallengerBtcPubkeys.map(k.stripHexPrefix);if(t.hashlocks.length!==t.amounts.length)throw new Error(`hashlocks.length (${t.hashlocks.length}) must equal amounts.length (${t.amounts.length})`);if(t.hashlocks.length===0)throw new Error("hashlocks must contain at least one entry");const a=r.length,p={depositorPubkey:s,vaultProviderPubkey:o,vaultKeeperPubkeys:r,universalChallengerPubkeys:i,hashlocks:t.hashlocks,timelockRefund:t.timelockRefund,pegInAmounts:t.amounts,feeRate:t.protocolFeeRate,numLocalChallengers:a,councilQuorum:t.councilQuorum,councilSize:t.councilSize,network:this.config.btcNetwork},h=await R.buildPrePeginPsbt(p),c=$.selectUtxosForPegin([...t.availableUTXOs],h.totalOutputValue,t.mempoolFeeRate,ft.peginOutputCount(h.htlcValues.length)),y=k.getNetwork(this.config.btcNetwork),l=ft.fundPeginTransaction({unfundedTxHex:h.psbtHex,selectedUTXOs:c.selectedUTXOs,changeAddress:t.changeAddress,changeAmount:c.changeAmount,network:y}),x=k.stripHexPrefix($.calculateBtcTxHash(l)),g=[],w=[],T=[];for(let m=0;m<t.hashlocks.length;m++){const b=await R.buildPeginTxFromFundedPrePegin({prePeginParams:p,timelockPegin:t.timelockPegin,fundedPrePeginTxHex:l,htlcVout:m}),I=await R.buildPeginInputPsbt({peginTxHex:b.txHex,fundedPrePeginTxHex:l,depositorPubkey:s,vaultProviderPubkey:o,vaultKeeperPubkeys:r,universalChallengerPubkeys:i,hashlock:t.hashlocks[m],timelockRefund:t.timelockRefund,network:this.config.btcNetwork});g.push(b),w.push(I.psbtHex),T.push(Kt.createTaprootScriptPathSignOptions(n,1))}const d=await this.signPsbtsWithFallback(w,T),f=[];for(let m=0;m<d.length;m++){const b=R.extractPeginInputSignature(d[m],s),I=R.finalizePeginInputPsbt(d[m]);f.push({htlcVout:m,htlcValue:h.htlcValues[m],peginTxHex:I,peginTxid:g[m].txid,peginInputSignature:b,vaultScriptPubKey:g[m].vaultScriptPubKey})}return{fundedPrePeginTxHex:l,prePeginTxid:x,perVault:f,selectedUTXOs:c.selectedUTXOs,fee:c.fee,changeAmount:c.changeAmount}}async signPsbtsWithFallback(t,n){if(typeof this.config.btcWallet.signPsbts=="function"){const o=await this.config.btcWallet.signPsbts(t,n);if(o.length!==t.length)throw new Error(`Expected ${t.length} signed PSBTs but received ${o.length}`);return o}const s=[];for(let o=0;o<t.length;o++){const r=await this.config.btcWallet.signPsbt(t[o],n[o]);s.push(r)}return s}async signAndBroadcast(t){const{fundedPrePeginTxHex:n,depositorBtcPubkey:s}=t,o=n.startsWith("0x")?n.slice(2):n,r=M.Transaction.fromHex(o);if(r.ins.length===0)throw new Error("Transaction has no inputs");const i=new M.Psbt;i.setVersion(r.version),i.setLocktime(r.locktime);const a=ot.Buffer.from(W(s),"hex"),p=this.config.mempoolApiUrl,h=r.ins.map(f=>{const m=ot.Buffer.from(f.hash).reverse().toString("hex"),b=f.index;return Yt(m,b,t.localPrevouts,p).then(I=>({input:f,utxoData:I,txid:m,vout:b}))}),c=await Promise.all(h),y=c.reduce((f,m)=>f+BigInt(m.utxoData.value),0n),l=r.outs.reduce((f,m)=>f+BigInt(m.value),0n);if(y<l)throw new Error(`UTXO value mismatch: total input value (${y} sat) is less than total output value (${l} sat). This may indicate the mempool API returned manipulated UTXO data.`);const x=y-l;if(x>ht.MAX_REASONABLE_FEE_SATS)throw new Error(`Implied transaction fee (${x} sat) exceeds maximum reasonable fee (${ht.MAX_REASONABLE_FEE_SATS} sat). This may indicate manipulated UTXO data.`);for(const{input:f,utxoData:m,txid:b,vout:I}of c){const E=$.getPsbtInputFields({value:m.value,scriptPubKey:m.scriptPubKey},a);i.addInput({hash:f.hash,index:f.index,sequence:f.sequence,...E})}for(const f of r.outs)i.addOutput({script:f.script,value:f.value});const g=await this.config.btcWallet.signPsbt(i.toHex()),w=M.Psbt.fromHex(g);try{w.finalizeAllInputs()}catch(f){if(!w.data.inputs.every(b=>b.finalScriptWitness||b.finalScriptSig))throw new Error(`PSBT finalization failed and wallet did not auto-finalize: ${f}`)}const T=w.extractTransaction().toHex();return await wt.pushTx(T,p)}async registerPeginOnChain(t){const{unsignedPrePeginTx:n,depositorSignedPeginTx:s,vaultProvider:o,hashlock:r,htlcVout:i,depositorPayoutBtcAddress:a,depositorWotsPkHash:p,popSignature:h}=t;if(!this.config.ethWallet.account)throw new Error("Ethereum wallet account not found");const c=this.config.ethWallet.account.address;if(!B.isAddressEqual(h.depositorEthAddress,c))throw new Error(`Proof of possession was signed for ${h.depositorEthAddress} but the Ethereum wallet is currently connected to ${c}. Reconnect the original account or call signProofOfPossession() again.`);await this.assertPopMatchesBtcWallet(h);const y=h.btcPopSignature,l=k.ensureHexPrefix(h.depositorBtcPubkey),x=k.ensureHexPrefix(n),g=k.ensureHexPrefix(s),w=await this.resolvePayoutScriptPubKey(a),T=$.calculateBtcTxHash(g),d=await ut.deriveVaultId(k.stripHexPrefix(T),k.stripHexPrefix(c)),f=k.ensureHexPrefix(d);if(await this.checkVaultExists(f))throw new Error(`Vault already exists (ID: ${f}, peginTxHash: ${T}). Vault IDs are derived from the pegin transaction hash and depositor address. To create a new vault, use different UTXOs or a different amount to generate a unique transaction.`);const b=B.createPublicClient({chain:this.config.ethChain,transport:B.http()});let I;try{I=await b.readContract({address:this.config.vaultContracts.btcVaultRegistry,abi:O.BTCVaultRegistryABI,functionName:"getPegInFee",args:[o]})}catch{throw new Error("Failed to query pegin fee from the contract. Please check your network connection and that the contract address is correct.")}const E=B.encodeFunctionData({abi:O.BTCVaultRegistryABI,functionName:"submitPeginRequest",args:[c,l,y,x,g,o,r,i,w,p]});let v;try{v=await b.estimateGas({to:this.config.vaultContracts.btcVaultRegistry,data:E,value:I,account:this.config.ethWallet.account.address})}catch(q){S(q)}let _;try{_=await this.config.ethWallet.sendTransaction({to:this.config.vaultContracts.btcVaultRegistry,data:E,value:I,account:this.config.ethWallet.account,chain:this.config.ethChain,gas:v})}catch(q){S(q)}const A=await b.waitForTransactionReceipt({hash:_,timeout:dt});return A.status==="reverted"&&S(new Error(`Transaction reverted. Hash: ${_}. Check the transaction on block explorer for details.`)),{ethTxHash:A.transactionHash,vaultId:f,peginTxHash:T}}async registerPeginBatchOnChain(t){const{vaultProvider:n,unsignedPrePeginTx:s,requests:o,popSignature:r}=t;if(o.length===0)throw new Error("Batch pegin requires at least one request");if(!this.config.ethWallet.account)throw new Error("Ethereum wallet account not found");const i=this.config.ethWallet.account.address;if(!B.isAddressEqual(r.depositorEthAddress,i))throw new Error(`Proof of possession was signed for ${r.depositorEthAddress} but the Ethereum wallet is currently connected to ${i}. Reconnect the original account or call signProofOfPossession() again.`);await this.assertPopMatchesBtcWallet(r);const a=r.btcPopSignature,p=[];for(const b of o)p.push(await this.resolvePayoutScriptPubKey(b.depositorPayoutBtcAddress));const h=[];for(const b of o){const I=k.ensureHexPrefix(b.depositorSignedPeginTx),E=$.calculateBtcTxHash(I),v=await ut.deriveVaultId(k.stripHexPrefix(E),k.stripHexPrefix(i)),_=k.ensureHexPrefix(v);if(await this.checkVaultExists(_))throw new Error(`Vault already exists (ID: ${_}, peginTxHash: ${E}). To create a new vault, use different UTXOs or a different amount.`);h.push({vaultId:_,peginTxHash:E})}const c=B.createPublicClient({chain:this.config.ethChain,transport:B.http()});let y;try{y=await c.readContract({address:this.config.vaultContracts.btcVaultRegistry,abi:O.BTCVaultRegistryABI,functionName:"getPegInFee",args:[n]})}catch{throw new Error("Failed to query pegin fee from the contract. Please check your network connection and that the contract address is correct.")}const l=y*BigInt(o.length),x=k.ensureHexPrefix(r.depositorBtcPubkey),g=k.ensureHexPrefix(s),w=o.map((b,I)=>({depositorBtcPubKey:x,btcPopSignature:a,unsignedPrePeginTx:g,depositorSignedPeginTx:k.ensureHexPrefix(b.depositorSignedPeginTx),hashlock:b.hashlock,htlcVout:b.htlcVout,referralCode:qt,depositorPayoutBtcAddress:p[I],depositorWotsPkHash:b.depositorWotsPkHash})),T=B.encodeFunctionData({abi:O.BTCVaultRegistryABI,functionName:"submitPeginRequestBatch",args:[i,n,w]});let d;try{d=await c.estimateGas({to:this.config.vaultContracts.btcVaultRegistry,data:T,value:l,account:this.config.ethWallet.account.address})}catch(b){S(b)}let f;try{f=await this.config.ethWallet.sendTransaction({to:this.config.vaultContracts.btcVaultRegistry,data:T,value:l,account:this.config.ethWallet.account,chain:this.config.ethChain,gas:d})}catch(b){S(b)}const m=await c.waitForTransactionReceipt({hash:f,timeout:dt});return m.status==="reverted"&&S(new Error(`Batch transaction reverted. Hash: ${f}. Check the transaction on block explorer for details.`)),{ethTxHash:m.transactionHash,vaults:h}}async checkVaultExists(t){try{return(await B.createPublicClient({chain:this.config.ethChain,transport:B.http()}).readContract({address:this.config.vaultContracts.btcVaultRegistry,abi:O.BTCVaultRegistryABI,functionName:"getBtcVaultBasicInfo",args:[t]}))[0]!==B.zeroAddress}catch{return!1}}async resolvePayoutScriptPubKey(t){let n;if(t)n=t;else{n=await this.config.btcWallet.getAddress();const o=await this.config.btcWallet.getPublicKeyHex();if(!k.isAddressFromPublicKey(n,o,this.config.btcNetwork))throw new Error("The BTC address from your wallet does not match the wallet's public key. Please ensure your wallet is using a supported address type (Taproot or Native SegWit).")}const s=k.getNetwork(this.config.btcNetwork);try{return`0x${Mt.address.toOutputScript(n,s).toString("hex")}`}catch{throw new Error(`Invalid BTC payout address: "${n}". Please provide a valid Bitcoin address for the ${this.config.btcNetwork} network.`)}}async signProofOfPossession(){if(!this.config.ethWallet.account)throw new Error("Ethereum wallet account not found");const t=this.config.ethWallet.account.address,n=W(await this.config.btcWallet.getPublicKeyHex()),s=this.config.vaultContracts.btcVaultRegistry,o=`${t.toLowerCase()}:${this.config.ethChain.id}:pegin:${s.toLowerCase()}`,r=await this.config.btcWallet.signMessage(o,"bip322-simple");return{btcPopSignature:Zt(r),depositorEthAddress:t,depositorBtcPubkey:n}}async assertPopMatchesBtcWallet(t){const n=W(await this.config.btcWallet.getPublicKeyHex()),s=W(t.depositorBtcPubkey);if(n!==s)throw new Error(`Proof of possession was signed with BTC pubkey ${s} but the BTC wallet is currently connected to ${n}. Reconnect the original wallet or call signProofOfPossession() again.`)}getNetwork(){return this.config.btcNetwork}getVaultContractAddress(){return this.config.vaultContracts.btcVaultRegistry}}class Pt{constructor(t,n){P(this,"oHash");P(this,"iHash");P(this,"blockLen");P(this,"outputLen");P(this,"finished",!1);P(this,"destroyed",!1);if(u.ahash(t),u.abytes(n,void 0,"key"),this.iHash=t.create(),typeof this.iHash.update!="function")throw new Error("Expected instance of class which extends utils.Hash");this.blockLen=this.iHash.blockLen,this.outputLen=this.iHash.outputLen;const s=this.blockLen,o=new Uint8Array(s);o.set(n.length>s?t.create().update(n).digest():n);for(let r=0;r<o.length;r++)o[r]^=54;this.iHash.update(o),this.oHash=t.create();for(let r=0;r<o.length;r++)o[r]^=106;this.oHash.update(o),u.clean(o)}update(t){return u.aexists(this),this.iHash.update(t),this}digestInto(t){u.aexists(this),u.abytes(t,this.outputLen,"output"),this.finished=!0,this.iHash.digestInto(t),this.oHash.update(t),this.oHash.digestInto(t),this.destroy()}digest(){const t=new Uint8Array(this.oHash.outputLen);return this.digestInto(t),t}_cloneInto(t){t||(t=Object.create(Object.getPrototypeOf(this),{}));const{oHash:n,iHash:s,finished:o,destroyed:r,blockLen:i,outputLen:a}=this;return t=t,t.finished=o,t.destroyed=r,t.blockLen=i,t.outputLen=a,t.oHash=n._cloneInto(t.oHash),t.iHash=s._cloneInto(t.iHash),t}clone(){return this._cloneInto()}destroy(){this.destroyed=!0,this.oHash.destroy(),this.iHash.destroy()}}const X=(e,t,n)=>new Pt(e,t).update(n).digest();X.create=(e,t)=>new Pt(e,t);const Qt=Uint8Array.from([7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8]),kt=Uint8Array.from(new Array(16).fill(0).map((e,t)=>t)),te=kt.map(e=>(9*e+5)%16),Tt=(()=>{const n=[[kt],[te]];for(let s=0;s<4;s++)for(let o of n)o.push(o[s].map(r=>Qt[r]));return n})(),Et=Tt[0],It=Tt[1],Ht=[[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8],[12,13,11,15,6,9,9,7,12,15,11,13,7,8,7,7],[13,15,14,11,7,7,6,8,13,14,13,12,5,5,6,9],[14,11,12,14,8,6,5,5,15,12,15,14,9,9,8,6],[15,12,13,13,9,5,8,6,14,11,12,11,8,6,5,5]].map(e=>Uint8Array.from(e)),ee=Et.map((e,t)=>e.map(n=>Ht[t][n])),ne=It.map((e,t)=>e.map(n=>Ht[t][n])),se=Uint32Array.from([0,1518500249,1859775393,2400959708,2840853838]),oe=Uint32Array.from([1352829926,1548603684,1836072691,2053994217,0]);function gt(e,t,n,s){return e===0?t^n^s:e===1?t&n|~t&s:e===2?(t|~n)^s:e===3?t&s|n&~s:t^(n|~s)}const V=new Uint32Array(16);class re extends u.HashMD{constructor(){super(64,20,8,!0);P(this,"h0",1732584193);P(this,"h1",-271733879);P(this,"h2",-1732584194);P(this,"h3",271733878);P(this,"h4",-1009589776)}get(){const{h0:n,h1:s,h2:o,h3:r,h4:i}=this;return[n,s,o,r,i]}set(n,s,o,r,i){this.h0=n|0,this.h1=s|0,this.h2=o|0,this.h3=r|0,this.h4=i|0}process(n,s){for(let g=0;g<16;g++,s+=4)V[g]=n.getUint32(s,!0);let o=this.h0|0,r=o,i=this.h1|0,a=i,p=this.h2|0,h=p,c=this.h3|0,y=c,l=this.h4|0,x=l;for(let g=0;g<5;g++){const w=4-g,T=se[g],d=oe[g],f=Et[g],m=It[g],b=ee[g],I=ne[g];for(let E=0;E<16;E++){const v=u.rotl(o+gt(g,i,p,c)+V[f[E]]+T,b[E])+l|0;o=l,l=c,c=u.rotl(p,10)|0,p=i,i=v}for(let E=0;E<16;E++){const v=u.rotl(r+gt(w,a,h,y)+V[m[E]]+d,I[E])+x|0;r=x,x=y,y=u.rotl(h,10)|0,h=a,a=v}}this.set(this.h1+p+y|0,this.h2+c+x|0,this.h3+l+r|0,this.h4+o+a|0,this.h0+i+h|0)}roundClean(){u.clean(V)}destroy(){this.destroyed=!0,u.clean(this.buffer),this.set(0,0,0,0,0)}}const vt=u.createHasher(()=>new re),ie=BigInt(0),U=BigInt(1),ae=BigInt(2),ce=BigInt(7),le=BigInt(256),ue=BigInt(113),Bt=[],_t=[],St=[];for(let e=0,t=U,n=1,s=0;e<24;e++){[n,s]=[s,(2*n+3*s)%5],Bt.push(2*(5*s+n)),_t.push((e+1)*(e+2)/2%64);let o=ie;for(let r=0;r<7;r++)t=(t<<U^(t>>ce)*ue)%le,t&ae&&(o^=U<<(U<<BigInt(r))-U);St.push(o)}const Ct=u.split(St,!0),he=Ct[0],fe=Ct[1],pt=(e,t,n)=>n>32?u.rotlBH(e,t,n):u.rotlSH(e,t,n),mt=(e,t,n)=>n>32?u.rotlBL(e,t,n):u.rotlSL(e,t,n);function de(e,t=24){const n=new Uint32Array(10);for(let s=24-t;s<24;s++){for(let i=0;i<10;i++)n[i]=e[i]^e[i+10]^e[i+20]^e[i+30]^e[i+40];for(let i=0;i<10;i+=2){const a=(i+8)%10,p=(i+2)%10,h=n[p],c=n[p+1],y=pt(h,c,1)^n[a],l=mt(h,c,1)^n[a+1];for(let x=0;x<50;x+=10)e[i+x]^=y,e[i+x+1]^=l}let o=e[2],r=e[3];for(let i=0;i<24;i++){const a=_t[i],p=pt(o,r,a),h=mt(o,r,a),c=Bt[i];o=e[c],r=e[c+1],e[c]=p,e[c+1]=h}for(let i=0;i<50;i+=10){for(let a=0;a<10;a++)n[a]=e[i+a];for(let a=0;a<10;a++)e[i+a]^=~n[(a+2)%10]&n[(a+4)%10]}e[0]^=he[s],e[1]^=fe[s]}u.clean(n)}class ct{constructor(t,n,s,o=!1,r=24){P(this,"state");P(this,"pos",0);P(this,"posOut",0);P(this,"finished",!1);P(this,"state32");P(this,"destroyed",!1);P(this,"blockLen");P(this,"suffix");P(this,"outputLen");P(this,"enableXOF",!1);P(this,"rounds");if(this.blockLen=t,this.suffix=n,this.outputLen=s,this.enableXOF=o,this.rounds=r,u.anumber(s,"outputLen"),!(0<t&&t<200))throw new Error("only keccak-f1600 function is supported");this.state=new Uint8Array(200),this.state32=u.u32(this.state)}clone(){return this._cloneInto()}keccak(){u.swap32IfBE(this.state32),de(this.state32,this.rounds),u.swap32IfBE(this.state32),this.posOut=0,this.pos=0}update(t){u.aexists(this),u.abytes(t);const{blockLen:n,state:s}=this,o=t.length;for(let r=0;r<o;){const i=Math.min(n-this.pos,o-r);for(let a=0;a<i;a++)s[this.pos++]^=t[r++];this.pos===n&&this.keccak()}return this}finish(){if(this.finished)return;this.finished=!0;const{state:t,suffix:n,pos:s,blockLen:o}=this;t[s]^=n,(n&128)!==0&&s===o-1&&this.keccak(),t[o-1]^=128,this.keccak()}writeInto(t){u.aexists(this,!1),u.abytes(t),this.finish();const n=this.state,{blockLen:s}=this;for(let o=0,r=t.length;o<r;){this.posOut>=s&&this.keccak();const i=Math.min(s-this.posOut,r-o);t.set(n.subarray(this.posOut,this.posOut+i),o),this.posOut+=i,o+=i}return t}xofInto(t){if(!this.enableXOF)throw new Error("XOF is not possible for this instance");return this.writeInto(t)}xof(t){return u.anumber(t),this.xofInto(new Uint8Array(t))}digestInto(t){if(u.aoutput(t,this),this.finished)throw new Error("digest() was already called");return this.writeInto(t),this.destroy(),t}digest(){return this.digestInto(new Uint8Array(this.outputLen))}destroy(){this.destroyed=!0,u.clean(this.state)}_cloneInto(t){const{blockLen:n,suffix:s,outputLen:o,rounds:r,enableXOF:i}=this;return t||(t=new ct(n,s,o,i,r)),t.state32.set(this.state32),t.pos=this.pos,t.posOut=this.posOut,t.finished=this.finished,t.rounds=r,t.suffix=s,t.outputLen=o,t.enableXOF=i,t.destroyed=this.destroyed,t}}const ge=(e,t,n,s={})=>u.createHasher(()=>new ct(t,e,n),s),At=ge(1,136,32);function pe(e,t,n,s){u.ahash(e);const o=u.checkOpts({dkLen:32,asyncTick:10},s),{c:r,dkLen:i,asyncTick:a}=o;if(u.anumber(r,"c"),u.anumber(i,"dkLen"),u.anumber(a,"asyncTick"),r<1)throw new Error("iterations (c) must be >= 1");const p=u.kdfInputToBytes(t,"password"),h=u.kdfInputToBytes(n,"salt"),c=new Uint8Array(i),y=X.create(e,p),l=y._cloneInto().update(h);return{c:r,dkLen:i,asyncTick:a,DK:c,PRF:y,PRFSalt:l}}function me(e,t,n,s,o){return e.destroy(),t.destroy(),s&&s.destroy(),u.clean(o),n}function ye(e,t,n,s){const{c:o,dkLen:r,DK:i,PRF:a,PRFSalt:p}=pe(e,t,n,s);let h;const c=new Uint8Array(4),y=u.createView(c),l=new Uint8Array(a.outputLen);for(let x=1,g=0;g<r;x++,g+=a.outputLen){const w=i.subarray(g,g+a.outputLen);y.setInt32(0,x,!1),(h=p._cloneInto(h)).update(c).digestInto(l),w.set(l.subarray(0,w.length));for(let T=1;T<o;T++){a._cloneInto(h).update(l).digestInto(l);for(let d=0;d<w.length;d++)w[d]^=l[d]}}return me(a,p,i,h,l)}function Rt(e){if(typeof e!="string")throw new TypeError("invalid mnemonic type: "+typeof e);return e.normalize("NFKD")}function be(e){const t=Rt(e),n=t.split(" ");if(![12,15,18,21,24].includes(n.length))throw new Error("Invalid mnemonic");return{nfkd:t,words:n}}const xe=e=>Rt("mnemonic"+e);function we(e,t=""){return ye(u.sha512,be(e).nfkd,xe(t),{c:2048,dkLen:64})}const Pe=508,yt=16,F=32,K=64,bt=5,ke=4;function L(...e){const t=e.reduce((o,r)=>o+r.length,0),n=new Uint8Array(t);let s=0;for(const o of e)n.set(o,s),s+=o.length;return n}function j(e){return new TextEncoder().encode(e)}function G(e){const t=new Uint8Array(ke);return new DataView(t.buffer).setUint32(0,e.length,!1),L(t,e)}function z(e,t){return X(u.sha512,e,t)}function xt(e){return vt(u.sha256(e))}const rt=e=>Array.from(e).map(t=>t.toString(16).padStart(2,"0")).join("");function $t(e){const t=we(e),n=new Uint8Array(t);return t.fill(0),n}async function Ot(e,t,n,s){if(e.length!==K)throw new Error(`WOTS seed must be ${K} bytes, got ${e.length}`);t=k.stripHexPrefix(t),n=k.stripHexPrefix(n);const o=e.slice(F,K),r=e.slice(0,F),i=[o,r];try{const a=L(G(j(t)),G(j(n)),G(j(s))),p=L(r,a);i.push(p);const h=z(o,p);i.push(h);const c=h.slice(0,F),y=h.slice(F,K);i.push(c,y);const l=[],x=[],g=[],w=[];let T=!1;try{for(let d=0;d<Pe;d++){const f=new Uint8Array(bt);f[0]=0,new DataView(f.buffer).setUint32(1,d,!1);const m=new Uint8Array(bt);m[0]=1,new DataView(m.buffer).setUint32(1,d,!1);const b=L(c,f),I=L(c,m),E=z(y,b),v=z(y,I);try{const _=E.slice(0,yt),A=v.slice(0,yt);l.push(_),x.push(A),g.push(xt(_)),w.push(xt(A))}finally{b.fill(0),I.fill(0),E.fill(0),v.fill(0)}}return T=!0,{falsePreimages:l,truePreimages:x,falseHashes:g,trueHashes:w}}finally{if(!T){for(const d of l)d.fill(0);for(const d of x)d.fill(0)}}}finally{for(const a of i)a.fill(0)}}function Te(e){return{false_list:e.falseHashes.map(rt),true_list:e.trueHashes.map(rt)}}function Wt(e){if(e.falseHashes.length===0||e.trueHashes.length===0)throw new Error("computeWotsPkHash: keypair hash arrays must not be empty");const t=e.falseHashes[0].length,n=(e.falseHashes.length+e.trueHashes.length)*t,s=new Uint8Array(n);let o=0;for(const i of e.falseHashes)s.set(i,o),o+=t;for(const i of e.trueHashes)s.set(i,o),o+=t;const r=At(s);return`0x${rt(r)}`}const Z=32,Y=64,Ee=4,H=20,it=4,Ut=2,Ie=0,He=1,D=[64,64];function at(...e){const t=e.reduce((o,r)=>o+r.length,0),n=new Uint8Array(t);let s=0;for(const o of e)n.set(o,s),s+=o.length;return n}function J(e){return new TextEncoder().encode(e)}function Q(e){const t=new Uint8Array(Ee);return new DataView(t.buffer).setUint32(0,e.length,!1),at(t,e)}function tt(e){return e.startsWith("0x")||e.startsWith("0X")?e.slice(2):e}const ve=e=>Array.from(e).map(t=>t.toString(16).padStart(2,"0")).join("");function Be(e,t){return X(u.sha512,e,t)}function lt(e){return vt(u.sha256(e))}function Lt(e){return(1<<e)-1}function _e(e){let t=1;for(;t*t<e+1;)t++;return Math.max(t,2)}function Se(e){const t=it,n=Lt(t),s=e*n;return{d:t,n:e,checksum_radix:_e(s)}}function et(e,t){const n=[];let s=t;for(;s>0;)n.push(s&255),s>>>=8;const o=new Uint8Array(e.length+n.length);o.set(e);for(let r=0;r<n.length;r++)o[e.length+r]=n[r];return lt(o)}function nt(e,t){let n=e;for(let s=0;s<t;s++)n=lt(n);return n}function Ce(e,t){const n=Lt(t.d),s=t.checksum_radix-1,o=Math.floor(t.n*n/t.checksum_radix),r=[];for(let c=0;c<t.n;c++){const y=et(e,c+Ut),l=nt(y,n);r.push(Array.from(l))}const i=et(e,Ie),a=nt(i,s),p=et(e,He),h=nt(p,o);return{config:t,message_terminals:r,checksum_major_terminal:Array.from(h),checksum_minor_terminal:Array.from(a)}}async function Ae(e,t,n,s){if(e.length!==Y)throw new Error(`WOTS seed must be exactly ${Y} bytes, got ${e.length}`);const o=tt(t),r=tt(n),i=e.slice(Z,Y),a=e.slice(0,Z),p=at(a,at(Q(J(o)),Q(J(r)),Q(J(tt(s))))),h=Be(i,p),c=h.slice(0,Z);try{const y=[];for(let l=0;l<D.length;l++){const x=D[l],g=Se(x),w=new Uint8Array(c.length+1);w.set(c),w[c.length]=l;const T=lt(w);try{const d=Ce(T,g);if(d.config.d!==it)throw new Error(`Block ${l}: expected d=${it}, got d=${d.config.d}`);if(d.config.n!==x)throw new Error(`Block ${l}: expected n=${x}, got n=${d.config.n}`);if(d.message_terminals.length!==x)throw new Error(`Block ${l}: expected ${x} message terminals, got ${d.message_terminals.length}`);for(let f=0;f<d.message_terminals.length;f++)if(d.message_terminals[f].length!==H)throw new Error(`Block ${l} terminal ${f}: expected ${H} bytes, got ${d.message_terminals[f].length}`);if(d.checksum_minor_terminal.length!==H)throw new Error(`Block ${l} checksum_minor: expected ${H} bytes`);if(d.checksum_major_terminal.length!==H)throw new Error(`Block ${l} checksum_major: expected ${H} bytes`);y.push(d)}finally{w.fill(0),T.fill(0)}}if(y.length!==D.length)throw new Error(`Expected ${D.length} blocks, got ${y.length}`);return y}finally{p.fill(0),i.fill(0),a.fill(0),h.fill(0),c.fill(0),e.fill(0)}}function st(e,t,n){if(e.length!==H)throw new Error(`Block ${t} ${n}: expected ${H} bytes, got ${e.length}`);for(let s=0;s<e.length;s++){const o=e[s];if(!Number.isInteger(o)||o<0||o>255)throw new Error(`Block ${t} ${n}[${s}]: invalid byte value ${o}`)}}function Re(e){if(e.length===0)throw new Error("Public keys array must not be empty");for(let r=0;r<e.length;r++){const i=e[r];st(i.checksum_minor_terminal,r,"checksum_minor_terminal"),st(i.checksum_major_terminal,r,"checksum_major_terminal");for(let a=0;a<i.message_terminals.length;a++)st(i.message_terminals[a],r,`message_terminal[${a}]`)}let t=0;for(const r of e)t+=Ut+r.message_terminals.length;const n=new Uint8Array(t*H);let s=0;for(const r of e){n.set(r.checksum_minor_terminal,s),s+=H,n.set(r.checksum_major_terminal,s),s+=H;for(const i of r.message_terminals)n.set(i,s),s+=H}const o=At(n);return`0x${ve(o)}`}async function $e(e,t,n,s){const o=$t(e);try{const r=await Ot(o,t,n,s);try{return Wt(r)}finally{for(const i of r.falsePreimages)i.fill(0);for(const i of r.truePreimages)i.fill(0)}}finally{o.fill(0)}}function Oe(e){const t=(e instanceof Error?e.message:typeof e=="string"?e:"").toLowerCase();return t.includes("wots")&&t.includes("hash")&&t.includes("does not match")}exports.CONTRACT_ERRORS=C;exports.PeginManager=Jt;exports.computeWotsBlockPublicKeysHash=Re;exports.computeWotsPkHash=Wt;exports.deriveWotsBlockPublicKeys=Ae;exports.deriveWotsKeypair=Ot;exports.deriveWotsPkHash=$e;exports.extractErrorData=N;exports.getContractErrorMessage=Nt;exports.handleContractError=S;exports.isKnownContractError=Xt;exports.isWotsMismatchError=Oe;exports.keypairToPublicKey=Te;exports.mnemonicToWotsSeed=$t;
2
- //# sourceMappingURL=errors-BqKsTgDW.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors-BqKsTgDW.cjs","sources":["../src/tbv/core/contracts/errors.ts","../src/tbv/core/managers/PeginManager.ts","../../../node_modules/.pnpm/@noble+hashes@2.0.1/node_modules/@noble/hashes/hmac.js","../../../node_modules/.pnpm/@noble+hashes@2.0.1/node_modules/@noble/hashes/legacy.js","../../../node_modules/.pnpm/@noble+hashes@2.0.1/node_modules/@noble/hashes/sha3.js","../../../node_modules/.pnpm/@noble+hashes@2.0.1/node_modules/@noble/hashes/pbkdf2.js","../../../node_modules/.pnpm/@scure+bip39@2.0.1/node_modules/@scure/bip39/index.js","../src/tbv/core/wots/derivation.ts","../src/tbv/core/wots/blockDerivation.ts","../src/tbv/core/wots/deriveWotsPkHash.ts","../src/tbv/core/wots/errors.ts"],"sourcesContent":["/**\n * Contract Error Handling Utilities\n *\n * Provides utilities for extracting and handling contract revert errors.\n * Maps known error selectors to user-friendly messages.\n *\n * @module contracts/errors\n */\n\n/**\n * Known contract error signatures mapped to user-friendly messages.\n *\n * Error selectors are the first 4 bytes of keccak256(error signature).\n * Example: keccak256(\"VaultAlreadyExists()\") = 0x04aabf33...\n */\nexport const CONTRACT_ERRORS: Record<string, string> = {\n // VaultAlreadyExists()\n \"0x04aabf33\":\n \"Vault already exists: This Bitcoin transaction has already been registered. \" +\n \"Please select different UTXOs or use a different amount to create a unique transaction.\",\n // ScriptPubKeyMismatch() - taproot output doesn't match expected script\n \"0x4fec082d\":\n \"Script mismatch: The Bitcoin transaction's taproot output does not match the expected vault script. \" +\n \"This may be caused by incorrect vault participants or key configuration.\",\n // InvalidBTCProofOfPossession()\n \"0x6cc363a5\":\n \"Invalid BTC proof of possession: The signature could not be verified. \" +\n \"Please ensure you're signing with the correct Bitcoin wallet.\",\n // InvalidBTCPublicKey()\n \"0x6c3f2bf6\":\n \"Invalid BTC public key: The Bitcoin public key format is invalid.\",\n // InvalidAmount()\n \"0x2c5211c6\":\n \"Invalid amount: The deposit amount is invalid or below the minimum required.\",\n // ApplicationNotRegistered()\n \"0x0405f772\":\n \"Application not registered: The application controller is not registered in the system.\",\n // InvalidProviderStatus()\n \"0x24e165cc\":\n \"Invalid provider status: The vault provider is not in a valid state to accept deposits.\",\n // ZeroAddress()\n \"0xd92e233d\":\n \"Zero address: One of the required addresses is the zero address.\",\n // BtcKeyMismatch()\n \"0x65aa7007\":\n \"BTC key mismatch: The Bitcoin public key does not match the expected key.\",\n // Unauthorized()\n \"0x82b42900\":\n \"Unauthorized: You must be the depositor or vault provider to submit this transaction.\",\n // InvalidSignature() - common signature verification error\n \"0x8baa579f\":\n \"Invalid signature: The BTC proof of possession signature could not be verified.\",\n // InvalidBtcTransaction()\n \"0x2f9d01e9\":\n \"Invalid BTC transaction: The Bitcoin transaction format is invalid.\",\n // VaultProviderNotRegistered()\n \"0x5a3c6b3e\":\n \"Vault provider not registered: The selected vault provider is not registered.\",\n // InvalidPeginFee(uint256,uint256)\n \"0x979f4518\":\n \"Invalid pegin fee: The ETH fee sent does not match the required amount. \" +\n \"This may indicate a fee rate change during the transaction.\",\n // PrePeginOutputAlreadyUsed()\n \"0x5fad9694\":\n \"This pre-pegin output has already been used to activate another vault.\",\n // PeginTransactionAlreadyUsed()\n \"0x7ed061c9\":\n \"This pegin transaction has already been used to activate another vault.\",\n};\n\n/**\n * Extract error data from various error formats.\n *\n * Viem and wallet providers wrap errors in multiple levels. This function\n * searches through the error chain to find the revert data.\n *\n * @param error - The error object to extract data from\n * @returns The error data (e.g., \"0x04aabf33\") or undefined\n */\nexport function extractErrorData(error: unknown): string | undefined {\n if (!error || typeof error !== \"object\") return undefined;\n\n const err = error as Record<string, unknown>;\n\n // Check direct properties first\n if (typeof err.data === \"string\" && err.data.startsWith(\"0x\")) {\n return err.data;\n }\n if (typeof err.details === \"string\" && err.details.startsWith(\"0x\")) {\n return err.details;\n }\n\n // Walk the cause chain (viem wraps errors multiple levels deep)\n let current: unknown = err.cause;\n let depth = 0;\n const maxDepth = 5;\n\n while (current && typeof current === \"object\" && depth < maxDepth) {\n const cause = current as Record<string, unknown>;\n if (typeof cause.data === \"string\" && cause.data.startsWith(\"0x\")) {\n return cause.data;\n }\n current = cause.cause;\n depth++;\n }\n\n // Check error message for embedded hex error selector\n const message = typeof err.message === \"string\" ? err.message : \"\";\n const hexMatch = message.match(/\\b(0x[a-fA-F0-9]{8})\\b/);\n if (hexMatch) {\n return hexMatch[1];\n }\n\n return undefined;\n}\n\n/**\n * Get a user-friendly error message for a contract error.\n *\n * @param error - The error object from a contract call\n * @returns A user-friendly error message, or undefined if error is not recognized\n */\nexport function getContractErrorMessage(error: unknown): string | undefined {\n const errorData = extractErrorData(error);\n if (errorData) {\n // Check exact match first, then match by 4-byte selector prefix.\n // Parametric errors (e.g. InvalidPeginFee(uint256,uint256)) return\n // the selector + ABI-encoded args, so the full string won't match.\n const selector = errorData.substring(0, 10); // \"0x\" + 4 bytes\n return CONTRACT_ERRORS[errorData] ?? CONTRACT_ERRORS[selector];\n }\n return undefined;\n}\n\n/**\n * Check if an error is a known contract error.\n *\n * @param error - The error object to check\n * @returns True if the error is a known contract error\n */\nexport function isKnownContractError(error: unknown): boolean {\n const errorData = extractErrorData(error);\n if (errorData === undefined) return false;\n const selector = errorData.substring(0, 10);\n return errorData in CONTRACT_ERRORS || selector in CONTRACT_ERRORS;\n}\n\n/**\n * Handle a contract error by throwing a user-friendly error.\n *\n * This function extracts error data, maps it to a user-friendly message,\n * and throws an appropriate error. Use this in catch blocks after contract calls.\n *\n * @param error - The error from a contract call\n * @throws Always throws an error with a descriptive message\n */\nexport function handleContractError(error: unknown): never {\n // Log full error for debugging\n console.error(\"[Contract Error] Raw error:\", error);\n\n // Extract error data from the error chain\n const errorData = extractErrorData(error);\n console.error(\"[Contract Error] Extracted error data:\", errorData);\n\n // Check for known contract error signatures (exact match or 4-byte selector prefix)\n if (errorData) {\n const selector = errorData.substring(0, 10);\n const knownError = CONTRACT_ERRORS[errorData] ?? CONTRACT_ERRORS[selector];\n if (knownError) {\n console.error(\"[Contract Error] Known error:\", knownError);\n throw new Error(knownError);\n }\n }\n\n // Check for gas estimation errors or internal JSON-RPC errors\n const errorMsg = (error as Error)?.message || \"\";\n if (\n errorMsg.includes(\"gas limit too high\") ||\n errorMsg.includes(\"21000000\") ||\n errorMsg.includes(\"Internal JSON-RPC error\")\n ) {\n // If we found error data but it's not in our known list, include it\n const errorHint = errorData ? ` (error code: ${errorData})` : \"\";\n console.error(\n \"[Contract Error] Transaction rejected. Error code:\",\n errorData,\n \"Message:\",\n errorMsg,\n );\n throw new Error(\n `Transaction failed: The contract rejected this transaction${errorHint}. ` +\n \"Possible causes: (1) Vault already exists for this transaction, \" +\n \"(2) Invalid signature, (3) Unauthorized caller. \" +\n \"Please check your transaction parameters and try again.\",\n );\n }\n\n // Default: re-throw original error with better context\n if (error instanceof Error) {\n console.error(\"[Contract Error] Unhandled error:\", error.message);\n throw error;\n }\n throw new Error(`Contract call failed: ${String(error)}`);\n}\n","/**\n * Peg-in Manager - Wallet Orchestration for Peg-in Operations\n *\n * This module provides the PeginManager class that orchestrates the complete\n * peg-in flow using SDK primitives, utilities, and wallet interfaces.\n *\n * @remarks\n * PeginManager handles the peg-in flow:\n * 1. **preparePegin()** - Build Pre-PegIn HTLC, fund it, sign PegIn input\n * 2. **signProofOfPossession()** - Sign BIP-322 PoP (one per deposit session)\n * 3. **registerPeginOnChain()** - Submit to Ethereum contract with PoP\n * 4. **signAndBroadcast()** - Sign and broadcast Pre-PegIn tx to Bitcoin network\n * 5. *(Use {@link PayoutManager} for payout authorization signing)*\n *\n * @see {@link PayoutManager} - For Step 5: sign payout transactions\n * @see {@link buildPrePeginPsbt} - Lower-level primitive used internally\n *\n * @module managers/PeginManager\n */\n\nimport * as bitcoin from \"bitcoinjs-lib\";\nimport { Psbt, Transaction } from \"bitcoinjs-lib\";\nimport { Buffer } from \"buffer\";\nimport {\n createPublicClient,\n encodeFunctionData,\n http,\n isAddressEqual,\n zeroAddress,\n type Address,\n type Chain,\n type Hex,\n type WalletClient,\n} from \"viem\";\n\nimport type { BitcoinWallet, Hash, SignPsbtOptions } from \"../../../shared/wallets\";\nimport { createTaprootScriptPathSignOptions } from \"../utils/signing\";\nimport { type UtxoInfo, getUtxoInfo, pushTx } from \"../clients/mempool\";\nimport { BTCVaultRegistryABI, handleContractError } from \"../contracts\";\nimport {\n buildPrePeginPsbt,\n buildPeginTxFromFundedPrePegin,\n buildPeginInputPsbt,\n extractPeginInputSignature,\n finalizePeginInputPsbt,\n deriveVaultId,\n type PrePeginParams,\n type Network,\n} from \"../primitives\";\nimport {\n ensureHexPrefix,\n isAddressFromPublicKey,\n processPublicKeyToXOnly,\n stripHexPrefix,\n} from \"../primitives/utils/bitcoin\";\nimport {\n calculateBtcTxHash,\n fundPeginTransaction,\n getNetwork,\n getPsbtInputFields,\n peginOutputCount,\n selectUtxosForPegin,\n type UTXO,\n MAX_REASONABLE_FEE_SATS,\n} from \"../utils\";\n\n/** Referral code sent with pegin registration — 0 means no referral. */\nconst NO_REFERRAL_CODE = 0;\n\nconst HEX_SIGNATURE_REGEX = /^0x[0-9a-f]+$/i;\nconst UNPREFIXED_HEX_SIGNATURE_REGEX = /^[0-9a-f]+$/i;\nconst BASE64_SIGNATURE_REGEX = /^[A-Za-z0-9+/]+={0,2}$/;\n\nfunction normalizeXOnlyPubkey(raw: unknown): string {\n if (typeof raw !== \"string\" || raw.length === 0) {\n throw new Error(\"BTC wallet returned empty public key\");\n }\n // Lowercase so case-sensitive equality checks downstream don't fail\n // on uppercase wallet output (processPublicKeyToXOnly passes a 64-char\n // input through unchanged).\n return processPublicKeyToXOnly(raw).toLowerCase();\n}\n\n/**\n * Normalize a wallet-returned BIP-322 signature into 0x-prefixed hex.\n *\n * Accepts:\n * - 0x-prefixed lowercase/uppercase hex\n * - unprefixed hex (wins over base64 when input is pure `[0-9a-fA-F]+`)\n * - canonical standard base64 (`[A-Za-z0-9+/]` with `=` padding to a\n * multiple of 4 and no non-canonical encodings)\n *\n * Rejects URL-safe base64 (`-`/`_`) and base64 without padding. Wallets\n * known to return BIP-322 signatures (Keystone, UniSat, OKX, OneKey,\n * Unisat) all use standard base64; URL-safe is an explicit non-goal.\n */\nfunction normalizePopSignature(raw: unknown): Hex {\n if (typeof raw !== \"string\" || raw.length === 0) {\n throw new Error(\"BTC wallet returned empty BIP-322 signature\");\n }\n\n if (raw.startsWith(\"0x\") || raw.startsWith(\"0X\")) {\n if (!HEX_SIGNATURE_REGEX.test(raw) || raw.length < 4 || raw.length % 2 !== 0) {\n throw new Error(\"BTC wallet returned malformed hex BIP-322 signature\");\n }\n return raw.toLowerCase() as Hex;\n }\n\n // Prefer hex when the input could be either: every hex char is also a\n // valid base64 char, so the base64 branch alone would silently misdecode\n // a wallet returning \"deadbeef\" instead of \"0xdeadbeef\".\n if (UNPREFIXED_HEX_SIGNATURE_REGEX.test(raw)) {\n if (raw.length % 2 !== 0) {\n throw new Error(\"BTC wallet returned malformed hex BIP-322 signature\");\n }\n return `0x${raw.toLowerCase()}` as Hex;\n }\n\n if (!BASE64_SIGNATURE_REGEX.test(raw) || raw.length % 4 !== 0) {\n throw new Error(\"BTC wallet returned malformed base64 BIP-322 signature\");\n }\n const bytes = Buffer.from(raw, \"base64\");\n // Round-trip to reject non-canonical base64 (e.g. \"AB==\" decodes but\n // re-encodes to \"AA==\").\n if (bytes.length === 0 || bytes.toString(\"base64\") !== raw) {\n throw new Error(\"BTC wallet returned malformed base64 BIP-322 signature\");\n }\n return `0x${bytes.toString(\"hex\")}` as Hex;\n}\n\n/**\n * Configuration for the PeginManager.\n */\nexport interface PeginManagerConfig {\n /**\n * Bitcoin network to use for transactions.\n */\n btcNetwork: Network;\n\n /**\n * Bitcoin wallet for signing peg-in transactions.\n */\n btcWallet: BitcoinWallet;\n\n /**\n * Ethereum wallet for registering peg-in on-chain.\n * Uses viem's WalletClient directly for proper gas estimation.\n */\n ethWallet: WalletClient;\n\n /**\n * Ethereum chain configuration.\n * Required for proper gas estimation in contract calls.\n */\n ethChain: Chain;\n\n /**\n * Vault contract addresses.\n */\n vaultContracts: {\n /**\n * BTCVaultRegistry contract address on Ethereum.\n */\n btcVaultRegistry: Address;\n };\n\n /**\n * Mempool API URL for fetching UTXO data and broadcasting transactions.\n * Use MEMPOOL_API_URLS constant for standard mempool.space URLs, or provide\n * a custom URL if running your own mempool instance.\n */\n mempoolApiUrl: string;\n}\n\n/**\n * Parameters for the pegin flow (pre-pegin + pegin transactions).\n */\nexport interface PreparePeginParams {\n /**\n * Amounts to peg in per HTLC (in satoshis).\n * Must have the same length as `hashlocks`.\n * For single deposits, pass a single-element array.\n */\n amounts: readonly bigint[];\n\n /**\n * Vault provider's BTC public key (x-only, 64-char hex).\n * Can be provided with or without \"0x\" prefix (will be stripped automatically).\n */\n vaultProviderBtcPubkey: string;\n\n /**\n * Vault keeper BTC public keys (x-only, 64-char hex).\n * Can be provided with or without \"0x\" prefix (will be stripped automatically).\n */\n vaultKeeperBtcPubkeys: readonly string[];\n\n /**\n * Universal challenger BTC public keys (x-only, 64-char hex).\n * Can be provided with or without \"0x\" prefix (will be stripped automatically).\n */\n universalChallengerBtcPubkeys: readonly string[];\n\n /**\n * CSV timelock in blocks for the PegIn vault output.\n */\n timelockPegin: number;\n\n /**\n * CSV timelock in blocks for the Pre-PegIn HTLC refund path.\n */\n timelockRefund: number;\n\n /**\n * SHA256 hash commitment(s) for the HTLC (64 hex chars = 32 bytes each).\n * Generated by the depositor as H = SHA256(secret).\n * For single deposits, pass a single-element array.\n */\n hashlocks: readonly string[];\n\n /**\n * Protocol fee rate in sat/vB from the contract offchain params.\n * Used by WASM for computing depositorClaimValue and min pegin fee.\n */\n protocolFeeRate: bigint;\n\n /**\n * Mempool fee rate in sat/vB for funding the Pre-PegIn transaction.\n * Used for UTXO selection and change calculation.\n */\n mempoolFeeRate: number;\n\n /**\n * M in M-of-N council multisig (from contract params).\n */\n councilQuorum: number;\n\n /**\n * N in M-of-N council multisig (from contract params).\n */\n councilSize: number;\n\n /**\n * Available UTXOs from the depositor's wallet for funding the Pre-PegIn transaction.\n */\n availableUTXOs: readonly UTXO[];\n\n /**\n * Bitcoin address for receiving change from the Pre-PegIn transaction.\n */\n changeAddress: string;\n}\n\n/**\n * Result of preparing a pegin.\n */\n/** Per-vault PegIn data derived from a shared Pre-PegIn transaction */\nexport interface PerVaultPeginData {\n /** Index of the HTLC output in the Pre-PegIn transaction (0, 1, 2, ...) */\n htlcVout: number;\n /** HTLC output value in satoshis */\n htlcValue: bigint;\n /** Depositor-signed PegIn transaction hex (for contract registration) */\n peginTxHex: string;\n /** PegIn transaction ID */\n peginTxid: string;\n /** Depositor's Schnorr signature over PegIn input (HTLC leaf 0) */\n peginInputSignature: string;\n /** Vault output scriptPubKey hex */\n vaultScriptPubKey: string;\n}\n\nexport interface PreparePeginResult {\n /**\n * Funded, pre-witness Pre-PegIn tx hex. Pass this for register calls'\n * `unsignedPrePeginTx` — despite the contract-side name, the registry\n * stores the funded form so indexers can rebuild refund PSBTs.\n */\n fundedPrePeginTxHex: string;\n /** Funded Pre-PegIn transaction ID */\n prePeginTxid: string;\n /** Per-vault PegIn data — one entry per hashlock/amount */\n perVault: PerVaultPeginData[];\n /** UTXOs selected to fund the Pre-PegIn transaction */\n selectedUTXOs: UTXO[];\n /** Transaction fee in satoshis */\n fee: bigint;\n /** Change amount in satoshis (if any) */\n changeAmount: bigint;\n}\n\n\n/**\n * Parameters for signing and broadcasting a transaction.\n */\nexport interface SignAndBroadcastParams {\n /**\n * Funded Pre-PegIn transaction hex from preparePegin().\n */\n fundedPrePeginTxHex: string;\n\n /**\n * Depositor's BTC public key (x-only, 64-char hex).\n * Can be provided with or without \"0x\" prefix.\n * Required for Taproot signing.\n */\n depositorBtcPubkey: string;\n\n /**\n * Optional pre-fetched prevout data for inputs not yet in the mempool.\n * Key format: \"txid:vout\" (e.g. \"abc123...def:0\").\n * When provided, matching inputs skip the mempool API fetch.\n * Useful for split transactions where outputs are unconfirmed.\n */\n localPrevouts?: Record<string, { scriptPubKey: string; value: number }>;\n}\n\n/**\n * BIP-322 BTC Proof-of-Possession binding a depositor's BTC key to their\n * Ethereum account. Produced by {@link PeginManager.signProofOfPossession}\n * and reusable across every register call in the same session — the\n * embedded identities are re-checked at register time.\n */\nexport interface PopSignature {\n /** BIP-322 signature over the PoP message (0x-prefixed hex). */\n btcPopSignature: Hex;\n /** Ethereum address the PoP was signed for. */\n depositorEthAddress: Address;\n /** BTC x-only public key (64-char hex, no 0x prefix). */\n depositorBtcPubkey: string;\n}\n\n/**\n * Parameters for registering a peg-in on Ethereum.\n */\nexport interface RegisterPeginParams {\n /**\n * Funded, pre-witness Pre-PegIn tx hex — pass\n * {@link PreparePeginResult.fundedPrePeginTxHex}. The contract-side\n * parameter is named `unsignedPrePeginTx` but it stores the funded form.\n */\n unsignedPrePeginTx: string;\n\n /**\n * Depositor-signed PegIn transaction hex (submitted to contract; vault ID derived from this).\n */\n depositorSignedPeginTx: string;\n\n /**\n * Vault provider's Ethereum address.\n */\n vaultProvider: Address;\n\n /**\n * SHA256 hashlock for HTLC activation (bytes32 hex with 0x prefix).\n */\n hashlock: Hex;\n\n /**\n * Depositor's BTC payout address (e.g. bc1p..., bc1q...).\n * Converted to scriptPubKey internally via bitcoinjs-lib.\n *\n * If omitted, defaults to the connected BTC wallet's address\n * via `btcWallet.getAddress()`.\n */\n depositorPayoutBtcAddress?: string;\n\n /** Keccak256 hash of the depositor's WOTS public key (bytes32) */\n depositorWotsPkHash: Hex;\n\n /** Proof of possession from {@link PeginManager.signProofOfPossession}. */\n popSignature: PopSignature;\n\n /**\n * Zero-based index of the HTLC output in the Pre-PegIn transaction that\n * this PegIn spends. In a batch Pre-PegIn with N HTLC outputs, each vault\n * registration references a different htlcVout (0..N-1).\n */\n htlcVout: number;\n}\n\n/**\n * Result of registering a peg-in on Ethereum.\n */\nexport interface RegisterPeginResult {\n /**\n * Ethereum transaction hash for the peg-in registration.\n */\n ethTxHash: Hash;\n\n /**\n * Derived vault ID: keccak256(abi.encode(peginTxHash, depositor)).\n * Used for contract reads/writes and indexer queries.\n */\n vaultId: Hex;\n\n /**\n * Raw Bitcoin pegin transaction hash (double-SHA256 of the signed pegin tx).\n * Used for VP RPC operations which key on the BTC transaction ID.\n */\n peginTxHash: Hex;\n}\n\n/**\n * Single request in a batch pegin registration.\n * All requests in a batch share the same vault provider, depositor BTC\n * pubkey, and Pre-PegIn transaction.\n */\nexport interface BatchPeginRequestItem {\n /** Signed PegIn tx hex for this vault */\n depositorSignedPeginTx: string;\n /** SHA256 hashlock for HTLC activation (bytes32 hex) */\n hashlock: Hex;\n /** Zero-based HTLC output index in the Pre-PegIn tx (unique per request) */\n htlcVout: number;\n /** Depositor's BTC payout address (required — funds are sent here on payout) */\n depositorPayoutBtcAddress: string;\n /** Keccak256 hash of the depositor's WOTS public key (bytes32) */\n depositorWotsPkHash: Hex;\n}\n\n/**\n * Parameters for registerPeginBatchOnChain.\n */\nexport interface RegisterPeginBatchParams {\n /** Vault provider address (shared across all vaults in batch) */\n vaultProvider: Address;\n /**\n * Funded, pre-witness Pre-PegIn tx hex — shared across every request in\n * the batch. See {@link RegisterPeginParams.unsignedPrePeginTx}.\n */\n unsignedPrePeginTx: string;\n /** Individual pegin requests (one per vault) */\n requests: BatchPeginRequestItem[];\n /** Proof of possession from {@link PeginManager.signProofOfPossession}. */\n popSignature: PopSignature;\n}\n\n/**\n * Per-vault result from a batch pegin registration.\n */\nexport interface BatchPeginResultItem {\n /** Derived vault ID: keccak256(abi.encode(peginTxHash, depositor)) */\n vaultId: Hex;\n /** Raw BTC pegin transaction hash */\n peginTxHash: Hex;\n}\n\n/**\n * Result of registering a batch of pegins on Ethereum in a single transaction.\n */\nexport interface RegisterPeginBatchResult {\n /** Ethereum transaction hash */\n ethTxHash: Hex;\n /** Per-vault results (same order as input requests) */\n vaults: BatchPeginResultItem[];\n}\n\n\n/**\n * Resolve prevout data for a transaction input.\n * Checks localPrevouts first; falls back to mempool API.\n */\nfunction resolveUtxoInfo(\n txid: string,\n vout: number,\n localPrevouts: Record<string, { scriptPubKey: string; value: number }> | undefined,\n apiUrl: string,\n): Promise<UtxoInfo> {\n const local = localPrevouts?.[`${txid}:${vout}`];\n if (local) {\n return Promise.resolve({\n txid,\n vout,\n value: local.value,\n scriptPubKey: local.scriptPubKey,\n });\n }\n return getUtxoInfo(txid, vout, apiUrl);\n}\n\n/**\n * Manager for orchestrating peg-in operations.\n *\n * This manager provides a high-level API for creating peg-in transactions\n * by coordinating between SDK primitives, utilities, and wallet interfaces.\n *\n * @remarks\n * The complete peg-in flow consists of 5 steps:\n *\n * | Step | Method | Description |\n * |------|--------|-------------|\n * | 1 | {@link preparePegin} | Build Pre-PegIn HTLC, fund it, sign PegIn input |\n * | 2 | {@link signProofOfPossession} | Sign BIP-322 PoP (one per deposit session) |\n * | 3 | {@link registerPeginOnChain} | Submit to Ethereum contract |\n * | 4 | {@link signAndBroadcast} | Sign and broadcast Pre-PegIn tx to Bitcoin network |\n * | 5 | {@link PayoutManager} | Sign BOTH payout authorizations |\n *\n * **Important:** Step 5 uses {@link PayoutManager}, not this class. After\n * step 4, the vault provider observes the broadcast Pre-PegIn and prepares\n * 3 transactions per claimer:\n * - `claim_tx` - Claim transaction\n * - `assert_tx` - Assert transaction\n * - `payout_tx` - Payout transaction\n *\n * You must sign the Payout transaction for each claimer:\n * - {@link PayoutManager.signPayoutTransaction} - uses assert_tx as input reference\n *\n * Submit all signatures to the vault provider to drive the contract to\n * `VERIFIED` (and then activate by revealing the HTLC secret, which is a\n * services-layer step outside this manager).\n *\n * @see {@link PayoutManager} - Required for Step 5 (payout authorization)\n * @see {@link buildPrePeginPsbt} - Lower-level primitive for custom implementations\n * @see {@link https://github.com/babylonlabs-io/babylon-toolkit/blob/main/packages/babylon-ts-sdk/docs/quickstart/managers.md | Managers Quickstart}\n */\n/**\n * Maximum time (ms) to wait for a transaction receipt before timing out.\n * Matches the prior vault-service polling timeout so users see a clear error\n * instead of an indefinite hang when a transaction is dropped from the mempool.\n */\nconst RECEIPT_TIMEOUT_MS = 120_000;\n\nexport class PeginManager {\n private readonly config: PeginManagerConfig;\n\n /**\n * Creates a new PeginManager instance.\n *\n * @param config - Manager configuration including wallets and contract addresses\n */\n constructor(config: PeginManagerConfig) {\n this.config = config;\n }\n\n /**\n * Prepares a peg-in by building the Pre-PegIn HTLC transaction,\n * funding it, constructing the PegIn transaction, and signing the PegIn input.\n *\n * This method orchestrates the following steps:\n * 1. Get depositor BTC public key from wallet\n * 2. Build unfunded Pre-PegIn transaction (HTLC output) using primitives\n * 3. Select UTXOs to cover the HTLC value\n * 4. Fund the Pre-PegIn transaction\n * 5. Derive the PegIn transaction from the funded Pre-PegIn tx\n * 6. Build PSBT for signing the PegIn input (HTLC leaf 0)\n * 7. Sign via BTC wallet and extract depositor signature\n *\n * The returned `fundedPrePeginTxHex` is funded but unsigned (inputs unsigned).\n * Use `signAndBroadcast()` AFTER registering on Ethereum to broadcast it.\n *\n * @param params - Pegin parameters including amount, HTLC params, UTXOs\n * @returns Pegin result with funded Pre-PegIn tx, signed PegIn input, and signatures\n * @throws Error if wallet operations fail or insufficient funds\n */\n async preparePegin(\n params: PreparePeginParams,\n ): Promise<PreparePeginResult> {\n // Step 1: Get depositor BTC public key from wallet. Keep the raw\n // wallet output (typically compressed sec1 66-char) for wallet sign\n // calls — UniSat/OKX/OneKey expect their native format on\n // signInputs[].publicKey — and derive the canonical x-only form for\n // protocol/HTLC use.\n const depositorBtcPubkeyRaw = await this.config.btcWallet.getPublicKeyHex();\n const depositorBtcPubkey = normalizeXOnlyPubkey(depositorBtcPubkeyRaw);\n\n const vaultProviderBtcPubkey = stripHexPrefix(params.vaultProviderBtcPubkey);\n const vaultKeeperBtcPubkeys = params.vaultKeeperBtcPubkeys.map(stripHexPrefix);\n const universalChallengerBtcPubkeys =\n params.universalChallengerBtcPubkeys.map(stripHexPrefix);\n\n if (params.hashlocks.length !== params.amounts.length) {\n throw new Error(\n `hashlocks.length (${params.hashlocks.length}) must equal amounts.length (${params.amounts.length})`,\n );\n }\n if (params.hashlocks.length === 0) {\n throw new Error(\"hashlocks must contain at least one entry\");\n }\n\n const numLocalChallengers = vaultKeeperBtcPubkeys.length;\n\n const prePeginParams: PrePeginParams = {\n depositorPubkey: depositorBtcPubkey,\n vaultProviderPubkey: vaultProviderBtcPubkey,\n vaultKeeperPubkeys: vaultKeeperBtcPubkeys,\n universalChallengerPubkeys: universalChallengerBtcPubkeys,\n hashlocks: params.hashlocks,\n timelockRefund: params.timelockRefund,\n pegInAmounts: params.amounts,\n feeRate: params.protocolFeeRate,\n numLocalChallengers,\n councilQuorum: params.councilQuorum,\n councilSize: params.councilSize,\n network: this.config.btcNetwork,\n };\n\n // Step 2: Build unfunded Pre-PegIn transaction (N HTLC outputs, no inputs)\n const prePeginResult = await buildPrePeginPsbt(prePeginParams);\n\n // Step 3: Select UTXOs to cover ALL unfunded tx outputs (HTLCs + CPFP anchor)\n const utxoSelection = selectUtxosForPegin(\n [...params.availableUTXOs],\n prePeginResult.totalOutputValue,\n params.mempoolFeeRate,\n peginOutputCount(prePeginResult.htlcValues.length),\n );\n\n // Step 4: Fund the Pre-PegIn transaction with selected UTXOs\n const network = getNetwork(this.config.btcNetwork);\n const fundedPrePeginTxHex = fundPeginTransaction({\n unfundedTxHex: prePeginResult.psbtHex,\n selectedUTXOs: utxoSelection.selectedUTXOs,\n changeAddress: params.changeAddress,\n changeAmount: utxoSelection.changeAmount,\n network,\n });\n\n const prePeginTxid = stripHexPrefix(calculateBtcTxHash(fundedPrePeginTxHex));\n\n // Step 5: For each HTLC output, derive PegIn tx and build PSBT (no signing yet)\n const peginTxResults: Array<{\n txHex: string;\n txid: string;\n vaultScriptPubKey: string;\n }> = [];\n const psbtsToSign: string[] = [];\n const signOptions: SignPsbtOptions[] = [];\n\n for (let i = 0; i < params.hashlocks.length; i++) {\n const peginTxResult = await buildPeginTxFromFundedPrePegin({\n prePeginParams,\n timelockPegin: params.timelockPegin,\n fundedPrePeginTxHex,\n htlcVout: i,\n });\n\n const peginInputPsbtResult = await buildPeginInputPsbt({\n peginTxHex: peginTxResult.txHex,\n fundedPrePeginTxHex,\n depositorPubkey: depositorBtcPubkey,\n vaultProviderPubkey: vaultProviderBtcPubkey,\n vaultKeeperPubkeys: vaultKeeperBtcPubkeys,\n universalChallengerPubkeys: universalChallengerBtcPubkeys,\n hashlock: params.hashlocks[i],\n timelockRefund: params.timelockRefund,\n network: this.config.btcNetwork,\n });\n\n peginTxResults.push(peginTxResult);\n psbtsToSign.push(peginInputPsbtResult.psbtHex);\n signOptions.push(\n createTaprootScriptPathSignOptions(depositorBtcPubkeyRaw, 1),\n );\n }\n\n // Step 6: Batch sign all PegIn input PSBTs (single signPsbts call where supported)\n const signedPsbts = await this.signPsbtsWithFallback(\n psbtsToSign,\n signOptions,\n );\n\n // Step 7: Extract signatures and finalize\n const perVault: PerVaultPeginData[] = [];\n for (let i = 0; i < signedPsbts.length; i++) {\n const peginInputSignature = extractPeginInputSignature(\n signedPsbts[i],\n depositorBtcPubkey,\n );\n\n const depositorSignedPeginTxHex = finalizePeginInputPsbt(signedPsbts[i]);\n\n perVault.push({\n htlcVout: i,\n htlcValue: prePeginResult.htlcValues[i],\n peginTxHex: depositorSignedPeginTxHex,\n peginTxid: peginTxResults[i].txid,\n peginInputSignature,\n vaultScriptPubKey: peginTxResults[i].vaultScriptPubKey,\n });\n }\n\n return {\n fundedPrePeginTxHex,\n prePeginTxid,\n perVault,\n selectedUTXOs: utxoSelection.selectedUTXOs,\n fee: utxoSelection.fee,\n changeAmount: utxoSelection.changeAmount,\n };\n }\n\n /**\n * Signs multiple PSBTs using batch signing if available, falling back to sequential signing.\n *\n * Wallets that support native batch signing (e.g. UniSat) will sign all PSBTs\n * in a single interaction. Others (e.g. Ledger, AppKit) implement signPsbts\n * by looping signPsbt internally, so the UX depends on the wallet adapter.\n */\n private async signPsbtsWithFallback(\n psbtsHexes: string[],\n options: SignPsbtOptions[],\n ): Promise<string[]> {\n if (typeof this.config.btcWallet.signPsbts === \"function\") {\n const signedPsbts = await this.config.btcWallet.signPsbts(\n psbtsHexes,\n options,\n );\n if (signedPsbts.length !== psbtsHexes.length) {\n throw new Error(\n `Expected ${psbtsHexes.length} signed PSBTs but received ${signedPsbts.length}`,\n );\n }\n return signedPsbts;\n }\n\n // Fallback: sign sequentially\n const signedPsbts: string[] = [];\n for (let i = 0; i < psbtsHexes.length; i++) {\n const signed = await this.config.btcWallet.signPsbt(\n psbtsHexes[i],\n options[i],\n );\n signedPsbts.push(signed);\n }\n return signedPsbts;\n }\n\n /**\n * Signs and broadcasts a funded peg-in transaction to the Bitcoin network.\n *\n * This method:\n * 1. Parses the funded transaction hex\n * 2. Fetches UTXO data from mempool for each input\n * 3. Creates a PSBT with proper witnessUtxo/tapInternalKey\n * 4. Signs via btcWallet.signPsbt()\n * 5. Finalizes and extracts the transaction\n * 6. Broadcasts via mempool API\n *\n * @param params - Transaction hex and depositor public key\n * @returns The broadcasted Bitcoin transaction ID\n * @throws Error if signing or broadcasting fails\n */\n async signAndBroadcast(params: SignAndBroadcastParams): Promise<string> {\n const { fundedPrePeginTxHex, depositorBtcPubkey } = params;\n\n // Step 1: Parse the funded transaction\n const cleanHex = fundedPrePeginTxHex.startsWith(\"0x\")\n ? fundedPrePeginTxHex.slice(2)\n : fundedPrePeginTxHex;\n const tx = Transaction.fromHex(cleanHex);\n\n if (tx.ins.length === 0) {\n throw new Error(\"Transaction has no inputs\");\n }\n\n // Step 2: Create PSBT and add inputs with UTXO data from mempool\n const psbt = new Psbt();\n psbt.setVersion(tx.version);\n psbt.setLocktime(tx.locktime);\n\n const publicKeyNoCoord = Buffer.from(\n normalizeXOnlyPubkey(depositorBtcPubkey),\n \"hex\",\n );\n const apiUrl = this.config.mempoolApiUrl;\n\n // Resolve prevout data for each input (local cache or mempool API)\n const utxoDataPromises = tx.ins.map((input) => {\n const txid = Buffer.from(input.hash).reverse().toString(\"hex\");\n const vout = input.index;\n return resolveUtxoInfo(txid, vout, params.localPrevouts, apiUrl).then(\n (utxoData) => ({ input, utxoData, txid, vout }),\n );\n });\n\n const inputsWithUtxoData = await Promise.all(utxoDataPromises);\n\n // Cross-validate: total input value must cover total output value.\n // A mismatch indicates the mempool API returned manipulated UTXO data,\n // which could lead to fee-siphoning or invalid signatures.\n const totalInputValue = inputsWithUtxoData.reduce(\n (sum, i) => sum + BigInt(i.utxoData.value),\n 0n,\n );\n const totalOutputValue = tx.outs.reduce(\n (sum, out) => sum + BigInt(out.value),\n 0n,\n );\n if (totalInputValue < totalOutputValue) {\n throw new Error(\n `UTXO value mismatch: total input value (${totalInputValue} sat) is less than ` +\n `total output value (${totalOutputValue} sat). ` +\n `This may indicate the mempool API returned manipulated UTXO data.`,\n );\n }\n\n const impliedFee = totalInputValue - totalOutputValue;\n if (impliedFee > MAX_REASONABLE_FEE_SATS) {\n throw new Error(\n `Implied transaction fee (${impliedFee} sat) exceeds maximum reasonable fee ` +\n `(${MAX_REASONABLE_FEE_SATS} sat). This may indicate manipulated UTXO data.`,\n );\n }\n\n // Add inputs with proper PSBT fields based on script type\n for (const { input, utxoData, txid, vout } of inputsWithUtxoData) {\n const psbtInputFields = getPsbtInputFields(\n {\n txid,\n vout,\n value: utxoData.value,\n scriptPubKey: utxoData.scriptPubKey,\n },\n publicKeyNoCoord,\n );\n\n psbt.addInput({\n hash: input.hash,\n index: input.index,\n sequence: input.sequence,\n ...psbtInputFields,\n });\n }\n\n // Step 3: Add outputs\n for (const output of tx.outs) {\n psbt.addOutput({\n script: output.script,\n value: output.value,\n });\n }\n\n // Step 4: Sign PSBT via wallet\n const signedPsbtHex = await this.config.btcWallet.signPsbt(psbt.toHex());\n const signedPsbt = Psbt.fromHex(signedPsbtHex);\n\n // Step 5: Finalize and extract transaction\n try {\n signedPsbt.finalizeAllInputs();\n } catch (e) {\n // Some wallets (e.g. UniSat, OKX) auto-finalize PSBTs before returning them.\n // Attempting to finalize again throws, which is expected and safe to skip —\n // but verify the wallet actually finalized all inputs.\n const allFinalized = signedPsbt.data.inputs.every(\n (inp) => inp.finalScriptWitness || inp.finalScriptSig,\n );\n if (!allFinalized) {\n throw new Error(\n `PSBT finalization failed and wallet did not auto-finalize: ${e}`,\n );\n }\n }\n\n const signedTxHex = signedPsbt.extractTransaction().toHex();\n\n // Step 6: Broadcast to Bitcoin network\n const btcTxid = await pushTx(signedTxHex, apiUrl);\n\n return btcTxid;\n }\n\n /**\n * Registers a peg-in on Ethereum by calling the BTCVaultRegistry contract.\n *\n * This method:\n * 1. Re-verifies the PopSignature against the currently connected ETH\n * and BTC wallets — refuses to proceed if either has changed\n * 2. Derives vault ID and checks if it already exists (pre-flight)\n * 3. Encodes the contract call using viem\n * 4. Estimates gas (catches contract errors early with proper revert\n * reasons)\n * 5. Sends transaction with pre-estimated gas via\n * ethWallet.sendTransaction()\n *\n * The PopSignature must be obtained via\n * {@link signProofOfPossession} before this call.\n *\n * @param params - Registration parameters including the PopSignature\n * and the prepared Pre-PegIn / PegIn transactions\n * @returns Result containing Ethereum transaction hash and vault ID\n * @throws Error if the PopSignature does not match the connected wallets\n * @throws Error if the vault already exists\n * @throws Error if contract simulation fails (e.g., invalid signature,\n * unauthorized)\n */\n async registerPeginOnChain(\n params: RegisterPeginParams,\n ): Promise<RegisterPeginResult> {\n const {\n unsignedPrePeginTx,\n depositorSignedPeginTx,\n vaultProvider,\n hashlock,\n htlcVout,\n depositorPayoutBtcAddress,\n depositorWotsPkHash,\n popSignature,\n } = params;\n\n // Step 1: Re-verify the PoP artifact against the currently connected\n // wallets so a mid-flow account/wallet switch fails here instead of\n // surfacing downstream as an opaque contract revert.\n if (!this.config.ethWallet.account) {\n throw new Error(\"Ethereum wallet account not found\");\n }\n const depositorEthAddress = this.config.ethWallet.account.address;\n if (!isAddressEqual(popSignature.depositorEthAddress, depositorEthAddress)) {\n throw new Error(\n `Proof of possession was signed for ${popSignature.depositorEthAddress} ` +\n `but the Ethereum wallet is currently connected to ${depositorEthAddress}. ` +\n `Reconnect the original account or call signProofOfPossession() again.`,\n );\n }\n await this.assertPopMatchesBtcWallet(popSignature);\n const btcPopSignature = popSignature.btcPopSignature;\n\n // Step 2: Format parameters for contract call\n const depositorBtcPubkeyHex = ensureHexPrefix(popSignature.depositorBtcPubkey);\n const unsignedPrePeginTxHex = ensureHexPrefix(unsignedPrePeginTx);\n const depositorSignedPeginTxHex = ensureHexPrefix(depositorSignedPeginTx);\n\n const payoutScriptPubKey = await this.resolvePayoutScriptPubKey(\n depositorPayoutBtcAddress,\n );\n\n // Step 3: Calculate pegin tx hash and derive vault ID, then check if it already exists\n const peginTxHash = calculateBtcTxHash(depositorSignedPeginTxHex);\n const derivedVaultIdHex = await deriveVaultId(\n stripHexPrefix(peginTxHash),\n stripHexPrefix(depositorEthAddress),\n );\n const vaultId = ensureHexPrefix(derivedVaultIdHex) as Hex;\n const exists = await this.checkVaultExists(vaultId);\n\n if (exists) {\n throw new Error(\n `Vault already exists (ID: ${vaultId}, peginTxHash: ${peginTxHash}). ` +\n `Vault IDs are derived from the pegin transaction hash and depositor address. ` +\n `To create a new vault, use different UTXOs or a different amount to generate a unique transaction.`,\n );\n }\n\n // Step 4: Query required pegin fee from the contract\n const publicClient = createPublicClient({\n chain: this.config.ethChain,\n transport: http(),\n });\n\n let peginFee: bigint;\n try {\n peginFee = (await publicClient.readContract({\n address: this.config.vaultContracts.btcVaultRegistry,\n abi: BTCVaultRegistryABI,\n functionName: \"getPegInFee\",\n args: [vaultProvider],\n })) as bigint;\n } catch {\n throw new Error(\n \"Failed to query pegin fee from the contract. \" +\n \"Please check your network connection and that the contract address is correct.\",\n );\n }\n\n // Step 5: Encode the contract call data\n const callData = encodeFunctionData({\n abi: BTCVaultRegistryABI,\n functionName: \"submitPeginRequest\",\n args: [\n depositorEthAddress,\n depositorBtcPubkeyHex,\n btcPopSignature,\n unsignedPrePeginTxHex,\n depositorSignedPeginTxHex,\n vaultProvider,\n hashlock,\n htlcVout,\n payoutScriptPubKey,\n depositorWotsPkHash,\n ],\n });\n\n // Step 6: Estimate gas first to catch contract errors before showing wallet popup\n // This ensures users see actual contract revert reasons instead of gas errors\n // The gas estimate is then passed to sendTransaction to avoid double estimation\n let gasEstimate: bigint;\n try {\n gasEstimate = await publicClient.estimateGas({\n to: this.config.vaultContracts.btcVaultRegistry,\n data: callData,\n value: peginFee,\n account: this.config.ethWallet.account.address,\n });\n } catch (error) {\n // Estimation failed - handle contract error with actual revert reason\n handleContractError(error); // always throws (return type: never)\n }\n\n // Step 7: Submit peg-in request to contract (estimation passed)\n let ethTxHash: Hex;\n try {\n // Send transaction with pre-estimated gas to skip internal estimation\n // Note: viem's sendTransaction uses `gas`, not `gasLimit`\n ethTxHash = await this.config.ethWallet.sendTransaction({\n to: this.config.vaultContracts.btcVaultRegistry,\n data: callData,\n value: peginFee,\n account: this.config.ethWallet.account,\n chain: this.config.ethChain,\n gas: gasEstimate,\n });\n } catch (error) {\n // Use proper error handler for better error messages\n handleContractError(error); // always throws (return type: never)\n }\n\n // Step 8: Wait for transaction receipt and verify it was not reverted\n const receipt = await publicClient.waitForTransactionReceipt({\n hash: ethTxHash,\n timeout: RECEIPT_TIMEOUT_MS,\n });\n if (receipt.status === \"reverted\") {\n handleContractError(\n new Error(\n `Transaction reverted. Hash: ${ethTxHash}. ` +\n `Check the transaction on block explorer for details.`,\n ),\n );\n }\n\n return {\n ethTxHash: receipt.transactionHash,\n vaultId,\n peginTxHash,\n };\n }\n\n /**\n * Register multiple pegins on Ethereum in a single transaction.\n *\n * Uses the contract's submitPeginRequestBatch() to submit all vault\n * registrations atomically. All vaults must share the same vault provider.\n * The PoP signature is signed once and included in each request.\n *\n * @param params - Batch registration parameters\n * @returns Batch result with per-vault IDs and single ETH tx hash\n */\n async registerPeginBatchOnChain(\n params: RegisterPeginBatchParams,\n ): Promise<RegisterPeginBatchResult> {\n const { vaultProvider, unsignedPrePeginTx, requests, popSignature } =\n params;\n\n if (requests.length === 0) {\n throw new Error(\"Batch pegin requires at least one request\");\n }\n\n // Step 1: Re-verify the PoP (same reasoning as registerPeginOnChain).\n if (!this.config.ethWallet.account) {\n throw new Error(\"Ethereum wallet account not found\");\n }\n const depositorEthAddress = this.config.ethWallet.account.address;\n if (!isAddressEqual(popSignature.depositorEthAddress, depositorEthAddress)) {\n throw new Error(\n `Proof of possession was signed for ${popSignature.depositorEthAddress} ` +\n `but the Ethereum wallet is currently connected to ${depositorEthAddress}. ` +\n `Reconnect the original account or call signProofOfPossession() again.`,\n );\n }\n await this.assertPopMatchesBtcWallet(popSignature);\n const btcPopSignature = popSignature.btcPopSignature;\n\n // Step 2: Resolve per-request payout scriptPubKey.\n const resolvedPayoutScripts: Hex[] = [];\n for (const req of requests) {\n resolvedPayoutScripts.push(\n await this.resolvePayoutScriptPubKey(req.depositorPayoutBtcAddress),\n );\n }\n\n // Step 3: Pre-compute vault IDs and check for duplicates\n const vaultResults: BatchPeginResultItem[] = [];\n for (const req of requests) {\n const depositorSignedPeginTxHex = ensureHexPrefix(\n req.depositorSignedPeginTx,\n );\n const peginTxHash = calculateBtcTxHash(depositorSignedPeginTxHex);\n const derivedVaultIdHex = await deriveVaultId(\n stripHexPrefix(peginTxHash),\n stripHexPrefix(depositorEthAddress),\n );\n const vaultId = ensureHexPrefix(derivedVaultIdHex) as Hex;\n const exists = await this.checkVaultExists(vaultId);\n if (exists) {\n throw new Error(\n `Vault already exists (ID: ${vaultId}, peginTxHash: ${peginTxHash}). ` +\n `To create a new vault, use different UTXOs or a different amount.`,\n );\n }\n vaultResults.push({ vaultId, peginTxHash });\n }\n\n // Step 4: Query pegin fee and compute total\n const publicClient = createPublicClient({\n chain: this.config.ethChain,\n transport: http(),\n });\n\n let peginFee: bigint;\n try {\n peginFee = (await publicClient.readContract({\n address: this.config.vaultContracts.btcVaultRegistry,\n abi: BTCVaultRegistryABI,\n functionName: \"getPegInFee\",\n args: [vaultProvider],\n })) as bigint;\n } catch {\n throw new Error(\n \"Failed to query pegin fee from the contract. \" +\n \"Please check your network connection and that the contract address is correct.\",\n );\n }\n const totalFee = peginFee * BigInt(requests.length);\n\n // Step 5: Build BatchPeginRequest[] tuple array. Depositor BTC pubkey,\n // PoP, and Pre-PegIn tx hex are shared across the batch (carried on\n // the top-level params / PopSignature, not per request).\n const depositorBtcPubkeyHex = ensureHexPrefix(\n popSignature.depositorBtcPubkey,\n ) as Hex;\n const unsignedPrePeginTxHex = ensureHexPrefix(unsignedPrePeginTx) as Hex;\n const batchRequests = requests.map((req, i) => ({\n depositorBtcPubKey: depositorBtcPubkeyHex,\n btcPopSignature,\n unsignedPrePeginTx: unsignedPrePeginTxHex,\n depositorSignedPeginTx: ensureHexPrefix(\n req.depositorSignedPeginTx,\n ) as Hex,\n hashlock: req.hashlock,\n htlcVout: req.htlcVout,\n referralCode: NO_REFERRAL_CODE,\n depositorPayoutBtcAddress: resolvedPayoutScripts[i],\n depositorWotsPkHash: req.depositorWotsPkHash,\n }));\n\n // Step 6: Encode batch call data\n const callData = encodeFunctionData({\n abi: BTCVaultRegistryABI,\n functionName: \"submitPeginRequestBatch\",\n args: [depositorEthAddress, vaultProvider, batchRequests],\n });\n\n // Step 7: Estimate gas\n let gasEstimate: bigint;\n try {\n gasEstimate = await publicClient.estimateGas({\n to: this.config.vaultContracts.btcVaultRegistry,\n data: callData,\n value: totalFee,\n account: this.config.ethWallet.account.address,\n });\n } catch (error) {\n handleContractError(error); // always throws (return type: never)\n }\n\n // Step 8: Submit batch transaction\n let ethTxHash: Hex;\n try {\n ethTxHash = await this.config.ethWallet.sendTransaction({\n to: this.config.vaultContracts.btcVaultRegistry,\n data: callData,\n value: totalFee,\n account: this.config.ethWallet.account,\n chain: this.config.ethChain,\n gas: gasEstimate,\n });\n } catch (error) {\n handleContractError(error); // always throws (return type: never)\n }\n\n // Step 9: Wait for receipt\n const receipt = await publicClient.waitForTransactionReceipt({\n hash: ethTxHash,\n timeout: RECEIPT_TIMEOUT_MS,\n });\n if (receipt.status === \"reverted\") {\n handleContractError(\n new Error(\n `Batch transaction reverted. Hash: ${ethTxHash}. ` +\n `Check the transaction on block explorer for details.`,\n ),\n );\n }\n\n return {\n ethTxHash: receipt.transactionHash,\n vaults: vaultResults,\n };\n }\n\n /**\n * Check if a vault already exists for a given vault ID.\n *\n * @param vaultId - The Bitcoin transaction hash (vault ID)\n * @returns True if vault exists, false otherwise\n */\n private async checkVaultExists(vaultId: Hex): Promise<boolean> {\n try {\n // Create a public client to read from the contract\n const publicClient = createPublicClient({\n chain: this.config.ethChain,\n transport: http(),\n });\n\n const result = (await publicClient.readContract({\n address: this.config.vaultContracts.btcVaultRegistry,\n abi: BTCVaultRegistryABI,\n functionName: \"getBtcVaultBasicInfo\",\n args: [vaultId],\n })) as readonly [Address, ...unknown[]];\n\n // First element is depositor; if not zero address, vault exists\n return result[0] !== zeroAddress;\n } catch {\n // If reading fails, assume vault doesn't exist and let contract handle it\n return false;\n }\n }\n\n /**\n * Resolve the BTC payout address to a scriptPubKey hex for the contract.\n *\n * If a payout address is provided, converts it directly.\n * If omitted, uses the wallet's address and validates it against the\n * wallet's public key to guard against a compromised wallet provider.\n */\n private async resolvePayoutScriptPubKey(\n depositorPayoutBtcAddress?: string,\n ): Promise<Hex> {\n let address: string;\n\n if (depositorPayoutBtcAddress) {\n address = depositorPayoutBtcAddress;\n } else {\n address = await this.config.btcWallet.getAddress();\n const walletPubkey = await this.config.btcWallet.getPublicKeyHex();\n if (\n !isAddressFromPublicKey(\n address,\n walletPubkey,\n this.config.btcNetwork,\n )\n ) {\n throw new Error(\n \"The BTC address from your wallet does not match the wallet's public key. \" +\n \"Please ensure your wallet is using a supported address type (Taproot or Native SegWit).\",\n );\n }\n }\n\n const network = getNetwork(this.config.btcNetwork);\n try {\n return `0x${bitcoin.address.toOutputScript(address, network).toString(\"hex\")}` as Hex;\n } catch {\n throw new Error(\n `Invalid BTC payout address: \"${address}\". ` +\n `Please provide a valid Bitcoin address for the ${this.config.btcNetwork} network.`,\n );\n }\n }\n\n /**\n * Sign a BIP-322 BTC Proof-of-Possession binding the connected BTC\n * wallet to the connected ETH account for this chain and vault\n * registry. The returned {@link PopSignature} can be reused across\n * every register call in the same session.\n */\n async signProofOfPossession(): Promise<PopSignature> {\n if (!this.config.ethWallet.account) {\n throw new Error(\"Ethereum wallet account not found\");\n }\n const depositorEthAddress = this.config.ethWallet.account.address;\n\n const depositorBtcPubkey = normalizeXOnlyPubkey(\n await this.config.btcWallet.getPublicKeyHex(),\n );\n\n // Message format matches BTCProofOfPossession.sol buildMessage()\n const verifyingContract = this.config.vaultContracts.btcVaultRegistry;\n const popMessage = `${depositorEthAddress.toLowerCase()}:${this.config.ethChain.id}:pegin:${verifyingContract.toLowerCase()}`;\n const raw = await this.config.btcWallet.signMessage(\n popMessage,\n \"bip322-simple\",\n );\n\n return {\n btcPopSignature: normalizePopSignature(raw),\n depositorEthAddress,\n depositorBtcPubkey,\n };\n }\n\n private async assertPopMatchesBtcWallet(\n popSignature: PopSignature,\n ): Promise<void> {\n const currentBtcPubkey = normalizeXOnlyPubkey(\n await this.config.btcWallet.getPublicKeyHex(),\n );\n // Normalize the PoP-embedded key the same way in case a consumer\n // serialized it through a path that changed casing or re-added 0x.\n const popBtcPubkey = normalizeXOnlyPubkey(popSignature.depositorBtcPubkey);\n if (currentBtcPubkey !== popBtcPubkey) {\n throw new Error(\n `Proof of possession was signed with BTC pubkey ${popBtcPubkey} ` +\n `but the BTC wallet is currently connected to ${currentBtcPubkey}. ` +\n `Reconnect the original wallet or call signProofOfPossession() again.`,\n );\n }\n }\n\n /**\n * Gets the configured Bitcoin network.\n *\n * @returns The Bitcoin network (mainnet, testnet, signet, regtest)\n */\n getNetwork(): Network {\n return this.config.btcNetwork;\n }\n\n /**\n * Gets the configured BTCVaultRegistry contract address.\n *\n * @returns The Ethereum address of the BTCVaultRegistry contract\n */\n getVaultContractAddress(): Address {\n return this.config.vaultContracts.btcVaultRegistry;\n }\n}\n","/**\n * HMAC: RFC2104 message authentication code.\n * @module\n */\nimport { abytes, aexists, ahash, clean } from \"./utils.js\";\n/** Internal class for HMAC. */\nexport class _HMAC {\n oHash;\n iHash;\n blockLen;\n outputLen;\n finished = false;\n destroyed = false;\n constructor(hash, key) {\n ahash(hash);\n abytes(key, undefined, 'key');\n this.iHash = hash.create();\n if (typeof this.iHash.update !== 'function')\n throw new Error('Expected instance of class which extends utils.Hash');\n this.blockLen = this.iHash.blockLen;\n this.outputLen = this.iHash.outputLen;\n const blockLen = this.blockLen;\n const pad = new Uint8Array(blockLen);\n // blockLen can be bigger than outputLen\n pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);\n for (let i = 0; i < pad.length; i++)\n pad[i] ^= 0x36;\n this.iHash.update(pad);\n // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone\n this.oHash = hash.create();\n // Undo internal XOR && apply outer XOR\n for (let i = 0; i < pad.length; i++)\n pad[i] ^= 0x36 ^ 0x5c;\n this.oHash.update(pad);\n clean(pad);\n }\n update(buf) {\n aexists(this);\n this.iHash.update(buf);\n return this;\n }\n digestInto(out) {\n aexists(this);\n abytes(out, this.outputLen, 'output');\n this.finished = true;\n this.iHash.digestInto(out);\n this.oHash.update(out);\n this.oHash.digestInto(out);\n this.destroy();\n }\n digest() {\n const out = new Uint8Array(this.oHash.outputLen);\n this.digestInto(out);\n return out;\n }\n _cloneInto(to) {\n // Create new instance without calling constructor since key already in state and we don't know it.\n to ||= Object.create(Object.getPrototypeOf(this), {});\n const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;\n to = to;\n to.finished = finished;\n to.destroyed = destroyed;\n to.blockLen = blockLen;\n to.outputLen = outputLen;\n to.oHash = oHash._cloneInto(to.oHash);\n to.iHash = iHash._cloneInto(to.iHash);\n return to;\n }\n clone() {\n return this._cloneInto();\n }\n destroy() {\n this.destroyed = true;\n this.oHash.destroy();\n this.iHash.destroy();\n }\n}\n/**\n * HMAC: RFC2104 message authentication code.\n * @param hash - function that would be used e.g. sha256\n * @param key - message key\n * @param message - message data\n * @example\n * import { hmac } from '@noble/hashes/hmac';\n * import { sha256 } from '@noble/hashes/sha2';\n * const mac1 = hmac(sha256, 'key', 'message');\n */\nexport const hmac = (hash, key, message) => new _HMAC(hash, key).update(message).digest();\nhmac.create = (hash, key) => new _HMAC(hash, key);\n//# sourceMappingURL=hmac.js.map","/**\n\nSHA1 (RFC 3174), MD5 (RFC 1321) and RIPEMD160 (RFC 2286) legacy, weak hash functions.\nDon't use them in a new protocol. What \"weak\" means:\n\n- Collisions can be made with 2^18 effort in MD5, 2^60 in SHA1, 2^80 in RIPEMD160.\n- No practical pre-image attacks (only theoretical, 2^123.4)\n- HMAC seems kinda ok: https://www.rfc-editor.org/rfc/rfc6151\n * @module\n */\nimport { Chi, HashMD, Maj } from \"./_md.js\";\nimport { clean, createHasher, rotl } from \"./utils.js\";\n/** Initial SHA1 state */\nconst SHA1_IV = /* @__PURE__ */ Uint32Array.from([\n 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0,\n]);\n// Reusable temporary buffer\nconst SHA1_W = /* @__PURE__ */ new Uint32Array(80);\n/** Internal SHA1 legacy hash class. */\nexport class _SHA1 extends HashMD {\n A = SHA1_IV[0] | 0;\n B = SHA1_IV[1] | 0;\n C = SHA1_IV[2] | 0;\n D = SHA1_IV[3] | 0;\n E = SHA1_IV[4] | 0;\n constructor() {\n super(64, 20, 8, false);\n }\n get() {\n const { A, B, C, D, E } = this;\n return [A, B, C, D, E];\n }\n set(A, B, C, D, E) {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n this.E = E | 0;\n }\n process(view, offset) {\n for (let i = 0; i < 16; i++, offset += 4)\n SHA1_W[i] = view.getUint32(offset, false);\n for (let i = 16; i < 80; i++)\n SHA1_W[i] = rotl(SHA1_W[i - 3] ^ SHA1_W[i - 8] ^ SHA1_W[i - 14] ^ SHA1_W[i - 16], 1);\n // Compression function main loop, 80 rounds\n let { A, B, C, D, E } = this;\n for (let i = 0; i < 80; i++) {\n let F, K;\n if (i < 20) {\n F = Chi(B, C, D);\n K = 0x5a827999;\n }\n else if (i < 40) {\n F = B ^ C ^ D;\n K = 0x6ed9eba1;\n }\n else if (i < 60) {\n F = Maj(B, C, D);\n K = 0x8f1bbcdc;\n }\n else {\n F = B ^ C ^ D;\n K = 0xca62c1d6;\n }\n const T = (rotl(A, 5) + F + E + K + SHA1_W[i]) | 0;\n E = D;\n D = C;\n C = rotl(B, 30);\n B = A;\n A = T;\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n E = (E + this.E) | 0;\n this.set(A, B, C, D, E);\n }\n roundClean() {\n clean(SHA1_W);\n }\n destroy() {\n this.set(0, 0, 0, 0, 0);\n clean(this.buffer);\n }\n}\n/** SHA1 (RFC 3174) legacy hash function. It was cryptographically broken. */\nexport const sha1 = /* @__PURE__ */ createHasher(() => new _SHA1());\n/** Per-round constants */\nconst p32 = /* @__PURE__ */ Math.pow(2, 32);\nconst K = /* @__PURE__ */ Array.from({ length: 64 }, (_, i) => Math.floor(p32 * Math.abs(Math.sin(i + 1))));\n/** md5 initial state: same as sha1, but 4 u32 instead of 5. */\nconst MD5_IV = /* @__PURE__ */ SHA1_IV.slice(0, 4);\n// Reusable temporary buffer\nconst MD5_W = /* @__PURE__ */ new Uint32Array(16);\n/** Internal MD5 legacy hash class. */\nexport class _MD5 extends HashMD {\n A = MD5_IV[0] | 0;\n B = MD5_IV[1] | 0;\n C = MD5_IV[2] | 0;\n D = MD5_IV[3] | 0;\n constructor() {\n super(64, 16, 8, true);\n }\n get() {\n const { A, B, C, D } = this;\n return [A, B, C, D];\n }\n set(A, B, C, D) {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n }\n process(view, offset) {\n for (let i = 0; i < 16; i++, offset += 4)\n MD5_W[i] = view.getUint32(offset, true);\n // Compression function main loop, 64 rounds\n let { A, B, C, D } = this;\n for (let i = 0; i < 64; i++) {\n let F, g, s;\n if (i < 16) {\n F = Chi(B, C, D);\n g = i;\n s = [7, 12, 17, 22];\n }\n else if (i < 32) {\n F = Chi(D, B, C);\n g = (5 * i + 1) % 16;\n s = [5, 9, 14, 20];\n }\n else if (i < 48) {\n F = B ^ C ^ D;\n g = (3 * i + 5) % 16;\n s = [4, 11, 16, 23];\n }\n else {\n F = C ^ (B | ~D);\n g = (7 * i) % 16;\n s = [6, 10, 15, 21];\n }\n F = F + A + K[i] + MD5_W[g];\n A = D;\n D = C;\n C = B;\n B = B + rotl(F, s[i % 4]);\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n this.set(A, B, C, D);\n }\n roundClean() {\n clean(MD5_W);\n }\n destroy() {\n this.set(0, 0, 0, 0);\n clean(this.buffer);\n }\n}\n/**\n * MD5 (RFC 1321) legacy hash function. It was cryptographically broken.\n * MD5 architecture is similar to SHA1, with some differences:\n * - Reduced output length: 16 bytes (128 bit) instead of 20\n * - 64 rounds, instead of 80\n * - Little-endian: could be faster, but will require more code\n * - Non-linear index selection: huge speed-up for unroll\n * - Per round constants: more memory accesses, additional speed-up for unroll\n */\nexport const md5 = /* @__PURE__ */ createHasher(() => new _MD5());\n// RIPEMD-160\nconst Rho160 = /* @__PURE__ */ Uint8Array.from([\n 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,\n]);\nconst Id160 = /* @__PURE__ */ (() => Uint8Array.from(new Array(16).fill(0).map((_, i) => i)))();\nconst Pi160 = /* @__PURE__ */ (() => Id160.map((i) => (9 * i + 5) % 16))();\nconst idxLR = /* @__PURE__ */ (() => {\n const L = [Id160];\n const R = [Pi160];\n const res = [L, R];\n for (let i = 0; i < 4; i++)\n for (let j of res)\n j.push(j[i].map((k) => Rho160[k]));\n return res;\n})();\nconst idxL = /* @__PURE__ */ (() => idxLR[0])();\nconst idxR = /* @__PURE__ */ (() => idxLR[1])();\n// const [idxL, idxR] = idxLR;\nconst shifts160 = /* @__PURE__ */ [\n [11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8],\n [12, 13, 11, 15, 6, 9, 9, 7, 12, 15, 11, 13, 7, 8, 7, 7],\n [13, 15, 14, 11, 7, 7, 6, 8, 13, 14, 13, 12, 5, 5, 6, 9],\n [14, 11, 12, 14, 8, 6, 5, 5, 15, 12, 15, 14, 9, 9, 8, 6],\n [15, 12, 13, 13, 9, 5, 8, 6, 14, 11, 12, 11, 8, 6, 5, 5],\n].map((i) => Uint8Array.from(i));\nconst shiftsL160 = /* @__PURE__ */ idxL.map((idx, i) => idx.map((j) => shifts160[i][j]));\nconst shiftsR160 = /* @__PURE__ */ idxR.map((idx, i) => idx.map((j) => shifts160[i][j]));\nconst Kl160 = /* @__PURE__ */ Uint32Array.from([\n 0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e,\n]);\nconst Kr160 = /* @__PURE__ */ Uint32Array.from([\n 0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000,\n]);\n// It's called f() in spec.\nfunction ripemd_f(group, x, y, z) {\n if (group === 0)\n return x ^ y ^ z;\n if (group === 1)\n return (x & y) | (~x & z);\n if (group === 2)\n return (x | ~y) ^ z;\n if (group === 3)\n return (x & z) | (y & ~z);\n return x ^ (y | ~z);\n}\n// Reusable temporary buffer\nconst BUF_160 = /* @__PURE__ */ new Uint32Array(16);\nexport class _RIPEMD160 extends HashMD {\n h0 = 0x67452301 | 0;\n h1 = 0xefcdab89 | 0;\n h2 = 0x98badcfe | 0;\n h3 = 0x10325476 | 0;\n h4 = 0xc3d2e1f0 | 0;\n constructor() {\n super(64, 20, 8, true);\n }\n get() {\n const { h0, h1, h2, h3, h4 } = this;\n return [h0, h1, h2, h3, h4];\n }\n set(h0, h1, h2, h3, h4) {\n this.h0 = h0 | 0;\n this.h1 = h1 | 0;\n this.h2 = h2 | 0;\n this.h3 = h3 | 0;\n this.h4 = h4 | 0;\n }\n process(view, offset) {\n for (let i = 0; i < 16; i++, offset += 4)\n BUF_160[i] = view.getUint32(offset, true);\n // prettier-ignore\n let al = this.h0 | 0, ar = al, bl = this.h1 | 0, br = bl, cl = this.h2 | 0, cr = cl, dl = this.h3 | 0, dr = dl, el = this.h4 | 0, er = el;\n // Instead of iterating 0 to 80, we split it into 5 groups\n // And use the groups in constants, functions, etc. Much simpler\n for (let group = 0; group < 5; group++) {\n const rGroup = 4 - group;\n const hbl = Kl160[group], hbr = Kr160[group]; // prettier-ignore\n const rl = idxL[group], rr = idxR[group]; // prettier-ignore\n const sl = shiftsL160[group], sr = shiftsR160[group]; // prettier-ignore\n for (let i = 0; i < 16; i++) {\n const tl = (rotl(al + ripemd_f(group, bl, cl, dl) + BUF_160[rl[i]] + hbl, sl[i]) + el) | 0;\n al = el, el = dl, dl = rotl(cl, 10) | 0, cl = bl, bl = tl; // prettier-ignore\n }\n // 2 loops are 10% faster\n for (let i = 0; i < 16; i++) {\n const tr = (rotl(ar + ripemd_f(rGroup, br, cr, dr) + BUF_160[rr[i]] + hbr, sr[i]) + er) | 0;\n ar = er, er = dr, dr = rotl(cr, 10) | 0, cr = br, br = tr; // prettier-ignore\n }\n }\n // Add the compressed chunk to the current hash value\n this.set((this.h1 + cl + dr) | 0, (this.h2 + dl + er) | 0, (this.h3 + el + ar) | 0, (this.h4 + al + br) | 0, (this.h0 + bl + cr) | 0);\n }\n roundClean() {\n clean(BUF_160);\n }\n destroy() {\n this.destroyed = true;\n clean(this.buffer);\n this.set(0, 0, 0, 0, 0);\n }\n}\n/**\n * RIPEMD-160 - a legacy hash function from 1990s.\n * * https://homes.esat.kuleuven.be/~bosselae/ripemd160.html\n * * https://homes.esat.kuleuven.be/~bosselae/ripemd160/pdf/AB-9601/AB-9601.pdf\n */\nexport const ripemd160 = /* @__PURE__ */ createHasher(() => new _RIPEMD160());\n//# sourceMappingURL=legacy.js.map","/**\n * SHA3 (keccak) hash function, based on a new \"Sponge function\" design.\n * Different from older hashes, the internal state is bigger than output size.\n *\n * Check out [FIPS-202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf),\n * [Website](https://keccak.team/keccak.html),\n * [the differences between SHA-3 and Keccak](https://crypto.stackexchange.com/questions/15727/what-are-the-key-differences-between-the-draft-sha-3-standard-and-the-keccak-sub).\n *\n * Check out `sha3-addons` module for cSHAKE, k12, and others.\n * @module\n */\nimport { rotlBH, rotlBL, rotlSH, rotlSL, split } from \"./_u64.js\";\n// prettier-ignore\nimport { abytes, aexists, anumber, aoutput, clean, createHasher, oidNist, swap32IfBE, u32 } from \"./utils.js\";\n// No __PURE__ annotations in sha3 header:\n// EVERYTHING is in fact used on every export.\n// Various per round constants calculations\nconst _0n = BigInt(0);\nconst _1n = BigInt(1);\nconst _2n = BigInt(2);\nconst _7n = BigInt(7);\nconst _256n = BigInt(256);\nconst _0x71n = BigInt(0x71);\nconst SHA3_PI = [];\nconst SHA3_ROTL = [];\nconst _SHA3_IOTA = []; // no pure annotation: var is always used\nfor (let round = 0, R = _1n, x = 1, y = 0; round < 24; round++) {\n // Pi\n [x, y] = [y, (2 * x + 3 * y) % 5];\n SHA3_PI.push(2 * (5 * y + x));\n // Rotational\n SHA3_ROTL.push((((round + 1) * (round + 2)) / 2) % 64);\n // Iota\n let t = _0n;\n for (let j = 0; j < 7; j++) {\n R = ((R << _1n) ^ ((R >> _7n) * _0x71n)) % _256n;\n if (R & _2n)\n t ^= _1n << ((_1n << BigInt(j)) - _1n);\n }\n _SHA3_IOTA.push(t);\n}\nconst IOTAS = split(_SHA3_IOTA, true);\nconst SHA3_IOTA_H = IOTAS[0];\nconst SHA3_IOTA_L = IOTAS[1];\n// Left rotation (without 0, 32, 64)\nconst rotlH = (h, l, s) => (s > 32 ? rotlBH(h, l, s) : rotlSH(h, l, s));\nconst rotlL = (h, l, s) => (s > 32 ? rotlBL(h, l, s) : rotlSL(h, l, s));\n/** `keccakf1600` internal function, additionally allows to adjust round count. */\nexport function keccakP(s, rounds = 24) {\n const B = new Uint32Array(5 * 2);\n // NOTE: all indices are x2 since we store state as u32 instead of u64 (bigints to slow in js)\n for (let round = 24 - rounds; round < 24; round++) {\n // Theta θ\n for (let x = 0; x < 10; x++)\n B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40];\n for (let x = 0; x < 10; x += 2) {\n const idx1 = (x + 8) % 10;\n const idx0 = (x + 2) % 10;\n const B0 = B[idx0];\n const B1 = B[idx0 + 1];\n const Th = rotlH(B0, B1, 1) ^ B[idx1];\n const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1];\n for (let y = 0; y < 50; y += 10) {\n s[x + y] ^= Th;\n s[x + y + 1] ^= Tl;\n }\n }\n // Rho (ρ) and Pi (π)\n let curH = s[2];\n let curL = s[3];\n for (let t = 0; t < 24; t++) {\n const shift = SHA3_ROTL[t];\n const Th = rotlH(curH, curL, shift);\n const Tl = rotlL(curH, curL, shift);\n const PI = SHA3_PI[t];\n curH = s[PI];\n curL = s[PI + 1];\n s[PI] = Th;\n s[PI + 1] = Tl;\n }\n // Chi (χ)\n for (let y = 0; y < 50; y += 10) {\n for (let x = 0; x < 10; x++)\n B[x] = s[y + x];\n for (let x = 0; x < 10; x++)\n s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10];\n }\n // Iota (ι)\n s[0] ^= SHA3_IOTA_H[round];\n s[1] ^= SHA3_IOTA_L[round];\n }\n clean(B);\n}\n/** Keccak sponge function. */\nexport class Keccak {\n state;\n pos = 0;\n posOut = 0;\n finished = false;\n state32;\n destroyed = false;\n blockLen;\n suffix;\n outputLen;\n enableXOF = false;\n rounds;\n // NOTE: we accept arguments in bytes instead of bits here.\n constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24) {\n this.blockLen = blockLen;\n this.suffix = suffix;\n this.outputLen = outputLen;\n this.enableXOF = enableXOF;\n this.rounds = rounds;\n // Can be passed from user as dkLen\n anumber(outputLen, 'outputLen');\n // 1600 = 5x5 matrix of 64bit. 1600 bits === 200 bytes\n // 0 < blockLen < 200\n if (!(0 < blockLen && blockLen < 200))\n throw new Error('only keccak-f1600 function is supported');\n this.state = new Uint8Array(200);\n this.state32 = u32(this.state);\n }\n clone() {\n return this._cloneInto();\n }\n keccak() {\n swap32IfBE(this.state32);\n keccakP(this.state32, this.rounds);\n swap32IfBE(this.state32);\n this.posOut = 0;\n this.pos = 0;\n }\n update(data) {\n aexists(this);\n abytes(data);\n const { blockLen, state } = this;\n const len = data.length;\n for (let pos = 0; pos < len;) {\n const take = Math.min(blockLen - this.pos, len - pos);\n for (let i = 0; i < take; i++)\n state[this.pos++] ^= data[pos++];\n if (this.pos === blockLen)\n this.keccak();\n }\n return this;\n }\n finish() {\n if (this.finished)\n return;\n this.finished = true;\n const { state, suffix, pos, blockLen } = this;\n // Do the padding\n state[pos] ^= suffix;\n if ((suffix & 0x80) !== 0 && pos === blockLen - 1)\n this.keccak();\n state[blockLen - 1] ^= 0x80;\n this.keccak();\n }\n writeInto(out) {\n aexists(this, false);\n abytes(out);\n this.finish();\n const bufferOut = this.state;\n const { blockLen } = this;\n for (let pos = 0, len = out.length; pos < len;) {\n if (this.posOut >= blockLen)\n this.keccak();\n const take = Math.min(blockLen - this.posOut, len - pos);\n out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);\n this.posOut += take;\n pos += take;\n }\n return out;\n }\n xofInto(out) {\n // Sha3/Keccak usage with XOF is probably mistake, only SHAKE instances can do XOF\n if (!this.enableXOF)\n throw new Error('XOF is not possible for this instance');\n return this.writeInto(out);\n }\n xof(bytes) {\n anumber(bytes);\n return this.xofInto(new Uint8Array(bytes));\n }\n digestInto(out) {\n aoutput(out, this);\n if (this.finished)\n throw new Error('digest() was already called');\n this.writeInto(out);\n this.destroy();\n return out;\n }\n digest() {\n return this.digestInto(new Uint8Array(this.outputLen));\n }\n destroy() {\n this.destroyed = true;\n clean(this.state);\n }\n _cloneInto(to) {\n const { blockLen, suffix, outputLen, rounds, enableXOF } = this;\n to ||= new Keccak(blockLen, suffix, outputLen, enableXOF, rounds);\n to.state32.set(this.state32);\n to.pos = this.pos;\n to.posOut = this.posOut;\n to.finished = this.finished;\n to.rounds = rounds;\n // Suffix can change in cSHAKE\n to.suffix = suffix;\n to.outputLen = outputLen;\n to.enableXOF = enableXOF;\n to.destroyed = this.destroyed;\n return to;\n }\n}\nconst genKeccak = (suffix, blockLen, outputLen, info = {}) => createHasher(() => new Keccak(blockLen, suffix, outputLen), info);\n/** SHA3-224 hash function. */\nexport const sha3_224 = /* @__PURE__ */ genKeccak(0x06, 144, 28, \n/* @__PURE__ */ oidNist(0x07));\n/** SHA3-256 hash function. Different from keccak-256. */\nexport const sha3_256 = /* @__PURE__ */ genKeccak(0x06, 136, 32, \n/* @__PURE__ */ oidNist(0x08));\n/** SHA3-384 hash function. */\nexport const sha3_384 = /* @__PURE__ */ genKeccak(0x06, 104, 48, \n/* @__PURE__ */ oidNist(0x09));\n/** SHA3-512 hash function. */\nexport const sha3_512 = /* @__PURE__ */ genKeccak(0x06, 72, 64, \n/* @__PURE__ */ oidNist(0x0a));\n/** keccak-224 hash function. */\nexport const keccak_224 = /* @__PURE__ */ genKeccak(0x01, 144, 28);\n/** keccak-256 hash function. Different from SHA3-256. */\nexport const keccak_256 = /* @__PURE__ */ genKeccak(0x01, 136, 32);\n/** keccak-384 hash function. */\nexport const keccak_384 = /* @__PURE__ */ genKeccak(0x01, 104, 48);\n/** keccak-512 hash function. */\nexport const keccak_512 = /* @__PURE__ */ genKeccak(0x01, 72, 64);\nconst genShake = (suffix, blockLen, outputLen, info = {}) => createHasher((opts = {}) => new Keccak(blockLen, suffix, opts.dkLen === undefined ? outputLen : opts.dkLen, true), info);\n/** SHAKE128 XOF with 128-bit security. */\nexport const shake128 = \n/* @__PURE__ */\ngenShake(0x1f, 168, 16, /* @__PURE__ */ oidNist(0x0b));\n/** SHAKE256 XOF with 256-bit security. */\nexport const shake256 = \n/* @__PURE__ */\ngenShake(0x1f, 136, 32, /* @__PURE__ */ oidNist(0x0c));\n/** SHAKE128 XOF with 256-bit output (NIST version). */\nexport const shake128_32 = \n/* @__PURE__ */\ngenShake(0x1f, 168, 32, /* @__PURE__ */ oidNist(0x0b));\n/** SHAKE256 XOF with 512-bit output (NIST version). */\nexport const shake256_64 = \n/* @__PURE__ */\ngenShake(0x1f, 136, 64, /* @__PURE__ */ oidNist(0x0c));\n//# sourceMappingURL=sha3.js.map","/**\n * PBKDF (RFC 2898). Can be used to create a key from password and salt.\n * @module\n */\nimport { hmac } from \"./hmac.js\";\n// prettier-ignore\nimport { ahash, anumber, asyncLoop, checkOpts, clean, createView, kdfInputToBytes } from \"./utils.js\";\n// Common start and end for sync/async functions\nfunction pbkdf2Init(hash, _password, _salt, _opts) {\n ahash(hash);\n const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts);\n const { c, dkLen, asyncTick } = opts;\n anumber(c, 'c');\n anumber(dkLen, 'dkLen');\n anumber(asyncTick, 'asyncTick');\n if (c < 1)\n throw new Error('iterations (c) must be >= 1');\n const password = kdfInputToBytes(_password, 'password');\n const salt = kdfInputToBytes(_salt, 'salt');\n // DK = PBKDF2(PRF, Password, Salt, c, dkLen);\n const DK = new Uint8Array(dkLen);\n // U1 = PRF(Password, Salt + INT_32_BE(i))\n const PRF = hmac.create(hash, password);\n const PRFSalt = PRF._cloneInto().update(salt);\n return { c, dkLen, asyncTick, DK, PRF, PRFSalt };\n}\nfunction pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {\n PRF.destroy();\n PRFSalt.destroy();\n if (prfW)\n prfW.destroy();\n clean(u);\n return DK;\n}\n/**\n * PBKDF2-HMAC: RFC 2898 key derivation function\n * @param hash - hash function that would be used e.g. sha256\n * @param password - password from which a derived key is generated\n * @param salt - cryptographic salt\n * @param opts - {c, dkLen} where c is work factor and dkLen is output message size\n * @example\n * const key = pbkdf2(sha256, 'password', 'salt', { dkLen: 32, c: Math.pow(2, 18) });\n */\nexport function pbkdf2(hash, password, salt, opts) {\n const { c, dkLen, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);\n let prfW; // Working copy\n const arr = new Uint8Array(4);\n const view = createView(arr);\n const u = new Uint8Array(PRF.outputLen);\n // DK = T1 + T2 + ⋯ + Tdklen/hlen\n for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {\n // Ti = F(Password, Salt, c, i)\n const Ti = DK.subarray(pos, pos + PRF.outputLen);\n view.setInt32(0, ti, false);\n // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc\n // U1 = PRF(Password, Salt + INT_32_BE(i))\n (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);\n Ti.set(u.subarray(0, Ti.length));\n for (let ui = 1; ui < c; ui++) {\n // Uc = PRF(Password, Uc−1)\n PRF._cloneInto(prfW).update(u).digestInto(u);\n for (let i = 0; i < Ti.length; i++)\n Ti[i] ^= u[i];\n }\n }\n return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);\n}\n/**\n * PBKDF2-HMAC: RFC 2898 key derivation function. Async version.\n * @example\n * await pbkdf2Async(sha256, 'password', 'salt', { dkLen: 32, c: 500_000 });\n */\nexport async function pbkdf2Async(hash, password, salt, opts) {\n const { c, dkLen, asyncTick, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);\n let prfW; // Working copy\n const arr = new Uint8Array(4);\n const view = createView(arr);\n const u = new Uint8Array(PRF.outputLen);\n // DK = T1 + T2 + ⋯ + Tdklen/hlen\n for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {\n // Ti = F(Password, Salt, c, i)\n const Ti = DK.subarray(pos, pos + PRF.outputLen);\n view.setInt32(0, ti, false);\n // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc\n // U1 = PRF(Password, Salt + INT_32_BE(i))\n (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);\n Ti.set(u.subarray(0, Ti.length));\n await asyncLoop(c - 1, asyncTick, () => {\n // Uc = PRF(Password, Uc−1)\n PRF._cloneInto(prfW).update(u).digestInto(u);\n for (let i = 0; i < Ti.length; i++)\n Ti[i] ^= u[i];\n });\n }\n return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);\n}\n//# sourceMappingURL=pbkdf2.js.map","/*! scure-bip39 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) */\nimport { pbkdf2, pbkdf2Async } from '@noble/hashes/pbkdf2.js';\nimport { sha256, sha512 } from '@noble/hashes/sha2.js';\nimport { abytes, anumber, randomBytes } from '@noble/hashes/utils.js';\nimport { pbkdf2 as pbkdf2web, sha512 as sha512web } from '@noble/hashes/webcrypto.js';\nimport { utils as baseUtils } from '@scure/base';\n// Japanese wordlist\nconst isJapanese = (wordlist) => wordlist[0] === '\\u3042\\u3044\\u3053\\u304f\\u3057\\u3093';\n// Normalization replaces equivalent sequences of characters\n// so that any two texts that are equivalent will be reduced\n// to the same sequence of code points, called the normal form of the original text.\n// https://tonsky.me/blog/unicode/#why-is-a----\nfunction nfkd(str) {\n if (typeof str !== 'string')\n throw new TypeError('invalid mnemonic type: ' + typeof str);\n return str.normalize('NFKD');\n}\nfunction normalize(str) {\n const norm = nfkd(str);\n const words = norm.split(' ');\n if (![12, 15, 18, 21, 24].includes(words.length))\n throw new Error('Invalid mnemonic');\n return { nfkd: norm, words };\n}\nfunction aentropy(ent) {\n abytes(ent);\n if (![16, 20, 24, 28, 32].includes(ent.length))\n throw new Error('invalid entropy length');\n}\n/**\n * Generate x random words. Uses Cryptographically-Secure Random Number Generator.\n * @param wordlist imported wordlist for specific language\n * @param strength mnemonic strength 128-256 bits\n * @example\n * generateMnemonic(wordlist, 128)\n * // 'legal winner thank year wave sausage worth useful legal winner thank yellow'\n */\nexport function generateMnemonic(wordlist, strength = 128) {\n anumber(strength);\n if (strength % 32 !== 0 || strength > 256)\n throw new TypeError('Invalid entropy');\n return entropyToMnemonic(randomBytes(strength / 8), wordlist);\n}\nconst calcChecksum = (entropy) => {\n // Checksum is ent.length/4 bits long\n const bitsLeft = 8 - entropy.length / 4;\n // Zero rightmost \"bitsLeft\" bits in byte\n // For example: bitsLeft=4 val=10111101 -> 10110000\n return new Uint8Array([(sha256(entropy)[0] >> bitsLeft) << bitsLeft]);\n};\nfunction getCoder(wordlist) {\n if (!Array.isArray(wordlist) || wordlist.length !== 2048 || typeof wordlist[0] !== 'string')\n throw new Error('Wordlist: expected array of 2048 strings');\n wordlist.forEach((i) => {\n if (typeof i !== 'string')\n throw new Error('wordlist: non-string element: ' + i);\n });\n return baseUtils.chain(baseUtils.checksum(1, calcChecksum), baseUtils.radix2(11, true), baseUtils.alphabet(wordlist));\n}\n/**\n * Reversible: Converts mnemonic string to raw entropy in form of byte array.\n * @param mnemonic 12-24 words\n * @param wordlist imported wordlist for specific language\n * @example\n * const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';\n * mnemonicToEntropy(mnem, wordlist)\n * // Produces\n * new Uint8Array([\n * 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,\n * 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f\n * ])\n */\nexport function mnemonicToEntropy(mnemonic, wordlist) {\n const { words } = normalize(mnemonic);\n const entropy = getCoder(wordlist).decode(words);\n aentropy(entropy);\n return entropy;\n}\n/**\n * Reversible: Converts raw entropy in form of byte array to mnemonic string.\n * @param entropy byte array\n * @param wordlist imported wordlist for specific language\n * @returns 12-24 words\n * @example\n * const ent = new Uint8Array([\n * 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,\n * 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f\n * ]);\n * entropyToMnemonic(ent, wordlist);\n * // 'legal winner thank year wave sausage worth useful legal winner thank yellow'\n */\nexport function entropyToMnemonic(entropy, wordlist) {\n aentropy(entropy);\n const words = getCoder(wordlist).encode(entropy);\n return words.join(isJapanese(wordlist) ? '\\u3000' : ' ');\n}\n/**\n * Validates mnemonic for being 12-24 words contained in `wordlist`.\n */\nexport function validateMnemonic(mnemonic, wordlist) {\n try {\n mnemonicToEntropy(mnemonic, wordlist);\n }\n catch (e) {\n return false;\n }\n return true;\n}\nconst psalt = (passphrase) => nfkd('mnemonic' + passphrase);\n/**\n * Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.\n * @param mnemonic 12-24 words\n * @param passphrase string that will additionally protect the key\n * @returns 64 bytes of key data\n * @example\n * const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';\n * await mnemonicToSeed(mnem, 'password');\n * // new Uint8Array([...64 bytes])\n */\nexport function mnemonicToSeed(mnemonic, passphrase = '') {\n return pbkdf2Async(sha512, normalize(mnemonic).nfkd, psalt(passphrase), { c: 2048, dkLen: 64 });\n}\n/**\n * Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.\n * @param mnemonic 12-24 words\n * @param passphrase string that will additionally protect the key\n * @returns 64 bytes of key data\n * @example\n * const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';\n * mnemonicToSeedSync(mnem, 'password');\n * // new Uint8Array([...64 bytes])\n */\nexport function mnemonicToSeedSync(mnemonic, passphrase = '') {\n return pbkdf2(sha512, normalize(mnemonic).nfkd, psalt(passphrase), { c: 2048, dkLen: 64 });\n}\n/**\n * Uses native, built-in functionality, provided by globalThis.crypto.\n * Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.\n * @param mnemonic 12-24 words\n * @param passphrase string that will additionally protect the key\n * @returns 64 bytes of key data\n * @example\n * const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';\n * mnemonicToSeedWebcrypto(mnem, 'password');\n * // new Uint8Array([...64 bytes])\n */\nexport function mnemonicToSeedWebcrypto(mnemonic, passphrase = '') {\n return pbkdf2web(sha512web, normalize(mnemonic).nfkd, psalt(passphrase), { c: 2048, dkLen: 64 });\n}\n","/**\n * @module wots/derivation\n *\n * Deterministic WOTS one-time-signature key derivation for Babylon vault\n * deposits. Pure crypto functions extracted from the vault frontend into the\n * shared SDK.\n *\n * See the vault frontend's `wotsService.ts` for the full derivation\n * documentation.\n */\nimport { hmac } from \"@noble/hashes/hmac.js\";\nimport { ripemd160 } from \"@noble/hashes/legacy.js\";\nimport { sha256, sha512 } from \"@noble/hashes/sha2.js\";\nimport { keccak_256 } from \"@noble/hashes/sha3.js\";\nimport { mnemonicToSeedSync } from \"@scure/bip39\";\n\nimport { stripHexPrefix } from \"../primitives/utils/bitcoin\";\n\nimport type { WotsKeypair, WotsPublicKey } from \"./types\";\n\n/**\n * Number of bit positions in the WOTS keypair. Corresponds to the number\n * of garbled-circuit labels used in the BitVM-style protocol (PI_1 circuit).\n */\nconst PI_1_BITS = 508;\n\n/**\n * Size in bytes of each WOTS preimage (garbled-circuit label size).\n * Preimages are truncated from HMAC-SHA-512 output to this length.\n */\nconst GC_LABEL_SIZE = 16;\n\n/** Size in bytes of the parent key or derived key (first half of a 64-byte seed/HMAC). */\nconst KEY_SIZE = 32;\n\n/** Size in bytes of the full BIP-39 seed / HMAC-SHA-512 output. */\nconst SEED_SIZE = 64;\n\n/** Size of the index buffer used in per-bit derivation (1 byte flag + 4 byte big-endian index). */\nconst INDEX_BUFFER_SIZE = 5;\n\n/** Size of the big-endian length prefix prepended to variable-length fields. */\nconst LENGTH_PREFIX_SIZE = 4;\n\n// ---------------------------------------------------------------------------\n// Internal byte-manipulation utilities\n// ---------------------------------------------------------------------------\n\n/** Concatenate multiple `Uint8Array` buffers into a single array. */\nfunction concatBytes(...arrays: Uint8Array[]): Uint8Array {\n const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const arr of arrays) {\n result.set(arr, offset);\n offset += arr.length;\n }\n return result;\n}\n\n/** Encode a UTF-8 string as bytes. */\nfunction stringToBytes(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\n/**\n * Prepend a 4-byte big-endian length prefix to `data`.\n * Used to unambiguously concatenate variable-length fields in the vault\n * derivation path.\n */\nfunction lengthPrefixed(data: Uint8Array): Uint8Array {\n const len = new Uint8Array(LENGTH_PREFIX_SIZE);\n new DataView(len.buffer).setUint32(0, data.length, false);\n return concatBytes(len, data);\n}\n\n// ---------------------------------------------------------------------------\n// Internal cryptographic primitives (@noble/hashes wrappers)\n// ---------------------------------------------------------------------------\n\n/**\n * Compute HMAC-SHA-512.\n *\n * Uses `@noble/hashes/hmac` which accepts `Uint8Array` directly,\n * avoiding the unsafe `Uint8Array.buffer as ArrayBuffer` cast that\n * the Web Crypto API would require.\n *\n * @param key - HMAC key bytes.\n * @param data - Message bytes.\n * @returns 64-byte HMAC digest.\n */\nfunction hmacSha512(key: Uint8Array, data: Uint8Array): Uint8Array {\n return hmac(sha512, key, data);\n}\n\n/**\n * Compute Hash160: `RIPEMD-160(SHA-256(data))`.\n *\n * This is the same hash function used in Bitcoin for address derivation.\n *\n * @param data - Input bytes.\n * @returns 20-byte hash.\n */\nfunction hash160(data: Uint8Array): Uint8Array {\n return ripemd160(sha256(data));\n}\n\n/** Convert a byte array to a lowercase hex string. */\nconst toHex = (bytes: Uint8Array) =>\n Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n\n// ---------------------------------------------------------------------------\n// Seed and keypair derivation\n// ---------------------------------------------------------------------------\n\n/**\n * Convert a BIP-39 mnemonic into a 64-byte seed.\n *\n * Internally uses PBKDF2 with 2048 rounds of HMAC-SHA-512 and the passphrase\n * `\"mnemonic\"` (no user password), per the BIP-39 specification.\n *\n * @param mnemonic - A valid 12-word BIP-39 mnemonic.\n * @returns 64-byte seed suitable for {@link deriveWotsKeypair}.\n */\nexport function mnemonicToWotsSeed(mnemonic: string): Uint8Array {\n const seed = mnemonicToSeedSync(mnemonic);\n const copy = new Uint8Array(seed);\n seed.fill(0);\n return copy;\n}\n\n/**\n * Derive a deterministic WOTS keypair for a specific vault.\n *\n * ### Derivation steps\n *\n * 1. **Split the seed** — bytes `[0..32)` = parent key, `[32..64)` = chain code.\n *\n * 2. **Child key derivation** —\n * ```\n * vaultData = lenPrefix(vaultId) || lenPrefix(depositorPk) || lenPrefix(appContractAddress)\n * hmac = HMAC-SHA-512(chainCode, parentKey || vaultData)\n * derivedKey = hmac[0..32)\n * derivedChainCode = hmac[32..64)\n * ```\n *\n * 3. **Bit-level key expansion** — For each bit index `i` in `[0, 508)`:\n * ```\n * falseHmac = HMAC-SHA-512(derivedChainCode, derivedKey || 0x00 || bigEndian32(i))\n * trueHmac = HMAC-SHA-512(derivedChainCode, derivedKey || 0x01 || bigEndian32(i))\n *\n * falsePreimage = falseHmac[0..16) // 16 bytes = GC_LABEL_SIZE\n * truePreimage = trueHmac[0..16)\n *\n * falseHash = Hash160(falsePreimage) // 20 bytes\n * trueHash = Hash160(truePreimage)\n * ```\n *\n * 4. **Cleanup** — All intermediate key material is zeroed.\n *\n * The same (mnemonic, vaultId, depositorPk, appContractAddress) tuple always\n * produces the same keypair, enabling recovery from the mnemonic alone.\n *\n * @param seed - 64-byte seed from {@link mnemonicToWotsSeed}.\n * @param vaultId - Unique identifier of the vault (e.g. pegin tx hash).\n * @param depositorPk - Depositor's public key (hex string).\n * @param appContractAddress - Ethereum address of the application contract.\n * @returns A {@link WotsKeypair} with 508 preimage/hash pairs per branch.\n */\nexport async function deriveWotsKeypair(\n seed: Uint8Array,\n vaultId: string,\n depositorPk: string,\n appContractAddress: string,\n): Promise<WotsKeypair> {\n if (seed.length !== SEED_SIZE) {\n throw new Error(\n `WOTS seed must be ${SEED_SIZE} bytes, got ${seed.length}`,\n );\n }\n\n // Normalize BTC-style inputs by stripping 0x prefixes.\n // appContractAddress is NOT stripped — Ethereum addresses include the 0x\n // prefix in their canonical form, and existing on-chain commitments were\n // computed with it included. Changing this would break hash determinism.\n vaultId = stripHexPrefix(vaultId);\n depositorPk = stripHexPrefix(depositorPk);\n\n const chainCode = seed.slice(KEY_SIZE, SEED_SIZE);\n const parentKey = seed.slice(0, KEY_SIZE);\n\n // Track all intermediate buffers containing key material for cleanup.\n const sensitiveBuffers: Uint8Array[] = [chainCode, parentKey];\n\n try {\n const vaultData = concatBytes(\n lengthPrefixed(stringToBytes(vaultId)),\n lengthPrefixed(stringToBytes(depositorPk)),\n lengthPrefixed(stringToBytes(appContractAddress)),\n );\n\n const hmacInput = concatBytes(parentKey, vaultData);\n sensitiveBuffers.push(hmacInput);\n\n const hmacResult = hmacSha512(chainCode, hmacInput);\n sensitiveBuffers.push(hmacResult);\n\n const derivedKey = hmacResult.slice(0, KEY_SIZE);\n const derivedChainCode = hmacResult.slice(KEY_SIZE, SEED_SIZE);\n sensitiveBuffers.push(derivedKey, derivedChainCode);\n\n const falsePreimages: Uint8Array[] = [];\n const truePreimages: Uint8Array[] = [];\n const falseHashes: Uint8Array[] = [];\n const trueHashes: Uint8Array[] = [];\n\n let succeeded = false;\n try {\n for (let bit = 0; bit < PI_1_BITS; bit++) {\n const falseIndex = new Uint8Array(INDEX_BUFFER_SIZE);\n falseIndex[0] = 0;\n new DataView(falseIndex.buffer).setUint32(1, bit, false);\n\n const trueIndex = new Uint8Array(INDEX_BUFFER_SIZE);\n trueIndex[0] = 1;\n new DataView(trueIndex.buffer).setUint32(1, bit, false);\n\n const falseInput = concatBytes(derivedKey, falseIndex);\n const trueInput = concatBytes(derivedKey, trueIndex);\n const falseHmac = hmacSha512(derivedChainCode, falseInput);\n const trueHmac = hmacSha512(derivedChainCode, trueInput);\n\n try {\n const falsePreimage = falseHmac.slice(0, GC_LABEL_SIZE);\n const truePreimage = trueHmac.slice(0, GC_LABEL_SIZE);\n\n falsePreimages.push(falsePreimage);\n truePreimages.push(truePreimage);\n falseHashes.push(hash160(falsePreimage));\n trueHashes.push(hash160(truePreimage));\n } finally {\n falseInput.fill(0);\n trueInput.fill(0);\n falseHmac.fill(0);\n trueHmac.fill(0);\n }\n }\n\n succeeded = true;\n return { falsePreimages, truePreimages, falseHashes, trueHashes };\n } finally {\n if (!succeeded) {\n for (const p of falsePreimages) p.fill(0);\n for (const p of truePreimages) p.fill(0);\n }\n }\n } finally {\n for (const buf of sensitiveBuffers) {\n buf.fill(0);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Serialization\n// ---------------------------------------------------------------------------\n\n/**\n * Extract the public key from a WOTS keypair.\n *\n * The public key consists of the Hash160 digests (hex-encoded) for both\n * the `false` and `true` branch of each bit position. This is the value\n * submitted on-chain and to the vault provider for later signature\n * verification.\n *\n * @param keypair - A derived {@link WotsKeypair}.\n * @returns The {@link WotsPublicKey} with `false_list` and `true_list`,\n * each containing 508 hex strings of 40 characters (20 bytes).\n */\nexport function keypairToPublicKey(keypair: WotsKeypair): WotsPublicKey {\n return {\n false_list: keypair.falseHashes.map(toHex),\n true_list: keypair.trueHashes.map(toHex),\n };\n}\n\n/**\n * Compute the keccak256 hash of a WOTS keypair's public key.\n *\n * Matches the Rust `InputLabelHashes::keccak256_hash()` implementation:\n * `keccak256(falseHashes[0] || falseHashes[1] || ... || trueHashes[0] || trueHashes[1] || ...)`\n *\n * Each hash is 20 bytes (Hash160). Total input: `PI_1_BITS * 20 * 2` bytes.\n * The result is committed on-chain as `depositorWotsPkHash` so the vault\n * provider can later verify submitted WOTS public keys.\n *\n * @param keypair - A derived {@link WotsKeypair}.\n * @returns 32-byte keccak256 digest as a `0x`-prefixed hex string.\n */\nexport function computeWotsPkHash(keypair: WotsKeypair): `0x${string}` {\n if (keypair.falseHashes.length === 0 || keypair.trueHashes.length === 0) {\n throw new Error(\n \"computeWotsPkHash: keypair hash arrays must not be empty\",\n );\n }\n const hashSize = keypair.falseHashes[0].length;\n const totalBytes =\n (keypair.falseHashes.length + keypair.trueHashes.length) * hashSize;\n const buffer = new Uint8Array(totalBytes);\n\n let offset = 0;\n for (const h of keypair.falseHashes) {\n buffer.set(h, offset);\n offset += hashSize;\n }\n for (const h of keypair.trueHashes) {\n buffer.set(h, offset);\n offset += hashSize;\n }\n\n const digest = keccak_256(buffer);\n return `0x${toHex(digest)}`;\n}\n","/**\n * WOTS Block Key Derivation\n *\n * Derives deterministic WOTS (Winternitz One-Time Signature) block public keys\n * for Babylon vault deposits, matching the Rust `babe::wots` implementation.\n *\n * The SDK function takes a raw `seed: Uint8Array` and does not prescribe how\n * the seed was produced. Today callers derive it from a BIP-39 mnemonic via\n * `mnemonicToWotsSeed()`; when the `deriveContextHash` wallet API ships,\n * callers will use a different seed expansion path. The core block derivation\n * logic stays the same either way.\n *\n * @module wots/blockDerivation\n */\n\nimport type {\n WotsBlockPublicKey,\n WotsConfig,\n} from \"../clients/vault-provider/types\";\n\nimport { hmac } from \"@noble/hashes/hmac.js\";\nimport { ripemd160 } from \"@noble/hashes/legacy.js\";\nimport { sha256, sha512 } from \"@noble/hashes/sha2.js\";\nimport { keccak_256 } from \"@noble/hashes/sha3.js\";\nimport type { Hex } from \"viem\";\n\n// ---------------------------------------------------------------------------\n// Constants — must match btc-vault / babe::wots\n// ---------------------------------------------------------------------------\n\n/** Size in bytes of the parent key or derived key (first half of 64-byte seed). */\nconst KEY_SIZE = 32;\n\n/** Size in bytes of the full seed (BIP-39 produces 64 bytes). */\nconst SEED_SIZE = 64;\n\n/** Size of the big-endian length prefix for variable-length fields. */\nconst LENGTH_PREFIX_SIZE = 4;\n\n/** Hash160 output size in bytes (= RIPEMD-160(SHA-256(x))). */\nconst CHAIN_ELEMENT_SIZE = 20;\n\n/** Bits per WOTS digit. Matches `babe::WOTS_DIGIT_BITS`. */\nconst WOTS_DIGIT_BITS = 4;\n\n/** Number of checksum digits in canonical WOTS ordering. */\nconst WOTS_CHECKSUM_DIGITS = 2;\n\n/** Digit index for the checksum minor chain (canonical ordering). */\nconst CHECKSUM_MINOR_DIGIT_INDEX = 0;\n\n/** Digit index for the checksum major chain (canonical ordering). */\nconst CHECKSUM_MAJOR_DIGIT_INDEX = 1;\n\n/**\n * Message digit counts per assert block.\n * Matches `btc_vault::ASSERT_WOTS_BLOCK_DIGIT_COUNTS`.\n */\nconst ASSERT_WOTS_BLOCK_DIGIT_COUNTS: readonly number[] = [64, 64];\n\n// ---------------------------------------------------------------------------\n// Byte utilities\n// ---------------------------------------------------------------------------\n\nfunction concatBytes(...arrays: Uint8Array[]): Uint8Array {\n const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const arr of arrays) {\n result.set(arr, offset);\n offset += arr.length;\n }\n return result;\n}\n\nfunction stringToBytes(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\nfunction lengthPrefixed(data: Uint8Array): Uint8Array {\n const len = new Uint8Array(LENGTH_PREFIX_SIZE);\n new DataView(len.buffer).setUint32(0, data.length, false);\n return concatBytes(len, data);\n}\n\nfunction stripHexPrefix(hex: string): string {\n return hex.startsWith(\"0x\") || hex.startsWith(\"0X\") ? hex.slice(2) : hex;\n}\n\nconst toHex = (bytes: Uint8Array) =>\n Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n\n// ---------------------------------------------------------------------------\n// Cryptographic primitives\n// ---------------------------------------------------------------------------\n\nfunction hmacSha512(key: Uint8Array, data: Uint8Array): Uint8Array {\n return hmac(sha512, key, data);\n}\n\nfunction hash160(data: Uint8Array): Uint8Array {\n return ripemd160(sha256(data));\n}\n\n// ---------------------------------------------------------------------------\n// WOTS chain derivation — mirrors Rust babe::wots\n// ---------------------------------------------------------------------------\n\n/** Maximum value representable by a single WOTS digit: `2^d - 1`. */\nfunction maxDigitValue(d: number): number {\n return (1 << d) - 1;\n}\n\n/**\n * Compute the default checksum radix for a given W_max.\n * Matches Rust `default_checksum_radix(w_max)`.\n */\nfunction defaultChecksumRadix(wMax: number): number {\n let radix = 1;\n while (radix * radix < wMax + 1) radix++;\n return Math.max(radix, 2);\n}\n\n/** Create a WOTS config for a given message digit count. */\nfunction createWotsConfig(n: number): WotsConfig {\n const d = WOTS_DIGIT_BITS;\n const maxVal = maxDigitValue(d);\n const wMax = n * maxVal;\n return { d, n, checksum_radix: defaultChecksumRadix(wMax) };\n}\n\n/**\n * Derive the starting chain value for a given digit index.\n * Matches Rust `chain_start_for_digit(seed, digit_index)`:\n * hash160(seed || varint_le(digit_index))\n */\nfunction chainStartForDigit(seed: Uint8Array, digitIndex: number): Uint8Array {\n const suffixBytes: number[] = [];\n let idx = digitIndex;\n while (idx > 0) {\n suffixBytes.push(idx & 0xff);\n idx >>>= 8;\n }\n const preimage = new Uint8Array(seed.length + suffixBytes.length);\n preimage.set(seed);\n for (let i = 0; i < suffixBytes.length; i++) {\n preimage[seed.length + i] = suffixBytes[i];\n }\n return hash160(preimage);\n}\n\n/**\n * Compute the terminal value of a Hash160 chain of given length.\n * Matches Rust `compute_chain(seed, len)` — returns chain[len].\n */\nfunction computeChainTerminal(start: Uint8Array, steps: number): Uint8Array {\n let current = start;\n for (let i = 0; i < steps; i++) {\n current = hash160(current);\n }\n return current;\n}\n\n// ---------------------------------------------------------------------------\n// Per-block public key derivation\n// ---------------------------------------------------------------------------\n\n/**\n * Derive a single WOTS block public key from a per-block seed.\n */\nfunction deriveBlockPublicKey(\n blockSeed: Uint8Array,\n config: WotsConfig,\n): WotsBlockPublicKey {\n const k = maxDigitValue(config.d);\n const checksumMinorMax = config.checksum_radix - 1;\n const checksumMajorMax = Math.floor((config.n * k) / config.checksum_radix);\n\n // Message chain terminals (digit indices 2..n+2 in canonical order)\n const messageTerminals: number[][] = [];\n for (let digit = 0; digit < config.n; digit++) {\n const start = chainStartForDigit(blockSeed, digit + WOTS_CHECKSUM_DIGITS);\n const terminal = computeChainTerminal(start, k);\n messageTerminals.push(Array.from(terminal));\n }\n\n // Checksum chain terminals\n const checksumMinorStart = chainStartForDigit(\n blockSeed,\n CHECKSUM_MINOR_DIGIT_INDEX,\n );\n const checksumMinorTerminal = computeChainTerminal(\n checksumMinorStart,\n checksumMinorMax,\n );\n\n const checksumMajorStart = chainStartForDigit(\n blockSeed,\n CHECKSUM_MAJOR_DIGIT_INDEX,\n );\n const checksumMajorTerminal = computeChainTerminal(\n checksumMajorStart,\n checksumMajorMax,\n );\n\n return {\n config,\n message_terminals: messageTerminals,\n checksum_major_terminal: Array.from(checksumMajorTerminal),\n checksum_minor_terminal: Array.from(checksumMinorTerminal),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Derive deterministic WOTS block public keys for a specific vault.\n *\n * Produces an array of {@link WotsBlockPublicKey} (one per assert block),\n * matching the Rust `Vec<babe::wots::PublicKey>` format expected by the\n * vault provider's `submitDepositorWotsKey` RPC.\n *\n * The VP expects exactly 2 blocks and validates that keccak256 of the\n * concatenated chain tips matches the on-chain `depositorWotsPkHash`.\n *\n * @param seed - 64-byte seed (e.g. from `mnemonicToWotsSeed`). Zeroed after use.\n * @param vaultId - Vault identifier / pegin tx hash (hex, with or without 0x prefix).\n * @param depositorPk - Depositor's BTC public key (hex, with or without 0x prefix).\n * @param appContractAddress - Application contract address.\n * @returns Array of 2 WOTS block public keys.\n * @throws If seed is not exactly 64 bytes.\n */\nexport async function deriveWotsBlockPublicKeys(\n seed: Uint8Array,\n vaultId: string,\n depositorPk: string,\n appContractAddress: string,\n): Promise<WotsBlockPublicKey[]> {\n if (seed.length !== SEED_SIZE) {\n throw new Error(\n `WOTS seed must be exactly ${SEED_SIZE} bytes, got ${seed.length}`,\n );\n }\n\n const cleanVaultId = stripHexPrefix(vaultId);\n const cleanDepositorPk = stripHexPrefix(depositorPk);\n\n const chainCode = seed.slice(KEY_SIZE, SEED_SIZE);\n const parentKey = seed.slice(0, KEY_SIZE);\n const hmacPreimage = concatBytes(\n parentKey,\n concatBytes(\n lengthPrefixed(stringToBytes(cleanVaultId)),\n lengthPrefixed(stringToBytes(cleanDepositorPk)),\n lengthPrefixed(stringToBytes(stripHexPrefix(appContractAddress))),\n ),\n );\n const hmacResult = hmacSha512(chainCode, hmacPreimage);\n const derivedKey = hmacResult.slice(0, KEY_SIZE);\n\n try {\n const blocks: WotsBlockPublicKey[] = [];\n\n for (\n let blockIdx = 0;\n blockIdx < ASSERT_WOTS_BLOCK_DIGIT_COUNTS.length;\n blockIdx++\n ) {\n const n = ASSERT_WOTS_BLOCK_DIGIT_COUNTS[blockIdx];\n const config = createWotsConfig(n);\n\n // Derive per-block 20-byte seed: hash160(derivedKey || blockIndex)\n const blockSeedInput = new Uint8Array(derivedKey.length + 1);\n blockSeedInput.set(derivedKey);\n blockSeedInput[derivedKey.length] = blockIdx;\n const blockSeed = hash160(blockSeedInput);\n\n try {\n const block = deriveBlockPublicKey(blockSeed, config);\n\n // Runtime validation (Codex review requirement)\n if (block.config.d !== WOTS_DIGIT_BITS) {\n throw new Error(`Block ${blockIdx}: expected d=${WOTS_DIGIT_BITS}, got d=${block.config.d}`);\n }\n if (block.config.n !== n) {\n throw new Error(`Block ${blockIdx}: expected n=${n}, got n=${block.config.n}`);\n }\n if (block.message_terminals.length !== n) {\n throw new Error(`Block ${blockIdx}: expected ${n} message terminals, got ${block.message_terminals.length}`);\n }\n for (let t = 0; t < block.message_terminals.length; t++) {\n if (block.message_terminals[t].length !== CHAIN_ELEMENT_SIZE) {\n throw new Error(`Block ${blockIdx} terminal ${t}: expected ${CHAIN_ELEMENT_SIZE} bytes, got ${block.message_terminals[t].length}`);\n }\n }\n if (block.checksum_minor_terminal.length !== CHAIN_ELEMENT_SIZE) {\n throw new Error(`Block ${blockIdx} checksum_minor: expected ${CHAIN_ELEMENT_SIZE} bytes`);\n }\n if (block.checksum_major_terminal.length !== CHAIN_ELEMENT_SIZE) {\n throw new Error(`Block ${blockIdx} checksum_major: expected ${CHAIN_ELEMENT_SIZE} bytes`);\n }\n\n blocks.push(block);\n } finally {\n blockSeedInput.fill(0);\n blockSeed.fill(0);\n }\n }\n\n if (blocks.length !== ASSERT_WOTS_BLOCK_DIGIT_COUNTS.length) {\n throw new Error(\n `Expected ${ASSERT_WOTS_BLOCK_DIGIT_COUNTS.length} blocks, got ${blocks.length}`,\n );\n }\n\n return blocks;\n } finally {\n hmacPreimage.fill(0);\n chainCode.fill(0);\n parentKey.fill(0);\n hmacResult.fill(0);\n derivedKey.fill(0);\n seed.fill(0);\n }\n}\n\n/** Validate a single chain terminal: correct length and all bytes in [0, 255]. */\nfunction validateTerminal(\n terminal: number[],\n blockIdx: number,\n label: string,\n): void {\n if (terminal.length !== CHAIN_ELEMENT_SIZE) {\n throw new Error(\n `Block ${blockIdx} ${label}: expected ${CHAIN_ELEMENT_SIZE} bytes, got ${terminal.length}`,\n );\n }\n for (let j = 0; j < terminal.length; j++) {\n const b = terminal[j];\n if (!Number.isInteger(b) || b < 0 || b > 255) {\n throw new Error(\n `Block ${blockIdx} ${label}[${j}]: invalid byte value ${b}`,\n );\n }\n }\n}\n\n/**\n * Compute the keccak256 hash of WOTS block public keys.\n *\n * Matches Rust `btc_vault::wots_public_keys_keccak256`: for each block,\n * chain tips are concatenated in canonical order\n * `[checksum_minor, checksum_major, message_terminals...]`, then all\n * blocks are concatenated and hashed.\n *\n * The result is committed on-chain as `depositorWotsPkHash` so the vault\n * provider can verify submitted WOTS public keys.\n *\n * @param publicKeys - Array of WOTS block public keys (must not be empty).\n * @returns 0x-prefixed keccak256 hex string.\n */\nexport function computeWotsBlockPublicKeysHash(\n publicKeys: WotsBlockPublicKey[],\n): Hex {\n if (publicKeys.length === 0) {\n throw new Error(\"Public keys array must not be empty\");\n }\n\n // Validate block structure before hashing to prevent silent zero-padding\n // or byte wrapping from out-of-range number[] values\n for (let i = 0; i < publicKeys.length; i++) {\n const pk = publicKeys[i];\n validateTerminal(pk.checksum_minor_terminal, i, \"checksum_minor_terminal\");\n validateTerminal(pk.checksum_major_terminal, i, \"checksum_major_terminal\");\n for (let t = 0; t < pk.message_terminals.length; t++) {\n validateTerminal(pk.message_terminals[t], i, `message_terminal[${t}]`);\n }\n }\n\n let totalTips = 0;\n for (const pk of publicKeys) {\n totalTips += WOTS_CHECKSUM_DIGITS + pk.message_terminals.length;\n }\n\n const buffer = new Uint8Array(totalTips * CHAIN_ELEMENT_SIZE);\n let offset = 0;\n\n for (const pk of publicKeys) {\n // Canonical order: checksum_minor, checksum_major, then message terminals\n buffer.set(pk.checksum_minor_terminal, offset);\n offset += CHAIN_ELEMENT_SIZE;\n buffer.set(pk.checksum_major_terminal, offset);\n offset += CHAIN_ELEMENT_SIZE;\n for (const terminal of pk.message_terminals) {\n buffer.set(terminal, offset);\n offset += CHAIN_ELEMENT_SIZE;\n }\n }\n\n const digest = keccak_256(buffer);\n return `0x${toHex(digest)}`;\n}\n","import { computeWotsPkHash, deriveWotsKeypair, mnemonicToWotsSeed } from \"./derivation\";\n\n/**\n * Convenience wrapper: derive a WOTS keypair from a mnemonic and return\n * the keccak256 hash of its public key. Handles seed creation and cleanup.\n *\n * Used before the ETH transaction to produce the `depositorWotsPkHash`\n * that gets committed on-chain.\n */\nexport async function deriveWotsPkHash(\n mnemonic: string,\n peginTxid: string,\n depositorBtcPubkey: string,\n appContractAddress: string,\n): Promise<`0x${string}`> {\n const seed = mnemonicToWotsSeed(mnemonic);\n try {\n const keypair = await deriveWotsKeypair(\n seed,\n peginTxid,\n depositorBtcPubkey,\n appContractAddress,\n );\n try {\n return computeWotsPkHash(keypair);\n } finally {\n for (const p of keypair.falsePreimages) p.fill(0);\n for (const p of keypair.truePreimages) p.fill(0);\n }\n } finally {\n seed.fill(0);\n }\n}\n","/**\n * Check whether an error from the vault provider indicates that the\n * submitted WOTS public key hash does not match the on-chain\n * commitment. This signals that the wrong mnemonic was used.\n */\nexport function isWotsMismatchError(error: unknown): boolean {\n const msg = (\n error instanceof Error\n ? error.message\n : typeof error === \"string\"\n ? error\n : \"\"\n ).toLowerCase();\n\n return (\n msg.includes(\"wots\") &&\n msg.includes(\"hash\") &&\n msg.includes(\"does not match\")\n );\n}\n"],"names":["CONTRACT_ERRORS","extractErrorData","error","err","current","depth","maxDepth","cause","hexMatch","getContractErrorMessage","errorData","selector","isKnownContractError","handleContractError","knownError","errorMsg","errorHint","NO_REFERRAL_CODE","HEX_SIGNATURE_REGEX","UNPREFIXED_HEX_SIGNATURE_REGEX","BASE64_SIGNATURE_REGEX","normalizeXOnlyPubkey","raw","processPublicKeyToXOnly","normalizePopSignature","bytes","Buffer","resolveUtxoInfo","txid","vout","localPrevouts","apiUrl","local","getUtxoInfo","RECEIPT_TIMEOUT_MS","PeginManager","config","__publicField","params","depositorBtcPubkeyRaw","depositorBtcPubkey","vaultProviderBtcPubkey","stripHexPrefix","vaultKeeperBtcPubkeys","universalChallengerBtcPubkeys","numLocalChallengers","prePeginParams","prePeginResult","buildPrePeginPsbt","utxoSelection","selectUtxosForPegin","peginOutputCount","network","getNetwork","fundedPrePeginTxHex","fundPeginTransaction","prePeginTxid","calculateBtcTxHash","peginTxResults","psbtsToSign","signOptions","i","peginTxResult","buildPeginTxFromFundedPrePegin","peginInputPsbtResult","buildPeginInputPsbt","createTaprootScriptPathSignOptions","signedPsbts","perVault","peginInputSignature","extractPeginInputSignature","depositorSignedPeginTxHex","finalizePeginInputPsbt","psbtsHexes","options","signed","cleanHex","tx","Transaction","psbt","Psbt","publicKeyNoCoord","utxoDataPromises","input","utxoData","inputsWithUtxoData","totalInputValue","sum","totalOutputValue","out","impliedFee","MAX_REASONABLE_FEE_SATS","psbtInputFields","getPsbtInputFields","output","signedPsbtHex","signedPsbt","e","inp","signedTxHex","pushTx","unsignedPrePeginTx","depositorSignedPeginTx","vaultProvider","hashlock","htlcVout","depositorPayoutBtcAddress","depositorWotsPkHash","popSignature","depositorEthAddress","isAddressEqual","btcPopSignature","depositorBtcPubkeyHex","ensureHexPrefix","unsignedPrePeginTxHex","payoutScriptPubKey","peginTxHash","derivedVaultIdHex","deriveVaultId","vaultId","publicClient","createPublicClient","http","peginFee","BTCVaultRegistryABI","callData","encodeFunctionData","gasEstimate","ethTxHash","receipt","requests","resolvedPayoutScripts","req","vaultResults","totalFee","batchRequests","zeroAddress","address","walletPubkey","isAddressFromPublicKey","bitcoin","verifyingContract","popMessage","currentBtcPubkey","popBtcPubkey","_HMAC","hash","key","ahash","abytes","blockLen","pad","clean","buf","aexists","to","oHash","iHash","finished","destroyed","outputLen","hmac","message","Rho160","Id160","_","Pi160","idxLR","res","j","k","idxL","idxR","shifts160","shiftsL160","idx","shiftsR160","Kl160","Kr160","ripemd_f","group","x","y","z","BUF_160","_RIPEMD160","HashMD","h0","h1","h2","h3","h4","view","offset","al","ar","bl","br","cl","cr","dl","dr","el","er","rGroup","hbl","hbr","rl","rr","sl","sr","tl","rotl","tr","ripemd160","createHasher","_0n","_1n","_2n","_7n","_256n","_0x71n","SHA3_PI","SHA3_ROTL","_SHA3_IOTA","round","R","t","IOTAS","split","SHA3_IOTA_H","SHA3_IOTA_L","rotlH","h","l","s","rotlBH","rotlSH","rotlL","rotlBL","rotlSL","keccakP","rounds","B","idx1","idx0","B0","B1","Th","Tl","curH","curL","shift","PI","Keccak","suffix","enableXOF","anumber","u32","swap32IfBE","data","state","len","pos","take","bufferOut","aoutput","genKeccak","info","keccak_256","pbkdf2Init","_password","_salt","_opts","opts","checkOpts","c","dkLen","asyncTick","password","kdfInputToBytes","salt","DK","PRF","PRFSalt","pbkdf2Output","prfW","u","pbkdf2","arr","createView","ti","Ti","ui","nfkd","str","normalize","norm","words","psalt","passphrase","mnemonicToSeedSync","mnemonic","sha512","PI_1_BITS","GC_LABEL_SIZE","KEY_SIZE","SEED_SIZE","INDEX_BUFFER_SIZE","LENGTH_PREFIX_SIZE","concatBytes","arrays","totalLength","result","stringToBytes","lengthPrefixed","hmacSha512","hash160","sha256","toHex","b","mnemonicToWotsSeed","seed","copy","deriveWotsKeypair","depositorPk","appContractAddress","chainCode","parentKey","sensitiveBuffers","vaultData","hmacInput","hmacResult","derivedKey","derivedChainCode","falsePreimages","truePreimages","falseHashes","trueHashes","succeeded","bit","falseIndex","trueIndex","falseInput","trueInput","falseHmac","trueHmac","falsePreimage","truePreimage","p","keypairToPublicKey","keypair","computeWotsPkHash","hashSize","totalBytes","buffer","digest","CHAIN_ELEMENT_SIZE","WOTS_DIGIT_BITS","WOTS_CHECKSUM_DIGITS","CHECKSUM_MINOR_DIGIT_INDEX","CHECKSUM_MAJOR_DIGIT_INDEX","ASSERT_WOTS_BLOCK_DIGIT_COUNTS","hex","maxDigitValue","d","defaultChecksumRadix","wMax","radix","createWotsConfig","n","maxVal","chainStartForDigit","digitIndex","suffixBytes","preimage","computeChainTerminal","start","steps","deriveBlockPublicKey","blockSeed","checksumMinorMax","checksumMajorMax","messageTerminals","digit","terminal","checksumMinorStart","checksumMinorTerminal","checksumMajorStart","checksumMajorTerminal","deriveWotsBlockPublicKeys","cleanVaultId","cleanDepositorPk","hmacPreimage","blocks","blockIdx","blockSeedInput","block","validateTerminal","label","computeWotsBlockPublicKeysHash","publicKeys","pk","totalTips","deriveWotsPkHash","peginTxid","isWotsMismatchError","msg"],"mappings":"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","x_google_ignoreList":[2,3,4,5,6]}