1#![allow(clippy::too_many_arguments)]
4
5use {
6 crate::{
7 find_deposit_authority_program_address, find_ephemeral_stake_program_address,
8 find_stake_program_address, find_transient_stake_program_address,
9 find_withdraw_authority_program_address,
10 state::{Fee, FeeType, StakePool, ValidatorList},
11 MAX_VALIDATORS_TO_UPDATE,
12 },
13 borsh::{BorshDeserialize, BorshSchema, BorshSerialize},
14 mpl_token_metadata::pda::find_metadata_account,
15 solana_program::{
16 instruction::{AccountMeta, Instruction},
17 pubkey::Pubkey,
18 stake, system_program, sysvar,
19 },
20 std::num::NonZeroU32,
21};
22
23#[repr(C)]
26#[derive(Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)]
27pub enum PreferredValidatorType {
28 Deposit,
30 Withdraw,
32}
33
34#[repr(C)]
37#[derive(Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)]
38pub enum FundingType {
39 StakeDeposit,
41 SolDeposit,
43 SolWithdraw,
45}
46
47#[repr(C)]
49#[derive(Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize)]
50pub enum StakePoolInstruction {
51 Initialize {
67 fee: Fee,
69 withdrawal_fee: Fee,
71 deposit_fee: Fee,
73 referral_fee: u8,
75 max_validators: u32,
77 },
78
79 AddValidatorToPool(u32),
103
104 RemoveValidatorFromPool,
119
120 DecreaseValidatorStake {
145 lamports: u64,
147 transient_stake_seed: u64,
149 },
150
151 IncreaseValidatorStake {
181 lamports: u64,
183 transient_stake_seed: u64,
185 },
186
187 SetPreferredValidator {
200 validator_type: PreferredValidatorType,
202 validator_vote_address: Option<Pubkey>,
205 },
206
207 UpdateValidatorListBalance {
225 start_index: u32,
227 no_merge: bool,
231 },
232
233 UpdateStakePoolBalance,
243
244 CleanupRemovedValidatorEntries,
249
250 DepositStake,
269
270 WithdrawStake(u64),
304
305 SetManager,
312
313 SetFee {
318 fee: FeeType,
320 },
321
322 SetStaker,
328
329 DepositSol(u64),
344
345 SetFundingAuthority(FundingType),
351
352 WithdrawSol(u64),
369
370 CreateTokenMetadata {
381 name: String,
383 symbol: String,
385 uri: String,
387 },
388 UpdateTokenMetadata {
397 name: String,
399 symbol: String,
401 uri: String,
403 },
404
405 IncreaseAdditionalValidatorStake {
437 lamports: u64,
439 transient_stake_seed: u64,
441 ephemeral_stake_seed: u64,
443 },
444
445 DecreaseAdditionalValidatorStake {
468 lamports: u64,
470 transient_stake_seed: u64,
472 ephemeral_stake_seed: u64,
474 },
475
476 Redelegate {
519 #[allow(dead_code)] lamports: u64,
522 #[allow(dead_code)] source_transient_stake_seed: u64,
525 #[allow(dead_code)] ephemeral_stake_seed: u64,
528 #[allow(dead_code)] destination_transient_stake_seed: u64,
533 },
534
535 DepositStakeWithSlippage {
555 minimum_pool_tokens_out: u64,
557 },
558
559 WithdrawStakeWithSlippage {
582 pool_tokens_in: u64,
584 minimum_lamports_out: u64,
586 },
587
588 DepositSolWithSlippage {
604 lamports_in: u64,
606 minimum_pool_tokens_out: u64,
608 },
609
610 WithdrawSolWithSlippage {
628 pool_tokens_in: u64,
630 minimum_lamports_out: u64,
632 },
633}
634
635pub fn initialize(
637 program_id: &Pubkey,
638 stake_pool: &Pubkey,
639 manager: &Pubkey,
640 staker: &Pubkey,
641 stake_pool_withdraw_authority: &Pubkey,
642 validator_list: &Pubkey,
643 reserve_stake: &Pubkey,
644 pool_mint: &Pubkey,
645 manager_pool_account: &Pubkey,
646 token_program_id: &Pubkey,
647 deposit_authority: Option<Pubkey>,
648 fee: Fee,
649 withdrawal_fee: Fee,
650 deposit_fee: Fee,
651 referral_fee: u8,
652 max_validators: u32,
653) -> Instruction {
654 let init_data = StakePoolInstruction::Initialize {
655 fee,
656 withdrawal_fee,
657 deposit_fee,
658 referral_fee,
659 max_validators,
660 };
661 let data = init_data.try_to_vec().unwrap();
662 let mut accounts = vec![
663 AccountMeta::new(*stake_pool, false),
664 AccountMeta::new_readonly(*manager, true),
665 AccountMeta::new_readonly(*staker, false),
666 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
667 AccountMeta::new(*validator_list, false),
668 AccountMeta::new_readonly(*reserve_stake, false),
669 AccountMeta::new(*pool_mint, false),
670 AccountMeta::new(*manager_pool_account, false),
671 AccountMeta::new_readonly(*token_program_id, false),
672 ];
673 if let Some(deposit_authority) = deposit_authority {
674 accounts.push(AccountMeta::new_readonly(deposit_authority, true));
675 }
676 Instruction {
677 program_id: *program_id,
678 accounts,
679 data,
680 }
681}
682
683pub fn add_validator_to_pool(
685 program_id: &Pubkey,
686 stake_pool: &Pubkey,
687 staker: &Pubkey,
688 reserve: &Pubkey,
689 stake_pool_withdraw: &Pubkey,
690 validator_list: &Pubkey,
691 stake: &Pubkey,
692 validator: &Pubkey,
693 seed: Option<NonZeroU32>,
694) -> Instruction {
695 let accounts = vec![
696 AccountMeta::new(*stake_pool, false),
697 AccountMeta::new_readonly(*staker, true),
698 AccountMeta::new(*reserve, false),
699 AccountMeta::new_readonly(*stake_pool_withdraw, false),
700 AccountMeta::new(*validator_list, false),
701 AccountMeta::new(*stake, false),
702 AccountMeta::new_readonly(*validator, false),
703 AccountMeta::new_readonly(sysvar::rent::id(), false),
704 AccountMeta::new_readonly(sysvar::clock::id(), false),
705 AccountMeta::new_readonly(sysvar::stake_history::id(), false),
706 AccountMeta::new_readonly(stake::config::id(), false),
707 AccountMeta::new_readonly(system_program::id(), false),
708 AccountMeta::new_readonly(stake::program::id(), false),
709 ];
710 let data = StakePoolInstruction::AddValidatorToPool(seed.map(|s| s.get()).unwrap_or(0))
711 .try_to_vec()
712 .unwrap();
713 Instruction {
714 program_id: *program_id,
715 accounts,
716 data,
717 }
718}
719
720pub fn remove_validator_from_pool(
722 program_id: &Pubkey,
723 stake_pool: &Pubkey,
724 staker: &Pubkey,
725 stake_pool_withdraw: &Pubkey,
726 validator_list: &Pubkey,
727 stake_account: &Pubkey,
728 transient_stake_account: &Pubkey,
729) -> Instruction {
730 let accounts = vec![
731 AccountMeta::new(*stake_pool, false),
732 AccountMeta::new_readonly(*staker, true),
733 AccountMeta::new_readonly(*stake_pool_withdraw, false),
734 AccountMeta::new(*validator_list, false),
735 AccountMeta::new(*stake_account, false),
736 AccountMeta::new_readonly(*transient_stake_account, false),
737 AccountMeta::new_readonly(sysvar::clock::id(), false),
738 AccountMeta::new_readonly(stake::program::id(), false),
739 ];
740 Instruction {
741 program_id: *program_id,
742 accounts,
743 data: StakePoolInstruction::RemoveValidatorFromPool
744 .try_to_vec()
745 .unwrap(),
746 }
747}
748
749pub fn decrease_validator_stake(
752 program_id: &Pubkey,
753 stake_pool: &Pubkey,
754 staker: &Pubkey,
755 stake_pool_withdraw_authority: &Pubkey,
756 validator_list: &Pubkey,
757 validator_stake: &Pubkey,
758 transient_stake: &Pubkey,
759 lamports: u64,
760 transient_stake_seed: u64,
761) -> Instruction {
762 let accounts = vec![
763 AccountMeta::new_readonly(*stake_pool, false),
764 AccountMeta::new_readonly(*staker, true),
765 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
766 AccountMeta::new(*validator_list, false),
767 AccountMeta::new(*validator_stake, false),
768 AccountMeta::new(*transient_stake, false),
769 AccountMeta::new_readonly(sysvar::clock::id(), false),
770 AccountMeta::new_readonly(sysvar::rent::id(), false),
771 AccountMeta::new_readonly(system_program::id(), false),
772 AccountMeta::new_readonly(stake::program::id(), false),
773 ];
774 Instruction {
775 program_id: *program_id,
776 accounts,
777 data: StakePoolInstruction::DecreaseValidatorStake {
778 lamports,
779 transient_stake_seed,
780 }
781 .try_to_vec()
782 .unwrap(),
783 }
784}
785
786pub fn decrease_additional_validator_stake(
789 program_id: &Pubkey,
790 stake_pool: &Pubkey,
791 staker: &Pubkey,
792 stake_pool_withdraw_authority: &Pubkey,
793 validator_list: &Pubkey,
794 validator_stake: &Pubkey,
795 ephemeral_stake: &Pubkey,
796 transient_stake: &Pubkey,
797 lamports: u64,
798 transient_stake_seed: u64,
799 ephemeral_stake_seed: u64,
800) -> Instruction {
801 let accounts = vec![
802 AccountMeta::new_readonly(*stake_pool, false),
803 AccountMeta::new_readonly(*staker, true),
804 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
805 AccountMeta::new(*validator_list, false),
806 AccountMeta::new(*validator_stake, false),
807 AccountMeta::new(*ephemeral_stake, false),
808 AccountMeta::new(*transient_stake, false),
809 AccountMeta::new_readonly(sysvar::clock::id(), false),
810 AccountMeta::new_readonly(sysvar::stake_history::id(), false),
811 AccountMeta::new_readonly(system_program::id(), false),
812 AccountMeta::new_readonly(stake::program::id(), false),
813 ];
814 Instruction {
815 program_id: *program_id,
816 accounts,
817 data: StakePoolInstruction::DecreaseAdditionalValidatorStake {
818 lamports,
819 transient_stake_seed,
820 ephemeral_stake_seed,
821 }
822 .try_to_vec()
823 .unwrap(),
824 }
825}
826
827pub fn increase_validator_stake(
830 program_id: &Pubkey,
831 stake_pool: &Pubkey,
832 staker: &Pubkey,
833 stake_pool_withdraw_authority: &Pubkey,
834 validator_list: &Pubkey,
835 reserve_stake: &Pubkey,
836 transient_stake: &Pubkey,
837 validator_stake: &Pubkey,
838 validator: &Pubkey,
839 lamports: u64,
840 transient_stake_seed: u64,
841) -> Instruction {
842 let accounts = vec![
843 AccountMeta::new_readonly(*stake_pool, false),
844 AccountMeta::new_readonly(*staker, true),
845 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
846 AccountMeta::new(*validator_list, false),
847 AccountMeta::new(*reserve_stake, false),
848 AccountMeta::new(*transient_stake, false),
849 AccountMeta::new_readonly(*validator_stake, false),
850 AccountMeta::new_readonly(*validator, false),
851 AccountMeta::new_readonly(sysvar::clock::id(), false),
852 AccountMeta::new_readonly(sysvar::rent::id(), false),
853 AccountMeta::new_readonly(sysvar::stake_history::id(), false),
854 AccountMeta::new_readonly(stake::config::id(), false),
855 AccountMeta::new_readonly(system_program::id(), false),
856 AccountMeta::new_readonly(stake::program::id(), false),
857 ];
858 Instruction {
859 program_id: *program_id,
860 accounts,
861 data: StakePoolInstruction::IncreaseValidatorStake {
862 lamports,
863 transient_stake_seed,
864 }
865 .try_to_vec()
866 .unwrap(),
867 }
868}
869
870pub fn increase_additional_validator_stake(
873 program_id: &Pubkey,
874 stake_pool: &Pubkey,
875 staker: &Pubkey,
876 stake_pool_withdraw_authority: &Pubkey,
877 validator_list: &Pubkey,
878 reserve_stake: &Pubkey,
879 ephemeral_stake: &Pubkey,
880 transient_stake: &Pubkey,
881 validator_stake: &Pubkey,
882 validator: &Pubkey,
883 lamports: u64,
884 transient_stake_seed: u64,
885 ephemeral_stake_seed: u64,
886) -> Instruction {
887 let accounts = vec![
888 AccountMeta::new_readonly(*stake_pool, false),
889 AccountMeta::new_readonly(*staker, true),
890 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
891 AccountMeta::new(*validator_list, false),
892 AccountMeta::new(*reserve_stake, false),
893 AccountMeta::new(*ephemeral_stake, false),
894 AccountMeta::new(*transient_stake, false),
895 AccountMeta::new_readonly(*validator_stake, false),
896 AccountMeta::new_readonly(*validator, false),
897 AccountMeta::new_readonly(sysvar::clock::id(), false),
898 AccountMeta::new_readonly(sysvar::stake_history::id(), false),
899 AccountMeta::new_readonly(stake::config::id(), false),
900 AccountMeta::new_readonly(system_program::id(), false),
901 AccountMeta::new_readonly(stake::program::id(), false),
902 ];
903 Instruction {
904 program_id: *program_id,
905 accounts,
906 data: StakePoolInstruction::IncreaseAdditionalValidatorStake {
907 lamports,
908 transient_stake_seed,
909 ephemeral_stake_seed,
910 }
911 .try_to_vec()
912 .unwrap(),
913 }
914}
915
916pub fn redelegate(
918 program_id: &Pubkey,
919 stake_pool: &Pubkey,
920 staker: &Pubkey,
921 stake_pool_withdraw_authority: &Pubkey,
922 validator_list: &Pubkey,
923 source_validator_stake: &Pubkey,
924 source_transient_stake: &Pubkey,
925 ephemeral_stake: &Pubkey,
926 destination_transient_stake: &Pubkey,
927 destination_validator_stake: &Pubkey,
928 validator: &Pubkey,
929 lamports: u64,
930 source_transient_stake_seed: u64,
931 ephemeral_stake_seed: u64,
932 destination_transient_stake_seed: u64,
933) -> Instruction {
934 let accounts = vec![
935 AccountMeta::new_readonly(*stake_pool, false),
936 AccountMeta::new_readonly(*staker, true),
937 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
938 AccountMeta::new(*validator_list, false),
939 AccountMeta::new(*source_validator_stake, false),
940 AccountMeta::new(*source_transient_stake, false),
941 AccountMeta::new(*ephemeral_stake, false),
942 AccountMeta::new(*destination_transient_stake, false),
943 AccountMeta::new_readonly(*destination_validator_stake, false),
944 AccountMeta::new_readonly(*validator, false),
945 AccountMeta::new_readonly(sysvar::clock::id(), false),
946 AccountMeta::new_readonly(sysvar::stake_history::id(), false),
947 AccountMeta::new_readonly(stake::config::id(), false),
948 AccountMeta::new_readonly(system_program::id(), false),
949 AccountMeta::new_readonly(stake::program::id(), false),
950 ];
951 Instruction {
952 program_id: *program_id,
953 accounts,
954 data: StakePoolInstruction::Redelegate {
955 lamports,
956 source_transient_stake_seed,
957 ephemeral_stake_seed,
958 destination_transient_stake_seed,
959 }
960 .try_to_vec()
961 .unwrap(),
962 }
963}
964
965pub fn set_preferred_validator(
967 program_id: &Pubkey,
968 stake_pool_address: &Pubkey,
969 staker: &Pubkey,
970 validator_list_address: &Pubkey,
971 validator_type: PreferredValidatorType,
972 validator_vote_address: Option<Pubkey>,
973) -> Instruction {
974 Instruction {
975 program_id: *program_id,
976 accounts: vec![
977 AccountMeta::new(*stake_pool_address, false),
978 AccountMeta::new_readonly(*staker, true),
979 AccountMeta::new_readonly(*validator_list_address, false),
980 ],
981 data: StakePoolInstruction::SetPreferredValidator {
982 validator_type,
983 validator_vote_address,
984 }
985 .try_to_vec()
986 .unwrap(),
987 }
988}
989
990pub fn add_validator_to_pool_with_vote(
993 program_id: &Pubkey,
994 stake_pool: &StakePool,
995 stake_pool_address: &Pubkey,
996 vote_account_address: &Pubkey,
997 seed: Option<NonZeroU32>,
998) -> Instruction {
999 let pool_withdraw_authority =
1000 find_withdraw_authority_program_address(program_id, stake_pool_address).0;
1001 let (stake_account_address, _) =
1002 find_stake_program_address(program_id, vote_account_address, stake_pool_address, seed);
1003 add_validator_to_pool(
1004 program_id,
1005 stake_pool_address,
1006 &stake_pool.staker,
1007 &stake_pool.reserve_stake,
1008 &pool_withdraw_authority,
1009 &stake_pool.validator_list,
1010 &stake_account_address,
1011 vote_account_address,
1012 seed,
1013 )
1014}
1015
1016pub fn remove_validator_from_pool_with_vote(
1019 program_id: &Pubkey,
1020 stake_pool: &StakePool,
1021 stake_pool_address: &Pubkey,
1022 vote_account_address: &Pubkey,
1023 validator_stake_seed: Option<NonZeroU32>,
1024 transient_stake_seed: u64,
1025) -> Instruction {
1026 let pool_withdraw_authority =
1027 find_withdraw_authority_program_address(program_id, stake_pool_address).0;
1028 let (stake_account_address, _) = find_stake_program_address(
1029 program_id,
1030 vote_account_address,
1031 stake_pool_address,
1032 validator_stake_seed,
1033 );
1034 let (transient_stake_account, _) = find_transient_stake_program_address(
1035 program_id,
1036 vote_account_address,
1037 stake_pool_address,
1038 transient_stake_seed,
1039 );
1040 remove_validator_from_pool(
1041 program_id,
1042 stake_pool_address,
1043 &stake_pool.staker,
1044 &pool_withdraw_authority,
1045 &stake_pool.validator_list,
1046 &stake_account_address,
1047 &transient_stake_account,
1048 )
1049}
1050
1051pub fn increase_validator_stake_with_vote(
1054 program_id: &Pubkey,
1055 stake_pool: &StakePool,
1056 stake_pool_address: &Pubkey,
1057 vote_account_address: &Pubkey,
1058 lamports: u64,
1059 validator_stake_seed: Option<NonZeroU32>,
1060 transient_stake_seed: u64,
1061) -> Instruction {
1062 let pool_withdraw_authority =
1063 find_withdraw_authority_program_address(program_id, stake_pool_address).0;
1064 let (transient_stake_address, _) = find_transient_stake_program_address(
1065 program_id,
1066 vote_account_address,
1067 stake_pool_address,
1068 transient_stake_seed,
1069 );
1070 let (validator_stake_address, _) = find_stake_program_address(
1071 program_id,
1072 vote_account_address,
1073 stake_pool_address,
1074 validator_stake_seed,
1075 );
1076
1077 increase_validator_stake(
1078 program_id,
1079 stake_pool_address,
1080 &stake_pool.staker,
1081 &pool_withdraw_authority,
1082 &stake_pool.validator_list,
1083 &stake_pool.reserve_stake,
1084 &transient_stake_address,
1085 &validator_stake_address,
1086 vote_account_address,
1087 lamports,
1088 transient_stake_seed,
1089 )
1090}
1091
1092pub fn increase_additional_validator_stake_with_vote(
1095 program_id: &Pubkey,
1096 stake_pool: &StakePool,
1097 stake_pool_address: &Pubkey,
1098 vote_account_address: &Pubkey,
1099 lamports: u64,
1100 validator_stake_seed: Option<NonZeroU32>,
1101 transient_stake_seed: u64,
1102 ephemeral_stake_seed: u64,
1103) -> Instruction {
1104 let pool_withdraw_authority =
1105 find_withdraw_authority_program_address(program_id, stake_pool_address).0;
1106 let (ephemeral_stake_address, _) =
1107 find_ephemeral_stake_program_address(program_id, stake_pool_address, ephemeral_stake_seed);
1108 let (transient_stake_address, _) = find_transient_stake_program_address(
1109 program_id,
1110 vote_account_address,
1111 stake_pool_address,
1112 transient_stake_seed,
1113 );
1114 let (validator_stake_address, _) = find_stake_program_address(
1115 program_id,
1116 vote_account_address,
1117 stake_pool_address,
1118 validator_stake_seed,
1119 );
1120
1121 increase_additional_validator_stake(
1122 program_id,
1123 stake_pool_address,
1124 &stake_pool.staker,
1125 &pool_withdraw_authority,
1126 &stake_pool.validator_list,
1127 &stake_pool.reserve_stake,
1128 &ephemeral_stake_address,
1129 &transient_stake_address,
1130 &validator_stake_address,
1131 vote_account_address,
1132 lamports,
1133 transient_stake_seed,
1134 ephemeral_stake_seed,
1135 )
1136}
1137
1138pub fn decrease_validator_stake_with_vote(
1141 program_id: &Pubkey,
1142 stake_pool: &StakePool,
1143 stake_pool_address: &Pubkey,
1144 vote_account_address: &Pubkey,
1145 lamports: u64,
1146 validator_stake_seed: Option<NonZeroU32>,
1147 transient_stake_seed: u64,
1148) -> Instruction {
1149 let pool_withdraw_authority =
1150 find_withdraw_authority_program_address(program_id, stake_pool_address).0;
1151 let (validator_stake_address, _) = find_stake_program_address(
1152 program_id,
1153 vote_account_address,
1154 stake_pool_address,
1155 validator_stake_seed,
1156 );
1157 let (transient_stake_address, _) = find_transient_stake_program_address(
1158 program_id,
1159 vote_account_address,
1160 stake_pool_address,
1161 transient_stake_seed,
1162 );
1163 decrease_validator_stake(
1164 program_id,
1165 stake_pool_address,
1166 &stake_pool.staker,
1167 &pool_withdraw_authority,
1168 &stake_pool.validator_list,
1169 &validator_stake_address,
1170 &transient_stake_address,
1171 lamports,
1172 transient_stake_seed,
1173 )
1174}
1175
1176pub fn decrease_additional_validator_stake_with_vote(
1179 program_id: &Pubkey,
1180 stake_pool: &StakePool,
1181 stake_pool_address: &Pubkey,
1182 vote_account_address: &Pubkey,
1183 lamports: u64,
1184 validator_stake_seed: Option<NonZeroU32>,
1185 transient_stake_seed: u64,
1186 ephemeral_stake_seed: u64,
1187) -> Instruction {
1188 let pool_withdraw_authority =
1189 find_withdraw_authority_program_address(program_id, stake_pool_address).0;
1190 let (validator_stake_address, _) = find_stake_program_address(
1191 program_id,
1192 vote_account_address,
1193 stake_pool_address,
1194 validator_stake_seed,
1195 );
1196 let (ephemeral_stake_address, _) =
1197 find_ephemeral_stake_program_address(program_id, stake_pool_address, ephemeral_stake_seed);
1198 let (transient_stake_address, _) = find_transient_stake_program_address(
1199 program_id,
1200 vote_account_address,
1201 stake_pool_address,
1202 transient_stake_seed,
1203 );
1204 decrease_additional_validator_stake(
1205 program_id,
1206 stake_pool_address,
1207 &stake_pool.staker,
1208 &pool_withdraw_authority,
1209 &stake_pool.validator_list,
1210 &validator_stake_address,
1211 &ephemeral_stake_address,
1212 &transient_stake_address,
1213 lamports,
1214 transient_stake_seed,
1215 ephemeral_stake_seed,
1216 )
1217}
1218
1219pub fn update_validator_list_balance(
1221 program_id: &Pubkey,
1222 stake_pool: &Pubkey,
1223 stake_pool_withdraw_authority: &Pubkey,
1224 validator_list_address: &Pubkey,
1225 reserve_stake: &Pubkey,
1226 validator_list: &ValidatorList,
1227 validator_vote_accounts: &[Pubkey],
1228 start_index: u32,
1229 no_merge: bool,
1230) -> Instruction {
1231 let mut accounts = vec![
1232 AccountMeta::new_readonly(*stake_pool, false),
1233 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
1234 AccountMeta::new(*validator_list_address, false),
1235 AccountMeta::new(*reserve_stake, false),
1236 AccountMeta::new_readonly(sysvar::clock::id(), false),
1237 AccountMeta::new_readonly(sysvar::stake_history::id(), false),
1238 AccountMeta::new_readonly(stake::program::id(), false),
1239 ];
1240 accounts.append(
1241 &mut validator_vote_accounts
1242 .iter()
1243 .flat_map(|vote_account_address| {
1244 let validator_stake_info = validator_list.find(vote_account_address);
1245 if let Some(validator_stake_info) = validator_stake_info {
1246 let (validator_stake_account, _) = find_stake_program_address(
1247 program_id,
1248 vote_account_address,
1249 stake_pool,
1250 NonZeroU32::new(validator_stake_info.validator_seed_suffix),
1251 );
1252 let (transient_stake_account, _) = find_transient_stake_program_address(
1253 program_id,
1254 vote_account_address,
1255 stake_pool,
1256 validator_stake_info.transient_seed_suffix,
1257 );
1258 vec![
1259 AccountMeta::new(validator_stake_account, false),
1260 AccountMeta::new(transient_stake_account, false),
1261 ]
1262 } else {
1263 vec![]
1264 }
1265 })
1266 .collect::<Vec<AccountMeta>>(),
1267 );
1268 Instruction {
1269 program_id: *program_id,
1270 accounts,
1271 data: StakePoolInstruction::UpdateValidatorListBalance {
1272 start_index,
1273 no_merge,
1274 }
1275 .try_to_vec()
1276 .unwrap(),
1277 }
1278}
1279
1280pub fn update_stake_pool_balance(
1282 program_id: &Pubkey,
1283 stake_pool: &Pubkey,
1284 withdraw_authority: &Pubkey,
1285 validator_list_storage: &Pubkey,
1286 reserve_stake: &Pubkey,
1287 manager_fee_account: &Pubkey,
1288 stake_pool_mint: &Pubkey,
1289 token_program_id: &Pubkey,
1290) -> Instruction {
1291 let accounts = vec![
1292 AccountMeta::new(*stake_pool, false),
1293 AccountMeta::new_readonly(*withdraw_authority, false),
1294 AccountMeta::new(*validator_list_storage, false),
1295 AccountMeta::new_readonly(*reserve_stake, false),
1296 AccountMeta::new(*manager_fee_account, false),
1297 AccountMeta::new(*stake_pool_mint, false),
1298 AccountMeta::new_readonly(*token_program_id, false),
1299 ];
1300 Instruction {
1301 program_id: *program_id,
1302 accounts,
1303 data: StakePoolInstruction::UpdateStakePoolBalance
1304 .try_to_vec()
1305 .unwrap(),
1306 }
1307}
1308
1309pub fn cleanup_removed_validator_entries(
1311 program_id: &Pubkey,
1312 stake_pool: &Pubkey,
1313 validator_list_storage: &Pubkey,
1314) -> Instruction {
1315 let accounts = vec![
1316 AccountMeta::new_readonly(*stake_pool, false),
1317 AccountMeta::new(*validator_list_storage, false),
1318 ];
1319 Instruction {
1320 program_id: *program_id,
1321 accounts,
1322 data: StakePoolInstruction::CleanupRemovedValidatorEntries
1323 .try_to_vec()
1324 .unwrap(),
1325 }
1326}
1327
1328pub fn update_stake_pool(
1331 program_id: &Pubkey,
1332 stake_pool: &StakePool,
1333 validator_list: &ValidatorList,
1334 stake_pool_address: &Pubkey,
1335 no_merge: bool,
1336) -> (Vec<Instruction>, Vec<Instruction>) {
1337 let vote_accounts: Vec<Pubkey> = validator_list
1338 .validators
1339 .iter()
1340 .map(|item| item.vote_account_address)
1341 .collect();
1342
1343 let (withdraw_authority, _) =
1344 find_withdraw_authority_program_address(program_id, stake_pool_address);
1345
1346 let mut update_list_instructions: Vec<Instruction> = vec![];
1347 let mut start_index = 0;
1348 for accounts_chunk in vote_accounts.chunks(MAX_VALIDATORS_TO_UPDATE) {
1349 update_list_instructions.push(update_validator_list_balance(
1350 program_id,
1351 stake_pool_address,
1352 &withdraw_authority,
1353 &stake_pool.validator_list,
1354 &stake_pool.reserve_stake,
1355 validator_list,
1356 accounts_chunk,
1357 start_index,
1358 no_merge,
1359 ));
1360 start_index = start_index.saturating_add(MAX_VALIDATORS_TO_UPDATE as u32);
1361 }
1362
1363 let final_instructions = vec![
1364 update_stake_pool_balance(
1365 program_id,
1366 stake_pool_address,
1367 &withdraw_authority,
1368 &stake_pool.validator_list,
1369 &stake_pool.reserve_stake,
1370 &stake_pool.manager_fee_account,
1371 &stake_pool.pool_mint,
1372 &stake_pool.token_program_id,
1373 ),
1374 cleanup_removed_validator_entries(
1375 program_id,
1376 stake_pool_address,
1377 &stake_pool.validator_list,
1378 ),
1379 ];
1380 (update_list_instructions, final_instructions)
1381}
1382
1383fn deposit_stake_internal(
1384 program_id: &Pubkey,
1385 stake_pool: &Pubkey,
1386 validator_list_storage: &Pubkey,
1387 stake_pool_deposit_authority: Option<&Pubkey>,
1388 stake_pool_withdraw_authority: &Pubkey,
1389 deposit_stake_address: &Pubkey,
1390 deposit_stake_withdraw_authority: &Pubkey,
1391 validator_stake_account: &Pubkey,
1392 reserve_stake_account: &Pubkey,
1393 pool_tokens_to: &Pubkey,
1394 manager_fee_account: &Pubkey,
1395 referrer_pool_tokens_account: &Pubkey,
1396 pool_mint: &Pubkey,
1397 token_program_id: &Pubkey,
1398 minimum_pool_tokens_out: Option<u64>,
1399) -> Vec<Instruction> {
1400 let mut instructions = vec![];
1401 let mut accounts = vec![
1402 AccountMeta::new(*stake_pool, false),
1403 AccountMeta::new(*validator_list_storage, false),
1404 ];
1405 if let Some(stake_pool_deposit_authority) = stake_pool_deposit_authority {
1406 accounts.push(AccountMeta::new_readonly(
1407 *stake_pool_deposit_authority,
1408 true,
1409 ));
1410 instructions.extend_from_slice(&[
1411 stake::instruction::authorize(
1412 deposit_stake_address,
1413 deposit_stake_withdraw_authority,
1414 stake_pool_deposit_authority,
1415 stake::state::StakeAuthorize::Staker,
1416 None,
1417 ),
1418 stake::instruction::authorize(
1419 deposit_stake_address,
1420 deposit_stake_withdraw_authority,
1421 stake_pool_deposit_authority,
1422 stake::state::StakeAuthorize::Withdrawer,
1423 None,
1424 ),
1425 ]);
1426 } else {
1427 let stake_pool_deposit_authority =
1428 find_deposit_authority_program_address(program_id, stake_pool).0;
1429 accounts.push(AccountMeta::new_readonly(
1430 stake_pool_deposit_authority,
1431 false,
1432 ));
1433 instructions.extend_from_slice(&[
1434 stake::instruction::authorize(
1435 deposit_stake_address,
1436 deposit_stake_withdraw_authority,
1437 &stake_pool_deposit_authority,
1438 stake::state::StakeAuthorize::Staker,
1439 None,
1440 ),
1441 stake::instruction::authorize(
1442 deposit_stake_address,
1443 deposit_stake_withdraw_authority,
1444 &stake_pool_deposit_authority,
1445 stake::state::StakeAuthorize::Withdrawer,
1446 None,
1447 ),
1448 ]);
1449 };
1450
1451 accounts.extend_from_slice(&[
1452 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
1453 AccountMeta::new(*deposit_stake_address, false),
1454 AccountMeta::new(*validator_stake_account, false),
1455 AccountMeta::new(*reserve_stake_account, false),
1456 AccountMeta::new(*pool_tokens_to, false),
1457 AccountMeta::new(*manager_fee_account, false),
1458 AccountMeta::new(*referrer_pool_tokens_account, false),
1459 AccountMeta::new(*pool_mint, false),
1460 AccountMeta::new_readonly(sysvar::clock::id(), false),
1461 AccountMeta::new_readonly(sysvar::stake_history::id(), false),
1462 AccountMeta::new_readonly(*token_program_id, false),
1463 AccountMeta::new_readonly(stake::program::id(), false),
1464 ]);
1465 instructions.push(
1466 if let Some(minimum_pool_tokens_out) = minimum_pool_tokens_out {
1467 Instruction {
1468 program_id: *program_id,
1469 accounts,
1470 data: StakePoolInstruction::DepositStakeWithSlippage {
1471 minimum_pool_tokens_out,
1472 }
1473 .try_to_vec()
1474 .unwrap(),
1475 }
1476 } else {
1477 Instruction {
1478 program_id: *program_id,
1479 accounts,
1480 data: StakePoolInstruction::DepositStake.try_to_vec().unwrap(),
1481 }
1482 },
1483 );
1484 instructions
1485}
1486
1487pub fn deposit_stake(
1490 program_id: &Pubkey,
1491 stake_pool: &Pubkey,
1492 validator_list_storage: &Pubkey,
1493 stake_pool_withdraw_authority: &Pubkey,
1494 deposit_stake_address: &Pubkey,
1495 deposit_stake_withdraw_authority: &Pubkey,
1496 validator_stake_account: &Pubkey,
1497 reserve_stake_account: &Pubkey,
1498 pool_tokens_to: &Pubkey,
1499 manager_fee_account: &Pubkey,
1500 referrer_pool_tokens_account: &Pubkey,
1501 pool_mint: &Pubkey,
1502 token_program_id: &Pubkey,
1503) -> Vec<Instruction> {
1504 deposit_stake_internal(
1505 program_id,
1506 stake_pool,
1507 validator_list_storage,
1508 None,
1509 stake_pool_withdraw_authority,
1510 deposit_stake_address,
1511 deposit_stake_withdraw_authority,
1512 validator_stake_account,
1513 reserve_stake_account,
1514 pool_tokens_to,
1515 manager_fee_account,
1516 referrer_pool_tokens_account,
1517 pool_mint,
1518 token_program_id,
1519 None,
1520 )
1521}
1522
1523pub fn deposit_stake_with_slippage(
1525 program_id: &Pubkey,
1526 stake_pool: &Pubkey,
1527 validator_list_storage: &Pubkey,
1528 stake_pool_withdraw_authority: &Pubkey,
1529 deposit_stake_address: &Pubkey,
1530 deposit_stake_withdraw_authority: &Pubkey,
1531 validator_stake_account: &Pubkey,
1532 reserve_stake_account: &Pubkey,
1533 pool_tokens_to: &Pubkey,
1534 manager_fee_account: &Pubkey,
1535 referrer_pool_tokens_account: &Pubkey,
1536 pool_mint: &Pubkey,
1537 token_program_id: &Pubkey,
1538 minimum_pool_tokens_out: u64,
1539) -> Vec<Instruction> {
1540 deposit_stake_internal(
1541 program_id,
1542 stake_pool,
1543 validator_list_storage,
1544 None,
1545 stake_pool_withdraw_authority,
1546 deposit_stake_address,
1547 deposit_stake_withdraw_authority,
1548 validator_stake_account,
1549 reserve_stake_account,
1550 pool_tokens_to,
1551 manager_fee_account,
1552 referrer_pool_tokens_account,
1553 pool_mint,
1554 token_program_id,
1555 Some(minimum_pool_tokens_out),
1556 )
1557}
1558
1559pub fn deposit_stake_with_authority(
1563 program_id: &Pubkey,
1564 stake_pool: &Pubkey,
1565 validator_list_storage: &Pubkey,
1566 stake_pool_deposit_authority: &Pubkey,
1567 stake_pool_withdraw_authority: &Pubkey,
1568 deposit_stake_address: &Pubkey,
1569 deposit_stake_withdraw_authority: &Pubkey,
1570 validator_stake_account: &Pubkey,
1571 reserve_stake_account: &Pubkey,
1572 pool_tokens_to: &Pubkey,
1573 manager_fee_account: &Pubkey,
1574 referrer_pool_tokens_account: &Pubkey,
1575 pool_mint: &Pubkey,
1576 token_program_id: &Pubkey,
1577) -> Vec<Instruction> {
1578 deposit_stake_internal(
1579 program_id,
1580 stake_pool,
1581 validator_list_storage,
1582 Some(stake_pool_deposit_authority),
1583 stake_pool_withdraw_authority,
1584 deposit_stake_address,
1585 deposit_stake_withdraw_authority,
1586 validator_stake_account,
1587 reserve_stake_account,
1588 pool_tokens_to,
1589 manager_fee_account,
1590 referrer_pool_tokens_account,
1591 pool_mint,
1592 token_program_id,
1593 None,
1594 )
1595}
1596
1597pub fn deposit_stake_with_authority_and_slippage(
1601 program_id: &Pubkey,
1602 stake_pool: &Pubkey,
1603 validator_list_storage: &Pubkey,
1604 stake_pool_deposit_authority: &Pubkey,
1605 stake_pool_withdraw_authority: &Pubkey,
1606 deposit_stake_address: &Pubkey,
1607 deposit_stake_withdraw_authority: &Pubkey,
1608 validator_stake_account: &Pubkey,
1609 reserve_stake_account: &Pubkey,
1610 pool_tokens_to: &Pubkey,
1611 manager_fee_account: &Pubkey,
1612 referrer_pool_tokens_account: &Pubkey,
1613 pool_mint: &Pubkey,
1614 token_program_id: &Pubkey,
1615 minimum_pool_tokens_out: u64,
1616) -> Vec<Instruction> {
1617 deposit_stake_internal(
1618 program_id,
1619 stake_pool,
1620 validator_list_storage,
1621 Some(stake_pool_deposit_authority),
1622 stake_pool_withdraw_authority,
1623 deposit_stake_address,
1624 deposit_stake_withdraw_authority,
1625 validator_stake_account,
1626 reserve_stake_account,
1627 pool_tokens_to,
1628 manager_fee_account,
1629 referrer_pool_tokens_account,
1630 pool_mint,
1631 token_program_id,
1632 Some(minimum_pool_tokens_out),
1633 )
1634}
1635
1636fn deposit_sol_internal(
1638 program_id: &Pubkey,
1639 stake_pool: &Pubkey,
1640 stake_pool_withdraw_authority: &Pubkey,
1641 reserve_stake_account: &Pubkey,
1642 lamports_from: &Pubkey,
1643 pool_tokens_to: &Pubkey,
1644 manager_fee_account: &Pubkey,
1645 referrer_pool_tokens_account: &Pubkey,
1646 pool_mint: &Pubkey,
1647 token_program_id: &Pubkey,
1648 sol_deposit_authority: Option<&Pubkey>,
1649 lamports_in: u64,
1650 minimum_pool_tokens_out: Option<u64>,
1651) -> Instruction {
1652 let mut accounts = vec![
1653 AccountMeta::new(*stake_pool, false),
1654 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
1655 AccountMeta::new(*reserve_stake_account, false),
1656 AccountMeta::new(*lamports_from, true),
1657 AccountMeta::new(*pool_tokens_to, false),
1658 AccountMeta::new(*manager_fee_account, false),
1659 AccountMeta::new(*referrer_pool_tokens_account, false),
1660 AccountMeta::new(*pool_mint, false),
1661 AccountMeta::new_readonly(system_program::id(), false),
1662 AccountMeta::new_readonly(*token_program_id, false),
1663 ];
1664 if let Some(sol_deposit_authority) = sol_deposit_authority {
1665 accounts.push(AccountMeta::new_readonly(*sol_deposit_authority, true));
1666 }
1667 if let Some(minimum_pool_tokens_out) = minimum_pool_tokens_out {
1668 Instruction {
1669 program_id: *program_id,
1670 accounts,
1671 data: StakePoolInstruction::DepositSolWithSlippage {
1672 lamports_in,
1673 minimum_pool_tokens_out,
1674 }
1675 .try_to_vec()
1676 .unwrap(),
1677 }
1678 } else {
1679 Instruction {
1680 program_id: *program_id,
1681 accounts,
1682 data: StakePoolInstruction::DepositSol(lamports_in)
1683 .try_to_vec()
1684 .unwrap(),
1685 }
1686 }
1687}
1688
1689pub fn deposit_sol(
1691 program_id: &Pubkey,
1692 stake_pool: &Pubkey,
1693 stake_pool_withdraw_authority: &Pubkey,
1694 reserve_stake_account: &Pubkey,
1695 lamports_from: &Pubkey,
1696 pool_tokens_to: &Pubkey,
1697 manager_fee_account: &Pubkey,
1698 referrer_pool_tokens_account: &Pubkey,
1699 pool_mint: &Pubkey,
1700 token_program_id: &Pubkey,
1701 lamports_in: u64,
1702) -> Instruction {
1703 deposit_sol_internal(
1704 program_id,
1705 stake_pool,
1706 stake_pool_withdraw_authority,
1707 reserve_stake_account,
1708 lamports_from,
1709 pool_tokens_to,
1710 manager_fee_account,
1711 referrer_pool_tokens_account,
1712 pool_mint,
1713 token_program_id,
1714 None,
1715 lamports_in,
1716 None,
1717 )
1718}
1719
1720pub fn deposit_sol_with_slippage(
1722 program_id: &Pubkey,
1723 stake_pool: &Pubkey,
1724 stake_pool_withdraw_authority: &Pubkey,
1725 reserve_stake_account: &Pubkey,
1726 lamports_from: &Pubkey,
1727 pool_tokens_to: &Pubkey,
1728 manager_fee_account: &Pubkey,
1729 referrer_pool_tokens_account: &Pubkey,
1730 pool_mint: &Pubkey,
1731 token_program_id: &Pubkey,
1732 lamports_in: u64,
1733 minimum_pool_tokens_out: u64,
1734) -> Instruction {
1735 deposit_sol_internal(
1736 program_id,
1737 stake_pool,
1738 stake_pool_withdraw_authority,
1739 reserve_stake_account,
1740 lamports_from,
1741 pool_tokens_to,
1742 manager_fee_account,
1743 referrer_pool_tokens_account,
1744 pool_mint,
1745 token_program_id,
1746 None,
1747 lamports_in,
1748 Some(minimum_pool_tokens_out),
1749 )
1750}
1751
1752pub fn deposit_sol_with_authority(
1756 program_id: &Pubkey,
1757 stake_pool: &Pubkey,
1758 sol_deposit_authority: &Pubkey,
1759 stake_pool_withdraw_authority: &Pubkey,
1760 reserve_stake_account: &Pubkey,
1761 lamports_from: &Pubkey,
1762 pool_tokens_to: &Pubkey,
1763 manager_fee_account: &Pubkey,
1764 referrer_pool_tokens_account: &Pubkey,
1765 pool_mint: &Pubkey,
1766 token_program_id: &Pubkey,
1767 lamports_in: u64,
1768) -> Instruction {
1769 deposit_sol_internal(
1770 program_id,
1771 stake_pool,
1772 stake_pool_withdraw_authority,
1773 reserve_stake_account,
1774 lamports_from,
1775 pool_tokens_to,
1776 manager_fee_account,
1777 referrer_pool_tokens_account,
1778 pool_mint,
1779 token_program_id,
1780 Some(sol_deposit_authority),
1781 lamports_in,
1782 None,
1783 )
1784}
1785
1786pub fn deposit_sol_with_authority_and_slippage(
1788 program_id: &Pubkey,
1789 stake_pool: &Pubkey,
1790 sol_deposit_authority: &Pubkey,
1791 stake_pool_withdraw_authority: &Pubkey,
1792 reserve_stake_account: &Pubkey,
1793 lamports_from: &Pubkey,
1794 pool_tokens_to: &Pubkey,
1795 manager_fee_account: &Pubkey,
1796 referrer_pool_tokens_account: &Pubkey,
1797 pool_mint: &Pubkey,
1798 token_program_id: &Pubkey,
1799 lamports_in: u64,
1800 minimum_pool_tokens_out: u64,
1801) -> Instruction {
1802 deposit_sol_internal(
1803 program_id,
1804 stake_pool,
1805 stake_pool_withdraw_authority,
1806 reserve_stake_account,
1807 lamports_from,
1808 pool_tokens_to,
1809 manager_fee_account,
1810 referrer_pool_tokens_account,
1811 pool_mint,
1812 token_program_id,
1813 Some(sol_deposit_authority),
1814 lamports_in,
1815 Some(minimum_pool_tokens_out),
1816 )
1817}
1818
1819fn withdraw_stake_internal(
1820 program_id: &Pubkey,
1821 stake_pool: &Pubkey,
1822 validator_list_storage: &Pubkey,
1823 stake_pool_withdraw: &Pubkey,
1824 stake_to_split: &Pubkey,
1825 stake_to_receive: &Pubkey,
1826 user_stake_authority: &Pubkey,
1827 user_transfer_authority: &Pubkey,
1828 user_pool_token_account: &Pubkey,
1829 manager_fee_account: &Pubkey,
1830 pool_mint: &Pubkey,
1831 token_program_id: &Pubkey,
1832 pool_tokens_in: u64,
1833 minimum_lamports_out: Option<u64>,
1834) -> Instruction {
1835 let accounts = vec![
1836 AccountMeta::new(*stake_pool, false),
1837 AccountMeta::new(*validator_list_storage, false),
1838 AccountMeta::new_readonly(*stake_pool_withdraw, false),
1839 AccountMeta::new(*stake_to_split, false),
1840 AccountMeta::new(*stake_to_receive, false),
1841 AccountMeta::new_readonly(*user_stake_authority, false),
1842 AccountMeta::new_readonly(*user_transfer_authority, true),
1843 AccountMeta::new(*user_pool_token_account, false),
1844 AccountMeta::new(*manager_fee_account, false),
1845 AccountMeta::new(*pool_mint, false),
1846 AccountMeta::new_readonly(sysvar::clock::id(), false),
1847 AccountMeta::new_readonly(*token_program_id, false),
1848 AccountMeta::new_readonly(stake::program::id(), false),
1849 ];
1850 if let Some(minimum_lamports_out) = minimum_lamports_out {
1851 Instruction {
1852 program_id: *program_id,
1853 accounts,
1854 data: StakePoolInstruction::WithdrawStakeWithSlippage {
1855 pool_tokens_in,
1856 minimum_lamports_out,
1857 }
1858 .try_to_vec()
1859 .unwrap(),
1860 }
1861 } else {
1862 Instruction {
1863 program_id: *program_id,
1864 accounts,
1865 data: StakePoolInstruction::WithdrawStake(pool_tokens_in)
1866 .try_to_vec()
1867 .unwrap(),
1868 }
1869 }
1870}
1871
1872pub fn withdraw_stake(
1874 program_id: &Pubkey,
1875 stake_pool: &Pubkey,
1876 validator_list_storage: &Pubkey,
1877 stake_pool_withdraw: &Pubkey,
1878 stake_to_split: &Pubkey,
1879 stake_to_receive: &Pubkey,
1880 user_stake_authority: &Pubkey,
1881 user_transfer_authority: &Pubkey,
1882 user_pool_token_account: &Pubkey,
1883 manager_fee_account: &Pubkey,
1884 pool_mint: &Pubkey,
1885 token_program_id: &Pubkey,
1886 pool_tokens_in: u64,
1887) -> Instruction {
1888 withdraw_stake_internal(
1889 program_id,
1890 stake_pool,
1891 validator_list_storage,
1892 stake_pool_withdraw,
1893 stake_to_split,
1894 stake_to_receive,
1895 user_stake_authority,
1896 user_transfer_authority,
1897 user_pool_token_account,
1898 manager_fee_account,
1899 pool_mint,
1900 token_program_id,
1901 pool_tokens_in,
1902 None,
1903 )
1904}
1905
1906pub fn withdraw_stake_with_slippage(
1908 program_id: &Pubkey,
1909 stake_pool: &Pubkey,
1910 validator_list_storage: &Pubkey,
1911 stake_pool_withdraw: &Pubkey,
1912 stake_to_split: &Pubkey,
1913 stake_to_receive: &Pubkey,
1914 user_stake_authority: &Pubkey,
1915 user_transfer_authority: &Pubkey,
1916 user_pool_token_account: &Pubkey,
1917 manager_fee_account: &Pubkey,
1918 pool_mint: &Pubkey,
1919 token_program_id: &Pubkey,
1920 pool_tokens_in: u64,
1921 minimum_lamports_out: u64,
1922) -> Instruction {
1923 withdraw_stake_internal(
1924 program_id,
1925 stake_pool,
1926 validator_list_storage,
1927 stake_pool_withdraw,
1928 stake_to_split,
1929 stake_to_receive,
1930 user_stake_authority,
1931 user_transfer_authority,
1932 user_pool_token_account,
1933 manager_fee_account,
1934 pool_mint,
1935 token_program_id,
1936 pool_tokens_in,
1937 Some(minimum_lamports_out),
1938 )
1939}
1940
1941fn withdraw_sol_internal(
1942 program_id: &Pubkey,
1943 stake_pool: &Pubkey,
1944 stake_pool_withdraw_authority: &Pubkey,
1945 user_transfer_authority: &Pubkey,
1946 pool_tokens_from: &Pubkey,
1947 reserve_stake_account: &Pubkey,
1948 lamports_to: &Pubkey,
1949 manager_fee_account: &Pubkey,
1950 pool_mint: &Pubkey,
1951 token_program_id: &Pubkey,
1952 sol_withdraw_authority: Option<&Pubkey>,
1953 pool_tokens_in: u64,
1954 minimum_lamports_out: Option<u64>,
1955) -> Instruction {
1956 let mut accounts = vec![
1957 AccountMeta::new(*stake_pool, false),
1958 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
1959 AccountMeta::new_readonly(*user_transfer_authority, true),
1960 AccountMeta::new(*pool_tokens_from, false),
1961 AccountMeta::new(*reserve_stake_account, false),
1962 AccountMeta::new(*lamports_to, false),
1963 AccountMeta::new(*manager_fee_account, false),
1964 AccountMeta::new(*pool_mint, false),
1965 AccountMeta::new_readonly(sysvar::clock::id(), false),
1966 AccountMeta::new_readonly(sysvar::stake_history::id(), false),
1967 AccountMeta::new_readonly(stake::program::id(), false),
1968 AccountMeta::new_readonly(*token_program_id, false),
1969 ];
1970 if let Some(sol_withdraw_authority) = sol_withdraw_authority {
1971 accounts.push(AccountMeta::new_readonly(*sol_withdraw_authority, true));
1972 }
1973 if let Some(minimum_lamports_out) = minimum_lamports_out {
1974 Instruction {
1975 program_id: *program_id,
1976 accounts,
1977 data: StakePoolInstruction::WithdrawSolWithSlippage {
1978 pool_tokens_in,
1979 minimum_lamports_out,
1980 }
1981 .try_to_vec()
1982 .unwrap(),
1983 }
1984 } else {
1985 Instruction {
1986 program_id: *program_id,
1987 accounts,
1988 data: StakePoolInstruction::WithdrawSol(pool_tokens_in)
1989 .try_to_vec()
1990 .unwrap(),
1991 }
1992 }
1993}
1994
1995pub fn withdraw_sol(
1997 program_id: &Pubkey,
1998 stake_pool: &Pubkey,
1999 stake_pool_withdraw_authority: &Pubkey,
2000 user_transfer_authority: &Pubkey,
2001 pool_tokens_from: &Pubkey,
2002 reserve_stake_account: &Pubkey,
2003 lamports_to: &Pubkey,
2004 manager_fee_account: &Pubkey,
2005 pool_mint: &Pubkey,
2006 token_program_id: &Pubkey,
2007 pool_tokens_in: u64,
2008) -> Instruction {
2009 withdraw_sol_internal(
2010 program_id,
2011 stake_pool,
2012 stake_pool_withdraw_authority,
2013 user_transfer_authority,
2014 pool_tokens_from,
2015 reserve_stake_account,
2016 lamports_to,
2017 manager_fee_account,
2018 pool_mint,
2019 token_program_id,
2020 None,
2021 pool_tokens_in,
2022 None,
2023 )
2024}
2025
2026pub fn withdraw_sol_with_slippage(
2029 program_id: &Pubkey,
2030 stake_pool: &Pubkey,
2031 stake_pool_withdraw_authority: &Pubkey,
2032 user_transfer_authority: &Pubkey,
2033 pool_tokens_from: &Pubkey,
2034 reserve_stake_account: &Pubkey,
2035 lamports_to: &Pubkey,
2036 manager_fee_account: &Pubkey,
2037 pool_mint: &Pubkey,
2038 token_program_id: &Pubkey,
2039 pool_tokens_in: u64,
2040 minimum_lamports_out: u64,
2041) -> Instruction {
2042 withdraw_sol_internal(
2043 program_id,
2044 stake_pool,
2045 stake_pool_withdraw_authority,
2046 user_transfer_authority,
2047 pool_tokens_from,
2048 reserve_stake_account,
2049 lamports_to,
2050 manager_fee_account,
2051 pool_mint,
2052 token_program_id,
2053 None,
2054 pool_tokens_in,
2055 Some(minimum_lamports_out),
2056 )
2057}
2058
2059pub fn withdraw_sol_with_authority(
2063 program_id: &Pubkey,
2064 stake_pool: &Pubkey,
2065 sol_withdraw_authority: &Pubkey,
2066 stake_pool_withdraw_authority: &Pubkey,
2067 user_transfer_authority: &Pubkey,
2068 pool_tokens_from: &Pubkey,
2069 reserve_stake_account: &Pubkey,
2070 lamports_to: &Pubkey,
2071 manager_fee_account: &Pubkey,
2072 pool_mint: &Pubkey,
2073 token_program_id: &Pubkey,
2074 pool_tokens_in: u64,
2075) -> Instruction {
2076 withdraw_sol_internal(
2077 program_id,
2078 stake_pool,
2079 stake_pool_withdraw_authority,
2080 user_transfer_authority,
2081 pool_tokens_from,
2082 reserve_stake_account,
2083 lamports_to,
2084 manager_fee_account,
2085 pool_mint,
2086 token_program_id,
2087 Some(sol_withdraw_authority),
2088 pool_tokens_in,
2089 None,
2090 )
2091}
2092
2093pub fn withdraw_sol_with_authority_and_slippage(
2098 program_id: &Pubkey,
2099 stake_pool: &Pubkey,
2100 sol_withdraw_authority: &Pubkey,
2101 stake_pool_withdraw_authority: &Pubkey,
2102 user_transfer_authority: &Pubkey,
2103 pool_tokens_from: &Pubkey,
2104 reserve_stake_account: &Pubkey,
2105 lamports_to: &Pubkey,
2106 manager_fee_account: &Pubkey,
2107 pool_mint: &Pubkey,
2108 token_program_id: &Pubkey,
2109 pool_tokens_in: u64,
2110 minimum_lamports_out: u64,
2111) -> Instruction {
2112 withdraw_sol_internal(
2113 program_id,
2114 stake_pool,
2115 stake_pool_withdraw_authority,
2116 user_transfer_authority,
2117 pool_tokens_from,
2118 reserve_stake_account,
2119 lamports_to,
2120 manager_fee_account,
2121 pool_mint,
2122 token_program_id,
2123 Some(sol_withdraw_authority),
2124 pool_tokens_in,
2125 Some(minimum_lamports_out),
2126 )
2127}
2128
2129pub fn set_manager(
2131 program_id: &Pubkey,
2132 stake_pool: &Pubkey,
2133 manager: &Pubkey,
2134 new_manager: &Pubkey,
2135 new_fee_receiver: &Pubkey,
2136) -> Instruction {
2137 let accounts = vec![
2138 AccountMeta::new(*stake_pool, false),
2139 AccountMeta::new_readonly(*manager, true),
2140 AccountMeta::new_readonly(*new_manager, true),
2141 AccountMeta::new_readonly(*new_fee_receiver, false),
2142 ];
2143 Instruction {
2144 program_id: *program_id,
2145 accounts,
2146 data: StakePoolInstruction::SetManager.try_to_vec().unwrap(),
2147 }
2148}
2149
2150pub fn set_fee(
2152 program_id: &Pubkey,
2153 stake_pool: &Pubkey,
2154 manager: &Pubkey,
2155 fee: FeeType,
2156) -> Instruction {
2157 let accounts = vec![
2158 AccountMeta::new(*stake_pool, false),
2159 AccountMeta::new_readonly(*manager, true),
2160 ];
2161 Instruction {
2162 program_id: *program_id,
2163 accounts,
2164 data: StakePoolInstruction::SetFee { fee }.try_to_vec().unwrap(),
2165 }
2166}
2167
2168pub fn set_staker(
2170 program_id: &Pubkey,
2171 stake_pool: &Pubkey,
2172 set_staker_authority: &Pubkey,
2173 new_staker: &Pubkey,
2174) -> Instruction {
2175 let accounts = vec![
2176 AccountMeta::new(*stake_pool, false),
2177 AccountMeta::new_readonly(*set_staker_authority, true),
2178 AccountMeta::new_readonly(*new_staker, false),
2179 ];
2180 Instruction {
2181 program_id: *program_id,
2182 accounts,
2183 data: StakePoolInstruction::SetStaker.try_to_vec().unwrap(),
2184 }
2185}
2186
2187pub fn set_funding_authority(
2189 program_id: &Pubkey,
2190 stake_pool: &Pubkey,
2191 manager: &Pubkey,
2192 new_sol_deposit_authority: Option<&Pubkey>,
2193 funding_type: FundingType,
2194) -> Instruction {
2195 let mut accounts = vec![
2196 AccountMeta::new(*stake_pool, false),
2197 AccountMeta::new_readonly(*manager, true),
2198 ];
2199 if let Some(auth) = new_sol_deposit_authority {
2200 accounts.push(AccountMeta::new_readonly(*auth, false))
2201 }
2202 Instruction {
2203 program_id: *program_id,
2204 accounts,
2205 data: StakePoolInstruction::SetFundingAuthority(funding_type)
2206 .try_to_vec()
2207 .unwrap(),
2208 }
2209}
2210
2211pub fn update_token_metadata(
2214 program_id: &Pubkey,
2215 stake_pool: &Pubkey,
2216 manager: &Pubkey,
2217 pool_mint: &Pubkey,
2218 name: String,
2219 symbol: String,
2220 uri: String,
2221) -> Instruction {
2222 let (stake_pool_withdraw_authority, _) =
2223 find_withdraw_authority_program_address(program_id, stake_pool);
2224 let (token_metadata, _) = find_metadata_account(pool_mint);
2225
2226 let accounts = vec![
2227 AccountMeta::new_readonly(*stake_pool, false),
2228 AccountMeta::new_readonly(*manager, true),
2229 AccountMeta::new_readonly(stake_pool_withdraw_authority, false),
2230 AccountMeta::new(token_metadata, false),
2231 AccountMeta::new_readonly(mpl_token_metadata::id(), false),
2232 ];
2233
2234 Instruction {
2235 program_id: *program_id,
2236 accounts,
2237 data: StakePoolInstruction::UpdateTokenMetadata { name, symbol, uri }
2238 .try_to_vec()
2239 .unwrap(),
2240 }
2241}
2242
2243pub fn create_token_metadata(
2246 program_id: &Pubkey,
2247 stake_pool: &Pubkey,
2248 manager: &Pubkey,
2249 pool_mint: &Pubkey,
2250 payer: &Pubkey,
2251 name: String,
2252 symbol: String,
2253 uri: String,
2254) -> Instruction {
2255 let (stake_pool_withdraw_authority, _) =
2256 find_withdraw_authority_program_address(program_id, stake_pool);
2257 let (token_metadata, _) = find_metadata_account(pool_mint);
2258
2259 let accounts = vec![
2260 AccountMeta::new_readonly(*stake_pool, false),
2261 AccountMeta::new_readonly(*manager, true),
2262 AccountMeta::new_readonly(stake_pool_withdraw_authority, false),
2263 AccountMeta::new_readonly(*pool_mint, false),
2264 AccountMeta::new(*payer, true),
2265 AccountMeta::new(token_metadata, false),
2266 AccountMeta::new_readonly(mpl_token_metadata::id(), false),
2267 AccountMeta::new_readonly(system_program::id(), false),
2268 ];
2269
2270 Instruction {
2271 program_id: *program_id,
2272 accounts,
2273 data: StakePoolInstruction::CreateTokenMetadata { name, symbol, uri }
2274 .try_to_vec()
2275 .unwrap(),
2276 }
2277}