1#![allow(deprecated)]
5
6#[cfg(feature = "codama")]
7use codama_macros::{CodamaInstructions, CodamaType};
8use {
9 crate::state::{Authorized, Lockup, StakeAuthorize},
10 solana_clock::{Epoch, UnixTimestamp},
11 solana_pubkey::Pubkey,
12};
13#[cfg(feature = "bincode")]
14use {
15 crate::{program::ID, state::StakeStateV2},
16 solana_instruction::{AccountMeta, Instruction},
17};
18
19#[cfg_attr(
24 feature = "serde",
25 derive(serde_derive::Deserialize, serde_derive::Serialize)
26)]
27#[cfg_attr(feature = "codama", derive(CodamaInstructions))]
28#[cfg_attr(feature = "codama", codama(enum_discriminator(size = number(u32))))]
29#[cfg_attr(feature = "codama", codama(optional_account_strategy = omitted))]
30#[derive(Debug, PartialEq, Eq, Clone)]
31pub enum StakeInstruction {
32 #[cfg_attr(
41 feature = "codama",
42 codama(display(
43 intent = "Initialize stake account",
44 interpolated_intent = "Initialize stake account ${accounts.stake}"
45 )),
46 codama(account(
47 name = "stake",
48 writable,
49 docs = "Uninitialized stake account",
50 display(label = "Stake Account")
51 ))
52 )]
53 Initialize(
54 #[cfg_attr(feature = "codama", codama(display(flatten = true)))] Authorized,
55 #[cfg_attr(feature = "codama", codama(display(flatten = true)))] Lockup,
56 ),
57
58 #[cfg_attr(
66 feature = "codama",
67 codama(display(
68 intent = "Update stake authority",
69 interpolated_intent = "Set the ${data.arg1} authority of ${accounts.stake} to ${data.arg0}"
70 )),
71 codama(account(
72 name = "stake",
73 writable,
74 docs = "Stake account to be updated",
75 display(label = "Stake Account")
76 )),
77 codama(account(name = "authority", signer, docs = "The stake or withdraw authority")),
78 codama(account(
79 name = "lockup_authority",
80 optional,
81 signer,
82 docs = "Lockup authority, if updating `StakeAuthorize::Withdrawer` before lockup expiration"
83 ))
84 )]
85 Authorize(
86 #[cfg_attr(feature = "codama", codama(display(label = "New Authority")))] Pubkey,
87 #[cfg_attr(feature = "codama", codama(display(label = "Authority Type")))] StakeAuthorize,
88 ),
89
90 #[cfg_attr(
100 feature = "codama",
101 codama(display(
102 intent = "Delegate stake",
103 interpolated_intent = "Delegate ${accounts.stake} to vote account ${accounts.vote}"
104 )),
105 codama(account(
106 name = "stake",
107 writable,
108 docs = "Initialized stake account to be delegated",
109 display(label = "Stake Account")
110 )),
111 codama(account(
112 name = "vote",
113 docs = "Vote account to which this stake will be delegated",
114 display(label = "Vote Account")
115 )),
116 codama(account(name = "stake_authority", signer, docs = "Stake authority"))
117 )]
118 DelegateStake,
119
120 #[cfg_attr(
127 feature = "codama",
128 codama(display(
129 intent = "Split stake",
130 interpolated_intent = "Split ${data.args} from ${accounts.stake} into ${accounts.splitStake}"
131 )),
132 codama(account(
133 name = "stake",
134 writable,
135 docs = "Stake account to be split; must be in the Initialized or Stake state",
136 display(label = "Stake Account")
137 )),
138 codama(account(
139 name = "split_stake",
140 writable,
141 docs = "Uninitialized stake account that will take the split-off amount",
142 display(label = "New Stake Account")
143 )),
144 codama(account(name = "stake_authority", signer, docs = "Stake authority"))
145 )]
146 Split(
149 #[cfg_attr(
150 feature = "codama",
151 codama(name = "args"),
152 codama(display(label = "Amount", amount(decimals = 9, unit = "SOL")))
153 )]
154 u64,
155 ),
156
157 #[cfg_attr(
168 feature = "codama",
169 codama(display(
170 intent = "Withdraw stake",
171 interpolated_intent = "Withdraw ${data.args} from ${accounts.stake} to ${accounts.recipient}"
172 )),
173 codama(account(
174 name = "stake",
175 writable,
176 docs = "Stake account from which to withdraw",
177 display(label = "Stake Account")
178 )),
179 codama(account(name = "recipient", writable, docs = "Recipient account")),
180 codama(account(name = "withdraw_authority", signer, docs = "Withdraw authority")),
181 codama(account(
182 name = "lockup_authority",
183 optional,
184 signer,
185 docs = "Lockup authority, if before lockup expiration"
186 ))
187 )]
188 Withdraw(
191 #[cfg_attr(
192 feature = "codama",
193 codama(name = "args"),
194 codama(display(label = "Amount", amount(decimals = 9, unit = "SOL")))
195 )]
196 u64,
197 ),
198
199 #[cfg_attr(
205 feature = "codama",
206 codama(display(
207 intent = "Deactivate stake",
208 interpolated_intent = "Deactivate ${accounts.stake}"
209 )),
210 codama(account(
211 name = "stake",
212 writable,
213 docs = "Delegated stake account to be deactivated",
214 display(label = "Stake Account")
215 )),
216 codama(account(name = "stake_authority", signer, docs = "Stake authority"))
217 )]
218 Deactivate,
219
220 #[cfg_attr(
229 feature = "codama",
230 codama(display(
231 intent = "Set stake lockup",
232 interpolated_intent = "Update the lockup of ${accounts.stake}"
233 )),
234 codama(account(
235 name = "stake",
236 writable,
237 docs = "Initialized stake account",
238 display(label = "Stake Account")
239 )),
240 codama(account(
241 name = "authority",
242 signer,
243 docs = "Lockup authority or withdraw authority"
244 ))
245 )]
246 SetLockup(
247 #[cfg_attr(
248 feature = "codama",
249 codama(type = link("lockupParams")),
250 codama(display(flatten = true))
251 )]
252 LockupArgs,
253 ),
254
255 #[cfg_attr(
278 feature = "codama",
279 codama(display(
280 intent = "Merge stake accounts",
281 interpolated_intent = "Merge ${accounts.sourceStake} into ${accounts.destinationStake}"
282 )),
283 codama(account(
284 name = "destination_stake",
285 writable,
286 docs = "Destination stake account for the merge",
287 display(label = "To")
288 )),
289 codama(account(
290 name = "source_stake",
291 writable,
292 docs = "Source stake account for to merge. This account will be drained",
293 display(label = "From")
294 )),
295 codama(account(name = "stake_authority", signer, docs = "Stake authority"))
296 )]
297 Merge,
298
299 #[cfg_attr(
307 feature = "codama",
308 codama(display(
309 intent = "Update stake authority",
310 interpolated_intent = "Change an authority of ${accounts.stake}"
311 )),
312 codama(account(
313 name = "stake",
314 writable,
315 docs = "Stake account to be updated",
316 display(label = "Stake Account")
317 )),
318 codama(account(
319 name = "base",
320 signer,
321 docs = "Base key of stake or withdraw authority",
322 display(label = "Base Key")
323 )),
324 codama(account(
325 name = "lockup_authority",
326 optional,
327 signer,
328 docs = "Lockup authority, if updating `StakeAuthorize::Withdrawer` before lockup expiration"
329 ))
330 )]
331 AuthorizeWithSeed(
332 #[cfg_attr(
333 feature = "codama",
334 codama(type = link("authorizeWithSeedParams")),
335 codama(display(flatten = true))
336 )]
337 AuthorizeWithSeedArgs,
338 ),
339
340 #[cfg_attr(
350 feature = "codama",
351 codama(display(
352 intent = "Initialize stake account",
353 interpolated_intent = "Initialize stake account ${accounts.stake}"
354 )),
355 codama(account(
356 name = "stake",
357 writable,
358 docs = "Uninitialized stake account",
359 display(label = "Stake Account")
360 )),
361 codama(account(name = "stake_authority", docs = "The stake authority")),
362 codama(account(name = "withdraw_authority", signer, docs = "The withdraw authority"))
363 )]
364 InitializeChecked,
365
366 #[cfg_attr(
378 feature = "codama",
379 codama(display(
380 intent = "Update stake authority",
381 interpolated_intent = "Set the ${data.stakeAuthorize} authority of ${accounts.stake} to ${accounts.newAuthority}"
382 )),
383 codama(account(
384 name = "stake",
385 writable,
386 docs = "Stake account to be updated",
387 display(label = "Stake Account")
388 )),
389 codama(account(name = "authority", signer, docs = "The stake or withdraw authority")),
390 codama(account(
391 name = "new_authority",
392 signer,
393 docs = "The new stake or withdraw authority"
394 )),
395 codama(account(
396 name = "lockup_authority",
397 optional,
398 signer,
399 docs = "Lockup authority, if updating `StakeAuthorize::Withdrawer` before lockup expiration"
400 ))
401 )]
402 AuthorizeChecked(
403 #[cfg_attr(
404 feature = "codama",
405 codama(name = "stakeAuthorize"),
406 codama(display(label = "Authority Type"))
407 )]
408 StakeAuthorize,
409 ),
410
411 #[cfg_attr(
423 feature = "codama",
424 codama(display(
425 intent = "Update stake authority",
426 interpolated_intent = "Set an authority of ${accounts.stake} to ${accounts.newAuthority}"
427 )),
428 codama(account(
429 name = "stake",
430 writable,
431 docs = "Stake account to be updated",
432 display(label = "Stake Account")
433 )),
434 codama(account(
435 name = "base",
436 signer,
437 docs = "Base key of stake or withdraw authority",
438 display(label = "Base Key")
439 )),
440 codama(account(
441 name = "new_authority",
442 signer,
443 docs = "The new stake or withdraw authority"
444 )),
445 codama(account(
446 name = "lockup_authority",
447 optional,
448 signer,
449 docs = "Lockup authority, if updating `StakeAuthorize::Withdrawer` before lockup expiration"
450 ))
451 )]
452 AuthorizeCheckedWithSeed(
453 #[cfg_attr(
454 feature = "codama",
455 codama(type = link("authorizeCheckedWithSeedParams")),
456 codama(display(flatten = true))
457 )]
458 AuthorizeCheckedWithSeedArgs,
459 ),
460
461 #[cfg_attr(
474 feature = "codama",
475 codama(display(
476 intent = "Set stake lockup",
477 interpolated_intent = "Update the lockup of ${accounts.stake}"
478 )),
479 codama(account(
480 name = "stake",
481 writable,
482 docs = "Initialized stake account",
483 display(label = "Stake Account")
484 )),
485 codama(account(
486 name = "authority",
487 signer,
488 docs = "Lockup authority or withdraw authority"
489 )),
490 codama(account(
491 name = "new_authority",
492 optional,
493 signer,
494 docs = "New lockup authority"
495 ))
496 )]
497 SetLockupChecked(
498 #[cfg_attr(
499 feature = "codama",
500 codama(type = link("lockupCheckedParams")),
501 codama(display(flatten = true))
502 )]
503 LockupCheckedArgs,
504 ),
505
506 #[cfg_attr(
517 feature = "codama",
518 codama(display(intent = "Get minimum stake delegation"))
519 )]
520 GetMinimumDelegation,
521
522 #[cfg_attr(
534 feature = "codama",
535 codama(display(
536 intent = "Deactivate delinquent stake",
537 interpolated_intent = "Deactivate delinquent stake ${accounts.stake}"
538 )),
539 codama(account(
540 name = "stake",
541 writable,
542 docs = "Delegated stake account",
543 display(label = "Stake Account")
544 )),
545 codama(account(
546 name = "delinquent_vote",
547 docs = "Delinquent vote account for the delegated stake account",
548 display(label = "Delinquent Vote Account")
549 )),
550 codama(account(
551 name = "reference_vote",
552 docs = "Reference vote account that has voted at least once in the last `MINIMUM_DELINQUENT_EPOCHS_FOR_DEACTIVATION` epochs",
553 display(label = "Reference Vote Account")
554 ))
555 )]
556 DeactivateDelinquent,
557
558 #[deprecated(since = "2.1.0", note = "Redelegate will not be enabled")]
578 Redelegate,
580
581 #[cfg_attr(
601 feature = "codama",
602 codama(display(
603 intent = "Move stake",
604 interpolated_intent = "Move ${data.args} of active stake from ${accounts.sourceStake} to ${accounts.destinationStake}"
605 )),
606 codama(account(
607 name = "sourceStake",
608 writable,
609 docs = "Active source stake account",
610 display(label = "From")
611 )),
612 codama(account(
613 name = "destinationStake",
614 writable,
615 docs = "Active or inactive destination stake account",
616 display(label = "To")
617 )),
618 codama(account(name = "stake_authority", signer, docs = "Stake authority"))
619 )]
620 MoveStake(
622 #[cfg_attr(
623 feature = "codama",
624 codama(name = "args"),
625 codama(display(label = "Amount", amount(decimals = 9, unit = "SOL")))
626 )]
627 u64,
628 ),
629
630 #[cfg_attr(
644 feature = "codama",
645 codama(display(
646 intent = "Move unstaked SOL",
647 interpolated_intent = "Move ${data.args} from ${accounts.sourceStake} to ${accounts.destinationStake}"
648 )),
649 codama(account(
650 name = "source_stake",
651 writable,
652 docs = "Active or inactive source stake account",
653 display(label = "From")
654 )),
655 codama(account(
656 name = "destination_stake",
657 writable,
658 docs = "Mergeable destination stake account",
659 display(label = "To")
660 )),
661 codama(account(name = "stake_authority", signer, docs = "Stake authority"))
662 )]
663 MoveLamports(
665 #[cfg_attr(
666 feature = "codama",
667 codama(name = "args"),
668 codama(display(label = "Amount", amount(decimals = 9, unit = "SOL")))
669 )]
670 u64,
671 ),
672}
673
674#[cfg_attr(feature = "codama", derive(CodamaType), codama(name = "lockupParams"))]
675#[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
676#[cfg_attr(
677 feature = "serde",
678 derive(serde_derive::Deserialize, serde_derive::Serialize)
679)]
680pub struct LockupArgs {
681 #[cfg_attr(feature = "codama", codama(display(label = "Locked Until")))]
682 pub unix_timestamp: Option<UnixTimestamp>,
683 #[cfg_attr(feature = "codama", codama(display(label = "Locked Until Epoch")))]
684 pub epoch: Option<Epoch>,
685 pub custodian: Option<Pubkey>,
686}
687
688#[cfg_attr(
689 feature = "codama",
690 derive(CodamaType),
691 codama(name = "lockupCheckedParams")
692)]
693#[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
694#[cfg_attr(
695 feature = "serde",
696 derive(serde_derive::Deserialize, serde_derive::Serialize)
697)]
698pub struct LockupCheckedArgs {
699 #[cfg_attr(feature = "codama", codama(display(label = "Locked Until")))]
700 pub unix_timestamp: Option<UnixTimestamp>,
701 #[cfg_attr(feature = "codama", codama(display(label = "Locked Until Epoch")))]
702 pub epoch: Option<Epoch>,
703}
704
705#[cfg_attr(
706 feature = "codama",
707 derive(CodamaType),
708 codama(name = "authorizeWithSeedParams")
709)]
710#[derive(Debug, PartialEq, Eq, Clone)]
711#[cfg_attr(
712 feature = "serde",
713 derive(serde_derive::Deserialize, serde_derive::Serialize)
714)]
715pub struct AuthorizeWithSeedArgs {
716 #[cfg_attr(feature = "codama", codama(display(label = "New Authority")))]
717 pub new_authorized_pubkey: Pubkey,
718 #[cfg_attr(feature = "codama", codama(display(label = "Authority Type")))]
719 pub stake_authorize: StakeAuthorize,
720 #[cfg_attr(feature = "codama", codama(size_prefix = number(u64)))]
721 pub authority_seed: String,
722 pub authority_owner: Pubkey,
723}
724
725#[cfg_attr(
726 feature = "codama",
727 derive(CodamaType),
728 codama(name = "authorizeCheckedWithSeedParams")
729)]
730#[derive(Debug, PartialEq, Eq, Clone)]
731#[cfg_attr(
732 feature = "serde",
733 derive(serde_derive::Deserialize, serde_derive::Serialize)
734)]
735pub struct AuthorizeCheckedWithSeedArgs {
736 #[cfg_attr(feature = "codama", codama(display(label = "Authority Type")))]
737 pub stake_authorize: StakeAuthorize,
738 #[cfg_attr(feature = "codama", codama(size_prefix = number(u64)))]
739 pub authority_seed: String,
740 pub authority_owner: Pubkey,
741}
742
743#[cfg(feature = "bincode")]
744pub fn initialize(stake_pubkey: &Pubkey, authorized: &Authorized, lockup: &Lockup) -> Instruction {
745 Instruction::new_with_bincode(
746 ID,
747 &StakeInstruction::Initialize(*authorized, *lockup),
748 vec![AccountMeta::new(*stake_pubkey, false)],
749 )
750}
751
752#[cfg(feature = "bincode")]
753pub fn initialize_checked(stake_pubkey: &Pubkey, authorized: &Authorized) -> Instruction {
754 Instruction::new_with_bincode(
755 ID,
756 &StakeInstruction::InitializeChecked,
757 vec![
758 AccountMeta::new(*stake_pubkey, false),
759 AccountMeta::new_readonly(authorized.staker, false),
760 AccountMeta::new_readonly(authorized.withdrawer, true),
761 ],
762 )
763}
764
765#[cfg(feature = "bincode")]
766pub fn create_account_with_seed(
767 from_pubkey: &Pubkey,
768 stake_pubkey: &Pubkey,
769 base: &Pubkey,
770 seed: &str,
771 authorized: &Authorized,
772 lockup: &Lockup,
773 lamports: u64,
774) -> Vec<Instruction> {
775 vec![
776 solana_system_interface::instruction::create_account_with_seed(
777 from_pubkey,
778 stake_pubkey,
779 base,
780 seed,
781 lamports,
782 StakeStateV2::size_of() as u64,
783 &ID,
784 ),
785 initialize(stake_pubkey, authorized, lockup),
786 ]
787}
788
789#[cfg(feature = "bincode")]
790pub fn create_account(
791 from_pubkey: &Pubkey,
792 stake_pubkey: &Pubkey,
793 authorized: &Authorized,
794 lockup: &Lockup,
795 lamports: u64,
796) -> Vec<Instruction> {
797 vec![
798 solana_system_interface::instruction::create_account(
799 from_pubkey,
800 stake_pubkey,
801 lamports,
802 StakeStateV2::size_of() as u64,
803 &ID,
804 ),
805 initialize(stake_pubkey, authorized, lockup),
806 ]
807}
808
809#[cfg(feature = "bincode")]
810pub fn create_account_with_seed_checked(
811 from_pubkey: &Pubkey,
812 stake_pubkey: &Pubkey,
813 base: &Pubkey,
814 seed: &str,
815 authorized: &Authorized,
816 lamports: u64,
817) -> Vec<Instruction> {
818 vec![
819 solana_system_interface::instruction::create_account_with_seed(
820 from_pubkey,
821 stake_pubkey,
822 base,
823 seed,
824 lamports,
825 StakeStateV2::size_of() as u64,
826 &ID,
827 ),
828 initialize_checked(stake_pubkey, authorized),
829 ]
830}
831
832#[cfg(feature = "bincode")]
833pub fn create_account_checked(
834 from_pubkey: &Pubkey,
835 stake_pubkey: &Pubkey,
836 authorized: &Authorized,
837 lamports: u64,
838) -> Vec<Instruction> {
839 vec![
840 solana_system_interface::instruction::create_account(
841 from_pubkey,
842 stake_pubkey,
843 lamports,
844 StakeStateV2::size_of() as u64,
845 &ID,
846 ),
847 initialize_checked(stake_pubkey, authorized),
848 ]
849}
850
851#[cfg(feature = "bincode")]
852fn _split(
853 stake_pubkey: &Pubkey,
854 authorized_pubkey: &Pubkey,
855 lamports: u64,
856 split_stake_pubkey: &Pubkey,
857) -> Instruction {
858 let account_metas = vec![
859 AccountMeta::new(*stake_pubkey, false),
860 AccountMeta::new(*split_stake_pubkey, false),
861 AccountMeta::new_readonly(*authorized_pubkey, true),
862 ];
863
864 Instruction::new_with_bincode(ID, &StakeInstruction::Split(lamports), account_metas)
865}
866
867#[cfg(feature = "bincode")]
868pub fn split(
869 stake_pubkey: &Pubkey,
870 authorized_pubkey: &Pubkey,
871 lamports: u64,
872 split_stake_pubkey: &Pubkey,
873) -> Vec<Instruction> {
874 vec![
875 solana_system_interface::instruction::allocate(
876 split_stake_pubkey,
877 StakeStateV2::size_of() as u64,
878 ),
879 solana_system_interface::instruction::assign(split_stake_pubkey, &ID),
880 _split(
881 stake_pubkey,
882 authorized_pubkey,
883 lamports,
884 split_stake_pubkey,
885 ),
886 ]
887}
888
889#[cfg(feature = "bincode")]
890pub fn split_with_seed(
891 stake_pubkey: &Pubkey,
892 authorized_pubkey: &Pubkey,
893 lamports: u64,
894 split_stake_pubkey: &Pubkey, base: &Pubkey, seed: &str, ) -> Vec<Instruction> {
898 vec![
899 solana_system_interface::instruction::allocate_with_seed(
900 split_stake_pubkey,
901 base,
902 seed,
903 StakeStateV2::size_of() as u64,
904 &ID,
905 ),
906 _split(
907 stake_pubkey,
908 authorized_pubkey,
909 lamports,
910 split_stake_pubkey,
911 ),
912 ]
913}
914
915#[cfg(feature = "bincode")]
916pub fn merge(
917 destination_stake_pubkey: &Pubkey,
918 source_stake_pubkey: &Pubkey,
919 authorized_pubkey: &Pubkey,
920) -> Vec<Instruction> {
921 let account_metas = vec![
922 AccountMeta::new(*destination_stake_pubkey, false),
923 AccountMeta::new(*source_stake_pubkey, false),
924 AccountMeta::new_readonly(*authorized_pubkey, true),
925 ];
926
927 vec![Instruction::new_with_bincode(
928 ID,
929 &StakeInstruction::Merge,
930 account_metas,
931 )]
932}
933
934#[cfg(feature = "bincode")]
935pub fn create_account_and_delegate_stake(
936 from_pubkey: &Pubkey,
937 stake_pubkey: &Pubkey,
938 vote_pubkey: &Pubkey,
939 authorized: &Authorized,
940 lockup: &Lockup,
941 lamports: u64,
942) -> Vec<Instruction> {
943 let mut instructions = create_account(from_pubkey, stake_pubkey, authorized, lockup, lamports);
944 instructions.push(delegate_stake(
945 stake_pubkey,
946 &authorized.staker,
947 vote_pubkey,
948 ));
949 instructions
950}
951
952#[cfg(feature = "bincode")]
953#[allow(clippy::too_many_arguments)]
954pub fn create_account_with_seed_and_delegate_stake(
955 from_pubkey: &Pubkey,
956 stake_pubkey: &Pubkey,
957 base: &Pubkey,
958 seed: &str,
959 vote_pubkey: &Pubkey,
960 authorized: &Authorized,
961 lockup: &Lockup,
962 lamports: u64,
963) -> Vec<Instruction> {
964 let mut instructions = create_account_with_seed(
965 from_pubkey,
966 stake_pubkey,
967 base,
968 seed,
969 authorized,
970 lockup,
971 lamports,
972 );
973 instructions.push(delegate_stake(
974 stake_pubkey,
975 &authorized.staker,
976 vote_pubkey,
977 ));
978 instructions
979}
980
981#[cfg(feature = "bincode")]
982pub fn authorize(
983 stake_pubkey: &Pubkey,
984 authorized_pubkey: &Pubkey,
985 new_authorized_pubkey: &Pubkey,
986 stake_authorize: StakeAuthorize,
987 custodian_pubkey: Option<&Pubkey>,
988) -> Instruction {
989 let mut account_metas = vec![
990 AccountMeta::new(*stake_pubkey, false),
991 AccountMeta::new_readonly(*authorized_pubkey, true),
992 ];
993
994 if let Some(custodian_pubkey) = custodian_pubkey {
995 account_metas.push(AccountMeta::new_readonly(*custodian_pubkey, true));
996 }
997
998 Instruction::new_with_bincode(
999 ID,
1000 &StakeInstruction::Authorize(*new_authorized_pubkey, stake_authorize),
1001 account_metas,
1002 )
1003}
1004
1005#[cfg(feature = "bincode")]
1006pub fn authorize_checked(
1007 stake_pubkey: &Pubkey,
1008 authorized_pubkey: &Pubkey,
1009 new_authorized_pubkey: &Pubkey,
1010 stake_authorize: StakeAuthorize,
1011 custodian_pubkey: Option<&Pubkey>,
1012) -> Instruction {
1013 let mut account_metas = vec![
1014 AccountMeta::new(*stake_pubkey, false),
1015 AccountMeta::new_readonly(*authorized_pubkey, true),
1016 AccountMeta::new_readonly(*new_authorized_pubkey, true),
1017 ];
1018
1019 if let Some(custodian_pubkey) = custodian_pubkey {
1020 account_metas.push(AccountMeta::new_readonly(*custodian_pubkey, true));
1021 }
1022
1023 Instruction::new_with_bincode(
1024 ID,
1025 &StakeInstruction::AuthorizeChecked(stake_authorize),
1026 account_metas,
1027 )
1028}
1029
1030#[cfg(feature = "bincode")]
1031pub fn authorize_with_seed(
1032 stake_pubkey: &Pubkey,
1033 authority_base: &Pubkey,
1034 authority_seed: String,
1035 authority_owner: &Pubkey,
1036 new_authorized_pubkey: &Pubkey,
1037 stake_authorize: StakeAuthorize,
1038 custodian_pubkey: Option<&Pubkey>,
1039) -> Instruction {
1040 let mut account_metas = vec![
1041 AccountMeta::new(*stake_pubkey, false),
1042 AccountMeta::new_readonly(*authority_base, true),
1043 ];
1044
1045 if let Some(custodian_pubkey) = custodian_pubkey {
1046 account_metas.push(AccountMeta::new_readonly(*custodian_pubkey, true));
1047 }
1048
1049 let args = AuthorizeWithSeedArgs {
1050 new_authorized_pubkey: *new_authorized_pubkey,
1051 stake_authorize,
1052 authority_seed,
1053 authority_owner: *authority_owner,
1054 };
1055
1056 Instruction::new_with_bincode(
1057 ID,
1058 &StakeInstruction::AuthorizeWithSeed(args),
1059 account_metas,
1060 )
1061}
1062
1063#[cfg(feature = "bincode")]
1064pub fn authorize_checked_with_seed(
1065 stake_pubkey: &Pubkey,
1066 authority_base: &Pubkey,
1067 authority_seed: String,
1068 authority_owner: &Pubkey,
1069 new_authorized_pubkey: &Pubkey,
1070 stake_authorize: StakeAuthorize,
1071 custodian_pubkey: Option<&Pubkey>,
1072) -> Instruction {
1073 let mut account_metas = vec![
1074 AccountMeta::new(*stake_pubkey, false),
1075 AccountMeta::new_readonly(*authority_base, true),
1076 AccountMeta::new_readonly(*new_authorized_pubkey, true),
1077 ];
1078
1079 if let Some(custodian_pubkey) = custodian_pubkey {
1080 account_metas.push(AccountMeta::new_readonly(*custodian_pubkey, true));
1081 }
1082
1083 let args = AuthorizeCheckedWithSeedArgs {
1084 stake_authorize,
1085 authority_seed,
1086 authority_owner: *authority_owner,
1087 };
1088
1089 Instruction::new_with_bincode(
1090 ID,
1091 &StakeInstruction::AuthorizeCheckedWithSeed(args),
1092 account_metas,
1093 )
1094}
1095
1096#[cfg(feature = "bincode")]
1097pub fn delegate_stake(
1098 stake_pubkey: &Pubkey,
1099 authorized_pubkey: &Pubkey,
1100 vote_pubkey: &Pubkey,
1101) -> Instruction {
1102 let account_metas = vec![
1103 AccountMeta::new(*stake_pubkey, false),
1104 AccountMeta::new_readonly(*vote_pubkey, false),
1105 AccountMeta::new_readonly(*authorized_pubkey, true),
1106 ];
1107 Instruction::new_with_bincode(ID, &StakeInstruction::DelegateStake, account_metas)
1108}
1109
1110#[cfg(feature = "bincode")]
1111pub fn withdraw(
1112 stake_pubkey: &Pubkey,
1113 withdrawer_pubkey: &Pubkey,
1114 to_pubkey: &Pubkey,
1115 lamports: u64,
1116 custodian_pubkey: Option<&Pubkey>,
1117) -> Instruction {
1118 let mut account_metas = vec![
1119 AccountMeta::new(*stake_pubkey, false),
1120 AccountMeta::new(*to_pubkey, false),
1121 AccountMeta::new_readonly(*withdrawer_pubkey, true),
1122 ];
1123
1124 if let Some(custodian_pubkey) = custodian_pubkey {
1125 account_metas.push(AccountMeta::new_readonly(*custodian_pubkey, true));
1126 }
1127
1128 Instruction::new_with_bincode(ID, &StakeInstruction::Withdraw(lamports), account_metas)
1129}
1130
1131#[cfg(feature = "bincode")]
1132pub fn deactivate_stake(stake_pubkey: &Pubkey, authorized_pubkey: &Pubkey) -> Instruction {
1133 let account_metas = vec![
1134 AccountMeta::new(*stake_pubkey, false),
1135 AccountMeta::new_readonly(*authorized_pubkey, true),
1136 ];
1137 Instruction::new_with_bincode(ID, &StakeInstruction::Deactivate, account_metas)
1138}
1139
1140#[cfg(feature = "bincode")]
1141pub fn set_lockup(
1142 stake_pubkey: &Pubkey,
1143 lockup: &LockupArgs,
1144 custodian_pubkey: &Pubkey,
1145) -> Instruction {
1146 let account_metas = vec![
1147 AccountMeta::new(*stake_pubkey, false),
1148 AccountMeta::new_readonly(*custodian_pubkey, true),
1149 ];
1150 Instruction::new_with_bincode(ID, &StakeInstruction::SetLockup(*lockup), account_metas)
1151}
1152
1153#[cfg(feature = "bincode")]
1154pub fn set_lockup_checked(
1155 stake_pubkey: &Pubkey,
1156 lockup: &LockupArgs,
1157 custodian_pubkey: &Pubkey,
1158) -> Instruction {
1159 let mut account_metas = vec![
1160 AccountMeta::new(*stake_pubkey, false),
1161 AccountMeta::new_readonly(*custodian_pubkey, true),
1162 ];
1163
1164 let lockup_checked = LockupCheckedArgs {
1165 unix_timestamp: lockup.unix_timestamp,
1166 epoch: lockup.epoch,
1167 };
1168 if let Some(new_custodian) = lockup.custodian {
1169 account_metas.push(AccountMeta::new_readonly(new_custodian, true));
1170 }
1171 Instruction::new_with_bincode(
1172 ID,
1173 &StakeInstruction::SetLockupChecked(lockup_checked),
1174 account_metas,
1175 )
1176}
1177
1178#[cfg(feature = "bincode")]
1179pub fn get_minimum_delegation() -> Instruction {
1180 Instruction::new_with_bincode(ID, &StakeInstruction::GetMinimumDelegation, Vec::default())
1181}
1182
1183#[cfg(feature = "bincode")]
1184pub fn deactivate_delinquent_stake(
1185 stake_account: &Pubkey,
1186 delinquent_vote_account: &Pubkey,
1187 reference_vote_account: &Pubkey,
1188) -> Instruction {
1189 let account_metas = vec![
1190 AccountMeta::new(*stake_account, false),
1191 AccountMeta::new_readonly(*delinquent_vote_account, false),
1192 AccountMeta::new_readonly(*reference_vote_account, false),
1193 ];
1194 Instruction::new_with_bincode(ID, &StakeInstruction::DeactivateDelinquent, account_metas)
1195}
1196
1197#[cfg(feature = "bincode")]
1198fn _redelegate(
1199 stake_pubkey: &Pubkey,
1200 authorized_pubkey: &Pubkey,
1201 vote_pubkey: &Pubkey,
1202 uninitialized_stake_pubkey: &Pubkey,
1203) -> Instruction {
1204 let account_metas = vec![
1205 AccountMeta::new(*stake_pubkey, false),
1206 AccountMeta::new(*uninitialized_stake_pubkey, false),
1207 AccountMeta::new_readonly(*vote_pubkey, false),
1208 AccountMeta::new_readonly(*authorized_pubkey, true),
1209 ];
1210 Instruction::new_with_bincode(ID, &StakeInstruction::Redelegate, account_metas)
1211}
1212
1213#[cfg(feature = "bincode")]
1214#[deprecated(since = "2.1.0", note = "Redelegate will not be enabled")]
1215pub fn redelegate(
1216 stake_pubkey: &Pubkey,
1217 authorized_pubkey: &Pubkey,
1218 vote_pubkey: &Pubkey,
1219 uninitialized_stake_pubkey: &Pubkey,
1220) -> Vec<Instruction> {
1221 vec![
1222 solana_system_interface::instruction::allocate(
1223 uninitialized_stake_pubkey,
1224 StakeStateV2::size_of() as u64,
1225 ),
1226 solana_system_interface::instruction::assign(uninitialized_stake_pubkey, &ID),
1227 _redelegate(
1228 stake_pubkey,
1229 authorized_pubkey,
1230 vote_pubkey,
1231 uninitialized_stake_pubkey,
1232 ),
1233 ]
1234}
1235
1236#[cfg(feature = "bincode")]
1237#[deprecated(since = "2.1.0", note = "Redelegate will not be enabled")]
1238pub fn redelegate_with_seed(
1239 stake_pubkey: &Pubkey,
1240 authorized_pubkey: &Pubkey,
1241 vote_pubkey: &Pubkey,
1242 uninitialized_stake_pubkey: &Pubkey, base: &Pubkey, seed: &str, ) -> Vec<Instruction> {
1246 vec![
1247 solana_system_interface::instruction::allocate_with_seed(
1248 uninitialized_stake_pubkey,
1249 base,
1250 seed,
1251 StakeStateV2::size_of() as u64,
1252 &ID,
1253 ),
1254 _redelegate(
1255 stake_pubkey,
1256 authorized_pubkey,
1257 vote_pubkey,
1258 uninitialized_stake_pubkey,
1259 ),
1260 ]
1261}
1262
1263#[cfg(feature = "bincode")]
1264pub fn move_stake(
1265 source_stake_pubkey: &Pubkey,
1266 destination_stake_pubkey: &Pubkey,
1267 authorized_pubkey: &Pubkey,
1268 lamports: u64,
1269) -> Instruction {
1270 let account_metas = vec![
1271 AccountMeta::new(*source_stake_pubkey, false),
1272 AccountMeta::new(*destination_stake_pubkey, false),
1273 AccountMeta::new_readonly(*authorized_pubkey, true),
1274 ];
1275
1276 Instruction::new_with_bincode(ID, &StakeInstruction::MoveStake(lamports), account_metas)
1277}
1278
1279#[cfg(feature = "bincode")]
1280pub fn move_lamports(
1281 source_stake_pubkey: &Pubkey,
1282 destination_stake_pubkey: &Pubkey,
1283 authorized_pubkey: &Pubkey,
1284 lamports: u64,
1285) -> Instruction {
1286 let account_metas = vec![
1287 AccountMeta::new(*source_stake_pubkey, false),
1288 AccountMeta::new(*destination_stake_pubkey, false),
1289 AccountMeta::new_readonly(*authorized_pubkey, true),
1290 ];
1291
1292 Instruction::new_with_bincode(ID, &StakeInstruction::MoveLamports(lamports), account_metas)
1293}