sui_types/
rpc_proto_conversions.rs

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