poseidon_client/rpc_client/
rpc_info.rs

1use crate::{
2    request, request_with_result, BorrowedBase58PublicKey, Commitment, PoseidonError,
3    PoseidonResult, PublicKey, RpcResponse, RpcResponseWithResult,
4};
5use borsh::{BorshDeserialize, BorshSerialize};
6use serde::{Deserialize, Serialize};
7
8pub const LAMPORT: u64 = 1_000_000_000;
9
10#[derive(Debug, Serialize, Deserialize, BorshDeserialize, BorshSerialize)]
11#[serde(rename_all = "camelCase")]
12pub struct GetLatestBlockhash {
13    pub blockhash: String,
14    pub last_valid_block_height: u64,
15}
16
17impl GetLatestBlockhash {
18    pub async fn process(
19        commitment: Commitment,
20    ) -> PoseidonResult<RpcResponseWithResult<GetLatestBlockhash>> {
21        let commitment: &str = commitment.into();
22        let body: json::JsonValue = json::object! {
23            jsonrpc: "2.0",
24            id: 1u8,
25            method: "getLatestBlockhash",
26            params: json::array![json::object!{
27                commitment: commitment,
28            }]
29        };
30
31        Ok(request_with_result::<GetLatestBlockhash>(body).await?)
32    }
33
34    pub fn get_hash(response: RpcResponseWithResult<GetLatestBlockhash>) -> GetLatestBlockhash {
35        response.result.value
36    }
37
38    pub async fn as_bytes(commitment: Commitment) -> PoseidonResult<[u8; 32]> {
39        let response = GetLatestBlockhash::process(commitment).await?;
40        let blockhash = GetLatestBlockhash::get_hash(response).blockhash;
41
42        let decoded = bs58::decode(&blockhash).into_vec()?;
43        match decoded.try_into() {
44            Ok(blockhash) => Ok(blockhash),
45            Err(_) => Err(PoseidonError::ErrorConvertingToU832),
46        }
47    }
48
49    pub fn to_bytes(&self) -> PoseidonResult<[u8; 32]> {
50        let decoded = bs58::decode(&self.blockhash).into_vec()?;
51        match decoded.try_into() {
52            Ok(blockhash) => Ok(blockhash),
53            Err(_) => Err(PoseidonError::ErrorConvertingToU832),
54        }
55    }
56}
57
58#[derive(Debug, Serialize, Deserialize, BorshDeserialize, BorshSerialize)]
59#[serde(rename_all = "camelCase")]
60pub struct GetFees {
61    pub blockhash: String,
62    pub fee_calculator: FeeCalculator,
63    pub last_valid_block_height: u64,
64    pub last_valid_slot: u64,
65}
66
67impl GetFees {
68    pub async fn process() -> PoseidonResult<RpcResponseWithResult<GetFees>> {
69        let body: json::JsonValue = json::object! {
70            jsonrpc: "2.0",
71            id: 1u8,
72            method: "getFees",
73        };
74
75        Ok(request_with_result::<GetFees>(body).await?)
76    }
77}
78
79#[derive(Debug, Serialize, Deserialize, BorshDeserialize, BorshSerialize)]
80#[serde(rename_all = "camelCase")]
81pub struct RequestAirdrop {
82    public_key: PublicKey,
83    lamports: u8,
84    commitment: Commitment,
85}
86
87impl RequestAirdrop {
88    pub fn new(public_key: PublicKey) -> Self {
89        RequestAirdrop {
90            public_key,
91            lamports: 2,
92            commitment: Commitment::Finalized,
93        }
94    }
95
96    pub fn add_lamports(&mut self, lamports: u8) -> &mut Self {
97        self.lamports = lamports;
98
99        self
100    }
101
102    pub fn change_commitment(&mut self, commitment: Commitment) -> &mut Self {
103        self.commitment = commitment;
104
105        self
106    }
107
108    pub async fn process(&self) -> PoseidonResult<RpcResponse<String>> {
109        let public_key = bs58::encode(&self.public_key).into_string();
110        let lamports = self.lamports as u64 * LAMPORT;
111
112        let body: json::JsonValue = json::object! {
113            jsonrpc: "2.0",
114            id: 1u8,
115            method: "requestAirdrop",
116            params: json::array![public_key, lamports]
117        };
118
119        Ok(request::<String>(body).await?)
120    }
121}
122
123#[derive(Debug, Serialize, Deserialize, BorshDeserialize, BorshSerialize)]
124#[serde(rename_all = "camelCase")]
125pub struct FeeCalculator {
126    pub lamports_per_signature: u64,
127}
128
129#[derive(Debug, Serialize, Deserialize, BorshDeserialize, BorshSerialize)]
130#[serde(rename_all = "camelCase")]
131pub struct GetMinimumBalanceForRentExemption;
132
133impl GetMinimumBalanceForRentExemption {
134    pub async fn process<T>() -> PoseidonResult<RpcResponse<u64>> {
135        let size = core::mem::size_of::<T>() as u64;
136
137        let body: json::JsonValue = json::object! {
138            jsonrpc: "2.0",
139            id: 1u8,
140            method: "getMinimumBalanceForRentExemption",
141            params: json::array![
142                size
143            ]
144        };
145
146        Ok(request::<u64>(body).await?)
147    }
148    pub async fn process_precalculated(size: usize) -> PoseidonResult<RpcResponse<u64>> {
149        let size = size as u64;
150
151        let body: json::JsonValue = json::object! {
152            jsonrpc: "2.0",
153            id: 1u8,
154            method: "getMinimumBalanceForRentExemption",
155            params: json::array![
156                size
157            ]
158        };
159
160        Ok(request::<u64>(body).await?)
161    }
162}
163
164#[derive(Debug, Serialize, Deserialize, BorshDeserialize, BorshSerialize)]
165#[serde(rename_all = "camelCase")]
166pub struct GetAccountInfo {
167    pub data: (String, String), // (PublicKey String, encoding)
168    pub executable: bool,
169    pub lamports: u64,
170    pub owner: String, // Base58 formatted PublicKey
171    pub rent_epoch: u64,
172}
173
174impl GetAccountInfo {
175    pub async fn process<'pn>(
176        public_key: BorrowedBase58PublicKey<'pn>,
177    ) -> PoseidonResult<RpcResponseWithResult<GetAccountInfo>> {
178        let body: json::JsonValue = json::object! {
179            jsonrpc: "2.0",
180            id: 1u8,
181            method: "getAccountInfo",
182            params: [
183                public_key,
184                {
185                    "encoding": "base58"
186                }
187            ]
188        };
189
190        Ok(request_with_result::<GetAccountInfo>(body).await?)
191    }
192}