Browse Source

Remove need for ts-ignore

psbt
junderw 6 years ago
parent
commit
93e1661c6c
No known key found for this signature in database GPG Key ID: B256185D3A971908
  1. 65
      src/psbt.js
  2. 70
      ts_src/psbt.ts
  3. 3
      types/psbt.d.ts

65
src/psbt.js

@ -13,8 +13,10 @@ const varuint = require('varuint-bitcoin');
class Psbt extends bip174_1.Psbt { class Psbt extends bip174_1.Psbt {
constructor(opts = {}) { constructor(opts = {}) {
super(); super();
this.__NON_WITNESS_UTXO_TX_CACHE = []; this.__NON_WITNESS_UTXO_CACHE = {
this.__NON_WITNESS_UTXO_BUF_CACHE = []; __NON_WITNESS_UTXO_TX_CACHE: [],
__NON_WITNESS_UTXO_BUF_CACHE: [],
};
// set defaults // set defaults
this.opts = Object.assign({}, DEFAULT_OPTS, opts); this.opts = Object.assign({}, DEFAULT_OPTS, opts);
this.__TX = transaction_1.Transaction.fromBuffer(this.globalMap.unsignedTx); this.__TX = transaction_1.Transaction.fromBuffer(this.globalMap.unsignedTx);
@ -46,8 +48,7 @@ class Psbt extends bip174_1.Psbt {
dpew(this, '__EXTRACTED_TX', false, true); dpew(this, '__EXTRACTED_TX', false, true);
dpew(this, '__FEE_RATE', false, true); dpew(this, '__FEE_RATE', false, true);
dpew(this, '__TX_BUF_CACHE', false, true); dpew(this, '__TX_BUF_CACHE', false, true);
dpew(this, '__NON_WITNESS_UTXO_TX_CACHE', false, true); dpew(this, '__NON_WITNESS_UTXO_CACHE', false, true);
dpew(this, '__NON_WITNESS_UTXO_BUF_CACHE', false, true);
dpew(this, 'opts', false, true); dpew(this, 'opts', false, true);
} }
static fromTransaction(txBuf) { static fromTransaction(txBuf) {
@ -181,7 +182,7 @@ class Psbt extends bip174_1.Psbt {
addNonWitnessUtxoToInput(inputIndex, nonWitnessUtxo) { addNonWitnessUtxoToInput(inputIndex, nonWitnessUtxo) {
super.addNonWitnessUtxoToInput(inputIndex, nonWitnessUtxo); super.addNonWitnessUtxoToInput(inputIndex, nonWitnessUtxo);
const input = this.inputs[inputIndex]; const input = this.inputs[inputIndex];
addNonWitnessTxCache(this, input, inputIndex); addNonWitnessTxCache(this.__NON_WITNESS_UTXO_CACHE, input, inputIndex);
return this; return this;
} }
extractTransaction(disableFeeCheck) { extractTransaction(disableFeeCheck) {
@ -237,12 +238,12 @@ class Psbt extends bip174_1.Psbt {
if (input.witnessUtxo) { if (input.witnessUtxo) {
inputAmount += input.witnessUtxo.value; inputAmount += input.witnessUtxo.value;
} else if (input.nonWitnessUtxo) { } else if (input.nonWitnessUtxo) {
// @ts-ignore const cache = this.__NON_WITNESS_UTXO_CACHE;
if (!this.__NON_WITNESS_UTXO_TX_CACHE[idx]) { if (!cache.__NON_WITNESS_UTXO_TX_CACHE[idx]) {
addNonWitnessTxCache(this, input, idx); addNonWitnessTxCache(this.__NON_WITNESS_UTXO_CACHE, input, idx);
} }
const vout = this.__TX.ins[idx].index; const vout = this.__TX.ins[idx].index;
const out = this.__NON_WITNESS_UTXO_TX_CACHE[idx].outs[vout]; const out = cache.__NON_WITNESS_UTXO_TX_CACHE[idx].outs[vout];
inputAmount += out.value; inputAmount += out.value;
} else { } else {
throw new Error('Missing input value: index #' + idx); throw new Error('Missing input value: index #' + idx);
@ -271,7 +272,7 @@ class Psbt extends bip174_1.Psbt {
inputIndex, inputIndex,
input, input,
this.__TX, this.__TX,
this, this.__NON_WITNESS_UTXO_CACHE,
); );
if (!script) return false; if (!script) return false;
const scriptType = classifyScript(script); const scriptType = classifyScript(script);
@ -300,7 +301,7 @@ class Psbt extends bip174_1.Psbt {
inputIndex, inputIndex,
keyPair.publicKey, keyPair.publicKey,
this.__TX, this.__TX,
this, this.__NON_WITNESS_UTXO_CACHE,
); );
const partialSig = { const partialSig = {
pubkey: keyPair.publicKey, pubkey: keyPair.publicKey,
@ -317,7 +318,7 @@ class Psbt extends bip174_1.Psbt {
inputIndex, inputIndex,
keyPair.publicKey, keyPair.publicKey,
this.__TX, this.__TX,
this, this.__NON_WITNESS_UTXO_CACHE,
); );
Promise.resolve(keyPair.sign(hash)).then(signature => { Promise.resolve(keyPair.sign(hash)).then(signature => {
const partialSig = { const partialSig = {
@ -335,34 +336,26 @@ const DEFAULT_OPTS = {
network: networks_1.bitcoin, network: networks_1.bitcoin,
maximumFeeRate: 5000, maximumFeeRate: 5000,
}; };
function addNonWitnessTxCache(psbt, input, inputIndex) { function addNonWitnessTxCache(cache, input, inputIndex) {
// @ts-ignore cache.__NON_WITNESS_UTXO_BUF_CACHE[inputIndex] = input.nonWitnessUtxo;
psbt.__NON_WITNESS_UTXO_BUF_CACHE[inputIndex] = input.nonWitnessUtxo;
const tx = transaction_1.Transaction.fromBuffer(input.nonWitnessUtxo); const tx = transaction_1.Transaction.fromBuffer(input.nonWitnessUtxo);
// @ts-ignore cache.__NON_WITNESS_UTXO_TX_CACHE[inputIndex] = tx;
psbt.__NON_WITNESS_UTXO_TX_CACHE[inputIndex] = tx; const self = cache;
const self = psbt;
const selfIndex = inputIndex; const selfIndex = inputIndex;
delete input.nonWitnessUtxo; delete input.nonWitnessUtxo;
Object.defineProperty(input, 'nonWitnessUtxo', { Object.defineProperty(input, 'nonWitnessUtxo', {
enumerable: true, enumerable: true,
get() { get() {
// @ts-ignore
if (self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex] !== undefined) { if (self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex] !== undefined) {
// @ts-ignore
return self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex]; return self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex];
} else { } else {
// @ts-ignore
self.__NON_WITNESS_UTXO_BUF_CACHE[ self.__NON_WITNESS_UTXO_BUF_CACHE[
selfIndex selfIndex
// @ts-ignore
] = self.__NON_WITNESS_UTXO_TX_CACHE[selfIndex].toBuffer(); ] = self.__NON_WITNESS_UTXO_TX_CACHE[selfIndex].toBuffer();
// @ts-ignore
return self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex]; return self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex];
} }
}, },
set(data) { set(data) {
// @ts-ignore
self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex] = data; self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex] = data;
}, },
}); });
@ -370,13 +363,13 @@ function addNonWitnessTxCache(psbt, input, inputIndex) {
function isFinalized(input) { function isFinalized(input) {
return !!input.finalScriptSig || !!input.finalScriptWitness; return !!input.finalScriptSig || !!input.finalScriptWitness;
} }
function getHashAndSighashType(inputs, inputIndex, pubkey, unsignedTx, psbt) { function getHashAndSighashType(inputs, inputIndex, pubkey, unsignedTx, cache) {
const input = utils_1.checkForInput(inputs, inputIndex); const input = utils_1.checkForInput(inputs, inputIndex);
const { hash, sighashType, script } = getHashForSig( const { hash, sighashType, script } = getHashForSig(
inputIndex, inputIndex,
input, input,
unsignedTx, unsignedTx,
psbt, cache,
); );
checkScriptForPubkey(pubkey, script); checkScriptForPubkey(pubkey, script);
return { return {
@ -495,18 +488,16 @@ function checkScriptForPubkey(pubkey, script) {
); );
} }
} }
const getHashForSig = (inputIndex, input, unsignedTx, psbt) => { const getHashForSig = (inputIndex, input, unsignedTx, cache) => {
const sighashType = const sighashType =
input.sighashType || transaction_1.Transaction.SIGHASH_ALL; input.sighashType || transaction_1.Transaction.SIGHASH_ALL;
let hash; let hash;
let script; let script;
if (input.nonWitnessUtxo) { if (input.nonWitnessUtxo) {
// @ts-ignore if (!cache.__NON_WITNESS_UTXO_TX_CACHE[inputIndex]) {
if (!psbt.__NON_WITNESS_UTXO_TX_CACHE[inputIndex]) { addNonWitnessTxCache(cache, input, inputIndex);
addNonWitnessTxCache(psbt, input, inputIndex);
} }
// @ts-ignore const nonWitnessUtxoTx = cache.__NON_WITNESS_UTXO_TX_CACHE[inputIndex];
const nonWitnessUtxoTx = psbt.__NON_WITNESS_UTXO_TX_CACHE[inputIndex];
const prevoutHash = unsignedTx.ins[inputIndex].hash; const prevoutHash = unsignedTx.ins[inputIndex].hash;
const utxoHash = nonWitnessUtxoTx.getHash(); const utxoHash = nonWitnessUtxoTx.getHash();
// If a non-witness UTXO is provided, its hash must match the hash specified in the prevout // If a non-witness UTXO is provided, its hash must match the hash specified in the prevout
@ -617,7 +608,7 @@ const classifyScript = script => {
if (isP2PK(script)) return 'pubkey'; if (isP2PK(script)) return 'pubkey';
return 'nonstandard'; return 'nonstandard';
}; };
function getScriptFromInput(inputIndex, input, unsignedTx, psbt) { function getScriptFromInput(inputIndex, input, unsignedTx, cache) {
const res = { const res = {
script: null, script: null,
isSegwit: false, isSegwit: false,
@ -629,12 +620,10 @@ function getScriptFromInput(inputIndex, input, unsignedTx, psbt) {
res.isP2SH = true; res.isP2SH = true;
res.script = input.redeemScript; res.script = input.redeemScript;
} else { } else {
// @ts-ignore if (!cache.__NON_WITNESS_UTXO_TX_CACHE[inputIndex]) {
if (!psbt.__NON_WITNESS_UTXO_TX_CACHE[inputIndex]) { addNonWitnessTxCache(cache, input, inputIndex);
addNonWitnessTxCache(psbt, input, inputIndex);
} }
// @ts-ignore const nonWitnessUtxoTx = cache.__NON_WITNESS_UTXO_TX_CACHE[inputIndex];
const nonWitnessUtxoTx = psbt.__NON_WITNESS_UTXO_TX_CACHE[inputIndex];
const prevoutIndex = unsignedTx.ins[inputIndex].index; const prevoutIndex = unsignedTx.ins[inputIndex].index;
res.script = nonWitnessUtxoTx.outs[prevoutIndex].script; res.script = nonWitnessUtxoTx.outs[prevoutIndex].script;
} }

70
ts_src/psbt.ts

@ -64,12 +64,14 @@ export class Psbt extends PsbtBase {
psbt.__TX = tx!; psbt.__TX = tx!;
return psbt as InstanceType<T>; return psbt as InstanceType<T>;
} }
private __NON_WITNESS_UTXO_CACHE = {
__NON_WITNESS_UTXO_TX_CACHE: [] as Transaction[],
__NON_WITNESS_UTXO_BUF_CACHE: [] as Buffer[],
};
private __TX: Transaction; private __TX: Transaction;
private __TX_BUF_CACHE?: Buffer; private __TX_BUF_CACHE?: Buffer;
private __FEE_RATE?: number; private __FEE_RATE?: number;
private __EXTRACTED_TX?: Transaction; private __EXTRACTED_TX?: Transaction;
private __NON_WITNESS_UTXO_TX_CACHE: Transaction[] = [];
private __NON_WITNESS_UTXO_BUF_CACHE: Buffer[] = [];
private opts: PsbtOpts; private opts: PsbtOpts;
constructor(opts: PsbtOptsOptional = {}) { constructor(opts: PsbtOptsOptional = {}) {
super(); super();
@ -111,8 +113,7 @@ export class Psbt extends PsbtBase {
dpew(this, '__EXTRACTED_TX', false, true); dpew(this, '__EXTRACTED_TX', false, true);
dpew(this, '__FEE_RATE', false, true); dpew(this, '__FEE_RATE', false, true);
dpew(this, '__TX_BUF_CACHE', false, true); dpew(this, '__TX_BUF_CACHE', false, true);
dpew(this, '__NON_WITNESS_UTXO_TX_CACHE', false, true); dpew(this, '__NON_WITNESS_UTXO_CACHE', false, true);
dpew(this, '__NON_WITNESS_UTXO_BUF_CACHE', false, true);
dpew(this, 'opts', false, true); dpew(this, 'opts', false, true);
} }
@ -226,7 +227,7 @@ export class Psbt extends PsbtBase {
): this { ): this {
super.addNonWitnessUtxoToInput(inputIndex, nonWitnessUtxo); super.addNonWitnessUtxoToInput(inputIndex, nonWitnessUtxo);
const input = this.inputs[inputIndex]; const input = this.inputs[inputIndex];
addNonWitnessTxCache(this, input, inputIndex); addNonWitnessTxCache(this.__NON_WITNESS_UTXO_CACHE, input, inputIndex);
return this; return this;
} }
@ -284,12 +285,12 @@ export class Psbt extends PsbtBase {
if (input.witnessUtxo) { if (input.witnessUtxo) {
inputAmount += input.witnessUtxo.value; inputAmount += input.witnessUtxo.value;
} else if (input.nonWitnessUtxo) { } else if (input.nonWitnessUtxo) {
// @ts-ignore const cache = this.__NON_WITNESS_UTXO_CACHE;
if (!this.__NON_WITNESS_UTXO_TX_CACHE[idx]) { if (!cache.__NON_WITNESS_UTXO_TX_CACHE[idx]) {
addNonWitnessTxCache(this, input, idx); addNonWitnessTxCache(this.__NON_WITNESS_UTXO_CACHE, input, idx);
} }
const vout = this.__TX.ins[idx].index; const vout = this.__TX.ins[idx].index;
const out = this.__NON_WITNESS_UTXO_TX_CACHE[idx].outs[vout] as Output; const out = cache.__NON_WITNESS_UTXO_TX_CACHE[idx].outs[vout] as Output;
inputAmount += out.value; inputAmount += out.value;
} else { } else {
throw new Error('Missing input value: index #' + idx); throw new Error('Missing input value: index #' + idx);
@ -326,7 +327,7 @@ export class Psbt extends PsbtBase {
inputIndex, inputIndex,
input, input,
this.__TX, this.__TX,
this, this.__NON_WITNESS_UTXO_CACHE,
); );
if (!script) return false; if (!script) return false;
@ -360,7 +361,7 @@ export class Psbt extends PsbtBase {
inputIndex, inputIndex,
keyPair.publicKey, keyPair.publicKey,
this.__TX, this.__TX,
this, this.__NON_WITNESS_UTXO_CACHE,
); );
const partialSig = { const partialSig = {
@ -381,7 +382,7 @@ export class Psbt extends PsbtBase {
inputIndex, inputIndex,
keyPair.publicKey, keyPair.publicKey,
this.__TX, this.__TX,
this, this.__NON_WITNESS_UTXO_CACHE,
); );
Promise.resolve(keyPair.sign(hash)).then(signature => { Promise.resolve(keyPair.sign(hash)).then(signature => {
@ -408,6 +409,11 @@ export class Psbt extends PsbtBase {
// //
// //
interface NonWitnessUtxoCache {
__NON_WITNESS_UTXO_TX_CACHE: Transaction[];
__NON_WITNESS_UTXO_BUF_CACHE: Buffer[];
}
interface PsbtOptsOptional { interface PsbtOptsOptional {
network?: Network; network?: Network;
maximumFeeRate?: number; maximumFeeRate?: number;
@ -424,39 +430,31 @@ const DEFAULT_OPTS = {
}; };
function addNonWitnessTxCache( function addNonWitnessTxCache(
psbt: Psbt, cache: NonWitnessUtxoCache,
input: PsbtInput, input: PsbtInput,
inputIndex: number, inputIndex: number,
): void { ): void {
// @ts-ignore cache.__NON_WITNESS_UTXO_BUF_CACHE[inputIndex] = input.nonWitnessUtxo!;
psbt.__NON_WITNESS_UTXO_BUF_CACHE[inputIndex] = input.nonWitnessUtxo!;
const tx = Transaction.fromBuffer(input.nonWitnessUtxo!); const tx = Transaction.fromBuffer(input.nonWitnessUtxo!);
// @ts-ignore cache.__NON_WITNESS_UTXO_TX_CACHE[inputIndex] = tx;
psbt.__NON_WITNESS_UTXO_TX_CACHE[inputIndex] = tx;
const self = psbt; const self = cache;
const selfIndex = inputIndex; const selfIndex = inputIndex;
delete input.nonWitnessUtxo; delete input.nonWitnessUtxo;
Object.defineProperty(input, 'nonWitnessUtxo', { Object.defineProperty(input, 'nonWitnessUtxo', {
enumerable: true, enumerable: true,
get(): Buffer { get(): Buffer {
// @ts-ignore
if (self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex] !== undefined) { if (self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex] !== undefined) {
// @ts-ignore
return self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex]; return self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex];
} else { } else {
// @ts-ignore
self.__NON_WITNESS_UTXO_BUF_CACHE[ self.__NON_WITNESS_UTXO_BUF_CACHE[
selfIndex selfIndex
// @ts-ignore
] = self.__NON_WITNESS_UTXO_TX_CACHE[selfIndex].toBuffer(); ] = self.__NON_WITNESS_UTXO_TX_CACHE[selfIndex].toBuffer();
// @ts-ignore
return self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex]; return self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex];
} }
}, },
set(data: Buffer): void { set(data: Buffer): void {
// @ts-ignore
self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex] = data; self.__NON_WITNESS_UTXO_BUF_CACHE[selfIndex] = data;
}, },
}); });
@ -471,7 +469,7 @@ function getHashAndSighashType(
inputIndex: number, inputIndex: number,
pubkey: Buffer, pubkey: Buffer,
unsignedTx: Transaction, unsignedTx: Transaction,
psbt: Psbt, cache: NonWitnessUtxoCache,
): { ): {
hash: Buffer; hash: Buffer;
sighashType: number; sighashType: number;
@ -481,7 +479,7 @@ function getHashAndSighashType(
inputIndex, inputIndex,
input, input,
unsignedTx, unsignedTx,
psbt, cache,
); );
checkScriptForPubkey(pubkey, script); checkScriptForPubkey(pubkey, script);
return { return {
@ -632,19 +630,17 @@ const getHashForSig = (
inputIndex: number, inputIndex: number,
input: PsbtInput, input: PsbtInput,
unsignedTx: Transaction, unsignedTx: Transaction,
psbt: Psbt, cache: NonWitnessUtxoCache,
): HashForSigData => { ): HashForSigData => {
const sighashType = input.sighashType || Transaction.SIGHASH_ALL; const sighashType = input.sighashType || Transaction.SIGHASH_ALL;
let hash: Buffer; let hash: Buffer;
let script: Buffer; let script: Buffer;
if (input.nonWitnessUtxo) { if (input.nonWitnessUtxo) {
// @ts-ignore if (!cache.__NON_WITNESS_UTXO_TX_CACHE[inputIndex]) {
if (!psbt.__NON_WITNESS_UTXO_TX_CACHE[inputIndex]) { addNonWitnessTxCache(cache, input, inputIndex);
addNonWitnessTxCache(psbt, input, inputIndex);
} }
// @ts-ignore const nonWitnessUtxoTx = cache.__NON_WITNESS_UTXO_TX_CACHE[inputIndex];
const nonWitnessUtxoTx = psbt.__NON_WITNESS_UTXO_TX_CACHE[inputIndex];
const prevoutHash = unsignedTx.ins[inputIndex].hash; const prevoutHash = unsignedTx.ins[inputIndex].hash;
const utxoHash = nonWitnessUtxoTx.getHash(); const utxoHash = nonWitnessUtxoTx.getHash();
@ -784,7 +780,7 @@ function getScriptFromInput(
inputIndex: number, inputIndex: number,
input: PsbtInput, input: PsbtInput,
unsignedTx: Transaction, unsignedTx: Transaction,
psbt: Psbt, cache: NonWitnessUtxoCache,
): GetScriptReturn { ): GetScriptReturn {
const res: GetScriptReturn = { const res: GetScriptReturn = {
script: null, script: null,
@ -797,12 +793,10 @@ function getScriptFromInput(
res.isP2SH = true; res.isP2SH = true;
res.script = input.redeemScript; res.script = input.redeemScript;
} else { } else {
// @ts-ignore if (!cache.__NON_WITNESS_UTXO_TX_CACHE[inputIndex]) {
if (!psbt.__NON_WITNESS_UTXO_TX_CACHE[inputIndex]) { addNonWitnessTxCache(cache, input, inputIndex);
addNonWitnessTxCache(psbt, input, inputIndex);
} }
// @ts-ignore const nonWitnessUtxoTx = cache.__NON_WITNESS_UTXO_TX_CACHE[inputIndex];
const nonWitnessUtxoTx = psbt.__NON_WITNESS_UTXO_TX_CACHE[inputIndex];
const prevoutIndex = unsignedTx.ins[inputIndex].index; const prevoutIndex = unsignedTx.ins[inputIndex].index;
res.script = nonWitnessUtxoTx.outs[prevoutIndex].script; res.script = nonWitnessUtxoTx.outs[prevoutIndex].script;
} }

3
types/psbt.d.ts

@ -7,12 +7,11 @@ import { Transaction } from './transaction';
export declare class Psbt extends PsbtBase { export declare class Psbt extends PsbtBase {
static fromTransaction<T extends typeof PsbtBase>(this: T, txBuf: Buffer): InstanceType<T>; static fromTransaction<T extends typeof PsbtBase>(this: T, txBuf: Buffer): InstanceType<T>;
static fromBuffer<T extends typeof PsbtBase>(this: T, buffer: Buffer): InstanceType<T>; static fromBuffer<T extends typeof PsbtBase>(this: T, buffer: Buffer): InstanceType<T>;
private __NON_WITNESS_UTXO_CACHE;
private __TX; private __TX;
private __TX_BUF_CACHE?; private __TX_BUF_CACHE?;
private __FEE_RATE?; private __FEE_RATE?;
private __EXTRACTED_TX?; private __EXTRACTED_TX?;
private __NON_WITNESS_UTXO_TX_CACHE;
private __NON_WITNESS_UTXO_BUF_CACHE;
private opts; private opts;
constructor(opts?: PsbtOptsOptional); constructor(opts?: PsbtOptsOptional);
setMaximumFeeRate(satoshiPerByte: number): void; setMaximumFeeRate(satoshiPerByte: number): void;

Loading…
Cancel
Save