riptide_amm/gpa/
market.rs1use anyhow::Result;
2use solana_client::{
3 rpc_client::RpcClient,
4 rpc_filter::{Memcmp, RpcFilterType},
5};
6use solana_pubkey::Pubkey;
7
8use crate::{generated::shared::DecodedAccount, Market, MARKET_DISCRIMINATOR, RIPTIDE_ID};
9
10use crate::fetch_decoded_program_accounts;
11
12#[derive(Debug, Clone)]
13pub enum StrategyFilter {
14 Authority(Pubkey),
15 Updater(Pubkey),
16 MintA(Pubkey),
17 MintB(Pubkey),
18}
19
20impl From<StrategyFilter> for RpcFilterType {
21 fn from(val: StrategyFilter) -> Self {
22 match val {
23 StrategyFilter::Authority(address) => {
24 RpcFilterType::Memcmp(Memcmp::new_raw_bytes(8, address.to_bytes().to_vec()))
25 }
26 StrategyFilter::Updater(address) => {
27 RpcFilterType::Memcmp(Memcmp::new_raw_bytes(40, address.to_bytes().to_vec()))
28 }
29 StrategyFilter::MintA(address) => {
30 RpcFilterType::Memcmp(Memcmp::new_raw_bytes(72, address.to_bytes().to_vec()))
31 }
32 StrategyFilter::MintB(address) => {
33 RpcFilterType::Memcmp(Memcmp::new_raw_bytes(104, address.to_bytes().to_vec()))
34 }
35 }
36 }
37}
38
39pub fn fetch_all_strategy_with_filter(
40 rpc: &RpcClient,
41 filters: Vec<StrategyFilter>,
42) -> Result<Vec<DecodedAccount<Market>>> {
43 let mut filters: Vec<RpcFilterType> = filters.into_iter().map(|filter| filter.into()).collect();
44 filters.push(RpcFilterType::Memcmp(Memcmp::new_raw_bytes(
45 0,
46 vec![MARKET_DISCRIMINATOR as u8],
47 )));
48 fetch_decoded_program_accounts(rpc, filters, RIPTIDE_ID)
49}
50
51#[cfg(test)]
52mod tests {
53 use solana_pubkey::pubkey;
54
55 use crate::AccountDiscriminator;
56
57 use super::*;
58
59 #[test]
60 fn test_fetch_all_strategy_with_filter() {
61 let strategy = Market {
62 discriminator: AccountDiscriminator::Market,
63 authority: pubkey!("BGDWUVagGJHzF4XmT3iYMAkgjpaWq8YYAqkhwiJFnXqf"),
64 updater: pubkey!("5bAXtoqFDCC4H9gkiS8zPAwXfFo6g4qmCWhT8AeZmBnS"),
65 mint_a: pubkey!("8tGnYJSpzCNgKs4G4iNMPBfMGLEVsTu9ofapntcMgrrM"),
66 mint_b: pubkey!("6yuYbHEz9ybDnZAuXeC6yCxHETtUspSsHfkMnzdY5mqS"),
67 bump: [0; 1],
68 id: 0,
69 sequence: 0,
70 valid_until: 0,
71 oracle: [0; 512],
72 padding1: [0; 2],
73 padding2: [0; 360],
74 };
75 let strategy_data = borsh::to_vec(&strategy).unwrap();
76 let filters: Vec<RpcFilterType> = vec![
77 StrategyFilter::Authority(strategy.authority).into(),
78 StrategyFilter::MintA(strategy.mint_a).into(),
79 StrategyFilter::MintB(strategy.mint_b).into(),
80 ];
81 for filter in filters {
82 match filter {
83 RpcFilterType::Memcmp(memcmp) => {
84 let offset = memcmp.offset();
85 let actual = memcmp.bytes().unwrap().to_vec();
86 let expected = strategy_data[offset..offset + actual.len()].to_vec();
87 assert_eq!(actual, expected);
88 }
89 _ => panic!("Unexpected filter type"),
90 }
91 }
92 }
93}