@exodus/solana-lib 1.2.3 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,782 @@
1
+ // @flow
2
+
3
+ import * as BufferLayout from '@exodus/buffer-layout'
4
+
5
+ import { encodeData, decodeData } from './instruction'
6
+ import * as Layout from './utils/layout'
7
+ import { NONCE_ACCOUNT_LENGTH } from './nonce-account'
8
+ import { PublicKey } from './publickey'
9
+ import { SYSVAR_RECENT_BLOCKHASHES_PUBKEY, SYSVAR_RENT_PUBKEY } from './sysvar'
10
+ import { Transaction, TransactionInstruction } from './transaction'
11
+
12
+ /**
13
+ * Create account system transaction params
14
+ * @typedef {Object} CreateAccountParams
15
+ * @property {PublicKey} fromPubkey
16
+ * @property {PublicKey} newAccountPubkey
17
+ * @property {number} lamports
18
+ * @property {number} space
19
+ * @property {PublicKey} programId
20
+ */
21
+ export type CreateAccountParams = {|
22
+ fromPubkey: PublicKey,
23
+ newAccountPubkey: PublicKey,
24
+ lamports: number,
25
+ space: number,
26
+ programId: PublicKey,
27
+ |}
28
+
29
+ /**
30
+ * Transfer system transaction params
31
+ * @typedef {Object} TransferParams
32
+ * @property {PublicKey} fromPubkey
33
+ * @property {PublicKey} toPubkey
34
+ * @property {number} lamports
35
+ */
36
+ export type TransferParams = {|
37
+ fromPubkey: PublicKey,
38
+ toPubkey: PublicKey,
39
+ lamports: number,
40
+ |}
41
+
42
+ /**
43
+ * Assign system transaction params
44
+ * @typedef {Object} AssignParams
45
+ * @property {PublicKey} accountPubkey
46
+ * @property {PublicKey} programId
47
+ */
48
+ export type AssignParams = {|
49
+ accountPubkey: PublicKey,
50
+ programId: PublicKey,
51
+ |}
52
+
53
+ /**
54
+ * Create account with seed system transaction params
55
+ * @typedef {Object} CreateAccountWithSeedParams
56
+ * @property {PublicKey} fromPubkey
57
+ * @property {PublicKey} newAccountPubkey
58
+ * @property {PublicKey} basePubkey
59
+ * @property {string} seed
60
+ * @property {number} lamports
61
+ * @property {number} space
62
+ * @property {PublicKey} programId
63
+ */
64
+ export type CreateAccountWithSeedParams = {|
65
+ fromPubkey: PublicKey,
66
+ newAccountPubkey: PublicKey,
67
+ basePubkey: PublicKey,
68
+ seed: string,
69
+ lamports: number,
70
+ space: number,
71
+ programId: PublicKey,
72
+ |}
73
+
74
+ /**
75
+ * Create nonce account system transaction params
76
+ * @typedef {Object} CreateNonceAccountParams
77
+ * @property {PublicKey} fromPubkey
78
+ * @property {PublicKey} noncePubkey
79
+ * @property {PublicKey} authorizedPubkey
80
+ * @property {number} lamports
81
+ */
82
+ export type CreateNonceAccountParams = {|
83
+ fromPubkey: PublicKey,
84
+ noncePubkey: PublicKey,
85
+ authorizedPubkey: PublicKey,
86
+ lamports: number,
87
+ |}
88
+
89
+ /**
90
+ * Create nonce account with seed system transaction params
91
+ * @typedef {Object} CreateNonceAccountWithSeedParams
92
+ * @property {PublicKey} fromPubkey
93
+ * @property {PublicKey} noncePubkey
94
+ * @property {PublicKey} authorizedPubkey
95
+ * @property {PublicKey} basePubkey
96
+ * @property {string} seed
97
+ * @property {number} lamports
98
+ */
99
+ export type CreateNonceAccountWithSeedParams = {|
100
+ fromPubkey: PublicKey,
101
+ noncePubkey: PublicKey,
102
+ authorizedPubkey: PublicKey,
103
+ lamports: number,
104
+ basePubkey: PublicKey,
105
+ seed: string,
106
+ |}
107
+
108
+ /**
109
+ * Initialize nonce account system instruction params
110
+ * @typedef {Object} InitializeNonceParams
111
+ * @property {PublicKey} fromPubkey
112
+ * @property {PublicKey} programId
113
+ */
114
+ export type InitializeNonceParams = {|
115
+ noncePubkey: PublicKey,
116
+ authorizedPubkey: PublicKey,
117
+ |}
118
+
119
+ /**
120
+ * Advance nonce account system instruction params
121
+ * @typedef {Object} AdvanceNonceParams
122
+ * @property {PublicKey} fromPubkey
123
+ * @property {PublicKey} programId
124
+ */
125
+ export type AdvanceNonceParams = {|
126
+ noncePubkey: PublicKey,
127
+ authorizedPubkey: PublicKey,
128
+ |}
129
+
130
+ /**
131
+ * Withdraw nonce account system transaction params
132
+ * @typedef {Object} WithdrawNonceParams
133
+ * @property {PublicKey} noncePubkey
134
+ * @property {PublicKey} authorizedPubkey
135
+ * @property {PublicKey} toPubkey
136
+ * @property {number} lamports
137
+ */
138
+ export type WithdrawNonceParams = {|
139
+ noncePubkey: PublicKey,
140
+ authorizedPubkey: PublicKey,
141
+ toPubkey: PublicKey,
142
+ lamports: number,
143
+ |}
144
+
145
+ /**
146
+ * Authorize nonce account system transaction params
147
+ * @typedef {Object} AuthorizeNonceParams
148
+ * @property {PublicKey} noncePubkey
149
+ * @property {PublicKey} authorizedPubkey
150
+ * @property {PublicKey} newAuthorizedPubkey
151
+ */
152
+ export type AuthorizeNonceParams = {|
153
+ noncePubkey: PublicKey,
154
+ authorizedPubkey: PublicKey,
155
+ newAuthorizedPubkey: PublicKey,
156
+ |}
157
+
158
+ /**
159
+ * Allocate account system transaction params
160
+ * @typedef {Object} AllocateParams
161
+ * @property {PublicKey} accountPubkey
162
+ * @property {number} space
163
+ */
164
+ export type AllocateParams = {|
165
+ accountPubkey: PublicKey,
166
+ space: number,
167
+ |}
168
+
169
+ /**
170
+ * Allocate account with seed system transaction params
171
+ * @typedef {Object} AllocateWithSeedParams
172
+ * @property {PublicKey} accountPubkey
173
+ * @property {PublicKey} basePubkey
174
+ * @property {string} seed
175
+ * @property {number} space
176
+ * @property {PublicKey} programId
177
+ */
178
+ export type AllocateWithSeedParams = {|
179
+ accountPubkey: PublicKey,
180
+ basePubkey: PublicKey,
181
+ seed: string,
182
+ space: number,
183
+ programId: PublicKey,
184
+ |}
185
+
186
+ /**
187
+ * Assign account with seed system transaction params
188
+ * @typedef {Object} AssignWithSeedParams
189
+ * @property {PublicKey} accountPubkey
190
+ * @property {PublicKey} basePubkey
191
+ * @property {string} seed
192
+ * @property {PublicKey} programId
193
+ */
194
+ export type AssignWithSeedParams = {|
195
+ accountPubkey: PublicKey,
196
+ basePubkey: PublicKey,
197
+ seed: string,
198
+ programId: PublicKey,
199
+ |}
200
+
201
+ /**
202
+ * An enumeration of valid system InstructionType's
203
+ */
204
+ export const SYSTEM_INSTRUCTION_LAYOUTS = Object.freeze({
205
+ Create: {
206
+ index: 0,
207
+ layout: BufferLayout.struct([
208
+ BufferLayout.u32('instruction'),
209
+ BufferLayout.ns64('lamports'),
210
+ BufferLayout.ns64('space'),
211
+ Layout.publicKey('programId'),
212
+ ]),
213
+ },
214
+ Assign: {
215
+ index: 1,
216
+ layout: BufferLayout.struct([BufferLayout.u32('instruction'), Layout.publicKey('programId')]),
217
+ },
218
+ Transfer: {
219
+ index: 2,
220
+ layout: BufferLayout.struct([BufferLayout.u32('instruction'), BufferLayout.ns64('lamports')]),
221
+ },
222
+ CreateWithSeed: {
223
+ index: 3,
224
+ layout: BufferLayout.struct([
225
+ BufferLayout.u32('instruction'),
226
+ Layout.publicKey('base'),
227
+ Layout.rustString('seed'),
228
+ BufferLayout.ns64('lamports'),
229
+ BufferLayout.ns64('space'),
230
+ Layout.publicKey('programId'),
231
+ ]),
232
+ },
233
+ AdvanceNonceAccount: {
234
+ index: 4,
235
+ layout: BufferLayout.struct([BufferLayout.u32('instruction')]),
236
+ },
237
+ WithdrawNonceAccount: {
238
+ index: 5,
239
+ layout: BufferLayout.struct([BufferLayout.u32('instruction'), BufferLayout.ns64('lamports')]),
240
+ },
241
+ InitializeNonceAccount: {
242
+ index: 6,
243
+ layout: BufferLayout.struct([BufferLayout.u32('instruction'), Layout.publicKey('authorized')]),
244
+ },
245
+ AuthorizeNonceAccount: {
246
+ index: 7,
247
+ layout: BufferLayout.struct([BufferLayout.u32('instruction'), Layout.publicKey('authorized')]),
248
+ },
249
+ Allocate: {
250
+ index: 8,
251
+ layout: BufferLayout.struct([BufferLayout.u32('instruction'), BufferLayout.ns64('space')]),
252
+ },
253
+ AllocateWithSeed: {
254
+ index: 9,
255
+ layout: BufferLayout.struct([
256
+ BufferLayout.u32('instruction'),
257
+ Layout.publicKey('base'),
258
+ Layout.rustString('seed'),
259
+ BufferLayout.ns64('space'),
260
+ Layout.publicKey('programId'),
261
+ ]),
262
+ },
263
+ AssignWithSeed: {
264
+ index: 10,
265
+ layout: BufferLayout.struct([
266
+ BufferLayout.u32('instruction'),
267
+ Layout.publicKey('base'),
268
+ Layout.rustString('seed'),
269
+ Layout.publicKey('programId'),
270
+ ]),
271
+ },
272
+ })
273
+
274
+ /**
275
+ * System Instruction class
276
+ */
277
+ export class SystemInstruction {
278
+ /**
279
+ * Decode a system instruction and retrieve the instruction type.
280
+ */
281
+ static decodeInstructionType(instruction: TransactionInstruction) {
282
+ this.checkProgramId(instruction.programId)
283
+
284
+ const instructionTypeLayout = BufferLayout.u32('instruction')
285
+ const typeIndex = instructionTypeLayout.decode(instruction.data)
286
+
287
+ let type
288
+ for (const t of Object.keys(SYSTEM_INSTRUCTION_LAYOUTS)) {
289
+ if (SYSTEM_INSTRUCTION_LAYOUTS[t].index === typeIndex) {
290
+ type = t
291
+ }
292
+ }
293
+
294
+ if (!type) {
295
+ throw new Error('Instruction type incorrect; not a SystemInstruction')
296
+ }
297
+
298
+ return type
299
+ }
300
+
301
+ /**
302
+ * Decode a create account system instruction and retrieve the instruction params.
303
+ */
304
+ static decodeCreateAccount(instruction: TransactionInstruction): CreateAccountParams {
305
+ this.checkProgramId(instruction.programId)
306
+ this.checkKeyLength(instruction.keys, 2)
307
+
308
+ const { lamports, space, programId } = decodeData(
309
+ SYSTEM_INSTRUCTION_LAYOUTS.Create,
310
+ instruction.data
311
+ )
312
+
313
+ return {
314
+ fromPubkey: instruction.keys[0].pubkey,
315
+ newAccountPubkey: instruction.keys[1].pubkey,
316
+ lamports,
317
+ space,
318
+ programId: new PublicKey(programId),
319
+ }
320
+ }
321
+
322
+ /**
323
+ * Decode a transfer system instruction and retrieve the instruction params.
324
+ */
325
+ static decodeTransfer(instruction: TransactionInstruction): TransferParams {
326
+ this.checkProgramId(instruction.programId)
327
+ this.checkKeyLength(instruction.keys, 2)
328
+
329
+ const { lamports } = decodeData(SYSTEM_INSTRUCTION_LAYOUTS.Transfer, instruction.data)
330
+
331
+ return {
332
+ fromPubkey: instruction.keys[0].pubkey,
333
+ toPubkey: instruction.keys[1].pubkey,
334
+ lamports,
335
+ }
336
+ }
337
+
338
+ /**
339
+ * Decode an allocate system instruction and retrieve the instruction params.
340
+ */
341
+ static decodeAllocate(instruction: TransactionInstruction): AllocateParams {
342
+ this.checkProgramId(instruction.programId)
343
+ this.checkKeyLength(instruction.keys, 1)
344
+
345
+ const { space } = decodeData(SYSTEM_INSTRUCTION_LAYOUTS.Allocate, instruction.data)
346
+
347
+ return {
348
+ accountPubkey: instruction.keys[0].pubkey,
349
+ space,
350
+ }
351
+ }
352
+
353
+ /**
354
+ * Decode an allocate with seed system instruction and retrieve the instruction params.
355
+ */
356
+ static decodeAllocateWithSeed(instruction: TransactionInstruction): AllocateWithSeedParams {
357
+ this.checkProgramId(instruction.programId)
358
+ this.checkKeyLength(instruction.keys, 1)
359
+
360
+ const { base, seed, space, programId } = decodeData(
361
+ SYSTEM_INSTRUCTION_LAYOUTS.AllocateWithSeed,
362
+ instruction.data
363
+ )
364
+
365
+ return {
366
+ accountPubkey: instruction.keys[0].pubkey,
367
+ basePubkey: new PublicKey(base),
368
+ seed,
369
+ space,
370
+ programId: new PublicKey(programId),
371
+ }
372
+ }
373
+
374
+ /**
375
+ * Decode an assign system instruction and retrieve the instruction params.
376
+ */
377
+ static decodeAssign(instruction: TransactionInstruction): AssignParams {
378
+ this.checkProgramId(instruction.programId)
379
+ this.checkKeyLength(instruction.keys, 1)
380
+
381
+ const { programId } = decodeData(SYSTEM_INSTRUCTION_LAYOUTS.Assign, instruction.data)
382
+
383
+ return {
384
+ accountPubkey: instruction.keys[0].pubkey,
385
+ programId: new PublicKey(programId),
386
+ }
387
+ }
388
+
389
+ /**
390
+ * Decode an assign with seed system instruction and retrieve the instruction params.
391
+ */
392
+ static decodeAssignWithSeed(instruction: TransactionInstruction): AssignWithSeedParams {
393
+ this.checkProgramId(instruction.programId)
394
+ this.checkKeyLength(instruction.keys, 1)
395
+
396
+ const { base, seed, programId } = decodeData(
397
+ SYSTEM_INSTRUCTION_LAYOUTS.AssignWithSeed,
398
+ instruction.data
399
+ )
400
+
401
+ return {
402
+ accountPubkey: instruction.keys[0].pubkey,
403
+ basePubkey: new PublicKey(base),
404
+ seed,
405
+ programId: new PublicKey(programId),
406
+ }
407
+ }
408
+
409
+ /**
410
+ * Decode a create account with seed system instruction and retrieve the instruction params.
411
+ */
412
+ static decodeCreateWithSeed(instruction: TransactionInstruction): CreateAccountWithSeedParams {
413
+ this.checkProgramId(instruction.programId)
414
+ this.checkKeyLength(instruction.keys, 2)
415
+
416
+ const { base, seed, lamports, space, programId } = decodeData(
417
+ SYSTEM_INSTRUCTION_LAYOUTS.CreateWithSeed,
418
+ instruction.data
419
+ )
420
+
421
+ return {
422
+ fromPubkey: instruction.keys[0].pubkey,
423
+ newAccountPubkey: instruction.keys[1].pubkey,
424
+ basePubkey: new PublicKey(base),
425
+ seed,
426
+ lamports,
427
+ space,
428
+ programId: new PublicKey(programId),
429
+ }
430
+ }
431
+
432
+ /**
433
+ * Decode a nonce initialize system instruction and retrieve the instruction params.
434
+ */
435
+ static decodeNonceInitialize(instruction: TransactionInstruction): InitializeNonceParams {
436
+ this.checkProgramId(instruction.programId)
437
+ this.checkKeyLength(instruction.keys, 3)
438
+
439
+ const { authorized } = decodeData(
440
+ SYSTEM_INSTRUCTION_LAYOUTS.InitializeNonceAccount,
441
+ instruction.data
442
+ )
443
+
444
+ return {
445
+ noncePubkey: instruction.keys[0].pubkey,
446
+ authorizedPubkey: new PublicKey(authorized),
447
+ }
448
+ }
449
+
450
+ /**
451
+ * Decode a nonce advance system instruction and retrieve the instruction params.
452
+ */
453
+ static decodeNonceAdvance(instruction: TransactionInstruction): AdvanceNonceParams {
454
+ this.checkProgramId(instruction.programId)
455
+ this.checkKeyLength(instruction.keys, 3)
456
+
457
+ decodeData(SYSTEM_INSTRUCTION_LAYOUTS.AdvanceNonceAccount, instruction.data)
458
+
459
+ return {
460
+ noncePubkey: instruction.keys[0].pubkey,
461
+ authorizedPubkey: instruction.keys[2].pubkey,
462
+ }
463
+ }
464
+
465
+ /**
466
+ * Decode a nonce withdraw system instruction and retrieve the instruction params.
467
+ */
468
+ static decodeNonceWithdraw(instruction: TransactionInstruction): WithdrawNonceParams {
469
+ this.checkProgramId(instruction.programId)
470
+ this.checkKeyLength(instruction.keys, 5)
471
+
472
+ const { lamports } = decodeData(
473
+ SYSTEM_INSTRUCTION_LAYOUTS.WithdrawNonceAccount,
474
+ instruction.data
475
+ )
476
+
477
+ return {
478
+ noncePubkey: instruction.keys[0].pubkey,
479
+ toPubkey: instruction.keys[1].pubkey,
480
+ authorizedPubkey: instruction.keys[4].pubkey,
481
+ lamports,
482
+ }
483
+ }
484
+
485
+ /**
486
+ * Decode a nonce authorize system instruction and retrieve the instruction params.
487
+ */
488
+ static decodeNonceAuthorize(instruction: TransactionInstruction): AuthorizeNonceParams {
489
+ this.checkProgramId(instruction.programId)
490
+ this.checkKeyLength(instruction.keys, 2)
491
+
492
+ const { authorized } = decodeData(
493
+ SYSTEM_INSTRUCTION_LAYOUTS.AuthorizeNonceAccount,
494
+ instruction.data
495
+ )
496
+
497
+ return {
498
+ noncePubkey: instruction.keys[0].pubkey,
499
+ authorizedPubkey: instruction.keys[1].pubkey,
500
+ newAuthorizedPubkey: new PublicKey(authorized),
501
+ }
502
+ }
503
+
504
+ /**
505
+ * @private
506
+ */
507
+ static checkProgramId(programId: PublicKey) {
508
+ if (!programId.equals(SystemProgram.programId)) {
509
+ throw new Error('invalid instruction; programId is not SystemProgram')
510
+ }
511
+ }
512
+
513
+ /**
514
+ * @private
515
+ */
516
+ static checkKeyLength(keys: Array<any>, expectedLength: number) {
517
+ if (keys.length < expectedLength) {
518
+ throw new Error(
519
+ `invalid instruction; found ${keys.length} keys, expected at least ${expectedLength}`
520
+ )
521
+ }
522
+ }
523
+ }
524
+
525
+ /**
526
+ * Factory class for transactions to interact with the System program
527
+ */
528
+ export class SystemProgram {
529
+ /**
530
+ * Public key that identifies the System program
531
+ */
532
+ static get programId(): PublicKey {
533
+ return new PublicKey('11111111111111111111111111111111')
534
+ }
535
+
536
+ /**
537
+ * Generate a transaction instruction that creates a new account
538
+ */
539
+ static createAccount(params: CreateAccountParams): TransactionInstruction {
540
+ const type = SYSTEM_INSTRUCTION_LAYOUTS.Create
541
+ const data = encodeData(type, {
542
+ lamports: params.lamports,
543
+ space: params.space,
544
+ programId: params.programId.toBuffer(),
545
+ })
546
+
547
+ return new TransactionInstruction({
548
+ keys: [
549
+ { pubkey: params.fromPubkey, isSigner: true, isWritable: true },
550
+ { pubkey: params.newAccountPubkey, isSigner: true, isWritable: true },
551
+ ],
552
+ programId: this.programId,
553
+ data,
554
+ })
555
+ }
556
+
557
+ /**
558
+ * Generate a transaction instruction that transfers lamports from one account to another
559
+ */
560
+ static transfer(params: TransferParams): TransactionInstruction {
561
+ const type = SYSTEM_INSTRUCTION_LAYOUTS.Transfer
562
+ const data = encodeData(type, { lamports: params.lamports })
563
+
564
+ return new TransactionInstruction({
565
+ keys: [
566
+ { pubkey: params.fromPubkey, isSigner: true, isWritable: true },
567
+ { pubkey: params.toPubkey, isSigner: false, isWritable: true },
568
+ ],
569
+ programId: this.programId,
570
+ data,
571
+ })
572
+ }
573
+
574
+ /**
575
+ * Generate a transaction instruction that assigns an account to a program
576
+ */
577
+ static assign(params: AssignParams | AssignWithSeedParams): TransactionInstruction {
578
+ let data
579
+ if (params.basePubkey) {
580
+ const type = SYSTEM_INSTRUCTION_LAYOUTS.AssignWithSeed
581
+ data = encodeData(type, {
582
+ base: params.basePubkey.toBuffer(),
583
+ seed: params.seed,
584
+ programId: params.programId.toBuffer(),
585
+ })
586
+ } else {
587
+ const type = SYSTEM_INSTRUCTION_LAYOUTS.Assign
588
+ data = encodeData(type, { programId: params.programId.toBuffer() })
589
+ }
590
+
591
+ return new TransactionInstruction({
592
+ keys: [{ pubkey: params.accountPubkey, isSigner: true, isWritable: true }],
593
+ programId: this.programId,
594
+ data,
595
+ })
596
+ }
597
+
598
+ /**
599
+ * Generate a transaction instruction that creates a new account at
600
+ * an address generated with `from`, a seed, and programId
601
+ */
602
+ static createAccountWithSeed(params: CreateAccountWithSeedParams): TransactionInstruction {
603
+ const type = SYSTEM_INSTRUCTION_LAYOUTS.CreateWithSeed
604
+ const data = encodeData(type, {
605
+ base: params.basePubkey.toBuffer(),
606
+ seed: params.seed,
607
+ lamports: params.lamports,
608
+ space: params.space,
609
+ programId: params.programId.toBuffer(),
610
+ })
611
+
612
+ return new TransactionInstruction({
613
+ keys: [
614
+ { pubkey: params.fromPubkey, isSigner: true, isWritable: true },
615
+ { pubkey: params.newAccountPubkey, isSigner: false, isWritable: true },
616
+ ],
617
+ programId: this.programId,
618
+ data,
619
+ })
620
+ }
621
+
622
+ /**
623
+ * Generate a transaction that creates a new Nonce account
624
+ */
625
+ static createNonceAccount(
626
+ params: CreateNonceAccountParams | CreateNonceAccountWithSeedParams
627
+ ): Transaction {
628
+ const transaction = new Transaction()
629
+ if (params.basePubkey && params.seed) {
630
+ transaction.add(
631
+ SystemProgram.createAccountWithSeed({
632
+ fromPubkey: params.fromPubkey,
633
+ newAccountPubkey: params.noncePubkey,
634
+ basePubkey: params.basePubkey,
635
+ seed: params.seed,
636
+ lamports: params.lamports,
637
+ space: NONCE_ACCOUNT_LENGTH,
638
+ programId: this.programId,
639
+ })
640
+ )
641
+ } else {
642
+ transaction.add(
643
+ SystemProgram.createAccount({
644
+ fromPubkey: params.fromPubkey,
645
+ newAccountPubkey: params.noncePubkey,
646
+ lamports: params.lamports,
647
+ space: NONCE_ACCOUNT_LENGTH,
648
+ programId: this.programId,
649
+ })
650
+ )
651
+ }
652
+
653
+ const initParams = {
654
+ noncePubkey: params.noncePubkey,
655
+ authorizedPubkey: params.authorizedPubkey,
656
+ }
657
+
658
+ transaction.add(this.nonceInitialize(initParams))
659
+ return transaction
660
+ }
661
+
662
+ /**
663
+ * Generate an instruction to initialize a Nonce account
664
+ */
665
+ static nonceInitialize(params: InitializeNonceParams): TransactionInstruction {
666
+ const type = SYSTEM_INSTRUCTION_LAYOUTS.InitializeNonceAccount
667
+ const data = encodeData(type, {
668
+ authorized: params.authorizedPubkey.toBuffer(),
669
+ })
670
+ const instructionData = {
671
+ keys: [
672
+ { pubkey: params.noncePubkey, isSigner: false, isWritable: true },
673
+ {
674
+ pubkey: SYSVAR_RECENT_BLOCKHASHES_PUBKEY,
675
+ isSigner: false,
676
+ isWritable: false,
677
+ },
678
+ { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
679
+ ],
680
+ programId: this.programId,
681
+ data,
682
+ }
683
+ return new TransactionInstruction(instructionData)
684
+ }
685
+
686
+ /**
687
+ * Generate an instruction to advance the nonce in a Nonce account
688
+ */
689
+ static nonceAdvance(params: AdvanceNonceParams): TransactionInstruction {
690
+ const type = SYSTEM_INSTRUCTION_LAYOUTS.AdvanceNonceAccount
691
+ const data = encodeData(type)
692
+ const instructionData = {
693
+ keys: [
694
+ { pubkey: params.noncePubkey, isSigner: false, isWritable: true },
695
+ {
696
+ pubkey: SYSVAR_RECENT_BLOCKHASHES_PUBKEY,
697
+ isSigner: false,
698
+ isWritable: false,
699
+ },
700
+ { pubkey: params.authorizedPubkey, isSigner: true, isWritable: false },
701
+ ],
702
+ programId: this.programId,
703
+ data,
704
+ }
705
+ return new TransactionInstruction(instructionData)
706
+ }
707
+
708
+ /**
709
+ * Generate a transaction instruction that withdraws lamports from a Nonce account
710
+ */
711
+ static nonceWithdraw(params: WithdrawNonceParams): TransactionInstruction {
712
+ const type = SYSTEM_INSTRUCTION_LAYOUTS.WithdrawNonceAccount
713
+ const data = encodeData(type, { lamports: params.lamports })
714
+
715
+ return new TransactionInstruction({
716
+ keys: [
717
+ { pubkey: params.noncePubkey, isSigner: false, isWritable: true },
718
+ { pubkey: params.toPubkey, isSigner: false, isWritable: true },
719
+ {
720
+ pubkey: SYSVAR_RECENT_BLOCKHASHES_PUBKEY,
721
+ isSigner: false,
722
+ isWritable: false,
723
+ },
724
+ {
725
+ pubkey: SYSVAR_RENT_PUBKEY,
726
+ isSigner: false,
727
+ isWritable: false,
728
+ },
729
+ { pubkey: params.authorizedPubkey, isSigner: true, isWritable: false },
730
+ ],
731
+ programId: this.programId,
732
+ data,
733
+ })
734
+ }
735
+
736
+ /**
737
+ * Generate a transaction instruction that authorizes a new PublicKey as the authority
738
+ * on a Nonce account.
739
+ */
740
+ static nonceAuthorize(params: AuthorizeNonceParams): TransactionInstruction {
741
+ const type = SYSTEM_INSTRUCTION_LAYOUTS.AuthorizeNonceAccount
742
+ const data = encodeData(type, {
743
+ authorized: params.newAuthorizedPubkey.toBuffer(),
744
+ })
745
+
746
+ return new TransactionInstruction({
747
+ keys: [
748
+ { pubkey: params.noncePubkey, isSigner: false, isWritable: true },
749
+ { pubkey: params.authorizedPubkey, isSigner: true, isWritable: false },
750
+ ],
751
+ programId: this.programId,
752
+ data,
753
+ })
754
+ }
755
+
756
+ /**
757
+ * Generate a transaction instruction that allocates space in an account without funding
758
+ */
759
+ static allocate(params: AllocateParams | AllocateWithSeedParams): TransactionInstruction {
760
+ let data
761
+ if (params.basePubkey) {
762
+ const type = SYSTEM_INSTRUCTION_LAYOUTS.AllocateWithSeed
763
+ data = encodeData(type, {
764
+ base: params.basePubkey.toBuffer(),
765
+ seed: params.seed,
766
+ space: params.space,
767
+ programId: params.programId.toBuffer(),
768
+ })
769
+ } else {
770
+ const type = SYSTEM_INSTRUCTION_LAYOUTS.Allocate
771
+ data = encodeData(type, {
772
+ space: params.space,
773
+ })
774
+ }
775
+
776
+ return new TransactionInstruction({
777
+ keys: [{ pubkey: params.accountPubkey, isSigner: true, isWritable: true }],
778
+ programId: this.programId,
779
+ data,
780
+ })
781
+ }
782
+ }