8000 Refactor transaction message type tests by lorisleiva · Pull Request #428 · anza-xyz/kit · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Refactor transaction message type tests #428

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
@@ -0,0 +1,70 @@
import { Blockhash } from '@solana/rpc-types';

import {
assertIsTransactionMessageWithBlockhashLifetime,
isTransactionMessageWithBlockhashLifetime,
setTransactionMessageLifetimeUsingBlockhash,
TransactionMessageWithBlockhashLifetime,
} from '../blockhash';
import { BaseTransactionMessage, TransactionMessage } from '../transaction-message';

const mockBlockhash = null as unknown as Blockhash;
const mockBlockhashLifetime = { blockhash: mockBlockhash, lastValidBlockHeight: 0n };

type LegacyTransactionMessage = Extract<TransactionMessage, { version: 'legacy' }>;
type V0TransactionMessage = Extract<TransactionMessage, { version: 0 }>;

// [DESCRIBE] isTransactionMessageWithBlockhashLifetime
{
// It narrows the transaction message type to one with a blockhash-based lifetime.
{
const message = null as unknown as BaseTransactionMessage & { some: 1 };
if (isTransactionMessageWithBlockhashLifetime(message)) {
message satisfies BaseTransactionMessage & TransactionMessageWithBlockhashLifetime & { some: 1 };
} else {
message satisfies BaseTransactionMessage & { some: 1 };
// @ts-expect-error It does not have a blockhash-based lifetime.
message satisfies TransactionMessageWithBlockhashLifetime;
}
}
}

// [DESCRIBE] assertIsTransactionMessageWithBlockhashLifetime
{
// It narrows the transaction message type to one with a blockhash-based lifetime.
{
const message = null as unknown as BaseTransactionMessage & { some: 1 };
// @ts-expect-error Should not be blockhash lifetime
message satisfies TransactionMessageWithBlockhashLifetime;
// @ts-expect-error Should not satisfy has blockhash
message satisfies { lifetimeConstraint: { blockhash: Blockhash } };
// @ts-expect-error Should not satisfy has lastValidBlockHeight
message satisfies { lifetimeConstraint: { lastValidBlockHeight: bigint } };
assertIsTransactionMessageWithBlockhashLifetime(message);
message satisfies BaseTransactionMessage & TransactionMessageWithBlockhashLifetime & { some: 1 };
message satisfies TransactionMessageWithBlockhashLifetime;
message satisfies { lifetimeConstraint: { blockhash: Blockhash } };
message satisfies { lifetimeConstraint: { lastValidBlockHeight: bigint } };
}
}

// [DESCRIBE] setTransactionMessageLifetimeUsingBlockhash
{
// It sets the blockhash lifetime on the transaction message for v0 messages.
{
const message = null as unknown as V0TransactionMessage & { some: 1 };
const newMessage = setTransactionMessageLifetimeUsingBlockhash(mockBlockhashLifetime, message);
newMessage satisfies TransactionMessageWithBlockhashLifetime & V0TransactionMessage & { some: 1 };
// @ts-expect-error Should not be a legacy message.
newMessage satisfies LegacyTransactionMessage & TransactionMessageWithBlockhashLifetime & { some: 1 };
}

// It sets the blockhash lifetime on the transaction message for legacy messages.
{
const message = null as unknown as LegacyTransactionMessage & { some: 1 };
const newMessage = setTransactionMessageLifetimeUsingBlockhash(mockBlockhashLifetime, message);
newMessage satisfies LegacyTransactionMessage & TransactionMessageWithBlockhashLifetime & { some: 1 };
// @ts-expect-error Should not be a v0 message.
newMessage satisfies TransactionMessageWithBlockhashLifetime & V0TransactionMessage & { some: 1 };
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { TransactionMessageWithBlockhashLifetime } from '../blockhash';
import { CompilableTransactionMessage } from '../compilable-transaction-message';
import { TransactionMessageWithDurableNonceLifetime } from '../durable-nonce';
import { TransactionMessageWithFeePayer } from '../fee-payer';
import { BaseTransactionMessage } from '../transaction-message';

// BaseTransactionMessage is not compilable.
{
const message = null as unknown as BaseTransactionMessage;
// @ts-expect-error missing fee payer + lifetime token
message satisfies CompilableTransactionMessage;
}

// BaseTransactionMessage with fee payer is not compilable.
{
const message = null as unknown as BaseTransactionMessage & TransactionMessageWithFeePayer;
// @ts-expect-error missing lifetime token
message satisfies CompilableTransactionMessage;
}

// BaseTransactionMessage with blockhash lifetime is not compilable.
{
const message = null as unknown as BaseTransactionMessage & TransactionMessageWithBlockhashLifetime;
// @ts-expect-error missing fee payer
message satisfies CompilableTransactionMessage;
}

// BaseTransactionMessage with durable nonce lifetime is not compilable.
{
const message = null as unknown as BaseTransactionMessage & TransactionMessageWithDurableNonceLifetime;
// @ts-expect-error missing fee payer
message satisfies CompilableTransactionMessage;
}

// BaseTransactionMessage with fee payer and blockhash lifetime is compilable.
{
const message = null as unknown as BaseTransactionMessage &
TransactionMessageWithBlockhashLifetime &
TransactionMessageWithFeePayer;
message satisfies CompilableTransactionMessage;
}

// BaseTransactionMessage with fee payer and durable nonce lifetime is compilable.
{
const message = null as unknown as BaseTransactionMessage &
TransactionMessageWithDurableNonceLifetime &
TransactionMessageWithFeePayer;
message satisfies CompilableTransactionMessage;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { createTransactionMessage } from '../create-transaction-message';
import { TransactionMessage } from '../transaction-message';

type LegacyTransactionMessage = Extract<TransactionMessage, { version: 'legacy' }>;
type V0TransactionMessage = Extract<TransactionMessage, { version: 0 }>;

// It creates legacy transaction messages.
{
const message = createTransactionMessage({ version: 'legacy' });
message satisfies LegacyTransactionMessage;
// @ts-expect-error Should not be V0.
message satisfies V0TransactionMessage;
}

// It creates v0 transaction messages.
{
const message = createTransactionMessage({ version: 0 });
message satisfies V0TransactionMessage;
// @ts-expect-error Should not be legacy.
message satisfies LegacyTransactionMessage;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import type { Address } from '@solana/addresses';

import {
assertIsTransactionMessageWithDurableNonceLifetime,
isTransactionMessageWithDurableNonceLifetime,
Nonce,
setTransactionMessageLifetimeUsingDurableNonce,
TransactionMessageWithDurableNonceLifetime,
} from '../durable-nonce';
import { AdvanceNonceAccountInstruction } from '../durable-nonce-instruction';
import { BaseTransactionMessage, TransactionMessage } from '../transaction-message';

const mockNonceConfig = {
nonce: null as unknown as Nonce<'nonce'>,
nonceAccountAddress: null as unknown as Address<'nonce'>,
nonceAuthorityAddress: null as unknown as Address<'nonceAuthority'>,
};

type LegacyTransactionMessage = Extract<TransactionMessage, { version: 'legacy' }>;
type V0TransactionMessage = Extract<TransactionMessage, { version: 0 }>;

// [DESCRIBE] isTransactionMessageWithDurableNonceLifetime
{
// It narrows the transaction message type to one with a nonce-based lifetime.
{
const message = null as unknown as BaseTransactionMessage & { some: 1 };
if (isTransactionMessageWithDurableNonceLifetime(message)) {
message satisfies BaseTransactionMessage & TransactionMessageWithDurableNonceLifetime & { some: 1 };
} else {
message satisfies BaseTransactionMessage & { some: 1 };
// @ts-expect-error It does not have a nonce-based lifetime.
message satisfies TransactionMessageWithDurableNonceLifetime;
}
}
}

// [DESCRIBE] assertIsTransactionMessageWithDurableNonceLifetime
{
// It narrows the transaction message type to one with a nonce-based lifetime.
{
const message = null as unknown as BaseTransactionMessage & { some: 1 };
// @ts-expect-error Should not be durable nonce lifetime
message satisfies TransactionMessageWithDurableNonceLifetime;
// @ts-expect-error Should not have a nonce-based lifetime
message satisfies { lifetimeConstraint: { nonce: Nonce } };
// @ts-expect-error Should not start with a nonce instruction.
message.instructions[0] satisfies AdvanceNonceAccountInstruction;
assertIsTransactionMessageWithDurableNonceLifetime(message);
message satisfies BaseTransactionMessage & TransactionMessageWithDurableNonceLifetime & { some: 1 };
message satisfies TransactionMessageWithDurableNonceLifetime;
message satisfies { lifetimeConstraint: { nonce: Nonce } };
message.instructions[0] satisfies AdvanceNonceAccountInstruction;
}
}

// [DESCRIBE] setTransactionMessageLifetimeUsingDurableNonce
{
// It sets the durable nonce lifetime on the transaction message for v0 messages.
{
const message = null as unknown as V0TransactionMessage & { some: 1 };
const newMessage = setTransactionMessageLifetimeUsingDurableNonce(mockNonceConfig, message);
newMessage satisfies TransactionMessageWithDurableNonceLifetime & V0TransactionMessage & { some: 1 };
// @ts-expect-error Should not be a legacy message.
newMessage satisfies LegacyTransactionMessage & TransactionMessageWithDurableNonceLifetime & { some: 1 };
}

// It sets the durable nonce lifetime on the transaction message for legacy messages.
{
const message = null as unknown as LegacyTransactionMessage & { some: 1 };
const newMessage = setTransactionMessageLifetimeUsingDurableNonce(mockNonceConfig, message);
newMessage satisfies LegacyTransactionMessage & TransactionMessageWithDurableNonceLifetime & { some: 1 };
// @ts-expect-error Should not be a v0 message.
newMessage satisfies TransactionMessageWithDurableNonceLifetime & V0TransactionMessage & { some: 1 };
}
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,103 @@
import { Address } from '@solana/addresses';

import { TransactionMessageWithBlockhashLifetime } from '../blockhash';
import { TransactionMessageWithDurableNonceLifetime } from '../durable-nonce';
import { setTransactionMessageFeePayer, TransactionMessageWithFeePayer } from '../fee-payer';
import { TransactionMessage } from '../transaction-message';
import { BaseTransactionMessage, TransactionMessage } from '../transaction-message';

const mockFeePayer = 'mock' as Address<'mockFeePayer'>;
const aliceAddress = 'alice' as Address<'alice'>;
const bobAddress = 'bob' as Address<'bob'>;

const message = null as unknown as TransactionMessage;
type LegacyTransactionMessage = Extract<TransactionMessage, { version: 'legacy' }>;
type V0TransactionMessage = Extract<TransactionMessage, { version: 0 }>;

// [DESCRIBE] setTransactionFeePayer
{
// It adds the fee payer to the new message
{
const message = null as unknown as BaseTransactionMessage & { some: 1 };
const messageWithFeePayer = setTransactionMessageFeePayer(aliceAddress, message);
messageWithFeePayer satisfies TransactionMessageWithFeePayer<'alice'>;
messageWithFeePayer satisfies BaseTransactionMessage & TransactionMessageWithFeePayer<'alice'> & { some: 1 };
}

// It *replaces* an existing fee payer with the new one
{
const messageWithAliceFeePayer = null as unknown as TransactionMessage &
TransactionMessageWithFeePayer<'alice'>;
const messageWithAliceFeePayer = null as unknown as BaseTransactionMessage &
TransactionMessageWithFeePayer<'alice'> & { some: 1 };
const messageWithBobFeePayer = setTransactionMessageFeePayer(bobAddress, messageWithAliceFeePayer);
messageWithBobFeePayer satisfies BaseTransactionMessage & TransactionMessageWithFeePayer<'bob'> & { some: 1 };
// @ts-expect-error Alice should no longer be a payer.
messageWithBobFeePayer satisfies TransactionMessageWithFeePayer<'alice'>;
messageWithBobFeePayer satisfies TransactionMessageWithFeePayer<'bob'>;
}

// Legacy messages with no lifetimes.
{
const message = null as unknown as LegacyTransactionMessage;
const messageWithFeePayer = setTransactionMessageFeePayer(mockFeePayer, message);
messageWithFeePayer satisfies LegacyTransactionMessage & TransactionMessageWithFeePayer<'mockFeePayer'>;
// @ts-expect-error Should not be V0.
messageWithFeePayer satisfies TransactionMessageWithFeePayer<'mockFeePayer'> & V0TransactionMessage;
}

// V0 messages with no lifetimes.
{
const message = null as unknown as V0TransactionMessage;
const messageWithFeePayer = setTransactionMessageFeePayer(mockFeePayer, message);
messageWithFeePayer satisfies TransactionMessageWithFeePayer<'mockFeePayer'> & V0TransactionMessage;
// @ts-expect-error Should not be legacy.
messageWithFeePayer satisfies LegacyTransactionMessage & TransactionMessageWithFeePayer<'mockFeePayer'>;
}

// Legacy messages with blockhash lifetime.
{
const message = null as unknown as LegacyTransactionMessage & TransactionMessageWithBlockhashLifetime;
const messageWithFeePayer = setTransactionMessageFeePayer(mockFeePayer, message);
messageWithFeePayer satisfies LegacyTransactionMessage &
TransactionMessageWithBlockhashLifetime &
TransactionMessageWithFeePayer<'mockFeePayer'>;
// @ts-expect-error Should not be V0.
messageWithFeePayer satisfies TransactionMessageWithBlockhashLifetime &
TransactionMessageWithFeePayer<'mockFeePayer'> &
V0TransactionMessage;
}

// V0 messages with blockhash lifetime.
{
const message = null as unknown as TransactionMessageWithBlockhashLifetime & V0TransactionMessage;
const messageWithFeePayer = setTransactionMessageFeePayer(mockFeePayer, message);
messageWithFeePayer satisfies TransactionMessageWithBlockhashLifetime &
TransactionMessageWithFeePayer<'mockFeePayer'> &
V0TransactionMessage;
// @ts-expect-error Should not be legacy.
messageWithFeePayer satisfies LegacyTransactionMessage &
TransactionMessageWithBlockhashLifetime &
TransactionMessageWithFeePayer<'mockFeePayer'>;
}

// Legacy messages with durable nonce lifetime.
{
const message = null as unknown as LegacyTransactionMessage & TransactionMessageWithDurableNonceLifetime;
const messageWithFeePayer = setTransactionMessageFeePayer(mockFeePayer, message);
messageWithFeePayer satisfies LegacyTransactionMessage &
TransactionMessageWithDurableNonceLifetime &
TransactionMessageWithFeePayer<'mockFeePayer'>;
// @ts-expect-error Should not be V0.
messageWithFeePayer satisfies TransactionMessageWithDurableNonceLifetime &
TransactionMessageWithFeePayer<'mockFeePayer'> &
V0TransactionMessage;
}

// V0 messages with durable nonce lifetime.
{
const message = null as unknown as TransactionMessageWithDurableNonceLifetime & V0TransactionMessage;
const messageWithFeePayer = setTransactionMessageFeePayer(mockFeePayer, message);
messageWithFeePayer satisfies TransactionMessageWithDurableNonceLifetime &
TransactionMessageWithFeePayer<'mockFeePayer'> &
V0TransactionMessage;
// @ts-expect-error Should not be legacy.
messageWithFeePayer satisfies LegacyTransactionMessage &
TransactionMessageWithDurableNonceLifetime &
TransactionMessageWithFeePayer<'mockFeePayer'>;
}
}
Loading
0