solana_tx_decoding/tx/
inner_instructions_loop.rs1use crate::instruction::classify_instruction::classify_instruction;
2use crate::instruction::pumpfun::process_pf_bonding_curve_create_instruction::process_pf_bonding_curve_create_instruction;
3use crate::instruction::pumpfun::process_pumpfun_event_instruction::process_pumpfun_event_instruction;
4use crate::instruction::pumpswap::process_pumpswap_swap_instruction::process_pumpswap_swap_instruction;
5use crate::instruction::raydium::process_raydium_ammv4_swap_instruction::process_raydium_ammv4_swap_instruction;
6use crate::instruction::raydium::process_raydium_cpmm_swap_instruction::process_raydium_cpmm_swap_instruction;
7use crate::instruction::raydium::process_raydium_launchpad_swap_instruction::process_raydium_launchpad_swap_instruction;
8use crate::types::instruction_type::InstructionType;
9use solana_central::Instruction;
10use solana_central::SwapTx;
11use solana_central::TokenCreation;
12use solana_central::constants::PUMP_CONSTANTS;
13use solana_sdk::pubkey::Pubkey;
14use solana_sdk::signature::Signature;
15use std::collections::HashMap;
16use std::collections::HashSet;
17use tokio::sync::broadcast::Sender;
18
19pub fn inner_instructions_loop(
23 inner_instructions: &Vec<Instruction>,
24 account_keys: &Vec<Pubkey>,
25 ta_mint: &HashMap<u8, Pubkey>,
26 running_token_balances: &mut HashMap<u8, u64>,
27 swap_tx_sender: &Sender<SwapTx>,
28 token_create_sender: &Sender<TokenCreation>,
29 block_time: u64,
30 slot: u64,
31 index: u64,
32 atomic_instruction_index: &mut u8,
33 signers: &HashSet<Pubkey>,
34 signature: &Signature,
35) {
36 let mut instr_index = 0;
38 while instr_index < inner_instructions.len() {
39 let instruction = &inner_instructions[instr_index];
40
41 let (instruction_type, swap_direction) = classify_instruction(&instruction);
42 if instruction_type == InstructionType::RaydiumLaunchpadSwap {
43 let event = &inner_instructions[instr_index + 1];
45 let swap_tx = process_raydium_launchpad_swap_instruction(
46 instruction,
47 event,
48 swap_direction,
49 block_time,
50 slot,
51 index,
52 *atomic_instruction_index,
53 signers,
54 signature,
55 );
56 let _ = swap_tx_sender.send(swap_tx);
57 } else if instruction_type == InstructionType::RaydiumCpmmSwap {
58 let transfers = &inner_instructions[instr_index + 1..instr_index + 3];
60 let swap_tx = process_raydium_cpmm_swap_instruction(
61 instruction,
62 transfers,
63 running_token_balances,
64 block_time,
65 slot,
66 index,
67 *atomic_instruction_index,
68 signers,
69 signature,
70 );
71 let _ = swap_tx_sender.send(swap_tx);
72 } else if instruction_type == InstructionType::RaydiumAmmV4Swap {
73 let transfers = &inner_instructions[instr_index + 1..instr_index + 3];
75 let swap_tx = process_raydium_ammv4_swap_instruction(
76 instruction,
77 transfers,
78 ta_mint,
79 running_token_balances,
80 block_time,
81 slot,
82 index,
83 *atomic_instruction_index,
84 signers,
85 signature,
86 );
87 let _ = swap_tx_sender.send(swap_tx);
88 } else if instruction_type == InstructionType::PumpswapSwap {
89 let mut event = None;
91 for i in instr_index + 1..inner_instructions.len() {
92 if account_keys[inner_instructions[i].program_id_index as usize]
93 == PUMP_CONSTANTS.pump_swap_program
94 {
95 event = Some(&inner_instructions[i]);
96 break;
97 }
98 }
99 let swap_tx = process_pumpswap_swap_instruction(
100 instruction,
101 event.expect(&format!("inner_instructions_loop: Unable to find pumpswap event following inner instruction swap, signature: {}", signature.to_string())),
102 swap_direction,
103 block_time,
104 slot,
105 index,
106 *atomic_instruction_index,
107 signers,
108 signature,
109 );
110 let _ = swap_tx_sender.send(swap_tx);
111 } else if instruction_type == InstructionType::PfBondingCurveSwap {
112 let swap_tx = process_pumpfun_event_instruction(
113 instruction,
114 block_time,
115 slot,
116 index,
117 *atomic_instruction_index,
118 signers,
119 signature,
120 );
121 let _ = swap_tx_sender.send(swap_tx);
122 } else if instruction_type == InstructionType::PfBondingCurveCreate {
123 let creation = process_pf_bonding_curve_create_instruction(
124 instruction,
125 block_time,
126 slot,
127 index,
128 *atomic_instruction_index,
129 signature,
130 );
131 let _ = token_create_sender.send(creation);
132 }
133
134 *atomic_instruction_index += 1;
135 instr_index += 1;
136 }
138}