Finalize should chain this as well.
This commit is contained in:
parent
ba33f0317f
commit
b8c341dea0
4 changed files with 51 additions and 48 deletions
30
src/psbt.js
30
src/psbt.js
|
@ -187,14 +187,9 @@ class Psbt extends bip174_1.Psbt {
|
||||||
return c.__FEE_RATE;
|
return c.__FEE_RATE;
|
||||||
}
|
}
|
||||||
finalizeAllInputs() {
|
finalizeAllInputs() {
|
||||||
const inputResults = range(this.inputs.length).map(idx =>
|
utils_1.checkForInput(this.inputs, 0); // making sure we have at least one
|
||||||
this.finalizeInput(idx),
|
range(this.inputs.length).forEach(idx => this.finalizeInput(idx));
|
||||||
);
|
return this;
|
||||||
const result = inputResults.every(val => val === true);
|
|
||||||
return {
|
|
||||||
result,
|
|
||||||
inputResults,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
finalizeInput(inputIndex) {
|
finalizeInput(inputIndex) {
|
||||||
const input = utils_1.checkForInput(this.inputs, inputIndex);
|
const input = utils_1.checkForInput(this.inputs, inputIndex);
|
||||||
|
@ -203,9 +198,10 @@ class Psbt extends bip174_1.Psbt {
|
||||||
input,
|
input,
|
||||||
this.__CACHE,
|
this.__CACHE,
|
||||||
);
|
);
|
||||||
if (!script) return false;
|
if (!script) throw new Error(`No script found for input #${inputIndex}`);
|
||||||
const scriptType = classifyScript(script);
|
const scriptType = classifyScript(script);
|
||||||
if (!canFinalize(input, script, scriptType)) return false;
|
if (!canFinalize(input, script, scriptType))
|
||||||
|
throw new Error(`Can not finalize input #${inputIndex}`);
|
||||||
const { finalScriptSig, finalScriptWitness } = getFinalScripts(
|
const { finalScriptSig, finalScriptWitness } = getFinalScripts(
|
||||||
script,
|
script,
|
||||||
scriptType,
|
scriptType,
|
||||||
|
@ -218,9 +214,17 @@ class Psbt extends bip174_1.Psbt {
|
||||||
this.addFinalScriptSigToInput(inputIndex, finalScriptSig);
|
this.addFinalScriptSigToInput(inputIndex, finalScriptSig);
|
||||||
if (finalScriptWitness)
|
if (finalScriptWitness)
|
||||||
this.addFinalScriptWitnessToInput(inputIndex, finalScriptWitness);
|
this.addFinalScriptWitnessToInput(inputIndex, finalScriptWitness);
|
||||||
if (!finalScriptSig && !finalScriptWitness) return false;
|
if (!finalScriptSig && !finalScriptWitness)
|
||||||
|
throw new Error(`Unknown error finalizing input #${inputIndex}`);
|
||||||
this.clearFinalizedInput(inputIndex);
|
this.clearFinalizedInput(inputIndex);
|
||||||
return true;
|
return this;
|
||||||
|
}
|
||||||
|
validateAllSignatures() {
|
||||||
|
utils_1.checkForInput(this.inputs, 0); // making sure we have at least one
|
||||||
|
const results = range(this.inputs.length).map(idx =>
|
||||||
|
this.validateSignatures(idx),
|
||||||
|
);
|
||||||
|
return results.reduce((final, res) => res === true && final, true);
|
||||||
}
|
}
|
||||||
validateSignatures(inputIndex, pubkey) {
|
validateSignatures(inputIndex, pubkey) {
|
||||||
const input = this.inputs[inputIndex];
|
const input = this.inputs[inputIndex];
|
||||||
|
@ -261,7 +265,7 @@ class Psbt extends bip174_1.Psbt {
|
||||||
// as input information is added, then eventually
|
// as input information is added, then eventually
|
||||||
// optimize this method.
|
// optimize this method.
|
||||||
const results = [];
|
const results = [];
|
||||||
for (const [i] of this.inputs.entries()) {
|
for (const i of range(this.inputs.length)) {
|
||||||
try {
|
try {
|
||||||
this.signInput(i, keyPair);
|
this.signInput(i, keyPair);
|
||||||
results.push(true);
|
results.push(true);
|
||||||
|
|
|
@ -225,26 +225,25 @@ describe('bitcoinjs-lib (transactions with psbt)', () => {
|
||||||
} = inputData
|
} = inputData
|
||||||
assert.deepStrictEqual({ hash, index, witnessUtxo, redeemScript }, inputData)
|
assert.deepStrictEqual({ hash, index, witnessUtxo, redeemScript }, inputData)
|
||||||
}
|
}
|
||||||
|
const keyPair = p2sh.keys[0]
|
||||||
|
const outputData = {
|
||||||
|
script: p2sh.payment.output, // sending to myself for fun
|
||||||
|
value: 2e4
|
||||||
|
}
|
||||||
|
|
||||||
const psbt = new bitcoin.Psbt({ network: regtest })
|
const tx = new bitcoin.Psbt()
|
||||||
.addInput(inputData)
|
.addInput(inputData)
|
||||||
.addOutput({
|
.addOutput(outputData)
|
||||||
address: regtestUtils.RANDOM_ADDRESS,
|
.sign(keyPair)
|
||||||
value: 2e4
|
.finalizeAllInputs()
|
||||||
})
|
.extractTransaction()
|
||||||
.signInput(0, p2sh.keys[0])
|
|
||||||
|
|
||||||
assert.strictEqual(psbt.validateSignatures(0), true)
|
|
||||||
psbt.finalizeAllInputs()
|
|
||||||
|
|
||||||
const tx = psbt.extractTransaction()
|
|
||||||
|
|
||||||
// build and broadcast to the Bitcoin RegTest network
|
// build and broadcast to the Bitcoin RegTest network
|
||||||
await regtestUtils.broadcast(tx.toHex())
|
await regtestUtils.broadcast(tx.toHex())
|
||||||
|
|
||||||
await regtestUtils.verify({
|
await regtestUtils.verify({
|
||||||
txId: tx.getId(),
|
txId: tx.getId(),
|
||||||
address: regtestUtils.RANDOM_ADDRESS,
|
address: p2sh.payment.address,
|
||||||
vout: 0,
|
vout: 0,
|
||||||
value: 2e4
|
value: 2e4
|
||||||
})
|
})
|
||||||
|
|
|
@ -233,31 +233,24 @@ export class Psbt extends PsbtBase {
|
||||||
return c.__FEE_RATE!;
|
return c.__FEE_RATE!;
|
||||||
}
|
}
|
||||||
|
|
||||||
finalizeAllInputs(): {
|
finalizeAllInputs(): this {
|
||||||
result: boolean;
|
checkForInput(this.inputs, 0); // making sure we have at least one
|
||||||
inputResults: boolean[];
|
range(this.inputs.length).forEach(idx => this.finalizeInput(idx));
|
||||||
} {
|
return this;
|
||||||
const inputResults = range(this.inputs.length).map(idx =>
|
|
||||||
this.finalizeInput(idx),
|
|
||||||
);
|
|
||||||
const result = inputResults.every(val => val === true);
|
|
||||||
return {
|
|
||||||
result,
|
|
||||||
inputResults,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
finalizeInput(inputIndex: number): boolean {
|
finalizeInput(inputIndex: number): this {
|
||||||
const input = checkForInput(this.inputs, inputIndex);
|
const input = checkForInput(this.inputs, inputIndex);
|
||||||
const { script, isP2SH, isP2WSH, isSegwit } = getScriptFromInput(
|
const { script, isP2SH, isP2WSH, isSegwit } = getScriptFromInput(
|
||||||
inputIndex,
|
inputIndex,
|
||||||
input,
|
input,
|
||||||
this.__CACHE,
|
this.__CACHE,
|
||||||
);
|
);
|
||||||
if (!script) return false;
|
if (!script) throw new Error(`No script found for input #${inputIndex}`);
|
||||||
|
|
||||||
const scriptType = classifyScript(script);
|
const scriptType = classifyScript(script);
|
||||||
if (!canFinalize(input, script, scriptType)) return false;
|
if (!canFinalize(input, script, scriptType))
|
||||||
|
throw new Error(`Can not finalize input #${inputIndex}`);
|
||||||
|
|
||||||
const { finalScriptSig, finalScriptWitness } = getFinalScripts(
|
const { finalScriptSig, finalScriptWitness } = getFinalScripts(
|
||||||
script,
|
script,
|
||||||
|
@ -272,10 +265,19 @@ export class Psbt extends PsbtBase {
|
||||||
this.addFinalScriptSigToInput(inputIndex, finalScriptSig);
|
this.addFinalScriptSigToInput(inputIndex, finalScriptSig);
|
||||||
if (finalScriptWitness)
|
if (finalScriptWitness)
|
||||||
this.addFinalScriptWitnessToInput(inputIndex, finalScriptWitness);
|
this.addFinalScriptWitnessToInput(inputIndex, finalScriptWitness);
|
||||||
if (!finalScriptSig && !finalScriptWitness) return false;
|
if (!finalScriptSig && !finalScriptWitness)
|
||||||
|
throw new Error(`Unknown error finalizing input #${inputIndex}`);
|
||||||
|
|
||||||
this.clearFinalizedInput(inputIndex);
|
this.clearFinalizedInput(inputIndex);
|
||||||
return true;
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
validateAllSignatures(): boolean {
|
||||||
|
checkForInput(this.inputs, 0); // making sure we have at least one
|
||||||
|
const results = range(this.inputs.length).map(idx =>
|
||||||
|
this.validateSignatures(idx),
|
||||||
|
);
|
||||||
|
return results.reduce((final, res) => res === true && final, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
validateSignatures(inputIndex: number, pubkey?: Buffer): boolean {
|
validateSignatures(inputIndex: number, pubkey?: Buffer): boolean {
|
||||||
|
@ -319,7 +321,7 @@ export class Psbt extends PsbtBase {
|
||||||
// as input information is added, then eventually
|
// as input information is added, then eventually
|
||||||
// optimize this method.
|
// optimize this method.
|
||||||
const results: boolean[] = [];
|
const results: boolean[] = [];
|
||||||
for (const [i] of this.inputs.entries()) {
|
for (const i of range(this.inputs.length)) {
|
||||||
try {
|
try {
|
||||||
this.signInput(i, keyPair);
|
this.signInput(i, keyPair);
|
||||||
results.push(true);
|
results.push(true);
|
||||||
|
|
8
types/psbt.d.ts
vendored
8
types/psbt.d.ts
vendored
|
@ -20,11 +20,9 @@ export declare class Psbt extends PsbtBase {
|
||||||
addNonWitnessUtxoToInput(inputIndex: number, nonWitnessUtxo: NonWitnessUtxo): this;
|
addNonWitnessUtxoToInput(inputIndex: number, nonWitnessUtxo: NonWitnessUtxo): this;
|
||||||
extractTransaction(disableFeeCheck?: boolean): Transaction;
|
extractTransaction(disableFeeCheck?: boolean): Transaction;
|
||||||
getFeeRate(): number;
|
getFeeRate(): number;
|
||||||
finalizeAllInputs(): {
|
finalizeAllInputs(): this;
|
||||||
result: boolean;
|
finalizeInput(inputIndex: number): this;
|
||||||
inputResults: boolean[];
|
validateAllSignatures(): boolean;
|
||||||
};
|
|
||||||
finalizeInput(inputIndex: number): boolean;
|
|
||||||
validateSignatures(inputIndex: number, pubkey?: Buffer): boolean;
|
validateSignatures(inputIndex: number, pubkey?: Buffer): boolean;
|
||||||
sign(keyPair: Signer): this;
|
sign(keyPair: Signer): this;
|
||||||
signAsync(keyPair: SignerAsync): Promise<void>;
|
signAsync(keyPair: SignerAsync): Promise<void>;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue