Allow custom implementations of finalizers
This commit is contained in:
parent
41bf2cd03d
commit
22682fc2c3
3 changed files with 76 additions and 10 deletions
19
src/psbt.js
19
src/psbt.js
|
@ -204,7 +204,18 @@ class Psbt {
|
|||
range(this.data.inputs.length).forEach(idx => this.finalizeInput(idx));
|
||||
return this;
|
||||
}
|
||||
finalizeInput(inputIndex) {
|
||||
finalizeInput(
|
||||
inputIndex,
|
||||
{
|
||||
classifyScript: classifyScriptF,
|
||||
canFinalize: canFinalizeF,
|
||||
getFinalScripts: getFinalScriptsF,
|
||||
} = {
|
||||
classifyScript,
|
||||
canFinalize,
|
||||
getFinalScripts,
|
||||
},
|
||||
) {
|
||||
const input = utils_1.checkForInput(this.data.inputs, inputIndex);
|
||||
const { script, isP2SH, isP2WSH, isSegwit } = getScriptFromInput(
|
||||
inputIndex,
|
||||
|
@ -212,11 +223,11 @@ class Psbt {
|
|||
this.__CACHE,
|
||||
);
|
||||
if (!script) throw new Error(`No script found for input #${inputIndex}`);
|
||||
const scriptType = classifyScript(script);
|
||||
if (!canFinalize(input, script, scriptType))
|
||||
const scriptType = classifyScriptF(script);
|
||||
if (!canFinalizeF(input, script, scriptType))
|
||||
throw new Error(`Can not finalize input #${inputIndex}`);
|
||||
checkPartialSigSighashes(input);
|
||||
const { finalScriptSig, finalScriptWitness } = getFinalScripts(
|
||||
const { finalScriptSig, finalScriptWitness } = getFinalScriptsF(
|
||||
script,
|
||||
scriptType,
|
||||
input.partialSig,
|
||||
|
|
|
@ -251,7 +251,18 @@ export class Psbt {
|
|||
return this;
|
||||
}
|
||||
|
||||
finalizeInput(inputIndex: number): this {
|
||||
finalizeInput(
|
||||
inputIndex: number,
|
||||
{
|
||||
classifyScript: classifyScriptF,
|
||||
canFinalize: canFinalizeF,
|
||||
getFinalScripts: getFinalScriptsF,
|
||||
}: IFinalizeFuncs = {
|
||||
classifyScript,
|
||||
canFinalize,
|
||||
getFinalScripts,
|
||||
},
|
||||
): this {
|
||||
const input = checkForInput(this.data.inputs, inputIndex);
|
||||
const { script, isP2SH, isP2WSH, isSegwit } = getScriptFromInput(
|
||||
inputIndex,
|
||||
|
@ -260,13 +271,13 @@ export class Psbt {
|
|||
);
|
||||
if (!script) throw new Error(`No script found for input #${inputIndex}`);
|
||||
|
||||
const scriptType = classifyScript(script);
|
||||
if (!canFinalize(input, script, scriptType))
|
||||
const scriptType = classifyScriptF(script);
|
||||
if (!canFinalizeF(input, script, scriptType))
|
||||
throw new Error(`Can not finalize input #${inputIndex}`);
|
||||
|
||||
checkPartialSigSighashes(input);
|
||||
|
||||
const { finalScriptSig, finalScriptWitness } = getFinalScripts(
|
||||
const { finalScriptSig, finalScriptWitness } = getFinalScriptsF(
|
||||
script,
|
||||
scriptType,
|
||||
input.partialSig!,
|
||||
|
@ -735,6 +746,39 @@ 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(
|
||||
input: PsbtInput,
|
||||
script: Buffer,
|
||||
|
|
15
types/psbt.d.ts
vendored
15
types/psbt.d.ts
vendored
|
@ -1,5 +1,5 @@
|
|||
import { Psbt as PsbtBase } from 'bip174';
|
||||
import { KeyValue, PsbtGlobalUpdate, PsbtInput, PsbtInputUpdate, PsbtOutput, PsbtOutputUpdate, TransactionInput } from 'bip174/src/lib/interfaces';
|
||||
import { KeyValue, PartialSig, PsbtGlobalUpdate, PsbtInput, PsbtInputUpdate, PsbtOutput, PsbtOutputUpdate, TransactionInput } from 'bip174/src/lib/interfaces';
|
||||
import { Signer, SignerAsync } from './ecpair';
|
||||
import { Network } from './networks';
|
||||
import { Transaction } from './transaction';
|
||||
|
@ -58,7 +58,7 @@ export declare class Psbt {
|
|||
getFeeRate(): number;
|
||||
getFee(): number;
|
||||
finalizeAllInputs(): this;
|
||||
finalizeInput(inputIndex: number): this;
|
||||
finalizeInput(inputIndex: number, { classifyScript: classifyScriptF, canFinalize: canFinalizeF, getFinalScripts: getFinalScriptsF, }?: IFinalizeFuncs): this;
|
||||
validateSignaturesOfAllInputs(): boolean;
|
||||
validateSignaturesOfInput(inputIndex: number, pubkey?: Buffer): boolean;
|
||||
signAllInputsHD(hdKeyPair: HDSigner, sighashTypes?: number[]): this;
|
||||
|
@ -124,4 +124,15 @@ interface HDSignerAsync extends HDSignerBase {
|
|||
derivePath(path: string): HDSignerAsync;
|
||||
sign(hash: Buffer): Promise<Buffer>;
|
||||
}
|
||||
interface IFinalizeFuncs {
|
||||
classifyScript: FinalizeFuncClassifyScript;
|
||||
canFinalize: FinalizeFuncCanFinalize;
|
||||
getFinalScripts: FinalizeFuncGetFinalScripts;
|
||||
}
|
||||
declare type FinalizeFuncClassifyScript = (script: Buffer) => string;
|
||||
declare type FinalizeFuncCanFinalize = (input: PsbtInput, script: Buffer, scriptType: string) => boolean;
|
||||
declare type FinalizeFuncGetFinalScripts = (script: Buffer, scriptType: string, partialSig: PartialSig[], isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean) => {
|
||||
finalScriptSig: Buffer | undefined;
|
||||
finalScriptWitness: Buffer | undefined;
|
||||
};
|
||||
export {};
|
||||
|
|
Loading…
Reference in a new issue