Skip to content

Commit 65d7603

Browse files
junderwpluswave
andcommitted
Fix signInputAsync when SignerAsync rejects
Co-authored-by: Zhang Zengbo <[email protected]>
1 parent 9e2a8fe commit 65d7603

File tree

3 files changed

+91
-40
lines changed

3 files changed

+91
-40
lines changed

src/psbt.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -488,25 +488,24 @@ class Psbt {
488488
keyPair,
489489
sighashTypes = [transaction_1.Transaction.SIGHASH_ALL],
490490
) {
491-
return new Promise((resolve, reject) => {
491+
return Promise.resolve().then(() => {
492492
if (!keyPair || !keyPair.publicKey)
493-
return reject(new Error('Need Signer to sign input'));
493+
throw new Error('Need Signer to sign input');
494494
const { hash, sighashType } = getHashAndSighashType(
495495
this.data.inputs,
496496
inputIndex,
497497
keyPair.publicKey,
498498
this.__CACHE,
499499
sighashTypes,
500500
);
501-
Promise.resolve(keyPair.sign(hash)).then(signature => {
501+
return Promise.resolve(keyPair.sign(hash)).then(signature => {
502502
const partialSig = [
503503
{
504504
pubkey: keyPair.publicKey,
505505
signature: bscript.signature.encode(signature, sighashType),
506506
},
507507
];
508508
this.data.updateInput(inputIndex, { partialSig });
509-
resolve();
510509
});
511510
});
512511
}

test/psbt.spec.ts

Lines changed: 68 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
import * as assert from 'assert';
22
import { describe, it } from 'mocha';
33

4-
import { bip32, ECPair, networks as NETWORKS, Psbt } from '..';
4+
import {
5+
bip32,
6+
ECPair,
7+
networks as NETWORKS,
8+
Psbt,
9+
Signer,
10+
SignerAsync,
11+
} from '..';
512

613
import * as preFixtures from './fixtures/psbt.json';
714

@@ -22,6 +29,40 @@ const fixtures = initBuffers(preFixtures);
2229
const upperCaseFirstLetter = (str: string): string =>
2330
str.replace(/^./, s => s.toUpperCase());
2431

32+
const toAsyncSigner = (signer: Signer): SignerAsync => {
33+
const ret: SignerAsync = {
34+
publicKey: signer.publicKey,
35+
sign: (hash: Buffer, lowerR: boolean | undefined): Promise<Buffer> => {
36+
return new Promise(
37+
(resolve, rejects): void => {
38+
setTimeout(() => {
39+
try {
40+
const r = signer.sign(hash, lowerR);
41+
resolve(r);
42+
} catch (e) {
43+
rejects(e);
44+
}
45+
}, 10);
46+
},
47+
);
48+
},
49+
};
50+
return ret;
51+
};
52+
const failedAsyncSigner = (publicKey: Buffer): SignerAsync => {
53+
return {
54+
publicKey,
55+
sign: (__: Buffer): Promise<Buffer> => {
56+
return new Promise(
57+
(_, reject): void => {
58+
setTimeout(() => {
59+
reject(new Error('sign failed'));
60+
}, 10);
61+
},
62+
);
63+
},
64+
};
65+
};
2566
// const b = (hex: string) => Buffer.from(hex, 'hex');
2667

2768
describe(`Psbt`, () => {
@@ -164,25 +205,39 @@ describe(`Psbt`, () => {
164205
it(f.description, async () => {
165206
if (f.shouldSign) {
166207
const psbtThatShouldsign = Psbt.fromBase64(f.shouldSign.psbt);
167-
assert.doesNotReject(async () => {
208+
await assert.doesNotReject(async () => {
168209
await psbtThatShouldsign.signInputAsync(
169210
f.shouldSign.inputToCheck,
170211
ECPair.fromWIF(f.shouldSign.WIF),
171212
f.shouldSign.sighashTypes || undefined,
172213
);
173214
});
215+
await assert.rejects(async () => {
216+
await psbtThatShouldsign.signInputAsync(
217+
f.shouldSign.inputToCheck,
218+
failedAsyncSigner(ECPair.fromWIF(f.shouldSign.WIF).publicKey),
219+
f.shouldSign.sighashTypes || undefined,
220+
);
221+
}, /sign failed/);
174222
}
175223

176224
if (f.shouldThrow) {
177225
const psbtThatShouldThrow = Psbt.fromBase64(f.shouldThrow.psbt);
178-
assert.rejects(async () => {
226+
await assert.rejects(async () => {
179227
await psbtThatShouldThrow.signInputAsync(
180228
f.shouldThrow.inputToCheck,
181229
ECPair.fromWIF(f.shouldThrow.WIF),
182230
(f.shouldThrow as any).sighashTypes || undefined,
183231
);
184232
}, new RegExp(f.shouldThrow.errorMessage));
185-
assert.rejects(async () => {
233+
await assert.rejects(async () => {
234+
await psbtThatShouldThrow.signInputAsync(
235+
f.shouldThrow.inputToCheck,
236+
toAsyncSigner(ECPair.fromWIF(f.shouldThrow.WIF)),
237+
(f.shouldThrow as any).sighashTypes || undefined,
238+
);
239+
}, new RegExp(f.shouldThrow.errorMessage));
240+
await assert.rejects(async () => {
186241
await (psbtThatShouldThrow.signInputAsync as any)(
187242
f.shouldThrow.inputToCheck,
188243
);
@@ -229,7 +284,7 @@ describe(`Psbt`, () => {
229284
it(f.description, async () => {
230285
if (f.shouldSign) {
231286
const psbtThatShouldsign = Psbt.fromBase64(f.shouldSign.psbt);
232-
assert.doesNotReject(async () => {
287+
await assert.doesNotReject(async () => {
233288
await psbtThatShouldsign.signAllInputsAsync(
234289
ECPair.fromWIF(f.shouldSign.WIF),
235290
f.shouldSign.sighashTypes || undefined,
@@ -239,13 +294,13 @@ describe(`Psbt`, () => {
239294

240295
if (f.shouldThrow) {
241296
const psbtThatShouldThrow = Psbt.fromBase64(f.shouldThrow.psbt);
242-
assert.rejects(async () => {
297+
await assert.rejects(async () => {
243298
await psbtThatShouldThrow.signAllInputsAsync(
244299
ECPair.fromWIF(f.shouldThrow.WIF),
245300
(f.shouldThrow as any).sighashTypes || undefined,
246301
);
247302
}, new RegExp('No inputs were signed'));
248-
assert.rejects(async () => {
303+
await assert.rejects(async () => {
249304
await (psbtThatShouldThrow.signAllInputsAsync as any)();
250305
}, new RegExp('Need Signer to sign input'));
251306
}
@@ -288,7 +343,7 @@ describe(`Psbt`, () => {
288343
it(f.description, async () => {
289344
if (f.shouldSign) {
290345
const psbtThatShouldsign = Psbt.fromBase64(f.shouldSign.psbt);
291-
assert.doesNotReject(async () => {
346+
await assert.doesNotReject(async () => {
292347
await psbtThatShouldsign.signInputHDAsync(
293348
f.shouldSign.inputToCheck,
294349
bip32.fromBase58(f.shouldSign.xprv),
@@ -299,14 +354,14 @@ describe(`Psbt`, () => {
299354

300355
if (f.shouldThrow) {
301356
const psbtThatShouldThrow = Psbt.fromBase64(f.shouldThrow.psbt);
302-
assert.rejects(async () => {
357+
await assert.rejects(async () => {
303358
await psbtThatShouldThrow.signInputHDAsync(
304359
f.shouldThrow.inputToCheck,
305360
bip32.fromBase58(f.shouldThrow.xprv),
306361
(f.shouldThrow as any).sighashTypes || undefined,
307362
);
308363
}, new RegExp(f.shouldThrow.errorMessage));
309-
assert.rejects(async () => {
364+
await assert.rejects(async () => {
310365
await (psbtThatShouldThrow.signInputHDAsync as any)(
311366
f.shouldThrow.inputToCheck,
312367
);
@@ -354,7 +409,7 @@ describe(`Psbt`, () => {
354409
it(f.description, async () => {
355410
if (f.shouldSign) {
356411
const psbtThatShouldsign = Psbt.fromBase64(f.shouldSign.psbt);
357-
assert.doesNotReject(async () => {
412+
await assert.doesNotReject(async () => {
358413
await psbtThatShouldsign.signAllInputsHDAsync(
359414
bip32.fromBase58(f.shouldSign.xprv),
360415
(f.shouldSign as any).sighashTypes || undefined,
@@ -364,13 +419,13 @@ describe(`Psbt`, () => {
364419

365420
if (f.shouldThrow) {
366421
const psbtThatShouldThrow = Psbt.fromBase64(f.shouldThrow.psbt);
367-
assert.rejects(async () => {
422+
await assert.rejects(async () => {
368423
await psbtThatShouldThrow.signAllInputsHDAsync(
369424
bip32.fromBase58(f.shouldThrow.xprv),
370425
(f.shouldThrow as any).sighashTypes || undefined,
371426
);
372427
}, new RegExp('No inputs were signed'));
373-
assert.rejects(async () => {
428+
await assert.rejects(async () => {
374429
await (psbtThatShouldThrow.signAllInputsHDAsync as any)();
375430
}, new RegExp('Need HDSigner to sign input'));
376431
}

ts_src/psbt.ts

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -580,31 +580,28 @@ export class Psbt {
580580
keyPair: Signer | SignerAsync,
581581
sighashTypes: number[] = [Transaction.SIGHASH_ALL],
582582
): Promise<void> {
583-
return new Promise(
584-
(resolve, reject): void => {
585-
if (!keyPair || !keyPair.publicKey)
586-
return reject(new Error('Need Signer to sign input'));
587-
const { hash, sighashType } = getHashAndSighashType(
588-
this.data.inputs,
589-
inputIndex,
590-
keyPair.publicKey,
591-
this.__CACHE,
592-
sighashTypes,
593-
);
583+
return Promise.resolve().then(() => {
584+
if (!keyPair || !keyPair.publicKey)
585+
throw new Error('Need Signer to sign input');
586+
const { hash, sighashType } = getHashAndSighashType(
587+
this.data.inputs,
588+
inputIndex,
589+
keyPair.publicKey,
590+
this.__CACHE,
591+
sighashTypes,
592+
);
594593

595-
Promise.resolve(keyPair.sign(hash)).then(signature => {
596-
const partialSig = [
597-
{
598-
pubkey: keyPair.publicKey,
599-
signature: bscript.signature.encode(signature, sighashType),
600-
},
601-
];
594+
return Promise.resolve(keyPair.sign(hash)).then(signature => {
595+
const partialSig = [
596+
{
597+
pubkey: keyPair.publicKey,
598+
signature: bscript.signature.encode(signature, sighashType),
599+
},
600+
];
602601

603-
this.data.updateInput(inputIndex, { partialSig });
604-
resolve();
605-
});
606-
},
607-
);
602+
this.data.updateInput(inputIndex, { partialSig });
603+
});
604+
});
608605
}
609606

610607
toBuffer(): Buffer {

0 commit comments

Comments
 (0)