@secux/app-btc
Advanced tools
Comparing version 3.2.10 to 3.2.11
@@ -18,2 +18,2 @@ "use strict"; | ||
limitations under the License. | ||
*/var _SecuxPsbt_instances,_SecuxPsbt_data,_SecuxPsbt_coin,_SecuxPsbt_payment,_SecuxPsbt_tx,_SecuxPsbt_isRBF,_SecuxPsbt_paths,_SecuxPsbt_inScripts,_SecuxPsbt_fetchInputScript,_SecuxPsbt_getDataForSig,_SecuxPsbt_extractInput,_SecuxPsbt_estimateVSize,_SecuxPsbt_checkDust,_SecuxPsbt_optimizeByFee,_PsbtTransaction_tx,__classPrivateFieldSet=this&&this.__classPrivateFieldSet||function(receiver,state,value,kind,f){if("m"===kind)throw new TypeError("Private method is not writable");if("a"===kind&&!f)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof state?receiver!==state||!f:!state.has(receiver))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===kind?f.call(receiver,value):f?f.value=value:state.set(receiver,value),value},__classPrivateFieldGet=this&&this.__classPrivateFieldGet||function(receiver,state,kind,f){if("a"===kind&&!f)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof state?receiver!==state||!f:!state.has(receiver))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===kind?f:"a"===kind?f.call(receiver):f?f.value:state.get(receiver)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.SecuxPsbt=void 0;const utils_1=require("bip174/src/lib/utils"),secp256k1=require("secp256k1/elliptic"),hash_js_1=require("hash.js"),bignumber_js_1=require("bignumber.js"),parser_1=require("./parser"),Script=require("./script"),utility_1=require("@secux/utility"),interface_1=require("./interface"),utils_2=require("./utils"),payment_1=require("./payment"),transaction_1=require("./transaction"),coindef_1=require("./coindef"),communication_1=require("@secux/utility/lib/communication"),protocol_transaction_1=require("@secux/protocol-transaction/lib/protocol-transaction"),bip340_1=require("./bip340"),logger=null===utility_1.Logger||void 0===utility_1.Logger?void 0:utility_1.Logger.child({id:"psbt"});class SecuxPsbt{constructor(coin,isRBF=!1,data=new parser_1.Psbtv2(new PsbtTransaction)){_SecuxPsbt_instances.add(this),_SecuxPsbt_data.set(this,void 0),_SecuxPsbt_coin.set(this,void 0),_SecuxPsbt_payment.set(this,void 0),_SecuxPsbt_tx.set(this,void 0),_SecuxPsbt_isRBF.set(this,void 0),_SecuxPsbt_paths.set(this,[]),_SecuxPsbt_inScripts.set(this,{}),__classPrivateFieldSet(this,_SecuxPsbt_data,data,"f"),__classPrivateFieldSet(this,_SecuxPsbt_coin,coin,"f"),__classPrivateFieldSet(this,_SecuxPsbt_payment,(0,utils_2.getPayment)(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f")),"f"),__classPrivateFieldSet(this,_SecuxPsbt_isRBF,isRBF,"f"),__classPrivateFieldSet(this,_SecuxPsbt_tx,__classPrivateFieldGet(this,_SecuxPsbt_data,"f").globalMap.unsignedTx.tx,"f"),coin===interface_1.CoinType.BITCOINCASH&&(__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").version=1)}static FromBuffer(data,coin){const psbtBase=parser_1.Psbtv2.fromBuffer(data,(x=>new PsbtTransaction(x)));return new SecuxPsbt(coin,!1,psbtBase)}AddInput(input){var _a;if(!(0,utility_1.isSupportedCoin)(input.path))throw Error(`ArgumentError: unsupport bip32 path, got "${input.path}"`);const mix1={},mix2={},publickey=(0,utils_2.getPublickey)(input.publickey),script=null!==(_a=input.script)&&void 0!==_a?_a:(0,utils_2.getDefaultScript)(input.path),value=new bignumber_js_1.BigNumber(input.satoshis).toNumber();switch(script){case interface_1.ScriptType.P2PKH:mix1.witnessUtxo={script:__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2pkh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey}).scriptPublickey,value};break;case interface_1.ScriptType.P2SH_P2PKH:const p2pkh=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2pkh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey});mix2.redeemScript=p2pkh.scriptPublickey,mix1.witnessUtxo={script:__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2sh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),p2pkh.redeemHash).scriptPublickey,value};break;case interface_1.ScriptType.P2SH_P2WPKH:const p2wpkh=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2wpkh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey});mix2.redeemScript=p2wpkh.scriptPublickey,mix1.witnessUtxo={script:__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2sh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),p2wpkh.redeemHash).scriptPublickey,value};break;case interface_1.ScriptType.P2WPKH:mix1.witnessUtxo={script:__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2wpkh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey}).scriptPublickey,value};break;case interface_1.ScriptType.P2TR:mix1.witnessUtxo={script:__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2tr(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey}).scriptPublickey,value};break;default:throw Error(`ArgumentError: Invalid ScriptType of input#${__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.length}, got "${interface_1.ScriptType[script]}"`)}if(input.txHex){const tx=transaction_1.Transaction.fromBuffer(Buffer.from(input.txHex,"hex"));if((0,utils_2.getSerializer)(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f")).getId(tx)!==input.hash)throw Error(`UTXO hash for input #${__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.length} doesn't match the hash specified in the prevout`);const out=tx.outs[input.vout];if(!new bignumber_js_1.BigNumber(out.value).eq(input.satoshis))throw Error(`UTXO value for input #${__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.length} doesn't match the value specified in the prevout`);out.script.equals(mix1.witnessUtxo.script)||null==logger||logger.warn(`Input script generation error: ${out.script.toString("hex")}, got "${mix1.witnessUtxo.script}"`)}const data=Object.assign(Object.assign({hash:input.hash,index:input.vout,sequence:__classPrivateFieldGet(this,_SecuxPsbt_isRBF,"f")?4294967293:void 0},mix1),mix2);return __classPrivateFieldGet(this,_SecuxPsbt_data,"f").addInput(data),__classPrivateFieldGet(this,_SecuxPsbt_paths,"f").push(input.path),this}AddInputs(inputs){for(const input of inputs)this.AddInput(input);return this}AddOutput(output){var _a;let out,script,path,value=new bignumber_js_1.BigNumber(output.satoshis).toNumber();if(out=(0,interface_1.isOutuptScriptExtended)(output)){const pk=(0,utils_2.getPublickey)(out.publickey);path=out.path;const scriptType=null!==(_a=out.script)&&void 0!==_a?_a:(0,utils_2.getDefaultScript)(path);let redeemHash,p2sh;switch(scriptType){case interface_1.ScriptType.P2SH_P2WPKH:if(!out.path.startsWith("m/49'/"))throw Error("P2SH(...) should use m/49' path");redeemHash=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2wpkh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey:pk}).redeemHash,p2sh=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2sh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),redeemHash),script=p2sh.scriptPublickey;break;case interface_1.ScriptType.P2SH_P2PKH:if(!out.path.startsWith("m/49'/"))throw Error("P2SH(...) should use m/49' path");redeemHash=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2pkh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey:pk}).redeemHash,p2sh=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2sh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),redeemHash),script=p2sh.scriptPublickey;break;case interface_1.ScriptType.P2PKH:if(!out.path.startsWith("m/44'/"))throw Error("P2PKH should use m/44' path");script=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2pkh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey:pk}).scriptPublickey;break;case interface_1.ScriptType.P2WPKH:if(!out.path.startsWith("m/84'/"))throw Error("P2WPKH should use m/84' path");script=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2wpkh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey:pk}).scriptPublickey;break;case interface_1.ScriptType.P2TR:if(!out.path.startsWith("m/86'/"))throw Error("P2TR should use m/86' path");script=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2tr(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey:pk}).scriptPublickey;break;default:throw Error(`ArgumentError: Invalid ScriptType of output#${__classPrivateFieldGet(this,_SecuxPsbt_data,"f").outputs.length}, got "${interface_1.ScriptType[scriptType]}"`)}}else if(out=(0,interface_1.isOutputAddress)(output))script=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").decode(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),out.address);else{if(!(out=(0,interface_1.isOutuptScript)(output)))throw Error("Invalid parameter of output");script=Buffer.from(out.scriptHex,"hex")}return __classPrivateFieldGet(this,_SecuxPsbt_data,"f").addOutput({script,value,path}),this}AddOutputs(outputs){for(const output of outputs)this.AddOutput(output);return this}PrepareSign(feeRate){feeRate&&__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_optimizeByFee).call(this,feeRate,__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs.length-1),__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_checkDust).call(this,!!feeRate);const outConfirm=Buffer.from([__classPrivateFieldGet(this,_SecuxPsbt_data,"f").outputs.length,...(0,utility_1.BigIntToBuffer)(__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs[0].value,8),__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs[0].script.length,...__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs[0].script,...__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs.slice(1).reduce(((data,out)=>[...data,...(0,utility_1.BigIntToBuffer)(out.value,8),...(0,utility_1.buildPathBuffer)(out.path).pathBuffer]),[])]),txs=__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.map(((_,i)=>{const data=__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_getDataForSig).call(this,i);if(null==logger||logger.debug(`tx data [${i}]: ${data.toString("hex")}`),data.length+communication_1.MAX_HEAD_SIZE>communication_1.ONESIGN_THRESHOLD)throw Error("ArgumentError: utxo exceed maximum payload size");return data}));null==logger||logger.debug(`confirm data: ${outConfirm.toString("hex")}`);const commands=[];let _txs=[],_paths=[],confirmBuf=__classPrivateFieldGet(this,_SecuxPsbt_coin,"f")!==interface_1.CoinType.BITCOINCASH&&__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_fetchInputScript).call(this,0).type===interface_1.ScriptType.P2PKH?Buffer.alloc(0):outConfirm;for(let i=0,size=0;i<txs.length;i++){if(size+=txs[i].length+communication_1.MAX_HEAD_SIZE,_txs.push(txs[i]),_paths.push(__classPrivateFieldGet(this,_SecuxPsbt_paths,"f")[i]),size+confirmBuf.length<communication_1.ONESIGN_THRESHOLD)continue;_txs.pop(),_paths.pop(),commands.push(protocol_transaction_1.SecuxTransactionTool.signRawTransactionList(_paths,_txs,confirmBuf)),size=txs[i].length+25,_txs=[txs[i]],_paths=[__classPrivateFieldGet(this,_SecuxPsbt_paths,"f")[i]];const{type}=__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_fetchInputScript).call(this,i);confirmBuf=__classPrivateFieldGet(this,_SecuxPsbt_coin,"f")!==interface_1.CoinType.BITCOINCASH&&type===interface_1.ScriptType.P2PKH?Buffer.alloc(0):outConfirm}return _txs.length>0&&commands.push(protocol_transaction_1.SecuxTransactionTool.signRawTransactionList(_paths,_txs,confirmBuf)),{commands,rawTx:__classPrivateFieldGet(this,_SecuxPsbt_data,"f").toHex()}}appendSignature(signatures,publickeys){var _a,_b;if(signatures.length!==publickeys.length)throw Error(`ArgumentError: each signature is correspond to one publickey, got ${signatures.length} signatures and ${publickeys.length} publickeys`);for(let i=0;i<__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.length;i++){const data=__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_getDataForSig).call(this,i);if(__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_fetchInputScript).call(this,i).type!==interface_1.ScriptType.P2TR){const hash=__classPrivateFieldGet(this,_SecuxPsbt_coin,"f")===interface_1.CoinType.GROESTL?Buffer.from((0,hash_js_1.sha256)().update(data).digest()):Buffer.from((0,hash_js_1.sha256)().update((0,hash_js_1.sha256)().update(data).digest()).digest()),publickey=publickeys[i];if(!secp256k1.ecdsaVerify(signatures[i],hash,publickey))throw Error(`Signature Error #${i}`);let sighashType=null!==(_a=__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs[i].sighashType)&&void 0!==_a?_a:transaction_1.Transaction.SIGHASH_ALL;__classPrivateFieldGet(this,_SecuxPsbt_coin,"f")===interface_1.CoinType.BITCOINCASH&&(sighashType|=64);const partialSig=[{pubkey:publickey,signature:Script.encode(signatures[i],sighashType)}];__classPrivateFieldGet(this,_SecuxPsbt_data,"f").updateInput(i,{partialSig})}else{const hash=(0,utils_2.taggedHash)("TapSighash",data),tweaked=(0,utils_2.toTweakedPublickey)(publickeys[i]),signature=signatures[i].slice(0,64);if(!(0,bip340_1.taprootVerify)(signature,hash,tweaked))throw Error(`Signature Error #${i}`);const sighashType=null!==(_b=__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs[i].sighashType)&&void 0!==_b?_b:transaction_1.Transaction.SIGHASH_DEFAULT;__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs[i].partialSig=[{pubkey:tweaked,signature:sighashType===transaction_1.Transaction.SIGHASH_DEFAULT?signature:Buffer.from([sighashType,...signature])}]}}return this}finalizeAllInputs(){if(__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.length<1)throw Error("utxo input cannot be empty");return __classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.forEach(((input,idx)=>{(0,utils_1.checkForInput)(__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs,idx);const{script,scriptType}=getScriptFromInput(input,__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"));if(!script)throw new Error(`No script found for input #${idx}`);if(input.sighashType&&input.partialSig){const{partialSig,sighashType}=input;for(const sig of partialSig){const{hashType}=Script.decode(sig.signature);if(hashType!==sighashType)throw new Error("Signature sighash does not match input sighash type")}}const{finalScriptSig,finalScriptWitness}=function(scriptType,partialSig){let finalScriptSig,finalScriptWitness;const{signature,pubkey}=partialSig[0];switch(scriptType){case interface_1.ScriptType.P2PKH:finalScriptSig=Script.compile([signature,pubkey]);break;case interface_1.ScriptType.P2SH_P2PKH:finalScriptSig=(()=>{const input=Script.compile([signature,pubkey]),chunks=Script.decompile(input),redeem={output:chunks[chunks.length-1],input:Script.compile(chunks.slice(0,-1))};return Script.compile([].concat(Script.decompile(redeem.input),redeem.output))})();break;case interface_1.ScriptType.P2SH_P2WPKH:finalScriptWitness=(0,utils_2.witnessStackToScriptWitness)([signature,pubkey]),finalScriptSig=(()=>{const input=Buffer.alloc(0),hash=(0,payment_1.Hash160)(pubkey),output=Script.compile([coindef_1.OPCODES.OP_0,hash]);return Script.compile([].concat(Script.decompile(input),output))})();break;case interface_1.ScriptType.P2WPKH:finalScriptWitness=(0,utils_2.witnessStackToScriptWitness)([signature,pubkey]);break;case interface_1.ScriptType.P2TR:finalScriptWitness=signature}return{finalScriptSig,finalScriptWitness}}(scriptType,input.partialSig);if(finalScriptSig&&__classPrivateFieldGet(this,_SecuxPsbt_data,"f").updateInput(idx,{finalScriptSig}),finalScriptWitness&&__classPrivateFieldGet(this,_SecuxPsbt_data,"f").updateInput(idx,{finalScriptWitness}),!finalScriptSig&&!finalScriptWitness)throw new Error(`Unknown error finalizing input #${idx}`)})),this}extractTransaction(){const tx=__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").clone();__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.forEach(((input,idx)=>__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_extractInput).call(this,tx,idx,input)));const input=__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.reduce(((sum,txIn)=>sum.plus(txIn.witnessUtxo.value)),new bignumber_js_1.BigNumber(0)),output=tx.outs.reduce(((sum,txOut)=>sum.plus(txOut.value)),new bignumber_js_1.BigNumber(0)),fee=input.minus(output),minFee=tx.virtualSize();if(fee.lt(minFee))throw Error(`Transaction fee must >= ${minFee}, but got ${fee}.`);return tx}}function getScriptFromInput(input,coin){let script,scriptType;const payment=(0,utils_2.getPayment)(coin);if(input.witnessScript)script=input.witnessScript;else if(input.redeemScript)switch(script=input.redeemScript,scriptType=payment.classify(script),scriptType){case interface_1.ScriptType.P2PKH:scriptType=interface_1.ScriptType.P2SH_P2PKH;break;case interface_1.ScriptType.P2WPKH:scriptType=interface_1.ScriptType.P2SH_P2WPKH}else script=input.witnessUtxo.script,scriptType=payment.classify(script);return{script,scriptType}}exports.SecuxPsbt=SecuxPsbt,_SecuxPsbt_data=new WeakMap,_SecuxPsbt_coin=new WeakMap,_SecuxPsbt_payment=new WeakMap,_SecuxPsbt_tx=new WeakMap,_SecuxPsbt_isRBF=new WeakMap,_SecuxPsbt_paths=new WeakMap,_SecuxPsbt_inScripts=new WeakMap,_SecuxPsbt_instances=new WeakSet,_SecuxPsbt_fetchInputScript=function(index){if(__classPrivateFieldGet(this,_SecuxPsbt_inScripts,"f")[index])return __classPrivateFieldGet(this,_SecuxPsbt_inScripts,"f")[index];const txIn=__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs[index],prevout=txIn.witnessUtxo,type=getScriptFromInput(txIn,__classPrivateFieldGet(this,_SecuxPsbt_coin,"f")).scriptType,scriptPubkey=function(script,scriptType,redeemScript){let meaningfulScript;switch(scriptType){case interface_1.ScriptType.P2SH_P2PKH:case interface_1.ScriptType.P2SH_P2WPKH:if(!redeemScript)throw Error("scriptPubkey is P2SH but redeemScript missing");meaningfulScript=redeemScript;break;default:meaningfulScript=script}if(!meaningfulScript)throw Error("cannot extract script");return meaningfulScript}(prevout.script,type,txIn.redeemScript);null==logger||logger.debug(`input #${index} script type: ${interface_1.ScriptType[type]}`),null==logger||logger.debug(`script: ${scriptPubkey.toString("hex")}`);const obj={type,scriptPubkey};return __classPrivateFieldGet(this,_SecuxPsbt_inScripts,"f")[index]=obj,obj},_SecuxPsbt_getDataForSig=function(inputIndex){var _a,_b;const txIn=__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs[inputIndex],unsignedTx=__classPrivateFieldGet(this,_SecuxPsbt_tx,"f");let sighashType=null!==(_a=txIn.sighashType)&&void 0!==_a?_a:transaction_1.Transaction.SIGHASH_ALL;const serializer=(0,utils_2.getSerializer)(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"));void 0===txIn.witnessUtxo&&Error("Need a Utxo input item for signing");const prevout=txIn.witnessUtxo,{type,scriptPubkey}=__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_fetchInputScript).call(this,inputIndex);let data;switch(type){case interface_1.ScriptType.P2WPKH:case interface_1.ScriptType.P2SH_P2WPKH:case interface_1.ScriptType.P2SH_P2PKH:null==logger||logger.debug(interface_1.ScriptType[type]);const signingScript=(0,utils_2.getPayment)(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f")).p2pkh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{hash:scriptPubkey.slice(2)}).scriptPublickey;data=serializer.dataForWitnessV0(unsignedTx,inputIndex,signingScript,prevout.value,sighashType);break;case interface_1.ScriptType.P2TR:null==logger||logger.debug("p2tr"),sighashType=null!==(_b=txIn.sighashType)&&void 0!==_b?_b:transaction_1.Transaction.SIGHASH_DEFAULT,data=serializer.dataForWitnessV1(unsignedTx,inputIndex,__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.map(((_,i)=>__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_fetchInputScript).call(this,i).scriptPubkey)),__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.map((x=>x.witnessUtxo.value)),sighashType);break;default:__classPrivateFieldGet(this,_SecuxPsbt_coin,"f")===interface_1.CoinType.BITCOINCASH?(null==logger||logger.debug("bch using bip143"),data=serializer.dataForWitnessV0(unsignedTx,inputIndex,scriptPubkey,prevout.value,64|sighashType)):(null==logger||logger.debug("non-segwit"),data=serializer.dataForSignature(unsignedTx,inputIndex,scriptPubkey,sighashType))}return data},_SecuxPsbt_extractInput=function(tx,index,_){if(!_.finalScriptSig&&!_.finalScriptWitness)throw Error(`input#${index} not finalized.`);_.finalScriptSig&&(tx.ins[index].script=_.finalScriptSig),_.finalScriptWitness&&(__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_fetchInputScript).call(this,index).type!==interface_1.ScriptType.P2TR?tx.ins[index].witness=(0,utils_2.scriptWitnessToWitnessStack)(_.finalScriptWitness):tx.ins[index].witness=[_.finalScriptWitness])},_SecuxPsbt_estimateVSize=function(){const txForFee=__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").clone();let scriptSize=0,witnessSize=2;return __classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.forEach(((txIn,i)=>{const{type}=__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_fetchInputScript).call(this,i);scriptSize+=(0,utils_2.getInScriptSize)(type);const witness=(0,utils_2.getWitnessSize)(type,txIn.sighashType);witnessSize+=(0,utils_2.vectorSize)(witness)})),txForFee.virtualSize()+scriptSize+witnessSize/4},_SecuxPsbt_checkDust=function(throwError){let error;for(let i=0;i<__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs.length;i++){const{script,value}=__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs[i],type=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").isP2SH(script)?interface_1.ScriptType.P2SH_P2WPKH:__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").classify(script),dust=(0,utils_2.getDustThreshold)(type,3),_value=(0,bignumber_js_1.BigNumber)(value);_value.lt(dust)&&(null==logger||logger.warn(`output #${i}: dust threshold is ${dust}, but got ${_value.toFixed(0)}`),error||(error=Error("Transaction has output below a certain value (Dust).")))}if(throwError&&error)throw error},_SecuxPsbt_optimizeByFee=function(feeRate,changeIndex=0){const vSize=__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_estimateVSize).call(this),estimateFee=Math.round(vSize*feeRate);null==logger||logger.info(`Estimated fee is ${estimateFee}, with ${feeRate} fee rates.`);const total=__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.reduce(((a,txIn)=>a+txIn.witnessUtxo.value),0),spend=__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs.reduce(((a,txOut)=>a+txOut.value),0),actualFee=total-spend;if(actualFee<estimateFee&&(null==logger||logger.warn(`Estimated fee is ${estimateFee}, but got ${actualFee}.`)),actualFee>estimateFee||actualFee<vSize){const change=__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs[changeIndex].value,value=actualFee-estimateFee;if(value<0)throw Error(`Insufficient amount, expect ${spend+estimateFee}, but got ${total}.`);__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs[changeIndex].value=value,null==logger||logger.info(`Modify output#${changeIndex} amount from ${change} to ${value}.`)}};class PsbtTransaction{constructor(buffer=Buffer.from([2,0,0,0,0,0,0,0,0,0])){_PsbtTransaction_tx.set(this,void 0),__classPrivateFieldSet(this,_PsbtTransaction_tx,transaction_1.Transaction.fromBuffer(buffer),"f")}getInputOutputCounts(){return{inputCount:__classPrivateFieldGet(this,_PsbtTransaction_tx,"f").ins.length,outputCount:__classPrivateFieldGet(this,_PsbtTransaction_tx,"f").outs.length}}addInput(input){if(void 0===input.hash||void 0===input.index||!Buffer.isBuffer(input.hash)&&"string"!=typeof input.hash||"number"!=typeof input.index)throw new Error("Error adding input.");const hash="string"==typeof input.hash?Buffer.from(Buffer.from(input.hash,"hex").reverse()):input.hash;__classPrivateFieldGet(this,_PsbtTransaction_tx,"f").addInput(hash,input.index,input.sequence)}addOutput(output){if(void 0===output.script||void 0===output.value||!Buffer.isBuffer(output.script)||"number"!=typeof output.value)throw new Error("Error adding output.");__classPrivateFieldGet(this,_PsbtTransaction_tx,"f").addOutput(output.script,output.value,output.path)}toBuffer(){return __classPrivateFieldGet(this,_PsbtTransaction_tx,"f").toBuffer()}get tx(){return __classPrivateFieldGet(this,_PsbtTransaction_tx,"f")}}_PsbtTransaction_tx=new WeakMap; | ||
*/var _SecuxPsbt_instances,_SecuxPsbt_data,_SecuxPsbt_coin,_SecuxPsbt_payment,_SecuxPsbt_tx,_SecuxPsbt_isRBF,_SecuxPsbt_paths,_SecuxPsbt_inScripts,_SecuxPsbt_fetchInputScript,_SecuxPsbt_getDataForSig,_SecuxPsbt_extractInput,_SecuxPsbt_estimateVSize,_SecuxPsbt_checkDust,_SecuxPsbt_checkSighashType,_SecuxPsbt_modifyByFee,_PsbtTransaction_tx,__classPrivateFieldSet=this&&this.__classPrivateFieldSet||function(receiver,state,value,kind,f){if("m"===kind)throw new TypeError("Private method is not writable");if("a"===kind&&!f)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof state?receiver!==state||!f:!state.has(receiver))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===kind?f.call(receiver,value):f?f.value=value:state.set(receiver,value),value},__classPrivateFieldGet=this&&this.__classPrivateFieldGet||function(receiver,state,kind,f){if("a"===kind&&!f)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof state?receiver!==state||!f:!state.has(receiver))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===kind?f:"a"===kind?f.call(receiver):f?f.value:state.get(receiver)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.SecuxPsbt=void 0;const utils_1=require("bip174/src/lib/utils"),secp256k1=require("secp256k1/elliptic"),hash_js_1=require("hash.js"),bignumber_js_1=require("bignumber.js"),parser_1=require("./parser"),Script=require("./script"),utility_1=require("@secux/utility"),interface_1=require("./interface"),utils_2=require("./utils"),payment_1=require("./payment"),transaction_1=require("./transaction"),coindef_1=require("./coindef"),communication_1=require("@secux/utility/lib/communication"),protocol_transaction_1=require("@secux/protocol-transaction/lib/protocol-transaction"),bip340_1=require("./bip340"),logger=null===utility_1.Logger||void 0===utility_1.Logger?void 0:utility_1.Logger.child({id:"psbt"});class SecuxPsbt{constructor(coin,isRBF=!1,data=new parser_1.Psbtv2(new PsbtTransaction)){_SecuxPsbt_instances.add(this),_SecuxPsbt_data.set(this,void 0),_SecuxPsbt_coin.set(this,void 0),_SecuxPsbt_payment.set(this,void 0),_SecuxPsbt_tx.set(this,void 0),_SecuxPsbt_isRBF.set(this,void 0),_SecuxPsbt_paths.set(this,[]),_SecuxPsbt_inScripts.set(this,{}),__classPrivateFieldSet(this,_SecuxPsbt_data,data,"f"),__classPrivateFieldSet(this,_SecuxPsbt_coin,coin,"f"),__classPrivateFieldSet(this,_SecuxPsbt_payment,(0,utils_2.getPayment)(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f")),"f"),__classPrivateFieldSet(this,_SecuxPsbt_isRBF,isRBF,"f"),__classPrivateFieldSet(this,_SecuxPsbt_tx,__classPrivateFieldGet(this,_SecuxPsbt_data,"f").globalMap.unsignedTx.tx,"f"),coin===interface_1.CoinType.BITCOINCASH&&(__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").version=1)}static FromBuffer(data,coin){const psbtBase=parser_1.Psbtv2.fromBuffer(data,(x=>new PsbtTransaction(x)));return new SecuxPsbt(coin,!1,psbtBase)}AddInput(input){var _a;if(!(0,utility_1.isSupportedCoin)(input.path))throw Error(`ArgumentError: unsupport bip32 path, got "${input.path}"`);const mix1={},mix2={},publickey=(0,utils_2.getPublickey)(input.publickey),script=null!==(_a=input.script)&&void 0!==_a?_a:(0,utils_2.getDefaultScript)(input.path),value=new bignumber_js_1.BigNumber(input.satoshis).toNumber();switch(script){case interface_1.ScriptType.P2PKH:mix1.witnessUtxo={script:__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2pkh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey}).scriptPublickey,value};break;case interface_1.ScriptType.P2SH_P2PKH:const p2pkh=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2pkh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey});mix2.redeemScript=p2pkh.scriptPublickey,mix1.witnessUtxo={script:__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2sh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),p2pkh.redeemHash).scriptPublickey,value};break;case interface_1.ScriptType.P2SH_P2WPKH:const p2wpkh=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2wpkh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey});mix2.redeemScript=p2wpkh.scriptPublickey,mix1.witnessUtxo={script:__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2sh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),p2wpkh.redeemHash).scriptPublickey,value};break;case interface_1.ScriptType.P2WPKH:mix1.witnessUtxo={script:__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2wpkh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey}).scriptPublickey,value};break;case interface_1.ScriptType.P2TR:mix1.witnessUtxo={script:__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2tr(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey}).scriptPublickey,value},mix2.sighashType=transaction_1.Transaction.SIGHASH_ALL|transaction_1.Transaction.SIGHASH_ANYONECANPAY;break;default:throw Error(`ArgumentError: Invalid ScriptType of input#${__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.length}, got "${interface_1.ScriptType[script]}"`)}if(input.txHex){const tx=transaction_1.Transaction.fromBuffer(Buffer.from(input.txHex,"hex"));if((0,utils_2.getSerializer)(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f")).getId(tx)!==input.hash)throw Error(`UTXO hash for input #${__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.length} doesn't match the hash specified in the prevout`);const out=tx.outs[input.vout];if(!new bignumber_js_1.BigNumber(out.value).eq(input.satoshis))throw Error(`UTXO value for input #${__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.length} doesn't match the value specified in the prevout`);out.script.equals(mix1.witnessUtxo.script)||null==logger||logger.warn(`Input script generation error: ${out.script.toString("hex")}, got "${mix1.witnessUtxo.script}"`)}const data=Object.assign(Object.assign({hash:input.hash,index:input.vout,sequence:__classPrivateFieldGet(this,_SecuxPsbt_isRBF,"f")?4294967293:void 0},mix1),mix2);return __classPrivateFieldGet(this,_SecuxPsbt_data,"f").addInput(data),__classPrivateFieldGet(this,_SecuxPsbt_paths,"f").push(input.path),this}AddInputs(inputs){for(const input of inputs)this.AddInput(input);return this}AddOutput(output){var _a;let out,script,path,value=new bignumber_js_1.BigNumber(output.satoshis).toNumber();if(out=(0,interface_1.isOutuptScriptExtended)(output)){const pk=(0,utils_2.getPublickey)(out.publickey);path=out.path;const scriptType=null!==(_a=out.script)&&void 0!==_a?_a:(0,utils_2.getDefaultScript)(path);let redeemHash,p2sh;switch(scriptType){case interface_1.ScriptType.P2SH_P2WPKH:if(!out.path.startsWith("m/49'/"))throw Error("P2SH(...) should use m/49' path");redeemHash=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2wpkh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey:pk}).redeemHash,p2sh=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2sh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),redeemHash),script=p2sh.scriptPublickey;break;case interface_1.ScriptType.P2SH_P2PKH:if(!out.path.startsWith("m/49'/"))throw Error("P2SH(...) should use m/49' path");redeemHash=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2pkh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey:pk}).redeemHash,p2sh=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2sh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),redeemHash),script=p2sh.scriptPublickey;break;case interface_1.ScriptType.P2PKH:if(!out.path.startsWith("m/44'/"))throw Error("P2PKH should use m/44' path");script=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2pkh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey:pk}).scriptPublickey;break;case interface_1.ScriptType.P2WPKH:if(!out.path.startsWith("m/84'/"))throw Error("P2WPKH should use m/84' path");script=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2wpkh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey:pk}).scriptPublickey;break;case interface_1.ScriptType.P2TR:if(!out.path.startsWith("m/86'/"))throw Error("P2TR should use m/86' path");script=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").p2tr(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{publickey:pk}).scriptPublickey;break;default:throw Error(`ArgumentError: Invalid ScriptType of output#${__classPrivateFieldGet(this,_SecuxPsbt_data,"f").outputs.length}, got "${interface_1.ScriptType[scriptType]}"`)}}else if(out=(0,interface_1.isOutputAddress)(output))script=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").decode(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),out.address);else{if(!(out=(0,interface_1.isOutuptScript)(output)))throw Error("Invalid parameter of output");script=Buffer.from(out.scriptHex,"hex")}return __classPrivateFieldGet(this,_SecuxPsbt_data,"f").addOutput({script,value,path}),this}AddOutputs(outputs){for(const output of outputs)this.AddOutput(output);return this}PrepareSign(feeRate){feeRate&&__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_modifyByFee).call(this,feeRate,__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs.length-1),__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_checkDust).call(this,!!feeRate);const outConfirm=Buffer.from([__classPrivateFieldGet(this,_SecuxPsbt_data,"f").outputs.length,...(0,utility_1.BigIntToBuffer)(__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs[0].value,8),__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs[0].script.length,...__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs[0].script,...__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs.slice(1).reduce(((data,out)=>[...data,...(0,utility_1.BigIntToBuffer)(out.value,8),...(0,utility_1.buildPathBuffer)(out.path).pathBuffer]),[])]),txs=__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.map(((_,i)=>{const data=__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_getDataForSig).call(this,i);if(null==logger||logger.debug(`tx data [${i}]: ${data.toString("hex")}`),data.length+communication_1.MAX_HEAD_SIZE>communication_1.ONESIGN_THRESHOLD)throw Error("ArgumentError: utxo exceed maximum payload size");return data}));null==logger||logger.debug(`confirm data: ${outConfirm.toString("hex")}`);const commands=[];let _txs=[],_paths=[],confirmBuf=__classPrivateFieldGet(this,_SecuxPsbt_coin,"f")!==interface_1.CoinType.BITCOINCASH&&__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_fetchInputScript).call(this,0).type===interface_1.ScriptType.P2PKH?Buffer.alloc(0):outConfirm;for(let i=0,size=0;i<txs.length;i++){if(size+=txs[i].length+communication_1.MAX_HEAD_SIZE,_txs.push(txs[i]),_paths.push(__classPrivateFieldGet(this,_SecuxPsbt_paths,"f")[i]),size+confirmBuf.length<communication_1.ONESIGN_THRESHOLD)continue;_txs.pop(),_paths.pop(),commands.push(protocol_transaction_1.SecuxTransactionTool.signRawTransactionList(_paths,_txs,confirmBuf)),size=txs[i].length+25,_txs=[txs[i]],_paths=[__classPrivateFieldGet(this,_SecuxPsbt_paths,"f")[i]];const{type}=__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_fetchInputScript).call(this,i);confirmBuf=__classPrivateFieldGet(this,_SecuxPsbt_coin,"f")!==interface_1.CoinType.BITCOINCASH&&type===interface_1.ScriptType.P2PKH?Buffer.alloc(0):outConfirm}return _txs.length>0&&commands.push(protocol_transaction_1.SecuxTransactionTool.signRawTransactionList(_paths,_txs,confirmBuf)),{commands,rawTx:__classPrivateFieldGet(this,_SecuxPsbt_data,"f").toHex()}}appendSignature(signatures,publickeys){var _a,_b;if(signatures.length!==publickeys.length)throw Error(`ArgumentError: each signature is correspond to one publickey, got ${signatures.length} signatures and ${publickeys.length} publickeys`);for(let i=0;i<__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.length;i++){const data=__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_getDataForSig).call(this,i);if(__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_fetchInputScript).call(this,i).type!==interface_1.ScriptType.P2TR){const hash=__classPrivateFieldGet(this,_SecuxPsbt_coin,"f")===interface_1.CoinType.GROESTL?Buffer.from((0,hash_js_1.sha256)().update(data).digest()):Buffer.from((0,hash_js_1.sha256)().update((0,hash_js_1.sha256)().update(data).digest()).digest()),publickey=publickeys[i];if(!secp256k1.ecdsaVerify(signatures[i],hash,publickey))throw Error(`Signature Error #${i}`);let sighashType=null!==(_a=__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs[i].sighashType)&&void 0!==_a?_a:transaction_1.Transaction.SIGHASH_ALL;__classPrivateFieldGet(this,_SecuxPsbt_coin,"f")===interface_1.CoinType.BITCOINCASH&&(sighashType|=64);const partialSig=[{pubkey:publickey,signature:Script.encode(signatures[i],sighashType)}];__classPrivateFieldGet(this,_SecuxPsbt_data,"f").updateInput(i,{partialSig})}else{const hash=(0,utils_2.taggedHash)("TapSighash",data),tweaked=(0,utils_2.toTweakedPublickey)(publickeys[i]),signature=signatures[i].slice(0,64);if(!(0,bip340_1.taprootVerify)(signature,hash,tweaked))throw Error(`Signature Error #${i}`);const sighashType=null!==(_b=__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs[i].sighashType)&&void 0!==_b?_b:transaction_1.Transaction.SIGHASH_DEFAULT;__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs[i].partialSig=[{pubkey:tweaked,signature:sighashType===transaction_1.Transaction.SIGHASH_DEFAULT?signature:Buffer.from([...signature,sighashType])}]}}return this}finalizeAllInputs(){if(__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.length<1)throw Error("utxo input cannot be empty");return __classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.forEach(((input,idx)=>{(0,utils_1.checkForInput)(__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs,idx);const{script,scriptType}=getScriptFromInput(input,__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"));if(!script)throw new Error(`No script found for input #${idx}`);__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_checkSighashType).call(this,input,scriptType);const{finalScriptSig,finalScriptWitness}=function(scriptType,partialSig){let finalScriptSig,finalScriptWitness;const{signature,pubkey}=partialSig[0];switch(scriptType){case interface_1.ScriptType.P2PKH:finalScriptSig=Script.compile([signature,pubkey]);break;case interface_1.ScriptType.P2SH_P2PKH:finalScriptSig=(()=>{const input=Script.compile([signature,pubkey]),chunks=Script.decompile(input),redeem={output:chunks[chunks.length-1],input:Script.compile(chunks.slice(0,-1))};return Script.compile([].concat(Script.decompile(redeem.input),redeem.output))})();break;case interface_1.ScriptType.P2SH_P2WPKH:finalScriptWitness=(0,utils_2.witnessStackToScriptWitness)([signature,pubkey]),finalScriptSig=(()=>{const input=Buffer.alloc(0),hash=(0,payment_1.Hash160)(pubkey),output=Script.compile([coindef_1.OPCODES.OP_0,hash]);return Script.compile([].concat(Script.decompile(input),output))})();break;case interface_1.ScriptType.P2WPKH:finalScriptWitness=(0,utils_2.witnessStackToScriptWitness)([signature,pubkey]);break;case interface_1.ScriptType.P2TR:finalScriptWitness=signature}return{finalScriptSig,finalScriptWitness}}(scriptType,input.partialSig);if(finalScriptSig&&__classPrivateFieldGet(this,_SecuxPsbt_data,"f").updateInput(idx,{finalScriptSig}),finalScriptWitness&&__classPrivateFieldGet(this,_SecuxPsbt_data,"f").updateInput(idx,{finalScriptWitness}),!finalScriptSig&&!finalScriptWitness)throw new Error(`Unknown error finalizing input #${idx}`)})),this}extractTransaction(){const tx=__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").clone();__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.forEach(((input,idx)=>__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_extractInput).call(this,tx,idx,input)));const input=__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.reduce(((sum,txIn)=>sum.plus(txIn.witnessUtxo.value)),new bignumber_js_1.BigNumber(0)),output=tx.outs.reduce(((sum,txOut)=>sum.plus(txOut.value)),new bignumber_js_1.BigNumber(0)),fee=input.minus(output),minFee=tx.virtualSize();if(fee.lt(minFee))throw Error(`Transaction fee must >= ${minFee}, but got ${fee}.`);return tx}}function getScriptFromInput(input,coin){let script,scriptType;const payment=(0,utils_2.getPayment)(coin);if(input.witnessScript)script=input.witnessScript;else if(input.redeemScript)switch(script=input.redeemScript,scriptType=payment.classify(script),scriptType){case interface_1.ScriptType.P2PKH:scriptType=interface_1.ScriptType.P2SH_P2PKH;break;case interface_1.ScriptType.P2WPKH:scriptType=interface_1.ScriptType.P2SH_P2WPKH}else script=input.witnessUtxo.script,scriptType=payment.classify(script);return{script,scriptType}}exports.SecuxPsbt=SecuxPsbt,_SecuxPsbt_data=new WeakMap,_SecuxPsbt_coin=new WeakMap,_SecuxPsbt_payment=new WeakMap,_SecuxPsbt_tx=new WeakMap,_SecuxPsbt_isRBF=new WeakMap,_SecuxPsbt_paths=new WeakMap,_SecuxPsbt_inScripts=new WeakMap,_SecuxPsbt_instances=new WeakSet,_SecuxPsbt_fetchInputScript=function(index){if(__classPrivateFieldGet(this,_SecuxPsbt_inScripts,"f")[index])return __classPrivateFieldGet(this,_SecuxPsbt_inScripts,"f")[index];const txIn=__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs[index],prevout=txIn.witnessUtxo,type=getScriptFromInput(txIn,__classPrivateFieldGet(this,_SecuxPsbt_coin,"f")).scriptType,scriptPubkey=function(script,scriptType,redeemScript){let meaningfulScript;switch(scriptType){case interface_1.ScriptType.P2SH_P2PKH:case interface_1.ScriptType.P2SH_P2WPKH:if(!redeemScript)throw Error("scriptPubkey is P2SH but redeemScript missing");meaningfulScript=redeemScript;break;default:meaningfulScript=script}if(!meaningfulScript)throw Error("cannot extract script");return meaningfulScript}(prevout.script,type,txIn.redeemScript);null==logger||logger.debug(`input #${index} script type: ${interface_1.ScriptType[type]}`),null==logger||logger.debug(`script: ${scriptPubkey.toString("hex")}`);const obj={type,scriptPubkey};return __classPrivateFieldGet(this,_SecuxPsbt_inScripts,"f")[index]=obj,obj},_SecuxPsbt_getDataForSig=function(inputIndex){var _a,_b;const txIn=__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs[inputIndex],unsignedTx=__classPrivateFieldGet(this,_SecuxPsbt_tx,"f");let sighashType=null!==(_a=txIn.sighashType)&&void 0!==_a?_a:transaction_1.Transaction.SIGHASH_ALL;const serializer=(0,utils_2.getSerializer)(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"));void 0===txIn.witnessUtxo&&Error("Need a Utxo input item for signing");const prevout=txIn.witnessUtxo,{type,scriptPubkey}=__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_fetchInputScript).call(this,inputIndex);let data;switch(type){case interface_1.ScriptType.P2WPKH:case interface_1.ScriptType.P2SH_P2WPKH:case interface_1.ScriptType.P2SH_P2PKH:null==logger||logger.debug(interface_1.ScriptType[type]);const signingScript=(0,utils_2.getPayment)(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f")).p2pkh(__classPrivateFieldGet(this,_SecuxPsbt_coin,"f"),{hash:scriptPubkey.slice(2)}).scriptPublickey;data=serializer.dataForWitnessV0(unsignedTx,inputIndex,signingScript,prevout.value,sighashType);break;case interface_1.ScriptType.P2TR:null==logger||logger.debug("p2tr"),sighashType=null!==(_b=txIn.sighashType)&&void 0!==_b?_b:transaction_1.Transaction.SIGHASH_DEFAULT,data=serializer.dataForWitnessV1(unsignedTx,inputIndex,__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.map(((_,i)=>__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_fetchInputScript).call(this,i).scriptPubkey)),__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.map((x=>x.witnessUtxo.value)),sighashType);break;default:__classPrivateFieldGet(this,_SecuxPsbt_coin,"f")===interface_1.CoinType.BITCOINCASH?(null==logger||logger.debug("bch using bip143"),data=serializer.dataForWitnessV0(unsignedTx,inputIndex,scriptPubkey,prevout.value,64|sighashType)):(null==logger||logger.debug("non-segwit"),data=serializer.dataForSignature(unsignedTx,inputIndex,scriptPubkey,sighashType))}return data},_SecuxPsbt_extractInput=function(tx,index,_){if(!_.finalScriptSig&&!_.finalScriptWitness)throw Error(`input#${index} not finalized.`);_.finalScriptSig&&(tx.ins[index].script=_.finalScriptSig),_.finalScriptWitness&&(__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_fetchInputScript).call(this,index).type!==interface_1.ScriptType.P2TR?tx.ins[index].witness=(0,utils_2.scriptWitnessToWitnessStack)(_.finalScriptWitness):tx.ins[index].witness=[_.finalScriptWitness])},_SecuxPsbt_estimateVSize=function(){const txForFee=__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").clone();let scriptSize=0,witnessSize=2;return __classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.forEach(((txIn,i)=>{const{type}=__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_fetchInputScript).call(this,i);scriptSize+=(0,utils_2.getInScriptSize)(type);const witness=(0,utils_2.getWitnessSize)(type,txIn.sighashType);witnessSize+=(0,utils_2.vectorSize)(witness)})),txForFee.virtualSize()+scriptSize+witnessSize/4},_SecuxPsbt_checkDust=function(throwError){let error;for(let i=0;i<__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs.length;i++){const{script,value}=__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs[i],type=__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").isP2SH(script)?interface_1.ScriptType.P2SH_P2WPKH:__classPrivateFieldGet(this,_SecuxPsbt_payment,"f").classify(script),dust=(0,utils_2.getDustThreshold)(type,3),_value=(0,bignumber_js_1.BigNumber)(value);_value.lt(dust)&&(null==logger||logger.warn(`output #${i}: dust threshold is ${dust}, but got ${_value.toFixed(0)}`),error||(error=Error("Transaction has output below a certain value (Dust).")))}if(throwError&&error)throw error},_SecuxPsbt_checkSighashType=function(input,type){if(type===interface_1.ScriptType.P2TR)return;if(!input.sighashType)return;if(!input.partialSig)return;const{partialSig,sighashType}=input;for(const sig of partialSig){const{hashType}=Script.decode(sig.signature);if(hashType!==sighashType)throw Error("Signature sighash does not match input sighash type")}},_SecuxPsbt_modifyByFee=function(feeRate,changeIndex=0){const vSize=__classPrivateFieldGet(this,_SecuxPsbt_instances,"m",_SecuxPsbt_estimateVSize).call(this),estimateFee=Math.round(vSize*feeRate);null==logger||logger.info(`Estimated fee is ${estimateFee}, with ${feeRate} fee rates.`);const actualFee=__classPrivateFieldGet(this,_SecuxPsbt_data,"f").inputs.reduce(((a,txIn)=>a+txIn.witnessUtxo.value),0)-__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs.reduce(((a,txOut)=>a+txOut.value),0);actualFee<estimateFee&&(null==logger||logger.warn(`Estimated fee is ${estimateFee}, but got ${actualFee}.`));const change=__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs[changeIndex].value,modified_change=change+(actualFee-estimateFee);__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs[changeIndex].value=modified_change,null==logger||logger.info(`Modify output#${changeIndex} amount from ${change} to ${modified_change}.`)};class PsbtTransaction{constructor(buffer=Buffer.from([2,0,0,0,0,0,0,0,0,0])){_PsbtTransaction_tx.set(this,void 0),__classPrivateFieldSet(this,_PsbtTransaction_tx,transaction_1.Transaction.fromBuffer(buffer),"f")}getInputOutputCounts(){return{inputCount:__classPrivateFieldGet(this,_PsbtTransaction_tx,"f").ins.length,outputCount:__classPrivateFieldGet(this,_PsbtTransaction_tx,"f").outs.length}}addInput(input){if(void 0===input.hash||void 0===input.index||!Buffer.isBuffer(input.hash)&&"string"!=typeof input.hash||"number"!=typeof input.index)throw new Error("Error adding input.");const hash="string"==typeof input.hash?Buffer.from(Buffer.from(input.hash,"hex").reverse()):input.hash;__classPrivateFieldGet(this,_PsbtTransaction_tx,"f").addInput(hash,input.index,input.sequence)}addOutput(output){if(void 0===output.script||void 0===output.value||!Buffer.isBuffer(output.script)||"number"!=typeof output.value)throw new Error("Error adding output.");__classPrivateFieldGet(this,_PsbtTransaction_tx,"f").addOutput(output.script,output.value,output.path)}toBuffer(){return __classPrivateFieldGet(this,_PsbtTransaction_tx,"f").toBuffer()}get tx(){return __classPrivateFieldGet(this,_PsbtTransaction_tx,"f")}}_PsbtTransaction_tx=new WeakMap; |
{ | ||
"name": "@secux/app-btc", | ||
"version": "3.2.10", | ||
"version": "3.2.11", | ||
"description": "SecuX Hardware Wallet BTC API", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
674157