solana-web3.js icon indicating copy to clipboard operation
solana-web3.js copied to clipboard

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

Open steveluscher opened this issue 1 year ago • 1 comments

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:

  • Loris(A)/Phantom, to
  • Loris(B)/NO_SIGNER

The Phantom feePayerSigner will still be on the message.

steveluscher avatar Jun 30 '24 19:06 steveluscher

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.

steveluscher avatar Jun 30 '24 19:06 steveluscher

@steveluscher I'm currently working on this and using a discriminator like __type: 'address' is problematic because it makes __type: 'signer' not compatible with the non-signer functions. Whatever we do here, we need the signer-specific feePayer type to be compatible with the base feePayer type.

My suggestion is to have the same but without the discriminator which will work because the signer object is compatible with { address: Address } and signer functions can be used as discriminators (which they already are).

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

lorisleiva avatar Oct 28 '24 11:10 lorisleiva

Because there has been no activity on this issue for 7 days since it was closed, it has been automatically locked. Please open a new issue if it requires a follow up.

github-actions[bot] avatar Nov 07 '24 08:11 github-actions[bot]