Skip to content

Commit 5d19abf

Browse files
committed
Add ability to get redeemScript|witnessScript from finalized scripts
1 parent c9f399e commit 5d19abf

File tree

3 files changed

+96
-16
lines changed

3 files changed

+96
-16
lines changed

src/psbt.js

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,9 @@ class Psbt {
293293
script,
294294
inputIndex,
295295
'input',
296-
input.redeemScript,
297-
input.witnessScript,
296+
input.redeemScript || redeemFromFinalScriptSig(input.finalScriptSig),
297+
input.witnessScript ||
298+
redeemFromFinalWitnessScript(input.finalScriptWitness),
298299
);
299300
const type = result.type === 'raw' ? '' : result.type + '-';
300301
const mainType = classifyScript(result.meaningfulScript);
@@ -1272,6 +1273,36 @@ function pubkeyInOutput(pubkey, output, outputIndex, cache) {
12721273
);
12731274
return pubkeyInScript(pubkey, meaningfulScript);
12741275
}
1276+
function redeemFromFinalScriptSig(finalScript) {
1277+
if (!finalScript) return;
1278+
const decomp = bscript.decompile(finalScript);
1279+
if (!decomp) return;
1280+
const lastItem = decomp[decomp.length - 1];
1281+
if (
1282+
!Buffer.isBuffer(lastItem) ||
1283+
isPubkeyLike(lastItem) ||
1284+
isSigLike(lastItem)
1285+
)
1286+
return;
1287+
const sDecomp = bscript.decompile(lastItem);
1288+
if (!sDecomp) return;
1289+
return lastItem;
1290+
}
1291+
function redeemFromFinalWitnessScript(finalScript) {
1292+
if (!finalScript) return;
1293+
const decomp = scriptWitnessToWitnessStack(finalScript);
1294+
const lastItem = decomp[decomp.length - 1];
1295+
if (isPubkeyLike(lastItem)) return;
1296+
const sDecomp = bscript.decompile(lastItem);
1297+
if (!sDecomp) return;
1298+
return lastItem;
1299+
}
1300+
function isPubkeyLike(buf) {
1301+
return buf.length === 33 && bscript.isCanonicalPubKey(buf);
1302+
}
1303+
function isSigLike(buf) {
1304+
return bscript.isCanonicalScriptSignature(buf);
1305+
}
12751306
function getMeaningfulScript(
12761307
script,
12771308
index,

test/psbt.spec.ts

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,8 @@ describe(`Psbt`, () => {
543543
});
544544

545545
describe('getInputType', () => {
546-
const { publicKey } = ECPair.makeRandom();
546+
const key = ECPair.makeRandom();
547+
const { publicKey } = key;
547548
const p2wpkhPub = (pubkey: Buffer): Buffer =>
548549
payments.p2wpkh({
549550
pubkey,
@@ -569,19 +570,26 @@ describe(`Psbt`, () => {
569570
redeemGetter,
570571
witnessGetter,
571572
expectedType,
573+
finalize,
572574
}: any): void {
573575
const psbt = new Psbt();
574-
psbt.addInput({
575-
hash:
576-
'0000000000000000000000000000000000000000000000000000000000000000',
577-
index: 0,
578-
witnessUtxo: {
579-
script: outerScript(innerScript(publicKey)),
580-
value: 2e3,
581-
},
582-
...(redeemGetter ? { redeemScript: redeemGetter(publicKey) } : {}),
583-
...(witnessGetter ? { witnessScript: witnessGetter(publicKey) } : {}),
584-
});
576+
psbt
577+
.addInput({
578+
hash:
579+
'0000000000000000000000000000000000000000000000000000000000000000',
580+
index: 0,
581+
witnessUtxo: {
582+
script: outerScript(innerScript(publicKey)),
583+
value: 2e3,
584+
},
585+
...(redeemGetter ? { redeemScript: redeemGetter(publicKey) } : {}),
586+
...(witnessGetter ? { witnessScript: witnessGetter(publicKey) } : {}),
587+
})
588+
.addOutput({
589+
script: Buffer.from('0014d85c2b71d0060b09c9886aeb815e50991dda124d'),
590+
value: 1800,
591+
});
592+
if (finalize) psbt.signInput(0, key).finalizeInput(0);
585593
const type = psbt.getInputType(0);
586594
assert.strictEqual(type, expectedType, 'incorrect input type');
587595
}
@@ -613,13 +621,15 @@ describe(`Psbt`, () => {
613621
redeemGetter: p2wpkhPub,
614622
witnessGetter: null,
615623
expectedType: 'p2sh-witnesspubkeyhash',
624+
finalize: true,
616625
},
617626
{
618627
innerScript: p2pkhPub,
619628
outerScript: p2wshOut,
620629
redeemGetter: null,
621630
witnessGetter: p2pkhPub,
622631
expectedType: 'p2wsh-pubkeyhash',
632+
finalize: true,
623633
},
624634
{
625635
innerScript: p2pkhPub,

ts_src/psbt.ts

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,8 +363,9 @@ export class Psbt {
363363
script,
364364
inputIndex,
365365
'input',
366-
input.redeemScript,
367-
input.witnessScript,
366+
input.redeemScript || redeemFromFinalScriptSig(input.finalScriptSig),
367+
input.witnessScript ||
368+
redeemFromFinalWitnessScript(input.finalScriptWitness),
368369
);
369370
const type = result.type === 'raw' ? '' : result.type + '-';
370371
const mainType = classifyScript(result.meaningfulScript);
@@ -1642,6 +1643,44 @@ function pubkeyInOutput(
16421643
return pubkeyInScript(pubkey, meaningfulScript);
16431644
}
16441645

1646+
function redeemFromFinalScriptSig(
1647+
finalScript: Buffer | undefined,
1648+
): Buffer | undefined {
1649+
if (!finalScript) return;
1650+
const decomp = bscript.decompile(finalScript);
1651+
if (!decomp) return;
1652+
const lastItem = decomp[decomp.length - 1];
1653+
if (
1654+
!Buffer.isBuffer(lastItem) ||
1655+
isPubkeyLike(lastItem) ||
1656+
isSigLike(lastItem)
1657+
)
1658+
return;
1659+
const sDecomp = bscript.decompile(lastItem);
1660+
if (!sDecomp) return;
1661+
return lastItem;
1662+
}
1663+
1664+
function redeemFromFinalWitnessScript(
1665+
finalScript: Buffer | undefined,
1666+
): Buffer | undefined {
1667+
if (!finalScript) return;
1668+
const decomp = scriptWitnessToWitnessStack(finalScript);
1669+
const lastItem = decomp[decomp.length - 1];
1670+
if (isPubkeyLike(lastItem)) return;
1671+
const sDecomp = bscript.decompile(lastItem);
1672+
if (!sDecomp) return;
1673+
return lastItem;
1674+
}
1675+
1676+
function isPubkeyLike(buf: Buffer): boolean {
1677+
return buf.length === 33 && bscript.isCanonicalPubKey(buf);
1678+
}
1679+
1680+
function isSigLike(buf: Buffer): boolean {
1681+
return bscript.isCanonicalScriptSignature(buf);
1682+
}
1683+
16451684
function getMeaningfulScript(
16461685
script: Buffer,
16471686
index: number,

0 commit comments

Comments
 (0)