11use std:: str:: FromStr ;
22
33use solana_pubkey:: Pubkey ;
4+ use solana_sdk:: instruction:: { AccountMeta , Instruction } ;
5+
6+ use crate :: ix_parser:: instruction:: ParsableInstruction ;
47
58/// Jito Steward Instructions
69#[ derive( Debug , PartialEq ) ]
@@ -36,6 +39,12 @@ pub enum JitoStewardInstruction {
3639 IncreaseAdditionalValidatorStake ,
3740 DecreaseAdditionalValidatorStake ,
3841 UpdatePriorityFeeParameters ,
42+ CopyDirectedStakeTargets {
43+ ix : Instruction ,
44+ vote_pubkey : Pubkey ,
45+ total_target_lamports : u64 ,
46+ validator_list_index : u32 ,
47+ } ,
3948}
4049
4150impl std:: fmt:: Display for JitoStewardInstruction {
@@ -88,6 +97,14 @@ impl std::fmt::Display for JitoStewardInstruction {
8897 JitoStewardInstruction :: UpdatePriorityFeeParameters => {
8998 write ! ( f, "update_priority_fee_parameters" )
9099 }
100+ JitoStewardInstruction :: CopyDirectedStakeTargets {
101+ ix : _,
102+ vote_pubkey : _,
103+ total_target_lamports : _,
104+ validator_list_index : _,
105+ } => {
106+ write ! ( f, "copy_directed_stake_targets" )
107+ }
91108 }
92109 }
93110}
@@ -97,4 +114,120 @@ impl JitoStewardInstruction {
97114 pub fn program_id ( ) -> Pubkey {
98115 Pubkey :: from_str ( "Stewardf95sJbmtcZsyagb2dg4Mo8eVQho8gpECvLx8" ) . unwrap ( )
99116 }
117+
118+ /// Parse Jito Steward instruction
119+ pub fn parse < T : ParsableInstruction > (
120+ instruction : & T ,
121+ account_keys : & [ Pubkey ] ,
122+ ) -> Option < JitoStewardInstruction > {
123+ let instruction_data = instruction. data ( ) ;
124+ match instruction_data[ 0 ..8 ] {
125+ [ 135 , 132 , 9 , 127 , 189 , 161 , 14 , 5 ] => {
126+ let vote_pubkey = {
127+ let mut pubkey_array = [ 0 ; 32 ] ;
128+ pubkey_array. copy_from_slice ( & instruction_data[ 8 ..40 ] ) ;
129+ Pubkey :: new_from_array ( pubkey_array)
130+ } ;
131+
132+ let total_target_lamports = {
133+ let mut slice = [ 0 ; 8 ] ;
134+ slice. copy_from_slice ( & instruction_data[ 40 ..48 ] ) ;
135+ u64:: from_le_bytes ( slice)
136+ } ;
137+
138+ let validator_list_index = {
139+ let mut slice = [ 0 ; 4 ] ;
140+ slice. copy_from_slice ( & instruction_data[ 48 ..52 ] ) ;
141+ u32:: from_le_bytes ( slice)
142+ } ;
143+
144+ Some ( Self :: parse_copy_directed_stake_targets_ix (
145+ instruction,
146+ account_keys,
147+ vote_pubkey,
148+ total_target_lamports,
149+ validator_list_index,
150+ ) )
151+ }
152+ _ => None ,
153+ }
154+ }
155+
156+ /// #[account(0, name = "config")]
157+ /// #[account(1, writable, name = "directed_stake_meta")]
158+ /// #[account(2, name = "clock")]
159+ /// #[account(3, writable, name = "validator_list")]
160+ /// #[account(4, writable, signer, name = "authority")]
161+ pub fn parse_copy_directed_stake_targets_ix < T : ParsableInstruction > (
162+ instruction : & T ,
163+ account_keys : & [ Pubkey ] ,
164+ vote_pubkey : Pubkey ,
165+ total_target_lamports : u64 ,
166+ validator_list_index : u32 ,
167+ ) -> Self {
168+ let mut account_metas = [
169+ AccountMeta :: new ( Pubkey :: new_unique ( ) , false ) ,
170+ AccountMeta :: new ( Pubkey :: new_unique ( ) , false ) ,
171+ AccountMeta :: new ( Pubkey :: new_unique ( ) , false ) ,
172+ AccountMeta :: new ( Pubkey :: new_unique ( ) , false ) ,
173+ AccountMeta :: new_readonly ( Pubkey :: new_unique ( ) , true ) ,
174+ ] ;
175+
176+ for ( index, account) in instruction. accounts ( ) . iter ( ) . enumerate ( ) {
177+ if let Some ( account_meta) = account_metas. get_mut ( index) {
178+ if let Some ( account) = account_keys. get ( * account as usize ) {
179+ account_meta. pubkey = * account;
180+ }
181+ }
182+ }
183+
184+ let ix = Instruction {
185+ program_id : Self :: program_id ( ) ,
186+ accounts : account_metas. to_vec ( ) ,
187+ data : instruction. data ( ) . to_vec ( ) ,
188+ } ;
189+
190+ Self :: CopyDirectedStakeTargets {
191+ ix,
192+ vote_pubkey,
193+ total_target_lamports,
194+ validator_list_index,
195+ }
196+ }
197+ }
198+
199+ #[ cfg( test) ]
200+ mod tests {
201+ use yellowstone_grpc_proto:: prelude:: CompiledInstruction ;
202+
203+ use crate :: ix_parser:: jito_steward:: JitoStewardInstruction ;
204+
205+ #[ test]
206+ fn test_parse_copy_directed_stake_targets ( ) {
207+ let instruction = {
208+ let data =
209+ hex:: decode (
210+ "8784097fbda10e054613d432f5da8f600ac38dcd8f5c07df361f5b832400b012604624443b3f457000000000000000006e000000"
211+ ) . unwrap ( ) ;
212+ CompiledInstruction {
213+ program_id_index : 0 ,
214+ accounts : vec ! [ 0 ] ,
215+ data,
216+ }
217+ } ;
218+
219+ let account_keys = vec ! [ ] ;
220+ let jito_steward_instruction =
221+ JitoStewardInstruction :: parse ( & instruction, & account_keys) . unwrap ( ) ;
222+
223+ match jito_steward_instruction {
224+ JitoStewardInstruction :: CopyDirectedStakeTargets {
225+ ix : _,
226+ vote_pubkey : _,
227+ total_target_lamports : _,
228+ validator_list_index : _,
229+ } => { }
230+ _ => panic ! ( "Wrong instruction" ) ,
231+ }
232+ }
100233}
0 commit comments