use solana_pubkey::{pubkey, Pubkey};
mod macros;
pub type PythFeedId = [u8; 32];
pub const TOKEN_PROGRAM_ID: Pubkey = pubkey!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
pub const TOKEN_2022_PROGRAM_ID: Pubkey = pubkey!("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb");
pub const PYRA_PROGRAM_ID: Pubkey = pubkey!("6JjHXLheGSNvvexgzMthEcgjkcirDrGduc3HAKB2P1v2");
pub const USDC: Token = SUPPORTED_TOKENS[0];
pub const WSOL: Token = SUPPORTED_TOKENS[1];
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Token {
pub asset_id: u16,
pub name: &'static str,
pub mint: Pubkey,
pub token_program: Pubkey,
pub decimals: u8,
pub pyth_price_feed: PythFeedId,
pub is_usd_stablecoin: bool,
pub drift_market_index: Option<u16>,
pub kamino_reserve: Option<Pubkey>,
}
impl Token {
pub fn find_by_asset_id(asset_id: u16) -> Option<&'static Self> {
SUPPORTED_TOKENS
.iter()
.find(|token| token.asset_id == asset_id)
}
pub fn find_by_mint(mint: &Pubkey) -> Option<&'static Self> {
SUPPORTED_TOKENS.iter().find(|token| token.mint == *mint)
}
pub fn find_by_drift_market_index(drift_market_index: u16) -> Option<&'static Self> {
SUPPORTED_TOKENS_DRIFT
.iter()
.find(|token| token.drift_market_index == Some(drift_market_index))
}
pub fn find_by_kamino_reserve(reserve: &Pubkey) -> Option<&'static Self> {
SUPPORTED_TOKENS_KAMINO
.iter()
.find(|token| token.kamino_reserve == Some(*reserve))
}
}
pub const SUPPORTED_TOKENS: [Token; 15] = [
Token {
asset_id: 0,
name: "USDC",
mint: pubkey!("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"),
token_program: TOKEN_PROGRAM_ID,
decimals: 6,
pyth_price_feed: feed_id!(
"0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a"
),
is_usd_stablecoin: true,
drift_market_index: Some(0),
kamino_reserve: Some(pubkey!("97zoywd8mPZsGTg8q1wdD2Wgkdrs2tqusp1Qqcxbyj7E")),
},
Token {
asset_id: 1,
name: "wSOL",
mint: pubkey!("So11111111111111111111111111111111111111112"),
token_program: TOKEN_PROGRAM_ID,
decimals: 9,
pyth_price_feed: feed_id!(
"0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d"
),
is_usd_stablecoin: false,
drift_market_index: Some(1),
kamino_reserve: None,
},
Token {
asset_id: 2,
name: "JitoSOL",
mint: pubkey!("J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn"),
token_program: TOKEN_PROGRAM_ID,
decimals: 9,
pyth_price_feed: feed_id!(
"0x67be9f519b95cf24338801051f9a808eff0a578ccb388db73b7f6fe1de019ffb"
),
is_usd_stablecoin: false,
drift_market_index: Some(6),
kamino_reserve: None,
},
Token {
asset_id: 3,
name: "cbBTC",
mint: pubkey!("cbbtcf3aa214zXHbiAZQwf4122FBYbraNdFqgw4iMij"),
token_program: TOKEN_PROGRAM_ID,
decimals: 8,
pyth_price_feed: feed_id!(
"0x2817d7bfe5c64b8ea956e9a26f573ef64e72e4d7891f2d6af9bcc93f7aff9a97"
),
is_usd_stablecoin: false,
drift_market_index: Some(27),
kamino_reserve: None,
},
Token {
asset_id: 4,
name: "wETH",
mint: pubkey!("7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs"),
token_program: TOKEN_PROGRAM_ID,
decimals: 8,
pyth_price_feed: feed_id!(
"0x9d4294bbcd1174d6f2003ec365831e64cc31d9f6f15a2b85399db8d5000960f6"
),
is_usd_stablecoin: false,
drift_market_index: Some(4),
kamino_reserve: None,
},
Token {
asset_id: 5,
name: "USDT",
mint: pubkey!("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"),
token_program: TOKEN_PROGRAM_ID,
decimals: 6,
pyth_price_feed: feed_id!(
"0x2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b"
),
is_usd_stablecoin: true,
drift_market_index: Some(5),
kamino_reserve: None,
},
Token {
asset_id: 6,
name: "PYUSD",
mint: pubkey!("2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo"),
token_program: TOKEN_2022_PROGRAM_ID,
decimals: 6,
pyth_price_feed: feed_id!(
"0xc1da1b73d7f01e7ddd54b3766cf7fcd644395ad14f70aa706ec5384c59e76692"
),
is_usd_stablecoin: true,
drift_market_index: Some(22),
kamino_reserve: None,
},
Token {
asset_id: 7,
name: "USDS",
mint: pubkey!("USDSwr9ApdHk5bvJKMjzff41FfuX8bSxdKcR81vTwcA"),
token_program: TOKEN_PROGRAM_ID,
decimals: 6,
pyth_price_feed: feed_id!(
"0x77f0971af11cc8bac224917275c1bf55f2319ed5c654a1ca955c82fa2d297ea1"
),
is_usd_stablecoin: true,
drift_market_index: Some(28),
kamino_reserve: None,
},
Token {
asset_id: 8,
name: "wBTC",
mint: pubkey!("3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh"),
token_program: TOKEN_PROGRAM_ID,
decimals: 8,
pyth_price_feed: feed_id!(
"0xc9d8b075a5c69303365ae23633d4e085199bf5c520a3b90fed1322a0342ffc33"
),
is_usd_stablecoin: false,
drift_market_index: Some(3),
kamino_reserve: None,
},
Token {
asset_id: 9,
name: "JLP",
mint: pubkey!("27G8MtK7VtTcCHkpASjSDdkWWYfoqT6ggEuKidVJidD4"),
token_program: TOKEN_PROGRAM_ID,
decimals: 6,
pyth_price_feed: feed_id!(
"0xc811abc82b4bad1f9bd711a2773ccaa935b03ecef974236942cec5e0eb845a3a"
),
is_usd_stablecoin: false,
drift_market_index: Some(19),
kamino_reserve: None,
},
Token {
asset_id: 10,
name: "bSOL",
mint: pubkey!("bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1"),
token_program: TOKEN_PROGRAM_ID,
decimals: 9,
pyth_price_feed: feed_id!(
"0x89875379e70f8fbadc17aef315adf3a8d5d160b811435537e03c97e8aac97d9c"
),
is_usd_stablecoin: false,
drift_market_index: Some(8),
kamino_reserve: None,
},
Token {
asset_id: 11,
name: "BONK",
mint: pubkey!("DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"),
token_program: TOKEN_PROGRAM_ID,
decimals: 5,
pyth_price_feed: feed_id!(
"0x72b021217ca3fe68922a19aaf990109cb9d84e9ad004b4d2025ad6f529314419"
),
is_usd_stablecoin: false,
drift_market_index: Some(32),
kamino_reserve: None,
},
Token {
asset_id: 12,
name: "JUP",
mint: pubkey!("JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN"),
token_program: TOKEN_PROGRAM_ID,
decimals: 6,
pyth_price_feed: feed_id!(
"0x0a0408d619e9380abad35060f9192039ed5042fa6f82301d0e48bb52be830996"
),
is_usd_stablecoin: false,
drift_market_index: Some(11),
kamino_reserve: None,
},
Token {
asset_id: 13,
name: "zBTC",
mint: pubkey!("zBTCug3er3tLyffELcvDNrKkCymbPWysGcWihESYfLg"),
token_program: TOKEN_PROGRAM_ID,
decimals: 8,
pyth_price_feed: feed_id!(
"0x3d824c7f7c26ed1c85421ecec8c754e6b52d66a4e45de20a9c9ea91de8b396f9"
),
is_usd_stablecoin: false,
drift_market_index: Some(45),
kamino_reserve: None,
},
Token {
asset_id: 14,
name: "syrupUSDC",
mint: pubkey!("AvZZF1YaZDziPY2RCK4oJrRVrbN3mTD9NL24hPeaZeUj"),
token_program: TOKEN_PROGRAM_ID,
decimals: 6,
pyth_price_feed: feed_id!(
"0x2ad31d1c4a85fbf2156ce57fab4104124c5ef76a6386375ecfc8da1ed5ce1486"
),
is_usd_stablecoin: false,
drift_market_index: Some(57),
kamino_reserve: None,
},
];
filter_supported_tokens!(pub SUPPORTED_TOKENS_DRIFT, drift_market_index);
filter_supported_tokens!(pub SUPPORTED_TOKENS_KAMINO, kamino_reserve);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn asset_id_matches_array_position() {
for (i, token) in SUPPORTED_TOKENS.iter().enumerate() {
assert_eq!(
token.asset_id,
i as u16,
"SUPPORTED_TOKENS[{i}] has asset_id {} — must match array position",
token.asset_id,
);
}
}
}