sol_parser_sdk/accounts/
mod.rs1pub mod nonce;
2pub mod program_ids;
3pub mod pumpswap;
4pub mod rpc_wallet;
5pub mod token;
6pub mod utils;
7use crate::core::events::EventMetadata;
8use crate::grpc::EventTypeFilter;
9use crate::DexEvent;
10pub use nonce::parse_nonce_account;
11use program_ids::*;
12pub use pumpswap::{
13 parse_global_config as parse_pumpswap_global_config, parse_pool as parse_pumpswap_pool,
14};
15pub use rpc_wallet::rpc_resolve_user_wallet_pubkey;
16pub use token::parse_token_account;
17pub use token::AccountData;
18pub use utils::*;
19
20pub fn parse_account_unified(
21 account: &AccountData,
22 metadata: EventMetadata,
23 event_type_filter: Option<&EventTypeFilter>,
24) -> Option<DexEvent> {
25 if account.data.is_empty() {
26 return None;
27 }
28
29 if let Some(filter) = event_type_filter {
31 if let Some(ref include_only) = filter.include_only {
32 let should_parse = include_only.iter().any(|t| {
34 use crate::grpc::EventType;
35 matches!(
36 t,
37 EventType::TokenAccount
38 | EventType::NonceAccount
39 | EventType::AccountPumpFunGlobal
40 | EventType::AccountPumpSwapGlobalConfig
41 | EventType::AccountPumpSwapPool
42 )
43 });
44 if !should_parse {
45 return None;
46 }
47 }
48 }
49
50 if account.owner == PUMPSWAP_PROGRAM_ID {
51 if let Some(filter) = event_type_filter {
52 if filter.should_include(crate::grpc::EventType::AccountPumpSwapGlobalConfig)
53 || filter.should_include(crate::grpc::EventType::AccountPumpSwapPool)
54 {
55 let event = parse_pumpswap_account(account, metadata.clone());
56 if event.is_some() {
57 return event;
58 }
59 }
60 }
61 }
62 if account.owner == crate::grpc::program_ids::PUMPFUN_PROGRAM {
63 if let Some(filter) = event_type_filter {
64 if filter.should_include(crate::grpc::EventType::AccountPumpFunGlobal) {
65 let event = parse_pumpfun_account(account, metadata.clone());
66 if event.is_some() {
67 return event;
68 }
69 }
70 }
71 }
72 if nonce::is_nonce_account(&account.data) {
73 if let Some(filter) = event_type_filter {
75 if !filter.should_include(crate::grpc::EventType::NonceAccount) {
76 return None;
77 }
78 }
79 return parse_nonce_account(account, metadata);
80 }
81 if let Some(filter) = event_type_filter {
83 let includes_token = filter.should_include(crate::grpc::EventType::TokenAccount);
84 if !includes_token {
85 return None;
86 }
87 }
88 return parse_token_account(account, metadata);
89}
90
91fn parse_pumpswap_account(account: &AccountData, metadata: EventMetadata) -> Option<DexEvent> {
92 if pumpswap::is_global_config_account(&account.data) {
94 return pumpswap::parse_global_config(account, metadata);
95 }
96 if pumpswap::is_pool_account(&account.data) {
97 return pumpswap::parse_pool(account, metadata);
98 }
99 None
100}
101
102fn parse_pumpfun_account(account: &AccountData, metadata: EventMetadata) -> Option<DexEvent> {
103 use crate::core::events::{PumpFunGlobal, PumpFunGlobalAccountEvent};
104
105 const GLOBAL_DISCRIMINATOR: &[u8; 8] = &[167, 232, 232, 177, 200, 108, 114, 127];
106 if !has_discriminator(&account.data, GLOBAL_DISCRIMINATOR) {
107 return None;
108 }
109
110 let data = &account.data[8..];
111 let mut offset = 0usize;
112 let initialized = read_u8(data, offset)? != 0;
113 offset += 1;
114 let authority = read_pubkey(data, offset)?;
115 offset += 32;
116 let fee_recipient = read_pubkey(data, offset)?;
117 offset += 32;
118 let initial_virtual_token_reserves = read_u64_le(data, offset)?;
119 offset += 8;
120 let initial_virtual_sol_reserves = read_u64_le(data, offset)?;
121 offset += 8;
122 let initial_real_token_reserves = read_u64_le(data, offset)?;
123 offset += 8;
124 let token_total_supply = read_u64_le(data, offset)?;
125 offset += 8;
126 let fee_basis_points = read_u64_le(data, offset)?;
127 offset += 8;
128 let withdraw_authority = read_pubkey(data, offset)?;
129 offset += 32;
130 let enable_migrate = read_u8(data, offset)? != 0;
131 offset += 1;
132 let pool_migration_fee = read_u64_le(data, offset)?;
133 offset += 8;
134 let creator_fee_basis_points = read_u64_le(data, offset)?;
135 offset += 8;
136 let mut fee_recipients = [solana_sdk::pubkey::Pubkey::default(); 8];
137 for i in 0..8 {
138 fee_recipients[i] = read_pubkey(data, offset)?;
139 offset += 32;
140 }
141 let set_creator_authority = read_pubkey(data, offset)?;
142 offset += 32;
143 let admin_set_creator_authority = read_pubkey(data, offset)?;
144 offset += 32;
145 let create_v2_enabled = read_u8(data, offset)? != 0;
146 offset += 1;
147 let whitelist_pda = read_pubkey(data, offset)?;
148 offset += 32;
149 let reserved_fee_recipient = read_pubkey(data, offset)?;
150 offset += 32;
151 let mayhem_mode_enabled = read_u8(data, offset)? != 0;
152 offset += 1;
153 let mut reserved_fee_recipients = [solana_sdk::pubkey::Pubkey::default(); 7];
154 for i in 0..7 {
155 reserved_fee_recipients[i] = read_pubkey(data, offset)?;
156 offset += 32;
157 }
158 let _is_cashback_enabled = read_u8(data, offset)? != 0;
159 offset += 1;
160 let _buyback_fee_recipients = {
161 let mut keys = [solana_sdk::pubkey::Pubkey::default(); 8];
162 for i in 0..8 {
163 keys[i] = read_pubkey(data, offset)?;
164 offset += 32;
165 }
166 keys
167 };
168
169 let global = PumpFunGlobal {
170 initialized,
171 authority,
172 fee_recipient,
173 initial_virtual_token_reserves,
174 initial_virtual_sol_reserves,
175 initial_real_token_reserves,
176 token_total_supply,
177 fee_basis_points,
178 withdraw_authority,
179 enable_migrate,
180 pool_migration_fee,
181 creator_fee_basis_points,
182 fee_recipients,
183 set_creator_authority,
184 admin_set_creator_authority,
185 create_v2_enabled,
186 whitelist_pda,
187 reserved_fee_recipient,
188 mayhem_mode_enabled,
189 reserved_fee_recipients,
190 };
191
192 Some(DexEvent::PumpFunGlobalAccount(PumpFunGlobalAccountEvent {
193 metadata,
194 pubkey: account.pubkey,
195 global,
196 }))
197}