solana-labs / solana-web3.js

Solana JavaScript SDK
https://solana-labs.github.io/solana-web3.js
MIT License
1.97k stars 791 forks source link

`setTransactionMessageFeePayer()` does not delete signer if one is present. #2899

Open steveluscher opened 4 days ago

steveluscher commented 4 days ago

Overview

Presume that you have a TransactionMessage with a feePayerSigner. If the fee payer address changes, setTransactionMessageFeePayer() won't blank out the pre-existing feePayerSigner.

Description of bug

This may cause problems if I go from:

The Phantom feePayerSigner will still be on the message.

steveluscher commented 4 days ago

We could fix this once and for all by making feePayer a discriminated union.

export interface ITransactionMessageWithFeePayer<TAddress extends string = string> {
    readonly feePayer: Readonly<{__type: 'address', address: Address<TAddress>}>;
}
export interface ITransactionMessageWithFeePayerSigner<
    TAddress extends string = string,
    TSigner extends TransactionSigner<TAddress> = TransactionSigner<TAddress>,
> {
    readonly feePayer: Readonly<{__type: 'signer'}> & TSigner;
}

That would be a whole bunch of surgery, but we'd end up with something that always had address on it as we have now, no matter if it was a signer or not, and the decision of whether to overwrite it could involve checking that the two __type properties match.