Skip to main content

solana_tx_parser/
types.rs

1//! Types for trades, pools, transfers, and parse results.
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct TokenAmount {
7    pub amount: String,
8    pub ui_amount: Option<f64>,
9    pub decimals: u8,
10}
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct TokenInfo {
14    pub mint: String,
15    pub amount: f64,
16    pub amount_raw: String,
17    pub decimals: u8,
18    pub authority: Option<String>,
19    pub destination: Option<String>,
20    pub destination_owner: Option<String>,
21    pub source: Option<String>,
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct BalanceChange {
26    pub pre: TokenAmount,
27    pub post: TokenAmount,
28    pub change: TokenAmount,
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
32#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
33pub enum TransactionStatus {
34    Unknown,
35    Success,
36    Failed,
37}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
40#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
41pub enum TradeType {
42    Buy,
43    Sell,
44    Swap,
45    Create,
46    Migrate,
47    Complete,
48    Add,
49    Remove,
50    Lock,
51    Burn,
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
55#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
56pub enum PoolEventType {
57    Create,
58    Add,
59    Remove,
60}
61
62#[derive(Debug, Clone, Serialize, Deserialize)]
63pub struct TransferInfoInner {
64    pub authority: Option<String>,
65    pub destination: String,
66    pub destination_owner: Option<String>,
67    pub mint: String,
68    pub source: String,
69    pub token_amount: TokenAmount,
70    pub source_balance: Option<TokenAmount>,
71    pub source_pre_balance: Option<TokenAmount>,
72    pub destination_balance: Option<TokenAmount>,
73    pub destination_pre_balance: Option<TokenAmount>,
74}
75
76#[derive(Debug, Clone, Serialize, Deserialize)]
77pub struct TransferData {
78    pub transfer_type: String, // "transfer" | "transferChecked" | etc
79    pub program_id: String,
80    pub info: TransferInfoInner,
81    pub idx: String,
82    pub timestamp: i64,
83    pub signature: String,
84    pub is_fee: Option<bool>,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
88pub struct FeeInfo {
89    pub mint: String,
90    pub amount: f64,
91    pub amount_raw: String,
92    pub decimals: u8,
93    pub dex: Option<String>,
94    pub type_: Option<String>,
95    pub recipient: Option<String>,
96}
97
98#[derive(Debug, Clone, Serialize, Deserialize)]
99pub struct TradeInfo {
100    pub user: String,
101    pub trade_type: TradeType,
102    pub pool: Vec<String>,
103    pub input_token: TokenInfo,
104    pub output_token: TokenInfo,
105    pub slippage_bps: Option<u64>,
106    pub fee: Option<FeeInfo>,
107    pub fees: Option<Vec<FeeInfo>>,
108    pub program_id: Option<String>,
109    pub amm: Option<String>,
110    pub amms: Option<Vec<String>>,
111    pub route: Option<String>,
112    pub slot: u64,
113    pub timestamp: i64,
114    pub signature: String,
115    pub idx: String,
116    pub signer: Option<Vec<String>>,
117}
118
119#[derive(Debug, Clone, Serialize, Deserialize)]
120pub struct PoolEvent {
121    pub user: String,
122    pub pool_event_type: PoolEventType,
123    pub program_id: Option<String>,
124    pub amm: Option<String>,
125    pub slot: u64,
126    pub timestamp: i64,
127    pub signature: String,
128    pub idx: String,
129    pub signer: Option<Vec<String>>,
130    pub pool_id: String,
131    pub config: Option<String>,
132    pub pool_lp_mint: Option<String>,
133    pub token0_mint: Option<String>,
134    pub token0_amount: Option<f64>,
135    pub token0_amount_raw: Option<String>,
136    pub token0_balance_change: Option<String>,
137    pub token0_decimals: Option<u8>,
138    pub token1_mint: Option<String>,
139    pub token1_amount: Option<f64>,
140    pub token1_amount_raw: Option<String>,
141    pub token1_balance_change: Option<String>,
142    pub token1_decimals: Option<u8>,
143    pub lp_amount: Option<f64>,
144    pub lp_amount_raw: Option<String>,
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize)]
148pub struct MemeEvent {
149    pub event_type: TradeType,
150    pub timestamp: i64,
151    pub idx: String,
152    pub slot: u64,
153    pub signature: String,
154    pub user: String,
155    pub base_mint: String,
156    pub quote_mint: String,
157    pub input_token: Option<TokenInfo>,
158    pub output_token: Option<TokenInfo>,
159    pub name: Option<String>,
160    pub symbol: Option<String>,
161    pub uri: Option<String>,
162    pub decimals: Option<u8>,
163    pub total_supply: Option<f64>,
164    pub fee: Option<f64>,
165    pub protocol_fee: Option<f64>,
166    pub platform_fee: Option<f64>,
167    pub creator: Option<String>,
168    pub bonding_curve: Option<String>,
169    pub pool: Option<String>,
170    pub protocol: Option<String>,
171}
172
173#[derive(Debug, Clone)]
174pub struct ClassifiedInstruction {
175    pub instruction: ParsedInstruction,
176    pub program_id: String,
177    pub outer_index: usize,
178    pub inner_index: Option<usize>,
179}
180
181#[derive(Debug, Clone)]
182pub struct ParsedInstruction {
183    pub program_id: String,
184    pub accounts: Vec<String>,
185    pub data: Vec<u8>,
186    pub parsed: Option<serde_json::Value>,
187}
188
189#[derive(Debug, Clone, Default)]
190pub struct DexInfo {
191    pub program_id: Option<String>,
192    pub amm: Option<String>,
193    pub route: Option<String>,
194}
195
196#[derive(Debug, Clone, Serialize, Deserialize)]
197pub struct ParseResult {
198    pub state: bool,
199    pub fee: TokenAmount,
200    pub aggregate_trade: Option<TradeInfo>,
201    pub trades: Vec<TradeInfo>,
202    pub liquidities: Vec<PoolEvent>,
203    pub transfers: Vec<TransferData>,
204    pub meme_events: Vec<MemeEvent>,
205    pub slot: u64,
206    pub timestamp: i64,
207    pub signature: String,
208    pub signer: Vec<String>,
209    pub compute_units: u64,
210    pub tx_status: TransactionStatus,
211    pub msg: Option<String>,
212    pub sol_balance_change: Option<BalanceChange>,
213    pub token_balance_change: Option<std::collections::HashMap<String, BalanceChange>>,
214}
215
216#[derive(Debug, Clone, Serialize, Deserialize)]
217pub struct ParseShredResult {
218    pub state: bool,
219    pub signature: String,
220    pub instructions: std::collections::HashMap<String, Vec<serde_json::Value>>,
221    pub msg: Option<String>,
222}
223
224/// Configuration for parsing
225#[derive(Debug, Clone, Default)]
226pub struct ParseConfig {
227    pub try_unknown_dex: bool,
228    pub program_ids: Option<Vec<String>>,
229    pub ignore_program_ids: Option<Vec<String>>,
230    pub throw_error: bool,
231    pub aggregate_trades: bool,
232}
233
234/// Input transaction + meta. Build from RPC getTransaction or Geyser.
235#[derive(Debug, Clone)]
236pub struct SolanaTransactionInput {
237    pub slot: u64,
238    pub block_time: Option<i64>,
239    pub version: Option<u8>,
240    pub signatures: Vec<Vec<u8>>,
241    pub account_keys: Vec<String>,
242    pub instructions: Vec<RawInstruction>,
243    pub inner_instructions: Option<Vec<InnerInstructionSet>>,
244    pub meta: Option<TransactionMetaInput>,
245}
246
247#[derive(Debug, Clone)]
248pub struct RawInstruction {
249    pub program_id_index: u8,
250    pub data: Vec<u8>,
251    pub account_key_indexes: Vec<u8>,
252}
253
254#[derive(Debug, Clone)]
255pub struct InnerInstructionSet {
256    pub index: u32,
257    pub instructions: Vec<RawInstruction>,
258}
259
260#[derive(Debug, Clone)]
261pub struct TransactionMetaInput {
262    pub err: Option<serde_json::Value>,
263    pub fee: Option<u64>,
264    pub pre_balances: Option<Vec<u64>>,
265    pub post_balances: Option<Vec<u64>>,
266    pub pre_token_balances: Option<Vec<TokenBalanceInput>>,
267    pub post_token_balances: Option<Vec<TokenBalanceInput>>,
268    pub inner_instructions: Option<Vec<InnerInstructionSet>>,
269    pub loaded_addresses: Option<LoadedAddressesInput>,
270    pub compute_units_consumed: Option<u64>,
271}
272
273#[derive(Debug, Clone)]
274pub struct TokenBalanceInput {
275    pub account_index: u32,
276    pub mint: Option<String>,
277    pub owner: Option<String>,
278    pub ui_token_amount: UiTokenAmountInput,
279}
280
281#[derive(Debug, Clone)]
282pub struct UiTokenAmountInput {
283    pub amount: String,
284    pub decimals: u8,
285    pub ui_amount: Option<f64>,
286    pub ui_amount_string: Option<String>,
287}
288
289#[derive(Debug, Clone)]
290pub struct LoadedAddressesInput {
291    pub writable: Vec<String>,
292    pub readonly: Vec<String>,
293}