New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@secux/app-btc

Package Overview
Dependencies
Maintainers
2
Versions
37
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 2.0.0-rc6 to 3.0.0

README.hbs

127

lib/app-btc.d.ts
/// <reference types="node" />
import { ITransport } from '@secux/transport';
import { CoinType, txInput, txOutput, ScriptType, txOutputAddress, txOutputScriptExtened, AddressOption } from './interface';
import { communicationData } from "@secux/utility/lib/communication";
import { CoinType, txInput, txOutput, ScriptType, txOutputAddress, txOutputScriptExtened, AddressOption, PathObject } from './interface';
import { ITransport } from "@secux/transport";
export { AddressOption, CoinType, ScriptType, txInput, txOutput, txOutputAddress, txOutputScriptExtened };

@@ -10,22 +11,116 @@ /**

/**
* Get address derived by given BIP32 path
* @param {ITransport} trans
* @param {string} path BIP32
* @param {AddressOption} [option]
* 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 getAddress(trans: ITransport, path: string, option?: AddressOption): Promise<string>;
static addressConvert(publickey: string | Buffer, path: string | PathObject): string;
/**
* Create transaction and Sign
* @param {ITransport} trans
* @param {Array<txInput>} inputs
* @param {txOutput} outputs
* @returns {object} signed
* @returns {string} signed.raw_tx
* @returns {Array<Buffer>} signed.signature
* @typedef AddressOption option for path validation
* @property {CoinType} [coin] enum
* @property {ScriptType} [script] enum
*/
static signTransaction(trans: ITransport, inputs: Array<txInput>, outputs: txOutput): Promise<{
/**
* 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 readonly prepareAddress: typeof SecuxBTC.preparePublickey;
/**
* 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: communicationData, path: string | PathObject): string;
/**
* 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: string, option?: AddressOption): communicationData;
/**
* Resolve secp256k1 publickey from response data.
* @param {communicationData} response data from device
* @returns {string} secp256k1 publickey (hex string)
*/
static resolvePublickey(response: communicationData): string;
/**
* 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: string): communicationData;
/**
* 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: communicationData, path: string): string;
/**
* @typedef txInput utxo object
* @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} satoshis referenced transaction output amount
* @property {ScriptType} [script] script type related to `path`
* @property {string} [txHex] referenced raw transaction for validation
*/
/**
* @typedef txOutput output object
* @property {txOutputAddress | txOutputScriptExtened} to receiving address information
* @property {txOutputScriptExtened} [utxo] changes
*/
/**
* @typedef txOutputAddress receiving address information
* @property {string} address receiving address
* @property {number} satoshis receiving amount
*/
/**
* @typedef txOutputScriptExtened own address information
* @property {string} path BIP32 path
* @property {string | Buffer} publickey scep256k1 publickey from `path`
* @property {number} satoshis amount
* @property {ScriptType} [script] script type related to `path`
*/
/**
* @typedef prepared
* @property {communicationData} commandData data for sending to device
* @property {string} rawTx unsigned raw transaction
*/
/**
* Prepare data for signing.
* @param {txInput} inputs array of utxo object
* @param {txOutput} outputs output object
* @returns {prepared}
*/
static prepareSign(inputs: Array<txInput>, outputs: txOutput): {
commandData: communicationData;
rawTx: string;
};
/**
* Reslove signature from response data.
* @param {communicationData} response data from device
* @returns {Array<string>} signature array of hex string
*/
static resolveSignatureList(response: communicationData): string[];
/**
* Serialize transaction wtih signature for broadcasting.
* @param {communicationData} response data from device
* @param {string} unsigned unsigned raw transaction
* @param {Array<communicationData>} publickeys secp256k1 publickey correspond to each input
* @param {CoinType} [coin] default: CoinType.BITCOIN
* @returns {string} signed raw transaction
*/
static resolveTransaction(response: communicationData, unsigned: string, publickeys: Array<string | Buffer>, coin?: CoinType): string;
static getAddress(this: ITransport, path: string): Promise<string>;
static getPublickey(this: ITransport, path: string): Promise<string>;
static getXPublickey(this: ITransport, path: string): Promise<string>;
static sign(this: ITransport, inputs: Array<txInput>, outputs: txOutput): Promise<{
raw_tx: string;
signature: Array<Buffer>;
}>;
}

2

lib/app-btc.js

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

"use strict";var t=this&&this.__awaiter||function(t,e,r,i){return new(r||(r=Promise))((function(o,n){function s(t){try{p(i.next(t))}catch(t){n(t)}}function c(t){try{p(i.throw(t))}catch(t){n(t)}}function p(t){var e;t.done?o(t.value):(e=t.value,e instanceof r?e:new r((function(t){t(e)}))).then(s,c)}p((i=i.apply(t,e||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.SecuxBTC=exports.ScriptType=exports.CoinType=void 0;const e=require("@secux/transport/lib/ITransaction"),r=require("@secux/utility"),i=require("ow"),o=require("./interface");Object.defineProperty(exports,"CoinType",{enumerable:!0,get:function(){return o.CoinType}}),Object.defineProperty(exports,"ScriptType",{enumerable:!0,get:function(){return o.ScriptType}});const n=require("./psbt"),s=require("./utils");exports.SecuxBTC=class{static getAddress(n,c,p){var u,a;return t(this,void 0,void 0,(function*(){(0,i.default)(c,r.ow_strictPath(o.btcCoinTypes,o.btcPurposes)),p&&(0,i.default)(p,o.ow_AddressOption);const t=null!==(u=null==p?void 0:p.coin)&&void 0!==u?u:(0,s.getCoinType)(c),d=o.coinmap[t].coinType,l=void 0===(null==p?void 0:p.script)?void 0:(0,s.getPurpose)(null==p?void 0:p.script);(0,i.default)(c,r.ow_strictPath(d,l));const y=yield n.getPublickey(c,e.EllipticCurve.SECP256K1,!0),P=(0,s.getPayment)(t);switch(null!==(a=null==p?void 0:p.script)&&void 0!==a?a:(0,s.getDefaultScript)(c)){case o.ScriptType.P2SH_P2WPKH:const e=P.p2wpkh(t,{publickey:y});return P.p2sh(t,e.redeemHash).address;case o.ScriptType.P2SH_P2PKH:const r=P.p2pkh(t,{publickey:y});return P.p2sh(t,r.redeemHash).address;case o.ScriptType.P2PKH:return P.p2pkh(t,{publickey:y}).address;case o.ScriptType.P2WPKH:return P.p2wpkh(t,{publickey:y}).address;default:throw Error("Invalid or unsupported ScriptType")}}))}static signTransaction(e,c,p){return t(this,void 0,void 0,(function*(){(0,i.default)(c,i.default.array.ofType(o.ow_txInput).minLength(1));const t=(0,s.getCoinType)(c[0].path);(0,i.default)(p,o.ow_txOutput),c.map((e=>{const n=e.script?(0,s.getPurpose)(e.script):o.btcPurposes;(0,i.default)(e.path,r.ow_strictPath(o.coinmap[t].coinType,n))}));let u=(0,o.isOutuptScriptExtended)(p.to);if(u){const e=u.script?(0,s.getPurpose)(u.script):o.btcPurposes;(0,i.default)(u.path,r.ow_strictPath(o.coinmap[t].coinType,e))}if(p.utxo){const e=p.utxo.script?(0,s.getPurpose)(p.utxo.script):o.btcPurposes;(0,i.default)(p.utxo.path,r.ow_strictPath(o.coinmap[t].coinType,e))}const a=new n.SecuxPsbt(e,t);yield a.AddInputs(c),yield a.AddOutputs(p.utxo?[p.to,p.utxo]:[p.to]);const d=yield a.Sign();return{raw_tx:a.finalizeAllInputs().extractTransaction().toHex(),signature:d}}))}};
"use strict";var e,t=this&&this.__decorate||function(e,t,r,i){var o,n=arguments.length,c=n<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,r):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)c=Reflect.decorate(e,t,r,i);else for(var u=e.length-1;u>=0;u--)(o=e[u])&&(c=(n<3?o(c):n>3?o(t,r,c):o(t,r))||c);return n>3&&c&&Object.defineProperty(t,r,c),c},r=this&&this.__awaiter||function(e,t,r,i){return new(r||(r=Promise))((function(o,n){function c(e){try{s(i.next(e))}catch(e){n(e)}}function u(e){try{s(i.throw(e))}catch(e){n(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(c,u)}s((i=i.apply(e,t||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.SecuxBTC=exports.ScriptType=exports.CoinType=void 0;const i=require("secp256k1/elliptic"),o=require("@secux/utility"),n=require("ow"),c=require("@secux/protocol-transaction"),u=require("@secux/utility/lib/communication"),s=require("@secux/protocol-transaction/lib/interface"),a=require("./interface");Object.defineProperty(exports,"CoinType",{enumerable:!0,get:function(){return a.CoinType}}),Object.defineProperty(exports,"ScriptType",{enumerable:!0,get:function(){return a.ScriptType}});const p=require("./psbt"),l=require("./utils"),d=require("@secux/transport");let f=e=class{static addressConvert(e,t){const r=(0,l.getPublickey)(e);(0,n.default)(t,n.default.any(a.ow_path,a.ow_PathObject));const o=i.publicKeyConvert(r,!0),c="string"==typeof t?(0,l.getCoinType)(t):t.coin,u="string"==typeof t?(0,l.getDefaultScript)(t):t.script,s=(0,l.getPayment)(c);switch(u){case a.ScriptType.P2SH_P2WPKH:const e=s.p2wpkh(c,{publickey:o});return s.p2sh(c,e.redeemHash).address;case a.ScriptType.P2SH_P2PKH:const t=s.p2pkh(c,{publickey:o});return s.p2sh(c,t.redeemHash).address;case a.ScriptType.P2PKH:return s.p2pkh(c,{publickey:o}).address;case a.ScriptType.P2WPKH:return s.p2wpkh(c,{publickey:o}).address;default:throw Error(`Invalid or unsupported ScriptType, got ${u} of ${c}`)}}static resolveAddress(t,r){const i=e.resolvePublickey(t);return e.addressConvert(i,r)}static preparePublickey(e,t){var r;(0,n.default)(e,a.ow_path),t&&(0,n.default)(t,a.ow_AddressOption);const i=null!==(r=null==t?void 0:t.coin)&&void 0!==r?r:(0,l.getCoinType)(e),u=a.coinmap[i].coinType,p=void 0===(null==t?void 0:t.script)?void 0:(0,l.getPurpose)(null==t?void 0:t.script);return(0,n.default)(e,o.ow_strictPath(u,p)),c.SecuxTransactionTool.getPublickey(e,s.EllipticCurve.SECP256K1)}static resolvePublickey(e){const t=c.SecuxTransactionTool.resolvePublickey(e,s.EllipticCurve.SECP256K1,!0);return Buffer.from(t,"base64").toString("hex")}static prepareXPublickey(e){return(0,n.default)(e,a.ow_path),c.SecuxTransactionTool.getXPublickey(e)}static resolveXPublickey(e,t){return(0,n.default)(t,a.ow_path),c.SecuxTransactionTool.resolveXPublickey(e,t)}static prepareSign(e,t){(0,n.default)(e,n.default.array.ofType(a.ow_txInput).minLength(1));const r=(0,l.getCoinType)(e[0].path);(0,n.default)(t,a.ow_txOutput),e.map((e=>{const t=e.script?(0,l.getPurpose)(e.script):a.btcPurposes;(0,n.default)(e.path,o.ow_strictPath(a.coinmap[r].coinType,t))}));let i=(0,a.isOutuptScriptExtended)(t.to);if(i){const e=i.script?(0,l.getPurpose)(i.script):a.btcPurposes;(0,n.default)(i.path,o.ow_strictPath(a.coinmap[r].coinType,e))}if(t.utxo){const e=t.utxo.script?(0,l.getPurpose)(t.utxo.script):a.btcPurposes;(0,n.default)(t.utxo.path,o.ow_strictPath(a.coinmap[r].coinType,e))}const c=new p.SecuxPsbt(r);return c.AddInputs(e),c.AddOutputs(t.utxo?[t.to,t.utxo]:[t.to]),c.PrepareSign()}static resolveSignatureList(e){return c.SecuxTransactionTool.resolveSignatureList(e).map((e=>Buffer.from(e,"base64"))).map((e=>o.Signature.fromSignature(e))).map((e=>Buffer.concat([e.r,e.s]).toString("hex")))}static resolveTransaction(t,r,i,c=a.CoinType.BITCOIN){(0,n.default)(t,u.ow_communicationData),(0,n.default)(r,o.ow_hexString),(0,n.default)(i,n.default.array.ofType(n.default.any(o.ow_hexString,n.default.buffer))),(0,n.default)(c,n.default.number.inRange(0,a.CoinType.__LENGTH-1));const s=e.resolveSignatureList(t).map((e=>Buffer.from(e,"hex"))),d=i.map((e=>(0,l.getPublickey)(e)));return p.SecuxPsbt.FromBuffer(Buffer.from(r,"hex"),c).appendSignature(s,d).finalizeAllInputs().extractTransaction().toHex()}static getAddress(t){return r(this,void 0,void 0,(function*(){const r=e.prepareAddress(t),i=yield this.Exchange((0,u.getBuffer)(r));return e.resolveAddress(i,t)}))}static getPublickey(t){return r(this,void 0,void 0,(function*(){const r=e.preparePublickey(t),i=yield this.Exchange((0,u.getBuffer)(r));return e.resolvePublickey(i)}))}static getXPublickey(t){return r(this,void 0,void 0,(function*(){const r=e.prepareXPublickey(t),i=yield this.Exchange((0,u.getBuffer)(r));return e.resolveXPublickey(i,t)}))}static sign(t,i){var o;return r(this,void 0,void 0,(function*(){const n={},c=t=>r(this,void 0,void 0,(function*(){if(void 0!==n[t])return n[t];const r=yield e.getPublickey.call(this,t),i=Buffer.from(r,"hex");return n[t]=i,i}));for(const e of t)void 0===e.publickey&&(e.publickey=yield c(e.path));i.to.path&&void 0===i.to.publickey&&(i.to.publickey=yield c(i.to.path)),(null===(o=i.utxo)||void 0===o?void 0:o.path)&&void 0===i.utxo.publickey&&(i.utxo.publickey=yield c(i.utxo.path));const{commandData:s,rawTx:a}=e.prepareSign(t,i),p=yield this.Exchange((0,u.getBuffer)(s));return{raw_tx:e.resolveTransaction(p,a,t.map((e=>e.publickey)),(0,l.getCoinType)(t[0].path))}}))}};f.prepareAddress=e.preparePublickey,f=e=t([(0,d.staticImplements)()],f),exports.SecuxBTC=f,(0,d.loadPlugin)(f,"SecuxBTC");

@@ -0,1 +1,2 @@

/// <reference types="node" />
import * as constants from "./coindef";

@@ -10,3 +11,26 @@ export { OPCODES } from "./coindef";

}
export declare enum CoinType {
BITCOIN = 0,
TESTNET = 1,
LITECOIN = 2,
BITCOINCASH = 3,
GROESTL = 4,
DIGIBYTE = 5,
DASH = 6,
DOGECOIN = 7,
__LENGTH = 8
}
export declare const coinmap: readonly Readonly<constants.Network>[];
export declare const btcCoinTypes: readonly number[];
export declare const btcPurposes: readonly number[];
export declare const ow_balance: import("ow").NumberPredicate;
export declare const ow_path: import("ow").StringPredicate;
export declare type PathObject = {
coin: CoinType;
script: ScriptType;
};
export declare const ow_PathObject: import("ow").ObjectPredicate<{
coin: number;
script: number;
}>;
export declare type txInput = {

@@ -19,2 +43,3 @@ hash: string;

path: string;
publickey?: string | Buffer;
};

@@ -28,2 +53,3 @@ export declare const ow_txInput: import("ow").ObjectPredicate<{

path: string;
publickey: string | Buffer | undefined;
}>;

@@ -47,10 +73,12 @@ export declare type txOutputAddress = {

export declare type txOutputScriptExtened = {
script?: ScriptType;
publickey?: string | Buffer;
path: string;
satoshis: number;
script?: ScriptType;
};
export declare const ow_txOutputScriptExtened: import("ow").ObjectPredicate<{
script: number | undefined;
publickey: string | Buffer | undefined;
path: string;
satoshis: number;
script: number | undefined;
}>;

@@ -66,10 +94,12 @@ export declare type txOutput = {

} | {
script: number | undefined;
publickey: string | Buffer | undefined;
path: string;
satoshis: number;
script: number | undefined;
};
utxo: {
script: number | undefined;
publickey: string | Buffer | undefined;
path: string;
satoshis: number;
script: number | undefined;
} | undefined;

@@ -81,16 +111,2 @@ }>;

export declare function isOutuptScriptExtended(output: txOutputExtended): txOutputScriptExtened | undefined;
export declare enum CoinType {
BITCOIN = 0,
TESTNET = 1,
LITECOIN = 2,
BITCOINCASH = 3,
GROESTL = 4,
DIGIBYTE = 5,
DASH = 6,
DOGECOIN = 7,
__LENGTH = 8
}
export declare const coinmap: readonly Readonly<constants.Network>[];
export declare const btcCoinTypes: readonly number[];
export declare const btcPurposes: readonly number[];
export declare type AddressOption = {

@@ -97,0 +113,0 @@ coin?: CoinType;

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

"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ow_AddressOption=exports.btcPurposes=exports.btcCoinTypes=exports.coinmap=exports.CoinType=exports.isOutuptScriptExtended=exports.isOutuptScript=exports.isOutputAddress=exports.ow_txOutput=exports.ow_txOutputScriptExtened=exports.ow_txOutputScript=exports.ow_txOutputAddress=exports.ow_txInput=exports.ow_balance=exports.ScriptType=exports.OPCODES=void 0;const e=require("ow"),t=require("./coindef"),r=require("@secux/utility");var o,p,s=require("./coindef");Object.defineProperty(exports,"OPCODES",{enumerable:!0,get:function(){return s.OPCODES}}),function(e){e[e.P2PKH=0]="P2PKH",e[e.P2WPKH=1]="P2WPKH",e[e.P2SH_P2PKH=2]="P2SH_P2PKH",e[e.P2SH_P2WPKH=3]="P2SH_P2WPKH",e[e.__LENGTH=4]="__LENGTH"}(o=exports.ScriptType||(exports.ScriptType={})),exports.ow_balance=e.default.number.integer.positive.lessThanOrEqual(9007199254740991),exports.ow_txInput=e.default.object.exactShape({hash:r.ow_hashString,vout:e.default.number.greaterThanOrEqual(0),txHex:e.default.any(e.default.undefined,r.ow_hexString),script:e.default.optional.number.inRange(0,o.__LENGTH-1),satoshis:exports.ow_balance,path:r.ow_bip32String}),exports.ow_txOutputAddress=e.default.object.exactShape({address:r.ow_hashString,satoshis:exports.ow_balance}),exports.ow_txOutputScript=e.default.object.exactShape({scriptHex:r.ow_hexString,satoshis:exports.ow_balance}),exports.ow_txOutputScriptExtened=e.default.object.exactShape({script:e.default.optional.number.inRange(0,o.__LENGTH-1),path:r.ow_bip32String,satoshis:exports.ow_balance}),exports.ow_txOutput=e.default.object.exactShape({to:e.default.any(exports.ow_txOutputAddress,exports.ow_txOutputScriptExtened),utxo:e.default.any(exports.ow_txOutputScriptExtened,e.default.undefined)}),exports.isOutputAddress=function(e){const t=e;if(t.address)return t},exports.isOutuptScript=function(e){const t=e;if(t.scriptHex)return t},exports.isOutuptScriptExtended=function(t){try{return(0,e.default)(t,exports.ow_txOutputScriptExtened),t}catch(e){}},function(e){e[e.BITCOIN=0]="BITCOIN",e[e.TESTNET=1]="TESTNET",e[e.LITECOIN=2]="LITECOIN",e[e.BITCOINCASH=3]="BITCOINCASH",e[e.GROESTL=4]="GROESTL",e[e.DIGIBYTE=5]="DIGIBYTE",e[e.DASH=6]="DASH",e[e.DOGECOIN=7]="DOGECOIN",e[e.__LENGTH=8]="__LENGTH"}(p=exports.CoinType||(exports.CoinType={})),exports.coinmap=Object.freeze([Object.freeze(t.bitcoin),Object.freeze(t.testnet),Object.freeze(t.litecoin),Object.freeze(t.bitcoincash),Object.freeze(t.groestl),Object.freeze(t.digibyte),Object.freeze(t.dash),Object.freeze(t.dogecoin)]),exports.btcCoinTypes=Object.freeze(exports.coinmap.map((e=>Object.freeze(e.coinType)))),exports.btcPurposes=Object.freeze([Object.freeze(44),Object.freeze(49),Object.freeze(84)]),exports.ow_AddressOption=e.default.object.exactShape({coin:e.default.optional.number.inRange(0,p.__LENGTH-1),script:e.default.optional.number.inRange(0,o.__LENGTH-1)});
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ow_AddressOption=exports.isOutuptScriptExtended=exports.isOutuptScript=exports.isOutputAddress=exports.ow_txOutput=exports.ow_txOutputScriptExtened=exports.ow_txOutputScript=exports.ow_txOutputAddress=exports.ow_txInput=exports.ow_PathObject=exports.ow_path=exports.ow_balance=exports.btcPurposes=exports.btcCoinTypes=exports.coinmap=exports.CoinType=exports.ScriptType=exports.OPCODES=void 0;const e=require("ow"),t=require("./coindef"),o=require("@secux/utility");var r,p,s=require("./coindef");Object.defineProperty(exports,"OPCODES",{enumerable:!0,get:function(){return s.OPCODES}}),function(e){e[e.P2PKH=0]="P2PKH",e[e.P2WPKH=1]="P2WPKH",e[e.P2SH_P2PKH=2]="P2SH_P2PKH",e[e.P2SH_P2WPKH=3]="P2SH_P2WPKH",e[e.__LENGTH=4]="__LENGTH"}(r=exports.ScriptType||(exports.ScriptType={})),function(e){e[e.BITCOIN=0]="BITCOIN",e[e.TESTNET=1]="TESTNET",e[e.LITECOIN=2]="LITECOIN",e[e.BITCOINCASH=3]="BITCOINCASH",e[e.GROESTL=4]="GROESTL",e[e.DIGIBYTE=5]="DIGIBYTE",e[e.DASH=6]="DASH",e[e.DOGECOIN=7]="DOGECOIN",e[e.__LENGTH=8]="__LENGTH"}(p=exports.CoinType||(exports.CoinType={})),exports.coinmap=Object.freeze([Object.freeze(t.bitcoin),Object.freeze(t.testnet),Object.freeze(t.litecoin),Object.freeze(t.bitcoincash),Object.freeze(t.groestl),Object.freeze(t.digibyte),Object.freeze(t.dash),Object.freeze(t.dogecoin)]),exports.btcCoinTypes=Object.freeze(exports.coinmap.map((e=>Object.freeze(e.coinType)))),exports.btcPurposes=Object.freeze([Object.freeze(44),Object.freeze(49),Object.freeze(84)]),exports.ow_balance=e.default.number.integer.positive.lessThanOrEqual(9007199254740991),exports.ow_path=o.ow_strictPath(exports.btcCoinTypes,exports.btcPurposes),exports.ow_PathObject=e.default.object.exactShape({coin:e.default.number.inRange(0,p.__LENGTH-1),script:e.default.number.inRange(0,r.__LENGTH-1)}),exports.ow_txInput=e.default.object.exactShape({hash:o.ow_hashString,vout:e.default.number.greaterThanOrEqual(0),txHex:e.default.any(e.default.undefined,o.ow_hexString),script:e.default.optional.number.inRange(0,r.__LENGTH-1),satoshis:exports.ow_balance,path:exports.ow_path,publickey:e.default.any(e.default.undefined,o.ow_hexString,e.default.buffer)}),exports.ow_txOutputAddress=e.default.object.exactShape({address:o.ow_hashString,satoshis:exports.ow_balance}),exports.ow_txOutputScript=e.default.object.exactShape({scriptHex:o.ow_hexString,satoshis:exports.ow_balance}),exports.ow_txOutputScriptExtened=e.default.object.exactShape({publickey:e.default.any(e.default.undefined,o.ow_hexString,e.default.buffer),path:exports.ow_path,satoshis:exports.ow_balance,script:e.default.optional.number.inRange(0,r.__LENGTH-1)}),exports.ow_txOutput=e.default.object.exactShape({to:e.default.any(exports.ow_txOutputAddress,exports.ow_txOutputScriptExtened),utxo:e.default.any(e.default.undefined,exports.ow_txOutputScriptExtened)}),exports.isOutputAddress=function(e){const t=e;if(t.address)return t},exports.isOutuptScript=function(e){const t=e;if(t.scriptHex)return t},exports.isOutuptScriptExtended=function(t){try{return(0,e.default)(t,exports.ow_txOutputScriptExtened),t}catch(e){}},exports.ow_AddressOption=e.default.object.exactShape({coin:e.default.optional.number.inRange(0,p.__LENGTH-1),script:e.default.optional.number.inRange(0,r.__LENGTH-1)});

@@ -9,26 +9,2 @@ /// <reference types="node" />

/**
* Pay to Public Key Hash for GROESTL
* @param {CoinType} coin
* @param {Buffer} param1 [publickey | hashed publickey]
* @returns
*/
static p2pkh(coin: CoinType, opt: {
publickey?: Buffer;
hash?: Buffer;
}): {
address: string;
scriptPublickey: Buffer;
redeemHash: Buffer;
};
/**
* Pay to Script Hash for GROESTL
* @param {CoinType} coin
* @param {Buffer} redeemHash
* @returns
*/
static p2sh(coin: CoinType, redeemHash: Buffer): {
address: string;
scriptPublickey: Buffer;
};
/**
* decode address to script

@@ -35,0 +11,0 @@ * @param {string} address

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

"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.CoinType=exports.PaymentGRS=void 0;const e=require("./payment");Object.defineProperty(exports,"CoinType",{enumerable:!0,get:function(){return e.CoinType}});const r=require("@secux/utility/lib/bs58"),t=require("groestl-hash-js"),o=require("./interface");class s extends e.PaymentBTC{static CoinSupported(r){if(r!==e.CoinType.GROESTL)throw Error("Not supported cointype")}static p2pkh(r,t){if(this.CoinSupported(r),!t.publickey&&!t.hash)throw Error("Invalid Parameters");if(t.publickey&&t.hash)throw Error("Invalid Parameters");const s=t.hash?t.hash:(0,e.Hash160)(t.publickey);null===e.logger||void 0===e.logger||e.logger.info(`publickey hash: ${s.toString("hex")}`);const i=o.coinmap[r],c=this.bs58check.encode(s,Buffer.from([i.pubKeyHash])),n=Buffer.from([o.OPCODES.OP_DUP,o.OPCODES.OP_HASH160,20]),u=Buffer.from([o.OPCODES.OP_EQUALVERIFY,o.OPCODES.OP_CHECKSIG]),p=Buffer.concat([n,s,u]),h=(0,e.Hash160)(p);return null===e.logger||void 0===e.logger||e.logger.info(`redeem hash: ${h.toString("hex")}`),{address:c,scriptPublickey:p,redeemHash:h}}static p2sh(e,r){this.CoinSupported(e);const t=o.coinmap[e],s=this.bs58check.encode(r,Buffer.from([t.scriptHash])),i=Buffer.from([o.OPCODES.OP_HASH160,20]),c=Buffer.from([o.OPCODES.OP_EQUAL]);return{address:s,scriptPublickey:Buffer.concat([i,r,c])}}static decode(e,r){const t=this.bs58check.decode(r),i=t[0],c=Buffer.from(t.slice(1)),n=o.coinmap[e];if(i===n.scriptHash)return s.p2sh(e,c).scriptPublickey;if(i===n.pubKeyHash)return s.p2pkh(e,{hash:c}).scriptPublickey;throw new Error("Invalid Output ScriptPubKey")}}exports.PaymentGRS=s,s.bs58check=new r.bs58Check((function(e){return Buffer.from(t.groestl_2(e,1,1))}));
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.CoinType=exports.PaymentGRS=void 0;const e=require("./payment");Object.defineProperty(exports,"CoinType",{enumerable:!0,get:function(){return e.CoinType}});const r=require("@secux/utility/lib/bs58"),t=require("groestl-hash-js"),i=require("./interface");class s extends e.PaymentBTC{static CoinSupported(r){if(r!==e.CoinType.GROESTL)throw Error("Not supported cointype")}static decode(e,r){const t=this.bs58check.decode(r),o=t[0],n=Buffer.from(t.slice(1)),c=i.coinmap[e];if(o===c.scriptHash)return s.p2sh(e,n).scriptPublickey;if(o===c.pubKeyHash)return s.p2pkh(e,{hash:n}).scriptPublickey;throw new Error("Invalid Output ScriptPubKey")}}exports.PaymentGRS=s,s.bs58check=new r.bs58Check((function(e){return Buffer.from(t.groestl_2(e,1,1))}));
/// <reference types="node" />
import { CoinType } from './interface';
import { CoinType, ScriptType } from './interface';
import { bs58Check } from "@secux/utility/lib/bs58";

@@ -63,3 +63,7 @@ export { PaymentBTC, CoinType, Hash160 };

static decode(coin: CoinType, address: string): Buffer;
static classify(script: Buffer): ScriptType;
static isP2PKH(script: Buffer): boolean;
static isP2SH(script: Buffer): boolean;
static isP2WPKH(script: Buffer): boolean;
}
declare function Hash160(publickey: Buffer): Buffer;

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

"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.logger=exports.Hash160=exports.CoinType=exports.PaymentBTC=void 0;const e=require("bech32"),r=require("ripemd160"),o=require("js-sha256"),t=require("./interface");Object.defineProperty(exports,"CoinType",{enumerable:!0,get:function(){return t.CoinType}});const s=require("@secux/utility/lib/bs58"),i=require("@secux/utility");exports.logger=null===i.Logger||void 0===i.Logger?void 0:i.Logger.child({id:"payment"});class c{static CoinSupported(e){if(e===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]),u=Buffer.from([t.OPCODES.OP_EQUALVERIFY,t.OPCODES.OP_CHECKSIG]),h=Buffer.concat([c,o,u]),p=n(h);return null===exports.logger||void 0===exports.logger||exports.logger.info(`redeem hash: ${p.toString("hex")}`),{address:i,scriptPublickey:h,redeemHash:p}}static p2sh(e,r){this.CoinSupported(e);let o=t.coinmap[e];const 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 u=e.bech32.encode(i.bech32,c),h=Buffer.from([t.OPCODES.OP_0,20]),p=Buffer.concat([h,s]),a=n(p);return null===exports.logger||void 0===exports.logger||exports.logger.info(`redeem hash: ${a.toString("hex")}`),{address:u,scriptPublickey:p,redeemHash:a}}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 u=Buffer.from([t.OPCODES.OP_HASH160,20]),h=Buffer.from([t.OPCODES.OP_EQUAL]);return{redeem:i,scriptPubicKey:Buffer.concat([u,c,h])}}static decode(r,o){let s;try{s=this.bs58check.decode(o)}catch(t){const i=e.bech32.decode(o);i.words.shift();return s=Buffer.from(e.bech32.fromWords(i.words)),null===exports.logger||void 0===exports.logger||exports.logger.debug(`bech32 address: ${o}\nbech32 decoded: ${s.toString("hex")}`),c.p2wpkh(r,{hash:s}).scriptPublickey}const i=s[0],n=s.slice(1),u=t.coinmap[r];if(i===u.scriptHash)return c.p2sh(r,n).scriptPublickey;if(i===u.pubKeyHash)return c.p2pkh(r,{hash:n}).scriptPublickey;throw Error("Invalid Output ScriptPubKey")}}function n(e){const t=Buffer.from(o.sha256.update(e).digest());return(new r).update(t).digest()}exports.PaymentBTC=c,c.bs58check=new s.bs58Check((function(e){const r=o.sha256.update(e).digest(),t=o.sha256.update(r).digest();return Buffer.from(t)})),exports.Hash160=n;
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.logger=exports.Hash160=exports.CoinType=exports.PaymentBTC=void 0;const e=require("bech32"),r=require("ripemd160"),t=require("js-sha256"),o=require("./interface");Object.defineProperty(exports,"CoinType",{enumerable:!0,get:function(){return o.CoinType}});const s=require("@secux/utility/lib/bs58"),i=require("@secux/utility");exports.logger=null===i.Logger||void 0===i.Logger?void 0:i.Logger.child({id:"payment"});class c{static CoinSupported(e){if(e===o.CoinType.BITCOINCASH)throw Error("Please use class PaymentBCH instead");if(e===o.CoinType.GROESTL)throw Error("Please use class PaymentGRS instead")}static p2pkh(e,r){if(this.CoinSupported(e),!r.publickey&&!r.hash)throw Error("Invalid Parameters");if(r.publickey&&r.hash)throw Error("Invalid Parameters");const t=r.hash?r.hash:n(r.publickey);null===exports.logger||void 0===exports.logger||exports.logger.info(`publickey hash: ${t.toString("hex")}`);const s=o.coinmap[e],i=this.bs58check.encode(t,Buffer.from([s.pubKeyHash])),c=Buffer.from([o.OPCODES.OP_DUP,o.OPCODES.OP_HASH160,20]),h=Buffer.from([o.OPCODES.OP_EQUALVERIFY,o.OPCODES.OP_CHECKSIG]),u=Buffer.concat([c,t,h]),a=n(u);return null===exports.logger||void 0===exports.logger||exports.logger.info(`redeem hash: ${a.toString("hex")}`),{address:i,scriptPublickey:u,redeemHash:a}}static p2sh(e,r){this.CoinSupported(e);const t=o.coinmap[e],s=this.bs58check.encode(r,Buffer.from([t.scriptHash])),i=Buffer.from([o.OPCODES.OP_HASH160,20]),c=Buffer.from([o.OPCODES.OP_EQUAL]);return{address:s,scriptPublickey:Buffer.concat([i,r,c])}}static p2wpkh(r,t){if(this.CoinSupported(r),!t.publickey&&!t.hash)throw Error("Invalid Parameters");if(t.publickey&&t.hash)throw Error("Invalid Parameters");const s=t.hash?t.hash:n(t.publickey);null===exports.logger||void 0===exports.logger||exports.logger.info(`publickey hash: ${s.toString("hex")}`);let i=o.coinmap[r];const c=e.bech32.toWords(s);c.unshift(0);const h=e.bech32.encode(i.bech32,c),u=Buffer.from([o.OPCODES.OP_0,20]),a=Buffer.concat([u,s]),p=n(a);return null===exports.logger||void 0===exports.logger||exports.logger.info(`redeem hash: ${p.toString("hex")}`),{address:h,scriptPublickey:a,redeemHash:p}}static p2ms(e,r){if(e<=0)throw Error('Invalid paramter "m"');e+=o.OPCODES.OP_INT_BASE;const t=r.length+o.OPCODES.OP_INT_BASE,s=Buffer.concat(r),i=Buffer.concat([Buffer.from([e]),s,Buffer.from([t]),Buffer.from([o.OPCODES.OP_CHECKMULTISIG])]),c=n(i);null===exports.logger||void 0===exports.logger||exports.logger.info(`redeem hash: ${c.toString("hex")}`);const h=Buffer.from([o.OPCODES.OP_HASH160,20]),u=Buffer.from([o.OPCODES.OP_EQUAL]);return{redeem:i,scriptPubicKey:Buffer.concat([h,c,u])}}static decode(r,t){let s;try{s=this.bs58check.decode(t)}catch(o){const i=e.bech32.decode(t);i.words.shift();return s=Buffer.from(e.bech32.fromWords(i.words)),null===exports.logger||void 0===exports.logger||exports.logger.debug(`bech32 address: ${t}\nbech32 decoded: ${s.toString("hex")}`),c.p2wpkh(r,{hash:s}).scriptPublickey}const i=s[0],n=s.slice(1),h=o.coinmap[r];if(i===h.scriptHash)return c.p2sh(r,n).scriptPublickey;if(i===h.pubKeyHash)return c.p2pkh(r,{hash:n}).scriptPublickey;throw Error("Invalid Output ScriptPubKey")}static classify(e){if(this.isP2WPKH(e))return o.ScriptType.P2WPKH;if(this.isP2PKH(e))return o.ScriptType.P2PKH;throw Error(`non-standard script: ${e.toString("hex")}`)}static isP2PKH(e){return 25===e.length&&e[0]===o.OPCODES.OP_DUP&&e[1]===o.OPCODES.OP_HASH160&&20===e[2]&&e[23]===o.OPCODES.OP_EQUALVERIFY&&e[24]===o.OPCODES.OP_CHECKSIG}static isP2SH(e){return 23===e.length&&e[0]===o.OPCODES.OP_HASH160&&20===e[1]&&e[22]===o.OPCODES.OP_EQUAL}static isP2WPKH(e){return 22===e.length&&e[0]===o.OPCODES.OP_0&&20===e[1]}}function n(e){const o=Buffer.from(t.sha256.update(e).digest());return(new r).update(o).digest()}exports.PaymentBTC=c,c.bs58check=new s.bs58Check((function(e){const r=t.sha256.update(e).digest(),o=t.sha256.update(r).digest();return Buffer.from(o)})),exports.Hash160=n;
/// <reference types="node" />
import { ITransport } from '@secux/transport';
import { Psbt } from "bip174";
import { CoinType, txInput, txOutputExtended } from './interface';
import { communicationData } from "@secux/utility/lib/communication";
export { SecuxPsbt };
declare class SecuxPsbt {
#private;
constructor(transport: ITransport, coin: CoinType);
AddInput(input: txInput): Promise<SecuxPsbt>;
AddInputs(inputs: Array<txInput>): Promise<SecuxPsbt>;
AddOutput(output: txOutputExtended): Promise<SecuxPsbt>;
AddOutputs(outputs: Array<txOutputExtended>): Promise<SecuxPsbt>;
Sign(): Promise<Array<Buffer>>;
constructor(coin: CoinType, data?: Psbt);
static FromBuffer(data: Buffer, coin: CoinType): SecuxPsbt;
AddInput(input: txInput): SecuxPsbt;
AddInputs(inputs: Array<txInput>): SecuxPsbt;
AddOutput(output: txOutputExtended): SecuxPsbt;
AddOutputs(outputs: Array<txOutputExtended>): SecuxPsbt;
PrepareSign(): {
commandData: communicationData;
rawTx: string;
};
appendSignature(signatures: Array<Buffer>, publickeys: Array<Buffer>): SecuxPsbt;
finalizeAllInputs(): SecuxPsbt;
extractTransaction(): any;
}

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

"use strict";var t,i,e,s,r,n,o,a,p,h,u,c,f,l=this&&this.__awaiter||function(t,i,e,s){return new(e||(e=Promise))((function(r,n){function o(t){try{p(s.next(t))}catch(t){n(t)}}function a(t){try{p(s.throw(t))}catch(t){n(t)}}function p(t){var i;t.done?r(t.value):(i=t.value,i instanceof e?i:new e((function(t){t(i)}))).then(o,a)}p((s=s.apply(t,i||[])).next())}))},d=this&&this.__classPrivateFieldSet||function(t,i,e,s,r){if("m"===s)throw new TypeError("Private method is not writable");if("a"===s&&!r)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof i?t!==i||!r:!i.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===s?r.call(t,e):r?r.value=e:i.set(t,e),e},S=this&&this.__classPrivateFieldGet||function(t,i,e,s){if("a"===e&&!s)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof i?t!==i||!s:!i.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===e?s:"a"===e?s.call(t):s?s.value:i.get(t)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.SecuxPsbt=void 0;const g=require("bip174"),w=require("bip174/src/lib/utils"),y=require("secp256k1/elliptic"),P=require("js-sha256"),v=require("./script"),m=require("@secux/utility"),b=require("./interface"),k=require("./utils"),T=require("./payment"),H=require("./transaction"),x=require("./coindef"),W=null===m.Logger||void 0===m.Logger?void 0:m.Logger.child({id:"psbt"});exports.SecuxPsbt=class{constructor(c,f){t.add(this),i.set(this,void 0),e.set(this,void 0),s.set(this,void 0),r.set(this,void 0),n.set(this,{}),o.set(this,[]),a.set(this,void 0),p.set(this,Buffer.alloc(0)),h.set(this,[]),u.set(this,{address:"",value:""}),d(this,i,c,"f"),d(this,e,new g.Psbt(new E),"f"),d(this,s,f,"f"),d(this,r,(0,k.getPayment)(S(this,s,"f")),"f"),d(this,a,{__TX:S(this,e,"f").globalMap.unsignedTx.tx},"f"),f===b.CoinType.BITCOINCASH&&(S(this,a,"f").__TX.version=1)}AddInput(i){var n;return l(this,void 0,void 0,(function*(){const a=yield S(this,t,"m",c).call(this,i.path),p={},u={},f=null!==(n=i.script)&&void 0!==n?n:(0,k.getDefaultScript)(i.path);switch(f){case b.ScriptType.P2PKH:p.witnessUtxo={script:S(this,r,"f").p2pkh(S(this,s,"f"),{publickey:a}).scriptPublickey,value:i.satoshis};break;case b.ScriptType.P2SH_P2PKH:const t=S(this,r,"f").p2pkh(S(this,s,"f"),{publickey:a});u.redeemScript=t.scriptPublickey,p.witnessUtxo={script:S(this,r,"f").p2sh(S(this,s,"f"),t.redeemHash).scriptPublickey,value:i.satoshis};break;case b.ScriptType.P2SH_P2WPKH:const n=S(this,r,"f").p2wpkh(S(this,s,"f"),{publickey:a});u.redeemScript=n.scriptPublickey,p.witnessUtxo={script:S(this,r,"f").p2sh(S(this,s,"f"),n.redeemHash).scriptPublickey,value:i.satoshis};break;case b.ScriptType.P2WPKH:p.witnessUtxo={script:S(this,r,"f").p2wpkh(S(this,s,"f"),{publickey:a}).scriptPublickey,value:i.satoshis};break;default:throw Error(`ArgumentError: Invalid ScriptType of input#${S(this,e,"f").inputs.length}, got "${b.ScriptType[f]}"`)}if(i.txHex){const t=H.Transaction.fromBuffer(Buffer.from(i.txHex,"hex"));if((0,k.getSerializer)(S(this,s,"f")).getId(t)!==i.hash)throw Error(`UTXO hash for input #${S(this,e,"f").inputs.length} doesn't match the hash specified in the prevout`);const r=t.outs[i.vout];if(r.value!==i.satoshis)throw Error(`UTXO value for input #${S(this,e,"f").inputs.length} doesn't match the value specified in the prevout`);r.script.equals(p.witnessUtxo.script)||null==W||W.warn(`Input script generation error: ${r.script.toString("hex")}, got "${p.witnessUtxo.script}"`)}const l=Object.assign(Object.assign({hash:i.hash,index:i.vout},p),u);return S(this,e,"f").addInput(l),S(this,h,"f").push(f),S(this,o,"f").push(i.path),this}))}AddInputs(t){return l(this,void 0,void 0,(function*(){for(const i of t)yield this.AddInput(i);return this}))}AddOutput(i){var n;return l(this,void 0,void 0,(function*(){const o=(0,m.BigIntToBuffer)(i.satoshis,8);let a,h,f,l,g=i.satoshis;if(a=(0,b.isOutuptScriptExtended)(i)){const i=yield S(this,t,"m",c).call(this,a.path);l=a.path;const o=null!==(n=a.script)&&void 0!==n?n:(0,k.getDefaultScript)(l);switch(o){case b.ScriptType.P2SH_P2WPKH:if(!a.path.startsWith("m/49'/"))throw Error("P2SH(...) should use m/49' path");let t=S(this,r,"f").p2wpkh(S(this,s,"f"),{publickey:i}).redeemHash,n=S(this,r,"f").p2sh(S(this,s,"f"),t);h=n.scriptPublickey,f=n.address;break;case b.ScriptType.P2SH_P2PKH:if(!a.path.startsWith("m/49'/"))throw Error("P2SH(...) should use m/49' path");t=S(this,r,"f").p2pkh(S(this,s,"f"),{publickey:i}).redeemHash,n=S(this,r,"f").p2sh(S(this,s,"f"),t),h=n.scriptPublickey,f=n.address;break;case b.ScriptType.P2PKH:if(!a.path.startsWith("m/44'/"))throw Error("P2PKH should use m/44' path");const p=S(this,r,"f").p2pkh(S(this,s,"f"),{publickey:i});h=p.scriptPublickey,f=p.address;break;case b.ScriptType.P2WPKH:if(!a.path.startsWith("m/84'/"))throw Error("P2WPKH should use m/84' path");const u=S(this,r,"f").p2wpkh(S(this,s,"f"),{publickey:i});h=u.scriptPublickey,f=u.address;break;default:throw Error(`ArgumentError: Invalid ScriptType of output#${S(this,e,"f").outputs.length}, got "${b.ScriptType[o]}"`)}}else if(a=(0,b.isOutputAddress)(i))h=S(this,r,"f").decode(S(this,s,"f"),a.address),f=a.address;else{if(!(a=(0,b.isOutuptScript)(i)))throw Error("Invalid parameter of output");h=Buffer.from(a.scriptHex,"hex")}return 0===S(this,e,"f").outputs.length?(d(this,p,Buffer.concat([S(this,p,"f"),o,Buffer.from([h.length]),h]),"f"),S(this,u,"f").address=f,S(this,u,"f").value=(1e-8*g).toString()):d(this,p,Buffer.concat([S(this,p,"f"),o,(0,m.buildPathBuffer)(l).pathBuffer]),"f"),S(this,e,"f").addOutput({script:h,value:g}),this}))}AddOutputs(t){return l(this,void 0,void 0,(function*(){for(const i of t)yield this.AddOutput(i);return this}))}Sign(){return l(this,void 0,void 0,(function*(){d(this,p,Buffer.concat([Buffer.from([S(this,e,"f").outputs.length]),S(this,p,"f")]),"f");const r=S(this,e,"f").inputs.map(((t,i)=>{const r=S(this,h,"f")[i],{data:n}=function(t,i,e,s,r){const n=r.__TX,o=e.sighashType||H.Transaction.SIGHASH_ALL,a=(0,k.getSerializer)(t);let p;if(!e.witnessUtxo)throw new Error("Need a Utxo input item for signing");p=e.witnessUtxo;const h=function(t,i,e,s){let r;switch(i){case b.ScriptType.P2SH_P2PKH:case b.ScriptType.P2SH_P2WPKH:if(!e)throw Error("scriptPubkey is P2SH but redeemScript missing");r=e;break;default:r=t}if(!r)throw Error("cannot extract script");return r}(p.script,s,e.redeemScript,e.witnessScript);let u;switch(null==W||W.debug(`input #${i} script type: ${b.ScriptType[s]}`),null==W||W.debug(`script: ${h.toString("hex")}`),s){case b.ScriptType.P2WPKH:case b.ScriptType.P2SH_P2WPKH:case b.ScriptType.P2SH_P2PKH:null==W||W.debug(b.ScriptType[s]);const e=(0,k.getPayment)(t).p2pkh(t,{hash:h.slice(2)}).scriptPublickey;u=a.dataForWitnessV0(n,i,e,p.value,o);break;default:t===b.CoinType.BITCOINCASH?(null==W||W.debug("bch using bip143"),u=a.dataForWitnessV0(n,i,h,p.value,64|o)):(null==W||W.debug("non-segwit"),u=a.dataForSignature(n,i,h,o))}return{script:h,sighashType:o,data:u}}(S(this,s,"f"),i,S(this,e,"f").inputs[i],r,S(this,a,"f"));return S(this,s,"f")!==b.CoinType.BITCOINCASH&&r===b.ScriptType.P2PKH?{data:n,confirm:Buffer.alloc(0)}:{data:n,confirm:S(this,p,"f")}}));for(let t=0;t<r.length;t++)null==W||W.debug(`tx data [${t}]: ${r[t].data.toString("hex")}`),null==W||W.debug(`confirm data [${t}]: ${r[t].confirm.toString("hex")}`);const n=r.map((t=>t.data)),u=yield S(this,i,"f").SignRawTransactionGroup(S(this,o,"f"),n,r[0].confirm);let f=[];for(let i=0;i<S(this,e,"f").inputs.length;i++){const n=u[i];n.trimZero();const a=Buffer.concat([n.r,n.s]),p=S(this,s,"f")===b.CoinType.GROESTL?Buffer.from(P.sha256.update(r[i].data).digest()):Buffer.from(P.sha256.update(P.sha256.update(r[i].data).digest()).digest()),h=yield S(this,t,"m",c).call(this,S(this,o,"f")[i]);if(!y.ecdsaVerify(a,p,h))throw Error(`Signature Error #${i}`);let l=S(this,e,"f").inputs[i].sighashType||H.Transaction.SIGHASH_ALL;S(this,s,"f")===b.CoinType.BITCOINCASH&&(l|=64);const d=[{pubkey:h,signature:v.encode(a,l)}];S(this,e,"f").updateInput(i,{partialSig:d}),f.push(d[0].signature)}return f}))}finalizeAllInputs(){if(S(this,e,"f").inputs.length<1)throw Error("utxo input cannot be empty");return S(this,e,"f").inputs.forEach(((t,i)=>{(0,w.checkForInput)(S(this,e,"f").inputs,i);const s=function(t){var i;let e;e=t.witnessScript?t.witnessScript:t.redeemScript?t.redeemScript:null===(i=t.witnessUtxo)||void 0===i?void 0:i.script;return e}(t);if(!s)throw new Error(`No script found for input #${i}`);if(t.sighashType&&t.partialSig){const{partialSig:i,sighashType:e}=t;for(const t of i){const{hashType:i}=v.decode(t.signature);if(i!==e)throw new Error("Signature sighash does not match input sighash type")}}const{finalScriptSig:r,finalScriptWitness:n}=function(t,i){let e,s;const{signature:r,pubkey:n}=i[0];switch(t){case b.ScriptType.P2PKH:e=v.compile([r,n]);break;case b.ScriptType.P2SH_P2PKH:e=(()=>{const t=v.compile([r,n]),i=v.decompile(t),e={output:i[i.length-1],input:v.compile(i.slice(0,-1))};return v.compile([].concat(v.decompile(e.input),e.output))})();break;case b.ScriptType.P2SH_P2WPKH:s=(0,k.witnessStackToScriptWitness)([r,n]),e=(()=>{const t=Buffer.alloc(0),i=(0,T.Hash160)(n),e=v.compile([x.OPCODES.OP_0,i]);return v.compile([].concat(v.decompile(t),e))})();break;case b.ScriptType.P2WPKH:s=(0,k.witnessStackToScriptWitness)([r,n])}return{finalScriptSig:e,finalScriptWitness:s}}(S(this,h,"f")[i],t.partialSig);if(r&&S(this,e,"f").updateInput(i,{finalScriptSig:r}),n&&S(this,e,"f").updateInput(i,{finalScriptWitness:n}),!r&&!n)throw new Error(`Unknown error finalizing input #${i}`)})),this}extractTransaction(){if(!S(this,e,"f").inputs.every((t=>!!t.finalScriptSig||!!t.finalScriptWitness)))throw new Error("Not finalized");const t=S(this,a,"f").__TX.clone();return S(this,e,"f").inputs.forEach(((i,e)=>{i.finalScriptSig&&(t.ins[e].script=i.finalScriptSig),i.finalScriptWitness&&(t.ins[e].witness=(0,k.scriptWitnessToWitnessStack)(i.finalScriptWitness))})),t}},i=new WeakMap,e=new WeakMap,s=new WeakMap,r=new WeakMap,n=new WeakMap,o=new WeakMap,a=new WeakMap,p=new WeakMap,h=new WeakMap,u=new WeakMap,t=new WeakSet,c=function(t){var e;return l(this,void 0,void 0,(function*(){let s=null===(e=S(this,n,"f")[t])||void 0===e?void 0:e.publicKey;if(!s){const e=yield S(this,i,"f").getXPublickey(t,!0);s=e.publicKey,S(this,n,"f")[t]=e}return s}))};class E{constructor(t=Buffer.from([2,0,0,0,0,0,0,0,0,0])){f.set(this,void 0),d(this,f,H.Transaction.fromBuffer(t),"f")}getInputOutputCounts(){return{inputCount:S(this,f,"f").ins.length,outputCount:S(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 i="string"==typeof t.hash?Buffer.from(Buffer.from(t.hash,"hex").reverse()):t.hash;S(this,f,"f").addInput(i,t.index,t.sequence)}addOutput(t){if(void 0===t.script||void 0===t.value||!Buffer.isBuffer(t.script)||"number"!=typeof t.value)throw new Error("Error adding output.");S(this,f,"f").addOutput(t.script,t.value)}toBuffer(){return S(this,f,"f").toBuffer()}get tx(){return S(this,f,"f")}}f=new WeakMap;
"use strict";var t,e,i,r,s,n,p,o=this&&this.__classPrivateFieldSet||function(t,e,i,r,s){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!s)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof e?t!==e||!s:!e.has(t))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?s.call(t,i):s?s.value=i:e.set(t,i),i},a=this&&this.__classPrivateFieldGet||function(t,e,i,r){if("a"===i&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof e?t!==e||!r:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===i?r:"a"===i?r.call(t):r?r.value:e.get(t)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.SecuxPsbt=void 0;const c=require("bip174"),u=require("bip174/src/lib/utils"),h=require("secp256k1/elliptic"),f=require("js-sha256"),l=require("./script"),d=require("@secux/utility"),S=require("./interface"),g=require("./utils"),y=require("./payment"),P=require("./transaction"),w=require("./coindef"),b=require("../../protocol-transaction/lib/protocol-transaction"),m=null===d.Logger||void 0===d.Logger?void 0:d.Logger.child({id:"psbt"});class T{constructor(p,u=new c.Psbt(new v)){t.set(this,void 0),e.set(this,void 0),i.set(this,void 0),r.set(this,[]),s.set(this,void 0),n.set(this,Buffer.alloc(0)),o(this,t,u,"f"),o(this,e,p,"f"),o(this,i,(0,g.getPayment)(a(this,e,"f")),"f"),o(this,s,a(this,t,"f").globalMap.unsignedTx.tx,"f"),p===S.CoinType.BITCOINCASH&&(a(this,s,"f").version=1)}static FromBuffer(t,e){const i=c.Psbt.fromBuffer(t,(t=>new v(t)));return new T(e,i)}AddInput(s){var n;if(!(0,d.isSupportedCoin)(s.path))throw Error(`ArgumentError: unsupport bip32 path, got "${s.path}"`);const p={},o={},c=(0,g.getPublickey)(s.publickey),u=null!==(n=s.script)&&void 0!==n?n:(0,g.getDefaultScript)(s.path);switch(u){case S.ScriptType.P2PKH:p.witnessUtxo={script:a(this,i,"f").p2pkh(a(this,e,"f"),{publickey:c}).scriptPublickey,value:s.satoshis};break;case S.ScriptType.P2SH_P2PKH:const r=a(this,i,"f").p2pkh(a(this,e,"f"),{publickey:c});o.redeemScript=r.scriptPublickey,p.witnessUtxo={script:a(this,i,"f").p2sh(a(this,e,"f"),r.redeemHash).scriptPublickey,value:s.satoshis};break;case S.ScriptType.P2SH_P2WPKH:const n=a(this,i,"f").p2wpkh(a(this,e,"f"),{publickey:c});o.redeemScript=n.scriptPublickey,p.witnessUtxo={script:a(this,i,"f").p2sh(a(this,e,"f"),n.redeemHash).scriptPublickey,value:s.satoshis};break;case S.ScriptType.P2WPKH:p.witnessUtxo={script:a(this,i,"f").p2wpkh(a(this,e,"f"),{publickey:c}).scriptPublickey,value:s.satoshis};break;default:throw Error(`ArgumentError: Invalid ScriptType of input#${a(this,t,"f").inputs.length}, got "${S.ScriptType[u]}"`)}if(s.txHex){const i=P.Transaction.fromBuffer(Buffer.from(s.txHex,"hex"));if((0,g.getSerializer)(a(this,e,"f")).getId(i)!==s.hash)throw Error(`UTXO hash for input #${a(this,t,"f").inputs.length} doesn't match the hash specified in the prevout`);const r=i.outs[s.vout];if(r.value!==s.satoshis)throw Error(`UTXO value for input #${a(this,t,"f").inputs.length} doesn't match the value specified in the prevout`);r.script.equals(p.witnessUtxo.script)||null==m||m.warn(`Input script generation error: ${r.script.toString("hex")}, got "${p.witnessUtxo.script}"`)}const h=Object.assign(Object.assign({hash:s.hash,index:s.vout},p),o);return a(this,t,"f").addInput(h),a(this,r,"f").push(s.path),this}AddInputs(t){for(const e of t)this.AddInput(e);return this}AddOutput(r){var s;const p=(0,d.BigIntToBuffer)(r.satoshis,8);let c,u,h,f,l=r.satoshis;if(c=(0,S.isOutuptScriptExtended)(r)){const r=(0,g.getPublickey)(c.publickey);f=c.path;const n=null!==(s=c.script)&&void 0!==s?s:(0,g.getDefaultScript)(f);switch(n){case S.ScriptType.P2SH_P2WPKH:if(!c.path.startsWith("m/49'/"))throw Error("P2SH(...) should use m/49' path");let s=a(this,i,"f").p2wpkh(a(this,e,"f"),{publickey:r}).redeemHash,p=a(this,i,"f").p2sh(a(this,e,"f"),s);u=p.scriptPublickey,h=p.address;break;case S.ScriptType.P2SH_P2PKH:if(!c.path.startsWith("m/49'/"))throw Error("P2SH(...) should use m/49' path");s=a(this,i,"f").p2pkh(a(this,e,"f"),{publickey:r}).redeemHash,p=a(this,i,"f").p2sh(a(this,e,"f"),s),u=p.scriptPublickey,h=p.address;break;case S.ScriptType.P2PKH:if(!c.path.startsWith("m/44'/"))throw Error("P2PKH should use m/44' path");const o=a(this,i,"f").p2pkh(a(this,e,"f"),{publickey:r});u=o.scriptPublickey,h=o.address;break;case S.ScriptType.P2WPKH:if(!c.path.startsWith("m/84'/"))throw Error("P2WPKH should use m/84' path");const f=a(this,i,"f").p2wpkh(a(this,e,"f"),{publickey:r});u=f.scriptPublickey,h=f.address;break;default:throw Error(`ArgumentError: Invalid ScriptType of output#${a(this,t,"f").outputs.length}, got "${S.ScriptType[n]}"`)}}else if(c=(0,S.isOutputAddress)(r))u=a(this,i,"f").decode(a(this,e,"f"),c.address),h=c.address;else{if(!(c=(0,S.isOutuptScript)(r)))throw Error("Invalid parameter of output");u=Buffer.from(c.scriptHex,"hex")}return 0===a(this,t,"f").outputs.length?o(this,n,Buffer.concat([a(this,n,"f"),p,Buffer.from([u.length]),u]),"f"):o(this,n,Buffer.concat([a(this,n,"f"),p,(0,d.buildPathBuffer)(f).pathBuffer]),"f"),a(this,t,"f").addOutput({script:u,value:l}),this}AddOutputs(t){for(const e of t)this.AddOutput(e);return this}PrepareSign(){o(this,n,Buffer.concat([Buffer.from([a(this,t,"f").outputs.length]),a(this,n,"f")]),"f");const i=a(this,t,"f").inputs.map(((i,r)=>{const{data:p}=k(a(this,e,"f"),r,a(this,t,"f").inputs[r],a(this,s,"f")),o=H(a(this,t,"f").inputs[r],a(this,e,"f")).scriptType;return a(this,e,"f")!==S.CoinType.BITCOINCASH&&o===S.ScriptType.P2PKH?{data:p,confirm:Buffer.alloc(0)}:{data:p,confirm:a(this,n,"f")}}));for(let t=0;t<i.length;t++)null==m||m.debug(`tx data [${t}]: ${i[t].data.toString("hex")}`),null==m||m.debug(`confirm data [${t}]: ${i[t].confirm.toString("hex")}`);const p=i.map((t=>t.data));return{commandData:b.SecuxTransactionTool.signRawTransactionList(a(this,r,"f"),p,i[0].confirm),rawTx:a(this,t,"f").toHex()}}appendSignature(i,r){var n;if(i.length!==r.length)throw Error(`ArgumentError: each signature is correspond to one publickey, got ${i.length} signatures and ${r.length} publickeys`);for(let p=0;p<a(this,t,"f").inputs.length;p++){const{data:o}=k(a(this,e,"f"),p,a(this,t,"f").inputs[p],a(this,s,"f")),c=a(this,e,"f")===S.CoinType.GROESTL?Buffer.from(f.sha256.update(o).digest()):Buffer.from(f.sha256.update(f.sha256.update(o).digest()).digest()),u=r[p];if(!h.ecdsaVerify(i[p],c,u))throw Error(`Signature Error #${p}`);let d=null!==(n=a(this,t,"f").inputs[p].sighashType)&&void 0!==n?n:P.Transaction.SIGHASH_ALL;a(this,e,"f")===S.CoinType.BITCOINCASH&&(d|=64);const g=[{pubkey:u,signature:l.encode(i[p],d)}];a(this,t,"f").updateInput(p,{partialSig:g})}return this}finalizeAllInputs(){if(a(this,t,"f").inputs.length<1)throw Error("utxo input cannot be empty");return a(this,t,"f").inputs.forEach(((i,r)=>{(0,u.checkForInput)(a(this,t,"f").inputs,r);const{script:s,scriptType:n}=H(i,a(this,e,"f"));if(!s)throw new Error(`No script found for input #${r}`);if(i.sighashType&&i.partialSig){const{partialSig:t,sighashType:e}=i;for(const i of t){const{hashType:t}=l.decode(i.signature);if(t!==e)throw new Error("Signature sighash does not match input sighash type")}}const{finalScriptSig:p,finalScriptWitness:o}=function(t,e){let i,r;const{signature:s,pubkey:n}=e[0];switch(t){case S.ScriptType.P2PKH:i=l.compile([s,n]);break;case S.ScriptType.P2SH_P2PKH:i=(()=>{const t=l.compile([s,n]),e=l.decompile(t),i={output:e[e.length-1],input:l.compile(e.slice(0,-1))};return l.compile([].concat(l.decompile(i.input),i.output))})();break;case S.ScriptType.P2SH_P2WPKH:r=(0,g.witnessStackToScriptWitness)([s,n]),i=(()=>{const t=Buffer.alloc(0),e=(0,y.Hash160)(n),i=l.compile([w.OPCODES.OP_0,e]);return l.compile([].concat(l.decompile(t),i))})();break;case S.ScriptType.P2WPKH:r=(0,g.witnessStackToScriptWitness)([s,n])}return{finalScriptSig:i,finalScriptWitness:r}}(n,i.partialSig);if(p&&a(this,t,"f").updateInput(r,{finalScriptSig:p}),o&&a(this,t,"f").updateInput(r,{finalScriptWitness:o}),!p&&!o)throw new Error(`Unknown error finalizing input #${r}`)})),this}extractTransaction(){if(!a(this,t,"f").inputs.every((t=>!!t.finalScriptSig||!!t.finalScriptWitness)))throw new Error("Not finalized");const e=a(this,s,"f").clone();return a(this,t,"f").inputs.forEach(((t,i)=>{t.finalScriptSig&&(e.ins[i].script=t.finalScriptSig),t.finalScriptWitness&&(e.ins[i].witness=(0,g.scriptWitnessToWitnessStack)(t.finalScriptWitness))})),e}}function k(t,e,i,r){const s=r,n=i.sighashType||P.Transaction.SIGHASH_ALL,p=(0,g.getSerializer)(t);let o;if(!i.witnessUtxo)throw new Error("Need a Utxo input item for signing");o=i.witnessUtxo;const a=H(i,t).scriptType,c=function(t,e,i,r){let s;switch(e){case S.ScriptType.P2SH_P2PKH:case S.ScriptType.P2SH_P2WPKH:if(!i)throw Error("scriptPubkey is P2SH but redeemScript missing");s=i;break;default:s=t}if(!s)throw Error("cannot extract script");return s}(o.script,a,i.redeemScript,i.witnessScript);let u;switch(null==m||m.debug(`input #${e} script type: ${S.ScriptType[a]}`),null==m||m.debug(`script: ${c.toString("hex")}`),a){case S.ScriptType.P2WPKH:case S.ScriptType.P2SH_P2WPKH:case S.ScriptType.P2SH_P2PKH:null==m||m.debug(S.ScriptType[a]);const i=(0,g.getPayment)(t).p2pkh(t,{hash:c.slice(2)}).scriptPublickey;u=p.dataForWitnessV0(s,e,i,o.value,n);break;default:t===S.CoinType.BITCOINCASH?(null==m||m.debug("bch using bip143"),u=p.dataForWitnessV0(s,e,c,o.value,64|n)):(null==m||m.debug("non-segwit"),u=p.dataForSignature(s,e,c,n))}return{script:c,sighashType:n,data:u}}function H(t,e){let i,r;const s=(0,g.getPayment)(e);if(t.witnessScript)i=t.witnessScript;else if(t.redeemScript)switch(i=t.redeemScript,r=s.classify(i),r){case S.ScriptType.P2PKH:r=S.ScriptType.P2SH_P2PKH;break;case S.ScriptType.P2WPKH:r=S.ScriptType.P2SH_P2WPKH}else i=t.witnessUtxo.script,r=s.classify(i);return{script:i,scriptType:r}}exports.SecuxPsbt=T,t=new WeakMap,e=new WeakMap,i=new WeakMap,r=new WeakMap,s=new WeakMap,n=new WeakMap;class v{constructor(t=Buffer.from([2,0,0,0,0,0,0,0,0,0])){p.set(this,void 0),o(this,p,P.Transaction.fromBuffer(t),"f")}getInputOutputCounts(){return{inputCount:a(this,p,"f").ins.length,outputCount:a(this,p,"f").outs.length}}addInput(t){if(void 0===t.hash||void 0===t.index||!Buffer.isBuffer(t.hash)&&"string"!=typeof t.hash||"number"!=typeof t.index)throw new Error("Error adding input.");const e="string"==typeof t.hash?Buffer.from(Buffer.from(t.hash,"hex").reverse()):t.hash;a(this,p,"f").addInput(e,t.index,t.sequence)}addOutput(t){if(void 0===t.script||void 0===t.value||!Buffer.isBuffer(t.script)||"number"!=typeof t.value)throw new Error("Error adding output.");a(this,p,"f").addOutput(t.script,t.value)}toBuffer(){return a(this,p,"f").toBuffer()}get tx(){return a(this,p,"f")}}p=new WeakMap;

@@ -12,1 +12,2 @@ /// <reference types="node" />

export declare function scriptWitnessToWitnessStack(buffer: Buffer): Buffer[];
export declare function getPublickey(data: string | Buffer): Buffer;

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

"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.scriptWitnessToWitnessStack=exports.witnessStackToScriptWitness=exports.getSerializer=exports.getDefaultScript=exports.getPurpose=exports.getCoinType=exports.getPayment=void 0;const e=require("varuint-bitcoin"),t=require("./interface"),r=require("./payment"),n=require("./payment_bch"),o=require("./payment_grs"),s=require("./transaction"),i=require("./transaction_grs"),c=require("ow"),p=require("@secux/utility");exports.getPayment=function(e){switch(e){case t.CoinType.BITCOINCASH:return n.PaymentBCH;case t.CoinType.GROESTL:return o.PaymentGRS;default:return r.PaymentBTC}},exports.getCoinType=function(e){(0,c.default)(e,p.ow_bip32String);const r=e.match(/\d+/g),n=parseInt(r[1],10);for(let e=0;e<t.coinmap.length;e++)if(n===t.coinmap[e].coinType)return e;throw Error(`ArgumentError: unsupport cointype of BIP32 path, got ${e}`)},exports.getPurpose=function(e){switch(e){case t.ScriptType.P2PKH:return 44;case t.ScriptType.P2SH_P2PKH:case t.ScriptType.P2SH_P2WPKH:return 49;case t.ScriptType.P2WPKH:return 84}throw Error(`ArgumentError: unsupport ScriptType, got ${e}`)},exports.getDefaultScript=function(e){(0,c.default)(e,p.ow_bip32String);const r=e.match(/\d+/g),n=parseInt(r[0],10);switch(n){case 44:return t.ScriptType.P2PKH;case 49:return t.ScriptType.P2SH_P2WPKH;case 84:return t.ScriptType.P2WPKH}throw Error(`ArgumentError: unsupport purpose of path, got "${n}" from ${e}`)},exports.getSerializer=function(e){return e===t.CoinType.GROESTL?i.TransactionGRS:s.Transaction},exports.witnessStackToScriptWitness=function(t){let r=Buffer.allocUnsafe(0);const n=t=>{const n=r.length,o=e.encodingLength(t);r=Buffer.concat([r,Buffer.allocUnsafe(o)]),e.encode(t,r,n)};n(t.length);for(const e of t)n(e.length),r=Buffer.concat([r,Buffer.from(e)]);return r},exports.scriptWitnessToWitnessStack=function(t){let r=0;const n=()=>{const n=e.decode(t,r);return r+=e.decode.bytes,n},o=()=>{const e=n();return r+=e,t.slice(r-e,r)},s=n(),i=[];for(let e=0;e<s;e++)i.push(o());return i};
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.getPublickey=exports.scriptWitnessToWitnessStack=exports.witnessStackToScriptWitness=exports.getSerializer=exports.getDefaultScript=exports.getPurpose=exports.getCoinType=exports.getPayment=void 0;const e=require("secp256k1/elliptic"),t=require("varuint-bitcoin"),r=require("./interface"),n=require("./payment"),o=require("./payment_bch"),i=require("./payment_grs"),s=require("./transaction"),c=require("./transaction_grs"),p=require("ow"),u=require("@secux/utility");function a(e){(0,p.default)(e,u.ow_bip32String);const t=e.match(/\d+/g),n=parseInt(t[1],10);for(let e=0;e<r.coinmap.length;e++)if(n===r.coinmap[e].coinType)return e;throw Error(`ArgumentError: unsupport cointype of BIP32 path, got ${e}`)}exports.getPayment=function(e){switch(e){case r.CoinType.BITCOINCASH:return o.PaymentBCH;case r.CoinType.GROESTL:return i.PaymentGRS;default:return n.PaymentBTC}},exports.getCoinType=a,exports.getPurpose=function(e){switch(e){case r.ScriptType.P2PKH:return 44;case r.ScriptType.P2SH_P2PKH:case r.ScriptType.P2SH_P2WPKH:return 49;case r.ScriptType.P2WPKH:return 84}throw Error(`ArgumentError: unsupport ScriptType, got ${e}`)},exports.getDefaultScript=function(e){(0,p.default)(e,u.ow_bip32String);const t=e.match(/\d+/g),n=parseInt(t[0],10),o=a(e);switch(n){case 44:return r.ScriptType.P2PKH;case 49:return o!==r.CoinType.BITCOINCASH?r.ScriptType.P2SH_P2WPKH:r.ScriptType.P2SH_P2PKH;case 84:return r.ScriptType.P2WPKH}throw Error(`ArgumentError: unsupport purpose of path, got "${n}" from ${e}`)},exports.getSerializer=function(e){return e===r.CoinType.GROESTL?c.TransactionGRS:s.Transaction},exports.witnessStackToScriptWitness=function(e){let r=Buffer.allocUnsafe(0);const n=e=>{const n=r.length,o=t.encodingLength(e);r=Buffer.concat([r,Buffer.allocUnsafe(o)]),t.encode(e,r,n)};n(e.length);for(const t of e)n(t.length),r=Buffer.concat([r,Buffer.from(t)]);return r},exports.scriptWitnessToWitnessStack=function(e){let r=0;const n=()=>{const n=t.decode(e,r);return r+=t.decode.bytes,n},o=()=>{const t=n();return r+=t,e.slice(r-t,r)},i=n(),s=[];for(let e=0;e<i;e++)s.push(o());return s},exports.getPublickey=function(t){(0,p.default)(t,p.default.any(u.ow_hexString,p.default.buffer));const r="string"==typeof t?Buffer.from(t,"hex"):t;if((0,p.default)(r,p.default.buffer.is((e=>33===e.length||65===e.length))),!e.publicKeyVerify(r))throw Error(`ArgumentError: invalid secp256k1 publickey, got "${r.toString("hex")}"`);return r};
{
"name": "@secux/app-btc",
"version": "2.0.0-rc6",
"version": "3.0.0",
"description": "SecuX Hardware Wallet BTC API",

@@ -28,2 +28,3 @@ "keywords": [

"build": "sh ../../build.sh",
"docs": "npx tsc && jsdoc2md --template ./README.hbs ./lib/app-btc.js > README.md",
"test:webusb": "webpack serve --progress --config ../../webpack.config.js --output-path ./__tests__ --entry ./__tests__/usb.js",

@@ -36,4 +37,5 @@ "test:webble": "webpack serve --progress --config ../../webpack.config.js --output-path ./__tests__ --entry ./__tests__/ble.js",

"dependencies": {
"@secux/transport": "^2.1.3",
"@secux/utility": "^2.0.6",
"@secux/protocol-transaction": "^3.0.0",
"@secux/transport": "^3.0.1",
"@secux/utility": "^3.0.0",
"bech32": "^2.0.0",

@@ -40,0 +42,0 @@ "bip174": "^2.0.1",

@@ -0,1 +1,5 @@

[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)
[![view on npm](https://badgen.net/npm/v/@secux/app-btc)](https://www.npmjs.com/package/@secux/app-btc)
[![npm module downloads](https://badgen.net/npm/dt/@secux/app-btc)](https://www.npmjs.org/package/@secux/app-btc)
# `@secux/app-btc`

@@ -8,6 +12,6 @@

```ts
import { CoinType, SecuxBTC, ScriptType } from "@secux/app-btc";
import { SecuxBTC } from "@secux/app-btc";
```
First, create instance of ITransport
First, create instance of ITransport.
- [Web Usb](https://www.npmjs.com/package/@secux/transport-webusb)

@@ -20,53 +24,43 @@ - [Web Bluetooth](https://www.npmjs.com/package/@secux/transport-webble)

## Examples
1. Get address by purpose and script type
```ts
// native segwit address (default script: P2WPKH)
const address = SecuxBTC.getAddress(
device,
"m/84'/0'/0'/0/0",
// optional object
{
// define cointype for checking path
coin: CoinType.BITCOIN,
1. Get address by purpose and script type.
- native segwit address (default script: P2WPKH)
```ts
const path = "m/84'/0'/0'/0/0";
const address = await device.getAddress(path);
// define specific script
script: ScriptType.P2WPKH
}
);
/*
// segwit address (default script: P2SH_P2WPKH)
const address = SecuxBTC.getAddress(
device,
"m/49'/0'/0'/0/0"
);
// transfer data to hardware wallet by custom transport layer.
const data = SecuxBTC.prepareAddress(path);
const response = await device.Exchange(data);
const address = SecuxBTC.resolveAddress(response, path);
// legacy address (default script: P2PKH)
const address = SecuxBTC.getAddress(
device,
"m/44'/0'/0'/0/0"
);
```
*/
```
- segwit address (default script: P2SH_P2WPKH)
```ts
cnost address = await device.getAddress("m/49'/0'/0'/0/0");
```
- legacy address (default script: P2PKH)
```ts
const address = await device.getAddress("m/44'/0'/0'/0/0");
```
2. For bitcoin ecosystem, you can use specific cointype by the coin
```ts
// native segwit address for dogecoin
const address = SecuxBTC.getAddress(
device,
"m/84'/3'/0'/0/0"
);
// segwit address for litecoin
const address = SecuxBTC.getAddress(
device,
"m/49'/2'/0'/0/0",
);
2. For bitcoin ecosystem, you can use specific cointype by the coin.
- native segwit address for `dogecoin`
```ts
const address = await device.getAddress("m/84'/3'/0'/0/0");
```
- segwit address for `litecoin`
```ts
const address = await device.getAddress("m/49'/2'/0'/0/0");
```
- legacy address for `bitcoincash`
```ts
const address = await device.getAddress("m/44'/145'/0'/0/0");
```
- you can refer to [here](https://github.com/satoshilabs/slips/blob/master/slip-0044.md) for cointype.
// legacy address for bitcoincash
const address = SecuxBTC.getAddress(
device,
"m/44'/145'/0'/0/0"
);
```
3. sign transaction
3. Sign transaction.
```ts

@@ -80,3 +74,5 @@ const inputs = [

satoshis: 700,
path: "m/44'/0'/0'/0/0"
path: "m/44'/0'/0'/0/0",
// for custom transport layer, each utxo need publickey.
// publickey: "03aaeb52dd7494c361049de67cc680e83ebcbbbdbeb13637d92cd845f70308af5e"
},

@@ -87,5 +83,7 @@ {

// optional, you can use specific script for each input
script: ScriptType.P2SH_P2WPKH,
// script: ScriptType.P2SH_P2PKH,
satoshis: 6000,
path: "m/49'/0'/0'/0/0"
path: "m/49'/0'/0'/0/0",
// for custom transport layer, each utxo need publickey.
// publickey: "039b3b694b8fc5b5e07fb069c783cac754f5d38c3e08bed1960e31fdb1dda35c24"
},

@@ -96,36 +94,33 @@ {

satoshis: 1083,
path: "m/84'/0'/0'/1/0"
path: "m/84'/0'/0'/1/0",
// for custom transport layer, each utxo need publickey.
// publickey: "03025324888e429ab8e3dbaf1f7802648b9cd01e9b418485c5fa4c1b9b5700e1a6"
}
];
const out = {
const to = {
address: "bc1qs0k3ekx0z7a7yuq3lse7prw373s8cr8lhxvccd",
satoshis: 1500
};
// or send to another account
// const out = {
// path: "m/84'/0'/1'/0/3",
// satoshis: 1500
// };
const utxo = {
path: "m/44'/0'/0'/0/0",
satoshis: 6100
satoshis: 6100,
// for custom transport layer, each utxo need publickey.
// publickey: "03aaeb52dd7494c361049de67cc680e83ebcbbbdbeb13637d92cd845f70308af5e"
};
const { raw_tx } = await device.sign(inputs, { to, utxo });
const { raw_tx, signature } = await SecuxBTC.signTransaction(
device,
inputs,
{
to: out,
utxo: utxo
}
);
/*
// transfer data to hardware wallet by custom transport layer.
const { commandData, rawTx } = SecuxBTC.prepareSign(inputs, { to, utxo });
const rsp = await device.Exchange(commandData);
const signed = SecuxBTC.resloveTransaction(rsp, rawTx, inputs.map(x => x.publickey));
*/
```
## API doc
<a name="SecuxBTC"></a>
### `SecuxBTC`
# API Reference
BTC package for SecuX device

@@ -135,12 +130,33 @@

- [SecuxBTC](#secuxbtc)
- [**SecuxBTC.getAddress(trans, path, [option])** ⇒ <code>string</code>](#secuxbtcgetaddresstrans-path-option--string)
- [SecuxBTC.signTransaction(trans, inputs, outputs) ⇒ <code>object</code>](#secuxbtcsigntransactiontrans-inputs-outputs--object)
* [SecuxBTC](#SecuxBTC)
* [.prepareAddress](#SecuxBTC.prepareAddress) ⇒ <code>communicationData</code>
* [.addressConvert(publickey, path)](#SecuxBTC.addressConvert) ⇒ <code>string</code>
* [.resolveAddress(response, path)](#SecuxBTC.resolveAddress) ⇒ <code>string</code>
* [.preparePublickey(path, [option])](#SecuxBTC.preparePublickey) ⇒ <code>communicationData</code>
* [.resolvePublickey(response)](#SecuxBTC.resolvePublickey) ⇒ <code>string</code>
* [.prepareXPublickey(path)](#SecuxBTC.prepareXPublickey) ⇒ <code>communicationData</code>
* [.resolveXPublickey(response, path)](#SecuxBTC.resolveXPublickey) ⇒ <code>string</code>
* [.prepareSign(inputs, outputs)](#SecuxBTC.prepareSign) ⇒ [<code>prepared</code>](#prepared)
* [.resolveSignatureList(response)](#SecuxBTC.resolveSignatureList) ⇒ <code>Array.&lt;string&gt;</code>
* [.resolveTransaction(response, unsigned, publickeys, [coin])](#SecuxBTC.resolveTransaction) ⇒ <code>string</code>
<a name="SecuxBTC.getAddress"></a><br/>
<br/>
<a name="SecuxBTC.prepareAddress"></a>
### **SecuxBTC.getAddress(trans, path, [option])** ⇒ <code>string</code>
*Get address derived by given BIP32 path*
### **SecuxBTC.prepareAddress ⇒ <code>communicationData</code>**
*Prepare data for address generation.*
**Kind**: static method of [<code>SecuxBTC</code>](#SecuxBTC)
**Returns**: <code>communicationData</code> - data for sending to device
| Param | Type | Description |
| --- | --- | --- |
| path | <code>string</code> | BIP32 path, ex: m/44'/0'/0'/0/0 |
| [option] | [<code>AddressOption</code>](#AddressOption) | for path validation |
<br/>
<a name="SecuxBTC.addressConvert"></a>
### **SecuxBTC.addressConvert(publickey, path) ⇒ <code>string</code>**
*Convert publickey to BTC address.*
**Returns**: <code>string</code> - address

@@ -150,21 +166,189 @@

| --- | --- | --- |
| trans | <code>ITransport</code> | |
| path | <code>string</code> | BIP32 |
| [option] | <code>AddressOption</code> | |
| publickey | <code>string</code> \| <code>Buffer</code> | secp256k1 publickey (hex string or buffer) |
| path | <code>string</code> \| <code>PathObject</code> | BIP32 path, ex: m/44'/0'/0'/0/0 |
<a name="SecuxBTC.signTransaction"></a><br/>
<br/>
<a name="SecuxBTC.resolveAddress"></a>
### SecuxBTC.signTransaction(trans, inputs, outputs) ⇒ <code>object</code>
*Create transaction and Sign*
### **SecuxBTC.resolveAddress(response, path) ⇒ <code>string</code>**
*Generate address from response data.*
**Kind**: static method of [<code>SecuxBTC</code>](#SecuxBTC)
**Returns**: <code>object</code> - signed<br/>
<code>string</code> - signed.raw_tx<br/>
<code>Array&lt;Buffer&gt;</code> - signed.signature<br/>
**Returns**: <code>string</code> - address
| Param | Type |
| --- | --- |
| trans | <code>ITransport</code> |
| inputs | <code>Array&lt;txInput&gt;</code> |
| outputs | <code>txOutput</code> |
| Param | Type | Description |
| --- | --- | --- |
| response | <code>communicationData</code> | data from device |
| path | <code>string</code> \| <code>PathObject</code> | BIP32 path, ex: m/44'/0'/0'/0/0 |
<br/>
<a name="SecuxBTC.preparePublickey"></a>
### **SecuxBTC.preparePublickey(path, [option]) ⇒ <code>communicationData</code>**
*Prepare data for secp256k1 publickey.*
**Returns**: <code>communicationData</code> - data for sending to device
| Param | Type | Description |
| --- | --- | --- |
| path | <code>string</code> | BIP32 path, ex: m/44'/0'/0'/0/0 |
| [option] | [<code>AddressOption</code>](#AddressOption) | for path validation |
<br/>
<a name="SecuxBTC.resolvePublickey"></a>
### **SecuxBTC.resolvePublickey(response) ⇒ <code>string</code>**
*Resolve secp256k1 publickey from response data.*
**Returns**: <code>string</code> - secp256k1 publickey (hex string)
| Param | Type | Description |
| --- | --- | --- |
| response | <code>communicationData</code> | data from device |
<br/>
<a name="SecuxBTC.prepareXPublickey"></a>
### **SecuxBTC.prepareXPublickey(path) ⇒ <code>communicationData</code>**
*Prepare data for extended publickey generation.*
**Returns**: <code>communicationData</code> - data for sending to device
| Param | Type | Description |
| --- | --- | --- |
| path | <code>string</code> | BIP32 path, ex: m/44'/0'/0'/0/0 |
<br/>
<a name="SecuxBTC.resolveXPublickey"></a>
### **SecuxBTC.resolveXPublickey(response, path) ⇒ <code>string</code>**
*Generate extended publickey from response data.*
**Returns**: <code>string</code> - extended publickey (xpub, ypub or zpub)
| Param | Type | Description |
| --- | --- | --- |
| response | <code>communicationData</code> | data from device |
| path | <code>string</code> | BIP32 path, ex: m/44'/0'/0'/0/0 |
<br/>
<a name="SecuxBTC.prepareSign"></a>
### **SecuxBTC.prepareSign(inputs, outputs) ⇒ [<code>prepared</code>](#prepared)**
*Prepare data for signing.*
| Param | Type | Description |
| --- | --- | --- |
| inputs | [<code>txInput</code>](#txInput) | array of utxo object |
| outputs | [<code>txOutput</code>](#txOutput) | output object |
<br/>
<a name="SecuxBTC.resolveSignatureList"></a>
### **SecuxBTC.resolveSignatureList(response) ⇒ <code>Array.&lt;string&gt;</code>**
*Reslove signature from response data.*
**Returns**: <code>Array.&lt;string&gt;</code> - signature array of hex string
| Param | Type | Description |
| --- | --- | --- |
| response | <code>communicationData</code> | data from device |
<br/>
<a name="SecuxBTC.resolveTransaction"></a>
### **SecuxBTC.resolveTransaction(response, unsigned, publickeys, [coin]) ⇒ <code>string</code>**
*Serialize transaction wtih signature for broadcasting.*
**Returns**: <code>string</code> - signed raw transaction
| Param | Type | Description |
| --- | --- | --- |
| response | <code>communicationData</code> | data from device |
| unsigned | <code>string</code> | unsigned raw transaction |
| publickeys | <code>Array.&lt;communicationData&gt;</code> | secp256k1 publickey correspond to each input |
| [coin] | <code>CoinType</code> | default: CoinType.BITCOIN |
<br/>
<br/>
<a name="txInput"></a>
## txInput
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| path | <code>string</code> | BIP32 path refer to utxo |
| publickey | <code>string</code> \| <code>Buffer</code> | scep256k1 publickey from `path` |
| hash | <code>string</code> | referenced transaction hash |
| vout | <code>number</code> | referenced transaction output index |
| satoshis | <code>number</code> | referenced transaction output amount |
| [script] | <code>ScriptType</code> | script type related to `path` |
| [txHex] | <code>string</code> | referenced raw transaction for validation |
<br/>
<a name="txOutput"></a>
## txOutput
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| to | [<code>txOutputAddress</code>](#txOutputAddress) \| [<code>txOutputScriptExtened</code>](#txOutputScriptExtened) | receiving address information |
| [utxo] | [<code>txOutputScriptExtened</code>](#txOutputScriptExtened) | changes |
<br/>
<a name="txOutputAddress"></a>
## txOutputAddress
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| address | <code>string</code> | receiving address |
| satoshis | <code>number</code> | receiving amount |
<br/>
<a name="txOutputScriptExtened"></a>
## txOutputScriptExtened
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| path | <code>string</code> | BIP32 path |
| publickey | <code>string</code> \| <code>Buffer</code> | scep256k1 publickey from `path` |
| satoshis | <code>number</code> | amount |
| [script] | <code>ScriptType</code> | script type related to `path` |
<br/>
<a name="prepared"></a>
## prepared
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| commandData | <code>communicationData</code> | data for sending to device |
| rawTx | <code>string</code> | unsigned raw transaction |
<br/>
<a name="AddressOption"></a>
## AddressOption
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| [coin] | <code>CoinType</code> | enum |
| [script] | <code>ScriptType</code> | enum |
<br/>
* * *
&copy; 2018-21 SecuX Technology Inc.
authors:<br/>
andersonwu@secuxtech.com
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