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