fuel_gql_client/client/schema/
tx.rs1use super::block::BlockIdFragment;
2use crate::client::{
3 schema::{
4 schema,
5 Address,
6 ConnectionArgs,
7 ConversionError,
8 HexString,
9 PageInfo,
10 Tai64Timestamp,
11 TransactionId,
12 },
13 types::TransactionResponse,
14 PageDirection,
15 PaginatedResult,
16 PaginationRequest,
17};
18use fuel_vm::fuel_types::{
19 bytes::Deserializable,
20 Bytes32,
21};
22use std::convert::{
23 TryFrom,
24 TryInto,
25};
26
27pub mod transparent_receipt;
28pub mod transparent_tx;
29
30#[derive(cynic::QueryVariables, Debug)]
31pub struct TxIdArgs {
32 pub id: TransactionId,
33}
34
35#[derive(cynic::QueryFragment, Debug)]
37#[cynic(
38 schema_path = "./assets/schema.sdl",
39 graphql_type = "Query",
40 variables = "TxIdArgs"
41)]
42pub struct TransactionQuery {
43 #[arguments(id: $id)]
44 pub transaction: Option<OpaqueTransaction>,
45}
46
47#[derive(cynic::QueryFragment, Debug)]
48#[cynic(
49 schema_path = "./assets/schema.sdl",
50 graphql_type = "Query",
51 variables = "ConnectionArgs"
52)]
53pub struct TransactionsQuery {
54 #[arguments(after: $after, before: $before, first: $first, last: $last)]
55 pub transactions: TransactionConnection,
56}
57
58#[derive(cynic::QueryFragment, Debug)]
59#[cynic(schema_path = "./assets/schema.sdl")]
60pub struct TransactionConnection {
61 pub edges: Vec<TransactionEdge>,
62 pub page_info: PageInfo,
63}
64
65impl TryFrom<TransactionConnection> for PaginatedResult<TransactionResponse, String> {
66 type Error = ConversionError;
67
68 fn try_from(conn: TransactionConnection) -> Result<Self, Self::Error> {
69 let results: Result<Vec<TransactionResponse>, Self::Error> =
70 conn.edges.into_iter().map(|e| e.node.try_into()).collect();
71
72 Ok(PaginatedResult {
73 cursor: conn.page_info.end_cursor,
74 has_next_page: conn.page_info.has_next_page,
75 has_previous_page: conn.page_info.has_previous_page,
76 results: results?,
77 })
78 }
79}
80
81#[derive(cynic::QueryFragment, Debug)]
82#[cynic(schema_path = "./assets/schema.sdl")]
83pub struct TransactionEdge {
84 pub cursor: String,
85 pub node: OpaqueTransaction,
86}
87
88#[derive(cynic::QueryFragment, Debug)]
89#[cynic(graphql_type = "Transaction", schema_path = "./assets/schema.sdl")]
90pub struct OpaqueTransaction {
91 pub raw_payload: HexString,
92 pub receipts: Option<Vec<OpaqueReceipt>>,
93 pub status: Option<TransactionStatus>,
94}
95
96impl TryFrom<OpaqueTransaction> for ::fuel_vm::fuel_tx::Transaction {
97 type Error = ConversionError;
98
99 fn try_from(value: OpaqueTransaction) -> Result<Self, Self::Error> {
100 let bytes = value.raw_payload.0 .0;
101 ::fuel_vm::fuel_tx::Transaction::from_bytes(bytes.as_slice())
102 .map_err(ConversionError::TransactionFromBytesError)
103 }
104}
105
106#[derive(cynic::QueryFragment, Debug)]
107#[cynic(schema_path = "./assets/schema.sdl", graphql_type = "Transaction")]
108pub struct TransactionIdFragment {
109 pub id: TransactionId,
110}
111
112#[derive(cynic::QueryFragment, Debug)]
113#[cynic(graphql_type = "Receipt", schema_path = "./assets/schema.sdl")]
114pub struct OpaqueReceipt {
115 pub raw_payload: HexString,
116}
117
118impl TryFrom<OpaqueReceipt> for ::fuel_vm::fuel_tx::Receipt {
119 type Error = ConversionError;
120
121 fn try_from(value: OpaqueReceipt) -> Result<Self, Self::Error> {
122 let bytes = value.raw_payload.0 .0;
123 ::fuel_vm::fuel_tx::Receipt::from_bytes(bytes.as_slice())
124 .map_err(ConversionError::ReceiptFromBytesError)
125 }
126}
127
128#[derive(cynic::Enum, Copy, Clone, Debug)]
129#[cynic(schema_path = "./assets/schema.sdl")]
130pub enum ReturnType {
131 Return,
132 ReturnData,
133 Revert,
134}
135
136#[derive(cynic::QueryFragment, Clone, Debug)]
137#[cynic(graphql_type = "ProgramState", schema_path = "./assets/schema.sdl")]
138pub struct ProgramState {
139 pub return_type: ReturnType,
140 pub data: HexString,
141}
142
143impl TryFrom<ProgramState> for fuel_vm::prelude::ProgramState {
144 type Error = ConversionError;
145
146 fn try_from(state: ProgramState) -> Result<Self, Self::Error> {
147 Ok(match state.return_type {
148 ReturnType::Return => fuel_vm::prelude::ProgramState::Return({
149 let b = state.data.0 .0;
150 let b: [u8; 8] =
151 b.try_into().map_err(|_| ConversionError::BytesLength)?;
152 u64::from_be_bytes(b)
153 }),
154 ReturnType::ReturnData => fuel_vm::prelude::ProgramState::ReturnData({
155 Bytes32::try_from(state.data.0 .0.as_slice())?
156 }),
157 ReturnType::Revert => fuel_vm::prelude::ProgramState::Revert({
158 let b = state.data.0 .0;
159 let b: [u8; 8] =
160 b.try_into().map_err(|_| ConversionError::BytesLength)?;
161 u64::from_be_bytes(b)
162 }),
163 })
164 }
165}
166
167#[allow(clippy::enum_variant_names)]
168#[derive(cynic::InlineFragments, Debug)]
169#[cynic(schema_path = "./assets/schema.sdl")]
170pub enum TransactionStatus {
171 SubmittedStatus(SubmittedStatus),
172 SuccessStatus(SuccessStatus),
173 SqueezedOutStatus(SqueezedOutStatus),
174 FailureStatus(FailureStatus),
175 #[cynic(fallback)]
176 Unknown,
177}
178
179#[derive(cynic::QueryFragment, Debug)]
180#[cynic(schema_path = "./assets/schema.sdl")]
181pub struct SubmittedStatus {
182 pub time: Tai64Timestamp,
183}
184
185#[derive(cynic::QueryFragment, Debug)]
186#[cynic(schema_path = "./assets/schema.sdl")]
187pub struct SuccessStatus {
188 pub block: BlockIdFragment,
189 pub time: Tai64Timestamp,
190 pub program_state: Option<ProgramState>,
191}
192
193#[derive(cynic::QueryFragment, Debug)]
194#[cynic(schema_path = "./assets/schema.sdl")]
195pub struct FailureStatus {
196 pub block: BlockIdFragment,
197 pub time: Tai64Timestamp,
198 pub reason: String,
199 pub program_state: Option<ProgramState>,
200}
201
202#[derive(cynic::QueryFragment, Debug)]
203#[cynic(schema_path = "./assets/schema.sdl")]
204pub struct SqueezedOutStatus {
205 pub reason: String,
206}
207
208#[derive(cynic::QueryVariables, Debug)]
209pub struct TransactionsByOwnerConnectionArgs {
210 pub owner: Address,
212 pub after: Option<String>,
214 pub before: Option<String>,
216 pub first: Option<i32>,
218 pub last: Option<i32>,
221}
222
223impl From<(Address, PaginationRequest<String>)> for TransactionsByOwnerConnectionArgs {
224 fn from(r: (Address, PaginationRequest<String>)) -> Self {
225 match r.1.direction {
226 PageDirection::Forward => TransactionsByOwnerConnectionArgs {
227 owner: r.0,
228 after: r.1.cursor,
229 before: None,
230 first: Some(r.1.results as i32),
231 last: None,
232 },
233 PageDirection::Backward => TransactionsByOwnerConnectionArgs {
234 owner: r.0,
235 after: None,
236 before: r.1.cursor,
237 first: None,
238 last: Some(r.1.results as i32),
239 },
240 }
241 }
242}
243
244#[derive(cynic::QueryFragment, Debug)]
245#[cynic(
246 schema_path = "./assets/schema.sdl",
247 graphql_type = "Query",
248 variables = "TransactionsByOwnerConnectionArgs"
249)]
250pub struct TransactionsByOwnerQuery {
251 #[arguments(owner: $owner, after: $after, before: $before, first: $first, last: $last)]
252 pub transactions_by_owner: TransactionConnection,
253}
254
255#[derive(cynic::QueryFragment, Debug)]
256#[cynic(
257 schema_path = "./assets/schema.sdl",
258 graphql_type = "Subscription",
259 variables = "TxIdArgs"
260)]
261pub struct StatusChangeSubscription {
262 #[arguments(id: $id)]
263 pub status_change: TransactionStatus,
264}
265
266#[derive(cynic::QueryVariables)]
269pub struct TxArg {
270 pub tx: HexString,
271}
272
273#[derive(cynic::QueryVariables)]
274pub struct DryRunArg {
275 pub tx: HexString,
276 pub utxo_validation: Option<bool>,
277}
278
279#[derive(cynic::QueryFragment, Debug)]
280#[cynic(
281 schema_path = "./assets/schema.sdl",
282 graphql_type = "Mutation",
283 variables = "DryRunArg"
284)]
285pub struct DryRun {
286 #[arguments(tx: $tx, utxoValidation: $utxo_validation)]
287 pub dry_run: Vec<transparent_receipt::Receipt>,
288}
289
290#[derive(cynic::QueryFragment, Debug)]
291#[cynic(
292 schema_path = "./assets/schema.sdl",
293 graphql_type = "Mutation",
294 variables = "TxArg"
295)]
296pub struct Submit {
297 #[arguments(tx: $tx)]
298 pub submit: TransactionIdFragment,
299}
300
301#[cfg(test)]
302pub mod tests {
303 use super::*;
304 use crate::client::schema::Bytes;
305 use fuel_vm::fuel_types::bytes::SerializableVec;
306
307 #[test]
308 fn transparent_transaction_by_id_query_gql_output() {
309 use cynic::QueryBuilder;
310 let operation = transparent_tx::TransactionQuery::build(TxIdArgs {
311 id: TransactionId::default(),
312 });
313 insta::assert_snapshot!(operation.query)
314 }
315
316 #[test]
317 fn opaque_transaction_by_id_query_gql_output() {
318 use cynic::QueryBuilder;
319 let operation = TransactionQuery::build(TxIdArgs {
320 id: TransactionId::default(),
321 });
322 insta::assert_snapshot!(operation.query)
323 }
324
325 #[test]
326 fn transactions_connection_query_gql_output() {
327 use cynic::QueryBuilder;
328 let operation = TransactionsQuery::build(ConnectionArgs {
329 after: None,
330 before: None,
331 first: None,
332 last: None,
333 });
334 insta::assert_snapshot!(operation.query)
335 }
336
337 #[test]
338 fn transactions_by_owner_gql_output() {
339 use cynic::QueryBuilder;
340 let operation =
341 TransactionsByOwnerQuery::build(TransactionsByOwnerConnectionArgs {
342 owner: Default::default(),
343 after: None,
344 before: None,
345 first: None,
346 last: None,
347 });
348 insta::assert_snapshot!(operation.query)
349 }
350
351 #[test]
352 fn dry_run_tx_gql_output() {
353 use cynic::MutationBuilder;
354 let mut tx = ::fuel_vm::fuel_tx::Transaction::default();
355 let query = DryRun::build(DryRunArg {
356 tx: HexString(Bytes(tx.to_bytes())),
357 utxo_validation: None,
358 });
359 insta::assert_snapshot!(query.query)
360 }
361
362 #[test]
363 fn submit_tx_gql_output() {
364 use cynic::MutationBuilder;
365 let mut tx = ::fuel_vm::fuel_tx::Transaction::default();
366 let query = Submit::build(TxArg {
367 tx: HexString(Bytes(tx.to_bytes())),
368 });
369 insta::assert_snapshot!(query.query)
370 }
371}