Add sign all inputs method

This commit is contained in:
junderw 2019-07-08 16:30:59 +09:00
parent d0d94c7f06
commit f66b568e4d
No known key found for this signature in database
GPG key ID: B256185D3A971908
4 changed files with 113 additions and 2 deletions

View file

@ -338,6 +338,55 @@ class Psbt extends bip174_1.Psbt {
}
return results.every(res => res === true);
}
sign(keyPair) {
if (!keyPair || !keyPair.publicKey)
throw new Error('Need Signer to sign input');
// TODO: Add a pubkey/pubkeyhash cache to each input
// as input information is added, then eventually
// optimize this method.
const results = [];
for (const [i] of this.inputs.entries()) {
try {
this.signInput(i, keyPair);
results.push(true);
} catch (err) {
results.push(false);
}
}
if (results.every(v => v === false)) {
throw new Error('No inputs were signed');
}
return this;
}
signAsync(keyPair) {
return new Promise((resolve, reject) => {
if (!keyPair || !keyPair.publicKey)
return reject(new Error('Need Signer to sign input'));
// TODO: Add a pubkey/pubkeyhash cache to each input
// as input information is added, then eventually
// optimize this method.
const results = [];
const promises = [];
for (const [i] of this.inputs.entries()) {
promises.push(
this.signInputAsync(i, keyPair).then(
() => {
results.push(true);
},
() => {
results.push(false);
},
),
);
}
return Promise.all(promises).then(() => {
if (results.every(v => v === false)) {
return reject(new Error('No inputs were signed'));
}
resolve();
});
});
}
signInput(inputIndex, keyPair) {
if (!keyPair || !keyPair.publicKey)
throw new Error('Need Signer to sign input');

View file

@ -110,8 +110,13 @@ describe('bitcoinjs-lib (transactions with psbt)', () => {
const signer2 = bitcoin.Psbt.fromBase64(psbtBaseText)
// Alice signs each input with the respective private keys
signer1.signInput(0, alice1.keys[0])
signer2.signInput(1, alice2.keys[0])
// signInput and signInputAsync are better
// (They take the input index explicitly as the first arg)
signer1.sign(alice1.keys[0])
signer2.sign(alice2.keys[0])
// If your signer object's sign method returns a promise, use the following
// await signer2.signAsync(alice2.keys[0])
// encode to send back to combiner (signer 1 and 2 are not near each other)
const s1text = signer1.toBase64()

View file

@ -405,6 +405,61 @@ export class Psbt extends PsbtBase {
return results.every(res => res === true);
}
sign(keyPair: Signer): this {
if (!keyPair || !keyPair.publicKey)
throw new Error('Need Signer to sign input');
// TODO: Add a pubkey/pubkeyhash cache to each input
// as input information is added, then eventually
// optimize this method.
const results: boolean[] = [];
for (const [i] of this.inputs.entries()) {
try {
this.signInput(i, keyPair);
results.push(true);
} catch (err) {
results.push(false);
}
}
if (results.every(v => v === false)) {
throw new Error('No inputs were signed');
}
return this;
}
signAsync(keyPair: SignerAsync): Promise<void> {
return new Promise(
(resolve, reject): any => {
if (!keyPair || !keyPair.publicKey)
return reject(new Error('Need Signer to sign input'));
// TODO: Add a pubkey/pubkeyhash cache to each input
// as input information is added, then eventually
// optimize this method.
const results: boolean[] = [];
const promises: Array<Promise<void>> = [];
for (const [i] of this.inputs.entries()) {
promises.push(
this.signInputAsync(i, keyPair).then(
() => {
results.push(true);
},
() => {
results.push(false);
},
),
);
}
return Promise.all(promises).then(() => {
if (results.every(v => v === false)) {
return reject(new Error('No inputs were signed'));
}
resolve();
});
},
);
}
signInput(inputIndex: number, keyPair: Signer): this {
if (!keyPair || !keyPair.publicKey)
throw new Error('Need Signer to sign input');

2
types/psbt.d.ts vendored
View file

@ -30,6 +30,8 @@ export declare class Psbt extends PsbtBase {
};
finalizeInput(inputIndex: number): boolean;
validateSignatures(inputIndex: number, pubkey?: Buffer): boolean;
sign(keyPair: Signer): this;
signAsync(keyPair: SignerAsync): Promise<void>;
signInput(inputIndex: number, keyPair: Signer): this;
signInputAsync(inputIndex: number, keyPair: SignerAsync): Promise<void>;
}