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