Use single func instead of 3
This commit is contained in:
parent
22682fc2c3
commit
4b5a519bfe
3 changed files with 78 additions and 78 deletions
37
src/psbt.js
37
src/psbt.js
|
@ -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,
|
||||||
|
|
|
@ -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
24
types/psbt.d.ts
vendored
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue