1use solana_sdk::{pubkey::Pubkey, signature::Signature};
6use crate::core::events::*;
7use super::utils::*;
8use super::program_ids;
9
10pub mod discriminators {
12 pub const TRADE: [u8; 8] = [2, 3, 4, 5, 6, 7, 8, 9];
13 pub const POOL_CREATE: [u8; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
14 pub const MIGRATE_AMM: [u8; 8] = [3, 4, 5, 6, 7, 8, 9, 10];
15}
16
17pub const PROGRAM_ID_PUBKEY: Pubkey = program_ids::BONK_PROGRAM_ID;
19
20pub fn parse_instruction(
22 instruction_data: &[u8],
23 accounts: &[Pubkey],
24 signature: Signature,
25 slot: u64,
26 tx_index: u64,
27 block_time: Option<i64>,
28) -> Option<DexEvent> {
29 if instruction_data.len() < 8 {
30 return None;
31 }
32
33 let discriminator: [u8; 8] = instruction_data[0..8].try_into().ok()?;
34 let data = &instruction_data[8..];
35
36 match discriminator {
37 discriminators::TRADE => {
38 parse_trade_instruction(data, accounts, signature, slot, tx_index, block_time)
39 },
40 discriminators::POOL_CREATE => {
41 parse_pool_create_instruction(data, accounts, signature, slot, tx_index, block_time)
42 },
43 discriminators::MIGRATE_AMM => {
44 parse_migrate_amm_instruction(data, accounts, signature, slot, tx_index, block_time)
45 },
46 _ => None,
47 }
48}
49
50fn parse_trade_instruction(
52 data: &[u8],
53 accounts: &[Pubkey],
54 signature: Signature,
55 slot: u64,
56 tx_index: u64,
57 block_time: Option<i64>,
58) -> Option<DexEvent> {
59 let mut offset = 0;
60
61 let amount_in = read_u64_le(data, offset)?;
62 offset += 8;
63
64 let amount_out_min = read_u64_le(data, offset)?;
65
66 let pool_state = get_account(accounts, 0)?;
67 let metadata = create_metadata_simple(signature, slot, tx_index, block_time, pool_state);
68
69 Some(DexEvent::BonkTrade(BonkTradeEvent {
70 metadata,
71 pool_state,
72 user: get_account(accounts, 1).unwrap_or_default(),
73 amount_in,
74 amount_out: amount_out_min, is_buy: true, trade_direction: TradeDirection::Buy,
77 exact_in: true,
78 }))
79}
80
81fn parse_pool_create_instruction(
83 data: &[u8],
84 accounts: &[Pubkey],
85 signature: Signature,
86 slot: u64,
87 tx_index: u64,
88 block_time: Option<i64>,
89) -> Option<DexEvent> {
90 let pool_state = get_account(accounts, 0)?;
91 let metadata = create_metadata_simple(signature, slot, tx_index, block_time, pool_state);
92
93 Some(DexEvent::BonkPoolCreate(BonkPoolCreateEvent {
94 metadata,
95 base_mint_param: BaseMintParam {
96 symbol: "BONK".to_string(),
97 name: "Bonk Pool".to_string(),
98 uri: "https://bonk.com".to_string(),
99 decimals: 5,
100 },
101 pool_state,
102 creator: get_account(accounts, 1).unwrap_or_default(),
103 }))
104}
105
106fn parse_migrate_amm_instruction(
108 data: &[u8],
109 accounts: &[Pubkey],
110 signature: Signature,
111 slot: u64,
112 tx_index: u64,
113 block_time: Option<i64>,
114) -> Option<DexEvent> {
115 let mut offset = 0;
116
117 let liquidity_amount = read_u64_le(data, offset)?;
118
119 let old_pool = get_account(accounts, 0)?;
120 let metadata = create_metadata_simple(signature, slot, tx_index, block_time, old_pool);
121
122 Some(DexEvent::BonkMigrateAmm(BonkMigrateAmmEvent {
123 metadata,
124 old_pool,
125 new_pool: get_account(accounts, 1).unwrap_or_default(),
126 user: get_account(accounts, 2).unwrap_or_default(),
127 liquidity_amount,
128 }))
129}