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