Skip to main content

solana_tx_parser/
constants.rs

1//! DEX program IDs, discriminators, tokens, and instruction types.
2
3use std::collections::HashMap;
4
5pub const TOKEN_PROGRAM_ID: &str = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
6pub const TOKEN_2022_PROGRAM_ID: &str = "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb";
7pub const ASSOCIATED_TOKEN_PROGRAM_ID: &str = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
8
9pub mod tokens {
10    pub const NATIVE: &str = "11111111111111111111111111111111";
11    pub const SOL: &str = "So11111111111111111111111111111111111111112";
12    pub const USDC: &str = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
13    pub const USDT: &str = "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB";
14    pub const USD1: &str = "USD1ttGY1N17NEEHLmELoaybftRBUSErhqYiQzvEmuB";
15    pub const USDG: &str = "2u1tszSeqZ3qBWF3uNGPFc8TzMk2tdiwknnRMWGWjGWH";
16    pub const PYUSD: &str = "2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo";
17    pub const EURC: &str = "HzwqbKZw8HxMN6bF2yFZNrht3c2iXXzpKcFu7uBEDKtr";
18    pub const USDY: &str = "A1KLoBrKBde8Ty9qtNQUtq3C2ortoC3u7twggz7sEto6";
19    pub const FDUSD: &str = "9zNQRsGLjNKwCUU5Gq5LR8beUCPzQMVMqKAi3SSZh54u";
20}
21
22pub fn token_decimals(mint: &str) -> Option<u8> {
23    let m: HashMap<&str, u8> = [
24        (tokens::SOL, 9),
25        (tokens::USDC, 6),
26        (tokens::USDT, 6),
27        (tokens::USD1, 6),
28        (tokens::USDG, 6),
29        (tokens::PYUSD, 6),
30        (tokens::EURC, 6),
31        (tokens::USDY, 6),
32        (tokens::FDUSD, 6),
33    ]
34    .into_iter()
35    .collect();
36    m.get(mint).copied()
37}
38
39#[derive(Clone, Debug)]
40pub struct DexProgram {
41    pub id: &'static str,
42    pub name: &'static str,
43    pub tags: &'static [&'static str],
44}
45
46pub mod dex_programs {
47    use super::DexProgram;
48
49    pub const JUPITER: DexProgram = DexProgram {
50        id: "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",
51        name: "Jupiter",
52        tags: &["route"],
53    };
54    pub const JUPITER_DCA: DexProgram = DexProgram {
55        id: "DCA265Vj8a9CEuX1eb1LWRnDT7uK6q1xMipnNyatn23M",
56        name: "JupiterDCA",
57        tags: &["route"],
58    };
59    pub const JUPITER_DCA_KEEPER1: DexProgram = DexProgram {
60        id: "DCAKxn5PFNN1mBREPWGdk1RXg5aVH9rPErLfBFEi2Emb",
61        name: "JupiterDcaKeeper1",
62        tags: &["route"],
63    };
64    pub const JUPITER_DCA_KEEPER2: DexProgram = DexProgram {
65        id: "DCAKuApAuZtVNYLk3KTAVW9GLWVvPbnb5CxxRRmVgcTr",
66        name: "JupiterDcaKeeper2",
67        tags: &["route"],
68    };
69    pub const JUPITER_DCA_KEEPER3: DexProgram = DexProgram {
70        id: "DCAK36VfExkPdAkYUQg6ewgxyinvcEyPLyHjRbmveKFw",
71        name: "JupiterDcaKeeper3",
72        tags: &["route"],
73    };
74    pub const JUPITER_LIMIT_ORDER: DexProgram = DexProgram {
75        id: "jupoNjAxXgZ4rjzxzPMP4oxduvQsQtZzyknqvzYNrNu",
76        name: "JupiterLimit",
77        tags: &["route"],
78    };
79    pub const JUPITER_LIMIT_ORDER_V2: DexProgram = DexProgram {
80        id: "j1o2qRpjcyUwEvwtcfhEQefh773ZgjxcVRry7LDqg5X",
81        name: "JupiterLimitV2",
82        tags: &["route"],
83    };
84    pub const JUPITER_VA: DexProgram = DexProgram {
85        id: "VALaaymxQh2mNy2trH9jUqHT1mTow76wpTcGmSWSwJe",
86        name: "JupiterVA",
87        tags: &["route"],
88    };
89    pub const RAYDIUM_ROUTE: DexProgram = DexProgram {
90        id: "routeUGWgWzqBWFcrCfv8tritsqukccJPu3q5GPP3xS",
91        name: "RaydiumRoute",
92        tags: &["route"],
93    };
94    pub const RAYDIUM_V4: DexProgram = DexProgram {
95        id: "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8",
96        name: "RaydiumV4",
97        tags: &["amm"],
98    };
99    pub const RAYDIUM_AMM: DexProgram = DexProgram {
100        id: "5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h",
101        name: "RaydiumAMM",
102        tags: &["amm"],
103    };
104    pub const RAYDIUM_CPMM: DexProgram = DexProgram {
105        id: "CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C",
106        name: "RaydiumCPMM",
107        tags: &["amm"],
108    };
109    pub const RAYDIUM_CL: DexProgram = DexProgram {
110        id: "CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK",
111        name: "RaydiumCL",
112        tags: &["amm"],
113    };
114    pub const RAYDIUM_LCP: DexProgram = DexProgram {
115        id: "LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj",
116        name: "RaydiumLaunchpad",
117        tags: &["amm"],
118    };
119    pub const ORCA: DexProgram = DexProgram {
120        id: "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc",
121        name: "Orca",
122        tags: &["amm"],
123    };
124    pub const METEORA: DexProgram = DexProgram {
125        id: "LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo",
126        name: "MeteoraDLMM",
127        tags: &["amm"],
128    };
129    pub const METEORA_DAMM: DexProgram = DexProgram {
130        id: "Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB",
131        name: "MeteoraDamm",
132        tags: &["amm"],
133    };
134    pub const METEORA_DAMM_V2: DexProgram = DexProgram {
135        id: "cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG",
136        name: "MeteoraDammV2",
137        tags: &["amm"],
138    };
139    pub const METEORA_DBC: DexProgram = DexProgram {
140        id: "dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN",
141        name: "MeteoraDBC",
142        tags: &["amm"],
143    };
144    pub const PUMP_FUN: DexProgram = DexProgram {
145        id: "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P",
146        name: "Pumpfun",
147        tags: &["amm"],
148    };
149    pub const PUMP_SWAP: DexProgram = DexProgram {
150        id: "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA",
151        name: "Pumpswap",
152        tags: &["amm"],
153    };
154    pub const MOONIT: DexProgram = DexProgram {
155        id: "MoonCVVNZFSYkqNXP6bxHLPL6QQJiMagDL3qcqUQTrG",
156        name: "Moonit",
157        tags: &["amm"],
158    };
159    pub const BOOP_FUN: DexProgram = DexProgram {
160        id: "boop8hVGQGqehUK2iVEMEnMrL5RbjywRzHKBmBE7ry4",
161        name: "Boopfun",
162        tags: &["amm"],
163    };
164    pub const SUGAR: DexProgram = DexProgram {
165        id: "deus4Bvftd5QKcEkE5muQaWGWDoma8GrySvPFrBPjhS",
166        name: "Sugar",
167        tags: &["amm"],
168    };
169    pub const HEAVEN: DexProgram = DexProgram {
170        id: "HEAVENoP2qxoeuF8Dj2oT1GHEnu49U5mJYkdeC8BAX2o",
171        name: "Heaven",
172        tags: &["amm"],
173    };
174}
175
176pub fn get_program_name(program_id: &str) -> &'static str {
177    let all: &[(&DexProgram, &str)] = &[
178        (&dex_programs::JUPITER, dex_programs::JUPITER.name),
179        (&dex_programs::JUPITER_DCA, dex_programs::JUPITER_DCA.name),
180        (&dex_programs::JUPITER_VA, dex_programs::JUPITER_VA.name),
181        (&dex_programs::JUPITER_LIMIT_ORDER_V2, dex_programs::JUPITER_LIMIT_ORDER_V2.name),
182        (&dex_programs::RAYDIUM_ROUTE, dex_programs::RAYDIUM_ROUTE.name),
183        (&dex_programs::RAYDIUM_V4, dex_programs::RAYDIUM_V4.name),
184        (&dex_programs::RAYDIUM_AMM, dex_programs::RAYDIUM_AMM.name),
185        (&dex_programs::RAYDIUM_CPMM, dex_programs::RAYDIUM_CPMM.name),
186        (&dex_programs::RAYDIUM_CL, dex_programs::RAYDIUM_CL.name),
187        (&dex_programs::RAYDIUM_LCP, dex_programs::RAYDIUM_LCP.name),
188        (&dex_programs::ORCA, dex_programs::ORCA.name),
189        (&dex_programs::METEORA, dex_programs::METEORA.name),
190        (&dex_programs::METEORA_DAMM, dex_programs::METEORA_DAMM.name),
191        (&dex_programs::METEORA_DAMM_V2, dex_programs::METEORA_DAMM_V2.name),
192        (&dex_programs::METEORA_DBC, dex_programs::METEORA_DBC.name),
193        (&dex_programs::PUMP_FUN, dex_programs::PUMP_FUN.name),
194        (&dex_programs::PUMP_SWAP, dex_programs::PUMP_SWAP.name),
195        (&dex_programs::MOONIT, dex_programs::MOONIT.name),
196        (&dex_programs::BOOP_FUN, dex_programs::BOOP_FUN.name),
197        (&dex_programs::SUGAR, dex_programs::SUGAR.name),
198        (&dex_programs::HEAVEN, dex_programs::HEAVEN.name),
199    ];
200    for (prog, name) in all {
201        if prog.id == program_id {
202            return name;
203        }
204    }
205    "Unknown"
206}
207
208pub const SYSTEM_PROGRAMS: &[&str] = &[
209    "ComputeBudget111111111111111111111111111111",
210    "11111111111111111111111111111111",
211    TOKEN_PROGRAM_ID,
212    TOKEN_2022_PROGRAM_ID,
213    ASSOCIATED_TOKEN_PROGRAM_ID,
214    "srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX",
215];
216
217pub const SKIP_PROGRAM_IDS: &[&str] = &[
218    "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ",
219];
220
221pub const FEE_ACCOUNTS: &[&str] = &[
222    "96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5",
223    "HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe",
224    "Cw8CFyM9FkoMi7K7Crf6HNQqf4uEMzpKw6QNghXLvLkY",
225    "ADaUMid9yfUytqMBgopwjb2DTLSokTSzL1zt6iGPaS49",
226    "DfXygSm4jCyNCybVYYK6DwvWqjKee8pbDmJGcLWNDXjh",
227    "ADuUkR4vqLUMWXxW9gh6D6L8pMSawimctcNZ5pGwDcEt",
228    "DttWaMuVvTiduZRnguLF7jNxTgiMBZ1hyAumKUiL2KRL",
229    "3AVi9Tg9Uo68tJfuvoKvqKNWKkC5wPdSSdeBnizKZ6jT",
230    "45ruCyfdRkWpRNGEqWzjCiXRHkZs8WXCLQ67Pnpye7Hp",
231    "39azUYFWPz3VHgKCf3VChUwbpURdCHRxjWVowf5jUJjg",
232    "FWsW1xNtWscwNmKv6wVsU1iTzRN6wmmk3MjxRP5tT7hz",
233    "G5UZAVbAf46s7cKWoyKu8kYTip9DGTpbLZ2qa9Aq69dP",
234    "7hTckgnGnLQR6sdH7YkqFTAA7VwTfYFaZ6EhEsU3saCX",
235    "9rPYyANsfQZw3DnDmKE3YCQF5E8oD89UXoHn9JFEhJUz",
236    "7VtfL8fvgNfhz17qKRMjzQEXgbdpnHHHQRh54R9jP2RJ",
237    "AVmoTthdrX6tKt4nDjco2D775W2YK3sDhxPcMmzUAmTY",
238    "62qc2CNXwrYqQScmEdiZFFAnJR262PxWEuNQtxfafNgV",
239    "JCRGumoE9Qi5BBgULTgdgTLjSgkCMSbF62ZZfGs84JeU",
240    "CebN5WGQ4jvEPvsVU4EoHEpgzq1VV7AbicfhtW4xC9iM",
241    "AVUCZyuT35YSuj4RH7fwiyPu82Djn2Hfg7y2ND2XcnZH",
242    "BUX7s2ef2htTGb2KKoPHWkmzxPj4nTWMWRgs5CSbQxf9",
243    "CdQTNULjDiTsvyR5UKjYBMqWvYpxXj6HY4m6atm2hErk",
244];
245
246// SPL Token instruction discriminators (first byte)
247pub mod spl_token_instruction {
248    pub const INITIALIZE_MINT: u8 = 0;
249    pub const INITIALIZE_ACCOUNT: u8 = 1;
250    pub const TRANSFER: u8 = 3;
251    pub const MINT_TO: u8 = 7;
252    pub const BURN: u8 = 8;
253    pub const TRANSFER_CHECKED: u8 = 12;
254    pub const MINT_TO_CHECKED: u8 = 14;
255    pub const BURN_CHECKED: u8 = 15;
256    pub const CLOSE_ACCOUNT: u8 = 9;
257}
258
259pub mod system_instruction {
260    pub const TRANSFER: u8 = 2;
261}
262
263// Discriminators (first N bytes of instruction data)
264pub mod discriminators {
265    // Jupiter route event (16 bytes)
266    pub const JUPITER_ROUTE_EVENT: [u8; 16] = [
267        228, 69, 165, 46, 81, 203, 154, 29, 64, 198, 205, 232, 38, 8, 113, 226,
268    ];
269    // Pumpfun
270    pub const PUMPFUN_CREATE: [u8; 8] = [24, 30, 200, 40, 5, 28, 7, 119];
271    pub const PUMPFUN_BUY: [u8; 8] = [102, 6, 61, 18, 1, 218, 235, 234];
272    pub const PUMPFUN_SELL: [u8; 8] = [51, 230, 133, 164, 1, 127, 131, 173];
273    // Pumpswap
274    pub const PUMPSWAP_BUY: [u8; 8] = [102, 6, 61, 18, 1, 218, 235, 234];
275    pub const PUMPSWAP_SELL: [u8; 8] = [51, 230, 133, 164, 1, 127, 131, 173];
276    // Raydium CPMM
277    pub const RAYDIUM_CPMM_CREATE: [u8; 8] = [175, 175, 109, 31, 13, 152, 155, 237];
278    pub const RAYDIUM_CPMM_ADD_LIQUIDITY: [u8; 8] = [242, 35, 198, 137, 82, 225, 242, 182];
279    pub const RAYDIUM_CPMM_REMOVE_LIQUIDITY: [u8; 8] = [183, 18, 70, 156, 148, 109, 161, 34];
280    // Meteora DLMM add liquidity
281    pub const METEORA_DLMM_ADD_LIQUIDITY: [u8; 8] = [181, 157, 89, 67, 143, 182, 52, 72];
282    pub const METEORA_DLMM_REMOVE_LIQUIDITY: [u8; 8] = [80, 85, 209, 72, 24, 206, 177, 108];
283    // Orca
284    pub const ORCA_CREATE: [u8; 8] = [242, 29, 134, 48, 58, 110, 14, 60];
285    pub const ORCA_CREATE2: [u8; 8] = [212, 47, 95, 92, 114, 102, 131, 250];
286    pub const ORCA_INCREASE_LIQUIDITY: [u8; 8] = [46, 156, 243, 118, 13, 205, 251, 178];
287    pub const ORCA_INCREASE_LIQUIDITY2: [u8; 8] = [133, 29, 89, 223, 69, 238, 176, 10];
288    pub const ORCA_DECREASE_LIQUIDITY: [u8; 8] = [160, 38, 208, 111, 104, 91, 44, 1];
289    // Raydium (1 byte)
290    pub const RAYDIUM_CREATE: [u8; 1] = [1];
291    pub const RAYDIUM_ADD_LIQUIDITY: [u8; 1] = [3];
292    pub const RAYDIUM_REMOVE_LIQUIDITY: [u8; 1] = [4];
293    // Meteora DAMM
294    pub const METEORA_DAMM_CREATE: [u8; 8] = [7, 166, 138, 171, 206, 171, 236, 244];
295    pub const METEORA_DAMM_ADD: [u8; 8] = [168, 227, 50, 62, 189, 171, 84, 176];
296    pub const METEORA_DAMM_REMOVE: [u8; 8] = [133, 109, 44, 179, 56, 238, 114, 33];
297    // Meteora DAMM V2
298    pub const METEORA_DAMM_V2_INIT: [u8; 8] = [95, 180, 10, 172, 84, 174, 232, 40];
299    pub const METEORA_DAMM_V2_ADD: [u8; 8] = [181, 157, 89, 67, 143, 182, 52, 72];
300    pub const METEORA_DAMM_V2_REMOVE: [u8; 8] = [80, 85, 209, 72, 24, 206, 177, 108];
301    // Pumpfun / Pumpswap 16-byte event discriminators
302    pub const PUMPFUN_TRADE_EVENT: [u8; 16] = [
303        228, 69, 165, 46, 81, 203, 154, 29, 189, 219, 127, 211, 78, 230, 97, 238,
304    ];
305    pub const PUMPFUN_CREATE_EVENT: [u8; 16] = [
306        228, 69, 165, 46, 81, 203, 154, 29, 27, 114, 169, 77, 222, 235, 99, 118,
307    ];
308    pub const PUMPSWAP_BUY_EVENT: [u8; 16] = [
309        228, 69, 165, 46, 81, 203, 154, 29, 103, 244, 82, 31, 44, 245, 119, 119,
310    ];
311    pub const PUMPSWAP_SELL_EVENT: [u8; 16] = [
312        228, 69, 165, 46, 81, 203, 154, 29, 62, 47, 55, 10, 165, 3, 220, 42,
313    ];
314}