Skip to content

Commit 22682fc

Browse files
committed
Allow custom implementations of finalizers
1 parent 41bf2cd commit 22682fc

File tree

3 files changed

+76
-10
lines changed

3 files changed

+76
-10
lines changed

src/psbt.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,19 +204,30 @@ class Psbt {
204204
range(this.data.inputs.length).forEach(idx => this.finalizeInput(idx));
205205
return this;
206206
}
207-
finalizeInput(inputIndex) {
207+
finalizeInput(
208+
inputIndex,
209+
{
210+
classifyScript: classifyScriptF,
211+
canFinalize: canFinalizeF,
212+
getFinalScripts: getFinalScriptsF,
213+
} = {
214+
classifyScript,
215+
canFinalize,
216+
getFinalScripts,
217+
},
218+
) {
208219
const input = utils_1.checkForInput(this.data.inputs, inputIndex);
209220
const { script, isP2SH, isP2WSH, isSegwit } = getScriptFromInput(
210221
inputIndex,
211222
input,
212223
this.__CACHE,
213224
);
214225
if (!script) throw new Error(`No script found for input #${inputIndex}`);
215-
const scriptType = classifyScript(script);
216-
if (!canFinalize(input, script, scriptType))
226+
const scriptType = classifyScriptF(script);
227+
if (!canFinalizeF(input, script, scriptType))
217228
throw new Error(`Can not finalize input #${inputIndex}`);
218229
checkPartialSigSighashes(input);
219-
const { finalScriptSig, finalScriptWitness } = getFinalScripts(
230+
const { finalScriptSig, finalScriptWitness } = getFinalScriptsF(
220231
script,
221232
scriptType,
222233
input.partialSig,

ts_src/psbt.ts

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,18 @@ export class Psbt {
251251
return this;
252252
}
253253

254-
finalizeInput(inputIndex: number): this {
254+
finalizeInput(
255+
inputIndex: number,
256+
{
257+
classifyScript: classifyScriptF,
258+
canFinalize: canFinalizeF,
259+
getFinalScripts: getFinalScriptsF,
260+
}: IFinalizeFuncs = {
261+
classifyScript,
262+
canFinalize,
263+
getFinalScripts,
264+
},
265+
): this {
255266
const input = checkForInput(this.data.inputs, inputIndex);
256267
const { script, isP2SH, isP2WSH, isSegwit } = getScriptFromInput(
257268
inputIndex,
@@ -260,13 +271,13 @@ export class Psbt {
260271
);
261272
if (!script) throw new Error(`No script found for input #${inputIndex}`);
262273

263-
const scriptType = classifyScript(script);
264-
if (!canFinalize(input, script, scriptType))
274+
const scriptType = classifyScriptF(script);
275+
if (!canFinalizeF(input, script, scriptType))
265276
throw new Error(`Can not finalize input #${inputIndex}`);
266277

267278
checkPartialSigSighashes(input);
268279

269-
const { finalScriptSig, finalScriptWitness } = getFinalScripts(
280+
const { finalScriptSig, finalScriptWitness } = getFinalScriptsF(
270281
script,
271282
scriptType,
272283
input.partialSig!,
@@ -735,6 +746,39 @@ class PsbtTransaction implements ITransaction {
735746
}
736747
}
737748

749+
// This interface is added to allow for custom scripts to be finalized with PSBT.
750+
interface IFinalizeFuncs {
751+
classifyScript: FinalizeFuncClassifyScript;
752+
canFinalize: FinalizeFuncCanFinalize;
753+
getFinalScripts: FinalizeFuncGetFinalScripts;
754+
}
755+
756+
// Takes the meaningful script (redeemScript for P2SH and witnessScript for P2WSH)
757+
// and returns a string to classify the script.
758+
type FinalizeFuncClassifyScript = (script: Buffer) => string;
759+
// Takes the Psbt data for the input and the meaningful script and its type name.
760+
// returns true if we can finalize the input
761+
type FinalizeFuncCanFinalize = (
762+
input: PsbtInput,
763+
script: Buffer,
764+
scriptType: string,
765+
) => boolean;
766+
// Takes the meaningful script, its type name, all the signatures from this input,
767+
// and 3 booleans to tell you if it is segwit, P2SH, and P2WSH.
768+
// it returns finalScriptSig and finalScriptWitness to be placed in the Psbt.
769+
// if one is not needed, it should be undefined. (In TypeScript, it must be declared but undefined.)
770+
type FinalizeFuncGetFinalScripts = (
771+
script: Buffer,
772+
scriptType: string,
773+
partialSig: PartialSig[],
774+
isSegwit: boolean,
775+
isP2SH: boolean,
776+
isP2WSH: boolean,
777+
) => {
778+
finalScriptSig: Buffer | undefined;
779+
finalScriptWitness: Buffer | undefined;
780+
};
781+
738782
function canFinalize(
739783
input: PsbtInput,
740784
script: Buffer,

types/psbt.d.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Psbt as PsbtBase } from 'bip174';
2-
import { KeyValue, PsbtGlobalUpdate, PsbtInput, PsbtInputUpdate, PsbtOutput, PsbtOutputUpdate, TransactionInput } from 'bip174/src/lib/interfaces';
2+
import { KeyValue, PartialSig, PsbtGlobalUpdate, PsbtInput, PsbtInputUpdate, PsbtOutput, PsbtOutputUpdate, TransactionInput } from 'bip174/src/lib/interfaces';
33
import { Signer, SignerAsync } from './ecpair';
44
import { Network } from './networks';
55
import { Transaction } from './transaction';
@@ -58,7 +58,7 @@ export declare class Psbt {
5858
getFeeRate(): number;
5959
getFee(): number;
6060
finalizeAllInputs(): this;
61-
finalizeInput(inputIndex: number): this;
61+
finalizeInput(inputIndex: number, { classifyScript: classifyScriptF, canFinalize: canFinalizeF, getFinalScripts: getFinalScriptsF, }?: IFinalizeFuncs): this;
6262
validateSignaturesOfAllInputs(): boolean;
6363
validateSignaturesOfInput(inputIndex: number, pubkey?: Buffer): boolean;
6464
signAllInputsHD(hdKeyPair: HDSigner, sighashTypes?: number[]): this;
@@ -124,4 +124,15 @@ interface HDSignerAsync extends HDSignerBase {
124124
derivePath(path: string): HDSignerAsync;
125125
sign(hash: Buffer): Promise<Buffer>;
126126
}
127+
interface IFinalizeFuncs {
128+
classifyScript: FinalizeFuncClassifyScript;
129+
canFinalize: FinalizeFuncCanFinalize;
130+
getFinalScripts: FinalizeFuncGetFinalScripts;
131+
}
132+
declare type FinalizeFuncClassifyScript = (script: Buffer) => string;
133+
declare type FinalizeFuncCanFinalize = (input: PsbtInput, script: Buffer, scriptType: string) => boolean;
134+
declare type FinalizeFuncGetFinalScripts = (script: Buffer, scriptType: string, partialSig: PartialSig[], isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean) => {
135+
finalScriptSig: Buffer | undefined;
136+
finalScriptWitness: Buffer | undefined;
137+
};
127138
export {};

0 commit comments

Comments
 (0)