poseidon_client/rpc_client/
tx.rs

1use crate::{
2    Base58BlockHash, Base58PublicKey, MessageHeader, PoseidonError, PoseidonResult, RpcClient,
3    Transaction, TransactionError, UnixTimestamp,
4};
5use borsh::{BorshDeserialize, BorshSerialize};
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, BorshSerialize, BorshDeserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct GetTransaction {
11    pub jsonrpc: String,
12    pub id: u8,
13    pub result: Option<RpcResult>,
14}
15
16impl GetTransaction {
17    pub async fn process(transaction: &str) -> PoseidonResult<GetTransaction> {
18        use json::JsonValue;
19
20        let body: json::JsonValue = json::object! {
21            jsonrpc: "2.0",
22            id: 1u8,
23            method: "getTransaction",
24            params: json::array![JsonValue::String(transaction.to_owned()), JsonValue::String("base58".to_owned())]
25        };
26
27        Ok(GetTransaction::request(body).await?)
28    }
29
30    pub fn transaction(&self) -> PoseidonResult<Transaction> {
31        match &self.result {
32            Some(rpc_result) => {
33                let encoded = &rpc_result.transaction.0;
34                let decoded = bs58::decode(encoded).into_vec()?;
35                let data = bincode::deserialize::<Transaction>(&decoded)?;
36
37                Ok(data)
38            }
39            None => Err(PoseidonError::TransactionNotFoundInCluster),
40        }
41    }
42
43    async fn request(body: json::JsonValue) -> PoseidonResult<GetTransaction> {
44        let mut rpc = RpcClient::new();
45        rpc.add_body(body);
46        let response = rpc.send().await?;
47        let deser_response: GetTransaction = serde_json::from_str(response.as_str()?)?;
48
49        Ok(deser_response)
50    }
51}
52
53#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, BorshSerialize, BorshDeserialize)]
54#[serde(rename_all = "camelCase")]
55pub struct RpcResult {
56    pub block_time: UnixTimestamp,
57    pub meta: RpcMeta,
58    pub transaction: (String, String),
59}
60
61#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, BorshSerialize, BorshDeserialize)]
62#[serde(rename_all = "camelCase")]
63pub struct RpcMeta {
64    pub err: Option<TransactionError>,
65    pub fee: u32,
66    pub inner_instructions: Vec<RpcInnerInstructions>,
67    pub log_messages: Vec<String>,
68    pub pre_balances: Vec<u64>,
69    pub post_balances: Vec<u64>,
70    pub pre_token_balances: Vec<TokenBalances>,
71    pub post_token_balances: Vec<TokenBalances>,
72    pub rewards: Vec<Reward>,
73    pub status: Result<(), TransactionError>,
74}
75
76#[derive(
77    Debug, PartialEq, PartialOrd, Clone, Deserialize, Serialize, BorshSerialize, BorshDeserialize,
78)]
79#[serde(rename_all = "camelCase")]
80pub struct RpcInnerInstructions {
81    pub index: u8,
82    pub instructions: Vec<RpcCompiledInstruction>,
83}
84
85#[derive(
86    Debug, PartialEq, PartialOrd, Clone, Deserialize, Serialize, BorshSerialize, BorshDeserialize,
87)]
88#[serde(rename_all = "camelCase")]
89pub struct TokenBalances {
90    pub account_index: u8,
91    pub mint: Base58PublicKey,
92    pub owner: Base58PublicKey,
93    pub ui_token_amount: TokenAmount,
94}
95
96#[derive(
97    Debug, PartialEq, PartialOrd, Clone, Deserialize, Serialize, BorshSerialize, BorshDeserialize,
98)]
99#[serde(rename_all = "camelCase")]
100pub struct TokenAmount {
101    pub amount: String,
102    pub decimals: u8,
103    pub ui_amount: f64,
104    pub ui_amount_string: String,
105}
106
107#[derive(
108    Debug, PartialEq, PartialOrd, Clone, Deserialize, Serialize, BorshSerialize, BorshDeserialize,
109)]
110#[serde(rename_all = "camelCase")]
111pub struct Reward {
112    pub pubkey: String,
113    pub lamports: i64,
114    pub post_balance: u64,
115    pub reward_type: RewardType,
116    pub commission: u8,
117}
118
119#[derive(
120    Debug, PartialEq, PartialOrd, Clone, Deserialize, Serialize, BorshSerialize, BorshDeserialize,
121)]
122#[serde(rename_all = "camelCase")]
123pub enum RewardType {
124    Fee,
125    Rent,
126    Staking,
127    Voting,
128}
129
130#[derive(
131    Debug, PartialEq, PartialOrd, Clone, Deserialize, Serialize, BorshSerialize, BorshDeserialize,
132)]
133#[serde(rename_all = "camelCase")]
134
135pub struct RpcCompiledInstruction {
136    pub program_id_index: u8,
137    pub accounts: Vec<u8>,
138    pub data: String,
139}
140
141#[derive(
142    Debug, PartialEq, PartialOrd, Clone, Deserialize, Serialize, BorshSerialize, BorshDeserialize,
143)]
144#[serde(rename_all = "camelCase")]
145pub struct RpcMessage {
146    pub header: MessageHeader,
147    pub account_keys: Vec<Base58PublicKey>,
148    pub recent_blockhash: Base58BlockHash,
149    pub instructions: Vec<RpcCompiledInstruction>,
150}
151
152#[derive(
153    Debug,
154    PartialEq,
155    Eq,
156    Ord,
157    PartialOrd,
158    Clone,
159    Deserialize,
160    Serialize,
161    BorshSerialize,
162    BorshDeserialize,
163)]
164#[serde(rename_all = "camelCase")]
165pub struct Context {
166    pub slot: u64,
167}