-
Notifications
You must be signed in to change notification settings - Fork 125
Description
Overview
I'm looking into whether we can make the signTransactionMessageWithSigners method return an unmodified specific lifetime (instead of the looser TransactionWithLifetime) in cases where the signers in a transaction message are non-modifying
I think this can be accomplished with some clever overloads, making use of the TransactionMessageWithSigners<TAddress, TSigners> type. As documented, this should allow us to narrow the type of signers permitted in the transaction.
But there's currently a bug where this type does not actually narrow the allowed signers.
Steps to reproduce
import { Address } from "@solana/addresses";
import { pipe } from "@solana/functional";
import { TransactionMessageWithSigners, TransactionModifyingSigner, TransactionPartialSigner, setTransactionMessageFeePayerSigner } from "@solana/signers";
import { createTransactionMessage } from "@solana/transaction-messages";
{
const signer = null as unknown as TransactionModifyingSigner;
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }),
tx => setTransactionMessageFeePayerSigner(signer, tx),
)
// no type error
transactionMessage satisfies TransactionMessageWithSigners<Address, TransactionPartialSigner>;
}Description of bug
The issue is that the type is defined to allow eg a non-signer fee payer, or a signer fee payer. TransactionModifyingSigner satisfies {feePayer: Address} since the signer is a superset of the fee payer {address: Address}. This means that the type narrowing on TransactionMessageWithFeePayerSigner<TAddress, TSigner>> is not applied.
The same logic affects instructions, where an instruction with a TransactionModifyingSigner will satisfy the Instruction part of that check and again the narrowing is never applied.
If I'm understanding this correctly, the signer-related types in this function are never actually used currently, because the non-signer subsets are always satisfied by all signers.
We will need to define types like TransactionMessageWithNonSignerFeePayer that signers cannot match, so that the narrowed signer checks are applied when a signer is the fee payer/in an instruction.