Skip to main content

af_iperps/graphql/
order_maps.rs

1use af_sui_types::Address;
2use enum_as_inner::EnumAsInner;
3use sui_gql_client::queries::Error;
4use sui_gql_client::queries::model::fragments::DynamicFieldName;
5use sui_gql_client::{GraphQlClient, GraphQlResponseExt, schema};
6
7use crate::keys;
8
9/// Object ids of the orderbook and asks/bids maps for a market.
10///
11/// Just a convenient return type for [`order_maps`].
12///
13/// [`order_maps`]: super::GraphQlClientExt::order_maps
14#[derive(Clone, Copy, Debug)]
15pub struct OrderMaps {
16    pub orderbook: Address,
17    pub asks: Address,
18    pub bids: Address,
19}
20
21pub(super) async fn query<C: GraphQlClient>(
22    client: &C,
23    package: Address,
24    ch: Address,
25) -> Result<OrderMaps, Error<C::Error>> {
26    let vars = Variables {
27        ch,
28        orderbook: keys::Orderbook::new()
29            .move_instance(package)
30            .try_into()
31            .expect("BCS-serializable"),
32        asks: keys::AsksMap::new()
33            .move_instance(package)
34            .try_into()
35            .expect("BCS-serializable"),
36        bids: keys::BidsMap::new()
37            .move_instance(package)
38            .try_into()
39            .expect("BCS-serializable"),
40    };
41    let data = client
42        .query::<Query, _>(vars)
43        .await
44        .map_err(Error::Client)?
45        .try_into_data()?;
46    let ordermaps = extract(data)?;
47    Ok(ordermaps)
48}
49
50fn extract(data: Option<Query>) -> Result<OrderMaps, &'static str> {
51    graphql_extract::extract!(data => {
52        ch? {
53            orderbook? {
54                value? {
55                    ... on OrderbookDofValue::MoveObject {
56                        orderbook: id
57                        asks? {
58                            value? {
59                                ... on MapDofValue::MoveObject {
60                                    asks: id
61                                }
62                            }
63                        }
64                        bids? {
65                            value? {
66                                ... on MapDofValue::MoveObject {
67                                    bids: id
68                                }
69                            }
70                        }
71                    }
72                }
73            }
74        }
75    });
76    Ok(OrderMaps {
77        orderbook,
78        asks,
79        bids,
80    })
81}
82
83#[cfg(test)]
84#[allow(clippy::unwrap_used)]
85#[test]
86fn gql_output() {
87    use cynic::QueryBuilder as _;
88
89    let package = Address::ZERO;
90    let vars = Variables {
91        ch: Address::ZERO,
92        orderbook: keys::Orderbook::new()
93            .move_instance(package)
94            .try_into()
95            .unwrap(),
96        asks: keys::AsksMap::new()
97            .move_instance(package)
98            .try_into()
99            .unwrap(),
100        bids: keys::BidsMap::new()
101            .move_instance(package)
102            .try_into()
103            .unwrap(),
104    };
105    let operation = Query::build(vars);
106    insta::assert_snapshot!(operation.query, @r###"
107    query Query($ch: SuiAddress!, $orderbook: DynamicFieldName!, $asks: DynamicFieldName!, $bids: DynamicFieldName!) {
108      ch: object(address: $ch) {
109        orderbook: dynamicObjectField(name: $orderbook) {
110          value {
111            __typename
112            ... on MoveObject {
113              id: address
114              asks: dynamicObjectField(name: $asks) {
115                value {
116                  __typename
117                  ... on MoveObject {
118                    id: address
119                  }
120                }
121              }
122              bids: dynamicObjectField(name: $bids) {
123                value {
124                  __typename
125                  ... on MoveObject {
126                    id: address
127                  }
128                }
129              }
130            }
131          }
132        }
133      }
134    }
135    "###);
136}
137
138#[derive(cynic::QueryVariables, Debug)]
139struct Variables {
140    ch: Address,
141    orderbook: DynamicFieldName,
142    asks: DynamicFieldName,
143    bids: DynamicFieldName,
144}
145
146#[derive(cynic::QueryFragment, Debug)]
147#[cynic(graphql_type = "Query", variables = "Variables")]
148struct Query {
149    #[arguments(address: $ch)]
150    #[cynic(alias, rename = "object")]
151    ch: Option<ClearingHouseObject>,
152}
153
154#[derive(cynic::QueryFragment, Debug)]
155#[cynic(graphql_type = "Object", variables = "Variables")]
156struct ClearingHouseObject {
157    #[arguments(name: $orderbook)]
158    #[cynic(alias, rename = "dynamicObjectField")]
159    orderbook: Option<OrderbookDof>,
160}
161
162#[derive(cynic::QueryFragment, Debug)]
163#[cynic(graphql_type = "DynamicField", variables = "Variables")]
164struct OrderbookDof {
165    value: Option<OrderbookDofValue>,
166}
167
168#[derive(cynic::InlineFragments, Debug, EnumAsInner)]
169#[cynic(graphql_type = "DynamicFieldValue", variables = "Variables")]
170enum OrderbookDofValue {
171    MoveObject(OrderbookMoveObject),
172    #[cynic(fallback)]
173    Unknown,
174}
175
176#[derive(cynic::QueryFragment, Debug)]
177#[cynic(graphql_type = "MoveObject", variables = "Variables")]
178struct OrderbookMoveObject {
179    #[cynic(alias, rename = "address")]
180    id: Address,
181    #[arguments(name: $asks)]
182    #[cynic(alias, rename = "dynamicObjectField")]
183    asks: Option<MapDof>,
184    #[arguments(name: $bids)]
185    #[cynic(alias, rename = "dynamicObjectField")]
186    bids: Option<MapDof>,
187}
188
189#[derive(cynic::QueryFragment, Debug)]
190#[cynic(graphql_type = "DynamicField")]
191struct MapDof {
192    value: Option<MapDofValue>,
193}
194
195#[derive(cynic::InlineFragments, Debug, EnumAsInner)]
196#[cynic(graphql_type = "DynamicFieldValue")]
197enum MapDofValue {
198    MoveObject(MapMoveObject),
199    #[cynic(fallback)]
200    Unknown,
201}
202
203#[derive(cynic::QueryFragment, Debug)]
204#[cynic(graphql_type = "MoveObject")]
205struct MapMoveObject {
206    #[cynic(alias, rename = "address")]
207    id: Address,
208}