@secux/app-btc
Advanced tools
Comparing version 3.0.0 to 3.0.1
/// <reference types="node" /> | ||
import { communicationData } from "@secux/utility/lib/communication"; | ||
import { CoinType, txInput, txOutput, ScriptType, txOutputAddress, txOutputScriptExtened, AddressOption, PathObject } from './interface'; | ||
import { CoinType, txInput, txOutput, ScriptType, txOutputAddress, txOutputScriptExtened, AddressOption, PathObject, SignOption } from './interface'; | ||
import { ITransport } from "@secux/transport"; | ||
@@ -18,2 +18,7 @@ export { AddressOption, CoinType, ScriptType, txInput, txOutput, txOutputAddress, txOutputScriptExtened }; | ||
/** | ||
* @typedef PathObject parameters for address generation | ||
* @property {CoinType} coin enum | ||
* @property {ScriptType} script enum | ||
*/ | ||
/** | ||
* @typedef AddressOption option for path validation | ||
@@ -79,2 +84,7 @@ * @property {CoinType} [coin] enum | ||
/** | ||
* @typedef SignOption | ||
* @property {CoinType} [coin] enum | ||
* @property {number} [feeRate] base fee per vbyte | ||
*/ | ||
/** | ||
* @typedef txOutputAddress receiving address information | ||
@@ -100,5 +110,6 @@ * @property {string} address receiving address | ||
* @param {txOutput} outputs output object | ||
* @param {SignOption} [option] | ||
* @returns {prepared} | ||
*/ | ||
static prepareSign(inputs: Array<txInput>, outputs: txOutput): { | ||
static prepareSign(inputs: Array<txInput>, outputs: txOutput, option?: SignOption): { | ||
commandData: communicationData; | ||
@@ -122,8 +133,17 @@ rawTx: string; | ||
static resolveTransaction(response: communicationData, unsigned: string, publickeys: Array<string | Buffer>, coin?: CoinType): string; | ||
static getAddress(this: ITransport, path: string): Promise<string>; | ||
static getPublickey(this: ITransport, path: string): Promise<string>; | ||
static getAddress(this: ITransport, path: string, option?: AddressOption): Promise<string>; | ||
static getPublickey(this: ITransport, path: string, option?: AddressOption): Promise<string>; | ||
static getXPublickey(this: ITransport, path: string): Promise<string>; | ||
static sign(this: ITransport, inputs: Array<txInput>, outputs: txOutput): Promise<{ | ||
static sign(this: ITransport, inputs: Array<txInput>, outputs: txOutput, option?: SignOption): Promise<{ | ||
raw_tx: string; | ||
}>; | ||
/** | ||
* Derive xpub and generate BTC address. | ||
* @param {string} xpub extended publickey (base58 encoded), depth must be 3 | ||
* @param {number} change BIP44 change field | ||
* @param {number} addressIndex BIP44 address_index field | ||
* @param {AddressOption} [option] for address generation | ||
* @returns {string} address | ||
*/ | ||
static deriveAddress(xpub: string, change: number, addressIndex: number, option?: AddressOption): string; | ||
} |
@@ -1,1 +0,1 @@ | ||
"use strict";var e,t=this&&this.__decorate||function(e,t,r,i){var o,n=arguments.length,c=n<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,r):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)c=Reflect.decorate(e,t,r,i);else for(var u=e.length-1;u>=0;u--)(o=e[u])&&(c=(n<3?o(c):n>3?o(t,r,c):o(t,r))||c);return n>3&&c&&Object.defineProperty(t,r,c),c},r=this&&this.__awaiter||function(e,t,r,i){return new(r||(r=Promise))((function(o,n){function c(e){try{s(i.next(e))}catch(e){n(e)}}function u(e){try{s(i.throw(e))}catch(e){n(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(c,u)}s((i=i.apply(e,t||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.SecuxBTC=exports.ScriptType=exports.CoinType=void 0;const i=require("secp256k1/elliptic"),o=require("@secux/utility"),n=require("ow"),c=require("@secux/protocol-transaction"),u=require("@secux/utility/lib/communication"),s=require("@secux/protocol-transaction/lib/interface"),a=require("./interface");Object.defineProperty(exports,"CoinType",{enumerable:!0,get:function(){return a.CoinType}}),Object.defineProperty(exports,"ScriptType",{enumerable:!0,get:function(){return a.ScriptType}});const p=require("./psbt"),l=require("./utils"),d=require("@secux/transport");let f=e=class{static addressConvert(e,t){const r=(0,l.getPublickey)(e);(0,n.default)(t,n.default.any(a.ow_path,a.ow_PathObject));const o=i.publicKeyConvert(r,!0),c="string"==typeof t?(0,l.getCoinType)(t):t.coin,u="string"==typeof t?(0,l.getDefaultScript)(t):t.script,s=(0,l.getPayment)(c);switch(u){case a.ScriptType.P2SH_P2WPKH:const e=s.p2wpkh(c,{publickey:o});return s.p2sh(c,e.redeemHash).address;case a.ScriptType.P2SH_P2PKH:const t=s.p2pkh(c,{publickey:o});return s.p2sh(c,t.redeemHash).address;case a.ScriptType.P2PKH:return s.p2pkh(c,{publickey:o}).address;case a.ScriptType.P2WPKH:return s.p2wpkh(c,{publickey:o}).address;default:throw Error(`Invalid or unsupported ScriptType, got ${u} of ${c}`)}}static resolveAddress(t,r){const i=e.resolvePublickey(t);return e.addressConvert(i,r)}static preparePublickey(e,t){var r;(0,n.default)(e,a.ow_path),t&&(0,n.default)(t,a.ow_AddressOption);const i=null!==(r=null==t?void 0:t.coin)&&void 0!==r?r:(0,l.getCoinType)(e),u=a.coinmap[i].coinType,p=void 0===(null==t?void 0:t.script)?void 0:(0,l.getPurpose)(null==t?void 0:t.script);return(0,n.default)(e,o.ow_strictPath(u,p)),c.SecuxTransactionTool.getPublickey(e,s.EllipticCurve.SECP256K1)}static resolvePublickey(e){const t=c.SecuxTransactionTool.resolvePublickey(e,s.EllipticCurve.SECP256K1,!0);return Buffer.from(t,"base64").toString("hex")}static prepareXPublickey(e){return(0,n.default)(e,a.ow_path),c.SecuxTransactionTool.getXPublickey(e)}static resolveXPublickey(e,t){return(0,n.default)(t,a.ow_path),c.SecuxTransactionTool.resolveXPublickey(e,t)}static prepareSign(e,t){(0,n.default)(e,n.default.array.ofType(a.ow_txInput).minLength(1));const r=(0,l.getCoinType)(e[0].path);(0,n.default)(t,a.ow_txOutput),e.map((e=>{const t=e.script?(0,l.getPurpose)(e.script):a.btcPurposes;(0,n.default)(e.path,o.ow_strictPath(a.coinmap[r].coinType,t))}));let i=(0,a.isOutuptScriptExtended)(t.to);if(i){const e=i.script?(0,l.getPurpose)(i.script):a.btcPurposes;(0,n.default)(i.path,o.ow_strictPath(a.coinmap[r].coinType,e))}if(t.utxo){const e=t.utxo.script?(0,l.getPurpose)(t.utxo.script):a.btcPurposes;(0,n.default)(t.utxo.path,o.ow_strictPath(a.coinmap[r].coinType,e))}const c=new p.SecuxPsbt(r);return c.AddInputs(e),c.AddOutputs(t.utxo?[t.to,t.utxo]:[t.to]),c.PrepareSign()}static resolveSignatureList(e){return c.SecuxTransactionTool.resolveSignatureList(e).map((e=>Buffer.from(e,"base64"))).map((e=>o.Signature.fromSignature(e))).map((e=>Buffer.concat([e.r,e.s]).toString("hex")))}static resolveTransaction(t,r,i,c=a.CoinType.BITCOIN){(0,n.default)(t,u.ow_communicationData),(0,n.default)(r,o.ow_hexString),(0,n.default)(i,n.default.array.ofType(n.default.any(o.ow_hexString,n.default.buffer))),(0,n.default)(c,n.default.number.inRange(0,a.CoinType.__LENGTH-1));const s=e.resolveSignatureList(t).map((e=>Buffer.from(e,"hex"))),d=i.map((e=>(0,l.getPublickey)(e)));return p.SecuxPsbt.FromBuffer(Buffer.from(r,"hex"),c).appendSignature(s,d).finalizeAllInputs().extractTransaction().toHex()}static getAddress(t){return r(this,void 0,void 0,(function*(){const r=e.prepareAddress(t),i=yield this.Exchange((0,u.getBuffer)(r));return e.resolveAddress(i,t)}))}static getPublickey(t){return r(this,void 0,void 0,(function*(){const r=e.preparePublickey(t),i=yield this.Exchange((0,u.getBuffer)(r));return e.resolvePublickey(i)}))}static getXPublickey(t){return r(this,void 0,void 0,(function*(){const r=e.prepareXPublickey(t),i=yield this.Exchange((0,u.getBuffer)(r));return e.resolveXPublickey(i,t)}))}static sign(t,i){var o;return r(this,void 0,void 0,(function*(){const n={},c=t=>r(this,void 0,void 0,(function*(){if(void 0!==n[t])return n[t];const r=yield e.getPublickey.call(this,t),i=Buffer.from(r,"hex");return n[t]=i,i}));for(const e of t)void 0===e.publickey&&(e.publickey=yield c(e.path));i.to.path&&void 0===i.to.publickey&&(i.to.publickey=yield c(i.to.path)),(null===(o=i.utxo)||void 0===o?void 0:o.path)&&void 0===i.utxo.publickey&&(i.utxo.publickey=yield c(i.utxo.path));const{commandData:s,rawTx:a}=e.prepareSign(t,i),p=yield this.Exchange((0,u.getBuffer)(s));return{raw_tx:e.resolveTransaction(p,a,t.map((e=>e.publickey)),(0,l.getCoinType)(t[0].path))}}))}};f.prepareAddress=e.preparePublickey,f=e=t([(0,d.staticImplements)()],f),exports.SecuxBTC=f,(0,d.loadPlugin)(f,"SecuxBTC"); | ||
"use strict";var e,t=this&&this.__decorate||function(e,t,r,i){var o,u=arguments.length,n=u<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,r):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,i);else for(var c=e.length-1;c>=0;c--)(o=e[c])&&(n=(u<3?o(n):u>3?o(t,r,n):o(t,r))||n);return u>3&&n&&Object.defineProperty(t,r,n),n},r=this&&this.__awaiter||function(e,t,r,i){return new(r||(r=Promise))((function(o,u){function n(e){try{s(i.next(e))}catch(e){u(e)}}function c(e){try{s(i.throw(e))}catch(e){u(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(n,c)}s((i=i.apply(e,t||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.SecuxBTC=exports.ScriptType=exports.CoinType=void 0;const i=require("./secp256k1"),o=require("@secux/utility"),u=require("@secux/utility/lib/xpub"),n=require("ow"),c=require("@secux/protocol-transaction"),s=require("@secux/utility/lib/communication"),a=require("@secux/protocol-transaction/lib/interface"),p=require("./interface");Object.defineProperty(exports,"CoinType",{enumerable:!0,get:function(){return p.CoinType}}),Object.defineProperty(exports,"ScriptType",{enumerable:!0,get:function(){return p.ScriptType}});const l=require("./psbt"),d=require("./utils"),f=require("@secux/transport");let y=e=class{static addressConvert(e,t){const r=(0,d.getPublickey)(e);(0,n.default)(t,n.default.any(p.ow_path,p.ow_PathObject));const o=Buffer.from(i.secp256k1.pointCompress(r,!0)),u="string"==typeof t?(0,d.getCoinType)(t):t.coin,c="string"==typeof t?(0,d.getDefaultScript)(t):t.script,s=(0,d.getPayment)(u);switch(c){case p.ScriptType.P2SH_P2WPKH:const e=s.p2wpkh(u,{publickey:o});return s.p2sh(u,e.redeemHash).address;case p.ScriptType.P2SH_P2PKH:const t=s.p2pkh(u,{publickey:o});return s.p2sh(u,t.redeemHash).address;case p.ScriptType.P2PKH:return s.p2pkh(u,{publickey:o}).address;case p.ScriptType.P2WPKH:return s.p2wpkh(u,{publickey:o}).address;case p.ScriptType.P2TR:return s.p2tr(u,{publickey:o}).address;default:throw Error(`Invalid or unsupported ScriptType, got ${c} of ${u}`)}}static resolveAddress(t,r){const i=e.resolvePublickey(t);return e.addressConvert(i,r)}static preparePublickey(e,t){var r;(0,n.default)(e,p.ow_path),t&&(0,n.default)(t,p.ow_AddressOption);const i=null!==(r=null==t?void 0:t.coin)&&void 0!==r?r:(0,d.getCoinType)(e),u=p.coinmap[i].coinType,s=void 0===(null==t?void 0:t.script)?void 0:(0,d.getPurpose)(null==t?void 0:t.script);return(0,n.default)(e,o.ow_strictPath(u,s)),c.SecuxTransactionTool.getPublickey(e,a.EllipticCurve.SECP256K1)}static resolvePublickey(e){const t=c.SecuxTransactionTool.resolvePublickey(e,a.EllipticCurve.SECP256K1,!0);return Buffer.from(t,"base64").toString("hex")}static prepareXPublickey(e){return(0,n.default)(e,p.ow_path),c.SecuxTransactionTool.getXPublickey(e)}static resolveXPublickey(e,t){return(0,n.default)(t,p.ow_path),c.SecuxTransactionTool.resolveXPublickey(e,t)}static prepareSign(e,t,r){var i;(0,n.default)(e,n.default.array.ofType(p.ow_txInput).minLength(1)),(0,n.default)(r,n.default.any(n.default.undefined,p.ow_SignOption));const u=null!==(i=null==r?void 0:r.coin)&&void 0!==i?i:(0,d.getCoinType)(e[0].path);(0,n.default)(t,p.ow_txOutput),e.map((e=>{const t=e.script?(0,d.getPurpose)(e.script):p.btcPurposes;(0,n.default)(e.path,o.ow_strictPath(p.coinmap[u].coinType,t))}));let c=(0,p.isOutuptScriptExtended)(t.to);if(c){const e=c.script?(0,d.getPurpose)(c.script):p.btcPurposes;(0,n.default)(c.path,o.ow_strictPath(p.coinmap[u].coinType,e))}if(t.utxo){const e=t.utxo.script?(0,d.getPurpose)(t.utxo.script):p.btcPurposes;(0,n.default)(t.utxo.path,o.ow_strictPath(p.coinmap[u].coinType,e))}const s=new l.SecuxPsbt(u);return s.AddInputs(e),s.AddOutputs(t.utxo?[t.to,t.utxo]:[t.to]),s.PrepareSign(null==r?void 0:r.feeRate)}static resolveSignatureList(e){return c.SecuxTransactionTool.resolveSignatureList(e).map((e=>Buffer.from(e,"base64"))).map((e=>o.Signature.fromSignature(e))).map((e=>Buffer.concat([e.r,e.s]).toString("hex")))}static resolveTransaction(t,r,i,u=p.CoinType.BITCOIN){(0,n.default)(t,s.ow_communicationData),(0,n.default)(r,o.ow_hexString),(0,n.default)(i,n.default.array.ofType(n.default.any(o.ow_hexString,n.default.buffer))),(0,n.default)(u,n.default.number.inRange(0,p.CoinType.__LENGTH-1));const c=e.resolveSignatureList(t).map((e=>Buffer.from(e,"hex"))),a=i.map((e=>(0,d.getPublickey)(e)));return l.SecuxPsbt.FromBuffer(Buffer.from(r,"hex"),u).appendSignature(c,a).finalizeAllInputs().extractTransaction().toHex()}static getAddress(t,i){var o,u;return r(this,void 0,void 0,(function*(){const r=e.prepareAddress(t,i),n=yield this.Exchange((0,s.getBuffer)(r));return e.resolveAddress(n,{coin:null!==(o=null==i?void 0:i.coin)&&void 0!==o?o:(0,d.getCoinType)(t),script:null!==(u=null==i?void 0:i.script)&&void 0!==u?u:(0,d.getDefaultScript)(t)})}))}static getPublickey(t,i){return r(this,void 0,void 0,(function*(){const r=e.preparePublickey(t,i),o=yield this.Exchange((0,s.getBuffer)(r));return e.resolvePublickey(o)}))}static getXPublickey(t){return r(this,void 0,void 0,(function*(){const r=e.prepareXPublickey(t),i=yield this.Exchange((0,s.getBuffer)(r));return e.resolveXPublickey(i,t)}))}static sign(t,i,o){var u,n;return r(this,void 0,void 0,(function*(){const c={},a=t=>r(this,void 0,void 0,(function*(){if(void 0!==c[t])return c[t];const r=yield e.getPublickey.call(this,t,{coin:p}),i=Buffer.from(r,"hex");return c[t]=i,i})),p=null!==(u=null==o?void 0:o.coin)&&void 0!==u?u:(0,d.getCoinType)(t[0].path);for(const e of t)void 0===e.publickey&&(e.publickey=yield a(e.path));i.to.path&&void 0===i.to.publickey&&(i.to.publickey=yield a(i.to.path)),(null===(n=i.utxo)||void 0===n?void 0:n.path)&&void 0===i.utxo.publickey&&(i.utxo.publickey=yield a(i.utxo.path));const{commandData:l,rawTx:f}=e.prepareSign(t,i,{coin:p,feeRate:null==o?void 0:o.feeRate}),y=yield this.Exchange((0,s.getBuffer)(l));return{raw_tx:e.resolveTransaction(y,f,t.map((e=>e.publickey)),p)}}))}static deriveAddress(t,r,i,o){var c,s;(0,n.default)(r,n.default.number.uint8),(0,n.default)(i,n.default.number.uint8),(0,n.default)(o,n.default.any(n.default.undefined,p.ow_AddressOption));const a=(0,u.decodeXPUB)(t);if(3!==a.depth)throw Error(`ArgumentError: expect depth from xpub is 3, but got ${a.depth}`);if(null==o?void 0:o.script){const e=(0,d.getPurpose)(null==o?void 0:o.script);if(a.purpose!==e)throw Error(`ArgumentError: expect purpose from xpub is ${e}, but got ${a.purpose}`)}const{publickey:l}=(0,u.deriveKey)(a.publickey,a.chaincode,[r,i]),f=null!==(c=null==o?void 0:o.coin)&&void 0!==c?c:p.CoinType.BITCOIN,y=null!==(s=null==o?void 0:o.script)&&void 0!==s?s:(0,d.getDefaultScript)(`m/${a.purpose}'`);return e.addressConvert(l,{coin:f,script:y})}};y.prepareAddress=e.preparePublickey,y=e=t([(0,f.staticImplements)()],y),exports.SecuxBTC=y,(0,f.loadPlugin)(y,"SecuxBTC"); |
export interface Network { | ||
messagePrefix: string; | ||
bech32: string; | ||
bech32?: string; | ||
bip32: Bip32; | ||
@@ -16,2 +16,3 @@ pubKeyHash: number; | ||
export declare const testnet: Network; | ||
export declare const regtest: Network; | ||
export declare const litecoin: Network; | ||
@@ -18,0 +19,0 @@ export declare const bitcoincash: Network; |
@@ -1,1 +0,1 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.OPCODES=exports.dogecoin=exports.dash=exports.digibyte=exports.groestl=exports.bitcoincash=exports.litecoin=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.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",bech32:"",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";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}); |
/// <reference types="node" /> | ||
import * as constants from "./coindef"; | ||
export { OPCODES } from "./coindef"; | ||
@@ -9,3 +8,4 @@ export declare enum ScriptType { | ||
P2SH_P2WPKH = 3, | ||
__LENGTH = 4 | ||
P2TR = 4, | ||
__LENGTH = 5 | ||
} | ||
@@ -15,12 +15,13 @@ export declare enum CoinType { | ||
TESTNET = 1, | ||
LITECOIN = 2, | ||
BITCOINCASH = 3, | ||
GROESTL = 4, | ||
DIGIBYTE = 5, | ||
DASH = 6, | ||
DOGECOIN = 7, | ||
__LENGTH = 8 | ||
REGTEST = 2, | ||
LITECOIN = 3, | ||
BITCOINCASH = 4, | ||
GROESTL = 5, | ||
DIGIBYTE = 6, | ||
DASH = 7, | ||
DOGECOIN = 8, | ||
__LENGTH = 9 | ||
} | ||
export declare const coinmap: readonly Readonly<constants.Network>[]; | ||
export declare const btcCoinTypes: readonly number[]; | ||
export declare const coinmap: readonly any[]; | ||
export declare const btcCoinTypes: readonly any[]; | ||
export declare const btcPurposes: readonly number[]; | ||
@@ -112,2 +113,6 @@ export declare const ow_balance: import("ow").NumberPredicate; | ||
}; | ||
export declare type SignOption = { | ||
coin?: CoinType; | ||
feeRate?: number; | ||
}; | ||
export declare const ow_AddressOption: import("ow").ObjectPredicate<{ | ||
@@ -117,1 +122,5 @@ coin: number | undefined; | ||
}>; | ||
export declare const ow_SignOption: import("ow").ObjectPredicate<{ | ||
coin: number | undefined; | ||
feeRate: number | undefined; | ||
}>; |
@@ -1,1 +0,1 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ow_AddressOption=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_path=exports.ow_balance=exports.btcPurposes=exports.btcCoinTypes=exports.coinmap=exports.CoinType=exports.ScriptType=exports.OPCODES=void 0;const e=require("ow"),t=require("./coindef"),o=require("@secux/utility");var r,p,s=require("./coindef");Object.defineProperty(exports,"OPCODES",{enumerable:!0,get:function(){return s.OPCODES}}),function(e){e[e.P2PKH=0]="P2PKH",e[e.P2WPKH=1]="P2WPKH",e[e.P2SH_P2PKH=2]="P2SH_P2PKH",e[e.P2SH_P2WPKH=3]="P2SH_P2WPKH",e[e.__LENGTH=4]="__LENGTH"}(r=exports.ScriptType||(exports.ScriptType={})),function(e){e[e.BITCOIN=0]="BITCOIN",e[e.TESTNET=1]="TESTNET",e[e.LITECOIN=2]="LITECOIN",e[e.BITCOINCASH=3]="BITCOINCASH",e[e.GROESTL=4]="GROESTL",e[e.DIGIBYTE=5]="DIGIBYTE",e[e.DASH=6]="DASH",e[e.DOGECOIN=7]="DOGECOIN",e[e.__LENGTH=8]="__LENGTH"}(p=exports.CoinType||(exports.CoinType={})),exports.coinmap=Object.freeze([Object.freeze(t.bitcoin),Object.freeze(t.testnet),Object.freeze(t.litecoin),Object.freeze(t.bitcoincash),Object.freeze(t.groestl),Object.freeze(t.digibyte),Object.freeze(t.dash),Object.freeze(t.dogecoin)]),exports.btcCoinTypes=Object.freeze(exports.coinmap.map((e=>Object.freeze(e.coinType)))),exports.btcPurposes=Object.freeze([Object.freeze(44),Object.freeze(49),Object.freeze(84)]),exports.ow_balance=e.default.number.integer.positive.lessThanOrEqual(9007199254740991),exports.ow_path=o.ow_strictPath(exports.btcCoinTypes,exports.btcPurposes),exports.ow_PathObject=e.default.object.exactShape({coin:e.default.number.inRange(0,p.__LENGTH-1),script:e.default.number.inRange(0,r.__LENGTH-1)}),exports.ow_txInput=e.default.object.exactShape({hash:o.ow_hashString,vout:e.default.number.greaterThanOrEqual(0),txHex:e.default.any(e.default.undefined,o.ow_hexString),script:e.default.optional.number.inRange(0,r.__LENGTH-1),satoshis:exports.ow_balance,path:exports.ow_path,publickey:e.default.any(e.default.undefined,o.ow_hexString,e.default.buffer)}),exports.ow_txOutputAddress=e.default.object.exactShape({address:o.ow_hashString,satoshis:exports.ow_balance}),exports.ow_txOutputScript=e.default.object.exactShape({scriptHex:o.ow_hexString,satoshis:exports.ow_balance}),exports.ow_txOutputScriptExtened=e.default.object.exactShape({publickey:e.default.any(e.default.undefined,o.ow_hexString,e.default.buffer),path:exports.ow_path,satoshis:exports.ow_balance,script:e.default.optional.number.inRange(0,r.__LENGTH-1)}),exports.ow_txOutput=e.default.object.exactShape({to:e.default.any(exports.ow_txOutputAddress,exports.ow_txOutputScriptExtened),utxo:e.default.any(e.default.undefined,exports.ow_txOutputScriptExtened)}),exports.isOutputAddress=function(e){const t=e;if(t.address)return t},exports.isOutuptScript=function(e){const t=e;if(t.scriptHex)return t},exports.isOutuptScriptExtended=function(t){try{return(0,e.default)(t,exports.ow_txOutputScriptExtened),t}catch(e){}},exports.ow_AddressOption=e.default.object.exactShape({coin:e.default.optional.number.inRange(0,p.__LENGTH-1),script:e.default.optional.number.inRange(0,r.__LENGTH-1)}); | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ow_SignOption=exports.ow_AddressOption=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_path=exports.ow_balance=exports.btcPurposes=exports.btcCoinTypes=exports.coinmap=exports.CoinType=exports.ScriptType=exports.OPCODES=void 0;const e=require("ow"),t=require("./coindef"),o=require("@secux/utility");var r,p,s=require("./coindef");Object.defineProperty(exports,"OPCODES",{enumerable:!0,get:function(){return s.OPCODES}}),function(e){e[e.P2PKH=0]="P2PKH",e[e.P2WPKH=1]="P2WPKH",e[e.P2SH_P2PKH=2]="P2SH_P2PKH",e[e.P2SH_P2WPKH=3]="P2SH_P2WPKH",e[e.P2TR=4]="P2TR",e[e.__LENGTH=5]="__LENGTH"}(r=exports.ScriptType||(exports.ScriptType={})),function(e){e[e.BITCOIN=0]="BITCOIN",e[e.TESTNET=1]="TESTNET",e[e.REGTEST=2]="REGTEST",e[e.LITECOIN=3]="LITECOIN",e[e.BITCOINCASH=4]="BITCOINCASH",e[e.GROESTL=5]="GROESTL",e[e.DIGIBYTE=6]="DIGIBYTE",e[e.DASH=7]="DASH",e[e.DOGECOIN=8]="DOGECOIN",e[e.__LENGTH=9]="__LENGTH"}(p=exports.CoinType||(exports.CoinType={})),exports.coinmap=Object.freeze(Object.values(p).slice(0,p.__LENGTH).map((e=>t[e.toLowerCase()]))),exports.btcCoinTypes=Object.freeze(exports.coinmap.map((e=>Object.freeze(e.coinType)))),exports.btcPurposes=Object.freeze([Object.freeze(44),Object.freeze(49),Object.freeze(84),Object.freeze(86)]),exports.ow_balance=e.default.number.integer.positive.lessThanOrEqual(9007199254740991),exports.ow_path=o.ow_strictPath(exports.btcCoinTypes,exports.btcPurposes),exports.ow_PathObject=e.default.object.exactShape({coin:e.default.number.inRange(0,p.__LENGTH-1),script:e.default.number.inRange(0,r.__LENGTH-1)}),exports.ow_txInput=e.default.object.exactShape({hash:o.ow_hashString,vout:e.default.number.greaterThanOrEqual(0),txHex:e.default.any(e.default.undefined,o.ow_hexString),script:e.default.optional.number.inRange(0,r.__LENGTH-1),satoshis:exports.ow_balance,path:exports.ow_path,publickey:e.default.any(e.default.undefined,o.ow_hexString,e.default.buffer)}),exports.ow_txOutputAddress=e.default.object.exactShape({address:o.ow_hashString,satoshis:exports.ow_balance}),exports.ow_txOutputScript=e.default.object.exactShape({scriptHex:o.ow_hexString,satoshis:exports.ow_balance}),exports.ow_txOutputScriptExtened=e.default.object.exactShape({publickey:e.default.any(e.default.undefined,o.ow_hexString,e.default.buffer),path:exports.ow_path,satoshis:exports.ow_balance,script:e.default.optional.number.inRange(0,r.__LENGTH-1)}),exports.ow_txOutput=e.default.object.exactShape({to:e.default.any(exports.ow_txOutputAddress,exports.ow_txOutputScriptExtened),utxo:e.default.any(e.default.undefined,exports.ow_txOutputScriptExtened)}),exports.isOutputAddress=function(e){const t=e;if(t.address)return t},exports.isOutuptScript=function(e){const t=e;if(t.scriptHex)return t},exports.isOutuptScriptExtended=function(t){try{return(0,e.default)(t,exports.ow_txOutputScriptExtened),t}catch(e){}},exports.ow_AddressOption=e.default.object.exactShape({coin:e.default.optional.number.inRange(0,p.__LENGTH-1),script:e.default.optional.number.inRange(0,r.__LENGTH-1)}),exports.ow_SignOption=e.default.object.exactShape({coin:e.default.optional.number.inRange(0,p.__LENGTH-1),feeRate:e.default.optional.number.greaterThanOrEqual(1)}); |
@@ -1,2 +0,1 @@ | ||
/// <reference types="node" /> | ||
import { PaymentBTC, CoinType } from './payment'; | ||
@@ -8,7 +7,2 @@ import { bs58Check } from "@secux/utility/lib/bs58"; | ||
protected static CoinSupported(coin: CoinType): void; | ||
/** | ||
* decode address to script | ||
* @param {string} address | ||
*/ | ||
static decode(coin: CoinType, address: string): Buffer; | ||
} |
@@ -1,1 +0,1 @@ | ||
"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 r=require("@secux/utility/lib/bs58"),t=require("groestl-hash-js"),i=require("./interface");class s extends e.PaymentBTC{static CoinSupported(r){if(r!==e.CoinType.GROESTL)throw Error("Not supported cointype")}static decode(e,r){const t=this.bs58check.decode(r),o=t[0],n=Buffer.from(t.slice(1)),c=i.coinmap[e];if(o===c.scriptHash)return s.p2sh(e,n).scriptPublickey;if(o===c.pubKeyHash)return s.p2pkh(e,{hash:n}).scriptPublickey;throw new Error("Invalid Output ScriptPubKey")}}exports.PaymentGRS=s,s.bs58check=new r.bs58Check((function(e){return Buffer.from(t.groestl_2(e,1,1))})); | ||
"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))})); |
@@ -57,2 +57,9 @@ /// <reference types="node" /> | ||
}; | ||
static p2tr(coin: CoinType, opt: { | ||
publickey?: Buffer; | ||
hash?: Buffer; | ||
}): { | ||
address: string; | ||
scriptPublickey: Buffer; | ||
}; | ||
/** | ||
@@ -68,3 +75,4 @@ * decode address to script | ||
static isP2WPKH(script: Buffer): boolean; | ||
static isP2TR(script: Buffer): boolean; | ||
} | ||
declare function Hash160(publickey: Buffer): Buffer; |
@@ -1,1 +0,1 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.logger=exports.Hash160=exports.CoinType=exports.PaymentBTC=void 0;const e=require("bech32"),r=require("ripemd160"),t=require("js-sha256"),o=require("./interface");Object.defineProperty(exports,"CoinType",{enumerable:!0,get:function(){return o.CoinType}});const s=require("@secux/utility/lib/bs58"),i=require("@secux/utility");exports.logger=null===i.Logger||void 0===i.Logger?void 0:i.Logger.child({id:"payment"});class c{static CoinSupported(e){if(e===o.CoinType.BITCOINCASH)throw Error("Please use class PaymentBCH instead");if(e===o.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 t=r.hash?r.hash:n(r.publickey);null===exports.logger||void 0===exports.logger||exports.logger.info(`publickey hash: ${t.toString("hex")}`);const s=o.coinmap[e],i=this.bs58check.encode(t,Buffer.from([s.pubKeyHash])),c=Buffer.from([o.OPCODES.OP_DUP,o.OPCODES.OP_HASH160,20]),h=Buffer.from([o.OPCODES.OP_EQUALVERIFY,o.OPCODES.OP_CHECKSIG]),u=Buffer.concat([c,t,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 t=o.coinmap[e],s=this.bs58check.encode(r,Buffer.from([t.scriptHash])),i=Buffer.from([o.OPCODES.OP_HASH160,20]),c=Buffer.from([o.OPCODES.OP_EQUAL]);return{address:s,scriptPublickey:Buffer.concat([i,r,c])}}static p2wpkh(r,t){if(this.CoinSupported(r),!t.publickey&&!t.hash)throw Error("Invalid Parameters");if(t.publickey&&t.hash)throw Error("Invalid Parameters");const s=t.hash?t.hash:n(t.publickey);null===exports.logger||void 0===exports.logger||exports.logger.info(`publickey hash: ${s.toString("hex")}`);let i=o.coinmap[r];const c=e.bech32.toWords(s);c.unshift(0);const h=e.bech32.encode(i.bech32,c),u=Buffer.from([o.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+=o.OPCODES.OP_INT_BASE;const t=r.length+o.OPCODES.OP_INT_BASE,s=Buffer.concat(r),i=Buffer.concat([Buffer.from([e]),s,Buffer.from([t]),Buffer.from([o.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([o.OPCODES.OP_HASH160,20]),u=Buffer.from([o.OPCODES.OP_EQUAL]);return{redeem:i,scriptPubicKey:Buffer.concat([h,c,u])}}static decode(r,t){let s;try{s=this.bs58check.decode(t)}catch(o){const i=e.bech32.decode(t);i.words.shift();return s=Buffer.from(e.bech32.fromWords(i.words)),null===exports.logger||void 0===exports.logger||exports.logger.debug(`bech32 address: ${t}\nbech32 decoded: ${s.toString("hex")}`),c.p2wpkh(r,{hash:s}).scriptPublickey}const i=s[0],n=s.slice(1),h=o.coinmap[r];if(i===h.scriptHash)return c.p2sh(r,n).scriptPublickey;if(i===h.pubKeyHash)return c.p2pkh(r,{hash:n}).scriptPublickey;throw Error("Invalid Output ScriptPubKey")}static classify(e){if(this.isP2WPKH(e))return o.ScriptType.P2WPKH;if(this.isP2PKH(e))return o.ScriptType.P2PKH;throw Error(`non-standard script: ${e.toString("hex")}`)}static isP2PKH(e){return 25===e.length&&e[0]===o.OPCODES.OP_DUP&&e[1]===o.OPCODES.OP_HASH160&&20===e[2]&&e[23]===o.OPCODES.OP_EQUALVERIFY&&e[24]===o.OPCODES.OP_CHECKSIG}static isP2SH(e){return 23===e.length&&e[0]===o.OPCODES.OP_HASH160&&20===e[1]&&e[22]===o.OPCODES.OP_EQUAL}static isP2WPKH(e){return 22===e.length&&e[0]===o.OPCODES.OP_0&&20===e[1]}}function n(e){const o=Buffer.from(t.sha256.update(e).digest());return(new r).update(o).digest()}exports.PaymentBTC=c,c.bs58check=new s.bs58Check((function(e){const r=t.sha256.update(e).digest(),o=t.sha256.update(r).digest();return Buffer.from(o)})),exports.Hash160=n; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.logger=exports.Hash160=exports.CoinType=exports.PaymentBTC=void 0;const e=require("bech32"),r=require("ripemd160"),t=require("js-sha256"),s=require("./secp256k1"),o=require("./interface");Object.defineProperty(exports,"CoinType",{enumerable:!0,get:function(){return o.CoinType}});const i=require("@secux/utility/lib/bs58"),c=require("@secux/utility"),n=require("./utils");exports.logger=null===c.Logger||void 0===c.Logger?void 0:c.Logger.child({id:"payment"});class h{static CoinSupported(e){if(e===o.CoinType.BITCOINCASH)throw Error("Please use class PaymentBCH instead");if(e===o.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 t=r.hash?r.hash:u(r.publickey);null===exports.logger||void 0===exports.logger||exports.logger.info(`publickey hash: ${t.toString("hex")}`);const s=o.coinmap[e],i=this.bs58check.encode(t,Buffer.from([s.pubKeyHash])),c=Buffer.from([o.OPCODES.OP_DUP,o.OPCODES.OP_HASH160,20]),n=Buffer.from([o.OPCODES.OP_EQUALVERIFY,o.OPCODES.OP_CHECKSIG]),h=Buffer.concat([c,t,n]),a=u(h);return null===exports.logger||void 0===exports.logger||exports.logger.info(`redeem hash: ${a.toString("hex")}`),{address:i,scriptPublickey:h,redeemHash:a}}static p2sh(e,r){this.CoinSupported(e);const t=o.coinmap[e],s=this.bs58check.encode(r,Buffer.from([t.scriptHash])),i=Buffer.from([o.OPCODES.OP_HASH160,20]),c=Buffer.from([o.OPCODES.OP_EQUAL]);return{address:s,scriptPublickey:Buffer.concat([i,r,c])}}static p2wpkh(r,t){if(this.CoinSupported(r),!t.publickey&&!t.hash)throw Error("Invalid Parameters");if(t.publickey&&t.hash)throw Error("Invalid Parameters");const s=t.hash?t.hash:u(t.publickey);null===exports.logger||void 0===exports.logger||exports.logger.info(`publickey hash: ${s.toString("hex")}`);let i=o.coinmap[r];const c=e.bech32.toWords(s);c.unshift(0);const n=e.bech32.encode(i.bech32,c),h=Buffer.from([o.OPCODES.OP_0,20]),a=Buffer.concat([h,s]),p=u(a);return null===exports.logger||void 0===exports.logger||exports.logger.info(`redeem hash: ${p.toString("hex")}`),{address:n,scriptPublickey:a,redeemHash:p}}static p2ms(e,r){if(e<=0)throw Error('Invalid paramter "m"');e+=o.OPCODES.OP_INT_BASE;const t=r.length+o.OPCODES.OP_INT_BASE,s=Buffer.concat(r),i=Buffer.concat([Buffer.from([e]),s,Buffer.from([t]),Buffer.from([o.OPCODES.OP_CHECKMULTISIG])]),c=u(i);null===exports.logger||void 0===exports.logger||exports.logger.info(`redeem hash: ${c.toString("hex")}`);const n=Buffer.from([o.OPCODES.OP_HASH160,20]),h=Buffer.from([o.OPCODES.OP_EQUAL]);return{redeem:i,scriptPubicKey:Buffer.concat([n,c,h])}}static p2tr(r,t){if(this.CoinSupported(r),!t.publickey&&!t.hash)throw Error("Invalid Parameters");if(t.publickey&&t.hash)throw Error("Invalid Parameters");let i=t.hash;if(void 0===i){const e=t.publickey.slice(1,33),r=(0,n.taggedHash)("TapTweak",e);i=s.secp256k1.xOnlyPointAddTweak(e,r).xOnlyPubkey}const c=o.coinmap[r],h=e.bech32.toWords(i);h.unshift(1);const u=e.bech32m.encode(c.bech32,h),a=Buffer.from([81,32]);return{address:u,scriptPublickey:Buffer.concat([a,i])}}static decode(r,t){const s=o.coinmap[r];if(s.bech32&&t.startsWith(s.bech32)){let o;if("p"===t.slice(s.bech32.length+1)[0])o=e.bech32m.decode(t);else o=e.bech32.decode(t);const i=o.words.shift();switch(i){case 0:const s=Buffer.from(e.bech32.fromWords(o.words));return null===exports.logger||void 0===exports.logger||exports.logger.debug(`bech32 address: ${t}\nbech32 decoded: ${s.toString("hex")}`),this.p2wpkh(r,{hash:s}).scriptPublickey;case 1:const c=Buffer.from(e.bech32m.fromWords(o.words));return null===exports.logger||void 0===exports.logger||exports.logger.debug(`bech32m address: ${t}\nbech32m decoded: ${c.toString("hex")}`),this.p2tr(r,{hash:c}).scriptPublickey;default:throw Error(`ArgumentError: unsupported witness version, got "${i}" from address "${t}"`)}}const i=this.bs58check.decode(t),c=i[0],n=i.slice(1);if(c===s.scriptHash)return this.p2sh(r,n).scriptPublickey;if(c===s.pubKeyHash)return this.p2pkh(r,{hash:n}).scriptPublickey;throw Error("Invalid Output ScriptPubKey")}static classify(e){if(this.isP2WPKH(e))return o.ScriptType.P2WPKH;if(this.isP2PKH(e))return o.ScriptType.P2PKH;if(this.isP2TR(e))return o.ScriptType.P2TR;throw Error(`non-standard script: ${e.toString("hex")}`)}static isP2PKH(e){return 25===e.length&&e[0]===o.OPCODES.OP_DUP&&e[1]===o.OPCODES.OP_HASH160&&20===e[2]&&e[23]===o.OPCODES.OP_EQUALVERIFY&&e[24]===o.OPCODES.OP_CHECKSIG}static isP2SH(e){return 23===e.length&&e[0]===o.OPCODES.OP_HASH160&&20===e[1]&&e[22]===o.OPCODES.OP_EQUAL}static isP2WPKH(e){return 22===e.length&&e[0]===o.OPCODES.OP_0&&20===e[1]}static isP2TR(e){return 34===e.length&&81===e[0]&&32===e[1]}}function u(e){const s=Buffer.from(t.sha256.update(e).digest());return(new r).update(s).digest()}exports.PaymentBTC=h,h.bs58check=new i.bs58Check((function(e){const r=t.sha256.update(e).digest(),s=t.sha256.update(r).digest();return Buffer.from(s)})),exports.Hash160=u; |
/// <reference types="node" /> | ||
import { Psbt } from "bip174"; | ||
import { Psbtv2 } from "./parser"; | ||
import { CoinType, txInput, txOutputExtended } from './interface'; | ||
@@ -8,3 +8,3 @@ import { communicationData } from "@secux/utility/lib/communication"; | ||
#private; | ||
constructor(coin: CoinType, data?: Psbt); | ||
constructor(coin: CoinType, data?: Psbtv2); | ||
static FromBuffer(data: Buffer, coin: CoinType): SecuxPsbt; | ||
@@ -15,3 +15,3 @@ AddInput(input: txInput): SecuxPsbt; | ||
AddOutputs(outputs: Array<txOutputExtended>): SecuxPsbt; | ||
PrepareSign(): { | ||
PrepareSign(feeRate?: number): { | ||
commandData: communicationData; | ||
@@ -18,0 +18,0 @@ rawTx: string; |
@@ -1,1 +0,1 @@ | ||
"use strict";var t,e,i,r,s,n,p,o=this&&this.__classPrivateFieldSet||function(t,e,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(t,i):s?s.value=i:e.set(t,i),i},a=this&&this.__classPrivateFieldGet||function(t,e,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!r:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(t):r?r.value:e.get(t)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.SecuxPsbt=void 0;const c=require("bip174"),u=require("bip174/src/lib/utils"),h=require("secp256k1/elliptic"),f=require("js-sha256"),l=require("./script"),d=require("@secux/utility"),S=require("./interface"),g=require("./utils"),y=require("./payment"),P=require("./transaction"),w=require("./coindef"),b=require("../../protocol-transaction/lib/protocol-transaction"),m=null===d.Logger||void 0===d.Logger?void 0:d.Logger.child({id:"psbt"});class T{constructor(p,u=new c.Psbt(new v)){t.set(this,void 0),e.set(this,void 0),i.set(this,void 0),r.set(this,[]),s.set(this,void 0),n.set(this,Buffer.alloc(0)),o(this,t,u,"f"),o(this,e,p,"f"),o(this,i,(0,g.getPayment)(a(this,e,"f")),"f"),o(this,s,a(this,t,"f").globalMap.unsignedTx.tx,"f"),p===S.CoinType.BITCOINCASH&&(a(this,s,"f").version=1)}static FromBuffer(t,e){const i=c.Psbt.fromBuffer(t,(t=>new v(t)));return new T(e,i)}AddInput(s){var n;if(!(0,d.isSupportedCoin)(s.path))throw Error(`ArgumentError: unsupport bip32 path, got "${s.path}"`);const p={},o={},c=(0,g.getPublickey)(s.publickey),u=null!==(n=s.script)&&void 0!==n?n:(0,g.getDefaultScript)(s.path);switch(u){case S.ScriptType.P2PKH:p.witnessUtxo={script:a(this,i,"f").p2pkh(a(this,e,"f"),{publickey:c}).scriptPublickey,value:s.satoshis};break;case S.ScriptType.P2SH_P2PKH:const r=a(this,i,"f").p2pkh(a(this,e,"f"),{publickey:c});o.redeemScript=r.scriptPublickey,p.witnessUtxo={script:a(this,i,"f").p2sh(a(this,e,"f"),r.redeemHash).scriptPublickey,value:s.satoshis};break;case S.ScriptType.P2SH_P2WPKH:const n=a(this,i,"f").p2wpkh(a(this,e,"f"),{publickey:c});o.redeemScript=n.scriptPublickey,p.witnessUtxo={script:a(this,i,"f").p2sh(a(this,e,"f"),n.redeemHash).scriptPublickey,value:s.satoshis};break;case S.ScriptType.P2WPKH:p.witnessUtxo={script:a(this,i,"f").p2wpkh(a(this,e,"f"),{publickey:c}).scriptPublickey,value:s.satoshis};break;default:throw Error(`ArgumentError: Invalid ScriptType of input#${a(this,t,"f").inputs.length}, got "${S.ScriptType[u]}"`)}if(s.txHex){const i=P.Transaction.fromBuffer(Buffer.from(s.txHex,"hex"));if((0,g.getSerializer)(a(this,e,"f")).getId(i)!==s.hash)throw Error(`UTXO hash for input #${a(this,t,"f").inputs.length} doesn't match the hash specified in the prevout`);const r=i.outs[s.vout];if(r.value!==s.satoshis)throw Error(`UTXO value for input #${a(this,t,"f").inputs.length} doesn't match the value specified in the prevout`);r.script.equals(p.witnessUtxo.script)||null==m||m.warn(`Input script generation error: ${r.script.toString("hex")}, got "${p.witnessUtxo.script}"`)}const h=Object.assign(Object.assign({hash:s.hash,index:s.vout},p),o);return a(this,t,"f").addInput(h),a(this,r,"f").push(s.path),this}AddInputs(t){for(const e of t)this.AddInput(e);return this}AddOutput(r){var s;const p=(0,d.BigIntToBuffer)(r.satoshis,8);let c,u,h,f,l=r.satoshis;if(c=(0,S.isOutuptScriptExtended)(r)){const r=(0,g.getPublickey)(c.publickey);f=c.path;const n=null!==(s=c.script)&&void 0!==s?s:(0,g.getDefaultScript)(f);switch(n){case S.ScriptType.P2SH_P2WPKH:if(!c.path.startsWith("m/49'/"))throw Error("P2SH(...) should use m/49' path");let s=a(this,i,"f").p2wpkh(a(this,e,"f"),{publickey:r}).redeemHash,p=a(this,i,"f").p2sh(a(this,e,"f"),s);u=p.scriptPublickey,h=p.address;break;case S.ScriptType.P2SH_P2PKH:if(!c.path.startsWith("m/49'/"))throw Error("P2SH(...) should use m/49' path");s=a(this,i,"f").p2pkh(a(this,e,"f"),{publickey:r}).redeemHash,p=a(this,i,"f").p2sh(a(this,e,"f"),s),u=p.scriptPublickey,h=p.address;break;case S.ScriptType.P2PKH:if(!c.path.startsWith("m/44'/"))throw Error("P2PKH should use m/44' path");const o=a(this,i,"f").p2pkh(a(this,e,"f"),{publickey:r});u=o.scriptPublickey,h=o.address;break;case S.ScriptType.P2WPKH:if(!c.path.startsWith("m/84'/"))throw Error("P2WPKH should use m/84' path");const f=a(this,i,"f").p2wpkh(a(this,e,"f"),{publickey:r});u=f.scriptPublickey,h=f.address;break;default:throw Error(`ArgumentError: Invalid ScriptType of output#${a(this,t,"f").outputs.length}, got "${S.ScriptType[n]}"`)}}else if(c=(0,S.isOutputAddress)(r))u=a(this,i,"f").decode(a(this,e,"f"),c.address),h=c.address;else{if(!(c=(0,S.isOutuptScript)(r)))throw Error("Invalid parameter of output");u=Buffer.from(c.scriptHex,"hex")}return 0===a(this,t,"f").outputs.length?o(this,n,Buffer.concat([a(this,n,"f"),p,Buffer.from([u.length]),u]),"f"):o(this,n,Buffer.concat([a(this,n,"f"),p,(0,d.buildPathBuffer)(f).pathBuffer]),"f"),a(this,t,"f").addOutput({script:u,value:l}),this}AddOutputs(t){for(const e of t)this.AddOutput(e);return this}PrepareSign(){o(this,n,Buffer.concat([Buffer.from([a(this,t,"f").outputs.length]),a(this,n,"f")]),"f");const i=a(this,t,"f").inputs.map(((i,r)=>{const{data:p}=k(a(this,e,"f"),r,a(this,t,"f").inputs[r],a(this,s,"f")),o=H(a(this,t,"f").inputs[r],a(this,e,"f")).scriptType;return a(this,e,"f")!==S.CoinType.BITCOINCASH&&o===S.ScriptType.P2PKH?{data:p,confirm:Buffer.alloc(0)}:{data:p,confirm:a(this,n,"f")}}));for(let t=0;t<i.length;t++)null==m||m.debug(`tx data [${t}]: ${i[t].data.toString("hex")}`),null==m||m.debug(`confirm data [${t}]: ${i[t].confirm.toString("hex")}`);const p=i.map((t=>t.data));return{commandData:b.SecuxTransactionTool.signRawTransactionList(a(this,r,"f"),p,i[0].confirm),rawTx:a(this,t,"f").toHex()}}appendSignature(i,r){var n;if(i.length!==r.length)throw Error(`ArgumentError: each signature is correspond to one publickey, got ${i.length} signatures and ${r.length} publickeys`);for(let p=0;p<a(this,t,"f").inputs.length;p++){const{data:o}=k(a(this,e,"f"),p,a(this,t,"f").inputs[p],a(this,s,"f")),c=a(this,e,"f")===S.CoinType.GROESTL?Buffer.from(f.sha256.update(o).digest()):Buffer.from(f.sha256.update(f.sha256.update(o).digest()).digest()),u=r[p];if(!h.ecdsaVerify(i[p],c,u))throw Error(`Signature Error #${p}`);let d=null!==(n=a(this,t,"f").inputs[p].sighashType)&&void 0!==n?n:P.Transaction.SIGHASH_ALL;a(this,e,"f")===S.CoinType.BITCOINCASH&&(d|=64);const g=[{pubkey:u,signature:l.encode(i[p],d)}];a(this,t,"f").updateInput(p,{partialSig:g})}return this}finalizeAllInputs(){if(a(this,t,"f").inputs.length<1)throw Error("utxo input cannot be empty");return a(this,t,"f").inputs.forEach(((i,r)=>{(0,u.checkForInput)(a(this,t,"f").inputs,r);const{script:s,scriptType:n}=H(i,a(this,e,"f"));if(!s)throw new Error(`No script found for input #${r}`);if(i.sighashType&&i.partialSig){const{partialSig:t,sighashType:e}=i;for(const i of t){const{hashType:t}=l.decode(i.signature);if(t!==e)throw new Error("Signature sighash does not match input sighash type")}}const{finalScriptSig:p,finalScriptWitness:o}=function(t,e){let i,r;const{signature:s,pubkey:n}=e[0];switch(t){case S.ScriptType.P2PKH:i=l.compile([s,n]);break;case S.ScriptType.P2SH_P2PKH:i=(()=>{const t=l.compile([s,n]),e=l.decompile(t),i={output:e[e.length-1],input:l.compile(e.slice(0,-1))};return l.compile([].concat(l.decompile(i.input),i.output))})();break;case S.ScriptType.P2SH_P2WPKH:r=(0,g.witnessStackToScriptWitness)([s,n]),i=(()=>{const t=Buffer.alloc(0),e=(0,y.Hash160)(n),i=l.compile([w.OPCODES.OP_0,e]);return l.compile([].concat(l.decompile(t),i))})();break;case S.ScriptType.P2WPKH:r=(0,g.witnessStackToScriptWitness)([s,n])}return{finalScriptSig:i,finalScriptWitness:r}}(n,i.partialSig);if(p&&a(this,t,"f").updateInput(r,{finalScriptSig:p}),o&&a(this,t,"f").updateInput(r,{finalScriptWitness:o}),!p&&!o)throw new Error(`Unknown error finalizing input #${r}`)})),this}extractTransaction(){if(!a(this,t,"f").inputs.every((t=>!!t.finalScriptSig||!!t.finalScriptWitness)))throw new Error("Not finalized");const e=a(this,s,"f").clone();return a(this,t,"f").inputs.forEach(((t,i)=>{t.finalScriptSig&&(e.ins[i].script=t.finalScriptSig),t.finalScriptWitness&&(e.ins[i].witness=(0,g.scriptWitnessToWitnessStack)(t.finalScriptWitness))})),e}}function k(t,e,i,r){const s=r,n=i.sighashType||P.Transaction.SIGHASH_ALL,p=(0,g.getSerializer)(t);let o;if(!i.witnessUtxo)throw new Error("Need a Utxo input item for signing");o=i.witnessUtxo;const a=H(i,t).scriptType,c=function(t,e,i,r){let s;switch(e){case S.ScriptType.P2SH_P2PKH:case S.ScriptType.P2SH_P2WPKH:if(!i)throw Error("scriptPubkey is P2SH but redeemScript missing");s=i;break;default:s=t}if(!s)throw Error("cannot extract script");return s}(o.script,a,i.redeemScript,i.witnessScript);let u;switch(null==m||m.debug(`input #${e} script type: ${S.ScriptType[a]}`),null==m||m.debug(`script: ${c.toString("hex")}`),a){case S.ScriptType.P2WPKH:case S.ScriptType.P2SH_P2WPKH:case S.ScriptType.P2SH_P2PKH:null==m||m.debug(S.ScriptType[a]);const i=(0,g.getPayment)(t).p2pkh(t,{hash:c.slice(2)}).scriptPublickey;u=p.dataForWitnessV0(s,e,i,o.value,n);break;default:t===S.CoinType.BITCOINCASH?(null==m||m.debug("bch using bip143"),u=p.dataForWitnessV0(s,e,c,o.value,64|n)):(null==m||m.debug("non-segwit"),u=p.dataForSignature(s,e,c,n))}return{script:c,sighashType:n,data:u}}function H(t,e){let i,r;const s=(0,g.getPayment)(e);if(t.witnessScript)i=t.witnessScript;else if(t.redeemScript)switch(i=t.redeemScript,r=s.classify(i),r){case S.ScriptType.P2PKH:r=S.ScriptType.P2SH_P2PKH;break;case S.ScriptType.P2WPKH:r=S.ScriptType.P2SH_P2WPKH}else i=t.witnessUtxo.script,r=s.classify(i);return{script:i,scriptType:r}}exports.SecuxPsbt=T,t=new WeakMap,e=new WeakMap,i=new WeakMap,r=new WeakMap,s=new WeakMap,n=new WeakMap;class v{constructor(t=Buffer.from([2,0,0,0,0,0,0,0,0,0])){p.set(this,void 0),o(this,p,P.Transaction.fromBuffer(t),"f")}getInputOutputCounts(){return{inputCount:a(this,p,"f").ins.length,outputCount:a(this,p,"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;a(this,p,"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.");a(this,p,"f").addOutput(t.script,t.value)}toBuffer(){return a(this,p,"f").toBuffer()}get tx(){return a(this,p,"f")}}p=new WeakMap; | ||
"use strict";var t,i,e,s,r,n,p,a,o,c,u,h,f=this&&this.__classPrivateFieldSet||function(t,i,e,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 i?t!==i||!r:!i.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?r.call(t,e):r?r.value=e:i.set(t,e),e},l=this&&this.__classPrivateFieldGet||function(t,i,e,s){if("a"===e&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof i?t!==i||!s:!i.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===e?s:"a"===e?s.call(t):s?s.value:i.get(t)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.SecuxPsbt=void 0;const d=require("./parser"),S=require("bip174/src/lib/utils"),y=require("./secp256k1"),g=require("js-sha256"),P=require("./script"),T=require("@secux/utility"),w=require("./interface"),b=require("./utils"),m=require("./payment"),k=require("./transaction"),v=require("./coindef"),H=require("../../protocol-transaction/lib/protocol-transaction"),E=null===T.Logger||void 0===T.Logger?void 0:T.Logger.child({id:"psbt"});class x{constructor(a,o=new d.Psbtv2(new I)){t.add(this),i.set(this,void 0),e.set(this,void 0),s.set(this,void 0),r.set(this,[]),n.set(this,void 0),p.set(this,{}),f(this,i,o,"f"),f(this,e,a,"f"),f(this,s,(0,b.getPayment)(l(this,e,"f")),"f"),f(this,n,l(this,i,"f").globalMap.unsignedTx.tx,"f"),a===w.CoinType.BITCOINCASH&&(l(this,n,"f").version=1)}static FromBuffer(t,i){const e=d.Psbtv2.fromBuffer(t,(t=>new I(t)));return new x(i,e)}AddInput(t){var n;if(!(0,T.isSupportedCoin)(t.path))throw Error(`ArgumentError: unsupport bip32 path, got "${t.path}"`);const p={},a={},o=(0,b.getPublickey)(t.publickey),c=null!==(n=t.script)&&void 0!==n?n:(0,b.getDefaultScript)(t.path);switch(c){case w.ScriptType.P2PKH:p.witnessUtxo={script:l(this,s,"f").p2pkh(l(this,e,"f"),{publickey:o}).scriptPublickey,value:t.satoshis};break;case w.ScriptType.P2SH_P2PKH:const r=l(this,s,"f").p2pkh(l(this,e,"f"),{publickey:o});a.redeemScript=r.scriptPublickey,p.witnessUtxo={script:l(this,s,"f").p2sh(l(this,e,"f"),r.redeemHash).scriptPublickey,value:t.satoshis};break;case w.ScriptType.P2SH_P2WPKH:const n=l(this,s,"f").p2wpkh(l(this,e,"f"),{publickey:o});a.redeemScript=n.scriptPublickey,p.witnessUtxo={script:l(this,s,"f").p2sh(l(this,e,"f"),n.redeemHash).scriptPublickey,value:t.satoshis};break;case w.ScriptType.P2WPKH:p.witnessUtxo={script:l(this,s,"f").p2wpkh(l(this,e,"f"),{publickey:o}).scriptPublickey,value:t.satoshis};break;case w.ScriptType.P2TR:p.witnessUtxo={script:l(this,s,"f").p2tr(l(this,e,"f"),{publickey:o}).scriptPublickey,value:t.satoshis};break;default:throw Error(`ArgumentError: Invalid ScriptType of input#${l(this,i,"f").inputs.length}, got "${w.ScriptType[c]}"`)}if(t.txHex){const s=k.Transaction.fromBuffer(Buffer.from(t.txHex,"hex"));if((0,b.getSerializer)(l(this,e,"f")).getId(s)!==t.hash)throw Error(`UTXO hash for input #${l(this,i,"f").inputs.length} doesn't match the hash specified in the prevout`);const r=s.outs[t.vout];if(r.value!==t.satoshis)throw Error(`UTXO value for input #${l(this,i,"f").inputs.length} doesn't match the value specified in the prevout`);r.script.equals(p.witnessUtxo.script)||null==E||E.warn(`Input script generation error: ${r.script.toString("hex")}, got "${p.witnessUtxo.script}"`)}const u=Object.assign(Object.assign({hash:t.hash,index:t.vout},p),a);return l(this,i,"f").addInput(u),l(this,r,"f").push(t.path),this}AddInputs(t){for(const i of t)this.AddInput(i);return this}AddOutput(t){var r;let n,p,a,o=t.satoshis;if(n=(0,w.isOutuptScriptExtended)(t)){const t=(0,b.getPublickey)(n.publickey);a=n.path;const o=null!==(r=n.script)&&void 0!==r?r:(0,b.getDefaultScript)(a);let c,u;switch(o){case w.ScriptType.P2SH_P2WPKH:if(!n.path.startsWith("m/49'/"))throw Error("P2SH(...) should use m/49' path");c=l(this,s,"f").p2wpkh(l(this,e,"f"),{publickey:t}).redeemHash,u=l(this,s,"f").p2sh(l(this,e,"f"),c),p=u.scriptPublickey;break;case w.ScriptType.P2SH_P2PKH:if(!n.path.startsWith("m/49'/"))throw Error("P2SH(...) should use m/49' path");c=l(this,s,"f").p2pkh(l(this,e,"f"),{publickey:t}).redeemHash,u=l(this,s,"f").p2sh(l(this,e,"f"),c),p=u.scriptPublickey;break;case w.ScriptType.P2PKH:if(!n.path.startsWith("m/44'/"))throw Error("P2PKH should use m/44' path");p=l(this,s,"f").p2pkh(l(this,e,"f"),{publickey:t}).scriptPublickey;break;case w.ScriptType.P2WPKH:if(!n.path.startsWith("m/84'/"))throw Error("P2WPKH should use m/84' path");p=l(this,s,"f").p2wpkh(l(this,e,"f"),{publickey:t}).scriptPublickey;break;case w.ScriptType.P2TR:if(!n.path.startsWith("m/86'/"))throw Error("P2TR should use m/86' path");p=l(this,s,"f").p2tr(l(this,e,"f"),{publickey:t}).scriptPublickey;break;default:throw Error(`ArgumentError: Invalid ScriptType of output#${l(this,i,"f").outputs.length}, got "${w.ScriptType[o]}"`)}}else if(n=(0,w.isOutputAddress)(t))p=l(this,s,"f").decode(l(this,e,"f"),n.address);else{if(!(n=(0,w.isOutuptScript)(t)))throw Error("Invalid parameter of output");p=Buffer.from(n.scriptHex,"hex")}return l(this,i,"f").addOutput({script:p,value:o,path:a}),this}AddOutputs(t){for(const i of t)this.AddOutput(i);return this}PrepareSign(s){if(s){const e=l(this,t,"m",u).call(this),r=Math.round(e*s);null==E||E.info(`Estimated fee is ${r}, with ${s} fee rates.`);const p=l(this,i,"f").inputs.reduce(((t,i)=>t+i.witnessUtxo.value),0),a=l(this,n,"f").outs[0].value,o=1===l(this,i,"f").outputs.length?0:l(this,n,"f").outs[1].value,c=p-a-o;if(c<r&&(null==E||E.warn(`Estimated fee is ${r}, but got ${c}.`)),c>r||c<e)if(0!==o){const t=p-a-r;if(t<0)throw Error(`Insufficient amount, expect ${a+r}, but got ${p}.`);l(this,n,"f").outs[1].value=t,null==E||E.info(`Modify change amount from ${o} to ${t}.`)}else{const t=p-r;if(t<0)throw Error(`Insufficient amount, expect at least ${r}, but got ${p}.`);l(this,n,"f").outs[0].value=t,null==E||E.info(`Modify spend amount from ${a} to ${t}.`)}}const{type:p}=l(this,t,"m",a).call(this,0),c=l(this,e,"f")!==w.CoinType.BITCOINCASH&&p===w.ScriptType.P2PKH?Buffer.alloc(0):Buffer.from([l(this,i,"f").outputs.length,...(0,T.BigIntToBuffer)(l(this,n,"f").outs[0].value,8),l(this,n,"f").outs[0].script.length,...l(this,n,"f").outs[0].script,...l(this,n,"f").outs.slice(1).reduce(((t,i)=>[...t,...(0,T.BigIntToBuffer)(i.value,8),...(0,T.buildPathBuffer)(i.path).pathBuffer]),[])]),h=l(this,i,"f").inputs.map(((i,e)=>{const s=l(this,t,"m",o).call(this,e);return null==E||E.debug(`tx data [${e}]: ${s.toString("hex")}`),s}));null==E||E.debug(`confirm data: ${c.toString("hex")}`);return{commandData:H.SecuxTransactionTool.signRawTransactionList(l(this,r,"f"),h,c),rawTx:l(this,i,"f").toHex()}}appendSignature(s,r){var n,p;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 c=0;c<l(this,i,"f").inputs.length;c++){const u=l(this,t,"m",o).call(this,c);if(l(this,t,"m",a).call(this,c).type!==w.ScriptType.P2TR){const t=l(this,e,"f")===w.CoinType.GROESTL?Buffer.from(g.sha256.update(u).digest()):Buffer.from(g.sha256.update(g.sha256.update(u).digest()).digest()),p=r[c];if(!y.secp256k1.verify(t,p,s[c]))throw Error(`Signature Error #${c}`);let a=null!==(n=l(this,i,"f").inputs[c].sighashType)&&void 0!==n?n:k.Transaction.SIGHASH_ALL;l(this,e,"f")===w.CoinType.BITCOINCASH&&(a|=64);const o=[{pubkey:p,signature:P.encode(s[c],a)}];l(this,i,"f").updateInput(c,{partialSig:o})}else{const t=(0,b.taggedHash)("TapSighash",u),e=(0,b.toTweakedPublickey)(r[c]),n=s[c].slice(0,64);if(!y.secp256k1.verifySchnorr(t,e,n))throw Error(`Signature Error #${c}`);const a=null!==(p=l(this,i,"f").inputs[c].sighashType)&&void 0!==p?p:k.Transaction.SIGHASH_DEFAULT;l(this,i,"f").inputs[c].partialSig=[{pubkey:e,signature:a===k.Transaction.SIGHASH_DEFAULT?n:Buffer.from([a,...n])}]}}return this}finalizeAllInputs(){if(l(this,i,"f").inputs.length<1)throw Error("utxo input cannot be empty");return l(this,i,"f").inputs.forEach(((t,s)=>{(0,S.checkForInput)(l(this,i,"f").inputs,s);const{script:r,scriptType:n}=W(t,l(this,e,"f"));if(!r)throw new Error(`No script found for input #${s}`);if(t.sighashType&&t.partialSig){const{partialSig:i,sighashType:e}=t;for(const t of i){const{hashType:i}=P.decode(t.signature);if(i!==e)throw new Error("Signature sighash does not match input sighash type")}}const{finalScriptSig:p,finalScriptWitness:a}=function(t,i){let e,s;const{signature:r,pubkey:n}=i[0];switch(t){case w.ScriptType.P2PKH:e=P.compile([r,n]);break;case w.ScriptType.P2SH_P2PKH:e=(()=>{const t=P.compile([r,n]),i=P.decompile(t),e={output:i[i.length-1],input:P.compile(i.slice(0,-1))};return P.compile([].concat(P.decompile(e.input),e.output))})();break;case w.ScriptType.P2SH_P2WPKH:s=(0,b.witnessStackToScriptWitness)([r,n]),e=(()=>{const t=Buffer.alloc(0),i=(0,m.Hash160)(n),e=P.compile([v.OPCODES.OP_0,i]);return P.compile([].concat(P.decompile(t),e))})();break;case w.ScriptType.P2WPKH:s=(0,b.witnessStackToScriptWitness)([r,n]);break;case w.ScriptType.P2TR:s=r}return{finalScriptSig:e,finalScriptWitness:s}}(n,t.partialSig);if(p&&l(this,i,"f").updateInput(s,{finalScriptSig:p}),a&&l(this,i,"f").updateInput(s,{finalScriptWitness:a}),!p&&!a)throw new Error(`Unknown error finalizing input #${s}`)})),this}extractTransaction(){const e=l(this,n,"f").clone();l(this,i,"f").inputs.forEach(((i,s)=>l(this,t,"m",c).call(this,e,s,i)));const s=l(this,i,"f").inputs.reduce(((t,i)=>t+i.witnessUtxo.value),0)-e.outs.reduce(((t,i)=>t+i.value),0),r=e.virtualSize();if(s<r)throw Error(`Transaction fee must >= ${r}, but got ${s}.`);return e}}function W(t,i){let e,s;const r=(0,b.getPayment)(i);if(t.witnessScript)e=t.witnessScript;else if(t.redeemScript)switch(e=t.redeemScript,s=r.classify(e),s){case w.ScriptType.P2PKH:s=w.ScriptType.P2SH_P2PKH;break;case w.ScriptType.P2WPKH:s=w.ScriptType.P2SH_P2WPKH}else e=t.witnessUtxo.script,s=r.classify(e);return{script:e,scriptType:s}}exports.SecuxPsbt=x,i=new WeakMap,e=new WeakMap,s=new WeakMap,r=new WeakMap,n=new WeakMap,p=new WeakMap,t=new WeakSet,a=function(t){if(l(this,p,"f")[t])return l(this,p,"f")[t];const s=l(this,i,"f").inputs[t],r=s.witnessUtxo,n=W(s,l(this,e,"f")).scriptType,a=function(t,i,e,s){let r;switch(i){case w.ScriptType.P2SH_P2PKH:case w.ScriptType.P2SH_P2WPKH:if(!e)throw Error("scriptPubkey is P2SH but redeemScript missing");r=e;break;default:r=t}if(!r)throw Error("cannot extract script");return r}(r.script,n,s.redeemScript,s.witnessScript);null==E||E.debug(`input #${t} script type: ${w.ScriptType[n]}`),null==E||E.debug(`script: ${a.toString("hex")}`);const o={type:n,scriptPubkey:a};return l(this,p,"f")[t]=o,o},o=function(s){var r,p;const o=l(this,i,"f").inputs[s],c=l(this,n,"f");let u=null!==(r=o.sighashType)&&void 0!==r?r:k.Transaction.SIGHASH_ALL;const h=(0,b.getSerializer)(l(this,e,"f"));void 0===o.witnessUtxo&&Error("Need a Utxo input item for signing");const f=o.witnessUtxo,{type:d,scriptPubkey:S}=l(this,t,"m",a).call(this,s);let y;switch(d){case w.ScriptType.P2WPKH:case w.ScriptType.P2SH_P2WPKH:case w.ScriptType.P2SH_P2PKH:null==E||E.debug(w.ScriptType[d]);const r=(0,b.getPayment)(l(this,e,"f")).p2pkh(l(this,e,"f"),{hash:S.slice(2)}).scriptPublickey;y=h.dataForWitnessV0(c,s,r,f.value,u);break;case w.ScriptType.P2TR:null==E||E.debug("p2tr"),u=null!==(p=o.sighashType)&&void 0!==p?p:k.Transaction.SIGHASH_DEFAULT,y=h.dataForWitnessV1(c,s,l(this,i,"f").inputs.map(((i,e)=>l(this,t,"m",a).call(this,e).scriptPubkey)),l(this,i,"f").inputs.map((t=>t.witnessUtxo.value)),u);break;default:l(this,e,"f")===w.CoinType.BITCOINCASH?(null==E||E.debug("bch using bip143"),y=h.dataForWitnessV0(c,s,S,f.value,64|u)):(null==E||E.debug("non-segwit"),y=h.dataForSignature(c,s,S,u))}return y},c=function(i,e,s){if(!s.finalScriptSig&&!s.finalScriptWitness)throw Error(`input#${e} not finalized.`);s.finalScriptSig&&(i.ins[e].script=s.finalScriptSig),s.finalScriptWitness&&(l(this,t,"m",a).call(this,e).type!==w.ScriptType.P2TR?i.ins[e].witness=(0,b.scriptWitnessToWitnessStack)(s.finalScriptWitness):i.ins[e].witness=[s.finalScriptWitness])},u=function(){const e=l(this,n,"f").clone();let s=0,r=2;return l(this,i,"f").inputs.forEach(((i,e)=>{var n;const{type:p}=l(this,t,"m",a).call(this,e);switch(p){case w.ScriptType.P2PKH:s+=107;break;case w.ScriptType.P2SH_P2PKH:break;case w.ScriptType.P2SH_P2WPKH:s+=23,r+=105,r+=2,r+=1;break;case w.ScriptType.P2WPKH:r+=105,r+=2,r+=1;break;case w.ScriptType.P2TR:const t=null!==(n=i.sighashType)&&void 0!==n?n:k.Transaction.SIGHASH_DEFAULT;r+=t===k.Transaction.SIGHASH_DEFAULT?64:65,r+=1,r+=1}})),e.virtualSize()+s+r/4};class I{constructor(t=Buffer.from([2,0,0,0,0,0,0,0,0,0])){h.set(this,void 0),f(this,h,k.Transaction.fromBuffer(t),"f")}getInputOutputCounts(){return{inputCount:l(this,h,"f").ins.length,outputCount:l(this,h,"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 i="string"==typeof t.hash?Buffer.from(Buffer.from(t.hash,"hex").reverse()):t.hash;l(this,h,"f").addInput(i,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.");l(this,h,"f").addOutput(t.script,t.value,t.path)}toBuffer(){return l(this,h,"f").toBuffer()}get tx(){return l(this,h,"f")}}h=new WeakMap; |
@@ -5,2 +5,3 @@ /// <reference types="node" /> | ||
static readonly DEFAULT_SEQUENCE = 4294967295; | ||
static readonly SIGHASH_DEFAULT = 0; | ||
static readonly SIGHASH_ALL = 1; | ||
@@ -10,2 +11,4 @@ static readonly SIGHASH_NONE = 2; | ||
static readonly SIGHASH_ANYONECANPAY = 128; | ||
static readonly SIGHASH_OUTPUT_MASK = 3; | ||
static readonly SIGHASH_INPUT_MASK = 128; | ||
static readonly ADVANCED_TRANSACTION_MARKER = 0; | ||
@@ -25,2 +28,3 @@ static readonly ADVANCED_TRANSACTION_FLAG = 1; | ||
value: number; | ||
path?: string; | ||
}>; | ||
@@ -31,6 +35,7 @@ constructor(); | ||
static dataForWitnessV0(trans: Transaction, inIndex: number, prevOutScript: Buffer, value: number, hashType: number): Buffer; | ||
static dataForWitnessV1(trans: Transaction, inIndex: number, prevOutScripts: Buffer[], values: number[], hashType: number, leafHash?: Buffer, annex?: Buffer): Buffer; | ||
static getHash(trans: Transaction, forWitness?: boolean): Buffer; | ||
static getId(trans: Transaction): string; | ||
addInput(hash: Buffer, index: number, sequence?: number, scriptSig?: Buffer): void; | ||
addOutput(scriptPubKey: Buffer, value: number): void; | ||
addOutput(scriptPubKey: Buffer, value: number, path?: string): void; | ||
toBuffer(buffer?: Buffer, initialOffset?: number, _ALLOW_WITNESS?: boolean): Buffer; | ||
@@ -41,4 +46,6 @@ toHex(): string; | ||
clone(): Transaction; | ||
weight(): number; | ||
virtualSize(): number; | ||
byteLength(_ALLOW_WITNESS?: boolean): number; | ||
} | ||
declare function varSliceSize(someScript: Buffer): number; |
@@ -1,1 +0,1 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.varSliceSize=exports.Transaction=void 0;const e=require("js-sha256"),t=require("varuint-bitcoin"),r=require("./bufferutils"),s=require("./script"),i=require("./coindef"),n=Buffer.from("0000000000000000000000000000000000000000000000000000000000000000","hex"),o=Buffer.from("0000000000000000000000000000000000000000000000000000000000000001","hex"),f=Buffer.allocUnsafe(0),c=Buffer.from("ffffffffffffffff","hex"),u={script:f,valueBuffer:c,value:0};class a{constructor(){this.ins=[],this.outs=[],this.version=2,this.locktime=0}static fromBuffer(e){const t=new r.BufferReader(e),s=new a;s.version=t.readInt32();const i=t.readUInt8(),n=t.readUInt8();let o=!1;i===a.ADVANCED_TRANSACTION_MARKER&&n===a.ADVANCED_TRANSACTION_FLAG?o=!0:t.offset-=2;const f=t.readVarInt();for(let e=0;e<f;++e)s.ins.push({hash:t.readSlice(32),index:t.readUInt32(),script:t.readVarSlice(),sequence:t.readUInt32(),witness:[]});const c=t.readVarInt();for(let e=0;e<c;++e)s.outs.push({value:t.readUInt64(),script:t.readVarSlice()});if(o){for(let e=0;e<f;++e)s.ins[e].witness=t.readVector();if(!s.hasWitnesses())throw new Error("Transaction has superfluous witness data")}if(s.locktime=t.readUInt32(),t.offset!==e.length)throw new Error("Transaction has unexpected data");return s}static dataForSignature(e,t,r,n){if(t>=e.ins.length)return o;const c=s.compile(s.decompile(r).filter((e=>e!==i.OPCODES.OP_CODESEPARATOR))),h=e.clone();if((31&n)===a.SIGHASH_NONE)h.outs=[],h.ins.forEach(((e,r)=>{r!==t&&(e.sequence=0)}));else if((31&n)===a.SIGHASH_SINGLE){if(t>=e.outs.length)return o;h.outs.length=t+1;for(let e=0;e<t;e++)h.outs[e]=u;h.ins.forEach(((e,r)=>{r!==t&&(e.sequence=0)}))}n&a.SIGHASH_ANYONECANPAY?(h.ins=[h.ins[t]],h.ins[0].script=c):(h.ins.forEach((e=>{e.script=f})),h.ins[t].script=c);const l=Buffer.allocUnsafe(h.byteLength(!1)+4);return l.writeInt32LE(n,l.length-4),h.toBuffer(l,0,!1),l}static dataForWitnessV0(e,t,s,i,o){let f,c=Buffer.from([]),u=n,S=n,A=n;if(o&a.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)})),S=h(c)),o&a.SIGHASH_ANYONECANPAY||(31&o)===a.SIGHASH_SINGLE||(31&o)===a.SIGHASH_NONE||(c=Buffer.allocUnsafe(4*e.ins.length),f=new r.BufferWriter(c,0),e.ins.forEach((e=>{f.writeUInt32(e.sequence)})),A=h(c)),(31&o)!==a.SIGHASH_SINGLE&&(31&o)!==a.SIGHASH_NONE){const t=e.outs.reduce(((e,t)=>e+8+l(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)})),u=h(c)}else if((31&o)===a.SIGHASH_SINGLE&&t<e.outs.length){const s=e.outs[t];c=Buffer.allocUnsafe(8+l(s.script)),f=new r.BufferWriter(c,0),f.writeUInt64(s.value),f.writeVarSlice(s.script),u=h(c)}c=Buffer.allocUnsafe(156+l(s)),f=new r.BufferWriter(c,0);const I=e.ins[t];return f.writeUInt32(e.version),f.writeSlice(S),f.writeSlice(A),f.writeSlice(I.hash),f.writeUInt32(I.index),f.writeVarSlice(s),f.writeUInt64(i),f.writeUInt32(I.sequence),f.writeSlice(u),f.writeUInt32(e.locktime),f.writeUInt32(o),c}static getHash(e,t){return t&&e.isCoinbase()?Buffer.alloc(32,0):h(e.toBuffer(void 0,void 0,t))}static getId(e){return this.getHash(e).reverse().toString("hex")}addInput(e,t,r,s){r&&0!==r||(r=a.DEFAULT_SEQUENCE),this.ins.push({hash:e,index:t,script:s||f,sequence:r,witness:[]})}addOutput(e,t){this.outs.push({script:e,value:t})}toBuffer(e,t,s=!1){e||(e=Buffer.allocUnsafe(this.byteLength(s)));const i=new r.BufferWriter(e,t||0);i.writeInt32(this.version);const n=s&&this.hasWitnesses();return n&&(i.writeUInt8(a.ADVANCED_TRANSACTION_MARKER),i.writeUInt8(a.ADVANCED_TRANSACTION_FLAG)),i.writeVarInt(this.ins.length),this.ins.forEach((e=>{i.writeSlice(e.hash),i.writeUInt32(e.index),i.writeVarSlice(e.script),i.writeUInt32(e.sequence)})),i.writeVarInt(this.outs.length),this.outs.forEach((e=>{void 0!==e.value?i.writeUInt64(e.value):i.writeSlice(e.valueBuffer),i.writeVarSlice(e.script)})),n&&this.ins.forEach((e=>{i.writeVector(e.witness)})),i.writeUInt32(this.locktime),void 0!==t?e.slice(t,i.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 a;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}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+l(t.script)),0)+this.outs.reduce(((e,t)=>e+8+l(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+l(t)),0)}(r.witness)),0):0)}}function h(t){const r=e.sha256.update(t).digest(),s=e.sha256.update(r).digest();return Buffer.from(s)}function l(e){const r=e.length;return t.encodingLength(r)+r}exports.Transaction=a,a.DEFAULT_SEQUENCE=4294967295,a.SIGHASH_ALL=1,a.SIGHASH_NONE=2,a.SIGHASH_SINGLE=3,a.SIGHASH_ANYONECANPAY=128,a.ADVANCED_TRANSACTION_MARKER=0,a.ADVANCED_TRANSACTION_FLAG=1,exports.varSliceSize=l; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.varSliceSize=exports.Transaction=void 0;const e=require("js-sha256"),t=require("varuint-bitcoin"),r=require("./bufferutils"),i=require("./script"),n=require("./coindef"),s=Buffer.from("0000000000000000000000000000000000000000000000000000000000000000","hex"),f=Buffer.from("0000000000000000000000000000000000000000000000000000000000000001","hex"),c=Buffer.alloc(0),o=Buffer.from("ffffffffffffffff","hex"),u={script:c,valueBuffer:o,value:0};class a{constructor(){this.ins=[],this.outs=[],this.version=2,this.locktime=0}static fromBuffer(e){const t=new r.BufferReader(e),i=new a;i.version=t.readInt32();const n=t.readUInt8(),s=t.readUInt8();let f=!1;n===a.ADVANCED_TRANSACTION_MARKER&&s===a.ADVANCED_TRANSACTION_FLAG?f=!0:t.offset-=2;const c=t.readVarInt();for(let e=0;e<c;++e)i.ins.push({hash:t.readSlice(32),index:t.readUInt32(),script:t.readVarSlice(),sequence:t.readUInt32(),witness:[]});const o=t.readVarInt();for(let e=0;e<o;++e)i.outs.push({value:t.readUInt64(),script:t.readVarSlice()});if(f){for(let e=0;e<c;++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 o=i.compile(i.decompile(r).filter((e=>e!==n.OPCODES.OP_CODESEPARATOR))),l=e.clone();if((31&s)===a.SIGHASH_NONE)l.outs=[],l.ins.forEach(((e,r)=>{r!==t&&(e.sequence=0)}));else if((31&s)===a.SIGHASH_SINGLE){if(t>=e.outs.length)return f;l.outs.length=t+1;for(let e=0;e<t;e++)l.outs[e]=u;l.ins.forEach(((e,r)=>{r!==t&&(e.sequence=0)}))}s&a.SIGHASH_ANYONECANPAY?(l.ins=[l.ins[t]],l.ins[0].script=o):(l.ins.forEach((e=>{e.script=c})),l.ins[t].script=o);const h=Buffer.allocUnsafe(l.byteLength(!1)+4);return h.writeInt32LE(s,h.length-4),l.toBuffer(h,0,!1),h}static dataForWitnessV0(e,t,i,n,f){let c,o=Buffer.from([]),u=s,l=s,w=s;if(f&a.SIGHASH_ANYONECANPAY||(o=Buffer.allocUnsafe(36*e.ins.length),c=new r.BufferWriter(o,0),e.ins.forEach((e=>{c.writeSlice(e.hash),c.writeUInt32(e.index)})),l=h(o)),f&a.SIGHASH_ANYONECANPAY||(31&f)===a.SIGHASH_SINGLE||(31&f)===a.SIGHASH_NONE||(o=Buffer.allocUnsafe(4*e.ins.length),c=new r.BufferWriter(o,0),e.ins.forEach((e=>{c.writeUInt32(e.sequence)})),w=h(o)),(31&f)!==a.SIGHASH_SINGLE&&(31&f)!==a.SIGHASH_NONE){const t=e.outs.reduce(((e,t)=>e+8+S(t.script)),0);o=Buffer.allocUnsafe(t),c=new r.BufferWriter(o,0),e.outs.forEach((e=>{c.writeUInt64(e.value),c.writeVarSlice(e.script)})),u=h(o)}else if((31&f)===a.SIGHASH_SINGLE&&t<e.outs.length){const i=e.outs[t];o=Buffer.allocUnsafe(8+S(i.script)),c=new r.BufferWriter(o,0),c.writeUInt64(i.value),c.writeVarSlice(i.script),u=h(o)}o=Buffer.allocUnsafe(156+S(i)),c=new r.BufferWriter(o,0);const I=e.ins[t];return c.writeUInt32(e.version),c.writeSlice(l),c.writeSlice(w),c.writeSlice(I.hash),c.writeUInt32(I.index),c.writeVarSlice(i),c.writeUInt64(n),c.writeUInt32(I.sequence),c.writeSlice(u),c.writeUInt32(e.locktime),c.writeUInt32(f),o}static dataForWitnessV1(e,t,i,n,s,f,o){if(n.length!==e.ins.length||i.length!==e.ins.length)throw new Error("Must supply prevout script and value for all inputs");const u=s===a.SIGHASH_DEFAULT?a.SIGHASH_ALL:s&a.SIGHASH_OUTPUT_MASK,h=(s&a.SIGHASH_INPUT_MASK)===a.SIGHASH_ANYONECANPAY,w=u===a.SIGHASH_NONE,I=u===a.SIGHASH_SINGLE;let A=c,d=c,E=c,U=c,p=c;if(!h){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=l(t),t=Buffer.alloc(8*e.ins.length),s=new r.BufferWriter(t),n.forEach((e=>s.writeUInt64(e))),d=l(t),t=Buffer.alloc(i.map(S).reduce(((e,t)=>e+t))),s=new r.BufferWriter(t),i.forEach((e=>s.writeVarSlice(e))),E=l(t),t=Buffer.alloc(4*e.ins.length),s=new r.BufferWriter(t),e.ins.forEach((e=>s.writeUInt32(e.sequence))),U=l(t)}if(w||I){if(I&&t<e.outs.length){const i=e.outs[t],n=Buffer.alloc(8+S(i.script)),s=new r.BufferWriter(n);s.writeUInt64(i.value),s.writeVarSlice(i.script),p=l(n)}}else{const t=e.outs.map((e=>8+S(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)})),p=l(i)}const N=(f?2:0)+(o?1:0),H=174-(h?49:0)-(w?32:0)+(o?32:0)+(f?37:0),g=Buffer.alloc(H),B=new r.BufferWriter(g);if(B.writeUInt8(s),B.writeInt32(e.version),B.writeUInt32(e.locktime),B.writeSlice(A),B.writeSlice(d),B.writeSlice(E),B.writeSlice(U),w||I||B.writeSlice(p),B.writeUInt8(N),h){const r=e.ins[t];B.writeSlice(r.hash),B.writeUInt32(r.index),B.writeUInt64(n[t]),B.writeVarSlice(i[t]),B.writeUInt32(r.sequence)}else B.writeUInt32(t);if(o){const e=Buffer.alloc(S(o));new r.BufferWriter(e).writeVarSlice(o),B.writeSlice(l(e))}return I&&B.writeSlice(p),f&&(B.writeSlice(f),B.writeUInt8(0),B.writeUInt32(4294967295)),Buffer.concat([Buffer.from([0]),g])}static getHash(e,t){return t&&e.isCoinbase()?Buffer.alloc(32,0):h(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=a.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(a.ADVANCED_TRANSACTION_MARKER),n.writeUInt8(a.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 a;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+S(t.script)),0)+this.outs.reduce(((e,t)=>e+8+S(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+S(t)),0)}(r.witness)),0):0)}}function l(t){return Buffer.from(e.sha256.update(t).digest())}function h(t){const r=e.sha256.update(t).digest(),i=e.sha256.update(r).digest();return Buffer.from(i)}function S(e){const r=e.length;return t.encodingLength(r)+r}exports.Transaction=a,a.DEFAULT_SEQUENCE=4294967295,a.SIGHASH_DEFAULT=0,a.SIGHASH_ALL=1,a.SIGHASH_NONE=2,a.SIGHASH_SINGLE=3,a.SIGHASH_ANYONECANPAY=128,a.SIGHASH_OUTPUT_MASK=3,a.SIGHASH_INPUT_MASK=128,a.ADVANCED_TRANSACTION_MARKER=0,a.ADVANCED_TRANSACTION_FLAG=1,exports.varSliceSize=S; |
@@ -13,1 +13,6 @@ /// <reference types="node" /> | ||
export declare function getPublickey(data: string | Buffer): Buffer; | ||
export declare function toTweakedPublickey(data: string | Buffer): Buffer; | ||
declare const TAGS: readonly ["BIP0340/challenge", "BIP0340/aux", "BIP0340/nonce", "TapLeaf", "TapBranch", "TapSighash", "TapTweak", "KeyAgg list", "KeyAgg coefficient"]; | ||
export declare type TaggedHashPrefix = typeof TAGS[number]; | ||
export declare function taggedHash(prefix: TaggedHashPrefix, data: Buffer): Buffer; | ||
export {}; |
@@ -1,1 +0,1 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.getPublickey=exports.scriptWitnessToWitnessStack=exports.witnessStackToScriptWitness=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"),o=require("./payment_bch"),i=require("./payment_grs"),s=require("./transaction"),c=require("./transaction_grs"),p=require("ow"),u=require("@secux/utility");function a(e){(0,p.default)(e,u.ow_bip32String);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}`)}exports.getPayment=function(e){switch(e){case r.CoinType.BITCOINCASH:return o.PaymentBCH;case r.CoinType.GROESTL:return i.PaymentGRS;default:return n.PaymentBTC}},exports.getCoinType=a,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}throw Error(`ArgumentError: unsupport ScriptType, got ${e}`)},exports.getDefaultScript=function(e){(0,p.default)(e,u.ow_bip32String);const t=e.match(/\d+/g),n=parseInt(t[0],10),o=a(e);switch(n){case 44:return r.ScriptType.P2PKH;case 49:return o!==r.CoinType.BITCOINCASH?r.ScriptType.P2SH_P2WPKH:r.ScriptType.P2SH_P2PKH;case 84:return r.ScriptType.P2WPKH}throw Error(`ArgumentError: unsupport purpose of path, got "${n}" from ${e}`)},exports.getSerializer=function(e){return e===r.CoinType.GROESTL?c.TransactionGRS:s.Transaction},exports.witnessStackToScriptWitness=function(e){let r=Buffer.allocUnsafe(0);const n=e=>{const n=r.length,o=t.encodingLength(e);r=Buffer.concat([r,Buffer.allocUnsafe(o)]),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},o=()=>{const t=n();return r+=t,e.slice(r-t,r)},i=n(),s=[];for(let e=0;e<i;e++)s.push(o());return s},exports.getPublickey=function(t){(0,p.default)(t,p.default.any(u.ow_hexString,p.default.buffer));const r="string"==typeof t?Buffer.from(t,"hex"):t;if((0,p.default)(r,p.default.buffer.is((e=>33===e.length||65===e.length))),!e.publicKeyVerify(r))throw Error(`ArgumentError: invalid secp256k1 publickey, got "${r.toString("hex")}"`);return r}; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.taggedHash=exports.toTweakedPublickey=exports.getPublickey=exports.scriptWitnessToWitnessStack=exports.witnessStackToScriptWitness=exports.getSerializer=exports.getDefaultScript=exports.getPurpose=exports.getCoinType=exports.getPayment=void 0;const e=require("./secp256k1"),t=require("varuint-bitcoin"),r=require("./interface"),n=require("./payment"),o=require("./payment_bch"),s=require("./payment_grs"),c=require("./transaction"),i=require("./transaction_grs"),u=require("ow"),p=require("@secux/utility"),a=require("js-sha256");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 g(t){(0,u.default)(t,u.default.any(p.ow_hexString,u.default.buffer));const r="string"==typeof t?Buffer.from(t,"hex"):t;if((0,u.default)(r,u.default.buffer.is((e=>33===e.length||65===e.length))),!e.secp256k1.isPoint(r))throw Error(`ArgumentError: invalid secp256k1 publickey, got "${r.toString("hex")}"`);return r}exports.getPayment=function(e){switch(e){case r.CoinType.BITCOINCASH:return o.PaymentBCH;case r.CoinType.GROESTL:return s.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}throw Error(`ArgumentError: unsupport ScriptType, got ${e}`)},exports.getDefaultScript=function(e){const t=e.match(/\d+/g),n=parseInt(t[0],10),o=t[1]?f(e):r.CoinType.BITCOIN;switch(n){case 44:return r.ScriptType.P2PKH;case 49:return o!==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?i.TransactionGRS:c.Transaction},exports.witnessStackToScriptWitness=function(e){let r=Buffer.allocUnsafe(0);const n=e=>{const n=r.length,o=t.encodingLength(e);r=Buffer.concat([r,Buffer.allocUnsafe(o)]),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},o=()=>{const t=n();return r+=t,e.slice(r-t,r)},s=n(),c=[];for(let e=0;e<s;e++)c.push(o());return c},exports.getPublickey=g,exports.toTweakedPublickey=function(t){const r=g(t).slice(1,33),n=T("TapTweak",r),o=e.secp256k1.xOnlyPointAddTweak(r,n).xOnlyPubkey;return Buffer.from(o)};const y=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(a.sha256.update(e).digest())}(e);return[e,Buffer.concat([t,t])]})));function T(e,t){const r=Buffer.concat([y[e],t]);return Buffer.from(a.sha256.update(r).digest())}exports.taggedHash=T; |
{ | ||
"name": "@secux/app-btc", | ||
"version": "3.0.0", | ||
"version": "3.0.1", | ||
"description": "SecuX Hardware Wallet BTC API", | ||
@@ -38,3 +38,3 @@ "keywords": [ | ||
"@secux/transport": "^3.0.1", | ||
"@secux/utility": "^3.0.0", | ||
"@secux/utility": "^3.0.1", | ||
"bech32": "^2.0.0", | ||
@@ -47,3 +47,3 @@ "bip174": "^2.0.1", | ||
"ripemd160": "^2.0.2", | ||
"secp256k1": "^4.0.2", | ||
"tiny-secp256k1": "^2.1.2", | ||
"varuint-bitcoin": "^1.1.2" | ||
@@ -53,4 +53,6 @@ }, | ||
"@bitgo/utxo-lib": "^1.9.6", | ||
"bitcoinjs-lib": "5.2.0", | ||
"@mempool/mempool.js": "^2.2.5", | ||
"bitcoinjs-lib": "^6.0.1", | ||
"cashaddress": "^1.1.0", | ||
"ecpair": "^1.0.1", | ||
"groestlcoin-address-validation": "^1.0.0", | ||
@@ -57,0 +59,0 @@ "groestlcoinjs-lib": "^5.2.0" |
@@ -40,3 +40,3 @@ [![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/) | ||
```ts | ||
cnost address = await device.getAddress("m/49'/0'/0'/0/0"); | ||
const address = await device.getAddress("m/49'/0'/0'/0/0"); | ||
``` | ||
@@ -109,3 +109,8 @@ - legacy address (default script: P2PKH) | ||
const { raw_tx } = await device.sign(inputs, { to, utxo }); | ||
const { raw_tx } = await device.sign( | ||
inputs, | ||
{ to, utxo }, | ||
// given feeRate to estimate fee, and fee will be changed if greater than estimated value or less than minimal fee. | ||
// { feeRate: 1 } | ||
); | ||
@@ -122,2 +127,30 @@ /* | ||
4. Derive address from xpub, ypub, or zpub. | ||
- native segwit address (default script: P2WPKH) | ||
```ts | ||
// m/84'/0'/0' | ||
const zpub = "zpub6rFR7y4Q2AijBEqTUquhVz398htDFrtymD9xYYfG1m4wAcvPhXNfE3EfH1r1ADqtfSdVCToUG868RvUUkgDKf31mGDtKsAYz2oz2AGutZYs"; | ||
// m/84'/0'/0'/0/0 | ||
const address = SecuxBTC.deriveAddress(zpub, 0, 0, | ||
{ | ||
// you can use specific coin and script | ||
// coin: CoinType.DOGECOIN, | ||
// script: ScriptType.P2WPKH | ||
}); | ||
``` | ||
- segwit address (default script: P2SH_P2WPKH) | ||
```ts | ||
// m/49'/0'/1' | ||
const ypub = "ypub6Ww3ibxVfGzLtJR4F9SRBicspAfvmvw54yern9Q6qZWFC9T6FYA34K57La5Sgs8pXuyvpDfEHX5KNZRiZRukUWaVPyL4NxA69sEAqdoV8ve"; | ||
// m/49'/0'/1'/0/1 | ||
const address = SecuxBTC.deriveAddress(ypub, 0, 1); | ||
``` | ||
- legacy address (default script: P2PKH) | ||
```ts | ||
// m/44'/0'/0' | ||
const xpub = "xpub6BosfCnifzxcFwrSzQiqu2DBVTshkCXacvNsWGYJVVhhawA7d4R5WSWGFNbi8Aw6ZRc1brxMyWMzG3DSSSSoekkudhUd9yLb6qx39T9nMdj"; | ||
// m/44'/0'/0'/1/0 | ||
const address = SecuxBTC.deriveAddress(xpub, 1, 0); | ||
``` | ||
# API Reference | ||
@@ -136,5 +169,6 @@ BTC package for SecuX device | ||
* [.resolveXPublickey(response, path)](#SecuxBTC.resolveXPublickey) ⇒ <code>string</code> | ||
* [.prepareSign(inputs, outputs)](#SecuxBTC.prepareSign) ⇒ [<code>prepared</code>](#prepared) | ||
* [.prepareSign(inputs, outputs, [option])](#SecuxBTC.prepareSign) ⇒ [<code>prepared</code>](#prepared) | ||
* [.resolveSignatureList(response)](#SecuxBTC.resolveSignatureList) ⇒ <code>Array.<string></code> | ||
* [.resolveTransaction(response, unsigned, publickeys, [coin])](#SecuxBTC.resolveTransaction) ⇒ <code>string</code> | ||
* [.deriveAddress(xpub, change, addressIndex, [option])](#SecuxBTC.deriveAddress) ⇒ <code>string</code> | ||
@@ -165,3 +199,3 @@ <br/> | ||
| publickey | <code>string</code> \| <code>Buffer</code> | secp256k1 publickey (hex string or buffer) | | ||
| path | <code>string</code> \| <code>PathObject</code> | BIP32 path, ex: m/44'/0'/0'/0/0 | | ||
| path | <code>string</code> \| [<code>PathObject</code>](#PathObject) | BIP32 path, ex: m/44'/0'/0'/0/0 | | ||
@@ -179,3 +213,3 @@ <br/> | ||
| response | <code>communicationData</code> | data from device | | ||
| path | <code>string</code> \| <code>PathObject</code> | BIP32 path, ex: m/44'/0'/0'/0/0 | | ||
| path | <code>string</code> \| [<code>PathObject</code>](#PathObject) | BIP32 path, ex: m/44'/0'/0'/0/0 | | ||
@@ -235,3 +269,3 @@ <br/> | ||
### **SecuxBTC.prepareSign(inputs, outputs) ⇒ [<code>prepared</code>](#prepared)** | ||
### **SecuxBTC.prepareSign(inputs, outputs, [option]) ⇒ [<code>prepared</code>](#prepared)** | ||
*Prepare data for signing.* | ||
@@ -244,2 +278,3 @@ | ||
| outputs | [<code>txOutput</code>](#txOutput) | output object | | ||
| [option] | [<code>SignOption</code>](#SignOption) | | | ||
@@ -274,4 +309,19 @@ <br/> | ||
<br/> | ||
<a name="SecuxBTC.deriveAddress"></a> | ||
### **SecuxBTC.deriveAddress(xpub, change, addressIndex, [option]) ⇒ <code>string</code>** | ||
*Derive xpub and generate BTC address.* | ||
**Returns**: <code>string</code> - address | ||
| Param | Type | Description | | ||
| --- | --- | --- | | ||
| xpub | <code>string</code> | extended publickey (base58 encoded), depth must be 3 | | ||
| change | <code>number</code> | BIP44 change field | | ||
| addressIndex | <code>number</code> | BIP44 address_index field | | ||
| [option] | [<code>AddressOption</code>](#AddressOption) | for address generation | | ||
<br/> | ||
<br/> | ||
<a name="txInput"></a> | ||
@@ -304,2 +354,13 @@ | ||
<br/> | ||
<a name="SignOption"></a> | ||
## SignOption | ||
**Properties** | ||
| Name | Type | Description | | ||
| --- | --- | --- | | ||
| [coin] | <code>CoinType</code> | enum | | ||
| [feeRate] | <code>number</code> | base fee per vbyte | | ||
<br/> | ||
<a name="txOutputAddress"></a> | ||
@@ -340,2 +401,13 @@ | ||
<br/> | ||
<a name="PathObject"></a> | ||
## PathObject | ||
**Properties** | ||
| Name | Type | Description | | ||
| --- | --- | --- | | ||
| coin | <code>CoinType</code> | enum | | ||
| script | <code>ScriptType</code> | enum | | ||
<br/> | ||
<a name="AddressOption"></a> | ||
@@ -342,0 +414,0 @@ |
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
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
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
105703
31
600
419
7
14
+ Addedtiny-secp256k1@^2.1.2
+ Addedtiny-secp256k1@2.2.3(transitive)
+ Addeduint8array-tools@0.0.7(transitive)
- Removedsecp256k1@^4.0.2
- Removednode-addon-api@5.1.0(transitive)
- Removednode-gyp-build@4.8.4(transitive)
- Removedsecp256k1@4.0.4(transitive)
Updated@secux/utility@^3.0.1