@ignitionfi/spl-stake-pool 1.1.8

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,1293 @@
1
+ import * as BufferLayout from '@solana/buffer-layout'
2
+ import { TOKEN_PROGRAM_ID } from '@solana/spl-token'
3
+ import {
4
+ PublicKey,
5
+ STAKE_CONFIG_ID,
6
+ StakeProgram,
7
+ SystemProgram,
8
+ SYSVAR_CLOCK_PUBKEY,
9
+ SYSVAR_RENT_PUBKEY,
10
+ SYSVAR_STAKE_HISTORY_PUBKEY,
11
+ TransactionInstruction,
12
+ } from '@solana/web3.js'
13
+ import {
14
+ DEVNET_STAKE_POOL_PROGRAM_ID,
15
+ METADATA_MAX_NAME_LENGTH,
16
+ METADATA_MAX_SYMBOL_LENGTH,
17
+ METADATA_MAX_URI_LENGTH,
18
+ METADATA_PROGRAM_ID,
19
+ STAKE_POOL_PROGRAM_ID,
20
+ } from './constants'
21
+ import { decodeData, encodeData, InstructionType } from './utils'
22
+
23
+ /**
24
+ * An enumeration of valid StakePoolInstructionType's
25
+ */
26
+ export type StakePoolInstructionType
27
+ = | 'IncreaseValidatorStake'
28
+ | 'DecreaseValidatorStake'
29
+ | 'UpdateValidatorListBalance'
30
+ | 'UpdateStakePoolBalance'
31
+ | 'CleanupRemovedValidatorEntries'
32
+ | 'DepositStake'
33
+ | 'DepositSol'
34
+ | 'WithdrawStake'
35
+ | 'WithdrawSol'
36
+ | 'IncreaseAdditionalValidatorStake'
37
+ | 'DecreaseAdditionalValidatorStake'
38
+ | 'DecreaseValidatorStakeWithReserve'
39
+ | 'Redelegate'
40
+ | 'AddValidatorToPool'
41
+ | 'RemoveValidatorFromPool'
42
+ | 'DepositWsolWithSession'
43
+ | 'WithdrawWsolWithSession'
44
+
45
+ // 'UpdateTokenMetadata' and 'CreateTokenMetadata' have dynamic layouts
46
+
47
+ const MOVE_STAKE_LAYOUT = BufferLayout.struct<any>([
48
+ BufferLayout.u8('instruction'),
49
+ BufferLayout.ns64('lamports'),
50
+ BufferLayout.ns64('transientStakeSeed'),
51
+ ])
52
+
53
+ const UPDATE_VALIDATOR_LIST_BALANCE_LAYOUT = BufferLayout.struct<any>([
54
+ BufferLayout.u8('instruction'),
55
+ BufferLayout.u32('startIndex'),
56
+ BufferLayout.u8('noMerge'),
57
+ ])
58
+
59
+ export function tokenMetadataLayout(
60
+ instruction: number,
61
+ nameLength: number,
62
+ symbolLength: number,
63
+ uriLength: number,
64
+ ) {
65
+ if (nameLength > METADATA_MAX_NAME_LENGTH) {
66
+ // eslint-disable-next-line no-throw-literal
67
+ throw 'maximum token name length is 32 characters'
68
+ }
69
+
70
+ if (symbolLength > METADATA_MAX_SYMBOL_LENGTH) {
71
+ // eslint-disable-next-line no-throw-literal
72
+ throw 'maximum token symbol length is 10 characters'
73
+ }
74
+
75
+ if (uriLength > METADATA_MAX_URI_LENGTH) {
76
+ // eslint-disable-next-line no-throw-literal
77
+ throw 'maximum token uri length is 200 characters'
78
+ }
79
+
80
+ return {
81
+ index: instruction,
82
+ layout: BufferLayout.struct<any>([
83
+ BufferLayout.u8('instruction'),
84
+ BufferLayout.u32('nameLen'),
85
+ BufferLayout.blob(nameLength, 'name'),
86
+ BufferLayout.u32('symbolLen'),
87
+ BufferLayout.blob(symbolLength, 'symbol'),
88
+ BufferLayout.u32('uriLen'),
89
+ BufferLayout.blob(uriLength, 'uri'),
90
+ ]),
91
+ }
92
+ }
93
+
94
+ /**
95
+ * An enumeration of valid stake InstructionType's
96
+ * @internal
97
+ */
98
+ export const STAKE_POOL_INSTRUCTION_LAYOUTS: {
99
+ [type in StakePoolInstructionType]: InstructionType;
100
+ } = Object.freeze({
101
+ AddValidatorToPool: {
102
+ index: 1,
103
+ layout: BufferLayout.struct<any>([BufferLayout.u8('instruction'), BufferLayout.u32('seed')]),
104
+ },
105
+ RemoveValidatorFromPool: {
106
+ index: 2,
107
+ layout: BufferLayout.struct<any>([BufferLayout.u8('instruction')]),
108
+ },
109
+ DecreaseValidatorStake: {
110
+ index: 3,
111
+ layout: MOVE_STAKE_LAYOUT,
112
+ },
113
+ IncreaseValidatorStake: {
114
+ index: 4,
115
+ layout: MOVE_STAKE_LAYOUT,
116
+ },
117
+ UpdateValidatorListBalance: {
118
+ index: 6,
119
+ layout: UPDATE_VALIDATOR_LIST_BALANCE_LAYOUT,
120
+ },
121
+ UpdateStakePoolBalance: {
122
+ index: 7,
123
+ layout: BufferLayout.struct<any>([BufferLayout.u8('instruction')]),
124
+ },
125
+ CleanupRemovedValidatorEntries: {
126
+ index: 8,
127
+ layout: BufferLayout.struct<any>([BufferLayout.u8('instruction')]),
128
+ },
129
+ DepositStake: {
130
+ index: 9,
131
+ layout: BufferLayout.struct<any>([BufferLayout.u8('instruction')]),
132
+ },
133
+ /// Withdraw the token from the pool at the current ratio.
134
+ WithdrawStake: {
135
+ index: 10,
136
+ layout: BufferLayout.struct<any>([
137
+ BufferLayout.u8('instruction'),
138
+ BufferLayout.ns64('poolTokens'),
139
+ ]),
140
+ },
141
+ /// Deposit SOL directly into the pool's reserve account. The output is a "pool" token
142
+ /// representing ownership into the pool. Inputs are converted to the current ratio.
143
+ DepositSol: {
144
+ index: 14,
145
+ layout: BufferLayout.struct<any>([
146
+ BufferLayout.u8('instruction'),
147
+ BufferLayout.ns64('lamports'),
148
+ ]),
149
+ },
150
+ /// Withdraw SOL directly from the pool's reserve account. Fails if the
151
+ /// reserve does not have enough SOL.
152
+ WithdrawSol: {
153
+ index: 16,
154
+ layout: BufferLayout.struct<any>([
155
+ BufferLayout.u8('instruction'),
156
+ BufferLayout.ns64('poolTokens'),
157
+ ]),
158
+ },
159
+ IncreaseAdditionalValidatorStake: {
160
+ index: 19,
161
+ layout: BufferLayout.struct<any>([
162
+ BufferLayout.u8('instruction'),
163
+ BufferLayout.ns64('lamports'),
164
+ BufferLayout.ns64('transientStakeSeed'),
165
+ BufferLayout.ns64('ephemeralStakeSeed'),
166
+ ]),
167
+ },
168
+ DecreaseAdditionalValidatorStake: {
169
+ index: 20,
170
+ layout: BufferLayout.struct<any>([
171
+ BufferLayout.u8('instruction'),
172
+ BufferLayout.ns64('lamports'),
173
+ BufferLayout.ns64('transientStakeSeed'),
174
+ BufferLayout.ns64('ephemeralStakeSeed'),
175
+ ]),
176
+ },
177
+ DecreaseValidatorStakeWithReserve: {
178
+ index: 21,
179
+ layout: MOVE_STAKE_LAYOUT,
180
+ },
181
+ Redelegate: {
182
+ index: 22,
183
+ layout: BufferLayout.struct<any>([BufferLayout.u8('instruction')]),
184
+ },
185
+ DepositStakeWithSlippage: {
186
+ index: 23,
187
+ layout: BufferLayout.struct<any>([
188
+ BufferLayout.u8('instruction'),
189
+ BufferLayout.ns64('lamports'),
190
+ ]),
191
+ },
192
+ WithdrawStakeWithSlippage: {
193
+ index: 24,
194
+ layout: BufferLayout.struct<any>([
195
+ BufferLayout.u8('instruction'),
196
+ BufferLayout.ns64('lamports'),
197
+ ]),
198
+ },
199
+ DepositSolWithSlippage: {
200
+ index: 25,
201
+ layout: BufferLayout.struct<any>([
202
+ BufferLayout.u8('instruction'),
203
+ BufferLayout.ns64('lamports'),
204
+ ]),
205
+ },
206
+ WithdrawSolWithSlippage: {
207
+ index: 26,
208
+ layout: BufferLayout.struct<any>([
209
+ BufferLayout.u8('instruction'),
210
+ BufferLayout.ns64('lamports'),
211
+ ]),
212
+ },
213
+ DepositWsolWithSession: {
214
+ index: 27,
215
+ layout: BufferLayout.struct<any>([
216
+ BufferLayout.u8('instruction'),
217
+ BufferLayout.ns64('lamports'),
218
+ ]),
219
+ },
220
+ WithdrawWsolWithSession: {
221
+ index: 28,
222
+ layout: BufferLayout.struct<any>([
223
+ BufferLayout.u8('instruction'),
224
+ BufferLayout.ns64('poolTokens'),
225
+ ]),
226
+ },
227
+ })
228
+
229
+ /**
230
+ * Cleans up validator stake account entries marked as `ReadyForRemoval`
231
+ */
232
+ export type CleanupRemovedValidatorEntriesParams = {
233
+ programId?: PublicKey | undefined
234
+ stakePool: PublicKey
235
+ validatorList: PublicKey
236
+ }
237
+
238
+ /**
239
+ * Updates balances of validator and transient stake accounts in the pool.
240
+ */
241
+ export type UpdateValidatorListBalanceParams = {
242
+ programId?: PublicKey | undefined
243
+ stakePool: PublicKey
244
+ withdrawAuthority: PublicKey
245
+ validatorList: PublicKey
246
+ reserveStake: PublicKey
247
+ validatorAndTransientStakePairs: PublicKey[]
248
+ startIndex: number
249
+ noMerge: boolean
250
+ }
251
+
252
+ /**
253
+ * Updates total pool balance based on balances in the reserve and validator list.
254
+ */
255
+ export type UpdateStakePoolBalanceParams = {
256
+ programId?: PublicKey | undefined
257
+ stakePool: PublicKey
258
+ withdrawAuthority: PublicKey
259
+ validatorList: PublicKey
260
+ reserveStake: PublicKey
261
+ managerFeeAccount: PublicKey
262
+ poolMint: PublicKey
263
+ }
264
+
265
+ /**
266
+ * (Staker only) Decrease active stake on a validator, eventually moving it to the reserve
267
+ */
268
+ export type DecreaseValidatorStakeParams = {
269
+ programId?: PublicKey | undefined
270
+ stakePool: PublicKey
271
+ staker: PublicKey
272
+ withdrawAuthority: PublicKey
273
+ validatorList: PublicKey
274
+ validatorStake: PublicKey
275
+ transientStake: PublicKey
276
+ // Amount of lamports to split into the transient stake account
277
+ lamports: number
278
+ // Seed to used to create the transient stake account
279
+ transientStakeSeed: number
280
+ }
281
+
282
+ export interface DecreaseValidatorStakeWithReserveParams extends DecreaseValidatorStakeParams {
283
+ reserveStake: PublicKey
284
+ }
285
+
286
+ export interface DecreaseAdditionalValidatorStakeParams extends DecreaseValidatorStakeParams {
287
+ reserveStake: PublicKey
288
+ ephemeralStake: PublicKey
289
+ ephemeralStakeSeed: number
290
+ }
291
+
292
+ /**
293
+ * (Staker only) Increase stake on a validator from the reserve account.
294
+ */
295
+ export type IncreaseValidatorStakeParams = {
296
+ programId?: PublicKey | undefined
297
+ stakePool: PublicKey
298
+ staker: PublicKey
299
+ withdrawAuthority: PublicKey
300
+ validatorList: PublicKey
301
+ reserveStake: PublicKey
302
+ transientStake: PublicKey
303
+ validatorStake: PublicKey
304
+ validatorVote: PublicKey
305
+ // Amount of lamports to split into the transient stake account
306
+ lamports: number
307
+ // Seed to used to create the transient stake account
308
+ transientStakeSeed: number
309
+ }
310
+
311
+ export interface IncreaseAdditionalValidatorStakeParams extends IncreaseValidatorStakeParams {
312
+ ephemeralStake: PublicKey
313
+ ephemeralStakeSeed: number
314
+ }
315
+
316
+ /**
317
+ * Deposits a stake account into the pool in exchange for pool tokens
318
+ */
319
+ export type DepositStakeParams = {
320
+ programId?: PublicKey | undefined
321
+ stakePool: PublicKey
322
+ validatorList: PublicKey
323
+ depositAuthority: PublicKey
324
+ withdrawAuthority: PublicKey
325
+ depositStake: PublicKey
326
+ validatorStake: PublicKey
327
+ reserveStake: PublicKey
328
+ destinationPoolAccount: PublicKey
329
+ managerFeeAccount: PublicKey
330
+ referralPoolAccount: PublicKey
331
+ poolMint: PublicKey
332
+ }
333
+
334
+ /**
335
+ * Withdraws a stake account from the pool in exchange for pool tokens
336
+ */
337
+ export type WithdrawStakeParams = {
338
+ programId?: PublicKey | undefined
339
+ stakePool: PublicKey
340
+ validatorList: PublicKey
341
+ withdrawAuthority: PublicKey
342
+ validatorStake: PublicKey
343
+ destinationStake: PublicKey
344
+ destinationStakeAuthority: PublicKey
345
+ sourceTransferAuthority: PublicKey
346
+ sourcePoolAccount: PublicKey
347
+ managerFeeAccount: PublicKey
348
+ poolMint: PublicKey
349
+ poolTokens: number
350
+ }
351
+
352
+ /**
353
+ * Withdraw sol instruction params
354
+ */
355
+ export type WithdrawSolParams = {
356
+ programId?: PublicKey | undefined
357
+ stakePool: PublicKey
358
+ sourcePoolAccount: PublicKey
359
+ withdrawAuthority: PublicKey
360
+ reserveStake: PublicKey
361
+ destinationSystemAccount: PublicKey
362
+ sourceTransferAuthority: PublicKey
363
+ solWithdrawAuthority?: PublicKey | undefined
364
+ managerFeeAccount: PublicKey
365
+ poolMint: PublicKey
366
+ poolTokens: number
367
+ }
368
+
369
+ /**
370
+ * Withdraw WSOL with session instruction params
371
+ */
372
+ export type WithdrawWsolWithSessionParams = {
373
+ programId: PublicKey
374
+ stakePool: PublicKey
375
+ withdrawAuthority: PublicKey
376
+ userTransferAuthority: PublicKey
377
+ poolTokensFrom: PublicKey
378
+ reserveStake: PublicKey
379
+ userWsolAccount: PublicKey
380
+ managerFeeAccount: PublicKey
381
+ poolMint: PublicKey
382
+ tokenProgramId: PublicKey
383
+ solWithdrawAuthority?: PublicKey
384
+ wsolMint: PublicKey
385
+ programSigner: PublicKey
386
+ poolTokens: number
387
+ }
388
+
389
+ /**
390
+ * Deposit SOL directly into the pool's reserve account. The output is a "pool" token
391
+ * representing ownership into the pool. Inputs are converted to the current ratio.
392
+ */
393
+ export type DepositSolParams = {
394
+ programId?: PublicKey | undefined
395
+ stakePool: PublicKey
396
+ depositAuthority?: PublicKey | undefined
397
+ withdrawAuthority: PublicKey
398
+ reserveStake: PublicKey
399
+ fundingAccount: PublicKey
400
+ destinationPoolAccount: PublicKey
401
+ managerFeeAccount: PublicKey
402
+ referralPoolAccount: PublicKey
403
+ poolMint: PublicKey
404
+ lamports: number
405
+ }
406
+
407
+ export type CreateTokenMetadataParams = {
408
+ programId?: PublicKey | undefined
409
+ stakePool: PublicKey
410
+ manager: PublicKey
411
+ tokenMetadata: PublicKey
412
+ withdrawAuthority: PublicKey
413
+ poolMint: PublicKey
414
+ payer: PublicKey
415
+ name: string
416
+ symbol: string
417
+ uri: string
418
+ }
419
+
420
+ export type UpdateTokenMetadataParams = {
421
+ programId?: PublicKey | undefined
422
+ stakePool: PublicKey
423
+ manager: PublicKey
424
+ tokenMetadata: PublicKey
425
+ withdrawAuthority: PublicKey
426
+ name: string
427
+ symbol: string
428
+ uri: string
429
+ }
430
+
431
+ export type AddValidatorToPoolParams = {
432
+ programId?: PublicKey | undefined
433
+ stakePool: PublicKey
434
+ staker: PublicKey
435
+ reserveStake: PublicKey
436
+ withdrawAuthority: PublicKey
437
+ validatorList: PublicKey
438
+ validatorStake: PublicKey
439
+ validatorVote: PublicKey
440
+ seed?: number
441
+ }
442
+
443
+ export type RemoveValidatorFromPoolParams = {
444
+ programId?: PublicKey | undefined
445
+ stakePool: PublicKey
446
+ staker: PublicKey
447
+ withdrawAuthority: PublicKey
448
+ validatorList: PublicKey
449
+ validatorStake: PublicKey
450
+ transientStake: PublicKey
451
+ }
452
+
453
+ /**
454
+ * Stake Pool Instruction class
455
+ */
456
+ export class StakePoolInstruction {
457
+ /**
458
+ * Creates instruction to add a validator into the stake pool.
459
+ */
460
+ static addValidatorToPool(params: AddValidatorToPoolParams): TransactionInstruction {
461
+ const {
462
+ programId,
463
+ stakePool,
464
+ staker,
465
+ reserveStake,
466
+ withdrawAuthority,
467
+ validatorList,
468
+ validatorStake,
469
+ validatorVote,
470
+ seed,
471
+ } = params
472
+ const type = STAKE_POOL_INSTRUCTION_LAYOUTS.AddValidatorToPool
473
+ const data = encodeData(type, { seed: seed ?? 0 })
474
+
475
+ const keys = [
476
+ { pubkey: stakePool, isSigner: false, isWritable: true },
477
+ { pubkey: staker, isSigner: true, isWritable: false },
478
+ { pubkey: reserveStake, isSigner: false, isWritable: true },
479
+ { pubkey: withdrawAuthority, isSigner: false, isWritable: false },
480
+ { pubkey: validatorList, isSigner: false, isWritable: true },
481
+ { pubkey: validatorStake, isSigner: false, isWritable: true },
482
+ { pubkey: validatorVote, isSigner: false, isWritable: false },
483
+ { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
484
+ { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },
485
+ { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false },
486
+ { pubkey: STAKE_CONFIG_ID, isSigner: false, isWritable: false },
487
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
488
+ { pubkey: StakeProgram.programId, isSigner: false, isWritable: false },
489
+ ]
490
+
491
+ return new TransactionInstruction({
492
+ programId: programId ?? STAKE_POOL_PROGRAM_ID,
493
+ keys,
494
+ data,
495
+ })
496
+ }
497
+
498
+ /**
499
+ * Creates instruction to remove a validator from the stake pool.
500
+ */
501
+ static removeValidatorFromPool(params: RemoveValidatorFromPoolParams): TransactionInstruction {
502
+ const {
503
+ programId,
504
+ stakePool,
505
+ staker,
506
+ withdrawAuthority,
507
+ validatorList,
508
+ validatorStake,
509
+ transientStake,
510
+ } = params
511
+ const type = STAKE_POOL_INSTRUCTION_LAYOUTS.RemoveValidatorFromPool
512
+ const data = encodeData(type)
513
+
514
+ const keys = [
515
+ { pubkey: stakePool, isSigner: false, isWritable: true },
516
+ { pubkey: staker, isSigner: true, isWritable: false },
517
+ { pubkey: withdrawAuthority, isSigner: false, isWritable: false },
518
+ { pubkey: validatorList, isSigner: false, isWritable: true },
519
+ { pubkey: validatorStake, isSigner: false, isWritable: true },
520
+ { pubkey: transientStake, isSigner: false, isWritable: true },
521
+ { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },
522
+ { pubkey: StakeProgram.programId, isSigner: false, isWritable: false },
523
+ ]
524
+
525
+ return new TransactionInstruction({
526
+ programId: programId ?? STAKE_POOL_PROGRAM_ID,
527
+ keys,
528
+ data,
529
+ })
530
+ }
531
+
532
+ /**
533
+ * Creates instruction to update a set of validators in the stake pool.
534
+ */
535
+ static updateValidatorListBalance(
536
+ params: UpdateValidatorListBalanceParams,
537
+ ): TransactionInstruction {
538
+ const {
539
+ programId,
540
+ stakePool,
541
+ withdrawAuthority,
542
+ validatorList,
543
+ reserveStake,
544
+ startIndex,
545
+ noMerge,
546
+ validatorAndTransientStakePairs,
547
+ } = params
548
+
549
+ const type = STAKE_POOL_INSTRUCTION_LAYOUTS.UpdateValidatorListBalance
550
+ const data = encodeData(type, { startIndex, noMerge: noMerge ? 1 : 0 })
551
+
552
+ const keys = [
553
+ { pubkey: stakePool, isSigner: false, isWritable: false },
554
+ { pubkey: withdrawAuthority, isSigner: false, isWritable: false },
555
+ { pubkey: validatorList, isSigner: false, isWritable: true },
556
+ { pubkey: reserveStake, isSigner: false, isWritable: true },
557
+ { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },
558
+ { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false },
559
+ { pubkey: StakeProgram.programId, isSigner: false, isWritable: false },
560
+ ...validatorAndTransientStakePairs.map(pubkey => ({
561
+ pubkey,
562
+ isSigner: false,
563
+ isWritable: true,
564
+ })),
565
+ ]
566
+
567
+ return new TransactionInstruction({
568
+ programId: programId ?? STAKE_POOL_PROGRAM_ID,
569
+ keys,
570
+ data,
571
+ })
572
+ }
573
+
574
+ /**
575
+ * Creates instruction to update the overall stake pool balance.
576
+ */
577
+ static updateStakePoolBalance(params: UpdateStakePoolBalanceParams): TransactionInstruction {
578
+ const {
579
+ programId,
580
+ stakePool,
581
+ withdrawAuthority,
582
+ validatorList,
583
+ reserveStake,
584
+ managerFeeAccount,
585
+ poolMint,
586
+ } = params
587
+
588
+ const type = STAKE_POOL_INSTRUCTION_LAYOUTS.UpdateStakePoolBalance
589
+ const data = encodeData(type)
590
+
591
+ const keys = [
592
+ { pubkey: stakePool, isSigner: false, isWritable: true },
593
+ { pubkey: withdrawAuthority, isSigner: false, isWritable: false },
594
+ { pubkey: validatorList, isSigner: false, isWritable: true },
595
+ { pubkey: reserveStake, isSigner: false, isWritable: false },
596
+ { pubkey: managerFeeAccount, isSigner: false, isWritable: true },
597
+ { pubkey: poolMint, isSigner: false, isWritable: true },
598
+ { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
599
+ ]
600
+
601
+ return new TransactionInstruction({
602
+ programId: programId ?? STAKE_POOL_PROGRAM_ID,
603
+ keys,
604
+ data,
605
+ })
606
+ }
607
+
608
+ /**
609
+ * Creates instruction to cleanup removed validator entries.
610
+ */
611
+ static cleanupRemovedValidatorEntries(
612
+ params: CleanupRemovedValidatorEntriesParams,
613
+ ): TransactionInstruction {
614
+ const { programId, stakePool, validatorList } = params
615
+
616
+ const type = STAKE_POOL_INSTRUCTION_LAYOUTS.CleanupRemovedValidatorEntries
617
+ const data = encodeData(type)
618
+
619
+ const keys = [
620
+ { pubkey: stakePool, isSigner: false, isWritable: false },
621
+ { pubkey: validatorList, isSigner: false, isWritable: true },
622
+ ]
623
+
624
+ return new TransactionInstruction({
625
+ programId: programId ?? STAKE_POOL_PROGRAM_ID,
626
+ keys,
627
+ data,
628
+ })
629
+ }
630
+
631
+ /**
632
+ * Creates `IncreaseValidatorStake` instruction (rebalance from reserve account to
633
+ * transient account)
634
+ */
635
+ static increaseValidatorStake(params: IncreaseValidatorStakeParams): TransactionInstruction {
636
+ const {
637
+ programId,
638
+ stakePool,
639
+ staker,
640
+ withdrawAuthority,
641
+ validatorList,
642
+ reserveStake,
643
+ transientStake,
644
+ validatorStake,
645
+ validatorVote,
646
+ lamports,
647
+ transientStakeSeed,
648
+ } = params
649
+
650
+ const type = STAKE_POOL_INSTRUCTION_LAYOUTS.IncreaseValidatorStake
651
+ const data = encodeData(type, { lamports, transientStakeSeed })
652
+
653
+ const keys = [
654
+ { pubkey: stakePool, isSigner: false, isWritable: false },
655
+ { pubkey: staker, isSigner: true, isWritable: false },
656
+ { pubkey: withdrawAuthority, isSigner: false, isWritable: false },
657
+ { pubkey: validatorList, isSigner: false, isWritable: true },
658
+ { pubkey: reserveStake, isSigner: false, isWritable: true },
659
+ { pubkey: transientStake, isSigner: false, isWritable: true },
660
+ { pubkey: validatorStake, isSigner: false, isWritable: false },
661
+ { pubkey: validatorVote, isSigner: false, isWritable: false },
662
+ { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },
663
+ { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
664
+ { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false },
665
+ { pubkey: STAKE_CONFIG_ID, isSigner: false, isWritable: false },
666
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
667
+ { pubkey: StakeProgram.programId, isSigner: false, isWritable: false },
668
+ ]
669
+
670
+ return new TransactionInstruction({
671
+ programId: programId ?? STAKE_POOL_PROGRAM_ID,
672
+ keys,
673
+ data,
674
+ })
675
+ }
676
+
677
+ /**
678
+ * Creates `IncreaseAdditionalValidatorStake` instruction (rebalance from reserve account to
679
+ * transient account)
680
+ */
681
+ static increaseAdditionalValidatorStake(
682
+ params: IncreaseAdditionalValidatorStakeParams,
683
+ ): TransactionInstruction {
684
+ const {
685
+ programId,
686
+ stakePool,
687
+ staker,
688
+ withdrawAuthority,
689
+ validatorList,
690
+ reserveStake,
691
+ transientStake,
692
+ validatorStake,
693
+ validatorVote,
694
+ lamports,
695
+ transientStakeSeed,
696
+ ephemeralStake,
697
+ ephemeralStakeSeed,
698
+ } = params
699
+
700
+ const type = STAKE_POOL_INSTRUCTION_LAYOUTS.IncreaseAdditionalValidatorStake
701
+ const data = encodeData(type, { lamports, transientStakeSeed, ephemeralStakeSeed })
702
+
703
+ const keys = [
704
+ { pubkey: stakePool, isSigner: false, isWritable: false },
705
+ { pubkey: staker, isSigner: true, isWritable: false },
706
+ { pubkey: withdrawAuthority, isSigner: false, isWritable: false },
707
+ { pubkey: validatorList, isSigner: false, isWritable: true },
708
+ { pubkey: reserveStake, isSigner: false, isWritable: true },
709
+ { pubkey: ephemeralStake, isSigner: false, isWritable: true },
710
+ { pubkey: transientStake, isSigner: false, isWritable: true },
711
+ { pubkey: validatorStake, isSigner: false, isWritable: false },
712
+ { pubkey: validatorVote, isSigner: false, isWritable: false },
713
+ { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },
714
+ { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false },
715
+ { pubkey: STAKE_CONFIG_ID, isSigner: false, isWritable: false },
716
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
717
+ { pubkey: StakeProgram.programId, isSigner: false, isWritable: false },
718
+ ]
719
+
720
+ return new TransactionInstruction({
721
+ programId: programId ?? STAKE_POOL_PROGRAM_ID,
722
+ keys,
723
+ data,
724
+ })
725
+ }
726
+
727
+ /**
728
+ * Creates `DecreaseValidatorStake` instruction (rebalance from validator account to
729
+ * transient account)
730
+ */
731
+ static decreaseValidatorStake(params: DecreaseValidatorStakeParams): TransactionInstruction {
732
+ const {
733
+ programId,
734
+ stakePool,
735
+ staker,
736
+ withdrawAuthority,
737
+ validatorList,
738
+ validatorStake,
739
+ transientStake,
740
+ lamports,
741
+ transientStakeSeed,
742
+ } = params
743
+
744
+ const type = STAKE_POOL_INSTRUCTION_LAYOUTS.DecreaseValidatorStake
745
+ const data = encodeData(type, { lamports, transientStakeSeed })
746
+
747
+ const keys = [
748
+ { pubkey: stakePool, isSigner: false, isWritable: false },
749
+ { pubkey: staker, isSigner: true, isWritable: false },
750
+ { pubkey: withdrawAuthority, isSigner: false, isWritable: false },
751
+ { pubkey: validatorList, isSigner: false, isWritable: true },
752
+ { pubkey: validatorStake, isSigner: false, isWritable: true },
753
+ { pubkey: transientStake, isSigner: false, isWritable: true },
754
+ { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },
755
+ { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
756
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
757
+ { pubkey: StakeProgram.programId, isSigner: false, isWritable: false },
758
+ ]
759
+
760
+ return new TransactionInstruction({
761
+ programId: programId ?? STAKE_POOL_PROGRAM_ID,
762
+ keys,
763
+ data,
764
+ })
765
+ }
766
+
767
+ /**
768
+ * Creates `DecreaseValidatorStakeWithReserve` instruction (rebalance from
769
+ * validator account to transient account)
770
+ */
771
+ static decreaseValidatorStakeWithReserve(
772
+ params: DecreaseValidatorStakeWithReserveParams,
773
+ ): TransactionInstruction {
774
+ const {
775
+ programId,
776
+ stakePool,
777
+ staker,
778
+ withdrawAuthority,
779
+ validatorList,
780
+ reserveStake,
781
+ validatorStake,
782
+ transientStake,
783
+ lamports,
784
+ transientStakeSeed,
785
+ } = params
786
+
787
+ const type = STAKE_POOL_INSTRUCTION_LAYOUTS.DecreaseValidatorStakeWithReserve
788
+ const data = encodeData(type, { lamports, transientStakeSeed })
789
+
790
+ const keys = [
791
+ { pubkey: stakePool, isSigner: false, isWritable: false },
792
+ { pubkey: staker, isSigner: true, isWritable: false },
793
+ { pubkey: withdrawAuthority, isSigner: false, isWritable: false },
794
+ { pubkey: validatorList, isSigner: false, isWritable: true },
795
+ { pubkey: reserveStake, isSigner: false, isWritable: true },
796
+ { pubkey: validatorStake, isSigner: false, isWritable: true },
797
+ { pubkey: transientStake, isSigner: false, isWritable: true },
798
+ { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },
799
+ { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false },
800
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
801
+ { pubkey: StakeProgram.programId, isSigner: false, isWritable: false },
802
+ ]
803
+
804
+ return new TransactionInstruction({
805
+ programId: programId ?? STAKE_POOL_PROGRAM_ID,
806
+ keys,
807
+ data,
808
+ })
809
+ }
810
+
811
+ /**
812
+ * Creates `DecreaseAdditionalValidatorStake` instruction (rebalance from
813
+ * validator account to transient account)
814
+ */
815
+ static decreaseAdditionalValidatorStake(
816
+ params: DecreaseAdditionalValidatorStakeParams,
817
+ ): TransactionInstruction {
818
+ const {
819
+ programId,
820
+ stakePool,
821
+ staker,
822
+ withdrawAuthority,
823
+ validatorList,
824
+ reserveStake,
825
+ validatorStake,
826
+ transientStake,
827
+ lamports,
828
+ transientStakeSeed,
829
+ ephemeralStakeSeed,
830
+ ephemeralStake,
831
+ } = params
832
+
833
+ const type = STAKE_POOL_INSTRUCTION_LAYOUTS.DecreaseAdditionalValidatorStake
834
+ const data = encodeData(type, { lamports, transientStakeSeed, ephemeralStakeSeed })
835
+
836
+ const keys = [
837
+ { pubkey: stakePool, isSigner: false, isWritable: false },
838
+ { pubkey: staker, isSigner: true, isWritable: false },
839
+ { pubkey: withdrawAuthority, isSigner: false, isWritable: false },
840
+ { pubkey: validatorList, isSigner: false, isWritable: true },
841
+ { pubkey: reserveStake, isSigner: false, isWritable: true },
842
+ { pubkey: validatorStake, isSigner: false, isWritable: true },
843
+ { pubkey: ephemeralStake, isSigner: false, isWritable: true },
844
+ { pubkey: transientStake, isSigner: false, isWritable: true },
845
+ { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },
846
+ { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false },
847
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
848
+ { pubkey: StakeProgram.programId, isSigner: false, isWritable: false },
849
+ ]
850
+
851
+ return new TransactionInstruction({
852
+ programId: programId ?? STAKE_POOL_PROGRAM_ID,
853
+ keys,
854
+ data,
855
+ })
856
+ }
857
+
858
+ /**
859
+ * Creates a transaction instruction to deposit a stake account into a stake pool.
860
+ */
861
+ static depositStake(params: DepositStakeParams): TransactionInstruction {
862
+ const {
863
+ programId,
864
+ stakePool,
865
+ validatorList,
866
+ depositAuthority,
867
+ withdrawAuthority,
868
+ depositStake,
869
+ validatorStake,
870
+ reserveStake,
871
+ destinationPoolAccount,
872
+ managerFeeAccount,
873
+ referralPoolAccount,
874
+ poolMint,
875
+ } = params
876
+
877
+ const type = STAKE_POOL_INSTRUCTION_LAYOUTS.DepositStake
878
+ const data = encodeData(type)
879
+
880
+ const keys = [
881
+ { pubkey: stakePool, isSigner: false, isWritable: true },
882
+ { pubkey: validatorList, isSigner: false, isWritable: true },
883
+ { pubkey: depositAuthority, isSigner: false, isWritable: false },
884
+ { pubkey: withdrawAuthority, isSigner: false, isWritable: false },
885
+ { pubkey: depositStake, isSigner: false, isWritable: true },
886
+ { pubkey: validatorStake, isSigner: false, isWritable: true },
887
+ { pubkey: reserveStake, isSigner: false, isWritable: true },
888
+ { pubkey: destinationPoolAccount, isSigner: false, isWritable: true },
889
+ { pubkey: managerFeeAccount, isSigner: false, isWritable: true },
890
+ { pubkey: referralPoolAccount, isSigner: false, isWritable: true },
891
+ { pubkey: poolMint, isSigner: false, isWritable: true },
892
+ { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },
893
+ { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false },
894
+ { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
895
+ { pubkey: StakeProgram.programId, isSigner: false, isWritable: false },
896
+ ]
897
+
898
+ return new TransactionInstruction({
899
+ programId: programId ?? STAKE_POOL_PROGRAM_ID,
900
+ keys,
901
+ data,
902
+ })
903
+ }
904
+
905
+ /**
906
+ * Creates a transaction instruction to deposit SOL into a stake pool.
907
+ */
908
+ static depositSol(params: DepositSolParams): TransactionInstruction {
909
+ const {
910
+ programId,
911
+ stakePool,
912
+ withdrawAuthority,
913
+ depositAuthority,
914
+ reserveStake,
915
+ fundingAccount,
916
+ destinationPoolAccount,
917
+ managerFeeAccount,
918
+ referralPoolAccount,
919
+ poolMint,
920
+ lamports,
921
+ } = params
922
+
923
+ const type = STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol
924
+ const data = encodeData(type, { lamports })
925
+
926
+ const keys = [
927
+ { pubkey: stakePool, isSigner: false, isWritable: true },
928
+ { pubkey: withdrawAuthority, isSigner: false, isWritable: false },
929
+ { pubkey: reserveStake, isSigner: false, isWritable: true },
930
+ { pubkey: fundingAccount, isSigner: true, isWritable: true },
931
+ { pubkey: destinationPoolAccount, isSigner: false, isWritable: true },
932
+ { pubkey: managerFeeAccount, isSigner: false, isWritable: true },
933
+ { pubkey: referralPoolAccount, isSigner: false, isWritable: true },
934
+ { pubkey: poolMint, isSigner: false, isWritable: true },
935
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
936
+ { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
937
+ ]
938
+
939
+ if (depositAuthority) {
940
+ keys.push({
941
+ pubkey: depositAuthority,
942
+ isSigner: true,
943
+ isWritable: false,
944
+ })
945
+ }
946
+
947
+ return new TransactionInstruction({
948
+ programId: programId ?? STAKE_POOL_PROGRAM_ID,
949
+ keys,
950
+ data,
951
+ })
952
+ }
953
+
954
+ /**
955
+ * Creates a transaction instruction to deposit WSOL into a stake pool.
956
+ */
957
+ static depositWsolWithSession(params: DepositSolParams & {
958
+ wsolMint: PublicKey
959
+ wsolTokenAccount: PublicKey
960
+ wsolTransientAccount: PublicKey
961
+ programSigner: PublicKey
962
+ tokenProgramId: PublicKey
963
+ programId: PublicKey
964
+ payer?: PublicKey
965
+ }): TransactionInstruction {
966
+ const type = STAKE_POOL_INSTRUCTION_LAYOUTS.DepositWsolWithSession
967
+ const data = encodeData(type, { lamports: params.lamports })
968
+
969
+ const keys = [
970
+ { pubkey: params.stakePool, isSigner: false, isWritable: true },
971
+ { pubkey: params.withdrawAuthority, isSigner: false, isWritable: false },
972
+ { pubkey: params.reserveStake, isSigner: false, isWritable: true },
973
+ { pubkey: params.fundingAccount, isSigner: true, isWritable: true },
974
+ { pubkey: params.destinationPoolAccount, isSigner: false, isWritable: true },
975
+ { pubkey: params.managerFeeAccount, isSigner: false, isWritable: true },
976
+ { pubkey: params.referralPoolAccount, isSigner: false, isWritable: true },
977
+ { pubkey: params.poolMint, isSigner: false, isWritable: true },
978
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
979
+ { pubkey: params.tokenProgramId, isSigner: false, isWritable: false },
980
+
981
+ // wsol specific accounts
982
+ { pubkey: params.wsolMint, isSigner: false, isWritable: false },
983
+ { pubkey: params.wsolTokenAccount, isSigner: false, isWritable: true },
984
+ { pubkey: params.wsolTransientAccount, isSigner: false, isWritable: true },
985
+ { pubkey: params.programSigner, isSigner: false, isWritable: true },
986
+ { pubkey: params.payer ?? params.fundingAccount, isSigner: true, isWritable: true },
987
+ ]
988
+
989
+ if (params.depositAuthority) {
990
+ keys.push({
991
+ pubkey: params.depositAuthority,
992
+ isSigner: true,
993
+ isWritable: false,
994
+ })
995
+ }
996
+
997
+ return new TransactionInstruction({
998
+ programId: params.programId,
999
+ keys,
1000
+ data,
1001
+ })
1002
+ }
1003
+
1004
+ /**
1005
+ * Creates a transaction instruction to withdraw active stake from a stake pool.
1006
+ */
1007
+ static withdrawStake(params: WithdrawStakeParams): TransactionInstruction {
1008
+ const {
1009
+ programId,
1010
+ stakePool,
1011
+ validatorList,
1012
+ withdrawAuthority,
1013
+ validatorStake,
1014
+ destinationStake,
1015
+ destinationStakeAuthority,
1016
+ sourceTransferAuthority,
1017
+ sourcePoolAccount,
1018
+ managerFeeAccount,
1019
+ poolMint,
1020
+ poolTokens,
1021
+ } = params
1022
+
1023
+ const type = STAKE_POOL_INSTRUCTION_LAYOUTS.WithdrawStake
1024
+ const data = encodeData(type, { poolTokens })
1025
+
1026
+ const keys = [
1027
+ { pubkey: stakePool, isSigner: false, isWritable: true },
1028
+ { pubkey: validatorList, isSigner: false, isWritable: true },
1029
+ { pubkey: withdrawAuthority, isSigner: false, isWritable: false },
1030
+ { pubkey: validatorStake, isSigner: false, isWritable: true },
1031
+ { pubkey: destinationStake, isSigner: false, isWritable: true },
1032
+ { pubkey: destinationStakeAuthority, isSigner: false, isWritable: false },
1033
+ { pubkey: sourceTransferAuthority, isSigner: true, isWritable: false },
1034
+ { pubkey: sourcePoolAccount, isSigner: false, isWritable: true },
1035
+ { pubkey: managerFeeAccount, isSigner: false, isWritable: true },
1036
+ { pubkey: poolMint, isSigner: false, isWritable: true },
1037
+ { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },
1038
+ { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
1039
+ { pubkey: StakeProgram.programId, isSigner: false, isWritable: false },
1040
+ ]
1041
+
1042
+ return new TransactionInstruction({
1043
+ programId: programId ?? STAKE_POOL_PROGRAM_ID,
1044
+ keys,
1045
+ data,
1046
+ })
1047
+ }
1048
+
1049
+ /**
1050
+ * Creates a transaction instruction to withdraw SOL from a stake pool.
1051
+ */
1052
+ static withdrawSol(params: WithdrawSolParams): TransactionInstruction {
1053
+ const {
1054
+ programId,
1055
+ stakePool,
1056
+ withdrawAuthority,
1057
+ sourceTransferAuthority,
1058
+ sourcePoolAccount,
1059
+ reserveStake,
1060
+ destinationSystemAccount,
1061
+ managerFeeAccount,
1062
+ solWithdrawAuthority,
1063
+ poolMint,
1064
+ poolTokens,
1065
+ } = params
1066
+
1067
+ const type = STAKE_POOL_INSTRUCTION_LAYOUTS.WithdrawSol
1068
+ const data = encodeData(type, { poolTokens })
1069
+
1070
+ const keys = [
1071
+ { pubkey: stakePool, isSigner: false, isWritable: true },
1072
+ { pubkey: withdrawAuthority, isSigner: false, isWritable: false },
1073
+ { pubkey: sourceTransferAuthority, isSigner: true, isWritable: false },
1074
+ { pubkey: sourcePoolAccount, isSigner: false, isWritable: true },
1075
+ { pubkey: reserveStake, isSigner: false, isWritable: true },
1076
+ { pubkey: destinationSystemAccount, isSigner: false, isWritable: true },
1077
+ { pubkey: managerFeeAccount, isSigner: false, isWritable: true },
1078
+ { pubkey: poolMint, isSigner: false, isWritable: true },
1079
+ { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },
1080
+ { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false },
1081
+ { pubkey: StakeProgram.programId, isSigner: false, isWritable: false },
1082
+ { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
1083
+ ]
1084
+
1085
+ if (solWithdrawAuthority) {
1086
+ keys.push({
1087
+ pubkey: solWithdrawAuthority,
1088
+ isSigner: true,
1089
+ isWritable: false,
1090
+ })
1091
+ }
1092
+
1093
+ return new TransactionInstruction({
1094
+ programId: programId ?? STAKE_POOL_PROGRAM_ID,
1095
+ keys,
1096
+ data,
1097
+ })
1098
+ }
1099
+
1100
+ /**
1101
+ * Creates a transaction instruction to withdraw WSOL from a stake pool using a session.
1102
+ */
1103
+ static withdrawWsolWithSession(
1104
+ params: WithdrawWsolWithSessionParams,
1105
+ ): TransactionInstruction {
1106
+ const type = STAKE_POOL_INSTRUCTION_LAYOUTS.WithdrawWsolWithSession
1107
+ const data = encodeData(type, { poolTokens: params.poolTokens })
1108
+
1109
+ const keys = [
1110
+ { pubkey: params.stakePool, isSigner: false, isWritable: true },
1111
+ { pubkey: params.withdrawAuthority, isSigner: false, isWritable: false },
1112
+ { pubkey: params.userTransferAuthority, isSigner: true, isWritable: true },
1113
+ { pubkey: params.poolTokensFrom, isSigner: false, isWritable: true },
1114
+ { pubkey: params.reserveStake, isSigner: false, isWritable: true },
1115
+ { pubkey: params.userWsolAccount, isSigner: false, isWritable: true },
1116
+ { pubkey: params.managerFeeAccount, isSigner: false, isWritable: true },
1117
+ { pubkey: params.poolMint, isSigner: false, isWritable: true },
1118
+ { pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },
1119
+ { pubkey: SYSVAR_STAKE_HISTORY_PUBKEY, isSigner: false, isWritable: false },
1120
+ { pubkey: StakeProgram.programId, isSigner: false, isWritable: false },
1121
+ { pubkey: params.tokenProgramId, isSigner: false, isWritable: false },
1122
+
1123
+ { pubkey: params.wsolMint, isSigner: false, isWritable: false },
1124
+ { pubkey: params.programSigner, isSigner: false, isWritable: true },
1125
+ ]
1126
+
1127
+ if (params.solWithdrawAuthority) {
1128
+ keys.push({
1129
+ pubkey: params.solWithdrawAuthority,
1130
+ isSigner: true,
1131
+ isWritable: false,
1132
+ })
1133
+ }
1134
+
1135
+ return new TransactionInstruction({
1136
+ programId: params.programId,
1137
+ keys,
1138
+ data,
1139
+ })
1140
+ }
1141
+
1142
+ /**
1143
+ * Creates an instruction to create metadata
1144
+ * using the mpl token metadata program for the pool token
1145
+ */
1146
+ static createTokenMetadata(params: CreateTokenMetadataParams): TransactionInstruction {
1147
+ const {
1148
+ programId,
1149
+ stakePool,
1150
+ withdrawAuthority,
1151
+ tokenMetadata,
1152
+ manager,
1153
+ payer,
1154
+ poolMint,
1155
+ name,
1156
+ symbol,
1157
+ uri,
1158
+ } = params
1159
+
1160
+ const keys = [
1161
+ { pubkey: stakePool, isSigner: false, isWritable: false },
1162
+ { pubkey: manager, isSigner: true, isWritable: false },
1163
+ { pubkey: withdrawAuthority, isSigner: false, isWritable: false },
1164
+ { pubkey: poolMint, isSigner: false, isWritable: false },
1165
+ { pubkey: payer, isSigner: true, isWritable: true },
1166
+ { pubkey: tokenMetadata, isSigner: false, isWritable: true },
1167
+ { pubkey: METADATA_PROGRAM_ID, isSigner: false, isWritable: false },
1168
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
1169
+ { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
1170
+ ]
1171
+
1172
+ const type = tokenMetadataLayout(17, name.length, symbol.length, uri.length)
1173
+ const data = encodeData(type, {
1174
+ nameLen: name.length,
1175
+ name: Buffer.from(name),
1176
+ symbolLen: symbol.length,
1177
+ symbol: Buffer.from(symbol),
1178
+ uriLen: uri.length,
1179
+ uri: Buffer.from(uri),
1180
+ })
1181
+
1182
+ return new TransactionInstruction({
1183
+ programId: programId ?? STAKE_POOL_PROGRAM_ID,
1184
+ keys,
1185
+ data,
1186
+ })
1187
+ }
1188
+
1189
+ /**
1190
+ * Creates an instruction to update metadata
1191
+ * in the mpl token metadata program account for the pool token
1192
+ */
1193
+ static updateTokenMetadata(params: UpdateTokenMetadataParams): TransactionInstruction {
1194
+ const { programId, stakePool, withdrawAuthority, tokenMetadata, manager, name, symbol, uri }
1195
+ = params
1196
+
1197
+ const keys = [
1198
+ { pubkey: stakePool, isSigner: false, isWritable: false },
1199
+ { pubkey: manager, isSigner: true, isWritable: false },
1200
+ { pubkey: withdrawAuthority, isSigner: false, isWritable: false },
1201
+ { pubkey: tokenMetadata, isSigner: false, isWritable: true },
1202
+ { pubkey: METADATA_PROGRAM_ID, isSigner: false, isWritable: false },
1203
+ ]
1204
+
1205
+ const type = tokenMetadataLayout(18, name.length, symbol.length, uri.length)
1206
+ const data = encodeData(type, {
1207
+ nameLen: name.length,
1208
+ name: Buffer.from(name),
1209
+ symbolLen: symbol.length,
1210
+ symbol: Buffer.from(symbol),
1211
+ uriLen: uri.length,
1212
+ uri: Buffer.from(uri),
1213
+ })
1214
+
1215
+ return new TransactionInstruction({
1216
+ programId: programId ?? STAKE_POOL_PROGRAM_ID,
1217
+ keys,
1218
+ data,
1219
+ })
1220
+ }
1221
+
1222
+ /**
1223
+ * Decode a deposit stake pool instruction and retrieve the instruction params.
1224
+ */
1225
+ static decodeDepositStake(instruction: TransactionInstruction): DepositStakeParams {
1226
+ this.checkProgramId(instruction.programId)
1227
+ this.checkKeyLength(instruction.keys, 11)
1228
+
1229
+ decodeData(STAKE_POOL_INSTRUCTION_LAYOUTS.DepositStake, instruction.data)
1230
+
1231
+ return {
1232
+ programId: instruction.programId,
1233
+ stakePool: instruction.keys[0].pubkey,
1234
+ validatorList: instruction.keys[1].pubkey,
1235
+ depositAuthority: instruction.keys[2].pubkey,
1236
+ withdrawAuthority: instruction.keys[3].pubkey,
1237
+ depositStake: instruction.keys[4].pubkey,
1238
+ validatorStake: instruction.keys[5].pubkey,
1239
+ reserveStake: instruction.keys[6].pubkey,
1240
+ destinationPoolAccount: instruction.keys[7].pubkey,
1241
+ managerFeeAccount: instruction.keys[8].pubkey,
1242
+ referralPoolAccount: instruction.keys[9].pubkey,
1243
+ poolMint: instruction.keys[10].pubkey,
1244
+ }
1245
+ }
1246
+
1247
+ /**
1248
+ * Decode a deposit sol instruction and retrieve the instruction params.
1249
+ */
1250
+ static decodeDepositSol(instruction: TransactionInstruction): DepositSolParams {
1251
+ this.checkProgramId(instruction.programId)
1252
+ this.checkKeyLength(instruction.keys, 9)
1253
+
1254
+ const { amount } = decodeData(STAKE_POOL_INSTRUCTION_LAYOUTS.DepositSol, instruction.data)
1255
+
1256
+ return {
1257
+ programId: instruction.programId,
1258
+ stakePool: instruction.keys[0].pubkey,
1259
+ depositAuthority: instruction.keys[1].pubkey,
1260
+ withdrawAuthority: instruction.keys[2].pubkey,
1261
+ reserveStake: instruction.keys[3].pubkey,
1262
+ fundingAccount: instruction.keys[4].pubkey,
1263
+ destinationPoolAccount: instruction.keys[5].pubkey,
1264
+ managerFeeAccount: instruction.keys[6].pubkey,
1265
+ referralPoolAccount: instruction.keys[7].pubkey,
1266
+ poolMint: instruction.keys[8].pubkey,
1267
+ lamports: amount,
1268
+ }
1269
+ }
1270
+
1271
+ /**
1272
+ * @internal
1273
+ */
1274
+ private static checkProgramId(programId: PublicKey) {
1275
+ if (
1276
+ !programId.equals(STAKE_POOL_PROGRAM_ID)
1277
+ && !programId.equals(DEVNET_STAKE_POOL_PROGRAM_ID)
1278
+ ) {
1279
+ throw new Error('Invalid instruction; programId is not the stake pool program')
1280
+ }
1281
+ }
1282
+
1283
+ /**
1284
+ * @internal
1285
+ */
1286
+ private static checkKeyLength(keys: Array<any>, expectedLength: number) {
1287
+ if (keys.length < expectedLength) {
1288
+ throw new Error(
1289
+ `Invalid instruction; found ${keys.length} keys, expected at least ${expectedLength}`,
1290
+ )
1291
+ }
1292
+ }
1293
+ }