onemoney_protocol/api/checkpoints.rs
1//! Checkpoint-related API operations.
2
3use crate::client::Client;
4use crate::client::config::api_path;
5use crate::client::config::endpoints::checkpoints::{BY_HASH, BY_NUMBER, NUMBER};
6use crate::{Checkpoint, CheckpointNumber, Result};
7
8impl Client {
9 /// Get a specific checkpoint by number.
10 ///
11 /// # Arguments
12 ///
13 /// * `number` - The checkpoint number
14 /// * `full` - Whether to include full transaction details
15 ///
16 /// # Returns
17 ///
18 /// The checkpoint information.
19 ///
20 /// # Example
21 ///
22 /// ```rust,no_run
23 /// use onemoney_protocol::Client;
24 ///
25 /// #[tokio::main]
26 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
27 /// let client = Client::mainnet()?;
28 ///
29 /// let checkpoint = client.get_checkpoint_by_number(456, false).await?;
30 /// println!("Checkpoint number: {}", checkpoint.number);
31 ///
32 /// Ok(())
33 /// }
34 /// ```
35 pub async fn get_checkpoint_by_number(&self, number: u64, full: bool) -> Result<Checkpoint> {
36 let path = api_path(&format!("{}?number={}&full={}", BY_NUMBER, number, full));
37 self.get(&path).await
38 }
39
40 /// Get a checkpoint by hash.
41 ///
42 /// # Arguments
43 ///
44 /// * `hash` - The checkpoint hash
45 /// * `full` - Whether to include full transaction details
46 ///
47 /// # Returns
48 ///
49 /// The checkpoint information.
50 ///
51 /// # Example
52 ///
53 /// ```rust,no_run
54 /// use onemoney_protocol::Client;
55 ///
56 /// #[tokio::main]
57 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
58 /// let client = Client::mainnet()?;
59 ///
60 /// let hash = "0x902006665c369834a0cf52eea2780f934a90b3c86a3918fb57371ac1fbbd7777";
61 /// let checkpoint = client.get_checkpoint_by_hash(hash, false).await?;
62 /// println!("Checkpoint number: {}", checkpoint.number);
63 ///
64 /// Ok(())
65 /// }
66 /// ```
67 pub async fn get_checkpoint_by_hash(&self, hash: &str, full: bool) -> Result<Checkpoint> {
68 let path = api_path(&format!("{}?hash={}&full={}", BY_HASH, hash, full));
69 self.get(&path).await
70 }
71
72 /// Get the latest checkpoint number.
73 ///
74 /// # Returns
75 ///
76 /// The latest checkpoint number.
77 ///
78 /// # Example
79 ///
80 /// ```rust,no_run
81 /// use onemoney_protocol::Client;
82 ///
83 /// #[tokio::main]
84 /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
85 /// let client = Client::mainnet()?;
86 ///
87 /// let checkpoint_number = client.get_checkpoint_number().await?;
88 /// println!("Latest checkpoint number: {}", checkpoint_number.number);
89 ///
90 /// Ok(())
91 /// }
92 /// ```
93 pub async fn get_checkpoint_number(&self) -> Result<CheckpointNumber> {
94 self.get(&api_path(NUMBER)).await
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101 use crate::CheckpointTransactions;
102 use crate::types::responses::transactions::Hash;
103 use alloy_primitives::B256;
104 use std::str::FromStr;
105
106 #[test]
107 fn test_checkpoint_structure() {
108 // Test that Checkpoint can be serialized/deserialized
109 let checkpoint = Checkpoint {
110 hash: Hash {
111 hash: B256::from_str(
112 "0x902006665c369834a0cf52eea2780f934a90b3c86a3918fb57371ac1fbbd7777",
113 )
114 .expect("Test data should be valid"),
115 },
116 parent_hash: Hash {
117 hash: B256::from_str(
118 "0x20e081da293ae3b81e30f864f38f6911663d7f2cf98337fca38db3cf5bbe7a8f",
119 )
120 .expect("Test data should be valid"),
121 },
122 state_root: Hash {
123 hash: B256::from_str(
124 "0x18b2b9746b15451d1f9bc414f1c12bda8249c63d4a46926e661ae74c69defd9a",
125 )
126 .expect("Test data should be valid"),
127 },
128 transactions_root: Hash {
129 hash: B256::from_str(
130 "0xa1e7ed47e548fa45c30232a7e7dfaad6495cff595a0ee1458aa470e574f3f6e4",
131 )
132 .expect("Test data should be valid"),
133 },
134 receipts_root: Hash {
135 hash: B256::from_str(
136 "0x59ff04f73d9f934800687c60fb80e2de6e8233817b46d144aec724b569d80c3b",
137 )
138 .expect("Test data should be valid"),
139 },
140 number: 1500,
141 timestamp: 1739760890,
142 extra_data: String::new(),
143 transactions: CheckpointTransactions::Hashes(vec![]),
144 size: Some(1024),
145 };
146
147 let json = serde_json::to_string(&checkpoint).expect("Test data should be valid");
148 let deserialized: Checkpoint =
149 serde_json::from_str(&json).expect("Test data should be valid");
150
151 assert_eq!(checkpoint.number, deserialized.number);
152 assert_eq!(checkpoint.hash, deserialized.hash);
153 assert_eq!(checkpoint.timestamp, deserialized.timestamp);
154 assert_eq!(checkpoint.size, deserialized.size);
155 }
156
157 #[test]
158 fn test_checkpoint_number() {
159 let checkpoint_number = CheckpointNumber { number: 50 };
160
161 let json = serde_json::to_string(&checkpoint_number).expect("Test data should be valid");
162 let deserialized: CheckpointNumber =
163 serde_json::from_str(&json).expect("Test data should be valid");
164
165 assert_eq!(checkpoint_number.number, deserialized.number);
166 }
167}