sui_graphql/
lib.rs

1//! GraphQL client for the [Sui] blockchain.
2//!
3//! [Sui]: https://sui.io
4//!
5//! This crate provides a typed GraphQL client for Sui's GraphQL API with
6//! automatic BCS deserialization and pagination support.
7//!
8//! # Quick Start
9//!
10//! ```no_run
11//! use sui_graphql::Client;
12//!
13//! #[tokio::main]
14//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
15//!     let client = Client::new(Client::MAINNET)?;
16//!
17//!     // Chain info
18//!     let chain_id = client.chain_identifier().await?;
19//!     println!("Chain: {chain_id}");
20//!
21//!     // Fetch objects, transactions, checkpoints
22//!     let obj = client.get_object("0x5".parse()?).await?;
23//!     let tx = client.get_transaction("digest...").await?;
24//!     let cp = client.get_checkpoint(None).await?; // latest
25//!
26//!     Ok(())
27//! }
28//! ```
29//!
30//! # Streaming
31//!
32//! List methods return async streams with automatic pagination:
33//!
34//! ```no_run
35//! use futures::StreamExt;
36//! use std::pin::pin;
37//! use sui_graphql::Client;
38//! use sui_sdk_types::Address;
39//!
40//! #[tokio::main]
41//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
42//!     let client = Client::new(Client::MAINNET)?;
43//!     let owner: Address = "0x123...".parse()?;
44//!
45//!     let mut stream = pin!(client.list_objects(owner));
46//!     while let Some(obj) = stream.next().await {
47//!         let obj = obj?;
48//!         println!("Object version: {}", obj.version());
49//!     }
50//!     Ok(())
51//! }
52//! ```
53//!
54//! # Custom Queries
55//!
56//! For queries beyond the built-in methods, use [`Client::query`] with a
57//! response type that implements [`serde::de::DeserializeOwned`]. The
58//! [`sui-graphql-macros`] crate provides `#[derive(Response)]` which generates
59//! the deserialization code from declarative field paths, with compile-time
60//! validation against the Sui GraphQL schema.
61//!
62//! [`sui-graphql-macros`]: https://docs.rs/sui-graphql-macros
63//!
64//! ```no_run
65//! use sui_graphql::Client;
66//! use sui_graphql_macros::Response;
67//!
68//! // Define a response type with field paths into the GraphQL response JSON.
69//! // Paths are validated against the schema at compile time — typos like
70//! // "epoch.epochIdd" will produce a compile error with a "Did you mean?" suggestion.
71//! #[derive(Response)]
72//! struct MyResponse {
73//!     #[field(path = "epoch.epochId")]
74//!     epoch_id: u64,
75//!     // Use `[]` to extract items from a list field
76//!     #[field(path = "epoch.checkpoints.nodes[].digest")]
77//!     checkpoint_digests: Vec<String>,
78//!     // Use `?` to mark nullable fields — null returns Ok(None) instead of an error.
79//!     // Without `?`, a null value at that segment is a runtime error.
80//!     #[field(path = "epoch.referenceGasPrice?")]
81//!     gas_price: Option<u64>,
82//! }
83//!
84//! #[tokio::main]
85//! async fn main() -> Result<(), sui_graphql::Error> {
86//!     let client = Client::new(Client::MAINNET)?;
87//!
88//!     let query = r#"
89//!         query($epoch_id: UInt53) {
90//!             epoch(id: $epoch_id) {
91//!                 epochId
92//!                 checkpoints { nodes { digest } }
93//!                 referenceGasPrice
94//!             }
95//!         }
96//!     "#;
97//!     let variables = serde_json::json!({ "epoch_id": 100 });
98//!
99//!     let response = client.query::<MyResponse>(query, variables).await?;
100//!
101//!     // GraphQL supports partial success — data and errors can coexist
102//!     for err in response.errors() {
103//!         eprintln!("GraphQL error: {}", err.message());
104//!     }
105//!     if let Some(data) = response.data() {
106//!         println!("Epoch: {}", data.epoch_id);
107//!         println!("Checkpoints: {:?}", data.checkpoint_digests);
108//!         println!("Gas price: {:?}", data.gas_price);
109//!     }
110//!     Ok(())
111//! }
112//! ```
113//!
114//! For the full path syntax reference (`?`, `[]`, aliases, enums), see the
115//! [`sui-graphql-macros` documentation](https://docs.rs/sui-graphql-macros).
116//!
117//! See [`Client`] for the full list of available methods.
118
119mod bcs;
120mod client;
121mod error;
122mod move_value;
123mod pagination;
124mod response;
125pub mod scalars;
126
127pub use bcs::Bcs;
128pub use bcs::BcsBytes;
129pub use client::Client;
130pub use client::chain::Epoch;
131pub use client::checkpoints::CheckpointResponse;
132pub use client::coins::Balance;
133pub use client::dynamic_fields::DynamicField;
134pub use client::dynamic_fields::DynamicFieldRequest;
135pub use client::dynamic_fields::DynamicFieldValue;
136pub use client::dynamic_fields::DynamicFieldsRequest;
137pub use client::dynamic_fields::Format;
138pub use client::execution::ExecutionResult;
139pub use client::transactions::TransactionResponse;
140pub use error::Error;
141pub use error::GraphQLError;
142pub use error::Location;
143pub use error::PathFragment;
144pub use move_value::MoveObject;
145pub use move_value::MoveValue;
146pub use pagination::Page;
147pub use pagination::PageInfo;
148pub use pagination::paginate;
149pub use pagination::paginate_backward;
150pub use response::Response;