1#![allow(deprecated)]
6#![allow(clippy::too_many_arguments)]
7
8use {
9 crate::{
10 find_deposit_authority_program_address, find_ephemeral_stake_program_address,
11 find_stake_program_address, find_transient_stake_program_address,
12 find_withdraw_authority_program_address,
13 inline_mpl_token_metadata::{self, pda::find_metadata_account},
14 state::{Fee, FeeType, StakePool, ValidatorList, ValidatorStakeInfo},
15 MAX_VALIDATORS_TO_UPDATE,
16 },
17 borsh::{BorshDeserialize, BorshSchema, BorshSerialize},
18 solana_program::{
19 instruction::{AccountMeta, Instruction},
20 program_error::ProgramError,
21 pubkey::Pubkey,
22 stake,
23 stake_history::Epoch,
24 system_program, sysvar,
25 },
26 std::num::NonZeroU32,
27};
28
29#[repr(C)]
32#[derive(Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)]
33pub enum PreferredValidatorType {
34 Deposit,
36 Withdraw,
38}
39
40#[repr(C)]
43#[derive(Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize, BorshSchema)]
44pub enum FundingType {
45 StakeDeposit,
47 SolDeposit,
49 SolWithdraw,
51}
52
53#[repr(C)]
55#[derive(Clone, Debug, PartialEq, BorshSerialize, BorshDeserialize)]
56pub enum StakePoolInstruction {
57 Initialize {
75 fee: Fee,
77 withdrawal_fee: Fee,
79 deposit_fee: Fee,
81 referral_fee: u8,
83 max_validators: u32,
85 },
86
87 AddValidatorToPool(u32),
114
115 RemoveValidatorFromPool,
131
132 DecreaseValidatorStake {
163 lamports: u64,
165 transient_stake_seed: u64,
167 },
168
169 IncreaseValidatorStake {
204 lamports: u64,
206 transient_stake_seed: u64,
208 },
209
210 SetPreferredValidator {
224 validator_type: PreferredValidatorType,
226 validator_vote_address: Option<Pubkey>,
229 },
230
231 UpdateValidatorListBalance {
249 start_index: u32,
251 no_merge: bool,
256 },
257
258 UpdateStakePoolBalance,
269
270 CleanupRemovedValidatorEntries,
275
276 DepositStake,
300
301 WithdrawStake(u64),
338
339 SetManager,
346
347 SetFee {
352 fee: FeeType,
354 },
355
356 SetStaker,
362
363 DepositSol(u64),
379
380 SetFundingAuthority(FundingType),
387
388 WithdrawSol(u64),
406
407 CreateTokenMetadata {
418 name: String,
420 symbol: String,
422 uri: String,
424 },
425 UpdateTokenMetadata {
434 name: String,
436 symbol: String,
438 uri: String,
440 },
441
442 IncreaseAdditionalValidatorStake {
479 lamports: u64,
481 transient_stake_seed: u64,
483 ephemeral_stake_seed: u64,
485 },
486
487 DecreaseAdditionalValidatorStake {
517 lamports: u64,
519 transient_stake_seed: u64,
521 ephemeral_stake_seed: u64,
523 },
524
525 DecreaseValidatorStakeWithReserve {
556 lamports: u64,
558 transient_stake_seed: u64,
560 },
561
562 #[deprecated(
613 since = "2.0.0",
614 note = "The stake redelegate instruction used in this will not be enabled."
615 )]
616 Redelegate {
617 #[allow(dead_code)] lamports: u64,
620 #[allow(dead_code)] source_transient_stake_seed: u64,
623 #[allow(dead_code)] ephemeral_stake_seed: u64,
626 #[allow(dead_code)] destination_transient_stake_seed: u64,
631 },
632
633 DepositStakeWithSlippage {
657 minimum_pool_tokens_out: u64,
659 },
660
661 WithdrawStakeWithSlippage {
687 pool_tokens_in: u64,
689 minimum_lamports_out: u64,
691 },
692
693 DepositSolWithSlippage {
710 lamports_in: u64,
712 minimum_pool_tokens_out: u64,
714 },
715
716 WithdrawSolWithSlippage {
735 pool_tokens_in: u64,
737 minimum_lamports_out: u64,
739 },
740}
741
742pub fn initialize(
744 program_id: &Pubkey,
745 stake_pool: &Pubkey,
746 manager: &Pubkey,
747 staker: &Pubkey,
748 stake_pool_withdraw_authority: &Pubkey,
749 validator_list: &Pubkey,
750 reserve_stake: &Pubkey,
751 pool_mint: &Pubkey,
752 manager_pool_account: &Pubkey,
753 token_program_id: &Pubkey,
754 deposit_authority: Option<Pubkey>,
755 fee: Fee,
756 withdrawal_fee: Fee,
757 deposit_fee: Fee,
758 referral_fee: u8,
759 max_validators: u32,
760) -> Instruction {
761 let init_data = StakePoolInstruction::Initialize {
762 fee,
763 withdrawal_fee,
764 deposit_fee,
765 referral_fee,
766 max_validators,
767 };
768 let data = borsh::to_vec(&init_data).unwrap();
769 let mut accounts = vec![
770 AccountMeta::new(*stake_pool, false),
771 AccountMeta::new_readonly(*manager, true),
772 AccountMeta::new_readonly(*staker, false),
773 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
774 AccountMeta::new(*validator_list, false),
775 AccountMeta::new_readonly(*reserve_stake, false),
776 AccountMeta::new(*pool_mint, false),
777 AccountMeta::new(*manager_pool_account, false),
778 AccountMeta::new_readonly(*token_program_id, false),
779 ];
780 if let Some(deposit_authority) = deposit_authority {
781 accounts.push(AccountMeta::new_readonly(deposit_authority, true));
782 }
783 Instruction {
784 program_id: *program_id,
785 accounts,
786 data,
787 }
788}
789
790pub fn add_validator_to_pool(
793 program_id: &Pubkey,
794 stake_pool: &Pubkey,
795 staker: &Pubkey,
796 reserve: &Pubkey,
797 stake_pool_withdraw: &Pubkey,
798 validator_list: &Pubkey,
799 stake: &Pubkey,
800 validator: &Pubkey,
801 seed: Option<NonZeroU32>,
802) -> Instruction {
803 let accounts = vec![
804 AccountMeta::new(*stake_pool, false),
805 AccountMeta::new_readonly(*staker, true),
806 AccountMeta::new(*reserve, false),
807 AccountMeta::new_readonly(*stake_pool_withdraw, false),
808 AccountMeta::new(*validator_list, false),
809 AccountMeta::new(*stake, false),
810 AccountMeta::new_readonly(*validator, false),
811 AccountMeta::new_readonly(sysvar::rent::id(), false),
812 AccountMeta::new_readonly(sysvar::clock::id(), false),
813 AccountMeta::new_readonly(sysvar::stake_history::id(), false),
814 #[allow(deprecated)]
815 AccountMeta::new_readonly(stake::config::id(), false),
816 AccountMeta::new_readonly(system_program::id(), false),
817 AccountMeta::new_readonly(stake::program::id(), false),
818 ];
819 let data = borsh::to_vec(&StakePoolInstruction::AddValidatorToPool(
820 seed.map(|s| s.get()).unwrap_or(0),
821 ))
822 .unwrap();
823 Instruction {
824 program_id: *program_id,
825 accounts,
826 data,
827 }
828}
829
830pub fn remove_validator_from_pool(
833 program_id: &Pubkey,
834 stake_pool: &Pubkey,
835 staker: &Pubkey,
836 stake_pool_withdraw: &Pubkey,
837 validator_list: &Pubkey,
838 stake_account: &Pubkey,
839 transient_stake_account: &Pubkey,
840) -> Instruction {
841 let accounts = vec![
842 AccountMeta::new(*stake_pool, false),
843 AccountMeta::new_readonly(*staker, true),
844 AccountMeta::new_readonly(*stake_pool_withdraw, false),
845 AccountMeta::new(*validator_list, false),
846 AccountMeta::new(*stake_account, false),
847 AccountMeta::new(*transient_stake_account, false),
848 AccountMeta::new_readonly(sysvar::clock::id(), false),
849 AccountMeta::new_readonly(stake::program::id(), false),
850 ];
851 Instruction {
852 program_id: *program_id,
853 accounts,
854 data: borsh::to_vec(&StakePoolInstruction::RemoveValidatorFromPool).unwrap(),
855 }
856}
857
858#[deprecated(
861 since = "0.7.0",
862 note = "please use `decrease_validator_stake_with_reserve`"
863)]
864pub fn decrease_validator_stake(
865 program_id: &Pubkey,
866 stake_pool: &Pubkey,
867 staker: &Pubkey,
868 stake_pool_withdraw_authority: &Pubkey,
869 validator_list: &Pubkey,
870 validator_stake: &Pubkey,
871 transient_stake: &Pubkey,
872 lamports: u64,
873 transient_stake_seed: u64,
874) -> Instruction {
875 let accounts = vec![
876 AccountMeta::new_readonly(*stake_pool, false),
877 AccountMeta::new_readonly(*staker, true),
878 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
879 AccountMeta::new(*validator_list, false),
880 AccountMeta::new(*validator_stake, false),
881 AccountMeta::new(*transient_stake, false),
882 AccountMeta::new_readonly(sysvar::clock::id(), false),
883 AccountMeta::new_readonly(sysvar::rent::id(), false),
884 AccountMeta::new_readonly(system_program::id(), false),
885 AccountMeta::new_readonly(stake::program::id(), false),
886 ];
887 Instruction {
888 program_id: *program_id,
889 accounts,
890 data: borsh::to_vec(&StakePoolInstruction::DecreaseValidatorStake {
891 lamports,
892 transient_stake_seed,
893 })
894 .unwrap(),
895 }
896}
897
898pub fn decrease_additional_validator_stake(
901 program_id: &Pubkey,
902 stake_pool: &Pubkey,
903 staker: &Pubkey,
904 stake_pool_withdraw_authority: &Pubkey,
905 validator_list: &Pubkey,
906 reserve_stake: &Pubkey,
907 validator_stake: &Pubkey,
908 ephemeral_stake: &Pubkey,
909 transient_stake: &Pubkey,
910 lamports: u64,
911 transient_stake_seed: u64,
912 ephemeral_stake_seed: u64,
913) -> Instruction {
914 let accounts = vec![
915 AccountMeta::new_readonly(*stake_pool, false),
916 AccountMeta::new_readonly(*staker, true),
917 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
918 AccountMeta::new(*validator_list, false),
919 AccountMeta::new(*reserve_stake, false),
920 AccountMeta::new(*validator_stake, false),
921 AccountMeta::new(*ephemeral_stake, false),
922 AccountMeta::new(*transient_stake, false),
923 AccountMeta::new_readonly(sysvar::clock::id(), false),
924 AccountMeta::new_readonly(sysvar::stake_history::id(), false),
925 AccountMeta::new_readonly(system_program::id(), false),
926 AccountMeta::new_readonly(stake::program::id(), false),
927 ];
928 Instruction {
929 program_id: *program_id,
930 accounts,
931 data: borsh::to_vec(&StakePoolInstruction::DecreaseAdditionalValidatorStake {
932 lamports,
933 transient_stake_seed,
934 ephemeral_stake_seed,
935 })
936 .unwrap(),
937 }
938}
939
940pub fn decrease_validator_stake_with_reserve(
943 program_id: &Pubkey,
944 stake_pool: &Pubkey,
945 staker: &Pubkey,
946 stake_pool_withdraw_authority: &Pubkey,
947 validator_list: &Pubkey,
948 reserve_stake: &Pubkey,
949 validator_stake: &Pubkey,
950 transient_stake: &Pubkey,
951 lamports: u64,
952 transient_stake_seed: u64,
953) -> Instruction {
954 let accounts = vec![
955 AccountMeta::new_readonly(*stake_pool, false),
956 AccountMeta::new_readonly(*staker, true),
957 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
958 AccountMeta::new(*validator_list, false),
959 AccountMeta::new(*reserve_stake, false),
960 AccountMeta::new(*validator_stake, false),
961 AccountMeta::new(*transient_stake, false),
962 AccountMeta::new_readonly(sysvar::clock::id(), false),
963 AccountMeta::new_readonly(sysvar::stake_history::id(), false),
964 AccountMeta::new_readonly(system_program::id(), false),
965 AccountMeta::new_readonly(stake::program::id(), false),
966 ];
967 Instruction {
968 program_id: *program_id,
969 accounts,
970 data: borsh::to_vec(&StakePoolInstruction::DecreaseValidatorStakeWithReserve {
971 lamports,
972 transient_stake_seed,
973 })
974 .unwrap(),
975 }
976}
977
978pub fn increase_validator_stake(
981 program_id: &Pubkey,
982 stake_pool: &Pubkey,
983 staker: &Pubkey,
984 stake_pool_withdraw_authority: &Pubkey,
985 validator_list: &Pubkey,
986 reserve_stake: &Pubkey,
987 transient_stake: &Pubkey,
988 validator_stake: &Pubkey,
989 validator: &Pubkey,
990 lamports: u64,
991 transient_stake_seed: u64,
992) -> Instruction {
993 let accounts = vec![
994 AccountMeta::new_readonly(*stake_pool, false),
995 AccountMeta::new_readonly(*staker, true),
996 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
997 AccountMeta::new(*validator_list, false),
998 AccountMeta::new(*reserve_stake, false),
999 AccountMeta::new(*transient_stake, false),
1000 AccountMeta::new_readonly(*validator_stake, false),
1001 AccountMeta::new_readonly(*validator, false),
1002 AccountMeta::new_readonly(sysvar::clock::id(), false),
1003 AccountMeta::new_readonly(sysvar::rent::id(), false),
1004 AccountMeta::new_readonly(sysvar::stake_history::id(), false),
1005 #[allow(deprecated)]
1006 AccountMeta::new_readonly(stake::config::id(), false),
1007 AccountMeta::new_readonly(system_program::id(), false),
1008 AccountMeta::new_readonly(stake::program::id(), false),
1009 ];
1010 Instruction {
1011 program_id: *program_id,
1012 accounts,
1013 data: borsh::to_vec(&StakePoolInstruction::IncreaseValidatorStake {
1014 lamports,
1015 transient_stake_seed,
1016 })
1017 .unwrap(),
1018 }
1019}
1020
1021pub fn increase_additional_validator_stake(
1024 program_id: &Pubkey,
1025 stake_pool: &Pubkey,
1026 staker: &Pubkey,
1027 stake_pool_withdraw_authority: &Pubkey,
1028 validator_list: &Pubkey,
1029 reserve_stake: &Pubkey,
1030 ephemeral_stake: &Pubkey,
1031 transient_stake: &Pubkey,
1032 validator_stake: &Pubkey,
1033 validator: &Pubkey,
1034 lamports: u64,
1035 transient_stake_seed: u64,
1036 ephemeral_stake_seed: u64,
1037) -> Instruction {
1038 let accounts = vec![
1039 AccountMeta::new_readonly(*stake_pool, false),
1040 AccountMeta::new_readonly(*staker, true),
1041 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
1042 AccountMeta::new(*validator_list, false),
1043 AccountMeta::new(*reserve_stake, false),
1044 AccountMeta::new(*ephemeral_stake, false),
1045 AccountMeta::new(*transient_stake, false),
1046 AccountMeta::new_readonly(*validator_stake, false),
1047 AccountMeta::new_readonly(*validator, false),
1048 AccountMeta::new_readonly(sysvar::clock::id(), false),
1049 AccountMeta::new_readonly(sysvar::stake_history::id(), false),
1050 #[allow(deprecated)]
1051 AccountMeta::new_readonly(stake::config::id(), false),
1052 AccountMeta::new_readonly(system_program::id(), false),
1053 AccountMeta::new_readonly(stake::program::id(), false),
1054 ];
1055 Instruction {
1056 program_id: *program_id,
1057 accounts,
1058 data: borsh::to_vec(&StakePoolInstruction::IncreaseAdditionalValidatorStake {
1059 lamports,
1060 transient_stake_seed,
1061 ephemeral_stake_seed,
1062 })
1063 .unwrap(),
1064 }
1065}
1066
1067#[deprecated(
1070 since = "2.0.0",
1071 note = "The stake redelegate instruction used in this will not be enabled."
1072)]
1073pub fn redelegate(
1074 program_id: &Pubkey,
1075 stake_pool: &Pubkey,
1076 staker: &Pubkey,
1077 stake_pool_withdraw_authority: &Pubkey,
1078 validator_list: &Pubkey,
1079 reserve_stake: &Pubkey,
1080 source_validator_stake: &Pubkey,
1081 source_transient_stake: &Pubkey,
1082 ephemeral_stake: &Pubkey,
1083 destination_transient_stake: &Pubkey,
1084 destination_validator_stake: &Pubkey,
1085 validator: &Pubkey,
1086 lamports: u64,
1087 source_transient_stake_seed: u64,
1088 ephemeral_stake_seed: u64,
1089 destination_transient_stake_seed: u64,
1090) -> Instruction {
1091 let accounts = vec![
1092 AccountMeta::new_readonly(*stake_pool, false),
1093 AccountMeta::new_readonly(*staker, true),
1094 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
1095 AccountMeta::new(*validator_list, false),
1096 AccountMeta::new(*reserve_stake, false),
1097 AccountMeta::new(*source_validator_stake, false),
1098 AccountMeta::new(*source_transient_stake, false),
1099 AccountMeta::new(*ephemeral_stake, false),
1100 AccountMeta::new(*destination_transient_stake, false),
1101 AccountMeta::new_readonly(*destination_validator_stake, false),
1102 AccountMeta::new_readonly(*validator, false),
1103 AccountMeta::new_readonly(sysvar::clock::id(), false),
1104 AccountMeta::new_readonly(sysvar::stake_history::id(), false),
1105 #[allow(deprecated)]
1106 AccountMeta::new_readonly(stake::config::id(), false),
1107 AccountMeta::new_readonly(system_program::id(), false),
1108 AccountMeta::new_readonly(stake::program::id(), false),
1109 ];
1110 Instruction {
1111 program_id: *program_id,
1112 accounts,
1113 data: borsh::to_vec(&StakePoolInstruction::Redelegate {
1114 lamports,
1115 source_transient_stake_seed,
1116 ephemeral_stake_seed,
1117 destination_transient_stake_seed,
1118 })
1119 .unwrap(),
1120 }
1121}
1122
1123pub fn set_preferred_validator(
1125 program_id: &Pubkey,
1126 stake_pool_address: &Pubkey,
1127 staker: &Pubkey,
1128 validator_list_address: &Pubkey,
1129 validator_type: PreferredValidatorType,
1130 validator_vote_address: Option<Pubkey>,
1131) -> Instruction {
1132 Instruction {
1133 program_id: *program_id,
1134 accounts: vec![
1135 AccountMeta::new(*stake_pool_address, false),
1136 AccountMeta::new_readonly(*staker, true),
1137 AccountMeta::new_readonly(*validator_list_address, false),
1138 ],
1139 data: borsh::to_vec(&StakePoolInstruction::SetPreferredValidator {
1140 validator_type,
1141 validator_vote_address,
1142 })
1143 .unwrap(),
1144 }
1145}
1146
1147pub fn add_validator_to_pool_with_vote(
1150 program_id: &Pubkey,
1151 stake_pool: &StakePool,
1152 stake_pool_address: &Pubkey,
1153 vote_account_address: &Pubkey,
1154 seed: Option<NonZeroU32>,
1155) -> Instruction {
1156 let pool_withdraw_authority =
1157 find_withdraw_authority_program_address(program_id, stake_pool_address).0;
1158 let (stake_account_address, _) =
1159 find_stake_program_address(program_id, vote_account_address, stake_pool_address, seed);
1160 add_validator_to_pool(
1161 program_id,
1162 stake_pool_address,
1163 &stake_pool.staker,
1164 &stake_pool.reserve_stake,
1165 &pool_withdraw_authority,
1166 &stake_pool.validator_list,
1167 &stake_account_address,
1168 vote_account_address,
1169 seed,
1170 )
1171}
1172
1173pub fn remove_validator_from_pool_with_vote(
1176 program_id: &Pubkey,
1177 stake_pool: &StakePool,
1178 stake_pool_address: &Pubkey,
1179 vote_account_address: &Pubkey,
1180 validator_stake_seed: Option<NonZeroU32>,
1181 transient_stake_seed: u64,
1182) -> Instruction {
1183 let pool_withdraw_authority =
1184 find_withdraw_authority_program_address(program_id, stake_pool_address).0;
1185 let (stake_account_address, _) = find_stake_program_address(
1186 program_id,
1187 vote_account_address,
1188 stake_pool_address,
1189 validator_stake_seed,
1190 );
1191 let (transient_stake_account, _) = find_transient_stake_program_address(
1192 program_id,
1193 vote_account_address,
1194 stake_pool_address,
1195 transient_stake_seed,
1196 );
1197 remove_validator_from_pool(
1198 program_id,
1199 stake_pool_address,
1200 &stake_pool.staker,
1201 &pool_withdraw_authority,
1202 &stake_pool.validator_list,
1203 &stake_account_address,
1204 &transient_stake_account,
1205 )
1206}
1207
1208pub fn increase_validator_stake_with_vote(
1211 program_id: &Pubkey,
1212 stake_pool: &StakePool,
1213 stake_pool_address: &Pubkey,
1214 vote_account_address: &Pubkey,
1215 lamports: u64,
1216 validator_stake_seed: Option<NonZeroU32>,
1217 transient_stake_seed: u64,
1218) -> Instruction {
1219 let pool_withdraw_authority =
1220 find_withdraw_authority_program_address(program_id, stake_pool_address).0;
1221 let (transient_stake_address, _) = find_transient_stake_program_address(
1222 program_id,
1223 vote_account_address,
1224 stake_pool_address,
1225 transient_stake_seed,
1226 );
1227 let (validator_stake_address, _) = find_stake_program_address(
1228 program_id,
1229 vote_account_address,
1230 stake_pool_address,
1231 validator_stake_seed,
1232 );
1233
1234 increase_validator_stake(
1235 program_id,
1236 stake_pool_address,
1237 &stake_pool.staker,
1238 &pool_withdraw_authority,
1239 &stake_pool.validator_list,
1240 &stake_pool.reserve_stake,
1241 &transient_stake_address,
1242 &validator_stake_address,
1243 vote_account_address,
1244 lamports,
1245 transient_stake_seed,
1246 )
1247}
1248
1249pub fn increase_additional_validator_stake_with_vote(
1252 program_id: &Pubkey,
1253 stake_pool: &StakePool,
1254 stake_pool_address: &Pubkey,
1255 vote_account_address: &Pubkey,
1256 lamports: u64,
1257 validator_stake_seed: Option<NonZeroU32>,
1258 transient_stake_seed: u64,
1259 ephemeral_stake_seed: u64,
1260) -> Instruction {
1261 let pool_withdraw_authority =
1262 find_withdraw_authority_program_address(program_id, stake_pool_address).0;
1263 let (ephemeral_stake_address, _) =
1264 find_ephemeral_stake_program_address(program_id, stake_pool_address, ephemeral_stake_seed);
1265 let (transient_stake_address, _) = find_transient_stake_program_address(
1266 program_id,
1267 vote_account_address,
1268 stake_pool_address,
1269 transient_stake_seed,
1270 );
1271 let (validator_stake_address, _) = find_stake_program_address(
1272 program_id,
1273 vote_account_address,
1274 stake_pool_address,
1275 validator_stake_seed,
1276 );
1277
1278 increase_additional_validator_stake(
1279 program_id,
1280 stake_pool_address,
1281 &stake_pool.staker,
1282 &pool_withdraw_authority,
1283 &stake_pool.validator_list,
1284 &stake_pool.reserve_stake,
1285 &ephemeral_stake_address,
1286 &transient_stake_address,
1287 &validator_stake_address,
1288 vote_account_address,
1289 lamports,
1290 transient_stake_seed,
1291 ephemeral_stake_seed,
1292 )
1293}
1294
1295pub fn decrease_validator_stake_with_vote(
1298 program_id: &Pubkey,
1299 stake_pool: &StakePool,
1300 stake_pool_address: &Pubkey,
1301 vote_account_address: &Pubkey,
1302 lamports: u64,
1303 validator_stake_seed: Option<NonZeroU32>,
1304 transient_stake_seed: u64,
1305) -> Instruction {
1306 let pool_withdraw_authority =
1307 find_withdraw_authority_program_address(program_id, stake_pool_address).0;
1308 let (validator_stake_address, _) = find_stake_program_address(
1309 program_id,
1310 vote_account_address,
1311 stake_pool_address,
1312 validator_stake_seed,
1313 );
1314 let (transient_stake_address, _) = find_transient_stake_program_address(
1315 program_id,
1316 vote_account_address,
1317 stake_pool_address,
1318 transient_stake_seed,
1319 );
1320 decrease_validator_stake_with_reserve(
1321 program_id,
1322 stake_pool_address,
1323 &stake_pool.staker,
1324 &pool_withdraw_authority,
1325 &stake_pool.validator_list,
1326 &stake_pool.reserve_stake,
1327 &validator_stake_address,
1328 &transient_stake_address,
1329 lamports,
1330 transient_stake_seed,
1331 )
1332}
1333
1334pub fn increase_additional_validator_stake_with_list(
1337 program_id: &Pubkey,
1338 stake_pool: &StakePool,
1339 validator_list: &ValidatorList,
1340 stake_pool_address: &Pubkey,
1341 vote_account_address: &Pubkey,
1342 lamports: u64,
1343 ephemeral_stake_seed: u64,
1344) -> Result<Instruction, ProgramError> {
1345 let validator_info = validator_list
1346 .find(vote_account_address)
1347 .ok_or(ProgramError::InvalidInstructionData)?;
1348 let transient_stake_seed = u64::from(validator_info.transient_seed_suffix);
1349 let validator_stake_seed = NonZeroU32::new(validator_info.validator_seed_suffix.into());
1350 Ok(increase_additional_validator_stake_with_vote(
1351 program_id,
1352 stake_pool,
1353 stake_pool_address,
1354 vote_account_address,
1355 lamports,
1356 validator_stake_seed,
1357 transient_stake_seed,
1358 ephemeral_stake_seed,
1359 ))
1360}
1361
1362pub fn decrease_additional_validator_stake_with_list(
1365 program_id: &Pubkey,
1366 stake_pool: &StakePool,
1367 validator_list: &ValidatorList,
1368 stake_pool_address: &Pubkey,
1369 vote_account_address: &Pubkey,
1370 lamports: u64,
1371 ephemeral_stake_seed: u64,
1372) -> Result<Instruction, ProgramError> {
1373 let validator_info = validator_list
1374 .find(vote_account_address)
1375 .ok_or(ProgramError::InvalidInstructionData)?;
1376 let transient_stake_seed = u64::from(validator_info.transient_seed_suffix);
1377 let validator_stake_seed = NonZeroU32::new(validator_info.validator_seed_suffix.into());
1378 Ok(decrease_additional_validator_stake_with_vote(
1379 program_id,
1380 stake_pool,
1381 stake_pool_address,
1382 vote_account_address,
1383 lamports,
1384 validator_stake_seed,
1385 transient_stake_seed,
1386 ephemeral_stake_seed,
1387 ))
1388}
1389
1390pub fn decrease_additional_validator_stake_with_vote(
1393 program_id: &Pubkey,
1394 stake_pool: &StakePool,
1395 stake_pool_address: &Pubkey,
1396 vote_account_address: &Pubkey,
1397 lamports: u64,
1398 validator_stake_seed: Option<NonZeroU32>,
1399 transient_stake_seed: u64,
1400 ephemeral_stake_seed: u64,
1401) -> Instruction {
1402 let pool_withdraw_authority =
1403 find_withdraw_authority_program_address(program_id, stake_pool_address).0;
1404 let (validator_stake_address, _) = find_stake_program_address(
1405 program_id,
1406 vote_account_address,
1407 stake_pool_address,
1408 validator_stake_seed,
1409 );
1410 let (ephemeral_stake_address, _) =
1411 find_ephemeral_stake_program_address(program_id, stake_pool_address, ephemeral_stake_seed);
1412 let (transient_stake_address, _) = find_transient_stake_program_address(
1413 program_id,
1414 vote_account_address,
1415 stake_pool_address,
1416 transient_stake_seed,
1417 );
1418 decrease_additional_validator_stake(
1419 program_id,
1420 stake_pool_address,
1421 &stake_pool.staker,
1422 &pool_withdraw_authority,
1423 &stake_pool.validator_list,
1424 &stake_pool.reserve_stake,
1425 &validator_stake_address,
1426 &ephemeral_stake_address,
1427 &transient_stake_address,
1428 lamports,
1429 transient_stake_seed,
1430 ephemeral_stake_seed,
1431 )
1432}
1433
1434#[deprecated(
1437 since = "1.1.0",
1438 note = "please use `update_validator_list_balance_chunk`"
1439)]
1440pub fn update_validator_list_balance(
1441 program_id: &Pubkey,
1442 stake_pool: &Pubkey,
1443 stake_pool_withdraw_authority: &Pubkey,
1444 validator_list_address: &Pubkey,
1445 reserve_stake: &Pubkey,
1446 validator_list: &ValidatorList,
1447 validator_vote_accounts: &[Pubkey],
1448 start_index: u32,
1449 no_merge: bool,
1450) -> Instruction {
1451 let mut accounts = vec![
1452 AccountMeta::new_readonly(*stake_pool, false),
1453 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
1454 AccountMeta::new(*validator_list_address, false),
1455 AccountMeta::new(*reserve_stake, false),
1456 AccountMeta::new_readonly(sysvar::clock::id(), false),
1457 AccountMeta::new_readonly(sysvar::stake_history::id(), false),
1458 AccountMeta::new_readonly(stake::program::id(), false),
1459 ];
1460 accounts.append(
1461 &mut validator_vote_accounts
1462 .iter()
1463 .flat_map(|vote_account_address| {
1464 let validator_stake_info = validator_list.find(vote_account_address);
1465 if let Some(validator_stake_info) = validator_stake_info {
1466 let (validator_stake_account, _) = find_stake_program_address(
1467 program_id,
1468 vote_account_address,
1469 stake_pool,
1470 NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()),
1471 );
1472 let (transient_stake_account, _) = find_transient_stake_program_address(
1473 program_id,
1474 vote_account_address,
1475 stake_pool,
1476 validator_stake_info.transient_seed_suffix.into(),
1477 );
1478 vec![
1479 AccountMeta::new(validator_stake_account, false),
1480 AccountMeta::new(transient_stake_account, false),
1481 ]
1482 } else {
1483 vec![]
1484 }
1485 })
1486 .collect::<Vec<AccountMeta>>(),
1487 );
1488 Instruction {
1489 program_id: *program_id,
1490 accounts,
1491 data: borsh::to_vec(&StakePoolInstruction::UpdateValidatorListBalance {
1492 start_index,
1493 no_merge,
1494 })
1495 .unwrap(),
1496 }
1497}
1498
1499pub fn update_validator_list_balance_chunk(
1507 program_id: &Pubkey,
1508 stake_pool: &Pubkey,
1509 stake_pool_withdraw_authority: &Pubkey,
1510 validator_list_address: &Pubkey,
1511 reserve_stake: &Pubkey,
1512 validator_list: &ValidatorList,
1513 len: usize,
1514 start_index: usize,
1515 no_merge: bool,
1516) -> Result<Instruction, ProgramError> {
1517 let mut accounts = vec![
1518 AccountMeta::new_readonly(*stake_pool, false),
1519 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
1520 AccountMeta::new(*validator_list_address, false),
1521 AccountMeta::new(*reserve_stake, false),
1522 AccountMeta::new_readonly(sysvar::clock::id(), false),
1523 AccountMeta::new_readonly(sysvar::stake_history::id(), false),
1524 AccountMeta::new_readonly(stake::program::id(), false),
1525 ];
1526 let validator_list_subslice = validator_list
1527 .validators
1528 .get(start_index..start_index.saturating_add(len))
1529 .ok_or(ProgramError::InvalidInstructionData)?;
1530 accounts.extend(validator_list_subslice.iter().flat_map(
1531 |ValidatorStakeInfo {
1532 vote_account_address,
1533 validator_seed_suffix,
1534 transient_seed_suffix,
1535 ..
1536 }| {
1537 let (validator_stake_account, _) = find_stake_program_address(
1538 program_id,
1539 vote_account_address,
1540 stake_pool,
1541 NonZeroU32::new((*validator_seed_suffix).into()),
1542 );
1543 let (transient_stake_account, _) = find_transient_stake_program_address(
1544 program_id,
1545 vote_account_address,
1546 stake_pool,
1547 (*transient_seed_suffix).into(),
1548 );
1549 [
1550 AccountMeta::new(validator_stake_account, false),
1551 AccountMeta::new(transient_stake_account, false),
1552 ]
1553 },
1554 ));
1555 Ok(Instruction {
1556 program_id: *program_id,
1557 accounts,
1558 data: borsh::to_vec(&StakePoolInstruction::UpdateValidatorListBalance {
1559 start_index: start_index.try_into().unwrap(),
1560 no_merge,
1561 })
1562 .unwrap(),
1563 })
1564}
1565
1566pub fn update_stale_validator_list_balance_chunk(
1572 program_id: &Pubkey,
1573 stake_pool: &Pubkey,
1574 stake_pool_withdraw_authority: &Pubkey,
1575 validator_list_address: &Pubkey,
1576 reserve_stake: &Pubkey,
1577 validator_list: &ValidatorList,
1578 len: usize,
1579 start_index: usize,
1580 no_merge: bool,
1581 current_epoch: Epoch,
1582) -> Result<Option<Instruction>, ProgramError> {
1583 let validator_list_subslice = validator_list
1584 .validators
1585 .get(start_index..start_index.saturating_add(len))
1586 .ok_or(ProgramError::InvalidInstructionData)?;
1587 if validator_list_subslice.iter().all(|info| {
1588 let last_update_epoch: u64 = info.last_update_epoch.into();
1589 last_update_epoch >= current_epoch
1590 }) {
1591 return Ok(None);
1592 }
1593 update_validator_list_balance_chunk(
1594 program_id,
1595 stake_pool,
1596 stake_pool_withdraw_authority,
1597 validator_list_address,
1598 reserve_stake,
1599 validator_list,
1600 len,
1601 start_index,
1602 no_merge,
1603 )
1604 .map(Some)
1605}
1606
1607pub fn update_stake_pool_balance(
1610 program_id: &Pubkey,
1611 stake_pool: &Pubkey,
1612 withdraw_authority: &Pubkey,
1613 validator_list_storage: &Pubkey,
1614 reserve_stake: &Pubkey,
1615 manager_fee_account: &Pubkey,
1616 stake_pool_mint: &Pubkey,
1617 token_program_id: &Pubkey,
1618) -> Instruction {
1619 let accounts = vec![
1620 AccountMeta::new(*stake_pool, false),
1621 AccountMeta::new_readonly(*withdraw_authority, false),
1622 AccountMeta::new(*validator_list_storage, false),
1623 AccountMeta::new_readonly(*reserve_stake, false),
1624 AccountMeta::new(*manager_fee_account, false),
1625 AccountMeta::new(*stake_pool_mint, false),
1626 AccountMeta::new_readonly(*token_program_id, false),
1627 ];
1628 Instruction {
1629 program_id: *program_id,
1630 accounts,
1631 data: borsh::to_vec(&StakePoolInstruction::UpdateStakePoolBalance).unwrap(),
1632 }
1633}
1634
1635pub fn cleanup_removed_validator_entries(
1638 program_id: &Pubkey,
1639 stake_pool: &Pubkey,
1640 validator_list_storage: &Pubkey,
1641) -> Instruction {
1642 let accounts = vec![
1643 AccountMeta::new_readonly(*stake_pool, false),
1644 AccountMeta::new(*validator_list_storage, false),
1645 ];
1646 Instruction {
1647 program_id: *program_id,
1648 accounts,
1649 data: borsh::to_vec(&StakePoolInstruction::CleanupRemovedValidatorEntries).unwrap(),
1650 }
1651}
1652
1653pub fn update_stake_pool(
1656 program_id: &Pubkey,
1657 stake_pool: &StakePool,
1658 validator_list: &ValidatorList,
1659 stake_pool_address: &Pubkey,
1660 no_merge: bool,
1661) -> (Vec<Instruction>, Vec<Instruction>) {
1662 let (withdraw_authority, _) =
1663 find_withdraw_authority_program_address(program_id, stake_pool_address);
1664
1665 let update_list_instructions = validator_list
1666 .validators
1667 .chunks(MAX_VALIDATORS_TO_UPDATE)
1668 .enumerate()
1669 .map(|(i, chunk)| {
1670 update_validator_list_balance_chunk(
1672 program_id,
1673 stake_pool_address,
1674 &withdraw_authority,
1675 &stake_pool.validator_list,
1676 &stake_pool.reserve_stake,
1677 validator_list,
1678 chunk.len(),
1679 i.saturating_mul(MAX_VALIDATORS_TO_UPDATE),
1680 no_merge,
1681 )
1682 .unwrap()
1683 })
1684 .collect();
1685
1686 let final_instructions = vec![
1687 update_stake_pool_balance(
1688 program_id,
1689 stake_pool_address,
1690 &withdraw_authority,
1691 &stake_pool.validator_list,
1692 &stake_pool.reserve_stake,
1693 &stake_pool.manager_fee_account,
1694 &stake_pool.pool_mint,
1695 &stake_pool.token_program_id,
1696 ),
1697 cleanup_removed_validator_entries(
1698 program_id,
1699 stake_pool_address,
1700 &stake_pool.validator_list,
1701 ),
1702 ];
1703 (update_list_instructions, final_instructions)
1704}
1705
1706pub fn update_stale_stake_pool(
1713 program_id: &Pubkey,
1714 stake_pool: &StakePool,
1715 validator_list: &ValidatorList,
1716 stake_pool_address: &Pubkey,
1717 no_merge: bool,
1718 current_epoch: Epoch,
1719) -> (Vec<Instruction>, Vec<Instruction>) {
1720 let (withdraw_authority, _) =
1721 find_withdraw_authority_program_address(program_id, stake_pool_address);
1722
1723 let update_list_instructions = validator_list
1724 .validators
1725 .chunks(MAX_VALIDATORS_TO_UPDATE)
1726 .enumerate()
1727 .filter_map(|(i, chunk)| {
1728 update_stale_validator_list_balance_chunk(
1730 program_id,
1731 stake_pool_address,
1732 &withdraw_authority,
1733 &stake_pool.validator_list,
1734 &stake_pool.reserve_stake,
1735 validator_list,
1736 chunk.len(),
1737 i.saturating_mul(MAX_VALIDATORS_TO_UPDATE),
1738 no_merge,
1739 current_epoch,
1740 )
1741 .unwrap()
1742 })
1743 .collect();
1744
1745 let final_instructions = vec![
1746 update_stake_pool_balance(
1747 program_id,
1748 stake_pool_address,
1749 &withdraw_authority,
1750 &stake_pool.validator_list,
1751 &stake_pool.reserve_stake,
1752 &stake_pool.manager_fee_account,
1753 &stake_pool.pool_mint,
1754 &stake_pool.token_program_id,
1755 ),
1756 cleanup_removed_validator_entries(
1757 program_id,
1758 stake_pool_address,
1759 &stake_pool.validator_list,
1760 ),
1761 ];
1762 (update_list_instructions, final_instructions)
1763}
1764
1765fn deposit_stake_internal(
1766 program_id: &Pubkey,
1767 stake_pool: &Pubkey,
1768 validator_list_storage: &Pubkey,
1769 stake_pool_deposit_authority: Option<&Pubkey>,
1770 stake_pool_withdraw_authority: &Pubkey,
1771 deposit_stake_address: &Pubkey,
1772 deposit_stake_withdraw_authority: &Pubkey,
1773 validator_stake_account: &Pubkey,
1774 reserve_stake_account: &Pubkey,
1775 pool_tokens_to: &Pubkey,
1776 manager_fee_account: &Pubkey,
1777 referrer_pool_tokens_account: &Pubkey,
1778 pool_mint: &Pubkey,
1779 token_program_id: &Pubkey,
1780 minimum_pool_tokens_out: Option<u64>,
1781) -> Vec<Instruction> {
1782 let mut instructions = vec![];
1783 let mut accounts = vec![
1784 AccountMeta::new(*stake_pool, false),
1785 AccountMeta::new(*validator_list_storage, false),
1786 ];
1787 if let Some(stake_pool_deposit_authority) = stake_pool_deposit_authority {
1788 accounts.push(AccountMeta::new_readonly(
1789 *stake_pool_deposit_authority,
1790 true,
1791 ));
1792 instructions.extend_from_slice(&[
1793 stake::instruction::authorize(
1794 deposit_stake_address,
1795 deposit_stake_withdraw_authority,
1796 stake_pool_deposit_authority,
1797 stake::state::StakeAuthorize::Staker,
1798 None,
1799 ),
1800 stake::instruction::authorize(
1801 deposit_stake_address,
1802 deposit_stake_withdraw_authority,
1803 stake_pool_deposit_authority,
1804 stake::state::StakeAuthorize::Withdrawer,
1805 None,
1806 ),
1807 ]);
1808 } else {
1809 let stake_pool_deposit_authority =
1810 find_deposit_authority_program_address(program_id, stake_pool).0;
1811 accounts.push(AccountMeta::new_readonly(
1812 stake_pool_deposit_authority,
1813 false,
1814 ));
1815 instructions.extend_from_slice(&[
1816 stake::instruction::authorize(
1817 deposit_stake_address,
1818 deposit_stake_withdraw_authority,
1819 &stake_pool_deposit_authority,
1820 stake::state::StakeAuthorize::Staker,
1821 None,
1822 ),
1823 stake::instruction::authorize(
1824 deposit_stake_address,
1825 deposit_stake_withdraw_authority,
1826 &stake_pool_deposit_authority,
1827 stake::state::StakeAuthorize::Withdrawer,
1828 None,
1829 ),
1830 ]);
1831 };
1832
1833 accounts.extend_from_slice(&[
1834 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
1835 AccountMeta::new(*deposit_stake_address, false),
1836 AccountMeta::new(*validator_stake_account, false),
1837 AccountMeta::new(*reserve_stake_account, false),
1838 AccountMeta::new(*pool_tokens_to, false),
1839 AccountMeta::new(*manager_fee_account, false),
1840 AccountMeta::new(*referrer_pool_tokens_account, false),
1841 AccountMeta::new(*pool_mint, false),
1842 AccountMeta::new_readonly(sysvar::clock::id(), false),
1843 AccountMeta::new_readonly(sysvar::stake_history::id(), false),
1844 AccountMeta::new_readonly(*token_program_id, false),
1845 AccountMeta::new_readonly(stake::program::id(), false),
1846 ]);
1847 instructions.push(
1848 if let Some(minimum_pool_tokens_out) = minimum_pool_tokens_out {
1849 Instruction {
1850 program_id: *program_id,
1851 accounts,
1852 data: borsh::to_vec(&StakePoolInstruction::DepositStakeWithSlippage {
1853 minimum_pool_tokens_out,
1854 })
1855 .unwrap(),
1856 }
1857 } else {
1858 Instruction {
1859 program_id: *program_id,
1860 accounts,
1861 data: borsh::to_vec(&StakePoolInstruction::DepositStake).unwrap(),
1862 }
1863 },
1864 );
1865 instructions
1866}
1867
1868pub fn deposit_stake(
1871 program_id: &Pubkey,
1872 stake_pool: &Pubkey,
1873 validator_list_storage: &Pubkey,
1874 stake_pool_withdraw_authority: &Pubkey,
1875 deposit_stake_address: &Pubkey,
1876 deposit_stake_withdraw_authority: &Pubkey,
1877 validator_stake_account: &Pubkey,
1878 reserve_stake_account: &Pubkey,
1879 pool_tokens_to: &Pubkey,
1880 manager_fee_account: &Pubkey,
1881 referrer_pool_tokens_account: &Pubkey,
1882 pool_mint: &Pubkey,
1883 token_program_id: &Pubkey,
1884) -> Vec<Instruction> {
1885 deposit_stake_internal(
1886 program_id,
1887 stake_pool,
1888 validator_list_storage,
1889 None,
1890 stake_pool_withdraw_authority,
1891 deposit_stake_address,
1892 deposit_stake_withdraw_authority,
1893 validator_stake_account,
1894 reserve_stake_account,
1895 pool_tokens_to,
1896 manager_fee_account,
1897 referrer_pool_tokens_account,
1898 pool_mint,
1899 token_program_id,
1900 None,
1901 )
1902}
1903
1904pub fn deposit_stake_with_slippage(
1906 program_id: &Pubkey,
1907 stake_pool: &Pubkey,
1908 validator_list_storage: &Pubkey,
1909 stake_pool_withdraw_authority: &Pubkey,
1910 deposit_stake_address: &Pubkey,
1911 deposit_stake_withdraw_authority: &Pubkey,
1912 validator_stake_account: &Pubkey,
1913 reserve_stake_account: &Pubkey,
1914 pool_tokens_to: &Pubkey,
1915 manager_fee_account: &Pubkey,
1916 referrer_pool_tokens_account: &Pubkey,
1917 pool_mint: &Pubkey,
1918 token_program_id: &Pubkey,
1919 minimum_pool_tokens_out: u64,
1920) -> Vec<Instruction> {
1921 deposit_stake_internal(
1922 program_id,
1923 stake_pool,
1924 validator_list_storage,
1925 None,
1926 stake_pool_withdraw_authority,
1927 deposit_stake_address,
1928 deposit_stake_withdraw_authority,
1929 validator_stake_account,
1930 reserve_stake_account,
1931 pool_tokens_to,
1932 manager_fee_account,
1933 referrer_pool_tokens_account,
1934 pool_mint,
1935 token_program_id,
1936 Some(minimum_pool_tokens_out),
1937 )
1938}
1939
1940pub fn deposit_stake_with_authority(
1944 program_id: &Pubkey,
1945 stake_pool: &Pubkey,
1946 validator_list_storage: &Pubkey,
1947 stake_pool_deposit_authority: &Pubkey,
1948 stake_pool_withdraw_authority: &Pubkey,
1949 deposit_stake_address: &Pubkey,
1950 deposit_stake_withdraw_authority: &Pubkey,
1951 validator_stake_account: &Pubkey,
1952 reserve_stake_account: &Pubkey,
1953 pool_tokens_to: &Pubkey,
1954 manager_fee_account: &Pubkey,
1955 referrer_pool_tokens_account: &Pubkey,
1956 pool_mint: &Pubkey,
1957 token_program_id: &Pubkey,
1958) -> Vec<Instruction> {
1959 deposit_stake_internal(
1960 program_id,
1961 stake_pool,
1962 validator_list_storage,
1963 Some(stake_pool_deposit_authority),
1964 stake_pool_withdraw_authority,
1965 deposit_stake_address,
1966 deposit_stake_withdraw_authority,
1967 validator_stake_account,
1968 reserve_stake_account,
1969 pool_tokens_to,
1970 manager_fee_account,
1971 referrer_pool_tokens_account,
1972 pool_mint,
1973 token_program_id,
1974 None,
1975 )
1976}
1977
1978pub fn deposit_stake_with_authority_and_slippage(
1983 program_id: &Pubkey,
1984 stake_pool: &Pubkey,
1985 validator_list_storage: &Pubkey,
1986 stake_pool_deposit_authority: &Pubkey,
1987 stake_pool_withdraw_authority: &Pubkey,
1988 deposit_stake_address: &Pubkey,
1989 deposit_stake_withdraw_authority: &Pubkey,
1990 validator_stake_account: &Pubkey,
1991 reserve_stake_account: &Pubkey,
1992 pool_tokens_to: &Pubkey,
1993 manager_fee_account: &Pubkey,
1994 referrer_pool_tokens_account: &Pubkey,
1995 pool_mint: &Pubkey,
1996 token_program_id: &Pubkey,
1997 minimum_pool_tokens_out: u64,
1998) -> Vec<Instruction> {
1999 deposit_stake_internal(
2000 program_id,
2001 stake_pool,
2002 validator_list_storage,
2003 Some(stake_pool_deposit_authority),
2004 stake_pool_withdraw_authority,
2005 deposit_stake_address,
2006 deposit_stake_withdraw_authority,
2007 validator_stake_account,
2008 reserve_stake_account,
2009 pool_tokens_to,
2010 manager_fee_account,
2011 referrer_pool_tokens_account,
2012 pool_mint,
2013 token_program_id,
2014 Some(minimum_pool_tokens_out),
2015 )
2016}
2017
2018fn deposit_sol_internal(
2020 program_id: &Pubkey,
2021 stake_pool: &Pubkey,
2022 stake_pool_withdraw_authority: &Pubkey,
2023 reserve_stake_account: &Pubkey,
2024 lamports_from: &Pubkey,
2025 pool_tokens_to: &Pubkey,
2026 manager_fee_account: &Pubkey,
2027 referrer_pool_tokens_account: &Pubkey,
2028 pool_mint: &Pubkey,
2029 token_program_id: &Pubkey,
2030 sol_deposit_authority: Option<&Pubkey>,
2031 lamports_in: u64,
2032 minimum_pool_tokens_out: Option<u64>,
2033) -> Instruction {
2034 let mut accounts = vec![
2035 AccountMeta::new(*stake_pool, false),
2036 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
2037 AccountMeta::new(*reserve_stake_account, false),
2038 AccountMeta::new(*lamports_from, true),
2039 AccountMeta::new(*pool_tokens_to, false),
2040 AccountMeta::new(*manager_fee_account, false),
2041 AccountMeta::new(*referrer_pool_tokens_account, false),
2042 AccountMeta::new(*pool_mint, false),
2043 AccountMeta::new_readonly(system_program::id(), false),
2044 AccountMeta::new_readonly(*token_program_id, false),
2045 ];
2046 if let Some(sol_deposit_authority) = sol_deposit_authority {
2047 accounts.push(AccountMeta::new_readonly(*sol_deposit_authority, true));
2048 }
2049 if let Some(minimum_pool_tokens_out) = minimum_pool_tokens_out {
2050 Instruction {
2051 program_id: *program_id,
2052 accounts,
2053 data: borsh::to_vec(&StakePoolInstruction::DepositSolWithSlippage {
2054 lamports_in,
2055 minimum_pool_tokens_out,
2056 })
2057 .unwrap(),
2058 }
2059 } else {
2060 Instruction {
2061 program_id: *program_id,
2062 accounts,
2063 data: borsh::to_vec(&StakePoolInstruction::DepositSol(lamports_in)).unwrap(),
2064 }
2065 }
2066}
2067
2068pub fn deposit_sol(
2070 program_id: &Pubkey,
2071 stake_pool: &Pubkey,
2072 stake_pool_withdraw_authority: &Pubkey,
2073 reserve_stake_account: &Pubkey,
2074 lamports_from: &Pubkey,
2075 pool_tokens_to: &Pubkey,
2076 manager_fee_account: &Pubkey,
2077 referrer_pool_tokens_account: &Pubkey,
2078 pool_mint: &Pubkey,
2079 token_program_id: &Pubkey,
2080 lamports_in: u64,
2081) -> Instruction {
2082 deposit_sol_internal(
2083 program_id,
2084 stake_pool,
2085 stake_pool_withdraw_authority,
2086 reserve_stake_account,
2087 lamports_from,
2088 pool_tokens_to,
2089 manager_fee_account,
2090 referrer_pool_tokens_account,
2091 pool_mint,
2092 token_program_id,
2093 None,
2094 lamports_in,
2095 None,
2096 )
2097}
2098
2099pub fn deposit_sol_with_slippage(
2102 program_id: &Pubkey,
2103 stake_pool: &Pubkey,
2104 stake_pool_withdraw_authority: &Pubkey,
2105 reserve_stake_account: &Pubkey,
2106 lamports_from: &Pubkey,
2107 pool_tokens_to: &Pubkey,
2108 manager_fee_account: &Pubkey,
2109 referrer_pool_tokens_account: &Pubkey,
2110 pool_mint: &Pubkey,
2111 token_program_id: &Pubkey,
2112 lamports_in: u64,
2113 minimum_pool_tokens_out: u64,
2114) -> Instruction {
2115 deposit_sol_internal(
2116 program_id,
2117 stake_pool,
2118 stake_pool_withdraw_authority,
2119 reserve_stake_account,
2120 lamports_from,
2121 pool_tokens_to,
2122 manager_fee_account,
2123 referrer_pool_tokens_account,
2124 pool_mint,
2125 token_program_id,
2126 None,
2127 lamports_in,
2128 Some(minimum_pool_tokens_out),
2129 )
2130}
2131
2132pub fn deposit_sol_with_authority(
2136 program_id: &Pubkey,
2137 stake_pool: &Pubkey,
2138 sol_deposit_authority: &Pubkey,
2139 stake_pool_withdraw_authority: &Pubkey,
2140 reserve_stake_account: &Pubkey,
2141 lamports_from: &Pubkey,
2142 pool_tokens_to: &Pubkey,
2143 manager_fee_account: &Pubkey,
2144 referrer_pool_tokens_account: &Pubkey,
2145 pool_mint: &Pubkey,
2146 token_program_id: &Pubkey,
2147 lamports_in: u64,
2148) -> Instruction {
2149 deposit_sol_internal(
2150 program_id,
2151 stake_pool,
2152 stake_pool_withdraw_authority,
2153 reserve_stake_account,
2154 lamports_from,
2155 pool_tokens_to,
2156 manager_fee_account,
2157 referrer_pool_tokens_account,
2158 pool_mint,
2159 token_program_id,
2160 Some(sol_deposit_authority),
2161 lamports_in,
2162 None,
2163 )
2164}
2165
2166pub fn deposit_sol_with_authority_and_slippage(
2169 program_id: &Pubkey,
2170 stake_pool: &Pubkey,
2171 sol_deposit_authority: &Pubkey,
2172 stake_pool_withdraw_authority: &Pubkey,
2173 reserve_stake_account: &Pubkey,
2174 lamports_from: &Pubkey,
2175 pool_tokens_to: &Pubkey,
2176 manager_fee_account: &Pubkey,
2177 referrer_pool_tokens_account: &Pubkey,
2178 pool_mint: &Pubkey,
2179 token_program_id: &Pubkey,
2180 lamports_in: u64,
2181 minimum_pool_tokens_out: u64,
2182) -> Instruction {
2183 deposit_sol_internal(
2184 program_id,
2185 stake_pool,
2186 stake_pool_withdraw_authority,
2187 reserve_stake_account,
2188 lamports_from,
2189 pool_tokens_to,
2190 manager_fee_account,
2191 referrer_pool_tokens_account,
2192 pool_mint,
2193 token_program_id,
2194 Some(sol_deposit_authority),
2195 lamports_in,
2196 Some(minimum_pool_tokens_out),
2197 )
2198}
2199
2200fn withdraw_stake_internal(
2201 program_id: &Pubkey,
2202 stake_pool: &Pubkey,
2203 validator_list_storage: &Pubkey,
2204 stake_pool_withdraw: &Pubkey,
2205 stake_to_split: &Pubkey,
2206 stake_to_receive: &Pubkey,
2207 user_stake_authority: &Pubkey,
2208 user_transfer_authority: &Pubkey,
2209 user_pool_token_account: &Pubkey,
2210 manager_fee_account: &Pubkey,
2211 pool_mint: &Pubkey,
2212 token_program_id: &Pubkey,
2213 pool_tokens_in: u64,
2214 minimum_lamports_out: Option<u64>,
2215) -> Instruction {
2216 let accounts = vec![
2217 AccountMeta::new(*stake_pool, false),
2218 AccountMeta::new(*validator_list_storage, false),
2219 AccountMeta::new_readonly(*stake_pool_withdraw, false),
2220 AccountMeta::new(*stake_to_split, false),
2221 AccountMeta::new(*stake_to_receive, false),
2222 AccountMeta::new_readonly(*user_stake_authority, false),
2223 AccountMeta::new_readonly(*user_transfer_authority, true),
2224 AccountMeta::new(*user_pool_token_account, false),
2225 AccountMeta::new(*manager_fee_account, false),
2226 AccountMeta::new(*pool_mint, false),
2227 AccountMeta::new_readonly(sysvar::clock::id(), false),
2228 AccountMeta::new_readonly(*token_program_id, false),
2229 AccountMeta::new_readonly(stake::program::id(), false),
2230 ];
2231 if let Some(minimum_lamports_out) = minimum_lamports_out {
2232 Instruction {
2233 program_id: *program_id,
2234 accounts,
2235 data: borsh::to_vec(&StakePoolInstruction::WithdrawStakeWithSlippage {
2236 pool_tokens_in,
2237 minimum_lamports_out,
2238 })
2239 .unwrap(),
2240 }
2241 } else {
2242 Instruction {
2243 program_id: *program_id,
2244 accounts,
2245 data: borsh::to_vec(&StakePoolInstruction::WithdrawStake(pool_tokens_in)).unwrap(),
2246 }
2247 }
2248}
2249
2250pub fn withdraw_stake(
2252 program_id: &Pubkey,
2253 stake_pool: &Pubkey,
2254 validator_list_storage: &Pubkey,
2255 stake_pool_withdraw: &Pubkey,
2256 stake_to_split: &Pubkey,
2257 stake_to_receive: &Pubkey,
2258 user_stake_authority: &Pubkey,
2259 user_transfer_authority: &Pubkey,
2260 user_pool_token_account: &Pubkey,
2261 manager_fee_account: &Pubkey,
2262 pool_mint: &Pubkey,
2263 token_program_id: &Pubkey,
2264 pool_tokens_in: u64,
2265) -> Instruction {
2266 withdraw_stake_internal(
2267 program_id,
2268 stake_pool,
2269 validator_list_storage,
2270 stake_pool_withdraw,
2271 stake_to_split,
2272 stake_to_receive,
2273 user_stake_authority,
2274 user_transfer_authority,
2275 user_pool_token_account,
2276 manager_fee_account,
2277 pool_mint,
2278 token_program_id,
2279 pool_tokens_in,
2280 None,
2281 )
2282}
2283
2284pub fn withdraw_stake_with_slippage(
2286 program_id: &Pubkey,
2287 stake_pool: &Pubkey,
2288 validator_list_storage: &Pubkey,
2289 stake_pool_withdraw: &Pubkey,
2290 stake_to_split: &Pubkey,
2291 stake_to_receive: &Pubkey,
2292 user_stake_authority: &Pubkey,
2293 user_transfer_authority: &Pubkey,
2294 user_pool_token_account: &Pubkey,
2295 manager_fee_account: &Pubkey,
2296 pool_mint: &Pubkey,
2297 token_program_id: &Pubkey,
2298 pool_tokens_in: u64,
2299 minimum_lamports_out: u64,
2300) -> Instruction {
2301 withdraw_stake_internal(
2302 program_id,
2303 stake_pool,
2304 validator_list_storage,
2305 stake_pool_withdraw,
2306 stake_to_split,
2307 stake_to_receive,
2308 user_stake_authority,
2309 user_transfer_authority,
2310 user_pool_token_account,
2311 manager_fee_account,
2312 pool_mint,
2313 token_program_id,
2314 pool_tokens_in,
2315 Some(minimum_lamports_out),
2316 )
2317}
2318
2319fn withdraw_sol_internal(
2320 program_id: &Pubkey,
2321 stake_pool: &Pubkey,
2322 stake_pool_withdraw_authority: &Pubkey,
2323 user_transfer_authority: &Pubkey,
2324 pool_tokens_from: &Pubkey,
2325 reserve_stake_account: &Pubkey,
2326 lamports_to: &Pubkey,
2327 manager_fee_account: &Pubkey,
2328 pool_mint: &Pubkey,
2329 token_program_id: &Pubkey,
2330 sol_withdraw_authority: Option<&Pubkey>,
2331 pool_tokens_in: u64,
2332 minimum_lamports_out: Option<u64>,
2333) -> Instruction {
2334 let mut accounts = vec![
2335 AccountMeta::new(*stake_pool, false),
2336 AccountMeta::new_readonly(*stake_pool_withdraw_authority, false),
2337 AccountMeta::new_readonly(*user_transfer_authority, true),
2338 AccountMeta::new(*pool_tokens_from, false),
2339 AccountMeta::new(*reserve_stake_account, false),
2340 AccountMeta::new(*lamports_to, false),
2341 AccountMeta::new(*manager_fee_account, false),
2342 AccountMeta::new(*pool_mint, false),
2343 AccountMeta::new_readonly(sysvar::clock::id(), false),
2344 AccountMeta::new_readonly(sysvar::stake_history::id(), false),
2345 AccountMeta::new_readonly(stake::program::id(), false),
2346 AccountMeta::new_readonly(*token_program_id, false),
2347 ];
2348 if let Some(sol_withdraw_authority) = sol_withdraw_authority {
2349 accounts.push(AccountMeta::new_readonly(*sol_withdraw_authority, true));
2350 }
2351 if let Some(minimum_lamports_out) = minimum_lamports_out {
2352 Instruction {
2353 program_id: *program_id,
2354 accounts,
2355 data: borsh::to_vec(&StakePoolInstruction::WithdrawSolWithSlippage {
2356 pool_tokens_in,
2357 minimum_lamports_out,
2358 })
2359 .unwrap(),
2360 }
2361 } else {
2362 Instruction {
2363 program_id: *program_id,
2364 accounts,
2365 data: borsh::to_vec(&StakePoolInstruction::WithdrawSol(pool_tokens_in)).unwrap(),
2366 }
2367 }
2368}
2369
2370pub fn withdraw_sol(
2372 program_id: &Pubkey,
2373 stake_pool: &Pubkey,
2374 stake_pool_withdraw_authority: &Pubkey,
2375 user_transfer_authority: &Pubkey,
2376 pool_tokens_from: &Pubkey,
2377 reserve_stake_account: &Pubkey,
2378 lamports_to: &Pubkey,
2379 manager_fee_account: &Pubkey,
2380 pool_mint: &Pubkey,
2381 token_program_id: &Pubkey,
2382 pool_tokens_in: u64,
2383) -> Instruction {
2384 withdraw_sol_internal(
2385 program_id,
2386 stake_pool,
2387 stake_pool_withdraw_authority,
2388 user_transfer_authority,
2389 pool_tokens_from,
2390 reserve_stake_account,
2391 lamports_to,
2392 manager_fee_account,
2393 pool_mint,
2394 token_program_id,
2395 None,
2396 pool_tokens_in,
2397 None,
2398 )
2399}
2400
2401pub fn withdraw_sol_with_slippage(
2404 program_id: &Pubkey,
2405 stake_pool: &Pubkey,
2406 stake_pool_withdraw_authority: &Pubkey,
2407 user_transfer_authority: &Pubkey,
2408 pool_tokens_from: &Pubkey,
2409 reserve_stake_account: &Pubkey,
2410 lamports_to: &Pubkey,
2411 manager_fee_account: &Pubkey,
2412 pool_mint: &Pubkey,
2413 token_program_id: &Pubkey,
2414 pool_tokens_in: u64,
2415 minimum_lamports_out: u64,
2416) -> Instruction {
2417 withdraw_sol_internal(
2418 program_id,
2419 stake_pool,
2420 stake_pool_withdraw_authority,
2421 user_transfer_authority,
2422 pool_tokens_from,
2423 reserve_stake_account,
2424 lamports_to,
2425 manager_fee_account,
2426 pool_mint,
2427 token_program_id,
2428 None,
2429 pool_tokens_in,
2430 Some(minimum_lamports_out),
2431 )
2432}
2433
2434pub fn withdraw_sol_with_authority(
2438 program_id: &Pubkey,
2439 stake_pool: &Pubkey,
2440 sol_withdraw_authority: &Pubkey,
2441 stake_pool_withdraw_authority: &Pubkey,
2442 user_transfer_authority: &Pubkey,
2443 pool_tokens_from: &Pubkey,
2444 reserve_stake_account: &Pubkey,
2445 lamports_to: &Pubkey,
2446 manager_fee_account: &Pubkey,
2447 pool_mint: &Pubkey,
2448 token_program_id: &Pubkey,
2449 pool_tokens_in: u64,
2450) -> Instruction {
2451 withdraw_sol_internal(
2452 program_id,
2453 stake_pool,
2454 stake_pool_withdraw_authority,
2455 user_transfer_authority,
2456 pool_tokens_from,
2457 reserve_stake_account,
2458 lamports_to,
2459 manager_fee_account,
2460 pool_mint,
2461 token_program_id,
2462 Some(sol_withdraw_authority),
2463 pool_tokens_in,
2464 None,
2465 )
2466}
2467
2468pub fn withdraw_sol_with_authority_and_slippage(
2473 program_id: &Pubkey,
2474 stake_pool: &Pubkey,
2475 sol_withdraw_authority: &Pubkey,
2476 stake_pool_withdraw_authority: &Pubkey,
2477 user_transfer_authority: &Pubkey,
2478 pool_tokens_from: &Pubkey,
2479 reserve_stake_account: &Pubkey,
2480 lamports_to: &Pubkey,
2481 manager_fee_account: &Pubkey,
2482 pool_mint: &Pubkey,
2483 token_program_id: &Pubkey,
2484 pool_tokens_in: u64,
2485 minimum_lamports_out: u64,
2486) -> Instruction {
2487 withdraw_sol_internal(
2488 program_id,
2489 stake_pool,
2490 stake_pool_withdraw_authority,
2491 user_transfer_authority,
2492 pool_tokens_from,
2493 reserve_stake_account,
2494 lamports_to,
2495 manager_fee_account,
2496 pool_mint,
2497 token_program_id,
2498 Some(sol_withdraw_authority),
2499 pool_tokens_in,
2500 Some(minimum_lamports_out),
2501 )
2502}
2503
2504pub fn set_manager(
2506 program_id: &Pubkey,
2507 stake_pool: &Pubkey,
2508 manager: &Pubkey,
2509 new_manager: &Pubkey,
2510 new_fee_receiver: &Pubkey,
2511) -> Instruction {
2512 let accounts = vec![
2513 AccountMeta::new(*stake_pool, false),
2514 AccountMeta::new_readonly(*manager, true),
2515 AccountMeta::new_readonly(*new_manager, true),
2516 AccountMeta::new_readonly(*new_fee_receiver, false),
2517 ];
2518 Instruction {
2519 program_id: *program_id,
2520 accounts,
2521 data: borsh::to_vec(&StakePoolInstruction::SetManager).unwrap(),
2522 }
2523}
2524
2525pub fn set_fee(
2527 program_id: &Pubkey,
2528 stake_pool: &Pubkey,
2529 manager: &Pubkey,
2530 fee: FeeType,
2531) -> Instruction {
2532 let accounts = vec![
2533 AccountMeta::new(*stake_pool, false),
2534 AccountMeta::new_readonly(*manager, true),
2535 ];
2536 Instruction {
2537 program_id: *program_id,
2538 accounts,
2539 data: borsh::to_vec(&StakePoolInstruction::SetFee { fee }).unwrap(),
2540 }
2541}
2542
2543pub fn set_staker(
2545 program_id: &Pubkey,
2546 stake_pool: &Pubkey,
2547 set_staker_authority: &Pubkey,
2548 new_staker: &Pubkey,
2549) -> Instruction {
2550 let accounts = vec![
2551 AccountMeta::new(*stake_pool, false),
2552 AccountMeta::new_readonly(*set_staker_authority, true),
2553 AccountMeta::new_readonly(*new_staker, false),
2554 ];
2555 Instruction {
2556 program_id: *program_id,
2557 accounts,
2558 data: borsh::to_vec(&StakePoolInstruction::SetStaker).unwrap(),
2559 }
2560}
2561
2562pub fn set_funding_authority(
2564 program_id: &Pubkey,
2565 stake_pool: &Pubkey,
2566 manager: &Pubkey,
2567 new_sol_deposit_authority: Option<&Pubkey>,
2568 funding_type: FundingType,
2569) -> Instruction {
2570 let mut accounts = vec![
2571 AccountMeta::new(*stake_pool, false),
2572 AccountMeta::new_readonly(*manager, true),
2573 ];
2574 if let Some(auth) = new_sol_deposit_authority {
2575 accounts.push(AccountMeta::new_readonly(*auth, false))
2576 }
2577 Instruction {
2578 program_id: *program_id,
2579 accounts,
2580 data: borsh::to_vec(&StakePoolInstruction::SetFundingAuthority(funding_type)).unwrap(),
2581 }
2582}
2583
2584pub fn update_token_metadata(
2587 program_id: &Pubkey,
2588 stake_pool: &Pubkey,
2589 manager: &Pubkey,
2590 pool_mint: &Pubkey,
2591 name: String,
2592 symbol: String,
2593 uri: String,
2594) -> Instruction {
2595 let (stake_pool_withdraw_authority, _) =
2596 find_withdraw_authority_program_address(program_id, stake_pool);
2597 let (token_metadata, _) = find_metadata_account(pool_mint);
2598
2599 let accounts = vec![
2600 AccountMeta::new_readonly(*stake_pool, false),
2601 AccountMeta::new_readonly(*manager, true),
2602 AccountMeta::new_readonly(stake_pool_withdraw_authority, false),
2603 AccountMeta::new(token_metadata, false),
2604 AccountMeta::new_readonly(inline_mpl_token_metadata::id(), false),
2605 ];
2606
2607 Instruction {
2608 program_id: *program_id,
2609 accounts,
2610 data: borsh::to_vec(&StakePoolInstruction::UpdateTokenMetadata { name, symbol, uri })
2611 .unwrap(),
2612 }
2613}
2614
2615pub fn create_token_metadata(
2618 program_id: &Pubkey,
2619 stake_pool: &Pubkey,
2620 manager: &Pubkey,
2621 pool_mint: &Pubkey,
2622 payer: &Pubkey,
2623 name: String,
2624 symbol: String,
2625 uri: String,
2626) -> Instruction {
2627 let (stake_pool_withdraw_authority, _) =
2628 find_withdraw_authority_program_address(program_id, stake_pool);
2629 let (token_metadata, _) = find_metadata_account(pool_mint);
2630
2631 let accounts = vec![
2632 AccountMeta::new_readonly(*stake_pool, false),
2633 AccountMeta::new_readonly(*manager, true),
2634 AccountMeta::new_readonly(stake_pool_withdraw_authority, false),
2635 AccountMeta::new_readonly(*pool_mint, false),
2636 AccountMeta::new(*payer, true),
2637 AccountMeta::new(token_metadata, false),
2638 AccountMeta::new_readonly(inline_mpl_token_metadata::id(), false),
2639 AccountMeta::new_readonly(system_program::id(), false),
2640 ];
2641
2642 Instruction {
2643 program_id: *program_id,
2644 accounts,
2645 data: borsh::to_vec(&StakePoolInstruction::CreateTokenMetadata { name, symbol, uri })
2646 .unwrap(),
2647 }
2648}