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 @@ -15,14 +15,16 @@ import {
prependTransactionMessageInstruction,
prependTransactionMessageInstructions,
} from '../instructions';
import { BaseTransactionMessage } from '../transaction-message';
import { BaseTransactionMessage, TransactionMessage } from '../transaction-message';
import { TransactionMessageWithinSizeLimit } from '../transaction-message-size';

type Instruction = BaseTransactionMessage['instructions'][number];
type InstructionA = Instruction & { identifier: 'A' };
type InstructionB = Instruction & { identifier: 'B' };
type InstructionC = Instruction & { identifier: 'C' };

type TransactionMessageNotLegacy = Exclude<TransactionMessage, { version: 'legacy' }>;

// [DESCRIBE] appendTransactionMessageInstruction
{
// It returns the same TransactionMessage type
Expand Down Expand Up @@ -91,6 +93,17 @@ type InstructionC = Instruction & { identifier: 'C' };
// @ts-expect-error Potentially no longer within size limit.
newMessage satisfies TransactionMessageWithinSizeLimit;
}

// It can narrow the version type
{
const message = null as unknown as TransactionMessage;
const newMessage = appendTransactionMessageInstruction(null as unknown as Instruction, message);
// @ts-expect-error Could be legacy
newMessage satisfies TransactionMessageNotLegacy;
if (newMessage.version === 0) {
newMessage satisfies TransactionMessageNotLegacy;
}
}
}

// [DESCRIBE] appendTransactionMessageInstructions
Expand Down Expand Up @@ -133,6 +146,17 @@ type InstructionC = Instruction & { identifier: 'C' };
// @ts-expect-error Potentially no longer within size limit.
newMessage satisfies TransactionMessageWithinSizeLimit;
}

// It can narrow the version type
{
const message = null as unknown as TransactionMessage;
const newMessage = appendTransactionMessageInstructions([null as unknown as Instruction], message);
// @ts-expect-error Could be legacy
newMessage satisfies TransactionMessageNotLegacy;
if (newMessage.version === 0) {
newMessage satisfies TransactionMessageNotLegacy;
}
}
}

// [DESCRIBE] prependTransactionMessageInstruction
Expand Down Expand Up @@ -221,6 +245,17 @@ type InstructionC = Instruction & { identifier: 'C' };
// @ts-expect-error Potentially no longer within size limit.
newMessage satisfies TransactionMessageWithinSizeLimit;
}

// It can narrow the version type
{
const message = null as unknown as TransactionMessage;
const newMessage = prependTransactionMessageInstruction(null as unknown as Instruction, message);
// @ts-expect-error Could be legacy
newMessage satisfies TransactionMessageNotLegacy;
if (newMessage.version === 0) {
newMessage satisfies TransactionMessageNotLegacy;
}
}
}

// [DESCRIBE] prependTransactionMessageInstructions
Expand Down Expand Up @@ -273,4 +308,15 @@ type InstructionC = Instruction & { identifier: 'C' };
// @ts-expect-error Potentially no longer within size limit.
newMessage satisfies TransactionMessageWithinSizeLimit;
}

// It can narrow the version type
{
const message = null as unknown as TransactionMessage;
const newMessage = prependTransactionMessageInstructions([null as unknown as Instruction], message);
// @ts-expect-error Could be legacy
newMessage satisfies TransactionMessageNotLegacy;
if (newMessage.version === 0) {
newMessage satisfies TransactionMessageNotLegacy;
}
}
}
40 changes: 22 additions & 18 deletions packages/transaction-messages/src/instructions.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,37 @@
import { Instruction } from '@solana/instructions';

import { ExcludeTransactionMessageDurableNonceLifetime } from './durable-nonce';
import { BaseTransactionMessage } from './transaction-message';
import { TransactionMessage } from './transaction-message';
import { ExcludeTransactionMessageWithinSizeLimit } from './transaction-message-size';

/**
* A helper type to append instructions to a transaction message
* without losing type information about the current instructions.
*/
type AppendTransactionMessageInstructions<
TTransactionMessage extends BaseTransactionMessage,
TTransactionMessage extends TransactionMessage,
TInstructions extends readonly Instruction[],
> = Omit<ExcludeTransactionMessageWithinSizeLimit<TTransactionMessage>, 'instructions'> & {
readonly instructions: readonly [...TTransactionMessage['instructions'], ...TInstructions];
};
> = TTransactionMessage extends TransactionMessage
? Omit<ExcludeTransactionMessageWithinSizeLimit<TTransactionMessage>, 'instructions'> & {
readonly instructions: readonly [...TTransactionMessage['instructions'], ...TInstructions];
}
: never;

/**
* A helper type to prepend instructions to a transaction message
* without losing type information about the current instructions.
*/
type PrependTransactionMessageInstructions<
TTransactionMessage extends BaseTransactionMessage,
TTransactionMessage extends TransactionMessage,
TInstructions extends readonly Instruction[],
> = Omit<
ExcludeTransactionMessageWithinSizeLimit<ExcludeTransactionMessageDurableNonceLifetime<TTransactionMessage>>,
'instructions'
> & {
readonly instructions: readonly [...TInstructions, ...TTransactionMessage['instructions']];
};
> = TTransactionMessage extends TransactionMessage
? Omit<
ExcludeTransactionMessageWithinSizeLimit<ExcludeTransactionMessageDurableNonceLifetime<TTransactionMessage>>,
'instructions'
> & {
readonly instructions: readonly [...TInstructions, ...TTransactionMessage['instructions']];
}
: never;

/**
* Given an instruction, this method will return a new transaction message with that instruction
Expand All @@ -52,7 +56,7 @@ type PrependTransactionMessageInstructions<
* ```
*/
export function appendTransactionMessageInstruction<
TTransactionMessage extends BaseTransactionMessage,
TTransactionMessage extends TransactionMessage,
TInstruction extends Instruction,
>(
instruction: TInstruction,
Expand Down Expand Up @@ -89,7 +93,7 @@ export function appendTransactionMessageInstruction<
* ```
*/
export function appendTransactionMessageInstructions<
TTransactionMessage extends BaseTransactionMessage,
TTransactionMessage extends TransactionMessage,
const TInstructions extends readonly Instruction[],
>(
instructions: TInstructions,
Expand All @@ -101,7 +105,7 @@ export function appendTransactionMessageInstructions<
...(transactionMessage.instructions as TTransactionMessage['instructions']),
...instructions,
] as readonly [...TTransactionMessage['instructions'], ...TInstructions]),
});
}) as AppendTransactionMessageInstructions<TTransactionMessage, TInstructions>;
}

/**
Expand All @@ -126,7 +130,7 @@ export function appendTransactionMessageInstructions<
* ```
*/
export function prependTransactionMessageInstruction<
TTransactionMessage extends BaseTransactionMessage,
TTransactionMessage extends TransactionMessage,
TInstruction extends Instruction,
>(
instruction: TInstruction,
Expand Down Expand Up @@ -163,7 +167,7 @@ export function prependTransactionMessageInstruction<
* ```
*/
export function prependTransactionMessageInstructions<
TTransactionMessage extends BaseTransactionMessage,
TTransactionMessage extends TransactionMessage,
const TInstructions extends readonly Instruction[],
>(
instructions: TInstructions,
Expand All @@ -175,5 +179,5 @@ export function prependTransactionMessageInstructions<
...instructions,
...(transactionMessage.instructions as TTransactionMessage['instructions']),
] as readonly [...TInstructions, ...TTransactionMessage['instructions']]),
});
}) as unknown as PrependTransactionMessageInstructions<TTransactionMessage, TInstructions>;
}
Loading