Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@secux/app-btc

Package Overview
Dependencies
Maintainers
2
Versions
35
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@secux/app-btc - npm Package Compare versions

Comparing version 3.2.4 to 3.2.5

393

lib/app-btc.js

@@ -1,392 +0,1 @@

"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var SecuxBTC_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SecuxBTC = exports.ScriptType = exports.CoinType = void 0;
const secp256k1 = require('secp256k1/elliptic');
const varuint = require("varuint-bitcoin");
const utility_1 = require("@secux/utility");
const xpub_1 = require("@secux/utility/lib/xpub");
const ow_1 = require("ow");
const protocol_transaction_1 = require("@secux/protocol-transaction");
const communication_1 = require("@secux/utility/lib/communication");
const interface_1 = require("@secux/protocol-transaction/lib/interface");
const interface_2 = require("./interface");
Object.defineProperty(exports, "CoinType", { enumerable: true, get: function () { return interface_2.CoinType; } });
Object.defineProperty(exports, "ScriptType", { enumerable: true, get: function () { return interface_2.ScriptType; } });
const psbt_1 = require("./psbt");
const utils_1 = require("./utils");
const transport_1 = require("@secux/transport");
/**
* BTC package for SecuX device
*/
let SecuxBTC = SecuxBTC_1 = class SecuxBTC {
/**
* Convert publickey to BTC address.
* @param {string | Buffer} publickey secp256k1 publickey (hex string or buffer)
* @param {string | PathObject} path BIP32 path, ex: m/44'/0'/0'/0/0
* @returns {string} address
*/
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, true));
const coin = (typeof path === "string") ? (0, utils_1.getCoinType)(path) : path.coin;
const script = (typeof path === "string") ? (0, utils_1.getDefaultScript)(path) : path.script;
const 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}`);
}
}
/**
* Prepare data for address generation.
* @param {string} path BIP32 path, ex: m/44'/0'/0'/0/0
* @param {AddressOption} [option] for path validation
* @returns {communicationData} data for sending to device
*/
static prepareAddress(path, option) {
return this.preparePublickey(path, option);
}
/**
* Generate address from response data.
* @param {communicationData} response data from device
* @param {string | PathObject} path BIP32 path, ex: m/44'/0'/0'/0/0
* @returns {string} address
*/
static resolveAddress(response, path) {
const pk = SecuxBTC_1.resolvePublickey(response);
return SecuxBTC_1.addressConvert(pk, path);
}
/**
* Prepare data for secp256k1 publickey.
* @param {string} path BIP32 path, ex: m/44'/0'/0'/0/0
* @param {AddressOption} [option] for path validation
* @returns {communicationData} data for sending to device
*/
static preparePublickey(path, option) {
var _a;
(0, ow_1.default)(path, interface_2.ow_path);
if (option)
(0, ow_1.default)(option, interface_2.ow_AddressOption);
const coin = (_a = option === null || option === void 0 ? void 0 : option.coin) !== null && _a !== void 0 ? _a : (0, utils_1.getCoinType)(path);
const cointype = interface_2.coinmap[coin].coinType;
const purpose = ((option === null || option === void 0 ? void 0 : option.script) === undefined) ? undefined : (0, utils_1.getPurpose)(option === null || option === void 0 ? void 0 : option.script);
(0, ow_1.default)(path, (0, utility_1.ow_strictPath)(cointype, purpose));
return protocol_transaction_1.SecuxTransactionTool.getPublickey(path, interface_1.EllipticCurve.SECP256K1);
}
/**
* Resolve secp256k1 publickey from response data.
* @param {communicationData} response data from device
* @returns {string} secp256k1 publickey (hex string)
*/
static resolvePublickey(response) {
const pk = protocol_transaction_1.SecuxTransactionTool.resolvePublickey(response, interface_1.EllipticCurve.SECP256K1, true);
return Buffer.from(pk, "base64").toString("hex");
}
/**
* Prepare data for extended publickey generation.
* @param {string} path BIP32 path, ex: m/44'/0'/0'/0/0
* @returns {communicationData} data for sending to device
*/
static prepareXPublickey(path) {
(0, ow_1.default)(path, interface_2.ow_accountPath);
return protocol_transaction_1.SecuxTransactionTool.getXPublickey(path);
}
/**
* Generate extended publickey from response data.
* @param {communicationData} response data from device
* @param {string} path BIP32 path, ex: m/44'/0'/0'/0/0
* @returns {string} extended publickey (xpub, ypub or zpub)
*/
static resolveXPublickey(response, path) {
(0, ow_1.default)(path, interface_2.ow_accountPath);
return protocol_transaction_1.SecuxTransactionTool.resolveXPublickey(response, path);
}
/**
* Prepare data for signing.
* @param {txInput} inputs array of utxo object
* @param {txOutput} outputs output object
* @param {SignOption} [option]
* @returns {prepared}
*/
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 = (_a = option === null || option === void 0 ? void 0 : option.coin) !== null && _a !== void 0 ? _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;
//@ts-ignore
(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;
//@ts-ignore
(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;
//@ts-ignore
(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, option === null || option === void 0 ? void 0 : option.isRBF);
psbt.AddInputs(inputs);
psbt.AddOutputs(outputs.utxo ? [outputs.to, outputs.utxo] : [outputs.to]);
return (0, communication_1.wrapResult)(psbt.PrepareSign(option === null || option === void 0 ? void 0 : option.feeRate));
}
/**
* Reslove signature from response data.
* @param {communicationData} response data from device
* @returns {Array<string>} signature array of hex string
*/
static resolveSignatureList(response) {
const sigBufList = protocol_transaction_1.SecuxTransactionTool.resolveSignatureList(response).map(x => Buffer.from(x, "base64"));
const sigList = sigBufList.map(x => utility_1.Signature.fromSignature(x));
return sigList.map(x => Buffer.concat([x.r, x.s]).toString("hex"));
}
/**
* Serialize transaction wtih signature for broadcasting.
* @param {communicationData|Array<communicationData>} response data from device
* @param {TransactionObject} params
* @returns {string} signed raw transaction
*/
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_1.resolveSignatureList(rsp).map(x => Buffer.from(x, "hex"));
signatures.push(...sigList);
}
const pks = params.publickeys.map(x => (0, utils_1.getPublickey)(x));
const psbt = psbt_1.SecuxPsbt.FromBuffer(Buffer.from(params.rawTx, "hex"), (_a = params.coin) !== null && _a !== void 0 ? _a : interface_2.CoinType.BITCOIN);
const tx = psbt.appendSignature(signatures, pks)
.finalizeAllInputs()
.extractTransaction()
.toHex();
return tx;
}
static async getAddress(path, option) {
var _a, _b;
const data = SecuxBTC_1.prepareAddress(path, option);
const rsp = await this.Exchange((0, communication_1.getBuffer)(data));
const address = SecuxBTC_1.resolveAddress(rsp, {
coin: (_a = option === null || option === void 0 ? void 0 : option.coin) !== null && _a !== void 0 ? _a : (0, utils_1.getCoinType)(path),
script: (_b = option === null || option === void 0 ? void 0 : option.script) !== null && _b !== void 0 ? _b : (0, utils_1.getDefaultScript)(path)
});
return address;
}
static async getPublickey(path, option) {
const data = SecuxBTC_1.preparePublickey(path, option);
const rsp = await this.Exchange((0, communication_1.getBuffer)(data));
const publickey = SecuxBTC_1.resolvePublickey(rsp);
return publickey;
}
static async getXPublickey(path) {
const data = SecuxBTC_1.prepareXPublickey(path);
const rsp = await this.Exchange((0, communication_1.getBuffer)(data));
const xpub = SecuxBTC_1.resolveXPublickey(rsp, path);
return xpub;
}
static async sign(inputs, outputs, option) {
var _a, _b;
const cache = {};
const getPK = async (path) => {
if (cache[path] !== undefined)
return cache[path];
const publickey = await SecuxBTC_1.getPublickey.call(this, path, { coin });
const pk = Buffer.from(publickey, "hex");
cache[path] = pk;
return pk;
};
const coin = (_a = option === null || option === void 0 ? void 0 : option.coin) !== null && _a !== void 0 ? _a : (0, utils_1.getCoinType)(inputs[0].path);
for (const txIn of inputs) {
if (txIn.publickey !== undefined)
continue;
txIn.publickey = await getPK(txIn.path);
}
//@ts-ignore
if (outputs.to.path && outputs.to.publickey === undefined) {
//@ts-ignore
outputs.to.publickey = await getPK(outputs.to.path);
}
if (((_b = outputs.utxo) === null || _b === void 0 ? void 0 : _b.path) && outputs.utxo.publickey === undefined) {
outputs.utxo.publickey = await getPK(outputs.utxo.path);
}
const { commands, rawTx } = SecuxBTC_1.prepareSign(inputs, outputs, Object.assign(Object.assign({}, option), { coin }));
return {
multi_command: commands,
rawTx,
publickeys: inputs.map(x => x.publickey),
coin
};
}
/**
* 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, 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 (_xpub.depth !== 3)
throw Error(`ArgumentError: expect depth from xpub is 3, but got ${_xpub.depth}`);
if (option === null || option === void 0 ? 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)(option === null || option === void 0 ? void 0 : option.script);
if (_xpub.purpose !== purpose) {
throw Error(`ArgumentError: expect purpose from xpub is ${purpose}, but got ${_xpub.purpose}`);
}
}
else {
if (_xpub.purpose !== 44)
throw Error(`ArgumentError: expect purpose from xpub is 44, but got ${_xpub.purpose}`);
_xpub.purpose === (0, utils_1.getPurpose)(option === null || option === void 0 ? void 0 : option.script);
}
}
const { publickey } = (0, xpub_1.deriveKey)(_xpub.publickey, _xpub.chaincode, [change, addressIndex]);
const coin = (_a = option === null || option === void 0 ? void 0 : option.coin) !== null && _a !== void 0 ? _a : interface_2.CoinType.BITCOIN;
const script = (_b = option === null || option === void 0 ? void 0 : option.script) !== null && _b !== void 0 ? _b : (0, utils_1.getDefaultScript)(`m/${_xpub.purpose}'`);
return SecuxBTC_1.addressConvert(publickey, { coin, script });
}
/**
* Estimate virtual size of transaction.
* @param {Array<ScriptType>} inputs
* @param {Array<ScriptType>} outputs
* @returns {number} virtual size
*/
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);
const inputsWitness = inputs.map(x => (0, utils_1.getWitnessSize)(x));
const hasWitness = inputsWitness.some(x => x.length !== 0);
const witnessSize = (!hasWitness) ? 0 :
2 + inputsWitness.reduce((sum, w) => sum + (0, utils_1.vectorSize)(w), 0);
return (baseSize * 4 + witnessSize) / 4;
}
};
SecuxBTC = SecuxBTC_1 = __decorate([
(0, transport_1.staticImplements)()
], SecuxBTC);
exports.SecuxBTC = SecuxBTC;
(0, utility_1.loadPlugin)(SecuxBTC, "SecuxBTC");
/**
* Data type for transmission.
* @typedef {string|Buffer} communicationData
*/
/**
* Script type for input/output.
* @typedef {enum} ScriptType
* @property {number} P2PKH 0
* @property {number} P2WPKH 1
* @property {number} P2SH_P2PKH 2
* @property {number} P2SH_P2WPKH 3
* @property {number} P2TR 4
*/
/**
* Coins that are nearly identical to Bitcoin.
* @typedef {enum} CoinType
* @property {number} BITCOIN 0
* @property {number} TESTNET 1
* @property {number} REGTEST 2
* @property {number} LITECOIN 3
* @property {number} BITCOINCASH 4
* @property {number} GROESTL 5
* @property {number} DIGIBYTE 6
* @property {number} DASH 7
* @property {number} DOGECOIN 8
*/
/**
* Parameters for address generation.
* @typedef {object} PathObject
* @property {CoinType} coin enum
* @property {ScriptType} script enum
*/
/**
* Options for path validation.
* @typedef {object} AddressOption
* @property {CoinType} [coin] enum
* @property {ScriptType} [script] enum
*/
/**
* UTXO.
* @typedef {object} txInput
* @property {string} path BIP32 path refer to utxo
* @property {string | Buffer} publickey scep256k1 publickey from `path`
* @property {string} hash referenced transaction hash
* @property {number} vout referenced transaction output index
* @property {number | string} satoshis referenced transaction output amount
* @property {ScriptType} [script] script type related to `path`
* @property {string} [txHex] referenced raw transaction for validation
*/
/**
* Outputs consist of one payment and one or no return.
* @typedef {object} txOutput
* @property {txOutputAddress | txOutputScriptExtened} to receiving address information
* @property {txOutputScriptExtened} [utxo] changes
*/
/**
* Receiving address and payment.
* @typedef {object} txOutputAddress
* @property {string} address receiving address
* @property {number | string} satoshis receiving amount
*/
/**
* Payment for another held account.
* @typedef {object} txOutputScriptExtened
* @property {string} path BIP32 path
* @property {string | Buffer} publickey scep256k1 publickey from `path`
* @property {number | string} satoshis amount
* @property {ScriptType} [script] script type related to `path`
*/
/**
* Options used during the signing.
* @typedef {object} SignOption
* @property {CoinType} [coin] check cointype for each input
* @property {number} [feeRate] calculate optimal transaction fee and replace it
* @property {boolean} [isRBF] make Replace-by-Fee transaction
*/
/**
* Object for the signing and validation.
* @typedef {object} prepared
* @property {communicationData} commandData data for sending to device
* @property {string} rawTx unsigned raw transaction
*/
/**
* Paramters for finalizing transaction.
* @typedef {object} TransactionObject
* @property {string} rawTx unsigned raw transaction
* @property {Array<string | Buffer>} publickeys publickey correspond to each input
* @property {CoinType} [coin]
*/
"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");

@@ -1,64 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.taprootVerify = exports.taprootConvert = void 0;
const utils_1 = require("./utils");
const BigInteger = require("bigi");
const ecurve = require('ecurve');
const curve = ecurve.getCurveByName('secp256k1');
const G = curve.G;
const p = curve.p;
const n = curve.n;
const zero = BigInteger.ZERO;
const one = BigInteger.ONE;
const two = BigInteger.valueOf(2);
const three = BigInteger.valueOf(3);
const four = BigInteger.valueOf(4);
const seven = BigInteger.valueOf(7);
function taprootConvert(XOnlyPubkey, commitHash) {
const P = liftX(XOnlyPubkey);
const tweak = BigInteger.fromBuffer(commitHash);
const Q = P.add(G.multiply(tweak));
return Q.affineX.toBuffer(32);
}
exports.taprootConvert = taprootConvert;
function taprootVerify(signature, message, XOnlyPubkey) {
const P = liftX(XOnlyPubkey);
const Px = P.affineX.toBuffer(32);
const r = BigInteger.fromBuffer(signature.slice(0, 32));
const s = BigInteger.fromBuffer(signature.slice(32, 64));
if (r.compareTo(p) >= 0)
return false;
if (s.compareTo(n) >= 0)
return false;
const e = getE(r.toBuffer(32), Px, message);
const R = getR(s, e, P);
if (R.curve.isInfinity(R) || !isEven(R) || !R.affineX.equals(r))
return false;
return true;
}
exports.taprootVerify = taprootVerify;
function liftX(XOnlyPubkey) {
const x = BigInteger.fromBuffer(XOnlyPubkey);
const c = x.pow(three).add(seven).mod(p);
const y = c.modPow(p.add(one).divide(four), p);
if (c.compareTo(y.modPow(two, p)) !== 0) {
throw new Error('c is not equal to y^2');
}
let P = ecurve.Point.fromAffine(curve, x, y);
if (!isEven(P)) {
P = ecurve.Point.fromAffine(curve, x, p.subtract(y));
}
return P;
}
function isEven(point) {
return point.affineY.mod(two).equals(zero);
}
function getE(Rx, Px, m) {
const hash = (0, utils_1.taggedHash)('BIP0340/challenge', Buffer.concat([Rx, Px, m]));
return BigInteger.fromBuffer(hash).mod(n);
}
function getR(s, e, P) {
const sG = G.multiply(s);
const eP = P.multiply(e);
return sG.add(eP.negate());
}
"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))};

@@ -1,134 +0,1 @@

"use strict";
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _BufferReader_buffer;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BufferWriter = exports.BufferReader = void 0;
const varuint = require("varuint-bitcoin");
const bignumber_js_1 = require("bignumber.js");
/**
* Helper class for serialization of bitcoin data types into a pre-allocated buffer.
*/
class BufferWriter {
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 = writeUInt64LE(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));
}
}
exports.BufferWriter = BufferWriter;
/**
* Helper class for reading of bitcoin data types from a buffer.
*/
class BufferReader {
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);
this.offset += 1;
return result;
}
readInt32() {
const result = __classPrivateFieldGet(this, _BufferReader_buffer, "f").readInt32LE(this.offset);
this.offset += 4;
return result;
}
readUInt32() {
const result = __classPrivateFieldGet(this, _BufferReader_buffer, "f").readUInt32LE(this.offset);
this.offset += 4;
return result;
}
readUInt64() {
const result = readUInt64LE(__classPrivateFieldGet(this, _BufferReader_buffer, "f"), this.offset);
this.offset += 8;
return result;
}
readVarInt() {
const vi = varuint.decode(__classPrivateFieldGet(this, _BufferReader_buffer, "f"), this.offset);
this.offset += varuint.decode.bytes;
return 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);
this.offset += n;
return result;
}
readVarSlice() {
return this.readSlice(this.readVarInt());
}
readVector() {
const count = this.readVarInt();
const vector = [];
for (let i = 0; i < count; i++)
vector.push(this.readVarSlice());
return vector;
}
}
exports.BufferReader = BufferReader;
_BufferReader_buffer = new WeakMap();
// https://github.com/feross/buffer/blob/master/index.js#L1127
function verifuint(value) {
if (typeof value !== 'number')
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');
}
function writeUInt64LE(buffer, value, offset) {
const num = new bignumber_js_1.BigNumber(value);
verifuint(num.toNumber());
const buf = Buffer.from(num.toString(16).padStart(16, '0'), "hex");
buf.reverse().copy(buffer, offset);
return offset + 8;
}
function readUInt64LE(buffer, offset) {
const str = buffer.slice(offset, offset + 8).reverse().toString("hex");
const value = new bignumber_js_1.BigNumber(str, 16);
verifuint(value.toNumber());
return value;
}
"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;

@@ -1,125 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
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: '\x18Bitcoin Signed Message:\n',
bech32: 'bc',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4,
},
pubKeyHash: 0x00,
scriptHash: 0x05,
wif: 0x80,
coinType: 0,
});
exports.testnet = Object.freeze({
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'tb',
bip32: {
public: 0x043587cf,
private: 0x04358394,
},
pubKeyHash: 0x6f,
scriptHash: 0xc4,
wif: 0xef,
coinType: 1,
});
exports.regtest = Object.freeze({
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'bcrt',
bip32: {
public: 0x043587cf,
private: 0x04358394,
},
pubKeyHash: 0x6f,
scriptHash: 0xc4,
wif: 0xef,
coinType: 1,
});
exports.litecoin = Object.freeze({
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'ltc',
bip32: {
public: 0x019da462,
private: 0x019d9cfe
},
pubKeyHash: 0x30,
scriptHash: 0x32,
wif: 0xb0,
coinType: 2,
});
exports.bitcoincash = Object.freeze({
messagePrefix: '\x18Bitcoin Signed Message:\n',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
pubKeyHash: 0x00,
scriptHash: 0x05,
wif: 0x80,
coinType: 145,
});
exports.groestl = Object.freeze({
messagePrefix: '\x1CGroestlCoin Signed Message:\n',
bech32: 'grs',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
pubKeyHash: 0x24,
scriptHash: 0x05,
wif: 0x80,
coinType: 17,
});
exports.digibyte = Object.freeze({
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'dgb',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
pubKeyHash: 0x1e,
scriptHash: 0x3f,
wif: 0x80,
coinType: 20,
});
exports.dash = Object.freeze({
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'dash',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4
},
pubKeyHash: 0x4c,
scriptHash: 0x10,
wif: 0xcc,
coinType: 5,
});
exports.dogecoin = Object.freeze({
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'doge',
bip32: {
public: 0x02facafd,
private: 0x02fac398
},
pubKeyHash: 0x1e,
scriptHash: 0x16,
wif: 0x9e,
coinType: 3,
});
exports.OPCODES = Object.freeze({
OP_0: 0x00,
OP_PUSHDATA1: 0x4c,
OP_PUSHDATA2: 0x4d,
OP_PUSHDATA4: 0x4e,
OP_1NEGATE: 0x4f,
OP_INT_BASE: 0x50,
OP_DUP: 0x76,
OP_HASH160: 0xa9,
OP_EQUAL: 0x87,
OP_EQUALVERIFY: 0x88,
OP_CODESEPARATOR: 0xab,
OP_CHECKSIG: 0xac,
OP_CHECKMULTISIG: 0xae
});
"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});

@@ -1,113 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
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");
const constants = require("./coindef");
const utils = require("@secux/utility");
var coindef_1 = require("./coindef");
Object.defineProperty(exports, "OPCODES", { enumerable: true, get: function () { return coindef_1.OPCODES; } });
var ScriptType;
(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 = {}));
var CoinType;
(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 = {}));
// must match above CoinType define
exports.coinmap = Object.freeze(Object.values(CoinType).slice(0, CoinType.__LENGTH)
//@ts-ignore
.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);
//@ts-ignore
exports.ow_path = utils.ow_strictPath(exports.btcCoinTypes, exports.btcPurposes);
//@ts-ignore
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)
});
function isOutputAddress(output) {
const out = output;
if (out.address)
return out;
}
exports.isOutputAddress = isOutputAddress;
function isOutuptScript(output) {
const out = output;
if (out.scriptHex)
return out;
}
exports.isOutuptScript = isOutuptScript;
function isOutuptScriptExtended(output) {
try {
(0, ow_1.default)(output, exports.ow_txOutputScriptExtened);
return output;
}
catch (error) { }
}
exports.isOutuptScriptExtended = isOutuptScriptExtended;
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
});
"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});

@@ -1,435 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Psbtv2 = void 0;
const bip174_1 = require("bip174");
const convert = require("bip174/src/lib/converter");
const bufferutils_1 = require("./bufferutils");
class Psbtv2 extends bip174_1.Psbt {
static fromBuffer(buffer, txFromBuffer) {
const results = psbtFromBuffer(buffer, txFromBuffer);
const psbt = new this(results.globalMap.unsignedTx);
Object.assign(psbt, results);
return psbt;
}
}
exports.Psbtv2 = Psbtv2;
function psbtFromBuffer(buffer, txGetter) {
// implements PSBTv2 (https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki)
// refer to https://github.com/achow101/hardware-wallet-interface/blob/psbt2/hwilib/psbt.py
if (buffer.readUInt32BE() !== 0x70736274) {
throw Error("Format Error: Invalid Magic Number");
}
if (buffer.readUInt8(4) !== 0xff) {
throw Error('Format Error: Magic Number must be followed by 0xff separator');
}
const reader = new bufferutils_1.BufferReader(buffer);
reader.offset += 5;
const getKeyValue = () => {
const key = reader.readVarSlice();
const value = reader.readVarSlice();
return { key, value };
};
const checkEndOfKeyValPairs = () => {
if (reader.offset >= buffer.length)
throw Error('Format Error: Unexpected End of PSBT');
const isEnd = buffer.readUInt8(reader.offset) === 0;
if (isEnd)
reader.offset += 1;
return isEnd;
};
const globalMapKeyVals = [];
const globalKeyIndex = {};
while (!checkEndOfKeyValPairs()) {
const keyVal = getKeyValue();
const 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 (unsignedTxMaps.length !== 1)
throw Error('Format Error: Only one UNSIGNED_TX allowed');
const unsignedTx = txGetter(unsignedTxMaps[0].value);
// Get input and output counts to loop the respective fields
const { inputCount, outputCount } = unsignedTx.getInputOutputCounts();
const inputKeyVals = [];
const outputKeyVals = [];
// Get input fields
for (let index = 0; index < inputCount; index++) {
const inputKeyIndex = {};
const input = [];
while (!checkEndOfKeyValPairs()) {
const keyVal = getKeyValue();
const 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 = {};
const output = [];
while (!checkEndOfKeyValPairs()) {
const keyVal = getKeyValue();
const 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 psbtFromKeyVals(unsignedTx, {
globalMapKeyVals,
inputKeyVals,
outputKeyVals,
});
}
function psbtFromKeyVals(unsignedTx, { globalMapKeyVals, inputKeyVals, outputKeyVals }) {
// That was easy :-)
const globalMap = {
unsignedTx,
};
let txCount = 0;
let inputCount;
let outputCount;
for (const keyVal of globalMapKeyVals) {
// If a globalMap item needs pubkey, uncomment
// const pubkey = convert.globals.checkPubkey(keyVal);
let reader;
switch (keyVal.key[0]) {
case GlobalTypes.UNSIGNED_TX:
checkKeyBuffer('global', keyVal.key, GlobalTypes.UNSIGNED_TX);
if (txCount > 0) {
throw new Error('Format Error: GlobalMap has multiple UNSIGNED_TX');
}
txCount++;
break;
case GlobalTypes.GLOBAL_XPUB:
if (globalMap.globalXpub === undefined) {
globalMap.globalXpub = [];
}
globalMap.globalXpub.push(convert.globals.globalXpub.decode(keyVal));
break;
case GlobalTypes.GLOBAL_TX_VERSION:
checkKeyBuffer('global', keyVal.key, GlobalTypes.GLOBAL_TX_VERSION);
if (keyVal.value.length !== 4)
throw Error("Value Error: Global transaction version is not 4 bytes");
globalMap.txVersion = keyVal.value.readUInt32LE();
break;
case GlobalTypes.GLOBAL_FALLBACK_LOCKTIME:
checkKeyBuffer('global', keyVal.key, GlobalTypes.GLOBAL_FALLBACK_LOCKTIME);
if (keyVal.value.length !== 4)
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(); // Value length, we can ignore this
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(); // Value length, we can ignore this
outputCount = reader.readVarInt();
break;
case GlobalTypes.GLOBAL_TXMODIFIABLE:
checkKeyBuffer('global', keyVal.key, GlobalTypes.GLOBAL_TXMODIFIABLE);
if (keyVal.value.length !== 1)
throw Error("Value Error: Global tx modifiable flags is not 1 bytes");
globalMap.txModifiable = (keyVal.value[0] & 1) === 1;
break;
case GlobalTypes.GLOBAL_VERSION:
checkKeyBuffer('global', keyVal.key, GlobalTypes.GLOBAL_VERSION);
if (keyVal.value.length !== 4)
throw Error("Value Error: Global PSBT version is not 4 bytes");
globalMap.version = keyVal.value.readUInt32LE();
break;
default:
// This will allow inclusion during serialization.
if (!globalMap.unknownKeyVals)
globalMap.unknownKeyVals = [];
globalMap.unknownKeyVals.push(keyVal);
}
}
// Get input and output counts to loop the respective fields
inputCount = inputCount !== null && inputCount !== void 0 ? inputCount : inputKeyVals.length;
outputCount = outputCount !== null && outputCount !== void 0 ? outputCount : outputKeyVals.length;
const inputs = [];
const outputs = [];
// Get input fields
for (let index = 0; index < inputCount; index++) {
const input = {
tapScriptSigs: {},
tapScripts: {},
tapBip32Paths: {}
};
for (const keyVal of inputKeyVals[index]) {
convert.inputs.checkPubkey(keyVal);
switch (keyVal.key[0]) {
case InputTypes.NON_WITNESS_UTXO:
checkKeyBuffer('input', keyVal.key, InputTypes.NON_WITNESS_UTXO);
if (input.nonWitnessUtxo !== undefined) {
throw Error('Format Error: Input has multiple NON_WITNESS_UTXO');
}
input.nonWitnessUtxo = convert.inputs.nonWitnessUtxo.decode(keyVal);
break;
case InputTypes.WITNESS_UTXO:
checkKeyBuffer('input', keyVal.key, InputTypes.WITNESS_UTXO);
if (input.witnessUtxo !== undefined) {
throw Error('Format Error: Input has multiple WITNESS_UTXO');
}
input.witnessUtxo = convert.inputs.witnessUtxo.decode(keyVal);
break;
case InputTypes.PARTIAL_SIG:
if (input.partialSig === undefined)
input.partialSig = [];
input.partialSig.push(convert.inputs.partialSig.decode(keyVal));
break;
case InputTypes.SIGHASH_TYPE:
checkKeyBuffer('input', keyVal.key, InputTypes.SIGHASH_TYPE);
if (input.sighashType !== undefined) {
throw Error('Format Error: Input has multiple SIGHASH_TYPE');
}
input.sighashType = convert.inputs.sighashType.decode(keyVal);
break;
case InputTypes.REDEEM_SCRIPT:
checkKeyBuffer('input', keyVal.key, InputTypes.REDEEM_SCRIPT);
if (input.redeemScript !== undefined) {
throw Error('Format Error: Input has multiple REDEEM_SCRIPT');
}
input.redeemScript = convert.inputs.redeemScript.decode(keyVal);
break;
case InputTypes.WITNESS_SCRIPT:
checkKeyBuffer('input', keyVal.key, InputTypes.WITNESS_SCRIPT);
if (input.witnessScript !== undefined) {
throw Error('Format Error: Input has multiple WITNESS_SCRIPT');
}
input.witnessScript = convert.inputs.witnessScript.decode(keyVal);
break;
case InputTypes.BIP32_DERIVATION:
if (input.bip32Derivation === undefined) {
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:
checkKeyBuffer('input', keyVal.key, InputTypes.PREVIOUS_TXID);
if (keyVal.value.length !== 32)
throw Error("Value Error: Previous txid is not 32 bytes");
input.prevTXID = keyVal.value.toString("hex");
break;
case InputTypes.OUTPUT_INDEX:
checkKeyBuffer('input', keyVal.key, InputTypes.OUTPUT_INDEX);
if (keyVal.value.length !== 4)
throw Error("Value Error: Previous output index is not 4 bytes");
input.prevOutputIndex = keyVal.value[0];
break;
case InputTypes.TAP_KEY_SIG:
checkKeyBuffer('input', keyVal.key, InputTypes.TAP_KEY_SIG);
if (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:
checkKeyBuffer('input', keyVal.key, InputTypes.TAP_SCRIPT_SIG);
if (keyVal.key.length !== 65)
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:
checkKeyBuffer('input', keyVal.key, InputTypes.TAP_LEAF_SCRIPT);
if (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 (keyVal.value.length === 0)
throw Error("Value Error: Intput Taproot leaf script cannot be empty");
const script = keyVal.value.slice(-1).toString("hex");
if (!input.tapScripts[script])
input.tapScripts[script] = new Set();
input.tapScripts[script].add(keyVal.key.slice(1).toString("hex"));
break;
case InputTypes.TAP_BIP32_DERIVATION:
checkKeyBuffer('input', keyVal.key, InputTypes.TAP_BIP32_DERIVATION);
if (keyVal.key.length !== 33)
throw Error("Format Error: Input Taproot BIP 32 keypath key is not 33 bytes");
const xonly = keyVal.key.slice(1).toString("hex");
const reader = new bufferutils_1.BufferReader(keyVal.value);
const num_hashs = reader.readVarInt();
const 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:
checkKeyBuffer('input', keyVal.key, InputTypes.TAP_INTERNAL_KEY);
if (keyVal.value.length !== 32)
throw Error("Value Error: Input Taproot internal key is not 32 bytes");
input.tapInternalKey = keyVal.value;
break;
case InputTypes.TAP_MERKLE_ROOT:
checkKeyBuffer('input', keyVal.key, InputTypes.TAP_MERKLE_ROOT);
if (keyVal.value.length !== 32)
throw Error("Value Error: Input Taproot merkle root is not 32 bytes");
input.tapMarkleRoot = keyVal.value.toString("hex");
break;
default:
// This will allow inclusion during serialization.
if (!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]) {
convert.outputs.checkPubkey(keyVal);
let reader;
switch (keyVal.key[0]) {
case OutputTypes.REDEEM_SCRIPT:
checkKeyBuffer('output', keyVal.key, OutputTypes.REDEEM_SCRIPT);
if (output.redeemScript !== undefined) {
throw Error('Format Error: Output has multiple REDEEM_SCRIPT');
}
output.redeemScript = convert.outputs.redeemScript.decode(keyVal);
break;
case OutputTypes.WITNESS_SCRIPT:
checkKeyBuffer('output', keyVal.key, OutputTypes.WITNESS_SCRIPT);
if (output.witnessScript !== undefined) {
throw Error('Format Error: Output has multiple WITNESS_SCRIPT');
}
output.witnessScript = convert.outputs.witnessScript.decode(keyVal);
break;
case OutputTypes.BIP32_DERIVATION:
if (output.bip32Derivation === undefined)
output.bip32Derivation = [];
output.bip32Derivation.push(convert.outputs.bip32Derivation.decode(keyVal));
break;
case OutputTypes.AMOUNT:
checkKeyBuffer('output', keyVal.key, OutputTypes.AMOUNT);
if (keyVal.value.length !== 8)
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:
checkKeyBuffer('output', keyVal.key, OutputTypes.TAP_INTERNAL_KEY);
if (keyVal.value.length !== 32)
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:
checkKeyBuffer('output', keyVal.key, OutputTypes.TAP_BIP32_DERIVATION);
if (keyVal.key.length !== 33)
throw Error("Output Taproot BIP 32 keypath key is not 33 bytes");
const xonly = keyVal.key.slice(1).toString("hex");
const 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:
if (!output.unknownKeyVals)
output.unknownKeyVals = [];
output.unknownKeyVals.push(keyVal);
}
}
outputs.push(output);
}
return { globalMap, inputs, outputs };
}
function checkKeyBuffer(type, keyBuf, keyNum) {
if (!keyBuf.equals(Buffer.from([keyNum]))) {
throw Error(`Format Error: Invalid ${type} key: ${keyBuf.toString('hex')}`);
}
}
var GlobalTypes;
(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 = {}));
var InputTypes;
(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 = {}));
var OutputTypes;
(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 = {}));
"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={}));

@@ -1,74 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CoinType = exports.PaymentBCH = void 0;
const cashaddr = require('cashaddrjs');
const payment_1 = require("./payment");
Object.defineProperty(exports, "CoinType", { enumerable: true, 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');
}
/**
* Pay to Public Key Hash for BITCOINCASH
* @param {CoinType} coin
* @param {Buffer} param1 [publickey | hashed publickey]
* @returns
*/
static p2pkh(coin, opt) {
this.CoinSupported(coin);
if (!opt.publickey && !opt.hash)
throw Error('Invalid Parameters');
if (opt.publickey && opt.hash)
throw Error('Invalid Parameters');
//@ts-ignore
const pkHash = (opt.hash) ? opt.hash : (0, payment_1.Hash160)(opt.publickey);
payment_1.logger === null || payment_1.logger === void 0 ? void 0 : payment_1.logger.info(`publickey hash: ${pkHash.toString('hex')}`);
// FIXME: no fixed params
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, 0x14]);
const check = Buffer.from([interface_1.OPCODES.OP_EQUALVERIFY, interface_1.OPCODES.OP_CHECKSIG]);
const scriptPublickey = Buffer.concat([op, pkHash, check]);
const redeemHash = (0, payment_1.Hash160)(scriptPublickey);
payment_1.logger === null || payment_1.logger === void 0 ? void 0 : payment_1.logger.info(`redeem hash: ${redeemHash.toString('hex')}`);
return { address, scriptPublickey, redeemHash };
}
/**
* Pay to Script Hash for BITCOINCASH
* @param {CoinType} coin
* @param {Buffer} redeemHash
* @returns
*/
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, 0x14]);
const check = Buffer.from([interface_1.OPCODES.OP_EQUAL]);
const scriptPublickey = Buffer.concat([op, redeemHash, check]);
return { address, scriptPublickey };
}
/**
* decode address to script
* @param {string} address
*/
static decode(coin, address) {
if (address.startsWith('1')) {
const hash160 = this.bs58check.decode(address);
const hash = Buffer.from(hash160.slice(1));
return PaymentBCH.p2pkh(coin, { hash }).scriptPublickey;
}
else {
address = (CheckPrefix(address)) ? address : `bitcoincash:${address}`;
const { hash } = cashaddr.decode(address);
return PaymentBCH.p2pkh(coin, { hash: Buffer.from(hash) }).scriptPublickey;
}
}
}
exports.PaymentBCH = PaymentBCH;
function CheckPrefix(address) {
const regexp = /^(?:bitcoincash|bchtest):q.+/;
return regexp.test(address);
}
"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;

@@ -1,18 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CoinType = exports.PaymentGRS = void 0;
const payment_1 = require("./payment");
Object.defineProperty(exports, "CoinType", { enumerable: true, get: function () { return payment_1.CoinType; } });
const bs58_1 = require("@secux/utility/lib/bs58");
const 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(hash);
function hash(data) {
return Buffer.from(groestl.groestl_2(data, 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))}));

@@ -1,232 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.logger = exports.Hash160 = exports.CoinType = exports.PaymentBTC = void 0;
const bech32_1 = require("bech32");
const hash_js_1 = require("hash.js");
const interface_1 = require("./interface");
Object.defineProperty(exports, "CoinType", { enumerable: true, get: function () { return interface_1.CoinType; } });
const bs58_1 = require("@secux/utility/lib/bs58");
const utility_1 = require("@secux/utility");
const utils_1 = require("./utils");
exports.logger = utility_1.Logger === null || utility_1.Logger === void 0 ? void 0 : utility_1.Logger.child({ id: "payment" });
const SEGWIT_VERSION_DIFF = 0x50;
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');
}
/**
* Pay to Public Key Hash for BTC compatible coin
* @param {CoinType} coin
* @param {Buffer} param1 [publickey | hashed publickey]
* @returns
*/
static p2pkh(coin, opt) {
this.CoinSupported(coin);
if (!opt.publickey && !opt.hash)
throw Error('Invalid Parameters');
if (opt.publickey && opt.hash)
throw Error('Invalid Parameters');
//@ts-ignore
const pkHash = (opt.hash) ? opt.hash : Hash160(opt.publickey);
exports.logger === null || exports.logger === void 0 ? void 0 : exports.logger.info(`publickey hash: ${pkHash.toString('hex')}`);
const network = interface_1.coinmap[coin];
const address = this.bs58check.encode(pkHash, Buffer.from([network.pubKeyHash]));
const op = Buffer.from([interface_1.OPCODES.OP_DUP, interface_1.OPCODES.OP_HASH160, 0x14]);
const check = Buffer.from([interface_1.OPCODES.OP_EQUALVERIFY, interface_1.OPCODES.OP_CHECKSIG]);
const scriptPublickey = Buffer.concat([op, pkHash, check]);
const redeemHash = Hash160(scriptPublickey);
exports.logger === null || exports.logger === void 0 ? void 0 : exports.logger.info(`redeem hash: ${redeemHash.toString('hex')}`);
return { address, scriptPublickey, redeemHash };
}
/**
* Pay to Script Hash for BTC compatible coin
* @param {CoinType} coin
* @param {Buffer} redeemHash
* @returns
*/
static p2sh(coin, redeemHash) {
this.CoinSupported(coin);
const network = interface_1.coinmap[coin];
const address = this.bs58check.encode(redeemHash, Buffer.from([network.scriptHash]));
const op = Buffer.from([interface_1.OPCODES.OP_HASH160, 0x14]);
const check = Buffer.from([interface_1.OPCODES.OP_EQUAL]);
const scriptPublickey = Buffer.concat([op, redeemHash, check]);
return { address, scriptPublickey };
}
/**
* Pay to Witness Public Key Hash
* @param {CoinType} coin
* @param {Buffer} param1 [publickey | hashed publickey]
* @returns
*/
static p2wpkh(coin, opt) {
this.CoinSupported(coin);
if (!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);
exports.logger === null || exports.logger === void 0 ? void 0 : exports.logger.info(`publickey hash: ${pkHash.toString('hex')}`);
let network = interface_1.coinmap[coin];
const words = bech32_1.bech32.toWords(pkHash);
words.unshift(0x00);
const address = bech32_1.bech32.encode(network.bech32, words);
const op = Buffer.from([interface_1.OPCODES.OP_0, 0x14]);
const scriptPublickey = Buffer.concat([op, pkHash]);
const redeemHash = Hash160(scriptPublickey);
exports.logger === null || exports.logger === void 0 ? void 0 : exports.logger.info(`redeem hash: ${redeemHash.toString('hex')}`);
return { address, scriptPublickey, redeemHash };
}
/**
* Pay to MultiSig
* @param {number} m
* @param {Array<Buffer>} publickeys
* @returns
*/
static p2ms(m, publickeys) {
if (m <= 0)
throw Error('Invalid paramter \"m\"');
m = m + interface_1.OPCODES.OP_INT_BASE;
const n = publickeys.length + interface_1.OPCODES.OP_INT_BASE;
const multi_pk = Buffer.concat(publickeys);
const redeem = Buffer.concat([
Buffer.from([m]),
multi_pk,
Buffer.from([n]),
Buffer.from([interface_1.OPCODES.OP_CHECKMULTISIG])
]);
const redeemHash = Hash160(redeem);
exports.logger === null || exports.logger === void 0 ? void 0 : exports.logger.info(`redeem hash: ${redeemHash.toString('hex')}`);
const op = Buffer.from([interface_1.OPCODES.OP_HASH160, 0x14]);
const check = Buffer.from([interface_1.OPCODES.OP_EQUAL]);
const scriptPubicKey = Buffer.concat([
op,
redeemHash,
check
]);
return { redeem, scriptPubicKey };
}
static p2tr(coin, opt) {
this.CoinSupported(coin);
if (!opt.publickey && !opt.hash)
throw Error('Invalid Parameters');
if (opt.publickey && opt.hash)
throw Error('Invalid Parameters');
let tweaked = opt.hash;
if (tweaked === undefined) {
tweaked = (0, utils_1.toTweakedPublickey)(opt.publickey);
}
const version = 1;
const network = interface_1.coinmap[coin];
const words = bech32_1.bech32.toWords(tweaked);
words.unshift(version);
const address = bech32_1.bech32m.encode(network.bech32, words);
// witness v1 | PUSH_DATA 32 bytes
const header = Buffer.from([SEGWIT_VERSION_DIFF + version, 0x20]);
const scriptPublickey = Buffer.concat([header, tweaked]);
return { address, scriptPublickey };
}
/**
* decode address to script
* @param {CoinType} coin
* @param {string} address
*/
static decode(coin, address) {
const network = interface_1.coinmap[coin];
// segwit address
if (network.bech32 && address.startsWith(network.bech32)) {
const trimmed = address.slice(network.bech32.length + 1);
let result;
switch (trimmed[0]) {
case 'p':
result = bech32_1.bech32m.decode(address);
break;
default:
result = bech32_1.bech32.decode(address);
break;
}
const version = result.words.shift();
switch (version) {
case 0:
const hash160 = Buffer.from(bech32_1.bech32.fromWords(result.words));
exports.logger === null || exports.logger === void 0 ? void 0 : exports.logger.debug(`bech32 address: ${address}\nbech32 decoded: ${hash160.toString("hex")}`);
return this.p2wpkh(coin, { hash: hash160 }).scriptPublickey;
case 1:
const tweaked = Buffer.from(bech32_1.bech32m.fromWords(result.words));
exports.logger === null || exports.logger === void 0 ? void 0 : exports.logger.debug(`bech32m address: ${address}\nbech32m decoded: ${tweaked.toString("hex")}`);
return 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);
const prefix = hash160[0];
const 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) {
exports.logger === null || exports.logger === void 0 ? void 0 : 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) {
if (script.length !== 25 ||
script[0] !== interface_1.OPCODES.OP_DUP ||
script[1] !== interface_1.OPCODES.OP_HASH160 ||
script[2] !== 0x14 ||
script[23] !== interface_1.OPCODES.OP_EQUALVERIFY ||
script[24] !== interface_1.OPCODES.OP_CHECKSIG)
return false;
return true;
}
static isP2SH(script) {
if (script.length !== 23 ||
script[0] !== interface_1.OPCODES.OP_HASH160 ||
script[1] !== 0x14 ||
script[22] !== interface_1.OPCODES.OP_EQUAL)
return false;
return true;
}
static isP2WPKH(script) {
if (script.length !== 22 ||
script[0] !== interface_1.OPCODES.OP_0 ||
script[1] !== 0x14)
return false;
return true;
}
static isP2TR(script) {
if (script.length !== 34 ||
script[0] !== SEGWIT_VERSION_DIFF + 1 ||
script[1] !== 0x20)
return false;
return true;
}
}
exports.PaymentBTC = PaymentBTC;
PaymentBTC.bs58check = new bs58_1.bs58Check(Hash256);
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.Hash160 = Hash160;
function Hash256(data) {
const sha1 = (0, hash_js_1.sha256)().update(data).digest();
const sha2 = (0, hash_js_1.sha256)().update(sha1).digest();
return Buffer.from(sha2);
}
"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;

@@ -1,566 +0,1 @@

"use strict";
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
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, _PsbtTransaction_tx;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SecuxPsbt = void 0;
const utils_1 = require("bip174/src/lib/utils");
const secp256k1 = require('secp256k1/elliptic');
const hash_js_1 = require("hash.js");
const bignumber_js_1 = require("bignumber.js");
const parser_1 = require("./parser");
const Script = require("./script");
const utility_1 = require("@secux/utility");
const interface_1 = require("./interface");
const utils_2 = require("./utils");
const payment_1 = require("./payment");
const transaction_1 = require("./transaction");
const coindef_1 = require("./coindef");
const communication_1 = require("@secux/utility/lib/communication");
const protocol_transaction_1 = require("@secux/protocol-transaction/lib/protocol-transaction");
const bip340_1 = require("./bip340");
const logger = utility_1.Logger === null || utility_1.Logger === void 0 ? void 0 : utility_1.Logger.child({ id: "psbt" });
const SIGHASH_FORKID = 0x40;
class SecuxPsbt {
constructor(coin, isRBF = false, 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");
//@ts-ignore
__classPrivateFieldSet(this, _SecuxPsbt_tx, __classPrivateFieldGet(this, _SecuxPsbt_data, "f").globalMap.unsignedTx.tx, "f");
if (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));
const psbt = new SecuxPsbt(coin, false, psbtBase);
return psbt;
}
AddInput(input) {
var _a;
if (!(0, utility_1.isSupportedCoin)(input.path))
throw Error(`ArgumentError: unsupport bip32 path, got "${input.path}"`);
const mix1 = {};
const mix2 = {};
const publickey = (0, utils_2.getPublickey)(input.publickey);
const script = (_a = input.script) !== null && _a !== void 0 ? _a : (0, utils_2.getDefaultScript)(input.path);
switch (script) {
case interface_1.ScriptType.P2PKH:
mix1.witnessUtxo = {
script: __classPrivateFieldGet(this, _SecuxPsbt_payment, "f").p2pkh(__classPrivateFieldGet(this, _SecuxPsbt_coin, "f"), { publickey }).scriptPublickey,
value: input.satoshis
};
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: input.satoshis
};
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: input.satoshis
};
break;
case interface_1.ScriptType.P2WPKH:
mix1.witnessUtxo = {
script: __classPrivateFieldGet(this, _SecuxPsbt_payment, "f").p2wpkh(__classPrivateFieldGet(this, _SecuxPsbt_coin, "f"), { publickey }).scriptPublickey,
value: input.satoshis
};
break;
case interface_1.ScriptType.P2TR:
mix1.witnessUtxo = {
script: __classPrivateFieldGet(this, _SecuxPsbt_payment, "f").p2tr(__classPrivateFieldGet(this, _SecuxPsbt_coin, "f"), { publickey }).scriptPublickey,
value: input.satoshis
};
break;
default:
throw Error(`ArgumentError: Invalid ScriptType of input#${__classPrivateFieldGet(this, _SecuxPsbt_data, "f").inputs.length}, got "${interface_1.ScriptType[script]}"`);
}
// check input
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`);
}
if (!out.script.equals(mix1.witnessUtxo.script)) {
logger === null || logger === void 0 ? void 0 : 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") ? 0xfffffffd : undefined }, mix1), mix2);
__classPrivateFieldGet(this, _SecuxPsbt_data, "f").addInput(data);
__classPrivateFieldGet(this, _SecuxPsbt_paths, "f").push(input.path);
return this;
}
AddInputs(inputs) {
for (const input of inputs) {
this.AddInput(input);
}
return this;
}
AddOutput(output) {
var _a;
let out, script, path;
let value = output.satoshis;
if ((out = (0, interface_1.isOutuptScriptExtended)(output))) {
const pk = (0, utils_2.getPublickey)(out.publickey);
path = out.path;
const scriptType = (_a = out.script) !== null && _a !== void 0 ? _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");
const p2pkh = __classPrivateFieldGet(this, _SecuxPsbt_payment, "f").p2pkh(__classPrivateFieldGet(this, _SecuxPsbt_coin, "f"), { publickey: pk });
script = p2pkh.scriptPublickey;
break;
case interface_1.ScriptType.P2WPKH:
if (!out.path.startsWith("m/84'/"))
throw Error("P2WPKH should use m/84' path");
const p2wpkh = __classPrivateFieldGet(this, _SecuxPsbt_payment, "f").p2wpkh(__classPrivateFieldGet(this, _SecuxPsbt_coin, "f"), { publickey: pk });
script = p2wpkh.scriptPublickey;
break;
case interface_1.ScriptType.P2TR:
if (!out.path.startsWith("m/86'/"))
throw Error("P2TR should use m/86' path");
const p2tr = __classPrivateFieldGet(this, _SecuxPsbt_payment, "f").p2tr(__classPrivateFieldGet(this, _SecuxPsbt_coin, "f"), { publickey: pk });
script = p2tr.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))) {
script = Buffer.from(out.scriptHex, "hex");
}
else
throw Error("Invalid parameter of output");
__classPrivateFieldGet(this, _SecuxPsbt_data, "f").addOutput({
script,
value,
path
});
return this;
}
AddOutputs(outputs) {
for (const output of outputs) {
this.AddOutput(output);
}
return this;
}
PrepareSign(feeRate) {
if (feeRate) {
const vSize = __classPrivateFieldGet(this, _SecuxPsbt_instances, "m", _SecuxPsbt_estimateVSize).call(this);
const estimateFee = Math.round(vSize * feeRate);
logger === null || logger === void 0 ? void 0 : 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);
const spend = __classPrivateFieldGet(this, _SecuxPsbt_tx, "f").outs[0].value;
const change = (__classPrivateFieldGet(this, _SecuxPsbt_data, "f").outputs.length === 1) ? 0 : __classPrivateFieldGet(this, _SecuxPsbt_tx, "f").outs[1].value;
const actualFee = total - spend - change;
if (actualFee < estimateFee)
logger === null || logger === void 0 ? void 0 : logger.warn(`Estimated fee is ${estimateFee}, but got ${actualFee}.`);
if (actualFee > estimateFee || actualFee < vSize) {
if (change !== 0) {
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;
logger === null || logger === void 0 ? void 0 : 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;
logger === null || logger === void 0 ? void 0 : logger.info(`Modify spend amount from ${spend} to ${value}.`);
}
}
}
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
], [])
]);
const txs = __classPrivateFieldGet(this, _SecuxPsbt_data, "f").inputs.map((_, i) => {
const data = __classPrivateFieldGet(this, _SecuxPsbt_instances, "m", _SecuxPsbt_getDataForSig).call(this, i);
logger === null || logger === void 0 ? void 0 : logger.debug(`tx data [${i}]: ${data.toString("hex")}`);
if (data.length + communication_1.MAX_HEAD_SIZE > communication_1.ONESIGN_THRESHOLD) {
throw Error("ArgumentError: utxo exceed maximum payload size");
}
return data;
});
logger === null || logger === void 0 ? void 0 : logger.debug(`confirm data: ${outConfirm.toString("hex")}`);
const commands = [];
let _txs = [], _paths = [];
let 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++) {
size += txs[i].length + communication_1.MAX_HEAD_SIZE;
_txs.push(txs[i]);
_paths.push(__classPrivateFieldGet(this, _SecuxPsbt_paths, "f")[i]);
if (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);
if (__classPrivateFieldGet(this, _SecuxPsbt_coin, "f") !== interface_1.CoinType.BITCOINCASH && type === interface_1.ScriptType.P2PKH) {
confirmBuf = Buffer.alloc(0);
}
else {
confirmBuf = outConfirm;
}
}
if (_txs.length > 0) {
commands.push(protocol_transaction_1.SecuxTransactionTool.signRawTransactionList(_paths, _txs, confirmBuf));
}
return {
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());
const publickey = publickeys[i];
if (!secp256k1.ecdsaVerify(signatures[i], hash, publickey))
throw Error(`Signature Error #${i}`);
let sighashType = (_a = __classPrivateFieldGet(this, _SecuxPsbt_data, "f").inputs[i].sighashType) !== null && _a !== void 0 ? _a : transaction_1.Transaction.SIGHASH_ALL;
if (__classPrivateFieldGet(this, _SecuxPsbt_coin, "f") === interface_1.CoinType.BITCOINCASH)
sighashType = sighashType | SIGHASH_FORKID;
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);
const tweaked = (0, utils_2.toTweakedPublickey)(publickeys[i]);
const signature = signatures[i].slice(0, 64);
if (!(0, bip340_1.taprootVerify)(signature, hash, tweaked))
throw Error(`Signature Error #${i}`);
const sighashType = (_b = __classPrivateFieldGet(this, _SecuxPsbt_data, "f").inputs[i].sighashType) !== null && _b !== void 0 ? _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");
__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}`);
// check sighash type
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 } = prepareFinalScripts(scriptType, input.partialSig);
if (finalScriptSig)
__classPrivateFieldGet(this, _SecuxPsbt_data, "f").updateInput(idx, { finalScriptSig });
if (finalScriptWitness)
__classPrivateFieldGet(this, _SecuxPsbt_data, "f").updateInput(idx, { finalScriptWitness });
if (!finalScriptSig && !finalScriptWitness)
throw new Error(`Unknown error finalizing input #${idx}`);
});
return 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));
const output = tx.outs.reduce((sum, txOut) => sum.plus(txOut.value), new bignumber_js_1.BigNumber(0));
const fee = input.minus(output);
const minFee = tx.virtualSize();
if (fee.lt(minFee))
throw Error(`Transaction fee must >= ${minFee}, but got ${fee}.`);
return tx;
}
}
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 _SecuxPsbt_fetchInputScript(index) {
if (__classPrivateFieldGet(this, _SecuxPsbt_inScripts, "f")[index])
return __classPrivateFieldGet(this, _SecuxPsbt_inScripts, "f")[index];
const txIn = __classPrivateFieldGet(this, _SecuxPsbt_data, "f").inputs[index];
const prevout = txIn.witnessUtxo;
const type = getScriptFromInput(txIn, __classPrivateFieldGet(this, _SecuxPsbt_coin, "f")).scriptType;
const scriptPubkey = getMeaningfulScript(prevout.script, type, txIn.redeemScript, txIn.witnessScript);
logger === null || logger === void 0 ? void 0 : logger.debug(`input #${index} script type: ${interface_1.ScriptType[type]}`);
logger === null || logger === void 0 ? void 0 : logger.debug(`script: ${scriptPubkey.toString("hex")}`);
const obj = { type, scriptPubkey };
__classPrivateFieldGet(this, _SecuxPsbt_inScripts, "f")[index] = obj;
return obj;
}, _SecuxPsbt_getDataForSig = function _SecuxPsbt_getDataForSig(inputIndex) {
var _a, _b;
const txIn = __classPrivateFieldGet(this, _SecuxPsbt_data, "f").inputs[inputIndex];
const unsignedTx = __classPrivateFieldGet(this, _SecuxPsbt_tx, "f");
let sighashType = (_a = txIn.sighashType) !== null && _a !== void 0 ? _a : transaction_1.Transaction.SIGHASH_ALL;
const serializer = (0, utils_2.getSerializer)(__classPrivateFieldGet(this, _SecuxPsbt_coin, "f"));
if (txIn.witnessUtxo === undefined)
Error('Need a Utxo input item for signing');
const prevout = txIn.witnessUtxo;
const { 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:
logger === null || logger === void 0 ? void 0 : logger.debug(interface_1.ScriptType[type]);
// P2WPKH uses the P2PKH template for prevoutScript when signing
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:
logger === null || logger === void 0 ? void 0 : logger.debug("p2tr");
sighashType = (_b = txIn.sighashType) !== null && _b !== void 0 ? _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:
if (__classPrivateFieldGet(this, _SecuxPsbt_coin, "f") === interface_1.CoinType.BITCOINCASH) {
logger === null || logger === void 0 ? void 0 : logger.debug("bch using bip143");
data = serializer.dataForWitnessV0(unsignedTx, inputIndex, scriptPubkey, prevout.value, sighashType | SIGHASH_FORKID);
}
else {
logger === null || logger === void 0 ? void 0 : logger.debug("non-segwit");
data = serializer.dataForSignature(unsignedTx, inputIndex, scriptPubkey, sighashType);
}
break;
}
return data;
}, _SecuxPsbt_extractInput = function _SecuxPsbt_extractInput(tx, index, _) {
if (!_.finalScriptSig && !_.finalScriptWitness)
throw Error(`input#${index} not finalized.`);
if (_.finalScriptSig)
tx.ins[index].script = _.finalScriptSig;
if (_.finalScriptWitness) {
if (__classPrivateFieldGet(this, _SecuxPsbt_instances, "m", _SecuxPsbt_fetchInputScript).call(this, index).type !== interface_1.ScriptType.P2TR) {
tx.ins[index].witness = (0, utils_2.scriptWitnessToWitnessStack)(_.finalScriptWitness);
}
else {
tx.ins[index].witness = [_.finalScriptWitness];
}
}
}, _SecuxPsbt_estimateVSize = function _SecuxPsbt_estimateVSize() {
const txForFee = __classPrivateFieldGet(this, _SecuxPsbt_tx, "f").clone();
let scriptSize = 0, witnessSize = 2;
__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);
});
return txForFee.virtualSize() + scriptSize + witnessSize / 4;
};
function getMeaningfulScript(script, scriptType, redeemScript, witnessScript) {
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;
// case ScriptType.P2SH_P2WSH, ScriptType.P2WSH:
// if (!witnessScript) throw Error("scriptPubkey or redeemScript is P2WSH but witnessScript missing");
// meaningfulScript = witnessScript;
// break;
default:
meaningfulScript = script;
}
if (!meaningfulScript)
throw Error("cannot extract script");
return meaningfulScript;
}
function getScriptFromInput(input, coin) {
let script;
let scriptType;
const payment = (0, utils_2.getPayment)(coin);
if (input.witnessScript) {
script = input.witnessScript;
// scriptType = payment.classify(script);
// switch (scriptType) {
// case ScriptType.P2PKH:
// scriptType = ScriptType.P2WSH_P2PKH;
// break;
// case ScriptType.P2WPKH:
// scriptType = ScriptType.P2WSH_P2WPKH;
// break;
// }
}
else if (input.redeemScript) {
script = input.redeemScript;
scriptType = payment.classify(script);
switch (scriptType) {
case interface_1.ScriptType.P2PKH:
scriptType = interface_1.ScriptType.P2SH_P2PKH;
break;
case interface_1.ScriptType.P2WPKH:
scriptType = interface_1.ScriptType.P2SH_P2WPKH;
break;
}
}
else {
script = input.witnessUtxo.script;
scriptType = payment.classify(script);
}
return {
script,
scriptType
};
}
function prepareFinalScripts(scriptType, partialSig) {
let finalScriptSig;
let 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]);
const chunks = Script.decompile(input);
const 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);
const hash = (0, payment_1.Hash160)(pubkey);
const 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;
break;
}
return {
finalScriptSig,
finalScriptWitness
};
}
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 (input.hash === undefined ||
input.index === undefined ||
(!Buffer.isBuffer(input.hash) && typeof input.hash !== 'string') ||
typeof input.index !== 'number') {
throw new Error('Error adding input.');
}
const hash = typeof input.hash === 'string'
? Buffer.from(Buffer.from(input.hash, 'hex').reverse())
: input.hash;
__classPrivateFieldGet(this, _PsbtTransaction_tx, "f").addInput(hash, input.index, input.sequence);
}
addOutput(output) {
if (output.script === undefined ||
output.value === undefined ||
!Buffer.isBuffer(output.script) ||
typeof output.value !== 'number') {
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();
"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;

@@ -1,205 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.encode = exports.decode = exports.decompile = exports.compile = void 0;
const bip66 = require("bip66");
const coindef_1 = require("./coindef");
const utility_1 = require("@secux/utility");
const ZERO = Buffer.alloc(1, 0);
const logger = utility_1.Logger === null || utility_1.Logger === void 0 ? void 0 : utility_1.Logger.child({ id: "script" });
function compile(chunks) {
const bufferSize = chunks.reduce((accum, chunk) => {
// data chunk
if (Buffer.isBuffer(chunk)) {
// adhere to BIP62.3, minimal push policy
if (chunk.length === 1 && asMinimalOP(chunk) !== undefined) {
return accum + 1;
}
return accum + pushdata.encodingLength(chunk.length) + chunk.length;
}
// opcode
return accum + 1;
}, 0);
const buffer = Buffer.allocUnsafe(bufferSize);
let offset = 0;
for (const chunk of chunks) {
// data chunk
if (Buffer.isBuffer(chunk)) {
// adhere to BIP62.3, minimal push policy
const opcode = asMinimalOP(chunk);
if (opcode !== undefined) {
buffer.writeUInt8(opcode, offset);
offset += 1;
return;
}
offset += pushdata.encode(buffer, chunk.length, offset);
chunk.copy(buffer, offset);
offset += chunk.length;
}
// opcode
else {
buffer.writeUInt8(chunk, offset);
offset += 1;
}
}
if (offset !== buffer.length)
throw new Error('Could not decode chunks');
return buffer;
}
exports.compile = compile;
function decompile(buffer) {
const chunks = [];
let i = 0;
while (i < buffer.length) {
const opcode = buffer[i];
// data chunk
if (opcode > coindef_1.OPCODES.OP_0 && opcode <= coindef_1.OPCODES.OP_PUSHDATA4) {
const d = pushdata.decode(buffer, i);
// did reading a pushDataInt fail?
if (d === null) {
logger === null || logger === void 0 ? void 0 : logger.warn(`decompile error: reading a pushDataInt fail, got ${buffer.toString("binary")}, index:${i}`);
return [];
}
i += d.size;
// attempt to read too much data?
if (i + d.number > buffer.length) {
logger === null || logger === void 0 ? void 0 : logger.warn(`decompile error: attempt to read too much data, got ${buffer.slice(i).toString("binary")}, desired length:${d.number}`);
return [];
}
const data = buffer.slice(i, i + d.number);
i += d.number;
// decompile minimally
const op = asMinimalOP(data);
if (op !== undefined) {
chunks.push(op);
}
else {
chunks.push(data);
}
}
// opcode
else {
chunks.push(opcode);
i += 1;
}
}
return chunks;
}
exports.decompile = decompile;
// BIP62: 1 byte hashType flag (only 0x01, 0x02, 0x03, 0x81, 0x82 and 0x83 are allowed)
function decode(buffer) {
const hashType = buffer.readUInt8(buffer.length - 1);
const hashTypeMod = hashType & ~0x80;
if (hashTypeMod <= 0 || hashTypeMod >= 4)
throw new Error('Invalid hashType ' + hashType);
const decoded = bip66.decode(buffer.slice(0, -1));
const r = fromDER(decoded.r);
const s = fromDER(decoded.s);
const signature = Buffer.concat([r, s], 64);
return { signature, hashType };
}
exports.decode = decode;
function encode(signature, hashType) {
const hashTypeBuffer = Buffer.allocUnsafe(1);
hashTypeBuffer.writeUInt8(hashType, 0);
const r = toDER(signature.slice(0, 32));
const s = toDER(signature.slice(32, 64));
return Buffer.concat([bip66.encode(r, s), hashTypeBuffer]);
}
exports.encode = encode;
function toDER(x) {
let i = 0;
while (x[i] === 0)
++i;
if (i === x.length)
return ZERO;
x = x.slice(i);
if (x[0] & 0x80)
return Buffer.concat([ZERO, x], 1 + x.length);
return x;
}
function fromDER(x) {
if (x[0] === 0x00)
x = x.slice(1);
const buffer = Buffer.alloc(32, 0);
const bstart = Math.max(0, 32 - x.length);
x.copy(buffer, bstart);
return buffer;
}
function asMinimalOP(buffer) {
if (buffer.length === 0)
return coindef_1.OPCODES.OP_0;
if (buffer.length !== 1)
return;
if (buffer[0] >= 1 && buffer[0] <= 16)
return coindef_1.OPCODES.OP_INT_BASE + buffer[0];
if (buffer[0] === 0x81)
return coindef_1.OPCODES.OP_1NEGATE;
}
class pushdata {
static encodingLength(i) {
return i < coindef_1.OPCODES.OP_PUSHDATA1 ? 1
: i <= 0xff ? 2
: i <= 0xffff ? 3
: 5;
}
static encode(buffer, number, offset) {
var size = this.encodingLength(number);
// ~6 bit
if (size === 1) {
buffer.writeUInt8(number, offset);
}
// 8 bit
else if (size === 2) {
buffer.writeUInt8(coindef_1.OPCODES.OP_PUSHDATA1, offset);
buffer.writeUInt8(number, offset + 1);
}
// 16 bit
else if (size === 3) {
buffer.writeUInt8(coindef_1.OPCODES.OP_PUSHDATA2, offset);
buffer.writeUInt16LE(number, offset + 1);
}
// 32 bit
else {
buffer.writeUInt8(coindef_1.OPCODES.OP_PUSHDATA4, offset);
buffer.writeUInt32LE(number, offset + 1);
}
return size;
}
static decode(buffer, offset) {
var opcode = buffer.readUInt8(offset);
var number, size;
// ~6 bit
if (opcode < coindef_1.OPCODES.OP_PUSHDATA1) {
number = opcode;
size = 1;
}
// 8 bit
else if (opcode === coindef_1.OPCODES.OP_PUSHDATA1) {
if (offset + 2 > buffer.length)
return null;
number = buffer.readUInt8(offset + 1);
size = 2;
}
// 16 bit
else if (opcode === coindef_1.OPCODES.OP_PUSHDATA2) {
if (offset + 3 > buffer.length)
return null;
number = buffer.readUInt16LE(offset + 1);
size = 3;
}
// 32 bit
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: opcode,
number: number,
size: size
};
}
}
"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}}}

@@ -1,80 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransactionGRS = void 0;
const hash_js_1 = require("hash.js");
const transaction_1 = require("./transaction");
const bufferutils_1 = require("./bufferutils");
const ZERO = Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex');
class TransactionGRS extends transaction_1.Transaction {
static dataForWitnessV0(trans, inIndex, prevOutScript, value, hashType) {
let tbuffer = Buffer.from([]);
let bufferWriter;
let hashOutputs = ZERO;
let hashPrevouts = ZERO;
let 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());
}
if (!(hashType & transaction_1.Transaction.SIGHASH_ANYONECANPAY) &&
(hashType & 0x1f) !== transaction_1.Transaction.SIGHASH_SINGLE &&
(hashType & 0x1f) !== 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());
}
if ((hashType & 0x1f) !== transaction_1.Transaction.SIGHASH_SINGLE &&
(hashType & 0x1f) !== transaction_1.Transaction.SIGHASH_NONE) {
const txOutsSize = trans.outs.reduce((sum, output) => {
return 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 ((hashType & 0x1f) === 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];
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);
return tbuffer;
}
static getHash(trans, forWitness) {
// wtxid for coinbase is always 32 bytes of 0x00
if (forWitness && trans.isCoinbase())
return Buffer.alloc(32, 0);
const data = trans.toBuffer(undefined, undefined, forWitness);
return Buffer.from((0, hash_js_1.sha256)().update(data).digest());
}
}
exports.TransactionGRS = TransactionGRS;
"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;

@@ -1,475 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.varSliceSize = exports.Transaction = void 0;
const hash_js_1 = require("hash.js");
const varuint = require("varuint-bitcoin");
const bufferutils_1 = require("./bufferutils");
const Script = require("./script");
const coindef_1 = require("./coindef");
const utility_1 = require("@secux/utility");
const logger = utility_1.Logger === null || utility_1.Logger === void 0 ? void 0 : utility_1.Logger.child({ id: "transaction" });
const ZERO = Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex');
const ONE = Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex');
const EMPTY = Buffer.alloc(0);
const VALUE_UINT64_MAX = Buffer.from('ffffffffffffffff', 'hex');
const 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);
const tx = new Transaction();
tx.version = bufferReader.readInt32();
const marker = bufferReader.readUInt8();
const flag = bufferReader.readUInt8();
let hasWitnesses = false;
if (marker === Transaction.ADVANCED_TRANSACTION_MARKER &&
flag === Transaction.ADVANCED_TRANSACTION_FLAG) {
hasWitnesses = true;
}
else {
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();
}
// was this pointless?
if (!tx.hasWitnesses())
throw new Error('Transaction has superfluous witness data');
}
tx.locktime = bufferReader.readUInt32();
if (bufferReader.offset !== buffer.length)
throw new Error('Transaction has unexpected data');
return tx;
}
static dataForSignature(trans, inIndex, prevOutScript, hashType) {
// https://github.com/bitcoin/bitcoin/blob/master/src/test/sighash_tests.cpp#L29
if (inIndex >= trans.ins.length)
return ONE;
// ignore OP_CODESEPARATOR
const ourScript = Script.compile(Script.decompile(prevOutScript).filter(x => {
return x !== coindef_1.OPCODES.OP_CODESEPARATOR;
}));
const txTmp = trans.clone();
// SIGHASH_NONE: ignore all outputs? (wildcard payee)
if ((hashType & 0x1f) === Transaction.SIGHASH_NONE) {
txTmp.outs = [];
// ignore sequence numbers (except at inIndex)
txTmp.ins.forEach((input, i) => {
if (i === inIndex)
return;
input.sequence = 0;
});
// SIGHASH_SINGLE: ignore all outputs, except at the same index?
}
else if ((hashType & 0x1f) === Transaction.SIGHASH_SINGLE) {
// https://github.com/bitcoin/bitcoin/blob/master/src/test/sighash_tests.cpp#L60
if (inIndex >= trans.outs.length)
return ONE;
// truncate outputs after
txTmp.outs.length = inIndex + 1;
// "blank" outputs before
for (let i = 0; i < inIndex; i++) {
txTmp.outs[i] = BLANK_OUTPUT;
}
// ignore sequence numbers (except at inIndex)
txTmp.ins.forEach((input, y) => {
if (y === inIndex)
return;
input.sequence = 0;
});
}
// SIGHASH_ANYONECANPAY: ignore inputs entirely?
if (hashType & Transaction.SIGHASH_ANYONECANPAY) {
txTmp.ins = [txTmp.ins[inIndex]];
txTmp.ins[0].script = ourScript;
// SIGHASH_ALL: only ignore input scripts
}
else {
// "blank" others input scripts
txTmp.ins.forEach(input => {
input.script = EMPTY;
});
txTmp.ins[inIndex].script = ourScript;
}
// serialize and hash
const buffer = Buffer.allocUnsafe(txTmp.byteLength(false) + 4);
buffer.writeInt32LE(hashType, buffer.length - 4);
txTmp.toBuffer(buffer, 0, false);
return buffer;
}
static dataForWitnessV0(trans, inIndex, prevOutScript, value, hashType) {
let tbuffer = Buffer.from([]);
let bufferWriter;
let hashOutputs = ZERO;
let hashPrevouts = ZERO;
let hashSequence = ZERO;
logger === null || logger === void 0 ? void 0 : logger.debug("begin dataForWitnessV0");
logger === null || logger === void 0 ? void 0 : logger.debug(`hashType: 0x${hashType.toString(16)}`);
if (!(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);
}
if (!(hashType & Transaction.SIGHASH_ANYONECANPAY) &&
(hashType & 0x1f) !== Transaction.SIGHASH_SINGLE &&
(hashType & 0x1f) !== 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);
}
if ((hashType & 0x1f) !== Transaction.SIGHASH_SINGLE &&
(hashType & 0x1f) !== Transaction.SIGHASH_NONE) {
const txOutsSize = trans.outs.reduce((sum, output) => {
return 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);
});
logger === null || logger === void 0 ? void 0 : logger.debug(`outputs: ${tbuffer.toString("hex")}`);
hashOutputs = hash256(tbuffer);
}
else if ((hashType & 0x1f) === 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);
logger === null || logger === void 0 ? void 0 : 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];
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);
logger === null || logger === void 0 ? void 0 : logger.debug("end dataForWitnessV0");
return tbuffer;
}
static dataForWitnessV1(trans, inIndex, prevOutScripts, values, hashType, leafHash, annex) {
// https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#common-signature-message
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;
const inputType = hashType & Transaction.SIGHASH_INPUT_MASK;
const isAnyoneCanPay = inputType === Transaction.SIGHASH_ANYONECANPAY;
const isNone = outputType === Transaction.SIGHASH_NONE;
const isSingle = outputType === Transaction.SIGHASH_SINGLE;
let hashPrevouts = EMPTY;
let hashAmounts = EMPTY;
let hashScriptPubKeys = EMPTY;
let hashSequences = EMPTY;
let hashOutputs = EMPTY;
logger === null || logger === void 0 ? void 0 : logger.debug("begin dataForWitnessV1");
logger === null || logger === void 0 ? void 0 : logger.debug(`hashType: 0x${hashType.toString(16)}`);
if (!isAnyoneCanPay) {
let buf = Buffer.alloc(36 * trans.ins.length);
let 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)) {
const txOutsSize = trans.outs
.map(output => 8 + varSliceSize(output.script))
.reduce((a, b) => a + b);
const buf = Buffer.alloc(txOutsSize);
const bufferWriter = new bufferutils_1.BufferWriter(buf);
trans.outs.forEach(out => {
bufferWriter.writeUInt64(out.value);
bufferWriter.writeVarSlice(out.script);
});
logger === null || logger === void 0 ? void 0 : logger.debug(`outputs: ${buf.toString("hex")}`);
hashOutputs = _sha256(buf);
}
else if (isSingle && inIndex < trans.outs.length) {
const output = trans.outs[inIndex];
const buf = Buffer.alloc(8 + varSliceSize(output.script));
const bufferWriter = new bufferutils_1.BufferWriter(buf);
bufferWriter.writeUInt64(output.value);
bufferWriter.writeVarSlice(output.script);
logger === null || logger === void 0 ? void 0 : logger.debug(`single output: ${buf.toString("hex")}`);
hashOutputs = _sha256(buf);
}
const spendType = (leafHash ? 2 : 0) + (annex ? 1 : 0);
// Length calculation from:
// https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#cite_note-14
// With extension from:
// https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki#signature-validation
const sigMsgSize = 174 -
(isAnyoneCanPay ? 49 : 0) -
(isNone ? 32 : 0) +
(annex ? 32 : 0) +
(leafHash ? 37 : 0);
const buf = Buffer.alloc(sigMsgSize);
const sigMsgWriter = new bufferutils_1.BufferWriter(buf);
sigMsgWriter.writeUInt8(hashType);
// Transaction
sigMsgWriter.writeInt32(trans.version);
sigMsgWriter.writeUInt32(trans.locktime);
sigMsgWriter.writeSlice(hashPrevouts);
sigMsgWriter.writeSlice(hashAmounts);
sigMsgWriter.writeSlice(hashScriptPubKeys);
sigMsgWriter.writeSlice(hashSequences);
if (!(isNone || isSingle)) {
sigMsgWriter.writeSlice(hashOutputs);
}
// Input
sigMsgWriter.writeUInt8(spendType);
if (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));
const bufferWriter = new bufferutils_1.BufferWriter(buf);
bufferWriter.writeVarSlice(annex);
sigMsgWriter.writeSlice(_sha256(buf));
}
// Output
if (isSingle) {
sigMsgWriter.writeSlice(hashOutputs);
}
// BIP342 extension
if (leafHash) {
sigMsgWriter.writeSlice(leafHash);
sigMsgWriter.writeUInt8(0);
sigMsgWriter.writeUInt32(0xffffffff);
}
logger === null || logger === void 0 ? void 0 : logger.debug("end dataForWitnessV1");
// Extra zero byte because:
// https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#cite_note-19
return Buffer.concat([Buffer.from([0x00]), buf]);
}
static getHash(trans, forWitness) {
// wtxid for coinbase is always 32 bytes of 0x00
if (forWitness && trans.isCoinbase())
return Buffer.alloc(32, 0);
return hash256(trans.toBuffer(undefined, undefined, forWitness));
}
static getId(trans) {
return this.getHash(trans).reverse().toString("hex");
}
addInput(hash, index, sequence, scriptSig) {
if (!sequence || sequence === 0)
sequence = Transaction.DEFAULT_SEQUENCE;
this.ins.push({
hash,
index,
script: scriptSig !== null && scriptSig !== void 0 ? scriptSig : EMPTY,
sequence: sequence,
witness: [],
});
}
addOutput(scriptPubKey, value, path) {
this.outs.push({
script: scriptPubKey,
value,
path
});
}
toBuffer(buffer, initialOffset, _ALLOW_WITNESS = false) {
if (!buffer)
buffer = Buffer.allocUnsafe(this.byteLength(_ALLOW_WITNESS));
const bufferWriter = new bufferutils_1.BufferWriter(buffer, initialOffset !== null && initialOffset !== void 0 ? initialOffset : 0);
bufferWriter.writeInt32(this.version);
const hasWitnesses = _ALLOW_WITNESS && this.hasWitnesses();
if (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 => {
if (txOut.value !== undefined) {
bufferWriter.writeUInt64(txOut.value);
}
else {
//@ts-ignore
bufferWriter.writeSlice(txOut.valueBuffer);
}
bufferWriter.writeVarSlice(txOut.script);
});
if (hasWitnesses) {
this.ins.forEach(input => {
bufferWriter.writeVector(input.witness);
});
}
bufferWriter.writeUInt32(this.locktime);
// avoid slicing unless necessary
if (initialOffset !== undefined)
return buffer.slice(initialOffset, bufferWriter.offset);
return buffer;
}
toHex() {
return this.toBuffer(undefined, undefined, true).toString('hex');
}
hasWitnesses() {
return this.ins.some(x => {
return x.witness.length !== 0;
});
}
isCoinbase() {
if (this.ins.length !== 1)
return false;
const hash = this.ins[0].hash;
for (let i = 0; i < 32; ++i) {
if (hash[i] !== 0)
return false;
}
return true;
}
clone() {
const newTx = new Transaction();
newTx.version = this.version;
newTx.locktime = this.locktime;
newTx.ins = this.ins.map(txIn => {
return {
hash: txIn.hash,
index: txIn.index,
script: txIn.script,
sequence: txIn.sequence,
witness: txIn.witness,
};
});
newTx.outs = this.outs.map(txOut => {
return {
script: txOut.script,
value: txOut.value,
};
});
return newTx;
}
weight() {
const base = this.byteLength(false);
const total = this.byteLength(true);
return base * 3 + total;
}
virtualSize() {
return Math.ceil(this.weight() / 4);
}
byteLength(_ALLOW_WITNESS = true) {
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) => {
return sum + 40 + varSliceSize(input.script);
}, 0) +
this.outs.reduce((sum, output) => {
return sum + 8 + varSliceSize(output.script);
}, 0) +
(hasWitnesses
? this.ins.reduce((sum, input) => {
return sum + vectorSize(input.witness);
}, 0)
: 0));
}
}
exports.Transaction = Transaction;
Transaction.DEFAULT_SEQUENCE = 0xffffffff;
Transaction.SIGHASH_DEFAULT = 0x00;
Transaction.SIGHASH_ALL = 0x01;
Transaction.SIGHASH_NONE = 0x02;
Transaction.SIGHASH_SINGLE = 0x03;
Transaction.SIGHASH_ANYONECANPAY = 0x80;
Transaction.SIGHASH_OUTPUT_MASK = 0x03;
Transaction.SIGHASH_INPUT_MASK = 0x80;
Transaction.ADVANCED_TRANSACTION_MARKER = 0x00;
Transaction.ADVANCED_TRANSACTION_FLAG = 0x01;
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();
const 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.varSliceSize = varSliceSize;
function vectorSize(someVector) {
const length = someVector.length;
return (varuint.encodingLength(length) +
someVector.reduce((sum, witness) => {
return sum + varSliceSize(witness);
}, 0));
}
"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;

@@ -1,183 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
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 secp256k1 = require('secp256k1/elliptic');
const varuint = require("varuint-bitcoin");
const interface_1 = require("./interface");
const payment_1 = require("./payment");
const payment_bch_1 = require("./payment_bch");
const payment_grs_1 = require("./payment_grs");
const transaction_1 = require("./transaction");
const transaction_grs_1 = require("./transaction_grs");
const ow_1 = require("ow");
const hash_js_1 = require("hash.js");
const bip340_1 = require("./bip340");
function getPayment(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.getPayment = getPayment;
function getCoinType(path) {
const bip32 = path.match(/\d+/g);
const 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}`);
}
exports.getCoinType = getCoinType;
function getPurpose(script) {
switch (script) {
case interface_1.ScriptType.P2PKH: return 44;
case interface_1.ScriptType.P2SH_P2PKH: return 49;
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.getPurpose = getPurpose;
function getDefaultScript(path) {
const bip32 = path.match(/\d+/g);
const purpose = parseInt(bip32[0], 10);
const 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.getDefaultScript = getDefaultScript;
function getSerializer(coin) {
switch (coin) {
case interface_1.CoinType.GROESTL:
return transaction_grs_1.TransactionGRS;
default:
return transaction_1.Transaction;
}
}
exports.getSerializer = getSerializer;
function getInScriptSize(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.getInScriptSize = getInScriptSize;
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 [];
}
exports.getWitnessSize = getWitnessSize;
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;
}
exports.getOutScriptSize = getOutScriptSize;
function sliceSize(size) {
return varuint.encodingLength(size) + size;
}
exports.sliceSize = sliceSize;
function vectorSize(sizes) {
return varuint.encodingLength(sizes.length) +
sizes.reduce((sum, size) => sum + sliceSize(size), 0);
}
exports.vectorSize = vectorSize;
function witnessStackToScriptWitness(witness) {
let buffer = Buffer.allocUnsafe(0);
const writeVarInt = (i) => {
const currentLen = buffer.length;
const 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.witnessStackToScriptWitness = witnessStackToScriptWitness;
function scriptWitnessToWitnessStack(buffer) {
let offset = 0;
const readVarInt = () => {
const vi = varuint.decode(buffer, offset);
offset += varuint.decode.bytes;
return vi;
};
const readVarSlice = () => {
const n = readVarInt();
offset += n;
return buffer.slice(offset - n, offset);
};
const count = readVarInt();
const vector = [];
for (let i = 0; i < count; i++) {
vector.push(readVarSlice());
}
return vector;
}
exports.scriptWitnessToWitnessStack = scriptWitnessToWitnessStack;
function getPublickey(data) {
(0, ow_1.default)(data, ow_1.default.any(interface_1.ow_hexString, ow_1.default.buffer));
const pk = (typeof data === "string") ? Buffer.from(data, "hex") : data;
(0, ow_1.default)(pk, ow_1.default.buffer.is(x => x.length === 33 || x.length === 65));
if (!secp256k1.publicKeyVerify(pk)) {
throw Error(`ArgumentError: invalid secp256k1 publickey, got "${pk.toString("hex")}"`);
}
return pk;
}
exports.getPublickey = getPublickey;
function toTweakedPublickey(data) {
const publickey = getPublickey(data);
const XOnlyPubkey = publickey.slice(1, 33);
const commitHash = taggedHash("TapTweak", XOnlyPubkey);
return (0, bip340_1.taprootConvert)(XOnlyPubkey, commitHash);
}
exports.toTweakedPublickey = toTweakedPublickey;
const TAGS = [
'BIP0340/challenge',
'BIP0340/aux',
'BIP0340/nonce',
'TapLeaf',
'TapBranch',
'TapSighash',
'TapTweak',
'KeyAgg list',
'KeyAgg coefficient',
];
/** An object mapping tags to their tagged hash prefix of [SHA256(tag) | SHA256(tag)] */
const TAGGED_HASH_PREFIXES = Object.fromEntries(TAGS.map(tag => {
const tagHash = _sha256(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;
function _sha256(tag) {
return Buffer.from((0, hash_js_1.sha256)().update(tag).digest());
}
"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;

4

package.json
{
"name": "@secux/app-btc",
"version": "3.2.4",
"version": "3.2.5",
"description": "SecuX Hardware Wallet BTC API",

@@ -39,3 +39,3 @@ "keywords": [

"@secux/protocol-transaction": "^3.0.0",
"@secux/utility": "^3.0.7",
"@secux/utility": "^3.0.8",
"bech32": "^2.0.0",

@@ -42,0 +42,0 @@ "bigi": "^1.4.2",

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc