sui_gql_client/queries/
owner_dof_content.rs

1use af_sui_types::Address as SuiAddress;
2use cynic::GraphQlResponse;
3
4use super::Error;
5use super::fragments::MoveValueRaw;
6use super::outputs::{ObjectKey, RawMoveStruct, RawMoveValue};
7use crate::{GraphQlClient, GraphQlResponseExt, missing_data, scalars, schema};
8
9pub async fn query<C: GraphQlClient>(
10    client: &C,
11    address: SuiAddress,
12    RawMoveValue {
13        type_: df_name_type,
14        bcs: df_name_bcs,
15    }: RawMoveValue,
16    root_version: Option<u64>,
17) -> Result<(ObjectKey, RawMoveStruct), Error<C::Error>> {
18    let vars = QueryVariables {
19        address,
20        root_version,
21        name: DynamicFieldName {
22            type_: scalars::TypeTag(df_name_type),
23            bcs: scalars::Base64::new(df_name_bcs),
24        },
25    };
26    let result: GraphQlResponse<Query> = client.query(vars).await.map_err(Error::Client)?;
27    let data = result
28        .try_into_data()?
29        .ok_or(missing_data!("Response empty"))?;
30    let df_value = data
31        .owner
32        .ok_or(missing_data!("Owner not found"))?
33        .dynamic_object_field
34        .ok_or(missing_data!("Dynamic object field not found"))?
35        .value
36        .ok_or(missing_data!("No dynamic field value"))?;
37    match df_value {
38        DynamicFieldValue::MoveObject(MoveObject {
39            object_id,
40            version,
41            contents,
42        }) => {
43            let struct_ = contents
44                .ok_or(missing_data!("No contents for DOF"))?
45                .try_into()
46                .expect("Only Move structs can be top-level objects");
47            Ok((ObjectKey { object_id, version }, struct_))
48        }
49        DynamicFieldValue::Unknown => Err(missing_data!("Not a dynamic object field")),
50    }
51}
52
53#[cfg(test)]
54#[allow(clippy::unwrap_used)]
55#[test]
56fn gql_output() {
57    use cynic::QueryBuilder as _;
58    let vars = QueryVariables {
59        address: SuiAddress::new(rand::random()),
60        root_version: None,
61        name: DynamicFieldName {
62            type_: scalars::TypeTag("0x2::sui::SUI".parse().unwrap()),
63            bcs: scalars::Base64::new(vec![]),
64        },
65    };
66    let operation = Query::build(vars);
67    insta::assert_snapshot!(operation.query, @r"
68    query Query($address: SuiAddress!, $name: DynamicFieldName!, $rootVersion: UInt53) {
69      owner(address: $address, rootVersion: $rootVersion) {
70        dynamicObjectField(name: $name) {
71          value {
72            __typename
73            ... on MoveObject {
74              address
75              version
76              contents {
77                type {
78                  repr
79                }
80                bcs
81              }
82            }
83          }
84        }
85      }
86    }
87    ");
88}
89
90// ================================================================================
91//  Mostly autogenerated by: https://generator.cynic-rs.dev/
92// ================================================================================
93
94#[derive(cynic::QueryVariables, Debug)]
95struct QueryVariables {
96    address: SuiAddress,
97    name: DynamicFieldName,
98    root_version: Option<af_sui_types::Version>,
99}
100
101#[derive(cynic::InputObject, Debug)]
102struct DynamicFieldName {
103    #[cynic(rename = "type")]
104    type_: scalars::TypeTag,
105    bcs: scalars::Base64<Vec<u8>>,
106}
107
108#[derive(cynic::QueryFragment, Debug)]
109#[cynic(variables = "QueryVariables")]
110struct Query {
111    #[arguments(address: $address, rootVersion: $root_version)]
112    owner: Option<Owner>,
113}
114
115#[derive(cynic::QueryFragment, Debug)]
116#[cynic(variables = "QueryVariables")]
117struct Owner {
118    #[arguments(name: $name)]
119    dynamic_object_field: Option<_DynamicField>,
120}
121
122#[derive(cynic::QueryFragment, Debug)]
123#[cynic(graphql_type = "DynamicField")]
124struct _DynamicField {
125    value: Option<DynamicFieldValue>,
126}
127
128#[derive(cynic::InlineFragments, Debug)]
129enum DynamicFieldValue {
130    MoveObject(MoveObject),
131    #[cynic(fallback)]
132    Unknown,
133}
134
135#[derive(cynic::QueryFragment, Debug)]
136struct MoveObject {
137    #[cynic(rename = "address")]
138    object_id: SuiAddress,
139    version: af_sui_types::Version,
140    contents: Option<MoveValueRaw>,
141}