Use single func instead of 3

This commit is contained in:
junderw 2019-10-28 11:40:56 +09:00
parent 22682fc2c3
commit 4b5a519bfe
No known key found for this signature in database
GPG key ID: B256185D3A971908
3 changed files with 78 additions and 78 deletions

View file

@ -204,18 +204,7 @@ class Psbt {
range(this.data.inputs.length).forEach(idx => this.finalizeInput(idx)); range(this.data.inputs.length).forEach(idx => this.finalizeInput(idx));
return this; return this;
} }
finalizeInput( finalizeInput(inputIndex, finalScriptsFunc = getFinalScripts) {
inputIndex,
{
classifyScript: classifyScriptF,
canFinalize: canFinalizeF,
getFinalScripts: getFinalScriptsF,
} = {
classifyScript,
canFinalize,
getFinalScripts,
},
) {
const input = utils_1.checkForInput(this.data.inputs, inputIndex); const input = utils_1.checkForInput(this.data.inputs, inputIndex);
const { script, isP2SH, isP2WSH, isSegwit } = getScriptFromInput( const { script, isP2SH, isP2WSH, isSegwit } = getScriptFromInput(
inputIndex, inputIndex,
@ -223,14 +212,11 @@ class Psbt {
this.__CACHE, this.__CACHE,
); );
if (!script) throw new Error(`No script found for input #${inputIndex}`); if (!script) throw new Error(`No script found for input #${inputIndex}`);
const scriptType = classifyScriptF(script);
if (!canFinalizeF(input, script, scriptType))
throw new Error(`Can not finalize input #${inputIndex}`);
checkPartialSigSighashes(input); checkPartialSigSighashes(input);
const { finalScriptSig, finalScriptWitness } = getFinalScriptsF( const { finalScriptSig, finalScriptWitness } = finalScriptsFunc(
inputIndex,
input,
script, script,
scriptType,
input.partialSig,
isSegwit, isSegwit,
isP2SH, isP2SH,
isP2WSH, isP2WSH,
@ -749,7 +735,20 @@ function getTxCacheValue(key, name, inputs, c) {
if (key === '__FEE_RATE') return c.__FEE_RATE; if (key === '__FEE_RATE') return c.__FEE_RATE;
else if (key === '__FEE') return c.__FEE; else if (key === '__FEE') return c.__FEE;
} }
function getFinalScripts( function getFinalScripts(inputIndex, input, script, isSegwit, isP2SH, isP2WSH) {
const scriptType = classifyScript(script);
if (!canFinalize(input, script, scriptType))
throw new Error(`Can not finalize input #${inputIndex}`);
return prepareFinalScripts(
script,
scriptType,
input.partialSig,
isSegwit,
isP2SH,
isP2WSH,
);
}
function prepareFinalScripts(
script, script,
scriptType, scriptType,
partialSig, partialSig,

View file

@ -253,15 +253,7 @@ export class Psbt {
finalizeInput( finalizeInput(
inputIndex: number, inputIndex: number,
{ finalScriptsFunc: FinalScriptsFunc = getFinalScripts,
classifyScript: classifyScriptF,
canFinalize: canFinalizeF,
getFinalScripts: getFinalScriptsF,
}: IFinalizeFuncs = {
classifyScript,
canFinalize,
getFinalScripts,
},
): this { ): this {
const input = checkForInput(this.data.inputs, inputIndex); const input = checkForInput(this.data.inputs, inputIndex);
const { script, isP2SH, isP2WSH, isSegwit } = getScriptFromInput( const { script, isP2SH, isP2WSH, isSegwit } = getScriptFromInput(
@ -271,16 +263,12 @@ export class Psbt {
); );
if (!script) throw new Error(`No script found for input #${inputIndex}`); if (!script) throw new Error(`No script found for input #${inputIndex}`);
const scriptType = classifyScriptF(script);
if (!canFinalizeF(input, script, scriptType))
throw new Error(`Can not finalize input #${inputIndex}`);
checkPartialSigSighashes(input); checkPartialSigSighashes(input);
const { finalScriptSig, finalScriptWitness } = getFinalScriptsF( const { finalScriptSig, finalScriptWitness } = finalScriptsFunc(
inputIndex,
input,
script, script,
scriptType,
input.partialSig!,
isSegwit, isSegwit,
isP2SH, isP2SH,
isP2WSH, isP2WSH,
@ -746,39 +734,6 @@ class PsbtTransaction implements ITransaction {
} }
} }
// This interface is added to allow for custom scripts to be finalized with PSBT.
interface IFinalizeFuncs {
classifyScript: FinalizeFuncClassifyScript;
canFinalize: FinalizeFuncCanFinalize;
getFinalScripts: FinalizeFuncGetFinalScripts;
}
// Takes the meaningful script (redeemScript for P2SH and witnessScript for P2WSH)
// and returns a string to classify the script.
type FinalizeFuncClassifyScript = (script: Buffer) => string;
// Takes the Psbt data for the input and the meaningful script and its type name.
// returns true if we can finalize the input
type FinalizeFuncCanFinalize = (
input: PsbtInput,
script: Buffer,
scriptType: string,
) => boolean;
// Takes the meaningful script, its type name, all the signatures from this input,
// and 3 booleans to tell you if it is segwit, P2SH, and P2WSH.
// it returns finalScriptSig and finalScriptWitness to be placed in the Psbt.
// if one is not needed, it should be undefined. (In TypeScript, it must be declared but undefined.)
type FinalizeFuncGetFinalScripts = (
script: Buffer,
scriptType: string,
partialSig: PartialSig[],
isSegwit: boolean,
isP2SH: boolean,
isP2WSH: boolean,
) => {
finalScriptSig: Buffer | undefined;
finalScriptWitness: Buffer | undefined;
};
function canFinalize( function canFinalize(
input: PsbtInput, input: PsbtInput,
script: Buffer, script: Buffer,
@ -996,7 +951,49 @@ function getTxCacheValue(
else if (key === '__FEE') return c.__FEE!; else if (key === '__FEE') return c.__FEE!;
} }
/**
* This function must do two things:
* 1. Check if the `input` can be finalized. If it can not be finalized, throw.
* ie. `Can not finalize input #${inputIndex}`
* 2. Create the finalScriptSig and finalScriptWitness Buffers.
*/
type FinalScriptsFunc = (
inputIndex: number, // Which input is it?
input: PsbtInput, // The PSBT input contents
script: Buffer, // The "meaningful" locking script Buffer (redeemScript for P2SH etc.)
isSegwit: boolean, // Is it segwit?
isP2SH: boolean, // Is it P2SH?
isP2WSH: boolean, // Is it P2WSH?
) => {
finalScriptSig: Buffer | undefined;
finalScriptWitness: Buffer | undefined;
};
function getFinalScripts( function getFinalScripts(
inputIndex: number,
input: PsbtInput,
script: Buffer,
isSegwit: boolean,
isP2SH: boolean,
isP2WSH: boolean,
): {
finalScriptSig: Buffer | undefined;
finalScriptWitness: Buffer | undefined;
} {
const scriptType = classifyScript(script);
if (!canFinalize(input, script, scriptType))
throw new Error(`Can not finalize input #${inputIndex}`);
return prepareFinalScripts(
script,
scriptType,
input.partialSig!,
isSegwit,
isP2SH,
isP2WSH,
);
}
function prepareFinalScripts(
script: Buffer, script: Buffer,
scriptType: string, scriptType: string,
partialSig: PartialSig[], partialSig: PartialSig[],

24
types/psbt.d.ts vendored
View file

@ -1,5 +1,5 @@
import { Psbt as PsbtBase } from 'bip174'; import { Psbt as PsbtBase } from 'bip174';
import { KeyValue, PartialSig, PsbtGlobalUpdate, PsbtInput, PsbtInputUpdate, PsbtOutput, PsbtOutputUpdate, TransactionInput } from 'bip174/src/lib/interfaces'; import { KeyValue, PsbtGlobalUpdate, PsbtInput, PsbtInputUpdate, PsbtOutput, PsbtOutputUpdate, TransactionInput } from 'bip174/src/lib/interfaces';
import { Signer, SignerAsync } from './ecpair'; import { Signer, SignerAsync } from './ecpair';
import { Network } from './networks'; import { Network } from './networks';
import { Transaction } from './transaction'; import { Transaction } from './transaction';
@ -58,7 +58,7 @@ export declare class Psbt {
getFeeRate(): number; getFeeRate(): number;
getFee(): number; getFee(): number;
finalizeAllInputs(): this; finalizeAllInputs(): this;
finalizeInput(inputIndex: number, { classifyScript: classifyScriptF, canFinalize: canFinalizeF, getFinalScripts: getFinalScriptsF, }?: IFinalizeFuncs): this; finalizeInput(inputIndex: number, finalScriptsFunc?: FinalScriptsFunc): this;
validateSignaturesOfAllInputs(): boolean; validateSignaturesOfAllInputs(): boolean;
validateSignaturesOfInput(inputIndex: number, pubkey?: Buffer): boolean; validateSignaturesOfInput(inputIndex: number, pubkey?: Buffer): boolean;
signAllInputsHD(hdKeyPair: HDSigner, sighashTypes?: number[]): this; signAllInputsHD(hdKeyPair: HDSigner, sighashTypes?: number[]): this;
@ -124,14 +124,18 @@ interface HDSignerAsync extends HDSignerBase {
derivePath(path: string): HDSignerAsync; derivePath(path: string): HDSignerAsync;
sign(hash: Buffer): Promise<Buffer>; sign(hash: Buffer): Promise<Buffer>;
} }
interface IFinalizeFuncs { /**
classifyScript: FinalizeFuncClassifyScript; * This function must do two things:
canFinalize: FinalizeFuncCanFinalize; * 1. Check if the `input` can be finalized. If it can not be finalized, throw.
getFinalScripts: FinalizeFuncGetFinalScripts; * ie. `Can not finalize input #${inputIndex}`
} * 2. Create the finalScriptSig and finalScriptWitness Buffers.
declare type FinalizeFuncClassifyScript = (script: Buffer) => string; */
declare type FinalizeFuncCanFinalize = (input: PsbtInput, script: Buffer, scriptType: string) => boolean; declare type FinalScriptsFunc = (inputIndex: number, // Which input is it?
declare type FinalizeFuncGetFinalScripts = (script: Buffer, scriptType: string, partialSig: PartialSig[], isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean) => { input: PsbtInput, // The PSBT input contents
script: Buffer, // The "meaningful" locking script Buffer (redeemScript for P2SH etc.)
isSegwit: boolean, // Is it segwit?
isP2SH: boolean, // Is it P2SH?
isP2WSH: boolean) => {
finalScriptSig: Buffer | undefined; finalScriptSig: Buffer | undefined;
finalScriptWitness: Buffer | undefined; finalScriptWitness: Buffer | undefined;
}; };