sui_types/
rpc_proto_conversions.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Module for conversions from sui-core types to rpc protos
5
6use crate::crypto::SuiSignature;
7
8fn ms_to_timestamp(ms: u64) -> prost_types::Timestamp {
9    prost_types::Timestamp {
10        seconds: (ms / 1000) as _,
11        nanos: ((ms % 1000) * 1_000_000) as _,
12    }
13}
14use crate::message_envelope::Message as _;
15use fastcrypto::traits::ToFromBytes;
16use sui_rpc::field::FieldMaskTree;
17use sui_rpc::merge::Merge;
18use sui_rpc::proto::TryFromProtoError;
19use sui_rpc::proto::sui::rpc::v2::*;
20
21//
22// CheckpointSummary
23//
24
25impl Merge<&crate::full_checkpoint_content::Checkpoint> for Checkpoint {
26    fn merge(&mut self, source: &crate::full_checkpoint_content::Checkpoint, mask: &FieldMaskTree) {
27        let sequence_number = source.summary.sequence_number;
28        let timestamp_ms = source.summary.timestamp_ms;
29
30        let summary = source.summary.data();
31        let signature = source.summary.auth_sig();
32
33        self.merge(summary, mask);
34        self.merge(signature.clone(), mask);
35
36        if mask.contains(Checkpoint::CONTENTS_FIELD.name) {
37            self.merge(&source.contents, mask);
38        }
39
40        if let Some(submask) = mask
41            .subtree(Checkpoint::OBJECTS_FIELD)
42            .and_then(|submask| submask.subtree(ObjectSet::OBJECTS_FIELD))
43        {
44            let set = source
45                .object_set
46                .iter()
47                .map(|o| sui_rpc::proto::sui::rpc::v2::Object::merge_from(o, &submask))
48                .collect();
49            self.objects = Some(ObjectSet::default().with_objects(set));
50        }
51
52        if let Some(submask) = mask.subtree(Checkpoint::TRANSACTIONS_FIELD.name) {
53            self.transactions = source
54                .transactions
55                .iter()
56                .map(|t| {
57                    let mut transaction = ExecutedTransaction::merge_from(t, &submask);
58                    transaction.checkpoint = submask
59                        .contains(ExecutedTransaction::CHECKPOINT_FIELD)
60                        .then_some(sequence_number);
61                    transaction.timestamp = submask
62                        .contains(ExecutedTransaction::TIMESTAMP_FIELD)
63                        .then(|| sui_rpc::proto::timestamp_ms_to_proto(timestamp_ms));
64                    transaction
65                })
66                .collect();
67        }
68    }
69}
70
71impl Merge<&crate::full_checkpoint_content::ExecutedTransaction> for ExecutedTransaction {
72    fn merge(
73        &mut self,
74        source: &crate::full_checkpoint_content::ExecutedTransaction,
75        mask: &FieldMaskTree,
76    ) {
77        if mask.contains(ExecutedTransaction::DIGEST_FIELD) {
78            self.digest = Some(source.transaction.digest().to_string());
79        }
80
81        if let Some(submask) = mask.subtree(ExecutedTransaction::TRANSACTION_FIELD) {
82            self.transaction = Some(Transaction::merge_from(&source.transaction, &submask));
83        }
84
85        if let Some(submask) = mask.subtree(ExecutedTransaction::SIGNATURES_FIELD) {
86            self.signatures = source
87                .signatures
88                .iter()
89                .map(|s| UserSignature::merge_from(s, &submask))
90                .collect();
91        }
92
93        if let Some(submask) = mask.subtree(ExecutedTransaction::EFFECTS_FIELD) {
94            let mut effects = TransactionEffects::merge_from(&source.effects, &submask);
95            if submask.contains(TransactionEffects::UNCHANGED_LOADED_RUNTIME_OBJECTS_FIELD) {
96                effects.set_unchanged_loaded_runtime_objects(
97                    source
98                        .unchanged_loaded_runtime_objects
99                        .iter()
100                        .map(Into::into)
101                        .collect(),
102                );
103            }
104            self.effects = Some(effects);
105        }
106
107        if let Some(submask) = mask.subtree(ExecutedTransaction::EVENTS_FIELD) {
108            self.events = source
109                .events
110                .as_ref()
111                .map(|events| TransactionEvents::merge_from(events, &submask));
112        }
113    }
114}
115
116impl TryFrom<&Checkpoint> for crate::full_checkpoint_content::Checkpoint {
117    type Error = TryFromProtoError;
118
119    fn try_from(checkpoint: &Checkpoint) -> Result<Self, Self::Error> {
120        let summary = checkpoint
121            .summary()
122            .bcs()
123            .deserialize()
124            .map_err(|e| TryFromProtoError::invalid("summary.bcs", e))?;
125
126        let signature =
127            crate::crypto::AuthorityStrongQuorumSignInfo::try_from(checkpoint.signature())?;
128
129        let summary = crate::messages_checkpoint::CertifiedCheckpointSummary::new_from_data_and_sig(
130            summary, signature,
131        );
132
133        let contents: crate::messages_checkpoint::CheckpointContents = checkpoint
134            .contents()
135            .bcs()
136            .deserialize()
137            .map_err(|e| TryFromProtoError::invalid("contents.bcs", e))?;
138
139        let user_signatures: Vec<_> = contents
140            .clone()
141            .into_iter_with_signatures()
142            .map(|(_, user_signatures)| user_signatures)
143            .collect();
144
145        let transactions = checkpoint
146            .transactions()
147            .iter()
148            .zip(user_signatures)
149            .map(|(tx, user_signatures)| {
150                let mut executed_tx: crate::full_checkpoint_content::ExecutedTransaction =
151                    tx.try_into()?;
152                executed_tx.signatures = user_signatures;
153                Ok(executed_tx)
154            })
155            .collect::<Result<_, TryFromProtoError>>()?;
156
157        let object_set = checkpoint.objects().try_into()?;
158
159        Ok(Self {
160            summary,
161            contents,
162            transactions,
163            object_set,
164        })
165    }
166}
167
168impl TryFrom<&ExecutedTransaction> for crate::full_checkpoint_content::ExecutedTransaction {
169    type Error = TryFromProtoError;
170
171    fn try_from(value: &ExecutedTransaction) -> Result<Self, Self::Error> {
172        Ok(Self {
173            transaction: value
174                .transaction()
175                .bcs()
176                .deserialize()
177                .map_err(|e| TryFromProtoError::invalid("transaction.bcs", e))?,
178            signatures: value
179                .signatures()
180                .iter()
181                .map(|sig| {
182                    crate::signature::GenericSignature::from_bytes(sig.bcs().value())
183                        .map_err(|e| TryFromProtoError::invalid("signature.bcs", e))
184                })
185                .collect::<Result<_, _>>()?,
186            effects: value
187                .effects()
188                .bcs()
189                .deserialize()
190                .map_err(|e| TryFromProtoError::invalid("effects.bcs", e))?,
191            events: value
192                .events_opt()
193                .map(|events| {
194                    events
195                        .bcs()
196                        .deserialize()
197                        .map_err(|e| TryFromProtoError::invalid("effects.bcs", e))
198                })
199                .transpose()?,
200            unchanged_loaded_runtime_objects: value
201                .effects()
202                .unchanged_loaded_runtime_objects()
203                .iter()
204                .map(TryInto::try_into)
205                .collect::<Result<_, _>>()?,
206        })
207    }
208}
209
210impl TryFrom<&ObjectReference> for crate::storage::ObjectKey {
211    type Error = TryFromProtoError;
212
213    fn try_from(value: &ObjectReference) -> Result<Self, Self::Error> {
214        Ok(Self(
215            value
216                .object_id()
217                .parse()
218                .map_err(|e| TryFromProtoError::invalid("object_id", e))?,
219            value.version().into(),
220        ))
221    }
222}
223
224//
225// CheckpointSummary
226//
227
228impl From<crate::messages_checkpoint::CheckpointSummary> for CheckpointSummary {
229    fn from(summary: crate::messages_checkpoint::CheckpointSummary) -> Self {
230        Self::merge_from(summary, &FieldMaskTree::new_wildcard())
231    }
232}
233
234impl Merge<crate::messages_checkpoint::CheckpointSummary> for CheckpointSummary {
235    fn merge(
236        &mut self,
237        source: crate::messages_checkpoint::CheckpointSummary,
238        mask: &FieldMaskTree,
239    ) {
240        if mask.contains(Self::BCS_FIELD) {
241            let mut bcs = Bcs::serialize(&source).unwrap();
242            bcs.name = Some("CheckpointSummary".to_owned());
243            self.bcs = Some(bcs);
244        }
245
246        if mask.contains(Self::DIGEST_FIELD) {
247            self.digest = Some(source.digest().to_string());
248        }
249
250        let crate::messages_checkpoint::CheckpointSummary {
251            epoch,
252            sequence_number,
253            network_total_transactions,
254            content_digest,
255            previous_digest,
256            epoch_rolling_gas_cost_summary,
257            timestamp_ms,
258            checkpoint_commitments,
259            end_of_epoch_data,
260            version_specific_data,
261        } = source;
262
263        if mask.contains(Self::EPOCH_FIELD) {
264            self.epoch = Some(epoch);
265        }
266
267        if mask.contains(Self::SEQUENCE_NUMBER_FIELD) {
268            self.sequence_number = Some(sequence_number);
269        }
270
271        if mask.contains(Self::TOTAL_NETWORK_TRANSACTIONS_FIELD) {
272            self.total_network_transactions = Some(network_total_transactions);
273        }
274
275        if mask.contains(Self::CONTENT_DIGEST_FIELD) {
276            self.content_digest = Some(content_digest.to_string());
277        }
278
279        if mask.contains(Self::PREVIOUS_DIGEST_FIELD) {
280            self.previous_digest = previous_digest.map(|d| d.to_string());
281        }
282
283        if mask.contains(Self::EPOCH_ROLLING_GAS_COST_SUMMARY_FIELD) {
284            self.epoch_rolling_gas_cost_summary = Some(epoch_rolling_gas_cost_summary.into());
285        }
286
287        if mask.contains(Self::TIMESTAMP_FIELD) {
288            self.timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(timestamp_ms));
289        }
290
291        if mask.contains(Self::COMMITMENTS_FIELD) {
292            self.commitments = checkpoint_commitments.into_iter().map(Into::into).collect();
293        }
294
295        if mask.contains(Self::END_OF_EPOCH_DATA_FIELD) {
296            self.end_of_epoch_data = end_of_epoch_data.map(Into::into);
297        }
298
299        if mask.contains(Self::VERSION_SPECIFIC_DATA_FIELD) {
300            self.version_specific_data = Some(version_specific_data.into());
301        }
302    }
303}
304
305//
306// GasCostSummary
307//
308
309impl From<crate::gas::GasCostSummary> for GasCostSummary {
310    fn from(
311        crate::gas::GasCostSummary {
312            computation_cost,
313            storage_cost,
314            storage_rebate,
315            non_refundable_storage_fee,
316        }: crate::gas::GasCostSummary,
317    ) -> Self {
318        let mut message = Self::default();
319        message.computation_cost = Some(computation_cost);
320        message.storage_cost = Some(storage_cost);
321        message.storage_rebate = Some(storage_rebate);
322        message.non_refundable_storage_fee = Some(non_refundable_storage_fee);
323        message
324    }
325}
326
327//
328// CheckpointCommitment
329//
330
331impl From<crate::messages_checkpoint::CheckpointCommitment> for CheckpointCommitment {
332    fn from(value: crate::messages_checkpoint::CheckpointCommitment) -> Self {
333        use checkpoint_commitment::CheckpointCommitmentKind;
334
335        let mut message = Self::default();
336
337        let kind = match value {
338            crate::messages_checkpoint::CheckpointCommitment::ECMHLiveObjectSetDigest(digest) => {
339                message.digest = Some(digest.digest.to_string());
340                CheckpointCommitmentKind::EcmhLiveObjectSet
341            }
342            crate::messages_checkpoint::CheckpointCommitment::CheckpointArtifactsDigest(digest) => {
343                message.digest = Some(digest.to_string());
344                CheckpointCommitmentKind::CheckpointArtifacts
345            }
346        };
347
348        message.set_kind(kind);
349        message
350    }
351}
352
353//
354// EndOfEpochData
355//
356
357impl From<crate::messages_checkpoint::EndOfEpochData> for EndOfEpochData {
358    fn from(
359        crate::messages_checkpoint::EndOfEpochData {
360            next_epoch_committee,
361            next_epoch_protocol_version,
362            epoch_commitments,
363        }: crate::messages_checkpoint::EndOfEpochData,
364    ) -> Self {
365        let mut message = Self::default();
366
367        message.next_epoch_committee = next_epoch_committee
368            .into_iter()
369            .map(|(name, weight)| {
370                let mut member = ValidatorCommitteeMember::default();
371                member.public_key = Some(name.0.to_vec().into());
372                member.weight = Some(weight);
373                member
374            })
375            .collect();
376        message.next_epoch_protocol_version = Some(next_epoch_protocol_version.as_u64());
377        message.epoch_commitments = epoch_commitments.into_iter().map(Into::into).collect();
378
379        message
380    }
381}
382
383//
384// CheckpointContents
385//
386
387impl From<crate::messages_checkpoint::CheckpointContents> for CheckpointContents {
388    fn from(value: crate::messages_checkpoint::CheckpointContents) -> Self {
389        Self::merge_from(value, &FieldMaskTree::new_wildcard())
390    }
391}
392
393impl Merge<crate::messages_checkpoint::CheckpointContents> for CheckpointContents {
394    fn merge(
395        &mut self,
396        source: crate::messages_checkpoint::CheckpointContents,
397        mask: &FieldMaskTree,
398    ) {
399        if mask.contains(Self::BCS_FIELD) {
400            let mut bcs = Bcs::serialize(&source).unwrap();
401            bcs.name = Some("CheckpointContents".to_owned());
402            self.bcs = Some(bcs);
403        }
404
405        if mask.contains(Self::DIGEST_FIELD) {
406            self.digest = Some(source.digest().to_string());
407        }
408
409        if mask.contains(Self::VERSION_FIELD) {
410            self.set_version(match &source {
411                crate::messages_checkpoint::CheckpointContents::V1(_) => 1,
412                crate::messages_checkpoint::CheckpointContents::V2(_) => 2,
413            });
414        }
415
416        if mask.contains(Self::TRANSACTIONS_FIELD) {
417            self.transactions = source
418                .inner()
419                .iter()
420                .map(|(digests, sigs)| {
421                    let mut info = CheckpointedTransactionInfo::default();
422                    info.transaction = Some(digests.transaction.to_string());
423                    info.effects = Some(digests.effects.to_string());
424                    let (signatures, versions) = sigs
425                        .map(|(s, v)| {
426                            (s.into(), {
427                                let mut message = AddressAliasesVersion::default();
428                                message.version = v.map(Into::into);
429                                message
430                            })
431                        })
432                        .unzip();
433                    info.signatures = signatures;
434                    info.address_aliases_versions = versions;
435                    info
436                })
437                .collect();
438        }
439    }
440}
441
442impl Merge<&crate::messages_checkpoint::CheckpointContents> for Checkpoint {
443    fn merge(
444        &mut self,
445        source: &crate::messages_checkpoint::CheckpointContents,
446        mask: &FieldMaskTree,
447    ) {
448        if let Some(submask) = mask.subtree(Self::CONTENTS_FIELD.name) {
449            self.contents = Some(CheckpointContents::merge_from(source.to_owned(), &submask));
450        }
451    }
452}
453
454//
455// Checkpoint
456//
457
458impl Merge<&crate::messages_checkpoint::CheckpointSummary> for Checkpoint {
459    fn merge(
460        &mut self,
461        source: &crate::messages_checkpoint::CheckpointSummary,
462        mask: &FieldMaskTree,
463    ) {
464        if mask.contains(Self::SEQUENCE_NUMBER_FIELD) {
465            self.sequence_number = Some(source.sequence_number);
466        }
467
468        if mask.contains(Self::DIGEST_FIELD) {
469            self.digest = Some(source.digest().to_string());
470        }
471
472        if let Some(submask) = mask.subtree(Self::SUMMARY_FIELD) {
473            self.summary = Some(CheckpointSummary::merge_from(source.clone(), &submask));
474        }
475    }
476}
477
478impl<const T: bool> Merge<crate::crypto::AuthorityQuorumSignInfo<T>> for Checkpoint {
479    fn merge(&mut self, source: crate::crypto::AuthorityQuorumSignInfo<T>, mask: &FieldMaskTree) {
480        if mask.contains(Self::SIGNATURE_FIELD) {
481            self.signature = Some(source.into());
482        }
483    }
484}
485
486impl Merge<crate::messages_checkpoint::CheckpointContents> for Checkpoint {
487    fn merge(
488        &mut self,
489        source: crate::messages_checkpoint::CheckpointContents,
490        mask: &FieldMaskTree,
491    ) {
492        if let Some(submask) = mask.subtree(Self::CONTENTS_FIELD) {
493            self.contents = Some(CheckpointContents::merge_from(source, &submask));
494        }
495    }
496}
497
498//
499// Event
500//
501
502impl From<crate::event::Event> for Event {
503    fn from(value: crate::event::Event) -> Self {
504        Self::merge_from(&value, &FieldMaskTree::new_wildcard())
505    }
506}
507
508impl Merge<&crate::event::Event> for Event {
509    fn merge(&mut self, source: &crate::event::Event, mask: &FieldMaskTree) {
510        if mask.contains(Self::PACKAGE_ID_FIELD) {
511            self.package_id = Some(source.package_id.to_canonical_string(true));
512        }
513
514        if mask.contains(Self::MODULE_FIELD) {
515            self.module = Some(source.transaction_module.to_string());
516        }
517
518        if mask.contains(Self::SENDER_FIELD) {
519            self.sender = Some(source.sender.to_string());
520        }
521
522        if mask.contains(Self::EVENT_TYPE_FIELD) {
523            self.event_type = Some(source.type_.to_canonical_string(true));
524        }
525
526        if mask.contains(Self::CONTENTS_FIELD) {
527            let mut bcs = Bcs::from(source.contents.clone());
528            bcs.name = Some(source.type_.to_canonical_string(true));
529            self.contents = Some(bcs);
530        }
531    }
532}
533
534//
535// TransactionEvents
536//
537
538impl From<crate::effects::TransactionEvents> for TransactionEvents {
539    fn from(value: crate::effects::TransactionEvents) -> Self {
540        Self::merge_from(&value, &FieldMaskTree::new_wildcard())
541    }
542}
543
544impl Merge<&crate::effects::TransactionEvents> for TransactionEvents {
545    fn merge(&mut self, source: &crate::effects::TransactionEvents, mask: &FieldMaskTree) {
546        if mask.contains(Self::BCS_FIELD) {
547            let mut bcs = Bcs::serialize(&source).unwrap();
548            bcs.name = Some("TransactionEvents".to_owned());
549            self.bcs = Some(bcs);
550        }
551
552        if mask.contains(Self::DIGEST_FIELD) {
553            self.digest = Some(source.digest().to_string());
554        }
555
556        if let Some(events_mask) = mask.subtree(Self::EVENTS_FIELD) {
557            self.events = source
558                .data
559                .iter()
560                .map(|event| Event::merge_from(event, &events_mask))
561                .collect();
562        }
563    }
564}
565
566//
567// SystemState
568//
569
570impl From<crate::sui_system_state::SuiSystemState> for SystemState {
571    fn from(value: crate::sui_system_state::SuiSystemState) -> Self {
572        match value {
573            crate::sui_system_state::SuiSystemState::V1(v1) => v1.into(),
574            crate::sui_system_state::SuiSystemState::V2(v2) => v2.into(),
575
576            #[allow(unreachable_patterns)]
577            _ => Self::default(),
578        }
579    }
580}
581
582impl From<crate::sui_system_state::sui_system_state_inner_v1::SuiSystemStateInnerV1>
583    for SystemState
584{
585    fn from(
586        crate::sui_system_state::sui_system_state_inner_v1::SuiSystemStateInnerV1 {
587            epoch,
588            protocol_version,
589            system_state_version,
590            validators,
591            storage_fund,
592            parameters,
593            reference_gas_price,
594            validator_report_records,
595            stake_subsidy,
596            safe_mode,
597            safe_mode_storage_rewards,
598            safe_mode_computation_rewards,
599            safe_mode_storage_rebates,
600            safe_mode_non_refundable_storage_fee,
601            epoch_start_timestamp_ms,
602            extra_fields,
603        }: crate::sui_system_state::sui_system_state_inner_v1::SuiSystemStateInnerV1,
604    ) -> Self {
605        let validator_report_records = validator_report_records
606            .contents
607            .into_iter()
608            .map(|entry| {
609                let mut record = ValidatorReportRecord::default();
610                record.reported = Some(entry.key.to_string());
611                record.reporters = entry
612                    .value
613                    .contents
614                    .iter()
615                    .map(ToString::to_string)
616                    .collect();
617                record
618            })
619            .collect();
620
621        let mut message = Self::default();
622
623        message.version = Some(system_state_version);
624        message.epoch = Some(epoch);
625        message.protocol_version = Some(protocol_version);
626        message.validators = Some(validators.into());
627        message.storage_fund = Some(storage_fund.into());
628        message.parameters = Some(parameters.into());
629        message.reference_gas_price = Some(reference_gas_price);
630        message.validator_report_records = validator_report_records;
631        message.stake_subsidy = Some(stake_subsidy.into());
632        message.safe_mode = Some(safe_mode);
633        message.safe_mode_storage_rewards = Some(safe_mode_storage_rewards.value());
634        message.safe_mode_computation_rewards = Some(safe_mode_computation_rewards.value());
635        message.safe_mode_storage_rebates = Some(safe_mode_storage_rebates);
636        message.safe_mode_non_refundable_storage_fee = Some(safe_mode_non_refundable_storage_fee);
637        message.epoch_start_timestamp_ms = Some(epoch_start_timestamp_ms);
638        message.extra_fields = Some(extra_fields.into());
639        message
640    }
641}
642
643impl From<crate::sui_system_state::sui_system_state_inner_v2::SuiSystemStateInnerV2>
644    for SystemState
645{
646    fn from(
647        crate::sui_system_state::sui_system_state_inner_v2::SuiSystemStateInnerV2 {
648            epoch,
649            protocol_version,
650            system_state_version,
651            validators,
652            storage_fund,
653            parameters,
654            reference_gas_price,
655            validator_report_records,
656            stake_subsidy,
657            safe_mode,
658            safe_mode_storage_rewards,
659            safe_mode_computation_rewards,
660            safe_mode_storage_rebates,
661            safe_mode_non_refundable_storage_fee,
662            epoch_start_timestamp_ms,
663            extra_fields,
664        }: crate::sui_system_state::sui_system_state_inner_v2::SuiSystemStateInnerV2,
665    ) -> Self {
666        let validator_report_records = validator_report_records
667            .contents
668            .into_iter()
669            .map(|entry| {
670                let mut record = ValidatorReportRecord::default();
671                record.reported = Some(entry.key.to_string());
672                record.reporters = entry
673                    .value
674                    .contents
675                    .iter()
676                    .map(ToString::to_string)
677                    .collect();
678                record
679            })
680            .collect();
681
682        let mut message = Self::default();
683
684        message.version = Some(system_state_version);
685        message.epoch = Some(epoch);
686        message.protocol_version = Some(protocol_version);
687        message.validators = Some(validators.into());
688        message.storage_fund = Some(storage_fund.into());
689        message.parameters = Some(parameters.into());
690        message.reference_gas_price = Some(reference_gas_price);
691        message.validator_report_records = validator_report_records;
692        message.stake_subsidy = Some(stake_subsidy.into());
693        message.safe_mode = Some(safe_mode);
694        message.safe_mode_storage_rewards = Some(safe_mode_storage_rewards.value());
695        message.safe_mode_computation_rewards = Some(safe_mode_computation_rewards.value());
696        message.safe_mode_storage_rebates = Some(safe_mode_storage_rebates);
697        message.safe_mode_non_refundable_storage_fee = Some(safe_mode_non_refundable_storage_fee);
698        message.epoch_start_timestamp_ms = Some(epoch_start_timestamp_ms);
699        message.extra_fields = Some(extra_fields.into());
700        message
701    }
702}
703
704impl From<crate::collection_types::Bag> for MoveTable {
705    fn from(crate::collection_types::Bag { id, size }: crate::collection_types::Bag) -> Self {
706        let mut message = Self::default();
707        message.id = Some(id.id.bytes.to_canonical_string(true));
708        message.size = Some(size);
709        message
710    }
711}
712
713impl From<crate::collection_types::Table> for MoveTable {
714    fn from(crate::collection_types::Table { id, size }: crate::collection_types::Table) -> Self {
715        let mut message = Self::default();
716        message.id = Some(id.to_canonical_string(true));
717        message.size = Some(size);
718        message
719    }
720}
721
722impl From<crate::collection_types::TableVec> for MoveTable {
723    fn from(value: crate::collection_types::TableVec) -> Self {
724        value.contents.into()
725    }
726}
727
728impl From<crate::sui_system_state::sui_system_state_inner_v1::StakeSubsidyV1> for StakeSubsidy {
729    fn from(
730        crate::sui_system_state::sui_system_state_inner_v1::StakeSubsidyV1 {
731            balance,
732            distribution_counter,
733            current_distribution_amount,
734            stake_subsidy_period_length,
735            stake_subsidy_decrease_rate,
736            extra_fields,
737        }: crate::sui_system_state::sui_system_state_inner_v1::StakeSubsidyV1,
738    ) -> Self {
739        let mut message = Self::default();
740        message.balance = Some(balance.value());
741        message.distribution_counter = Some(distribution_counter);
742        message.current_distribution_amount = Some(current_distribution_amount);
743        message.stake_subsidy_period_length = Some(stake_subsidy_period_length);
744        message.stake_subsidy_decrease_rate = Some(stake_subsidy_decrease_rate.into());
745        message.extra_fields = Some(extra_fields.into());
746        message
747    }
748}
749
750impl From<crate::sui_system_state::sui_system_state_inner_v1::SystemParametersV1>
751    for SystemParameters
752{
753    fn from(
754        crate::sui_system_state::sui_system_state_inner_v1::SystemParametersV1 {
755            epoch_duration_ms,
756            stake_subsidy_start_epoch,
757            max_validator_count,
758            min_validator_joining_stake,
759            validator_low_stake_threshold,
760            validator_very_low_stake_threshold,
761            validator_low_stake_grace_period,
762            extra_fields,
763        }: crate::sui_system_state::sui_system_state_inner_v1::SystemParametersV1,
764    ) -> Self {
765        let mut message = Self::default();
766        message.epoch_duration_ms = Some(epoch_duration_ms);
767        message.stake_subsidy_start_epoch = Some(stake_subsidy_start_epoch);
768        message.min_validator_count = None;
769        message.max_validator_count = Some(max_validator_count);
770        message.min_validator_joining_stake = Some(min_validator_joining_stake);
771        message.validator_low_stake_threshold = Some(validator_low_stake_threshold);
772        message.validator_very_low_stake_threshold = Some(validator_very_low_stake_threshold);
773        message.validator_low_stake_grace_period = Some(validator_low_stake_grace_period);
774        message.extra_fields = Some(extra_fields.into());
775        message
776    }
777}
778
779impl From<crate::sui_system_state::sui_system_state_inner_v2::SystemParametersV2>
780    for SystemParameters
781{
782    fn from(
783        crate::sui_system_state::sui_system_state_inner_v2::SystemParametersV2 {
784            epoch_duration_ms,
785            stake_subsidy_start_epoch,
786            min_validator_count,
787            max_validator_count,
788            min_validator_joining_stake,
789            validator_low_stake_threshold,
790            validator_very_low_stake_threshold,
791            validator_low_stake_grace_period,
792            extra_fields,
793        }: crate::sui_system_state::sui_system_state_inner_v2::SystemParametersV2,
794    ) -> Self {
795        let mut message = Self::default();
796        message.epoch_duration_ms = Some(epoch_duration_ms);
797        message.stake_subsidy_start_epoch = Some(stake_subsidy_start_epoch);
798        message.min_validator_count = Some(min_validator_count);
799        message.max_validator_count = Some(max_validator_count);
800        message.min_validator_joining_stake = Some(min_validator_joining_stake);
801        message.validator_low_stake_threshold = Some(validator_low_stake_threshold);
802        message.validator_very_low_stake_threshold = Some(validator_very_low_stake_threshold);
803        message.validator_low_stake_grace_period = Some(validator_low_stake_grace_period);
804        message.extra_fields = Some(extra_fields.into());
805        message
806    }
807}
808
809impl From<crate::sui_system_state::sui_system_state_inner_v1::StorageFundV1> for StorageFund {
810    fn from(
811        crate::sui_system_state::sui_system_state_inner_v1::StorageFundV1 {
812            total_object_storage_rebates,
813            non_refundable_balance,
814        }: crate::sui_system_state::sui_system_state_inner_v1::StorageFundV1,
815    ) -> Self {
816        let mut message = Self::default();
817        message.total_object_storage_rebates = Some(total_object_storage_rebates.value());
818        message.non_refundable_balance = Some(non_refundable_balance.value());
819        message
820    }
821}
822
823impl From<crate::sui_system_state::sui_system_state_inner_v1::ValidatorSetV1> for ValidatorSet {
824    fn from(
825        crate::sui_system_state::sui_system_state_inner_v1::ValidatorSetV1 {
826            total_stake,
827            active_validators,
828            pending_active_validators,
829            pending_removals,
830            staking_pool_mappings,
831            inactive_validators,
832            validator_candidates,
833            at_risk_validators,
834            extra_fields,
835        }: crate::sui_system_state::sui_system_state_inner_v1::ValidatorSetV1,
836    ) -> Self {
837        let at_risk_validators = at_risk_validators
838            .contents
839            .into_iter()
840            .map(|entry| (entry.key.to_string(), entry.value))
841            .collect();
842
843        let mut message = Self::default();
844        message.total_stake = Some(total_stake);
845        message.active_validators = active_validators.into_iter().map(Into::into).collect();
846        message.pending_active_validators = Some(pending_active_validators.into());
847        message.pending_removals = pending_removals;
848        message.staking_pool_mappings = Some(staking_pool_mappings.into());
849        message.inactive_validators = Some(inactive_validators.into());
850        message.validator_candidates = Some(validator_candidates.into());
851        message.at_risk_validators = at_risk_validators;
852        message.extra_fields = Some(extra_fields.into());
853        message
854    }
855}
856
857impl From<crate::sui_system_state::sui_system_state_inner_v1::StakingPoolV1> for StakingPool {
858    fn from(
859        crate::sui_system_state::sui_system_state_inner_v1::StakingPoolV1 {
860            id,
861            activation_epoch,
862            deactivation_epoch,
863            sui_balance,
864            rewards_pool,
865            pool_token_balance,
866            exchange_rates,
867            pending_stake,
868            pending_total_sui_withdraw,
869            pending_pool_token_withdraw,
870            extra_fields,
871        }: crate::sui_system_state::sui_system_state_inner_v1::StakingPoolV1,
872    ) -> Self {
873        let mut message = Self::default();
874        message.id = Some(id.to_canonical_string(true));
875        message.activation_epoch = activation_epoch;
876        message.deactivation_epoch = deactivation_epoch;
877        message.sui_balance = Some(sui_balance);
878        message.rewards_pool = Some(rewards_pool.value());
879        message.pool_token_balance = Some(pool_token_balance);
880        message.exchange_rates = Some(exchange_rates.into());
881        message.pending_stake = Some(pending_stake);
882        message.pending_total_sui_withdraw = Some(pending_total_sui_withdraw);
883        message.pending_pool_token_withdraw = Some(pending_pool_token_withdraw);
884        message.extra_fields = Some(extra_fields.into());
885        message
886    }
887}
888
889impl From<crate::sui_system_state::sui_system_state_inner_v1::ValidatorV1> for Validator {
890    fn from(
891        crate::sui_system_state::sui_system_state_inner_v1::ValidatorV1 {
892            metadata:
893                crate::sui_system_state::sui_system_state_inner_v1::ValidatorMetadataV1 {
894                    sui_address,
895                    protocol_pubkey_bytes,
896                    network_pubkey_bytes,
897                    worker_pubkey_bytes,
898                    proof_of_possession_bytes,
899                    name,
900                    description,
901                    image_url,
902                    project_url,
903                    net_address,
904                    p2p_address,
905                    primary_address,
906                    worker_address,
907                    next_epoch_protocol_pubkey_bytes,
908                    next_epoch_proof_of_possession,
909                    next_epoch_network_pubkey_bytes,
910                    next_epoch_worker_pubkey_bytes,
911                    next_epoch_net_address,
912                    next_epoch_p2p_address,
913                    next_epoch_primary_address,
914                    next_epoch_worker_address,
915                    extra_fields: metadata_extra_fields,
916                },
917            voting_power,
918            operation_cap_id,
919            gas_price,
920            staking_pool,
921            commission_rate,
922            next_epoch_stake,
923            next_epoch_gas_price,
924            next_epoch_commission_rate,
925            extra_fields,
926            ..
927        }: crate::sui_system_state::sui_system_state_inner_v1::ValidatorV1,
928    ) -> Self {
929        let mut message = Self::default();
930        message.name = Some(name);
931        message.address = Some(sui_address.to_string());
932        message.description = Some(description);
933        message.image_url = Some(image_url);
934        message.project_url = Some(project_url);
935        message.protocol_public_key = Some(protocol_pubkey_bytes.into());
936        message.proof_of_possession = Some(proof_of_possession_bytes.into());
937        message.network_public_key = Some(network_pubkey_bytes.into());
938        message.worker_public_key = Some(worker_pubkey_bytes.into());
939        message.network_address = Some(net_address);
940        message.p2p_address = Some(p2p_address);
941        message.primary_address = Some(primary_address);
942        message.worker_address = Some(worker_address);
943        message.next_epoch_protocol_public_key = next_epoch_protocol_pubkey_bytes.map(Into::into);
944        message.next_epoch_proof_of_possession = next_epoch_proof_of_possession.map(Into::into);
945        message.next_epoch_network_public_key = next_epoch_network_pubkey_bytes.map(Into::into);
946        message.next_epoch_worker_public_key = next_epoch_worker_pubkey_bytes.map(Into::into);
947        message.next_epoch_network_address = next_epoch_net_address;
948        message.next_epoch_p2p_address = next_epoch_p2p_address;
949        message.next_epoch_primary_address = next_epoch_primary_address;
950        message.next_epoch_worker_address = next_epoch_worker_address;
951        message.metadata_extra_fields = Some(metadata_extra_fields.into());
952        message.voting_power = Some(voting_power);
953        message.operation_cap_id = Some(operation_cap_id.bytes.to_canonical_string(true));
954        message.gas_price = Some(gas_price);
955        message.staking_pool = Some(staking_pool.into());
956        message.commission_rate = Some(commission_rate);
957        message.next_epoch_stake = Some(next_epoch_stake);
958        message.next_epoch_gas_price = Some(next_epoch_gas_price);
959        message.next_epoch_commission_rate = Some(next_epoch_commission_rate);
960        message.extra_fields = Some(extra_fields.into());
961        message
962    }
963}
964
965impl TryFrom<&SystemState>
966    for crate::sui_system_state::sui_system_state_summary::SuiSystemStateSummary
967{
968    type Error = TryFromProtoError;
969
970    fn try_from(s: &SystemState) -> Result<Self, Self::Error> {
971        Ok(Self {
972            epoch: s.epoch(),
973            protocol_version: s.protocol_version(),
974            system_state_version: s.version(),
975            storage_fund_total_object_storage_rebates: s
976                .storage_fund()
977                .total_object_storage_rebates(),
978            storage_fund_non_refundable_balance: s.storage_fund().non_refundable_balance(),
979            reference_gas_price: s.reference_gas_price(),
980            safe_mode: s.safe_mode(),
981            safe_mode_storage_rewards: s.safe_mode_storage_rewards(),
982            safe_mode_computation_rewards: s.safe_mode_computation_rewards(),
983            safe_mode_storage_rebates: s.safe_mode_storage_rebates(),
984            safe_mode_non_refundable_storage_fee: s.safe_mode_non_refundable_storage_fee(),
985            epoch_start_timestamp_ms: s.epoch_start_timestamp_ms(),
986            epoch_duration_ms: s.parameters().epoch_duration_ms(),
987            stake_subsidy_start_epoch: s.parameters().stake_subsidy_start_epoch(),
988            max_validator_count: s.parameters().max_validator_count(),
989            min_validator_joining_stake: s.parameters().min_validator_joining_stake(),
990            validator_low_stake_threshold: s.parameters().validator_low_stake_threshold(),
991            validator_very_low_stake_threshold: s.parameters().validator_very_low_stake_threshold(),
992            validator_low_stake_grace_period: s.parameters().validator_low_stake_grace_period(),
993            stake_subsidy_balance: s.stake_subsidy().balance(),
994            stake_subsidy_distribution_counter: s.stake_subsidy().distribution_counter(),
995            stake_subsidy_current_distribution_amount: s
996                .stake_subsidy()
997                .current_distribution_amount(),
998            stake_subsidy_period_length: s.stake_subsidy().stake_subsidy_period_length(),
999            stake_subsidy_decrease_rate: s.stake_subsidy().stake_subsidy_decrease_rate() as u16,
1000            total_stake: s.validators().total_stake(),
1001            active_validators: s
1002                .validators()
1003                .active_validators()
1004                .iter()
1005                .map(TryInto::try_into)
1006                .collect::<Result<_, _>>()?,
1007            pending_active_validators_id: s
1008                .validators()
1009                .pending_active_validators()
1010                .id()
1011                .parse()
1012                .map_err(|e| {
1013                TryFromProtoError::invalid("pending_active_validators_id", e)
1014            })?,
1015            pending_active_validators_size: s.validators().pending_active_validators().size(),
1016            pending_removals: s.validators().pending_removals().to_vec(),
1017            staking_pool_mappings_id: s
1018                .validators()
1019                .staking_pool_mappings()
1020                .id()
1021                .parse()
1022                .map_err(|e| TryFromProtoError::invalid("staking_pool_mappings_id", e))?,
1023            staking_pool_mappings_size: s.validators().staking_pool_mappings().size(),
1024            inactive_pools_id: s
1025                .validators()
1026                .inactive_validators()
1027                .id()
1028                .parse()
1029                .map_err(|e| TryFromProtoError::invalid("inactive_pools_id", e))?,
1030            inactive_pools_size: s.validators().inactive_validators().size(),
1031            validator_candidates_id: s
1032                .validators()
1033                .validator_candidates()
1034                .id()
1035                .parse()
1036                .map_err(|e| TryFromProtoError::invalid("validator_candidates", e))?,
1037            validator_candidates_size: s.validators().validator_candidates().size(),
1038            at_risk_validators: s
1039                .validators()
1040                .at_risk_validators()
1041                .iter()
1042                .map(|(address, epoch)| {
1043                    address
1044                        .parse()
1045                        .map(|address| (address, *epoch))
1046                        .map_err(|e| TryFromProtoError::invalid("at_risk_validators", e))
1047                })
1048                .collect::<Result<_, _>>()?,
1049            validator_report_records: s
1050                .validator_report_records()
1051                .iter()
1052                .map(|record| {
1053                    let reported = record.reported().parse()?;
1054                    let reporters = record
1055                        .reporters()
1056                        .iter()
1057                        .map(|address| address.parse())
1058                        .collect::<Result<Vec<_>, _>>()?;
1059                    Ok((reported, reporters))
1060                })
1061                .collect::<Result<_, anyhow::Error>>()
1062                .map_err(|e| TryFromProtoError::invalid("validator_report_records", e))?,
1063        })
1064    }
1065}
1066
1067impl TryFrom<&Validator>
1068    for crate::sui_system_state::sui_system_state_summary::SuiValidatorSummary
1069{
1070    type Error = TryFromProtoError;
1071
1072    fn try_from(v: &Validator) -> Result<Self, Self::Error> {
1073        Ok(Self {
1074            sui_address: v
1075                .address()
1076                .parse()
1077                .map_err(|e| TryFromProtoError::invalid("address", e))?,
1078            protocol_pubkey_bytes: v.protocol_public_key().into(),
1079            network_pubkey_bytes: v.network_public_key().into(),
1080            worker_pubkey_bytes: v.worker_public_key().into(),
1081            proof_of_possession_bytes: v.proof_of_possession().into(),
1082            name: v.name().into(),
1083            description: v.description().into(),
1084            image_url: v.image_url().into(),
1085            project_url: v.project_url().into(),
1086            net_address: v.network_address().into(),
1087            p2p_address: v.p2p_address().into(),
1088            primary_address: v.primary_address().into(),
1089            worker_address: v.worker_address().into(),
1090            next_epoch_protocol_pubkey_bytes: v
1091                .next_epoch_protocol_public_key_opt()
1092                .map(Into::into),
1093            next_epoch_proof_of_possession: v.next_epoch_proof_of_possession_opt().map(Into::into),
1094            next_epoch_network_pubkey_bytes: v.next_epoch_network_public_key_opt().map(Into::into),
1095            next_epoch_worker_pubkey_bytes: v.next_epoch_worker_public_key_opt().map(Into::into),
1096            next_epoch_net_address: v.next_epoch_network_address_opt().map(Into::into),
1097            next_epoch_p2p_address: v.next_epoch_p2p_address_opt().map(Into::into),
1098            next_epoch_primary_address: v.next_epoch_primary_address_opt().map(Into::into),
1099            next_epoch_worker_address: v.next_epoch_worker_address_opt().map(Into::into),
1100            voting_power: v.voting_power(),
1101            operation_cap_id: v
1102                .operation_cap_id()
1103                .parse()
1104                .map_err(|e| TryFromProtoError::invalid("operation_cap_id", e))?,
1105            gas_price: v.gas_price(),
1106            commission_rate: v.commission_rate(),
1107            next_epoch_stake: v.next_epoch_stake(),
1108            next_epoch_gas_price: v.next_epoch_gas_price(),
1109            next_epoch_commission_rate: v.next_epoch_commission_rate(),
1110            staking_pool_id: v
1111                .staking_pool()
1112                .id()
1113                .parse()
1114                .map_err(|e| TryFromProtoError::invalid("staking_pool_id", e))?,
1115            staking_pool_activation_epoch: v.staking_pool().activation_epoch_opt(),
1116            staking_pool_deactivation_epoch: v.staking_pool().deactivation_epoch_opt(),
1117            staking_pool_sui_balance: v.staking_pool().sui_balance(),
1118            rewards_pool: v.staking_pool().rewards_pool(),
1119            pool_token_balance: v.staking_pool().pool_token_balance(),
1120            pending_stake: v.staking_pool().pending_stake(),
1121            pending_total_sui_withdraw: v.staking_pool().pending_total_sui_withdraw(),
1122            pending_pool_token_withdraw: v.staking_pool().pending_pool_token_withdraw(),
1123            exchange_rates_id: v
1124                .staking_pool()
1125                .exchange_rates()
1126                .id()
1127                .parse()
1128                .map_err(|e| TryFromProtoError::invalid("exchange_rates_id", e))?,
1129            exchange_rates_size: v.staking_pool().exchange_rates().size(),
1130        })
1131    }
1132}
1133
1134//
1135// ExecutionStatus
1136//
1137
1138impl From<crate::execution_status::ExecutionStatus> for ExecutionStatus {
1139    fn from(value: crate::execution_status::ExecutionStatus) -> Self {
1140        let mut message = Self::default();
1141        match value {
1142            crate::execution_status::ExecutionStatus::Success => {
1143                message.success = Some(true);
1144            }
1145            crate::execution_status::ExecutionStatus::Failure(
1146                crate::execution_status::ExecutionFailure { error, command },
1147            ) => {
1148                let description = if let Some(command) = command {
1149                    format!("{error:?} in command {command}")
1150                } else {
1151                    format!("{error:?}")
1152                };
1153                let mut error_message = ExecutionError::from(error);
1154                error_message.command = command.map(|i| i as u64);
1155                error_message.description = Some(description);
1156
1157                message.success = Some(false);
1158                message.error = Some(error_message);
1159            }
1160        }
1161
1162        message
1163    }
1164}
1165
1166//
1167// ExecutionError
1168//
1169
1170fn size_error(size: u64, max_size: u64) -> SizeError {
1171    let mut message = SizeError::default();
1172    message.size = Some(size);
1173    message.max_size = Some(max_size);
1174    message
1175}
1176
1177fn index_error(index: u32, secondary_idx: Option<u32>) -> IndexError {
1178    let mut message = IndexError::default();
1179    message.index = Some(index);
1180    message.subresult = secondary_idx;
1181    message
1182}
1183
1184impl From<crate::execution_status::ExecutionErrorKind> for ExecutionError {
1185    fn from(value: crate::execution_status::ExecutionErrorKind) -> Self {
1186        use crate::execution_status::ExecutionErrorKind as E;
1187        use execution_error::ErrorDetails;
1188        use execution_error::ExecutionErrorKind;
1189
1190        let mut message = Self::default();
1191
1192        let kind = match value {
1193            E::InsufficientGas => ExecutionErrorKind::InsufficientGas,
1194            E::InvalidGasObject => ExecutionErrorKind::InvalidGasObject,
1195            E::InvariantViolation => ExecutionErrorKind::InvariantViolation,
1196            E::FeatureNotYetSupported => ExecutionErrorKind::FeatureNotYetSupported,
1197            E::MoveObjectTooBig {
1198                object_size,
1199                max_object_size,
1200            } => {
1201                message.error_details = Some(ErrorDetails::SizeError(size_error(
1202                    object_size,
1203                    max_object_size,
1204                )));
1205                ExecutionErrorKind::ObjectTooBig
1206            }
1207            E::MovePackageTooBig {
1208                object_size,
1209                max_object_size,
1210            } => {
1211                message.error_details = Some(ErrorDetails::SizeError(size_error(
1212                    object_size,
1213                    max_object_size,
1214                )));
1215                ExecutionErrorKind::PackageTooBig
1216            }
1217            E::CircularObjectOwnership { object } => {
1218                message.error_details =
1219                    Some(ErrorDetails::ObjectId(object.to_canonical_string(true)));
1220                ExecutionErrorKind::CircularObjectOwnership
1221            }
1222            E::InsufficientCoinBalance => ExecutionErrorKind::InsufficientCoinBalance,
1223            E::CoinBalanceOverflow => ExecutionErrorKind::CoinBalanceOverflow,
1224            E::PublishErrorNonZeroAddress => ExecutionErrorKind::PublishErrorNonZeroAddress,
1225            E::SuiMoveVerificationError => ExecutionErrorKind::SuiMoveVerificationError,
1226            E::MovePrimitiveRuntimeError(location) => {
1227                message.error_details = location.0.map(|l| {
1228                    let mut abort = MoveAbort::default();
1229                    abort.location = Some(l.into());
1230                    ErrorDetails::Abort(abort)
1231                });
1232                ExecutionErrorKind::MovePrimitiveRuntimeError
1233            }
1234            E::MoveAbort(location, code) => {
1235                let mut abort = MoveAbort::default();
1236                abort.abort_code = Some(code);
1237                abort.location = Some(location.into());
1238                message.error_details = Some(ErrorDetails::Abort(abort));
1239                ExecutionErrorKind::MoveAbort
1240            }
1241            E::VMVerificationOrDeserializationError => {
1242                ExecutionErrorKind::VmVerificationOrDeserializationError
1243            }
1244            E::VMInvariantViolation => ExecutionErrorKind::VmInvariantViolation,
1245            E::FunctionNotFound => ExecutionErrorKind::FunctionNotFound,
1246            E::ArityMismatch => ExecutionErrorKind::ArityMismatch,
1247            E::TypeArityMismatch => ExecutionErrorKind::TypeArityMismatch,
1248            E::NonEntryFunctionInvoked => ExecutionErrorKind::NonEntryFunctionInvoked,
1249            E::CommandArgumentError { arg_idx, kind } => {
1250                let mut command_argument_error = CommandArgumentError::from(kind);
1251                command_argument_error.argument = Some(arg_idx.into());
1252                message.error_details =
1253                    Some(ErrorDetails::CommandArgumentError(command_argument_error));
1254                ExecutionErrorKind::CommandArgumentError
1255            }
1256            E::TypeArgumentError { argument_idx, kind } => {
1257                let mut type_argument_error = TypeArgumentError::default();
1258                type_argument_error.type_argument = Some(argument_idx.into());
1259                type_argument_error.kind =
1260                    Some(type_argument_error::TypeArgumentErrorKind::from(kind).into());
1261                message.error_details = Some(ErrorDetails::TypeArgumentError(type_argument_error));
1262                ExecutionErrorKind::TypeArgumentError
1263            }
1264            E::UnusedValueWithoutDrop {
1265                result_idx,
1266                secondary_idx,
1267            } => {
1268                message.error_details = Some(ErrorDetails::IndexError(index_error(
1269                    result_idx.into(),
1270                    Some(secondary_idx.into()),
1271                )));
1272                ExecutionErrorKind::UnusedValueWithoutDrop
1273            }
1274            E::InvalidPublicFunctionReturnType { idx } => {
1275                message.error_details =
1276                    Some(ErrorDetails::IndexError(index_error(idx.into(), None)));
1277                ExecutionErrorKind::InvalidPublicFunctionReturnType
1278            }
1279            E::InvalidTransferObject => ExecutionErrorKind::InvalidTransferObject,
1280            E::EffectsTooLarge {
1281                current_size,
1282                max_size,
1283            } => {
1284                message.error_details =
1285                    Some(ErrorDetails::SizeError(size_error(current_size, max_size)));
1286                ExecutionErrorKind::EffectsTooLarge
1287            }
1288            E::PublishUpgradeMissingDependency => {
1289                ExecutionErrorKind::PublishUpgradeMissingDependency
1290            }
1291            E::PublishUpgradeDependencyDowngrade => {
1292                ExecutionErrorKind::PublishUpgradeDependencyDowngrade
1293            }
1294            E::PackageUpgradeError { upgrade_error } => {
1295                message.error_details =
1296                    Some(ErrorDetails::PackageUpgradeError(upgrade_error.into()));
1297                ExecutionErrorKind::PackageUpgradeError
1298            }
1299            E::WrittenObjectsTooLarge {
1300                current_size,
1301                max_size,
1302            } => {
1303                message.error_details =
1304                    Some(ErrorDetails::SizeError(size_error(current_size, max_size)));
1305
1306                ExecutionErrorKind::WrittenObjectsTooLarge
1307            }
1308            E::CertificateDenied => ExecutionErrorKind::CertificateDenied,
1309            E::SuiMoveVerificationTimedout => ExecutionErrorKind::SuiMoveVerificationTimedout,
1310            E::SharedObjectOperationNotAllowed => {
1311                ExecutionErrorKind::ConsensusObjectOperationNotAllowed
1312            }
1313            E::InputObjectDeleted => ExecutionErrorKind::InputObjectDeleted,
1314            E::ExecutionCancelledDueToSharedObjectCongestion { congested_objects } => {
1315                message.error_details = Some(ErrorDetails::CongestedObjects({
1316                    let mut message = CongestedObjects::default();
1317                    message.objects = congested_objects
1318                        .0
1319                        .iter()
1320                        .map(|o| o.to_canonical_string(true))
1321                        .collect();
1322                    message
1323                }));
1324
1325                ExecutionErrorKind::ExecutionCanceledDueToConsensusObjectCongestion
1326            }
1327            E::AddressDeniedForCoin { address, coin_type } => {
1328                message.error_details = Some(ErrorDetails::CoinDenyListError({
1329                    let mut message = CoinDenyListError::default();
1330                    message.address = Some(address.to_string());
1331                    message.coin_type = Some(coin_type);
1332                    message
1333                }));
1334                ExecutionErrorKind::AddressDeniedForCoin
1335            }
1336            E::CoinTypeGlobalPause { coin_type } => {
1337                message.error_details = Some(ErrorDetails::CoinDenyListError({
1338                    let mut message = CoinDenyListError::default();
1339                    message.coin_type = Some(coin_type);
1340                    message
1341                }));
1342                ExecutionErrorKind::CoinTypeGlobalPause
1343            }
1344            E::ExecutionCancelledDueToRandomnessUnavailable => {
1345                ExecutionErrorKind::ExecutionCanceledDueToRandomnessUnavailable
1346            }
1347            E::MoveVectorElemTooBig {
1348                value_size,
1349                max_scaled_size,
1350            } => {
1351                message.error_details = Some(ErrorDetails::SizeError(size_error(
1352                    value_size,
1353                    max_scaled_size,
1354                )));
1355
1356                ExecutionErrorKind::MoveVectorElemTooBig
1357            }
1358            E::MoveRawValueTooBig {
1359                value_size,
1360                max_scaled_size,
1361            } => {
1362                message.error_details = Some(ErrorDetails::SizeError(size_error(
1363                    value_size,
1364                    max_scaled_size,
1365                )));
1366                ExecutionErrorKind::MoveRawValueTooBig
1367            }
1368            E::InvalidLinkage => ExecutionErrorKind::InvalidLinkage,
1369            E::InsufficientFundsForWithdraw => ExecutionErrorKind::InsufficientFundsForWithdraw,
1370            E::NonExclusiveWriteInputObjectModified { id } => {
1371                message.set_object_id(id.to_canonical_string(true));
1372                ExecutionErrorKind::NonExclusiveWriteInputObjectModified
1373            }
1374        };
1375
1376        message.set_kind(kind);
1377        message
1378    }
1379}
1380
1381//
1382// CommandArgumentError
1383//
1384
1385impl From<crate::execution_status::CommandArgumentError> for CommandArgumentError {
1386    fn from(value: crate::execution_status::CommandArgumentError) -> Self {
1387        use crate::execution_status::CommandArgumentError as E;
1388        use command_argument_error::CommandArgumentErrorKind;
1389
1390        let mut message = Self::default();
1391
1392        let kind = match value {
1393            E::TypeMismatch => CommandArgumentErrorKind::TypeMismatch,
1394            E::InvalidBCSBytes => CommandArgumentErrorKind::InvalidBcsBytes,
1395            E::InvalidUsageOfPureArg => CommandArgumentErrorKind::InvalidUsageOfPureArgument,
1396            E::InvalidArgumentToPrivateEntryFunction => {
1397                CommandArgumentErrorKind::InvalidArgumentToPrivateEntryFunction
1398            }
1399            E::IndexOutOfBounds { idx } => {
1400                message.index_error = Some(index_error(idx.into(), None));
1401                CommandArgumentErrorKind::IndexOutOfBounds
1402            }
1403            E::SecondaryIndexOutOfBounds {
1404                result_idx,
1405                secondary_idx,
1406            } => {
1407                message.index_error =
1408                    Some(index_error(result_idx.into(), Some(secondary_idx.into())));
1409                CommandArgumentErrorKind::SecondaryIndexOutOfBounds
1410            }
1411            E::InvalidResultArity { result_idx } => {
1412                message.index_error = Some(index_error(result_idx.into(), None));
1413                CommandArgumentErrorKind::InvalidResultArity
1414            }
1415            E::InvalidGasCoinUsage => CommandArgumentErrorKind::InvalidGasCoinUsage,
1416            E::InvalidValueUsage => CommandArgumentErrorKind::InvalidValueUsage,
1417            E::InvalidObjectByValue => CommandArgumentErrorKind::InvalidObjectByValue,
1418            E::InvalidObjectByMutRef => CommandArgumentErrorKind::InvalidObjectByMutRef,
1419            E::SharedObjectOperationNotAllowed => {
1420                CommandArgumentErrorKind::ConsensusObjectOperationNotAllowed
1421            }
1422            E::InvalidArgumentArity => CommandArgumentErrorKind::InvalidArgumentArity,
1423
1424            E::InvalidTransferObject => CommandArgumentErrorKind::InvalidTransferObject,
1425            E::InvalidMakeMoveVecNonObjectArgument => {
1426                CommandArgumentErrorKind::InvalidMakeMoveVecNonObjectArgument
1427            }
1428            E::ArgumentWithoutValue => CommandArgumentErrorKind::ArgumentWithoutValue,
1429            E::CannotMoveBorrowedValue => CommandArgumentErrorKind::CannotMoveBorrowedValue,
1430            E::CannotWriteToExtendedReference => {
1431                CommandArgumentErrorKind::CannotWriteToExtendedReference
1432            }
1433            E::InvalidReferenceArgument => CommandArgumentErrorKind::InvalidReferenceArgument,
1434        };
1435
1436        message.set_kind(kind);
1437        message
1438    }
1439}
1440
1441//
1442// TypeArgumentError
1443//
1444
1445impl From<crate::execution_status::TypeArgumentError>
1446    for type_argument_error::TypeArgumentErrorKind
1447{
1448    fn from(value: crate::execution_status::TypeArgumentError) -> Self {
1449        use crate::execution_status::TypeArgumentError::*;
1450
1451        match value {
1452            TypeNotFound => Self::TypeNotFound,
1453            ConstraintNotSatisfied => Self::ConstraintNotSatisfied,
1454        }
1455    }
1456}
1457
1458//
1459// PackageUpgradeError
1460//
1461
1462impl From<crate::execution_status::PackageUpgradeError> for PackageUpgradeError {
1463    fn from(value: crate::execution_status::PackageUpgradeError) -> Self {
1464        use crate::execution_status::PackageUpgradeError as E;
1465        use package_upgrade_error::PackageUpgradeErrorKind;
1466
1467        let mut message = Self::default();
1468
1469        let kind = match value {
1470            E::UnableToFetchPackage { package_id } => {
1471                message.package_id = Some(package_id.to_canonical_string(true));
1472                PackageUpgradeErrorKind::UnableToFetchPackage
1473            }
1474            E::NotAPackage { object_id } => {
1475                message.package_id = Some(object_id.to_canonical_string(true));
1476                PackageUpgradeErrorKind::NotAPackage
1477            }
1478            E::IncompatibleUpgrade => PackageUpgradeErrorKind::IncompatibleUpgrade,
1479            E::DigestDoesNotMatch { digest } => {
1480                message.digest = crate::digests::Digest::try_from(digest)
1481                    .ok()
1482                    .map(|d| d.to_string());
1483                PackageUpgradeErrorKind::DigestDoesNotMatch
1484            }
1485            E::UnknownUpgradePolicy { policy } => {
1486                message.policy = Some(policy.into());
1487                PackageUpgradeErrorKind::UnknownUpgradePolicy
1488            }
1489            E::PackageIDDoesNotMatch {
1490                package_id,
1491                ticket_id,
1492            } => {
1493                message.package_id = Some(package_id.to_canonical_string(true));
1494                message.ticket_id = Some(ticket_id.to_canonical_string(true));
1495                PackageUpgradeErrorKind::PackageIdDoesNotMatch
1496            }
1497        };
1498
1499        message.set_kind(kind);
1500        message
1501    }
1502}
1503
1504//
1505// MoveLocation
1506//
1507
1508impl From<crate::execution_status::MoveLocation> for MoveLocation {
1509    fn from(value: crate::execution_status::MoveLocation) -> Self {
1510        let mut message = Self::default();
1511        message.package = Some(value.module.address().to_canonical_string(true));
1512        message.module = Some(value.module.name().to_string());
1513        message.function = Some(value.function.into());
1514        message.instruction = Some(value.instruction.into());
1515        message.function_name = value.function_name.map(|name| name.to_string());
1516        message
1517    }
1518}
1519
1520//
1521// AuthorityQuorumSignInfo aka ValidatorAggregatedSignature
1522//
1523
1524impl<const T: bool> From<crate::crypto::AuthorityQuorumSignInfo<T>>
1525    for ValidatorAggregatedSignature
1526{
1527    fn from(value: crate::crypto::AuthorityQuorumSignInfo<T>) -> Self {
1528        let mut bitmap = Vec::new();
1529        value.signers_map.serialize_into(&mut bitmap).unwrap();
1530
1531        Self::default()
1532            .with_epoch(value.epoch)
1533            .with_signature(value.signature.as_ref().to_vec())
1534            .with_bitmap(bitmap)
1535    }
1536}
1537
1538impl<const T: bool> TryFrom<&ValidatorAggregatedSignature>
1539    for crate::crypto::AuthorityQuorumSignInfo<T>
1540{
1541    type Error = TryFromProtoError;
1542
1543    fn try_from(value: &ValidatorAggregatedSignature) -> Result<Self, Self::Error> {
1544        Ok(Self {
1545            epoch: value.epoch(),
1546            signature: crate::crypto::AggregateAuthoritySignature::from_bytes(value.signature())
1547                .map_err(|e| TryFromProtoError::invalid("signature", e))?,
1548            signers_map: crate::sui_serde::deserialize_sui_bitmap(value.bitmap())
1549                .map_err(|e| TryFromProtoError::invalid("bitmap", e))?,
1550        })
1551    }
1552}
1553
1554//
1555// ValidatorCommittee
1556//
1557
1558impl From<crate::committee::Committee> for ValidatorCommittee {
1559    fn from(value: crate::committee::Committee) -> Self {
1560        let mut message = Self::default();
1561        message.epoch = Some(value.epoch);
1562        message.members = value
1563            .voting_rights
1564            .into_iter()
1565            .map(|(name, weight)| {
1566                let mut member = ValidatorCommitteeMember::default();
1567                member.public_key = Some(name.0.to_vec().into());
1568                member.weight = Some(weight);
1569                member
1570            })
1571            .collect();
1572        message
1573    }
1574}
1575
1576impl TryFrom<&ValidatorCommittee> for crate::committee::Committee {
1577    type Error = TryFromProtoError;
1578
1579    fn try_from(s: &ValidatorCommittee) -> Result<Self, Self::Error> {
1580        let members = s
1581            .members()
1582            .iter()
1583            .map(|member| {
1584                let public_key =
1585                    crate::crypto::AuthorityPublicKeyBytes::from_bytes(member.public_key())
1586                        .map_err(|e| TryFromProtoError::invalid("public_key", e))?;
1587                Ok((public_key, member.weight()))
1588            })
1589            .collect::<Result<_, _>>()?;
1590        Ok(Self::new(s.epoch(), members))
1591    }
1592}
1593
1594//
1595// ZkLoginAuthenticator
1596//
1597
1598impl From<&crate::zk_login_authenticator::ZkLoginAuthenticator> for ZkLoginAuthenticator {
1599    fn from(value: &crate::zk_login_authenticator::ZkLoginAuthenticator) -> Self {
1600        //TODO implement this without going through the sdk type
1601        let mut inputs = ZkLoginInputs::default();
1602        inputs.address_seed = Some(value.inputs.get_address_seed().to_string());
1603        let mut message = Self::default();
1604        message.inputs = Some(inputs);
1605        message.max_epoch = Some(value.get_max_epoch());
1606        message.signature = Some(value.user_signature.clone().into());
1607
1608        sui_sdk_types::ZkLoginAuthenticator::try_from(value.clone())
1609            .map(Into::into)
1610            .ok()
1611            .unwrap_or(message)
1612    }
1613}
1614
1615//
1616// ZkLoginPublicIdentifier
1617//
1618
1619impl From<&crate::crypto::ZkLoginPublicIdentifier> for ZkLoginPublicIdentifier {
1620    fn from(value: &crate::crypto::ZkLoginPublicIdentifier) -> Self {
1621        //TODO implement this without going through the sdk type
1622        sui_sdk_types::ZkLoginPublicIdentifier::try_from(value.to_owned())
1623            .map(|id| (&id).into())
1624            .ok()
1625            .unwrap_or_default()
1626    }
1627}
1628
1629//
1630// SignatureScheme
1631//
1632
1633impl From<crate::crypto::SignatureScheme> for SignatureScheme {
1634    fn from(value: crate::crypto::SignatureScheme) -> Self {
1635        use crate::crypto::SignatureScheme as S;
1636
1637        match value {
1638            S::ED25519 => Self::Ed25519,
1639            S::Secp256k1 => Self::Secp256k1,
1640            S::Secp256r1 => Self::Secp256r1,
1641            S::BLS12381 => Self::Bls12381,
1642            S::MultiSig => Self::Multisig,
1643            S::ZkLoginAuthenticator => Self::Zklogin,
1644            S::PasskeyAuthenticator => Self::Passkey,
1645        }
1646    }
1647}
1648
1649//
1650// SimpleSignature
1651//
1652
1653impl From<crate::crypto::Signature> for SimpleSignature {
1654    fn from(value: crate::crypto::Signature) -> Self {
1655        Self::from(&value)
1656    }
1657}
1658
1659impl From<&crate::crypto::Signature> for SimpleSignature {
1660    fn from(value: &crate::crypto::Signature) -> Self {
1661        let scheme: SignatureScheme = value.scheme().into();
1662        let signature = value.signature_bytes();
1663        let public_key = value.public_key_bytes();
1664
1665        let mut message = Self::default();
1666        message.scheme = Some(scheme.into());
1667        message.signature = Some(signature.to_vec().into());
1668        message.public_key = Some(public_key.to_vec().into());
1669        message
1670    }
1671}
1672
1673//
1674// PasskeyAuthenticator
1675//
1676
1677impl From<&crate::passkey_authenticator::PasskeyAuthenticator> for PasskeyAuthenticator {
1678    fn from(value: &crate::passkey_authenticator::PasskeyAuthenticator) -> Self {
1679        let mut message = Self::default();
1680        message.authenticator_data = Some(value.authenticator_data().to_vec().into());
1681        message.client_data_json = Some(value.client_data_json().to_owned());
1682        message.signature = Some(value.signature().into());
1683        message
1684    }
1685}
1686
1687//
1688// MultisigMemberPublicKey
1689//
1690
1691impl From<&crate::crypto::PublicKey> for MultisigMemberPublicKey {
1692    fn from(value: &crate::crypto::PublicKey) -> Self {
1693        let mut message = Self::default();
1694
1695        match value {
1696            crate::crypto::PublicKey::Ed25519(_)
1697            | crate::crypto::PublicKey::Secp256k1(_)
1698            | crate::crypto::PublicKey::Secp256r1(_)
1699            | crate::crypto::PublicKey::Passkey(_) => {
1700                message.public_key = Some(value.as_ref().to_vec().into());
1701            }
1702            crate::crypto::PublicKey::ZkLogin(z) => {
1703                message.zklogin = Some(z.into());
1704            }
1705        }
1706
1707        message.set_scheme(value.scheme().into());
1708        message
1709    }
1710}
1711
1712//
1713// MultisigCommittee
1714//
1715
1716impl From<&crate::multisig::MultiSigPublicKey> for MultisigCommittee {
1717    fn from(value: &crate::multisig::MultiSigPublicKey) -> Self {
1718        let mut message = Self::default();
1719        message.members = value
1720            .pubkeys()
1721            .iter()
1722            .map(|(pk, weight)| {
1723                let mut member = MultisigMember::default();
1724                member.public_key = Some(pk.into());
1725                member.weight = Some((*weight).into());
1726                member
1727            })
1728            .collect();
1729        message.threshold = Some((*value.threshold()).into());
1730        message
1731    }
1732}
1733
1734impl From<&crate::multisig_legacy::MultiSigPublicKeyLegacy> for MultisigCommittee {
1735    fn from(value: &crate::multisig_legacy::MultiSigPublicKeyLegacy) -> Self {
1736        let mut message = Self::default();
1737        message.members = value
1738            .pubkeys()
1739            .iter()
1740            .map(|(pk, weight)| {
1741                let mut member = MultisigMember::default();
1742                member.public_key = Some(pk.into());
1743                member.weight = Some((*weight).into());
1744                member
1745            })
1746            .collect();
1747        message.threshold = Some((*value.threshold()).into());
1748        message
1749    }
1750}
1751
1752//
1753// MultisigMemberSignature
1754//
1755
1756impl From<&crate::crypto::CompressedSignature> for MultisigMemberSignature {
1757    fn from(value: &crate::crypto::CompressedSignature) -> Self {
1758        let mut message = Self::default();
1759
1760        let scheme = match value {
1761            crate::crypto::CompressedSignature::Ed25519(b) => {
1762                message.signature = Some(b.0.to_vec().into());
1763                SignatureScheme::Ed25519
1764            }
1765            crate::crypto::CompressedSignature::Secp256k1(b) => {
1766                message.signature = Some(b.0.to_vec().into());
1767                SignatureScheme::Secp256k1
1768            }
1769            crate::crypto::CompressedSignature::Secp256r1(b) => {
1770                message.signature = Some(b.0.to_vec().into());
1771                SignatureScheme::Secp256r1
1772            }
1773            crate::crypto::CompressedSignature::ZkLogin(_z) => {
1774                //TODO
1775                SignatureScheme::Zklogin
1776            }
1777            crate::crypto::CompressedSignature::Passkey(_p) => {
1778                //TODO
1779                SignatureScheme::Passkey
1780            }
1781        };
1782
1783        message.set_scheme(scheme);
1784        message
1785    }
1786}
1787
1788//
1789// MultisigAggregatedSignature
1790//
1791
1792impl From<&crate::multisig_legacy::MultiSigLegacy> for MultisigAggregatedSignature {
1793    fn from(value: &crate::multisig_legacy::MultiSigLegacy) -> Self {
1794        let mut legacy_bitmap = Vec::new();
1795        value
1796            .get_bitmap()
1797            .serialize_into(&mut legacy_bitmap)
1798            .unwrap();
1799
1800        Self::default()
1801            .with_signatures(value.get_sigs().iter().map(Into::into).collect())
1802            .with_legacy_bitmap(legacy_bitmap)
1803            .with_committee(value.get_pk())
1804    }
1805}
1806
1807impl From<&crate::multisig::MultiSig> for MultisigAggregatedSignature {
1808    fn from(value: &crate::multisig::MultiSig) -> Self {
1809        let mut message = Self::default();
1810        message.signatures = value.get_sigs().iter().map(Into::into).collect();
1811        message.bitmap = Some(value.get_bitmap().into());
1812        message.committee = Some(value.get_pk().into());
1813        message
1814    }
1815}
1816
1817//
1818// UserSignature
1819//
1820
1821impl From<&crate::signature::GenericSignature> for UserSignature {
1822    fn from(value: &crate::signature::GenericSignature) -> Self {
1823        Self::merge_from(value, &FieldMaskTree::new_wildcard())
1824    }
1825}
1826
1827impl Merge<&crate::signature::GenericSignature> for UserSignature {
1828    fn merge(&mut self, source: &crate::signature::GenericSignature, mask: &FieldMaskTree) {
1829        use user_signature::Signature;
1830
1831        if mask.contains(Self::BCS_FIELD) {
1832            let mut bcs = Bcs::from(source.as_ref().to_vec());
1833            bcs.name = Some("UserSignatureBytes".to_owned());
1834            self.bcs = Some(bcs);
1835        }
1836
1837        let scheme = match source {
1838            crate::signature::GenericSignature::MultiSig(multi_sig) => {
1839                if mask.contains(Self::MULTISIG_FIELD) {
1840                    self.signature = Some(Signature::Multisig(multi_sig.into()));
1841                }
1842                SignatureScheme::Multisig
1843            }
1844            crate::signature::GenericSignature::MultiSigLegacy(multi_sig_legacy) => {
1845                if mask.contains(Self::MULTISIG_FIELD) {
1846                    self.signature = Some(Signature::Multisig(multi_sig_legacy.into()));
1847                }
1848                SignatureScheme::Multisig
1849            }
1850            crate::signature::GenericSignature::Signature(signature) => {
1851                let scheme = signature.scheme().into();
1852                if mask.contains(Self::SIMPLE_FIELD) {
1853                    self.signature = Some(Signature::Simple(signature.into()));
1854                }
1855                scheme
1856            }
1857            crate::signature::GenericSignature::ZkLoginAuthenticator(z) => {
1858                if mask.contains(Self::ZKLOGIN_FIELD) {
1859                    self.signature = Some(Signature::Zklogin(z.into()));
1860                }
1861                SignatureScheme::Zklogin
1862            }
1863            crate::signature::GenericSignature::PasskeyAuthenticator(p) => {
1864                if mask.contains(Self::PASSKEY_FIELD) {
1865                    self.signature = Some(Signature::Passkey(p.into()));
1866                }
1867                SignatureScheme::Passkey
1868            }
1869        };
1870
1871        if mask.contains(Self::SCHEME_FIELD) {
1872            self.set_scheme(scheme);
1873        }
1874    }
1875}
1876
1877//
1878// BalanceChange
1879//
1880
1881impl From<crate::balance_change::BalanceChange> for BalanceChange {
1882    fn from(value: crate::balance_change::BalanceChange) -> Self {
1883        let mut message = Self::default();
1884        message.address = Some(value.address.to_string());
1885        message.coin_type = Some(value.coin_type.to_canonical_string(true));
1886        message.amount = Some(value.amount.to_string());
1887        message
1888    }
1889}
1890
1891impl TryFrom<&BalanceChange> for crate::balance_change::BalanceChange {
1892    type Error = TryFromProtoError;
1893
1894    fn try_from(value: &BalanceChange) -> Result<Self, Self::Error> {
1895        Ok(Self {
1896            address: value
1897                .address()
1898                .parse()
1899                .map_err(|e| TryFromProtoError::invalid(BalanceChange::ADDRESS_FIELD, e))?,
1900            coin_type: value
1901                .coin_type()
1902                .parse()
1903                .map_err(|e| TryFromProtoError::invalid(BalanceChange::COIN_TYPE_FIELD, e))?,
1904            amount: value
1905                .amount()
1906                .parse()
1907                .map_err(|e| TryFromProtoError::invalid(BalanceChange::AMOUNT_FIELD, e))?,
1908        })
1909    }
1910}
1911
1912//
1913// Object
1914//
1915
1916pub const PACKAGE_TYPE: &str = "package";
1917
1918impl From<crate::object::Object> for Object {
1919    fn from(value: crate::object::Object) -> Self {
1920        Self::merge_from(&value, &FieldMaskTree::new_wildcard())
1921    }
1922}
1923
1924impl Merge<&crate::object::Object> for Object {
1925    fn merge(&mut self, source: &crate::object::Object, mask: &FieldMaskTree) {
1926        if mask.contains(Self::BCS_FIELD.name) {
1927            let mut bcs = Bcs::serialize(&source).unwrap();
1928            bcs.name = Some("Object".to_owned());
1929            self.bcs = Some(bcs);
1930        }
1931
1932        if mask.contains(Self::DIGEST_FIELD.name) {
1933            self.digest = Some(source.digest().to_string());
1934        }
1935
1936        if mask.contains(Self::OBJECT_ID_FIELD.name) {
1937            self.object_id = Some(source.id().to_canonical_string(true));
1938        }
1939
1940        if mask.contains(Self::VERSION_FIELD.name) {
1941            self.version = Some(source.version().value());
1942        }
1943
1944        if mask.contains(Self::OWNER_FIELD.name) {
1945            self.owner = Some(source.owner().to_owned().into());
1946        }
1947
1948        if mask.contains(Self::PREVIOUS_TRANSACTION_FIELD.name) {
1949            self.previous_transaction = Some(source.previous_transaction.to_string());
1950        }
1951
1952        if mask.contains(Self::STORAGE_REBATE_FIELD.name) {
1953            self.storage_rebate = Some(source.storage_rebate);
1954        }
1955
1956        if mask.contains(Self::BALANCE_FIELD) {
1957            self.balance = source.as_coin_maybe().map(|coin| coin.balance.value());
1958        }
1959
1960        self.merge(&source.data, mask);
1961    }
1962}
1963
1964impl Merge<&crate::object::MoveObject> for Object {
1965    fn merge(&mut self, source: &crate::object::MoveObject, mask: &FieldMaskTree) {
1966        self.object_id = Some(source.id().to_canonical_string(true));
1967        self.version = Some(source.version().value());
1968
1969        if mask.contains(Self::OBJECT_TYPE_FIELD.name) {
1970            self.object_type = Some(source.type_().to_canonical_string(true));
1971        }
1972
1973        if mask.contains(Self::HAS_PUBLIC_TRANSFER_FIELD.name) {
1974            self.has_public_transfer = Some(source.has_public_transfer());
1975        }
1976
1977        if mask.contains(Self::CONTENTS_FIELD.name) {
1978            let mut bcs = Bcs::from(source.contents().to_vec());
1979            bcs.name = Some(source.type_().to_canonical_string(true));
1980            self.contents = Some(bcs);
1981        }
1982    }
1983}
1984
1985impl Merge<&crate::move_package::MovePackage> for Object {
1986    fn merge(&mut self, source: &crate::move_package::MovePackage, mask: &FieldMaskTree) {
1987        self.object_id = Some(source.id().to_canonical_string(true));
1988        self.version = Some(source.version().value());
1989
1990        if mask.contains(Self::OBJECT_TYPE_FIELD.name) {
1991            self.object_type = Some(PACKAGE_TYPE.to_owned());
1992        }
1993
1994        if mask.contains(Self::PACKAGE_FIELD.name) {
1995            let mut package = Package::default();
1996            package.modules = source
1997                .serialized_module_map()
1998                .iter()
1999                .map(|(name, contents)| {
2000                    let mut module = Module::default();
2001                    module.name = Some(name.to_string());
2002                    module.contents = Some(contents.clone().into());
2003                    module
2004                })
2005                .collect();
2006            package.type_origins = source
2007                .type_origin_table()
2008                .clone()
2009                .into_iter()
2010                .map(Into::into)
2011                .collect();
2012            package.linkage = source
2013                .linkage_table()
2014                .iter()
2015                .map(
2016                    |(
2017                        original_id,
2018                        crate::move_package::UpgradeInfo {
2019                            upgraded_id,
2020                            upgraded_version,
2021                        },
2022                    )| {
2023                        let mut linkage = Linkage::default();
2024                        linkage.original_id = Some(original_id.to_canonical_string(true));
2025                        linkage.upgraded_id = Some(upgraded_id.to_canonical_string(true));
2026                        linkage.upgraded_version = Some(upgraded_version.value());
2027                        linkage
2028                    },
2029                )
2030                .collect();
2031
2032            self.package = Some(package);
2033        }
2034    }
2035}
2036
2037impl Merge<&crate::object::Data> for Object {
2038    fn merge(&mut self, source: &crate::object::Data, mask: &FieldMaskTree) {
2039        match source {
2040            crate::object::Data::Move(object) => self.merge(object, mask),
2041            crate::object::Data::Package(package) => self.merge(package, mask),
2042        }
2043    }
2044}
2045
2046//
2047// TypeOrigin
2048//
2049
2050impl From<crate::move_package::TypeOrigin> for TypeOrigin {
2051    fn from(value: crate::move_package::TypeOrigin) -> Self {
2052        let mut message = Self::default();
2053        message.module_name = Some(value.module_name.to_string());
2054        message.datatype_name = Some(value.datatype_name.to_string());
2055        message.package_id = Some(value.package.to_canonical_string(true));
2056        message
2057    }
2058}
2059
2060//
2061// GenesisObject
2062//
2063
2064impl From<crate::transaction::GenesisObject> for Object {
2065    fn from(value: crate::transaction::GenesisObject) -> Self {
2066        let crate::transaction::GenesisObject::RawObject { data, owner } = value;
2067        let mut message = Self::default();
2068        message.owner = Some(owner.into());
2069
2070        message.merge(&data, &FieldMaskTree::new_wildcard());
2071
2072        message
2073    }
2074}
2075
2076//
2077// ObjectReference
2078//
2079
2080pub trait ObjectRefExt {
2081    fn to_proto(self) -> ObjectReference;
2082}
2083
2084pub trait ObjectReferenceExt {
2085    fn try_to_object_ref(&self) -> Result<crate::base_types::ObjectRef, anyhow::Error>;
2086}
2087
2088impl ObjectRefExt for crate::base_types::ObjectRef {
2089    fn to_proto(self) -> ObjectReference {
2090        let (object_id, version, digest) = self;
2091        let mut message = ObjectReference::default();
2092        message.object_id = Some(object_id.to_canonical_string(true));
2093        message.version = Some(version.value());
2094        message.digest = Some(digest.to_string());
2095        message
2096    }
2097}
2098
2099impl ObjectReferenceExt for ObjectReference {
2100    fn try_to_object_ref(&self) -> Result<crate::base_types::ObjectRef, anyhow::Error> {
2101        use anyhow::Context;
2102
2103        let object_id = self
2104            .object_id_opt()
2105            .ok_or_else(|| anyhow::anyhow!("missing object_id"))?;
2106        let object_id = crate::base_types::ObjectID::from_hex_literal(object_id)
2107            .with_context(|| format!("Failed to parse object_id: {}", object_id))?;
2108
2109        let version = self
2110            .version_opt()
2111            .ok_or_else(|| anyhow::anyhow!("missing version"))?;
2112        let version = crate::base_types::SequenceNumber::from(version);
2113
2114        let digest = self
2115            .digest_opt()
2116            .ok_or_else(|| anyhow::anyhow!("missing digest"))?;
2117        let digest = digest
2118            .parse::<crate::digests::ObjectDigest>()
2119            .with_context(|| format!("Failed to parse digest: {}", digest))?;
2120
2121        Ok((object_id, version, digest))
2122    }
2123}
2124
2125impl From<&crate::storage::ObjectKey> for ObjectReference {
2126    fn from(value: &crate::storage::ObjectKey) -> Self {
2127        Self::default()
2128            .with_object_id(value.0.to_canonical_string(true))
2129            .with_version(value.1.value())
2130    }
2131}
2132
2133//
2134// Owner
2135//
2136
2137impl From<crate::object::Owner> for Owner {
2138    fn from(value: crate::object::Owner) -> Self {
2139        use crate::object::Owner as O;
2140        use owner::OwnerKind;
2141
2142        let mut message = Self::default();
2143
2144        let kind = match value {
2145            O::AddressOwner(address) => {
2146                message.address = Some(address.to_string());
2147                OwnerKind::Address
2148            }
2149            O::ObjectOwner(address) => {
2150                message.address = Some(address.to_string());
2151                OwnerKind::Object
2152            }
2153            O::Shared {
2154                initial_shared_version,
2155            } => {
2156                message.version = Some(initial_shared_version.value());
2157                OwnerKind::Shared
2158            }
2159            O::Immutable => OwnerKind::Immutable,
2160            O::ConsensusAddressOwner {
2161                start_version,
2162                owner,
2163            } => {
2164                message.version = Some(start_version.value());
2165                message.address = Some(owner.to_string());
2166                OwnerKind::ConsensusAddress
2167            }
2168        };
2169
2170        message.set_kind(kind);
2171        message
2172    }
2173}
2174
2175//
2176// Transaction
2177//
2178
2179impl From<crate::transaction::TransactionData> for Transaction {
2180    fn from(value: crate::transaction::TransactionData) -> Self {
2181        Self::merge_from(&value, &FieldMaskTree::new_wildcard())
2182    }
2183}
2184
2185impl Merge<&crate::transaction::TransactionData> for Transaction {
2186    fn merge(&mut self, source: &crate::transaction::TransactionData, mask: &FieldMaskTree) {
2187        if mask.contains(Self::BCS_FIELD.name) {
2188            let mut bcs = Bcs::serialize(&source).unwrap();
2189            bcs.name = Some("TransactionData".to_owned());
2190            self.bcs = Some(bcs);
2191        }
2192
2193        if mask.contains(Self::DIGEST_FIELD.name) {
2194            self.digest = Some(source.digest().to_string());
2195        }
2196
2197        if mask.contains(Self::VERSION_FIELD.name) {
2198            self.version = Some(1);
2199        }
2200
2201        let crate::transaction::TransactionData::V1(source) = source;
2202
2203        if mask.contains(Self::KIND_FIELD.name) {
2204            self.kind = Some(source.kind.clone().into());
2205        }
2206
2207        if mask.contains(Self::SENDER_FIELD.name) {
2208            self.sender = Some(source.sender.to_string());
2209        }
2210
2211        if mask.contains(Self::GAS_PAYMENT_FIELD.name) {
2212            self.gas_payment = Some((&source.gas_data).into());
2213        }
2214
2215        if mask.contains(Self::EXPIRATION_FIELD.name) {
2216            self.expiration = Some(source.expiration.into());
2217        }
2218    }
2219}
2220
2221//
2222// GasPayment
2223//
2224
2225impl From<&crate::transaction::GasData> for GasPayment {
2226    fn from(value: &crate::transaction::GasData) -> Self {
2227        let mut message = Self::default();
2228        message.objects = value
2229            .payment
2230            .iter()
2231            .map(|obj_ref| obj_ref.to_proto())
2232            .collect();
2233        message.owner = Some(value.owner.to_string());
2234        message.price = Some(value.price);
2235        message.budget = Some(value.budget);
2236        message
2237    }
2238}
2239
2240//
2241// TransactionExpiration
2242//
2243
2244impl From<crate::transaction::TransactionExpiration> for TransactionExpiration {
2245    fn from(value: crate::transaction::TransactionExpiration) -> Self {
2246        use crate::transaction::TransactionExpiration as E;
2247        use transaction_expiration::TransactionExpirationKind;
2248
2249        let mut message = Self::default();
2250
2251        let kind = match value {
2252            E::None => TransactionExpirationKind::None,
2253            E::Epoch(epoch) => {
2254                message.epoch = Some(epoch);
2255                TransactionExpirationKind::Epoch
2256            }
2257            E::ValidDuring {
2258                min_epoch,
2259                max_epoch,
2260                min_timestamp,
2261                max_timestamp,
2262                chain,
2263                nonce,
2264            } => {
2265                message.epoch = max_epoch;
2266                message.min_epoch = min_epoch;
2267                message.min_timestamp = min_timestamp.map(ms_to_timestamp);
2268                message.max_timestamp = max_timestamp.map(ms_to_timestamp);
2269                message.set_chain(sui_sdk_types::Digest::new(*chain.as_bytes()));
2270                message.set_nonce(nonce);
2271
2272                TransactionExpirationKind::ValidDuring
2273            }
2274        };
2275
2276        message.set_kind(kind);
2277        message
2278    }
2279}
2280
2281impl TryFrom<&TransactionExpiration> for crate::transaction::TransactionExpiration {
2282    type Error = &'static str;
2283
2284    fn try_from(value: &TransactionExpiration) -> Result<Self, Self::Error> {
2285        use transaction_expiration::TransactionExpirationKind;
2286
2287        Ok(match value.kind() {
2288            TransactionExpirationKind::None => Self::None,
2289            TransactionExpirationKind::Epoch => Self::Epoch(value.epoch()),
2290            TransactionExpirationKind::Unknown | _ => {
2291                return Err("unknown TransactionExpirationKind");
2292            }
2293        })
2294    }
2295}
2296
2297//
2298// TransactionKind
2299//
2300
2301impl From<crate::transaction::TransactionKind> for TransactionKind {
2302    fn from(value: crate::transaction::TransactionKind) -> Self {
2303        use crate::transaction::TransactionKind as K;
2304        use transaction_kind::Kind;
2305
2306        let message = Self::default();
2307
2308        match value {
2309            K::ProgrammableTransaction(ptb) => message
2310                .with_programmable_transaction(ptb)
2311                .with_kind(Kind::ProgrammableTransaction),
2312            K::ChangeEpoch(change_epoch) => message
2313                .with_change_epoch(change_epoch)
2314                .with_kind(Kind::ChangeEpoch),
2315            K::Genesis(genesis) => message.with_genesis(genesis).with_kind(Kind::Genesis),
2316            K::ConsensusCommitPrologue(prologue) => message
2317                .with_consensus_commit_prologue(prologue)
2318                .with_kind(Kind::ConsensusCommitPrologueV1),
2319            K::AuthenticatorStateUpdate(update) => message
2320                .with_authenticator_state_update(update)
2321                .with_kind(Kind::AuthenticatorStateUpdate),
2322            K::EndOfEpochTransaction(transactions) => message
2323                .with_end_of_epoch({
2324                    EndOfEpochTransaction::default()
2325                        .with_transactions(transactions.into_iter().map(Into::into).collect())
2326                })
2327                .with_kind(Kind::EndOfEpoch),
2328            K::RandomnessStateUpdate(update) => message
2329                .with_randomness_state_update(update)
2330                .with_kind(Kind::RandomnessStateUpdate),
2331            K::ConsensusCommitPrologueV2(prologue) => message
2332                .with_consensus_commit_prologue(prologue)
2333                .with_kind(Kind::ConsensusCommitPrologueV2),
2334            K::ConsensusCommitPrologueV3(prologue) => message
2335                .with_consensus_commit_prologue(prologue)
2336                .with_kind(Kind::ConsensusCommitPrologueV3),
2337            K::ConsensusCommitPrologueV4(prologue) => message
2338                .with_consensus_commit_prologue(prologue)
2339                .with_kind(Kind::ConsensusCommitPrologueV4),
2340            K::ProgrammableSystemTransaction(ptb) => message
2341                .with_programmable_transaction(ptb)
2342                .with_kind(Kind::ProgrammableSystemTransaction),
2343        }
2344    }
2345}
2346
2347//
2348// ConsensusCommitPrologue
2349//
2350
2351impl From<crate::messages_consensus::ConsensusCommitPrologue> for ConsensusCommitPrologue {
2352    fn from(value: crate::messages_consensus::ConsensusCommitPrologue) -> Self {
2353        let mut message = Self::default();
2354        message.epoch = Some(value.epoch);
2355        message.round = Some(value.round);
2356        message.commit_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(
2357            value.commit_timestamp_ms,
2358        ));
2359        message
2360    }
2361}
2362
2363impl From<crate::messages_consensus::ConsensusCommitPrologueV2> for ConsensusCommitPrologue {
2364    fn from(value: crate::messages_consensus::ConsensusCommitPrologueV2) -> Self {
2365        let mut message = Self::default();
2366        message.epoch = Some(value.epoch);
2367        message.round = Some(value.round);
2368        message.commit_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(
2369            value.commit_timestamp_ms,
2370        ));
2371        message.consensus_commit_digest = Some(value.consensus_commit_digest.to_string());
2372        message
2373    }
2374}
2375
2376impl From<crate::messages_consensus::ConsensusCommitPrologueV3> for ConsensusCommitPrologue {
2377    fn from(value: crate::messages_consensus::ConsensusCommitPrologueV3) -> Self {
2378        let mut message = Self::default();
2379        message.epoch = Some(value.epoch);
2380        message.round = Some(value.round);
2381        message.commit_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(
2382            value.commit_timestamp_ms,
2383        ));
2384        message.consensus_commit_digest = Some(value.consensus_commit_digest.to_string());
2385        message.sub_dag_index = value.sub_dag_index;
2386        message.consensus_determined_version_assignments =
2387            Some(value.consensus_determined_version_assignments.into());
2388        message
2389    }
2390}
2391
2392impl From<crate::messages_consensus::ConsensusCommitPrologueV4> for ConsensusCommitPrologue {
2393    fn from(
2394        crate::messages_consensus::ConsensusCommitPrologueV4 {
2395            epoch,
2396            round,
2397            sub_dag_index,
2398            commit_timestamp_ms,
2399            consensus_commit_digest,
2400            consensus_determined_version_assignments,
2401            additional_state_digest,
2402        }: crate::messages_consensus::ConsensusCommitPrologueV4,
2403    ) -> Self {
2404        let mut message = Self::default();
2405        message.epoch = Some(epoch);
2406        message.round = Some(round);
2407        message.commit_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(commit_timestamp_ms));
2408        message.consensus_commit_digest = Some(consensus_commit_digest.to_string());
2409        message.sub_dag_index = sub_dag_index;
2410        message.consensus_determined_version_assignments =
2411            Some(consensus_determined_version_assignments.into());
2412        message.additional_state_digest = Some(additional_state_digest.to_string());
2413        message
2414    }
2415}
2416
2417//
2418// ConsensusDeterminedVersionAssignments
2419//
2420
2421impl From<crate::messages_consensus::ConsensusDeterminedVersionAssignments>
2422    for ConsensusDeterminedVersionAssignments
2423{
2424    fn from(value: crate::messages_consensus::ConsensusDeterminedVersionAssignments) -> Self {
2425        use crate::messages_consensus::ConsensusDeterminedVersionAssignments as A;
2426
2427        let mut message = Self::default();
2428
2429        let version = match value {
2430            A::CancelledTransactions(canceled_transactions) => {
2431                message.canceled_transactions = canceled_transactions
2432                    .into_iter()
2433                    .map(|(tx_digest, assignments)| {
2434                        let mut message = CanceledTransaction::default();
2435                        message.digest = Some(tx_digest.to_string());
2436                        message.version_assignments = assignments
2437                            .into_iter()
2438                            .map(|(id, version)| {
2439                                let mut message = VersionAssignment::default();
2440                                message.object_id = Some(id.to_canonical_string(true));
2441                                message.version = Some(version.value());
2442                                message
2443                            })
2444                            .collect();
2445                        message
2446                    })
2447                    .collect();
2448                1
2449            }
2450            A::CancelledTransactionsV2(canceled_transactions) => {
2451                message.canceled_transactions = canceled_transactions
2452                    .into_iter()
2453                    .map(|(tx_digest, assignments)| {
2454                        let mut message = CanceledTransaction::default();
2455                        message.digest = Some(tx_digest.to_string());
2456                        message.version_assignments = assignments
2457                            .into_iter()
2458                            .map(|((id, start_version), version)| {
2459                                let mut message = VersionAssignment::default();
2460                                message.object_id = Some(id.to_canonical_string(true));
2461                                message.start_version = Some(start_version.value());
2462                                message.version = Some(version.value());
2463                                message
2464                            })
2465                            .collect();
2466                        message
2467                    })
2468                    .collect();
2469                2
2470            }
2471        };
2472
2473        message.version = Some(version);
2474        message
2475    }
2476}
2477
2478//
2479// GenesisTransaction
2480//
2481
2482impl From<crate::transaction::GenesisTransaction> for GenesisTransaction {
2483    fn from(value: crate::transaction::GenesisTransaction) -> Self {
2484        let mut message = Self::default();
2485        message.objects = value.objects.into_iter().map(Into::into).collect();
2486        message
2487    }
2488}
2489
2490//
2491// RandomnessStateUpdate
2492//
2493
2494impl From<crate::transaction::RandomnessStateUpdate> for RandomnessStateUpdate {
2495    fn from(value: crate::transaction::RandomnessStateUpdate) -> Self {
2496        let mut message = Self::default();
2497        message.epoch = Some(value.epoch);
2498        message.randomness_round = Some(value.randomness_round.0);
2499        message.random_bytes = Some(value.random_bytes.into());
2500        message.randomness_object_initial_shared_version =
2501            Some(value.randomness_obj_initial_shared_version.value());
2502        message
2503    }
2504}
2505
2506//
2507// AuthenticatorStateUpdate
2508//
2509
2510impl From<crate::transaction::AuthenticatorStateUpdate> for AuthenticatorStateUpdate {
2511    fn from(value: crate::transaction::AuthenticatorStateUpdate) -> Self {
2512        let mut message = Self::default();
2513        message.epoch = Some(value.epoch);
2514        message.round = Some(value.round);
2515        message.new_active_jwks = value.new_active_jwks.into_iter().map(Into::into).collect();
2516        message.authenticator_object_initial_shared_version =
2517            Some(value.authenticator_obj_initial_shared_version.value());
2518        message
2519    }
2520}
2521
2522//
2523// ActiveJwk
2524//
2525
2526impl From<crate::authenticator_state::ActiveJwk> for ActiveJwk {
2527    fn from(value: crate::authenticator_state::ActiveJwk) -> Self {
2528        let mut jwk_id = JwkId::default();
2529        jwk_id.iss = Some(value.jwk_id.iss);
2530        jwk_id.kid = Some(value.jwk_id.kid);
2531
2532        let mut jwk = Jwk::default();
2533        jwk.kty = Some(value.jwk.kty);
2534        jwk.e = Some(value.jwk.e);
2535        jwk.n = Some(value.jwk.n);
2536        jwk.alg = Some(value.jwk.alg);
2537
2538        let mut message = Self::default();
2539        message.id = Some(jwk_id);
2540        message.jwk = Some(jwk);
2541        message.epoch = Some(value.epoch);
2542        message
2543    }
2544}
2545
2546//
2547// ChangeEpoch
2548//
2549
2550impl From<crate::transaction::ChangeEpoch> for ChangeEpoch {
2551    fn from(value: crate::transaction::ChangeEpoch) -> Self {
2552        let mut message = Self::default();
2553        message.epoch = Some(value.epoch);
2554        message.protocol_version = Some(value.protocol_version.as_u64());
2555        message.storage_charge = Some(value.storage_charge);
2556        message.computation_charge = Some(value.computation_charge);
2557        message.storage_rebate = Some(value.storage_rebate);
2558        message.non_refundable_storage_fee = Some(value.non_refundable_storage_fee);
2559        message.epoch_start_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(
2560            value.epoch_start_timestamp_ms,
2561        ));
2562        message.system_packages = value
2563            .system_packages
2564            .into_iter()
2565            .map(|(version, modules, dependencies)| {
2566                let mut message = SystemPackage::default();
2567                message.version = Some(version.value());
2568                message.modules = modules.into_iter().map(Into::into).collect();
2569                message.dependencies = dependencies
2570                    .iter()
2571                    .map(|d| d.to_canonical_string(true))
2572                    .collect();
2573                message
2574            })
2575            .collect();
2576        message
2577    }
2578}
2579
2580//
2581// EndOfEpochTransactionkind
2582//
2583
2584impl From<crate::transaction::EndOfEpochTransactionKind> for EndOfEpochTransactionKind {
2585    fn from(value: crate::transaction::EndOfEpochTransactionKind) -> Self {
2586        use crate::transaction::EndOfEpochTransactionKind as K;
2587        use end_of_epoch_transaction_kind::Kind;
2588
2589        let message = Self::default();
2590
2591        match value {
2592            K::ChangeEpoch(change_epoch) => message
2593                .with_change_epoch(change_epoch)
2594                .with_kind(Kind::ChangeEpoch),
2595            K::AuthenticatorStateCreate => message.with_kind(Kind::AuthenticatorStateCreate),
2596            K::AuthenticatorStateExpire(expire) => message
2597                .with_authenticator_state_expire(expire)
2598                .with_kind(Kind::AuthenticatorStateExpire),
2599            K::RandomnessStateCreate => message.with_kind(Kind::RandomnessStateCreate),
2600            K::DenyListStateCreate => message.with_kind(Kind::DenyListStateCreate),
2601            K::BridgeStateCreate(chain_id) => message
2602                .with_bridge_chain_id(chain_id.to_string())
2603                .with_kind(Kind::BridgeStateCreate),
2604            K::BridgeCommitteeInit(bridge_object_version) => message
2605                .with_bridge_object_version(bridge_object_version.into())
2606                .with_kind(Kind::BridgeCommitteeInit),
2607            K::StoreExecutionTimeObservations(observations) => message
2608                .with_execution_time_observations(observations)
2609                .with_kind(Kind::StoreExecutionTimeObservations),
2610            K::AccumulatorRootCreate => message.with_kind(Kind::AccumulatorRootCreate),
2611            K::CoinRegistryCreate => message.with_kind(Kind::CoinRegistryCreate),
2612            K::DisplayRegistryCreate => message.with_kind(Kind::DisplayRegistryCreate),
2613            K::AddressAliasStateCreate => message.with_kind(Kind::AddressAliasStateCreate),
2614            K::WriteAccumulatorStorageCost(storage_cost) => message
2615                .with_kind(Kind::WriteAccumulatorStorageCost)
2616                .with_storage_cost(storage_cost.storage_cost),
2617        }
2618    }
2619}
2620
2621//
2622// AuthenticatorStateExpire
2623//
2624
2625impl From<crate::transaction::AuthenticatorStateExpire> for AuthenticatorStateExpire {
2626    fn from(value: crate::transaction::AuthenticatorStateExpire) -> Self {
2627        let mut message = Self::default();
2628        message.min_epoch = Some(value.min_epoch);
2629        message.authenticator_object_initial_shared_version =
2630            Some(value.authenticator_obj_initial_shared_version.value());
2631        message
2632    }
2633}
2634
2635// ExecutionTimeObservations
2636
2637impl From<crate::transaction::StoredExecutionTimeObservations> for ExecutionTimeObservations {
2638    fn from(value: crate::transaction::StoredExecutionTimeObservations) -> Self {
2639        let mut message = Self::default();
2640        match value {
2641            crate::transaction::StoredExecutionTimeObservations::V1(vec) => {
2642                message.version = Some(1);
2643                message.observations = vec
2644                    .into_iter()
2645                    .map(|(key, observation)| {
2646                        use crate::execution::ExecutionTimeObservationKey as K;
2647                        use execution_time_observation::ExecutionTimeObservationKind;
2648
2649                        let mut message = ExecutionTimeObservation::default();
2650
2651                        let kind = match key {
2652                            K::MoveEntryPoint {
2653                                package,
2654                                module,
2655                                function,
2656                                type_arguments,
2657                            } => {
2658                                message.move_entry_point = Some({
2659                                    let mut message = MoveCall::default();
2660                                    message.package = Some(package.to_canonical_string(true));
2661                                    message.module = Some(module);
2662                                    message.function = Some(function);
2663                                    message.type_arguments = type_arguments
2664                                        .into_iter()
2665                                        .map(|ty| ty.to_canonical_string(true))
2666                                        .collect();
2667                                    message
2668                                });
2669                                ExecutionTimeObservationKind::MoveEntryPoint
2670                            }
2671                            K::TransferObjects => ExecutionTimeObservationKind::TransferObjects,
2672                            K::SplitCoins => ExecutionTimeObservationKind::SplitCoins,
2673                            K::MergeCoins => ExecutionTimeObservationKind::MergeCoins,
2674                            K::Publish => ExecutionTimeObservationKind::Publish,
2675                            K::MakeMoveVec => ExecutionTimeObservationKind::MakeMoveVector,
2676                            K::Upgrade => ExecutionTimeObservationKind::Upgrade,
2677                        };
2678
2679                        message.validator_observations = observation
2680                            .into_iter()
2681                            .map(|(name, duration)| {
2682                                let mut message = ValidatorExecutionTimeObservation::default();
2683                                message.validator = Some(name.0.to_vec().into());
2684                                message.duration = Some(prost_types::Duration {
2685                                    seconds: duration.as_secs() as i64,
2686                                    nanos: duration.subsec_nanos() as i32,
2687                                });
2688                                message
2689                            })
2690                            .collect();
2691
2692                        message.set_kind(kind);
2693                        message
2694                    })
2695                    .collect();
2696            }
2697        }
2698
2699        message
2700    }
2701}
2702
2703//
2704// ProgrammableTransaction
2705//
2706
2707impl From<crate::transaction::ProgrammableTransaction> for ProgrammableTransaction {
2708    fn from(value: crate::transaction::ProgrammableTransaction) -> Self {
2709        let mut message = Self::default();
2710        message.inputs = value.inputs.into_iter().map(Into::into).collect();
2711        message.commands = value.commands.into_iter().map(Into::into).collect();
2712        message
2713    }
2714}
2715
2716//
2717// Input
2718//
2719
2720impl From<crate::transaction::CallArg> for Input {
2721    fn from(value: crate::transaction::CallArg) -> Self {
2722        use crate::transaction::CallArg as I;
2723        use crate::transaction::ObjectArg as O;
2724        use input::InputKind;
2725        use input::Mutability;
2726
2727        let mut message = Self::default();
2728
2729        let kind = match value {
2730            I::Pure(value) => {
2731                message.pure = Some(value.into());
2732                InputKind::Pure
2733            }
2734            I::Object(o) => match o {
2735                O::ImmOrOwnedObject((id, version, digest)) => {
2736                    message.object_id = Some(id.to_canonical_string(true));
2737                    message.version = Some(version.value());
2738                    message.digest = Some(digest.to_string());
2739                    InputKind::ImmutableOrOwned
2740                }
2741                O::SharedObject {
2742                    id,
2743                    initial_shared_version,
2744                    mutability,
2745                } => {
2746                    message.object_id = Some(id.to_canonical_string(true));
2747                    message.version = Some(initial_shared_version.value());
2748                    message.mutable = Some(mutability.is_exclusive());
2749                    message.set_mutability(match mutability {
2750                        crate::transaction::SharedObjectMutability::Immutable => {
2751                            Mutability::Immutable
2752                        }
2753                        crate::transaction::SharedObjectMutability::Mutable => Mutability::Mutable,
2754                        crate::transaction::SharedObjectMutability::NonExclusiveWrite => {
2755                            Mutability::NonExclusiveWrite
2756                        }
2757                    });
2758                    InputKind::Shared
2759                }
2760                O::Receiving((id, version, digest)) => {
2761                    message.object_id = Some(id.to_canonical_string(true));
2762                    message.version = Some(version.value());
2763                    message.digest = Some(digest.to_string());
2764                    InputKind::Receiving
2765                }
2766            },
2767            I::FundsWithdrawal(withdrawal) => {
2768                message.set_funds_withdrawal(withdrawal);
2769                InputKind::FundsWithdrawal
2770            }
2771        };
2772
2773        message.set_kind(kind);
2774        message
2775    }
2776}
2777
2778impl From<crate::transaction::FundsWithdrawalArg> for FundsWithdrawal {
2779    fn from(value: crate::transaction::FundsWithdrawalArg) -> Self {
2780        use funds_withdrawal::Source;
2781
2782        let mut message = Self::default();
2783
2784        message.amount = match value.reservation {
2785            crate::transaction::Reservation::MaxAmountU64(amount) => Some(amount),
2786        };
2787        let crate::transaction::WithdrawalTypeArg::Balance(coin_type) = value.type_arg;
2788        message.coin_type = Some(coin_type.to_canonical_string(true));
2789        message.set_source(match value.withdraw_from {
2790            crate::transaction::WithdrawFrom::Sender => Source::Sender,
2791            crate::transaction::WithdrawFrom::Sponsor => Source::Sponsor,
2792        });
2793
2794        message
2795    }
2796}
2797
2798//
2799// Argument
2800//
2801
2802impl From<crate::transaction::Argument> for Argument {
2803    fn from(value: crate::transaction::Argument) -> Self {
2804        use crate::transaction::Argument as A;
2805        use argument::ArgumentKind;
2806
2807        let mut message = Self::default();
2808
2809        let kind = match value {
2810            A::GasCoin => ArgumentKind::Gas,
2811            A::Input(input) => {
2812                message.input = Some(input.into());
2813                ArgumentKind::Input
2814            }
2815            A::Result(result) => {
2816                message.result = Some(result.into());
2817                ArgumentKind::Result
2818            }
2819            A::NestedResult(result, subresult) => {
2820                message.result = Some(result.into());
2821                message.subresult = Some(subresult.into());
2822                ArgumentKind::Result
2823            }
2824        };
2825
2826        message.set_kind(kind);
2827        message
2828    }
2829}
2830
2831//
2832// Command
2833//
2834
2835impl From<crate::transaction::Command> for Command {
2836    fn from(value: crate::transaction::Command) -> Self {
2837        use crate::transaction::Command as C;
2838        use command::Command;
2839
2840        let command = match value {
2841            C::MoveCall(move_call) => Command::MoveCall((*move_call).into()),
2842            C::TransferObjects(objects, address) => Command::TransferObjects({
2843                let mut message = TransferObjects::default();
2844                message.objects = objects.into_iter().map(Into::into).collect();
2845                message.address = Some(address.into());
2846                message
2847            }),
2848            C::SplitCoins(coin, amounts) => Command::SplitCoins({
2849                let mut message = SplitCoins::default();
2850                message.coin = Some(coin.into());
2851                message.amounts = amounts.into_iter().map(Into::into).collect();
2852                message
2853            }),
2854            C::MergeCoins(coin, coins_to_merge) => Command::MergeCoins({
2855                let mut message = MergeCoins::default();
2856                message.coin = Some(coin.into());
2857                message.coins_to_merge = coins_to_merge.into_iter().map(Into::into).collect();
2858                message
2859            }),
2860            C::Publish(modules, dependencies) => Command::Publish({
2861                let mut message = Publish::default();
2862                message.modules = modules.into_iter().map(Into::into).collect();
2863                message.dependencies = dependencies
2864                    .iter()
2865                    .map(|d| d.to_canonical_string(true))
2866                    .collect();
2867                message
2868            }),
2869            C::MakeMoveVec(element_type, elements) => Command::MakeMoveVector({
2870                let mut message = MakeMoveVector::default();
2871                message.element_type = element_type.map(|t| t.to_canonical_string(true));
2872                message.elements = elements.into_iter().map(Into::into).collect();
2873                message
2874            }),
2875            C::Upgrade(modules, dependencies, package, ticket) => Command::Upgrade({
2876                let mut message = Upgrade::default();
2877                message.modules = modules.into_iter().map(Into::into).collect();
2878                message.dependencies = dependencies
2879                    .iter()
2880                    .map(|d| d.to_canonical_string(true))
2881                    .collect();
2882                message.package = Some(package.to_canonical_string(true));
2883                message.ticket = Some(ticket.into());
2884                message
2885            }),
2886        };
2887
2888        let mut message = Self::default();
2889        message.command = Some(command);
2890        message
2891    }
2892}
2893
2894//
2895// MoveCall
2896//
2897
2898impl From<crate::transaction::ProgrammableMoveCall> for MoveCall {
2899    fn from(value: crate::transaction::ProgrammableMoveCall) -> Self {
2900        let mut message = Self::default();
2901        message.package = Some(value.package.to_canonical_string(true));
2902        message.module = Some(value.module.to_string());
2903        message.function = Some(value.function.to_string());
2904        message.type_arguments = value
2905            .type_arguments
2906            .iter()
2907            .map(|t| t.to_canonical_string(true))
2908            .collect();
2909        message.arguments = value.arguments.into_iter().map(Into::into).collect();
2910        message
2911    }
2912}
2913
2914//
2915// TransactionEffects
2916//
2917
2918impl From<crate::effects::TransactionEffects> for TransactionEffects {
2919    fn from(value: crate::effects::TransactionEffects) -> Self {
2920        Self::merge_from(&value, &FieldMaskTree::new_wildcard())
2921    }
2922}
2923
2924impl Merge<&crate::effects::TransactionEffects> for TransactionEffects {
2925    fn merge(&mut self, source: &crate::effects::TransactionEffects, mask: &FieldMaskTree) {
2926        if mask.contains(Self::BCS_FIELD.name) {
2927            let mut bcs = Bcs::serialize(&source).unwrap();
2928            bcs.name = Some("TransactionEffects".to_owned());
2929            self.bcs = Some(bcs);
2930        }
2931
2932        if mask.contains(Self::DIGEST_FIELD.name) {
2933            self.digest = Some(source.digest().to_string());
2934        }
2935
2936        match source {
2937            crate::effects::TransactionEffects::V1(v1) => self.merge(v1, mask),
2938            crate::effects::TransactionEffects::V2(v2) => self.merge(v2, mask),
2939        }
2940    }
2941}
2942
2943//
2944// TransactionEffectsV1
2945//
2946
2947impl Merge<&crate::effects::TransactionEffectsV1> for TransactionEffects {
2948    fn merge(&mut self, value: &crate::effects::TransactionEffectsV1, mask: &FieldMaskTree) {
2949        use crate::effects::TransactionEffectsAPI;
2950
2951        if mask.contains(Self::VERSION_FIELD.name) {
2952            self.version = Some(1);
2953        }
2954
2955        if mask.contains(Self::STATUS_FIELD.name) {
2956            self.status = Some(value.status().clone().into());
2957        }
2958
2959        if mask.contains(Self::EPOCH_FIELD.name) {
2960            self.epoch = Some(value.executed_epoch());
2961        }
2962
2963        if mask.contains(Self::GAS_USED_FIELD.name) {
2964            self.gas_used = Some(value.gas_cost_summary().clone().into());
2965        }
2966
2967        if mask.contains(Self::TRANSACTION_DIGEST_FIELD.name) {
2968            self.transaction_digest = Some(value.transaction_digest().to_string());
2969        }
2970
2971        if mask.contains(Self::EVENTS_DIGEST_FIELD.name) {
2972            self.events_digest = value.events_digest().map(|d| d.to_string());
2973        }
2974
2975        if mask.contains(Self::DEPENDENCIES_FIELD.name) {
2976            self.dependencies = value
2977                .dependencies()
2978                .iter()
2979                .map(ToString::to_string)
2980                .collect();
2981        }
2982
2983        if mask.contains(Self::CHANGED_OBJECTS_FIELD.name)
2984            || mask.contains(Self::UNCHANGED_CONSENSUS_OBJECTS_FIELD.name)
2985            || mask.contains(Self::GAS_OBJECT_FIELD.name)
2986        {
2987            let mut changed_objects = Vec::new();
2988            let mut unchanged_consensus_objects = Vec::new();
2989
2990            for ((id, version, digest), owner) in value.created() {
2991                let mut change = ChangedObject::default();
2992                change.object_id = Some(id.to_canonical_string(true));
2993                change.input_state = Some(changed_object::InputObjectState::DoesNotExist.into());
2994                change.output_state = Some(changed_object::OutputObjectState::ObjectWrite.into());
2995                change.output_version = Some(version.value());
2996                change.output_digest = Some(digest.to_string());
2997                change.output_owner = Some(owner.clone().into());
2998                change.id_operation = Some(changed_object::IdOperation::Created.into());
2999
3000                changed_objects.push(change);
3001            }
3002
3003            for ((id, version, digest), owner) in value.mutated() {
3004                let mut change = ChangedObject::default();
3005                change.object_id = Some(id.to_canonical_string(true));
3006                change.input_state = Some(changed_object::InputObjectState::Exists.into());
3007                change.output_state = Some(changed_object::OutputObjectState::ObjectWrite.into());
3008                change.output_version = Some(version.value());
3009                change.output_digest = Some(digest.to_string());
3010                change.output_owner = Some(owner.clone().into());
3011                change.id_operation = Some(changed_object::IdOperation::None.into());
3012
3013                changed_objects.push(change);
3014            }
3015
3016            for ((id, version, digest), owner) in value.unwrapped() {
3017                let mut change = ChangedObject::default();
3018                change.object_id = Some(id.to_canonical_string(true));
3019                change.input_state = Some(changed_object::InputObjectState::DoesNotExist.into());
3020                change.output_state = Some(changed_object::OutputObjectState::ObjectWrite.into());
3021                change.output_version = Some(version.value());
3022                change.output_digest = Some(digest.to_string());
3023                change.output_owner = Some(owner.clone().into());
3024                change.id_operation = Some(changed_object::IdOperation::None.into());
3025
3026                changed_objects.push(change);
3027            }
3028
3029            for (id, version, digest) in value.deleted() {
3030                let mut change = ChangedObject::default();
3031                change.object_id = Some(id.to_canonical_string(true));
3032                change.input_state = Some(changed_object::InputObjectState::Exists.into());
3033                change.output_state = Some(changed_object::OutputObjectState::DoesNotExist.into());
3034                change.output_version = Some(version.value());
3035                change.output_digest = Some(digest.to_string());
3036                change.id_operation = Some(changed_object::IdOperation::Deleted.into());
3037
3038                changed_objects.push(change);
3039            }
3040
3041            for (id, version, digest) in value.unwrapped_then_deleted() {
3042                let mut change = ChangedObject::default();
3043                change.object_id = Some(id.to_canonical_string(true));
3044                change.input_state = Some(changed_object::InputObjectState::DoesNotExist.into());
3045                change.output_state = Some(changed_object::OutputObjectState::DoesNotExist.into());
3046                change.output_version = Some(version.value());
3047                change.output_digest = Some(digest.to_string());
3048                change.id_operation = Some(changed_object::IdOperation::Deleted.into());
3049
3050                changed_objects.push(change);
3051            }
3052
3053            for (id, version, digest) in value.wrapped() {
3054                let mut change = ChangedObject::default();
3055                change.object_id = Some(id.to_canonical_string(true));
3056                change.input_state = Some(changed_object::InputObjectState::Exists.into());
3057                change.output_state = Some(changed_object::OutputObjectState::DoesNotExist.into());
3058                change.output_version = Some(version.value());
3059                change.output_digest = Some(digest.to_string());
3060                change.id_operation = Some(changed_object::IdOperation::Deleted.into());
3061
3062                changed_objects.push(change);
3063            }
3064
3065            for (object_id, version) in value.modified_at_versions() {
3066                let object_id = object_id.to_canonical_string(true);
3067                let version = version.value();
3068                if let Some(changed_object) = changed_objects
3069                    .iter_mut()
3070                    .find(|object| object.object_id() == object_id)
3071                {
3072                    changed_object.input_version = Some(version);
3073                }
3074            }
3075
3076            for (id, version, digest) in value.shared_objects() {
3077                let object_id = id.to_canonical_string(true);
3078                let version = version.value();
3079                let digest = digest.to_string();
3080
3081                if let Some(changed_object) = changed_objects
3082                    .iter_mut()
3083                    .find(|object| object.object_id() == object_id)
3084                {
3085                    changed_object.input_version = Some(version);
3086                    changed_object.input_digest = Some(digest);
3087                } else {
3088                    let mut unchanged_consensus_object = UnchangedConsensusObject::default();
3089                    unchanged_consensus_object.kind = Some(
3090                        unchanged_consensus_object::UnchangedConsensusObjectKind::ReadOnlyRoot
3091                            .into(),
3092                    );
3093                    unchanged_consensus_object.object_id = Some(object_id);
3094                    unchanged_consensus_object.version = Some(version);
3095                    unchanged_consensus_object.digest = Some(digest);
3096
3097                    unchanged_consensus_objects.push(unchanged_consensus_object);
3098                }
3099            }
3100
3101            if mask.contains(Self::GAS_OBJECT_FIELD.name) {
3102                let gas_object_id = value.gas_object().0.0.to_canonical_string(true);
3103                self.gas_object = changed_objects
3104                    .iter()
3105                    .find(|object| object.object_id() == gas_object_id)
3106                    .cloned();
3107            }
3108
3109            if mask.contains(Self::CHANGED_OBJECTS_FIELD.name) {
3110                self.changed_objects = changed_objects;
3111            }
3112
3113            if mask.contains(Self::UNCHANGED_CONSENSUS_OBJECTS_FIELD.name) {
3114                self.unchanged_consensus_objects = unchanged_consensus_objects;
3115            }
3116        }
3117    }
3118}
3119
3120//
3121// TransactionEffectsV2
3122//
3123
3124impl Merge<&crate::effects::TransactionEffectsV2> for TransactionEffects {
3125    fn merge(
3126        &mut self,
3127        crate::effects::TransactionEffectsV2 {
3128            status,
3129            executed_epoch,
3130            gas_used,
3131            transaction_digest,
3132            gas_object_index,
3133            events_digest,
3134            dependencies,
3135            lamport_version,
3136            changed_objects,
3137            unchanged_consensus_objects,
3138            aux_data_digest,
3139        }: &crate::effects::TransactionEffectsV2,
3140        mask: &FieldMaskTree,
3141    ) {
3142        if mask.contains(Self::VERSION_FIELD.name) {
3143            self.version = Some(2);
3144        }
3145
3146        if mask.contains(Self::STATUS_FIELD.name) {
3147            self.status = Some(status.clone().into());
3148        }
3149
3150        if mask.contains(Self::EPOCH_FIELD.name) {
3151            self.epoch = Some(*executed_epoch);
3152        }
3153
3154        if mask.contains(Self::GAS_USED_FIELD.name) {
3155            self.gas_used = Some(gas_used.clone().into());
3156        }
3157
3158        if mask.contains(Self::TRANSACTION_DIGEST_FIELD.name) {
3159            self.transaction_digest = Some(transaction_digest.to_string());
3160        }
3161
3162        if mask.contains(Self::GAS_OBJECT_FIELD.name) {
3163            self.gas_object = gas_object_index
3164                .map(|index| {
3165                    changed_objects
3166                        .get(index as usize)
3167                        .cloned()
3168                        .map(|(id, change)| {
3169                            let mut message = ChangedObject::from(change);
3170                            message.object_id = Some(id.to_canonical_string(true));
3171                            message
3172                        })
3173                })
3174                .flatten();
3175        }
3176
3177        if mask.contains(Self::EVENTS_DIGEST_FIELD.name) {
3178            self.events_digest = events_digest.map(|d| d.to_string());
3179        }
3180
3181        if mask.contains(Self::DEPENDENCIES_FIELD.name) {
3182            self.dependencies = dependencies.iter().map(ToString::to_string).collect();
3183        }
3184
3185        if mask.contains(Self::LAMPORT_VERSION_FIELD.name) {
3186            self.lamport_version = Some(lamport_version.value());
3187        }
3188
3189        if mask.contains(Self::CHANGED_OBJECTS_FIELD.name) {
3190            self.changed_objects = changed_objects
3191                .clone()
3192                .into_iter()
3193                .map(|(id, change)| {
3194                    let mut message = ChangedObject::from(change);
3195                    message.object_id = Some(id.to_canonical_string(true));
3196                    message
3197                })
3198                .collect();
3199        }
3200
3201        for object in self.changed_objects.iter_mut().chain(&mut self.gas_object) {
3202            if object.output_digest.is_some() && object.output_version.is_none() {
3203                object.output_version = Some(lamport_version.value());
3204            }
3205        }
3206
3207        if mask.contains(Self::UNCHANGED_CONSENSUS_OBJECTS_FIELD.name) {
3208            self.unchanged_consensus_objects = unchanged_consensus_objects
3209                .clone()
3210                .into_iter()
3211                .map(|(id, unchanged)| {
3212                    let mut message = UnchangedConsensusObject::from(unchanged);
3213                    message.object_id = Some(id.to_canonical_string(true));
3214                    message
3215                })
3216                .collect();
3217        }
3218
3219        if mask.contains(Self::AUXILIARY_DATA_DIGEST_FIELD.name) {
3220            self.auxiliary_data_digest = aux_data_digest.map(|d| d.to_string());
3221        }
3222    }
3223}
3224
3225//
3226// ChangedObject
3227//
3228
3229impl From<crate::effects::EffectsObjectChange> for ChangedObject {
3230    fn from(value: crate::effects::EffectsObjectChange) -> Self {
3231        use crate::effects::ObjectIn;
3232        use crate::effects::ObjectOut;
3233        use changed_object::InputObjectState;
3234        use changed_object::OutputObjectState;
3235
3236        let mut message = Self::default();
3237
3238        // Input State
3239        let input_state = match value.input_state {
3240            ObjectIn::NotExist => InputObjectState::DoesNotExist,
3241            ObjectIn::Exist(((version, digest), owner)) => {
3242                message.input_version = Some(version.value());
3243                message.input_digest = Some(digest.to_string());
3244                message.input_owner = Some(owner.into());
3245                InputObjectState::Exists
3246            }
3247        };
3248        message.set_input_state(input_state);
3249
3250        // Output State
3251        let output_state = match value.output_state {
3252            ObjectOut::NotExist => OutputObjectState::DoesNotExist,
3253            ObjectOut::ObjectWrite((digest, owner)) => {
3254                message.output_digest = Some(digest.to_string());
3255                message.output_owner = Some(owner.into());
3256                OutputObjectState::ObjectWrite
3257            }
3258            ObjectOut::PackageWrite((version, digest)) => {
3259                message.output_version = Some(version.value());
3260                message.output_digest = Some(digest.to_string());
3261                OutputObjectState::PackageWrite
3262            }
3263            ObjectOut::AccumulatorWriteV1(accumulator_write) => {
3264                message.set_accumulator_write(accumulator_write);
3265                OutputObjectState::AccumulatorWrite
3266            }
3267        };
3268        message.set_output_state(output_state);
3269
3270        message.set_id_operation(value.id_operation.into());
3271        message
3272    }
3273}
3274
3275impl From<crate::effects::AccumulatorWriteV1> for AccumulatorWrite {
3276    fn from(value: crate::effects::AccumulatorWriteV1) -> Self {
3277        use accumulator_write::AccumulatorOperation;
3278
3279        let mut message = Self::default();
3280
3281        message.set_address(value.address.address.to_string());
3282        message.set_accumulator_type(value.address.ty.to_canonical_string(true));
3283        message.set_operation(match value.operation {
3284            crate::effects::AccumulatorOperation::Merge => AccumulatorOperation::Merge,
3285            crate::effects::AccumulatorOperation::Split => AccumulatorOperation::Split,
3286        });
3287        match value.value {
3288            crate::effects::AccumulatorValue::Integer(value) => message.set_value(value),
3289            //TODO unsupported value types
3290            crate::effects::AccumulatorValue::IntegerTuple(_, _)
3291            | crate::effects::AccumulatorValue::EventDigest(_) => {}
3292        }
3293
3294        message
3295    }
3296}
3297
3298//
3299// IdOperation
3300//
3301
3302impl From<crate::effects::IDOperation> for changed_object::IdOperation {
3303    fn from(value: crate::effects::IDOperation) -> Self {
3304        use crate::effects::IDOperation as I;
3305
3306        match value {
3307            I::None => Self::None,
3308            I::Created => Self::Created,
3309            I::Deleted => Self::Deleted,
3310        }
3311    }
3312}
3313
3314//
3315// UnchangedConsensusObject
3316//
3317
3318impl From<crate::effects::UnchangedConsensusKind> for UnchangedConsensusObject {
3319    fn from(value: crate::effects::UnchangedConsensusKind) -> Self {
3320        use crate::effects::UnchangedConsensusKind as K;
3321        use unchanged_consensus_object::UnchangedConsensusObjectKind;
3322
3323        let mut message = Self::default();
3324
3325        let kind = match value {
3326            K::ReadOnlyRoot((version, digest)) => {
3327                message.version = Some(version.value());
3328                message.digest = Some(digest.to_string());
3329                UnchangedConsensusObjectKind::ReadOnlyRoot
3330            }
3331            K::MutateConsensusStreamEnded(version) => {
3332                message.version = Some(version.value());
3333                UnchangedConsensusObjectKind::MutateConsensusStreamEnded
3334            }
3335            K::ReadConsensusStreamEnded(version) => {
3336                message.version = Some(version.value());
3337                UnchangedConsensusObjectKind::ReadConsensusStreamEnded
3338            }
3339            K::Cancelled(version) => {
3340                message.version = Some(version.value());
3341                UnchangedConsensusObjectKind::Canceled
3342            }
3343            K::PerEpochConfig => UnchangedConsensusObjectKind::PerEpochConfig,
3344            // PerEpochConfigWithSequenceNumber { version } => {
3345            //     message.version = Some(version);
3346            //     UnchangedSharedObjectKind::PerEpochConfig
3347            // }
3348        };
3349
3350        message.set_kind(kind);
3351        message
3352    }
3353}
3354
3355//
3356// TransactionChecks
3357//
3358
3359impl From<simulate_transaction_request::TransactionChecks>
3360    for crate::transaction_executor::TransactionChecks
3361{
3362    fn from(value: simulate_transaction_request::TransactionChecks) -> Self {
3363        match value {
3364            simulate_transaction_request::TransactionChecks::Enabled => Self::Enabled,
3365            simulate_transaction_request::TransactionChecks::Disabled => Self::Disabled,
3366            // Default to enabled
3367            _ => Self::Enabled,
3368        }
3369    }
3370}
3371
3372//
3373// Coin-related conversions
3374//
3375
3376impl From<crate::coin_registry::MetadataCapState> for coin_metadata::MetadataCapState {
3377    fn from(value: crate::coin_registry::MetadataCapState) -> Self {
3378        match value {
3379            crate::coin_registry::MetadataCapState::Claimed(_) => {
3380                coin_metadata::MetadataCapState::Claimed
3381            }
3382            crate::coin_registry::MetadataCapState::Unclaimed => {
3383                coin_metadata::MetadataCapState::Unclaimed
3384            }
3385            crate::coin_registry::MetadataCapState::Deleted => {
3386                coin_metadata::MetadataCapState::Deleted
3387            }
3388        }
3389    }
3390}
3391
3392impl From<&crate::coin_registry::Currency> for CoinMetadata {
3393    fn from(value: &crate::coin_registry::Currency) -> Self {
3394        let mut metadata = CoinMetadata::default();
3395        metadata.id = Some(sui_sdk_types::Address::from(value.id.into_bytes()).to_string());
3396        metadata.decimals = Some(value.decimals.into());
3397        metadata.name = Some(value.name.clone());
3398        metadata.symbol = Some(value.symbol.clone());
3399        metadata.description = Some(value.description.clone());
3400        metadata.icon_url = Some(value.icon_url.clone());
3401
3402        match &value.metadata_cap_id {
3403            crate::coin_registry::MetadataCapState::Claimed(id) => {
3404                metadata.metadata_cap_state = Some(coin_metadata::MetadataCapState::Claimed as i32);
3405                metadata.metadata_cap_id = Some(sui_sdk_types::Address::from(*id).to_string());
3406            }
3407            crate::coin_registry::MetadataCapState::Unclaimed => {
3408                metadata.metadata_cap_state =
3409                    Some(coin_metadata::MetadataCapState::Unclaimed as i32);
3410            }
3411            crate::coin_registry::MetadataCapState::Deleted => {
3412                metadata.metadata_cap_state = Some(coin_metadata::MetadataCapState::Deleted as i32);
3413            }
3414        }
3415
3416        metadata
3417    }
3418}
3419
3420impl From<crate::coin::CoinMetadata> for CoinMetadata {
3421    fn from(value: crate::coin::CoinMetadata) -> Self {
3422        let mut metadata = CoinMetadata::default();
3423        metadata.id = Some(sui_sdk_types::Address::from(value.id.id.bytes).to_string());
3424        metadata.decimals = Some(value.decimals.into());
3425        metadata.name = Some(value.name);
3426        metadata.symbol = Some(value.symbol);
3427        metadata.description = Some(value.description);
3428        metadata.icon_url = value.icon_url;
3429        metadata
3430    }
3431}
3432
3433impl From<crate::coin_registry::SupplyState> for coin_treasury::SupplyState {
3434    fn from(value: crate::coin_registry::SupplyState) -> Self {
3435        match value {
3436            crate::coin_registry::SupplyState::Fixed(_) => coin_treasury::SupplyState::Fixed,
3437            crate::coin_registry::SupplyState::BurnOnly(_) => coin_treasury::SupplyState::BurnOnly,
3438            crate::coin_registry::SupplyState::Unknown => coin_treasury::SupplyState::Unknown,
3439        }
3440    }
3441}
3442
3443impl From<crate::coin::TreasuryCap> for CoinTreasury {
3444    fn from(value: crate::coin::TreasuryCap) -> Self {
3445        let mut treasury = CoinTreasury::default();
3446        treasury.id = Some(sui_sdk_types::Address::from(value.id.id.bytes).to_string());
3447        treasury.total_supply = Some(value.total_supply.value);
3448        treasury
3449    }
3450}
3451
3452impl From<&crate::coin_registry::RegulatedState> for RegulatedCoinMetadata {
3453    fn from(value: &crate::coin_registry::RegulatedState) -> Self {
3454        let mut regulated = RegulatedCoinMetadata::default();
3455
3456        match value {
3457            crate::coin_registry::RegulatedState::Regulated {
3458                cap,
3459                allow_global_pause,
3460                variant,
3461            } => {
3462                regulated.deny_cap_object = Some(sui_sdk_types::Address::from(*cap).to_string());
3463                regulated.allow_global_pause = *allow_global_pause;
3464                regulated.variant = Some(*variant as u32);
3465                regulated.coin_regulated_state =
3466                    Some(regulated_coin_metadata::CoinRegulatedState::Regulated as i32);
3467            }
3468            crate::coin_registry::RegulatedState::Unregulated => {
3469                regulated.coin_regulated_state =
3470                    Some(regulated_coin_metadata::CoinRegulatedState::Unregulated as i32);
3471            }
3472            crate::coin_registry::RegulatedState::Unknown => {
3473                regulated.coin_regulated_state =
3474                    Some(regulated_coin_metadata::CoinRegulatedState::Unknown as i32);
3475            }
3476        }
3477
3478        regulated
3479    }
3480}
3481
3482impl From<crate::coin_registry::RegulatedState> for RegulatedCoinMetadata {
3483    fn from(value: crate::coin_registry::RegulatedState) -> Self {
3484        (&value).into()
3485    }
3486}
3487
3488impl From<crate::coin::RegulatedCoinMetadata> for RegulatedCoinMetadata {
3489    fn from(value: crate::coin::RegulatedCoinMetadata) -> Self {
3490        let mut message = RegulatedCoinMetadata::default();
3491        message.id = Some(sui_sdk_types::Address::from(value.id.id.bytes).to_string());
3492        message.coin_metadata_object =
3493            Some(sui_sdk_types::Address::from(value.coin_metadata_object.bytes).to_string());
3494        message.deny_cap_object =
3495            Some(sui_sdk_types::Address::from(value.deny_cap_object.bytes).to_string());
3496        message.coin_regulated_state =
3497            Some(regulated_coin_metadata::CoinRegulatedState::Regulated as i32);
3498        message
3499    }
3500}
3501
3502impl TryFrom<&ObjectSet> for crate::full_checkpoint_content::ObjectSet {
3503    type Error = TryFromProtoError;
3504
3505    fn try_from(value: &ObjectSet) -> Result<Self, Self::Error> {
3506        let mut objects = Self::default();
3507
3508        for o in value.objects() {
3509            objects.insert(
3510                o.bcs()
3511                    .deserialize()
3512                    .map_err(|e| TryFromProtoError::invalid("object.bcs", e))?,
3513            );
3514        }
3515
3516        Ok(objects)
3517    }
3518}