Skip to main content

solana_tool/
lib.rs

1/// reader associated with byte arrays module
2pub mod reader {
3    use solana_sdk::pubkey::Pubkey;
4    pub fn r_u8(data: &[u8], offset: usize) -> u8 {
5        if data.len() <= offset {
6            return 0;
7        }
8        data[offset]
9    }
10    pub fn r_u16(data: &[u8], offset: usize) -> u16 {
11        if data.len() < offset + 2 {
12            return 0;
13        }
14        u16::from_le_bytes(data[offset..offset + 2].try_into().unwrap())
15    }
16    pub fn r_u32(data: &[u8], offset: usize) -> u32 {
17        if data.len() < offset + 4 {
18            return 0;
19        }
20        u32::from_le_bytes(data[offset..offset + 4].try_into().unwrap())
21    }
22    pub fn r_u64(data: &[u8], offset: usize) -> u64 {
23        if data.len() < offset + 8 {
24            return 0;
25        }
26        u64::from_le_bytes(data[offset..offset + 8].try_into().unwrap())
27    }
28    pub fn r_u128(data: &[u8], offset: usize) -> u128 {
29        if data.len() < offset + 16 {
30            return 0;
31        }
32        u128::from_le_bytes(data[offset..offset + 16].try_into().unwrap())
33    }
34    pub fn r_pubkey(data: &[u8], offset: usize) -> Pubkey {
35        if data.len() < offset + 32 {
36            return Pubkey::default();
37        }
38        Pubkey::new_from_array(data[offset..offset + 32].try_into().unwrap())
39    }
40    pub fn r_string(data: &[u8], offset: usize) -> String {
41        if data.len() <= offset {
42            return String::new();
43        }
44
45        let len = data[offset] as usize;
46        if data.len() < offset + 1 + len {
47            return String::new();
48        }
49
50        String::from_utf8_lossy(&data[offset + 1..offset + 1 + len]).to_string()
51    }
52    pub fn r_bool(data: &[u8], offset: usize) -> bool {
53        r_u8(data, offset) != 0
54    }
55}
56
57/// account data analysis tools module
58pub mod account {
59    use std::sync::Arc;
60
61    use solana_client::nonblocking::rpc_client::RpcClient;
62    use solana_sdk::pubkey::Pubkey;
63    /// parse spl account info
64    pub fn parse_spl_account_info(data: &[u8]) -> Result<(Pubkey, Pubkey, f64), String> {
65        if data.len() < 72 {
66            return Err("account data length error".to_string());
67        }
68        // mint
69        let mint_address = Pubkey::new_from_array(data[..32].try_into().unwrap());
70        // owner
71        let owner_address = Pubkey::new_from_array(data[32..64].try_into().unwrap());
72        // amount
73        let amount = u64::from_le_bytes(data[64..72].try_into().unwrap());
74        Ok((mint_address, owner_address, amount as f64))
75    }
76    /// get spl token balance
77    /// # address
78    /// spl token address
79    pub async fn get_spl_token_balance(
80        client: Arc<RpcClient>,
81        address: Pubkey,
82    ) -> Result<f64, String> {
83        match client.get_account_data(&address).await {
84            Ok(data) => {
85                if data.len() < 72 {
86                    return Err("Account data too short".to_string());
87                }
88                match parse_spl_account_info(&data) {
89                    Ok(account) => return Ok(account.2),
90                    Err(e) => return Err(e),
91                }
92            }
93            Err(e) => return Err(format!("{:?}", e)),
94        }
95    }
96}
97
98/// unit processing module
99pub mod unit {
100    /// conver balance
101    pub fn conver_balance(balance: f64, decimal: u8) -> f64 {
102        balance as f64 / 10f64.powi(decimal as i32)
103    }
104}