1use std::str::FromStr;
2
3use juniper::{GraphQLInputObject, GraphQLObject};
4use ledger::{FpExt, VerificationKey};
5use mina_p2p_messages::{
6 bigint::BigInt,
7 list::List,
8 pseq::PaddedSeq,
9 string::{TokenSymbol, ZkAppUri},
10 v2::{
11 CurrencyAmountStableV1, CurrencyBalanceStableV1, CurrencyFeeStableV1,
12 MinaBaseAccountUpdateAccountPreconditionStableV1,
13 MinaBaseAccountUpdateAuthorizationKindStableV1, MinaBaseAccountUpdateBodyEventsStableV1,
14 MinaBaseAccountUpdateBodyFeePayerStableV1, MinaBaseAccountUpdateBodyStableV1,
15 MinaBaseAccountUpdateFeePayerStableV1, MinaBaseAccountUpdateMayUseTokenStableV1,
16 MinaBaseAccountUpdatePreconditionsStableV1, MinaBaseAccountUpdateTStableV1,
17 MinaBaseAccountUpdateUpdateStableV1, MinaBaseAccountUpdateUpdateStableV1AppStateA,
18 MinaBaseAccountUpdateUpdateStableV1Delegate,
19 MinaBaseAccountUpdateUpdateStableV1Permissions, MinaBaseAccountUpdateUpdateStableV1Timing,
20 MinaBaseAccountUpdateUpdateStableV1TokenSymbol,
21 MinaBaseAccountUpdateUpdateStableV1VerificationKey,
22 MinaBaseAccountUpdateUpdateStableV1VotingFor, MinaBaseAccountUpdateUpdateStableV1ZkappUri,
23 MinaBaseAccountUpdateUpdateTimingInfoStableV1, MinaBaseControlStableV2,
24 MinaBasePermissionsStableV2, MinaBaseReceiptChainHashStableV1,
25 MinaBaseSignedCommandMemoStableV1, MinaBaseUserCommandStableV2,
26 MinaBaseVerificationKeyWireStableV1, MinaBaseZkappCommandTStableV1WireStableV1,
27 MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesA,
28 MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAA,
29 MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAACallsA,
30 MinaBaseZkappPreconditionAccountStableV2, MinaBaseZkappPreconditionAccountStableV2Balance,
31 MinaBaseZkappPreconditionAccountStableV2BalanceA,
32 MinaBaseZkappPreconditionAccountStableV2Delegate,
33 MinaBaseZkappPreconditionAccountStableV2ProvedState,
34 MinaBaseZkappPreconditionAccountStableV2ReceiptChainHash,
35 MinaBaseZkappPreconditionAccountStableV2StateA,
36 MinaBaseZkappPreconditionProtocolStateEpochDataStableV1,
37 MinaBaseZkappPreconditionProtocolStateEpochDataStableV1EpochLedger,
38 MinaBaseZkappPreconditionProtocolStateEpochDataStableV1EpochSeed,
39 MinaBaseZkappPreconditionProtocolStateEpochDataStableV1StartCheckpoint,
40 MinaBaseZkappPreconditionProtocolStateStableV1,
41 MinaBaseZkappPreconditionProtocolStateStableV1Amount,
42 MinaBaseZkappPreconditionProtocolStateStableV1AmountA,
43 MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlot,
44 MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlotA,
45 MinaBaseZkappPreconditionProtocolStateStableV1Length,
46 MinaBaseZkappPreconditionProtocolStateStableV1LengthA,
47 MinaBaseZkappPreconditionProtocolStateStableV1SnarkedLedgerHash,
48 MinaNumbersGlobalSlotSinceGenesisMStableV1, MinaNumbersGlobalSlotSpanStableV1,
49 MinaStateBlockchainStateValueStableV2SignedAmount, PicklesProofProofsVerifiedMaxStableV2,
50 StateHash,
51 },
52};
53
54use node::account::AccountPublicKey;
55use serde::Deserialize;
56
57use super::{
58 account::{GraphQLTiming, InputGraphQLTiming},
59 ConversionError,
60};
61
62#[derive(GraphQLInputObject, Debug)]
63pub struct SendZkappInput {
64 pub zkapp_command: InputGraphQLZkappCommand,
65}
66
67impl TryFrom<SendZkappInput> for MinaBaseUserCommandStableV2 {
68 type Error = ConversionError;
69 fn try_from(value: SendZkappInput) -> Result<Self, Self::Error> {
70 value.zkapp_command.try_into()
71 }
72}
73
74#[derive(GraphQLObject, Debug)]
75pub struct GraphQLSendZkappResponse {
76 pub zkapp: GraphQLZkapp,
77}
78
79#[derive(GraphQLObject, Debug)]
80pub struct GraphQLZkapp {
81 pub hash: String,
82 pub failure_reason: Option<Vec<GraphQLFailureReason>>,
83 pub id: String,
85 pub zkapp_command: GraphQLZkappCommand,
86}
87
88#[derive(GraphQLInputObject, Debug)]
89pub struct InputGraphQLZkapp {
90 pub zkapp_command: InputGraphQLZkappCommand,
95}
96
97#[derive(GraphQLObject, Debug)]
98pub struct GraphQLZkappCommand {
99 pub memo: String,
100 pub account_updates: Vec<GraphQLAccountUpdate>,
101 pub fee_payer: GraphQLFeePayer,
102}
103
104#[derive(GraphQLInputObject, Debug)]
105pub struct InputGraphQLZkappCommand {
106 pub memo: Option<String>,
107 pub account_updates: Vec<InputGraphQLAccountUpdate>,
108 pub fee_payer: InputGraphQLFeePayer,
109}
110
111impl TryFrom<MinaBaseZkappCommandTStableV1WireStableV1> for GraphQLZkapp {
112 type Error = ConversionError;
113
114 fn try_from(zkapp: MinaBaseZkappCommandTStableV1WireStableV1) -> Result<Self, Self::Error> {
115 let account_updates = zkapp
116 .account_updates
117 .clone()
118 .into_iter()
119 .map(|v| v.elt.account_update.try_into())
120 .collect::<Result<Vec<_>, _>>()?;
121
122 Ok(GraphQLZkapp {
123 hash: zkapp.hash()?.to_string(),
124 failure_reason: None,
125 id: zkapp.to_base64()?,
126 zkapp_command: GraphQLZkappCommand {
127 memo: zkapp.memo.to_base58check(),
128 account_updates,
129 fee_payer: GraphQLFeePayer::from(zkapp.fee_payer),
130 },
131 })
132 }
133}
134
135impl TryFrom<MinaBaseUserCommandStableV2> for GraphQLSendZkappResponse {
136 type Error = ConversionError;
137 fn try_from(value: MinaBaseUserCommandStableV2) -> Result<Self, Self::Error> {
138 if let MinaBaseUserCommandStableV2::ZkappCommand(zkapp) = value {
139 Ok(GraphQLSendZkappResponse {
140 zkapp: GraphQLZkapp::try_from(zkapp)?,
141 })
142 } else {
143 Err(ConversionError::WrongVariant)
144 }
145 }
146}
147
148impl TryFrom<InputGraphQLZkappCommand> for MinaBaseUserCommandStableV2 {
149 type Error = ConversionError;
150 fn try_from(value: InputGraphQLZkappCommand) -> Result<Self, Self::Error> {
151 Ok(MinaBaseUserCommandStableV2::ZkappCommand(
152 MinaBaseZkappCommandTStableV1WireStableV1 {
153 fee_payer: value.fee_payer.try_into()?,
154 account_updates: try_tree_from_account_updates(List::from_iter(
155 value.account_updates,
156 ))?,
157 memo: if let Some(memo) = value.memo {
158 MinaBaseSignedCommandMemoStableV1::from_base58check(&memo)
159 } else {
160 let empty_memo = ledger::scan_state::transaction_logic::Memo::empty();
161 MinaBaseSignedCommandMemoStableV1::from(&empty_memo)
162 },
163 },
164 ))
165 }
166}
167
168fn try_tree_from_account_updates(
170 updates: List<InputGraphQLAccountUpdate>,
171) -> Result<List<MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesA>, ConversionError> {
172 let result =
173 try_tree_from_account_updates_aux(updates)?
174 .into_iter()
175 .map(|update| {
176 let MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAACallsA {
177 elt,
178 stack_hash,
179 } = update;
180 let MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAA {
181 account_update,
182 account_update_digest,
183 calls,
184 } = *elt;
185 let elt = MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAA {
186 account_update,
187 account_update_digest,
188 calls,
189 };
190 MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesA { elt, stack_hash }
191 })
192 .collect();
193 Ok(result)
194}
195
196fn try_tree_from_account_updates_aux(
197 updates: List<InputGraphQLAccountUpdate>,
198) -> Result<List<MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAACallsA>, ConversionError>
199{
200 let mut result = List::new();
201 let mut iter = updates.into_iter().peekable();
202
203 while let Some(account_update) = iter.next() {
204 let depth = account_update.body.call_depth;
205 let mut children = List::new();
206
207 while let Some(next_p) = iter.peek() {
208 if next_p.body.call_depth > depth {
209 children.push_back(iter.next().unwrap());
211 } else {
212 break;
213 }
214 }
215
216 let calls = try_tree_from_account_updates_aux(children)?;
217
218 result.push_back(
219 MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAACallsA {
220 elt: Box::new(MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAA {
221 account_update: account_update.try_into()?, account_update_digest: (),
223 calls,
224 }),
225 stack_hash: (),
226 },
227 );
228 }
229
230 Ok(result)
231}
232
233#[derive(GraphQLObject, Debug)]
234pub struct GraphQLFeePayer {
235 pub body: GraphQLFeePayerBody,
236 pub authorization: String,
237}
238
239#[derive(GraphQLInputObject, Debug)]
240pub struct InputGraphQLFeePayer {
241 pub body: InputGraphQLFeePayerBody,
242 pub authorization: String,
243}
244
245#[derive(GraphQLObject, Debug)]
246pub struct GraphQLFeePayerBody {
247 pub public_key: String,
248 pub fee: String,
249 pub valid_until: Option<String>,
250 pub nonce: String,
251}
252
253#[derive(GraphQLInputObject, Debug)]
254pub struct InputGraphQLFeePayerBody {
255 pub public_key: String,
256 pub fee: String,
257 pub valid_until: Option<String>,
258 pub nonce: String,
259}
260
261#[derive(GraphQLObject, Debug)]
262pub struct GraphQLAccountUpdate {
263 pub body: GraphQLAccountUpdateBody,
264 pub authorization: GraphQLAuthorization,
265}
266
267#[derive(GraphQLInputObject, Debug)]
268pub struct InputGraphQLAccountUpdate {
269 pub body: InputGraphQLAccountUpdateBody,
270 pub authorization: InputGraphQLAuthorization,
271}
272
273#[derive(GraphQLObject, Debug)]
274pub struct GraphQLAuthorization {
275 pub proof: Option<String>,
276 pub signature: Option<String>,
277}
278
279#[derive(GraphQLInputObject, Debug)]
280pub struct InputGraphQLAuthorization {
281 pub proof: Option<String>,
282 pub signature: Option<String>,
283}
284
285impl TryFrom<MinaBaseControlStableV2> for GraphQLAuthorization {
286 type Error = ConversionError;
287
288 fn try_from(value: MinaBaseControlStableV2) -> Result<Self, Self::Error> {
289 let auth = match value {
290 MinaBaseControlStableV2::Signature(signature) => GraphQLAuthorization {
291 proof: None,
292 signature: Some(signature.to_string()),
293 },
294 MinaBaseControlStableV2::Proof(proof) => GraphQLAuthorization {
295 proof: Some(
296 serde_json::to_string_pretty(&proof)?
297 .trim_matches('"')
298 .to_string(),
299 ),
300 signature: None,
301 },
302 MinaBaseControlStableV2::NoneGiven => GraphQLAuthorization {
303 proof: None,
304 signature: None,
305 },
306 };
307 Ok(auth)
308 }
309}
310
311impl TryFrom<InputGraphQLAuthorization> for MinaBaseControlStableV2 {
312 type Error = ConversionError;
313
314 fn try_from(value: InputGraphQLAuthorization) -> Result<Self, Self::Error> {
315 match (value.signature, value.proof) {
316 (Some(signature), None) => {
317 Ok(MinaBaseControlStableV2::Signature(signature.parse()?))
319 }
320 (None, Some(proof)) => {
321 let proof = PicklesProofProofsVerifiedMaxStableV2::deserialize(
323 serde_json::Value::String(proof),
324 )?;
325 Ok(MinaBaseControlStableV2::Proof(Box::new(proof)))
326 }
327 _ => Err(ConversionError::Custom(
328 "Either signature or proof must be provided, but not both".into(),
329 )),
330 }
331 }
332}
333
334#[derive(GraphQLObject, Debug)]
335pub struct GraphQLAccountUpdateBody {
336 pub public_key: String,
337 pub token_id: String,
338 pub use_full_commitment: bool,
339 pub increment_nonce: bool,
340 pub update: GraphQLAccountUpdateUpdate,
341 pub balance_change: GraphQLBalanceChange,
342 pub events: Vec<Vec<String>>,
343 pub actions: Vec<Vec<String>>,
344 pub call_data: String,
345 pub call_depth: i32,
346 pub preconditions: GraphQLPreconditions,
347 pub may_use_token: GraphQLMayUseToken,
348 pub authorization_kind: GraphQLAuthorizationKind,
349 pub implicit_account_creation_fee: bool,
350}
351
352#[derive(GraphQLInputObject, Debug)]
353pub struct InputGraphQLAccountUpdateBody {
354 pub public_key: String,
355 pub token_id: String,
356 pub use_full_commitment: bool,
357 pub increment_nonce: bool,
358 pub update: InputGraphQLAccountUpdateUpdate,
359 pub balance_change: InputGraphQLBalanceChange,
360 pub events: Vec<Vec<String>>,
361 pub actions: Vec<Vec<String>>,
362 pub call_data: String,
363 pub call_depth: i32,
364 pub preconditions: InputGraphQLPreconditions,
365 pub may_use_token: InputGraphQLMayUseToken,
366 pub authorization_kind: InputGraphQLAuthorizationKind,
367 pub implicit_account_creation_fee: bool,
368}
369
370#[derive(GraphQLObject, Debug)]
371pub struct GraphQLAuthorizationKind {
372 pub is_signed: bool,
373 pub is_proved: bool,
374 pub verification_key_hash: Option<String>,
375}
376
377#[derive(GraphQLInputObject, Debug)]
378pub struct InputGraphQLAuthorizationKind {
379 pub is_signed: bool,
380 pub is_proved: bool,
381 pub verification_key_hash: Option<String>,
382}
383
384impl From<MinaBaseAccountUpdateAuthorizationKindStableV1> for GraphQLAuthorizationKind {
385 fn from(value: MinaBaseAccountUpdateAuthorizationKindStableV1) -> Self {
386 match value {
387 MinaBaseAccountUpdateAuthorizationKindStableV1::Signature => GraphQLAuthorizationKind {
388 is_signed: true,
389 is_proved: false,
390 verification_key_hash: None,
391 },
392 MinaBaseAccountUpdateAuthorizationKindStableV1::Proof(proof) => {
393 GraphQLAuthorizationKind {
394 is_signed: false,
395 is_proved: true,
396 verification_key_hash: Some(proof.to_decimal()),
397 }
398 }
399 MinaBaseAccountUpdateAuthorizationKindStableV1::NoneGiven => GraphQLAuthorizationKind {
400 is_signed: false,
401 is_proved: false,
402 verification_key_hash: None,
403 },
404 }
405 }
406}
407
408impl TryFrom<InputGraphQLAuthorizationKind> for MinaBaseAccountUpdateAuthorizationKindStableV1 {
409 type Error = ConversionError;
410 fn try_from(value: InputGraphQLAuthorizationKind) -> Result<Self, Self::Error> {
411 if value.is_signed {
412 return Ok(MinaBaseAccountUpdateAuthorizationKindStableV1::Signature);
413 }
414
415 if value.is_proved {
416 match &value.verification_key_hash {
417 Some(vk_hash) => {
418 let big_int = BigInt::from_decimal(vk_hash)?;
419 return Ok(MinaBaseAccountUpdateAuthorizationKindStableV1::Proof(
420 big_int,
421 ));
422 }
423 None => {
424 return Err(ConversionError::MissingField(
425 "verification_key_hash".to_string(),
426 ));
427 }
428 }
429 }
430
431 Ok(MinaBaseAccountUpdateAuthorizationKindStableV1::NoneGiven)
432 }
433}
434
435#[derive(GraphQLObject, Debug)]
436pub struct GraphQLMayUseToken {
437 pub parents_own_token: bool,
438 pub inherit_from_parent: bool,
439}
440
441#[derive(GraphQLInputObject, Debug)]
442pub struct InputGraphQLMayUseToken {
443 pub parents_own_token: bool,
444 pub inherit_from_parent: bool,
445}
446
447impl From<MinaBaseAccountUpdateMayUseTokenStableV1> for GraphQLMayUseToken {
448 fn from(value: MinaBaseAccountUpdateMayUseTokenStableV1) -> Self {
449 match value {
450 MinaBaseAccountUpdateMayUseTokenStableV1::ParentsOwnToken => GraphQLMayUseToken {
451 parents_own_token: true,
452 inherit_from_parent: false,
453 },
454 MinaBaseAccountUpdateMayUseTokenStableV1::InheritFromParent => GraphQLMayUseToken {
455 parents_own_token: false,
456 inherit_from_parent: true,
457 },
458 MinaBaseAccountUpdateMayUseTokenStableV1::No => GraphQLMayUseToken {
459 parents_own_token: false,
460 inherit_from_parent: false,
461 },
462 }
463 }
464}
465
466impl From<InputGraphQLMayUseToken> for MinaBaseAccountUpdateMayUseTokenStableV1 {
467 fn from(value: InputGraphQLMayUseToken) -> Self {
468 if value.parents_own_token {
469 MinaBaseAccountUpdateMayUseTokenStableV1::ParentsOwnToken
470 } else if value.inherit_from_parent {
471 MinaBaseAccountUpdateMayUseTokenStableV1::InheritFromParent
472 } else {
473 MinaBaseAccountUpdateMayUseTokenStableV1::No
474 }
475 }
476}
477
478#[derive(GraphQLObject, Debug)]
479pub struct GraphQLEvent {
480 pub event: String,
481 pub data: String,
482}
483
484#[derive(GraphQLInputObject, Debug)]
485pub struct InputGraphQLEvent {
486 pub event: String,
487 pub data: String,
488}
489
490#[derive(GraphQLObject, Debug)]
491pub struct GraphQLAction {
492 pub action: String,
493 pub data: String,
494}
495
496#[derive(GraphQLInputObject, Debug)]
497pub struct InputGraphQLAction {
498 pub action: String,
499 pub data: String,
500}
501
502#[derive(GraphQLObject, Debug)]
503pub struct GraphQLPreconditions {
504 pub network: GraphQLPreconditionsNetwork,
505 pub account: GraphQLPreconditionsAccount,
506 pub valid_while: Option<GraphQLPreconditionsNetworkBounds>,
507}
508
509#[derive(GraphQLInputObject, Debug)]
510pub struct InputGraphQLPreconditions {
511 pub network: InputGraphQLPreconditionsNetwork,
512 pub account: InputGraphQLPreconditionsAccount,
513 pub valid_while: Option<InputGraphQLPreconditionsNetworkBounds>,
514}
515
516#[derive(GraphQLObject, Debug)]
517pub struct GraphQLPreconditionsAccount {
518 pub balance: Option<GraphQLPreconditionsNetworkBounds>,
519 pub nonce: Option<GraphQLPreconditionsNetworkBounds>,
520 pub receipt_chain_hash: Option<String>,
521 pub delegate: Option<String>,
522 pub state: Vec<Option<String>>,
523 pub action_state: Option<String>,
524 pub proved_state: Option<bool>,
525 pub is_new: Option<bool>,
526}
527
528#[derive(GraphQLInputObject, Debug)]
529pub struct InputGraphQLPreconditionsAccount {
530 pub balance: Option<InputGraphQLPreconditionsNetworkBounds>,
531 pub nonce: Option<InputGraphQLPreconditionsNetworkBounds>,
532 pub receipt_chain_hash: Option<String>,
533 pub delegate: Option<String>,
534 pub state: Vec<Option<String>>,
535 pub action_state: Option<String>,
536 pub proved_state: Option<bool>,
537 pub is_new: Option<bool>,
538}
539
540impl From<MinaBaseAccountUpdateAccountPreconditionStableV1> for GraphQLPreconditionsAccount {
541 fn from(value: MinaBaseAccountUpdateAccountPreconditionStableV1) -> Self {
542 Self {
543 balance: if let MinaBaseZkappPreconditionAccountStableV2Balance::Check(v) =
544 value.0.balance
545 {
546 Some(GraphQLPreconditionsNetworkBounds {
547 upper: v.upper.as_u64().to_string(),
548 lower: v.lower.as_u64().to_string(),
549 })
550 } else {
551 None
552 },
553 nonce: if let MinaBaseZkappPreconditionProtocolStateStableV1Length::Check(v) =
554 value.0.nonce
555 {
556 Some(GraphQLPreconditionsNetworkBounds {
557 upper: v.upper.as_u32().to_string(),
558 lower: v.lower.as_u32().to_string(),
559 })
560 } else {
561 None
562 },
563 receipt_chain_hash:
564 if let MinaBaseZkappPreconditionAccountStableV2ReceiptChainHash::Check(v) =
565 value.0.receipt_chain_hash
566 {
567 Some(v.to_decimal())
568 } else {
569 None
570 },
571 delegate: if let MinaBaseZkappPreconditionAccountStableV2Delegate::Check(v) =
572 value.0.delegate
573 {
574 Some(v.to_string())
575 } else {
576 None
577 },
578 state: value
579 .0
580 .state
581 .clone()
582 .iter()
583 .map(|v| {
584 if let MinaBaseZkappPreconditionAccountStableV2StateA::Check(state_value) = v {
585 Some(state_value.to_decimal())
586 } else {
587 None
588 }
589 })
590 .collect(),
591 action_state: if let MinaBaseZkappPreconditionAccountStableV2StateA::Check(value) =
592 value.0.action_state
593 {
594 Some(value.to_decimal())
595 } else {
596 None
597 },
598 proved_state: if let MinaBaseZkappPreconditionAccountStableV2ProvedState::Check(v) =
599 value.0.proved_state
600 {
601 Some(v)
602 } else {
603 None
604 },
605 is_new: if let MinaBaseZkappPreconditionAccountStableV2ProvedState::Check(v) =
606 value.0.is_new
607 {
608 Some(v)
609 } else {
610 None
611 },
612 }
613 }
614}
615
616impl TryFrom<InputGraphQLPreconditionsAccount>
617 for MinaBaseAccountUpdateAccountPreconditionStableV1
618{
619 type Error = ConversionError;
620 fn try_from(value: InputGraphQLPreconditionsAccount) -> Result<Self, Self::Error> {
621 let state: Result<Vec<_>, _> = value
622 .state
623 .iter()
624 .map(|v| {
625 if let Some(state) = v {
626 BigInt::from_decimal(state)
627 .map(MinaBaseZkappPreconditionAccountStableV2StateA::Check)
628 } else {
629 Ok(MinaBaseZkappPreconditionAccountStableV2StateA::Ignore)
630 }
631 })
632 .collect();
633
634 let state = state?;
635 Ok(Self(MinaBaseZkappPreconditionAccountStableV2 {
636 balance: if let Some(balance) = value.balance {
637 MinaBaseZkappPreconditionAccountStableV2Balance::Check(
638 MinaBaseZkappPreconditionAccountStableV2BalanceA {
639 lower: CurrencyBalanceStableV1(CurrencyAmountStableV1(
640 balance.lower.parse::<u64>()?.into(),
641 )),
642 upper: CurrencyBalanceStableV1(CurrencyAmountStableV1(
643 balance.upper.parse::<u64>()?.into(),
644 )),
645 },
646 )
647 } else {
648 MinaBaseZkappPreconditionAccountStableV2Balance::Ignore
649 },
650 nonce: if let Some(nonce) = value.nonce {
651 MinaBaseZkappPreconditionProtocolStateStableV1Length::Check(
652 MinaBaseZkappPreconditionProtocolStateStableV1LengthA {
653 lower: (nonce.lower.parse::<u32>()?).into(),
654 upper: (nonce.upper.parse::<u32>()?).into(),
655 },
656 )
657 } else {
658 MinaBaseZkappPreconditionProtocolStateStableV1Length::Ignore
659 },
660 receipt_chain_hash: if let Some(receipt_chain_hash) = value.receipt_chain_hash {
661 MinaBaseZkappPreconditionAccountStableV2ReceiptChainHash::Check(
662 MinaBaseReceiptChainHashStableV1(BigInt::from_decimal(&receipt_chain_hash)?),
663 )
664 } else {
665 MinaBaseZkappPreconditionAccountStableV2ReceiptChainHash::Ignore
666 },
667 delegate: if let Some(delegate) = value.delegate {
668 MinaBaseZkappPreconditionAccountStableV2Delegate::Check(
669 AccountPublicKey::from_str(&delegate)?.into(),
670 )
671 } else {
672 MinaBaseZkappPreconditionAccountStableV2Delegate::Ignore
673 },
674 state: PaddedSeq(
675 state
676 .try_into()
677 .map_err(|_| ConversionError::InvalidLength)?,
678 ),
679 action_state: if let Some(action_state) = value.action_state {
680 MinaBaseZkappPreconditionAccountStableV2StateA::Check(BigInt::from_decimal(
681 &action_state,
682 )?)
683 } else {
684 MinaBaseZkappPreconditionAccountStableV2StateA::Ignore
685 },
686 proved_state: if let Some(proved_state) = value.proved_state {
687 MinaBaseZkappPreconditionAccountStableV2ProvedState::Check(proved_state)
688 } else {
689 MinaBaseZkappPreconditionAccountStableV2ProvedState::Ignore
690 },
691 is_new: if let Some(is_new) = value.is_new {
692 MinaBaseZkappPreconditionAccountStableV2ProvedState::Check(is_new)
693 } else {
694 MinaBaseZkappPreconditionAccountStableV2ProvedState::Ignore
695 },
696 }))
697 }
698}
699#[derive(GraphQLObject, Debug)]
700pub struct GraphQLPreconditionsNetwork {
701 pub snarked_ledger_hash: Option<String>,
702 pub blockchain_length: Option<GraphQLPreconditionsNetworkBounds>,
703 pub min_window_density: Option<GraphQLPreconditionsNetworkBounds>,
704 pub total_currency: Option<GraphQLPreconditionsNetworkBounds>,
705 pub global_slot_since_genesis: Option<GraphQLPreconditionsNetworkBounds>,
706 pub staking_epoch_data: GraphQLPreconditionsNetworkEpochData,
707 pub next_epoch_data: GraphQLPreconditionsNetworkEpochData,
708}
709
710#[derive(GraphQLInputObject, Debug)]
711pub struct InputGraphQLPreconditionsNetwork {
712 pub snarked_ledger_hash: Option<String>,
713 pub blockchain_length: Option<InputGraphQLPreconditionsNetworkBounds>,
714 pub min_window_density: Option<InputGraphQLPreconditionsNetworkBounds>,
715 pub total_currency: Option<InputGraphQLPreconditionsNetworkBounds>,
716 pub global_slot_since_genesis: Option<InputGraphQLPreconditionsNetworkBounds>,
717 pub staking_epoch_data: InputGraphQLPreconditionsNetworkEpochData,
718 pub next_epoch_data: InputGraphQLPreconditionsNetworkEpochData,
719}
720
721#[derive(GraphQLObject, Debug)]
722pub struct GraphQLPreconditionsNetworkEpochData {
723 pub ledger: GraphQLPreconditionsNetworkLedger,
724 pub seed: Option<String>,
725 pub start_checkpoint: Option<String>,
726 pub lock_checkpoint: Option<String>,
727 pub epoch_length: Option<GraphQLPreconditionsNetworkBounds>,
728}
729
730#[derive(GraphQLInputObject, Debug)]
731pub struct InputGraphQLPreconditionsNetworkEpochData {
732 pub ledger: InputGraphQLPreconditionsNetworkLedger,
733 pub seed: Option<String>,
734 pub start_checkpoint: Option<String>,
735 pub lock_checkpoint: Option<String>,
736 pub epoch_length: Option<InputGraphQLPreconditionsNetworkBounds>,
737}
738
739#[derive(GraphQLObject, Debug)]
740pub struct GraphQLPreconditionsNetworkLedger {
741 pub hash: Option<String>,
742 pub total_currency: Option<GraphQLPreconditionsNetworkBounds>,
743}
744
745#[derive(GraphQLInputObject, Debug)]
746pub struct InputGraphQLPreconditionsNetworkLedger {
747 pub hash: Option<String>,
748 pub total_currency: Option<InputGraphQLPreconditionsNetworkBounds>,
749}
750#[derive(GraphQLObject, Debug)]
751pub struct GraphQLPreconditionsNetworkBounds {
752 pub upper: String,
753 pub lower: String,
754}
755
756#[derive(GraphQLInputObject, Debug)]
757pub struct InputGraphQLPreconditionsNetworkBounds {
758 pub upper: String,
759 pub lower: String,
760}
761
762impl From<MinaBaseZkappPreconditionProtocolStateEpochDataStableV1>
763 for GraphQLPreconditionsNetworkEpochData
764{
765 fn from(value: MinaBaseZkappPreconditionProtocolStateEpochDataStableV1) -> Self {
766 Self {
767 ledger: GraphQLPreconditionsNetworkLedger::from(value.ledger),
768 seed: if let MinaBaseZkappPreconditionProtocolStateEpochDataStableV1EpochSeed::Check(v) = value.seed {
769 Some(v.to_string())
770 } else {
771 None
772 },
773 start_checkpoint: if let MinaBaseZkappPreconditionProtocolStateEpochDataStableV1StartCheckpoint::Check(v) = value.start_checkpoint {
774 Some(v.to_string())
775 } else {
776 None
777 },
778 lock_checkpoint: if let MinaBaseZkappPreconditionProtocolStateEpochDataStableV1StartCheckpoint::Check(v) = value.lock_checkpoint {
779 Some(v.to_string())
780 } else {
781 None
782 },
783 epoch_length: if let MinaBaseZkappPreconditionProtocolStateStableV1Length::Check(v) = value.epoch_length {
784 Some(GraphQLPreconditionsNetworkBounds {
785 upper: v.upper.as_u32().to_string(),
786 lower: v.lower.as_u32().to_string(),
787 })
788 } else {
789 None
790 },
791 }
792 }
793}
794
795impl TryFrom<InputGraphQLPreconditionsNetworkEpochData>
796 for MinaBaseZkappPreconditionProtocolStateEpochDataStableV1
797{
798 type Error = ConversionError;
799 fn try_from(value: InputGraphQLPreconditionsNetworkEpochData) -> Result<Self, Self::Error> {
800 Ok(Self {
801 ledger: value.ledger.try_into()?,
802 seed: if let Some(seed) = value.seed {
803 MinaBaseZkappPreconditionProtocolStateEpochDataStableV1EpochSeed::Check(
804 seed.parse()?,
805 )
806 } else {
807 MinaBaseZkappPreconditionProtocolStateEpochDataStableV1EpochSeed::Ignore
808 },
809 start_checkpoint: if let Some(start_checkpoint) = value.start_checkpoint {
810 MinaBaseZkappPreconditionProtocolStateEpochDataStableV1StartCheckpoint::Check(
811 start_checkpoint.parse()?,
812 )
813 } else {
814 MinaBaseZkappPreconditionProtocolStateEpochDataStableV1StartCheckpoint::Ignore
815 },
816 lock_checkpoint: if let Some(lock_checkpoint) = value.lock_checkpoint {
817 MinaBaseZkappPreconditionProtocolStateEpochDataStableV1StartCheckpoint::Check(
818 lock_checkpoint.parse()?,
819 )
820 } else {
821 MinaBaseZkappPreconditionProtocolStateEpochDataStableV1StartCheckpoint::Ignore
822 },
823 epoch_length: if let Some(epoch_length) = value.epoch_length {
824 MinaBaseZkappPreconditionProtocolStateStableV1Length::Check(
825 MinaBaseZkappPreconditionProtocolStateStableV1LengthA {
826 lower: (epoch_length.lower.parse::<u32>()?).into(),
827 upper: (epoch_length.upper.parse::<u32>()?).into(),
828 },
829 )
830 } else {
831 MinaBaseZkappPreconditionProtocolStateStableV1Length::Ignore
832 },
833 })
834 }
835}
836impl From<MinaBaseZkappPreconditionProtocolStateEpochDataStableV1EpochLedger>
837 for GraphQLPreconditionsNetworkLedger
838{
839 fn from(value: MinaBaseZkappPreconditionProtocolStateEpochDataStableV1EpochLedger) -> Self {
840 Self {
841 hash: if let MinaBaseZkappPreconditionProtocolStateStableV1SnarkedLedgerHash::Check(v) =
842 value.hash
843 {
844 Some(v.to_string())
845 } else {
846 None
847 },
848 total_currency: if let MinaBaseZkappPreconditionProtocolStateStableV1Amount::Check(v) =
849 value.total_currency
850 {
851 Some(GraphQLPreconditionsNetworkBounds {
852 upper: v.upper.as_u64().to_string(),
853 lower: v.lower.as_u64().to_string(),
854 })
855 } else {
856 None
857 },
858 }
859 }
860}
861
862impl TryFrom<InputGraphQLPreconditionsNetworkLedger>
863 for MinaBaseZkappPreconditionProtocolStateEpochDataStableV1EpochLedger
864{
865 type Error = ConversionError;
866 fn try_from(value: InputGraphQLPreconditionsNetworkLedger) -> Result<Self, Self::Error> {
867 Ok(Self {
868 hash: if let Some(hash) = value.hash {
869 MinaBaseZkappPreconditionProtocolStateStableV1SnarkedLedgerHash::Check(
870 hash.parse()?,
871 )
872 } else {
873 MinaBaseZkappPreconditionProtocolStateStableV1SnarkedLedgerHash::Ignore
874 },
875 total_currency: if let Some(total_currency) = value.total_currency {
876 MinaBaseZkappPreconditionProtocolStateStableV1Amount::Check(
877 MinaBaseZkappPreconditionProtocolStateStableV1AmountA {
878 lower: CurrencyAmountStableV1(
879 (total_currency.lower.parse::<u64>()?).into(),
880 ),
881 upper: CurrencyAmountStableV1(
882 (total_currency.upper.parse::<u64>()?).into(),
883 ),
884 },
885 )
886 } else {
887 MinaBaseZkappPreconditionProtocolStateStableV1Amount::Ignore
888 },
889 })
890 }
891}
892
893impl From<MinaBaseZkappPreconditionProtocolStateStableV1> for GraphQLPreconditionsNetwork {
894 fn from(value: MinaBaseZkappPreconditionProtocolStateStableV1) -> Self {
895 Self {
896 snarked_ledger_hash:
897 if let MinaBaseZkappPreconditionProtocolStateStableV1SnarkedLedgerHash::Check(v) =
898 value.snarked_ledger_hash
899 {
900 Some(v.to_string())
901 } else {
902 None
903 },
904 blockchain_length: if let MinaBaseZkappPreconditionProtocolStateStableV1Length::Check(
905 v,
906 ) = value.blockchain_length
907 {
908 Some(GraphQLPreconditionsNetworkBounds {
909 upper: v.upper.as_u32().to_string(),
910 lower: v.lower.as_u32().to_string(),
911 })
912 } else {
913 None
914 },
915 min_window_density: if let MinaBaseZkappPreconditionProtocolStateStableV1Length::Check(
916 v,
917 ) = value.min_window_density
918 {
919 Some(GraphQLPreconditionsNetworkBounds {
920 upper: v.upper.as_u32().to_string(),
921 lower: v.lower.as_u32().to_string(),
922 })
923 } else {
924 None
925 },
926 total_currency: if let MinaBaseZkappPreconditionProtocolStateStableV1Amount::Check(v) =
927 value.total_currency
928 {
929 Some(GraphQLPreconditionsNetworkBounds {
930 upper: v.upper.as_u64().to_string(),
931 lower: v.lower.as_u64().to_string(),
932 })
933 } else {
934 None
935 },
936 global_slot_since_genesis:
937 if let MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlot::Check(v) =
938 value.global_slot_since_genesis
939 {
940 Some(GraphQLPreconditionsNetworkBounds {
941 upper: v.upper.as_u32().to_string(),
942 lower: v.lower.as_u32().to_string(),
943 })
944 } else {
945 None
946 },
947 staking_epoch_data: GraphQLPreconditionsNetworkEpochData::from(
948 value.staking_epoch_data,
949 ),
950 next_epoch_data: GraphQLPreconditionsNetworkEpochData::from(value.next_epoch_data),
951 }
952 }
953}
954
955impl TryFrom<InputGraphQLPreconditionsNetwork> for MinaBaseZkappPreconditionProtocolStateStableV1 {
956 type Error = ConversionError;
957 fn try_from(value: InputGraphQLPreconditionsNetwork) -> Result<Self, Self::Error> {
958 Ok(Self {
959 snarked_ledger_hash: if let Some(snarked_ledger_hash) = value.snarked_ledger_hash {
960 MinaBaseZkappPreconditionProtocolStateStableV1SnarkedLedgerHash::Check(
961 snarked_ledger_hash.parse()?,
962 )
963 } else {
964 MinaBaseZkappPreconditionProtocolStateStableV1SnarkedLedgerHash::Ignore
965 },
966 blockchain_length: if let Some(blockchain_length) = value.blockchain_length {
967 MinaBaseZkappPreconditionProtocolStateStableV1Length::Check(
968 MinaBaseZkappPreconditionProtocolStateStableV1LengthA {
969 lower: (blockchain_length.lower.parse::<u32>()?).into(),
970 upper: (blockchain_length.upper.parse::<u32>()?).into(),
971 },
972 )
973 } else {
974 MinaBaseZkappPreconditionProtocolStateStableV1Length::Ignore
975 },
976 min_window_density: if let Some(min_window_density) = value.min_window_density {
977 MinaBaseZkappPreconditionProtocolStateStableV1Length::Check(
978 MinaBaseZkappPreconditionProtocolStateStableV1LengthA {
979 lower: (min_window_density.lower.parse::<u32>()?).into(),
980 upper: (min_window_density.upper.parse::<u32>()?).into(),
981 },
982 )
983 } else {
984 MinaBaseZkappPreconditionProtocolStateStableV1Length::Ignore
985 },
986 total_currency: if let Some(total_currency) = value.total_currency {
987 MinaBaseZkappPreconditionProtocolStateStableV1Amount::Check(
988 MinaBaseZkappPreconditionProtocolStateStableV1AmountA {
989 lower: CurrencyAmountStableV1(
990 (total_currency.lower.parse::<u64>()?).into(),
991 ),
992 upper: CurrencyAmountStableV1(
993 (total_currency.upper.parse::<u64>()?).into(),
994 ),
995 },
996 )
997 } else {
998 MinaBaseZkappPreconditionProtocolStateStableV1Amount::Ignore
999 },
1000 global_slot_since_genesis: if let Some(global_slot_since_genesis) =
1001 value.global_slot_since_genesis
1002 {
1003 MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlot::Check(
1004 MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlotA {
1005 lower: MinaNumbersGlobalSlotSinceGenesisMStableV1::SinceGenesis(
1006 (global_slot_since_genesis.lower.parse::<u32>()?).into(),
1007 ),
1008 upper: MinaNumbersGlobalSlotSinceGenesisMStableV1::SinceGenesis(
1009 (global_slot_since_genesis.upper.parse::<u32>()?).into(),
1010 ),
1011 },
1012 )
1013 } else {
1014 MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlot::Ignore
1015 },
1016 staking_epoch_data: value.staking_epoch_data.try_into()?,
1017 next_epoch_data: value.next_epoch_data.try_into()?,
1018 })
1019 }
1020}
1021
1022#[derive(GraphQLObject, Debug)]
1023pub struct GraphQLAccountUpdateUpdate {
1024 pub app_state: Vec<Option<String>>,
1025 pub delegate: Option<String>,
1026 pub verification_key: Option<GraphQLVerificationKey>,
1027 pub permissions: Option<GraphQLAccountUpdateUpdatePermissions>,
1028 pub zkapp_uri: Option<String>,
1029 pub token_symbol: Option<String>,
1030 pub timing: Option<GraphQLTiming>,
1031 pub voting_for: Option<String>,
1032}
1033
1034#[derive(GraphQLObject, Debug)]
1035pub struct GraphQLVerificationKey {
1036 pub data: String,
1037 pub hash: String,
1038}
1039
1040#[derive(GraphQLInputObject, Debug)]
1041pub struct InputGraphQLAccountUpdateUpdate {
1042 pub app_state: Vec<Option<String>>,
1043 pub delegate: Option<String>,
1044 pub verification_key: Option<InputGraphQLVerificationKey>,
1045 pub permissions: Option<InputGraphQLAccountUpdateUpdatePermissions>,
1046 pub zkapp_uri: Option<String>,
1047 pub token_symbol: Option<String>,
1048 pub timing: Option<InputGraphQLTiming>,
1049 pub voting_for: Option<String>,
1050}
1051
1052#[derive(GraphQLInputObject, Debug)]
1053pub struct InputGraphQLVerificationKey {
1054 pub data: String,
1055 pub hash: String,
1056}
1057
1058#[derive(GraphQLObject, Debug)]
1059pub struct GraphQLAccountUpdateUpdatePermissions {
1060 pub edit_state: String,
1061 pub access: String,
1062 pub send: String,
1063 pub receive: String,
1064 pub set_delegate: String,
1065 pub set_permissions: String,
1066 pub set_verification_key: GraphQLSetVerificationKeyPermissions,
1067 pub set_zkapp_uri: String,
1068 pub edit_action_state: String,
1069 pub set_token_symbol: String,
1070 pub set_timing: String,
1071 pub set_voting_for: String,
1072 pub increment_nonce: String,
1073}
1074
1075#[derive(GraphQLObject, Debug)]
1076pub struct GraphQLSetVerificationKeyPermissions {
1077 pub auth: String,
1078 pub txn_version: String,
1079}
1080
1081#[derive(GraphQLInputObject, Debug)]
1082pub struct InputGraphQLAccountUpdateUpdatePermissions {
1083 pub edit_state: String,
1084 pub access: String,
1085 pub send: String,
1086 pub receive: String,
1087 pub set_delegate: String,
1088 pub set_permissions: String,
1089 pub set_verification_key: InputGraphQLSetVerificationKeyPermissions,
1090 pub set_zkapp_uri: String,
1091 pub edit_action_state: String,
1092 pub set_token_symbol: String,
1093 pub set_timing: String,
1094 pub set_voting_for: String,
1095 pub increment_nonce: String,
1096}
1097
1098#[derive(GraphQLInputObject, Debug)]
1099pub struct InputGraphQLSetVerificationKeyPermissions {
1100 pub auth: String,
1101 pub txn_version: String,
1102}
1103
1104impl From<MinaBasePermissionsStableV2> for GraphQLAccountUpdateUpdatePermissions {
1105 fn from(value: MinaBasePermissionsStableV2) -> Self {
1106 Self {
1107 edit_state: value.edit_state.to_string(),
1108 access: value.access.to_string(),
1109 send: value.send.to_string(),
1110 receive: value.receive.to_string(),
1111 set_delegate: value.set_delegate.to_string(),
1112 set_permissions: value.set_permissions.to_string(),
1113 set_verification_key: GraphQLSetVerificationKeyPermissions {
1114 auth: value.set_verification_key.0.to_string(),
1115 txn_version: value.set_verification_key.1.as_u32().to_string(),
1116 },
1117 set_zkapp_uri: value.set_zkapp_uri.to_string(),
1118 edit_action_state: value.edit_action_state.to_string(),
1119 set_token_symbol: value.set_token_symbol.to_string(),
1120 set_timing: value.set_timing.to_string(),
1121 set_voting_for: value.set_voting_for.to_string(),
1122 increment_nonce: value.increment_nonce.to_string(),
1123 }
1124 }
1125}
1126
1127impl TryFrom<InputGraphQLAccountUpdateUpdatePermissions> for MinaBasePermissionsStableV2 {
1128 type Error = ConversionError;
1129 fn try_from(value: InputGraphQLAccountUpdateUpdatePermissions) -> Result<Self, Self::Error> {
1130 Ok(Self {
1131 edit_state: value.edit_state.parse()?,
1132 access: value.access.parse()?,
1133 send: value.send.parse()?,
1134 receive: value.receive.parse()?,
1135 set_delegate: value.set_delegate.parse()?,
1136 set_permissions: value.set_permissions.parse()?,
1137 set_verification_key: (
1138 value.set_verification_key.auth.parse()?,
1139 value
1140 .set_verification_key
1141 .txn_version
1142 .parse::<u32>()?
1143 .into(),
1144 ),
1145 set_zkapp_uri: value.set_zkapp_uri.parse()?,
1146 edit_action_state: value.edit_action_state.parse()?,
1147 set_token_symbol: value.set_token_symbol.parse()?,
1148 set_timing: value.set_timing.parse()?,
1149 set_voting_for: value.set_voting_for.parse()?,
1150 increment_nonce: value.increment_nonce.parse()?,
1151 })
1152 }
1153}
1154
1155#[derive(GraphQLObject, Debug)]
1156pub struct GraphQLBalanceChange {
1157 pub magnitude: String,
1158 pub sgn: String,
1159}
1160
1161#[derive(GraphQLInputObject, Debug)]
1162pub struct InputGraphQLBalanceChange {
1163 pub magnitude: String,
1164 pub sgn: String,
1165}
1166
1167#[derive(GraphQLObject, Debug)]
1168pub struct GraphQLFailureReason {
1169 pub index: String,
1170 pub failures: Vec<String>,
1171}
1172
1173impl From<MinaStateBlockchainStateValueStableV2SignedAmount> for GraphQLBalanceChange {
1174 fn from(value: MinaStateBlockchainStateValueStableV2SignedAmount) -> Self {
1175 Self {
1176 magnitude: value.magnitude.as_u64().to_string(),
1177 sgn: value.sgn.to_string(),
1178 }
1179 }
1180}
1181
1182impl TryFrom<InputGraphQLBalanceChange> for MinaStateBlockchainStateValueStableV2SignedAmount {
1183 type Error = ConversionError;
1184 fn try_from(value: InputGraphQLBalanceChange) -> Result<Self, Self::Error> {
1185 Ok(Self {
1186 magnitude: CurrencyAmountStableV1(value.magnitude.parse::<u64>()?.into()),
1187 sgn: value
1188 .sgn
1189 .parse()
1190 .map_err(|_| ConversionError::WrongVariant)?,
1191 })
1192 }
1193}
1194
1195impl From<MinaBaseAccountUpdatePreconditionsStableV1> for GraphQLPreconditions {
1196 fn from(value: MinaBaseAccountUpdatePreconditionsStableV1) -> Self {
1197 Self {
1198 network: GraphQLPreconditionsNetwork::from(value.network),
1199 account: GraphQLPreconditionsAccount::from(value.account),
1200 valid_while: if let MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlot::Check(v) =
1201 value.valid_while
1202 {
1203 Some(GraphQLPreconditionsNetworkBounds {
1204 upper: v.upper.as_u32().to_string(),
1205 lower: v.lower.as_u32().to_string(),
1206 })
1207 } else {
1208 None
1209 },
1210 }
1211 }
1212}
1213
1214impl TryFrom<InputGraphQLPreconditions> for MinaBaseAccountUpdatePreconditionsStableV1 {
1215 type Error = ConversionError;
1216 fn try_from(value: InputGraphQLPreconditions) -> Result<Self, Self::Error> {
1217 Ok(Self {
1218 network: value.network.try_into()?,
1219 account: value.account.try_into()?,
1220 valid_while: if let Some(v) = value.valid_while {
1221 MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlot::Check(
1222 MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlotA {
1223 upper: MinaNumbersGlobalSlotSinceGenesisMStableV1::SinceGenesis(
1224 (v.upper.parse::<u32>()?).into(),
1225 ),
1226 lower: MinaNumbersGlobalSlotSinceGenesisMStableV1::SinceGenesis(
1227 (v.lower.parse::<u32>()?).into(),
1228 ),
1229 },
1230 )
1231 } else {
1232 MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlot::Ignore
1233 },
1234 })
1235 }
1236}
1237
1238impl TryFrom<MinaBaseVerificationKeyWireStableV1> for GraphQLVerificationKey {
1239 type Error = ConversionError;
1240
1241 fn try_from(value: MinaBaseVerificationKeyWireStableV1) -> Result<Self, Self::Error> {
1242 Ok(Self {
1243 data: value.to_base64()?,
1244 hash: VerificationKey::try_from(&value)
1245 .map_err(|_| ConversionError::InvalidBigInt)?
1246 .hash()
1247 .to_decimal(),
1248 })
1249 }
1250}
1251
1252impl TryFrom<InputGraphQLVerificationKey> for MinaBaseVerificationKeyWireStableV1 {
1253 type Error = ConversionError;
1254
1255 fn try_from(value: InputGraphQLVerificationKey) -> Result<Self, Self::Error> {
1256 Ok(Self::from_base64(&value.data)?)
1257 }
1258}
1259
1260impl TryFrom<MinaBaseAccountUpdateUpdateStableV1> for GraphQLAccountUpdateUpdate {
1261 type Error = ConversionError;
1262
1263 fn try_from(value: MinaBaseAccountUpdateUpdateStableV1) -> Result<Self, Self::Error> {
1264 Ok(Self {
1265 app_state: value
1266 .app_state
1267 .0
1268 .into_iter()
1269 .map(|v| {
1270 if let MinaBaseAccountUpdateUpdateStableV1AppStateA::Set(value) = v {
1271 Some(value.to_decimal())
1272 } else {
1273 None
1274 }
1275 })
1276 .collect(),
1277 delegate: if let MinaBaseAccountUpdateUpdateStableV1Delegate::Set(v) = value.delegate {
1278 Some(v.to_string())
1279 } else {
1280 None
1281 },
1282 verification_key: if let MinaBaseAccountUpdateUpdateStableV1VerificationKey::Set(v) =
1283 value.verification_key
1284 {
1285 Some(GraphQLVerificationKey::try_from(*v)?)
1286 } else {
1287 None
1288 },
1289 permissions: if let MinaBaseAccountUpdateUpdateStableV1Permissions::Set(v) =
1290 value.permissions
1291 {
1292 Some(GraphQLAccountUpdateUpdatePermissions::from(*v))
1293 } else {
1294 None
1295 },
1296 zkapp_uri: if let MinaBaseAccountUpdateUpdateStableV1ZkappUri::Set(v) = value.zkapp_uri
1297 {
1298 Some(v.to_string())
1299 } else {
1300 None
1301 },
1302 token_symbol: if let MinaBaseAccountUpdateUpdateStableV1TokenSymbol::Set(v) =
1303 value.token_symbol
1304 {
1305 Some(v.to_string())
1306 } else {
1307 None
1308 },
1309 timing: if let MinaBaseAccountUpdateUpdateStableV1Timing::Set(v) = value.timing {
1310 Some(GraphQLTiming::from(*v))
1311 } else {
1312 None
1313 },
1314 voting_for: if let MinaBaseAccountUpdateUpdateStableV1VotingFor::Set(v) =
1315 value.voting_for
1316 {
1317 Some(v.to_string())
1318 } else {
1319 None
1320 },
1321 })
1322 }
1323}
1324
1325impl TryFrom<InputGraphQLAccountUpdateUpdate> for MinaBaseAccountUpdateUpdateStableV1 {
1326 type Error = ConversionError;
1327 fn try_from(value: InputGraphQLAccountUpdateUpdate) -> Result<Self, Self::Error> {
1328 let app_state: Vec<_> = value
1329 .app_state
1330 .iter()
1331 .map(|v| {
1332 if let Some(v) = v {
1333 Ok(MinaBaseAccountUpdateUpdateStableV1AppStateA::Set(
1334 BigInt::from_decimal(v)?,
1335 ))
1336 } else {
1337 Ok(MinaBaseAccountUpdateUpdateStableV1AppStateA::Keep)
1338 }
1339 })
1340 .collect::<Result<Vec<_>, ConversionError>>()?;
1341 Ok(Self {
1342 app_state: PaddedSeq(
1343 app_state
1344 .try_into()
1345 .map_err(|_| ConversionError::InvalidLength)?,
1346 ),
1347 delegate: if let Some(delegate) = value.delegate {
1348 MinaBaseAccountUpdateUpdateStableV1Delegate::Set(
1349 AccountPublicKey::from_str(&delegate)?.into(),
1350 )
1351 } else {
1352 MinaBaseAccountUpdateUpdateStableV1Delegate::Keep
1353 },
1354 verification_key: if let Some(vk) = value.verification_key {
1355 MinaBaseAccountUpdateUpdateStableV1VerificationKey::Set(Box::new(
1356 MinaBaseVerificationKeyWireStableV1::try_from(vk)?,
1357 ))
1358 } else {
1359 MinaBaseAccountUpdateUpdateStableV1VerificationKey::Keep
1360 },
1361 permissions: if let Some(permissions) = value.permissions {
1362 MinaBaseAccountUpdateUpdateStableV1Permissions::Set(Box::new(
1363 MinaBasePermissionsStableV2::try_from(permissions)?,
1364 ))
1365 } else {
1366 MinaBaseAccountUpdateUpdateStableV1Permissions::Keep
1367 },
1368 zkapp_uri: if let Some(zkapp_uri) = value.zkapp_uri {
1369 MinaBaseAccountUpdateUpdateStableV1ZkappUri::Set(ZkAppUri::from(zkapp_uri.as_str()))
1370 } else {
1371 MinaBaseAccountUpdateUpdateStableV1ZkappUri::Keep
1372 },
1373 token_symbol: if let Some(token_symbol) = value.token_symbol {
1374 MinaBaseAccountUpdateUpdateStableV1TokenSymbol::Set(TokenSymbol::from(
1375 token_symbol.as_str(),
1376 ))
1377 } else {
1378 MinaBaseAccountUpdateUpdateStableV1TokenSymbol::Keep
1379 },
1380 timing: if let Some(timing) = value.timing {
1381 MinaBaseAccountUpdateUpdateStableV1Timing::Set(Box::new(
1382 MinaBaseAccountUpdateUpdateTimingInfoStableV1::try_from(timing)?,
1383 ))
1384 } else {
1385 MinaBaseAccountUpdateUpdateStableV1Timing::Keep
1386 },
1387 voting_for: if let Some(voting_for) = value.voting_for {
1388 MinaBaseAccountUpdateUpdateStableV1VotingFor::Set(StateHash::from_str(&voting_for)?)
1389 } else {
1390 MinaBaseAccountUpdateUpdateStableV1VotingFor::Keep
1391 },
1392 })
1393 }
1394}
1395
1396impl From<MinaBaseAccountUpdateFeePayerStableV1> for GraphQLFeePayer {
1397 fn from(value: MinaBaseAccountUpdateFeePayerStableV1) -> Self {
1398 Self {
1399 authorization: value.authorization.to_string(),
1400 body: GraphQLFeePayerBody {
1401 public_key: value.body.public_key.to_string(),
1402 fee: value.body.fee.as_u64().to_string(),
1403 valid_until: value.body.valid_until.map(|v| v.as_u32().to_string()),
1404 nonce: value.body.nonce.to_string(),
1405 },
1406 }
1407 }
1408}
1409
1410impl TryFrom<InputGraphQLFeePayer> for MinaBaseAccountUpdateFeePayerStableV1 {
1411 type Error = ConversionError;
1412
1413 fn try_from(value: InputGraphQLFeePayer) -> Result<Self, Self::Error> {
1414 Ok(Self {
1415 authorization: value.authorization.parse()?,
1416 body: MinaBaseAccountUpdateBodyFeePayerStableV1 {
1417 public_key: value.body.public_key.parse()?,
1418 fee: CurrencyFeeStableV1(value.body.fee.parse::<u64>()?.into()),
1419 valid_until: value
1420 .body
1421 .valid_until
1422 .map(|v| -> Result<_, ConversionError> {
1423 Ok(MinaNumbersGlobalSlotSinceGenesisMStableV1::SinceGenesis(
1424 v.parse::<u32>()?.into(),
1425 ))
1426 })
1427 .transpose()?,
1428 nonce: value.body.nonce.parse::<u32>()?.into(),
1429 },
1430 })
1431 }
1432}
1433
1434impl TryFrom<MinaBaseAccountUpdateTStableV1> for GraphQLAccountUpdate {
1435 type Error = ConversionError;
1436
1437 fn try_from(value: MinaBaseAccountUpdateTStableV1) -> Result<Self, Self::Error> {
1438 Ok(Self {
1439 body: GraphQLAccountUpdateBody {
1440 public_key: value.body.public_key.to_string(),
1441 token_id: value.body.token_id.to_string(),
1442 use_full_commitment: value.body.use_full_commitment,
1443 increment_nonce: value.body.increment_nonce,
1444 update: GraphQLAccountUpdateUpdate::try_from(value.body.update)?,
1445 balance_change: GraphQLBalanceChange::from(value.body.balance_change),
1446 events: value
1447 .body
1448 .events
1449 .0
1450 .into_iter()
1451 .map(|v| v.into_iter().map(|i| i.to_decimal()).collect())
1452 .collect(),
1453 actions: value
1454 .body
1455 .actions
1456 .0
1457 .into_iter()
1458 .map(|v| v.into_iter().map(|i| i.to_decimal()).collect())
1459 .collect(),
1460 call_data: value.body.call_data.to_decimal(),
1461 call_depth: 0,
1463 preconditions: GraphQLPreconditions::from(value.body.preconditions),
1464 may_use_token: GraphQLMayUseToken::from(value.body.may_use_token),
1465 authorization_kind: GraphQLAuthorizationKind::from(value.body.authorization_kind),
1466 implicit_account_creation_fee: value.body.implicit_account_creation_fee,
1467 },
1468 authorization: GraphQLAuthorization::try_from(value.authorization)?,
1469 })
1470 }
1471}
1472
1473impl TryFrom<InputGraphQLAccountUpdate> for MinaBaseAccountUpdateTStableV1 {
1474 type Error = ConversionError;
1475
1476 fn try_from(value: InputGraphQLAccountUpdate) -> Result<Self, Self::Error> {
1477 Ok(Self {
1478 body: MinaBaseAccountUpdateBodyStableV1 {
1479 public_key: value.body.public_key.parse()?,
1480 token_id: value.body.token_id.parse()?,
1481 update: value.body.update.try_into()?,
1482 balance_change: value.body.balance_change.try_into()?,
1483 increment_nonce: value.body.increment_nonce,
1484 events: MinaBaseAccountUpdateBodyEventsStableV1(
1485 value
1486 .body
1487 .events
1488 .into_iter()
1489 .map(|v| {
1490 v.into_iter()
1491 .map(|i| BigInt::from_decimal(&i).map_err(ConversionError::from))
1492 .collect::<Result<_, _>>()
1493 })
1494 .collect::<Result<_, _>>()?,
1495 ),
1496 actions: MinaBaseAccountUpdateBodyEventsStableV1(
1497 value
1498 .body
1499 .actions
1500 .into_iter()
1501 .map(|v| {
1502 v.into_iter()
1503 .map(|i| BigInt::from_decimal(&i).map_err(ConversionError::from))
1504 .collect::<Result<_, _>>()
1505 })
1506 .collect::<Result<_, _>>()?,
1507 ),
1508 call_data: BigInt::from_decimal(&value.body.call_data)?,
1509 preconditions: value.body.preconditions.try_into()?,
1510 use_full_commitment: value.body.use_full_commitment,
1511 implicit_account_creation_fee: value.body.implicit_account_creation_fee,
1512 may_use_token: value.body.may_use_token.into(),
1513 authorization_kind: value.body.authorization_kind.try_into()?,
1514 },
1515 authorization: value.authorization.try_into()?,
1516 })
1517 }
1518}
1519
1520impl TryFrom<InputGraphQLTiming> for MinaBaseAccountUpdateUpdateTimingInfoStableV1 {
1521 type Error = ConversionError;
1522
1523 fn try_from(value: InputGraphQLTiming) -> Result<Self, Self::Error> {
1524 let cliff_time: u32 = value.cliff_time.try_into()?;
1525 let vesting_period: u32 = value.vesting_period.try_into()?;
1526 Ok(Self {
1527 initial_minimum_balance: CurrencyBalanceStableV1(CurrencyAmountStableV1(
1528 value.initial_minimum_balance.parse::<u64>()?.into(),
1529 )),
1530 cliff_time: MinaNumbersGlobalSlotSinceGenesisMStableV1::SinceGenesis(cliff_time.into()),
1531 cliff_amount: CurrencyAmountStableV1(value.cliff_amount.parse::<u64>()?.into()),
1532 vesting_period: MinaNumbersGlobalSlotSpanStableV1::GlobalSlotSpan(
1533 vesting_period.into(),
1534 ),
1535 vesting_increment: CurrencyAmountStableV1(
1536 value.vesting_increment.parse::<u64>()?.into(),
1537 ),
1538 })
1539 }
1540}
1541
1542#[cfg(test)]
1543mod test {
1544 use std::str::FromStr;
1545
1546 use mina_p2p_messages::{
1547 binprot::BinProtRead,
1548 v2::{
1549 MinaBaseSignedCommandMemoStableV1, MinaBaseUserCommandStableV2,
1550 MinaBaseZkappCommandTStableV1WireStableV1,
1551 },
1552 };
1553
1554 use super::*;
1555
1556 #[test]
1557 fn test_empty_memo() {
1558 use ledger::scan_state::transaction_logic::Memo;
1559
1560 let expected = "E4YM2vTHhWEg66xpj52JErHUBU4pZ1yageL4TVDDpTTSsv8mK6YaH";
1561 let empty_memo = Memo::from_str("").unwrap();
1562 let mina_empty_memo = MinaBaseSignedCommandMemoStableV1::from(&empty_memo);
1563 assert_eq!(mina_empty_memo.to_base58check(), expected);
1564 let empty_memo = Memo::empty();
1565 let mina_empty_memo = MinaBaseSignedCommandMemoStableV1::from(&empty_memo);
1566 assert_eq!(mina_empty_memo.to_base58check(), expected);
1567 }
1568
1569 #[test]
1570 fn test_zkapp_from_input() {
1571 let bytes = include_bytes!("../../../../tests/files/zkapps/valid_zkapp.bin");
1572 let zkapp =
1573 MinaBaseZkappCommandTStableV1WireStableV1::binprot_read(&mut bytes.as_slice()).unwrap();
1574
1575 let serialized_valid = serde_json::to_string_pretty(&zkapp).unwrap();
1576
1577 std::fs::write("zkapp_valid.json", &serialized_valid).unwrap();
1578
1579 let from_input = create_input_graphql_zkapp();
1580 let converted: MinaBaseUserCommandStableV2 = from_input.zkapp_command.try_into().unwrap();
1581 if let MinaBaseUserCommandStableV2::ZkappCommand(zkapp_cmd) = converted {
1582 let serialized_converted = serde_json::to_string_pretty(&zkapp_cmd).unwrap();
1583 std::fs::write("zkapp_converted.json", &serialized_converted).unwrap();
1584 assert_eq!(serialized_valid, serialized_converted);
1585 } else {
1586 unreachable!()
1587 }
1588 }
1589
1590 #[test]
1591 fn test_authorization_kind() {
1592 let kind = InputGraphQLAuthorizationKind {
1593 is_signed: false,
1594 is_proved: true,
1595 verification_key_hash: Some(
1596 "19951435866906059835892103359374709356309230417850637795098911039647240505427"
1597 .to_string(),
1598 ),
1599 };
1600 let converted: Result<MinaBaseAccountUpdateAuthorizationKindStableV1, ConversionError> =
1601 kind.try_into();
1602
1603 assert!(converted.is_ok());
1604 }
1605
1606 #[test]
1607 fn test_authorization_proof() {
1608 let proof = InputGraphQLAuthorization {
1609 signature: None,
1610 proof: Some(
1611 include_str!("../../../../tests/files/zkapps/proof_string.txt").to_string(),
1612 ),
1613 };
1614 let converted: Result<MinaBaseControlStableV2, _> = proof.try_into();
1615 assert!(converted.is_ok());
1616 }
1617
1618 fn create_input_graphql_zkapp() -> InputGraphQLZkapp {
1619 InputGraphQLZkapp {
1620 zkapp_command: InputGraphQLZkappCommand {
1621 memo: Some("E4YM2vTHhWEg66xpj52JErHUBU4pZ1yageL4TVDDpTTSsv8mK6YaH".to_string()),
1622 fee_payer: InputGraphQLFeePayer {
1623 body: InputGraphQLFeePayerBody {
1624 public_key: "B62qpD75xH5R19wxZG2uz8whNsHPTioVoYcPV3zfjjSbzTmaHQHKKEV".to_string(),
1625 fee: "117000000".to_string(),
1626 valid_until: None,
1627 nonce: "1128".to_string(),
1628 },
1629 authorization: "7mX5Lwu2bdnJPc4DJu7CkwTSR5behoKH8yZh7myCGgYfib5Sq3dfgPQY6LcXdrpQma1NvoLC5i7HLFEQZTnkBFcn96TP57JF".to_string(),
1630 },
1631 account_updates: vec![
1632 InputGraphQLAccountUpdate {
1633 body: InputGraphQLAccountUpdateBody {
1634 call_depth: 0,
1635 public_key: "B62qpD75xH5R19wxZG2uz8whNsHPTioVoYcPV3zfjjSbzTmaHQHKKEV".to_string(),
1636 token_id: "wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf".to_string(),
1637 update: InputGraphQLAccountUpdateUpdate {
1638 app_state: vec![
1639 None,
1640 None,
1641 None,
1642 None,
1643 None,
1644 None,
1645 None,
1646 None,
1647 ],
1648 delegate: None,
1649 verification_key: None,
1650 permissions: None,
1651 zkapp_uri: None,
1652 token_symbol: None,
1653 timing: None,
1654 voting_for: None,
1655 },
1656 balance_change: InputGraphQLBalanceChange {
1657 magnitude: "1000000000".to_string(),
1658 sgn: "Negative".to_string(),
1659 },
1660 increment_nonce: false,
1661 events: vec![],
1662 actions: vec![],
1663 call_data: "0".to_string(),
1664 preconditions: InputGraphQLPreconditions {
1665 network: InputGraphQLPreconditionsNetwork {
1666 snarked_ledger_hash: None,
1667 blockchain_length: None,
1668 min_window_density: None,
1669 total_currency: None,
1670 global_slot_since_genesis: None,
1671 staking_epoch_data: InputGraphQLPreconditionsNetworkEpochData {
1672 ledger: InputGraphQLPreconditionsNetworkLedger {
1673 hash: None,
1674 total_currency: None,
1675 },
1676 seed: None,
1677 start_checkpoint: None,
1678 lock_checkpoint: None,
1679 epoch_length: None,
1680 },
1681 next_epoch_data: InputGraphQLPreconditionsNetworkEpochData {
1682 ledger: InputGraphQLPreconditionsNetworkLedger {
1683 hash: None,
1684 total_currency: None,
1685 },
1686 seed: None,
1687 start_checkpoint: None,
1688 lock_checkpoint: None,
1689 epoch_length: None,
1690 },
1691 },
1692 account: InputGraphQLPreconditionsAccount {
1693 balance: None,
1694 nonce: None,
1695 receipt_chain_hash: None,
1696 delegate: None,
1697 state: vec![
1698 None, None, None, None, None, None, None, None
1699 ],
1700 action_state: None,
1701 proved_state: None,
1702 is_new: None,
1703 },
1704 valid_while: None,
1705 },
1706 use_full_commitment: true,
1707 implicit_account_creation_fee: false,
1708 may_use_token: InputGraphQLMayUseToken {
1709 parents_own_token: false,
1710 inherit_from_parent: false,
1711 },
1712 authorization_kind: InputGraphQLAuthorizationKind {
1713 is_signed: true,
1714 is_proved: false,
1715 verification_key_hash: None,
1716 },
1717 },
1718 authorization: InputGraphQLAuthorization {
1719 proof: None,
1720 signature: Some("7mX5Lwu2bdnJPc4DJu7CkwTSR5behoKH8yZh7myCGgYfib5Sq3dfgPQY6LcXdrpQma1NvoLC5i7HLFEQZTnkBFcn96TP57JF".to_string()),
1721 },
1722 },
1723 InputGraphQLAccountUpdate {
1724 body: InputGraphQLAccountUpdateBody {
1725 call_depth: 0,
1726 public_key: "B62qqKAQh8M61uvuw3tjJsmRgsEvzRm84Nc9MwXTF3zoqFRZ86rV8qk".to_string(),
1727 token_id: "wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf".to_string(),
1728 update: InputGraphQLAccountUpdateUpdate {
1729 app_state: vec![
1730 Some("1".to_string()),
1731 Some("0".to_string()),
1732 Some("0".to_string()),
1733 Some("0".to_string()),
1734 Some("0".to_string()),
1735 Some("0".to_string()),
1736 Some("0".to_string()),
1737 Some("0".to_string()),
1738 ],
1739 delegate: None,
1740 verification_key: Some(InputGraphQLVerificationKey {
1741 data: "AACcenc1yLdGBm4xtUN1dpModROI0zovuy5rz2a94vfdBgG1C75BqviU4vw6JUYqODF8n9ivtfeU5s9PcpEGIP0htil2mfx8v2DB5RuNQ7VxJWkha0TSnJJsOl0FxhjldBbOY3tUZzZxHpPhHOKHz/ZAXRYFIsf2x+7boXC0iPurEX9VcnaJIq+YxxmnSfeYYxHkjxO9lrDBqjXzd5AHMnYyjTPC69B+5In7AOGS6R+A/g3/aR/MKDa4eDVrnsF9Oy/Ay8ahic2sSAZvtn08MdRyk/jm2cLlJbeAAad6Xyz/H9l7JrkbVwDMMPxvHVHs27tNoJCzIlrRzB7pg3ju9aQOu4h3thDr+WSgFQWKvcRPeL7f3TFjIr8WZ2457RgMcTwXwORKbqJCcyKVNOE+FlNwVkOKER+WIpC0OlgGuayPFwQQkbb91jaRlJvahfwkbF2+AJmDnavmNpop9T+/Xak1adXIrsRPeOjC+qIKxIbGimoMOoYzYlevKA80LnJ7HC0IxR+yNLvoSYxDDPNRD+OCCxk5lM2h8IDUiCNWH4FZNJ+doiigKjyZlu/xZ7jHcX7qibu/32KFTX85DPSkQM8dAEkH+vlkHmyXGLF4+xOVKeM0ihV5OEQrOABcgfTkbRsyxNInUBh0WiQyALE2ctjvkRCiE2P24bjFA8SgFmTM7gAKR89XcqLS/NP7lwCEej/L8q8R7sKGMCXmgFYluWH4JBSPDgvMxScfjFS33oBNb7po8cLnAORzohXoYTSgztklD0mKn6EegLbkLtwwr9ObsLz3m7fp/3wkNWFRkY5xzSZN1VybbQbmpyQNCpxd/kdDsvlszqlowkyC8HnKbhnvE0Mrz3ZIk4vSs/UGBSXAoESFCFCPcTq11TCOhE5rumMJErv5LusDHJgrBtQUMibLU9A1YbF7SPDAR2QZd0yx3waAC2F3xF+U682SOKF7oCZl2OICysRHqH+rZ604UfdGG0zWRuP2yg6kfGwcGQbO1ql40WrWTiFhbxxdKC7Gbz4y9Sb7q5EsPt6Z1AIn34/nXB/IWfC0gg/OgfPQTR7uxiTo2OOwjHni1f4KhT4rEmDAQn6ty6/ZRKHPWjUaAREbEw3tC36fI09hCYjjVTEmMAFTApk/tMUu0tC9Dt/vfDgXAlDJBwN5Y2Pt60qWY92skizVcWyWBxp5A8e4cVu3iToxOGUbSHzawovjubcH7qWjIZoghZJ16QB1c0ryiAfHB48OHhs2p/JZWz8Dp7kfcPkeg2Of2NbupJlNVMLIH4IGWaPAscBRkZ+F4oLqOhJ5as7fAzzU8PQdeZi0YgssGDJVmNEHP61I16KZNcxQqR0EUVwhyMmYmpVjvtfhHi/6I3TgYCmfnm6GL2sN144vMWg/gJ+p9a4GcEA0+gK3oCcKcwkq5rm+1Oxo9LWLp92Bdxq3iqfoIFmJ/ANGSbHF8StVmlVsP8zA+xuHylyiww/Lercce7cq0YA5PtYS3ge9IDYwXckBUXb5ikD3alrrv5mvMu6itB7ix2f8lbiF9Fkmc4Bk2ycIWXJDCuBN+2sTFqzUeoT6xY8XWaOcnDvqOgSm/CCSv38umiOE2jEpsKYxhRc6W70UJkrzd3hr2DiSF1I2B+krpUVK1GeOdCLC5sl7YPzk+pF8183uI9wse6UTlqIiroKqsggzLBy/IjAfxS0BxFy5zywXqp+NogFkoTEJmR5MaqOkPfap+OsD1lGScY6+X4WW/HqCWrmA3ZTqDGngQMTGXLCtl6IS/cQpihS1NRbNqOtKTaCB9COQu0oz6RivBlywuaj3MKUdmbQ2gVDj+SGQItCNaXawyPSBjB9VT+68SoJVySQsYPCuEZCb0V/40n/a7RAbyrnNjP+2HwD7p27Pl1RSzqq35xiPdnycD1UeEPLpx/ON65mYCkn+KLQZmkqPio+vA2KmJngWTx+ol4rVFimGm76VT0xCFDsu2K0YX0yoLNH4u2XfmT9NR8gGfkVRCnnNjlbgHQmEwC75+GmEJ5DjD3d+s6IXTQ60MHvxbTHHlnfmPbgKn2SAI0uVoewKC9GyK6dSaboLw3C48jl0E2kyc+7umhCk3kEeWmt//GSjRNhoq+B+mynXiOtgFs/Am2v1TBjSb+6tcijsf5tFJmeGxlCjJnTdNWBkSHpMoo6OFkkpA6/FBAUHLSM7Yv8oYyd0GtwF5cCwQ6aRTbl9oG/mUn5Q92OnDMQcUjpgEho0Dcp2OqZyyxqQSPrbIIZZQrS2HkxBgjcfcSTuSHo7ONqlRjLUpO5yS95VLGXBLLHuCiIMGT+DW6DoJRtRIS+JieVWBoX0YsWgYInXrVlWUv6gDng5AyVFkUIFwZk7/3mVAgvXO83ArVKA4S747jT60w5bgV4Jy55slDM=".to_string(),
1742 hash: "11640126627177324946637007967436400725357874055180801746732941023691529117236".to_string(),
1743 }),
1744 permissions: Some(InputGraphQLAccountUpdateUpdatePermissions {
1745 edit_state: "Proof".to_string(),
1746 access: "Proof".to_string(),
1747 send: "Proof".to_string(),
1748 receive: "Proof".to_string(),
1749 set_delegate: "Proof".to_string(),
1750 set_permissions: "Proof".to_string(),
1751 set_verification_key: InputGraphQLSetVerificationKeyPermissions {
1752 auth: "Proof".to_string(),
1753 txn_version: "3".to_string(),
1754 },
1755 set_zkapp_uri: "Proof".to_string(),
1756 edit_action_state: "Proof".to_string(),
1757 set_token_symbol: "Proof".to_string(),
1758 set_timing: "Proof".to_string(),
1759 set_voting_for: "Proof".to_string(),
1760 increment_nonce: "Proof".to_string(),
1761 }),
1762 zkapp_uri: None,
1763 token_symbol: None,
1764 timing: None,
1765 voting_for: None,
1766 },
1767 balance_change: InputGraphQLBalanceChange {
1768 magnitude: "0".to_string(),
1769 sgn: "Positive".to_string(),
1770 },
1771 increment_nonce: true,
1772 events: vec![],
1773 actions: vec![],
1774 call_data: "0".to_string(),
1775 preconditions: InputGraphQLPreconditions {
1776 network: InputGraphQLPreconditionsNetwork {
1777 snarked_ledger_hash: None,
1778 blockchain_length: None,
1779 min_window_density: None,
1780 total_currency: None,
1781 global_slot_since_genesis: None,
1782 staking_epoch_data: InputGraphQLPreconditionsNetworkEpochData {
1783 ledger: InputGraphQLPreconditionsNetworkLedger {
1784 hash: None,
1785 total_currency: None,
1786 },
1787 seed: None,
1788 start_checkpoint: None,
1789 lock_checkpoint: None,
1790 epoch_length: None,
1791 },
1792 next_epoch_data: InputGraphQLPreconditionsNetworkEpochData {
1793 ledger: InputGraphQLPreconditionsNetworkLedger {
1794 hash: None,
1795 total_currency: None,
1796 },
1797 seed: None,
1798 start_checkpoint: None,
1799 lock_checkpoint: None,
1800 epoch_length: None,
1801 },
1802 },
1803 account: InputGraphQLPreconditionsAccount {
1804 balance: None,
1805 nonce: Some(InputGraphQLPreconditionsNetworkBounds {
1806 upper: "0".to_string(),
1807 lower: "0".to_string(),
1808 }),
1809 receipt_chain_hash: None,
1810 delegate: None,
1811 state: vec![
1812 None, None, None, None, None, None, None, None
1813 ],
1814 action_state: None,
1815 proved_state: Some(false),
1816 is_new: None,
1817 },
1818 valid_while: None,
1819 },
1820 use_full_commitment: false,
1821 implicit_account_creation_fee: false,
1822 may_use_token: InputGraphQLMayUseToken {
1823 parents_own_token: false,
1824 inherit_from_parent: false,
1825 },
1826 authorization_kind: InputGraphQLAuthorizationKind {
1827 is_signed: true,
1828 is_proved: false,
1829 verification_key_hash: None,
1830 },
1831 },
1832 authorization: InputGraphQLAuthorization {
1833 proof: None,
1834 signature: Some("7mXFnDxZBE5iXBfw9LRPXST3sSodXAdTJSWFqX3hBoDA3wv5s2s9TLMDCXgatMvMH4bDttAFyJuezWmbSA81FXeMFZgqcxtt".to_string()),
1835 },
1836 },
1837 ],
1838 },
1839 }
1840 }
1841
1842 #[test]
1843 pub fn test_bigint_to_decimal() {
1844 let bigint = BigInt::from_decimal("1").unwrap();
1845 let decimal = serde_json::to_string(&bigint).unwrap();
1846 assert_eq!(
1847 decimal,
1848 "\"0x0000000000000000000000000000000000000000000000000000000000000001\"".to_string()
1849 );
1850 }
1851}