@secux/app-btc
Advanced tools
Comparing version 3.2.5 to 3.2.6
@@ -15,2 +15,20 @@ /*! | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */ | ||
@@ -17,0 +35,0 @@ |
@@ -0,1 +1,18 @@ | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
/// <reference types="node" /> | ||
@@ -103,2 +120,9 @@ import { communicationData } from "@secux/utility/lib/communication"; | ||
static getVirtualSize(inputs: Array<ScriptType>, outputs: Array<ScriptType>): number; | ||
/** | ||
* Estimate dust threshold of an output. | ||
* @param {ScriptType} output script type of txout | ||
* @param {number} [dustRelayFee] satoshis/vB, default: 3 | ||
* @returns {number} dust threshold | ||
*/ | ||
static getDustThreshold(output: ScriptType, dustRelayFee?: number): number; | ||
} | ||
@@ -105,0 +129,0 @@ /** |
@@ -1,1 +0,18 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.SecuxBTC=exports.ScriptType=exports.CoinType=void 0;const e=require("secp256k1/elliptic"),t=require("varuint-bitcoin"),r=require("@secux/utility"),i=require("@secux/utility/lib/xpub"),o=require("ow"),u=require("@secux/protocol-transaction"),c=require("@secux/utility/lib/communication"),n=require("@secux/protocol-transaction/lib/interface"),s=require("./interface");Object.defineProperty(exports,"CoinType",{enumerable:!0,get:function(){return s.CoinType}}),Object.defineProperty(exports,"ScriptType",{enumerable:!0,get:function(){return s.ScriptType}});const p=require("./psbt"),a=require("./utils");class l{static addressConvert(t,r){const i=(0,a.getPublickey)(t);(0,o.default)(r,o.default.any(s.ow_path,s.ow_PathObject));const u=Buffer.from(e.publicKeyConvert(i,!0)),c="string"==typeof r?(0,a.getCoinType)(r):r.coin,n="string"==typeof r?(0,a.getDefaultScript)(r):r.script,p=(0,a.getPayment)(c);switch(n){case s.ScriptType.P2SH_P2WPKH:const e=p.p2wpkh(c,{publickey:u});return p.p2sh(c,e.redeemHash).address;case s.ScriptType.P2SH_P2PKH:const t=p.p2pkh(c,{publickey:u});return p.p2sh(c,t.redeemHash).address;case s.ScriptType.P2PKH:return p.p2pkh(c,{publickey:u}).address;case s.ScriptType.P2WPKH:return p.p2wpkh(c,{publickey:u}).address;case s.ScriptType.P2TR:return p.p2tr(c,{publickey:u}).address;default:throw Error(`Invalid or unsupported ScriptType, got ${n} of ${c}`)}}static prepareAddress(e,t){return this.preparePublickey(e,t)}static resolveAddress(e,t){const r=l.resolvePublickey(e);return l.addressConvert(r,t)}static preparePublickey(e,t){var i;(0,o.default)(e,s.ow_path),t&&(0,o.default)(t,s.ow_AddressOption);const c=null!==(i=null==t?void 0:t.coin)&&void 0!==i?i:(0,a.getCoinType)(e),p=s.coinmap[c].coinType,l=void 0===(null==t?void 0:t.script)?void 0:(0,a.getPurpose)(null==t?void 0:t.script);return(0,o.default)(e,(0,r.ow_strictPath)(p,l)),u.SecuxTransactionTool.getPublickey(e,n.EllipticCurve.SECP256K1)}static resolvePublickey(e){const t=u.SecuxTransactionTool.resolvePublickey(e,n.EllipticCurve.SECP256K1,!0);return Buffer.from(t,"base64").toString("hex")}static prepareXPublickey(e){return(0,o.default)(e,s.ow_accountPath),u.SecuxTransactionTool.getXPublickey(e)}static resolveXPublickey(e,t){return(0,o.default)(t,s.ow_accountPath),u.SecuxTransactionTool.resolveXPublickey(e,t)}static prepareSign(e,t,i){var u;(0,o.default)(e,o.default.array.ofType(s.ow_txInput).minLength(1)),(0,o.default)(i,o.default.any(o.default.undefined,s.ow_SignOption));const n=null!==(u=null==i?void 0:i.coin)&&void 0!==u?u:(0,a.getCoinType)(e[0].path);(0,o.default)(t,s.ow_txOutput),e.map((e=>{const t=e.script?(0,a.getPurpose)(e.script):s.btcPurposes;(0,o.default)(e.path,(0,r.ow_strictPath)(s.coinmap[n].coinType,t))}));let l=(0,s.isOutuptScriptExtended)(t.to);if(l){const e=l.script?(0,a.getPurpose)(l.script):s.btcPurposes;(0,o.default)(l.path,(0,r.ow_strictPath)(s.coinmap[n].coinType,e))}if(t.utxo){const e=t.utxo.script?(0,a.getPurpose)(t.utxo.script):s.btcPurposes;(0,o.default)(t.utxo.path,(0,r.ow_strictPath)(s.coinmap[n].coinType,e))}const d=new p.SecuxPsbt(n,null==i?void 0:i.isRBF);return d.AddInputs(e),d.AddOutputs(t.utxo?[t.to,t.utxo]:[t.to]),(0,c.wrapResult)(d.PrepareSign(null==i?void 0:i.feeRate))}static resolveSignatureList(e){return u.SecuxTransactionTool.resolveSignatureList(e).map((e=>Buffer.from(e,"base64"))).map((e=>r.Signature.fromSignature(e))).map((e=>Buffer.concat([e.r,e.s]).toString("hex")))}static resolveTransaction(e,t){var r;(0,o.default)(e,o.default.any(c.ow_communicationData,o.default.array.ofType(c.ow_communicationData))),(0,o.default)(t,s.ow_TransactionObject),e=Array.isArray(e)?e:[e];const i=[];for(const t of e){const e=l.resolveSignatureList(t).map((e=>Buffer.from(e,"hex")));i.push(...e)}const u=t.publickeys.map((e=>(0,a.getPublickey)(e)));return p.SecuxPsbt.FromBuffer(Buffer.from(t.rawTx,"hex"),null!==(r=t.coin)&&void 0!==r?r:s.CoinType.BITCOIN).appendSignature(i,u).finalizeAllInputs().extractTransaction().toHex()}static async getAddress(e,t){var r,i;const o=l.prepareAddress(e,t),u=await this.Exchange((0,c.getBuffer)(o));return l.resolveAddress(u,{coin:null!==(r=null==t?void 0:t.coin)&&void 0!==r?r:(0,a.getCoinType)(e),script:null!==(i=null==t?void 0:t.script)&&void 0!==i?i:(0,a.getDefaultScript)(e)})}static async getPublickey(e,t){const r=l.preparePublickey(e,t),i=await this.Exchange((0,c.getBuffer)(r));return l.resolvePublickey(i)}static async getXPublickey(e){const t=l.prepareXPublickey(e),r=await this.Exchange((0,c.getBuffer)(t));return l.resolveXPublickey(r,e)}static async sign(e,t,r){var i,o;const u={},c=async e=>{if(void 0!==u[e])return u[e];const t=await l.getPublickey.call(this,e,{coin:n}),r=Buffer.from(t,"hex");return u[e]=r,r},n=null!==(i=null==r?void 0:r.coin)&&void 0!==i?i:(0,a.getCoinType)(e[0].path);for(const t of e)void 0===t.publickey&&(t.publickey=await c(t.path));t.to.path&&void 0===t.to.publickey&&(t.to.publickey=await c(t.to.path)),(null===(o=t.utxo)||void 0===o?void 0:o.path)&&void 0===t.utxo.publickey&&(t.utxo.publickey=await c(t.utxo.path));const{commands:s,rawTx:p}=l.prepareSign(e,t,Object.assign(Object.assign({},r),{coin:n}));return{multi_command:s,rawTx:p,publickeys:e.map((e=>e.publickey)),coin:n}}static deriveAddress(e,t,r,u){var c,n;(0,o.default)(t,o.default.number.uint8),(0,o.default)(r,o.default.number.uint8),(0,o.default)(u,o.default.any(o.default.undefined,s.ow_AddressOption));const p=(0,i.decodeXPUB)(e);if(3!==p.depth)throw Error(`ArgumentError: expect depth from xpub is 3, but got ${p.depth}`);if(null==u?void 0:u.script)if(u.script in[s.ScriptType.P2PKH,s.ScriptType.P2SH_P2PKH,s.ScriptType.P2SH_P2WPKH,s.ScriptType.P2WPKH]){const e=(0,a.getPurpose)(null==u?void 0:u.script);if(p.purpose!==e)throw Error(`ArgumentError: expect purpose from xpub is ${e}, but got ${p.purpose}`)}else{if(44!==p.purpose)throw Error(`ArgumentError: expect purpose from xpub is 44, but got ${p.purpose}`);p.purpose,(0,a.getPurpose)(null==u?void 0:u.script)}const{publickey:d}=(0,i.deriveKey)(p.publickey,p.chaincode,[t,r]),f=null!==(c=null==u?void 0:u.coin)&&void 0!==c?c:s.CoinType.BITCOIN,y=null!==(n=null==u?void 0:u.script)&&void 0!==n?n:(0,a.getDefaultScript)(`m/${p.purpose}'`);return l.addressConvert(d,{coin:f,script:y})}static getVirtualSize(e,r){const i=8+t.encodingLength(e.length)+t.encodingLength(r.length)+e.reduce(((e,t)=>e+40+(0,a.sliceSize)((0,a.getInScriptSize)(t))),0)+r.reduce(((e,t)=>e+8+(0,a.sliceSize)((0,a.getOutScriptSize)(t))),0),o=e.map((e=>(0,a.getWitnessSize)(e)));return(4*i+(o.some((e=>0!==e.length))?2+o.reduce(((e,t)=>e+(0,a.vectorSize)(t)),0):0))/4}}exports.SecuxBTC=l,(0,r.loadPlugin)(l,"SecuxBTC"); | ||
"use strict"; | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/Object.defineProperty(exports,"__esModule",{value:!0}),exports.SecuxBTC=exports.ScriptType=exports.CoinType=void 0;const secp256k1=require("secp256k1/elliptic"),varuint=require("varuint-bitcoin"),utility_1=require("@secux/utility"),xpub_1=require("@secux/utility/lib/xpub"),ow_1=require("ow"),protocol_transaction_1=require("@secux/protocol-transaction"),communication_1=require("@secux/utility/lib/communication"),interface_1=require("@secux/protocol-transaction/lib/interface"),interface_2=require("./interface");Object.defineProperty(exports,"CoinType",{enumerable:!0,get:function(){return interface_2.CoinType}}),Object.defineProperty(exports,"ScriptType",{enumerable:!0,get:function(){return interface_2.ScriptType}});const psbt_1=require("./psbt"),utils_1=require("./utils");class SecuxBTC{static addressConvert(publickey,path){const pk=(0,utils_1.getPublickey)(publickey);(0,ow_1.default)(path,ow_1.default.any(interface_2.ow_path,interface_2.ow_PathObject));const compressed=Buffer.from(secp256k1.publicKeyConvert(pk,!0)),coin="string"==typeof path?(0,utils_1.getCoinType)(path):path.coin,script="string"==typeof path?(0,utils_1.getDefaultScript)(path):path.script,payment=(0,utils_1.getPayment)(coin);switch(script){case interface_2.ScriptType.P2SH_P2WPKH:const p2wpkh=payment.p2wpkh(coin,{publickey:compressed});return payment.p2sh(coin,p2wpkh.redeemHash).address;case interface_2.ScriptType.P2SH_P2PKH:const p2pkh=payment.p2pkh(coin,{publickey:compressed});return payment.p2sh(coin,p2pkh.redeemHash).address;case interface_2.ScriptType.P2PKH:return payment.p2pkh(coin,{publickey:compressed}).address;case interface_2.ScriptType.P2WPKH:return payment.p2wpkh(coin,{publickey:compressed}).address;case interface_2.ScriptType.P2TR:return payment.p2tr(coin,{publickey:compressed}).address;default:throw Error(`Invalid or unsupported ScriptType, got ${script} of ${coin}`)}}static prepareAddress(path,option){return this.preparePublickey(path,option)}static resolveAddress(response,path){const pk=SecuxBTC.resolvePublickey(response);return SecuxBTC.addressConvert(pk,path)}static preparePublickey(path,option){var _a;(0,ow_1.default)(path,interface_2.ow_path),option&&(0,ow_1.default)(option,interface_2.ow_AddressOption);const coin=null!==(_a=null==option?void 0:option.coin)&&void 0!==_a?_a:(0,utils_1.getCoinType)(path),cointype=interface_2.coinmap[coin].coinType,purpose=void 0===(null==option?void 0:option.script)?void 0:(0,utils_1.getPurpose)(null==option?void 0:option.script);return(0,ow_1.default)(path,(0,utility_1.ow_strictPath)(cointype,purpose)),protocol_transaction_1.SecuxTransactionTool.getPublickey(path,interface_1.EllipticCurve.SECP256K1)}static resolvePublickey(response){const pk=protocol_transaction_1.SecuxTransactionTool.resolvePublickey(response,interface_1.EllipticCurve.SECP256K1,!0);return Buffer.from(pk,"base64").toString("hex")}static prepareXPublickey(path){return(0,ow_1.default)(path,interface_2.ow_accountPath),protocol_transaction_1.SecuxTransactionTool.getXPublickey(path)}static resolveXPublickey(response,path){return(0,ow_1.default)(path,interface_2.ow_accountPath),protocol_transaction_1.SecuxTransactionTool.resolveXPublickey(response,path)}static prepareSign(inputs,outputs,option){var _a;(0,ow_1.default)(inputs,ow_1.default.array.ofType(interface_2.ow_txInput).minLength(1)),(0,ow_1.default)(option,ow_1.default.any(ow_1.default.undefined,interface_2.ow_SignOption));const coin=null!==(_a=null==option?void 0:option.coin)&&void 0!==_a?_a:(0,utils_1.getCoinType)(inputs[0].path);(0,ow_1.default)(outputs,interface_2.ow_txOutput),inputs.map((input=>{const purpose=input.script?(0,utils_1.getPurpose)(input.script):interface_2.btcPurposes;(0,ow_1.default)(input.path,(0,utility_1.ow_strictPath)(interface_2.coinmap[coin].coinType,purpose))}));let _=(0,interface_2.isOutuptScriptExtended)(outputs.to);if(_){const purpose=_.script?(0,utils_1.getPurpose)(_.script):interface_2.btcPurposes;(0,ow_1.default)(_.path,(0,utility_1.ow_strictPath)(interface_2.coinmap[coin].coinType,purpose))}if(outputs.utxo){const purpose=outputs.utxo.script?(0,utils_1.getPurpose)(outputs.utxo.script):interface_2.btcPurposes;(0,ow_1.default)(outputs.utxo.path,(0,utility_1.ow_strictPath)(interface_2.coinmap[coin].coinType,purpose))}const psbt=new psbt_1.SecuxPsbt(coin,null==option?void 0:option.isRBF);return psbt.AddInputs(inputs),psbt.AddOutputs(outputs.utxo?[outputs.to,outputs.utxo]:[outputs.to]),(0,communication_1.wrapResult)(psbt.PrepareSign(null==option?void 0:option.feeRate))}static resolveSignatureList(response){return protocol_transaction_1.SecuxTransactionTool.resolveSignatureList(response).map((x=>Buffer.from(x,"base64"))).map((x=>utility_1.Signature.fromSignature(x))).map((x=>Buffer.concat([x.r,x.s]).toString("hex")))}static resolveTransaction(response,params){var _a;(0,ow_1.default)(response,ow_1.default.any(communication_1.ow_communicationData,ow_1.default.array.ofType(communication_1.ow_communicationData))),(0,ow_1.default)(params,interface_2.ow_TransactionObject),response=Array.isArray(response)?response:[response];const signatures=[];for(const rsp of response){const sigList=SecuxBTC.resolveSignatureList(rsp).map((x=>Buffer.from(x,"hex")));signatures.push(...sigList)}const pks=params.publickeys.map((x=>(0,utils_1.getPublickey)(x)));return psbt_1.SecuxPsbt.FromBuffer(Buffer.from(params.rawTx,"hex"),null!==(_a=params.coin)&&void 0!==_a?_a:interface_2.CoinType.BITCOIN).appendSignature(signatures,pks).finalizeAllInputs().extractTransaction().toHex()}static async getAddress(path,option){var _a,_b;const data=SecuxBTC.prepareAddress(path,option),rsp=await this.Exchange((0,communication_1.getBuffer)(data));return SecuxBTC.resolveAddress(rsp,{coin:null!==(_a=null==option?void 0:option.coin)&&void 0!==_a?_a:(0,utils_1.getCoinType)(path),script:null!==(_b=null==option?void 0:option.script)&&void 0!==_b?_b:(0,utils_1.getDefaultScript)(path)})}static async getPublickey(path,option){const data=SecuxBTC.preparePublickey(path,option),rsp=await this.Exchange((0,communication_1.getBuffer)(data));return SecuxBTC.resolvePublickey(rsp)}static async getXPublickey(path){const data=SecuxBTC.prepareXPublickey(path),rsp=await this.Exchange((0,communication_1.getBuffer)(data));return SecuxBTC.resolveXPublickey(rsp,path)}static async sign(inputs,outputs,option){var _a,_b;const cache={},getPK=async path=>{if(void 0!==cache[path])return cache[path];const publickey=await SecuxBTC.getPublickey.call(this,path,{coin}),pk=Buffer.from(publickey,"hex");return cache[path]=pk,pk},coin=null!==(_a=null==option?void 0:option.coin)&&void 0!==_a?_a:(0,utils_1.getCoinType)(inputs[0].path);for(const txIn of inputs)void 0===txIn.publickey&&(txIn.publickey=await getPK(txIn.path));outputs.to.path&&void 0===outputs.to.publickey&&(outputs.to.publickey=await getPK(outputs.to.path)),(null===(_b=outputs.utxo)||void 0===_b?void 0:_b.path)&&void 0===outputs.utxo.publickey&&(outputs.utxo.publickey=await getPK(outputs.utxo.path));const{commands,rawTx}=SecuxBTC.prepareSign(inputs,outputs,Object.assign(Object.assign({},option),{coin}));return{multi_command:commands,rawTx,publickeys:inputs.map((x=>x.publickey)),coin}}static deriveAddress(xpub,change,addressIndex,option){var _a,_b;(0,ow_1.default)(change,ow_1.default.number.uint8),(0,ow_1.default)(addressIndex,ow_1.default.number.uint8),(0,ow_1.default)(option,ow_1.default.any(ow_1.default.undefined,interface_2.ow_AddressOption));const _xpub=(0,xpub_1.decodeXPUB)(xpub);if(3!==_xpub.depth)throw Error(`ArgumentError: expect depth from xpub is 3, but got ${_xpub.depth}`);if(null==option?void 0:option.script)if(option.script in[interface_2.ScriptType.P2PKH,interface_2.ScriptType.P2SH_P2PKH,interface_2.ScriptType.P2SH_P2WPKH,interface_2.ScriptType.P2WPKH]){const purpose=(0,utils_1.getPurpose)(null==option?void 0:option.script);if(_xpub.purpose!==purpose)throw Error(`ArgumentError: expect purpose from xpub is ${purpose}, but got ${_xpub.purpose}`)}else{if(44!==_xpub.purpose)throw Error(`ArgumentError: expect purpose from xpub is 44, but got ${_xpub.purpose}`);_xpub.purpose,(0,utils_1.getPurpose)(null==option?void 0:option.script)}const{publickey}=(0,xpub_1.deriveKey)(_xpub.publickey,_xpub.chaincode,[change,addressIndex]),coin=null!==(_a=null==option?void 0:option.coin)&&void 0!==_a?_a:interface_2.CoinType.BITCOIN,script=null!==(_b=null==option?void 0:option.script)&&void 0!==_b?_b:(0,utils_1.getDefaultScript)(`m/${_xpub.purpose}'`);return SecuxBTC.addressConvert(publickey,{coin,script})}static getVirtualSize(inputs,outputs){const baseSize=8+varuint.encodingLength(inputs.length)+varuint.encodingLength(outputs.length)+inputs.reduce(((sum,input)=>sum+40+(0,utils_1.sliceSize)((0,utils_1.getInScriptSize)(input))),0)+outputs.reduce(((sum,output)=>sum+8+(0,utils_1.sliceSize)((0,utils_1.getOutScriptSize)(output))),0),inputsWitness=inputs.map((x=>(0,utils_1.getWitnessSize)(x)));return(4*baseSize+(inputsWitness.some((x=>0!==x.length))?2+inputsWitness.reduce(((sum,w)=>sum+(0,utils_1.vectorSize)(w)),0):0))/4}static getDustThreshold(output,dustRelayFee=3){return(0,utils_1.getDustThreshold)(output,dustRelayFee)}}exports.SecuxBTC=SecuxBTC,(0,utility_1.loadPlugin)(SecuxBTC,"SecuxBTC"); |
@@ -0,3 +1,20 @@ | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
/// <reference types="node" /> | ||
export declare function taprootConvert(XOnlyPubkey: Buffer, commitHash: Buffer): any; | ||
export declare function taprootVerify(signature: Buffer, message: Buffer, XOnlyPubkey: Buffer): boolean; |
@@ -1,1 +0,18 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.taprootVerify=exports.taprootConvert=void 0;const e=require("./utils"),r=require("bigi"),o=require("ecurve"),t=o.getCurveByName("secp256k1"),f=t.G,n=t.p,u=t.n,i=r.ZERO,a=r.ONE,c=r.valueOf(2),s=r.valueOf(3),l=r.valueOf(4),d=r.valueOf(7);function m(e){const f=r.fromBuffer(e),u=f.pow(s).add(d).mod(n),i=u.modPow(n.add(a).divide(l),n);if(0!==u.compareTo(i.modPow(c,n)))throw new Error("c is not equal to y^2");let m=o.Point.fromAffine(t,f,i);return p(m)||(m=o.Point.fromAffine(t,f,n.subtract(i))),m}function p(e){return e.affineY.mod(c).equals(i)}exports.taprootConvert=function(e,o){const t=m(e),n=r.fromBuffer(o);return t.add(f.multiply(n)).affineX.toBuffer(32)},exports.taprootVerify=function(o,t,i){const a=m(i),c=a.affineX.toBuffer(32),s=r.fromBuffer(o.slice(0,32)),l=r.fromBuffer(o.slice(32,64));if(s.compareTo(n)>=0)return!1;if(l.compareTo(u)>=0)return!1;const d=function(o,t,f){const n=(0,e.taggedHash)("BIP0340/challenge",Buffer.concat([o,t,f]));return r.fromBuffer(n).mod(u)}(s.toBuffer(32),c,t),v=function(e,r,o){const t=f.multiply(e),n=o.multiply(r);return t.add(n.negate())}(l,d,a);return!(v.curve.isInfinity(v)||!p(v)||!v.affineX.equals(s))}; | ||
"use strict"; | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/Object.defineProperty(exports,"__esModule",{value:!0}),exports.taprootVerify=exports.taprootConvert=void 0;const utils_1=require("./utils"),BigInteger=require("bigi"),ecurve=require("ecurve"),curve=ecurve.getCurveByName("secp256k1"),G=curve.G,p=curve.p,n=curve.n,zero=BigInteger.ZERO,one=BigInteger.ONE,two=BigInteger.valueOf(2),three=BigInteger.valueOf(3),four=BigInteger.valueOf(4),seven=BigInteger.valueOf(7);function liftX(XOnlyPubkey){const x=BigInteger.fromBuffer(XOnlyPubkey),c=x.pow(three).add(seven).mod(p),y=c.modPow(p.add(one).divide(four),p);if(0!==c.compareTo(y.modPow(two,p)))throw new Error("c is not equal to y^2");let P=ecurve.Point.fromAffine(curve,x,y);return isEven(P)||(P=ecurve.Point.fromAffine(curve,x,p.subtract(y))),P}function isEven(point){return point.affineY.mod(two).equals(zero)}exports.taprootConvert=function(XOnlyPubkey,commitHash){const P=liftX(XOnlyPubkey),tweak=BigInteger.fromBuffer(commitHash);return P.add(G.multiply(tweak)).affineX.toBuffer(32)},exports.taprootVerify=function(signature,message,XOnlyPubkey){const P=liftX(XOnlyPubkey),Px=P.affineX.toBuffer(32),r=BigInteger.fromBuffer(signature.slice(0,32)),s=BigInteger.fromBuffer(signature.slice(32,64));if(r.compareTo(p)>=0)return!1;if(s.compareTo(n)>=0)return!1;const e=function(Rx,Px,m){const hash=(0,utils_1.taggedHash)("BIP0340/challenge",Buffer.concat([Rx,Px,m]));return BigInteger.fromBuffer(hash).mod(n)}(r.toBuffer(32),Px,message),R=function(s,e,P){const sG=G.multiply(s),eP=P.multiply(e);return sG.add(eP.negate())}(s,e,P);return!(R.curve.isInfinity(R)||!isEven(R)||!R.affineX.equals(r))}; |
@@ -0,1 +1,18 @@ | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
/// <reference types="node" /> | ||
@@ -2,0 +19,0 @@ import { BigNumber } from "bignumber.js"; |
@@ -1,1 +0,18 @@ | ||
"use strict";var t,e=this&&this.__classPrivateFieldSet||function(t,e,r,s,i){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!i)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!i:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?i.call(t,r):i?i.value=r:e.set(t,r),r},r=this&&this.__classPrivateFieldGet||function(t,e,r,s){if("a"===r&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===r?s:"a"===r?s.call(t):s?s.value:e.get(t)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.BufferWriter=exports.BufferReader=void 0;const s=require("varuint-bitcoin"),i=require("bignumber.js");exports.BufferWriter=class{constructor(t,e=0){this.buffer=t,this.offset=e}writeUInt8(t){this.offset=this.buffer.writeUInt8(t,this.offset)}writeInt32(t){this.offset=this.buffer.writeInt32LE(t,this.offset)}writeUInt32(t){this.offset=this.buffer.writeUInt32LE(t,this.offset)}writeUInt64(t){this.offset=function(t,e,r){const s=new i.BigNumber(e);o(s.toNumber());return Buffer.from(s.toString(16).padStart(16,"0"),"hex").reverse().copy(t,r),r+8}(this.buffer,t,this.offset)}writeVarInt(t){s.encode(t,this.buffer,this.offset),this.offset+=s.encode.bytes}writeSlice(t){if(this.buffer.length<this.offset+t.length)throw new Error("Cannot write slice out of bounds");this.offset+=t.copy(this.buffer,this.offset)}writeVarSlice(t){this.writeVarInt(t.length),this.writeSlice(t)}writeVector(t){this.writeVarInt(t.length),t.forEach((t=>this.writeVarSlice(t)))}};function o(t){if("number"!=typeof t)throw new Error("cannot write a non-number as a number");if(t<0)throw new Error("specified a negative value for writing an unsigned value");if(Math.floor(t)!==t)throw new Error("value has a fractional component")}exports.BufferReader=class{constructor(r,s=0){t.set(this,void 0),e(this,t,Buffer.from([...r]),"f"),this.offset=s}readUInt8(){const e=r(this,t,"f").readUInt8(this.offset);return this.offset+=1,e}readInt32(){const e=r(this,t,"f").readInt32LE(this.offset);return this.offset+=4,e}readUInt32(){const e=r(this,t,"f").readUInt32LE(this.offset);return this.offset+=4,e}readUInt64(){const e=function(t,e){const r=t.slice(e,e+8).reverse().toString("hex"),s=new i.BigNumber(r,16);return o(s.toNumber()),s}(r(this,t,"f"),this.offset);return this.offset+=8,e}readVarInt(){const e=s.decode(r(this,t,"f"),this.offset);return this.offset+=s.decode.bytes,e}readSlice(e){if(r(this,t,"f").length<this.offset+e)throw new Error("Cannot read slice out of bounds");const s=r(this,t,"f").slice(this.offset,this.offset+e);return this.offset+=e,s}readVarSlice(){return this.readSlice(this.readVarInt())}readVector(){const t=this.readVarInt(),e=[];for(let r=0;r<t;r++)e.push(this.readVarSlice());return e}},t=new WeakMap; | ||
"use strict"; | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/var _BufferReader_buffer,__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.BufferWriter=exports.BufferReader=void 0;const varuint=require("varuint-bitcoin"),bignumber_js_1=require("bignumber.js");exports.BufferWriter=class{constructor(buffer,offset=0){this.buffer=buffer,this.offset=offset}writeUInt8(i){this.offset=this.buffer.writeUInt8(i,this.offset)}writeInt32(i){this.offset=this.buffer.writeInt32LE(i,this.offset)}writeUInt32(i){this.offset=this.buffer.writeUInt32LE(i,this.offset)}writeUInt64(i){this.offset=function(buffer,value,offset){const num=new bignumber_js_1.BigNumber(value);verifuint(num.toNumber());return Buffer.from(num.toString(16).padStart(16,"0"),"hex").reverse().copy(buffer,offset),offset+8}(this.buffer,i,this.offset)}writeVarInt(i){varuint.encode(i,this.buffer,this.offset),this.offset+=varuint.encode.bytes}writeSlice(slice){if(this.buffer.length<this.offset+slice.length)throw new Error("Cannot write slice out of bounds");this.offset+=slice.copy(this.buffer,this.offset)}writeVarSlice(slice){this.writeVarInt(slice.length),this.writeSlice(slice)}writeVector(vector){this.writeVarInt(vector.length),vector.forEach((buf=>this.writeVarSlice(buf)))}};function verifuint(value){if("number"!=typeof value)throw new Error("cannot write a non-number as a number");if(value<0)throw new Error("specified a negative value for writing an unsigned value");if(Math.floor(value)!==value)throw new Error("value has a fractional component")}exports.BufferReader=class{constructor(buffer,offset=0){_BufferReader_buffer.set(this,void 0),__classPrivateFieldSet(this,_BufferReader_buffer,Buffer.from([...buffer]),"f"),this.offset=offset}readUInt8(){const result=__classPrivateFieldGet(this,_BufferReader_buffer,"f").readUInt8(this.offset);return this.offset+=1,result}readInt32(){const result=__classPrivateFieldGet(this,_BufferReader_buffer,"f").readInt32LE(this.offset);return this.offset+=4,result}readUInt32(){const result=__classPrivateFieldGet(this,_BufferReader_buffer,"f").readUInt32LE(this.offset);return this.offset+=4,result}readUInt64(){const result=function(buffer,offset){const str=buffer.slice(offset,offset+8).reverse().toString("hex"),value=new bignumber_js_1.BigNumber(str,16);return verifuint(value.toNumber()),value}(__classPrivateFieldGet(this,_BufferReader_buffer,"f"),this.offset);return this.offset+=8,result}readVarInt(){const vi=varuint.decode(__classPrivateFieldGet(this,_BufferReader_buffer,"f"),this.offset);return this.offset+=varuint.decode.bytes,vi}readSlice(n){if(__classPrivateFieldGet(this,_BufferReader_buffer,"f").length<this.offset+n)throw new Error("Cannot read slice out of bounds");const result=__classPrivateFieldGet(this,_BufferReader_buffer,"f").slice(this.offset,this.offset+n);return this.offset+=n,result}readVarSlice(){return this.readSlice(this.readVarInt())}readVector(){const count=this.readVarInt(),vector=[];for(let i=0;i<count;i++)vector.push(this.readVarSlice());return vector}},_BufferReader_buffer=new WeakMap; |
@@ -0,1 +1,18 @@ | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
export interface Network { | ||
@@ -24,15 +41,15 @@ messagePrefix: string; | ||
export declare const OPCODES: Readonly<{ | ||
OP_0: number; | ||
OP_PUSHDATA1: number; | ||
OP_PUSHDATA2: number; | ||
OP_PUSHDATA4: number; | ||
OP_1NEGATE: number; | ||
OP_INT_BASE: number; | ||
OP_DUP: number; | ||
OP_HASH160: number; | ||
OP_EQUAL: number; | ||
OP_EQUALVERIFY: number; | ||
OP_CODESEPARATOR: number; | ||
OP_CHECKSIG: number; | ||
OP_CHECKMULTISIG: number; | ||
OP_0: 0; | ||
OP_PUSHDATA1: 76; | ||
OP_PUSHDATA2: 77; | ||
OP_PUSHDATA4: 78; | ||
OP_1NEGATE: 79; | ||
OP_INT_BASE: 80; | ||
OP_DUP: 118; | ||
OP_HASH160: 169; | ||
OP_EQUAL: 135; | ||
OP_EQUALVERIFY: 136; | ||
OP_CODESEPARATOR: 171; | ||
OP_CHECKSIG: 172; | ||
OP_CHECKMULTISIG: 174; | ||
}>; |
@@ -1,1 +0,18 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.OPCODES=exports.dogecoin=exports.dash=exports.digibyte=exports.groestl=exports.bitcoincash=exports.litecoin=exports.regtest=exports.testnet=exports.bitcoin=void 0,exports.bitcoin=Object.freeze({messagePrefix:"Bitcoin Signed Message:\n",bech32:"bc",bip32:{public:76067358,private:76066276},pubKeyHash:0,scriptHash:5,wif:128,coinType:0}),exports.testnet=Object.freeze({messagePrefix:"Bitcoin Signed Message:\n",bech32:"tb",bip32:{public:70617039,private:70615956},pubKeyHash:111,scriptHash:196,wif:239,coinType:1}),exports.regtest=Object.freeze({messagePrefix:"Bitcoin Signed Message:\n",bech32:"bcrt",bip32:{public:70617039,private:70615956},pubKeyHash:111,scriptHash:196,wif:239,coinType:1}),exports.litecoin=Object.freeze({messagePrefix:"Bitcoin Signed Message:\n",bech32:"ltc",bip32:{public:27108450,private:27106558},pubKeyHash:48,scriptHash:50,wif:176,coinType:2}),exports.bitcoincash=Object.freeze({messagePrefix:"Bitcoin Signed Message:\n",bip32:{public:76067358,private:76066276},pubKeyHash:0,scriptHash:5,wif:128,coinType:145}),exports.groestl=Object.freeze({messagePrefix:"GroestlCoin Signed Message:\n",bech32:"grs",bip32:{public:76067358,private:76066276},pubKeyHash:36,scriptHash:5,wif:128,coinType:17}),exports.digibyte=Object.freeze({messagePrefix:"Bitcoin Signed Message:\n",bech32:"dgb",bip32:{public:76067358,private:76066276},pubKeyHash:30,scriptHash:63,wif:128,coinType:20}),exports.dash=Object.freeze({messagePrefix:"Bitcoin Signed Message:\n",bech32:"dash",bip32:{public:76067358,private:76066276},pubKeyHash:76,scriptHash:16,wif:204,coinType:5}),exports.dogecoin=Object.freeze({messagePrefix:"Bitcoin Signed Message:\n",bech32:"doge",bip32:{public:49990397,private:49988504},pubKeyHash:30,scriptHash:22,wif:158,coinType:3}),exports.OPCODES=Object.freeze({OP_0:0,OP_PUSHDATA1:76,OP_PUSHDATA2:77,OP_PUSHDATA4:78,OP_1NEGATE:79,OP_INT_BASE:80,OP_DUP:118,OP_HASH160:169,OP_EQUAL:135,OP_EQUALVERIFY:136,OP_CODESEPARATOR:171,OP_CHECKSIG:172,OP_CHECKMULTISIG:174}); | ||
"use strict"; | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/Object.defineProperty(exports,"__esModule",{value:!0}),exports.OPCODES=exports.dogecoin=exports.dash=exports.digibyte=exports.groestl=exports.bitcoincash=exports.litecoin=exports.regtest=exports.testnet=exports.bitcoin=void 0,exports.bitcoin=Object.freeze({messagePrefix:"Bitcoin Signed Message:\n",bech32:"bc",bip32:{public:76067358,private:76066276},pubKeyHash:0,scriptHash:5,wif:128,coinType:0}),exports.testnet=Object.freeze({messagePrefix:"Bitcoin Signed Message:\n",bech32:"tb",bip32:{public:70617039,private:70615956},pubKeyHash:111,scriptHash:196,wif:239,coinType:1}),exports.regtest=Object.freeze({messagePrefix:"Bitcoin Signed Message:\n",bech32:"bcrt",bip32:{public:70617039,private:70615956},pubKeyHash:111,scriptHash:196,wif:239,coinType:1}),exports.litecoin=Object.freeze({messagePrefix:"Bitcoin Signed Message:\n",bech32:"ltc",bip32:{public:27108450,private:27106558},pubKeyHash:48,scriptHash:50,wif:176,coinType:2}),exports.bitcoincash=Object.freeze({messagePrefix:"Bitcoin Signed Message:\n",bip32:{public:76067358,private:76066276},pubKeyHash:0,scriptHash:5,wif:128,coinType:145}),exports.groestl=Object.freeze({messagePrefix:"GroestlCoin Signed Message:\n",bech32:"grs",bip32:{public:76067358,private:76066276},pubKeyHash:36,scriptHash:5,wif:128,coinType:17}),exports.digibyte=Object.freeze({messagePrefix:"Bitcoin Signed Message:\n",bech32:"dgb",bip32:{public:76067358,private:76066276},pubKeyHash:30,scriptHash:63,wif:128,coinType:20}),exports.dash=Object.freeze({messagePrefix:"Bitcoin Signed Message:\n",bech32:"dash",bip32:{public:76067358,private:76066276},pubKeyHash:76,scriptHash:16,wif:204,coinType:5}),exports.dogecoin=Object.freeze({messagePrefix:"Bitcoin Signed Message:\n",bech32:"doge",bip32:{public:49990397,private:49988504},pubKeyHash:30,scriptHash:22,wif:158,coinType:3}),exports.OPCODES=Object.freeze({OP_0:0,OP_PUSHDATA1:76,OP_PUSHDATA2:77,OP_PUSHDATA4:78,OP_1NEGATE:79,OP_INT_BASE:80,OP_DUP:118,OP_HASH160:169,OP_EQUAL:135,OP_EQUALVERIFY:136,OP_CODESEPARATOR:171,OP_CHECKSIG:172,OP_CHECKMULTISIG:174}); |
@@ -0,1 +1,18 @@ | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
/// <reference types="node" /> | ||
@@ -2,0 +19,0 @@ export { OPCODES } from "./coindef"; |
@@ -1,1 +0,18 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ow_SignOption=exports.ow_AddressOption=exports.ow_TransactionObject=exports.isOutuptScriptExtended=exports.isOutuptScript=exports.isOutputAddress=exports.ow_txOutput=exports.ow_txOutputScriptExtened=exports.ow_txOutputScript=exports.ow_txOutputAddress=exports.ow_txInput=exports.ow_PathObject=exports.ow_hashString=exports.ow_hexString=exports.ow_accountPath=exports.ow_path=exports.ow_balance=exports.btcPurposes=exports.btcCoinTypes=exports.coinmap=exports.CoinType=exports.ScriptType=exports.OPCODES=void 0;const t=require("ow"),e=require("./coindef"),o=require("@secux/utility");var r,p,s=require("./coindef");Object.defineProperty(exports,"OPCODES",{enumerable:!0,get:function(){return s.OPCODES}}),function(t){t[t.P2PKH=0]="P2PKH",t[t.P2WPKH=1]="P2WPKH",t[t.P2SH_P2PKH=2]="P2SH_P2PKH",t[t.P2SH_P2WPKH=3]="P2SH_P2WPKH",t[t.P2TR=4]="P2TR",t[t.__LENGTH=5]="__LENGTH"}(r=exports.ScriptType||(exports.ScriptType={})),function(t){t[t.BITCOIN=0]="BITCOIN",t[t.TESTNET=1]="TESTNET",t[t.REGTEST=2]="REGTEST",t[t.LITECOIN=3]="LITECOIN",t[t.BITCOINCASH=4]="BITCOINCASH",t[t.GROESTL=5]="GROESTL",t[t.DIGIBYTE=6]="DIGIBYTE",t[t.DASH=7]="DASH",t[t.DOGECOIN=8]="DOGECOIN",t[t.__LENGTH=9]="__LENGTH"}(p=exports.CoinType||(exports.CoinType={})),exports.coinmap=Object.freeze(Object.values(p).slice(0,p.__LENGTH).map((t=>e[t.toLowerCase()]))),exports.btcCoinTypes=Object.freeze(exports.coinmap.map((t=>Object.freeze(t.coinType)))),exports.btcPurposes=Object.freeze([Object.freeze(44),Object.freeze(49),Object.freeze(84),Object.freeze(86)]),exports.ow_balance=t.default.any(t.default.number.integer.positive,o.owTool.numberString),exports.ow_path=o.ow_strictPath(exports.btcCoinTypes,exports.btcPurposes),exports.ow_accountPath=o.ow_accountPath(exports.btcCoinTypes,exports.btcPurposes),exports.ow_hexString=o.owTool.hexString,exports.ow_hashString=o.owTool.hashString,exports.ow_PathObject=t.default.object.exactShape({coin:t.default.number.inRange(0,p.__LENGTH-1),script:t.default.number.inRange(0,r.__LENGTH-1)}),exports.ow_txInput=t.default.object.exactShape({hash:exports.ow_hashString,vout:t.default.number.greaterThanOrEqual(0),txHex:t.default.any(t.default.undefined,exports.ow_hexString),script:t.default.optional.number.inRange(0,r.__LENGTH-1),satoshis:exports.ow_balance,path:exports.ow_path,publickey:t.default.any(t.default.undefined,exports.ow_hexString,t.default.buffer)}),exports.ow_txOutputAddress=t.default.object.exactShape({address:exports.ow_hashString,satoshis:exports.ow_balance}),exports.ow_txOutputScript=t.default.object.exactShape({scriptHex:exports.ow_hexString,satoshis:exports.ow_balance}),exports.ow_txOutputScriptExtened=t.default.object.exactShape({publickey:t.default.any(t.default.undefined,exports.ow_hexString,t.default.buffer),path:exports.ow_path,satoshis:exports.ow_balance,script:t.default.optional.number.inRange(0,r.__LENGTH-1)}),exports.ow_txOutput=t.default.object.exactShape({to:t.default.any(exports.ow_txOutputAddress,exports.ow_txOutputScriptExtened),utxo:t.default.any(t.default.undefined,exports.ow_txOutputScriptExtened)}),exports.isOutputAddress=function(t){const e=t;if(e.address)return e},exports.isOutuptScript=function(t){const e=t;if(e.scriptHex)return e},exports.isOutuptScriptExtended=function(e){try{return(0,t.default)(e,exports.ow_txOutputScriptExtened),e}catch(t){}},exports.ow_TransactionObject=t.default.object.partialShape({rawTx:exports.ow_hexString,publickeys:t.default.array.ofType(t.default.any(exports.ow_hexString,t.default.buffer)),coin:t.default.optional.number.inRange(0,p.__LENGTH-1)}),exports.ow_AddressOption=t.default.object.exactShape({coin:t.default.optional.number.inRange(0,p.__LENGTH-1),script:t.default.optional.number.inRange(0,r.__LENGTH-1)}),exports.ow_SignOption=t.default.object.exactShape({coin:t.default.optional.number.inRange(0,p.__LENGTH-1),feeRate:t.default.optional.number.greaterThanOrEqual(1),isRBF:t.default.optional.boolean}); | ||
"use strict"; | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/Object.defineProperty(exports,"__esModule",{value:!0}),exports.ow_SignOption=exports.ow_AddressOption=exports.ow_TransactionObject=exports.isOutuptScriptExtended=exports.isOutuptScript=exports.isOutputAddress=exports.ow_txOutput=exports.ow_txOutputScriptExtened=exports.ow_txOutputScript=exports.ow_txOutputAddress=exports.ow_txInput=exports.ow_PathObject=exports.ow_hashString=exports.ow_hexString=exports.ow_accountPath=exports.ow_path=exports.ow_balance=exports.btcPurposes=exports.btcCoinTypes=exports.coinmap=exports.CoinType=exports.ScriptType=exports.OPCODES=void 0;const ow_1=require("ow"),constants=require("./coindef"),utils=require("@secux/utility");var ScriptType,CoinType,coindef_1=require("./coindef");Object.defineProperty(exports,"OPCODES",{enumerable:!0,get:function(){return coindef_1.OPCODES}}),function(ScriptType){ScriptType[ScriptType.P2PKH=0]="P2PKH",ScriptType[ScriptType.P2WPKH=1]="P2WPKH",ScriptType[ScriptType.P2SH_P2PKH=2]="P2SH_P2PKH",ScriptType[ScriptType.P2SH_P2WPKH=3]="P2SH_P2WPKH",ScriptType[ScriptType.P2TR=4]="P2TR",ScriptType[ScriptType.__LENGTH=5]="__LENGTH"}(ScriptType=exports.ScriptType||(exports.ScriptType={})),function(CoinType){CoinType[CoinType.BITCOIN=0]="BITCOIN",CoinType[CoinType.TESTNET=1]="TESTNET",CoinType[CoinType.REGTEST=2]="REGTEST",CoinType[CoinType.LITECOIN=3]="LITECOIN",CoinType[CoinType.BITCOINCASH=4]="BITCOINCASH",CoinType[CoinType.GROESTL=5]="GROESTL",CoinType[CoinType.DIGIBYTE=6]="DIGIBYTE",CoinType[CoinType.DASH=7]="DASH",CoinType[CoinType.DOGECOIN=8]="DOGECOIN",CoinType[CoinType.__LENGTH=9]="__LENGTH"}(CoinType=exports.CoinType||(exports.CoinType={})),exports.coinmap=Object.freeze(Object.values(CoinType).slice(0,CoinType.__LENGTH).map((x=>constants[x.toLowerCase()]))),exports.btcCoinTypes=Object.freeze(exports.coinmap.map((x=>Object.freeze(x.coinType)))),exports.btcPurposes=Object.freeze([Object.freeze(44),Object.freeze(49),Object.freeze(84),Object.freeze(86)]),exports.ow_balance=ow_1.default.any(ow_1.default.number.integer.positive,utils.owTool.numberString),exports.ow_path=utils.ow_strictPath(exports.btcCoinTypes,exports.btcPurposes),exports.ow_accountPath=utils.ow_accountPath(exports.btcCoinTypes,exports.btcPurposes),exports.ow_hexString=utils.owTool.hexString,exports.ow_hashString=utils.owTool.hashString,exports.ow_PathObject=ow_1.default.object.exactShape({coin:ow_1.default.number.inRange(0,CoinType.__LENGTH-1),script:ow_1.default.number.inRange(0,ScriptType.__LENGTH-1)}),exports.ow_txInput=ow_1.default.object.exactShape({hash:exports.ow_hashString,vout:ow_1.default.number.greaterThanOrEqual(0),txHex:ow_1.default.any(ow_1.default.undefined,exports.ow_hexString),script:ow_1.default.optional.number.inRange(0,ScriptType.__LENGTH-1),satoshis:exports.ow_balance,path:exports.ow_path,publickey:ow_1.default.any(ow_1.default.undefined,exports.ow_hexString,ow_1.default.buffer)}),exports.ow_txOutputAddress=ow_1.default.object.exactShape({address:exports.ow_hashString,satoshis:exports.ow_balance}),exports.ow_txOutputScript=ow_1.default.object.exactShape({scriptHex:exports.ow_hexString,satoshis:exports.ow_balance}),exports.ow_txOutputScriptExtened=ow_1.default.object.exactShape({publickey:ow_1.default.any(ow_1.default.undefined,exports.ow_hexString,ow_1.default.buffer),path:exports.ow_path,satoshis:exports.ow_balance,script:ow_1.default.optional.number.inRange(0,ScriptType.__LENGTH-1)}),exports.ow_txOutput=ow_1.default.object.exactShape({to:ow_1.default.any(exports.ow_txOutputAddress,exports.ow_txOutputScriptExtened),utxo:ow_1.default.any(ow_1.default.undefined,exports.ow_txOutputScriptExtened)}),exports.isOutputAddress=function(output){const out=output;if(out.address)return out},exports.isOutuptScript=function(output){const out=output;if(out.scriptHex)return out},exports.isOutuptScriptExtended=function(output){try{return(0,ow_1.default)(output,exports.ow_txOutputScriptExtened),output}catch(error){}},exports.ow_TransactionObject=ow_1.default.object.partialShape({rawTx:exports.ow_hexString,publickeys:ow_1.default.array.ofType(ow_1.default.any(exports.ow_hexString,ow_1.default.buffer)),coin:ow_1.default.optional.number.inRange(0,CoinType.__LENGTH-1)}),exports.ow_AddressOption=ow_1.default.object.exactShape({coin:ow_1.default.optional.number.inRange(0,CoinType.__LENGTH-1),script:ow_1.default.optional.number.inRange(0,ScriptType.__LENGTH-1)}),exports.ow_SignOption=ow_1.default.object.exactShape({coin:ow_1.default.optional.number.inRange(0,CoinType.__LENGTH-1),feeRate:ow_1.default.optional.number.greaterThanOrEqual(1),isRBF:ow_1.default.optional.boolean}); |
@@ -0,1 +1,18 @@ | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
/// <reference types="node" /> | ||
@@ -2,0 +19,0 @@ import { Psbt } from "bip174"; |
@@ -1,1 +0,18 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Psbtv2=void 0;const e=require("bip174"),r=require("bip174/src/lib/converter"),t=require("./bufferutils");class o extends e.Psbt{static fromBuffer(e,o){const E=function(e,o){if(1886610036!==e.readUInt32BE())throw Error("Format Error: Invalid Magic Number");if(255!==e.readUInt8(4))throw Error("Format Error: Magic Number must be followed by 0xff separator");const E=new t.BufferReader(e);E.offset+=5;const u=()=>({key:E.readVarSlice(),value:E.readVarSlice()}),I=()=>{if(E.offset>=e.length)throw Error("Format Error: Unexpected End of PSBT");const r=0===e.readUInt8(E.offset);return r&&(E.offset+=1),r},T=[],l={};for(;!I();){const e=u(),r=e.key.toString("hex");if(l[r])throw Error("Format Error: Keys must be unique for global keymap: key "+r);l[r]=1,T.push(e)}const p=T.filter((e=>e.key[0]===i.UNSIGNED_TX));if(1!==p.length)throw Error("Format Error: Only one UNSIGNED_TX allowed");const _=o(p[0].value),{inputCount:S,outputCount:c}=_.getInputOutputCounts(),P=[],O=[];for(let e=0;e<S;e++){const r={},t=[];for(;!I();){const o=u(),a=o.key.toString("hex");if(r[a])throw Error(`Format Error: Keys must be unique, got "${a}" from input#${e}`);r[a]=1,t.push(o)}P.push(t)}for(let e=0;e<c;e++){const r={},t=[];for(;!I();){const o=u(),a=o.key.toString("hex");if(r[a])throw Error(`Format Error: Keys must be unique, got "${a}" from output#${e}`);r[a]=1,t.push(o)}O.push(t)}return function(e,{globalMapKeyVals:o,inputKeyVals:E,outputKeyVals:u}){const I={unsignedTx:e};let T,l,p=0;for(const e of o){let o;switch(e.key[0]){case i.UNSIGNED_TX:if(a("global",e.key,i.UNSIGNED_TX),p>0)throw new Error("Format Error: GlobalMap has multiple UNSIGNED_TX");p++;break;case i.GLOBAL_XPUB:void 0===I.globalXpub&&(I.globalXpub=[]),I.globalXpub.push(r.globals.globalXpub.decode(e));break;case i.GLOBAL_TX_VERSION:if(a("global",e.key,i.GLOBAL_TX_VERSION),4!==e.value.length)throw Error("Value Error: Global transaction version is not 4 bytes");I.txVersion=e.value.readUInt32LE();break;case i.GLOBAL_FALLBACK_LOCKTIME:if(a("global",e.key,i.GLOBAL_FALLBACK_LOCKTIME),4!==e.value.length)throw Error("Value Error: Global fallback locktime is not 4 bytes");I.fallbackLocktime=e.value.readUInt32LE();break;case i.GLOBAL_INPUT_COUNT:a("global",e.key,i.GLOBAL_INPUT_COUNT),o=new t.BufferReader(e.value),o.readVarInt(),T=o.readVarInt();break;case i.GLOBAL_OUTPUT_COUNT:a("global",e.key,i.GLOBAL_OUTPUT_COUNT),o=new t.BufferReader(e.value),o.readVarInt(),l=o.readVarInt();break;case i.GLOBAL_TXMODIFIABLE:if(a("global",e.key,i.GLOBAL_TXMODIFIABLE),1!==e.value.length)throw Error("Value Error: Global tx modifiable flags is not 1 bytes");I.txModifiable=1==(1&e.value[0]);break;case i.GLOBAL_VERSION:if(a("global",e.key,i.GLOBAL_VERSION),4!==e.value.length)throw Error("Value Error: Global PSBT version is not 4 bytes");I.version=e.value.readUInt32LE();break;default:I.unknownKeyVals||(I.unknownKeyVals=[]),I.unknownKeyVals.push(e)}}T=null!=T?T:E.length,l=null!=l?l:u.length;const _=[],S=[];for(let e=0;e<T;e++){const o={tapScriptSigs:{},tapScripts:{},tapBip32Paths:{}};for(const i of E[e])switch(r.inputs.checkPubkey(i),i.key[0]){case n.NON_WITNESS_UTXO:if(a("input",i.key,n.NON_WITNESS_UTXO),void 0!==o.nonWitnessUtxo)throw Error("Format Error: Input has multiple NON_WITNESS_UTXO");o.nonWitnessUtxo=r.inputs.nonWitnessUtxo.decode(i);break;case n.WITNESS_UTXO:if(a("input",i.key,n.WITNESS_UTXO),void 0!==o.witnessUtxo)throw Error("Format Error: Input has multiple WITNESS_UTXO");o.witnessUtxo=r.inputs.witnessUtxo.decode(i);break;case n.PARTIAL_SIG:void 0===o.partialSig&&(o.partialSig=[]),o.partialSig.push(r.inputs.partialSig.decode(i));break;case n.SIGHASH_TYPE:if(a("input",i.key,n.SIGHASH_TYPE),void 0!==o.sighashType)throw Error("Format Error: Input has multiple SIGHASH_TYPE");o.sighashType=r.inputs.sighashType.decode(i);break;case n.REDEEM_SCRIPT:if(a("input",i.key,n.REDEEM_SCRIPT),void 0!==o.redeemScript)throw Error("Format Error: Input has multiple REDEEM_SCRIPT");o.redeemScript=r.inputs.redeemScript.decode(i);break;case n.WITNESS_SCRIPT:if(a("input",i.key,n.WITNESS_SCRIPT),void 0!==o.witnessScript)throw Error("Format Error: Input has multiple WITNESS_SCRIPT");o.witnessScript=r.inputs.witnessScript.decode(i);break;case n.BIP32_DERIVATION:void 0===o.bip32Derivation&&(o.bip32Derivation=[]),o.bip32Derivation.push(r.inputs.bip32Derivation.decode(i));break;case n.FINAL_SCRIPTSIG:a("input",i.key,n.FINAL_SCRIPTSIG),o.finalScriptSig=r.inputs.finalScriptSig.decode(i);break;case n.FINAL_SCRIPTWITNESS:a("input",i.key,n.FINAL_SCRIPTWITNESS),o.finalScriptWitness=r.inputs.finalScriptWitness.decode(i);break;case n.POR_COMMITMENT:a("input",i.key,n.POR_COMMITMENT),o.porCommitment=r.inputs.porCommitment.decode(i);break;case n.PREVIOUS_TXID:if(a("input",i.key,n.PREVIOUS_TXID),32!==i.value.length)throw Error("Value Error: Previous txid is not 32 bytes");o.prevTXID=i.value.toString("hex");break;case n.OUTPUT_INDEX:if(a("input",i.key,n.OUTPUT_INDEX),4!==i.value.length)throw Error("Value Error: Previous output index is not 4 bytes");o.prevOutputIndex=i.value[0];break;case n.TAP_KEY_SIG:if(a("input",i.key,n.TAP_KEY_SIG),i.value.length<64)throw Error("Value Error: Input Taproot key path signature is shorter than 64 bytes");if(i.value.length>65)throw Error("Value Error: Input Taproot key path signature is longer than 65 bytes");o.tapKeySig=i.value;break;case n.TAP_SCRIPT_SIG:if(a("input",i.key,n.TAP_SCRIPT_SIG),65!==i.key.length)throw Error("Format Error: Input Taproot script signature key is not 65 bytes");if(i.value.length<64)throw Error("Value Error: Input Taproot script path signature is shorter than 64 bytes");if(i.value.length>65)throw Error("Value Error: Input Taproot script path signature is longer than 65 bytes");const e=i.key.slice(1).toString("hex");o.tapScriptSigs[e]=i.value;break;case n.TAP_LEAF_SCRIPT:if(a("input",i.key,n.TAP_LEAF_SCRIPT),i.key.length<34)throw Error("Format Error: Input Taproot leaf script key is not at least 34 bytes");if(i.key.length%32!=2)throw Error("Format Error: Input Taproot leaf script key's control block is not valid");if(0===i.value.length)throw Error("Value Error: Intput Taproot leaf script cannot be empty");const s=i.value.slice(-1).toString("hex");o.tapScripts[s]||(o.tapScripts[s]=new Set),o.tapScripts[s].add(i.key.slice(1).toString("hex"));break;case n.TAP_BIP32_DERIVATION:if(a("input",i.key,n.TAP_BIP32_DERIVATION),33!==i.key.length)throw Error("Format Error: Input Taproot BIP 32 keypath key is not 33 bytes");const E=i.key.slice(1).toString("hex"),u=new t.BufferReader(i.value),I=u.readVarInt(),T=new Set;for(let e=0;e<I;e++)T.add(u.readSlice(32).toString("hex"));o.tapBip32Paths[E]={leafHashs:T,Bip32Derivation:i.value.slice(u.offset)};break;case n.TAP_INTERNAL_KEY:if(a("input",i.key,n.TAP_INTERNAL_KEY),32!==i.value.length)throw Error("Value Error: Input Taproot internal key is not 32 bytes");o.tapInternalKey=i.value;break;case n.TAP_MERKLE_ROOT:if(a("input",i.key,n.TAP_MERKLE_ROOT),32!==i.value.length)throw Error("Value Error: Input Taproot merkle root is not 32 bytes");o.tapMarkleRoot=i.value.toString("hex");break;default:o.unknownKeyVals||(o.unknownKeyVals=[]),o.unknownKeyVals.push(i)}_.push(o)}for(let e=0;e<l;e++){const o={tapBip32Paths:{}};for(const i of u[e]){let e;switch(r.outputs.checkPubkey(i),i.key[0]){case s.REDEEM_SCRIPT:if(a("output",i.key,s.REDEEM_SCRIPT),void 0!==o.redeemScript)throw Error("Format Error: Output has multiple REDEEM_SCRIPT");o.redeemScript=r.outputs.redeemScript.decode(i);break;case s.WITNESS_SCRIPT:if(a("output",i.key,s.WITNESS_SCRIPT),void 0!==o.witnessScript)throw Error("Format Error: Output has multiple WITNESS_SCRIPT");o.witnessScript=r.outputs.witnessScript.decode(i);break;case s.BIP32_DERIVATION:void 0===o.bip32Derivation&&(o.bip32Derivation=[]),o.bip32Derivation.push(r.outputs.bip32Derivation.decode(i));break;case s.AMOUNT:if(a("output",i.key,s.AMOUNT),8!==i.value.length)throw Error("Value Error: Output amount is not 8 bytes");e=new t.BufferReader(i.value),o.amount=e.readUInt64();break;case s.SCRIPT:a("output",i.key,s.SCRIPT),o.script=i.value;break;case s.TAP_INTERNAL_KEY:if(a("output",i.key,s.TAP_INTERNAL_KEY),32!==i.value.length)throw Error("Value Error: Output Taproot internal key is not 32 bytes");o.tapInternalKey=i.value;break;case s.TAP_TREE:a("output",i.key,s.TAP_TREE),o.tapTree=i.value;break;case s.TAP_BIP32_DERIVATION:if(a("output",i.key,s.TAP_BIP32_DERIVATION),33!==i.key.length)throw Error("Output Taproot BIP 32 keypath key is not 33 bytes");const n=i.key.slice(1).toString("hex"),E=new Set;e=new t.BufferReader(i.value);const u=e.readVarInt();for(let r=0;r<u;r++)E.add(e.readSlice(32).toString("hex"));o.tapBip32Paths[n]={leafHashs:E,Bip32Derivation:i.value.slice(e.offset)};break;default:o.unknownKeyVals||(o.unknownKeyVals=[]),o.unknownKeyVals.push(i)}}S.push(o)}return{globalMap:I,inputs:_,outputs:S}}(_,{globalMapKeyVals:T,inputKeyVals:P,outputKeyVals:O})}(e,o),u=new this(E.globalMap.unsignedTx);return Object.assign(u,E),u}}function a(e,r,t){if(!r.equals(Buffer.from([t])))throw Error(`Format Error: Invalid ${e} key: ${r.toString("hex")}`)}var i,n,s;exports.Psbtv2=o,function(e){e[e.UNSIGNED_TX=0]="UNSIGNED_TX",e[e.GLOBAL_XPUB=1]="GLOBAL_XPUB",e[e.GLOBAL_TX_VERSION=2]="GLOBAL_TX_VERSION",e[e.GLOBAL_FALLBACK_LOCKTIME=3]="GLOBAL_FALLBACK_LOCKTIME",e[e.GLOBAL_INPUT_COUNT=4]="GLOBAL_INPUT_COUNT",e[e.GLOBAL_OUTPUT_COUNT=5]="GLOBAL_OUTPUT_COUNT",e[e.GLOBAL_TXMODIFIABLE=6]="GLOBAL_TXMODIFIABLE",e[e.GLOBAL_VERSION=251]="GLOBAL_VERSION"}(i||(i={})),function(e){e[e.NON_WITNESS_UTXO=0]="NON_WITNESS_UTXO",e[e.WITNESS_UTXO=1]="WITNESS_UTXO",e[e.PARTIAL_SIG=2]="PARTIAL_SIG",e[e.SIGHASH_TYPE=3]="SIGHASH_TYPE",e[e.REDEEM_SCRIPT=4]="REDEEM_SCRIPT",e[e.WITNESS_SCRIPT=5]="WITNESS_SCRIPT",e[e.BIP32_DERIVATION=6]="BIP32_DERIVATION",e[e.FINAL_SCRIPTSIG=7]="FINAL_SCRIPTSIG",e[e.FINAL_SCRIPTWITNESS=8]="FINAL_SCRIPTWITNESS",e[e.POR_COMMITMENT=9]="POR_COMMITMENT",e[e.PREVIOUS_TXID=14]="PREVIOUS_TXID",e[e.OUTPUT_INDEX=15]="OUTPUT_INDEX",e[e.SEQUENCE=16]="SEQUENCE",e[e.REQUIRED_TIME_LOCKTIME=17]="REQUIRED_TIME_LOCKTIME",e[e.REQUIRED_HEIGHT_LOCKTIME=18]="REQUIRED_HEIGHT_LOCKTIME",e[e.TAP_KEY_SIG=19]="TAP_KEY_SIG",e[e.TAP_SCRIPT_SIG=20]="TAP_SCRIPT_SIG",e[e.TAP_LEAF_SCRIPT=21]="TAP_LEAF_SCRIPT",e[e.TAP_BIP32_DERIVATION=22]="TAP_BIP32_DERIVATION",e[e.TAP_INTERNAL_KEY=23]="TAP_INTERNAL_KEY",e[e.TAP_MERKLE_ROOT=24]="TAP_MERKLE_ROOT"}(n||(n={})),function(e){e[e.REDEEM_SCRIPT=0]="REDEEM_SCRIPT",e[e.WITNESS_SCRIPT=1]="WITNESS_SCRIPT",e[e.BIP32_DERIVATION=2]="BIP32_DERIVATION",e[e.AMOUNT=3]="AMOUNT",e[e.SCRIPT=4]="SCRIPT",e[e.TAP_INTERNAL_KEY=5]="TAP_INTERNAL_KEY",e[e.TAP_TREE=6]="TAP_TREE",e[e.TAP_BIP32_DERIVATION=7]="TAP_BIP32_DERIVATION"}(s||(s={})); | ||
"use strict"; | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/Object.defineProperty(exports,"__esModule",{value:!0}),exports.Psbtv2=void 0;const bip174_1=require("bip174"),convert=require("bip174/src/lib/converter"),bufferutils_1=require("./bufferutils");class Psbtv2 extends bip174_1.Psbt{static fromBuffer(buffer,txFromBuffer){const results=function(buffer,txGetter){if(1886610036!==buffer.readUInt32BE())throw Error("Format Error: Invalid Magic Number");if(255!==buffer.readUInt8(4))throw Error("Format Error: Magic Number must be followed by 0xff separator");const reader=new bufferutils_1.BufferReader(buffer);reader.offset+=5;const getKeyValue=()=>({key:reader.readVarSlice(),value:reader.readVarSlice()}),checkEndOfKeyValPairs=()=>{if(reader.offset>=buffer.length)throw Error("Format Error: Unexpected End of PSBT");const isEnd=0===buffer.readUInt8(reader.offset);return isEnd&&(reader.offset+=1),isEnd},globalMapKeyVals=[],globalKeyIndex={};for(;!checkEndOfKeyValPairs();){const keyVal=getKeyValue(),hexKey=keyVal.key.toString("hex");if(globalKeyIndex[hexKey])throw Error("Format Error: Keys must be unique for global keymap: key "+hexKey);globalKeyIndex[hexKey]=1,globalMapKeyVals.push(keyVal)}const unsignedTxMaps=globalMapKeyVals.filter((keyVal=>keyVal.key[0]===GlobalTypes.UNSIGNED_TX));if(1!==unsignedTxMaps.length)throw Error("Format Error: Only one UNSIGNED_TX allowed");const unsignedTx=txGetter(unsignedTxMaps[0].value),{inputCount,outputCount}=unsignedTx.getInputOutputCounts(),inputKeyVals=[],outputKeyVals=[];for(let index=0;index<inputCount;index++){const inputKeyIndex={},input=[];for(;!checkEndOfKeyValPairs();){const keyVal=getKeyValue(),hexKey=keyVal.key.toString("hex");if(inputKeyIndex[hexKey])throw Error(`Format Error: Keys must be unique, got "${hexKey}" from input#${index}`);inputKeyIndex[hexKey]=1,input.push(keyVal)}inputKeyVals.push(input)}for(let index=0;index<outputCount;index++){const outputKeyIndex={},output=[];for(;!checkEndOfKeyValPairs();){const keyVal=getKeyValue(),hexKey=keyVal.key.toString("hex");if(outputKeyIndex[hexKey])throw Error(`Format Error: Keys must be unique, got "${hexKey}" from output#${index}`);outputKeyIndex[hexKey]=1,output.push(keyVal)}outputKeyVals.push(output)}return function(unsignedTx,{globalMapKeyVals,inputKeyVals,outputKeyVals}){const globalMap={unsignedTx};let inputCount,outputCount,txCount=0;for(const keyVal of globalMapKeyVals){let reader;switch(keyVal.key[0]){case GlobalTypes.UNSIGNED_TX:if(checkKeyBuffer("global",keyVal.key,GlobalTypes.UNSIGNED_TX),txCount>0)throw new Error("Format Error: GlobalMap has multiple UNSIGNED_TX");txCount++;break;case GlobalTypes.GLOBAL_XPUB:void 0===globalMap.globalXpub&&(globalMap.globalXpub=[]),globalMap.globalXpub.push(convert.globals.globalXpub.decode(keyVal));break;case GlobalTypes.GLOBAL_TX_VERSION:if(checkKeyBuffer("global",keyVal.key,GlobalTypes.GLOBAL_TX_VERSION),4!==keyVal.value.length)throw Error("Value Error: Global transaction version is not 4 bytes");globalMap.txVersion=keyVal.value.readUInt32LE();break;case GlobalTypes.GLOBAL_FALLBACK_LOCKTIME:if(checkKeyBuffer("global",keyVal.key,GlobalTypes.GLOBAL_FALLBACK_LOCKTIME),4!==keyVal.value.length)throw Error("Value Error: Global fallback locktime is not 4 bytes");globalMap.fallbackLocktime=keyVal.value.readUInt32LE();break;case GlobalTypes.GLOBAL_INPUT_COUNT:checkKeyBuffer("global",keyVal.key,GlobalTypes.GLOBAL_INPUT_COUNT),reader=new bufferutils_1.BufferReader(keyVal.value),reader.readVarInt(),inputCount=reader.readVarInt();break;case GlobalTypes.GLOBAL_OUTPUT_COUNT:checkKeyBuffer("global",keyVal.key,GlobalTypes.GLOBAL_OUTPUT_COUNT),reader=new bufferutils_1.BufferReader(keyVal.value),reader.readVarInt(),outputCount=reader.readVarInt();break;case GlobalTypes.GLOBAL_TXMODIFIABLE:if(checkKeyBuffer("global",keyVal.key,GlobalTypes.GLOBAL_TXMODIFIABLE),1!==keyVal.value.length)throw Error("Value Error: Global tx modifiable flags is not 1 bytes");globalMap.txModifiable=1==(1&keyVal.value[0]);break;case GlobalTypes.GLOBAL_VERSION:if(checkKeyBuffer("global",keyVal.key,GlobalTypes.GLOBAL_VERSION),4!==keyVal.value.length)throw Error("Value Error: Global PSBT version is not 4 bytes");globalMap.version=keyVal.value.readUInt32LE();break;default:globalMap.unknownKeyVals||(globalMap.unknownKeyVals=[]),globalMap.unknownKeyVals.push(keyVal)}}inputCount=null!=inputCount?inputCount:inputKeyVals.length,outputCount=null!=outputCount?outputCount:outputKeyVals.length;const inputs=[],outputs=[];for(let index=0;index<inputCount;index++){const input={tapScriptSigs:{},tapScripts:{},tapBip32Paths:{}};for(const keyVal of inputKeyVals[index])switch(convert.inputs.checkPubkey(keyVal),keyVal.key[0]){case InputTypes.NON_WITNESS_UTXO:if(checkKeyBuffer("input",keyVal.key,InputTypes.NON_WITNESS_UTXO),void 0!==input.nonWitnessUtxo)throw Error("Format Error: Input has multiple NON_WITNESS_UTXO");input.nonWitnessUtxo=convert.inputs.nonWitnessUtxo.decode(keyVal);break;case InputTypes.WITNESS_UTXO:if(checkKeyBuffer("input",keyVal.key,InputTypes.WITNESS_UTXO),void 0!==input.witnessUtxo)throw Error("Format Error: Input has multiple WITNESS_UTXO");input.witnessUtxo=convert.inputs.witnessUtxo.decode(keyVal);break;case InputTypes.PARTIAL_SIG:void 0===input.partialSig&&(input.partialSig=[]),input.partialSig.push(convert.inputs.partialSig.decode(keyVal));break;case InputTypes.SIGHASH_TYPE:if(checkKeyBuffer("input",keyVal.key,InputTypes.SIGHASH_TYPE),void 0!==input.sighashType)throw Error("Format Error: Input has multiple SIGHASH_TYPE");input.sighashType=convert.inputs.sighashType.decode(keyVal);break;case InputTypes.REDEEM_SCRIPT:if(checkKeyBuffer("input",keyVal.key,InputTypes.REDEEM_SCRIPT),void 0!==input.redeemScript)throw Error("Format Error: Input has multiple REDEEM_SCRIPT");input.redeemScript=convert.inputs.redeemScript.decode(keyVal);break;case InputTypes.WITNESS_SCRIPT:if(checkKeyBuffer("input",keyVal.key,InputTypes.WITNESS_SCRIPT),void 0!==input.witnessScript)throw Error("Format Error: Input has multiple WITNESS_SCRIPT");input.witnessScript=convert.inputs.witnessScript.decode(keyVal);break;case InputTypes.BIP32_DERIVATION:void 0===input.bip32Derivation&&(input.bip32Derivation=[]),input.bip32Derivation.push(convert.inputs.bip32Derivation.decode(keyVal));break;case InputTypes.FINAL_SCRIPTSIG:checkKeyBuffer("input",keyVal.key,InputTypes.FINAL_SCRIPTSIG),input.finalScriptSig=convert.inputs.finalScriptSig.decode(keyVal);break;case InputTypes.FINAL_SCRIPTWITNESS:checkKeyBuffer("input",keyVal.key,InputTypes.FINAL_SCRIPTWITNESS),input.finalScriptWitness=convert.inputs.finalScriptWitness.decode(keyVal);break;case InputTypes.POR_COMMITMENT:checkKeyBuffer("input",keyVal.key,InputTypes.POR_COMMITMENT),input.porCommitment=convert.inputs.porCommitment.decode(keyVal);break;case InputTypes.PREVIOUS_TXID:if(checkKeyBuffer("input",keyVal.key,InputTypes.PREVIOUS_TXID),32!==keyVal.value.length)throw Error("Value Error: Previous txid is not 32 bytes");input.prevTXID=keyVal.value.toString("hex");break;case InputTypes.OUTPUT_INDEX:if(checkKeyBuffer("input",keyVal.key,InputTypes.OUTPUT_INDEX),4!==keyVal.value.length)throw Error("Value Error: Previous output index is not 4 bytes");input.prevOutputIndex=keyVal.value[0];break;case InputTypes.TAP_KEY_SIG:if(checkKeyBuffer("input",keyVal.key,InputTypes.TAP_KEY_SIG),keyVal.value.length<64)throw Error("Value Error: Input Taproot key path signature is shorter than 64 bytes");if(keyVal.value.length>65)throw Error("Value Error: Input Taproot key path signature is longer than 65 bytes");input.tapKeySig=keyVal.value;break;case InputTypes.TAP_SCRIPT_SIG:if(checkKeyBuffer("input",keyVal.key,InputTypes.TAP_SCRIPT_SIG),65!==keyVal.key.length)throw Error("Format Error: Input Taproot script signature key is not 65 bytes");if(keyVal.value.length<64)throw Error("Value Error: Input Taproot script path signature is shorter than 64 bytes");if(keyVal.value.length>65)throw Error("Value Error: Input Taproot script path signature is longer than 65 bytes");const scriptkey=keyVal.key.slice(1).toString("hex");input.tapScriptSigs[scriptkey]=keyVal.value;break;case InputTypes.TAP_LEAF_SCRIPT:if(checkKeyBuffer("input",keyVal.key,InputTypes.TAP_LEAF_SCRIPT),keyVal.key.length<34)throw Error("Format Error: Input Taproot leaf script key is not at least 34 bytes");if(keyVal.key.length%32!=2)throw Error("Format Error: Input Taproot leaf script key's control block is not valid");if(0===keyVal.value.length)throw Error("Value Error: Intput Taproot leaf script cannot be empty");const script=keyVal.value.slice(-1).toString("hex");input.tapScripts[script]||(input.tapScripts[script]=new Set),input.tapScripts[script].add(keyVal.key.slice(1).toString("hex"));break;case InputTypes.TAP_BIP32_DERIVATION:if(checkKeyBuffer("input",keyVal.key,InputTypes.TAP_BIP32_DERIVATION),33!==keyVal.key.length)throw Error("Format Error: Input Taproot BIP 32 keypath key is not 33 bytes");const xonly=keyVal.key.slice(1).toString("hex"),reader=new bufferutils_1.BufferReader(keyVal.value),num_hashs=reader.readVarInt(),leaf_hashes=new Set;for(let i=0;i<num_hashs;i++)leaf_hashes.add(reader.readSlice(32).toString("hex"));input.tapBip32Paths[xonly]={leafHashs:leaf_hashes,Bip32Derivation:keyVal.value.slice(reader.offset)};break;case InputTypes.TAP_INTERNAL_KEY:if(checkKeyBuffer("input",keyVal.key,InputTypes.TAP_INTERNAL_KEY),32!==keyVal.value.length)throw Error("Value Error: Input Taproot internal key is not 32 bytes");input.tapInternalKey=keyVal.value;break;case InputTypes.TAP_MERKLE_ROOT:if(checkKeyBuffer("input",keyVal.key,InputTypes.TAP_MERKLE_ROOT),32!==keyVal.value.length)throw Error("Value Error: Input Taproot merkle root is not 32 bytes");input.tapMarkleRoot=keyVal.value.toString("hex");break;default:input.unknownKeyVals||(input.unknownKeyVals=[]),input.unknownKeyVals.push(keyVal)}inputs.push(input)}for(let index=0;index<outputCount;index++){const output={tapBip32Paths:{}};for(const keyVal of outputKeyVals[index]){let reader;switch(convert.outputs.checkPubkey(keyVal),keyVal.key[0]){case OutputTypes.REDEEM_SCRIPT:if(checkKeyBuffer("output",keyVal.key,OutputTypes.REDEEM_SCRIPT),void 0!==output.redeemScript)throw Error("Format Error: Output has multiple REDEEM_SCRIPT");output.redeemScript=convert.outputs.redeemScript.decode(keyVal);break;case OutputTypes.WITNESS_SCRIPT:if(checkKeyBuffer("output",keyVal.key,OutputTypes.WITNESS_SCRIPT),void 0!==output.witnessScript)throw Error("Format Error: Output has multiple WITNESS_SCRIPT");output.witnessScript=convert.outputs.witnessScript.decode(keyVal);break;case OutputTypes.BIP32_DERIVATION:void 0===output.bip32Derivation&&(output.bip32Derivation=[]),output.bip32Derivation.push(convert.outputs.bip32Derivation.decode(keyVal));break;case OutputTypes.AMOUNT:if(checkKeyBuffer("output",keyVal.key,OutputTypes.AMOUNT),8!==keyVal.value.length)throw Error("Value Error: Output amount is not 8 bytes");reader=new bufferutils_1.BufferReader(keyVal.value),output.amount=reader.readUInt64();break;case OutputTypes.SCRIPT:checkKeyBuffer("output",keyVal.key,OutputTypes.SCRIPT),output.script=keyVal.value;break;case OutputTypes.TAP_INTERNAL_KEY:if(checkKeyBuffer("output",keyVal.key,OutputTypes.TAP_INTERNAL_KEY),32!==keyVal.value.length)throw Error("Value Error: Output Taproot internal key is not 32 bytes");output.tapInternalKey=keyVal.value;break;case OutputTypes.TAP_TREE:checkKeyBuffer("output",keyVal.key,OutputTypes.TAP_TREE),output.tapTree=keyVal.value;break;case OutputTypes.TAP_BIP32_DERIVATION:if(checkKeyBuffer("output",keyVal.key,OutputTypes.TAP_BIP32_DERIVATION),33!==keyVal.key.length)throw Error("Output Taproot BIP 32 keypath key is not 33 bytes");const xonly=keyVal.key.slice(1).toString("hex"),leafHashs=new Set;reader=new bufferutils_1.BufferReader(keyVal.value);const num_hashs=reader.readVarInt();for(let i=0;i<num_hashs;i++)leafHashs.add(reader.readSlice(32).toString("hex"));output.tapBip32Paths[xonly]={leafHashs,Bip32Derivation:keyVal.value.slice(reader.offset)};break;default:output.unknownKeyVals||(output.unknownKeyVals=[]),output.unknownKeyVals.push(keyVal)}}outputs.push(output)}return{globalMap,inputs,outputs}}(unsignedTx,{globalMapKeyVals,inputKeyVals,outputKeyVals})}(buffer,txFromBuffer),psbt=new this(results.globalMap.unsignedTx);return Object.assign(psbt,results),psbt}}function checkKeyBuffer(type,keyBuf,keyNum){if(!keyBuf.equals(Buffer.from([keyNum])))throw Error(`Format Error: Invalid ${type} key: ${keyBuf.toString("hex")}`)}var GlobalTypes,InputTypes,OutputTypes;exports.Psbtv2=Psbtv2,function(GlobalTypes){GlobalTypes[GlobalTypes.UNSIGNED_TX=0]="UNSIGNED_TX",GlobalTypes[GlobalTypes.GLOBAL_XPUB=1]="GLOBAL_XPUB",GlobalTypes[GlobalTypes.GLOBAL_TX_VERSION=2]="GLOBAL_TX_VERSION",GlobalTypes[GlobalTypes.GLOBAL_FALLBACK_LOCKTIME=3]="GLOBAL_FALLBACK_LOCKTIME",GlobalTypes[GlobalTypes.GLOBAL_INPUT_COUNT=4]="GLOBAL_INPUT_COUNT",GlobalTypes[GlobalTypes.GLOBAL_OUTPUT_COUNT=5]="GLOBAL_OUTPUT_COUNT",GlobalTypes[GlobalTypes.GLOBAL_TXMODIFIABLE=6]="GLOBAL_TXMODIFIABLE",GlobalTypes[GlobalTypes.GLOBAL_VERSION=251]="GLOBAL_VERSION"}(GlobalTypes||(GlobalTypes={})),function(InputTypes){InputTypes[InputTypes.NON_WITNESS_UTXO=0]="NON_WITNESS_UTXO",InputTypes[InputTypes.WITNESS_UTXO=1]="WITNESS_UTXO",InputTypes[InputTypes.PARTIAL_SIG=2]="PARTIAL_SIG",InputTypes[InputTypes.SIGHASH_TYPE=3]="SIGHASH_TYPE",InputTypes[InputTypes.REDEEM_SCRIPT=4]="REDEEM_SCRIPT",InputTypes[InputTypes.WITNESS_SCRIPT=5]="WITNESS_SCRIPT",InputTypes[InputTypes.BIP32_DERIVATION=6]="BIP32_DERIVATION",InputTypes[InputTypes.FINAL_SCRIPTSIG=7]="FINAL_SCRIPTSIG",InputTypes[InputTypes.FINAL_SCRIPTWITNESS=8]="FINAL_SCRIPTWITNESS",InputTypes[InputTypes.POR_COMMITMENT=9]="POR_COMMITMENT",InputTypes[InputTypes.PREVIOUS_TXID=14]="PREVIOUS_TXID",InputTypes[InputTypes.OUTPUT_INDEX=15]="OUTPUT_INDEX",InputTypes[InputTypes.SEQUENCE=16]="SEQUENCE",InputTypes[InputTypes.REQUIRED_TIME_LOCKTIME=17]="REQUIRED_TIME_LOCKTIME",InputTypes[InputTypes.REQUIRED_HEIGHT_LOCKTIME=18]="REQUIRED_HEIGHT_LOCKTIME",InputTypes[InputTypes.TAP_KEY_SIG=19]="TAP_KEY_SIG",InputTypes[InputTypes.TAP_SCRIPT_SIG=20]="TAP_SCRIPT_SIG",InputTypes[InputTypes.TAP_LEAF_SCRIPT=21]="TAP_LEAF_SCRIPT",InputTypes[InputTypes.TAP_BIP32_DERIVATION=22]="TAP_BIP32_DERIVATION",InputTypes[InputTypes.TAP_INTERNAL_KEY=23]="TAP_INTERNAL_KEY",InputTypes[InputTypes.TAP_MERKLE_ROOT=24]="TAP_MERKLE_ROOT"}(InputTypes||(InputTypes={})),function(OutputTypes){OutputTypes[OutputTypes.REDEEM_SCRIPT=0]="REDEEM_SCRIPT",OutputTypes[OutputTypes.WITNESS_SCRIPT=1]="WITNESS_SCRIPT",OutputTypes[OutputTypes.BIP32_DERIVATION=2]="BIP32_DERIVATION",OutputTypes[OutputTypes.AMOUNT=3]="AMOUNT",OutputTypes[OutputTypes.SCRIPT=4]="SCRIPT",OutputTypes[OutputTypes.TAP_INTERNAL_KEY=5]="TAP_INTERNAL_KEY",OutputTypes[OutputTypes.TAP_TREE=6]="TAP_TREE",OutputTypes[OutputTypes.TAP_BIP32_DERIVATION=7]="TAP_BIP32_DERIVATION"}(OutputTypes||(OutputTypes={})); |
@@ -0,1 +1,18 @@ | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
/// <reference types="node" /> | ||
@@ -2,0 +19,0 @@ import { PaymentBTC, CoinType } from './payment'; |
@@ -1,1 +0,18 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.CoinType=exports.PaymentBCH=void 0;const e=require("cashaddrjs"),r=require("./payment");Object.defineProperty(exports,"CoinType",{enumerable:!0,get:function(){return r.CoinType}});const t=require("./interface");class o extends r.PaymentBTC{static CoinSupported(e){if(e!==r.CoinType.BITCOINCASH)throw Error("Not supported cointype")}static p2pkh(o,s){if(this.CoinSupported(o),!s.publickey&&!s.hash)throw Error("Invalid Parameters");if(s.publickey&&s.hash)throw Error("Invalid Parameters");const i=s.hash?s.hash:(0,r.Hash160)(s.publickey);null===r.logger||void 0===r.logger||r.logger.info(`publickey hash: ${i.toString("hex")}`);let c=e.encode("bitcoincash","P2PKH",i);c=c.split(":")[1];const n=Buffer.from([t.OPCODES.OP_DUP,t.OPCODES.OP_HASH160,20]),h=Buffer.from([t.OPCODES.OP_EQUALVERIFY,t.OPCODES.OP_CHECKSIG]),a=Buffer.concat([n,i,h]),p=(0,r.Hash160)(a);return null===r.logger||void 0===r.logger||r.logger.info(`redeem hash: ${p.toString("hex")}`),{address:c,scriptPublickey:a,redeemHash:p}}static p2sh(r,o){this.CoinSupported(r);let s=e.encode("bitcoincash","P2SH",o);s=s.split(":")[1];const i=Buffer.from([t.OPCODES.OP_HASH160,20]),c=Buffer.from([t.OPCODES.OP_EQUAL]);return{address:s,scriptPublickey:Buffer.concat([i,o,c])}}static decode(r,t){if(t.startsWith("1")){const e=this.bs58check.decode(t),s=Buffer.from(e.slice(1));return o.p2pkh(r,{hash:s}).scriptPublickey}{t=function(e){return/^(?:bitcoincash|bchtest):q.+/.test(e)}(t)?t:`bitcoincash:${t}`;const{hash:s,type:i}=e.decode(t);return"P2SH"===i?o.p2sh(r,Buffer.from(s)).scriptPublickey:o.p2pkh(r,{hash:Buffer.from(s)}).scriptPublickey}}}exports.PaymentBCH=o; | ||
"use strict"; | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/Object.defineProperty(exports,"__esModule",{value:!0}),exports.CoinType=exports.PaymentBCH=void 0;const cashaddr=require("cashaddrjs"),payment_1=require("./payment");Object.defineProperty(exports,"CoinType",{enumerable:!0,get:function(){return payment_1.CoinType}});const interface_1=require("./interface");class PaymentBCH extends payment_1.PaymentBTC{static CoinSupported(coin){if(coin!==payment_1.CoinType.BITCOINCASH)throw Error("Not supported cointype")}static p2pkh(coin,opt){if(this.CoinSupported(coin),!opt.publickey&&!opt.hash)throw Error("Invalid Parameters");if(opt.publickey&&opt.hash)throw Error("Invalid Parameters");const pkHash=opt.hash?opt.hash:(0,payment_1.Hash160)(opt.publickey);null===payment_1.logger||void 0===payment_1.logger||payment_1.logger.info(`publickey hash: ${pkHash.toString("hex")}`);let address=cashaddr.encode("bitcoincash","P2PKH",pkHash);address=address.split(":")[1];const op=Buffer.from([interface_1.OPCODES.OP_DUP,interface_1.OPCODES.OP_HASH160,20]),check=Buffer.from([interface_1.OPCODES.OP_EQUALVERIFY,interface_1.OPCODES.OP_CHECKSIG]),scriptPublickey=Buffer.concat([op,pkHash,check]),redeemHash=(0,payment_1.Hash160)(scriptPublickey);return null===payment_1.logger||void 0===payment_1.logger||payment_1.logger.info(`redeem hash: ${redeemHash.toString("hex")}`),{address,scriptPublickey,redeemHash}}static p2sh(coin,redeemHash){this.CoinSupported(coin);let address=cashaddr.encode("bitcoincash","P2SH",redeemHash);address=address.split(":")[1];const op=Buffer.from([interface_1.OPCODES.OP_HASH160,20]),check=Buffer.from([interface_1.OPCODES.OP_EQUAL]);return{address,scriptPublickey:Buffer.concat([op,redeemHash,check])}}static decode(coin,address){if(address.startsWith("1")){const hash160=this.bs58check.decode(address),hash=Buffer.from(hash160.slice(1));return PaymentBCH.p2pkh(coin,{hash}).scriptPublickey}{address=function(address){return/^(?:bitcoincash|bchtest):q.+/.test(address)}(address)?address:`bitcoincash:${address}`;const{hash,type}=cashaddr.decode(address);return"P2SH"===type?PaymentBCH.p2sh(coin,Buffer.from(hash)).scriptPublickey:PaymentBCH.p2pkh(coin,{hash:Buffer.from(hash)}).scriptPublickey}}}exports.PaymentBCH=PaymentBCH; |
@@ -0,1 +1,18 @@ | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
import { PaymentBTC, CoinType } from './payment'; | ||
@@ -2,0 +19,0 @@ import { bs58Check } from "@secux/utility/lib/bs58"; |
@@ -1,1 +0,18 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.CoinType=exports.PaymentGRS=void 0;const e=require("./payment");Object.defineProperty(exports,"CoinType",{enumerable:!0,get:function(){return e.CoinType}});const t=require("@secux/utility/lib/bs58"),r=require("groestl-hash-js");class o extends e.PaymentBTC{static CoinSupported(t){if(t!==e.CoinType.GROESTL)throw Error("Not supported cointype")}}exports.PaymentGRS=o,o.bs58check=new t.bs58Check((function(e){return Buffer.from(r.groestl_2(e,1,1))})); | ||
"use strict"; | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/Object.defineProperty(exports,"__esModule",{value:!0}),exports.CoinType=exports.PaymentGRS=void 0;const payment_1=require("./payment");Object.defineProperty(exports,"CoinType",{enumerable:!0,get:function(){return payment_1.CoinType}});const bs58_1=require("@secux/utility/lib/bs58"),groestl=require("groestl-hash-js");class PaymentGRS extends payment_1.PaymentBTC{static CoinSupported(coin){if(coin!==payment_1.CoinType.GROESTL)throw Error("Not supported cointype")}}exports.PaymentGRS=PaymentGRS,PaymentGRS.bs58check=new bs58_1.bs58Check((function(data){return Buffer.from(groestl.groestl_2(data,1,1))})); |
@@ -0,1 +1,18 @@ | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
/// <reference types="node" /> | ||
@@ -2,0 +19,0 @@ import { CoinType, ScriptType } from './interface'; |
@@ -1,1 +0,18 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.logger=exports.Hash160=exports.CoinType=exports.PaymentBTC=void 0;const e=require("bech32"),r=require("hash.js"),t=require("./interface");Object.defineProperty(exports,"CoinType",{enumerable:!0,get:function(){return t.CoinType}});const o=require("@secux/utility/lib/bs58"),s=require("@secux/utility"),i=require("./utils");exports.logger=null===s.Logger||void 0===s.Logger?void 0:s.Logger.child({id:"payment"});class c{static CoinSupported(e){if(e===t.CoinType.BITCOINCASH)throw Error("Please use class PaymentBCH instead");if(e===t.CoinType.GROESTL)throw Error("Please use class PaymentGRS instead")}static p2pkh(e,r){if(this.CoinSupported(e),!r.publickey&&!r.hash)throw Error("Invalid Parameters");if(r.publickey&&r.hash)throw Error("Invalid Parameters");const o=r.hash?r.hash:n(r.publickey);null===exports.logger||void 0===exports.logger||exports.logger.info(`publickey hash: ${o.toString("hex")}`);const s=t.coinmap[e],i=this.bs58check.encode(o,Buffer.from([s.pubKeyHash])),c=Buffer.from([t.OPCODES.OP_DUP,t.OPCODES.OP_HASH160,20]),h=Buffer.from([t.OPCODES.OP_EQUALVERIFY,t.OPCODES.OP_CHECKSIG]),u=Buffer.concat([c,o,h]),a=n(u);return null===exports.logger||void 0===exports.logger||exports.logger.info(`redeem hash: ${a.toString("hex")}`),{address:i,scriptPublickey:u,redeemHash:a}}static p2sh(e,r){this.CoinSupported(e);const o=t.coinmap[e],s=this.bs58check.encode(r,Buffer.from([o.scriptHash])),i=Buffer.from([t.OPCODES.OP_HASH160,20]),c=Buffer.from([t.OPCODES.OP_EQUAL]);return{address:s,scriptPublickey:Buffer.concat([i,r,c])}}static p2wpkh(r,o){if(this.CoinSupported(r),!o.publickey&&!o.hash)throw Error("Invalid Parameters");if(o.publickey&&o.hash)throw Error("Invalid Parameters");const s=o.hash?o.hash:n(o.publickey);null===exports.logger||void 0===exports.logger||exports.logger.info(`publickey hash: ${s.toString("hex")}`);let i=t.coinmap[r];const c=e.bech32.toWords(s);c.unshift(0);const h=e.bech32.encode(i.bech32,c),u=Buffer.from([t.OPCODES.OP_0,20]),a=Buffer.concat([u,s]),p=n(a);return null===exports.logger||void 0===exports.logger||exports.logger.info(`redeem hash: ${p.toString("hex")}`),{address:h,scriptPublickey:a,redeemHash:p}}static p2ms(e,r){if(e<=0)throw Error('Invalid paramter "m"');e+=t.OPCODES.OP_INT_BASE;const o=r.length+t.OPCODES.OP_INT_BASE,s=Buffer.concat(r),i=Buffer.concat([Buffer.from([e]),s,Buffer.from([o]),Buffer.from([t.OPCODES.OP_CHECKMULTISIG])]),c=n(i);null===exports.logger||void 0===exports.logger||exports.logger.info(`redeem hash: ${c.toString("hex")}`);const h=Buffer.from([t.OPCODES.OP_HASH160,20]),u=Buffer.from([t.OPCODES.OP_EQUAL]);return{redeem:i,scriptPubicKey:Buffer.concat([h,c,u])}}static p2tr(r,o){if(this.CoinSupported(r),!o.publickey&&!o.hash)throw Error("Invalid Parameters");if(o.publickey&&o.hash)throw Error("Invalid Parameters");let s=o.hash;void 0===s&&(s=(0,i.toTweakedPublickey)(o.publickey));const c=t.coinmap[r],n=e.bech32.toWords(s);n.unshift(1);const h=e.bech32m.encode(c.bech32,n),u=Buffer.from([81,32]);return{address:h,scriptPublickey:Buffer.concat([u,s])}}static decode(r,o){const s=t.coinmap[r];if(s.bech32&&o.startsWith(s.bech32)){let t;if("p"===o.slice(s.bech32.length+1)[0])t=e.bech32m.decode(o);else t=e.bech32.decode(o);const i=t.words.shift();switch(i){case 0:const s=Buffer.from(e.bech32.fromWords(t.words));return null===exports.logger||void 0===exports.logger||exports.logger.debug(`bech32 address: ${o}\nbech32 decoded: ${s.toString("hex")}`),this.p2wpkh(r,{hash:s}).scriptPublickey;case 1:const c=Buffer.from(e.bech32m.fromWords(t.words));return null===exports.logger||void 0===exports.logger||exports.logger.debug(`bech32m address: ${o}\nbech32m decoded: ${c.toString("hex")}`),this.p2tr(r,{hash:c}).scriptPublickey;default:throw Error(`ArgumentError: unsupported witness version, got "${i}" from address "${o}"`)}}try{const e=this.bs58check.decode(o),t=e[0],i=e.slice(1);if(t===s.scriptHash)return this.p2sh(r,i).scriptPublickey;if(t===s.pubKeyHash)return this.p2pkh(r,{hash:i}).scriptPublickey}catch(e){null===exports.logger||void 0===exports.logger||exports.logger.debug(`${e.toString()}, cointype: ${t.CoinType[r]}, address: ${o}`)}throw Error(`ArgumentError: invalid address for ${t.CoinType[r]}, got ${o}`)}static classify(e){if(this.isP2WPKH(e))return t.ScriptType.P2WPKH;if(this.isP2PKH(e))return t.ScriptType.P2PKH;if(this.isP2TR(e))return t.ScriptType.P2TR;throw Error(`non-standard script: ${e.toString("hex")}`)}static isP2PKH(e){return 25===e.length&&e[0]===t.OPCODES.OP_DUP&&e[1]===t.OPCODES.OP_HASH160&&20===e[2]&&e[23]===t.OPCODES.OP_EQUALVERIFY&&e[24]===t.OPCODES.OP_CHECKSIG}static isP2SH(e){return 23===e.length&&e[0]===t.OPCODES.OP_HASH160&&20===e[1]&&e[22]===t.OPCODES.OP_EQUAL}static isP2WPKH(e){return 22===e.length&&e[0]===t.OPCODES.OP_0&&20===e[1]}static isP2TR(e){return 34===e.length&&81===e[0]&&32===e[1]}}function n(e){const t=Buffer.from((0,r.sha256)().update(e).digest());return Buffer.from((0,r.ripemd160)().update(t).digest())}exports.PaymentBTC=c,c.bs58check=new o.bs58Check((function(e){const t=(0,r.sha256)().update(e).digest(),o=(0,r.sha256)().update(t).digest();return Buffer.from(o)})),exports.Hash160=n; | ||
"use strict"; | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/Object.defineProperty(exports,"__esModule",{value:!0}),exports.logger=exports.Hash160=exports.CoinType=exports.PaymentBTC=void 0;const bech32_1=require("bech32"),hash_js_1=require("hash.js"),interface_1=require("./interface");Object.defineProperty(exports,"CoinType",{enumerable:!0,get:function(){return interface_1.CoinType}});const bs58_1=require("@secux/utility/lib/bs58"),utility_1=require("@secux/utility"),utils_1=require("./utils");exports.logger=null===utility_1.Logger||void 0===utility_1.Logger?void 0:utility_1.Logger.child({id:"payment"});class PaymentBTC{static CoinSupported(coin){if(coin===interface_1.CoinType.BITCOINCASH)throw Error("Please use class PaymentBCH instead");if(coin===interface_1.CoinType.GROESTL)throw Error("Please use class PaymentGRS instead")}static p2pkh(coin,opt){if(this.CoinSupported(coin),!opt.publickey&&!opt.hash)throw Error("Invalid Parameters");if(opt.publickey&&opt.hash)throw Error("Invalid Parameters");const pkHash=opt.hash?opt.hash:Hash160(opt.publickey);null===exports.logger||void 0===exports.logger||exports.logger.info(`publickey hash: ${pkHash.toString("hex")}`);const network=interface_1.coinmap[coin],address=this.bs58check.encode(pkHash,Buffer.from([network.pubKeyHash])),op=Buffer.from([interface_1.OPCODES.OP_DUP,interface_1.OPCODES.OP_HASH160,20]),check=Buffer.from([interface_1.OPCODES.OP_EQUALVERIFY,interface_1.OPCODES.OP_CHECKSIG]),scriptPublickey=Buffer.concat([op,pkHash,check]),redeemHash=Hash160(scriptPublickey);return null===exports.logger||void 0===exports.logger||exports.logger.info(`redeem hash: ${redeemHash.toString("hex")}`),{address,scriptPublickey,redeemHash}}static p2sh(coin,redeemHash){this.CoinSupported(coin);const network=interface_1.coinmap[coin],address=this.bs58check.encode(redeemHash,Buffer.from([network.scriptHash])),op=Buffer.from([interface_1.OPCODES.OP_HASH160,20]),check=Buffer.from([interface_1.OPCODES.OP_EQUAL]);return{address,scriptPublickey:Buffer.concat([op,redeemHash,check])}}static p2wpkh(coin,opt){if(this.CoinSupported(coin),!opt.publickey&&!opt.hash)throw Error("Invalid Parameters");if(opt.publickey&&opt.hash)throw Error("Invalid Parameters");const pkHash=opt.hash?opt.hash:Hash160(opt.publickey);null===exports.logger||void 0===exports.logger||exports.logger.info(`publickey hash: ${pkHash.toString("hex")}`);let network=interface_1.coinmap[coin];const words=bech32_1.bech32.toWords(pkHash);words.unshift(0);const address=bech32_1.bech32.encode(network.bech32,words),op=Buffer.from([interface_1.OPCODES.OP_0,20]),scriptPublickey=Buffer.concat([op,pkHash]),redeemHash=Hash160(scriptPublickey);return null===exports.logger||void 0===exports.logger||exports.logger.info(`redeem hash: ${redeemHash.toString("hex")}`),{address,scriptPublickey,redeemHash}}static p2ms(m,publickeys){if(m<=0)throw Error('Invalid paramter "m"');m+=interface_1.OPCODES.OP_INT_BASE;const n=publickeys.length+interface_1.OPCODES.OP_INT_BASE,multi_pk=Buffer.concat(publickeys),redeem=Buffer.concat([Buffer.from([m]),multi_pk,Buffer.from([n]),Buffer.from([interface_1.OPCODES.OP_CHECKMULTISIG])]),redeemHash=Hash160(redeem);null===exports.logger||void 0===exports.logger||exports.logger.info(`redeem hash: ${redeemHash.toString("hex")}`);const op=Buffer.from([interface_1.OPCODES.OP_HASH160,20]),check=Buffer.from([interface_1.OPCODES.OP_EQUAL]);return{redeem,scriptPubicKey:Buffer.concat([op,redeemHash,check])}}static p2tr(coin,opt){if(this.CoinSupported(coin),!opt.publickey&&!opt.hash)throw Error("Invalid Parameters");if(opt.publickey&&opt.hash)throw Error("Invalid Parameters");let tweaked=opt.hash;void 0===tweaked&&(tweaked=(0,utils_1.toTweakedPublickey)(opt.publickey));const network=interface_1.coinmap[coin],words=bech32_1.bech32.toWords(tweaked);words.unshift(1);const address=bech32_1.bech32m.encode(network.bech32,words),header=Buffer.from([81,32]);return{address,scriptPublickey:Buffer.concat([header,tweaked])}}static decode(coin,address){const network=interface_1.coinmap[coin];if(network.bech32&&address.startsWith(network.bech32)){let result;if("p"===address.slice(network.bech32.length+1)[0])result=bech32_1.bech32m.decode(address);else result=bech32_1.bech32.decode(address);const version=result.words.shift();switch(version){case 0:const hash160=Buffer.from(bech32_1.bech32.fromWords(result.words));return null===exports.logger||void 0===exports.logger||exports.logger.debug(`bech32 address: ${address}\nbech32 decoded: ${hash160.toString("hex")}`),this.p2wpkh(coin,{hash:hash160}).scriptPublickey;case 1:const tweaked=Buffer.from(bech32_1.bech32m.fromWords(result.words));return null===exports.logger||void 0===exports.logger||exports.logger.debug(`bech32m address: ${address}\nbech32m decoded: ${tweaked.toString("hex")}`),this.p2tr(coin,{hash:tweaked}).scriptPublickey;default:throw Error(`ArgumentError: unsupported witness version, got "${version}" from address "${address}"`)}}try{const hash160=this.bs58check.decode(address),prefix=hash160[0],hash=hash160.slice(1);if(prefix===network.scriptHash)return this.p2sh(coin,hash).scriptPublickey;if(prefix===network.pubKeyHash)return this.p2pkh(coin,{hash}).scriptPublickey}catch(error){null===exports.logger||void 0===exports.logger||exports.logger.debug(`${error.toString()}, cointype: ${interface_1.CoinType[coin]}, address: ${address}`)}throw Error(`ArgumentError: invalid address for ${interface_1.CoinType[coin]}, got ${address}`)}static classify(script){if(this.isP2WPKH(script))return interface_1.ScriptType.P2WPKH;if(this.isP2PKH(script))return interface_1.ScriptType.P2PKH;if(this.isP2TR(script))return interface_1.ScriptType.P2TR;throw Error(`non-standard script: ${script.toString("hex")}`)}static isP2PKH(script){return 25===script.length&&script[0]===interface_1.OPCODES.OP_DUP&&script[1]===interface_1.OPCODES.OP_HASH160&&20===script[2]&&script[23]===interface_1.OPCODES.OP_EQUALVERIFY&&script[24]===interface_1.OPCODES.OP_CHECKSIG}static isP2SH(script){return 23===script.length&&script[0]===interface_1.OPCODES.OP_HASH160&&20===script[1]&&script[22]===interface_1.OPCODES.OP_EQUAL}static isP2WPKH(script){return 22===script.length&&script[0]===interface_1.OPCODES.OP_0&&20===script[1]}static isP2TR(script){return 34===script.length&&81===script[0]&&32===script[1]}}function Hash160(publickey){const sha=Buffer.from((0,hash_js_1.sha256)().update(publickey).digest());return Buffer.from((0,hash_js_1.ripemd160)().update(sha).digest())}exports.PaymentBTC=PaymentBTC,PaymentBTC.bs58check=new bs58_1.bs58Check((function(data){const sha1=(0,hash_js_1.sha256)().update(data).digest(),sha2=(0,hash_js_1.sha256)().update(sha1).digest();return Buffer.from(sha2)})),exports.Hash160=Hash160; |
@@ -0,1 +1,18 @@ | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
/// <reference types="node" /> | ||
@@ -2,0 +19,0 @@ import { Psbtv2 } from "./parser"; |
@@ -1,1 +0,18 @@ | ||
"use strict";var t,e,i,s,r,n,o,p,a,u,c,h,f,l=this&&this.__classPrivateFieldSet||function(t,e,i,s,r){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!r)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!r:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?r.call(t,i):r?r.value=i:e.set(t,i),i},d=this&&this.__classPrivateFieldGet||function(t,e,i,s){if("a"===i&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?s:"a"===i?s.call(t):s?s.value:e.get(t)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.SecuxPsbt=void 0;const S=require("bip174/src/lib/utils"),g=require("secp256k1/elliptic"),y=require("hash.js"),P=require("bignumber.js"),m=require("./parser"),w=require("./script"),b=require("@secux/utility"),T=require("./interface"),k=require("./utils"),v=require("./payment"),H=require("./transaction"),E=require("./coindef"),x=require("@secux/utility/lib/communication"),I=require("@secux/protocol-transaction/lib/protocol-transaction"),W=require("./bip340"),B=null===b.Logger||void 0===b.Logger?void 0:b.Logger.child({id:"psbt"});class ${constructor(a,u=!1,c=new m.Psbtv2(new _)){t.add(this),e.set(this,void 0),i.set(this,void 0),s.set(this,void 0),r.set(this,void 0),n.set(this,void 0),o.set(this,[]),p.set(this,{}),l(this,e,c,"f"),l(this,i,a,"f"),l(this,s,(0,k.getPayment)(d(this,i,"f")),"f"),l(this,n,u,"f"),l(this,r,d(this,e,"f").globalMap.unsignedTx.tx,"f"),a===T.CoinType.BITCOINCASH&&(d(this,r,"f").version=1)}static FromBuffer(t,e){const i=m.Psbtv2.fromBuffer(t,(t=>new _(t)));return new $(e,!1,i)}AddInput(t){var r;if(!(0,b.isSupportedCoin)(t.path))throw Error(`ArgumentError: unsupport bip32 path, got "${t.path}"`);const p={},a={},u=(0,k.getPublickey)(t.publickey),c=null!==(r=t.script)&&void 0!==r?r:(0,k.getDefaultScript)(t.path),h=new P.BigNumber(t.satoshis).toNumber();switch(c){case T.ScriptType.P2PKH:p.witnessUtxo={script:d(this,s,"f").p2pkh(d(this,i,"f"),{publickey:u}).scriptPublickey,value:h};break;case T.ScriptType.P2SH_P2PKH:const t=d(this,s,"f").p2pkh(d(this,i,"f"),{publickey:u});a.redeemScript=t.scriptPublickey,p.witnessUtxo={script:d(this,s,"f").p2sh(d(this,i,"f"),t.redeemHash).scriptPublickey,value:h};break;case T.ScriptType.P2SH_P2WPKH:const r=d(this,s,"f").p2wpkh(d(this,i,"f"),{publickey:u});a.redeemScript=r.scriptPublickey,p.witnessUtxo={script:d(this,s,"f").p2sh(d(this,i,"f"),r.redeemHash).scriptPublickey,value:h};break;case T.ScriptType.P2WPKH:p.witnessUtxo={script:d(this,s,"f").p2wpkh(d(this,i,"f"),{publickey:u}).scriptPublickey,value:h};break;case T.ScriptType.P2TR:p.witnessUtxo={script:d(this,s,"f").p2tr(d(this,i,"f"),{publickey:u}).scriptPublickey,value:h};break;default:throw Error(`ArgumentError: Invalid ScriptType of input#${d(this,e,"f").inputs.length}, got "${T.ScriptType[c]}"`)}if(t.txHex){const s=H.Transaction.fromBuffer(Buffer.from(t.txHex,"hex"));if((0,k.getSerializer)(d(this,i,"f")).getId(s)!==t.hash)throw Error(`UTXO hash for input #${d(this,e,"f").inputs.length} doesn't match the hash specified in the prevout`);const r=s.outs[t.vout];if(!new P.BigNumber(r.value).eq(t.satoshis))throw Error(`UTXO value for input #${d(this,e,"f").inputs.length} doesn't match the value specified in the prevout`);r.script.equals(p.witnessUtxo.script)||null==B||B.warn(`Input script generation error: ${r.script.toString("hex")}, got "${p.witnessUtxo.script}"`)}const f=Object.assign(Object.assign({hash:t.hash,index:t.vout,sequence:d(this,n,"f")?4294967293:void 0},p),a);return d(this,e,"f").addInput(f),d(this,o,"f").push(t.path),this}AddInputs(t){for(const e of t)this.AddInput(e);return this}AddOutput(t){var r;let n,o,p,a=new P.BigNumber(t.satoshis).toNumber();if(n=(0,T.isOutuptScriptExtended)(t)){const t=(0,k.getPublickey)(n.publickey);p=n.path;const a=null!==(r=n.script)&&void 0!==r?r:(0,k.getDefaultScript)(p);let u,c;switch(a){case T.ScriptType.P2SH_P2WPKH:if(!n.path.startsWith("m/49'/"))throw Error("P2SH(...) should use m/49' path");u=d(this,s,"f").p2wpkh(d(this,i,"f"),{publickey:t}).redeemHash,c=d(this,s,"f").p2sh(d(this,i,"f"),u),o=c.scriptPublickey;break;case T.ScriptType.P2SH_P2PKH:if(!n.path.startsWith("m/49'/"))throw Error("P2SH(...) should use m/49' path");u=d(this,s,"f").p2pkh(d(this,i,"f"),{publickey:t}).redeemHash,c=d(this,s,"f").p2sh(d(this,i,"f"),u),o=c.scriptPublickey;break;case T.ScriptType.P2PKH:if(!n.path.startsWith("m/44'/"))throw Error("P2PKH should use m/44' path");o=d(this,s,"f").p2pkh(d(this,i,"f"),{publickey:t}).scriptPublickey;break;case T.ScriptType.P2WPKH:if(!n.path.startsWith("m/84'/"))throw Error("P2WPKH should use m/84' path");o=d(this,s,"f").p2wpkh(d(this,i,"f"),{publickey:t}).scriptPublickey;break;case T.ScriptType.P2TR:if(!n.path.startsWith("m/86'/"))throw Error("P2TR should use m/86' path");o=d(this,s,"f").p2tr(d(this,i,"f"),{publickey:t}).scriptPublickey;break;default:throw Error(`ArgumentError: Invalid ScriptType of output#${d(this,e,"f").outputs.length}, got "${T.ScriptType[a]}"`)}}else if(n=(0,T.isOutputAddress)(t))o=d(this,s,"f").decode(d(this,i,"f"),n.address);else{if(!(n=(0,T.isOutuptScript)(t)))throw Error("Invalid parameter of output");o=Buffer.from(n.scriptHex,"hex")}return d(this,e,"f").addOutput({script:o,value:a,path:p}),this}AddOutputs(t){for(const e of t)this.AddOutput(e);return this}PrepareSign(s){if(s){const i=d(this,t,"m",h).call(this),n=Math.round(i*s);null==B||B.info(`Estimated fee is ${n}, with ${s} fee rates.`);const o=d(this,e,"f").inputs.reduce(((t,e)=>t+e.witnessUtxo.value),0),p=d(this,r,"f").outs[0].value,a=1===d(this,e,"f").outputs.length?0:d(this,r,"f").outs[1].value,u=o-p-a;if(u<n&&(null==B||B.warn(`Estimated fee is ${n}, but got ${u}.`)),u>n||u<i)if(0!==a){const t=o-p-n;if(t<0)throw Error(`Insufficient amount, expect ${p+n}, but got ${o}.`);d(this,r,"f").outs[1].value=t,null==B||B.info(`Modify change amount from ${a} to ${t}.`)}else{const t=o-n;if(t<0)throw Error(`Insufficient amount, expect at least ${n}, but got ${o}.`);d(this,r,"f").outs[0].value=t,null==B||B.info(`Modify spend amount from ${p} to ${t}.`)}}const n=Buffer.from([d(this,e,"f").outputs.length,...(0,b.BigIntToBuffer)(d(this,r,"f").outs[0].value,8),d(this,r,"f").outs[0].script.length,...d(this,r,"f").outs[0].script,...d(this,r,"f").outs.slice(1).reduce(((t,e)=>[...t,...(0,b.BigIntToBuffer)(e.value,8),...(0,b.buildPathBuffer)(e.path).pathBuffer]),[])]),p=d(this,e,"f").inputs.map(((e,i)=>{const s=d(this,t,"m",u).call(this,i);if(null==B||B.debug(`tx data [${i}]: ${s.toString("hex")}`),s.length+x.MAX_HEAD_SIZE>x.ONESIGN_THRESHOLD)throw Error("ArgumentError: utxo exceed maximum payload size");return s}));null==B||B.debug(`confirm data: ${n.toString("hex")}`);const c=[];let f=[],l=[],S=d(this,i,"f")!==T.CoinType.BITCOINCASH&&d(this,t,"m",a).call(this,0).type===T.ScriptType.P2PKH?Buffer.alloc(0):n;for(let e=0,s=0;e<p.length;e++){if(s+=p[e].length+x.MAX_HEAD_SIZE,f.push(p[e]),l.push(d(this,o,"f")[e]),s+S.length<x.ONESIGN_THRESHOLD)continue;f.pop(),l.pop(),c.push(I.SecuxTransactionTool.signRawTransactionList(l,f,S)),s=p[e].length+25,f=[p[e]],l=[d(this,o,"f")[e]];const{type:r}=d(this,t,"m",a).call(this,e);S=d(this,i,"f")!==T.CoinType.BITCOINCASH&&r===T.ScriptType.P2PKH?Buffer.alloc(0):n}return f.length>0&&c.push(I.SecuxTransactionTool.signRawTransactionList(l,f,S)),{commands:c,rawTx:d(this,e,"f").toHex()}}appendSignature(s,r){var n,o;if(s.length!==r.length)throw Error(`ArgumentError: each signature is correspond to one publickey, got ${s.length} signatures and ${r.length} publickeys`);for(let p=0;p<d(this,e,"f").inputs.length;p++){const c=d(this,t,"m",u).call(this,p);if(d(this,t,"m",a).call(this,p).type!==T.ScriptType.P2TR){const t=d(this,i,"f")===T.CoinType.GROESTL?Buffer.from((0,y.sha256)().update(c).digest()):Buffer.from((0,y.sha256)().update((0,y.sha256)().update(c).digest()).digest()),o=r[p];if(!g.ecdsaVerify(s[p],t,o))throw Error(`Signature Error #${p}`);let a=null!==(n=d(this,e,"f").inputs[p].sighashType)&&void 0!==n?n:H.Transaction.SIGHASH_ALL;d(this,i,"f")===T.CoinType.BITCOINCASH&&(a|=64);const u=[{pubkey:o,signature:w.encode(s[p],a)}];d(this,e,"f").updateInput(p,{partialSig:u})}else{const t=(0,k.taggedHash)("TapSighash",c),i=(0,k.toTweakedPublickey)(r[p]),n=s[p].slice(0,64);if(!(0,W.taprootVerify)(n,t,i))throw Error(`Signature Error #${p}`);const a=null!==(o=d(this,e,"f").inputs[p].sighashType)&&void 0!==o?o:H.Transaction.SIGHASH_DEFAULT;d(this,e,"f").inputs[p].partialSig=[{pubkey:i,signature:a===H.Transaction.SIGHASH_DEFAULT?n:Buffer.from([a,...n])}]}}return this}finalizeAllInputs(){if(d(this,e,"f").inputs.length<1)throw Error("utxo input cannot be empty");return d(this,e,"f").inputs.forEach(((t,s)=>{(0,S.checkForInput)(d(this,e,"f").inputs,s);const{script:r,scriptType:n}=A(t,d(this,i,"f"));if(!r)throw new Error(`No script found for input #${s}`);if(t.sighashType&&t.partialSig){const{partialSig:e,sighashType:i}=t;for(const t of e){const{hashType:e}=w.decode(t.signature);if(e!==i)throw new Error("Signature sighash does not match input sighash type")}}const{finalScriptSig:o,finalScriptWitness:p}=function(t,e){let i,s;const{signature:r,pubkey:n}=e[0];switch(t){case T.ScriptType.P2PKH:i=w.compile([r,n]);break;case T.ScriptType.P2SH_P2PKH:i=(()=>{const t=w.compile([r,n]),e=w.decompile(t),i={output:e[e.length-1],input:w.compile(e.slice(0,-1))};return w.compile([].concat(w.decompile(i.input),i.output))})();break;case T.ScriptType.P2SH_P2WPKH:s=(0,k.witnessStackToScriptWitness)([r,n]),i=(()=>{const t=Buffer.alloc(0),e=(0,v.Hash160)(n),i=w.compile([E.OPCODES.OP_0,e]);return w.compile([].concat(w.decompile(t),i))})();break;case T.ScriptType.P2WPKH:s=(0,k.witnessStackToScriptWitness)([r,n]);break;case T.ScriptType.P2TR:s=r}return{finalScriptSig:i,finalScriptWitness:s}}(n,t.partialSig);if(o&&d(this,e,"f").updateInput(s,{finalScriptSig:o}),p&&d(this,e,"f").updateInput(s,{finalScriptWitness:p}),!o&&!p)throw new Error(`Unknown error finalizing input #${s}`)})),this}extractTransaction(){const i=d(this,r,"f").clone();d(this,e,"f").inputs.forEach(((e,s)=>d(this,t,"m",c).call(this,i,s,e)));const s=d(this,e,"f").inputs.reduce(((t,e)=>t.plus(e.witnessUtxo.value)),new P.BigNumber(0)),n=i.outs.reduce(((t,e)=>t.plus(e.value)),new P.BigNumber(0)),o=s.minus(n),p=i.virtualSize();if(o.lt(p))throw Error(`Transaction fee must >= ${p}, but got ${o}.`);return i}}function A(t,e){let i,s;const r=(0,k.getPayment)(e);if(t.witnessScript)i=t.witnessScript;else if(t.redeemScript)switch(i=t.redeemScript,s=r.classify(i),s){case T.ScriptType.P2PKH:s=T.ScriptType.P2SH_P2PKH;break;case T.ScriptType.P2WPKH:s=T.ScriptType.P2SH_P2WPKH}else i=t.witnessUtxo.script,s=r.classify(i);return{script:i,scriptType:s}}exports.SecuxPsbt=$,e=new WeakMap,i=new WeakMap,s=new WeakMap,r=new WeakMap,n=new WeakMap,o=new WeakMap,p=new WeakMap,t=new WeakSet,a=function(t){if(d(this,p,"f")[t])return d(this,p,"f")[t];const s=d(this,e,"f").inputs[t],r=s.witnessUtxo,n=A(s,d(this,i,"f")).scriptType,o=function(t,e,i,s){let r;switch(e){case T.ScriptType.P2SH_P2PKH:case T.ScriptType.P2SH_P2WPKH:if(!i)throw Error("scriptPubkey is P2SH but redeemScript missing");r=i;break;default:r=t}if(!r)throw Error("cannot extract script");return r}(r.script,n,s.redeemScript,s.witnessScript);null==B||B.debug(`input #${t} script type: ${T.ScriptType[n]}`),null==B||B.debug(`script: ${o.toString("hex")}`);const a={type:n,scriptPubkey:o};return d(this,p,"f")[t]=a,a},u=function(s){var n,o;const p=d(this,e,"f").inputs[s],u=d(this,r,"f");let c=null!==(n=p.sighashType)&&void 0!==n?n:H.Transaction.SIGHASH_ALL;const h=(0,k.getSerializer)(d(this,i,"f"));void 0===p.witnessUtxo&&Error("Need a Utxo input item for signing");const f=p.witnessUtxo,{type:l,scriptPubkey:S}=d(this,t,"m",a).call(this,s);let g;switch(l){case T.ScriptType.P2WPKH:case T.ScriptType.P2SH_P2WPKH:case T.ScriptType.P2SH_P2PKH:null==B||B.debug(T.ScriptType[l]);const r=(0,k.getPayment)(d(this,i,"f")).p2pkh(d(this,i,"f"),{hash:S.slice(2)}).scriptPublickey;g=h.dataForWitnessV0(u,s,r,f.value,c);break;case T.ScriptType.P2TR:null==B||B.debug("p2tr"),c=null!==(o=p.sighashType)&&void 0!==o?o:H.Transaction.SIGHASH_DEFAULT,g=h.dataForWitnessV1(u,s,d(this,e,"f").inputs.map(((e,i)=>d(this,t,"m",a).call(this,i).scriptPubkey)),d(this,e,"f").inputs.map((t=>t.witnessUtxo.value)),c);break;default:d(this,i,"f")===T.CoinType.BITCOINCASH?(null==B||B.debug("bch using bip143"),g=h.dataForWitnessV0(u,s,S,f.value,64|c)):(null==B||B.debug("non-segwit"),g=h.dataForSignature(u,s,S,c))}return g},c=function(e,i,s){if(!s.finalScriptSig&&!s.finalScriptWitness)throw Error(`input#${i} not finalized.`);s.finalScriptSig&&(e.ins[i].script=s.finalScriptSig),s.finalScriptWitness&&(d(this,t,"m",a).call(this,i).type!==T.ScriptType.P2TR?e.ins[i].witness=(0,k.scriptWitnessToWitnessStack)(s.finalScriptWitness):e.ins[i].witness=[s.finalScriptWitness])},h=function(){const i=d(this,r,"f").clone();let s=0,n=2;return d(this,e,"f").inputs.forEach(((e,i)=>{const{type:r}=d(this,t,"m",a).call(this,i);s+=(0,k.getInScriptSize)(r);const o=(0,k.getWitnessSize)(r,e.sighashType);n+=(0,k.vectorSize)(o)})),i.virtualSize()+s+n/4};class _{constructor(t=Buffer.from([2,0,0,0,0,0,0,0,0,0])){f.set(this,void 0),l(this,f,H.Transaction.fromBuffer(t),"f")}getInputOutputCounts(){return{inputCount:d(this,f,"f").ins.length,outputCount:d(this,f,"f").outs.length}}addInput(t){if(void 0===t.hash||void 0===t.index||!Buffer.isBuffer(t.hash)&&"string"!=typeof t.hash||"number"!=typeof t.index)throw new Error("Error adding input.");const e="string"==typeof t.hash?Buffer.from(Buffer.from(t.hash,"hex").reverse()):t.hash;d(this,f,"f").addInput(e,t.index,t.sequence)}addOutput(t){if(void 0===t.script||void 0===t.value||!Buffer.isBuffer(t.script)||"number"!=typeof t.value)throw new Error("Error adding output.");d(this,f,"f").addOutput(t.script,t.value,t.path)}toBuffer(){return d(this,f,"f").toBuffer()}get tx(){return d(this,f,"f")}}f=new WeakMap; | ||
"use strict"; | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
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_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){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[0].value,change=1===__classPrivateFieldGet(this,_SecuxPsbt_data,"f").outputs.length?0:__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs[1].value,actualFee=total-spend-change;if(actualFee<estimateFee&&(null==logger||logger.warn(`Estimated fee is ${estimateFee}, but got ${actualFee}.`)),actualFee>estimateFee||actualFee<vSize)if(0!==change){const value=total-spend-estimateFee;if(value<0)throw Error(`Insufficient amount, expect ${spend+estimateFee}, but got ${total}.`);__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs[1].value=value,null==logger||logger.info(`Modify change amount from ${change} to ${value}.`)}else{const value=total-estimateFee;if(value<0)throw Error(`Insufficient amount, expect at least ${estimateFee}, but got ${total}.`);__classPrivateFieldGet(this,_SecuxPsbt_tx,"f").outs[0].value=value,null==logger||logger.info(`Modify spend amount from ${spend} 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; |
@@ -0,1 +1,18 @@ | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
/// <reference types="node" /> | ||
@@ -2,0 +19,0 @@ export declare function compile(chunks: any[]): Buffer | undefined; |
@@ -1,1 +0,18 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.encode=exports.decode=exports.decompile=exports.compile=void 0;const e=require("bip66"),t=require("./coindef"),n=require("@secux/utility"),r=Buffer.alloc(1,0),o=null===n.Logger||void 0===n.Logger?void 0:n.Logger.child({id:"script"});function i(e){let t=0;for(;0===e[t];)++t;return t===e.length?r:128&(e=e.slice(t))[0]?Buffer.concat([r,e],1+e.length):e}function c(e){0===e[0]&&(e=e.slice(1));const t=Buffer.alloc(32,0),n=Math.max(0,32-e.length);return e.copy(t,n),t}function l(e){return 0===e.length?t.OPCODES.OP_0:1===e.length?e[0]>=1&&e[0]<=16?t.OPCODES.OP_INT_BASE+e[0]:129===e[0]?t.OPCODES.OP_1NEGATE:void 0:void 0}exports.compile=function(e){const t=e.reduce(((e,t)=>Buffer.isBuffer(t)?1===t.length&&void 0!==l(t)?e+1:e+u.encodingLength(t.length)+t.length:e+1),0),n=Buffer.allocUnsafe(t);let r=0;for(const t of e)if(Buffer.isBuffer(t)){const e=l(t);if(void 0!==e)return n.writeUInt8(e,r),void(r+=1);r+=u.encode(n,t.length,r),t.copy(n,r),r+=t.length}else n.writeUInt8(t,r),r+=1;if(r!==n.length)throw new Error("Could not decode chunks");return n},exports.decompile=function(e){const n=[];let r=0;for(;r<e.length;){const i=e[r];if(i>t.OPCODES.OP_0&&i<=t.OPCODES.OP_PUSHDATA4){const t=u.decode(e,r);if(null===t)return null==o||o.warn(`decompile error: reading a pushDataInt fail, got ${e.toString("binary")}, index:${r}`),[];if(r+=t.size,r+t.number>e.length)return null==o||o.warn(`decompile error: attempt to read too much data, got ${e.slice(r).toString("binary")}, desired length:${t.number}`),[];const i=e.slice(r,r+t.number);r+=t.number;const c=l(i);void 0!==c?n.push(c):n.push(i)}else n.push(i),r+=1}return n},exports.decode=function(t){const n=t.readUInt8(t.length-1),r=-129&n;if(r<=0||r>=4)throw new Error("Invalid hashType "+n);const o=e.decode(t.slice(0,-1)),i=c(o.r),l=c(o.s);return{signature:Buffer.concat([i,l],64),hashType:n}},exports.encode=function(t,n){const r=Buffer.allocUnsafe(1);r.writeUInt8(n,0);const o=i(t.slice(0,32)),c=i(t.slice(32,64));return Buffer.concat([e.encode(o,c),r])};class u{static encodingLength(e){return e<t.OPCODES.OP_PUSHDATA1?1:e<=255?2:e<=65535?3:5}static encode(e,n,r){var o=this.encodingLength(n);return 1===o?e.writeUInt8(n,r):2===o?(e.writeUInt8(t.OPCODES.OP_PUSHDATA1,r),e.writeUInt8(n,r+1)):3===o?(e.writeUInt8(t.OPCODES.OP_PUSHDATA2,r),e.writeUInt16LE(n,r+1)):(e.writeUInt8(t.OPCODES.OP_PUSHDATA4,r),e.writeUInt32LE(n,r+1)),o}static decode(e,n){var r,o,i=e.readUInt8(n);if(i<t.OPCODES.OP_PUSHDATA1)r=i,o=1;else if(i===t.OPCODES.OP_PUSHDATA1){if(n+2>e.length)return null;r=e.readUInt8(n+1),o=2}else if(i===t.OPCODES.OP_PUSHDATA2){if(n+3>e.length)return null;r=e.readUInt16LE(n+1),o=3}else{if(n+5>e.length)return null;if(i!==t.OPCODES.OP_PUSHDATA4)throw new Error("Unexpected opcode");r=e.readUInt32LE(n+1),o=5}return{opcode:i,number:r,size:o}}} | ||
"use strict"; | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/Object.defineProperty(exports,"__esModule",{value:!0}),exports.encode=exports.decode=exports.decompile=exports.compile=void 0;const bip66=require("bip66"),coindef_1=require("./coindef"),utility_1=require("@secux/utility"),ZERO=Buffer.alloc(1,0),logger=null===utility_1.Logger||void 0===utility_1.Logger?void 0:utility_1.Logger.child({id:"script"});function toDER(x){let i=0;for(;0===x[i];)++i;return i===x.length?ZERO:128&(x=x.slice(i))[0]?Buffer.concat([ZERO,x],1+x.length):x}function fromDER(x){0===x[0]&&(x=x.slice(1));const buffer=Buffer.alloc(32,0),bstart=Math.max(0,32-x.length);return x.copy(buffer,bstart),buffer}function asMinimalOP(buffer){return 0===buffer.length?coindef_1.OPCODES.OP_0:1===buffer.length?buffer[0]>=1&&buffer[0]<=16?coindef_1.OPCODES.OP_INT_BASE+buffer[0]:129===buffer[0]?coindef_1.OPCODES.OP_1NEGATE:void 0:void 0}exports.compile=function(chunks){const bufferSize=chunks.reduce(((accum,chunk)=>Buffer.isBuffer(chunk)?1===chunk.length&&void 0!==asMinimalOP(chunk)?accum+1:accum+pushdata.encodingLength(chunk.length)+chunk.length:accum+1),0),buffer=Buffer.allocUnsafe(bufferSize);let offset=0;for(const chunk of chunks)if(Buffer.isBuffer(chunk)){const opcode=asMinimalOP(chunk);if(void 0!==opcode)return buffer.writeUInt8(opcode,offset),void(offset+=1);offset+=pushdata.encode(buffer,chunk.length,offset),chunk.copy(buffer,offset),offset+=chunk.length}else buffer.writeUInt8(chunk,offset),offset+=1;if(offset!==buffer.length)throw new Error("Could not decode chunks");return buffer},exports.decompile=function(buffer){const chunks=[];let i=0;for(;i<buffer.length;){const opcode=buffer[i];if(opcode>coindef_1.OPCODES.OP_0&&opcode<=coindef_1.OPCODES.OP_PUSHDATA4){const d=pushdata.decode(buffer,i);if(null===d)return null==logger||logger.warn(`decompile error: reading a pushDataInt fail, got ${buffer.toString("binary")}, index:${i}`),[];if(i+=d.size,i+d.number>buffer.length)return null==logger||logger.warn(`decompile error: attempt to read too much data, got ${buffer.slice(i).toString("binary")}, desired length:${d.number}`),[];const data=buffer.slice(i,i+d.number);i+=d.number;const op=asMinimalOP(data);void 0!==op?chunks.push(op):chunks.push(data)}else chunks.push(opcode),i+=1}return chunks},exports.decode=function(buffer){const hashType=buffer.readUInt8(buffer.length-1),hashTypeMod=-129&hashType;if(hashTypeMod<=0||hashTypeMod>=4)throw new Error("Invalid hashType "+hashType);const decoded=bip66.decode(buffer.slice(0,-1)),r=fromDER(decoded.r),s=fromDER(decoded.s);return{signature:Buffer.concat([r,s],64),hashType}},exports.encode=function(signature,hashType){const hashTypeBuffer=Buffer.allocUnsafe(1);hashTypeBuffer.writeUInt8(hashType,0);const r=toDER(signature.slice(0,32)),s=toDER(signature.slice(32,64));return Buffer.concat([bip66.encode(r,s),hashTypeBuffer])};class pushdata{static encodingLength(i){return i<coindef_1.OPCODES.OP_PUSHDATA1?1:i<=255?2:i<=65535?3:5}static encode(buffer,number,offset){var size=this.encodingLength(number);return 1===size?buffer.writeUInt8(number,offset):2===size?(buffer.writeUInt8(coindef_1.OPCODES.OP_PUSHDATA1,offset),buffer.writeUInt8(number,offset+1)):3===size?(buffer.writeUInt8(coindef_1.OPCODES.OP_PUSHDATA2,offset),buffer.writeUInt16LE(number,offset+1)):(buffer.writeUInt8(coindef_1.OPCODES.OP_PUSHDATA4,offset),buffer.writeUInt32LE(number,offset+1)),size}static decode(buffer,offset){var number,size,opcode=buffer.readUInt8(offset);if(opcode<coindef_1.OPCODES.OP_PUSHDATA1)number=opcode,size=1;else if(opcode===coindef_1.OPCODES.OP_PUSHDATA1){if(offset+2>buffer.length)return null;number=buffer.readUInt8(offset+1),size=2}else if(opcode===coindef_1.OPCODES.OP_PUSHDATA2){if(offset+3>buffer.length)return null;number=buffer.readUInt16LE(offset+1),size=3}else{if(offset+5>buffer.length)return null;if(opcode!==coindef_1.OPCODES.OP_PUSHDATA4)throw new Error("Unexpected opcode");number=buffer.readUInt32LE(offset+1),size=5}return{opcode,number,size}}} |
@@ -0,1 +1,18 @@ | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
/// <reference types="node" /> | ||
@@ -2,0 +19,0 @@ import { Transaction } from "./transaction"; |
@@ -1,1 +0,18 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.TransactionGRS=void 0;const e=require("hash.js"),r=require("./transaction"),t=require("./bufferutils"),i=Buffer.from("0000000000000000000000000000000000000000000000000000000000000000","hex");class s extends r.Transaction{static dataForWitnessV0(s,n,a,f,c){let o,u=Buffer.from([]),l=i,S=i,w=i;if(c&r.Transaction.SIGHASH_ANYONECANPAY||(u=Buffer.allocUnsafe(36*s.ins.length),o=new t.BufferWriter(u,0),s.ins.forEach((e=>{o.writeSlice(e.hash),o.writeUInt32(e.index)})),S=Buffer.from((0,e.sha256)().update(u).digest())),c&r.Transaction.SIGHASH_ANYONECANPAY||(31&c)===r.Transaction.SIGHASH_SINGLE||(31&c)===r.Transaction.SIGHASH_NONE||(u=Buffer.allocUnsafe(4*s.ins.length),o=new t.BufferWriter(u,0),s.ins.forEach((e=>{o.writeUInt32(e.sequence)})),w=Buffer.from((0,e.sha256)().update(u).digest())),(31&c)!==r.Transaction.SIGHASH_SINGLE&&(31&c)!==r.Transaction.SIGHASH_NONE){const i=s.outs.reduce(((e,t)=>e+8+(0,r.varSliceSize)(t.script)),0);u=Buffer.allocUnsafe(i),o=new t.BufferWriter(u,0),s.outs.forEach((e=>{o.writeUInt64(e.value),o.writeVarSlice(e.script)})),l=Buffer.from((0,e.sha256)().update(u).digest())}else if((31&c)===r.Transaction.SIGHASH_SINGLE&&n<s.outs.length){const i=s.outs[n];u=Buffer.allocUnsafe(8+(0,r.varSliceSize)(i.script)),o=new t.BufferWriter(u,0),o.writeUInt64(i.value),o.writeVarSlice(i.script),l=Buffer.from((0,e.sha256)().update(u).digest())}u=Buffer.allocUnsafe(156+(0,r.varSliceSize)(a)),o=new t.BufferWriter(u,0);const d=s.ins[n];return o.writeUInt32(s.version),o.writeSlice(S),o.writeSlice(w),o.writeSlice(d.hash),o.writeUInt32(d.index),o.writeVarSlice(a),o.writeUInt64(f),o.writeUInt32(d.sequence),o.writeSlice(l),o.writeUInt32(s.locktime),o.writeUInt32(c),u}static getHash(r,t){if(t&&r.isCoinbase())return Buffer.alloc(32,0);const i=r.toBuffer(void 0,void 0,t);return Buffer.from((0,e.sha256)().update(i).digest())}}exports.TransactionGRS=s; | ||
"use strict"; | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/Object.defineProperty(exports,"__esModule",{value:!0}),exports.TransactionGRS=void 0;const hash_js_1=require("hash.js"),transaction_1=require("./transaction"),bufferutils_1=require("./bufferutils"),ZERO=Buffer.from("0000000000000000000000000000000000000000000000000000000000000000","hex");class TransactionGRS extends transaction_1.Transaction{static dataForWitnessV0(trans,inIndex,prevOutScript,value,hashType){let bufferWriter,tbuffer=Buffer.from([]),hashOutputs=ZERO,hashPrevouts=ZERO,hashSequence=ZERO;if(hashType&transaction_1.Transaction.SIGHASH_ANYONECANPAY||(tbuffer=Buffer.allocUnsafe(36*trans.ins.length),bufferWriter=new bufferutils_1.BufferWriter(tbuffer,0),trans.ins.forEach((txIn=>{bufferWriter.writeSlice(txIn.hash),bufferWriter.writeUInt32(txIn.index)})),hashPrevouts=Buffer.from((0,hash_js_1.sha256)().update(tbuffer).digest())),hashType&transaction_1.Transaction.SIGHASH_ANYONECANPAY||(31&hashType)===transaction_1.Transaction.SIGHASH_SINGLE||(31&hashType)===transaction_1.Transaction.SIGHASH_NONE||(tbuffer=Buffer.allocUnsafe(4*trans.ins.length),bufferWriter=new bufferutils_1.BufferWriter(tbuffer,0),trans.ins.forEach((txIn=>{bufferWriter.writeUInt32(txIn.sequence)})),hashSequence=Buffer.from((0,hash_js_1.sha256)().update(tbuffer).digest())),(31&hashType)!==transaction_1.Transaction.SIGHASH_SINGLE&&(31&hashType)!==transaction_1.Transaction.SIGHASH_NONE){const txOutsSize=trans.outs.reduce(((sum,output)=>sum+8+(0,transaction_1.varSliceSize)(output.script)),0);tbuffer=Buffer.allocUnsafe(txOutsSize),bufferWriter=new bufferutils_1.BufferWriter(tbuffer,0),trans.outs.forEach((out=>{bufferWriter.writeUInt64(out.value),bufferWriter.writeVarSlice(out.script)})),hashOutputs=Buffer.from((0,hash_js_1.sha256)().update(tbuffer).digest())}else if((31&hashType)===transaction_1.Transaction.SIGHASH_SINGLE&&inIndex<trans.outs.length){const output=trans.outs[inIndex];tbuffer=Buffer.allocUnsafe(8+(0,transaction_1.varSliceSize)(output.script)),bufferWriter=new bufferutils_1.BufferWriter(tbuffer,0),bufferWriter.writeUInt64(output.value),bufferWriter.writeVarSlice(output.script),hashOutputs=Buffer.from((0,hash_js_1.sha256)().update(tbuffer).digest())}tbuffer=Buffer.allocUnsafe(156+(0,transaction_1.varSliceSize)(prevOutScript)),bufferWriter=new bufferutils_1.BufferWriter(tbuffer,0);const input=trans.ins[inIndex];return bufferWriter.writeUInt32(trans.version),bufferWriter.writeSlice(hashPrevouts),bufferWriter.writeSlice(hashSequence),bufferWriter.writeSlice(input.hash),bufferWriter.writeUInt32(input.index),bufferWriter.writeVarSlice(prevOutScript),bufferWriter.writeUInt64(value),bufferWriter.writeUInt32(input.sequence),bufferWriter.writeSlice(hashOutputs),bufferWriter.writeUInt32(trans.locktime),bufferWriter.writeUInt32(hashType),tbuffer}static getHash(trans,forWitness){if(forWitness&&trans.isCoinbase())return Buffer.alloc(32,0);const data=trans.toBuffer(void 0,void 0,forWitness);return Buffer.from((0,hash_js_1.sha256)().update(data).digest())}}exports.TransactionGRS=TransactionGRS; |
@@ -0,1 +1,18 @@ | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
/// <reference types="node" /> | ||
@@ -2,0 +19,0 @@ import { BigNumber } from "bignumber.js"; |
@@ -1,1 +0,18 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.varSliceSize=exports.Transaction=void 0;const e=require("hash.js"),t=require("varuint-bitcoin"),r=require("./bufferutils"),i=require("./script"),n=require("./coindef"),s=require("@secux/utility"),u=null===s.Logger||void 0===s.Logger?void 0:s.Logger.child({id:"transaction"}),o=Buffer.from("0000000000000000000000000000000000000000000000000000000000000000","hex"),f=Buffer.from("0000000000000000000000000000000000000000000000000000000000000001","hex"),c=Buffer.alloc(0),l=Buffer.from("ffffffffffffffff","hex"),a={script:c,valueBuffer:l,value:0};class h{constructor(){this.ins=[],this.outs=[],this.version=2,this.locktime=0}static fromBuffer(e){const t=new r.BufferReader(e),i=new h;i.version=t.readInt32();const n=t.readUInt8(),s=t.readUInt8();let u=!1;n===h.ADVANCED_TRANSACTION_MARKER&&s===h.ADVANCED_TRANSACTION_FLAG?u=!0:t.offset-=2;const o=t.readVarInt();for(let e=0;e<o;++e)i.ins.push({hash:t.readSlice(32),index:t.readUInt32(),script:t.readVarSlice(),sequence:t.readUInt32(),witness:[]});const f=t.readVarInt();for(let e=0;e<f;++e)i.outs.push({value:t.readUInt64(),script:t.readVarSlice()});if(u){for(let e=0;e<o;++e)i.ins[e].witness=t.readVector();if(!i.hasWitnesses())throw new Error("Transaction has superfluous witness data")}if(i.locktime=t.readUInt32(),t.offset!==e.length)throw new Error("Transaction has unexpected data");return i}static dataForSignature(e,t,r,s){if(t>=e.ins.length)return f;const u=i.compile(i.decompile(r).filter((e=>e!==n.OPCODES.OP_CODESEPARATOR))),o=e.clone();if((31&s)===h.SIGHASH_NONE)o.outs=[],o.ins.forEach(((e,r)=>{r!==t&&(e.sequence=0)}));else if((31&s)===h.SIGHASH_SINGLE){if(t>=e.outs.length)return f;o.outs.length=t+1;for(let e=0;e<t;e++)o.outs[e]=a;o.ins.forEach(((e,r)=>{r!==t&&(e.sequence=0)}))}s&h.SIGHASH_ANYONECANPAY?(o.ins=[o.ins[t]],o.ins[0].script=u):(o.ins.forEach((e=>{e.script=c})),o.ins[t].script=u);const l=Buffer.allocUnsafe(o.byteLength(!1)+4);return l.writeInt32LE(s,l.length-4),o.toBuffer(l,0,!1),l}static dataForWitnessV0(e,t,i,n,s){let f,c=Buffer.from([]),l=o,a=o,S=o;if(null==u||u.debug("begin dataForWitnessV0"),null==u||u.debug(`hashType: 0x${s.toString(16)}`),s&h.SIGHASH_ANYONECANPAY||(c=Buffer.allocUnsafe(36*e.ins.length),f=new r.BufferWriter(c,0),e.ins.forEach((e=>{f.writeSlice(e.hash),f.writeUInt32(e.index)})),a=w(c)),s&h.SIGHASH_ANYONECANPAY||(31&s)===h.SIGHASH_SINGLE||(31&s)===h.SIGHASH_NONE||(c=Buffer.allocUnsafe(4*e.ins.length),f=new r.BufferWriter(c,0),e.ins.forEach((e=>{f.writeUInt32(e.sequence)})),S=w(c)),(31&s)!==h.SIGHASH_SINGLE&&(31&s)!==h.SIGHASH_NONE){const t=e.outs.reduce(((e,t)=>e+8+I(t.script)),0);c=Buffer.allocUnsafe(t),f=new r.BufferWriter(c,0),e.outs.forEach((e=>{f.writeUInt64(e.value),f.writeVarSlice(e.script)})),null==u||u.debug(`outputs: ${c.toString("hex")}`),l=w(c)}else if((31&s)===h.SIGHASH_SINGLE&&t<e.outs.length){const i=e.outs[t];c=Buffer.allocUnsafe(8+I(i.script)),f=new r.BufferWriter(c,0),f.writeUInt64(i.value),f.writeVarSlice(i.script),null==u||u.debug(`single output: ${c.toString("hex")}`),l=w(c)}c=Buffer.allocUnsafe(156+I(i)),f=new r.BufferWriter(c,0);const d=e.ins[t];return f.writeUInt32(e.version),f.writeSlice(a),f.writeSlice(S),f.writeSlice(d.hash),f.writeUInt32(d.index),f.writeVarSlice(i),f.writeUInt64(n),f.writeUInt32(d.sequence),f.writeSlice(l),f.writeUInt32(e.locktime),f.writeUInt32(s),null==u||u.debug("end dataForWitnessV0"),c}static dataForWitnessV1(e,t,i,n,s,o,f){if(n.length!==e.ins.length||i.length!==e.ins.length)throw new Error("Must supply prevout script and value for all inputs");const l=s===h.SIGHASH_DEFAULT?h.SIGHASH_ALL:s&h.SIGHASH_OUTPUT_MASK,a=(s&h.SIGHASH_INPUT_MASK)===h.SIGHASH_ANYONECANPAY,w=l===h.SIGHASH_NONE,d=l===h.SIGHASH_SINGLE;let A=c,g=c,p=c,E=c,U=c;if(null==u||u.debug("begin dataForWitnessV1"),null==u||u.debug(`hashType: 0x${s.toString(16)}`),!a){let t=Buffer.alloc(36*e.ins.length),s=new r.BufferWriter(t);e.ins.forEach((e=>{s.writeSlice(e.hash),s.writeUInt32(e.index)})),A=S(t),t=Buffer.alloc(8*e.ins.length),s=new r.BufferWriter(t),n.forEach((e=>s.writeUInt64(e))),g=S(t),t=Buffer.alloc(i.map(I).reduce(((e,t)=>e+t))),s=new r.BufferWriter(t),i.forEach((e=>s.writeVarSlice(e))),p=S(t),t=Buffer.alloc(4*e.ins.length),s=new r.BufferWriter(t),e.ins.forEach((e=>s.writeUInt32(e.sequence))),E=S(t)}if(w||d){if(d&&t<e.outs.length){const i=e.outs[t],n=Buffer.alloc(8+I(i.script)),s=new r.BufferWriter(n);s.writeUInt64(i.value),s.writeVarSlice(i.script),null==u||u.debug(`single output: ${n.toString("hex")}`),U=S(n)}}else{const t=e.outs.map((e=>8+I(e.script))).reduce(((e,t)=>e+t)),i=Buffer.alloc(t),n=new r.BufferWriter(i);e.outs.forEach((e=>{n.writeUInt64(e.value),n.writeVarSlice(e.script)})),null==u||u.debug(`outputs: ${i.toString("hex")}`),U=S(i)}const N=(o?2:0)+(f?1:0),H=174-(a?49:0)-(w?32:0)+(f?32:0)+(o?37:0),B=Buffer.alloc(H),_=new r.BufferWriter(B);if(_.writeUInt8(s),_.writeInt32(e.version),_.writeUInt32(e.locktime),_.writeSlice(A),_.writeSlice(g),_.writeSlice(p),_.writeSlice(E),w||d||_.writeSlice(U),_.writeUInt8(N),a){const r=e.ins[t];_.writeSlice(r.hash),_.writeUInt32(r.index),_.writeUInt64(n[t]),_.writeVarSlice(i[t]),_.writeUInt32(r.sequence)}else _.writeUInt32(t);if(f){const e=Buffer.alloc(I(f));new r.BufferWriter(e).writeVarSlice(f),_.writeSlice(S(e))}return d&&_.writeSlice(U),o&&(_.writeSlice(o),_.writeUInt8(0),_.writeUInt32(4294967295)),null==u||u.debug("end dataForWitnessV1"),Buffer.concat([Buffer.from([0]),B])}static getHash(e,t){return t&&e.isCoinbase()?Buffer.alloc(32,0):w(e.toBuffer(void 0,void 0,t))}static getId(e){return this.getHash(e).reverse().toString("hex")}addInput(e,t,r,i){r&&0!==r||(r=h.DEFAULT_SEQUENCE),this.ins.push({hash:e,index:t,script:null!=i?i:c,sequence:r,witness:[]})}addOutput(e,t,r){this.outs.push({script:e,value:t,path:r})}toBuffer(e,t,i=!1){e||(e=Buffer.allocUnsafe(this.byteLength(i)));const n=new r.BufferWriter(e,null!=t?t:0);n.writeInt32(this.version);const s=i&&this.hasWitnesses();return s&&(n.writeUInt8(h.ADVANCED_TRANSACTION_MARKER),n.writeUInt8(h.ADVANCED_TRANSACTION_FLAG)),n.writeVarInt(this.ins.length),this.ins.forEach((e=>{n.writeSlice(e.hash),n.writeUInt32(e.index),n.writeVarSlice(e.script),n.writeUInt32(e.sequence)})),n.writeVarInt(this.outs.length),this.outs.forEach((e=>{void 0!==e.value?n.writeUInt64(e.value):n.writeSlice(e.valueBuffer),n.writeVarSlice(e.script)})),s&&this.ins.forEach((e=>{n.writeVector(e.witness)})),n.writeUInt32(this.locktime),void 0!==t?e.slice(t,n.offset):e}toHex(){return this.toBuffer(void 0,void 0,!0).toString("hex")}hasWitnesses(){return this.ins.some((e=>0!==e.witness.length))}isCoinbase(){if(1!==this.ins.length)return!1;const e=this.ins[0].hash;for(let t=0;t<32;++t)if(0!==e[t])return!1;return!0}clone(){const e=new h;return e.version=this.version,e.locktime=this.locktime,e.ins=this.ins.map((e=>({hash:e.hash,index:e.index,script:e.script,sequence:e.sequence,witness:e.witness}))),e.outs=this.outs.map((e=>({script:e.script,value:e.value}))),e}weight(){return 3*this.byteLength(!1)+this.byteLength(!0)}virtualSize(){return Math.ceil(this.weight()/4)}byteLength(e=!0){const r=e&&this.hasWitnesses();return(r?10:8)+t.encodingLength(this.ins.length)+t.encodingLength(this.outs.length)+this.ins.reduce(((e,t)=>e+40+I(t.script)),0)+this.outs.reduce(((e,t)=>e+8+I(t.script)),0)+(r?this.ins.reduce(((e,r)=>e+function(e){const r=e.length;return t.encodingLength(r)+e.reduce(((e,t)=>e+I(t)),0)}(r.witness)),0):0)}}function S(t){return Buffer.from((0,e.sha256)().update(t).digest())}function w(t){const r=(0,e.sha256)().update(t).digest(),i=(0,e.sha256)().update(r).digest();return Buffer.from(i)}function I(e){const r=e.length;return t.encodingLength(r)+r}exports.Transaction=h,h.DEFAULT_SEQUENCE=4294967295,h.SIGHASH_DEFAULT=0,h.SIGHASH_ALL=1,h.SIGHASH_NONE=2,h.SIGHASH_SINGLE=3,h.SIGHASH_ANYONECANPAY=128,h.SIGHASH_OUTPUT_MASK=3,h.SIGHASH_INPUT_MASK=128,h.ADVANCED_TRANSACTION_MARKER=0,h.ADVANCED_TRANSACTION_FLAG=1,exports.varSliceSize=I; | ||
"use strict"; | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/Object.defineProperty(exports,"__esModule",{value:!0}),exports.varSliceSize=exports.Transaction=void 0;const hash_js_1=require("hash.js"),varuint=require("varuint-bitcoin"),bufferutils_1=require("./bufferutils"),Script=require("./script"),coindef_1=require("./coindef"),utility_1=require("@secux/utility"),logger=null===utility_1.Logger||void 0===utility_1.Logger?void 0:utility_1.Logger.child({id:"transaction"}),ZERO=Buffer.from("0000000000000000000000000000000000000000000000000000000000000000","hex"),ONE=Buffer.from("0000000000000000000000000000000000000000000000000000000000000001","hex"),EMPTY=Buffer.alloc(0),VALUE_UINT64_MAX=Buffer.from("ffffffffffffffff","hex"),BLANK_OUTPUT={script:EMPTY,valueBuffer:VALUE_UINT64_MAX,value:0};class Transaction{constructor(){this.ins=[],this.outs=[],this.version=2,this.locktime=0}static fromBuffer(buffer){const bufferReader=new bufferutils_1.BufferReader(buffer),tx=new Transaction;tx.version=bufferReader.readInt32();const marker=bufferReader.readUInt8(),flag=bufferReader.readUInt8();let hasWitnesses=!1;marker===Transaction.ADVANCED_TRANSACTION_MARKER&&flag===Transaction.ADVANCED_TRANSACTION_FLAG?hasWitnesses=!0:bufferReader.offset-=2;const vinLen=bufferReader.readVarInt();for(let i=0;i<vinLen;++i)tx.ins.push({hash:bufferReader.readSlice(32),index:bufferReader.readUInt32(),script:bufferReader.readVarSlice(),sequence:bufferReader.readUInt32(),witness:[]});const voutLen=bufferReader.readVarInt();for(let i=0;i<voutLen;++i)tx.outs.push({value:bufferReader.readUInt64(),script:bufferReader.readVarSlice()});if(hasWitnesses){for(let i=0;i<vinLen;++i)tx.ins[i].witness=bufferReader.readVector();if(!tx.hasWitnesses())throw new Error("Transaction has superfluous witness data")}if(tx.locktime=bufferReader.readUInt32(),bufferReader.offset!==buffer.length)throw new Error("Transaction has unexpected data");return tx}static dataForSignature(trans,inIndex,prevOutScript,hashType){if(inIndex>=trans.ins.length)return ONE;const ourScript=Script.compile(Script.decompile(prevOutScript).filter((x=>x!==coindef_1.OPCODES.OP_CODESEPARATOR))),txTmp=trans.clone();if((31&hashType)===Transaction.SIGHASH_NONE)txTmp.outs=[],txTmp.ins.forEach(((input,i)=>{i!==inIndex&&(input.sequence=0)}));else if((31&hashType)===Transaction.SIGHASH_SINGLE){if(inIndex>=trans.outs.length)return ONE;txTmp.outs.length=inIndex+1;for(let i=0;i<inIndex;i++)txTmp.outs[i]=BLANK_OUTPUT;txTmp.ins.forEach(((input,y)=>{y!==inIndex&&(input.sequence=0)}))}hashType&Transaction.SIGHASH_ANYONECANPAY?(txTmp.ins=[txTmp.ins[inIndex]],txTmp.ins[0].script=ourScript):(txTmp.ins.forEach((input=>{input.script=EMPTY})),txTmp.ins[inIndex].script=ourScript);const buffer=Buffer.allocUnsafe(txTmp.byteLength(!1)+4);return buffer.writeInt32LE(hashType,buffer.length-4),txTmp.toBuffer(buffer,0,!1),buffer}static dataForWitnessV0(trans,inIndex,prevOutScript,value,hashType){let bufferWriter,tbuffer=Buffer.from([]),hashOutputs=ZERO,hashPrevouts=ZERO,hashSequence=ZERO;if(null==logger||logger.debug("begin dataForWitnessV0"),null==logger||logger.debug(`hashType: 0x${hashType.toString(16)}`),hashType&Transaction.SIGHASH_ANYONECANPAY||(tbuffer=Buffer.allocUnsafe(36*trans.ins.length),bufferWriter=new bufferutils_1.BufferWriter(tbuffer,0),trans.ins.forEach((txIn=>{bufferWriter.writeSlice(txIn.hash),bufferWriter.writeUInt32(txIn.index)})),hashPrevouts=hash256(tbuffer)),hashType&Transaction.SIGHASH_ANYONECANPAY||(31&hashType)===Transaction.SIGHASH_SINGLE||(31&hashType)===Transaction.SIGHASH_NONE||(tbuffer=Buffer.allocUnsafe(4*trans.ins.length),bufferWriter=new bufferutils_1.BufferWriter(tbuffer,0),trans.ins.forEach((txIn=>{bufferWriter.writeUInt32(txIn.sequence)})),hashSequence=hash256(tbuffer)),(31&hashType)!==Transaction.SIGHASH_SINGLE&&(31&hashType)!==Transaction.SIGHASH_NONE){const txOutsSize=trans.outs.reduce(((sum,output)=>sum+8+varSliceSize(output.script)),0);tbuffer=Buffer.allocUnsafe(txOutsSize),bufferWriter=new bufferutils_1.BufferWriter(tbuffer,0),trans.outs.forEach((out=>{bufferWriter.writeUInt64(out.value),bufferWriter.writeVarSlice(out.script)})),null==logger||logger.debug(`outputs: ${tbuffer.toString("hex")}`),hashOutputs=hash256(tbuffer)}else if((31&hashType)===Transaction.SIGHASH_SINGLE&&inIndex<trans.outs.length){const output=trans.outs[inIndex];tbuffer=Buffer.allocUnsafe(8+varSliceSize(output.script)),bufferWriter=new bufferutils_1.BufferWriter(tbuffer,0),bufferWriter.writeUInt64(output.value),bufferWriter.writeVarSlice(output.script),null==logger||logger.debug(`single output: ${tbuffer.toString("hex")}`),hashOutputs=hash256(tbuffer)}tbuffer=Buffer.allocUnsafe(156+varSliceSize(prevOutScript)),bufferWriter=new bufferutils_1.BufferWriter(tbuffer,0);const input=trans.ins[inIndex];return bufferWriter.writeUInt32(trans.version),bufferWriter.writeSlice(hashPrevouts),bufferWriter.writeSlice(hashSequence),bufferWriter.writeSlice(input.hash),bufferWriter.writeUInt32(input.index),bufferWriter.writeVarSlice(prevOutScript),bufferWriter.writeUInt64(value),bufferWriter.writeUInt32(input.sequence),bufferWriter.writeSlice(hashOutputs),bufferWriter.writeUInt32(trans.locktime),bufferWriter.writeUInt32(hashType),null==logger||logger.debug("end dataForWitnessV0"),tbuffer}static dataForWitnessV1(trans,inIndex,prevOutScripts,values,hashType,leafHash,annex){if(values.length!==trans.ins.length||prevOutScripts.length!==trans.ins.length)throw new Error("Must supply prevout script and value for all inputs");const outputType=hashType===Transaction.SIGHASH_DEFAULT?Transaction.SIGHASH_ALL:hashType&Transaction.SIGHASH_OUTPUT_MASK,isAnyoneCanPay=(hashType&Transaction.SIGHASH_INPUT_MASK)===Transaction.SIGHASH_ANYONECANPAY,isNone=outputType===Transaction.SIGHASH_NONE,isSingle=outputType===Transaction.SIGHASH_SINGLE;let hashPrevouts=EMPTY,hashAmounts=EMPTY,hashScriptPubKeys=EMPTY,hashSequences=EMPTY,hashOutputs=EMPTY;if(null==logger||logger.debug("begin dataForWitnessV1"),null==logger||logger.debug(`hashType: 0x${hashType.toString(16)}`),!isAnyoneCanPay){let buf=Buffer.alloc(36*trans.ins.length),bufferWriter=new bufferutils_1.BufferWriter(buf);trans.ins.forEach((txIn=>{bufferWriter.writeSlice(txIn.hash),bufferWriter.writeUInt32(txIn.index)})),hashPrevouts=_sha256(buf),buf=Buffer.alloc(8*trans.ins.length),bufferWriter=new bufferutils_1.BufferWriter(buf),values.forEach((value=>bufferWriter.writeUInt64(value))),hashAmounts=_sha256(buf),buf=Buffer.alloc(prevOutScripts.map(varSliceSize).reduce(((a,b)=>a+b))),bufferWriter=new bufferutils_1.BufferWriter(buf),prevOutScripts.forEach((prevOutScript=>bufferWriter.writeVarSlice(prevOutScript))),hashScriptPubKeys=_sha256(buf),buf=Buffer.alloc(4*trans.ins.length),bufferWriter=new bufferutils_1.BufferWriter(buf),trans.ins.forEach((txIn=>bufferWriter.writeUInt32(txIn.sequence))),hashSequences=_sha256(buf)}if(isNone||isSingle){if(isSingle&&inIndex<trans.outs.length){const output=trans.outs[inIndex],buf=Buffer.alloc(8+varSliceSize(output.script)),bufferWriter=new bufferutils_1.BufferWriter(buf);bufferWriter.writeUInt64(output.value),bufferWriter.writeVarSlice(output.script),null==logger||logger.debug(`single output: ${buf.toString("hex")}`),hashOutputs=_sha256(buf)}}else{const txOutsSize=trans.outs.map((output=>8+varSliceSize(output.script))).reduce(((a,b)=>a+b)),buf=Buffer.alloc(txOutsSize),bufferWriter=new bufferutils_1.BufferWriter(buf);trans.outs.forEach((out=>{bufferWriter.writeUInt64(out.value),bufferWriter.writeVarSlice(out.script)})),null==logger||logger.debug(`outputs: ${buf.toString("hex")}`),hashOutputs=_sha256(buf)}const spendType=(leafHash?2:0)+(annex?1:0),sigMsgSize=174-(isAnyoneCanPay?49:0)-(isNone?32:0)+(annex?32:0)+(leafHash?37:0),buf=Buffer.alloc(sigMsgSize),sigMsgWriter=new bufferutils_1.BufferWriter(buf);if(sigMsgWriter.writeUInt8(hashType),sigMsgWriter.writeInt32(trans.version),sigMsgWriter.writeUInt32(trans.locktime),sigMsgWriter.writeSlice(hashPrevouts),sigMsgWriter.writeSlice(hashAmounts),sigMsgWriter.writeSlice(hashScriptPubKeys),sigMsgWriter.writeSlice(hashSequences),isNone||isSingle||sigMsgWriter.writeSlice(hashOutputs),sigMsgWriter.writeUInt8(spendType),isAnyoneCanPay){const input=trans.ins[inIndex];sigMsgWriter.writeSlice(input.hash),sigMsgWriter.writeUInt32(input.index),sigMsgWriter.writeUInt64(values[inIndex]),sigMsgWriter.writeVarSlice(prevOutScripts[inIndex]),sigMsgWriter.writeUInt32(input.sequence)}else sigMsgWriter.writeUInt32(inIndex);if(annex){const buf=Buffer.alloc(varSliceSize(annex));new bufferutils_1.BufferWriter(buf).writeVarSlice(annex),sigMsgWriter.writeSlice(_sha256(buf))}return isSingle&&sigMsgWriter.writeSlice(hashOutputs),leafHash&&(sigMsgWriter.writeSlice(leafHash),sigMsgWriter.writeUInt8(0),sigMsgWriter.writeUInt32(4294967295)),null==logger||logger.debug("end dataForWitnessV1"),Buffer.concat([Buffer.from([0]),buf])}static getHash(trans,forWitness){return forWitness&&trans.isCoinbase()?Buffer.alloc(32,0):hash256(trans.toBuffer(void 0,void 0,forWitness))}static getId(trans){return this.getHash(trans).reverse().toString("hex")}addInput(hash,index,sequence,scriptSig){sequence&&0!==sequence||(sequence=Transaction.DEFAULT_SEQUENCE),this.ins.push({hash,index,script:null!=scriptSig?scriptSig:EMPTY,sequence,witness:[]})}addOutput(scriptPubKey,value,path){this.outs.push({script:scriptPubKey,value,path})}toBuffer(buffer,initialOffset,_ALLOW_WITNESS=!1){buffer||(buffer=Buffer.allocUnsafe(this.byteLength(_ALLOW_WITNESS)));const bufferWriter=new bufferutils_1.BufferWriter(buffer,null!=initialOffset?initialOffset:0);bufferWriter.writeInt32(this.version);const hasWitnesses=_ALLOW_WITNESS&&this.hasWitnesses();return hasWitnesses&&(bufferWriter.writeUInt8(Transaction.ADVANCED_TRANSACTION_MARKER),bufferWriter.writeUInt8(Transaction.ADVANCED_TRANSACTION_FLAG)),bufferWriter.writeVarInt(this.ins.length),this.ins.forEach((txIn=>{bufferWriter.writeSlice(txIn.hash),bufferWriter.writeUInt32(txIn.index),bufferWriter.writeVarSlice(txIn.script),bufferWriter.writeUInt32(txIn.sequence)})),bufferWriter.writeVarInt(this.outs.length),this.outs.forEach((txOut=>{void 0!==txOut.value?bufferWriter.writeUInt64(txOut.value):bufferWriter.writeSlice(txOut.valueBuffer),bufferWriter.writeVarSlice(txOut.script)})),hasWitnesses&&this.ins.forEach((input=>{bufferWriter.writeVector(input.witness)})),bufferWriter.writeUInt32(this.locktime),void 0!==initialOffset?buffer.slice(initialOffset,bufferWriter.offset):buffer}toHex(){return this.toBuffer(void 0,void 0,!0).toString("hex")}hasWitnesses(){return this.ins.some((x=>0!==x.witness.length))}isCoinbase(){if(1!==this.ins.length)return!1;const hash=this.ins[0].hash;for(let i=0;i<32;++i)if(0!==hash[i])return!1;return!0}clone(){const newTx=new Transaction;return newTx.version=this.version,newTx.locktime=this.locktime,newTx.ins=this.ins.map((txIn=>({hash:txIn.hash,index:txIn.index,script:txIn.script,sequence:txIn.sequence,witness:txIn.witness}))),newTx.outs=this.outs.map((txOut=>({script:txOut.script,value:txOut.value}))),newTx}weight(){return 3*this.byteLength(!1)+this.byteLength(!0)}virtualSize(){return Math.ceil(this.weight()/4)}byteLength(_ALLOW_WITNESS=!0){const hasWitnesses=_ALLOW_WITNESS&&this.hasWitnesses();return(hasWitnesses?10:8)+varuint.encodingLength(this.ins.length)+varuint.encodingLength(this.outs.length)+this.ins.reduce(((sum,input)=>sum+40+varSliceSize(input.script)),0)+this.outs.reduce(((sum,output)=>sum+8+varSliceSize(output.script)),0)+(hasWitnesses?this.ins.reduce(((sum,input)=>sum+function(someVector){const length=someVector.length;return varuint.encodingLength(length)+someVector.reduce(((sum,witness)=>sum+varSliceSize(witness)),0)}(input.witness)),0):0)}}function _sha256(data){return Buffer.from((0,hash_js_1.sha256)().update(data).digest())}function hash256(data){const hash1=(0,hash_js_1.sha256)().update(data).digest(),hash2=(0,hash_js_1.sha256)().update(hash1).digest();return Buffer.from(hash2)}function varSliceSize(someScript){const length=someScript.length;return varuint.encodingLength(length)+length}exports.Transaction=Transaction,Transaction.DEFAULT_SEQUENCE=4294967295,Transaction.SIGHASH_DEFAULT=0,Transaction.SIGHASH_ALL=1,Transaction.SIGHASH_NONE=2,Transaction.SIGHASH_SINGLE=3,Transaction.SIGHASH_ANYONECANPAY=128,Transaction.SIGHASH_OUTPUT_MASK=3,Transaction.SIGHASH_INPUT_MASK=128,Transaction.ADVANCED_TRANSACTION_MARKER=0,Transaction.ADVANCED_TRANSACTION_FLAG=1,exports.varSliceSize=varSliceSize; |
@@ -0,1 +1,18 @@ | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
/// <reference types="node" /> | ||
@@ -13,2 +30,3 @@ import { CoinType, ScriptType } from "./interface"; | ||
export declare function getOutScriptSize(type: ScriptType): number; | ||
export declare function getDustThreshold(output: ScriptType, dustRelayFee: number): number; | ||
export declare function sliceSize(size: number): number; | ||
@@ -15,0 +33,0 @@ export declare function vectorSize(sizes: Array<number>): number; |
@@ -1,1 +0,18 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.taggedHash=exports.toTweakedPublickey=exports.getPublickey=exports.scriptWitnessToWitnessStack=exports.witnessStackToScriptWitness=exports.vectorSize=exports.sliceSize=exports.getOutScriptSize=exports.getWitnessSize=exports.getInScriptSize=exports.getSerializer=exports.getDefaultScript=exports.getPurpose=exports.getCoinType=exports.getPayment=void 0;const e=require("secp256k1/elliptic"),t=require("varuint-bitcoin"),r=require("./interface"),n=require("./payment"),c=require("./payment_bch"),i=require("./payment_grs"),o=require("./transaction"),s=require("./transaction_grs"),p=require("ow"),u=require("hash.js"),a=require("./bip340");function f(e){const t=e.match(/\d+/g),n=parseInt(t[1],10);for(let e=0;e<r.coinmap.length;e++)if(n===r.coinmap[e].coinType)return e;throw Error(`ArgumentError: unsupport cointype of BIP32 path, got ${e}`)}function S(e){return t.encodingLength(e)+e}function P(t){(0,p.default)(t,p.default.any(r.ow_hexString,p.default.buffer));const n="string"==typeof t?Buffer.from(t,"hex"):t;if((0,p.default)(n,p.default.buffer.is((e=>33===e.length||65===e.length))),!e.publicKeyVerify(n))throw Error(`ArgumentError: invalid secp256k1 publickey, got "${n.toString("hex")}"`);return n}exports.getPayment=function(e){switch(e){case r.CoinType.BITCOINCASH:return c.PaymentBCH;case r.CoinType.GROESTL:return i.PaymentGRS;default:return n.PaymentBTC}},exports.getCoinType=f,exports.getPurpose=function(e){switch(e){case r.ScriptType.P2PKH:return 44;case r.ScriptType.P2SH_P2PKH:case r.ScriptType.P2SH_P2WPKH:return 49;case r.ScriptType.P2WPKH:return 84;case r.ScriptType.P2TR:return 86}throw Error(`ArgumentError: unsupport ScriptType, got ${e}`)},exports.getDefaultScript=function(e){const t=e.match(/\d+/g),n=parseInt(t[0],10),c=t[1]?f(e):r.CoinType.BITCOIN;switch(n){case 44:return r.ScriptType.P2PKH;case 49:return c!==r.CoinType.BITCOINCASH?r.ScriptType.P2SH_P2WPKH:r.ScriptType.P2SH_P2PKH;case 84:return r.ScriptType.P2WPKH;case 86:return r.ScriptType.P2TR}throw Error(`ArgumentError: unsupport purpose of path, got "${n}" from ${e}`)},exports.getSerializer=function(e){return e===r.CoinType.GROESTL?s.TransactionGRS:o.Transaction},exports.getInScriptSize=function(e){switch(e){case r.ScriptType.P2PKH:case r.ScriptType.P2SH_P2PKH:return 107;case r.ScriptType.P2SH_P2WPKH:return 23}return 0},exports.getWitnessSize=function(e,t=o.Transaction.SIGHASH_DEFAULT){switch(e){case r.ScriptType.P2SH_P2WPKH:case r.ScriptType.P2WPKH:return[72,33];case r.ScriptType.P2TR:return t===o.Transaction.SIGHASH_DEFAULT?[64]:[65]}return[]},exports.getOutScriptSize=function(e){switch(e){case r.ScriptType.P2PKH:return 25;case r.ScriptType.P2SH_P2PKH:case r.ScriptType.P2SH_P2WPKH:return 23;case r.ScriptType.P2WPKH:return 22;case r.ScriptType.P2TR:return 34}return 0},exports.sliceSize=S,exports.vectorSize=function(e){return t.encodingLength(e.length)+e.reduce(((e,t)=>e+S(t)),0)},exports.witnessStackToScriptWitness=function(e){let r=Buffer.allocUnsafe(0);const n=e=>{const n=r.length,c=t.encodingLength(e);r=Buffer.concat([r,Buffer.allocUnsafe(c)]),t.encode(e,r,n)};n(e.length);for(const t of e)n(t.length),r=Buffer.concat([r,Buffer.from(t)]);return r},exports.scriptWitnessToWitnessStack=function(e){let r=0;const n=()=>{const n=t.decode(e,r);return r+=t.decode.bytes,n},c=()=>{const t=n();return r+=t,e.slice(r-t,r)},i=n(),o=[];for(let e=0;e<i;e++)o.push(c());return o},exports.getPublickey=P,exports.toTweakedPublickey=function(e){const t=P(e).slice(1,33),r=g("TapTweak",t);return(0,a.taprootConvert)(t,r)};const T=Object.fromEntries(["BIP0340/challenge","BIP0340/aux","BIP0340/nonce","TapLeaf","TapBranch","TapSighash","TapTweak","KeyAgg list","KeyAgg coefficient"].map((e=>{const t=function(e){return Buffer.from((0,u.sha256)().update(e).digest())}(e);return[e,Buffer.concat([t,t])]})));function g(e,t){const r=Buffer.concat([T[e],t]);return Buffer.from((0,u.sha256)().update(r).digest())}exports.taggedHash=g; | ||
"use strict"; | ||
/*! | ||
Copyright 2022 SecuX Technology Inc | ||
Copyright Chen Wei-En | ||
Copyright Wu Tsung-Yu | ||
Licensed under the Apache License, Version 2.0 (the License); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an AS IS BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/Object.defineProperty(exports,"__esModule",{value:!0}),exports.taggedHash=exports.toTweakedPublickey=exports.getPublickey=exports.scriptWitnessToWitnessStack=exports.witnessStackToScriptWitness=exports.vectorSize=exports.sliceSize=exports.getDustThreshold=exports.getOutScriptSize=exports.getWitnessSize=exports.getInScriptSize=exports.getSerializer=exports.getDefaultScript=exports.getPurpose=exports.getCoinType=exports.getPayment=void 0;const secp256k1=require("secp256k1/elliptic"),varuint=require("varuint-bitcoin"),interface_1=require("./interface"),payment_1=require("./payment"),payment_bch_1=require("./payment_bch"),payment_grs_1=require("./payment_grs"),transaction_1=require("./transaction"),transaction_grs_1=require("./transaction_grs"),ow_1=require("ow"),hash_js_1=require("hash.js"),bip340_1=require("./bip340");function getCoinType(path){const bip32=path.match(/\d+/g),cointype=parseInt(bip32[1],10);for(let i=0;i<interface_1.coinmap.length;i++)if(cointype===interface_1.coinmap[i].coinType)return i;throw Error(`ArgumentError: unsupport cointype of BIP32 path, got ${path}`)}function getWitnessSize(type,sighashType=transaction_1.Transaction.SIGHASH_DEFAULT){switch(type){case interface_1.ScriptType.P2SH_P2WPKH:case interface_1.ScriptType.P2WPKH:return[72,33];case interface_1.ScriptType.P2TR:return sighashType===transaction_1.Transaction.SIGHASH_DEFAULT?[64]:[65]}return[]}function getOutScriptSize(type){switch(type){case interface_1.ScriptType.P2PKH:return 25;case interface_1.ScriptType.P2SH_P2PKH:case interface_1.ScriptType.P2SH_P2WPKH:return 23;case interface_1.ScriptType.P2WPKH:return 22;case interface_1.ScriptType.P2TR:return 34}return 0}function sliceSize(size){return varuint.encodingLength(size)+size}function getPublickey(data){(0,ow_1.default)(data,ow_1.default.any(interface_1.ow_hexString,ow_1.default.buffer));const pk="string"==typeof data?Buffer.from(data,"hex"):data;if((0,ow_1.default)(pk,ow_1.default.buffer.is((x=>33===x.length||65===x.length))),!secp256k1.publicKeyVerify(pk))throw Error(`ArgumentError: invalid secp256k1 publickey, got "${pk.toString("hex")}"`);return pk}exports.getPayment=function(coin){switch(coin){case interface_1.CoinType.BITCOINCASH:return payment_bch_1.PaymentBCH;case interface_1.CoinType.GROESTL:return payment_grs_1.PaymentGRS;default:return payment_1.PaymentBTC}},exports.getCoinType=getCoinType,exports.getPurpose=function(script){switch(script){case interface_1.ScriptType.P2PKH:return 44;case interface_1.ScriptType.P2SH_P2PKH:case interface_1.ScriptType.P2SH_P2WPKH:return 49;case interface_1.ScriptType.P2WPKH:return 84;case interface_1.ScriptType.P2TR:return 86}throw Error(`ArgumentError: unsupport ScriptType, got ${script}`)},exports.getDefaultScript=function(path){const bip32=path.match(/\d+/g),purpose=parseInt(bip32[0],10),coin=bip32[1]?getCoinType(path):interface_1.CoinType.BITCOIN;switch(purpose){case 44:return interface_1.ScriptType.P2PKH;case 49:return coin!==interface_1.CoinType.BITCOINCASH?interface_1.ScriptType.P2SH_P2WPKH:interface_1.ScriptType.P2SH_P2PKH;case 84:return interface_1.ScriptType.P2WPKH;case 86:return interface_1.ScriptType.P2TR}throw Error(`ArgumentError: unsupport purpose of path, got "${purpose}" from ${path}`)},exports.getSerializer=function(coin){return coin===interface_1.CoinType.GROESTL?transaction_grs_1.TransactionGRS:transaction_1.Transaction},exports.getInScriptSize=function(type){switch(type){case interface_1.ScriptType.P2PKH:case interface_1.ScriptType.P2SH_P2PKH:return 107;case interface_1.ScriptType.P2SH_P2WPKH:return 23}return 0},exports.getWitnessSize=getWitnessSize,exports.getOutScriptSize=getOutScriptSize,exports.getDustThreshold=function(output,dustRelayFee){return(8+varuint.encodingLength(1)+getOutScriptSize(output)+(0!==getWitnessSize(output).length?67:148))*dustRelayFee},exports.sliceSize=sliceSize,exports.vectorSize=function(sizes){return varuint.encodingLength(sizes.length)+sizes.reduce(((sum,size)=>sum+sliceSize(size)),0)},exports.witnessStackToScriptWitness=function(witness){let buffer=Buffer.allocUnsafe(0);const writeVarInt=i=>{const currentLen=buffer.length,varintLen=varuint.encodingLength(i);buffer=Buffer.concat([buffer,Buffer.allocUnsafe(varintLen)]),varuint.encode(i,buffer,currentLen)};writeVarInt(witness.length);for(const w of witness)writeVarInt(w.length),buffer=Buffer.concat([buffer,Buffer.from(w)]);return buffer},exports.scriptWitnessToWitnessStack=function(buffer){let offset=0;const readVarInt=()=>{const vi=varuint.decode(buffer,offset);return offset+=varuint.decode.bytes,vi},readVarSlice=()=>{const n=readVarInt();return offset+=n,buffer.slice(offset-n,offset)},count=readVarInt(),vector=[];for(let i=0;i<count;i++)vector.push(readVarSlice());return vector},exports.getPublickey=getPublickey,exports.toTweakedPublickey=function(data){const XOnlyPubkey=getPublickey(data).slice(1,33),commitHash=taggedHash("TapTweak",XOnlyPubkey);return(0,bip340_1.taprootConvert)(XOnlyPubkey,commitHash)};const TAGGED_HASH_PREFIXES=Object.fromEntries(["BIP0340/challenge","BIP0340/aux","BIP0340/nonce","TapLeaf","TapBranch","TapSighash","TapTweak","KeyAgg list","KeyAgg coefficient"].map((tag=>{const tagHash=function(tag){return Buffer.from((0,hash_js_1.sha256)().update(tag).digest())}(tag);return[tag,Buffer.concat([tagHash,tagHash])]})));function taggedHash(prefix,data){const buf=Buffer.concat([TAGGED_HASH_PREFIXES[prefix],data]);return Buffer.from((0,hash_js_1.sha256)().update(buf).digest())}exports.taggedHash=taggedHash; |
{ | ||
"name": "@secux/app-btc", | ||
"version": "3.2.5", | ||
"version": "3.2.6", | ||
"description": "SecuX Hardware Wallet BTC API", | ||
@@ -13,4 +13,5 @@ "keywords": [ | ||
], | ||
"homepage": "https://github.com/secuxtech/secux-js/tree/master/packages/app-btc", | ||
"author": "SecuX Technology Inc.", | ||
"license": "MIT", | ||
"license": "Apache-2.0", | ||
"main": "lib/app-btc.js", | ||
@@ -32,5 +33,5 @@ "directories": { | ||
"doc:api": "sh ../../api_doc.sh ./src/app-btc.ts ./lib/app-btc.js", | ||
"test:webusb": "webpack serve --progress --config ../../webpack.config.js --output-path ./__tests__ --entry ./__tests__/usb.js", | ||
"test:webble": "webpack serve --progress --config ../../webpack.config.js --output-path ./__tests__ --entry ./__tests__/ble.js", | ||
"test:virtual": "webpack serve --progress --config ../../webpack.config.js --output-path ./__tests__ --entry ./__tests__/virtual.js", | ||
"test:webusb": "npx webpack serve --progress --config ../../webpack.config.js --output-path ./__tests__ --entry ./__tests__/usb.js", | ||
"test:webble": "npx webpack serve --progress --config ../../webpack.config.js --output-path ./__tests__ --entry ./__tests__/ble.js", | ||
"test:virtual": "npx webpack serve --progress --config ../../webpack.config.js --output-path ./__tests__ --entry ./__tests__/virtual.js", | ||
"tsc": "tsc", | ||
@@ -37,0 +38,0 @@ "watch": "tsc --watch" |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 2 instances 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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
666297
1072
14