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