diff --git a/packages/transactions/src/signer.ts b/packages/transactions/src/signer.ts index 9724bfb6b..47463af6b 100644 --- a/packages/transactions/src/signer.ts +++ b/packages/transactions/src/signer.ts @@ -1,6 +1,7 @@ import { StacksTransaction } from './transaction'; import { StacksPrivateKey, StacksPublicKey } from './keys'; import { + isNonSequentialMultiSig, isSequentialMultiSig, isSingleSig, nextVerification, @@ -38,16 +39,19 @@ export class TransactionSigner { } spendingCondition.fields.forEach(field => { - if (field.contents.type === StacksMessageType.MessageSignature) { - const signature = field.contents; - const nextVerify = nextVerification( - this.sigHash, - transaction.auth.authType, - spendingCondition.fee, - spendingCondition.nonce, - PubKeyEncoding.Compressed, // always compressed for multisig - signature - ); + if (field.contents.type !== StacksMessageType.MessageSignature) return; + + const signature = field.contents; + const nextVerify = nextVerification( + this.sigHash, + transaction.auth.authType, + spendingCondition.fee, + spendingCondition.nonce, + PubKeyEncoding.Compressed, // always compressed for multisig + signature + ); + + if (!isNonSequentialMultiSig(spendingCondition.hashMode)) { this.sigHash = nextVerify.nextSigHash; } }); diff --git a/packages/transactions/tests/builder.test.ts b/packages/transactions/tests/builder.test.ts index a70a612a2..cbf5cea2a 100644 --- a/packages/transactions/tests/builder.test.ts +++ b/packages/transactions/tests/builder.test.ts @@ -412,7 +412,9 @@ test('Make Multi-Sig STX token transfer', async () => { anchorMode: AnchorMode.Any, }); const signer = new TransactionSigner(transaction); + expect(signer.sigHash).toBe(transaction.signBegin()); signer.signOrigin(privKeys[0]); + expect(signer.sigHash).not.toBe(transaction.signBegin()); signer.signOrigin(privKeys[1]); signer.appendOrigin(pubKeys[2]); expect(() => transaction.verifyOrigin()).not.toThrow(); @@ -2629,12 +2631,18 @@ describe('multi-sig', () => { const signer = new TransactionSigner(tx); // sign in reverse order + expect(signer.sigHash).toBe(tx.signBegin()); signer.signOrigin(createStacksPrivateKey(pk3)); + expect(signer.sigHash).toBe(tx.signBegin()); signer.signOrigin(createStacksPrivateKey(pk2)); + expect(signer.sigHash).toBe(tx.signBegin()); signer.appendOrigin(getPublicKey(createStacksPrivateKey(pk1))); + expect(signer.sigHash).toBe(tx.signBegin()); if (isSingleSig(tx.auth.spendingCondition)) throw 'type error'; + expect(signer.sigHash).toBe(tx.signBegin()); // sighash doesn't change for non-sequential multisig + // todo: a `finalize` method would be nice to do this for us // we'll manually need to fix the order (for now) tx.auth.spendingCondition.fields.reverse();