diff --git a/packages/signers/src/__tests__/sign-transaction-test.ts b/packages/signers/src/__tests__/sign-transaction-test.ts index 30ee4cfcabc1..c341baedadbd 100644 --- a/packages/signers/src/__tests__/sign-transaction-test.ts +++ b/packages/signers/src/__tests__/sign-transaction-test.ts @@ -331,7 +331,7 @@ describe('signTransactionWithSigners', () => { // Then we expect an error letting us know the transaction is not fully signed. // This is because sending signers are ignored by signTransactionWithSigners. - await expect(promise).rejects.toThrow('Transaction is missing signature for address `2222`'); + await expect(promise).rejects.toThrow('Transaction is missing signatures for addresses: 2222'); }); it('can be cancelled using an AbortSignal', async () => { diff --git a/packages/transactions/src/__tests__/signatures-test.ts b/packages/transactions/src/__tests__/signatures-test.ts index 00bebaf8735c..4419202161d1 100644 --- a/packages/transactions/src/__tests__/signatures-test.ts +++ b/packages/transactions/src/__tests__/signatures-test.ts @@ -279,7 +279,7 @@ describe('signTransaction', () => { expect.assertions(1); const signedTransactionPromise = signTransaction([mockKeyPairA], MOCK_TRANSACTION); await expect(signedTransactionPromise).rejects.toThrow( - `Transaction is missing signature for address \`${mockPublicKeyAddressB}\``, + `Transaction is missing signatures for addresses: ${mockPublicKeyAddressB}`, ); }); it('returns a transaction object having multiple signatures', async () => { @@ -368,7 +368,26 @@ describe('assertTransactionIsFullySigned', () => { }; expect(() => assertTransactionIsFullySigned(transaction)).toThrow( - 'Transaction is missing signature for address `A`', + 'Transaction is missing signatures for addresses: A', + ); + }); + + it('throws all missing signers if the transaction has no signature for multiple signers', () => { + const transaction: SignedTransaction = { + feePayer: mockPublicKeyAddressA, + instructions: [ + { + accounts: [{ address: mockPublicKeyAddressB, role: AccountRole.READONLY_SIGNER }], + programAddress: '11111111111111111111111111111111' as Address<'11111111111111111111111111111111'>, + }, + ], + lifetimeConstraint: mockBlockhashConstraint, + signatures: {}, + version: 0, + }; + + expect(() => assertTransactionIsFullySigned(transaction)).toThrow( + 'Transaction is missing signatures for addresses: A, B', ); }); @@ -394,7 +413,7 @@ describe('assertTransactionIsFullySigned', () => { }; expect(() => assertTransactionIsFullySigned(transaction)).toThrow( - 'Transaction is missing signature for address `B`', + 'Transaction is missing signatures for addresses: B', ); }); @@ -420,7 +439,7 @@ describe('assertTransactionIsFullySigned', () => { }; expect(() => assertTransactionIsFullySigned(transaction)).toThrow( - 'Transaction is missing signature for address `B`', + 'Transaction is missing signatures for addresses: B', ); }); @@ -456,7 +475,7 @@ describe('assertTransactionIsFullySigned', () => { }; expect(() => assertTransactionIsFullySigned(transaction)).toThrow( - 'Transaction is missing signature for address `C`', + 'Transaction is missing signatures for addresses: C', ); }); diff --git a/packages/transactions/src/signatures.ts b/packages/transactions/src/signatures.ts index e34bbfcfbdf9..ef6d00419dfe 100644 --- a/packages/transactions/src/signatures.ts +++ b/packages/transactions/src/signatures.ts @@ -77,10 +77,15 @@ export function assertTransactionIsFullySigned a.address); const requiredSigners = new Set([transaction.feePayer, ...signerAddressesFromInstructions]); + const missingSigs: Address[] = []; requiredSigners.forEach(address => { if (!transaction.signatures[address]) { - // TODO coded error - throw new Error(`Transaction is missing signature for address \`${address}\``); + missingSigs.push(address); } }); + + if (missingSigs.length > 0) { + // TODO coded error + throw new Error('Transaction is missing signatures for addresses: ' + missingSigs.join(', ')); + } }