From e62ce521424f633cdc5ca37b7776442e6dbde377 Mon Sep 17 00:00:00 2001 From: stefan-mysten <135084671+stefan-mysten@users.noreply.github.com> Date: Thu, 17 Oct 2024 13:47:00 -0700 Subject: [PATCH] sui-graphql-client: add checkpoints query (#34) --- crates/sui-graphql-client/src/lib.rs | 52 ++++++++++++++++++- .../src/query_types/checkpoint.rs | 22 ++++++++ .../sui-graphql-client/src/query_types/mod.rs | 2 + 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/crates/sui-graphql-client/src/lib.rs b/crates/sui-graphql-client/src/lib.rs index 10f132084..15791556f 100644 --- a/crates/sui-graphql-client/src/lib.rs +++ b/crates/sui-graphql-client/src/lib.rs @@ -15,6 +15,8 @@ use query_types::ChainIdentifierQuery; use query_types::CheckpointArgs; use query_types::CheckpointId; use query_types::CheckpointQuery; +use query_types::CheckpointsArgs; +use query_types::CheckpointsQuery; use query_types::CoinMetadata; use query_types::CoinMetadataArgs; use query_types::CoinMetadataQuery; @@ -438,7 +440,7 @@ impl Client { // Checkpoints API // =========================================================================== - /// Get the `CheckpointSummary` for a given checkpoint digest or checkpoint id. If none is + /// Get the [`CheckpointSummary`] for a given checkpoint digest or checkpoint id. If none is /// provided, it will use the last known checkpoint id. pub async fn checkpoint( &self, @@ -468,6 +470,42 @@ impl Client { .ok_or_else(|| Error::msg("No data in response"))? } + /// Get a page of [`CheckpointSummary`] for the provided parameters. + pub async fn checkpoints( + &self, + after: Option<&str>, + before: Option<&str>, + first: Option, + last: Option, + ) -> Result>, Error> { + let operation = CheckpointsQuery::build(CheckpointsArgs { + after, + before, + first, + last, + }); + + let response = self.run_query(&operation).await?; + + if let Some(errors) = response.errors { + return Err(Error::msg(format!("{:?}", errors))); + } + + if let Some(checkpoints) = response.data { + let cc = checkpoints.checkpoints; + let page_info = cc.page_info; + let nodes = cc + .nodes + .into_iter() + .map(|c| c.try_into()) + .collect::, _>>()?; + + Ok(Some(Page::new(page_info, nodes))) + } else { + Ok(None) + } + } + /// Return the sequence number of the latest checkpoint that has been executed. pub async fn latest_checkpoint_sequence_number( &self, @@ -1008,6 +1046,18 @@ mod tests { ); } } + #[tokio::test] + async fn test_checkpoints_query() { + for (n, _) in NETWORKS { + let client = Client::new(n).unwrap(); + let c = client.checkpoints(None, None, None, Some(5)).await; + assert!( + c.is_ok(), + "Checkpoints query failed for network: {n}. Error: {}", + c.unwrap_err() + ); + } + } #[tokio::test] async fn test_latest_checkpoint_sequence_number_query() { diff --git a/crates/sui-graphql-client/src/query_types/checkpoint.rs b/crates/sui-graphql-client/src/query_types/checkpoint.rs index 57aa018bb..ecf3c68b6 100644 --- a/crates/sui-graphql-client/src/query_types/checkpoint.rs +++ b/crates/sui-graphql-client/src/query_types/checkpoint.rs @@ -14,6 +14,7 @@ use crate::query_types::Base64; use crate::query_types::BigInt; use crate::query_types::DateTime; use crate::query_types::Epoch; +use crate::query_types::PageInfo; // =========================================================================== // Checkpoint Queries @@ -26,6 +27,27 @@ pub struct CheckpointQuery { pub checkpoint: Option, } +#[derive(cynic::QueryFragment, Debug)] +#[cynic(schema = "rpc", graphql_type = "Query", variables = "CheckpointsArgs")] +pub struct CheckpointsQuery { + pub checkpoints: CheckpointConnection, +} + +#[derive(cynic::QueryFragment, Debug)] +#[cynic(schema = "rpc", graphql_type = "CheckpointConnection")] +pub struct CheckpointConnection { + pub nodes: Vec, + pub page_info: PageInfo, +} + +#[derive(cynic::QueryVariables, Debug)] +pub struct CheckpointsArgs<'a> { + pub first: Option, + pub after: Option<&'a str>, + pub last: Option, + pub before: Option<&'a str>, +} + // =========================================================================== // Checkpoint Query Args // =========================================================================== diff --git a/crates/sui-graphql-client/src/query_types/mod.rs b/crates/sui-graphql-client/src/query_types/mod.rs index 824b6d65e..1ac458c8c 100644 --- a/crates/sui-graphql-client/src/query_types/mod.rs +++ b/crates/sui-graphql-client/src/query_types/mod.rs @@ -29,6 +29,8 @@ pub use chain::ChainIdentifierQuery; pub use checkpoint::CheckpointArgs; pub use checkpoint::CheckpointId; pub use checkpoint::CheckpointQuery; +pub use checkpoint::CheckpointsArgs; +pub use checkpoint::CheckpointsQuery; pub use coin::CoinMetadata; pub use coin::CoinMetadataArgs; pub use coin::CoinMetadataQuery;