sui_rpc/proto/sui/rpc/v2beta2/
transaction.rs

1use super::*;
2use crate::field::FieldMaskTree;
3use crate::merge::Merge;
4use crate::proto::TryFromProtoError;
5use tap::Pipe;
6
7//
8// Transaction
9//
10
11impl From<sui_sdk_types::Transaction> for Transaction {
12    fn from(value: sui_sdk_types::Transaction) -> Self {
13        Self::merge_from(value, &FieldMaskTree::new_wildcard())
14    }
15}
16
17impl Merge<sui_sdk_types::Transaction> for Transaction {
18    fn merge(&mut self, source: sui_sdk_types::Transaction, mask: &FieldMaskTree) {
19        if mask.contains(Self::BCS_FIELD.name) {
20            let mut bcs = Bcs::serialize(&source).unwrap();
21            bcs.name = Some("TransactionData".to_owned());
22            self.bcs = Some(bcs);
23        }
24
25        if mask.contains(Self::DIGEST_FIELD.name) {
26            self.digest = Some(source.digest().to_string());
27        }
28
29        if mask.contains(Self::VERSION_FIELD.name) {
30            self.version = Some(1);
31        }
32
33        if mask.contains(Self::KIND_FIELD.name) {
34            self.kind = Some(source.kind.into());
35        }
36
37        if mask.contains(Self::SENDER_FIELD.name) {
38            self.sender = Some(source.sender.to_string());
39        }
40
41        if mask.contains(Self::GAS_PAYMENT_FIELD.name) {
42            self.gas_payment = Some(source.gas_payment.into());
43        }
44
45        if mask.contains(Self::EXPIRATION_FIELD.name) {
46            self.expiration = Some(source.expiration.into());
47        }
48    }
49}
50
51impl Merge<&Transaction> for Transaction {
52    fn merge(&mut self, source: &Transaction, mask: &FieldMaskTree) {
53        let Transaction {
54            bcs,
55            digest,
56            version,
57            kind,
58            sender,
59            gas_payment,
60            expiration,
61        } = source;
62
63        if mask.contains(Self::BCS_FIELD.name) {
64            self.bcs = bcs.clone();
65        }
66
67        if mask.contains(Self::DIGEST_FIELD.name) {
68            self.digest = digest.clone();
69        }
70
71        if mask.contains(Self::VERSION_FIELD.name) {
72            self.version = *version;
73        }
74
75        if mask.contains(Self::KIND_FIELD.name) {
76            self.kind = kind.clone();
77        }
78
79        if mask.contains(Self::SENDER_FIELD.name) {
80            self.sender = sender.clone();
81        }
82
83        if mask.contains(Self::GAS_PAYMENT_FIELD.name) {
84            self.gas_payment = gas_payment.clone();
85        }
86
87        if mask.contains(Self::EXPIRATION_FIELD.name) {
88            self.expiration = *expiration;
89        }
90    }
91}
92
93impl TryFrom<&Transaction> for sui_sdk_types::Transaction {
94    type Error = TryFromProtoError;
95
96    fn try_from(value: &Transaction) -> Result<Self, Self::Error> {
97        if let Some(bcs) = &value.bcs {
98            return bcs
99                .deserialize()
100                .map_err(|e| TryFromProtoError::invalid(Transaction::BCS_FIELD, e));
101        }
102
103        match value.version {
104            Some(1) => {}
105            v => {
106                return Err(TryFromProtoError::invalid(
107                    Transaction::VERSION_FIELD,
108                    format!("unknown Transaction version {v:?}"),
109                ));
110            }
111        }
112
113        let kind = value
114            .kind
115            .as_ref()
116            .ok_or_else(|| TryFromProtoError::missing("kind"))?
117            .try_into()?;
118
119        let sender = value
120            .sender
121            .as_ref()
122            .ok_or_else(|| TryFromProtoError::missing("sender"))?
123            .parse()
124            .map_err(|e| TryFromProtoError::invalid(Transaction::SENDER_FIELD, e))?;
125
126        let gas_payment = value
127            .gas_payment
128            .as_ref()
129            .ok_or_else(|| TryFromProtoError::missing("gas_payment"))?
130            .try_into()?;
131
132        let expiration = value
133            .expiration
134            .as_ref()
135            .ok_or_else(|| TryFromProtoError::missing("expiration"))?
136            .try_into()?;
137
138        Ok(Self {
139            kind,
140            sender,
141            gas_payment,
142            expiration,
143        })
144    }
145}
146
147//
148// GasPayment
149//
150
151impl From<sui_sdk_types::GasPayment> for GasPayment {
152    fn from(value: sui_sdk_types::GasPayment) -> Self {
153        Self {
154            objects: value.objects.into_iter().map(Into::into).collect(),
155            owner: Some(value.owner.to_string()),
156            price: Some(value.price),
157            budget: Some(value.budget),
158        }
159    }
160}
161
162impl TryFrom<&GasPayment> for sui_sdk_types::GasPayment {
163    type Error = TryFromProtoError;
164
165    fn try_from(value: &GasPayment) -> Result<Self, Self::Error> {
166        let objects = value
167            .objects
168            .iter()
169            .map(TryInto::try_into)
170            .collect::<Result<_, _>>()?;
171
172        let owner = value
173            .owner
174            .as_ref()
175            .ok_or_else(|| TryFromProtoError::missing("owner"))?
176            .parse()
177            .map_err(|e| TryFromProtoError::invalid(GasPayment::OWNER_FIELD, e))?;
178        let price = value
179            .price
180            .ok_or_else(|| TryFromProtoError::missing("price"))?;
181        let budget = value
182            .budget
183            .ok_or_else(|| TryFromProtoError::missing("budget"))?;
184        Ok(Self {
185            objects,
186            owner,
187            price,
188            budget,
189        })
190    }
191}
192
193//
194// TransactionExpiration
195//
196
197impl From<sui_sdk_types::TransactionExpiration> for TransactionExpiration {
198    fn from(value: sui_sdk_types::TransactionExpiration) -> Self {
199        use sui_sdk_types::TransactionExpiration::*;
200        use transaction_expiration::TransactionExpirationKind;
201
202        let mut message = Self::default();
203
204        let kind = match value {
205            None => TransactionExpirationKind::None,
206            Epoch(epoch) => {
207                message.epoch = Some(epoch);
208                TransactionExpirationKind::Epoch
209            }
210            _ => TransactionExpirationKind::Unknown,
211        };
212
213        message.set_kind(kind);
214        message
215    }
216}
217
218impl TryFrom<&TransactionExpiration> for sui_sdk_types::TransactionExpiration {
219    type Error = TryFromProtoError;
220
221    fn try_from(value: &TransactionExpiration) -> Result<Self, Self::Error> {
222        use transaction_expiration::TransactionExpirationKind;
223
224        match value.kind() {
225            TransactionExpirationKind::Unknown => {
226                return Err(TryFromProtoError::invalid(
227                    TransactionExpiration::KIND_FIELD,
228                    "unknown TransactionExpirationKind",
229                ))
230            }
231            TransactionExpirationKind::None => Self::None,
232            TransactionExpirationKind::Epoch => Self::Epoch(value.epoch()),
233        }
234        .pipe(Ok)
235    }
236}
237
238//
239// TransactionKind
240//
241
242impl From<ProgrammableTransaction> for TransactionKind {
243    fn from(value: ProgrammableTransaction) -> Self {
244        Self {
245            kind: Some(transaction_kind::Kind::ProgrammableTransaction(value)),
246        }
247    }
248}
249
250impl From<sui_sdk_types::TransactionKind> for TransactionKind {
251    fn from(value: sui_sdk_types::TransactionKind) -> Self {
252        use sui_sdk_types::TransactionKind as K;
253        use transaction_kind::Kind;
254
255        let kind = match value {
256            K::ProgrammableTransaction(ptb) => Kind::ProgrammableTransaction(ptb.into()),
257            // ProgrammableSystemTransaction(ptb) => Kind::ProgrammableSystemTransaction(ptb.into()),
258            K::ChangeEpoch(change_epoch) => Kind::ChangeEpoch(change_epoch.into()),
259            K::Genesis(genesis) => Kind::Genesis(genesis.into()),
260            K::ConsensusCommitPrologue(prologue) => {
261                Kind::ConsensusCommitPrologueV1(prologue.into())
262            }
263            K::AuthenticatorStateUpdate(update) => Kind::AuthenticatorStateUpdate(update.into()),
264            K::EndOfEpoch(transactions) => Kind::EndOfEpoch(EndOfEpochTransaction {
265                transactions: transactions.into_iter().map(Into::into).collect(),
266            }),
267            K::RandomnessStateUpdate(update) => Kind::RandomnessStateUpdate(update.into()),
268            K::ConsensusCommitPrologueV2(prologue) => {
269                Kind::ConsensusCommitPrologueV2(prologue.into())
270            }
271            K::ConsensusCommitPrologueV3(prologue) => {
272                Kind::ConsensusCommitPrologueV3(prologue.into())
273            }
274            K::ConsensusCommitPrologueV4(prologue) => {
275                Kind::ConsensusCommitPrologueV4(prologue.into())
276            }
277            _ => return Self::default(),
278        };
279
280        Self { kind: Some(kind) }
281    }
282}
283
284impl TryFrom<&TransactionKind> for sui_sdk_types::TransactionKind {
285    type Error = TryFromProtoError;
286
287    fn try_from(value: &TransactionKind) -> Result<Self, Self::Error> {
288        use transaction_kind::Kind;
289
290        match value
291            .kind
292            .as_ref()
293            .ok_or_else(|| TryFromProtoError::missing("kind"))?
294        {
295            Kind::ProgrammableTransaction(ptb) => Self::ProgrammableTransaction(ptb.try_into()?),
296            Kind::ProgrammableSystemTransaction(_) => {
297                return Err(TryFromProtoError::invalid(
298                    "kind",
299                    "Unknown TransactionKind",
300                ));
301            }
302            Kind::ChangeEpoch(change_epoch) => Self::ChangeEpoch(change_epoch.try_into()?),
303            Kind::Genesis(genesis) => Self::Genesis(genesis.try_into()?),
304            Kind::ConsensusCommitPrologueV1(prologue) => {
305                Self::ConsensusCommitPrologue(prologue.try_into()?)
306            }
307            Kind::AuthenticatorStateUpdate(update) => {
308                Self::AuthenticatorStateUpdate(update.try_into()?)
309            }
310            Kind::EndOfEpoch(EndOfEpochTransaction { transactions }) => Self::EndOfEpoch(
311                transactions
312                    .iter()
313                    .map(TryInto::try_into)
314                    .collect::<Result<_, _>>()?,
315            ),
316            Kind::RandomnessStateUpdate(update) => Self::RandomnessStateUpdate(update.try_into()?),
317            Kind::ConsensusCommitPrologueV2(prologue) => {
318                Self::ConsensusCommitPrologueV2(prologue.try_into()?)
319            }
320            Kind::ConsensusCommitPrologueV3(prologue) => {
321                Self::ConsensusCommitPrologueV3(prologue.try_into()?)
322            }
323            Kind::ConsensusCommitPrologueV4(prologue) => {
324                Self::ConsensusCommitPrologueV4(prologue.try_into()?)
325            }
326        }
327        .pipe(Ok)
328    }
329}
330
331//
332// ConsensusCommitPrologue
333//
334
335impl From<sui_sdk_types::ConsensusCommitPrologue> for ConsensusCommitPrologue {
336    fn from(value: sui_sdk_types::ConsensusCommitPrologue) -> Self {
337        Self {
338            epoch: Some(value.epoch),
339            round: Some(value.round),
340            commit_timestamp: Some(crate::proto::timestamp_ms_to_proto(
341                value.commit_timestamp_ms,
342            )),
343            consensus_commit_digest: None,
344            sub_dag_index: None,
345            consensus_determined_version_assignments: None,
346            additional_state_digest: None,
347        }
348    }
349}
350
351impl TryFrom<&ConsensusCommitPrologue> for sui_sdk_types::ConsensusCommitPrologue {
352    type Error = TryFromProtoError;
353
354    fn try_from(value: &ConsensusCommitPrologue) -> Result<Self, Self::Error> {
355        let epoch = value
356            .epoch
357            .ok_or_else(|| TryFromProtoError::missing("epoch"))?;
358        let round = value
359            .round
360            .ok_or_else(|| TryFromProtoError::missing("round"))?;
361        let commit_timestamp_ms = value
362            .commit_timestamp
363            .ok_or_else(|| TryFromProtoError::missing("commit_timestamp"))?
364            .pipe(crate::proto::proto_to_timestamp_ms)?;
365
366        Ok(Self {
367            epoch,
368            round,
369            commit_timestamp_ms,
370        })
371    }
372}
373
374impl From<sui_sdk_types::ConsensusCommitPrologueV2> for ConsensusCommitPrologue {
375    fn from(value: sui_sdk_types::ConsensusCommitPrologueV2) -> Self {
376        Self {
377            epoch: Some(value.epoch),
378            round: Some(value.round),
379            commit_timestamp: Some(crate::proto::timestamp_ms_to_proto(
380                value.commit_timestamp_ms,
381            )),
382            consensus_commit_digest: Some(value.consensus_commit_digest.to_string()),
383            sub_dag_index: None,
384            consensus_determined_version_assignments: None,
385            additional_state_digest: None,
386        }
387    }
388}
389
390impl TryFrom<&ConsensusCommitPrologue> for sui_sdk_types::ConsensusCommitPrologueV2 {
391    type Error = TryFromProtoError;
392
393    fn try_from(value: &ConsensusCommitPrologue) -> Result<Self, Self::Error> {
394        let epoch = value
395            .epoch
396            .ok_or_else(|| TryFromProtoError::missing("epoch"))?;
397        let round = value
398            .round
399            .ok_or_else(|| TryFromProtoError::missing("round"))?;
400        let commit_timestamp_ms = value
401            .commit_timestamp
402            .ok_or_else(|| TryFromProtoError::missing("commit_timestamp"))?
403            .pipe(crate::proto::proto_to_timestamp_ms)?;
404
405        let consensus_commit_digest = value
406            .consensus_commit_digest
407            .as_ref()
408            .ok_or_else(|| TryFromProtoError::missing("consensus_commit_digest"))?
409            .parse()
410            .map_err(|e| {
411                TryFromProtoError::invalid(
412                    ConsensusCommitPrologue::CONSENSUS_COMMIT_DIGEST_FIELD,
413                    e,
414                )
415            })?;
416
417        Ok(Self {
418            epoch,
419            round,
420            commit_timestamp_ms,
421            consensus_commit_digest,
422        })
423    }
424}
425
426impl From<sui_sdk_types::ConsensusCommitPrologueV3> for ConsensusCommitPrologue {
427    fn from(value: sui_sdk_types::ConsensusCommitPrologueV3) -> Self {
428        Self {
429            epoch: Some(value.epoch),
430            round: Some(value.round),
431            commit_timestamp: Some(crate::proto::timestamp_ms_to_proto(
432                value.commit_timestamp_ms,
433            )),
434            consensus_commit_digest: Some(value.consensus_commit_digest.to_string()),
435            sub_dag_index: value.sub_dag_index,
436            consensus_determined_version_assignments: Some(
437                value.consensus_determined_version_assignments.into(),
438            ),
439            additional_state_digest: None,
440        }
441    }
442}
443
444impl TryFrom<&ConsensusCommitPrologue> for sui_sdk_types::ConsensusCommitPrologueV3 {
445    type Error = TryFromProtoError;
446
447    fn try_from(value: &ConsensusCommitPrologue) -> Result<Self, Self::Error> {
448        let epoch = value
449            .epoch
450            .ok_or_else(|| TryFromProtoError::missing("epoch"))?;
451        let round = value
452            .round
453            .ok_or_else(|| TryFromProtoError::missing("round"))?;
454        let commit_timestamp_ms = value
455            .commit_timestamp
456            .ok_or_else(|| TryFromProtoError::missing("commit_timestamp"))?
457            .pipe(crate::proto::proto_to_timestamp_ms)?;
458
459        let consensus_commit_digest = value
460            .consensus_commit_digest
461            .as_ref()
462            .ok_or_else(|| TryFromProtoError::missing("consensus_commit_digest"))?
463            .parse()
464            .map_err(|e| {
465                TryFromProtoError::invalid(
466                    ConsensusCommitPrologue::CONSENSUS_COMMIT_DIGEST_FIELD,
467                    e,
468                )
469            })?;
470
471        let consensus_determined_version_assignments = value
472            .consensus_determined_version_assignments
473            .as_ref()
474            .ok_or_else(|| TryFromProtoError::missing("consensus_determined_version_assignments"))?
475            .try_into()?;
476
477        Ok(Self {
478            epoch,
479            round,
480            commit_timestamp_ms,
481            sub_dag_index: value.sub_dag_index,
482            consensus_commit_digest,
483            consensus_determined_version_assignments,
484        })
485    }
486}
487
488impl From<sui_sdk_types::ConsensusCommitPrologueV4> for ConsensusCommitPrologue {
489    fn from(
490        sui_sdk_types::ConsensusCommitPrologueV4 {
491            epoch,
492            round,
493            sub_dag_index,
494            commit_timestamp_ms,
495            consensus_commit_digest,
496            consensus_determined_version_assignments,
497            additional_state_digest,
498        }: sui_sdk_types::ConsensusCommitPrologueV4,
499    ) -> Self {
500        Self {
501            epoch: Some(epoch),
502            round: Some(round),
503            commit_timestamp: Some(crate::proto::timestamp_ms_to_proto(commit_timestamp_ms)),
504            consensus_commit_digest: Some(consensus_commit_digest.to_string()),
505            sub_dag_index,
506            consensus_determined_version_assignments: Some(
507                consensus_determined_version_assignments.into(),
508            ),
509            additional_state_digest: Some(additional_state_digest.to_string()),
510        }
511    }
512}
513
514impl TryFrom<&ConsensusCommitPrologue> for sui_sdk_types::ConsensusCommitPrologueV4 {
515    type Error = TryFromProtoError;
516
517    fn try_from(value: &ConsensusCommitPrologue) -> Result<Self, Self::Error> {
518        let epoch = value
519            .epoch
520            .ok_or_else(|| TryFromProtoError::missing("epoch"))?;
521        let round = value
522            .round
523            .ok_or_else(|| TryFromProtoError::missing("round"))?;
524        let commit_timestamp_ms = value
525            .commit_timestamp
526            .ok_or_else(|| TryFromProtoError::missing("commit_timestamp"))?
527            .pipe(crate::proto::proto_to_timestamp_ms)?;
528
529        let consensus_commit_digest = value
530            .consensus_commit_digest
531            .as_ref()
532            .ok_or_else(|| TryFromProtoError::missing("consensus_commit_digest"))?
533            .parse()
534            .map_err(|e| {
535                TryFromProtoError::invalid(
536                    ConsensusCommitPrologue::CONSENSUS_COMMIT_DIGEST_FIELD,
537                    e,
538                )
539            })?;
540
541        let consensus_determined_version_assignments = value
542            .consensus_determined_version_assignments
543            .as_ref()
544            .ok_or_else(|| TryFromProtoError::missing("consensus_determined_version_assignments"))?
545            .try_into()?;
546
547        let additional_state_digest = value
548            .additional_state_digest
549            .as_ref()
550            .ok_or_else(|| TryFromProtoError::missing("additional_state_digest"))?
551            .parse()
552            .map_err(|e| {
553                TryFromProtoError::invalid(
554                    ConsensusCommitPrologue::ADDITIONAL_STATE_DIGEST_FIELD,
555                    e,
556                )
557            })?;
558
559        Ok(Self {
560            epoch,
561            round,
562            commit_timestamp_ms,
563            sub_dag_index: value.sub_dag_index,
564            consensus_commit_digest,
565            consensus_determined_version_assignments,
566            additional_state_digest,
567        })
568    }
569}
570
571//
572// ConsensusDeterminedVersionAssignments
573//
574
575impl From<sui_sdk_types::ConsensusDeterminedVersionAssignments>
576    for ConsensusDeterminedVersionAssignments
577{
578    fn from(value: sui_sdk_types::ConsensusDeterminedVersionAssignments) -> Self {
579        use sui_sdk_types::ConsensusDeterminedVersionAssignments::*;
580
581        let mut message = Self::default();
582
583        let version = match value {
584            CanceledTransactions {
585                canceled_transactions,
586            } => {
587                message.canceled_transactions =
588                    canceled_transactions.into_iter().map(Into::into).collect();
589                1
590            }
591            CanceledTransactionsV2 {
592                canceled_transactions,
593            } => {
594                message.canceled_transactions =
595                    canceled_transactions.into_iter().map(Into::into).collect();
596                2
597            }
598            _ => return Self::default(),
599        };
600
601        message.version = Some(version);
602        message
603    }
604}
605
606impl TryFrom<&ConsensusDeterminedVersionAssignments>
607    for sui_sdk_types::ConsensusDeterminedVersionAssignments
608{
609    type Error = TryFromProtoError;
610
611    fn try_from(value: &ConsensusDeterminedVersionAssignments) -> Result<Self, Self::Error> {
612        match value.version() {
613            1 => Self::CanceledTransactions {
614                canceled_transactions: value
615                    .canceled_transactions
616                    .iter()
617                    .map(TryFrom::try_from)
618                    .collect::<Result<_, _>>()?,
619            },
620            2 => Self::CanceledTransactionsV2 {
621                canceled_transactions: value
622                    .canceled_transactions
623                    .iter()
624                    .map(TryFrom::try_from)
625                    .collect::<Result<_, _>>()?,
626            },
627            _ => {
628                return Err(TryFromProtoError::invalid(
629                    ConsensusDeterminedVersionAssignments::VERSION_FIELD,
630                    "unknown ConsensusDeterminedVersionAssignments version",
631                ))
632            }
633        }
634        .pipe(Ok)
635    }
636}
637
638//
639// CanceledTransaction
640//
641
642impl From<sui_sdk_types::CanceledTransaction> for CanceledTransaction {
643    fn from(value: sui_sdk_types::CanceledTransaction) -> Self {
644        Self {
645            digest: Some(value.digest.to_string()),
646            version_assignments: value
647                .version_assignments
648                .into_iter()
649                .map(Into::into)
650                .collect(),
651        }
652    }
653}
654
655impl TryFrom<&CanceledTransaction> for sui_sdk_types::CanceledTransaction {
656    type Error = TryFromProtoError;
657
658    fn try_from(value: &CanceledTransaction) -> Result<Self, Self::Error> {
659        let digest = value
660            .digest
661            .as_ref()
662            .ok_or_else(|| TryFromProtoError::missing("digest"))?
663            .parse()
664            .map_err(|e| TryFromProtoError::invalid(CanceledTransaction::DIGEST_FIELD, e))?;
665
666        let version_assignments = value
667            .version_assignments
668            .iter()
669            .map(TryInto::try_into)
670            .collect::<Result<_, _>>()?;
671
672        Ok(Self {
673            digest,
674            version_assignments,
675        })
676    }
677}
678
679impl From<sui_sdk_types::CanceledTransactionV2> for CanceledTransaction {
680    fn from(value: sui_sdk_types::CanceledTransactionV2) -> Self {
681        Self {
682            digest: Some(value.digest.to_string()),
683            version_assignments: value
684                .version_assignments
685                .into_iter()
686                .map(Into::into)
687                .collect(),
688        }
689    }
690}
691
692impl TryFrom<&CanceledTransaction> for sui_sdk_types::CanceledTransactionV2 {
693    type Error = TryFromProtoError;
694
695    fn try_from(value: &CanceledTransaction) -> Result<Self, Self::Error> {
696        let digest = value
697            .digest
698            .as_ref()
699            .ok_or_else(|| TryFromProtoError::missing("digest"))?
700            .parse()
701            .map_err(|e| TryFromProtoError::invalid(CanceledTransaction::DIGEST_FIELD, e))?;
702
703        let version_assignments = value
704            .version_assignments
705            .iter()
706            .map(TryInto::try_into)
707            .collect::<Result<_, _>>()?;
708
709        Ok(Self {
710            digest,
711            version_assignments,
712        })
713    }
714}
715
716//
717// VersionAssignment
718//
719
720impl From<sui_sdk_types::VersionAssignment> for VersionAssignment {
721    fn from(value: sui_sdk_types::VersionAssignment) -> Self {
722        Self {
723            object_id: Some(value.object_id.to_string()),
724            start_version: None,
725            version: Some(value.version),
726        }
727    }
728}
729
730impl TryFrom<&VersionAssignment> for sui_sdk_types::VersionAssignment {
731    type Error = TryFromProtoError;
732
733    fn try_from(value: &VersionAssignment) -> Result<Self, Self::Error> {
734        let object_id = value
735            .object_id
736            .as_ref()
737            .ok_or_else(|| TryFromProtoError::missing("object_id"))?
738            .parse()
739            .map_err(|e| TryFromProtoError::invalid(VersionAssignment::OBJECT_ID_FIELD, e))?;
740        let version = value
741            .version
742            .ok_or_else(|| TryFromProtoError::missing("version"))?;
743
744        Ok(Self { object_id, version })
745    }
746}
747
748impl From<sui_sdk_types::VersionAssignmentV2> for VersionAssignment {
749    fn from(value: sui_sdk_types::VersionAssignmentV2) -> Self {
750        Self {
751            object_id: Some(value.object_id.to_string()),
752            start_version: Some(value.start_version),
753            version: Some(value.version),
754        }
755    }
756}
757
758impl TryFrom<&VersionAssignment> for sui_sdk_types::VersionAssignmentV2 {
759    type Error = TryFromProtoError;
760
761    fn try_from(value: &VersionAssignment) -> Result<Self, Self::Error> {
762        let object_id = value
763            .object_id
764            .as_ref()
765            .ok_or_else(|| TryFromProtoError::missing("object_id"))?
766            .parse()
767            .map_err(|e| TryFromProtoError::invalid(VersionAssignment::OBJECT_ID_FIELD, e))?;
768        let start_version = value
769            .start_version
770            .ok_or_else(|| TryFromProtoError::missing(VersionAssignment::START_VERSION_FIELD))?;
771        let version = value
772            .version
773            .ok_or_else(|| TryFromProtoError::missing("version"))?;
774
775        Ok(Self {
776            object_id,
777            start_version,
778            version,
779        })
780    }
781}
782
783//
784// GenesisTransaction
785//
786
787impl From<sui_sdk_types::GenesisTransaction> for GenesisTransaction {
788    fn from(value: sui_sdk_types::GenesisTransaction) -> Self {
789        Self {
790            objects: value.objects.into_iter().map(Into::into).collect(),
791        }
792    }
793}
794
795impl TryFrom<&GenesisTransaction> for sui_sdk_types::GenesisTransaction {
796    type Error = TryFromProtoError;
797
798    fn try_from(value: &GenesisTransaction) -> Result<Self, Self::Error> {
799        let objects = value
800            .objects
801            .iter()
802            .map(TryInto::try_into)
803            .collect::<Result<_, _>>()?;
804
805        Ok(Self { objects })
806    }
807}
808
809//
810// RandomnessStateUpdate
811//
812
813impl From<sui_sdk_types::RandomnessStateUpdate> for RandomnessStateUpdate {
814    fn from(value: sui_sdk_types::RandomnessStateUpdate) -> Self {
815        Self {
816            epoch: Some(value.epoch),
817            randomness_round: Some(value.randomness_round),
818            random_bytes: Some(value.random_bytes.into()),
819            randomness_object_initial_shared_version: Some(
820                value.randomness_obj_initial_shared_version,
821            ),
822        }
823    }
824}
825
826impl TryFrom<&RandomnessStateUpdate> for sui_sdk_types::RandomnessStateUpdate {
827    type Error = TryFromProtoError;
828
829    fn try_from(
830        RandomnessStateUpdate {
831            epoch,
832            randomness_round,
833            random_bytes,
834            randomness_object_initial_shared_version,
835        }: &RandomnessStateUpdate,
836    ) -> Result<Self, Self::Error> {
837        let epoch = epoch.ok_or_else(|| TryFromProtoError::missing("epoch"))?;
838        let randomness_round =
839            randomness_round.ok_or_else(|| TryFromProtoError::missing("randomness_round"))?;
840        let random_bytes = random_bytes
841            .as_ref()
842            .ok_or_else(|| TryFromProtoError::missing("random_bytes"))?
843            .to_vec();
844        let randomness_obj_initial_shared_version = randomness_object_initial_shared_version
845            .ok_or_else(|| {
846                TryFromProtoError::missing("randomness_object_initial_shared_version")
847            })?;
848        Ok(Self {
849            epoch,
850            randomness_round,
851            random_bytes,
852            randomness_obj_initial_shared_version,
853        })
854    }
855}
856
857//
858// AuthenticatorStateUpdate
859//
860
861impl From<sui_sdk_types::AuthenticatorStateUpdate> for AuthenticatorStateUpdate {
862    fn from(value: sui_sdk_types::AuthenticatorStateUpdate) -> Self {
863        Self {
864            epoch: Some(value.epoch),
865            round: Some(value.round),
866            new_active_jwks: value.new_active_jwks.into_iter().map(Into::into).collect(),
867            authenticator_object_initial_shared_version: Some(
868                value.authenticator_obj_initial_shared_version,
869            ),
870        }
871    }
872}
873
874impl TryFrom<&AuthenticatorStateUpdate> for sui_sdk_types::AuthenticatorStateUpdate {
875    type Error = TryFromProtoError;
876
877    fn try_from(
878        AuthenticatorStateUpdate {
879            epoch,
880            round,
881            new_active_jwks,
882            authenticator_object_initial_shared_version,
883        }: &AuthenticatorStateUpdate,
884    ) -> Result<Self, Self::Error> {
885        let epoch = epoch.ok_or_else(|| TryFromProtoError::missing("epoch"))?;
886        let round = round.ok_or_else(|| TryFromProtoError::missing("round"))?;
887        let authenticator_obj_initial_shared_version = authenticator_object_initial_shared_version
888            .ok_or_else(|| {
889                TryFromProtoError::missing("authenticator_object_initial_shared_version")
890            })?;
891        Ok(Self {
892            epoch,
893            round,
894            new_active_jwks: new_active_jwks
895                .iter()
896                .map(TryInto::try_into)
897                .collect::<Result<_, _>>()?,
898            authenticator_obj_initial_shared_version,
899        })
900    }
901}
902
903//
904// Jwk
905//
906
907impl From<sui_sdk_types::Jwk> for Jwk {
908    fn from(sui_sdk_types::Jwk { kty, e, n, alg }: sui_sdk_types::Jwk) -> Self {
909        Self {
910            kty: Some(kty),
911            e: Some(e),
912            n: Some(n),
913            alg: Some(alg),
914        }
915    }
916}
917
918impl TryFrom<&Jwk> for sui_sdk_types::Jwk {
919    type Error = TryFromProtoError;
920
921    fn try_from(Jwk { kty, e, n, alg }: &Jwk) -> Result<Self, Self::Error> {
922        let kty = kty
923            .as_ref()
924            .ok_or_else(|| TryFromProtoError::missing("kty"))?
925            .into();
926        let e = e
927            .as_ref()
928            .ok_or_else(|| TryFromProtoError::missing("e"))?
929            .into();
930        let n = n
931            .as_ref()
932            .ok_or_else(|| TryFromProtoError::missing("n"))?
933            .into();
934        let alg = alg
935            .as_ref()
936            .ok_or_else(|| TryFromProtoError::missing("alg"))?
937            .into();
938        Ok(Self { kty, e, n, alg })
939    }
940}
941
942//
943// JwkId
944//
945
946impl From<sui_sdk_types::JwkId> for JwkId {
947    fn from(sui_sdk_types::JwkId { iss, kid }: sui_sdk_types::JwkId) -> Self {
948        Self {
949            iss: Some(iss),
950            kid: Some(kid),
951        }
952    }
953}
954
955impl TryFrom<&JwkId> for sui_sdk_types::JwkId {
956    type Error = TryFromProtoError;
957
958    fn try_from(JwkId { iss, kid }: &JwkId) -> Result<Self, Self::Error> {
959        let iss = iss
960            .as_ref()
961            .ok_or_else(|| TryFromProtoError::missing("iss"))?
962            .into();
963        let kid = kid
964            .as_ref()
965            .ok_or_else(|| TryFromProtoError::missing("kid"))?
966            .into();
967        Ok(Self { iss, kid })
968    }
969}
970
971//
972// ActiveJwk
973//
974
975impl From<sui_sdk_types::ActiveJwk> for ActiveJwk {
976    fn from(value: sui_sdk_types::ActiveJwk) -> Self {
977        Self {
978            id: Some(value.jwk_id.into()),
979            jwk: Some(value.jwk.into()),
980            epoch: Some(value.epoch),
981        }
982    }
983}
984
985impl TryFrom<&ActiveJwk> for sui_sdk_types::ActiveJwk {
986    type Error = TryFromProtoError;
987
988    fn try_from(value: &ActiveJwk) -> Result<Self, Self::Error> {
989        let jwk_id = value
990            .id
991            .as_ref()
992            .ok_or_else(|| TryFromProtoError::missing("id"))?
993            .try_into()?;
994
995        let jwk = value
996            .jwk
997            .as_ref()
998            .ok_or_else(|| TryFromProtoError::missing("jwk"))?
999            .try_into()?;
1000
1001        let epoch = value
1002            .epoch
1003            .ok_or_else(|| TryFromProtoError::missing("epoch"))?;
1004
1005        Ok(Self { jwk_id, jwk, epoch })
1006    }
1007}
1008
1009//
1010// ChangeEpoch
1011//
1012
1013impl From<sui_sdk_types::ChangeEpoch> for ChangeEpoch {
1014    fn from(value: sui_sdk_types::ChangeEpoch) -> Self {
1015        Self {
1016            epoch: Some(value.epoch),
1017            protocol_version: Some(value.protocol_version),
1018            storage_charge: Some(value.storage_charge),
1019            computation_charge: Some(value.computation_charge),
1020            storage_rebate: Some(value.storage_rebate),
1021            non_refundable_storage_fee: Some(value.non_refundable_storage_fee),
1022            epoch_start_timestamp: Some(crate::proto::timestamp_ms_to_proto(
1023                value.epoch_start_timestamp_ms,
1024            )),
1025            system_packages: value.system_packages.into_iter().map(Into::into).collect(),
1026        }
1027    }
1028}
1029
1030impl TryFrom<&ChangeEpoch> for sui_sdk_types::ChangeEpoch {
1031    type Error = TryFromProtoError;
1032
1033    fn try_from(
1034        ChangeEpoch {
1035            epoch,
1036            protocol_version,
1037            storage_charge,
1038            computation_charge,
1039            storage_rebate,
1040            non_refundable_storage_fee,
1041            epoch_start_timestamp,
1042            system_packages,
1043        }: &ChangeEpoch,
1044    ) -> Result<Self, Self::Error> {
1045        let epoch = epoch.ok_or_else(|| TryFromProtoError::missing("epoch"))?;
1046        let protocol_version =
1047            protocol_version.ok_or_else(|| TryFromProtoError::missing("protocol_version"))?;
1048        let storage_charge =
1049            storage_charge.ok_or_else(|| TryFromProtoError::missing("storage_charge"))?;
1050        let computation_charge =
1051            computation_charge.ok_or_else(|| TryFromProtoError::missing("computation_charge"))?;
1052        let storage_rebate =
1053            storage_rebate.ok_or_else(|| TryFromProtoError::missing("storage_rebate"))?;
1054        let non_refundable_storage_fee = non_refundable_storage_fee
1055            .ok_or_else(|| TryFromProtoError::missing("non_refundable_storage_fee"))?;
1056        let epoch_start_timestamp_ms = epoch_start_timestamp
1057            .ok_or_else(|| TryFromProtoError::missing("epoch_start_timestamp_ms"))?
1058            .pipe(crate::proto::proto_to_timestamp_ms)?;
1059
1060        Ok(Self {
1061            epoch,
1062            protocol_version,
1063            storage_charge,
1064            computation_charge,
1065            storage_rebate,
1066            non_refundable_storage_fee,
1067            epoch_start_timestamp_ms,
1068            system_packages: system_packages
1069                .iter()
1070                .map(TryInto::try_into)
1071                .collect::<Result<_, _>>()?,
1072        })
1073    }
1074}
1075
1076//
1077// SystemPackage
1078//
1079
1080impl From<sui_sdk_types::SystemPackage> for SystemPackage {
1081    fn from(value: sui_sdk_types::SystemPackage) -> Self {
1082        Self {
1083            version: Some(value.version),
1084            modules: value.modules.into_iter().map(Into::into).collect(),
1085            dependencies: value.dependencies.iter().map(ToString::to_string).collect(),
1086        }
1087    }
1088}
1089
1090impl TryFrom<&SystemPackage> for sui_sdk_types::SystemPackage {
1091    type Error = TryFromProtoError;
1092
1093    fn try_from(value: &SystemPackage) -> Result<Self, Self::Error> {
1094        Ok(Self {
1095            version: value
1096                .version
1097                .ok_or_else(|| TryFromProtoError::missing("version"))?,
1098            modules: value.modules.iter().map(|bytes| bytes.to_vec()).collect(),
1099            dependencies: value
1100                .dependencies
1101                .iter()
1102                .map(|s| s.parse())
1103                .collect::<Result<_, _>>()
1104                .map_err(|e| TryFromProtoError::invalid(SystemPackage::DEPENDENCIES_FIELD, e))?,
1105        })
1106    }
1107}
1108
1109//
1110// EndOfEpochTransactionkind
1111//
1112
1113impl From<sui_sdk_types::EndOfEpochTransactionKind> for EndOfEpochTransactionKind {
1114    fn from(value: sui_sdk_types::EndOfEpochTransactionKind) -> Self {
1115        use end_of_epoch_transaction_kind::Kind;
1116        use sui_sdk_types::EndOfEpochTransactionKind as K;
1117
1118        let kind = match value {
1119            K::ChangeEpoch(change_epoch) => Kind::ChangeEpoch(change_epoch.into()),
1120            K::AuthenticatorStateCreate => Kind::AuthenticatorStateCreate(()),
1121            K::AuthenticatorStateExpire(expire) => Kind::AuthenticatorStateExpire(expire.into()),
1122            K::RandomnessStateCreate => Kind::RandomnessStateCreate(()),
1123            K::DenyListStateCreate => Kind::DenyListStateCreate(()),
1124            K::BridgeStateCreate { chain_id } => Kind::BridgeStateCreate(chain_id.to_string()),
1125            K::BridgeCommitteeInit {
1126                bridge_object_version,
1127            } => Kind::BridgeCommitteeInit(bridge_object_version),
1128            K::StoreExecutionTimeObservations(observations) => {
1129                Kind::ExecutionTimeObservations(observations.into())
1130            }
1131            K::AccumulatorRootCreate => Kind::AccumulatorRootCreate(()),
1132            K::CoinRegistryCreate => Kind::CoinRegistryCreate(()),
1133            _ => return Self::default(),
1134        };
1135
1136        Self { kind: Some(kind) }
1137    }
1138}
1139
1140impl TryFrom<&EndOfEpochTransactionKind> for sui_sdk_types::EndOfEpochTransactionKind {
1141    type Error = TryFromProtoError;
1142
1143    fn try_from(value: &EndOfEpochTransactionKind) -> Result<Self, Self::Error> {
1144        use end_of_epoch_transaction_kind::Kind;
1145
1146        match value
1147            .kind
1148            .as_ref()
1149            .ok_or_else(|| TryFromProtoError::missing("kind"))?
1150        {
1151            Kind::ChangeEpoch(change_epoch) => Self::ChangeEpoch(change_epoch.try_into()?),
1152            Kind::AuthenticatorStateExpire(expire) => {
1153                Self::AuthenticatorStateExpire(expire.try_into()?)
1154            }
1155            Kind::AuthenticatorStateCreate(()) => Self::AuthenticatorStateCreate,
1156            Kind::RandomnessStateCreate(()) => Self::RandomnessStateCreate,
1157            Kind::DenyListStateCreate(()) => Self::DenyListStateCreate,
1158            Kind::BridgeStateCreate(digest) => Self::BridgeStateCreate {
1159                chain_id: digest.parse().map_err(|e| {
1160                    TryFromProtoError::invalid(
1161                        EndOfEpochTransactionKind::BRIDGE_STATE_CREATE_FIELD,
1162                        e,
1163                    )
1164                })?,
1165            },
1166            Kind::BridgeCommitteeInit(version) => Self::BridgeCommitteeInit {
1167                bridge_object_version: *version,
1168            },
1169            Kind::ExecutionTimeObservations(execution_time_observations) => {
1170                Self::StoreExecutionTimeObservations(execution_time_observations.try_into()?)
1171            }
1172            Kind::AccumulatorRootCreate(()) => Self::AccumulatorRootCreate,
1173            Kind::CoinRegistryCreate(()) => Self::CoinRegistryCreate,
1174        }
1175        .pipe(Ok)
1176    }
1177}
1178
1179//
1180// AuthenticatorStateExpire
1181//
1182
1183impl From<sui_sdk_types::AuthenticatorStateExpire> for AuthenticatorStateExpire {
1184    fn from(value: sui_sdk_types::AuthenticatorStateExpire) -> Self {
1185        Self {
1186            min_epoch: Some(value.min_epoch),
1187            authenticator_object_initial_shared_version: Some(
1188                value.authenticator_object_initial_shared_version,
1189            ),
1190        }
1191    }
1192}
1193
1194impl TryFrom<&AuthenticatorStateExpire> for sui_sdk_types::AuthenticatorStateExpire {
1195    type Error = TryFromProtoError;
1196
1197    fn try_from(
1198        AuthenticatorStateExpire {
1199            min_epoch,
1200            authenticator_object_initial_shared_version,
1201        }: &AuthenticatorStateExpire,
1202    ) -> Result<Self, Self::Error> {
1203        let min_epoch = min_epoch.ok_or_else(|| TryFromProtoError::missing("min_epoch"))?;
1204        let authenticator_object_initial_shared_version =
1205            authenticator_object_initial_shared_version.ok_or_else(|| {
1206                TryFromProtoError::missing("authenticator_object_initial_shared_version")
1207            })?;
1208        Ok(Self {
1209            min_epoch,
1210            authenticator_object_initial_shared_version,
1211        })
1212    }
1213}
1214
1215// ExecutionTimeObservations
1216
1217impl From<sui_sdk_types::ExecutionTimeObservations> for ExecutionTimeObservations {
1218    fn from(value: sui_sdk_types::ExecutionTimeObservations) -> Self {
1219        match value {
1220            sui_sdk_types::ExecutionTimeObservations::V1(vec) => Self {
1221                version: Some(1),
1222                observations: vec.into_iter().map(Into::into).collect(),
1223            },
1224            _ => Self::default(),
1225        }
1226    }
1227}
1228
1229impl TryFrom<&ExecutionTimeObservations> for sui_sdk_types::ExecutionTimeObservations {
1230    type Error = TryFromProtoError;
1231
1232    fn try_from(value: &ExecutionTimeObservations) -> Result<Self, Self::Error> {
1233        Ok(Self::V1(
1234            value
1235                .observations
1236                .iter()
1237                .map(|observation| observation.try_into())
1238                .collect::<Result<_, _>>()?,
1239        ))
1240    }
1241}
1242
1243impl
1244    From<(
1245        sui_sdk_types::ExecutionTimeObservationKey,
1246        Vec<sui_sdk_types::ValidatorExecutionTimeObservation>,
1247    )> for ExecutionTimeObservation
1248{
1249    fn from(
1250        value: (
1251            sui_sdk_types::ExecutionTimeObservationKey,
1252            Vec<sui_sdk_types::ValidatorExecutionTimeObservation>,
1253        ),
1254    ) -> Self {
1255        use execution_time_observation::ExecutionTimeObservationKind;
1256        use sui_sdk_types::ExecutionTimeObservationKey;
1257
1258        let mut message = Self::default();
1259
1260        let kind = match value.0 {
1261            ExecutionTimeObservationKey::MoveEntryPoint {
1262                package,
1263                module,
1264                function,
1265                type_arguments,
1266            } => {
1267                message.move_entry_point = Some(MoveCall {
1268                    package: Some(package.to_string()),
1269                    module: Some(module),
1270                    function: Some(function),
1271                    type_arguments: type_arguments
1272                        .into_iter()
1273                        .map(|ty| ty.to_string())
1274                        .collect(),
1275                    arguments: Vec::new(),
1276                });
1277                ExecutionTimeObservationKind::MoveEntryPoint
1278            }
1279            ExecutionTimeObservationKey::TransferObjects => {
1280                ExecutionTimeObservationKind::TransferObjects
1281            }
1282            ExecutionTimeObservationKey::SplitCoins => ExecutionTimeObservationKind::SplitCoins,
1283            ExecutionTimeObservationKey::MergeCoins => ExecutionTimeObservationKind::MergeCoins,
1284            ExecutionTimeObservationKey::Publish => ExecutionTimeObservationKind::Publish,
1285            ExecutionTimeObservationKey::MakeMoveVec => {
1286                ExecutionTimeObservationKind::MakeMoveVector
1287            }
1288            ExecutionTimeObservationKey::Upgrade => ExecutionTimeObservationKind::Upgrade,
1289
1290            _ => ExecutionTimeObservationKind::Unknown,
1291        };
1292
1293        message.validator_observations = value.1.into_iter().map(Into::into).collect();
1294        message.set_kind(kind);
1295        message
1296    }
1297}
1298
1299impl TryFrom<&ExecutionTimeObservation>
1300    for (
1301        sui_sdk_types::ExecutionTimeObservationKey,
1302        Vec<sui_sdk_types::ValidatorExecutionTimeObservation>,
1303    )
1304{
1305    type Error = TryFromProtoError;
1306
1307    fn try_from(value: &ExecutionTimeObservation) -> Result<Self, Self::Error> {
1308        use execution_time_observation::ExecutionTimeObservationKind;
1309        use sui_sdk_types::ExecutionTimeObservationKey;
1310
1311        let key = match value.kind() {
1312            ExecutionTimeObservationKind::Unknown => {
1313                return Err(TryFromProtoError::invalid(
1314                    ExecutionTimeObservation::KIND_FIELD,
1315                    "unknown ExecutionTimeObservationKind",
1316                ))
1317            }
1318            ExecutionTimeObservationKind::MoveEntryPoint => {
1319                let move_call = value
1320                    .move_entry_point
1321                    .as_ref()
1322                    .ok_or_else(|| TryFromProtoError::missing("move_entry_point"))?;
1323                ExecutionTimeObservationKey::MoveEntryPoint {
1324                    package: move_call
1325                        .package()
1326                        .parse()
1327                        .map_err(|e| TryFromProtoError::invalid(MoveCall::PACKAGE_FIELD, e))?,
1328                    module: move_call.module().to_owned(),
1329                    function: move_call.function().to_owned(),
1330                    type_arguments: move_call
1331                        .type_arguments
1332                        .iter()
1333                        .map(|t| {
1334                            t.parse().map_err(|e| {
1335                                TryFromProtoError::invalid(MoveCall::TYPE_ARGUMENTS_FIELD, e)
1336                            })
1337                        })
1338                        .collect::<Result<_, _>>()?,
1339                }
1340            }
1341            ExecutionTimeObservationKind::TransferObjects => {
1342                ExecutionTimeObservationKey::TransferObjects
1343            }
1344            ExecutionTimeObservationKind::SplitCoins => ExecutionTimeObservationKey::SplitCoins,
1345            ExecutionTimeObservationKind::MergeCoins => ExecutionTimeObservationKey::MergeCoins,
1346            ExecutionTimeObservationKind::Publish => ExecutionTimeObservationKey::Publish,
1347            ExecutionTimeObservationKind::MakeMoveVector => {
1348                ExecutionTimeObservationKey::MakeMoveVec
1349            }
1350            ExecutionTimeObservationKind::Upgrade => ExecutionTimeObservationKey::Upgrade,
1351        };
1352
1353        let observations = value
1354            .validator_observations
1355            .iter()
1356            .map(sui_sdk_types::ValidatorExecutionTimeObservation::try_from)
1357            .collect::<Result<_, _>>()?;
1358
1359        Ok((key, observations))
1360    }
1361}
1362
1363// ValidatorExecutionTimeObservation
1364
1365impl From<sui_sdk_types::ValidatorExecutionTimeObservation> for ValidatorExecutionTimeObservation {
1366    fn from(value: sui_sdk_types::ValidatorExecutionTimeObservation) -> Self {
1367        Self {
1368            validator: Some(value.validator.as_bytes().to_vec().into()),
1369            duration: Some(prost_types::Duration {
1370                seconds: value.duration.as_secs() as i64,
1371                nanos: value.duration.subsec_nanos() as i32,
1372            }),
1373        }
1374    }
1375}
1376
1377impl TryFrom<&ValidatorExecutionTimeObservation>
1378    for sui_sdk_types::ValidatorExecutionTimeObservation
1379{
1380    type Error = TryFromProtoError;
1381
1382    fn try_from(value: &ValidatorExecutionTimeObservation) -> Result<Self, Self::Error> {
1383        Ok(Self {
1384            validator: value
1385                .validator
1386                .as_ref()
1387                .ok_or_else(|| TryFromProtoError::missing("validator"))?
1388                .as_ref()
1389                .pipe(sui_sdk_types::Bls12381PublicKey::from_bytes)
1390                .map_err(|e| {
1391                    TryFromProtoError::invalid(
1392                        ValidatorExecutionTimeObservation::VALIDATOR_FIELD,
1393                        e,
1394                    )
1395                })?,
1396            duration: value
1397                .duration
1398                .ok_or_else(|| TryFromProtoError::missing("duration"))?
1399                .try_into()
1400                .map_err(|e| {
1401                    TryFromProtoError::invalid(ValidatorExecutionTimeObservation::DURATION_FIELD, e)
1402                })?,
1403        })
1404    }
1405}
1406
1407//
1408// ProgrammableTransaction
1409//
1410
1411impl From<sui_sdk_types::ProgrammableTransaction> for ProgrammableTransaction {
1412    fn from(value: sui_sdk_types::ProgrammableTransaction) -> Self {
1413        Self {
1414            inputs: value.inputs.into_iter().map(Into::into).collect(),
1415            commands: value.commands.into_iter().map(Into::into).collect(),
1416        }
1417    }
1418}
1419
1420impl TryFrom<&ProgrammableTransaction> for sui_sdk_types::ProgrammableTransaction {
1421    type Error = TryFromProtoError;
1422
1423    fn try_from(value: &ProgrammableTransaction) -> Result<Self, Self::Error> {
1424        Ok(Self {
1425            inputs: value
1426                .inputs
1427                .iter()
1428                .map(TryInto::try_into)
1429                .collect::<Result<_, _>>()?,
1430            commands: value
1431                .commands
1432                .iter()
1433                .map(TryInto::try_into)
1434                .collect::<Result<_, _>>()?,
1435        })
1436    }
1437}
1438
1439//
1440// Input
1441//
1442
1443impl From<sui_sdk_types::Input> for Input {
1444    fn from(value: sui_sdk_types::Input) -> Self {
1445        use input::InputKind;
1446        use sui_sdk_types::Input::*;
1447
1448        let mut message = Self::default();
1449
1450        let kind = match value {
1451            Pure { value } => {
1452                message.pure = Some(value.into());
1453                InputKind::Pure
1454            }
1455            ImmutableOrOwned(reference) => {
1456                message.object_id = Some(reference.object_id().to_string());
1457                message.version = Some(reference.version());
1458                message.digest = Some(reference.digest().to_string());
1459                InputKind::ImmutableOrOwned
1460            }
1461            Shared {
1462                object_id,
1463                initial_shared_version,
1464                mutable,
1465            } => {
1466                message.object_id = Some(object_id.to_string());
1467                message.version = Some(initial_shared_version);
1468                message.mutable = Some(mutable);
1469                InputKind::Shared
1470            }
1471            Receiving(reference) => {
1472                message.object_id = Some(reference.object_id().to_string());
1473                message.version = Some(reference.version());
1474                message.digest = Some(reference.digest().to_string());
1475                InputKind::Receiving
1476            }
1477            _ => InputKind::Unknown,
1478        };
1479
1480        message.set_kind(kind);
1481        message
1482    }
1483}
1484
1485impl TryFrom<&Input> for sui_sdk_types::Input {
1486    type Error = TryFromProtoError;
1487
1488    fn try_from(value: &Input) -> Result<Self, Self::Error> {
1489        use input::InputKind;
1490
1491        match value.kind() {
1492            InputKind::Unknown => {
1493                return Err(TryFromProtoError::invalid(
1494                    Input::KIND_FIELD,
1495                    "unknown InputKind",
1496                ))
1497            }
1498
1499            InputKind::Pure => Self::Pure {
1500                value: value
1501                    .pure
1502                    .as_ref()
1503                    .ok_or_else(|| TryFromProtoError::missing("pure"))?
1504                    .to_vec(),
1505            },
1506            InputKind::ImmutableOrOwned => {
1507                let object_id = value
1508                    .object_id
1509                    .as_ref()
1510                    .ok_or_else(|| TryFromProtoError::missing("object_id"))?
1511                    .parse()
1512                    .map_err(|e| TryFromProtoError::invalid(Input::OBJECT_ID_FIELD, e))?;
1513                let version = value
1514                    .version
1515                    .ok_or_else(|| TryFromProtoError::missing("version"))?;
1516                let digest = value
1517                    .digest
1518                    .as_ref()
1519                    .ok_or_else(|| TryFromProtoError::missing("digest"))?
1520                    .parse()
1521                    .map_err(|e| TryFromProtoError::invalid(Input::DIGEST_FIELD, e))?;
1522                let reference = sui_sdk_types::ObjectReference::new(object_id, version, digest);
1523                Self::ImmutableOrOwned(reference)
1524            }
1525            InputKind::Shared => {
1526                let object_id = value
1527                    .object_id
1528                    .as_ref()
1529                    .ok_or_else(|| TryFromProtoError::missing("object_id"))?
1530                    .parse()
1531                    .map_err(|e| TryFromProtoError::invalid(Input::OBJECT_ID_FIELD, e))?;
1532                let initial_shared_version = value
1533                    .version
1534                    .ok_or_else(|| TryFromProtoError::missing("version"))?;
1535                let mutable = value
1536                    .mutable
1537                    .ok_or_else(|| TryFromProtoError::missing("mutable"))?;
1538                Self::Shared {
1539                    object_id,
1540                    initial_shared_version,
1541                    mutable,
1542                }
1543            }
1544            InputKind::Receiving => {
1545                let object_id = value
1546                    .object_id
1547                    .as_ref()
1548                    .ok_or_else(|| TryFromProtoError::missing("object_id"))?
1549                    .parse()
1550                    .map_err(|e| TryFromProtoError::invalid(Input::OBJECT_ID_FIELD, e))?;
1551                let version = value
1552                    .version
1553                    .ok_or_else(|| TryFromProtoError::missing("version"))?;
1554                let digest = value
1555                    .digest
1556                    .as_ref()
1557                    .ok_or_else(|| TryFromProtoError::missing("digest"))?
1558                    .parse()
1559                    .map_err(|e| TryFromProtoError::invalid(Input::DIGEST_FIELD, e))?;
1560                let reference = sui_sdk_types::ObjectReference::new(object_id, version, digest);
1561                Self::Receiving(reference)
1562            }
1563        }
1564        .pipe(Ok)
1565    }
1566}
1567
1568//
1569// Argument
1570//
1571
1572impl Argument {
1573    pub fn gas() -> Self {
1574        Self {
1575            kind: Some(argument::ArgumentKind::Gas.into()),
1576            input: None,
1577            result: None,
1578            subresult: None,
1579        }
1580    }
1581
1582    pub fn new_input(input: u16) -> Self {
1583        Self {
1584            kind: Some(argument::ArgumentKind::Input.into()),
1585            input: Some(input.into()),
1586            result: None,
1587            subresult: None,
1588        }
1589    }
1590
1591    pub fn new_result(command: u16) -> Self {
1592        Self {
1593            kind: Some(argument::ArgumentKind::Result.into()),
1594            input: None,
1595            result: Some(command.into()),
1596            subresult: None,
1597        }
1598    }
1599
1600    pub fn nested_result(command: u16, subresult: u16) -> Self {
1601        Self {
1602            kind: Some(argument::ArgumentKind::Result.into()),
1603            input: None,
1604            result: Some(command.into()),
1605            subresult: Some(subresult.into()),
1606        }
1607    }
1608}
1609
1610impl From<sui_sdk_types::Argument> for Argument {
1611    fn from(value: sui_sdk_types::Argument) -> Self {
1612        use argument::ArgumentKind;
1613        use sui_sdk_types::Argument::*;
1614
1615        let mut message = Self::default();
1616
1617        let kind = match value {
1618            Gas => ArgumentKind::Gas,
1619            Input(input) => {
1620                message.input = Some(input.into());
1621                ArgumentKind::Input
1622            }
1623            Result(result) => {
1624                message.result = Some(result.into());
1625                ArgumentKind::Result
1626            }
1627            NestedResult(result, subresult) => {
1628                message.result = Some(result.into());
1629                message.subresult = Some(subresult.into());
1630                ArgumentKind::Result
1631            }
1632        };
1633
1634        message.set_kind(kind);
1635        message
1636    }
1637}
1638
1639impl TryFrom<&Argument> for sui_sdk_types::Argument {
1640    type Error = TryFromProtoError;
1641
1642    fn try_from(value: &Argument) -> Result<Self, Self::Error> {
1643        use argument::ArgumentKind;
1644
1645        match value.kind() {
1646            ArgumentKind::Unknown => {
1647                return Err(TryFromProtoError::invalid(
1648                    Argument::KIND_FIELD,
1649                    "unknown ArgumentKind",
1650                ))
1651            }
1652            ArgumentKind::Gas => Self::Gas,
1653            ArgumentKind::Input => {
1654                let input = value
1655                    .input
1656                    .ok_or_else(|| TryFromProtoError::missing("input"))?
1657                    .try_into()
1658                    .map_err(|e| TryFromProtoError::invalid(Argument::INPUT_FIELD, e))?;
1659                Self::Input(input)
1660            }
1661            ArgumentKind::Result => {
1662                let result = value
1663                    .result
1664                    .ok_or_else(|| TryFromProtoError::missing("result"))?
1665                    .try_into()
1666                    .map_err(|e| TryFromProtoError::invalid(Argument::RESULT_FIELD, e))?;
1667
1668                if let Some(subresult) = value.subresult {
1669                    Self::NestedResult(
1670                        result,
1671                        subresult.try_into().map_err(|e| {
1672                            TryFromProtoError::invalid(Argument::SUBRESULT_FIELD, e)
1673                        })?,
1674                    )
1675                } else {
1676                    Self::Result(result)
1677                }
1678            }
1679        }
1680        .pipe(Ok)
1681    }
1682}
1683
1684//
1685// Command
1686//
1687
1688impl From<command::Command> for Command {
1689    fn from(value: command::Command) -> Self {
1690        Self {
1691            command: Some(value),
1692        }
1693    }
1694}
1695
1696impl From<MoveCall> for command::Command {
1697    fn from(value: MoveCall) -> Self {
1698        Self::MoveCall(value)
1699    }
1700}
1701
1702impl From<MoveCall> for Command {
1703    fn from(value: MoveCall) -> Self {
1704        command::Command::from(value).into()
1705    }
1706}
1707
1708impl From<TransferObjects> for command::Command {
1709    fn from(value: TransferObjects) -> Self {
1710        Self::TransferObjects(value)
1711    }
1712}
1713
1714impl From<TransferObjects> for Command {
1715    fn from(value: TransferObjects) -> Self {
1716        command::Command::from(value).into()
1717    }
1718}
1719
1720impl From<sui_sdk_types::Command> for Command {
1721    fn from(value: sui_sdk_types::Command) -> Self {
1722        use command::Command;
1723        use sui_sdk_types::Command::*;
1724
1725        let command = match value {
1726            MoveCall(move_call) => Command::MoveCall(move_call.into()),
1727            TransferObjects(transfer_objects) => Command::TransferObjects(transfer_objects.into()),
1728            SplitCoins(split_coins) => Command::SplitCoins(split_coins.into()),
1729            MergeCoins(merge_coins) => Command::MergeCoins(merge_coins.into()),
1730            Publish(publish) => Command::Publish(publish.into()),
1731            MakeMoveVector(make_move_vector) => Command::MakeMoveVector(make_move_vector.into()),
1732            Upgrade(upgrade) => Command::Upgrade(upgrade.into()),
1733
1734            //
1735            _ => return Self::default(),
1736        };
1737
1738        Self {
1739            command: Some(command),
1740        }
1741    }
1742}
1743
1744impl TryFrom<&Command> for sui_sdk_types::Command {
1745    type Error = TryFromProtoError;
1746
1747    fn try_from(value: &Command) -> Result<Self, Self::Error> {
1748        use command::Command;
1749
1750        match value
1751            .command
1752            .as_ref()
1753            .ok_or_else(|| TryFromProtoError::missing("command"))?
1754        {
1755            Command::MoveCall(move_call) => Self::MoveCall(move_call.try_into()?),
1756            Command::TransferObjects(transfer_objects) => {
1757                Self::TransferObjects(transfer_objects.try_into()?)
1758            }
1759            Command::SplitCoins(split_coins) => Self::SplitCoins(split_coins.try_into()?),
1760            Command::MergeCoins(merge_coins) => Self::MergeCoins(merge_coins.try_into()?),
1761            Command::Publish(publish) => Self::Publish(publish.try_into()?),
1762            Command::MakeMoveVector(make_move_vector) => {
1763                Self::MakeMoveVector(make_move_vector.try_into()?)
1764            }
1765            Command::Upgrade(upgrade) => Self::Upgrade(upgrade.try_into()?),
1766        }
1767        .pipe(Ok)
1768    }
1769}
1770
1771//
1772// MoveCall
1773//
1774
1775impl From<sui_sdk_types::MoveCall> for MoveCall {
1776    fn from(value: sui_sdk_types::MoveCall) -> Self {
1777        Self {
1778            package: Some(value.package.to_string()),
1779            module: Some(value.module.to_string()),
1780            function: Some(value.function.to_string()),
1781            type_arguments: value
1782                .type_arguments
1783                .iter()
1784                .map(ToString::to_string)
1785                .collect(),
1786            arguments: value.arguments.into_iter().map(Into::into).collect(),
1787        }
1788    }
1789}
1790
1791impl TryFrom<&MoveCall> for sui_sdk_types::MoveCall {
1792    type Error = TryFromProtoError;
1793
1794    fn try_from(value: &MoveCall) -> Result<Self, Self::Error> {
1795        let package = value
1796            .package
1797            .as_ref()
1798            .ok_or_else(|| TryFromProtoError::missing("package"))?
1799            .parse()
1800            .map_err(|e| TryFromProtoError::invalid(MoveCall::PACKAGE_FIELD, e))?;
1801
1802        let module = value
1803            .module
1804            .as_ref()
1805            .ok_or_else(|| TryFromProtoError::missing("module"))?
1806            .parse()
1807            .map_err(|e| TryFromProtoError::invalid(MoveCall::MODULE_FIELD, e))?;
1808
1809        let function = value
1810            .function
1811            .as_ref()
1812            .ok_or_else(|| TryFromProtoError::missing("function"))?
1813            .parse()
1814            .map_err(|e| TryFromProtoError::invalid(MoveCall::FUNCTION_FIELD, e))?;
1815
1816        let type_arguments = value
1817            .type_arguments
1818            .iter()
1819            .map(|t| {
1820                t.parse()
1821                    .map_err(|e| TryFromProtoError::invalid(MoveCall::TYPE_ARGUMENTS_FIELD, e))
1822            })
1823            .collect::<Result<_, _>>()?;
1824        let arguments = value
1825            .arguments
1826            .iter()
1827            .map(TryInto::try_into)
1828            .collect::<Result<_, _>>()?;
1829
1830        Ok(Self {
1831            package,
1832            module,
1833            function,
1834            type_arguments,
1835            arguments,
1836        })
1837    }
1838}
1839
1840//
1841// TransferObjects
1842//
1843
1844impl From<sui_sdk_types::TransferObjects> for TransferObjects {
1845    fn from(value: sui_sdk_types::TransferObjects) -> Self {
1846        Self {
1847            objects: value.objects.into_iter().map(Into::into).collect(),
1848            address: Some(value.address.into()),
1849        }
1850    }
1851}
1852
1853impl TryFrom<&TransferObjects> for sui_sdk_types::TransferObjects {
1854    type Error = TryFromProtoError;
1855
1856    fn try_from(value: &TransferObjects) -> Result<Self, Self::Error> {
1857        let objects = value
1858            .objects
1859            .iter()
1860            .map(TryInto::try_into)
1861            .collect::<Result<_, _>>()?;
1862
1863        let address = value
1864            .address
1865            .as_ref()
1866            .ok_or_else(|| TryFromProtoError::missing("address"))?
1867            .try_into()?;
1868
1869        Ok(Self { objects, address })
1870    }
1871}
1872
1873//
1874// SplitCoins
1875//
1876
1877impl From<sui_sdk_types::SplitCoins> for SplitCoins {
1878    fn from(value: sui_sdk_types::SplitCoins) -> Self {
1879        Self {
1880            coin: Some(value.coin.into()),
1881            amounts: value.amounts.into_iter().map(Into::into).collect(),
1882        }
1883    }
1884}
1885
1886impl TryFrom<&SplitCoins> for sui_sdk_types::SplitCoins {
1887    type Error = TryFromProtoError;
1888
1889    fn try_from(value: &SplitCoins) -> Result<Self, Self::Error> {
1890        let coin = value
1891            .coin
1892            .as_ref()
1893            .ok_or_else(|| TryFromProtoError::missing("coin"))?
1894            .try_into()?;
1895
1896        let amounts = value
1897            .amounts
1898            .iter()
1899            .map(TryInto::try_into)
1900            .collect::<Result<_, _>>()?;
1901
1902        Ok(Self { coin, amounts })
1903    }
1904}
1905
1906//
1907// MergeCoins
1908//
1909
1910impl From<sui_sdk_types::MergeCoins> for MergeCoins {
1911    fn from(value: sui_sdk_types::MergeCoins) -> Self {
1912        Self {
1913            coin: Some(value.coin.into()),
1914            coins_to_merge: value.coins_to_merge.into_iter().map(Into::into).collect(),
1915        }
1916    }
1917}
1918
1919impl TryFrom<&MergeCoins> for sui_sdk_types::MergeCoins {
1920    type Error = TryFromProtoError;
1921
1922    fn try_from(value: &MergeCoins) -> Result<Self, Self::Error> {
1923        let coin = value
1924            .coin
1925            .as_ref()
1926            .ok_or_else(|| TryFromProtoError::missing("coin"))?
1927            .try_into()?;
1928
1929        let coins_to_merge = value
1930            .coins_to_merge
1931            .iter()
1932            .map(TryInto::try_into)
1933            .collect::<Result<_, _>>()?;
1934
1935        Ok(Self {
1936            coin,
1937            coins_to_merge,
1938        })
1939    }
1940}
1941
1942//
1943// Publish
1944//
1945
1946impl From<sui_sdk_types::Publish> for Publish {
1947    fn from(value: sui_sdk_types::Publish) -> Self {
1948        Self {
1949            modules: value.modules.into_iter().map(Into::into).collect(),
1950            dependencies: value.dependencies.iter().map(ToString::to_string).collect(),
1951        }
1952    }
1953}
1954
1955impl TryFrom<&Publish> for sui_sdk_types::Publish {
1956    type Error = TryFromProtoError;
1957
1958    fn try_from(value: &Publish) -> Result<Self, Self::Error> {
1959        let modules = value.modules.iter().map(|bytes| bytes.to_vec()).collect();
1960
1961        let dependencies = value
1962            .dependencies
1963            .iter()
1964            .map(|s| s.parse())
1965            .collect::<Result<_, _>>()
1966            .map_err(|e| TryFromProtoError::invalid(Publish::DEPENDENCIES_FIELD, e))?;
1967
1968        Ok(Self {
1969            modules,
1970            dependencies,
1971        })
1972    }
1973}
1974
1975//
1976// MakeMoveVector
1977//
1978
1979impl From<sui_sdk_types::MakeMoveVector> for MakeMoveVector {
1980    fn from(value: sui_sdk_types::MakeMoveVector) -> Self {
1981        Self {
1982            element_type: value.type_.map(|t| t.to_string()),
1983            elements: value.elements.into_iter().map(Into::into).collect(),
1984        }
1985    }
1986}
1987
1988impl TryFrom<&MakeMoveVector> for sui_sdk_types::MakeMoveVector {
1989    type Error = TryFromProtoError;
1990
1991    fn try_from(value: &MakeMoveVector) -> Result<Self, Self::Error> {
1992        let element_type = value
1993            .element_type
1994            .as_ref()
1995            .map(|t| {
1996                t.parse()
1997                    .map_err(|e| TryFromProtoError::invalid(MakeMoveVector::ELEMENT_TYPE_FIELD, e))
1998            })
1999            .transpose()?;
2000
2001        let elements = value
2002            .elements
2003            .iter()
2004            .map(TryInto::try_into)
2005            .collect::<Result<_, _>>()?;
2006
2007        Ok(Self {
2008            type_: element_type,
2009            elements,
2010        })
2011    }
2012}
2013
2014//
2015// Upgrade
2016//
2017
2018impl From<sui_sdk_types::Upgrade> for Upgrade {
2019    fn from(value: sui_sdk_types::Upgrade) -> Self {
2020        Self {
2021            modules: value.modules.into_iter().map(Into::into).collect(),
2022            dependencies: value.dependencies.iter().map(ToString::to_string).collect(),
2023            package: Some(value.package.to_string()),
2024            ticket: Some(value.ticket.into()),
2025        }
2026    }
2027}
2028
2029impl TryFrom<&Upgrade> for sui_sdk_types::Upgrade {
2030    type Error = TryFromProtoError;
2031
2032    fn try_from(value: &Upgrade) -> Result<Self, Self::Error> {
2033        let modules = value.modules.iter().map(|bytes| bytes.to_vec()).collect();
2034
2035        let dependencies = value
2036            .dependencies
2037            .iter()
2038            .map(|s| s.parse())
2039            .collect::<Result<_, _>>()
2040            .map_err(|e| TryFromProtoError::invalid(Upgrade::DEPENDENCIES_FIELD, e))?;
2041
2042        let package = value
2043            .package
2044            .as_ref()
2045            .ok_or_else(|| TryFromProtoError::missing("package"))?
2046            .parse()
2047            .map_err(|e| TryFromProtoError::invalid(Upgrade::PACKAGE_FIELD, e))?;
2048
2049        let ticket = value
2050            .ticket
2051            .as_ref()
2052            .ok_or_else(|| TryFromProtoError::missing("ticket"))?
2053            .try_into()?;
2054
2055        Ok(Self {
2056            modules,
2057            dependencies,
2058            package,
2059            ticket,
2060        })
2061    }
2062}