Skip to main content

solana_tx_parser/
shred_parser.rs

1//! Parser for shred-stream / pre-execution instruction analysis.
2//! Parses instructions by DEX without full transaction meta.
3
4use crate::constants::get_program_name;
5use crate::instruction_classifier::InstructionClassifier;
6use crate::transaction_adapter::TransactionAdapter;
7use crate::types::{ParseConfig, ParseShredResult};
8use std::collections::HashMap;
9
10pub struct ShredParser;
11
12impl ShredParser {
13    pub fn new() -> Self {
14        Self
15    }
16
17    /// Parse instructions from transaction (e.g. from shred stream) grouped by DEX name.
18    pub fn parse_all(
19        &self,
20        tx: &crate::types::SolanaTransactionInput,
21        config: Option<ParseConfig>,
22    ) -> ParseShredResult {
23        let config = config.unwrap_or_default();
24        let mut result = ParseShredResult {
25            state: true,
26            signature: String::new(),
27            instructions: HashMap::new(),
28            msg: None,
29        };
30        let adapter = TransactionAdapter::new(tx, Some(config.clone()));
31        result.signature = adapter.signature();
32        let classifier = InstructionClassifier::new(&adapter);
33        let all_program_ids = classifier.get_all_program_ids();
34        if let Some(ref filter) = config.program_ids {
35            if !all_program_ids.iter().any(|id| filter.contains(id)) {
36                return result;
37            }
38        }
39        for program_id in &all_program_ids {
40            if config.program_ids.as_ref().map(|p| !p.contains(program_id)).unwrap_or(false) {
41                continue;
42            }
43            if config.ignore_program_ids.as_ref().map(|p| p.contains(program_id)).unwrap_or(false) {
44                continue;
45            }
46            let instructions = classifier.get_instructions(program_id);
47            let name = get_program_name(program_id);
48            result.instructions.insert(
49                name.to_string(),
50                instructions
51                    .into_iter()
52                    .map(|ci| serde_json::json!({ "programId": ci.program_id, "outerIndex": ci.outer_index, "innerIndex": ci.inner_index }))
53                    .collect(),
54            );
55        }
56        result
57    }
58}
59
60impl Default for ShredParser {
61    fn default() -> Self {
62        Self::new()
63    }
64}