solana_tx_decoding/tx/
top_level_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::pumpswap::process_pumpswap_swap_instruction::process_pumpswap_swap_instruction;
4use crate::instruction::raydium::process_raydium_ammv4_swap_instruction::process_raydium_ammv4_swap_instruction;
5use crate::instruction::raydium::process_raydium_cpmm_swap_instruction::process_raydium_cpmm_swap_instruction;
6use crate::instruction::raydium::process_raydium_launchpad_swap_instruction::process_raydium_launchpad_swap_instruction;
7use crate::tx::inner_instructions_loop::inner_instructions_loop;
8use crate::types::instruction_type::InstructionType;
9use solana_central::Instruction;
10use solana_central::SwapTx;
11use solana_central::TokenCreation;
12use solana_sdk::pubkey::Pubkey;
13use solana_sdk::signature::Signature;
14use std::collections::HashMap;
15use std::collections::HashSet;
16use tokio::sync::broadcast::Sender;
17
18pub fn top_level_instructions_loop(
22 top_level_instructions: &Vec<Instruction>,
23 inner_instructions: &HashMap<u8, 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 signers: &HashSet<Pubkey>,
33 signature: &Signature,
34) {
35 let mut atomic_instruction_index = 0;
36 for (instr_index, instruction) in top_level_instructions.iter().enumerate() {
37 let instr_index = instr_index as u8;
38 let (instruction_type, swap_direction) = classify_instruction(&instruction);
39 if instruction_type == InstructionType::None {
43 atomic_instruction_index += 1;
45 if let Some(inner_instructions) = inner_instructions.get(&instr_index) {
46 inner_instructions_loop(
47 inner_instructions,
48 account_keys,
49 ta_mint,
50 running_token_balances,
51 swap_tx_sender,
52 token_create_sender,
53 block_time,
54 slot,
55 index,
56 &mut atomic_instruction_index,
57 signers,
58 signature,
59 );
60 }
61 } else if instruction_type == InstructionType::RaydiumLaunchpadSwap {
62 let event = &inner_instructions.get(&instr_index).unwrap()[0];
63 let swap_tx = process_raydium_launchpad_swap_instruction(
64 instruction,
65 event,
66 swap_direction,
67 block_time,
68 slot,
69 index,
70 atomic_instruction_index,
71 signers,
72 signature,
73 );
74 let _ = swap_tx_sender.send(swap_tx);
75 } else if instruction_type == InstructionType::RaydiumCpmmSwap {
76 let transfers = inner_instructions.get(&instr_index).unwrap();
77 let swap_tx = process_raydium_cpmm_swap_instruction(
78 instruction,
79 transfers,
80 running_token_balances,
81 block_time,
82 slot,
83 index,
84 atomic_instruction_index,
85 signers,
86 signature,
87 );
88 let _ = swap_tx_sender.send(swap_tx);
89 } else if instruction_type == InstructionType::RaydiumAmmV4Swap {
90 let transfers = inner_instructions.get(&instr_index).unwrap();
91 let swap_tx = process_raydium_ammv4_swap_instruction(
92 instruction,
93 transfers,
94 ta_mint,
95 running_token_balances,
96 block_time,
97 slot,
98 index,
99 atomic_instruction_index,
100 signers,
101 signature,
102 );
103 let _ = swap_tx_sender.send(swap_tx);
104 } else if instruction_type == InstructionType::PumpswapSwap {
105 let event = inner_instructions
106 .get(&instr_index)
107 .unwrap()
108 .last()
109 .unwrap();
110 let swap_tx = process_pumpswap_swap_instruction(
111 instruction,
112 event,
113 swap_direction,
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 if instruction_type != InstructionType::None {
135 let a = inner_instructions.get(&instr_index).unwrap().len() as u8;
136 atomic_instruction_index += a + 1;
138 }
139 }
141}