11import { Address } from '@solana/addresses' ;
2+ import { ReadonlyUint8Array } from '@solana/codecs-core' ;
23import { SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE , SolanaError } from '@solana/errors' ;
34import { Blockhash } from '@solana/rpc-types' ;
45import {
@@ -7,7 +8,12 @@ import {
78 Nonce ,
89} from '@solana/transaction-messages' ;
910
10- import { getTransactionLifetimeConstraintFromCompiledTransactionMessage } from '../lifetime' ;
11+ import {
12+ assertIsTransactionWithBlockhashLifetime ,
13+ assertIsTransactionWithDurableNonceLifetime ,
14+ getTransactionLifetimeConstraintFromCompiledTransactionMessage ,
15+ } from '../lifetime' ;
16+ import { Transaction , TransactionMessageBytes } from '../transaction' ;
1117
1218const SYSTEM_PROGRAM_ADDRESS = '11111111111111111111111111111111' as Address ;
1319const U64_MAX = 2n ** 64n - 1n ;
@@ -149,3 +155,129 @@ describe('getTransactionLifetimeConstraintFromCompiledTransactionMessage', () =>
149155 ) ;
150156 } ) ;
151157} ) ;
158+
159+ describe ( 'assertIsTransactionWithBlockhashLifetime' , ( ) => {
160+ it ( 'throws for a transaction with no lifetime constraint' , ( ) => {
161+ const transaction : Transaction = {
162+ messageBytes : new Uint8Array ( ) as ReadonlyUint8Array as TransactionMessageBytes ,
163+ signatures : { } ,
164+ } ;
165+ expect ( ( ) => assertIsTransactionWithBlockhashLifetime ( transaction ) ) . toThrow ( ) ;
166+ } ) ;
167+ it ( 'throws for a transaction with a durable nonce constraint' , ( ) => {
168+ const transaction = {
169+ lifetimeConstraint : {
170+ nonce : 'abcd' as Nonce ,
171+ nonceAccountAddress : 'nonceAccountAddress' as Address ,
172+ } ,
173+ messageBytes : new Uint8Array ( ) as ReadonlyUint8Array as TransactionMessageBytes ,
174+ signatures : { } ,
175+ } as Transaction ;
176+ expect ( ( ) => assertIsTransactionWithBlockhashLifetime ( transaction ) ) . toThrow ( ) ;
177+ } ) ;
178+ it ( 'throws for a transaction with a blockhash but no lastValidBlockHeight in lifetimeConstraint' , ( ) => {
179+ const transaction = {
180+ lifetimeConstraint : {
181+ blockhash : '11111111111111111111111111111111' ,
182+ } ,
183+ messageBytes : new Uint8Array ( ) as ReadonlyUint8Array as TransactionMessageBytes ,
184+ signatures : { } ,
185+ } as Transaction ;
186+ expect ( ( ) => assertIsTransactionWithBlockhashLifetime ( transaction ) ) . toThrow ( ) ;
187+ } ) ;
188+ it ( 'throws for a transaction with a lastValidBlockHeight but no blockhash in lifetimeConstraint' , ( ) => {
189+ const transaction = {
190+ lifetimeConstraint : {
191+ lastValidBlockHeight : 1234n ,
192+ } ,
193+ messageBytes : new Uint8Array ( ) as ReadonlyUint8Array as TransactionMessageBytes ,
194+ signatures : { } ,
195+ } as Transaction ;
196+ expect ( ( ) => assertIsTransactionWithBlockhashLifetime ( transaction ) ) . toThrow ( ) ;
197+ } ) ;
198+ it ( 'throws for a transaction with a blockhash lifetime but an invalid blockhash value' , ( ) => {
199+ const transaction = {
200+ lifetimeConstraint : {
201+ blockhash : 'not a valid blockhash value' ,
202+ } ,
203+ messageBytes : new Uint8Array ( ) as ReadonlyUint8Array as TransactionMessageBytes ,
204+ signatures : { } ,
205+ } as Transaction ;
206+ expect ( ( ) => assertIsTransactionWithBlockhashLifetime ( transaction ) ) . toThrow ( ) ;
207+ } ) ;
208+ it ( 'does not throw for a transaction with a valid blockhash lifetime constraint' , ( ) => {
209+ const transaction = {
210+ lifetimeConstraint : {
211+ blockhash : '11111111111111111111111111111111' ,
212+ lastValidBlockHeight : 1234n ,
213+ } ,
214+ messageBytes : new Uint8Array ( ) as ReadonlyUint8Array as TransactionMessageBytes ,
215+ signatures : { } ,
216+ } as Transaction ;
217+ expect ( ( ) => assertIsTransactionWithBlockhashLifetime ( transaction ) ) . not . toThrow ( ) ;
218+ } ) ;
219+ } ) ;
220+
221+ describe ( 'assertIsTransactionWithDurableNonceLifetime()' , ( ) => {
222+ const validAddress = '2B7hCrBozp5hPV31mw1qUh5XhXYs9f6p1GsRdHNjF4xS' as Address ;
223+ it ( 'throws for a transaction with no lifetime constraint' , ( ) => {
224+ const transaction : Transaction = {
225+ messageBytes : new Uint8Array ( ) as ReadonlyUint8Array as TransactionMessageBytes ,
226+ signatures : { } ,
227+ } ;
228+ expect ( ( ) => assertIsTransactionWithDurableNonceLifetime ( transaction ) ) . toThrow ( ) ;
229+ } ) ;
230+ it ( 'throws for a transaction with a blockhash constraint' , ( ) => {
231+ const transaction = {
232+ lifetimeConstraint : {
233+ blockhash : '11111111111111111111111111111111' ,
234+ lastValidBlockHeight : 1234n ,
235+ } ,
236+ messageBytes : new Uint8Array ( ) as ReadonlyUint8Array as TransactionMessageBytes ,
237+ signatures : { } ,
238+ } as Transaction ;
239+ expect ( ( ) => assertIsTransactionWithDurableNonceLifetime ( transaction ) ) . toThrow ( ) ;
240+ } ) ;
241+ it ( 'throws for a transaction with a nonce but no nonceAccountAddress in lifetimeConstraint' , ( ) => {
242+ const transaction = {
243+ lifetimeConstraint : {
244+ nonce : 'abcd' as Nonce ,
245+ } ,
246+ messageBytes : new Uint8Array ( ) as ReadonlyUint8Array as TransactionMessageBytes ,
247+ signatures : { } ,
248+ } as Transaction ;
249+ expect ( ( ) => assertIsTransactionWithDurableNonceLifetime ( transaction ) ) . toThrow ( ) ;
250+ } ) ;
251+ it ( 'throws for a transaction with a nonceAccountAddress but no nonce in lifetimeConstraint' , ( ) => {
252+ const transaction = {
253+ lifetimeConstraint : {
254+ nonceAccountAddress : validAddress ,
255+ } ,
256+ messageBytes : new Uint8Array ( ) as ReadonlyUint8Array as TransactionMessageBytes ,
257+ signatures : { } ,
258+ } as Transaction ;
259+ expect ( ( ) => assertIsTransactionWithDurableNonceLifetime ( transaction ) ) . toThrow ( ) ;
260+ } ) ;
261+ it ( 'throws for a transaction with a durable nonce lifetime but an invalid nonceAccountAddress value' , ( ) => {
262+ const transaction = {
263+ lifetimeConstraint : {
264+ nonce : 'abcd' as Nonce ,
265+ nonceAccountAddress : 'not a valid address' as Address ,
266+ } ,
267+ messageBytes : new Uint8Array ( ) as ReadonlyUint8Array as TransactionMessageBytes ,
268+ signatures : { } ,
269+ } as Transaction ;
270+ expect ( ( ) => assertIsTransactionWithDurableNonceLifetime ( transaction ) ) . toThrow ( ) ;
271+ } ) ;
272+ it ( 'does not throw for a transaction with a valid durable nonce lifetime constraint' , ( ) => {
273+ const transaction = {
274+ lifetimeConstraint : {
275+ nonce : 'abcd' as Nonce ,
276+ nonceAccountAddress : validAddress ,
277+ } ,
278+ messageBytes : new Uint8Array ( ) as ReadonlyUint8Array as TransactionMessageBytes ,
279+ signatures : { } ,
280+ } as Transaction ;
281+ expect ( ( ) => assertIsTransactionWithDurableNonceLifetime ( transaction ) ) . not . toThrow ( ) ;
282+ } ) ;
283+ } ) ;
0 commit comments