Add ability to get redeemScript|witnessScript from finalized scripts
This commit is contained in:
parent
c9f399e509
commit
5d19abfb85
3 changed files with 96 additions and 16 deletions
35
src/psbt.js
35
src/psbt.js
|
@ -293,8 +293,9 @@ class Psbt {
|
||||||
script,
|
script,
|
||||||
inputIndex,
|
inputIndex,
|
||||||
'input',
|
'input',
|
||||||
input.redeemScript,
|
input.redeemScript || redeemFromFinalScriptSig(input.finalScriptSig),
|
||||||
input.witnessScript,
|
input.witnessScript ||
|
||||||
|
redeemFromFinalWitnessScript(input.finalScriptWitness),
|
||||||
);
|
);
|
||||||
const type = result.type === 'raw' ? '' : result.type + '-';
|
const type = result.type === 'raw' ? '' : result.type + '-';
|
||||||
const mainType = classifyScript(result.meaningfulScript);
|
const mainType = classifyScript(result.meaningfulScript);
|
||||||
|
@ -1272,6 +1273,36 @@ function pubkeyInOutput(pubkey, output, outputIndex, cache) {
|
||||||
);
|
);
|
||||||
return pubkeyInScript(pubkey, meaningfulScript);
|
return pubkeyInScript(pubkey, meaningfulScript);
|
||||||
}
|
}
|
||||||
|
function redeemFromFinalScriptSig(finalScript) {
|
||||||
|
if (!finalScript) return;
|
||||||
|
const decomp = bscript.decompile(finalScript);
|
||||||
|
if (!decomp) return;
|
||||||
|
const lastItem = decomp[decomp.length - 1];
|
||||||
|
if (
|
||||||
|
!Buffer.isBuffer(lastItem) ||
|
||||||
|
isPubkeyLike(lastItem) ||
|
||||||
|
isSigLike(lastItem)
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
const sDecomp = bscript.decompile(lastItem);
|
||||||
|
if (!sDecomp) return;
|
||||||
|
return lastItem;
|
||||||
|
}
|
||||||
|
function redeemFromFinalWitnessScript(finalScript) {
|
||||||
|
if (!finalScript) return;
|
||||||
|
const decomp = scriptWitnessToWitnessStack(finalScript);
|
||||||
|
const lastItem = decomp[decomp.length - 1];
|
||||||
|
if (isPubkeyLike(lastItem)) return;
|
||||||
|
const sDecomp = bscript.decompile(lastItem);
|
||||||
|
if (!sDecomp) return;
|
||||||
|
return lastItem;
|
||||||
|
}
|
||||||
|
function isPubkeyLike(buf) {
|
||||||
|
return buf.length === 33 && bscript.isCanonicalPubKey(buf);
|
||||||
|
}
|
||||||
|
function isSigLike(buf) {
|
||||||
|
return bscript.isCanonicalScriptSignature(buf);
|
||||||
|
}
|
||||||
function getMeaningfulScript(
|
function getMeaningfulScript(
|
||||||
script,
|
script,
|
||||||
index,
|
index,
|
||||||
|
|
|
@ -543,7 +543,8 @@ describe(`Psbt`, () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getInputType', () => {
|
describe('getInputType', () => {
|
||||||
const { publicKey } = ECPair.makeRandom();
|
const key = ECPair.makeRandom();
|
||||||
|
const { publicKey } = key;
|
||||||
const p2wpkhPub = (pubkey: Buffer): Buffer =>
|
const p2wpkhPub = (pubkey: Buffer): Buffer =>
|
||||||
payments.p2wpkh({
|
payments.p2wpkh({
|
||||||
pubkey,
|
pubkey,
|
||||||
|
@ -569,19 +570,26 @@ describe(`Psbt`, () => {
|
||||||
redeemGetter,
|
redeemGetter,
|
||||||
witnessGetter,
|
witnessGetter,
|
||||||
expectedType,
|
expectedType,
|
||||||
|
finalize,
|
||||||
}: any): void {
|
}: any): void {
|
||||||
const psbt = new Psbt();
|
const psbt = new Psbt();
|
||||||
psbt.addInput({
|
psbt
|
||||||
hash:
|
.addInput({
|
||||||
'0000000000000000000000000000000000000000000000000000000000000000',
|
hash:
|
||||||
index: 0,
|
'0000000000000000000000000000000000000000000000000000000000000000',
|
||||||
witnessUtxo: {
|
index: 0,
|
||||||
script: outerScript(innerScript(publicKey)),
|
witnessUtxo: {
|
||||||
value: 2e3,
|
script: outerScript(innerScript(publicKey)),
|
||||||
},
|
value: 2e3,
|
||||||
...(redeemGetter ? { redeemScript: redeemGetter(publicKey) } : {}),
|
},
|
||||||
...(witnessGetter ? { witnessScript: witnessGetter(publicKey) } : {}),
|
...(redeemGetter ? { redeemScript: redeemGetter(publicKey) } : {}),
|
||||||
});
|
...(witnessGetter ? { witnessScript: witnessGetter(publicKey) } : {}),
|
||||||
|
})
|
||||||
|
.addOutput({
|
||||||
|
script: Buffer.from('0014d85c2b71d0060b09c9886aeb815e50991dda124d'),
|
||||||
|
value: 1800,
|
||||||
|
});
|
||||||
|
if (finalize) psbt.signInput(0, key).finalizeInput(0);
|
||||||
const type = psbt.getInputType(0);
|
const type = psbt.getInputType(0);
|
||||||
assert.strictEqual(type, expectedType, 'incorrect input type');
|
assert.strictEqual(type, expectedType, 'incorrect input type');
|
||||||
}
|
}
|
||||||
|
@ -613,6 +621,7 @@ describe(`Psbt`, () => {
|
||||||
redeemGetter: p2wpkhPub,
|
redeemGetter: p2wpkhPub,
|
||||||
witnessGetter: null,
|
witnessGetter: null,
|
||||||
expectedType: 'p2sh-witnesspubkeyhash',
|
expectedType: 'p2sh-witnesspubkeyhash',
|
||||||
|
finalize: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
innerScript: p2pkhPub,
|
innerScript: p2pkhPub,
|
||||||
|
@ -620,6 +629,7 @@ describe(`Psbt`, () => {
|
||||||
redeemGetter: null,
|
redeemGetter: null,
|
||||||
witnessGetter: p2pkhPub,
|
witnessGetter: p2pkhPub,
|
||||||
expectedType: 'p2wsh-pubkeyhash',
|
expectedType: 'p2wsh-pubkeyhash',
|
||||||
|
finalize: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
innerScript: p2pkhPub,
|
innerScript: p2pkhPub,
|
||||||
|
|
|
@ -363,8 +363,9 @@ export class Psbt {
|
||||||
script,
|
script,
|
||||||
inputIndex,
|
inputIndex,
|
||||||
'input',
|
'input',
|
||||||
input.redeemScript,
|
input.redeemScript || redeemFromFinalScriptSig(input.finalScriptSig),
|
||||||
input.witnessScript,
|
input.witnessScript ||
|
||||||
|
redeemFromFinalWitnessScript(input.finalScriptWitness),
|
||||||
);
|
);
|
||||||
const type = result.type === 'raw' ? '' : result.type + '-';
|
const type = result.type === 'raw' ? '' : result.type + '-';
|
||||||
const mainType = classifyScript(result.meaningfulScript);
|
const mainType = classifyScript(result.meaningfulScript);
|
||||||
|
@ -1642,6 +1643,44 @@ function pubkeyInOutput(
|
||||||
return pubkeyInScript(pubkey, meaningfulScript);
|
return pubkeyInScript(pubkey, meaningfulScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function redeemFromFinalScriptSig(
|
||||||
|
finalScript: Buffer | undefined,
|
||||||
|
): Buffer | undefined {
|
||||||
|
if (!finalScript) return;
|
||||||
|
const decomp = bscript.decompile(finalScript);
|
||||||
|
if (!decomp) return;
|
||||||
|
const lastItem = decomp[decomp.length - 1];
|
||||||
|
if (
|
||||||
|
!Buffer.isBuffer(lastItem) ||
|
||||||
|
isPubkeyLike(lastItem) ||
|
||||||
|
isSigLike(lastItem)
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
const sDecomp = bscript.decompile(lastItem);
|
||||||
|
if (!sDecomp) return;
|
||||||
|
return lastItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
function redeemFromFinalWitnessScript(
|
||||||
|
finalScript: Buffer | undefined,
|
||||||
|
): Buffer | undefined {
|
||||||
|
if (!finalScript) return;
|
||||||
|
const decomp = scriptWitnessToWitnessStack(finalScript);
|
||||||
|
const lastItem = decomp[decomp.length - 1];
|
||||||
|
if (isPubkeyLike(lastItem)) return;
|
||||||
|
const sDecomp = bscript.decompile(lastItem);
|
||||||
|
if (!sDecomp) return;
|
||||||
|
return lastItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPubkeyLike(buf: Buffer): boolean {
|
||||||
|
return buf.length === 33 && bscript.isCanonicalPubKey(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSigLike(buf: Buffer): boolean {
|
||||||
|
return bscript.isCanonicalScriptSignature(buf);
|
||||||
|
}
|
||||||
|
|
||||||
function getMeaningfulScript(
|
function getMeaningfulScript(
|
||||||
script: Buffer,
|
script: Buffer,
|
||||||
index: number,
|
index: number,
|
||||||
|
|
Loading…
Reference in a new issue