linera_service_graphql_client/
service.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use graphql_client::GraphQLQuery;
5use linera_base::{
6    crypto::CryptoHash,
7    data_types::{Amount, BlockHeight, OracleResponse, Timestamp},
8    identifiers::{
9        Account, ChainDescription, ChainId, ChannelName, Destination, GenericApplicationId, Owner,
10        StreamName,
11    },
12};
13
14pub type JSONObject = serde_json::Value;
15
16#[cfg(target_arch = "wasm32")]
17mod types {
18    use linera_base::data_types::Round;
19    use serde::{Deserialize, Serialize};
20    use serde_json::Value;
21
22    use super::{BlockHeight, ChainId, CryptoHash};
23
24    pub type ChainManager = Value;
25    pub type ChainOwnership = Value;
26    pub type ChannelFullName = Value;
27    pub type Epoch = Value;
28    pub type MessageBundle = Value;
29    pub type MessageKind = Value;
30    pub type Message = Value;
31    pub type MessageAction = Value;
32    pub type Operation = Value;
33    pub type Origin = Value;
34    pub type Target = Value;
35    pub type UserApplicationDescription = Value;
36
37    #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
38    pub struct Notification {
39        pub chain_id: ChainId,
40        pub reason: Reason,
41    }
42
43    #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
44    #[expect(clippy::enum_variant_names)]
45    pub enum Reason {
46        NewBlock {
47            height: BlockHeight,
48            hash: CryptoHash,
49        },
50        NewIncomingBundle {
51            origin: Origin,
52            height: BlockHeight,
53        },
54        NewRound {
55            height: BlockHeight,
56            round: Round,
57        },
58    }
59}
60
61#[cfg(not(target_arch = "wasm32"))]
62mod types {
63    pub use linera_base::{data_types::UserApplicationDescription, ownership::ChainOwnership};
64    pub use linera_chain::{
65        data_types::{ChannelFullName, MessageAction, MessageBundle, Origin, Target},
66        manager::ChainManager,
67    };
68    pub use linera_core::worker::{Notification, Reason};
69    pub use linera_execution::{committee::Epoch, Message, MessageKind, Operation};
70}
71
72pub use types::*;
73pub type ApplicationId = String;
74
75#[derive(GraphQLQuery)]
76#[graphql(
77    schema_path = "gql/service_schema.graphql",
78    query_path = "gql/service_requests.graphql",
79    response_derives = "Debug, Serialize, Clone"
80)]
81pub struct Chain;
82
83#[derive(GraphQLQuery)]
84#[graphql(
85    schema_path = "gql/service_schema.graphql",
86    query_path = "gql/service_requests.graphql",
87    response_derives = "Debug, Serialize, Clone"
88)]
89pub struct Chains;
90
91#[derive(GraphQLQuery)]
92#[graphql(
93    schema_path = "gql/service_schema.graphql",
94    query_path = "gql/service_requests.graphql",
95    response_derives = "Debug, Serialize, Clone, PartialEq"
96)]
97pub struct Applications;
98
99#[derive(GraphQLQuery)]
100#[graphql(
101    schema_path = "gql/service_schema.graphql",
102    query_path = "gql/service_requests.graphql",
103    response_derives = "Debug, Serialize, Clone, PartialEq"
104)]
105pub struct Blocks;
106
107#[derive(GraphQLQuery)]
108#[graphql(
109    schema_path = "gql/service_schema.graphql",
110    query_path = "gql/service_requests.graphql",
111    response_derives = "Debug, Serialize, Clone, PartialEq"
112)]
113pub struct Block;
114
115#[derive(GraphQLQuery)]
116#[graphql(
117    schema_path = "gql/service_schema.graphql",
118    query_path = "gql/service_requests.graphql",
119    response_derives = "Debug, Serialize, Clone, PartialEq"
120)]
121pub struct Notifications;
122
123#[derive(GraphQLQuery)]
124#[graphql(
125    schema_path = "gql/service_schema.graphql",
126    query_path = "gql/service_requests.graphql",
127    response_derives = "Debug, Serialize, Clone"
128)]
129pub struct Transfer;
130
131#[cfg(not(target_arch = "wasm32"))]
132mod from {
133    use linera_base::identifiers::StreamId;
134    use linera_chain::data_types::{
135        BlockExecutionOutcome, EventRecord, ExecutedBlock, HashedCertificateValue, IncomingBundle,
136        MessageBundle, OutgoingMessage, PostedMessage,
137    };
138
139    use super::*;
140
141    impl From<block::BlockBlockValueExecutedBlockBlockIncomingBundles> for IncomingBundle {
142        fn from(val: block::BlockBlockValueExecutedBlockBlockIncomingBundles) -> Self {
143            let block::BlockBlockValueExecutedBlockBlockIncomingBundles {
144                origin,
145                bundle,
146                action,
147            } = val;
148            IncomingBundle {
149                origin,
150                bundle: bundle.into(),
151                action,
152            }
153        }
154    }
155
156    impl From<block::BlockBlockValueExecutedBlockBlockIncomingBundlesBundle> for MessageBundle {
157        fn from(val: block::BlockBlockValueExecutedBlockBlockIncomingBundlesBundle) -> Self {
158            let block::BlockBlockValueExecutedBlockBlockIncomingBundlesBundle {
159                height,
160                timestamp,
161                certificate_hash,
162                transaction_index,
163                messages,
164            } = val;
165            let messages = messages.into_iter().map(PostedMessage::from).collect();
166            MessageBundle {
167                height,
168                timestamp,
169                certificate_hash,
170                transaction_index: transaction_index as u32,
171                messages,
172            }
173        }
174    }
175
176    impl From<block::BlockBlockValueExecutedBlockBlockIncomingBundlesBundleMessages> for PostedMessage {
177        fn from(
178            val: block::BlockBlockValueExecutedBlockBlockIncomingBundlesBundleMessages,
179        ) -> Self {
180            let block::BlockBlockValueExecutedBlockBlockIncomingBundlesBundleMessages {
181                authenticated_signer,
182                grant,
183                refund_grant_to,
184                kind,
185                index,
186                message,
187            } = val;
188            PostedMessage {
189                authenticated_signer,
190                grant,
191                refund_grant_to,
192                kind,
193                index: index as u32,
194                message,
195            }
196        }
197    }
198
199    impl From<block::BlockBlockValueExecutedBlockBlock> for linera_chain::data_types::Block {
200        fn from(val: block::BlockBlockValueExecutedBlockBlock) -> Self {
201            let block::BlockBlockValueExecutedBlockBlock {
202                chain_id,
203                epoch,
204                incoming_bundles,
205                operations,
206                height,
207                timestamp,
208                authenticated_signer,
209                previous_block_hash,
210            } = val;
211            let incoming_bundles = incoming_bundles
212                .into_iter()
213                .map(IncomingBundle::from)
214                .collect();
215            linera_chain::data_types::Block {
216                chain_id,
217                epoch,
218                incoming_bundles,
219                operations,
220                height,
221                timestamp,
222                authenticated_signer,
223                previous_block_hash,
224            }
225        }
226    }
227
228    impl From<block::BlockBlockValueExecutedBlockOutcomeMessages> for OutgoingMessage {
229        fn from(val: block::BlockBlockValueExecutedBlockOutcomeMessages) -> Self {
230            let block::BlockBlockValueExecutedBlockOutcomeMessages {
231                destination,
232                authenticated_signer,
233                grant,
234                refund_grant_to,
235                kind,
236                message,
237            } = val;
238            OutgoingMessage {
239                destination,
240                authenticated_signer,
241                grant,
242                refund_grant_to,
243                kind,
244                message,
245            }
246        }
247    }
248
249    impl From<block::BlockBlockValueExecutedBlock> for ExecutedBlock {
250        fn from(val: block::BlockBlockValueExecutedBlock) -> Self {
251            let block::BlockBlockValueExecutedBlock {
252                block,
253                outcome:
254                    block::BlockBlockValueExecutedBlockOutcome {
255                        messages,
256                        state_hash,
257                        oracle_responses,
258                        events,
259                    },
260            } = val;
261            let messages = messages
262                .into_iter()
263                .map(|messages| messages.into_iter().map(OutgoingMessage::from).collect())
264                .collect::<Vec<Vec<_>>>();
265            ExecutedBlock {
266                block: block.into(),
267                outcome: BlockExecutionOutcome {
268                    messages,
269                    state_hash,
270                    oracle_responses: oracle_responses.into_iter().map(Into::into).collect(),
271                    events: events
272                        .into_iter()
273                        .map(|events| events.into_iter().map(Into::into).collect())
274                        .collect(),
275                },
276            }
277        }
278    }
279
280    impl From<block::BlockBlockValueExecutedBlockOutcomeEvents> for EventRecord {
281        fn from(event: block::BlockBlockValueExecutedBlockOutcomeEvents) -> Self {
282            EventRecord {
283                stream_id: event.stream_id.into(),
284                key: event.key.into_iter().map(|byte| byte as u8).collect(),
285                value: event.value.into_iter().map(|byte| byte as u8).collect(),
286            }
287        }
288    }
289
290    impl From<block::BlockBlockValueExecutedBlockOutcomeEventsStreamId> for StreamId {
291        fn from(stream_id: block::BlockBlockValueExecutedBlockOutcomeEventsStreamId) -> Self {
292            StreamId {
293                application_id: stream_id.application_id,
294                stream_name: stream_id.stream_name,
295            }
296        }
297    }
298
299    impl TryFrom<block::BlockBlock> for HashedCertificateValue {
300        type Error = String;
301        fn try_from(val: block::BlockBlock) -> Result<Self, Self::Error> {
302            match (val.value.status.as_str(), val.value.executed_block) {
303                ("validated", Some(executed_block)) => {
304                    Ok(HashedCertificateValue::new_validated(executed_block.into()))
305                }
306                ("confirmed", Some(executed_block)) => {
307                    Ok(HashedCertificateValue::new_confirmed(executed_block.into()))
308                }
309                _ => Err(val.value.status),
310            }
311        }
312    }
313}