Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,17 @@ type V0TransactionMessage = Extract<TransactionMessage, { version: 0 }>;
TransactionMessageWithDurableNonceLifetime &
TransactionMessageWithFeePayer<'mockFeePayer'>;
}

// It can narrow the result by transaction version
{
type TransactionMessageNotLegacy = Exclude<TransactionMessage, { version: 'legacy' }>;

const message = null as unknown as TransactionMessage;
const messageWithFeePayer = setTransactionMessageFeePayer(mockFeePayer, message);
// @ts-expect-error Could be legacy
messageWithFeePayer satisfies TransactionMessageNotLegacy;
if (messageWithFeePayer.version === 0) {
messageWithFeePayer satisfies TransactionMessageNotLegacy;
}
}
}
15 changes: 7 additions & 8 deletions packages/transaction-messages/src/fee-payer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Address } from '@solana/addresses';

import { BaseTransactionMessage } from './transaction-message';
import { TransactionMessage } from './transaction-message';

/**
* Represents a transaction message for which a fee payer has been declared. A transaction must
Expand All @@ -13,10 +13,8 @@ export interface TransactionMessageWithFeePayer<TAddress extends string = string
/**
* A helper type to exclude the fee payer from a transaction message.
*/
type ExcludeTransactionMessageFeePayer<TTransactionMessage extends BaseTransactionMessage> = Omit<
TTransactionMessage,
'feePayer'
>;
type ExcludeTransactionMessageFeePayer<TTransactionMessage extends TransactionMessage> =
TTransactionMessage extends unknown ? Omit<TTransactionMessage, 'feePayer'> : never;

/**
* Given a base58-encoded address of a system account, this method will return a new transaction
Expand All @@ -34,7 +32,7 @@ type ExcludeTransactionMessageFeePayer<TTransactionMessage extends BaseTransacti
*/
export function setTransactionMessageFeePayer<
TFeePayerAddress extends string,
TTransactionMessage extends BaseTransactionMessage & Partial<TransactionMessageWithFeePayer>,
TTransactionMessage extends Partial<TransactionMessageWithFeePayer> & TransactionMessage,
>(
feePayer: Address<TFeePayerAddress>,
transactionMessage: TTransactionMessage,
Expand All @@ -44,15 +42,16 @@ export function setTransactionMessageFeePayer<
feePayer === transactionMessage.feePayer?.address &&
isAddressOnlyFeePayer(transactionMessage.feePayer)
) {
return transactionMessage as unknown as Omit<TTransactionMessage, 'feePayer'> &
return transactionMessage as ExcludeTransactionMessageFeePayer<TTransactionMessage> &
TransactionMessageWithFeePayer<TFeePayerAddress>;
}
const out = {
...transactionMessage,
feePayer: Object.freeze({ address: feePayer }),
};
Object.freeze(out);
return out;
return out as ExcludeTransactionMessageFeePayer<TTransactionMessage> &
TransactionMessageWithFeePayer<TFeePayerAddress>;
}

function isAddressOnlyFeePayer(
Expand Down