1#![allow(clippy::type_complexity)]
2
3use super::{Account, AccountId, AuthRequired, TokenId, VerificationKeyWire};
4use crate::{
5 proofs::{
6 field::FieldWitness,
7 transaction::{make_group, InnerCurve, PlonkVerificationKeyEvals},
8 },
9 scan_state::currency::{Amount, Balance, Nonce, Slot, SlotSpan, TxnVersion},
10 AccountIndex, Permissions, ProofVerified, ReceiptChainHash, SetVerificationKey, Timing,
11 TokenSymbol, VerificationKey, VotingFor, ZkAppAccount,
12};
13use ark_ec::short_weierstrass::Affine;
14use ark_ff::{Field, PrimeField};
15use mina_curves::pasta::Fp;
16use mina_p2p_messages::{
17 bigint::{BigInt, InvalidBigInt},
18 binprot,
19 pseq::PaddedSeq,
20 v2::{
21 self, MinaBaseAccountBinableArgStableV2, MinaBaseAccountIdDigestStableV1,
22 MinaBaseAccountIdStableV2, MinaBaseAccountIndexStableV1, MinaBaseAccountTimingStableV2,
23 MinaBasePermissionsAuthRequiredStableV2, MinaBasePermissionsStableV2,
24 MinaBaseReceiptChainHashStableV1, MinaBaseVerificationKeyWireStableV1,
25 MinaBaseVerificationKeyWireStableV1WrapIndex, NonZeroCurvePointUncompressedStableV1,
26 PicklesBaseProofsVerifiedStableV1, TokenIdKeyHash,
27 },
28};
29
30impl binprot::BinProtRead for TokenId {
31 fn binprot_read<R: std::io::Read + ?Sized>(r: &mut R) -> Result<Self, binprot::Error>
32 where
33 Self: Sized,
34 {
35 let token_id = TokenIdKeyHash::binprot_read(r)?;
36 let token_id: MinaBaseAccountIdDigestStableV1 = token_id.into_inner();
37 token_id
38 .try_into()
39 .map_err(|e| binprot::Error::CustomError(Box::new(e)))
40 }
41}
42
43impl binprot::BinProtWrite for TokenId {
44 fn binprot_write<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
45 let token_id: MinaBaseAccountIdDigestStableV1 = self.clone().into();
46 let token_id: TokenIdKeyHash = token_id.into();
47 token_id.binprot_write(w)?;
48 Ok(())
49 }
50}
51
52impl From<TokenId> for TokenIdKeyHash {
53 fn from(value: TokenId) -> Self {
54 MinaBaseAccountIdDigestStableV1(value.0.into()).into()
55 }
56}
57
58impl From<TokenIdKeyHash> for TokenId {
59 fn from(value: TokenIdKeyHash) -> Self {
60 value.inner().try_into().unwrap()
61 }
62}
63
64impl<F: FieldWitness> TryFrom<(BigInt, BigInt)> for InnerCurve<F>
65where
66 F: Field + From<BigInt>,
67{
68 type Error = InvalidBigInt;
69
70 fn try_from((x, y): (BigInt, BigInt)) -> Result<Self, Self::Error> {
71 Ok(Self::of_affine(make_group::<F>(
72 x.to_field()?,
73 y.to_field()?,
74 )))
75 }
76}
77
78impl<F: FieldWitness> From<InnerCurve<F>> for (BigInt, BigInt)
79where
80 F: Field + Into<BigInt>,
81{
82 fn from(fps: InnerCurve<F>) -> Self {
83 let Affine { x, y, .. } = fps.to_affine();
84 (x.into(), y.into())
85 }
86}
87
88impl<F: FieldWitness> TryFrom<&(BigInt, BigInt)> for InnerCurve<F>
89where
90 F: Field,
91{
92 type Error = InvalidBigInt;
93
94 fn try_from((x, y): &(BigInt, BigInt)) -> Result<Self, Self::Error> {
95 Ok(Self::of_affine(make_group::<F>(
96 x.to_field()?,
97 y.to_field()?,
98 )))
99 }
100}
101
102impl<F: FieldWitness> From<&InnerCurve<F>> for (BigInt, BigInt)
103where
104 F: Field + Into<BigInt>,
105{
106 fn from(fps: &InnerCurve<F>) -> Self {
107 let Affine { x, y, .. } = fps.to_affine();
108 (x.into(), y.into())
109 }
110}
111
112impl binprot::BinProtRead for AccountId {
113 fn binprot_read<R: std::io::Read + ?Sized>(r: &mut R) -> Result<Self, binprot::Error>
114 where
115 Self: Sized,
116 {
117 let account_id = MinaBaseAccountIdStableV2::binprot_read(r)?;
118 account_id
119 .try_into()
120 .map_err(|e| binprot::Error::CustomError(Box::new(e)))
121 }
122}
123
124impl binprot::BinProtWrite for AccountId {
125 fn binprot_write<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
126 let account_id: MinaBaseAccountIdStableV2 = self.clone().into();
127 account_id.binprot_write(w)?;
128 Ok(())
129 }
130}
131
132pub fn array_into<'a, T, U, const N: usize>(value: &'a [T; N]) -> [U; N]
133where
134 T: 'a,
135 U: From<&'a T>,
136{
137 value.each_ref().map(|value| U::from(value))
138}
139
140pub fn array_into_with<'a, T, U, F, const N: usize>(value: &'a [T; N], fun: F) -> [U; N]
141where
142 T: 'a,
143 F: Fn(&T) -> U,
144{
145 value.each_ref().map(fun)
146}
147
148pub fn try_array_into_with<'a, T, E, U, F, const N: usize>(
151 value: &'a [T; N],
152 fun: F,
153) -> Result<[U; N], E>
154where
155 T: 'a,
156 F: Fn(&T) -> Result<U, E>,
157 U: std::fmt::Debug,
158{
159 Ok(value
160 .iter()
161 .map(fun)
162 .collect::<Result<Vec<_>, _>>()?
163 .try_into()
164 .unwrap()) }
166
167impl TryFrom<&MinaBaseVerificationKeyWireStableV1> for VerificationKey {
168 type Error = InvalidBigInt;
169
170 fn try_from(vk: &MinaBaseVerificationKeyWireStableV1) -> Result<Self, Self::Error> {
171 let MinaBaseVerificationKeyWireStableV1 {
172 max_proofs_verified,
173 actual_wrap_domain_size,
174 wrap_index,
175 } = vk;
176
177 Ok(VerificationKey {
178 max_proofs_verified: match max_proofs_verified {
179 PicklesBaseProofsVerifiedStableV1::N0 => ProofVerified::N0,
180 PicklesBaseProofsVerifiedStableV1::N1 => ProofVerified::N1,
181 PicklesBaseProofsVerifiedStableV1::N2 => ProofVerified::N2,
182 },
183 actual_wrap_domain_size: match actual_wrap_domain_size {
184 PicklesBaseProofsVerifiedStableV1::N0 => ProofVerified::N0,
185 PicklesBaseProofsVerifiedStableV1::N1 => ProofVerified::N1,
186 PicklesBaseProofsVerifiedStableV1::N2 => ProofVerified::N2,
187 },
188 wrap_index: Box::new(wrap_index.try_into()?),
189 wrap_vk: None,
190 })
191 }
192}
193
194impl TryFrom<&MinaBaseVerificationKeyWireStableV1WrapIndex> for PlonkVerificationKeyEvals<Fp> {
195 type Error = InvalidBigInt;
196
197 fn try_from(value: &MinaBaseVerificationKeyWireStableV1WrapIndex) -> Result<Self, Self::Error> {
198 let MinaBaseVerificationKeyWireStableV1WrapIndex {
199 sigma_comm,
200 coefficients_comm,
201 generic_comm,
202 psm_comm,
203 complete_add_comm,
204 mul_comm,
205 emul_comm,
206 endomul_scalar_comm,
207 } = value;
208
209 let sigma = try_array_into_with(sigma_comm, |s| s.try_into())?;
210 let coefficients = try_array_into_with(coefficients_comm, |s| s.try_into())?;
211
212 Ok(PlonkVerificationKeyEvals {
213 sigma,
214 coefficients,
215 generic: generic_comm.try_into()?,
216 psm: psm_comm.try_into()?,
217 complete_add: complete_add_comm.try_into()?,
218 mul: mul_comm.try_into()?,
219 emul: emul_comm.try_into()?,
220 endomul_scalar: endomul_scalar_comm.try_into()?,
221 })
222 }
223}
224impl TryFrom<MinaBaseVerificationKeyWireStableV1WrapIndex> for PlonkVerificationKeyEvals<Fp> {
225 type Error = InvalidBigInt;
226
227 fn try_from(value: MinaBaseVerificationKeyWireStableV1WrapIndex) -> Result<Self, Self::Error> {
228 (&value).try_into()
229 }
230}
231
232impl From<&VerificationKey> for MinaBaseVerificationKeyWireStableV1 {
233 fn from(vk: &VerificationKey) -> Self {
234 let VerificationKey {
235 max_proofs_verified,
236 actual_wrap_domain_size,
237 wrap_index,
238 wrap_vk: _, } = vk;
240
241 Self {
242 max_proofs_verified: match max_proofs_verified {
243 super::ProofVerified::N0 => PicklesBaseProofsVerifiedStableV1::N0,
244 super::ProofVerified::N1 => PicklesBaseProofsVerifiedStableV1::N1,
245 super::ProofVerified::N2 => PicklesBaseProofsVerifiedStableV1::N2,
246 },
247 actual_wrap_domain_size: match actual_wrap_domain_size {
248 super::ProofVerified::N0 => PicklesBaseProofsVerifiedStableV1::N0,
249 super::ProofVerified::N1 => PicklesBaseProofsVerifiedStableV1::N1,
250 super::ProofVerified::N2 => PicklesBaseProofsVerifiedStableV1::N2,
251 },
252 wrap_index: wrap_index.as_ref().into(),
253 }
254 }
255}
256
257impl From<&MinaBaseAccountTimingStableV2> for Timing {
258 fn from(timing: &MinaBaseAccountTimingStableV2) -> Self {
259 match timing {
260 MinaBaseAccountTimingStableV2::Untimed => Timing::Untimed,
261 MinaBaseAccountTimingStableV2::Timed {
262 initial_minimum_balance,
263 cliff_time,
264 cliff_amount,
265 vesting_period,
266 vesting_increment,
267 } => Timing::Timed {
268 initial_minimum_balance: Balance::from_u64(initial_minimum_balance.as_u64()),
269 cliff_time: Slot::from_u32(cliff_time.as_u32()),
270 cliff_amount: Amount::from_u64(cliff_amount.as_u64()),
271 vesting_period: SlotSpan::from_u32(vesting_period.as_u32()),
272 vesting_increment: Amount::from_u64(vesting_increment.as_u64()),
273 },
274 }
275 }
276}
277
278impl From<&Timing> for MinaBaseAccountTimingStableV2 {
279 fn from(timing: &Timing) -> Self {
280 use mina_p2p_messages::v2::*;
281
282 match timing {
283 super::Timing::Untimed => MinaBaseAccountTimingStableV2::Untimed,
284 super::Timing::Timed {
285 initial_minimum_balance,
286 cliff_time,
287 cliff_amount,
288 vesting_period,
289 vesting_increment,
290 } => MinaBaseAccountTimingStableV2::Timed {
291 initial_minimum_balance: CurrencyBalanceStableV1(CurrencyAmountStableV1(
292 UnsignedExtendedUInt64Int64ForVersionTagsStableV1(
293 initial_minimum_balance.as_u64().into(),
294 ),
295 )),
296 cliff_time: cliff_time.into(),
297 cliff_amount: CurrencyAmountStableV1(
298 UnsignedExtendedUInt64Int64ForVersionTagsStableV1(cliff_amount.as_u64().into()),
299 ),
300 vesting_period: vesting_period.into(),
301 vesting_increment: CurrencyAmountStableV1(
302 UnsignedExtendedUInt64Int64ForVersionTagsStableV1(
303 vesting_increment.as_u64().into(),
304 ),
305 ),
306 },
307 }
308 }
309}
310
311impl From<&Account> for mina_p2p_messages::v2::MinaBaseAccountBinableArgStableV2 {
312 fn from(acc: &Account) -> Self {
313 use mina_p2p_messages::v2::*;
314
315 Self {
316 public_key: (&acc.public_key).into(),
317 token_id: (&acc.token_id).into(),
318 token_symbol: acc.token_symbol.as_bytes().into(),
319 balance: CurrencyBalanceStableV1(CurrencyAmountStableV1(
320 UnsignedExtendedUInt64Int64ForVersionTagsStableV1(acc.balance.as_u64().into()),
321 )),
322 nonce: UnsignedExtendedUInt32StableV1(acc.nonce.as_u32().into()),
323 receipt_chain_hash: MinaBaseReceiptChainHashStableV1(acc.receipt_chain_hash.0.into()),
324 delegate: acc.delegate.as_ref().map(|delegate| {
325 let delegate: NonZeroCurvePointUncompressedStableV1 = delegate.into();
326 delegate.into()
327 }),
328 voting_for: DataHashLibStateHashStableV1(acc.voting_for.0.into()).into(),
329 timing: (&acc.timing).into(),
330 permissions: (&acc.permissions).into(),
331 zkapp: acc.zkapp.as_ref().map(|zkapp| {
332 let s = zkapp.app_state;
333 let app_state = MinaBaseZkappStateValueStableV1(PaddedSeq(s.map(|v| v.into())));
334
335 let verification_key = zkapp.verification_key.as_ref().map(|vk| vk.vk().into());
336
337 let seq = zkapp.action_state;
338 let action_state = PaddedSeq(seq.map(|v| v.into()));
339
340 MinaBaseZkappAccountStableV2 {
341 app_state,
342 verification_key,
343 zkapp_version: MinaNumbersNatMake32StableV1(UnsignedExtendedUInt32StableV1(
344 zkapp.zkapp_version.into(),
345 )),
346 action_state,
347 last_action_slot: (&zkapp.last_action_slot).into(),
348 proved_state: zkapp.proved_state,
349 zkapp_uri: (&zkapp.zkapp_uri).into(),
350 }
351 }),
352 }
353 }
354}
355impl From<Account> for mina_p2p_messages::v2::MinaBaseAccountBinableArgStableV2 {
356 fn from(account: Account) -> Self {
357 (&account).into()
358 }
359}
360
361impl From<&AuthRequired> for mina_p2p_messages::v2::MinaBasePermissionsAuthRequiredStableV2 {
362 fn from(perms: &AuthRequired) -> Self {
363 match perms {
364 AuthRequired::None => Self::None,
365 AuthRequired::Either => Self::Either,
366 AuthRequired::Proof => Self::Proof,
367 AuthRequired::Signature => Self::Signature,
368 AuthRequired::Impossible => Self::Impossible,
369 AuthRequired::Both => panic!("doesn't exist in `develop` branch"),
370 }
371 }
372}
373
374impl From<&PlonkVerificationKeyEvals<Fp>>
375 for mina_p2p_messages::v2::MinaBaseVerificationKeyWireStableV1WrapIndex
376{
377 fn from(vk: &PlonkVerificationKeyEvals<Fp>) -> Self {
378 let sigma = PaddedSeq(array_into(&vk.sigma));
379 let coef = PaddedSeq(array_into(&vk.coefficients));
380
381 Self {
382 sigma_comm: sigma,
383 coefficients_comm: coef,
384 generic_comm: (&vk.generic).into(),
385 psm_comm: (&vk.psm).into(),
386 complete_add_comm: (&vk.complete_add).into(),
387 mul_comm: (&vk.mul).into(),
388 emul_comm: (&vk.emul).into(),
389 endomul_scalar_comm: (&vk.endomul_scalar).into(),
390 }
391 }
392}
393impl From<PlonkVerificationKeyEvals<Fp>>
394 for mina_p2p_messages::v2::MinaBaseVerificationKeyWireStableV1WrapIndex
395{
396 fn from(value: PlonkVerificationKeyEvals<Fp>) -> Self {
397 (&value).into()
398 }
399}
400
401impl From<AccountId> for mina_p2p_messages::v2::MinaBaseAccountIdStableV2 {
404 fn from(account_id: AccountId) -> Self {
405 let public_key: NonZeroCurvePointUncompressedStableV1 = account_id.public_key.into();
406 Self(public_key.into(), account_id.token_id.into())
407 }
408}
409
410impl TryFrom<mina_p2p_messages::v2::MinaBaseAccountIdStableV2> for AccountId {
411 type Error = InvalidBigInt;
412
413 fn try_from(
414 account_id: mina_p2p_messages::v2::MinaBaseAccountIdStableV2,
415 ) -> Result<Self, Self::Error> {
416 Ok(Self {
417 public_key: account_id.0.into_inner().try_into()?,
418 token_id: account_id.1.try_into()?,
419 })
420 }
421}
422
423impl TryFrom<&mina_p2p_messages::v2::MinaBaseAccountIdStableV2> for AccountId {
424 type Error = InvalidBigInt;
425
426 fn try_from(
427 account_id: &mina_p2p_messages::v2::MinaBaseAccountIdStableV2,
428 ) -> Result<Self, Self::Error> {
429 Ok(Self {
430 public_key: account_id.0.clone().into_inner().try_into()?,
431 token_id: account_id.1.clone().try_into()?,
432 })
433 }
434}
435
436impl From<TokenId> for mina_p2p_messages::v2::MinaBaseAccountIdDigestStableV1 {
437 fn from(token_id: TokenId) -> Self {
438 Self(token_id.0.into())
439 }
440}
441
442impl TryFrom<mina_p2p_messages::v2::MinaBaseAccountIdDigestStableV1> for TokenId {
443 type Error = InvalidBigInt;
444
445 fn try_from(
446 token_id: mina_p2p_messages::v2::MinaBaseAccountIdDigestStableV1,
447 ) -> Result<Self, Self::Error> {
448 Ok(Self(token_id.0.try_into()?))
449 }
450}
451
452impl TryFrom<&mina_p2p_messages::v2::MinaBaseAccountIdDigestStableV1> for TokenId {
453 type Error = InvalidBigInt;
454
455 fn try_from(
456 token_id: &mina_p2p_messages::v2::MinaBaseAccountIdDigestStableV1,
457 ) -> Result<Self, Self::Error> {
458 Ok(Self(token_id.0.to_field()?))
459 }
460}
461
462impl From<&TokenId> for mina_p2p_messages::v2::MinaBaseTokenIdStableV2 {
463 fn from(token_id: &TokenId) -> Self {
464 Self(MinaBaseAccountIdDigestStableV1(token_id.0.into()))
465 }
466}
467
468impl From<TokenId> for mina_p2p_messages::v2::MinaBaseTokenIdStableV2 {
469 fn from(token_id: TokenId) -> Self {
470 Self(MinaBaseAccountIdDigestStableV1(token_id.0.into()))
471 }
472}
473
474impl TryFrom<&mina_p2p_messages::v2::MinaBaseTokenIdStableV2> for TokenId {
475 type Error = InvalidBigInt;
476
477 fn try_from(
478 token_id: &mina_p2p_messages::v2::MinaBaseTokenIdStableV2,
479 ) -> Result<Self, Self::Error> {
480 Ok(Self(token_id.to_field()?))
481 }
482}
483
484impl TryFrom<mina_p2p_messages::v2::MinaBaseTokenIdStableV2> for TokenId {
485 type Error = InvalidBigInt;
486
487 fn try_from(
488 token_id: mina_p2p_messages::v2::MinaBaseTokenIdStableV2,
489 ) -> Result<Self, Self::Error> {
490 Ok(Self(token_id.to_field()?))
491 }
492}
493
494impl binprot::BinProtRead for Account {
495 fn binprot_read<R: std::io::Read + ?Sized>(r: &mut R) -> Result<Self, binprot::Error>
496 where
497 Self: Sized,
498 {
499 let account = MinaBaseAccountBinableArgStableV2::binprot_read(r)?;
500 (&account)
501 .try_into()
502 .map_err(|e| binprot::Error::CustomError(Box::new(e)))
503 }
504}
505
506impl binprot::BinProtWrite for Account {
507 fn binprot_write<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
508 let account: MinaBaseAccountBinableArgStableV2 = self.into();
509 account.binprot_write(w)?;
510 Ok(())
511 }
512}
513
514impl From<&MinaBasePermissionsAuthRequiredStableV2> for AuthRequired {
515 fn from(auth: &MinaBasePermissionsAuthRequiredStableV2) -> Self {
516 match auth {
517 MinaBasePermissionsAuthRequiredStableV2::None => Self::None,
518 MinaBasePermissionsAuthRequiredStableV2::Either => Self::Either,
519 MinaBasePermissionsAuthRequiredStableV2::Proof => Self::Proof,
520 MinaBasePermissionsAuthRequiredStableV2::Signature => Self::Signature,
521 MinaBasePermissionsAuthRequiredStableV2::Impossible => Self::Impossible,
522 }
523 }
524}
525
526impl From<&MinaBasePermissionsStableV2> for Permissions<AuthRequired> {
527 fn from(perms: &MinaBasePermissionsStableV2) -> Self {
528 let MinaBasePermissionsStableV2 {
529 edit_state,
530 access,
531 send,
532 receive,
533 set_delegate,
534 set_permissions,
535 set_verification_key: (auth, txn_version),
536 set_zkapp_uri,
537 edit_action_state,
538 set_token_symbol,
539 increment_nonce,
540 set_voting_for,
541 set_timing,
542 } = perms;
543
544 Permissions {
545 edit_state: edit_state.into(),
546 send: send.into(),
547 receive: receive.into(),
548 set_delegate: set_delegate.into(),
549 set_permissions: set_permissions.into(),
550 set_verification_key: SetVerificationKey {
551 auth: auth.into(),
552 txn_version: TxnVersion::from_u32(txn_version.as_u32()),
553 },
554 set_zkapp_uri: set_zkapp_uri.into(),
555 edit_action_state: edit_action_state.into(),
556 set_token_symbol: set_token_symbol.into(),
557 increment_nonce: increment_nonce.into(),
558 set_voting_for: set_voting_for.into(),
559 access: access.into(),
560 set_timing: set_timing.into(),
561 }
562 }
563}
564
565impl From<&Permissions<AuthRequired>> for MinaBasePermissionsStableV2 {
566 fn from(perms: &Permissions<AuthRequired>) -> Self {
567 let Permissions {
568 edit_state,
569 access,
570 send,
571 receive,
572 set_delegate,
573 set_permissions,
574 set_verification_key: SetVerificationKey { auth, txn_version },
575 set_zkapp_uri,
576 edit_action_state,
577 set_token_symbol,
578 increment_nonce,
579 set_voting_for,
580 set_timing,
581 } = perms;
582
583 MinaBasePermissionsStableV2 {
584 edit_state: edit_state.into(),
585 send: send.into(),
586 receive: receive.into(),
587 set_delegate: set_delegate.into(),
588 set_permissions: set_permissions.into(),
589 set_verification_key: (auth.into(), txn_version.as_u32().into()),
590 set_zkapp_uri: set_zkapp_uri.into(),
591 edit_action_state: edit_action_state.into(),
592 set_token_symbol: set_token_symbol.into(),
593 increment_nonce: increment_nonce.into(),
594 set_voting_for: set_voting_for.into(),
595 access: access.into(),
596 set_timing: set_timing.into(),
597 }
598 }
599}
600
601impl TryFrom<&MinaBaseAccountBinableArgStableV2> for Account {
602 type Error = InvalidBigInt;
603
604 fn try_from(acc: &MinaBaseAccountBinableArgStableV2) -> Result<Self, Self::Error> {
605 Ok(Self {
606 public_key: acc.public_key.inner().try_into()?,
607 token_id: acc.token_id.inner().try_into()?,
608 token_symbol: {
609 let s = acc.token_symbol.0.clone();
610 TokenSymbol::from(s)
611 },
612 balance: Balance::from_u64(acc.balance.0 .0 .0 .0),
613 nonce: Nonce::from_u32(acc.nonce.0 .0),
614 receipt_chain_hash: ReceiptChainHash(acc.receipt_chain_hash.to_field()?),
615 delegate: match acc.delegate.as_ref() {
616 Some(delegate) => Some(delegate.try_into()?),
617 None => None,
618 },
619 voting_for: VotingFor(acc.voting_for.to_field()?),
620 timing: (&acc.timing).into(),
621 permissions: (&acc.permissions).into(),
622 zkapp: match acc.zkapp.as_ref() {
623 Some(zkapp) => {
624 let v2::MinaBaseZkappAccountStableV2 {
625 app_state,
626 verification_key,
627 zkapp_version,
628 action_state,
629 last_action_slot,
630 proved_state,
631 zkapp_uri,
632 } = zkapp;
633
634 Some(Box::new(ZkAppAccount {
635 app_state: try_array_into_with(app_state, BigInt::to_field)?,
636 verification_key: match verification_key.as_ref() {
637 Some(vk) => Some(VerificationKeyWire::new(vk.try_into()?)),
638 None => None,
639 },
640 zkapp_version: zkapp_version.as_u32(),
641 action_state: try_array_into_with(action_state, BigInt::to_field)?,
642 last_action_slot: Slot::from_u32(last_action_slot.as_u32()),
643 proved_state: *proved_state,
644 zkapp_uri: zkapp_uri.into(),
645 }))
646 }
647 None => None,
648 },
649 })
650 }
651}
652impl TryFrom<MinaBaseAccountBinableArgStableV2> for Account {
653 type Error = InvalidBigInt;
654
655 fn try_from(account: MinaBaseAccountBinableArgStableV2) -> Result<Self, Self::Error> {
656 (&account).try_into()
657 }
658}
659
660impl From<AccountIndex> for MinaBaseAccountIndexStableV1 {
661 fn from(value: AccountIndex) -> Self {
662 Self(value.as_u64().into())
663 }
664}
665
666impl From<ReceiptChainHash> for mina_p2p_messages::v2::ReceiptChainHash {
667 fn from(value: ReceiptChainHash) -> Self {
668 MinaBaseReceiptChainHashStableV1(value.0.into_bigint().into()).into()
669 }
670}
671
672#[cfg(test)]
673mod tests {
674 use super::*;
675
676 #[cfg(target_family = "wasm")]
677 use wasm_bindgen_test::wasm_bindgen_test as test;
678
679 #[test]
680 fn test_deserialize_account() {
681 let account = Account::rand();
682 let hash = account.hash();
683
684 let bytes = account.serialize();
685
686 elog!("len={:?}", bytes.len());
687 let result: Account = Account::deserialize(&bytes);
688 elog!("account={:#?}", result);
689
690 assert_eq!(hash, result.hash());
691 }
692}