Skip to main content

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            K::ForwardingAddressRegistryCreate => {
1215                message.with_kind(Kind::ForwardingAddressRegistryCreate)
1216            }
1217            _ => message,
1218        }
1219    }
1220}
1221
1222impl TryFrom<&EndOfEpochTransactionKind> for sui_sdk_types::EndOfEpochTransactionKind {
1223    type Error = TryFromProtoError;
1224
1225    fn try_from(value: &EndOfEpochTransactionKind) -> Result<Self, Self::Error> {
1226        use end_of_epoch_transaction_kind::Kind;
1227
1228        match value.kind() {
1229            Kind::Unknown => {
1230                return Err(TryFromProtoError::invalid(
1231                    EndOfEpochTransactionKind::KIND_FIELD,
1232                    "unknown EndOfEpochTransactionKind",
1233                ));
1234            }
1235            Kind::ChangeEpoch => Self::ChangeEpoch(value.change_epoch().try_into()?),
1236            Kind::AuthenticatorStateCreate => Self::AuthenticatorStateCreate,
1237            Kind::AuthenticatorStateExpire => {
1238                Self::AuthenticatorStateExpire(value.authenticator_state_expire().try_into()?)
1239            }
1240            Kind::RandomnessStateCreate => Self::RandomnessStateCreate,
1241            Kind::DenyListStateCreate => Self::DenyListStateCreate,
1242            Kind::BridgeStateCreate => Self::BridgeStateCreate {
1243                chain_id: value.bridge_chain_id().parse().map_err(|e| {
1244                    TryFromProtoError::invalid(EndOfEpochTransactionKind::BRIDGE_CHAIN_ID_FIELD, e)
1245                })?,
1246            },
1247            Kind::BridgeCommitteeInit => Self::BridgeCommitteeInit {
1248                bridge_object_version: value.bridge_object_version(),
1249            },
1250            Kind::StoreExecutionTimeObservations => Self::StoreExecutionTimeObservations(
1251                value.execution_time_observations().try_into()?,
1252            ),
1253            Kind::AccumulatorRootCreate => Self::AccumulatorRootCreate,
1254            Kind::CoinRegistryCreate => Self::CoinRegistryCreate,
1255            Kind::DisplayRegistryCreate => Self::DisplayRegistryCreate,
1256            Kind::AddressAliasStateCreate => Self::AddressAliasStateCreate,
1257            Kind::WriteAccumulatorStorageCost => Self::WriteAccumulatorStorageCost {
1258                storage_cost: value.storage_cost_opt().ok_or_else(|| {
1259                    TryFromProtoError::missing(EndOfEpochTransactionKind::STORAGE_COST_FIELD)
1260                })?,
1261            },
1262            Kind::ForwardingAddressRegistryCreate => Self::ForwardingAddressRegistryCreate,
1263        }
1264        .pipe(Ok)
1265    }
1266}
1267
1268//
1269// AuthenticatorStateExpire
1270//
1271
1272impl From<sui_sdk_types::AuthenticatorStateExpire> for AuthenticatorStateExpire {
1273    fn from(value: sui_sdk_types::AuthenticatorStateExpire) -> Self {
1274        Self {
1275            min_epoch: Some(value.min_epoch),
1276            authenticator_object_initial_shared_version: Some(
1277                value.authenticator_object_initial_shared_version,
1278            ),
1279        }
1280    }
1281}
1282
1283impl TryFrom<&AuthenticatorStateExpire> for sui_sdk_types::AuthenticatorStateExpire {
1284    type Error = TryFromProtoError;
1285
1286    fn try_from(
1287        AuthenticatorStateExpire {
1288            min_epoch,
1289            authenticator_object_initial_shared_version,
1290        }: &AuthenticatorStateExpire,
1291    ) -> Result<Self, Self::Error> {
1292        let min_epoch = min_epoch.ok_or_else(|| TryFromProtoError::missing("min_epoch"))?;
1293        let authenticator_object_initial_shared_version =
1294            authenticator_object_initial_shared_version.ok_or_else(|| {
1295                TryFromProtoError::missing("authenticator_object_initial_shared_version")
1296            })?;
1297        Ok(Self {
1298            min_epoch,
1299            authenticator_object_initial_shared_version,
1300        })
1301    }
1302}
1303
1304// ExecutionTimeObservations
1305
1306impl From<sui_sdk_types::ExecutionTimeObservations> for ExecutionTimeObservations {
1307    fn from(value: sui_sdk_types::ExecutionTimeObservations) -> Self {
1308        match value {
1309            sui_sdk_types::ExecutionTimeObservations::V1(vec) => Self {
1310                version: Some(1),
1311                observations: vec.into_iter().map(Into::into).collect(),
1312            },
1313            _ => Self::default(),
1314        }
1315    }
1316}
1317
1318impl TryFrom<&ExecutionTimeObservations> for sui_sdk_types::ExecutionTimeObservations {
1319    type Error = TryFromProtoError;
1320
1321    fn try_from(value: &ExecutionTimeObservations) -> Result<Self, Self::Error> {
1322        Ok(Self::V1(
1323            value
1324                .observations
1325                .iter()
1326                .map(|observation| observation.try_into())
1327                .collect::<Result<_, _>>()?,
1328        ))
1329    }
1330}
1331
1332impl
1333    From<(
1334        sui_sdk_types::ExecutionTimeObservationKey,
1335        Vec<sui_sdk_types::ValidatorExecutionTimeObservation>,
1336    )> for ExecutionTimeObservation
1337{
1338    fn from(
1339        value: (
1340            sui_sdk_types::ExecutionTimeObservationKey,
1341            Vec<sui_sdk_types::ValidatorExecutionTimeObservation>,
1342        ),
1343    ) -> Self {
1344        use execution_time_observation::ExecutionTimeObservationKind;
1345        use sui_sdk_types::ExecutionTimeObservationKey;
1346
1347        let mut message = Self::default();
1348
1349        let kind = match value.0 {
1350            ExecutionTimeObservationKey::MoveEntryPoint {
1351                package,
1352                module,
1353                function,
1354                type_arguments,
1355            } => {
1356                message.move_entry_point = Some(MoveCall {
1357                    package: Some(package.to_string()),
1358                    module: Some(module),
1359                    function: Some(function),
1360                    type_arguments: type_arguments
1361                        .into_iter()
1362                        .map(|ty| ty.to_string())
1363                        .collect(),
1364                    arguments: Vec::new(),
1365                });
1366                ExecutionTimeObservationKind::MoveEntryPoint
1367            }
1368            ExecutionTimeObservationKey::TransferObjects => {
1369                ExecutionTimeObservationKind::TransferObjects
1370            }
1371            ExecutionTimeObservationKey::SplitCoins => ExecutionTimeObservationKind::SplitCoins,
1372            ExecutionTimeObservationKey::MergeCoins => ExecutionTimeObservationKind::MergeCoins,
1373            ExecutionTimeObservationKey::Publish => ExecutionTimeObservationKind::Publish,
1374            ExecutionTimeObservationKey::MakeMoveVec => {
1375                ExecutionTimeObservationKind::MakeMoveVector
1376            }
1377            ExecutionTimeObservationKey::Upgrade => ExecutionTimeObservationKind::Upgrade,
1378
1379            _ => ExecutionTimeObservationKind::Unknown,
1380        };
1381
1382        message.validator_observations = value.1.into_iter().map(Into::into).collect();
1383        message.set_kind(kind);
1384        message
1385    }
1386}
1387
1388impl TryFrom<&ExecutionTimeObservation>
1389    for (
1390        sui_sdk_types::ExecutionTimeObservationKey,
1391        Vec<sui_sdk_types::ValidatorExecutionTimeObservation>,
1392    )
1393{
1394    type Error = TryFromProtoError;
1395
1396    fn try_from(value: &ExecutionTimeObservation) -> Result<Self, Self::Error> {
1397        use execution_time_observation::ExecutionTimeObservationKind;
1398        use sui_sdk_types::ExecutionTimeObservationKey;
1399
1400        let key = match value.kind() {
1401            ExecutionTimeObservationKind::Unknown => {
1402                return Err(TryFromProtoError::invalid(
1403                    ExecutionTimeObservation::KIND_FIELD,
1404                    "unknown ExecutionTimeObservationKind",
1405                ));
1406            }
1407            ExecutionTimeObservationKind::MoveEntryPoint => {
1408                let move_call = value
1409                    .move_entry_point
1410                    .as_ref()
1411                    .ok_or_else(|| TryFromProtoError::missing("move_entry_point"))?;
1412                ExecutionTimeObservationKey::MoveEntryPoint {
1413                    package: move_call
1414                        .package()
1415                        .parse()
1416                        .map_err(|e| TryFromProtoError::invalid(MoveCall::PACKAGE_FIELD, e))?,
1417                    module: move_call.module().to_owned(),
1418                    function: move_call.function().to_owned(),
1419                    type_arguments: move_call
1420                        .type_arguments
1421                        .iter()
1422                        .map(|t| {
1423                            t.parse().map_err(|e| {
1424                                TryFromProtoError::invalid(MoveCall::TYPE_ARGUMENTS_FIELD, e)
1425                            })
1426                        })
1427                        .collect::<Result<_, _>>()?,
1428                }
1429            }
1430            ExecutionTimeObservationKind::TransferObjects => {
1431                ExecutionTimeObservationKey::TransferObjects
1432            }
1433            ExecutionTimeObservationKind::SplitCoins => ExecutionTimeObservationKey::SplitCoins,
1434            ExecutionTimeObservationKind::MergeCoins => ExecutionTimeObservationKey::MergeCoins,
1435            ExecutionTimeObservationKind::Publish => ExecutionTimeObservationKey::Publish,
1436            ExecutionTimeObservationKind::MakeMoveVector => {
1437                ExecutionTimeObservationKey::MakeMoveVec
1438            }
1439            ExecutionTimeObservationKind::Upgrade => ExecutionTimeObservationKey::Upgrade,
1440        };
1441
1442        let observations = value
1443            .validator_observations
1444            .iter()
1445            .map(sui_sdk_types::ValidatorExecutionTimeObservation::try_from)
1446            .collect::<Result<_, _>>()?;
1447
1448        Ok((key, observations))
1449    }
1450}
1451
1452// ValidatorExecutionTimeObservation
1453
1454impl From<sui_sdk_types::ValidatorExecutionTimeObservation> for ValidatorExecutionTimeObservation {
1455    fn from(value: sui_sdk_types::ValidatorExecutionTimeObservation) -> Self {
1456        Self {
1457            validator: Some(value.validator.as_bytes().to_vec().into()),
1458            duration: Some(prost_types::Duration {
1459                seconds: value.duration.as_secs() as i64,
1460                nanos: value.duration.subsec_nanos() as i32,
1461            }),
1462        }
1463    }
1464}
1465
1466impl TryFrom<&ValidatorExecutionTimeObservation>
1467    for sui_sdk_types::ValidatorExecutionTimeObservation
1468{
1469    type Error = TryFromProtoError;
1470
1471    fn try_from(value: &ValidatorExecutionTimeObservation) -> Result<Self, Self::Error> {
1472        Ok(Self {
1473            validator: value
1474                .validator
1475                .as_ref()
1476                .ok_or_else(|| TryFromProtoError::missing("validator"))?
1477                .as_ref()
1478                .pipe(sui_sdk_types::Bls12381PublicKey::from_bytes)
1479                .map_err(|e| {
1480                    TryFromProtoError::invalid(
1481                        ValidatorExecutionTimeObservation::VALIDATOR_FIELD,
1482                        e,
1483                    )
1484                })?,
1485            duration: value
1486                .duration
1487                .ok_or_else(|| TryFromProtoError::missing("duration"))?
1488                .try_into()
1489                .map_err(|e| {
1490                    TryFromProtoError::invalid(ValidatorExecutionTimeObservation::DURATION_FIELD, e)
1491                })?,
1492        })
1493    }
1494}
1495
1496//
1497// ProgrammableTransaction
1498//
1499
1500impl From<sui_sdk_types::ProgrammableTransaction> for ProgrammableTransaction {
1501    fn from(value: sui_sdk_types::ProgrammableTransaction) -> Self {
1502        Self {
1503            inputs: value.inputs.into_iter().map(Into::into).collect(),
1504            commands: value.commands.into_iter().map(Into::into).collect(),
1505        }
1506    }
1507}
1508
1509impl TryFrom<&ProgrammableTransaction> for sui_sdk_types::ProgrammableTransaction {
1510    type Error = TryFromProtoError;
1511
1512    fn try_from(value: &ProgrammableTransaction) -> Result<Self, Self::Error> {
1513        Ok(Self {
1514            inputs: value
1515                .inputs
1516                .iter()
1517                .map(TryInto::try_into)
1518                .collect::<Result<_, _>>()?,
1519            commands: value
1520                .commands
1521                .iter()
1522                .map(TryInto::try_into)
1523                .collect::<Result<_, _>>()?,
1524        })
1525    }
1526}
1527
1528//
1529// Input
1530//
1531
1532impl From<sui_sdk_types::Input> for Input {
1533    fn from(value: sui_sdk_types::Input) -> Self {
1534        use input::InputKind;
1535        use sui_sdk_types::Input::*;
1536
1537        let mut message = Self::default();
1538
1539        let kind = match value {
1540            Pure(value) => {
1541                message.pure = Some(value.into());
1542                InputKind::Pure
1543            }
1544            ImmutableOrOwned(reference) => {
1545                message.object_id = Some(reference.object_id().to_string());
1546                message.version = Some(reference.version());
1547                message.digest = Some(reference.digest().to_string());
1548                InputKind::ImmutableOrOwned
1549            }
1550            Shared(shared_input) => {
1551                message.object_id = Some(shared_input.object_id().to_string());
1552                message.version = Some(shared_input.version());
1553                message.mutable = Some(shared_input.mutability().is_mutable());
1554                message.set_mutability(shared_input.mutability().into());
1555
1556                InputKind::Shared
1557            }
1558            Receiving(reference) => {
1559                message.object_id = Some(reference.object_id().to_string());
1560                message.version = Some(reference.version());
1561                message.digest = Some(reference.digest().to_string());
1562                InputKind::Receiving
1563            }
1564            FundsWithdrawal(funds_withdrawal) => {
1565                message.set_funds_withdrawal(funds_withdrawal);
1566                InputKind::FundsWithdrawal
1567            }
1568            _ => InputKind::Unknown,
1569        };
1570
1571        message.set_kind(kind);
1572        message
1573    }
1574}
1575
1576impl TryFrom<&Input> for sui_sdk_types::Input {
1577    type Error = TryFromProtoError;
1578
1579    fn try_from(value: &Input) -> Result<Self, Self::Error> {
1580        use input::InputKind;
1581
1582        match value.kind() {
1583            InputKind::Unknown => {
1584                return Err(TryFromProtoError::invalid(
1585                    Input::KIND_FIELD,
1586                    "unknown InputKind",
1587                ));
1588            }
1589            InputKind::Pure => Self::Pure(
1590                value
1591                    .pure
1592                    .as_ref()
1593                    .ok_or_else(|| TryFromProtoError::missing("pure"))?
1594                    .to_vec(),
1595            ),
1596            InputKind::ImmutableOrOwned => {
1597                let object_id = value
1598                    .object_id
1599                    .as_ref()
1600                    .ok_or_else(|| TryFromProtoError::missing("object_id"))?
1601                    .parse()
1602                    .map_err(|e| TryFromProtoError::invalid(Input::OBJECT_ID_FIELD, e))?;
1603                let version = value
1604                    .version
1605                    .ok_or_else(|| TryFromProtoError::missing("version"))?;
1606                let digest = value
1607                    .digest
1608                    .as_ref()
1609                    .ok_or_else(|| TryFromProtoError::missing("digest"))?
1610                    .parse()
1611                    .map_err(|e| TryFromProtoError::invalid(Input::DIGEST_FIELD, e))?;
1612                let reference = sui_sdk_types::ObjectReference::new(object_id, version, digest);
1613                Self::ImmutableOrOwned(reference)
1614            }
1615            InputKind::Shared => {
1616                let object_id = value
1617                    .object_id
1618                    .as_ref()
1619                    .ok_or_else(|| TryFromProtoError::missing("object_id"))?
1620                    .parse()
1621                    .map_err(|e| TryFromProtoError::invalid(Input::OBJECT_ID_FIELD, e))?;
1622                let initial_shared_version = value
1623                    .version
1624                    .ok_or_else(|| TryFromProtoError::missing("version"))?;
1625
1626                let shared_input = match value.mutability() {
1627                    input::Mutability::Unknown => {
1628                        let mutable = value
1629                            .mutable
1630                            .ok_or_else(|| TryFromProtoError::missing("mutable"))?;
1631                        sui_sdk_types::SharedInput::new(object_id, initial_shared_version, mutable)
1632                    }
1633                    input::Mutability::Immutable => sui_sdk_types::SharedInput::new(
1634                        object_id,
1635                        initial_shared_version,
1636                        sui_sdk_types::Mutability::Immutable,
1637                    ),
1638                    input::Mutability::Mutable => sui_sdk_types::SharedInput::new(
1639                        object_id,
1640                        initial_shared_version,
1641                        sui_sdk_types::Mutability::Mutable,
1642                    ),
1643                    input::Mutability::NonExclusiveWrite => sui_sdk_types::SharedInput::new(
1644                        object_id,
1645                        initial_shared_version,
1646                        sui_sdk_types::Mutability::NonExclusiveWrite,
1647                    ),
1648                };
1649
1650                Self::Shared(shared_input)
1651            }
1652            InputKind::Receiving => {
1653                let object_id = value
1654                    .object_id
1655                    .as_ref()
1656                    .ok_or_else(|| TryFromProtoError::missing("object_id"))?
1657                    .parse()
1658                    .map_err(|e| TryFromProtoError::invalid(Input::OBJECT_ID_FIELD, e))?;
1659                let version = value
1660                    .version
1661                    .ok_or_else(|| TryFromProtoError::missing("version"))?;
1662                let digest = value
1663                    .digest
1664                    .as_ref()
1665                    .ok_or_else(|| TryFromProtoError::missing("digest"))?
1666                    .parse()
1667                    .map_err(|e| TryFromProtoError::invalid(Input::DIGEST_FIELD, e))?;
1668                let reference = sui_sdk_types::ObjectReference::new(object_id, version, digest);
1669                Self::Receiving(reference)
1670            }
1671            InputKind::FundsWithdrawal => {
1672                let funds_withdrawal = value
1673                    .funds_withdrawal_opt()
1674                    .ok_or_else(|| TryFromProtoError::missing("funds_withdrawal"))?
1675                    .try_into()?;
1676                Self::FundsWithdrawal(funds_withdrawal)
1677            }
1678        }
1679        .pipe(Ok)
1680    }
1681}
1682
1683impl From<sui_sdk_types::Mutability> for input::Mutability {
1684    fn from(value: sui_sdk_types::Mutability) -> Self {
1685        match value {
1686            sui_sdk_types::Mutability::Immutable => Self::Immutable,
1687            sui_sdk_types::Mutability::Mutable => Self::Mutable,
1688            sui_sdk_types::Mutability::NonExclusiveWrite => Self::NonExclusiveWrite,
1689        }
1690    }
1691}
1692
1693//
1694// FundsWithdrawal
1695//
1696
1697impl From<sui_sdk_types::FundsWithdrawal> for FundsWithdrawal {
1698    fn from(value: sui_sdk_types::FundsWithdrawal) -> Self {
1699        let mut message = Self::default();
1700        message.set_coin_type(value.coin_type());
1701        message.set_source(value.source().into());
1702        if let sui_sdk_types::WithdrawFrom::Allowance { funder, allowance } = value.source() {
1703            message.set_funder(funder.to_string());
1704            message.set_allowance(allowance.to_string());
1705        }
1706        message.amount = value.amount();
1707        message
1708    }
1709}
1710
1711impl TryFrom<&FundsWithdrawal> for sui_sdk_types::FundsWithdrawal {
1712    type Error = TryFromProtoError;
1713
1714    fn try_from(value: &FundsWithdrawal) -> Result<Self, Self::Error> {
1715        use funds_withdrawal::Source;
1716
1717        let amount = value
1718            .amount_opt()
1719            .ok_or_else(|| TryFromProtoError::missing("amount"))?;
1720        let coin_type = value
1721            .coin_type_opt()
1722            .ok_or_else(|| TryFromProtoError::missing("coin_type"))?
1723            .parse()
1724            .map_err(|e| TryFromProtoError::invalid("coin_type", e))?;
1725        let source = match value.source() {
1726            Source::Unknown => return Err(TryFromProtoError::invalid("source", "unknown source")),
1727            Source::Sender => sui_sdk_types::WithdrawFrom::Sender,
1728            Source::Sponsor => sui_sdk_types::WithdrawFrom::Sponsor,
1729            Source::Allowance => {
1730                let funder = value
1731                    .funder_opt()
1732                    .ok_or_else(|| TryFromProtoError::missing("funder"))?
1733                    .parse()
1734                    .map_err(|e| TryFromProtoError::invalid(FundsWithdrawal::FUNDER_FIELD, e))?;
1735                let allowance = value
1736                    .allowance_opt()
1737                    .ok_or_else(|| TryFromProtoError::missing("allowance"))?
1738                    .parse()
1739                    .map_err(|e| TryFromProtoError::invalid(FundsWithdrawal::ALLOWANCE_FIELD, e))?;
1740                sui_sdk_types::WithdrawFrom::Allowance { funder, allowance }
1741            }
1742        };
1743
1744        Ok(Self::new(amount, coin_type, source))
1745    }
1746}
1747
1748impl From<sui_sdk_types::WithdrawFrom> for funds_withdrawal::Source {
1749    fn from(value: sui_sdk_types::WithdrawFrom) -> Self {
1750        match value {
1751            sui_sdk_types::WithdrawFrom::Sender => Self::Sender,
1752            sui_sdk_types::WithdrawFrom::Sponsor => Self::Sponsor,
1753            sui_sdk_types::WithdrawFrom::Allowance { .. } => Self::Allowance,
1754            _ => Self::Unknown,
1755        }
1756    }
1757}
1758
1759//
1760// Argument
1761//
1762
1763impl Argument {
1764    pub fn gas() -> Self {
1765        Self {
1766            kind: Some(argument::ArgumentKind::Gas.into()),
1767            input: None,
1768            result: None,
1769            subresult: None,
1770        }
1771    }
1772
1773    pub fn new_input(input: u16) -> Self {
1774        Self {
1775            kind: Some(argument::ArgumentKind::Input.into()),
1776            input: Some(input.into()),
1777            result: None,
1778            subresult: None,
1779        }
1780    }
1781
1782    pub fn new_result(command: u16) -> Self {
1783        Self {
1784            kind: Some(argument::ArgumentKind::Result.into()),
1785            input: None,
1786            result: Some(command.into()),
1787            subresult: None,
1788        }
1789    }
1790
1791    pub fn nested_result(command: u16, subresult: u16) -> Self {
1792        Self {
1793            kind: Some(argument::ArgumentKind::Result.into()),
1794            input: None,
1795            result: Some(command.into()),
1796            subresult: Some(subresult.into()),
1797        }
1798    }
1799}
1800
1801impl From<sui_sdk_types::Argument> for Argument {
1802    fn from(value: sui_sdk_types::Argument) -> Self {
1803        use argument::ArgumentKind;
1804        use sui_sdk_types::Argument::*;
1805
1806        let mut message = Self::default();
1807
1808        let kind = match value {
1809            Gas => ArgumentKind::Gas,
1810            Input(input) => {
1811                message.input = Some(input.into());
1812                ArgumentKind::Input
1813            }
1814            Result(result) => {
1815                message.result = Some(result.into());
1816                ArgumentKind::Result
1817            }
1818            NestedResult(result, subresult) => {
1819                message.result = Some(result.into());
1820                message.subresult = Some(subresult.into());
1821                ArgumentKind::Result
1822            }
1823        };
1824
1825        message.set_kind(kind);
1826        message
1827    }
1828}
1829
1830impl TryFrom<&Argument> for sui_sdk_types::Argument {
1831    type Error = TryFromProtoError;
1832
1833    fn try_from(value: &Argument) -> Result<Self, Self::Error> {
1834        use argument::ArgumentKind;
1835
1836        match value.kind() {
1837            ArgumentKind::Unknown => {
1838                return Err(TryFromProtoError::invalid(
1839                    Argument::KIND_FIELD,
1840                    "unknown ArgumentKind",
1841                ));
1842            }
1843            ArgumentKind::Gas => Self::Gas,
1844            ArgumentKind::Input => {
1845                let input = value
1846                    .input
1847                    .ok_or_else(|| TryFromProtoError::missing("input"))?
1848                    .try_into()
1849                    .map_err(|e| TryFromProtoError::invalid(Argument::INPUT_FIELD, e))?;
1850                Self::Input(input)
1851            }
1852            ArgumentKind::Result => {
1853                let result = value
1854                    .result
1855                    .ok_or_else(|| TryFromProtoError::missing("result"))?
1856                    .try_into()
1857                    .map_err(|e| TryFromProtoError::invalid(Argument::RESULT_FIELD, e))?;
1858
1859                if let Some(subresult) = value.subresult {
1860                    Self::NestedResult(
1861                        result,
1862                        subresult.try_into().map_err(|e| {
1863                            TryFromProtoError::invalid(Argument::SUBRESULT_FIELD, e)
1864                        })?,
1865                    )
1866                } else {
1867                    Self::Result(result)
1868                }
1869            }
1870        }
1871        .pipe(Ok)
1872    }
1873}
1874
1875//
1876// Command
1877//
1878
1879impl From<command::Command> for Command {
1880    fn from(value: command::Command) -> Self {
1881        Self {
1882            command: Some(value),
1883        }
1884    }
1885}
1886
1887impl From<MoveCall> for command::Command {
1888    fn from(value: MoveCall) -> Self {
1889        Self::MoveCall(value)
1890    }
1891}
1892
1893impl From<MoveCall> for Command {
1894    fn from(value: MoveCall) -> Self {
1895        command::Command::from(value).into()
1896    }
1897}
1898
1899impl From<TransferObjects> for command::Command {
1900    fn from(value: TransferObjects) -> Self {
1901        Self::TransferObjects(value)
1902    }
1903}
1904
1905impl From<TransferObjects> for Command {
1906    fn from(value: TransferObjects) -> Self {
1907        command::Command::from(value).into()
1908    }
1909}
1910
1911impl From<sui_sdk_types::Command> for Command {
1912    fn from(value: sui_sdk_types::Command) -> Self {
1913        use command::Command;
1914        use sui_sdk_types::Command::*;
1915
1916        let command = match value {
1917            MoveCall(move_call) => Command::MoveCall(move_call.into()),
1918            TransferObjects(transfer_objects) => Command::TransferObjects(transfer_objects.into()),
1919            SplitCoins(split_coins) => Command::SplitCoins(split_coins.into()),
1920            MergeCoins(merge_coins) => Command::MergeCoins(merge_coins.into()),
1921            Publish(publish) => Command::Publish(publish.into()),
1922            MakeMoveVector(make_move_vector) => Command::MakeMoveVector(make_move_vector.into()),
1923            Upgrade(upgrade) => Command::Upgrade(upgrade.into()),
1924
1925            //
1926            _ => return Self::default(),
1927        };
1928
1929        Self {
1930            command: Some(command),
1931        }
1932    }
1933}
1934
1935impl TryFrom<&Command> for sui_sdk_types::Command {
1936    type Error = TryFromProtoError;
1937
1938    fn try_from(value: &Command) -> Result<Self, Self::Error> {
1939        use command::Command;
1940
1941        match value
1942            .command
1943            .as_ref()
1944            .ok_or_else(|| TryFromProtoError::missing("command"))?
1945        {
1946            Command::MoveCall(move_call) => Self::MoveCall(move_call.try_into()?),
1947            Command::TransferObjects(transfer_objects) => {
1948                Self::TransferObjects(transfer_objects.try_into()?)
1949            }
1950            Command::SplitCoins(split_coins) => Self::SplitCoins(split_coins.try_into()?),
1951            Command::MergeCoins(merge_coins) => Self::MergeCoins(merge_coins.try_into()?),
1952            Command::Publish(publish) => Self::Publish(publish.try_into()?),
1953            Command::MakeMoveVector(make_move_vector) => {
1954                Self::MakeMoveVector(make_move_vector.try_into()?)
1955            }
1956            Command::Upgrade(upgrade) => Self::Upgrade(upgrade.try_into()?),
1957        }
1958        .pipe(Ok)
1959    }
1960}
1961
1962//
1963// MoveCall
1964//
1965
1966impl From<sui_sdk_types::MoveCall> for MoveCall {
1967    fn from(value: sui_sdk_types::MoveCall) -> Self {
1968        Self {
1969            package: Some(value.package.to_string()),
1970            module: Some(value.module.to_string()),
1971            function: Some(value.function.to_string()),
1972            type_arguments: value
1973                .type_arguments
1974                .iter()
1975                .map(ToString::to_string)
1976                .collect(),
1977            arguments: value.arguments.into_iter().map(Into::into).collect(),
1978        }
1979    }
1980}
1981
1982impl TryFrom<&MoveCall> for sui_sdk_types::MoveCall {
1983    type Error = TryFromProtoError;
1984
1985    fn try_from(value: &MoveCall) -> Result<Self, Self::Error> {
1986        let package = value
1987            .package
1988            .as_ref()
1989            .ok_or_else(|| TryFromProtoError::missing("package"))?
1990            .parse()
1991            .map_err(|e| TryFromProtoError::invalid(MoveCall::PACKAGE_FIELD, e))?;
1992
1993        let module = value
1994            .module
1995            .as_ref()
1996            .ok_or_else(|| TryFromProtoError::missing("module"))?
1997            .parse()
1998            .map_err(|e| TryFromProtoError::invalid(MoveCall::MODULE_FIELD, e))?;
1999
2000        let function = value
2001            .function
2002            .as_ref()
2003            .ok_or_else(|| TryFromProtoError::missing("function"))?
2004            .parse()
2005            .map_err(|e| TryFromProtoError::invalid(MoveCall::FUNCTION_FIELD, e))?;
2006
2007        let type_arguments = value
2008            .type_arguments
2009            .iter()
2010            .map(|t| {
2011                t.parse()
2012                    .map_err(|e| TryFromProtoError::invalid(MoveCall::TYPE_ARGUMENTS_FIELD, e))
2013            })
2014            .collect::<Result<_, _>>()?;
2015        let arguments = value
2016            .arguments
2017            .iter()
2018            .map(TryInto::try_into)
2019            .collect::<Result<_, _>>()?;
2020
2021        Ok(Self {
2022            package,
2023            module,
2024            function,
2025            type_arguments,
2026            arguments,
2027        })
2028    }
2029}
2030
2031//
2032// TransferObjects
2033//
2034
2035impl From<sui_sdk_types::TransferObjects> for TransferObjects {
2036    fn from(value: sui_sdk_types::TransferObjects) -> Self {
2037        Self {
2038            objects: value.objects.into_iter().map(Into::into).collect(),
2039            address: Some(value.address.into()),
2040        }
2041    }
2042}
2043
2044impl TryFrom<&TransferObjects> for sui_sdk_types::TransferObjects {
2045    type Error = TryFromProtoError;
2046
2047    fn try_from(value: &TransferObjects) -> Result<Self, Self::Error> {
2048        let objects = value
2049            .objects
2050            .iter()
2051            .map(TryInto::try_into)
2052            .collect::<Result<_, _>>()?;
2053
2054        let address = value
2055            .address
2056            .as_ref()
2057            .ok_or_else(|| TryFromProtoError::missing("address"))?
2058            .try_into()?;
2059
2060        Ok(Self { objects, address })
2061    }
2062}
2063
2064//
2065// SplitCoins
2066//
2067
2068impl From<sui_sdk_types::SplitCoins> for SplitCoins {
2069    fn from(value: sui_sdk_types::SplitCoins) -> Self {
2070        Self {
2071            coin: Some(value.coin.into()),
2072            amounts: value.amounts.into_iter().map(Into::into).collect(),
2073        }
2074    }
2075}
2076
2077impl TryFrom<&SplitCoins> for sui_sdk_types::SplitCoins {
2078    type Error = TryFromProtoError;
2079
2080    fn try_from(value: &SplitCoins) -> Result<Self, Self::Error> {
2081        let coin = value
2082            .coin
2083            .as_ref()
2084            .ok_or_else(|| TryFromProtoError::missing("coin"))?
2085            .try_into()?;
2086
2087        let amounts = value
2088            .amounts
2089            .iter()
2090            .map(TryInto::try_into)
2091            .collect::<Result<_, _>>()?;
2092
2093        Ok(Self { coin, amounts })
2094    }
2095}
2096
2097//
2098// MergeCoins
2099//
2100
2101impl From<sui_sdk_types::MergeCoins> for MergeCoins {
2102    fn from(value: sui_sdk_types::MergeCoins) -> Self {
2103        Self {
2104            coin: Some(value.coin.into()),
2105            coins_to_merge: value.coins_to_merge.into_iter().map(Into::into).collect(),
2106        }
2107    }
2108}
2109
2110impl TryFrom<&MergeCoins> for sui_sdk_types::MergeCoins {
2111    type Error = TryFromProtoError;
2112
2113    fn try_from(value: &MergeCoins) -> Result<Self, Self::Error> {
2114        let coin = value
2115            .coin
2116            .as_ref()
2117            .ok_or_else(|| TryFromProtoError::missing("coin"))?
2118            .try_into()?;
2119
2120        let coins_to_merge = value
2121            .coins_to_merge
2122            .iter()
2123            .map(TryInto::try_into)
2124            .collect::<Result<_, _>>()?;
2125
2126        Ok(Self {
2127            coin,
2128            coins_to_merge,
2129        })
2130    }
2131}
2132
2133//
2134// Publish
2135//
2136
2137impl From<sui_sdk_types::Publish> for Publish {
2138    fn from(value: sui_sdk_types::Publish) -> Self {
2139        Self {
2140            modules: value.modules.into_iter().map(Into::into).collect(),
2141            dependencies: value.dependencies.iter().map(ToString::to_string).collect(),
2142        }
2143    }
2144}
2145
2146impl TryFrom<&Publish> for sui_sdk_types::Publish {
2147    type Error = TryFromProtoError;
2148
2149    fn try_from(value: &Publish) -> Result<Self, Self::Error> {
2150        let modules = value.modules.iter().map(|bytes| bytes.to_vec()).collect();
2151
2152        let dependencies = value
2153            .dependencies
2154            .iter()
2155            .map(|s| s.parse())
2156            .collect::<Result<_, _>>()
2157            .map_err(|e| TryFromProtoError::invalid(Publish::DEPENDENCIES_FIELD, e))?;
2158
2159        Ok(Self {
2160            modules,
2161            dependencies,
2162        })
2163    }
2164}
2165
2166//
2167// MakeMoveVector
2168//
2169
2170impl From<sui_sdk_types::MakeMoveVector> for MakeMoveVector {
2171    fn from(value: sui_sdk_types::MakeMoveVector) -> Self {
2172        Self {
2173            element_type: value.type_.map(|t| t.to_string()),
2174            elements: value.elements.into_iter().map(Into::into).collect(),
2175        }
2176    }
2177}
2178
2179impl TryFrom<&MakeMoveVector> for sui_sdk_types::MakeMoveVector {
2180    type Error = TryFromProtoError;
2181
2182    fn try_from(value: &MakeMoveVector) -> Result<Self, Self::Error> {
2183        let element_type = value
2184            .element_type
2185            .as_ref()
2186            .map(|t| {
2187                t.parse()
2188                    .map_err(|e| TryFromProtoError::invalid(MakeMoveVector::ELEMENT_TYPE_FIELD, e))
2189            })
2190            .transpose()?;
2191
2192        let elements = value
2193            .elements
2194            .iter()
2195            .map(TryInto::try_into)
2196            .collect::<Result<_, _>>()?;
2197
2198        Ok(Self {
2199            type_: element_type,
2200            elements,
2201        })
2202    }
2203}
2204
2205//
2206// Upgrade
2207//
2208
2209impl From<sui_sdk_types::Upgrade> for Upgrade {
2210    fn from(value: sui_sdk_types::Upgrade) -> Self {
2211        Self {
2212            modules: value.modules.into_iter().map(Into::into).collect(),
2213            dependencies: value.dependencies.iter().map(ToString::to_string).collect(),
2214            package: Some(value.package.to_string()),
2215            ticket: Some(value.ticket.into()),
2216        }
2217    }
2218}
2219
2220impl TryFrom<&Upgrade> for sui_sdk_types::Upgrade {
2221    type Error = TryFromProtoError;
2222
2223    fn try_from(value: &Upgrade) -> Result<Self, Self::Error> {
2224        let modules = value.modules.iter().map(|bytes| bytes.to_vec()).collect();
2225
2226        let dependencies = value
2227            .dependencies
2228            .iter()
2229            .map(|s| s.parse())
2230            .collect::<Result<_, _>>()
2231            .map_err(|e| TryFromProtoError::invalid(Upgrade::DEPENDENCIES_FIELD, e))?;
2232
2233        let package = value
2234            .package
2235            .as_ref()
2236            .ok_or_else(|| TryFromProtoError::missing("package"))?
2237            .parse()
2238            .map_err(|e| TryFromProtoError::invalid(Upgrade::PACKAGE_FIELD, e))?;
2239
2240        let ticket = value
2241            .ticket
2242            .as_ref()
2243            .ok_or_else(|| TryFromProtoError::missing("ticket"))?
2244            .try_into()?;
2245
2246        Ok(Self {
2247            modules,
2248            dependencies,
2249            package,
2250            ticket,
2251        })
2252    }
2253}