1use solana_program::program_error::ProgramError;
2use solana_program::pubkey;
3use solana_program::pubkey::Pubkey;
4
5#[derive(Debug, Clone, Copy)]
6pub enum SupportedToken {
7 USDC,
8 USDT,
9 Sol,
10 Fida,
11 MSol,
12 Bonk,
13 BAT,
14 Pyth,
15 BSol,
16 Inj,
17 Trump,
18}
19
20const USDC_MINT: Pubkey = pubkey!("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
21const USDT_MINT: Pubkey = pubkey!("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB");
22const SOL_MINT: Pubkey = pubkey!("So11111111111111111111111111111111111111112");
23const FIDA_MINT: Pubkey = pubkey!("EchesyfXePKdLtoiZSL8pBe8Myagyy8ZRqsACNCFGnvp");
24const MSOL_MINT: Pubkey = pubkey!("mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So");
25const BONK_MINT: Pubkey = pubkey!("DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263");
26const BAT_MINT: Pubkey = pubkey!("EPeUFDgHRxs9xxEPVaL6kfGQvCon7jmAWKVUHuux1Tpz");
27const PYTH_MINT: Pubkey = pubkey!("HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3");
28const BSOL_MINT: Pubkey = pubkey!("bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1");
29const INJ_MINT: Pubkey = pubkey!("6McPRfPV6bY1e9hLxWyG54W9i9Epq75QBvXg2oetBVTB");
30const TRUMP_MINT: Pubkey = pubkey!("6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN");
31
32impl SupportedToken {
33 pub const fn mint(self) -> Pubkey {
34 match self {
35 SupportedToken::USDC => USDC_MINT,
36 SupportedToken::USDT => USDT_MINT,
37 SupportedToken::Sol => SOL_MINT,
38 SupportedToken::Fida => FIDA_MINT,
39 SupportedToken::MSol => MSOL_MINT,
40 SupportedToken::Bonk => BONK_MINT,
41 SupportedToken::BAT => BAT_MINT,
42 SupportedToken::Pyth => PYTH_MINT,
43 SupportedToken::BSol => BSOL_MINT,
44 SupportedToken::Inj => INJ_MINT,
45 SupportedToken::Trump => TRUMP_MINT,
46 }
47 }
48
49 pub const fn from_mint(mint: &Pubkey) -> Result<Self, ProgramError> {
50 Ok(match *mint {
51 USDC_MINT => SupportedToken::USDC,
52 USDT_MINT => SupportedToken::USDT,
53 SOL_MINT => SupportedToken::Sol,
54 FIDA_MINT => SupportedToken::Fida,
55 MSOL_MINT => SupportedToken::MSol,
56 BONK_MINT => SupportedToken::Bonk,
57 BAT_MINT => SupportedToken::BAT,
58 PYTH_MINT => SupportedToken::Pyth,
59 BSOL_MINT => SupportedToken::BSol,
60 INJ_MINT => SupportedToken::Inj,
61 TRUMP_MINT => SupportedToken::Trump,
62 _ => return Err(ProgramError::InvalidArgument),
63 })
64 }
65
66 pub const fn decimals(self) -> u8 {
67 match self {
68 SupportedToken::Sol | SupportedToken::MSol | SupportedToken::BSol => 9,
69 SupportedToken::Bonk => 5,
70 SupportedToken::BAT | SupportedToken::Inj => 8,
71 SupportedToken::USDC
72 | SupportedToken::USDT
73 | SupportedToken::Fida
74 | SupportedToken::Pyth
75 | SupportedToken::Trump => 6,
76 }
77 }
78
79 pub const fn price_feed_account_key(self) -> Pubkey {
80 match self {
81 SupportedToken::USDC => pubkey!("Dpw1EAVrSB1ibxiDQyTAW6Zip3J4Btk2x4SgApQCeFbX"),
82 SupportedToken::USDT => pubkey!("HT2PLQBcG5EiCcNSaMHAjSgd9F98ecpATbk4Sk5oYuM"),
83 SupportedToken::Sol => pubkey!("7UVimffxr9ow1uXYxsr4LHAcV58mLzhmwaeKvJ1pjLiE"),
84 SupportedToken::Fida => pubkey!("2cfmeuVBf7bvBJcjKBQgAwfvpUvdZV7K8NZxUEuccrub"),
85 SupportedToken::MSol => pubkey!("5CKzb9j4ChgLUt8Gfm5CNGLN6khXKiqMbnGAW4cgXgxK"),
86 SupportedToken::Bonk => pubkey!("DBE3N8uNjhKPRHfANdwGvCZghWXyLPdqdSbEW2XFwBiX"),
87 SupportedToken::BAT => pubkey!("EHH5mjVUsBUF7jD9nFcvB5TnG1fi6U54hRRphAxsVAWQ"),
88 SupportedToken::Pyth => pubkey!("8vjchtMuJNY4oFQdTi8yCe6mhCaNBFaUbktT482TpLPS"),
89 SupportedToken::BSol => pubkey!("5cN76Xm2Dtx9MnrQqBDeZZRsWruTTcw37UruznAdSvvE"),
90 SupportedToken::Inj => pubkey!("GwXYEfmPdgHcowF9GZwbb1WiTGTn1fuT3hbSLneoBKK6"),
91 SupportedToken::Trump => pubkey!("9vNb2tQoZ8bB4vzMbQLWViGwNaDJVtct13AGgno1wazp"),
92 }
93 }
94
95 pub const fn price_feed(self) -> [u8; 32] {
96 match self {
97 SupportedToken::USDC => [
98 234, 160, 32, 198, 28, 196, 121, 113, 40, 19, 70, 28, 225, 83, 137, 74, 150, 166,
99 192, 11, 33, 237, 12, 252, 39, 152, 209, 249, 169, 233, 201, 74,
100 ],
101 SupportedToken::USDT => [
102 43, 137, 185, 220, 143, 223, 159, 52, 112, 154, 91, 16, 107, 71, 47, 15, 57, 187,
103 108, 169, 206, 4, 176, 253, 127, 46, 151, 22, 136, 226, 229, 59,
104 ],
105 SupportedToken::Sol => [
106 239, 13, 139, 111, 218, 44, 235, 164, 29, 161, 93, 64, 149, 209, 218, 57, 42, 13,
107 47, 142, 208, 198, 199, 188, 15, 76, 250, 200, 194, 128, 181, 109,
108 ],
109 SupportedToken::Fida => [
110 200, 6, 87, 183, 246, 243, 234, 194, 114, 24, 208, 157, 90, 78, 84, 228, 123, 37,
111 118, 141, 159, 94, 16, 172, 21, 254, 44, 249, 0, 136, 20, 0,
112 ],
113 SupportedToken::MSol => [
114 194, 40, 154, 106, 67, 210, 206, 145, 198, 245, 92, 174, 195, 112, 244, 172, 195,
115 138, 46, 212, 119, 245, 136, 19, 51, 76, 109, 3, 116, 159, 242, 164,
116 ],
117 SupportedToken::Bonk => [
118 114, 176, 33, 33, 124, 163, 254, 104, 146, 42, 25, 170, 249, 144, 16, 156, 185,
119 216, 78, 154, 208, 4, 180, 210, 2, 90, 214, 245, 41, 49, 68, 25,
120 ],
121 SupportedToken::BAT => [
122 142, 134, 15, 183, 78, 96, 229, 115, 107, 69, 93, 130, 246, 11, 55, 40, 4, 156, 52,
123 142, 148, 150, 26, 221, 95, 150, 27, 2, 253, 238, 37, 53,
124 ],
125 SupportedToken::Pyth => [
126 11, 191, 40, 233, 168, 65, 161, 204, 120, 143, 106, 54, 27, 23, 202, 7, 45, 14,
127 163, 9, 138, 30, 93, 241, 195, 146, 45, 6, 113, 149, 121, 255,
128 ],
129 SupportedToken::BSol => [
130 137, 135, 83, 121, 231, 15, 143, 186, 220, 23, 174, 243, 21, 173, 243, 168, 213,
131 209, 96, 184, 17, 67, 85, 55, 224, 60, 151, 232, 170, 201, 125, 156,
132 ],
133 SupportedToken::Inj => [
134 122, 91, 193, 210, 181, 106, 208, 41, 4, 140, 214, 57, 100, 179, 173, 39, 118, 234,
135 223, 129, 46, 220, 26, 67, 163, 20, 6, 203, 84, 191, 245, 146,
136 ],
137 SupportedToken::Trump => [
138 135, 149, 81, 2, 24, 83, 238, 199, 167, 220, 130, 117, 120, 232, 230, 157, 167,
139 228, 250, 129, 72, 51, 154, 160, 211, 213, 41, 100, 5, 190, 75, 26,
140 ],
141 }
142 }
143}
144
145#[cfg(test)]
146mod test {
147 use crate::pyth::get_pyth_feed_account_key;
148 use crate::tokens::SupportedToken;
149
150 #[test]
151 fn test_price_feed_account_key() {
152 assert_eq!(
153 SupportedToken::USDC.price_feed_account_key(),
154 get_pyth_feed_account_key(0, &SupportedToken::USDC.price_feed())
155 );
156 assert_eq!(
157 SupportedToken::USDT.price_feed_account_key(),
158 get_pyth_feed_account_key(0, &SupportedToken::USDT.price_feed())
159 );
160 assert_eq!(
161 SupportedToken::Sol.price_feed_account_key(),
162 get_pyth_feed_account_key(0, &SupportedToken::Sol.price_feed())
163 );
164 assert_eq!(
165 SupportedToken::Fida.price_feed_account_key(),
166 get_pyth_feed_account_key(0, &SupportedToken::Fida.price_feed())
167 );
168 assert_eq!(
169 SupportedToken::MSol.price_feed_account_key(),
170 get_pyth_feed_account_key(0, &SupportedToken::MSol.price_feed())
171 );
172 assert_eq!(
173 SupportedToken::Bonk.price_feed_account_key(),
174 get_pyth_feed_account_key(0, &SupportedToken::Bonk.price_feed())
175 );
176 assert_eq!(
177 SupportedToken::BAT.price_feed_account_key(),
178 get_pyth_feed_account_key(0, &SupportedToken::BAT.price_feed())
179 );
180 assert_eq!(
181 SupportedToken::Pyth.price_feed_account_key(),
182 get_pyth_feed_account_key(0, &SupportedToken::Pyth.price_feed())
183 );
184 assert_eq!(
185 SupportedToken::BSol.price_feed_account_key(),
186 get_pyth_feed_account_key(0, &SupportedToken::BSol.price_feed())
187 );
188 assert_eq!(
189 SupportedToken::Inj.price_feed_account_key(),
190 get_pyth_feed_account_key(0, &SupportedToken::Inj.price_feed())
191 );
192 assert_eq!(
193 SupportedToken::Trump.price_feed_account_key(),
194 get_pyth_feed_account_key(0, &SupportedToken::Trump.price_feed())
195 )
196 }
197
198 #[test]
199 fn test_feed_id() {
200 assert_eq!(
202 SupportedToken::USDC.price_feed(),
203 hex::decode("eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a")
204 .unwrap()
205 .as_slice()
206 );
207 assert_eq!(
208 SupportedToken::USDT.price_feed(),
209 hex::decode("2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b")
210 .unwrap()
211 .as_slice()
212 );
213 assert_eq!(
214 SupportedToken::Sol.price_feed(),
215 hex::decode("ef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d")
216 .unwrap()
217 .as_slice()
218 );
219 assert_eq!(
220 SupportedToken::Fida.price_feed(),
221 hex::decode("c80657b7f6f3eac27218d09d5a4e54e47b25768d9f5e10ac15fe2cf900881400")
222 .unwrap()
223 .as_slice()
224 );
225 assert_eq!(
226 SupportedToken::MSol.price_feed(),
227 hex::decode("c2289a6a43d2ce91c6f55caec370f4acc38a2ed477f58813334c6d03749ff2a4")
228 .unwrap()
229 .as_slice()
230 );
231 assert_eq!(
232 SupportedToken::Bonk.price_feed(),
233 hex::decode("72b021217ca3fe68922a19aaf990109cb9d84e9ad004b4d2025ad6f529314419")
234 .unwrap()
235 .as_slice()
236 );
237 assert_eq!(
238 SupportedToken::BAT.price_feed(),
239 hex::decode("8e860fb74e60e5736b455d82f60b3728049c348e94961add5f961b02fdee2535")
240 .unwrap()
241 .as_slice()
242 );
243 assert_eq!(
244 SupportedToken::Pyth.price_feed(),
245 hex::decode("0bbf28e9a841a1cc788f6a361b17ca072d0ea3098a1e5df1c3922d06719579ff")
246 .unwrap()
247 .as_slice()
248 );
249 assert_eq!(
250 SupportedToken::BSol.price_feed(),
251 hex::decode("89875379e70f8fbadc17aef315adf3a8d5d160b811435537e03c97e8aac97d9c")
252 .unwrap()
253 .as_slice()
254 );
255 assert_eq!(
256 SupportedToken::Inj.price_feed(),
257 hex::decode("7a5bc1d2b56ad029048cd63964b3ad2776eadf812edc1a43a31406cb54bff592")
258 .unwrap()
259 .as_slice()
260 );
261 assert_eq!(
262 SupportedToken::Trump.price_feed(),
263 hex::decode("879551021853eec7a7dc827578e8e69da7e4fa8148339aa0d3d5296405be4b1a")
264 .unwrap()
265 .as_slice()
266 );
267 }
268}