fix: narrow transaction message signer types#1851
Conversation
🦋 Changeset detectedLatest commit: 937db2a The changes in this PR will be included in the next version bump. This PR includes changesets to release 48 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
That's not a bad design. @mcintyre94 wdyt? |
mcintyre94
left a comment
There was a problem hiding this comment.
I think this looks good, definitely think it was a mistake to accept the other signer types here. Just a small suggestion to make the feePayer exclusion more future proof.
| feePayer: Readonly<{ | ||
| modifyAndSignTransactions?: never; | ||
| signAndSendTransactions?: never; | ||
| signTransactions?: never; | ||
| }> & | ||
| TransactionMessageWithFeePayer<TAddress>['feePayer']; |
There was a problem hiding this comment.
Something we might like to do here is to make this defensive against a future signer type, by deriving the methods of TransactionSigner. I think we could do something like this:
type UnionKeys<T> = T extends unknown ? keyof T : never;
type TransactionSignerMethodKeys = Exclude<UnionKeys<TransactionSigner>, 'address'>;
type WithoutSignerMethods = { readonly [K in TransactionSignerMethodKeys]?: never };
type TransactionMessageWithNonSignerFeePayer<TAddress extends string = string> = Readonly<{
feePayer: TransactionMessageWithFeePayer<TAddress>['feePayer'] & WithoutSignerMethods;
}>;
BundleMonUnchanged files (150)
Total files change +1B 0% Final result: ✅ View report in BundleMon website ➡️ |
Summary
Make
TransactionMessageWithSigners<TAddress, TSigner>enforce its signer type parameter for both fee payers and instruction account metas.Problem
Signer objects structurally satisfy the plain fee-payer and account-meta branches because their extra methods and
signerproperty do not make them incompatible. As a result, a transaction containing aTransactionModifyingSignercan satisfyTransactionMessageWithSigners<Address, TransactionPartialSigner>.Changes
@solana/signers.Testing
Before
The narrowed signer parameter can be bypassed through the plain structural union branches.
After
Mismatched fee-payer and instruction signers are rejected, while matching signers and plain non-signer account shapes remain accepted.
Related issue
Fixes #1036