sui_gql_client/queries/
transactions_by_digests.rs

1use af_sui_types::Transaction;
2use itertools::Itertools as _;
3use sui_gql_schema::scalars::Base64Bcs;
4
5use crate::queries::Error;
6use crate::queries::model::fragments::TransactionGql;
7use crate::{GraphQlClient, GraphQlResponseExt as _, schema};
8
9#[derive(cynic::QueryVariables, Clone, Debug)]
10struct Variables {
11    keys: Vec<String>,
12}
13
14#[derive(cynic::QueryFragment, Clone, Debug)]
15#[cynic(variables = "Variables")]
16struct Query {
17    #[arguments(keys: $keys)]
18    multi_get_transactions: Vec<Option<TransactionGql>>,
19}
20
21pub(super) async fn query<C: GraphQlClient>(
22    client: &C,
23    digests: impl IntoIterator<Item = String> + Send,
24) -> super::Result<Vec<Transaction>, C> {
25    let mut digests = digests.into_iter().sorted().dedup().collect_vec();
26
27    let vars = Variables {
28        keys: digests.clone(),
29    };
30
31    let data = client
32        .query::<Query, _>(vars)
33        .await
34        .map_err(Error::Client)?
35        .try_into_data()?;
36
37    graphql_extract::extract!(data => {
38        transactions: multi_get_transactions
39    });
40
41    let returned = transactions
42        .into_iter()
43        .flatten()
44        .filter_map(|o| o.bcs)
45        .map(Base64Bcs::into_inner)
46        .inspect(|t| {
47            digests
48                .iter()
49                .position(|k| k == &t.digest().to_string())
50                .map(|p| digests.swap_remove(p));
51        })
52        .collect_vec();
53
54    if !digests.is_empty() {
55        return Err(Error::MissingData(format!("Digests {digests:?}")));
56    }
57    Ok(returned)
58}
59
60#[cfg(test)]
61#[allow(clippy::unwrap_used)]
62#[test]
63fn gql_output() -> color_eyre::Result<()> {
64    use cynic::QueryBuilder as _;
65
66    // Variables don't matter, we just need it so taht `Query::build()` compiles
67    let vars = Variables { keys: vec![] };
68
69    let operation = Query::build(vars);
70    insta::assert_snapshot!(operation.query, @r"
71    query Query($keys: [String!]!) {
72      multiGetTransactions(keys: $keys) {
73        digest
74        transactionBcs
75        effects {
76          status
77        }
78      }
79    }
80    ");
81    Ok(())
82}