Skip to content

Commit cec9048

Browse files
authored
refactor(experimental): assert single sending signer inside signAndSend function (#2852)
Fixes #2818 This PR calls the `assertIsTransactionMessageWithSingleSendingSigner` inside the `signAndSendTransactionMessageWithSigners` so the end-user doesn't need to do it explicitly. This is partly to improve the developer experience and partly because TS doesn't fail properly when the transaction message hasn't been asserted on prior to calling the sign and send function. Note that I did not remove the `assertIsTransactionMessageWithSingleSendingSigner` and the `isTransactionMessageWithSingleSendingSigner` from the package's exports since they may still be useful for custom use-cases such as the one described in the documentation: ```ts let transactionSignature: SignatureBytes; if (isTransactionMessageWithSingleSendingSigner(transaction)) { transactionSignature = await signAndSendTransactionMessageWithSigners(transaction); } else { const signedTransaction = await signTransactionMessageWithSigners(transaction); const encodedTransaction = getBase64EncodedWireTransaction(signedTransaction); transactionSignature = await rpc.sendTransaction(encodedTransaction).send(); } ```
1 parent 53b60c9 commit cec9048

File tree

3 files changed

+11
-6
lines changed

3 files changed

+11
-6
lines changed

.changeset/short-jokes-begin.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@solana/signers': patch
3+
---
4+
5+
The `signAndSendTransactionMessageWithSigners` function now automatically asserts that the provided transaction message contains a single sending signer and fails otherwise.

packages/signers/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -549,9 +549,9 @@ Here as well, composite transaction signers are treated such that at least one s
549549
- `TransactionModifyingSigner`, if no other `TransactionModifyingSigner` exists.
550550
- `TransactionPartialSigner`, otherwise.
551551

552-
The provided transaction must be of type `ITransactionWithSingleSendingSigner` meaning that it must contain exactly one `TransactionSendingSigner` inside its account metas. If more than one composite signers implement the `TransactionSendingSigner` interface, one of them will be selected as the sending signer.
552+
The provided transaction must contain exactly one `TransactionSendingSigner` inside its account metas. If more than one composite signers implement the `TransactionSendingSigner` interface, one of them will be selected as the sending signer. Otherwise, if multiple `TransactionSendingSigners` must be selected, the function will throw an error.
553553

554-
Therefore, you may use the `assertIsTransactionWithSingleSendingSigner()` function to ensure the transaction is of the expected type.
554+
If you'd like to assert that a transaction makes use of exactly one `TransactionSendingSigner` _before_ calling this function, you may use the `assertIsTransactionWithSingleSendingSigner` function.
555555

556556
```ts
557557
assertIsTransactionWithSingleSendingSigner(myTransaction);

packages/signers/src/sign-transaction.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { isTransactionModifyingSigner, TransactionModifyingSigner } from './tran
2121
import { isTransactionPartialSigner, TransactionPartialSigner } from './transaction-partial-signer';
2222
import { isTransactionSendingSigner, TransactionSendingSigner } from './transaction-sending-signer';
2323
import { isTransactionSigner, TransactionSigner } from './transaction-signer';
24-
import { ITransactionMessageWithSingleSendingSigner } from './transaction-with-single-sending-signer';
24+
import { assertIsTransactionMessageWithSingleSendingSigner } from './transaction-with-single-sending-signer';
2525

2626
type CompilableTransactionMessageWithSigners = CompilableTransactionMessage & ITransactionMessageWithSigners;
2727

@@ -123,10 +123,10 @@ export async function signTransactionMessageWithSigners<
123123
* Otherwise, it will send the transaction using the provided fallbackSender.
124124
*/
125125
export async function signAndSendTransactionMessageWithSigners<
126-
TTransactionMessage extends CompilableTransactionMessageWithSigners &
127-
ITransactionMessageWithSingleSendingSigner = CompilableTransactionMessageWithSigners &
128-
ITransactionMessageWithSingleSendingSigner,
126+
TTransactionMessage extends CompilableTransactionMessageWithSigners = CompilableTransactionMessageWithSigners,
129127
>(transaction: TTransactionMessage, config: { abortSignal?: AbortSignal } = {}): Promise<SignatureBytes> {
128+
assertIsTransactionMessageWithSingleSendingSigner(transaction);
129+
130130
const abortSignal = config.abortSignal;
131131
const { partialSigners, modifyingSigners, sendingSigner } = categorizeTransactionSigners(
132132
deduplicateSigners(getSignersFromTransactionMessage(transaction).filter(isTransactionSigner)),

0 commit comments

Comments
 (0)